To see a bit more about how the internals of CadQuery work, let's mokeypatch some more verbose string represenations and create a simple model.
import cadquery as cq
def _ctx_str(self):
return (
f"CQContext object with id: {id(self)}\n"
+ f" pendingWires: {self.pendingWires}\n"
+ f" pendingEdges: {self.pendingEdges}\n"
)
cq.cq.CQContext.__str__ = _ctx_str
def _wp_str(self):
out = f"Workplane with id: {id(self)}\n"
if self.parent is not None:
out += f" parent: {id(self.parent)}\n"
else:
out += f" no parent\n"
out += f" objects: {self.objects}\n"
out += f" modelling context: {self.ctx}"
return out
cq.Workplane.__str__ = _wp_str
part = cq.Workplane()
print("Step 1")
print(part)
part = part.box(1, 1, 1)
print("Step 2")
print(part)
part = part.wires(">Z")
print("Step 3")
print(part)
part = part.toPending()
print("Step 4")
print(part)
part = part.translate((0.1, 0.1, 1.0))
print("Step 5")
print(part)
part = part.toPending()
print("Step 6")
print(part)
part = part.loft()
print("Step 7")
print(part)
The model that we create above (ie. the part =
lines) creates a box, selects the square Wire on the top face, creates a translated copy of the wire, and lofts between the two. The result looks like:
The output from running the above, with my comments interleaved:
Step 1
Workplane with id: 140497843287712
no parent
objects: []
modelling context: CQContext object with id: 140497387051808
pendingWires: []
pendingEdges: []
We just create a simple Workplane here. It does not have a parent, and the modelling context is empty.
Step 2
Workplane with id: 140497843288240
parent: 140497843287712
objects: [<cadquery.occ_impl.shapes.Solid object at 0x7fc818d8d670>]
modelling context: CQContext object with id: 140497387051808
pendingWires: []
pendingEdges: []
After creating a box, we have a different Workplane object. The Workplane object from step 1 is now in the parent
attribute. The objects
attribute contains a single Solid object (the box).
Note that we have the same modelling context as in step 1. The same modelling context is shared between all the Workplane objects in a chain.
Step 3
Workplane with id: 140497387052384
parent: 140497843288240
objects: [<cadquery.occ_impl.shapes.Wire object at 0x7fc8340a5520>]
modelling context: CQContext object with id: 140497387051808
pendingWires: []
pendingEdges: []
After selecting the ">Z"
Wire, we once again have a new Workplane object, with the parent
set to the previous Workplane. The objects
attribute contains the single wire that was selected.
Somewhat counterintuitively, this Workplane object does not contain any reference to the box Solid that we are currently modelling. When the Solid is needed, the method Workplane.findSolid
is used to seach backwards through the parent chain and return the most recent Solid.
Step 4
Workplane with id: 140497387052384
parent: 140497843288240
objects: [<cadquery.occ_impl.shapes.Wire object at 0x7fc8340a5520>]
modelling context: CQContext object with id: 140497387051808
pendingWires: [<cadquery.occ_impl.shapes.Wire object at 0x7fc8340a5520>]
pendingEdges: []
After the toPending
method is called, the Wire is now also in part.ctx.pendingWires
.
As an aside, note that toPending
actually returns the same (and unmodified) Workplane object.
Step 5
Workplane with id: 140497843306560
parent: 140497387052384
objects: [<cadquery.occ_impl.shapes.Wire object at 0x7fc8340a1f40>]
modelling context: CQContext object with id: 140497387051808
pendingWires: [<cadquery.occ_impl.shapes.Wire object at 0x7fc8340a5520>]
pendingEdges: []
The translate
method has placed a new wire in the objects
attribute.
Step 6
Workplane with id: 140497843306560
parent: 140497387052384
objects: [<cadquery.occ_impl.shapes.Wire object at 0x7fc8340a1f40>]
modelling context: CQContext object with id: 140497387051808
pendingWires: [<cadquery.occ_impl.shapes.Wire object at 0x7fc8340a5520>, <cadquery.occ_impl.shapes.Wire object at 0x7fc8340a1f40>]
pendingEdges: []
The toPending
method has added that wire to part.ctx.pendingWires
.
Step 7
Workplane with id: 140497843279760
parent: 140497843306560
objects: [<cadquery.occ_impl.shapes.Compound object at 0x7fc8340a5b50>]
modelling context: CQContext object with id: 140497387051808
pendingWires: []
pendingEdges: []
The final loft
method has popped both wires from part.ctx.pendingWires
, used them to create a new Solid object and placed that in objects
.