Fillet Process
mermaid
flowchart TB
A[User creates or runs FilletFeature] --> B[Read debug mode and derive debug config]
B --> C[Read inputParams.edges and preview snapshots]
C --> D[Expand reference selections into scene objects]
D --> E[Collect edge objects from resolved selections]
E --> F[Try to resolve sheet-metal carrier from raw selections]
F --> G[Resolve single target solid from edge objects]
G --> H{Sheet-metal carrier found?}
H -- Yes --> I[Force target solid to sheet-metal carrier]
H -- No --> J[Use solid resolved from selected edges]
I --> K{Target solid resolved?}
J --> K
K -- No --> K1[Abort fillet and return no added/removed objects]
K -- Yes --> L[Validate radius and normalize direction]
L --> M{Radius > 0?}
M -- No --> M1[Abort fillet and return no added/removed objects]
M -- Yes --> N{Target is sheet-metal carrier?}
N -- Yes --> SM0
N -- No --> S0
subgraph SheetMetalPath [Sheet-Metal Corner Fillet Replacement Path]
direction TB
SM0[Build sheet source from carrier]
SM0 --> SM1{Sheet source found?}
SM1 -- No --> SM1A[Return handled false summary with no_sheet_source]
SM1 -- Yes --> SM2[Clone sheet tree]
SM2 --> SM3[Resolve sheet-metal fillet targets from selections and edge selections]
SM3 --> SM4[Apply corner fillets to tree]
SM4 --> SM5[Validate radius]
SM5 --> SM6{Radius valid?}
SM6 -- No --> SM6A[Mark all requested targets skipped]
SM6 -- Yes --> SM7[Group targets by flat and outline corner anchors]
SM7 --> SM8[For each target resolve flat/edge or corner-pair match]
SM8 --> SM9{Target edge/corner valid on outer outline?}
SM9 -- No --> SM9A[Mark target skipped with reason]
SM9 -- Yes --> SM10[Create per-flat fillet plan]
SM10 --> SM11[For each flat plan locate eligible convex corner anchors]
SM11 --> SM12{Eligible corners found?}
SM12 -- No --> SM12A[Mark plan sources skipped]
SM12 -- Yes --> SM13[Round each eligible outline corner into an arc polyline]
SM13 --> SM14[Replace flat outline with rounded loop]
SM14 --> SM15[Rebuild flat outer edges from rounded outline]
SM15 --> SM16{Rebuild succeeded?}
SM16 -- No --> SM16A[Restore old outline/edges and mark skipped]
SM16 -- Yes --> SM17[Record applied targets and applied corner count]
SM17 --> SM18[Restore flat boundary vertices and synchronize bend/attach subdivision]
SM18 --> SM19{Any corners actually applied?}
SM19 -- No --> SM19A[Return handled true with null root and no_corners_modified or no_sheet_metal_edge_targets]
SM19 -- Yes --> SM20[Update sheet metadata and last feature id]
SM20 --> SM21[Build renderable sheet model from updated tree]
SM21 --> SM22[Preserve sheet-metal face names and carrier name]
SM22 --> SM23[Set persistentData.usedSheetMetalPath to true and store summary]
SM23 --> SM24{Renderable root built?}
SM24 -- No --> SM24A[Return no replacement]
SM24 -- Yes --> SM25[Return added:new sheet root and removed:old carrier]
end
subgraph SolidPath [Standard Solid Fillet Path]
direction TB
S0[Read standard fillet toggles: simplify, native tiny-face cleanup, reverse nudge, merge end caps, sliver reassign, collapse tiny triangles, post-collapse cleanup]
S0 --> S1[Call targetSolid.fillet]
S1 --> S2[Require native combined/batch/corner-bridge/classifier support]
S2 --> S3[Validate radius again]
S3 --> S4[Resolve and dedupe selected edges on this solid]
S4 --> S5{Any edges resolved?}
S5 -- No --> S5A[Return unchanged clone of solid]
S5 -- Yes --> S6[Build authoring-state snapshot of target solid]
S6 --> S7[Build per-edge payloads: names, face names, local polylines, closedLoop flags, optional segment-face pairs]
S7 --> S8{Any valid edge payloads built?}
S8 -- No --> S8A[Return unchanged clone of solid]
S8 --> S9[Call native buildFilletAuthoringState]
S9 --> S10{Native fillet build succeeded?}
S10 -- No --> S10A[Log native failure and return unchanged clone]
S10 -- Yes --> S11[Optional: log AUTO direction classification summary]
S11 --> S12[Rehydrate final snapshot into a new Solid]
S12 --> S13{Final snapshot present?}
S13 -- No --> S13A[Return unchanged clone]
S13 -- Yes --> S14[Optional: rehydrate native debug snapshots into debug solids]
S14 --> S15[Attach direction decision, corner bridge count, and end-cap toggle metadata to result]
S15 --> S16{Reverse end-cap nudge enabled?}
S16 -- No --> S16A[Set reverse-nudge count to 0]
S16 -- Yes --> S17[Reverse post-boolean fillet end-cap nudge on eligible end-cap faces]
S17 --> S18{Merge coplanar end caps enabled?}
S16A --> S18
S18 -- No --> S18A[Set end-cap merge count to 0]
S18 -- Yes --> S19[Find coplanar adjacent face for each fillet end cap and rename face ids to merge labels]
S19 --> S20{Sliver triangle reassignment enabled?}
S18A --> S20
S20 -- No --> S20A[Set sliver reassign count to 0]
S20 -- Yes --> S21[Reassign tiny fillet sidewall sliver triangles into planar neighbor faces]
S21 --> S22[Return solid result to FilletFeature.run]
S20A --> S22
end
subgraph NativeAuthoring [Native buildFilletAuthoringState Pipeline]
direction TB
N0[Receive target snapshot, edge payloads, radius, direction mode, inflate, nudge, resolution, cleanup area, debug flags]
N0 --> N1[Run buildFilletBatchAuthoringState]
N1 --> N2[For each edge decide direction]
N2 --> N3{Direction mode AUTO?}
N3 -- No --> N3A[Use explicit INSET/OUTSET]
N3 -- Yes --> N4[Run classifyFilletEdgeDirection]
N4 --> N5[Resolve shared boundary chain between faceA and faceB]
N5 --> N6[Resolve oriented edge tangent and local normals at boundary midpoint]
N6 --> N7[Vote for inset/outset using signed dihedral / sample classification]
N7 --> N8{Classifier produced confident result?}
N8 -- No --> N8A[Use fallback direction and mark fallback/ambiguous counts]
N8 -- Yes --> N8B[Use classified direction]
N3A --> N9
N8A --> N9
N8B --> N9
N9[Build one native edge fillet entry with buildFilletEdgeAuthoringState]
N9 --> N10[Compute fillet centerline for the edge]
N10 --> N11[Sanitize input polyline and build centerline samples]
N11 --> N12{Segment-face pairs supplied?}
N12 -- No --> N12A[Use fixed faceA/faceB meshes along the edge]
N12 -- Yes --> N12B[Resolve per-segment/blended face context]
N12A --> N13
N12B --> N13
N13[For each sample project onto host faces and compute local normals]
N13 --> N14[Build tangent frame and bisector]
N14 --> N15[Estimate max allowed radius from face projection ranges]
N15 --> N16[Solve inset and outset center candidates from offset planes]
N16 --> N17[Score candidates against projected tangency and requested side]
N17 --> N18[Choose center candidate or fallback bisector/average-normal center]
N18 --> N19[Refine center against reprojected tangency points when needed]
N19 --> N20[Clamp pathological center distances]
N20 --> N21[Collect centerline point, tangentA, tangentB, and edge sample]
N21 --> N22[Stabilize open endpoints or close the loop]
N22 --> N23[Fix winding and align rails to centerline ends]
N23 --> N24[Return centerline/tangent/edge rails and optional radius-clamp info]
N24 --> N25[Sanitize tangent rails]
N25 --> N26{Inflate offset requested?}
N26 -- Yes --> N26A[Apply tangent offset to tangent rails]
N26 -- No --> N26B[Keep tangent rails unchanged]
N26A --> N27
N26B --> N27
N27{Need wedge inset adjustment?}
N27 -- Yes --> N27A[Inset edge rail for wedge construction]
N27 -- No --> N27B[Keep edge rail for wedge construction]
N27A --> N28
N27B --> N28
N28[Build fillet segment geometry with buildFilletSegmentAuthoringState]
N28 --> N29[Create wedge triangles from centerline, tangency rails, and edge rail]
N29 --> N30{Open edge?}
N30 -- Yes --> N30A[Add end-cap faces and push them outward by nudge distance]
N30 -- No --> N30B[Build closed-loop wedge faces only]
N30A --> N31
N30B --> N31
N31[Apply wedge metadata]
N31 --> N32[Build tube along centerline path]
N32 --> N33[Apply tube metadata]
N33 --> N34[Boolean wedge minus tube to create one edge fillet solid]
N34 --> N35[Collect tube cap points for open edges]
N35 --> N36[Store edge entry: wedge snapshot, tube snapshot, final snapshot, centerline data, direction]
N36 --> N37[Repeat for all selected edges]
N37 --> N38[Detect shared non-tangent endpoints between compatible entries]
N38 --> N39{Corner bridge needed?}
N39 -- No --> N39A[Skip bridge for that pair]
N39 -- Yes --> N40[Build corner bridge]
N40 --> N41[Resolve wedge/tube cap point sets near shared corner]
N41 --> N42[Reject if centerlines cross or tube gap is too small]
N42 --> N43[Build wedge bridge hull, subtract adjacent edge tubes, build bridge tube]
N43 --> N44[Boolean corner bridge wedge minus bridge tube]
N44 --> N45[Append corner bridge as another fillet entry]
N45 --> N46[For each non-corner entry decide whether start/end caps should be merged into sidewall label]
N46 --> N47[Build combine entry list with direction and optional face-rename merge metadata]
N47 --> N48[Call buildFilletCombinedAuthoringState]
N48 --> N49[Normalize target snapshot for booleans]
N49 --> N50[Normalize each fillet entry snapshot for booleans]
N50 --> N51[Optional: rename entry faces into one merged sidewall face before combine]
N51 --> N52[Union all INSET tools together and all OUTSET tools together]
N52 --> N53[Subtract inset group from target]
N53 --> N54[Union outset group into target]
N54 --> N55[Combine id maps, metadata, and aux edges]
N55 --> N56[Relabel fallback face names by adjacency]
N56 --> N57[Clean up tiny face islands in the combined native result]
N57 --> N58[Build final combined snapshot and attach debug snapshots]
end
S22 --> F0
SM25 --> F9
SM24A --> F8
SM19A --> F8
subgraph FeatureFinalize [Back In FilletFeature.run]
direction TB
F0[Attach simplify/native-cleanup/post-cleanup flags onto returned solid]
F0 --> F1[Collect debug solids from native result]
F1 --> F2[Store persistentData.edgeDirectionDecision cornerBridgeCount and usedSheetMetalPath false]
F2 --> F3{Result object exists?}
F3 -- No --> F3A[Throw fillet returned no result]
F3 -- Yes --> F4{Final simplify enabled?}
F4 -- Yes --> F4A[Run result.simplify with tolerance 0.0004]
F4 -- No --> F5
F4A --> F5[Measure triangle and vertex counts]
F5 --> F6{Geometry empty?}
F6 -- Yes --> F6A[Throw fillet produced empty geometry]
F6 -- No --> F7[Queue result solid and debug solids in added and queue original target solid in removed]
F7 --> F8[For each added solid optionally collapse tiny triangles]
F8 --> F9[For each added solid optionally run post-collapse tiny-face island cleanup]
F9 --> F10[Visualize each added solid]
F10 --> F11[Return added and removed object lists]
end
SM1A --> F11
K1 --> F11
M1 --> F11
F11 --> Z[Scene replacement uses returned added/removed objects]