Read half-edge path from geometry layer

This commit is contained in:
Hanno Braun 2024-03-18 13:56:28 +01:00
parent 2438f529d1
commit ecc7f26e3f
14 changed files with 79 additions and 34 deletions

View File

@ -46,7 +46,7 @@ impl Approx for (&Handle<HalfEdge>, &SurfaceGeometry) {
let rest = {
let approx = (
half_edge.curve(),
half_edge.path(),
core.layers.geometry.of_half_edge(half_edge).path,
surface,
half_edge.boundary(),
)
@ -57,8 +57,12 @@ impl Approx for (&Handle<HalfEdge>, &SurfaceGeometry) {
);
approx.points.into_iter().map(|point| {
let point_surface =
half_edge.path().point_from_path_coords(point.local_form);
let point_surface = core
.layers
.geometry
.of_half_edge(half_edge)
.path
.point_from_path_coords(point.local_form);
ApproxPoint::new(point_surface, point.global_form)
})

View File

@ -7,8 +7,8 @@ use crate::{
};
impl super::BoundingVolume<2> for Handle<HalfEdge> {
fn aabb(&self, _: &Geometry) -> Option<Aabb<2>> {
match self.path() {
fn aabb(&self, geometry: &Geometry) -> Option<Aabb<2>> {
match geometry.of_half_edge(self).path {
SurfacePath::Circle(circle) => {
// Just calculate the AABB of the whole circle. This is not the
// most precise, but it should do for now.
@ -23,7 +23,10 @@ impl super::BoundingVolume<2> for Handle<HalfEdge> {
}
SurfacePath::Line(_) => {
let points = self.boundary().inner.map(|point_curve| {
self.path().point_from_path_coords(point_curve)
geometry
.of_half_edge(self)
.path
.point_from_path_coords(point_curve)
});
Some(Aabb::<2>::from_points(points))

View File

@ -29,7 +29,7 @@ impl Cycle {
/// Please note that this is not *the* winding of the cycle, only one of the
/// two possible windings, depending on the direction you look at the
/// surface that the cycle is defined on from.
pub fn winding(&self, _: &Geometry) -> Winding {
pub fn winding(&self, geometry: &Geometry) -> Winding {
// The cycle could be made up of one or two circles. If that is the
// case, the winding of the cycle is determined by the winding of the
// first circle.
@ -43,7 +43,7 @@ impl Cycle {
let [a, b] = first.boundary().inner;
let edge_direction_positive = a < b;
let circle = match first.path() {
let circle = match geometry.of_half_edge(first).path {
SurfacePath::Circle(circle) => circle,
SurfacePath::Line(_) => unreachable!(
"Invalid cycle: less than 3 edges, but not all are circles"

View File

@ -34,7 +34,7 @@ pub trait BuildHalfEdge {
core: &mut Core,
) -> Handle<HalfEdge> {
let half_edge = HalfEdge::new(
sibling.path(),
core.layers.geometry.of_half_edge(sibling).path,
sibling.boundary().reverse(),
sibling.curve().clone(),
start_vertex,
@ -44,7 +44,7 @@ pub trait BuildHalfEdge {
core.layers.geometry.define_half_edge(
half_edge.clone(),
HalfEdgeGeometry {
path: sibling.path(),
path: core.layers.geometry.of_half_edge(sibling).path,
},
);

View File

@ -50,7 +50,7 @@ impl UpdateHalfEdgeGeometry for Handle<HalfEdge> {
update: impl FnOnce(SurfacePath) -> SurfacePath,
core: &mut Core,
) -> Self {
let path = update(self.path());
let path = update(core.layers.geometry.of_half_edge(self).path);
let half_edge = HalfEdge::new(
path,
@ -73,7 +73,7 @@ impl UpdateHalfEdgeGeometry for Handle<HalfEdge> {
core: &mut Core,
) -> Self {
HalfEdge::new(
self.path(),
core.layers.geometry.of_half_edge(self).path,
update(self.boundary()),
self.curve().clone(),
self.start_vertex().clone(),

View File

@ -68,7 +68,10 @@ impl AddHole for Shell {
[Cycle::empty().add_joined_edges(
[(
entry.clone(),
entry.path(),
core.layers
.geometry
.of_half_edge(&entry)
.path,
entry.boundary(),
)],
core,
@ -139,7 +142,10 @@ impl AddHole for Shell {
[Cycle::empty().add_joined_edges(
[(
entry.clone(),
entry.path(),
core.layers
.geometry
.of_half_edge(&entry)
.path,
entry.boundary(),
)],
core,
@ -159,7 +165,14 @@ impl AddHole for Shell {
|region, core| {
region.add_interiors(
[Cycle::empty().add_joined_edges(
[(exit.clone(), exit.path(), exit.boundary())],
[(
exit.clone(),
core.layers
.geometry
.of_half_edge(exit)
.path,
exit.boundary(),
)],
core,
)],
core,

View File

@ -14,7 +14,7 @@ impl Reverse for Cycle {
.pairs()
.map(|(current, next)| {
let half_edge = HalfEdge::new(
current.path(),
core.layers.geometry.of_half_edge(current).path,
current.boundary().reverse(),
current.curve().clone(),
next.start_vertex().clone(),
@ -25,7 +25,7 @@ impl Reverse for Cycle {
core.layers.geometry.define_half_edge(
half_edge.clone(),
HalfEdgeGeometry {
path: current.path(),
path: core.layers.geometry.of_half_edge(current).path,
},
);

View File

@ -10,7 +10,7 @@ use super::ReverseCurveCoordinateSystems;
impl ReverseCurveCoordinateSystems for Handle<HalfEdge> {
fn reverse_curve_coordinate_systems(&self, core: &mut Core) -> Self {
let path = self.path().reverse();
let path = core.layers.geometry.of_half_edge(self).path.reverse();
let boundary = self.boundary().reverse();
let half_edge = HalfEdge::new(

View File

@ -44,14 +44,14 @@ impl SplitHalfEdge for Handle<HalfEdge> {
let [start, end] = self.boundary().inner;
let a = HalfEdge::new(
self.path(),
core.layers.geometry.of_half_edge(self).path,
[start, point],
self.curve().clone(),
self.start_vertex().clone(),
)
.insert(core);
let b = HalfEdge::new(
self.path(),
core.layers.geometry.of_half_edge(self).path,
[point, end],
self.curve().clone(),
Vertex::new().insert(core),
@ -60,11 +60,15 @@ impl SplitHalfEdge for Handle<HalfEdge> {
core.layers.geometry.define_half_edge(
a.clone(),
HalfEdgeGeometry { path: self.path() },
HalfEdgeGeometry {
path: core.layers.geometry.of_half_edge(self).path,
},
);
core.layers.geometry.define_half_edge(
b.clone(),
HalfEdgeGeometry { path: self.path() },
HalfEdgeGeometry {
path: core.layers.geometry.of_half_edge(self).path,
},
);
[a, b]

View File

@ -77,7 +77,7 @@ impl SweepCycle for Cycle {
top_edges.push((
top_edge,
bottom_half_edge.path(),
core.layers.geometry.of_half_edge(bottom_half_edge).path,
bottom_half_edge.boundary(),
));
}

View File

@ -59,7 +59,12 @@ impl SweepHalfEdge for Handle<HalfEdge> {
) -> (Face, Handle<HalfEdge>) {
let path = path.into();
let surface = self.path().sweep_surface_path(surface, path, core);
let surface = core
.layers
.geometry
.of_half_edge(self)
.path
.sweep_surface_path(surface, path, core);
// Next, we need to define the boundaries of the face. Let's start with
// the global vertices and edges.

View File

@ -16,7 +16,7 @@ impl TransformObject for Handle<HalfEdge> {
) -> Self {
// Don't need to transform the path, as that's defined in surface
// coordinates.
let path = self.path();
let path = core.layers.geometry.of_half_edge(self).path;
let boundary = self.boundary();
let curve = self
.curve()

View File

@ -104,6 +104,7 @@ impl ShellValidationError {
surface_a: &SurfaceGeometry,
edge_b: &Handle<HalfEdge>,
surface_b: &SurfaceGeometry,
geometry: &Geometry,
config: &ValidationConfig,
mismatches: &mut Vec<CurveCoordinateSystemMismatch>,
) {
@ -116,10 +117,14 @@ impl ShellValidationError {
let c = a + (d - a) * 2. / 3.;
for point_curve in [a, b, c, d] {
let a_surface =
edge_a.path().point_from_path_coords(point_curve);
let b_surface =
edge_b.path().point_from_path_coords(point_curve);
let a_surface = geometry
.of_half_edge(edge_a)
.path
.point_from_path_coords(point_curve);
let b_surface = geometry
.of_half_edge(edge_b)
.path
.point_from_path_coords(point_curve);
let a_global =
surface_a.point_from_surface_coords(a_surface);
@ -148,6 +153,7 @@ impl ShellValidationError {
&geometry.of_surface(surface_a),
edge_b,
&geometry.of_surface(surface_b),
geometry,
config,
&mut mismatches,
);
@ -156,6 +162,7 @@ impl ShellValidationError {
&geometry.of_surface(surface_b),
edge_a,
&geometry.of_surface(surface_a),
geometry,
config,
&mut mismatches,
);
@ -245,6 +252,7 @@ impl ShellValidationError {
&geometry.of_surface(surface_a),
half_edge_b.clone(),
&geometry.of_surface(surface_b),
geometry,
)
.all(|d| d < config.distinct_min_distance)
{
@ -369,14 +377,19 @@ fn distances(
surface_a: &SurfaceGeometry,
edge_b: Handle<HalfEdge>,
surface_b: &SurfaceGeometry,
geometry: &Geometry,
) -> impl Iterator<Item = Scalar> {
fn sample(
percent: f64,
(edge, surface): (&Handle<HalfEdge>, &SurfaceGeometry),
geometry: &Geometry,
) -> Point<3> {
let [start, end] = edge.boundary().inner;
let path_coords = start + (end - start) * percent;
let surface_coords = edge.path().point_from_path_coords(path_coords);
let surface_coords = geometry
.of_half_edge(edge)
.path
.point_from_path_coords(path_coords);
surface.point_from_surface_coords(surface_coords)
}
@ -389,8 +402,8 @@ fn distances(
let mut distances = Vec::new();
for i in 0..sample_count {
let percent = i as f64 * step;
let sample1 = sample(percent, (&edge_a, surface_a));
let sample2 = sample(1.0 - percent, (&edge_b, surface_b));
let sample1 = sample(percent, (&edge_a, surface_a), geometry);
let sample2 = sample(1.0 - percent, (&edge_b, surface_b), geometry);
distances.push(sample1.distance_to(&sample2))
}
distances.into_iter()

View File

@ -41,13 +41,16 @@ pub struct AdjacentHalfEdgesNotConnected {
impl ValidationCheck<Cycle> for AdjacentHalfEdgesNotConnected {
fn check(
object: &Cycle,
_: &Geometry,
geometry: &Geometry,
config: &ValidationConfig,
) -> impl Iterator<Item = Self> {
object.half_edges().pairs().filter_map(|(first, second)| {
let end_pos_of_first_half_edge = {
let [_, end] = first.boundary().inner;
first.path().point_from_path_coords(end)
geometry
.of_half_edge(first)
.path
.point_from_path_coords(end)
};
let start_pos_of_second_half_edge = second.start_position();