mirror of
https://github.com/hannobraun/Fornjot
synced 2025-05-06 10:58:28 +00:00
Merge pull request #2417 from hannobraun/geom
Replace all reads of half-edge geometry with reads of vertex geometry
This commit is contained in:
commit
7c7bfe5c0b
@ -5,7 +5,7 @@
|
|||||||
use fj_math::Segment;
|
use fj_math::Segment;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
geometry::Geometry,
|
geometry::{CurveBoundary, Geometry},
|
||||||
storage::Handle,
|
storage::Handle,
|
||||||
topology::{Cycle, Surface},
|
topology::{Cycle, Surface},
|
||||||
};
|
};
|
||||||
@ -28,9 +28,24 @@ pub fn approx_cycle(
|
|||||||
|
|
||||||
let half_edges = cycle
|
let half_edges = cycle
|
||||||
.half_edges()
|
.half_edges()
|
||||||
.iter()
|
.pairs()
|
||||||
.map(|half_edge| {
|
.map(|(half_edge, next_half_edge)| {
|
||||||
let boundary = geometry.of_half_edge(half_edge).boundary;
|
let boundary = CurveBoundary {
|
||||||
|
inner: [
|
||||||
|
geometry
|
||||||
|
.of_vertex(half_edge.start_vertex())
|
||||||
|
.unwrap()
|
||||||
|
.local_on(half_edge.curve())
|
||||||
|
.unwrap()
|
||||||
|
.position,
|
||||||
|
geometry
|
||||||
|
.of_vertex(next_half_edge.start_vertex())
|
||||||
|
.unwrap()
|
||||||
|
.local_on(half_edge.curve())
|
||||||
|
.unwrap()
|
||||||
|
.position,
|
||||||
|
],
|
||||||
|
};
|
||||||
let [start_position_curve, _] = boundary.inner;
|
let [start_position_curve, _] = boundary.inner;
|
||||||
|
|
||||||
let start = approx_vertex(
|
let start = approx_vertex(
|
||||||
|
@ -12,8 +12,8 @@ impl super::BoundingVolume<2> for (&Cycle, &Handle<Surface>) {
|
|||||||
|
|
||||||
let mut aabb: Option<Aabb<2>> = None;
|
let mut aabb: Option<Aabb<2>> = None;
|
||||||
|
|
||||||
for half_edge in cycle.half_edges() {
|
for (half_edge, half_edge_next) in cycle.half_edges().pairs() {
|
||||||
let new_aabb = (half_edge, surface)
|
let new_aabb = (half_edge, half_edge_next.start_vertex(), surface)
|
||||||
.aabb(geometry)
|
.aabb(geometry)
|
||||||
.expect("`HalfEdge` can always compute AABB");
|
.expect("`HalfEdge` can always compute AABB");
|
||||||
aabb = Some(aabb.map_or(new_aabb, |aabb| aabb.merged(&new_aabb)));
|
aabb = Some(aabb.map_or(new_aabb, |aabb| aabb.merged(&new_aabb)));
|
||||||
|
@ -3,14 +3,15 @@ use fj_math::{Aabb, Vector};
|
|||||||
use crate::{
|
use crate::{
|
||||||
geometry::{Geometry, SurfacePath},
|
geometry::{Geometry, SurfacePath},
|
||||||
storage::Handle,
|
storage::Handle,
|
||||||
topology::{HalfEdge, Surface},
|
topology::{HalfEdge, Surface, Vertex},
|
||||||
};
|
};
|
||||||
|
|
||||||
impl super::BoundingVolume<2> for (&Handle<HalfEdge>, &Handle<Surface>) {
|
impl super::BoundingVolume<2>
|
||||||
|
for (&Handle<HalfEdge>, &Handle<Vertex>, &Handle<Surface>)
|
||||||
|
{
|
||||||
fn aabb(self, geometry: &Geometry) -> Option<Aabb<2>> {
|
fn aabb(self, geometry: &Geometry) -> Option<Aabb<2>> {
|
||||||
let (half_edge, surface) = self;
|
let (half_edge, end_vertex, surface) = self;
|
||||||
|
|
||||||
let half_edge_geom = geometry.of_half_edge(half_edge);
|
|
||||||
let path = geometry
|
let path = geometry
|
||||||
.of_curve(half_edge.curve())
|
.of_curve(half_edge.curve())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -32,9 +33,17 @@ impl super::BoundingVolume<2> for (&Handle<HalfEdge>, &Handle<Surface>) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
SurfacePath::Line(_) => {
|
SurfacePath::Line(_) => {
|
||||||
let points = half_edge_geom.boundary.inner.map(|point_curve| {
|
let points =
|
||||||
path.point_from_path_coords(point_curve)
|
[half_edge.start_vertex(), end_vertex].map(|vertex| {
|
||||||
});
|
let point_curve = geometry
|
||||||
|
.of_vertex(vertex)
|
||||||
|
.unwrap()
|
||||||
|
.local_on(half_edge.curve())
|
||||||
|
.unwrap()
|
||||||
|
.position;
|
||||||
|
|
||||||
|
path.point_from_path_coords(point_curve)
|
||||||
|
});
|
||||||
|
|
||||||
Some(Aabb::<2>::from_points(points))
|
Some(Aabb::<2>::from_points(points))
|
||||||
}
|
}
|
||||||
|
@ -104,29 +104,43 @@ impl SplitFace for Shell {
|
|||||||
|
|
||||||
// Build the edge that's going to divide the new faces.
|
// Build the edge that's going to divide the new faces.
|
||||||
let dividing_half_edge_a_to_d = {
|
let dividing_half_edge_a_to_d = {
|
||||||
|
let start = core
|
||||||
|
.layers
|
||||||
|
.geometry
|
||||||
|
.of_curve(b.curve())
|
||||||
|
.unwrap()
|
||||||
|
.local_on(face.surface())
|
||||||
|
.unwrap()
|
||||||
|
.path
|
||||||
|
.point_from_path_coords(
|
||||||
|
core.layers
|
||||||
|
.geometry
|
||||||
|
.of_vertex(b.start_vertex())
|
||||||
|
.unwrap()
|
||||||
|
.local_on(b.curve())
|
||||||
|
.unwrap()
|
||||||
|
.position,
|
||||||
|
);
|
||||||
|
let end = core
|
||||||
|
.layers
|
||||||
|
.geometry
|
||||||
|
.of_curve(d.curve())
|
||||||
|
.unwrap()
|
||||||
|
.local_on(face.surface())
|
||||||
|
.unwrap()
|
||||||
|
.path
|
||||||
|
.point_from_path_coords(
|
||||||
|
core.layers
|
||||||
|
.geometry
|
||||||
|
.of_vertex(d.start_vertex())
|
||||||
|
.unwrap()
|
||||||
|
.local_on(d.curve())
|
||||||
|
.unwrap()
|
||||||
|
.position,
|
||||||
|
);
|
||||||
|
|
||||||
let (half_edge, boundary) = HalfEdge::line_segment(
|
let (half_edge, boundary) = HalfEdge::line_segment(
|
||||||
[
|
[start, end],
|
||||||
core.layers.geometry.of_half_edge(&b).start_position(
|
|
||||||
&core
|
|
||||||
.layers
|
|
||||||
.geometry
|
|
||||||
.of_curve(b.curve())
|
|
||||||
.unwrap()
|
|
||||||
.local_on(face.surface())
|
|
||||||
.unwrap()
|
|
||||||
.path,
|
|
||||||
),
|
|
||||||
core.layers.geometry.of_half_edge(&d).start_position(
|
|
||||||
&core
|
|
||||||
.layers
|
|
||||||
.geometry
|
|
||||||
.of_curve(d.curve())
|
|
||||||
.unwrap()
|
|
||||||
.local_on(face.surface())
|
|
||||||
.unwrap()
|
|
||||||
.path,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
face.surface().clone(),
|
face.surface().clone(),
|
||||||
core,
|
core,
|
||||||
);
|
);
|
||||||
|
@ -46,7 +46,27 @@ impl SplitHalfEdge for Cycle {
|
|||||||
let point = point.into();
|
let point = point.into();
|
||||||
|
|
||||||
let geometry = *core.layers.geometry.of_half_edge(half_edge);
|
let geometry = *core.layers.geometry.of_half_edge(half_edge);
|
||||||
let [start, end] = geometry.boundary.inner;
|
let [start, end] = [
|
||||||
|
core.layers
|
||||||
|
.geometry
|
||||||
|
.of_vertex(half_edge.start_vertex())
|
||||||
|
.unwrap()
|
||||||
|
.local_on(half_edge.curve())
|
||||||
|
.unwrap()
|
||||||
|
.position,
|
||||||
|
core.layers
|
||||||
|
.geometry
|
||||||
|
.of_vertex(
|
||||||
|
self.half_edges()
|
||||||
|
.after(half_edge)
|
||||||
|
.expect("Expected half-edge to be in cycle")
|
||||||
|
.start_vertex(),
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.local_on(half_edge.curve())
|
||||||
|
.unwrap()
|
||||||
|
.position,
|
||||||
|
];
|
||||||
|
|
||||||
let a = HalfEdge::new(
|
let a = HalfEdge::new(
|
||||||
half_edge.curve().clone(),
|
half_edge.curve().clone(),
|
||||||
|
@ -59,7 +59,22 @@ impl SweepHalfEdge for Handle<HalfEdge> {
|
|||||||
) -> SweptHalfEdge {
|
) -> SweptHalfEdge {
|
||||||
let path = path.into();
|
let path = path.into();
|
||||||
|
|
||||||
let half_edge_geom = *core.layers.geometry.of_half_edge(self);
|
let boundary = [
|
||||||
|
core.layers
|
||||||
|
.geometry
|
||||||
|
.of_vertex(self.start_vertex())
|
||||||
|
.unwrap()
|
||||||
|
.local_on(self.curve())
|
||||||
|
.unwrap()
|
||||||
|
.position,
|
||||||
|
core.layers
|
||||||
|
.geometry
|
||||||
|
.of_vertex(&end_vertex)
|
||||||
|
.unwrap()
|
||||||
|
.local_on(self.curve())
|
||||||
|
.unwrap()
|
||||||
|
.position,
|
||||||
|
];
|
||||||
let curve_geom = core
|
let curve_geom = core
|
||||||
.layers
|
.layers
|
||||||
.geometry
|
.geometry
|
||||||
@ -94,7 +109,7 @@ impl SweepHalfEdge for Handle<HalfEdge> {
|
|||||||
|
|
||||||
// Let's figure out the surface coordinates of the edge vertices.
|
// Let's figure out the surface coordinates of the edge vertices.
|
||||||
let surface_points = {
|
let surface_points = {
|
||||||
let [a, b] = half_edge_geom.boundary.inner;
|
let [a, b] = boundary;
|
||||||
|
|
||||||
[
|
[
|
||||||
[a.t, Scalar::ZERO],
|
[a.t, Scalar::ZERO],
|
||||||
@ -112,7 +127,7 @@ impl SweepHalfEdge for Handle<HalfEdge> {
|
|||||||
|
|
||||||
// Now, the boundaries of each edge.
|
// Now, the boundaries of each edge.
|
||||||
let boundaries = {
|
let boundaries = {
|
||||||
let [a, b] = half_edge_geom.boundary.inner;
|
let [a, b] = boundary;
|
||||||
let [c, d] = [0., 1.].map(|coord| Point::from([coord]));
|
let [c, d] = [0., 1.].map(|coord| Point::from([coord]));
|
||||||
|
|
||||||
[[a, b], [c, d], [b, a], [d, c]]
|
[[a, b], [c, d], [b, a], [d, c]]
|
||||||
|
@ -46,7 +46,6 @@ impl Cycle {
|
|||||||
.next()
|
.next()
|
||||||
.expect("Invalid cycle: expected at least one edge");
|
.expect("Invalid cycle: expected at least one edge");
|
||||||
|
|
||||||
let half_edge_geom = geometry.of_half_edge(first);
|
|
||||||
let curve_geom = geometry
|
let curve_geom = geometry
|
||||||
.of_curve(first.curve())
|
.of_curve(first.curve())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -54,7 +53,29 @@ impl Cycle {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.clone();
|
.clone();
|
||||||
|
|
||||||
let [a, b] = half_edge_geom.boundary.inner;
|
let [a, b] = [
|
||||||
|
curve_geom.path.point_from_path_coords(
|
||||||
|
geometry
|
||||||
|
.of_vertex(first.start_vertex())
|
||||||
|
.unwrap()
|
||||||
|
.local_on(first.curve())
|
||||||
|
.unwrap()
|
||||||
|
.position,
|
||||||
|
),
|
||||||
|
curve_geom.path.point_from_path_coords(
|
||||||
|
geometry
|
||||||
|
.of_vertex(
|
||||||
|
self.half_edges()
|
||||||
|
.after(first)
|
||||||
|
.expect("Just got half-edge from this cycle")
|
||||||
|
.start_vertex(),
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.local_on(first.curve())
|
||||||
|
.unwrap()
|
||||||
|
.position,
|
||||||
|
),
|
||||||
|
];
|
||||||
let edge_direction_positive = a < b;
|
let edge_direction_positive = a < b;
|
||||||
|
|
||||||
let circle = match curve_geom.path {
|
let circle = match curve_geom.path {
|
||||||
@ -80,14 +101,20 @@ impl Cycle {
|
|||||||
|
|
||||||
for (a, b) in self.half_edges().pairs() {
|
for (a, b) in self.half_edges().pairs() {
|
||||||
let [a, b] = [a, b].map(|half_edge| {
|
let [a, b] = [a, b].map(|half_edge| {
|
||||||
geometry.of_half_edge(half_edge).start_position(
|
geometry
|
||||||
&geometry
|
.of_curve(half_edge.curve())
|
||||||
.of_curve(half_edge.curve())
|
.unwrap()
|
||||||
.unwrap()
|
.local_on(surface)
|
||||||
.local_on(surface)
|
.unwrap()
|
||||||
.unwrap()
|
.path
|
||||||
.path,
|
.point_from_path_coords(
|
||||||
)
|
geometry
|
||||||
|
.of_vertex(half_edge.start_vertex())
|
||||||
|
.unwrap()
|
||||||
|
.local_on(half_edge.curve())
|
||||||
|
.unwrap()
|
||||||
|
.position,
|
||||||
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
sum += (b.u - a.u) * (b.v + a.v);
|
sum += (b.u - a.u) * (b.v + a.v);
|
||||||
|
@ -117,9 +117,14 @@ impl SolidValidationError {
|
|||||||
|
|
||||||
Some((
|
Some((
|
||||||
geometry.of_surface(s).point_from_surface_coords(
|
geometry.of_surface(s).point_from_surface_coords(
|
||||||
geometry
|
local_curve_geometry.path.point_from_path_coords(
|
||||||
.of_half_edge(&h)
|
geometry
|
||||||
.start_position(&local_curve_geometry.path),
|
.of_vertex(h.start_vertex())
|
||||||
|
.unwrap()
|
||||||
|
.local_on(h.curve())
|
||||||
|
.unwrap()
|
||||||
|
.position,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
h.start_vertex().clone(),
|
h.start_vertex().clone(),
|
||||||
))
|
))
|
||||||
|
@ -5,7 +5,8 @@ use fj_math::{Point, Scalar};
|
|||||||
use crate::{
|
use crate::{
|
||||||
geometry::{CurveBoundary, Geometry},
|
geometry::{CurveBoundary, Geometry},
|
||||||
queries::{
|
queries::{
|
||||||
AllHalfEdgesWithSurface, BoundingVerticesOfHalfEdge, SiblingOfHalfEdge,
|
AllHalfEdgesWithSurface, BoundingVerticesOfHalfEdge, CycleOfHalfEdge,
|
||||||
|
SiblingOfHalfEdge,
|
||||||
},
|
},
|
||||||
storage::Handle,
|
storage::Handle,
|
||||||
topology::{Curve, HalfEdge, Shell, Surface, Vertex},
|
topology::{Curve, HalfEdge, Shell, Surface, Vertex},
|
||||||
@ -109,8 +110,22 @@ impl ValidationCheck<Shell> for CoincidentHalfEdgesAreNotSiblings {
|
|||||||
|
|
||||||
let Some(mut distances) = distances(
|
let Some(mut distances) = distances(
|
||||||
half_edge_a.clone(),
|
half_edge_a.clone(),
|
||||||
|
object
|
||||||
|
.find_cycle_of_half_edge(half_edge_a)
|
||||||
|
.unwrap()
|
||||||
|
.half_edges()
|
||||||
|
.after(half_edge_a)
|
||||||
|
.unwrap()
|
||||||
|
.start_vertex(),
|
||||||
surface_a,
|
surface_a,
|
||||||
half_edge_b.clone(),
|
half_edge_b.clone(),
|
||||||
|
object
|
||||||
|
.find_cycle_of_half_edge(half_edge_b)
|
||||||
|
.unwrap()
|
||||||
|
.half_edges()
|
||||||
|
.after(half_edge_b)
|
||||||
|
.unwrap()
|
||||||
|
.start_vertex(),
|
||||||
surface_b,
|
surface_b,
|
||||||
geometry,
|
geometry,
|
||||||
) else {
|
) else {
|
||||||
@ -152,25 +167,39 @@ impl ValidationCheck<Shell> for CoincidentHalfEdgesAreNotSiblings {
|
|||||||
/// Returns an [`Iterator`] of the distance at each sample.
|
/// Returns an [`Iterator`] of the distance at each sample.
|
||||||
fn distances(
|
fn distances(
|
||||||
half_edge_a: Handle<HalfEdge>,
|
half_edge_a: Handle<HalfEdge>,
|
||||||
|
end_vertex_a: &Handle<Vertex>,
|
||||||
surface_a: &Handle<Surface>,
|
surface_a: &Handle<Surface>,
|
||||||
half_edge_b: Handle<HalfEdge>,
|
half_edge_b: Handle<HalfEdge>,
|
||||||
|
end_vertex_b: &Handle<Vertex>,
|
||||||
surface_b: &Handle<Surface>,
|
surface_b: &Handle<Surface>,
|
||||||
geometry: &Geometry,
|
geometry: &Geometry,
|
||||||
) -> Option<impl Iterator<Item = Scalar>> {
|
) -> Option<impl Iterator<Item = Scalar>> {
|
||||||
fn sample(
|
fn sample(
|
||||||
percent: f64,
|
percent: f64,
|
||||||
half_edge: &Handle<HalfEdge>,
|
half_edge: &Handle<HalfEdge>,
|
||||||
|
end_vertex: &Handle<Vertex>,
|
||||||
surface: &Handle<Surface>,
|
surface: &Handle<Surface>,
|
||||||
geometry: &Geometry,
|
geometry: &Geometry,
|
||||||
) -> Option<Point<3>> {
|
) -> Option<Point<3>> {
|
||||||
let [start, end] = geometry.of_half_edge(half_edge).boundary.inner;
|
let [start, end] = [
|
||||||
|
geometry
|
||||||
|
.of_vertex(half_edge.start_vertex())
|
||||||
|
.unwrap()
|
||||||
|
.local_on(half_edge.curve())
|
||||||
|
.unwrap()
|
||||||
|
.position,
|
||||||
|
geometry
|
||||||
|
.of_vertex(end_vertex)
|
||||||
|
.unwrap()
|
||||||
|
.local_on(half_edge.curve())
|
||||||
|
.unwrap()
|
||||||
|
.position,
|
||||||
|
];
|
||||||
let path_coords = start + (end - start) * percent;
|
let path_coords = start + (end - start) * percent;
|
||||||
// let path = geometry.of_half_edge(half_edge).path;
|
|
||||||
let path = geometry
|
let path = geometry
|
||||||
.of_curve(half_edge.curve())?
|
.of_curve(half_edge.curve())?
|
||||||
.local_on(surface)?
|
.local_on(surface)?
|
||||||
.path;
|
.path;
|
||||||
// assert_eq!(path, path_from_curve);
|
|
||||||
let surface_coords = path.point_from_path_coords(path_coords);
|
let surface_coords = path.point_from_path_coords(path_coords);
|
||||||
Some(
|
Some(
|
||||||
geometry
|
geometry
|
||||||
@ -188,8 +217,15 @@ fn distances(
|
|||||||
let mut distances = Vec::new();
|
let mut distances = Vec::new();
|
||||||
for i in 0..sample_count {
|
for i in 0..sample_count {
|
||||||
let percent = i as f64 * step;
|
let percent = i as f64 * step;
|
||||||
let sample1 = sample(percent, &half_edge_a, surface_a, geometry)?;
|
let sample1 =
|
||||||
let sample2 = sample(1.0 - percent, &half_edge_b, surface_b, geometry)?;
|
sample(percent, &half_edge_a, end_vertex_a, surface_a, geometry)?;
|
||||||
|
let sample2 = sample(
|
||||||
|
1.0 - percent,
|
||||||
|
&half_edge_b,
|
||||||
|
end_vertex_b,
|
||||||
|
surface_b,
|
||||||
|
geometry,
|
||||||
|
)?;
|
||||||
distances.push(sample1.distance_to(&sample2))
|
distances.push(sample1.distance_to(&sample2))
|
||||||
}
|
}
|
||||||
Some(distances.into_iter())
|
Some(distances.into_iter())
|
||||||
|
@ -3,7 +3,7 @@ use itertools::Itertools;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
geometry::Geometry,
|
geometry::Geometry,
|
||||||
queries::AllHalfEdgesWithSurface,
|
queries::{AllHalfEdgesWithSurface, CycleOfHalfEdge},
|
||||||
storage::Handle,
|
storage::Handle,
|
||||||
topology::{HalfEdge, Shell},
|
topology::{HalfEdge, Shell},
|
||||||
validation::{ValidationCheck, ValidationConfig},
|
validation::{ValidationCheck, ValidationConfig},
|
||||||
@ -130,8 +130,28 @@ impl ValidationCheck<Shell> for CurveGeometryMismatch {
|
|||||||
// we have right now are circles, 3 would be enough to check
|
// we have right now are circles, 3 would be enough to check
|
||||||
// for coincidence. But the first and last might be
|
// for coincidence. But the first and last might be
|
||||||
// identical, so let's add an extra one.
|
// identical, so let's add an extra one.
|
||||||
let [a, d] =
|
let [a, d] = [
|
||||||
geometry.of_half_edge(&half_edge_a).boundary.inner;
|
geometry
|
||||||
|
.of_vertex(half_edge_a.start_vertex())
|
||||||
|
.unwrap()
|
||||||
|
.local_on(half_edge_a.curve())
|
||||||
|
.unwrap()
|
||||||
|
.position,
|
||||||
|
geometry
|
||||||
|
.of_vertex(
|
||||||
|
object
|
||||||
|
.find_cycle_of_half_edge(&half_edge_a)
|
||||||
|
.unwrap()
|
||||||
|
.half_edges()
|
||||||
|
.after(&half_edge_a)
|
||||||
|
.unwrap()
|
||||||
|
.start_vertex(),
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.local_on(half_edge_a.curve())
|
||||||
|
.unwrap()
|
||||||
|
.position,
|
||||||
|
];
|
||||||
let b = a + (d - a) * 1. / 3.;
|
let b = a + (d - a) * 1. / 3.;
|
||||||
let c = a + (d - a) * 2. / 3.;
|
let c = a + (d - a) * 2. / 3.;
|
||||||
|
|
||||||
|
@ -99,7 +99,12 @@ fn check_cycle<'r>(
|
|||||||
) -> impl Iterator<Item = AdjacentHalfEdgesNotConnected> + 'r {
|
) -> impl Iterator<Item = AdjacentHalfEdgesNotConnected> + 'r {
|
||||||
cycle.half_edges().pairs().filter_map(|(first, second)| {
|
cycle.half_edges().pairs().filter_map(|(first, second)| {
|
||||||
let end_pos_of_first_half_edge = {
|
let end_pos_of_first_half_edge = {
|
||||||
let [_, end] = geometry.of_half_edge(first).boundary.inner;
|
let end = geometry
|
||||||
|
.of_vertex(second.start_vertex())
|
||||||
|
.unwrap()
|
||||||
|
.local_on(first.curve())
|
||||||
|
.unwrap()
|
||||||
|
.position;
|
||||||
geometry
|
geometry
|
||||||
.of_curve(first.curve())
|
.of_curve(first.curve())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -117,9 +122,18 @@ fn check_cycle<'r>(
|
|||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
let start_pos_of_second_half_edge = geometry
|
let start_pos_of_second_half_edge = {
|
||||||
.of_half_edge(second)
|
let point_curve = geometry
|
||||||
.start_position(&local_curve_geometry.path);
|
.of_vertex(second.start_vertex())
|
||||||
|
.unwrap()
|
||||||
|
.local_on(second.curve())
|
||||||
|
.unwrap()
|
||||||
|
.position;
|
||||||
|
|
||||||
|
local_curve_geometry
|
||||||
|
.path
|
||||||
|
.point_from_path_coords(point_curve)
|
||||||
|
};
|
||||||
|
|
||||||
let distance_between_positions = (end_pos_of_first_half_edge
|
let distance_between_positions = (end_pos_of_first_half_edge
|
||||||
- start_pos_of_second_half_edge)
|
- start_pos_of_second_half_edge)
|
||||||
|
Loading…
Reference in New Issue
Block a user