Skip to content

Instantly share code, notes, and snippets.

@marcus7070
Last active January 30, 2023 23:15
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marcus7070/271e2ec67d1ff548341a4820868be0c2 to your computer and use it in GitHub Desktop.
Save marcus7070/271e2ec67d1ff548341a4820868be0c2 to your computer and use it in GitHub Desktop.
CQ internals example

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment