mirror of
https://github.com/hannobraun/Fornjot
synced 2025-02-13 02:35:53 +00:00
Add BuildShell::from_vertices_and_indices
This commit is contained in:
parent
9d56ada45d
commit
caf6991d46
@ -1,13 +1,19 @@
|
|||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
use fj_interop::ext::ArrayExt;
|
||||||
use fj_math::Point;
|
use fj_math::Point;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
objects::{Face, Shell},
|
geometry::CurveBoundary,
|
||||||
|
objects::{Curve, Face, HalfEdge, Shell, Surface, Vertex},
|
||||||
operations::{
|
operations::{
|
||||||
build::{BuildFace, Polygon},
|
build::{BuildFace, BuildHalfEdge, BuildSurface, Polygon},
|
||||||
insert::{Insert, IsInserted, IsInsertedNo, IsInsertedYes},
|
insert::{Insert, IsInserted, IsInsertedNo, IsInsertedYes},
|
||||||
join::JoinCycle,
|
join::JoinCycle,
|
||||||
reverse::ReverseCurveCoordinateSystems,
|
reverse::ReverseCurveCoordinateSystems,
|
||||||
update::{UpdateCycle, UpdateFace, UpdateRegion},
|
update::{
|
||||||
|
UpdateCycle, UpdateFace, UpdateHalfEdge, UpdateRegion, UpdateShell,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
services::Services,
|
services::Services,
|
||||||
};
|
};
|
||||||
@ -23,6 +29,96 @@ pub trait BuildShell {
|
|||||||
Shell::new([])
|
Shell::new([])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Build a polyhedron by specifying its vertices and indices
|
||||||
|
fn from_vertices_and_indices(
|
||||||
|
vertices: impl IntoIterator<Item = impl Into<Point<3>>>,
|
||||||
|
indices: impl IntoIterator<Item = [usize; 3]>,
|
||||||
|
services: &mut Services,
|
||||||
|
) -> Shell {
|
||||||
|
let vertices = vertices
|
||||||
|
.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(index, position)| {
|
||||||
|
let vertex = Vertex::new().insert(services);
|
||||||
|
let position = position.into();
|
||||||
|
|
||||||
|
(index, (vertex, position))
|
||||||
|
})
|
||||||
|
.collect::<BTreeMap<_, _>>();
|
||||||
|
|
||||||
|
let mut curves = BTreeMap::new();
|
||||||
|
|
||||||
|
let faces = indices
|
||||||
|
.into_iter()
|
||||||
|
.map(|indices| {
|
||||||
|
let [(a, a_pos), (b, b_pos), (c, c_pos)] = indices
|
||||||
|
.map(|index| vertices.get(&index).expect("Invalid index"));
|
||||||
|
|
||||||
|
let (surface, _) = Surface::plane_from_points(
|
||||||
|
[a_pos, b_pos, c_pos].map(Clone::clone),
|
||||||
|
);
|
||||||
|
let surface = surface.insert(services);
|
||||||
|
|
||||||
|
let curves_and_boundaries =
|
||||||
|
[[a, b], [b, c], [c, a]].map(|vertices| {
|
||||||
|
let vertices = vertices.map(Clone::clone);
|
||||||
|
let vertices = CurveBoundary::<Vertex>::from(vertices);
|
||||||
|
|
||||||
|
curves
|
||||||
|
.get(&vertices.clone().reverse())
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
let curve = Curve::new().insert(services);
|
||||||
|
let boundary =
|
||||||
|
CurveBoundary::<Point<1>>::from([
|
||||||
|
[0.],
|
||||||
|
[1.],
|
||||||
|
]);
|
||||||
|
|
||||||
|
curves.insert(
|
||||||
|
vertices,
|
||||||
|
(curve.clone(), boundary),
|
||||||
|
);
|
||||||
|
|
||||||
|
(curve, boundary.reverse())
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
let half_edges = {
|
||||||
|
let vertices = [a, b, c].map(Clone::clone);
|
||||||
|
let [a, b, c] = [[0., 0.], [1., 0.], [0., 1.]];
|
||||||
|
vertices
|
||||||
|
.zip_ext([[a, b], [b, c], [c, a]])
|
||||||
|
.zip_ext(curves_and_boundaries)
|
||||||
|
.map(|((vertex, positions), (curve, boundary))| {
|
||||||
|
HalfEdge::line_segment(
|
||||||
|
positions,
|
||||||
|
Some(boundary.reverse().inner),
|
||||||
|
services,
|
||||||
|
)
|
||||||
|
.update_start_vertex(|_| vertex)
|
||||||
|
.update_curve(|_| curve)
|
||||||
|
.insert(services)
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
Face::unbound(surface, services)
|
||||||
|
.update_region(|region| {
|
||||||
|
region
|
||||||
|
.update_exterior(|cycle| {
|
||||||
|
cycle
|
||||||
|
.add_half_edges(half_edges)
|
||||||
|
.insert(services)
|
||||||
|
})
|
||||||
|
.insert(services)
|
||||||
|
})
|
||||||
|
.insert(services)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
Shell::empty().add_faces(faces)
|
||||||
|
}
|
||||||
|
|
||||||
/// Build a tetrahedron from the provided points
|
/// Build a tetrahedron from the provided points
|
||||||
///
|
///
|
||||||
/// Accepts 4 points, naturally. For the purposes of the following
|
/// Accepts 4 points, naturally. For the purposes of the following
|
||||||
|
Loading…
Reference in New Issue
Block a user