-
Notifications
You must be signed in to change notification settings - Fork 514
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SVG path with "hole" does not import correctly #1087
Comments
Yep this looks like an issue. Here is a simplified SVG that shows the same problem: <svg>
<path d="m0 0v16h16v-16h-16zm4 4h8v8h-8v-8z" fill="#777"/>
</svg> |
@z3dev Any idea what is going wrong where? I can try to solve it, but its not clear to me at this point Also notice, to get the correct result I need to invert the second geom3 and the subtract it from the first. Because of this I was thinking that the second geom3 is a hole and that I would get the correct result by taking the union of the two geoms3s. Should it work like that, or am I missing something? |
Actually after some more investigation I realized I was wrong. The real problem is that the deserializer produces two separate const { extrusions } = require('@jscad/modeling')
const { deserializers } = require('@jscad/io')
const main = () => {
let s_text = `
<svg>
<path d="m0 0v16h16v-16h-16zm4 4h8v8h-8v-8z" fill="#81e"/>
</svg>`
let s = deserializers.svg({ output: "geometry", target: "geom2"}, s_text)
// merge sides
s = {
...s[0],
sides: [ ...s[0].sides, ...s[1].sides ]
}
s = extrusions.extrudeLinear({ height: 10 }, s)
return s
}
module.exports = { main } It seems like each svg |
@kbruneel this is a common issue when importing SVG paths. #888 SVG is about rendering a raster image (and has rules too) so JSCAD takes a simple approach when converting to useable geometry. Complex, multi-part paths are split into pieces. So, you have to KNOW the contents in order to use results. If you want to extrude the results then some inspection is required to assure geometries follow proper orientation. If you have some suggestions then please let us know. We are considering some new functionality to assist users in the conversation of one geometry to another, I.e. path2 to geom2, etc. |
@z3dev I understand that and looking into it a bit more now, but my question was about something else. I didn't explain it well, so let me explain it a bit more. When I import my svg and extrude it I get two geom3s let's call them Solid and Hole. I get the correct result when I do this:
But I expect to also get the same result when I do this
Just because I expect
But this does not give the same result. Is there something I'm not understanding about union and subtract? I'm thinking about this because if it would work with union the solution could be as simple as taking the union of all the geometries that are exported from the svg, to get the correct result. |
@z3dev @platypii I looked a bit more into the how the insideness of a SVG path is determined (https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/fill-rule) and if I understand it correctly it does look like they also use clockwise and counterclockwise to distinguish solid and hole. At least in the standard setting for the standard setting |
@z3dev I did misunderstand Union. It has happened before :) I had to use intersect instead. Now I get the correct result like this:
I'm wondering if the solution could be that: |
Intersect is not the correct solution, in general. It works specifically in this case because the hole essentially defines "all the plane except this hole" and the outer polygon defines the area inside itself, so the intersection is the correct area in this example. But in general there can be holes inside of holes and that wouldn't work using intersection. I really think the answer is returning a single |
I think a utility function that converts multiple path2 into geom2 would be better. Then the utility function is available for general use. Also, the conversion can be complex, as you already pointed out. And SVG import should just return paths, period. |
Also, those SVG fill rules are not about holes. Those rules are about how to display the internal areas of shapes. It does not equate to booleans, although it may seem that at first. |
@z3dev Do you mean that when importing an SVG path, the d-property should be imported as a path without taking into account things like fill, stroke-width, stroke-style, ... Or do you mean all these extra properties of SVG paths should be taken into account when converting an SVG path to JSCAD paths? |
@platypii yes indeed you are right. Intersect may be a quick fix while waiting for a general solution. |
I'm looking at this further now. So, the resulting code (translation of svg to js) looks like this.
The sub-paths are being translated into geom2 shapes, and accumulated into a group of 'parts'. All good. The NEXT step should perform some inspection, and then call a boolean function on the 'parts' to produce the final geom2 shape. There are several IO libraries that create paths, so hopefully the utility function can be re-used. An even better solution might be... just return the sub-paths as a group of 'parts'. And then call the utility function to convert from a group of paths to geom2 shape. |
It may not be about import alg. jscad uses CW/CCW to diferentiate in vs out for extrude ... because it affects the orientation of vertices during extrusion. Maybe blender and openscad are doing bit more work in the extrude step to recognize holes. |
Here is what I more or less understand. Please correct or expand.
items 3. and 4. seem to work correctly with an appropriate baseSlice with a hole. Perhaps do a simple design to test (slice with a hole). It may be usefuf to add a caps options to extrudeLinearGeom2, passed on to extrudeFromSlides. Turning off caps to make sure that sides are getting properly extruded. In this sequence, is earcut the only place where the winding order is considered ?
|
@platypii has added a very nice 2D boolean library to V3. And the 2D geometry is now a totally different structure as well; a list of outlines. So, let's try to address this in V3, as the toolset for 2D is far better. Thoughts? |
Just for reference: https://github.com/jscad/OpenJSCAD.org/blob/V3/packages/modeling/src/operations/extrusions/extrudeLinear.test.js#L160 |
Expected Behavior
When I import an svg path with a hole, the hole is not shown.
Actual Behavior
Hole is not visible.
Steps to Reproduce the Problem
Specifications
The text was updated successfully, but these errors were encountered: