aws-cqc / aws-cqc/DeviceLayout.jl

intersect_geom! in postrender_ops silently drops entities

Open
#231 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Julia
Stars
67
Forks
14
Avg merge
1d 16h
Merged PRs (30d)
21

Description

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

Contributor guide

Open the contributing guide

Research direction

Start by tracing intersect_geom! through postrender_ops and render!, comparing the pre-_fragment_and_map! path with the direct post-render call. Use the reproduction's Case A and Case B to verify that intersecting the mixed-dimension geometry preserves both entities and that each case reports the expected two results.

Written by the indexing model from the issue text.

Assessment

Tech stack
julia
Domain
computer-graphics
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.