Apologies for the traffic, but I figured out a way to get to where I was trying to go (after a bunch of blind alleys). Someone here once said "Use the source, Luke", and that was what finally got me to an answer.
Here's a little demo, it:
- makes a cube with some holes through one face (to make things "interesting")
- then cuts an array of squares (or whatever)
- but avoids cutting through the edges of the cube or the "interesting" holes.
Things I learned, or was reminded of, include:
- working with a face's outer and inner wires;
- making a Face from a set of Wires;
- getting a Plane from a Workspace with a Face;
- using that Plane to set up a new Workspace with the coordinate system that's useful;
- Workplane add() and toPending()
Here's the demo I ended up with:
and here's the source code for it:
from datetime import datetime
import cadquery as cq
from cadquery import Face
log(f"Starting new run at: {datetime.now()}")
face_selector = ">Y"
size = 50
# create a box with some holes drilled through from some face face.
box = cq.Workplane("XY").box(size, size, size)
c = (
box.faces(face_selector)
.workplane()
.rect(15, 30, forConstruction=True)
.vertices()
.circle(4)
.extrude(-size, combine=False)
)
box = box.cut(c)
# Get the "<Y" face and its wires
the_face = box.faces(face_selector)
# debug(the_face, name="the_face")
da_workplane = cq.Workplane(the_face.workplane(centerOption="ProjectedOrigin").plane)
# debug(da_workplane, name="da_workplane")
# Make a new face with modified wires
_tf = the_face.val()
ow = _tf.outerWire()
iw = _tf.innerWires()
new_ow = ow.offset2D(-2)[0]
new_iw = [w.offset2D(2)[0] for w in iw]
f2 = Face.makeFromWires(new_ow, new_iw)
# debug(f2, name="f2")
# Generate a big array of cylinders
tubes = da_workplane.rarray(7, 7, 10, 10).rect(5, 5).extrude(-size) # Extrude the tubes
# debug(tubes, name="tubes")
mask = da_workplane.add(f2).wires().toPending().extrude(-size)
# debug(mask, name="mask")
masked_tubes = tubes.intersect(mask)
# debug(masked_tubes, name="masked tubes")
box = box.cut(masked_tubes)
show_object(box, options={"alpha": 0.5, "color": (0, 127, 127)})