Skip to content
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

Sketch clean not working in some cases #1534

Open
diorcety opened this issue Mar 10, 2024 · 2 comments
Open

Sketch clean not working in some cases #1534

diorcety opened this issue Mar 10, 2024 · 2 comments

Comments

@diorcety
Copy link
Contributor

I fall on strange issue with clean on sketch, some faces of complexe sketch are not correctly removed. I tried to create a simple test case
From svg containing two path, I recreate edges, then face and making union from these two faces. The second face is completly inside the first one.
But following the path rotation of the second one (which is 2 arcs for a full circle) the clean function doesn't work

eddddd_ok.svg file:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
   height="398px"
   version="1.1"
   viewBox="-0.9757118500000002 31.906598149999994 17.6351237 11.672203700000022"
   width="600px"
   id="svg1"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:svg="http://www.w3.org/2000/svg">
  <defs
     id="defs1" />
  <path
     d="M 5.2941,38.7 8.0133,38.3941 4.3021,35.4 l 0.992,3.3"
     fill="#000000"
     id="path5" />
  <path
     d="M 5.3882,37.5328 A 0.35,0.35 0.0 0,0 6.0882,37.5328 A 0.35,0.35 0.0 0,0 5.3882,37.5328"
     fill="black"
     id="path1207" />
</svg>

eddddd_ko.svg file:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
   height="398px"
   version="1.1"
   viewBox="-0.9757118500000002 31.906598149999994 17.6351237 11.672203700000022"
   width="600px"
   id="svg1"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:svg="http://www.w3.org/2000/svg">
  <defs
     id="defs1" />
  <path
     d="M 5.2941,38.7 8.0133,38.3941 4.3021,35.4 l 0.992,3.3"
     fill="#000000"
     id="path5" />
  <path
     d="M 5.3882,37.5328 A 0.35,0.35 0.0 0,1 6.0882,37.5328 A 0.35,0.35 0.0 0,1 5.3882,37.5328"
     fill="black"
     id="path1207" />
</svg>

test.py file:

import numpy as np
import svgpathtools
import cadquery as cq

from typing import Union

from cadquery import Edge, Wire


def euclid_to_tuple(p, dim3=False):
    if dim3:
        return np.real(p), np.imag(p), 0
    else:
        return np.real(p), np.imag(p)


def to_wire(path, support: Union[cq.Workplane, cq.Sketch] = cq.Workplane("front"), mode="a"):
    def convert(seg):
        if isinstance(seg, svgpathtools.Line):
            return Edge.makeLine(euclid_to_tuple(seg.start), euclid_to_tuple(seg.end))
        elif isinstance(seg, svgpathtools.Arc):
            points = euclid_to_tuple(seg.start), euclid_to_tuple(seg.point(0.5)), euclid_to_tuple(seg.end)
            return Edge.makeThreePointArc(*points)
        else:
            raise Exception("Not supported: {0}".format(type(seg)))

    edges = [convert(seg) for seg in path]
    wires = Wire.combine(edges)
    assert len(wires) == 1
    wire = wires[0]
    ret = support.face(wire, mode=mode)
    return ret


for file in ['eddddd_ok.svg', 'eddddd_ko.svg']:
    paths, attributes = svgpathtools.svg2paths(file)

    sketch = cq.Sketch()

    for path in paths:
        sketch = to_wire(path, sketch, "a")

    sketch = sketch.clean()

    r = cq.Workplane("front").placeSketch(sketch).extrude(1, combine=False)

    cq.exporters.export(r, file.replace("svg", "step"))

And here the results: https://imgur.com/a/4JZ0p26

The only difference here is:
Wire.combine([
Edge.makeThreePointArc((5.3882, 37.5328), (5.7382, 37.1828), (6.0882, 37.5328))
Edge.makeThreePointArc((6.0882, 37.5328), (5.7382, 37.8828), (5.3882, 37.5328))])

vs

Wire.combine([
Edge.makeThreePointArc((5.3882, 37.5328), (5.7382, 37.8828), (6.0882, 37.5328))
Edge.makeThreePointArc((6.0882, 37.5328), (5.7382, 37.1828), (5.3882, 37.5328))])

@diorcety
Copy link
Contributor Author

@diorcety
Copy link
Contributor Author

Using following function before running clean seems to work

def normalize_faces(sketch):
    sketch._faces = Compound.makeCompound([Face(f.wrapped.Reversed()) if f.normalAt().z < 0 else f for f in sketch.faces()])
    return sketch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant