gumyr / build123d

A python CAD programming library
Apache License 2.0
432 stars 81 forks source link

CQ-editor error when trying to export build123d objects #54

Closed jdegenstein closed 1 year ago

jdegenstein commented 1 year ago

Not sure what the appropriate fix for this is, but CQ-editor will export foo.part.wrapped but not foo.part nor foo. The error for the CQ-editor log is:

[18:18:07.994772] ERROR: Uncaught exception occurred
Traceback (most recent call last):
  File "cq_editor\widgets\object_tree.py", line 139, in <lambda>
  File "cq_editor\widgets\object_tree.py", line 337, in export
  File "cq_editor\cq_utils.py", line 92, in export
  File "cq_editor\cq_utils.py", line 50, in to_compound
ValueError: Invalid type <class 'list'>
gumyr commented 1 year ago

The problem here is goes back to the change that was put in to_compound to support objects from the build123d APIs in addition to the cadquery APIs - but this change wasn't made of lists of objects. Here is the current code:

def to_compound(obj : Union[cq.Workplane, List[cq.Workplane], cq.Shape, List[cq.Shape], cq.Sketch]):

    vals = []

    if isinstance(obj,cq.Workplane):
        vals.extend(obj.vals())
    elif isinstance(obj,cq.Shape):
        vals.append(obj)
    elif isinstance(obj,list) and isinstance(obj[0],cq.Workplane):
        for o in obj: vals.extend(o.vals())
    elif isinstance(obj,list) and isinstance(obj[0],cq.Shape):
        vals.extend(obj)
    elif isinstance(obj, TopoDS_Shape):
        vals.append(cq.Shape.cast(obj))
    elif isinstance(obj,list) and isinstance(obj[0],TopoDS_Shape):
        vals.extend(cq.Shape.cast(o) for o in obj)
    elif hasattr(obj, "wrapped") and isinstance(obj.wrapped, TopoDS_Shape):
        vals.append(cq.Shape.cast(obj.wrapped))        
    elif hasattr(obj, "_obj") and hasattr(obj._obj, "wrapped") and isinstance(obj._obj.wrapped, TopoDS_Shape):
        vals.append(cq.Shape.cast(obj._obj.wrapped))
    elif isinstance(obj, cq.Sketch):
        if obj._faces:
            vals.append(obj._faces)
        else:
            vals.extend(obj._edges)
    else:
        raise ValueError(f'Invalid type {type(obj)}')

    return cq.Compound.makeCompound(vals)

The line elif isinstance(obj,list) and isinstance(obj[0],TopoDS_Shape): handles list of foo.part.wrapped (i.e. TopoDS_Shape objects), similar list condition checks needs to be created for: elif hasattr(obj, "wrapped") and isinstance(obj.wrapped, TopoDS_Shape): and hasattr(obj, "_obj") and hasattr(obj._obj, "wrapped") and isinstance(obj._obj.wrapped, TopoDS_Shape):.

It would be very nice if cq-editor supported lists of build123d objects.

jdegenstein commented 1 year ago

OK thanks for looking into the details -- I can certainly implement on my fork of CQ-editor.

gumyr commented 1 year ago

This is a CQ-editor problem, there isn't anything that can be done in buildl123d to fix this.