Skip to content

intersect_geom! in postrender_ops silently drops entities #231

Description

@parrangoiz

intersect_geom! in postrender_ops silently 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 in postrender_ops is in general not going to get the right output. Here's a minimal reproduction with DL v1.13.0:

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)")

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions