SVGLoader - compound shape (circle with hole) loads inverted

Hi,
sorry if too many posts recently.
all pertain to the same thing, however I’m trying to keep the problems separate.

I know I’ve solved this before, and wish i had made notes on it.
using SVG Loader I’m loading a multi-shape svg.
some of the parts are compound paths.

They are circles with a circle cut out of the center. (donut)
This is what they look like in Illustrator.
illustrator_compound_circle

they have the xml path code as such:

    <path id="pipe_04" data-name="pipe 04"
      d="M600.5,665a20,20,0,1,0,20,20A20,20,0,0,0,600.5,665Zm0,27.5A7.5,7.5,0,1,1,608,685,7.5,7.5,0,0,1,600.5,692.5Z"
      transform="translate(0 -15)" fill="#9f8600" />

and here’s a simplified isolated svg with it…
compound circle

when the complex object gets loaded, everything comes in perfectly except these.

this is how they appear…
the BOTTOM one (small dot) is the way they all appear in my THREE app.
the TOP larger yellow circle one is there to show as comparison to how it should come in (but with a hole)

notice that in the bottom one the inner center is only showing, yet in the next picture down, you can see that the outer circle is still there, not showing, and is extruded inversely.
when extruded, this is the result i get.
BOTTOM one is how they all look.
TOP yellow one is just the regular comparison circle showing KIND of how it should look. (but the middle would be empty not extruded.)

here is my SVG loader function code…

loadSVG( svgFileInput );
                

                function loadSVG( url ) 
                {

                    const loader = new THREE.SVGLoader();

                    loader.load( url, function ( data ) {


                        console.log('data from data: ',data);

                        const paths = data.paths;

                        
                        for ( let i = 0; i < paths.length; i ++ ) {

                            const path = paths[ i ];


                            const fillColor = path.userData.style.fill;
                            console.log('fillColor: ',fillColor);


                            const material = new THREE.MeshBasicMaterial( {
                                
                                color: new THREE.Color().setStyle( fillColor ),
                                opacity: path.userData.style.fillOpacity,
                                transparent: path.userData.style.fillOpacity < 1,
                                side: THREE.DoubleSide,
                                depthWrite: false,
                               
                            } );

                            const shapes = path.toShapes( true );
                            console.log('shapes: ',shapes);



                            for ( let j = 0; j < shapes.length; j ++ ) {

                                const shape = shapes[ j ];

                                const geometry = new THREE.ShapeBufferGeometry( shape );
                                
                                mesh = new THREE.Mesh( geometry, material );

                                let nodeId = path.userData.node.id;

                                mesh.name = nodeId;

                                LIST_svgParts.push(mesh.name);


                                mesh.scale.multiplyScalar( 0.25 );
                                mesh.position.x = - 70;
                                mesh.position.y = 70;
                                mesh.scale.y *= - 1;


                                console.log('mesh: ',mesh);
                                app.scene.add( mesh );

                            }
                        }

                    } );


                    console.log('LIST_svgParts: ',LIST_svgParts);

                };  //  END loadSVG 

any advice on how to fix this would be great.
thanks!

Are you using the latest version of SVGLoader? Previously the shape generation process often had problems to work with shape definitions with holes or nested definitions. In r127 a new implementation of this logic should make things more robust.

When I import the SVG file in the three.js editor, it looks like so:

Notice that the loader has now an own method for generating shapes like demonstrated by the official example (and does not use ShapePath.toShapes() anymore). It’s now:

1 Like

Ok thanks.
I will try that.

perfecto. works great. problem solved. thank you very much for that important info about the updated version, Mugen!

1 Like