gumyr / build123d

A python CAD programming library
Apache License 2.0
395 stars 72 forks source link

Assembly solve() is broken by import build123d #2

Closed gumyr closed 1 year ago

gumyr commented 1 year ago

import build123d breaks the following code:

import cadquery as cq

asm = (
    cq.Assembly()
    .add(cq.Solid.makeBox(1, 1, 1), name='b1', color=cq.Color('yellow'))
    .add(cq.Solid.makeBox(1, 1, 1), name='b2', color=cq.Color('red'))
    .constrain('b1@faces@<Z', 'b2@faces@<Z', 'Plane')
)
asm.solve()
show_object(asm)
gumyr commented 1 year ago

generates:

>>> cq.Face.makePlane(3,4).copy()._geomAdaptor()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/peter/cadquery/cadquery/occ_impl/shapes.py", line 2206, in _geomAdaptor
    return BRep_Tool.Surface_s(self.wrapped)
TypeError: Surface_s(): incompatible function arguments. The following argument types are supported:
    1. (F: OCP.TopoDS.TopoDS_Face, L: OCP.TopLoc.TopLoc_Location) -> OCP.Geom.Geom_Surface
    2. (F: OCP.TopoDS.TopoDS_Face) -> OCP.Geom.Geom_Surface

Invoked with: <OCP.TopoDS.TopoDS_Shape object at 0x7f1dc0ad2730>
>>> 
gumyr commented 1 year ago

This change to the Shape.copy() method fixes the problem:

def shape_copy(self: "Shape") -> "Shape":
    """
    Creates a new object that is a copy of this object.
    """
    # The wrapped object is a OCCT TopoDS_Shape which can't be pickled or copied
    # with the standard python copy/deepcopy, so create a deepcopy 'memo' with this
    # value already copied which causes deepcopy to skip it.
    # memo = {id(self.wrapped): BRepBuilderAPI_Copy(self.wrapped).Shape()}
    memo = {id(self.wrapped): downcast(BRepBuilderAPI_Copy(self.wrapped).Shape())}
    copy_of_shape = copy.deepcopy(self, memo)
    return copy_of_shape

The TopoDS_Shape object needs to be downcast.

gumyr commented 1 year ago

Fixed by cq_warehouse commit https://github.com/gumyr/cq_warehouse/pull/68/commits/5d5b839f5a0dd33648e772f6f9dbc3970db9f2df