jscad / OpenJSCAD.org

JSCAD is an open source set of modular, browser and command line tools for creating parametric 2D and 3D designs with JavaScript code. It provides a quick, precise and reproducible method for generating 3D models, and is especially useful for 3D printing applications.
https://openjscad.xyz/
MIT License
2.63k stars 512 forks source link

svg deserializer constructs invalid 2D geometry (wrong orientation) #888

Open brucedjones opened 3 years ago

brucedjones commented 3 years ago

Expected Behavior

Geometries have correct normals when extruded from svg

Actual Behavior

Geometry normals are flipped.

Steps to Reproduce the Problem

Run the code below. Note you must be using the fixes described here: https://github.com/jscad/OpenJSCAD.org/pull/887

const { deserializers } = require("@jscad/io");

const main = () => {
  const svg = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="5.6298828125" height="11.71875"><path d="M5.37 6.60L5.37 6.68Q5.37 7.98 4.83 8.68Q4.29 9.38 3.32 9.38L3.32 9.38Q2.51 9.38 2.02 8.74L2.02 8.74L1.95 9.28L0.47 9.28L0.47 1.78L2.12 1.78L2.12 4.42Q2.58 3.90 3.31 3.90L3.31 3.90Q4.29 3.90 4.83 4.60Q5.37 5.31 5.37 6.60L5.37 6.60ZM3.72 6.58L3.72 6.58Q3.72 5.82 3.51 5.49Q3.31 5.17 2.89 5.17L2.89 5.17Q2.33 5.17 2.12 5.59L2.12 5.59L2.12 7.69Q2.33 8.11 2.90 8.11L2.90 8.11Q3.48 8.11 3.64 7.54L3.64 7.54Q3.72 7.27 3.72 6.58Z"/></svg>`;
  const shapes = deserializers.svg({ output: "geometry", target: "geom2" }, svg);
  return extrudeLinear({ height: 10 }, shapes);
}

module.exports = { main }

Specifications

z3dev commented 3 years ago

SVG paths don’t have a concept of rotation. So, yeah. Some paths with definitely be going clockwise about Z. You’ll have to do some calculations to determine if the path needs to be reversed before extruding, or converting to 2D geometry.

brucedjones commented 3 years ago

Hm I'm going to have to do some reading on this... Fwiw the svg in the example is a filled polygon, there must be some convention to that for it to work and I think a user would intuitively expect the svg deserializer to figure it out

z3dev commented 3 years ago

The results are paths… which can be any order of points.

If the path is closed then it’s easy to convert to 2D geometry (geom2). The area of a 2D geometry will be positive (CCW rotation) or negative (CW rotation).

hrgdavor commented 3 years ago

@brucedjones #889 isCCW willl probably be useful

z3dev commented 2 years ago

@brucedjones taking another look at the given example, using target: "geom2" should produce valid useful geometries, so this is probably something that should be fixed.