Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sweep Faces and Wires along a path #155

Merged
merged 7 commits into from
Nov 26, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 super::Shell;
mkovaxx marked this conversation as resolved.
Show resolved Hide resolved

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 @@ -61,6 +61,8 @@ enum Example {
Keycap,
Offset2d,
RoundedChamfer,
SweptFace,
SweptWire,
TurnersCube,
VariableFillet,
}
Expand All @@ -77,6 +79,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()
}