Fix compas-brep API use in Lap and Pocket - #843
Conversation
Pocket, Lap, and BTLxPart's Brep-handling code still called the old compas.geometry.brep API (face.nurbssurface, face.frame_at) which no longer exists on compas_brep's BrepFace. face.surface now returns a Plane directly for planar faces, so no NurbsSurface/frame_at detour is needed; only genuinely curved faces need surface.frame_at. Along the way, face.surface didn't account for face.is_reversed, so opposite faces of a box reported identical normals instead of opposite ones - fixed by flipping the normal for reversed faces. Also fixes _get_optimal_ref_side_index in Pocket and Lap, where edge.curve already returns a Line directly (no .points attribute to unpack). Pocket.apply additionally now raises a clear FeatureApplicationError when start_depth is negative (the pocket volume lies entirely outside the element's material on the ref_side's outward side) instead of letting a corrupted/erased geometry reach the boolean subtraction.
Line is no longer needed in pocket.py now that _get_optimal_ref_side_index uses edge.curve directly instead of wrapping it in Line(*curve.points).
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #843 +/- ##
==========================================
- Coverage 82.67% 82.57% -0.11%
==========================================
Files 83 83
Lines 12009 12018 +9
==========================================
- Hits 9929 9924 -5
- Misses 2080 2094 +14 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR updates COMPAS Timber’s fabrication features to match the current compas_brep Brep API, removing calls to deprecated/removed methods and fixing orientation handling for reversed Brep faces so downstream plane/frame computations behave correctly.
Changes:
- Replace deprecated Brep face surface access (
nurbssurface,frame_at) withface.surfaceand handle planar vs curved faces appropriately. - Correct face orientation handling by flipping normals/frames when
face.is_reversedso opposing faces report opposing normals. - Fix
Pocket/Lapref-side edge handling (edge.curvealready returns aLine) and add an earlyFeatureApplicationErrorfor negativePocket.start_depth.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| src/compas_timber/fabrication/pocket.py | Update Brep face plane extraction + edge handling; add explicit error for negative start_depth to prevent invalid boolean subtraction. |
| src/compas_timber/fabrication/lap.py | Update Brep face plane extraction + edge handling to use the current Brep API and correct reversed-face orientation. |
| src/compas_timber/fabrication/btlx.py | Make BTLx shape export robust for planar faces by avoiding frame_at on Plane and correcting reversed-face orientation. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| for face in volume.faces: | ||
| plane = face.surface | ||
| if face.is_reversed: | ||
| plane.normal = -plane.normal | ||
| planes.append(plane) |
| for face in volume.faces: | ||
| plane = face.surface | ||
| if face.is_reversed: | ||
| plane.normal = -plane.normal | ||
| planes.append(plane) |
| if self.start_depth < -TOL.absolute: | ||
| raise FeatureApplicationError( | ||
| None, | ||
| geometry.transformed(element.modeltransformation), | ||
| "Pocket's start_depth ({:.4f}) is negative: the pocket volume lies entirely outside " |
| surface = face.surface | ||
| # planar faces (the common case) return a Plane, which has no frame_at (parameter-independent | ||
| # anyway); only genuinely curved faces (NurbsSurface, etc.) need parametric evaluation. | ||
| frame = Frame.from_plane(surface) if isinstance(surface, Plane) else surface.frame_at(0.5, 0.5) | ||
| if face.is_reversed: |
| scaled_geometry = self.element.geometry.scaled(self._scale_factor) | ||
| for face in scaled_geometry.faces: | ||
| pts = [] | ||
| frame = face.surface.frame_at(0.5, 0.5) |
There was a problem hiding this comment.
Hey! I think these should be fixed upstream. could you check if gramaziokohler/compas_brep#8
solves these issues?
it should be as easy as calling face.from_at() which should now get you the properly oriented frame.
Pocket, Lap, and BTLxPart's Brep-handling code still called the old compas.geometry.brep API (face.nurbssurface, face.frame_at) which no longer exists on compas_brep's BrepFace. face.surface now returns a Plane directly for planar faces, so no NurbsSurface/frame_at detour is needed; only genuinely curved faces need surface.frame_at.
Along the way, face.surface didn't account for face.is_reversed, so opposite faces of a box reported identical normals instead of opposite ones - fixed by flipping the normal for reversed faces.
Also fixes _get_optimal_ref_side_index in Pocket and Lap, where edge.curve already returns a Line directly (no .points attribute to unpack).
Pocket.apply additionally now raises a clear FeatureApplicationError when start_depth is negative (the pocket volume lies entirely outside the element's material on the ref_side's outward side) instead of letting a corrupted/erased geometry reach the boolean subtraction.
What type of change is this?
Checklist
Put an
xin the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your code.CHANGELOG.mdfile in theUnreleasedsection under the most fitting heading (e.g.Added,Changed,Removed).invoke test).invoke lint).compas_timber.datastructures.Beam.class_diagrams.rst(if appropriate).