Skip to content

Commit

Permalink
Merge pull request #1778 from hannobraun/operations
Browse files Browse the repository at this point in the history
Correctly join triangles in `BuildShell::tetrahedron`
  • Loading branch information
hannobraun authored Apr 21, 2023
2 parents a6c8e10 + 9769fc2 commit 2af2116
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 44 deletions.
45 changes: 22 additions & 23 deletions crates/fj-kernel/src/operations/build/face.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use fj_interop::ext::ArrayExt;
use fj_math::Point;

use crate::{
objects::{Cycle, Face, GlobalEdge, HalfEdge, Objects, Surface},
operations::{Insert, UpdateHalfEdge},
objects::{Cycle, Face, HalfEdge, Objects, Surface, Vertex},
operations::Insert,
services::Service,
storage::Handle,
};
Expand All @@ -15,39 +15,35 @@ pub trait BuildFace {
/// Build a triangle
fn triangle(
points: [impl Into<Point<3>>; 3],
edges: [Option<Handle<GlobalEdge>>; 3],
objects: &mut Service<Objects>,
) -> Triangle {
let [a, b, c] = points.map(Into::into);

let surface = Surface::plane_from_points([a, b, c]).insert(objects);
let (exterior, edges) = {
let half_edges = [[a, b], [b, c], [c, a]].zip_ext(edges).map(
|(points, global_form)| {
let mut half_edge =
HalfEdge::line_segment_from_global_points(
points, &surface, None, objects,
);
let (exterior, edges, vertices) = {
let half_edges = [[a, b], [b, c], [c, a]].map(|points| {
let half_edge = HalfEdge::line_segment_from_global_points(
points, &surface, None, objects,
);

if let Some(global_form) = global_form {
half_edge = half_edge.replace_global_form(global_form);
}

half_edge.insert(objects)
},
);
half_edge.insert(objects)
});
let vertices = half_edges
.each_ref_ext()
.map(|half_edge| half_edge.start_vertex().clone());

let cycle = Cycle::new(half_edges.clone()).insert(objects);

let global_edges =
half_edges.map(|half_edge| half_edge.global_form().clone());

(cycle, global_edges)
(cycle, half_edges, vertices)
};

let face = Face::new(surface, exterior, [], None);

Triangle { face, edges }
Triangle {
face,
edges,
vertices,
}
}
}

Expand All @@ -61,5 +57,8 @@ pub struct Triangle {
pub face: Face,

/// The edges of the triangle
pub edges: [Handle<GlobalEdge>; 3],
pub edges: [Handle<HalfEdge>; 3],

/// The vertices of the triangle
pub vertices: [Handle<Vertex>; 3],
}
100 changes: 79 additions & 21 deletions crates/fj-kernel/src/operations/build/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use fj_math::Point;

use crate::{
objects::{Face, Objects, Shell},
operations::Insert,
operations::{Insert, UpdateCycle, UpdateFace, UpdateHalfEdge},
services::Service,
storage::Handle,
};
Expand Down Expand Up @@ -35,33 +35,91 @@ pub trait BuildShell {
) -> Tetrahedron {
let [a, b, c, d] = points.map(Into::into);

let Triangle {
let [Triangle {
face: face_abc,
edges: [ab, bc, ca],
} = Face::triangle([a, b, c], [None, None, None], objects);
let Triangle {
vertices: [a, b, c],
}, Triangle {
face: face_bad,
edges: [_, ad, db],
} = Face::triangle([b, a, d], [Some(ab), None, None], objects);
let Triangle {
edges: [ba, ad, db],
vertices: [_, _, d],
}, Triangle {
face: face_dac,
edges: [_, _, cd],
} = Face::triangle([d, a, c], [Some(ad), Some(ca), None], objects);
let Triangle { face: face_cbd, .. } =
Face::triangle([c, b, d], [Some(bc), Some(db), Some(cd)], objects);
edges: [da, ac, cd],
..
}, Triangle {
face: face_cbd,
edges: [cb, bd, dc],
..
}] = [
Face::triangle([a, b, c], objects),
Face::triangle([b, a, d], objects),
Face::triangle([d, a, c], objects),
Face::triangle([c, b, d], objects),
];

let face_bad = face_bad.update_exterior(|cycle| {
let ba_joined = ba
.replace_start_vertex(b.clone())
.replace_global_form(ab.global_form().clone())
.insert(objects);
let ad_joined = ad.replace_start_vertex(a.clone()).insert(objects);

cycle
.replace_half_edge(&ba, ba_joined)
.replace_half_edge(&ad, ad_joined)
.insert(objects)
});
let face_dac = face_dac.update_exterior(|cycle| {
let da_joined = da
.replace_start_vertex(d.clone())
.replace_global_form(ad.global_form().clone())
.insert(objects);
let ac_joined = ac
.replace_start_vertex(a)
.replace_global_form(ca.global_form().clone())
.insert(objects);
let cd_joined = cd.replace_start_vertex(c.clone()).insert(objects);

cycle
.replace_half_edge(&da, da_joined)
.replace_half_edge(&ac, ac_joined)
.replace_half_edge(&cd, cd_joined)
.insert(objects)
});
let face_cbd = face_cbd.update_exterior(|cycle| {
let cb_joined = cb
.replace_start_vertex(c)
.replace_global_form(bc.global_form().clone())
.insert(objects);
let bd_joined = bd
.replace_start_vertex(b)
.replace_global_form(db.global_form().clone())
.insert(objects);
let dc_joined = dc
.replace_start_vertex(d)
.replace_global_form(cd.global_form().clone())
.insert(objects);

cycle
.replace_half_edge(&cb, cb_joined)
.replace_half_edge(&bd, bd_joined)
.replace_half_edge(&dc, dc_joined)
.insert(objects)
});

let faces = [face_abc, face_bad, face_dac, face_cbd]
.map(|face| face.insert(objects));
let shell = Shell::new(faces.clone());

let [face_abc, face_abd, face_cad, face_bcd] = faces;
let [face_abc, face_bad, face_dac, face_cbd] = faces;

Tetrahedron {
shell,
face_abc,
face_abd,
face_cad,
face_bcd,
face_bad,
face_dac,
face_cbd,
}
}
}
Expand All @@ -82,12 +140,12 @@ pub struct Tetrahedron {
/// The face formed by the points `a`, `b`, and `c`.
pub face_abc: Handle<Face>,

/// The face formed by the points `a`, `b`, and `d`.
pub face_abd: Handle<Face>,
/// The face formed by the points `b`, `a`, and `d`.
pub face_bad: Handle<Face>,

/// The face formed by the points `c`, `a`, and `d`.
pub face_cad: Handle<Face>,
/// The face formed by the points `d`, `a`, and `c`.
pub face_dac: Handle<Face>,

/// The face formed by the points `b`, `c`, and `d`.
pub face_bcd: Handle<Face>,
/// The face formed by the points `c`, `b`, and `d`.
pub face_cbd: Handle<Face>,
}

0 comments on commit 2af2116

Please sign in to comment.