using DeviceLayout
using DeviceLayout.PreferredUnits
using DeviceLayout.SolidModels
using DeviceLayout.SolidModels: difference_geom!, intersect_geom!, extrude_z!
cs = CoordinateSystem("repro", nm)
# Layer 1 (→ PG :metal): ground plane (with hole) + island
ground = DeviceLayout.difference2d(centered(Rectangle(100μm, 100μm)),
centered(Rectangle(40μm, 40μm)))
place!(cs, ground, :metal)
island = centered(Rectangle(20μm, 20μm))
place!(cs, island, :metal)
# Layer 2 (→ PG :substrate): chip outline (becomes substrate)
chip = centered(Rectangle(120μm, 120μm))
place!(cs, chip, :substrate)
# Layer 3 (→ PG :box): chip outline (becomes bounding volume)
place!(cs, chip, :box)
# --- Case A: intersect inside postrender_ops (BEFORE _fragment_and_map!) ---
sm_a = SolidModel("repro_A"; overwrite=true)
render!(sm_a, cs;
postrender_ops=[
(:substrate, extrude_z!, (:substrate, -50.0μm)),
(:vacuum, extrude_z!, (:box, 50.0μm)),
(:interface, intersect_geom!, (:metal, :vacuum, 2, 3)),
],
)
n_a = SolidModels.hasgroup(sm_a, :interface, 2) ?
length(SolidModels.entitytags(sm_a[:interface, 2])) : 0
# --- Case B: intersect AFTER render! (AFTER _fragment_and_map!) ---
sm_b = SolidModel("repro_B"; overwrite=true)
render!(sm_b, cs;
postrender_ops=[
(:substrate, extrude_z!, (:substrate, -50.0μm)),
(:vacuum, extrude_z!, (:box, 50.0μm)),
],
)
result_b = intersect_geom!(sm_b, :metal, :vacuum, 2, 3)
n_b = length(result_b)
println("Case A (intersect in postrender_ops): $n_a entities")
println("Case B (intersect after render!): $n_b entities")
println("Expected: both should return 2 (ground plane + island)")
intersect_geom!inpostrender_opssilently drops entities from a multi-entity 2D physical group when intersected with a 3D volume. This isn't a bug, as OCC intersection ops are meant to be run on fragmented/conformal models AFAIK, but it's certainly a footgun as any user who schedules a mixed-dimension intersection inpostrender_opsis in general not going to get the right output. Here's a minimal reproduction with DL v1.13.0: