mirror of
https://github.com/hannobraun/Fornjot
synced 2025-03-10 07:02:36 +00:00
Merge pull request #2149 from hannobraun/vertices-indices
Add operation for creating shell from vertices and indices
This commit is contained in:
commit
8f25f3b621
7
Cargo.lock
generated
7
Cargo.lock
generated
@ -3513,6 +3513,13 @@ version = "0.9.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "vertices-indices"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"fj",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "walkdir"
|
name = "walkdir"
|
||||||
version = "2.4.0"
|
version = "2.4.0"
|
||||||
|
@ -15,6 +15,7 @@ members = [
|
|||||||
"models/spacer",
|
"models/spacer",
|
||||||
"models/split",
|
"models/split",
|
||||||
"models/star",
|
"models/star",
|
||||||
|
"models/vertices-indices",
|
||||||
|
|
||||||
"tools/autolib",
|
"tools/autolib",
|
||||||
"tools/automator",
|
"tools/automator",
|
||||||
|
@ -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
|
||||||
|
7
models/vertices-indices/Cargo.toml
Normal file
7
models/vertices-indices/Cargo.toml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[package]
|
||||||
|
name = "vertices-indices"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies.fj]
|
||||||
|
path = "../../crates/fj"
|
21
models/vertices-indices/src/lib.rs
Normal file
21
models/vertices-indices/src/lib.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
use fj::core::{
|
||||||
|
objects::{Shell, Solid},
|
||||||
|
operations::{
|
||||||
|
build::{BuildShell, BuildSolid},
|
||||||
|
insert::Insert,
|
||||||
|
update::UpdateSolid,
|
||||||
|
},
|
||||||
|
services::Services,
|
||||||
|
storage::Handle,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn model(services: &mut Services) -> Handle<Solid> {
|
||||||
|
Solid::empty()
|
||||||
|
.add_shells([Shell::from_vertices_and_indices(
|
||||||
|
[[0., 0., 0.], [1., 0., 0.], [0., 1., 0.], [0., 0., 1.]],
|
||||||
|
[[2, 1, 0], [0, 1, 3], [1, 2, 3], [2, 0, 3]],
|
||||||
|
services,
|
||||||
|
)
|
||||||
|
.insert(services)])
|
||||||
|
.insert(services)
|
||||||
|
}
|
8
models/vertices-indices/src/main.rs
Normal file
8
models/vertices-indices/src/main.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
use fj::{core::services::Services, handle_model};
|
||||||
|
|
||||||
|
fn main() -> fj::Result {
|
||||||
|
let mut services = Services::new();
|
||||||
|
let model = vertices_indices::model(&mut services);
|
||||||
|
handle_model(model, services)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user