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

Create a closed loop with rectangular cross section - obtaining two extra unwanted faces #1478

Open
nfoppiani-pf opened this issue Jan 4, 2024 · 7 comments
Labels
question Further information is requested

Comments

@nfoppiani-pf
Copy link

Hello! I am relatively new to CadQuery, and I have a question for which I have not found any good example.
I am trying to create a CAD model of a loop with rectangular cross section. Here is a minimal example for a single ring using a sweep operation. In general the shapes I am interested in are more complex, but the topology is the same.

import os
import cadquery as cq
import numpy as np

RADIUS = 10
if __name__ == "__main__":

    # let's generate a ring with a sweep command

    # Create a circle profile for the ring on the xy plane
    thetas = np.linspace(0, 2 * np.pi, 100)
    x = RADIUS*np.cos(thetas)
    y = RADIUS*np.sin(thetas)
    z = np.zeros_like(thetas)

    xyz = np.stack([x, y, z], axis=1).tolist()
    assert len(xyz) == len(thetas)

    circle_profile = cq.Workplane("XY").spline(xyz, includeCurrent=False).close()

    # Create a rectangle profile for the ring
    rectangle_edges = [(9, 0, -1), (9, 0, 1), (11, 0, 1), (11, 0, -1)]
    rectangle_profile = cq.Workplane("XY").polyline(rectangle_edges, includeCurrent=False).close()

    # let's run a sweep
    sweep = rectangle_profile.sweep(path=circle_profile)
    assert sweep.solids().size() == 1

    # export the file as STEP
    cq.exporters.export(sweep.solids().val(), "ring.step")

However, the output is not a fully closed loop, but I get two overlapping rectangular faces at the beginning and end of the process.
Basically, the solid now has 4 faces rather than 6.
Here is an example of the file I created opened in FreeCad.
Screenshot from 2024-01-04 11-47-42

How can I make it a fully closed loop, with only 4 faces?

Thanks!

@nfoppiani-pf nfoppiani-pf added the question Further information is requested label Jan 4, 2024
@lorenzncode
Copy link
Member

Try increasing the number of points for the spline profile from 100 to a larger value. (I find >= 109 points results in 4 faces and valid shape).

In this case it is simpler to use revolve to create the ring:

import cadquery as cq

# Create a rectangle profile for the ring
rectangle_edges = [(9, 0, -1), (9, 0, 1), (11, 0, 1), (11, 0, -1)]
rectangle_profile = cq.Workplane("XY").polyline(rectangle_edges, includeCurrent=False).close()

ring = rectangle_profile.revolve(360, (0, 0, 0), (0, 0, 1))

@nfoppiani-pf
Copy link
Author

Thank you for your answer.
Unfortunately, even with >= 109 points I still see the same problem when opening in FreeCAD.
How did you perform your check on the number of faces and valid shape?

Moreover, when running with a revolve of 360 degrees, when opening in FreeCad I still see an edge (and one on the outer cylindrical surface).
image

@shimwell
Copy link
Contributor

shimwell commented Jan 8, 2024

I've seen something like this before when revolving 360 degrees. It came up a while back on this issue #259

I remember trying the clean argument that is part of the revolve method but it didn't help at the time, might be worth trying again.

I've see this extra faces happen again recently and in the end we made two revolutions and used a union to combine them.
https://github.com/fusion-energy/model_benchmark_zoo/blob/2b8f991065e81873f6f6a50ca0cee50bdfadfacb/src/model_benchmark_zoo/ellipticaltorus.py#L28-L29

Noting that OCP 7.7.2 is just out so it might also be worth trying the latest version

@nfoppiani-pf
Copy link
Author

Thank you! I think I tried something like this hack before but it did not solve the issue in my case.
I will try to see if perhaps there is a problem with using too few points for the spline.
I have got the latest CadQuery and OCP, although I am not calling OCP directly here.

I have seen you had a command on this issue #449 (comment) to remove faces using OCP and Brep files. I tried to do something like that but it did not work though.

@lorenzncode
Copy link
Member

How did you perform your check on the number of faces and valid shape?

To count faces: len(sweep.faces().vals())
isValid check: sweep.val().isValid()

Moreover, when running with a revolve of 360 degrees, when opening in FreeCad I still see an edge (and one on the outer cylindrical surface).

These are seam edges. Seam edges are expected when working with cadquery and OCCT.

For example, the seam when creating a cylinder:

cyl = cq.Workplane().circle(10).extrude(20)

seam_cyl_cq-editor

@nfoppiani-pf
Copy link
Author

Thank you so much, that's really helpful! Is there a way to remove seam edges?

@adam-urbanczyk
Copy link
Member

Nope, that is how B-Rep works.

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

No branches or pull requests

4 participants