Elliptic arc and ellipse rotation implementation

I am working on a SVG that has different types of curves. When I load the SVG using the SVGLoader and parse the paths into geometries (similar to the example - three.js/webgl_loader_svg.html at d4aa9e00ea29808534a3e082f602c544e5f2419c · mrdoob/three.js · GitHub), some of the shapes are displayed mirrored on the y-axis:

Mirrored (threejs):

Correct (different svg loader):

After some further investigation, I noticed that the only curve types in my SVGs that are displayed mirrored are the EllipseCurve types. Seems like this is related to the warning I am getting when loading the SVG:

SVGLoader: Elliptic arc or ellipse rotation or skewing is not implemented.

node_modules/three/examples/jsm/loaders/SVGLoader.js:1569

If I try to rotate the geometries that are generated for the EllipseCurve paths, they just get translated around the scene instead of rotating.

Are there any plans to implement this feature in the near future? Is there a workaround?

Thank you!
Adam

There is an issue at GitHub which is tracking this particular warning (and some others):

So yeah, the project is aware of this feature request.

Thanks @Mugen87

Do you mind sharing the above SVG for debugging?

I can’t share the original SVG (for confidentiality reasons) so I created a sample one which has the same issue (arc is not produced in correct orientation).

In my sample one I don’t get the warning I mentioned in my first post though.

threejs:
image

browser:
image

This is the snippet of code which converts the SVG to geometries:

  const convertSubPathsToGeometries = (paths: SVGResultPaths[]) => {
  // for each path, convert the list of subpaths to geometries.
  const allSubpathGeometriesFlat: BufferGeometry[] = [];
  paths.forEach((path: SVGResultPaths) => {
     path.subPaths.forEach((subPath: any) => {
         if (path.userData && path.userData.style) {
             path.userData.style.strokeWidth = SVG_STROKE_WIDTH;
         }
         const geometry = SVGLoader.pointsToStroke(subPath.getPoints(), path.userData?.style);
         if (geometry) allSubpathGeometriesFlat.push(geometry);
     });
  });
  return allSubpathGeometriesFlat;
};

The SVG:

<?xml version="1.0"?>
<svg
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
  preserveAspectRatio="xMinYMin meet"
  viewBox="0 -23.71921885906557 7.899282037992328 23.71921885906557"
  width="100%" height="100%"
>
  <g stroke="#000000" stroke-width="0.1%" fill="none" transform="matrix(1,0,0,-1,0,0)">
    <g stroke="rgb(0, 0, 0)">
  <path d="M0,0L7.899282037992328,0L7.899282037992328,23.71921885906557L0,23.71921885906557L0,0" />
</g>
<g stroke="rgb(0, 0, 0)">
  <path d="M 3.957425579064875 2.258681501672981 A 2.258681501672981 2.258681501672981 0 0 1 1.6987440773918938 2.7660870713171536e-16" />
</g>
<g stroke="rgb(0, 0, 0)">
  <path d="M 3.949641018996163 -6.661338147750939e-16 A 1.131866878519715 1.131866878519715 0 0 1 3.9574255790648745 2.2586815016729807" />
</g>
  </g>
</svg>

Please let me know if there is anything else that can be useful.
Thanks,
Adam

1 Like

Hello,
Are there any updates on this one?

Thanks,
Adam

No sorry. This feature request is not yet implemented.

If you can’t wait for the feature request to be implemented and there aren’t too many arcs involved in your SVG, you may get the desired result by patching your SVG file :innocent:

It appears like the “sweep-flag” is being interpreted the wrong way around, so changing a “1” to “0” and vice-versa should do the trick.

See the SVG-spec (chapter 9.3.8 The elliptical arc curve commands) for more details.