Skip to content

Commit

Permalink
Extend Shape::faces_along_ray to return a LineFaceHitPoint with more …
Browse files Browse the repository at this point in the history
…info (#147)

* extend Shape::faces_along_ray to return a struct LineFaceHitPoint with more info

* split doc comment

* rename stuff faces_along_ray to faces_along_line
  • Loading branch information
mkovaxx authored Nov 12, 2023
1 parent 05bad7f commit 0adabcb
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 13 deletions.
3 changes: 3 additions & 0 deletions crates/opencascade-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -940,6 +940,9 @@ pub mod ffi {
pub fn BRepIntCurveSurface_Inter_point(
intersector: &BRepIntCurveSurface_Inter,
) -> UniquePtr<gp_Pnt>;
pub fn U(self: &BRepIntCurveSurface_Inter) -> f64;
pub fn V(self: &BRepIntCurveSurface_Inter) -> f64;
pub fn W(self: &BRepIntCurveSurface_Inter) -> f64;

// BRepFeat
type BRepFeat_MakeCylindricalHole;
Expand Down
26 changes: 23 additions & 3 deletions crates/opencascade/src/primitives/shape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -542,12 +542,12 @@ impl Shape {
}

// TODO(bschwind) - Convert the return type to an iterator.
pub fn faces_along_ray(&self, ray_start: DVec3, ray_dir: DVec3) -> Vec<(Face, DVec3)> {
pub fn faces_along_line(&self, line_origin: DVec3, line_dir: DVec3) -> Vec<LineFaceHitPoint> {
let mut intersector = ffi::BRepIntCurveSurface_Inter_ctor();
let tolerance = 0.0001;
intersector.pin_mut().Init(
&self.inner,
&ffi::gp_Lin_ctor(&make_point(ray_start), &make_dir(ray_dir)),
&ffi::gp_Lin_ctor(&make_point(line_origin), &make_dir(line_dir)),
tolerance,
);

Expand All @@ -558,7 +558,13 @@ impl Shape {
let face = Face::from_face(&face);
let point = ffi::BRepIntCurveSurface_Inter_point(&intersector);

results.push((face, dvec3(point.X(), point.Y(), point.Z())));
results.push(LineFaceHitPoint {
face,
t: intersector.W(),
u: intersector.U(),
v: intersector.V(),
point: dvec3(point.X(), point.Y(), point.Z()),
});

intersector.pin_mut().Next();
}
Expand Down Expand Up @@ -605,3 +611,17 @@ impl Shape {
Self::from_shape(make_hole.pin_mut().Shape())
}
}

/// Information about a point where a line hits (i.e. intersects) a face
pub struct LineFaceHitPoint {
/// The face that is hit
pub face: Face,
/// The T parameter along the line
pub t: f64,
/// The U parameter on the face
pub u: f64,
/// The V parameter on the face
pub v: f64,
/// The intersection point
pub point: DVec3,
}
16 changes: 6 additions & 10 deletions examples/src/keycap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,16 +210,12 @@ pub fn shape() -> Shape {

// TODO(bschwind) - Abstract all this into a "extrude_to_next_face" function.
let origin = workplane.to_world_pos(dvec3(*x, *y, 0.0));
let mut faces = keycap.faces_along_ray(origin, workplane.normal());
faces.sort_by(|(_, a_point), (_, b_point)| {
let a_dist = (*a_point - origin).length();
let b_dist = (*b_point - origin).length();

a_dist.total_cmp(&b_dist)
});

let (face_target, _) = faces.get(0).expect("We should have a face to extrude to");
let post = circle.extrude_to_face(&keycap, face_target);
let faces = keycap.faces_along_line(origin, workplane.normal());
let nearest_hit = faces
.iter()
.min_by(|hit_a, hit_b| hit_a.t.partial_cmp(&hit_b.t).unwrap())
.expect("We should have a face to extrude to");
let post = circle.extrude_to_face(&keycap, &nearest_hit.face);

keycap = keycap.union(&post).into();
}
Expand Down

0 comments on commit 0adabcb

Please sign in to comment.