Browse Source

Merge pull request #20644 from gregzanch/svgarcfix

Fixes SVGLoader arc parsing with zero radius path commands.
Mr.doob 4 years ago
parent
commit
212d49813b

+ 12 - 0
examples/js/loaders/SVGLoader.js

@@ -386,6 +386,9 @@ THREE.SVGLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype
 						var numbers = parseFloats( data );
 
 						for ( var j = 0, jl = numbers.length; j < jl; j += 7 ) {
+							
+							// skip command if start point == end point
+							if ( numbers[ j + 5 ] == point.x && numbers[ j + 6 ] == point.y ) continue;
 
 							var start = point.clone();
 							point.x = numbers[ j + 5 ];
@@ -576,6 +579,9 @@ THREE.SVGLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype
 
 						for ( var j = 0, jl = numbers.length; j < jl; j += 7 ) {
 
+							// skip command if no displacement
+							if ( numbers[ j + 5 ] == 0 && numbers[ j + 6 ] == 0 ) continue;
+
 							var start = point.clone();
 							point.x += numbers[ j + 5 ];
 							point.y += numbers[ j + 6 ];
@@ -660,6 +666,12 @@ THREE.SVGLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype
 
 		function parseArcCommand( path, rx, ry, x_axis_rotation, large_arc_flag, sweep_flag, start, end ) {
 
+			if ( rx == 0 || ry == 0 ) {
+				// draw a line if either of the radii == 0
+				path.lineTo( end.x, end.y );
+				return;
+			}
+
 			x_axis_rotation = x_axis_rotation * Math.PI / 180;
 
 			// Ensure radii are positive

+ 12 - 0
examples/jsm/loaders/SVGLoader.js

@@ -398,6 +398,9 @@ SVGLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
 						var numbers = parseFloats( data );
 
 						for ( var j = 0, jl = numbers.length; j < jl; j += 7 ) {
+							
+							// skip command if start point == end point
+							if ( numbers[ j + 5 ] == point.x && numbers[ j + 6 ] == point.y ) continue;
 
 							var start = point.clone();
 							point.x = numbers[ j + 5 ];
@@ -588,6 +591,9 @@ SVGLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
 
 						for ( var j = 0, jl = numbers.length; j < jl; j += 7 ) {
 
+							// skip command if no displacement
+							if ( numbers[ j + 5 ] == 0 && numbers[ j + 6 ] == 0 ) continue;
+
 							var start = point.clone();
 							point.x += numbers[ j + 5 ];
 							point.y += numbers[ j + 6 ];
@@ -672,6 +678,12 @@ SVGLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
 
 		function parseArcCommand( path, rx, ry, x_axis_rotation, large_arc_flag, sweep_flag, start, end ) {
 
+			if ( rx == 0 || ry == 0 ) {
+				// draw a line if either of the radii == 0
+				path.lineTo( end.x, end.y );
+				return;
+			}
+
 			x_axis_rotation = x_axis_rotation * Math.PI / 180;
 
 			// Ensure radii are positive

+ 8 - 0
examples/models/svg/zero-radius.svg

@@ -0,0 +1,8 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="930.29" height="802.11" viewBox="0 0 930.29 802.11">
+  <path
+    d="M731.61,544H889.45A10.5,10.5,0,0,1,900,554.5v16.13a0,0,0,0,1,0,0H713.61a0,0,0,0,1,0,0V562A18,18,0,0,1,731.61,544Z"
+   fill="#40414d" />
+  <path
+    d="M906.69,385.69h8.06a0,0,0,0,1,0,0V563.63a7,7,0,0,1-7,7H901a7,7,0,0,1-7-7V398.35a12.66,12.66,0,0,1,12.66-12.66Z"
+    fill="#40414d" />
+</svg>

+ 2 - 2
examples/webgl_loader_svg.html

@@ -104,8 +104,8 @@
 					"Defs": 'models/svg/tests/testDefs/Svg-defs.svg',
 					"Defs2": 'models/svg/tests/testDefs/Svg-defs2.svg',
 					"Defs3": 'models/svg/tests/testDefs/Wave-defs.svg',
-					"Defs4": 'models/svg/tests/testDefs/defs4.svg'
-
+					"Defs4": 'models/svg/tests/testDefs/defs4.svg',
+					"Zero Radius": 'models/svg/zero-radius.svg'
 
 				} ).name( 'SVG File' ).onChange( update );