From 1b017cee8e86ab1ffc339c3138699255d2e70049 Mon Sep 17 00:00:00 2001 From: Brian Schwind Date: Sat, 9 Sep 2023 22:19:13 +0900 Subject: [PATCH 1/7] Start binding to BRepOffsetAPI_MakePipeShell --- crates/opencascade-sys/include/wrapper.hxx | 1 + crates/opencascade-sys/src/lib.rs | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/crates/opencascade-sys/include/wrapper.hxx b/crates/opencascade-sys/include/wrapper.hxx index a36b5b57..cb7d23b7 100644 --- a/crates/opencascade-sys/include/wrapper.hxx +++ b/crates/opencascade-sys/include/wrapper.hxx @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/crates/opencascade-sys/src/lib.rs b/crates/opencascade-sys/src/lib.rs index 4b757491..9811f06b 100644 --- a/crates/opencascade-sys/src/lib.rs +++ b/crates/opencascade-sys/src/lib.rs @@ -765,6 +765,21 @@ pub mod ffi { ); pub fn IsDone(self: &BRepOffsetAPI_MakeThickSolid) -> bool; + type BRepOffsetAPI_MakePipeShell; + + #[cxx_name = "construct_unique"] + pub fn BRepOffsetAPI_MakePipeShell_ctor( + wire: &TopoDS_Wire, + ) -> UniquePtr; + + pub fn Add( + self: Pin<&mut BRepOffsetAPI_MakePipeShell>, + profile: &TopoDS_Shape, + with_contact: bool, + with_correction: bool, + ); + pub fn Shape(self: Pin<&mut BRepOffsetAPI_MakePipeShell>) -> &TopoDS_Shape; + // Lofting type BRepOffsetAPI_ThruSections; From fcc51d98643dcaf5caa51619417a43b8966158eb Mon Sep 17 00:00:00 2001 From: Mate Kovacs Date: Sat, 25 Nov 2023 22:14:59 +0900 Subject: [PATCH 2/7] get wire sweep working --- crates/opencascade/src/primitives/face.rs | 6 ++++++ crates/opencascade/src/primitives/wire.rs | 18 ++++++++++++++++++ crates/viewer/src/main.rs | 2 ++ examples/src/lib.rs | 1 + examples/src/pipe.rs | 22 ++++++++++++++++++++++ 5 files changed, 49 insertions(+) create mode 100644 examples/src/pipe.rs diff --git a/crates/opencascade/src/primitives/face.rs b/crates/opencascade/src/primitives/face.rs index 808ddf70..a2c0bc99 100644 --- a/crates/opencascade/src/primitives/face.rs +++ b/crates/opencascade/src/primitives/face.rs @@ -201,6 +201,12 @@ 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 { + todo!() + } + pub fn edges(&self) -> EdgeIterator { let explorer = ffi::TopExp_Explorer_ctor( ffi::cast_face_to_shape(&self.inner), diff --git a/crates/opencascade/src/primitives/wire.rs b/crates/opencascade/src/primitives/wire.rs index 08f2a504..23c84847 100644 --- a/crates/opencascade/src/primitives/wire.rs +++ b/crates/opencascade/src/primitives/wire.rs @@ -9,6 +9,8 @@ use cxx::UniquePtr; use glam::{dvec3, DVec3}; use opencascade_sys::ffi; +use super::Shell; + pub struct Wire { pub(crate) inner: UniquePtr, } @@ -188,6 +190,22 @@ 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 mut make_pipe = ffi::BRepOffsetAPI_MakePipeShell_ctor(&path.inner); + + let profile_shape = ffi::cast_wire_to_shape(&self.inner); + let with_contact = false; + let with_correction = false; + make_pipe.pin_mut().Add(profile_shape, with_contact, with_correction); + + 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()) diff --git a/crates/viewer/src/main.rs b/crates/viewer/src/main.rs index 0fe90469..92134d08 100644 --- a/crates/viewer/src/main.rs +++ b/crates/viewer/src/main.rs @@ -60,6 +60,7 @@ enum Example { KeyboardCase, Keycap, Offset2d, + Pipe, RoundedChamfer, TurnersCube, VariableFillet, @@ -76,6 +77,7 @@ impl Example { Example::KeyboardCase => examples::keyboard_case::shape(), Example::Keycap => examples::keycap::shape(), Example::Offset2d => examples::offset_2d::shape(), + Example::Pipe => examples::pipe::shape(), Example::RoundedChamfer => examples::rounded_chamfer::shape(), Example::TurnersCube => examples::turners_cube::shape(), Example::VariableFillet => examples::variable_fillet::shape(), diff --git a/examples/src/lib.rs b/examples/src/lib.rs index 82b0ee47..3ccebe76 100644 --- a/examples/src/lib.rs +++ b/examples/src/lib.rs @@ -6,6 +6,7 @@ pub mod high_level_bottle; pub mod keyboard_case; pub mod keycap; pub mod offset_2d; +pub mod pipe; pub mod rounded_chamfer; pub mod turners_cube; pub mod variable_fillet; diff --git a/examples/src/pipe.rs b/examples/src/pipe.rs new file mode 100644 index 00000000..a3cd9a93 --- /dev/null +++ b/examples/src/pipe.rs @@ -0,0 +1,22 @@ +use glam::DVec3; +use opencascade::{ + angle::{RVec, ToAngle}, + primitives::Shape, + workplane::Workplane, +}; + +pub fn shape() -> Shape { + let r = 10.0; + let a = 5.0; + + let profile = Workplane::xz() + .rotated(RVec::z(45.0.degrees())) + .translated(DVec3::new(-r, 0.0, 0.0)) + .rect(a, a); + let spine = Workplane::xy().sketch().arc((-r, 0.0), (0.0, r), (r, 0.0)).wire(); + + //spine.into_shape().union(&profile.into_shape()).into_shape() + + let pipe = profile.sweep_along(&spine); + pipe.into() +} From 15743335f2ba057bd8fa8fb47200938f1662b832 Mon Sep 17 00:00:00 2001 From: Mate Kovacs Date: Sun, 26 Nov 2023 20:17:55 +0900 Subject: [PATCH 3/7] use the simpler MakePipe instead of MakePipeShell --- crates/opencascade-sys/include/wrapper.hxx | 1 + crates/opencascade-sys/src/lib.rs | 18 +++++++---------- crates/opencascade/src/primitives/face.rs | 8 +++++++- crates/opencascade/src/primitives/wire.rs | 6 +----- crates/viewer/src/main.rs | 6 ++++-- examples/src/lib.rs | 3 ++- examples/src/pipe.rs | 22 --------------------- examples/src/swept_face.rs | 23 ++++++++++++++++++++++ examples/src/swept_wire.rs | 22 +++++++++++++++++++++ 9 files changed, 67 insertions(+), 42 deletions(-) delete mode 100644 examples/src/pipe.rs create mode 100644 examples/src/swept_face.rs create mode 100644 examples/src/swept_wire.rs diff --git a/crates/opencascade-sys/include/wrapper.hxx b/crates/opencascade-sys/include/wrapper.hxx index cb7d23b7..bf971556 100644 --- a/crates/opencascade-sys/include/wrapper.hxx +++ b/crates/opencascade-sys/include/wrapper.hxx @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/crates/opencascade-sys/src/lib.rs b/crates/opencascade-sys/src/lib.rs index 9811f06b..2901179e 100644 --- a/crates/opencascade-sys/src/lib.rs +++ b/crates/opencascade-sys/src/lib.rs @@ -765,20 +765,16 @@ pub mod ffi { ); pub fn IsDone(self: &BRepOffsetAPI_MakeThickSolid) -> bool; - type BRepOffsetAPI_MakePipeShell; + // Sweeps + type BRepOffsetAPI_MakePipe; #[cxx_name = "construct_unique"] - pub fn BRepOffsetAPI_MakePipeShell_ctor( - wire: &TopoDS_Wire, - ) -> UniquePtr; - - pub fn Add( - self: Pin<&mut BRepOffsetAPI_MakePipeShell>, + pub fn BRepOffsetAPI_MakePipe_ctor( + spine: &TopoDS_Wire, profile: &TopoDS_Shape, - with_contact: bool, - with_correction: bool, - ); - pub fn Shape(self: Pin<&mut BRepOffsetAPI_MakePipeShell>) -> &TopoDS_Shape; + ) -> UniquePtr; + + pub fn Shape(self: Pin<&mut BRepOffsetAPI_MakePipe>) -> &TopoDS_Shape; // Lofting type BRepOffsetAPI_ThruSections; diff --git a/crates/opencascade/src/primitives/face.rs b/crates/opencascade/src/primitives/face.rs index a2c0bc99..e0706b55 100644 --- a/crates/opencascade/src/primitives/face.rs +++ b/crates/opencascade/src/primitives/face.rs @@ -204,7 +204,13 @@ impl Face { /// Sweep the face along a path to produce a solid #[must_use] pub fn sweep_along(&self, path: &Wire) -> Solid { - todo!() + 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 { diff --git a/crates/opencascade/src/primitives/wire.rs b/crates/opencascade/src/primitives/wire.rs index 23c84847..e4f31eac 100644 --- a/crates/opencascade/src/primitives/wire.rs +++ b/crates/opencascade/src/primitives/wire.rs @@ -193,12 +193,8 @@ impl Wire { /// Sweep the wire along a path to produce a shell #[must_use] pub fn sweep_along(&self, path: &Wire) -> Shell { - let mut make_pipe = ffi::BRepOffsetAPI_MakePipeShell_ctor(&path.inner); - let profile_shape = ffi::cast_wire_to_shape(&self.inner); - let with_contact = false; - let with_correction = false; - make_pipe.pin_mut().Add(profile_shape, with_contact, with_correction); + 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); diff --git a/crates/viewer/src/main.rs b/crates/viewer/src/main.rs index 92134d08..9062f292 100644 --- a/crates/viewer/src/main.rs +++ b/crates/viewer/src/main.rs @@ -60,8 +60,9 @@ enum Example { KeyboardCase, Keycap, Offset2d, - Pipe, RoundedChamfer, + SweptFace, + SweptWire, TurnersCube, VariableFillet, } @@ -77,8 +78,9 @@ impl Example { Example::KeyboardCase => examples::keyboard_case::shape(), Example::Keycap => examples::keycap::shape(), Example::Offset2d => examples::offset_2d::shape(), - Example::Pipe => examples::pipe::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(), } diff --git a/examples/src/lib.rs b/examples/src/lib.rs index 3ccebe76..8c237478 100644 --- a/examples/src/lib.rs +++ b/examples/src/lib.rs @@ -6,7 +6,8 @@ pub mod high_level_bottle; pub mod keyboard_case; pub mod keycap; pub mod offset_2d; -pub mod pipe; pub mod rounded_chamfer; +pub mod swept_face; +pub mod swept_wire; pub mod turners_cube; pub mod variable_fillet; diff --git a/examples/src/pipe.rs b/examples/src/pipe.rs deleted file mode 100644 index a3cd9a93..00000000 --- a/examples/src/pipe.rs +++ /dev/null @@ -1,22 +0,0 @@ -use glam::DVec3; -use opencascade::{ - angle::{RVec, ToAngle}, - primitives::Shape, - workplane::Workplane, -}; - -pub fn shape() -> Shape { - let r = 10.0; - let a = 5.0; - - let profile = Workplane::xz() - .rotated(RVec::z(45.0.degrees())) - .translated(DVec3::new(-r, 0.0, 0.0)) - .rect(a, a); - let spine = Workplane::xy().sketch().arc((-r, 0.0), (0.0, r), (r, 0.0)).wire(); - - //spine.into_shape().union(&profile.into_shape()).into_shape() - - let pipe = profile.sweep_along(&spine); - pipe.into() -} diff --git a/examples/src/swept_face.rs b/examples/src/swept_face.rs new file mode 100644 index 00000000..00c60b9b --- /dev/null +++ b/examples/src/swept_face.rs @@ -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() +} diff --git a/examples/src/swept_wire.rs b/examples/src/swept_wire.rs new file mode 100644 index 00000000..37f74d71 --- /dev/null +++ b/examples/src/swept_wire.rs @@ -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() +} From 542abff5f0e6f8c2073bd1cbabe9d4864b4d4d6f Mon Sep 17 00:00:00 2001 From: Mate Kovacs Date: Sun, 26 Nov 2023 20:19:23 +0900 Subject: [PATCH 4/7] remove unnecessary include --- crates/opencascade-sys/include/wrapper.hxx | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/opencascade-sys/include/wrapper.hxx b/crates/opencascade-sys/include/wrapper.hxx index bf971556..7495277c 100644 --- a/crates/opencascade-sys/include/wrapper.hxx +++ b/crates/opencascade-sys/include/wrapper.hxx @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include From f1025cde8b2ac3c6c9fa7d6c62af5dde4ffbbab9 Mon Sep 17 00:00:00 2001 From: Mate Kovacs Date: Sun, 26 Nov 2023 20:26:28 +0900 Subject: [PATCH 5/7] fix clippy warnings --- crates/opencascade/src/primitives/face.rs | 4 ++-- crates/opencascade/src/primitives/wire.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/opencascade/src/primitives/face.rs b/crates/opencascade/src/primitives/face.rs index e0706b55..5791a514 100644 --- a/crates/opencascade/src/primitives/face.rs +++ b/crates/opencascade/src/primitives/face.rs @@ -205,12 +205,12 @@ impl Face { #[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 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) + Solid::from_solid(result_solid) } pub fn edges(&self) -> EdgeIterator { diff --git a/crates/opencascade/src/primitives/wire.rs b/crates/opencascade/src/primitives/wire.rs index e4f31eac..6bb179b9 100644 --- a/crates/opencascade/src/primitives/wire.rs +++ b/crates/opencascade/src/primitives/wire.rs @@ -194,12 +194,12 @@ impl Wire { #[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 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) + Shell::from_shell(result_shell) } #[must_use] From 702c13b8816ccce4adbfc84cdda81d003d1a8903 Mon Sep 17 00:00:00 2001 From: Mate Kovacs Date: Sun, 26 Nov 2023 20:42:26 +0900 Subject: [PATCH 6/7] clang format --- crates/opencascade-sys/include/wrapper.hxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/opencascade-sys/include/wrapper.hxx b/crates/opencascade-sys/include/wrapper.hxx index 7495277c..da4e7325 100644 --- a/crates/opencascade-sys/include/wrapper.hxx +++ b/crates/opencascade-sys/include/wrapper.hxx @@ -22,9 +22,9 @@ #include #include #include +#include #include #include -#include #include #include #include From 394b923c212f199f39aad5350c17c1604bac983d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kov=C3=A1cs?= <481354+mkovaxx@users.noreply.github.com> Date: Sun, 26 Nov 2023 22:18:29 +0900 Subject: [PATCH 7/7] Update crates/opencascade/src/primitives/wire.rs Co-authored-by: Brian Schwind --- crates/opencascade/src/primitives/wire.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/opencascade/src/primitives/wire.rs b/crates/opencascade/src/primitives/wire.rs index 6bb179b9..63022122 100644 --- a/crates/opencascade/src/primitives/wire.rs +++ b/crates/opencascade/src/primitives/wire.rs @@ -9,7 +9,7 @@ use cxx::UniquePtr; use glam::{dvec3, DVec3}; use opencascade_sys::ffi; -use super::Shell; +use crate::primitives::Shell; pub struct Wire { pub(crate) inner: UniquePtr,