mirror of
https://github.com/bherbruck/solidcraft.git
synced 2026-11-03 10:35:58 +00:00
brep: orientation, not position, tells a face's outer loop
truck lists some planar faces' hole loops before the outer loop, so the rule that loops[0] is the outer loop never held for truck's records; moving it in the adapter would renumber those faces' edges, which history and names stand on. The outer loop is the one that runs counter-clockwise about the natural normal (what check_geometry checks); the order is the producer's, and SMLib's import puts the outer loop first, as SMLib needs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QWhMwdqJYQKQq8RCLSL1LT
This commit is contained in:
@@ -85,9 +85,11 @@ pub struct Face {
|
||||
/// The modelled rectangle in surface parameters, `[[u0, u1], [v0, v1]]`, inside the
|
||||
/// surface's natural domain and around every loop.
|
||||
pub domain: [[f64; 2]; 2],
|
||||
/// `loops[0]` is the outer loop, the rest inner. Loops are stored relative to the surface's
|
||||
/// natural normal, whatever side a shell uses: seen from that normal, the outer loop runs
|
||||
/// counter-clockwise and inner loops clockwise.
|
||||
/// One outer loop and any inner ones, in the producer's order (truck lists some holes
|
||||
/// first; SMLib's import puts the outer loop first, as SMLib requires). Loops are stored
|
||||
/// relative to the surface's natural normal, whatever side a shell uses: seen from that
|
||||
/// normal, the outer loop runs counter-clockwise and inner loops clockwise, which is what
|
||||
/// tells them apart. The first loop is an edge loop.
|
||||
pub loops: Vec<Loop>,
|
||||
}
|
||||
|
||||
|
||||
@@ -172,7 +172,7 @@ impl Brep {
|
||||
}
|
||||
}
|
||||
}
|
||||
// The area the loop encloses, its sign by its place (outer first). Where
|
||||
// The signed area the loop encloses (positive for the outer loop). Where
|
||||
// uses meet at a pole the ring runs straight along the pole's line.
|
||||
let at = Record::Loop { face, r#loop };
|
||||
let mut ring: Vec<[f64; 2]> = Vec::with_capacity(edges.len().saturating_mul(AREA_SAMPLES));
|
||||
|
||||
+6
-3
@@ -52,8 +52,11 @@ shells with opposite `forward`. `forward` means the face's normal in that shell
|
||||
its surface's natural normal, ∂S/∂u × ∂S/∂v. In a closed shell, normals point out
|
||||
of the material.
|
||||
|
||||
**Loops.** A face's first loop is its outer loop and is an edge loop. A vertex
|
||||
loop (a pole, a collapsed boundary) is only ever an inner loop. Loops are stored
|
||||
**Loops.** A face has one outer loop and any number of inner ones, in the
|
||||
producer's order: truck lists some holes before the outer loop, and an SMLib
|
||||
import puts the outer loop first, as SMLib requires. The first loop is an edge
|
||||
loop. A vertex loop (a pole, a collapsed boundary) is only ever an inner loop.
|
||||
Orientation tells outer from inner. Loops are stored
|
||||
relative to the surface's natural normal, whichever side a shell uses: seen from
|
||||
that normal, the outer loop runs counter-clockwise and inner loops clockwise.
|
||||
This lets one face sit in two shells without contradicting itself. An edge loop
|
||||
@@ -82,7 +85,7 @@ paint and persistent names. The same holds for edges and vertices.
|
||||
1. Regions: the infinite region, then bounded regions in the producer's order.
|
||||
2. Shells and faces in order of first appearance, walking regions → shells →
|
||||
oriented faces.
|
||||
3. Edges in order of first appearance, walking faces → loops (outer first) →
|
||||
3. Edges in order of first appearance, walking faces → loops (in stored order) →
|
||||
oriented edges, then wire edges walking shells. A face whose first oriented
|
||||
face is reversed is walked backwards: each of its loops from its last
|
||||
oriented edge to its first. That is how a reversed face is traversed.
|
||||
|
||||
Reference in New Issue
Block a user