cadquery icon indicating copy to clipboard operation
cadquery copied to clipboard

Rotated shapes 180° + union

Open RemDelaporteMathurin opened this issue 5 years ago • 3 comments

The paramak project recently ran into an issue when moving from v2 to the master version of CQ. When rotating shapes 180° and do a union, an error is raised. Original issue : https://github.com/ukaea/paramak/issues/548 The following MWE can reproduce the bug:

import cadquery as cq

def create_solid(workplane):
    solid0 = (
        cq.Workplane(workplane) 
        .moveTo(0, 0)
        .circle(1)
        .extrude(1, both=False)
    )

    solid1 = solid0.rotate((0, 0, -1), (0, 0, 1), 0)
    solid2 = solid0.rotate((0, 0, -1), (0, 0, 1), 180)
    solid = cq.Workplane(workplane)

    solid = solid.union(solid1)
    solid = solid.union(solid2)
    return solid

solid = create_solid("XY") # works
solid = create_solid("XZ") # does not work
solid = create_solid("YZ") # does not work

Error:

Traceback (most recent call last):
  File "test.py", line 11, in <module>
    test_component.export_stl('out.stl')
  File "/home/paramak/shape.py", line 692, in export_stl
    exporters.exportShape(self.solid, "STL", f, tolerance)
  File "/home/paramak/shape.py", line 125, in solid
    self.create_solid()
  File "/home/paramak/parametric_shapes/extruded_circle_shape.py", line 88, in create_solid
    solid = self.rotate_solid(solid)
  File "/home/paramak/shape.py", line 608, in rotate_solid
    solid = solid.union(i)
  File "/opt/conda/lib/python3.7/site-packages/cadquery/cq.py", line 2913, in union
    r = r.clean()
  File "/opt/conda/lib/python3.7/site-packages/cadquery/occ_impl/shapes.py", line 343, in clean
    upgrader.Build()
OCP.Standard.Standard_NullObject: BRep_Tool:: TopoDS_Vertex hasn't gp_Pnt

Thanks in advance for the help!

RemDelaporteMathurin avatar Nov 23 '20 09:11 RemDelaporteMathurin

Funnily enough, the following seems to work:

import cadquery as cq


def create_solid(workplane):
    solid0 = (
        cq.Workplane(workplane)
        .moveTo(0, 0)
        .circle(1)
        .extrude(1, both=False)
    )

    solid1 = solid0.rotate((0, 0, -1), (0, 0, 1), 0)
    solid2 = solid0.rotate((0, 0, -1), (0, 0, 1), 180)
    solid = cq.Workplane(workplane)

    solid = solid.union(solid1)
    solid = solid.union(solid2, clean=False)
    return solid

solid = create_solid("XY") # works
solid = create_solid("XZ") # works
solid = create_solid("YZ") # works

RemDelaporteMathurin avatar Nov 23 '20 09:11 RemDelaporteMathurin

I knew generally what @Shimwell was working on, but I'm glad to have a project name to associate with the work.

In some cases like that clean is required, and it's a target that seems to move over time as OCCT is updated. @adam-urbanczyk understands more about what's going on behind the scenes in the CAD kernel than I do, so he may have some insight.

I'm not sure if it's related, but it's been noted that union success/failure can sometimes depend on the order in which objects are unioned: https://github.com/CadQuery/cadquery/issues/500

jmwright avatar Nov 23 '20 22:11 jmwright

Confirmed, the issue occurs in ShapeUpgrade_UnifySameDomain. As far as I see this is not fixed by OCCT 7.5 .

image

adam-urbanczyk avatar Nov 24 '20 08:11 adam-urbanczyk

The error is reproducible with OCP7.6.3.

I cannot reproduce with OCCT7.7.0/OCP7.7.0 (PR #1215).

lorenzncode avatar Jan 11 '23 01:01 lorenzncode