Commit Graph

335 Commits

Author SHA1 Message Date
78f56a68b0 fix: boundary conformance — use Shapely buffer + vertex-preserving PSLG sampling
Root cause: typed segment offsetting created self-intersecting geometry at
concave corners (notches). Triangle's PSLG boundary didn't match the plotted
inset contour, allowing vertices 7+ mm outside.

Changes:
- _build_inner_plate: always use Shapely buffer(-w_frame) (robust at concavities)
- _sample_ring: use simplified polygon vertices + interpolated points on long edges
  (preserves tight features without vertex clustering)
- Plot uses same inner_plate from triangulation (no mismatch)
- Post-process: snap any residual outside vertices to boundary
- Result: 0 vertices outside inner plate (was 10, up to 7.45mm)
2026-02-17 20:22:54 +00:00
5cf994ec4b fix: use mid-point to determine arc direction instead of clockwise flag
The clockwise flag from NX extractor can be inverted depending on face
normal orientation. The sampled mid-point is always reliable. Now
_arc_angles checks which direction (CW vs CCW) passes through the
mid-point and uses that.
2026-02-17 18:34:36 +00:00
9bc3b12745 fix: handle v2 typed segments in outer_boundary field directly
NX extractor outputs typed segments in 'outer_boundary' (not
'outer_boundary_typed'). Normalize now detects dict segments and
promotes them correctly.
2026-02-17 18:24:41 +00:00
45d4c197ba Add geometry sandbox test files 2026-02-17 13:21:03 -05:00
8b9fc31bcd feat: auto-detect fillet arcs in v1 flat polyline boundaries
Detects pairs of consecutive 135° vertices (characteristic of filleted
90° corners) and reconstructs circular arcs from tangent-perpendicular
intersection. Verified on sandbox 2: 2 arcs detected at R=7.5mm with
correct centers. Chain continuity validated.

When arcs are detected, v1 boundaries get promoted to v2 typed segments
and the polyline is re-densified with proper arc interpolation.
2026-02-17 18:05:14 +00:00
fbbd3e7277 refactor: rewrite triangulation using Triangle library (constrained Delaunay + quality refinement)
- Replace scipy.spatial.Delaunay with Shewchuk's Triangle (PSLG-based)
- Boundary conforming: PSLG constrains edges along inset contour + hole keepout rings
- Quality: min angle 25°, no slivers
- Per-triangle density-based area refinement (s_min=20, s_max=80)
- Clean boundary plotting (no more crooked v1 line resampling)
- Triangulation plot shows inset contour (red dashed) + keepout rings (orange dashed)
- Add sandbox2_brain_input.json geometry file
2026-02-17 17:14:11 +00:00
1a14f7c420 fix: v1 boundary handling — inset vertices, 3-point hole keepouts, boundary-aligned triangles, smooth plotting
- Triangulation: force inset boundary corner vertices for v1 geometry (Shapely buffer)
- Hole keepouts: 3 evenly-spaced points per circular hole (not dense polyline)
- Boundary layer: seed points derived from inset polygon for proper alignment
- Triangle filtering: full polygon coverage check against inset-valid region
- Plotting: uniform polyline resampling for smooth v1 boundaries, analytic circle rendering
- Verified: 0 bad triangles on both Quicksat sandboxes
2026-02-17 16:24:27 +00:00
139a355ef3 Add v2 geometry normalization and boundary-layer seed points 2026-02-17 14:37:13 +00:00
7d5bd33bb5 brain: add arc-aware inset boundary handling 2026-02-17 14:05:28 +00:00
18a8347765 feat: enforce Delaunay vertices at inset boundary corners + update geometry to v2.0 with arcs
- Add explicit corner vertices of the inset boundary (w_frame offset) to Delaunay point set
- This guarantees no triangle can cross a boundary corner
- Updated test_data geometry files to v2.0 format with typed segments
- Sandbox 2 now has proper arc curves (4 arc segments) from extract_sandbox
- Preserved holes from v1.0 geometry
- Boundary vertices also enforced on keepout boundaries
2026-02-17 13:41:24 +00:00
856ff239d6 fix: match reference rib profile style — green boundary, pink outlines, blue holes, 2mm w_frame, zoomed corner view, pocket clipping to inner plate 2026-02-17 12:56:58 +00:00
732e41ec3a fix: clip pockets and triangulation to boundary in plots — no visual crossovers 2026-02-17 12:42:52 +00:00
39a3420a8e Fix: skip pockets crossing sandbox boundary
profile_assembly.py now checks each pocket's polyline against the plate
boundary using Shapely contains(). Pockets extending outside are dropped.
Sandbox 1: 1 pocket removed (was crossing corner near x=150, y=-20).
2026-02-17 11:41:48 +00:00
03232be7b1 chore(hq): daily sync 2026-02-17 2026-02-17 10:00:15 +00:00
44a5b4aac5 import_profile: use structured pocket outlines (lines+arcs), not rib_web polylines
Reverts to drawing outer boundary + pocket outlines (3 lines + 3 arcs
per pocket) + bolt hole circles. These are the red curves from the
Brain plot. NX sketch regions between outer boundary and pocket/hole
outlines define the rib web material for extrusion.

The rib_web Shapely approach was wrong: it approximated arcs as dense
polylines, losing the clean geometry.
2026-02-17 03:10:32 +00:00
1badc370ab Add rib_web to Brain output + import_profile draws rib material
Brain: profile_assembly.py now exports 'rib_web' — the actual material
geometry from Shapely boolean (exterior + interior rings). This is the
rib shape, not the pocket cutouts.

import_profile.py: prefers rib_web when available, drawing exterior +
interior polyline rings directly. Falls back to pocket-based drawing
for older rib JSONs without rib_web.
2026-02-17 03:02:15 +00:00
0bc0c24c1c import_profile: draw bolt holes from rib profile JSON
Holes drawn as two 3-point arcs (semicircles) using center/diameter.
Both structured and legacy pocket formats supported.
2026-02-17 02:54:49 +00:00
f61616d76a Update test_data rib profiles: sandbox_2 new geometry, re-run Brain for both
- sandbox_1: 75 pockets, 2315g mass estimate
- sandbox_2: 11 pockets (was 10), 371g mass estimate, updated geometry from NX
2026-02-17 02:45:19 +00:00
e07c26c6fe test: save NX-exported v1.0 geometry for sandbox_1 (from Antoine) 2026-02-17 02:39:01 +00:00
68ebee7432 test: Brain profiles from latest geometry with mid-field arcs 2026-02-17 02:36:38 +00:00
dc34b7f6d5 fix: arc midpoint parsing + edge type detection for NX integer enums
- EvaluateUnitVectors returns nested lists — added recursive parser
- SolidEdgeType returns int 1 (not 'Linear') — handle both formats
2026-02-17 02:32:52 +00:00
b6dc15e19e test: Brain-generated rib profiles from existing pipeline
Used existing src/brain/ module (density + Delaunay + pockets).
Sandbox 1: 75 pockets, 16 holes. Sandbox 2: 10 pockets, no holes.
Added v2→v1 geometry converter for Brain compatibility.
2026-02-17 02:26:05 +00:00
b411eaac25 fix: arc direction — sample midpoint from NX edge instead of cross-product
Cross product of (start-center) × (end-center) is zero for 180° arcs,
causing random clockwise assignment. Now samples actual midpoint via
UF Eval at t_mid, stores as 'mid' in JSON. Import prefers 'mid' over
computed clockwise direction.
2026-02-17 02:24:32 +00:00
e3a79d4888 feat: proper alternating up/down isogrid pattern with Shapely clipping
- Alternating up/down equilateral triangles filling full boundary
- buffer(-rib_w) for uniform rib spacing
- buffer(-fillet_r).buffer(+fillet_r) for rounded corners
- Clipped to actual boundary polygon
- Sandbox 2: 39 pockets (40mm), Sandbox 1: 112 pockets (60mm)
2026-02-17 02:17:24 +00:00
6d443df3ec Remap channels: project-dashboard→feed, add #reports channel 2026-02-17 02:08:56 +00:00
d954b2b816 feat: proper isogrid pocket generation with boundary clipping + v2.0 outer boundary
- Equilateral triangle grid pattern
- Shapely polygon clipping to actual boundary shape
- v2.0 typed segments (arcs) for outer boundary
- 4mm fillets, 3mm ribs, 2mm frame offset
- Sandbox 1: 25 pockets (80mm), Sandbox 2: 8 pockets (50mm)
2026-02-17 02:08:01 +00:00
43aea01fb5 test: larger cells (120mm/75mm), 4mm fillets, 2mm frame — 9+2 pockets 2026-02-17 02:00:33 +00:00
709612ece4 test: regenerate rib profiles with 4mm fillets, no frame offset 2026-02-17 01:56:39 +00:00
b38194c4d9 test: add rib profile test JSONs for sandbox_1 (64 pockets) and sandbox_2 (9 pockets) 2026-02-17 01:54:48 +00:00
634bf611c9 fix: remove stale chord_tol_mm kwarg from main() 2026-02-17 01:49:24 +00:00
612a21f561 feat(adaptive-isogrid): preserve arcs as typed segments instead of polyline discretization
Schema v2.0: outer_boundary is now a list of typed segments:
  - {type: 'line', start: [x,y], end: [x,y]}
  - {type: 'arc', start: [x,y], end: [x,y], center: [x,y], radius: R, clockwise: bool}

Extract: detect arcs via UF Eval.IsArc/AskArc, output exact geometry.
Import: create NX sketch arcs (3-point) for arc segments, backward-compatible with v1.0 polylines.
2026-02-17 01:47:36 +00:00
abc7d5f013 fix(extract): increase chord tolerance to 1mm, cap at 500 pts/edge
0.1mm was generating thousands of unnecessary points on straight
edges. Now: 1mm default, 0.5mm minimum, 500 max per edge.
Curves still get proper sampling, straight edges stay lean.
2026-02-17 01:40:55 +00:00
c3125b458b Add taskboard CLI tool for kanban orchestration (Phase 1 of plan 13) 2026-02-17 01:39:33 +00:00
cd7f7e8aa9 fix(extract): use EvaluateUnitVectors for parametric edge sampling
Available NXOpen.UF.Eval methods discovered:
- EvaluateUnitVectors(evaluator, t) - parametric point+tangent
- AskArc(evaluator) - arc center/radius for circular edges
- Initialize2, AskLimits, Free - evaluator lifecycle

Also logs arc data attributes for debugging.
2026-02-17 01:36:25 +00:00
fbdafb9a37 fix(extract): discover UF curve eval methods dynamically
NXOpen Python wraps UF methods with version-specific names.
Now dumps available methods on UF.Modl, UF.Eval, UF.Curve
and tries them in order. Detailed logging shows which method
was found and used, plus raw result format on parse failures.
2026-02-17 01:33:39 +00:00
fc1c1dc142 fix(extract): use UF_MODL_ask_curve_props instead of UF_EVAL
UF_EVAL.Evaluate() doesn't exist in NXOpen Python.
UF_MODL.AskCurveProps(tag, param) uses normalized 0-1
parameter and returns (point, tangent, normal, binormal,
torsion, radius). Works on all edge types.
2026-02-17 01:31:29 +00:00
97fe055b8d Add plan 13: Taskboard/Kanban Dynamic Project Orchestration 2026-02-17 01:27:54 +00:00
89e0ffbbf2 Fix NX curved edge sampling with robust UF_EVAL parsing 2026-02-17 01:24:55 +00:00
20d035205a fix(extrude): start extend negative for symmetric extrude 2026-02-17 01:16:36 +00:00
e6f98ac921 feat(extrude): symmetric extrude using part expression
- Uses ISOGRID_RIB_sandbox_N_thk expression for thickness
- Creates expression if missing, uses existing if present
- Symmetric extrude: ±thk/2 from sketch plane
- Fallback to literal value if expression fails
2026-02-17 01:12:16 +00:00
9a5f086684 fix(extrude): robust section creation with multi-approach fallback
- Create section explicitly if builder.Section returns None
- Try 3 approaches for adding curves: CreateRuleCurveFeature,
  CreateRuleCurveDumb with options, CreateRuleCurveDumb without
- Detailed step-by-step logging for debugging
- Get help point from first sketch curve for section seeding
2026-02-17 00:59:37 +00:00
070a211c69 fix(nxopen): simplify sketch extrude and correct rule/builder APIs 2026-02-17 00:55:36 +00:00
4c3457c17c fix: add missing NXOpen.Features and NXOpen.GeometricUtilities imports
NXOpen submodules must be imported explicitly in NX's Python
environment - they're not accessible as attributes of the
parent module.
2026-02-17 00:46:50 +00:00
ecba40f189 feat(import_profile): auto-extrude after sketch creation
Full cycle now automated:
1. Delete old extrude (if exists)
2. Delete old sketch (try ReplaceFeatureBuilder first, fallback to delete)
3. Create new sketch with rib geometry
4. Extrude new sketch by rib thickness along face normal
5. Name both features for identification on next iteration

Rib thickness read from profile JSON (parameters_used.thickness)
with fallback to geometry JSON or default 10mm.

No more manual extrude step needed between iterations.
2026-02-17 00:40:00 +00:00
515eef145f feat(import_profile): use ReplaceFeatureBuilder for sketch replacement
Replaces naive ReplaceEntity approach with NX's proper
ReplaceFeatureBuilder API. This mirrors the interactive
right-click → Replace Feature workflow:

- SelectFeature: old sketch to replace
- ReplacementFeature: new sketch taking over
- DoAutomaticGeomMatch: auto-maps curves
- DeleteOriginalFeature: removes old after remap
- Fallback: manual delete if builder fails

All downstream features (extrude, trim) automatically
re-reference the new sketch.
2026-02-16 23:36:14 +00:00
c4d98ee97c Importer: rename sketch feature + replace/delete old sketch on update 2026-02-16 22:00:18 +00:00
1bfc747cf9 Fix importer: always create new sketch + generate sandbox 2 rib profile (11 pockets) 2026-02-16 21:49:07 +00:00
c5226084fe Generate sandbox 2 rib profile (11 pockets, validated) 2026-02-16 21:33:58 +00:00
98e4b2be02 Add sandbox 2 rib profile geometry 2026-02-16 21:27:27 +00:00
379801c8aa demo: cantilever scenario ready for NX test (52 pockets, 343 entities)
rib_profile_sandbox_1.json now contains the cantilever demo profile.
Also includes 4 demo scenarios with density heatmaps + profiles.
2026-02-16 21:15:09 +00:00