SVG extrude without filling the path?

Hi,
I have the following SVG:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.dev/svgjs" width="900" height="800">
      <path d="M 650,750  L 50,750  L 100,350  L 850,50  L 850,550  L 650,750" fill="none" stroke="black" stroke-width="3"  />
</svg>

When I try to render it with ExtrudeGeometry , I get the following:
2023-02-10_08h05_08

The filling of the SVG path is set to none, so I would need to show only a border (with some predefined depth).

This is what I’m using to load it:

const svgResult = loader.parse(svgTxt);
svgResult.paths.forEach((path) => {
  const shapes = SVGLoader.createShapes(path);
  shapes.forEach((shape) => {
  const geom = new THREE.ExtrudeGeometry(shape, {
          bevelEnabled: true,
          bevelSize: 14,
          bevelThickness: 5,
          bevelSegments: 15,
          depth: 20,
  });

  const mesh = new THREE.Mesh(
          geom,
          new THREE.MeshPhysicalMaterial({
            color: "white",
          })
        );
   ...
  }

Is it possible to extrude only the stroke, or should I use a different approach to visualize this kind of SVG?

Most likely SVGLoader does not care whether a shape is filled or stroked. If this is true, my suggestion is to define pseudo-stroked shapes in SVG – i.e. a filled shape with a hole in it. Here is a demo of your filled shape (left) and your pseudo-stroked shape (right):

https://codepen.io/boytchev/full/jOvOJxo

image

1 Like

Thank you for your inputs here. Your solution works for this example, although it is quite tricky to calculate the “inner path” for non-convex polygons, like this one:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" 
xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.dev/svgjs" width="1000"
 height="1000" >
   <path d="M 10,10 L 10,300 A 200,200 0,0,1 210,500 L 300,500 A 200,200 0,0,1 500,300 L 500,10 L 10,10 "
	 stroke="green" stroke-width="4" fill="none" />
 </svg>

Here if the stroke is big enough, the arcs would reach each other, thus the bottom line would get ‘dropped’ from the final path.

1 Like

I think what you look for is beyond the scope of Three.js. Maybe some more advanced version of SVGLoader can handle strokes of any width.

Meanwhile, there are other options. One of them is to make a filled 3D object and then to remove bottom and top faces. This will keep all the side faces.

Oh, and I have another idea (only for infinitely thin strokes). Very crazy idea. I will try it first, and if it works, I will share it.

I don’t know how useful or helpful it is, as the code has hardcoded things :sweat_smile: https://codepen.io/prisoner849/pen/RwYrZKg?editors=0010

2 Likes

Ah, my solution is obviously not so good as @prisoner849’s, but I’ll show it because of the idea to swap extrusion dimensions. First, here is the result with thin and fat strokes:

https://codepen.io/boytchev/full/jOvWGPN

image

And here is an illustration of the idea – instead of extruding a SVG shape vertically (left), we can extrude a vertical profile shape along the SVG shape (right).

2 Likes

Great solutions, thanks both of you!

If you don’t necessarily need SVG, you could try that too.

However, in the version only linear structures, no arcs. But you could extend that.

However, in the version only linear structures, no arcs. But you could extend that.