Closed gumyr closed 1 year ago
This doesn't look to be feasible after all. Consider this example:
from cadquery import Solid, Vector
from cadquery.occ_impl.shapes import VectorLike
class ChamferBox(Solid):
def __init__(
self,
length: float,
width: float,
height: float,
chamfer_size: float,
pnt: VectorLike = Vector(0, 0, 0),
dir: VectorLike = Vector(0, 0, 1),
) -> Solid:
box = Solid.makeBox(length, width, height, pnt, dir)
box = box.chamfer(chamfer_size, None, box.Edges())
super().__init__(box.wrapped)
chamfer_box = ChamferBox(1, 1, 1, 0.1)
if "show_object" in locals():
show_object(chamfer_box)
print(
f"{type(chamfer_box)=},{isinstance(chamfer_box, Solid)=},{chamfer_box.isValid()=}"
)
which generates:
type(chamfer_box)=<class '__main__.ChamferBox'>,isinstance(chamfer_box, Solid)=True,chamfer_box.isValid()=True
However, if a one does translated_chamfer_box = chamfer_box.translate((1, 0, 0))
the following traceback is generated:
Traceback (most recent call last):
File "/home/roger/Documents/Bugs/subclass.py", line 27, in <module>
translated_chamfer_box = chamfer_box.translate((1, 0, 0))
File "/home/roger/anaconda3/envs/cqJuly/lib/python3.9/site-packages/cadquery/occ_impl/shapes.py", line 892, in translate
return self._apply_transform(T)
File "/home/roger/anaconda3/envs/cqJuly/lib/python3.9/site-packages/cadquery/occ_impl/shapes.py", line 852, in _apply_transform
return self.__class__(BRepBuilderAPI_Transform(self.wrapped, Tr, True).Shape())
TypeError: __init__() missing 3 required positional arguments: 'width', 'height', and 'chamfer_size'
The problem seems to be how _apply_transform()
(and many other methods) is/are implemented - it/they take apart the object and rebuild it with the object's Shape()
which works for the base classes but with a sub-classed object Shape()
doesn't provide sufficient information to recreate the object.
def _apply_transform(self: T, Tr: gp_Trsf) -> T:
return self.__class__(BRepBuilderAPI_Transform(self.wrapped, Tr, True).Shape())
In addition, there appears to be no way to subclass an Assembly.
It seems as though significant development in the cadquery direct API layer would need to be done to support sub-classing.
By sub-classing all of the objects created with cq_warehouse the use of
.cq_object
will become unnecessary and result in a more natural user interface. For example:will be possible.
The changes to do this are as follows:
class Nut(ABC,cq.Compound):
. Note that the Nut body is of typeSolid
but once the thread is added it becomes typeCompound
therefore the base class must be determined for all objects.__init__
method must initialize the super class as follows:super().__init__(self._cq_object.wrapped)
warn("cq_object will be deprecated.", DeprecationWarning, stacklevel=2)
Note that for derived classes, only the base class need to change.
Thread will require more change as currently the actual thread object isn't created until the cq_object property is accessed - for performance reasons when building threaded objects with the
simple
option. A new optional parametersimple
may need to be introduced to thread which will create a null thread object.