Skip to content

Commit

Permalink
Sweep Faces and Wires along a path (#155)
Browse files Browse the repository at this point in the history
* Start binding to BRepOffsetAPI_MakePipeShell

* get wire sweep working

* use the simpler MakePipe instead of MakePipeShell

* remove unnecessary include

* fix clippy warnings

* clang format

* Update crates/opencascade/src/primitives/wire.rs

Co-authored-by: Brian Schwind <[email protected]>

---------

Co-authored-by: Brian Schwind <[email protected]>
  • Loading branch information
mkovaxx and bschwind authored Nov 26, 2023
1 parent 2eadab5 commit edf0924
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 0 deletions.
1 change: 1 addition & 0 deletions crates/opencascade-sys/include/wrapper.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <BRepLib_ToolTriangulatedShape.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
#include <BRepOffsetAPI_MakeOffset.hxx>
#include <BRepOffsetAPI_MakePipe.hxx>
#include <BRepOffsetAPI_MakeThickSolid.hxx>
#include <BRepOffsetAPI_ThruSections.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
Expand Down
11 changes: 11 additions & 0 deletions crates/opencascade-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,17 @@ pub mod ffi {
);
pub fn IsDone(self: &BRepOffsetAPI_MakeThickSolid) -> bool;

// Sweeps
type BRepOffsetAPI_MakePipe;

#[cxx_name = "construct_unique"]
pub fn BRepOffsetAPI_MakePipe_ctor(
spine: &TopoDS_Wire,
profile: &TopoDS_Shape,
) -> UniquePtr<BRepOffsetAPI_MakePipe>;

pub fn Shape(self: Pin<&mut BRepOffsetAPI_MakePipe>) -> &TopoDS_Shape;

// Lofting
type BRepOffsetAPI_ThruSections;

Expand Down
12 changes: 12 additions & 0 deletions crates/opencascade/src/primitives/face.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,18 @@ impl Face {
wire.to_face()
}

/// Sweep the face along a path to produce a solid
#[must_use]
pub fn sweep_along(&self, path: &Wire) -> Solid {
let profile_shape = ffi::cast_face_to_shape(&self.inner);
let mut make_pipe = ffi::BRepOffsetAPI_MakePipe_ctor(&path.inner, profile_shape);

let pipe_shape = make_pipe.pin_mut().Shape();
let result_solid = ffi::TopoDS_cast_to_solid(pipe_shape);

Solid::from_solid(result_solid)
}

pub fn edges(&self) -> EdgeIterator {
let explorer = ffi::TopExp_Explorer_ctor(
ffi::cast_face_to_shape(&self.inner),
Expand Down
14 changes: 14 additions & 0 deletions crates/opencascade/src/primitives/wire.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use cxx::UniquePtr;
use glam::{dvec3, DVec3};
use opencascade_sys::ffi;

use crate::primitives::Shell;

pub struct Wire {
pub(crate) inner: UniquePtr<ffi::TopoDS_Wire>,
}
Expand Down Expand Up @@ -188,6 +190,18 @@ impl Wire {
Self::from_wire(result_wire)
}

/// Sweep the wire along a path to produce a shell
#[must_use]
pub fn sweep_along(&self, path: &Wire) -> Shell {
let profile_shape = ffi::cast_wire_to_shape(&self.inner);
let mut make_pipe = ffi::BRepOffsetAPI_MakePipe_ctor(&path.inner, profile_shape);

let pipe_shape = make_pipe.pin_mut().Shape();
let result_shell = ffi::TopoDS_cast_to_shell(pipe_shape);

Shell::from_shell(result_shell)
}

#[must_use]
pub fn translate(&self, offset: DVec3) -> Self {
self.transform(offset, dvec3(1.0, 0.0, 0.0), 0.degrees())
Expand Down
4 changes: 4 additions & 0 deletions crates/viewer/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ enum Example {
Keycap,
Offset2d,
RoundedChamfer,
SweptFace,
SweptWire,
TurnersCube,
VariableFillet,
}
Expand All @@ -79,6 +81,8 @@ impl Example {
Example::Keycap => examples::keycap::shape(),
Example::Offset2d => examples::offset_2d::shape(),
Example::RoundedChamfer => examples::rounded_chamfer::shape(),
Example::SweptFace => examples::swept_face::shape(),
Example::SweptWire => examples::swept_wire::shape(),
Example::TurnersCube => examples::turners_cube::shape(),
Example::VariableFillet => examples::variable_fillet::shape(),
}
Expand Down
2 changes: 2 additions & 0 deletions examples/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@ pub mod keyboard_case;
pub mod keycap;
pub mod offset_2d;
pub mod rounded_chamfer;
pub mod swept_face;
pub mod swept_wire;
pub mod turners_cube;
pub mod variable_fillet;
23 changes: 23 additions & 0 deletions examples/src/swept_face.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use glam::DVec3;
use opencascade::{
angle::{RVec, ToAngle},
primitives::{Face, IntoShape, Shape, Solid, Wire},
workplane::Workplane,
};

pub fn shape() -> Shape {
let r = 10.0;
let a = 5.0;

let face_profile: Face = Workplane::xz()
.rotated(RVec::z(45.0.degrees()))
.translated(DVec3::new(-r, 0.0, 0.0))
.rect(a, a)
.to_face();

let path: Wire = Workplane::xy().sketch().arc((-r, 0.0), (0.0, r), (r, 0.0)).wire();

let pipe_solid: Solid = face_profile.sweep_along(&path);

pipe_solid.into_shape()
}
22 changes: 22 additions & 0 deletions examples/src/swept_wire.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use glam::DVec3;
use opencascade::{
angle::{RVec, ToAngle},
primitives::{IntoShape, Shape, Shell, Wire},
workplane::Workplane,
};

pub fn shape() -> Shape {
let r = 10.0;
let a = 5.0;

let wire_profile: Wire = Workplane::xz()
.rotated(RVec::z(45.0.degrees()))
.translated(DVec3::new(-r, 0.0, 0.0))
.rect(a, a);

let path: Wire = Workplane::xy().sketch().arc((-r, 0.0), (0.0, r), (r, 0.0)).wire();

let pipe_shell: Shell = wire_profile.sweep_along(&path);

pipe_shell.into_shape()
}

0 comments on commit edf0924

Please sign in to comment.