SVGLoader renders wrong shape

I’m loading this SVG with the SVGLoader and the shape is looking bad:

I added an example here react-ts-xnwmxg - StackBlitz

And this is how it should look:

I’m thinking it can be that the SVGLoader breaks with scientific notation (the e in the path data). Does anyone have a solution for this?
Thank you!

Are you sure the issue is caused by three :thinking: ? I pasted your SVG into a codepen (as plain HTML, no JS, no frameworks) and it seems to look the same way as it does in your example:

Screenshot 2021-02-14 at 05.20.19

Hey, sorry I changed the example when trying to solve it removing the scientific notation.
This is the original data:

"M92.79482019042968 214.3000000000004C45.294820190429675 182.00000000000034 40.794820190429675 145.40000000000032 39.59482019042969 97.30000000000041L39.494820190429664 94.70000000000039C38.494820190429664 55.40000000000032 34.794820190429675 52.40000000000032 10.594820190429687 33.40000000000032L10.494820190429664 33.30000000000041C0.39482019042969796 26.40000000000032 -1.2051798095703248 17.50000000000034 0.6948201904297093 11.400000000000318C2.894820190429698 4.300000000000409 9.494820190429664 3.410605131648481e-13 17.994820190429664 3.410605131648481e-13C25.19482019042971 3.410605131648481e-13 33.3948201904297 3.100000000000364 41.59482019042969 9.100000000000364C68.29482019042968 28.40000000000032 76.29482019042968 47.20000000000039 77.3948201904297 92.90000000000032L77.59482019042969 100.60000000000036C78.49482019042966 139.8000000000004 78.99482019042966 161.40000000000032 116.09482019042969 189.2000000000004L92.79482019042968 214.3000000000004Z"

and this is how it looks image

I think these are causing problems

Could you paste it in HTML field on codepen and see if it looks alright there? I’m still wondering if it’s three’s issue, or just general SVG problem.

yes it looks right, and I’m porting a canvas svg renderer that uses this svg without three js and it works well, opening with illustrator, figma and any other tool also works fine.
Here’s a codepen with the svg looking okay:

removing the e-[number] sort of work so that the issue is not super noticeable, but the curve is not exactly the same shape as the original :slightly_frowning_face:
replacing with the correct amount of zeros doesn’t look right either

I’m trying to replicate it on codepen - but meanwhile, wouldn’t just scaling the SVG up (so that these super low e-values don’t appear around) and then using .scale to scale them down work?

It seems like a number precision issue.

1 Like

hm that’s interesting. I will try it, but ideally I think It should support it. With our current use case we store a lot of path data in a database and scaling all our svgs before passing them to the three js SVGLoader may not work out great. But thanks for the quick answer, I will experiment with that idea :+1:

This issue was lately fixed on dev so it should be all good with the next release r126. Respective PR:

2 Likes

@juansalvatore @mjurczyk @Mugen87 I have same issue and want to know how I should use parseFloats function to fix it ?
Three.js version - r127

Do you mind sharing the SVG which does not load properly?

Yes this is SVG

<?xml version="1.0" encoding="UTF-8"?>
<svg id="Layer_2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 526.04 349.63">
  <g id="s8">
    <path d="M 0 6 L 11 1 L 22 6 L 11 11 L 0 6 L 11 1 L 22 6 L 11 11 L 0 6 Z" fill="transparent" stroke="white" stroke-width="0.5" stroke-miterlimit="10" />
  </g>
</svg>

And this is the result which I have in Canvas

This is the steps which I use for draw (Not All steps)

const geometry = new THREE.ShapeGeometry(shape, 0)

const material = new THREE.MeshBasicMaterial({
      color: new THREE.Color(0xffffff),
    })

const mesh = new THREE.LineSegments(geometry, material)

I’m afraid this does not work. ShapeGeometry is supposed to be used with Mesh. It is not intended for lines or points.

When loading the SVG as a mesh, it is rendered as expected as a quad.

1 Like

Thanks for answer @Mugen87.
So which Geometry I should use with shapes received from SVG paths and LineSegments for having result for example this shape from image in canvas ?

I suppose what you are planning to do is not supported. As mentioned above, SVGLoader output shapes intended for shape rendering via ShapeGeometry.

Thank you for hint @Mugen87 I think I find solution for my case if I want to generate wireframe (only bordered box ) from SVG shapes I should use EdgesGeometry and generate edges from shape geometry and after that use edges in LineSegments.

const geometry = new THREE.ShapeGeometry(shape)
const edges = new THREE.EdgesGeometry(geometry)

const material = new THREE.MeshBasicMaterial({
      color: new THREE.Color(0xffffff),
    })

const mesh = new THREE.LineSegments(edges, material)

This example works for me.
Thanks a lot

2 Likes

Nice solution!

1 Like