mirror of
https://github.com/hannobraun/Fornjot
synced 2025-09-07 09:56:46 +00:00
Merge pull request #2405 from hannobraun/geom
Define vertex geometry in more places
This commit is contained in:
commit
f4676a283f
@ -2,7 +2,7 @@ use fj_math::{Point, Scalar, Vector};
|
|||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
geometry::LocalVertexGeom,
|
geometry::{CurveBoundary, LocalVertexGeom},
|
||||||
operations::build::BuildHalfEdge,
|
operations::build::BuildHalfEdge,
|
||||||
storage::Handle,
|
storage::Handle,
|
||||||
topology::{Cycle, HalfEdge, Surface},
|
topology::{Cycle, HalfEdge, Surface},
|
||||||
@ -20,6 +20,38 @@ pub trait BuildCycle {
|
|||||||
Cycle::new([])
|
Cycle::new([])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// # Build a cycle from half-edges and associated curve boundaries
|
||||||
|
fn from_half_edges_and_boundaries<I>(
|
||||||
|
half_edges_and_boundaries: I,
|
||||||
|
core: &mut Core,
|
||||||
|
) -> Cycle
|
||||||
|
where
|
||||||
|
I: IntoIterator<Item = (Handle<HalfEdge>, CurveBoundary<Point<1>>)>,
|
||||||
|
I::IntoIter: Clone + ExactSizeIterator,
|
||||||
|
{
|
||||||
|
let half_edges = half_edges_and_boundaries
|
||||||
|
.into_iter()
|
||||||
|
.circular_tuple_windows()
|
||||||
|
.map(|((half_edge, boundary), (next_half_edge, _))| {
|
||||||
|
let [start, end] = boundary.inner;
|
||||||
|
|
||||||
|
core.layers.geometry.define_vertex(
|
||||||
|
half_edge.start_vertex().clone(),
|
||||||
|
half_edge.curve().clone(),
|
||||||
|
LocalVertexGeom { position: start },
|
||||||
|
);
|
||||||
|
core.layers.geometry.define_vertex(
|
||||||
|
next_half_edge.start_vertex().clone(),
|
||||||
|
half_edge.curve().clone(),
|
||||||
|
LocalVertexGeom { position: end },
|
||||||
|
);
|
||||||
|
|
||||||
|
half_edge
|
||||||
|
});
|
||||||
|
|
||||||
|
Cycle::new(half_edges)
|
||||||
|
}
|
||||||
|
|
||||||
/// # Build a circle
|
/// # Build a circle
|
||||||
///
|
///
|
||||||
/// This circle is built out of 4 distinct arcs.
|
/// This circle is built out of 4 distinct arcs.
|
||||||
@ -55,14 +87,14 @@ pub trait BuildCycle {
|
|||||||
|
|
||||||
let angle = Scalar::TAU / 4.;
|
let angle = Scalar::TAU / 4.;
|
||||||
|
|
||||||
let half_edges =
|
let half_edges_and_boundaries = [[a, b], [b, c], [c, d], [d, a]]
|
||||||
[[a, b], [b, c], [c, d], [d, a]]
|
.into_iter()
|
||||||
.into_iter()
|
.map(|[start, end]| {
|
||||||
.map(|[start, end]| {
|
HalfEdge::arc(start, end, angle, surface.clone(), core)
|
||||||
HalfEdge::arc(start, end, angle, surface.clone(), core)
|
})
|
||||||
});
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
Cycle::new(half_edges)
|
Self::from_half_edges_and_boundaries(half_edges_and_boundaries, core)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Build a polygon
|
/// Build a polygon
|
||||||
@ -84,27 +116,8 @@ pub trait BuildCycle {
|
|||||||
HalfEdge::line_segment([start, end], surface.clone(), core)
|
HalfEdge::line_segment([start, end], surface.clone(), core)
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let half_edges = half_edges_and_boundaries
|
|
||||||
.into_iter()
|
|
||||||
.circular_tuple_windows()
|
|
||||||
.map(|((half_edge, boundary), (next_half_edge, _))| {
|
|
||||||
let [start, end] = boundary.inner;
|
|
||||||
|
|
||||||
core.layers.geometry.define_vertex(
|
Self::from_half_edges_and_boundaries(half_edges_and_boundaries, core)
|
||||||
half_edge.start_vertex().clone(),
|
|
||||||
half_edge.curve().clone(),
|
|
||||||
LocalVertexGeom { position: start },
|
|
||||||
);
|
|
||||||
core.layers.geometry.define_vertex(
|
|
||||||
next_half_edge.start_vertex().clone(),
|
|
||||||
half_edge.curve().clone(),
|
|
||||||
LocalVertexGeom { position: end },
|
|
||||||
);
|
|
||||||
|
|
||||||
half_edge
|
|
||||||
});
|
|
||||||
|
|
||||||
Cycle::new(half_edges)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ pub trait BuildHalfEdge {
|
|||||||
angle_rad: impl Into<Scalar>,
|
angle_rad: impl Into<Scalar>,
|
||||||
surface: Handle<Surface>,
|
surface: Handle<Surface>,
|
||||||
core: &mut Core,
|
core: &mut Core,
|
||||||
) -> Handle<HalfEdge> {
|
) -> (Handle<HalfEdge>, CurveBoundary<Point<1>>) {
|
||||||
let angle_rad = angle_rad.into();
|
let angle_rad = angle_rad.into();
|
||||||
if angle_rad <= -Scalar::TAU || angle_rad >= Scalar::TAU {
|
if angle_rad <= -Scalar::TAU || angle_rad >= Scalar::TAU {
|
||||||
panic!("arc angle must be in the range (-2pi, 2pi) radians");
|
panic!("arc angle must be in the range (-2pi, 2pi) radians");
|
||||||
@ -60,8 +60,10 @@ pub trait BuildHalfEdge {
|
|||||||
|
|
||||||
let path =
|
let path =
|
||||||
SurfacePath::circle_from_center_and_radius(arc.center, arc.radius);
|
SurfacePath::circle_from_center_and_radius(arc.center, arc.radius);
|
||||||
let boundary =
|
let boundary = CurveBoundary {
|
||||||
[arc.start_angle, arc.end_angle].map(|coord| Point::from([coord]));
|
inner: [arc.start_angle, arc.end_angle]
|
||||||
|
.map(|coord| Point::from([coord])),
|
||||||
|
};
|
||||||
|
|
||||||
let half_edge = HalfEdge::unjoined(core).insert(core);
|
let half_edge = HalfEdge::unjoined(core).insert(core);
|
||||||
|
|
||||||
@ -70,14 +72,11 @@ pub trait BuildHalfEdge {
|
|||||||
surface,
|
surface,
|
||||||
LocalCurveGeom { path },
|
LocalCurveGeom { path },
|
||||||
);
|
);
|
||||||
core.layers.geometry.define_half_edge(
|
core.layers
|
||||||
half_edge.clone(),
|
.geometry
|
||||||
HalfEdgeGeom {
|
.define_half_edge(half_edge.clone(), HalfEdgeGeom { boundary });
|
||||||
boundary: boundary.into(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
half_edge
|
(half_edge, boundary)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a line segment
|
/// Create a line segment
|
||||||
|
@ -182,8 +182,15 @@ pub trait BuildShell {
|
|||||||
cycle
|
cycle
|
||||||
.update_half_edge(
|
.update_half_edge(
|
||||||
cycle.half_edges().nth_circular(0),
|
cycle.half_edges().nth_circular(0),
|
||||||
|edge, core| {
|
|half_edge, core| {
|
||||||
[(edge, bad.face.surface())
|
[(
|
||||||
|
half_edge,
|
||||||
|
cycle
|
||||||
|
.half_edges()
|
||||||
|
.nth_circular(1)
|
||||||
|
.start_vertex(),
|
||||||
|
bad.face.surface(),
|
||||||
|
)
|
||||||
.reverse_curve_coordinate_systems(
|
.reverse_curve_coordinate_systems(
|
||||||
core,
|
core,
|
||||||
)]
|
)]
|
||||||
@ -204,111 +211,154 @@ pub trait BuildShell {
|
|||||||
core,
|
core,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
let dac =
|
let dac = {
|
||||||
{
|
let dac = Face::triangle([d, a, c], core);
|
||||||
let dac = Face::triangle([d, a, c], core);
|
dac.update_region(
|
||||||
dac.update_region(
|
|region, core| {
|
||||||
|region, core| {
|
region.update_exterior(
|
||||||
region.update_exterior(
|
|cycle, core| {
|
||||||
|cycle, core| {
|
cycle
|
||||||
cycle
|
.update_half_edge(
|
||||||
.update_half_edge(
|
cycle.half_edges().nth_circular(1),
|
||||||
cycle.half_edges().nth_circular(1),
|
|half_edge, core| {
|
||||||
|edge, core| {
|
[(
|
||||||
[(edge, dac.face.surface())
|
half_edge,
|
||||||
.reverse_curve_coordinate_systems(core)]
|
cycle
|
||||||
},
|
.half_edges()
|
||||||
core,
|
.nth_circular(2)
|
||||||
)
|
.start_vertex(),
|
||||||
.join_to(
|
dac.face.surface(),
|
||||||
abc.face.region().exterior(),
|
)
|
||||||
1..=1,
|
.reverse_curve_coordinate_systems(
|
||||||
2..=2,
|
core,
|
||||||
dac.face.surface().clone(),
|
)]
|
||||||
core,
|
},
|
||||||
)
|
core,
|
||||||
.update_half_edge(
|
)
|
||||||
cycle.half_edges().nth_circular(0),
|
.join_to(
|
||||||
|edge, core| {
|
abc.face.region().exterior(),
|
||||||
[(edge, dac.face.surface())
|
1..=1,
|
||||||
.reverse_curve_coordinate_systems(core)]
|
2..=2,
|
||||||
},
|
dac.face.surface().clone(),
|
||||||
core,
|
core,
|
||||||
)
|
)
|
||||||
.join_to(
|
.update_half_edge(
|
||||||
bad.face.region().exterior(),
|
cycle.half_edges().nth_circular(0),
|
||||||
0..=0,
|
|half_edge, core| {
|
||||||
1..=1,
|
[(
|
||||||
dac.face.surface().clone(),
|
half_edge,
|
||||||
core,
|
cycle
|
||||||
)
|
.half_edges()
|
||||||
},
|
.nth_circular(1)
|
||||||
core,
|
.start_vertex(),
|
||||||
)
|
dac.face.surface(),
|
||||||
},
|
)
|
||||||
core,
|
.reverse_curve_coordinate_systems(
|
||||||
)
|
core,
|
||||||
};
|
)]
|
||||||
let cbd =
|
},
|
||||||
{
|
core,
|
||||||
let cbd = Face::triangle([c, b, d], core);
|
)
|
||||||
cbd.update_region(
|
.join_to(
|
||||||
|region, core| {
|
bad.face.region().exterior(),
|
||||||
region.update_exterior(
|
0..=0,
|
||||||
|cycle, core| {
|
1..=1,
|
||||||
cycle
|
dac.face.surface().clone(),
|
||||||
.update_half_edge(
|
core,
|
||||||
cycle.half_edges().nth_circular(0),
|
)
|
||||||
|edge, core| {
|
},
|
||||||
[(edge, cbd.face.surface())
|
core,
|
||||||
.reverse_curve_coordinate_systems(core)]
|
)
|
||||||
},
|
},
|
||||||
core,
|
core,
|
||||||
)
|
)
|
||||||
.update_half_edge(
|
};
|
||||||
cycle.half_edges().nth_circular(1),
|
let cbd = {
|
||||||
|edge, core| {
|
let cbd = Face::triangle([c, b, d], core);
|
||||||
[(edge, cbd.face.surface())
|
cbd.update_region(
|
||||||
.reverse_curve_coordinate_systems(core)]
|
|region, core| {
|
||||||
},
|
region.update_exterior(
|
||||||
core,
|
|cycle, core| {
|
||||||
)
|
cycle
|
||||||
.update_half_edge(
|
.update_half_edge(
|
||||||
cycle.half_edges().nth_circular(2),
|
cycle.half_edges().nth_circular(0),
|
||||||
|edge, core| {
|
|half_edge, core| {
|
||||||
[(edge, cbd.face.surface())
|
[(
|
||||||
.reverse_curve_coordinate_systems(core)]
|
half_edge,
|
||||||
},
|
cycle
|
||||||
core,
|
.half_edges()
|
||||||
)
|
.nth_circular(1)
|
||||||
.join_to(
|
.start_vertex(),
|
||||||
abc.face.region().exterior(),
|
cbd.face.surface(),
|
||||||
0..=0,
|
)
|
||||||
1..=1,
|
.reverse_curve_coordinate_systems(
|
||||||
cbd.face.surface().clone(),
|
core,
|
||||||
core,
|
)]
|
||||||
)
|
},
|
||||||
.join_to(
|
core,
|
||||||
bad.face.region().exterior(),
|
)
|
||||||
1..=1,
|
.update_half_edge(
|
||||||
2..=2,
|
cycle.half_edges().nth_circular(1),
|
||||||
cbd.face.surface().clone(),
|
|half_edge, core| {
|
||||||
core,
|
[(
|
||||||
)
|
half_edge,
|
||||||
.join_to(
|
cycle
|
||||||
dac.face.region().exterior(),
|
.half_edges()
|
||||||
2..=2,
|
.nth_circular(2)
|
||||||
2..=2,
|
.start_vertex(),
|
||||||
cbd.face.surface().clone(),
|
cbd.face.surface(),
|
||||||
core,
|
)
|
||||||
)
|
.reverse_curve_coordinate_systems(
|
||||||
},
|
core,
|
||||||
core,
|
)]
|
||||||
)
|
},
|
||||||
},
|
core,
|
||||||
core,
|
)
|
||||||
)
|
.update_half_edge(
|
||||||
};
|
cycle.half_edges().nth_circular(2),
|
||||||
|
|half_edge, core| {
|
||||||
|
[(
|
||||||
|
half_edge,
|
||||||
|
cycle
|
||||||
|
.half_edges()
|
||||||
|
.nth_circular(3)
|
||||||
|
.start_vertex(),
|
||||||
|
cbd.face.surface(),
|
||||||
|
)
|
||||||
|
.reverse_curve_coordinate_systems(
|
||||||
|
core,
|
||||||
|
)]
|
||||||
|
},
|
||||||
|
core,
|
||||||
|
)
|
||||||
|
.join_to(
|
||||||
|
abc.face.region().exterior(),
|
||||||
|
0..=0,
|
||||||
|
1..=1,
|
||||||
|
cbd.face.surface().clone(),
|
||||||
|
core,
|
||||||
|
)
|
||||||
|
.join_to(
|
||||||
|
bad.face.region().exterior(),
|
||||||
|
1..=1,
|
||||||
|
2..=2,
|
||||||
|
cbd.face.surface().clone(),
|
||||||
|
core,
|
||||||
|
)
|
||||||
|
.join_to(
|
||||||
|
dac.face.region().exterior(),
|
||||||
|
2..=2,
|
||||||
|
2..=2,
|
||||||
|
cbd.face.surface().clone(),
|
||||||
|
core,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
core,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
core,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
let triangles =
|
let triangles =
|
||||||
[abc, bad, dac, cbd].map(|triangle| triangle.insert(core));
|
[abc, bad, dac, cbd].map(|triangle| triangle.insert(core));
|
||||||
|
@ -154,11 +154,16 @@ impl JoinCycle for Cycle {
|
|||||||
range.zip(range_other).fold(
|
range.zip(range_other).fold(
|
||||||
self.clone(),
|
self.clone(),
|
||||||
|cycle, (index, index_other)| {
|
|cycle, (index, index_other)| {
|
||||||
let edge_other = other.half_edges().nth_circular(index_other);
|
let half_edge = self.half_edges().nth_circular(index);
|
||||||
|
let half_edge_next = self.half_edges().nth_circular(index + 1);
|
||||||
|
let half_edge_other =
|
||||||
|
other.half_edges().nth_circular(index_other);
|
||||||
|
let half_edge_other_next =
|
||||||
|
other.half_edges().nth_circular(index_other + 1);
|
||||||
|
|
||||||
cycle
|
cycle
|
||||||
.update_half_edge(
|
.update_half_edge(
|
||||||
self.half_edges().nth_circular(index),
|
half_edge,
|
||||||
|half_edge, core| {
|
|half_edge, core| {
|
||||||
// The curve of the other half-edge we're joining
|
// The curve of the other half-edge we're joining
|
||||||
// this one to already has a curve geometry,
|
// this one to already has a curve geometry,
|
||||||
@ -178,22 +183,78 @@ impl JoinCycle for Cycle {
|
|||||||
});
|
});
|
||||||
if let Some(curve_geom) = curve_geom {
|
if let Some(curve_geom) = curve_geom {
|
||||||
core.layers.geometry.define_curve(
|
core.layers.geometry.define_curve(
|
||||||
edge_other.curve().clone(),
|
half_edge_other.curve().clone(),
|
||||||
surface_self.clone(),
|
surface_self.clone(),
|
||||||
curve_geom.clone(),
|
curve_geom.clone(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The same goes for vertices. We have to move over
|
||||||
|
// any local definitions we have to the other
|
||||||
|
// vertices.
|
||||||
|
let vertex_geom_prev_end = core
|
||||||
|
.layers
|
||||||
|
.geometry
|
||||||
|
.of_vertex(half_edge.start_vertex())
|
||||||
|
.and_then(|vertex_geom| {
|
||||||
|
vertex_geom.local_on(
|
||||||
|
self.half_edges()
|
||||||
|
.before(half_edge)
|
||||||
|
.unwrap()
|
||||||
|
.curve(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.cloned();
|
||||||
|
let vertex_geom_start = core
|
||||||
|
.layers
|
||||||
|
.geometry
|
||||||
|
.of_vertex(half_edge.start_vertex())
|
||||||
|
.and_then(|vertex_geom| {
|
||||||
|
vertex_geom.local_on(half_edge.curve())
|
||||||
|
})
|
||||||
|
.cloned();
|
||||||
|
let vertex_geom_end = core
|
||||||
|
.layers
|
||||||
|
.geometry
|
||||||
|
.of_vertex(half_edge_next.start_vertex())
|
||||||
|
.and_then(|vertex_geom| {
|
||||||
|
vertex_geom.local_on(half_edge.curve())
|
||||||
|
})
|
||||||
|
.cloned();
|
||||||
|
if let Some(vertex_geom) = vertex_geom_prev_end {
|
||||||
|
core.layers.geometry.define_vertex(
|
||||||
|
half_edge_other_next.start_vertex().clone(),
|
||||||
|
self.half_edges()
|
||||||
|
.before(half_edge)
|
||||||
|
.unwrap()
|
||||||
|
.curve()
|
||||||
|
.clone(),
|
||||||
|
vertex_geom,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if let Some(vertex_geom_start) = vertex_geom_start {
|
||||||
|
core.layers.geometry.define_vertex(
|
||||||
|
half_edge_other_next.start_vertex().clone(),
|
||||||
|
half_edge_other.curve().clone(),
|
||||||
|
vertex_geom_start,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if let Some(vertex_geom_end) = vertex_geom_end {
|
||||||
|
core.layers.geometry.define_vertex(
|
||||||
|
half_edge_other.start_vertex().clone(),
|
||||||
|
half_edge_other.curve().clone(),
|
||||||
|
vertex_geom_end,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
[half_edge
|
[half_edge
|
||||||
.update_curve(
|
.update_curve(
|
||||||
|_, _| edge_other.curve().clone(),
|
|_, _| half_edge_other.curve().clone(),
|
||||||
core,
|
core,
|
||||||
)
|
)
|
||||||
.update_start_vertex(
|
.update_start_vertex(
|
||||||
|_, _| {
|
|_, _| {
|
||||||
other
|
half_edge_other_next
|
||||||
.half_edges()
|
|
||||||
.nth_circular(index_other + 1)
|
|
||||||
.start_vertex()
|
.start_vertex()
|
||||||
.clone()
|
.clone()
|
||||||
},
|
},
|
||||||
@ -211,11 +272,31 @@ impl JoinCycle for Cycle {
|
|||||||
core,
|
core,
|
||||||
)
|
)
|
||||||
.update_half_edge(
|
.update_half_edge(
|
||||||
self.half_edges().nth_circular(index + 1),
|
half_edge_next,
|
||||||
|half_edge, core| {
|
|half_edge, core| {
|
||||||
|
// And we need to move over the geometry for this
|
||||||
|
// vertex too.
|
||||||
|
let vertex_geom = core
|
||||||
|
.layers
|
||||||
|
.geometry
|
||||||
|
.of_vertex(half_edge_next.start_vertex())
|
||||||
|
.and_then(|vertex_geom| {
|
||||||
|
vertex_geom.local_on(half_edge_next.curve())
|
||||||
|
})
|
||||||
|
.cloned();
|
||||||
|
if let Some(vertex_geom) = vertex_geom {
|
||||||
|
core.layers.geometry.define_vertex(
|
||||||
|
half_edge_other.start_vertex().clone(),
|
||||||
|
half_edge.curve().clone(),
|
||||||
|
vertex_geom,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
[half_edge
|
[half_edge
|
||||||
.update_start_vertex(
|
.update_start_vertex(
|
||||||
|_, _| edge_other.start_vertex().clone(),
|
|_, _| {
|
||||||
|
half_edge_other.start_vertex().clone()
|
||||||
|
},
|
||||||
core,
|
core,
|
||||||
)
|
)
|
||||||
.insert(core)
|
.insert(core)
|
||||||
|
@ -14,8 +14,9 @@ impl Reverse for Cycle {
|
|||||||
.half_edges()
|
.half_edges()
|
||||||
.pairs()
|
.pairs()
|
||||||
.map(|(current, next)| {
|
.map(|(current, next)| {
|
||||||
let mut geometry = *core.layers.geometry.of_half_edge(current);
|
let mut half_edge_geom =
|
||||||
geometry.boundary = geometry.boundary.reverse();
|
*core.layers.geometry.of_half_edge(current);
|
||||||
|
half_edge_geom.boundary = half_edge_geom.boundary.reverse();
|
||||||
|
|
||||||
HalfEdge::new(
|
HalfEdge::new(
|
||||||
current.curve().clone(),
|
current.curve().clone(),
|
||||||
@ -23,7 +24,7 @@ impl Reverse for Cycle {
|
|||||||
)
|
)
|
||||||
.insert(core)
|
.insert(core)
|
||||||
.derive_from(current, core)
|
.derive_from(current, core)
|
||||||
.set_geometry(geometry, &mut core.layers.geometry)
|
.set_geometry(half_edge_geom, &mut core.layers.geometry)
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
@ -1,20 +1,39 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
operations::{derive::DeriveFrom, insert::Insert},
|
operations::{derive::DeriveFrom, insert::Insert},
|
||||||
storage::Handle,
|
storage::Handle,
|
||||||
topology::{HalfEdge, Surface},
|
topology::{HalfEdge, Surface, Vertex},
|
||||||
Core,
|
Core,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::ReverseCurveCoordinateSystems;
|
use super::ReverseCurveCoordinateSystems;
|
||||||
|
|
||||||
impl ReverseCurveCoordinateSystems for (&Handle<HalfEdge>, &Handle<Surface>) {
|
impl ReverseCurveCoordinateSystems
|
||||||
|
for (&Handle<HalfEdge>, &Handle<Vertex>, &Handle<Surface>)
|
||||||
|
{
|
||||||
type Reversed = Handle<HalfEdge>;
|
type Reversed = Handle<HalfEdge>;
|
||||||
|
|
||||||
fn reverse_curve_coordinate_systems(
|
fn reverse_curve_coordinate_systems(
|
||||||
self,
|
self,
|
||||||
core: &mut Core,
|
core: &mut Core,
|
||||||
) -> Self::Reversed {
|
) -> Self::Reversed {
|
||||||
let (half_edge, surface) = self;
|
let (half_edge, end_vertex, surface) = self;
|
||||||
|
|
||||||
|
let vertex_geom_start = core
|
||||||
|
.layers
|
||||||
|
.geometry
|
||||||
|
.of_vertex(half_edge.start_vertex())
|
||||||
|
.unwrap()
|
||||||
|
.local_on(half_edge.curve())
|
||||||
|
.unwrap()
|
||||||
|
.clone();
|
||||||
|
let vertex_geom_end = core
|
||||||
|
.layers
|
||||||
|
.geometry
|
||||||
|
.of_vertex(end_vertex)
|
||||||
|
.unwrap()
|
||||||
|
.local_on(half_edge.curve())
|
||||||
|
.unwrap()
|
||||||
|
.clone();
|
||||||
|
|
||||||
let mut half_edge_geom = *core.layers.geometry.of_half_edge(half_edge);
|
let mut half_edge_geom = *core.layers.geometry.of_half_edge(half_edge);
|
||||||
half_edge_geom.boundary = half_edge_geom.boundary.reverse();
|
half_edge_geom.boundary = half_edge_geom.boundary.reverse();
|
||||||
@ -26,6 +45,17 @@ impl ReverseCurveCoordinateSystems for (&Handle<HalfEdge>, &Handle<Surface>) {
|
|||||||
.insert(core)
|
.insert(core)
|
||||||
.derive_from(half_edge, core);
|
.derive_from(half_edge, core);
|
||||||
|
|
||||||
|
core.layers.geometry.define_vertex(
|
||||||
|
half_edge.start_vertex().clone(),
|
||||||
|
half_edge.curve().clone(),
|
||||||
|
vertex_geom_end,
|
||||||
|
);
|
||||||
|
core.layers.geometry.define_vertex(
|
||||||
|
end_vertex.clone(),
|
||||||
|
half_edge.curve().clone(),
|
||||||
|
vertex_geom_start,
|
||||||
|
);
|
||||||
|
|
||||||
core.layers
|
core.layers
|
||||||
.geometry
|
.geometry
|
||||||
.define_half_edge(half_edge.clone(), half_edge_geom);
|
.define_half_edge(half_edge.clone(), half_edge_geom);
|
||||||
|
@ -266,6 +266,37 @@ mod tests {
|
|||||||
&mut core.layers.geometry,
|
&mut core.layers.geometry,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let start_vertex =
|
||||||
|
half_edge.start_vertex();
|
||||||
|
let end_vertex = cycle
|
||||||
|
.half_edges()
|
||||||
|
.after(half_edge)
|
||||||
|
.unwrap()
|
||||||
|
.start_vertex();
|
||||||
|
|
||||||
|
core.layers.geometry.define_vertex(
|
||||||
|
start_vertex.clone(),
|
||||||
|
curve.clone(),
|
||||||
|
core.layers
|
||||||
|
.geometry
|
||||||
|
.of_vertex(start_vertex)
|
||||||
|
.unwrap()
|
||||||
|
.local_on(half_edge.curve())
|
||||||
|
.unwrap()
|
||||||
|
.clone(),
|
||||||
|
);
|
||||||
|
core.layers.geometry.define_vertex(
|
||||||
|
end_vertex.clone(),
|
||||||
|
curve.clone(),
|
||||||
|
core.layers
|
||||||
|
.geometry
|
||||||
|
.of_vertex(end_vertex)
|
||||||
|
.unwrap()
|
||||||
|
.local_on(half_edge.curve())
|
||||||
|
.unwrap()
|
||||||
|
.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
[half_edge
|
[half_edge
|
||||||
.update_curve(|_, _| curve, core)
|
.update_curve(|_, _| curve, core)
|
||||||
.insert(core)
|
.insert(core)
|
||||||
|
@ -142,6 +142,7 @@ fn check_cycle<'r>(
|
|||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
geometry::LocalVertexGeom,
|
||||||
operations::{
|
operations::{
|
||||||
build::{BuildFace, BuildHalfEdge},
|
build::{BuildFace, BuildHalfEdge},
|
||||||
update::{UpdateCycle, UpdateFace, UpdateRegion},
|
update::{UpdateCycle, UpdateFace, UpdateRegion},
|
||||||
@ -178,12 +179,47 @@ mod tests {
|
|||||||
cycle.update_half_edge(
|
cycle.update_half_edge(
|
||||||
cycle.half_edges().first(),
|
cycle.half_edges().first(),
|
||||||
|_, core| {
|
|_, core| {
|
||||||
[HalfEdge::line_segment(
|
let (half_edge, boundary) =
|
||||||
[[0., 0.], [2., 0.]],
|
HalfEdge::line_segment(
|
||||||
surface,
|
[[0., 0.], [2., 0.]],
|
||||||
core,
|
surface,
|
||||||
)
|
core,
|
||||||
.0]
|
);
|
||||||
|
|
||||||
|
let half_edge_prev =
|
||||||
|
cycle.half_edges().nth(2).unwrap();
|
||||||
|
let half_edge_next = cycle
|
||||||
|
.half_edges()
|
||||||
|
.nth(1)
|
||||||
|
.unwrap()
|
||||||
|
.start_vertex()
|
||||||
|
.clone();
|
||||||
|
|
||||||
|
core.layers.geometry.define_vertex(
|
||||||
|
half_edge.start_vertex().clone(),
|
||||||
|
half_edge_prev.curve().clone(),
|
||||||
|
core.layers
|
||||||
|
.geometry
|
||||||
|
.of_vertex(
|
||||||
|
cycle
|
||||||
|
.half_edges()
|
||||||
|
.first()
|
||||||
|
.start_vertex(),
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.local_on(half_edge_prev.curve())
|
||||||
|
.unwrap()
|
||||||
|
.clone(),
|
||||||
|
);
|
||||||
|
core.layers.geometry.define_vertex(
|
||||||
|
half_edge_next,
|
||||||
|
half_edge.curve().clone(),
|
||||||
|
LocalVertexGeom {
|
||||||
|
position: boundary.inner[1],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
[half_edge]
|
||||||
},
|
},
|
||||||
core,
|
core,
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user