Skip to content

Commit

Permalink
Start prototyping a high level API (#25)
Browse files Browse the repository at this point in the history
* Start adding experimentation for a higher-level API

* Make the high_level example easier to distinguish orientation

* Transform points according to the workplane

* Add more TaggedItem variants, key them off of a String for now

* Add a stub file for primitive shapes

* Fix a build error

* Add internal fields to all the primitive types

* Add more primitive-level construction functions, recreate part of the bottle example at a higher level

* Add better support for TopoDS_Compound

* Add various functions to accomplish filleting 2D wires

* Format wrapper.hxx

* Add the start of a keycap example

* Add a lofting function

* Clean up warnings, add an Error type

* Make the APIs that use Iterators a little nicer

* Add the ability to translate shapes

* Support rotation in the shape transforms

* Add a WorkPlane abstraction

* Update glam

* Add the ability to rotate and translate workplanes

* Add support for BRepAdaptor_Curve

* Continue on with the keycap example

* Add the concave scoop

* Retrieve edges from result of intersection of boolean operations

* Carve out the inner part of the keycap

* Add the ability to create workplanes from faces

* Run clang-format

* Add support for shape cleaning

* Fix clippy warning

* Remove the unnecessary geometry module
  • Loading branch information
bschwind authored May 20, 2023
1 parent 0c4ce79 commit 24223a4
Show file tree
Hide file tree
Showing 8 changed files with 1,210 additions and 10 deletions.
43 changes: 40 additions & 3 deletions crates/opencascade-sys/include/wrapper.hxx
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
#include "rust/cxx.h"
#include <BRepAdaptor_Curve.hxx>
#include <BRepAlgoAPI_Common.hxx>
#include <BRepAlgoAPI_Cut.hxx>
#include <BRepAlgoAPI_Fuse.hxx>
#include <BRepAlgoAPI_Section.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepBuilderAPI_Transform.hxx>
#include <BRepFeat_MakeCylindricalHole.hxx>
#include <BRepFilletAPI_MakeChamfer.hxx>
#include <BRepFilletAPI_MakeFillet.hxx>
#include <BRepFilletAPI_MakeFillet2d.hxx>
#include <BRepGProp.hxx>
#include <BRepGProp_Face.hxx>
#include <BRepLib.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
#include <BRepOffsetAPI_MakeThickSolid.hxx>
Expand All @@ -20,16 +24,19 @@
#include <BRepPrimAPI_MakePrism.hxx>
#include <BRepPrimAPI_MakeRevol.hxx>
#include <BRepPrimAPI_MakeSphere.hxx>
#include <BRepTools.hxx>
#include <GCE2d_MakeSegment.hxx>
#include <GC_MakeArcOfCircle.hxx>
#include <GC_MakeSegment.hxx>
#include <GProp_GProps.hxx>
#include <Geom2d_Ellipse.hxx>
#include <Geom2d_TrimmedCurve.hxx>
#include <GeomAPI_ProjectPointOnSurf.hxx>
#include <Geom_CylindricalSurface.hxx>
#include <Geom_Plane.hxx>
#include <Geom_Surface.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <ShapeUpgrade_UnifySameDomain.hxx>
#include <Standard_Type.hxx>
#include <StlAPI_Writer.hxx>
#include <TopAbs_ShapeEnum.hxx>
Expand All @@ -50,6 +57,11 @@ template <typename T, typename... Args> std::unique_ptr<T> construct_unique(Args
return std::unique_ptr<T>(new T(args...));
}

// Generic List
template <typename T> std::unique_ptr<std::vector<T>> list_to_vector(const NCollection_List<T> &list) {
return std::unique_ptr<std::vector<T>>(new std::vector<T>(list.begin(), list.end()));
}

// Handles
typedef opencascade::handle<Standard_Type> HandleStandardType;
typedef opencascade::handle<Geom_Curve> HandleGeomCurve;
Expand Down Expand Up @@ -139,6 +151,10 @@ inline std::unique_ptr<HandleGeomTrimmedCurve> GC_MakeArcOfCircle_Value(const GC
return std::unique_ptr<HandleGeomTrimmedCurve>(new opencascade::handle<Geom_TrimmedCurve>(arc.Value()));
}

inline std::unique_ptr<gp_Pnt> BRepAdaptor_Curve_value(const BRepAdaptor_Curve &curve, const Standard_Real U) {
return std::unique_ptr<gp_Pnt>(new gp_Pnt(curve.Value(U)));
}

// BRepLib
inline bool BRepLibBuildCurves3d(const TopoDS_Shape &shape) { return BRepLib::BuildCurves3d(shape); }

Expand Down Expand Up @@ -181,12 +197,16 @@ inline std::unique_ptr<gp_Ax2d> gp_Ax2d_ctor(const gp_Pnt2d &point, const gp_Dir

// Shape stuff
inline const TopoDS_Vertex &TopoDS_cast_to_vertex(const TopoDS_Shape &shape) { return TopoDS::Vertex(shape); }

inline const TopoDS_Wire &TopoDS_cast_to_wire(const TopoDS_Shape &shape) { return TopoDS::Wire(shape); }

inline const TopoDS_Edge &TopoDS_cast_to_edge(const TopoDS_Shape &shape) { return TopoDS::Edge(shape); }

inline const TopoDS_Face &TopoDS_cast_to_face(const TopoDS_Shape &shape) { return TopoDS::Face(shape); }
inline const TopoDS_Solid &TopoDS_cast_to_solid(const TopoDS_Shape &shape) { return TopoDS::Solid(shape); }
inline const TopoDS_Compound &TopoDS_cast_to_compound(const TopoDS_Shape &shape) { return TopoDS::Compound(shape); }

inline const TopoDS_Shape &cast_wire_to_shape(const TopoDS_Wire &wire) { return wire; }
inline const TopoDS_Shape &cast_face_to_shape(const TopoDS_Face &face) { return face; }
inline const TopoDS_Shape &cast_solid_to_shape(const TopoDS_Solid &solid) { return solid; }
inline const TopoDS_Shape &cast_compound_to_shape(const TopoDS_Compound &compound) { return compound; }

// Compound shapes
inline std::unique_ptr<TopoDS_Shape> TopoDS_Compound_as_shape(std::unique_ptr<TopoDS_Compound> compound) {
Expand Down Expand Up @@ -255,3 +275,20 @@ inline void BRepGProp_SurfaceProperties(const TopoDS_Shape &shape, GProp_GProps
inline void BRepGProp_VolumeProperties(const TopoDS_Shape &shape, GProp_GProps &props) {
BRepGProp::VolumeProperties(shape, props);
}

// Fillets
inline std::unique_ptr<TopoDS_Edge> BRepFilletAPI_MakeFillet2d_add_fillet(BRepFilletAPI_MakeFillet2d &make_fillet,
const TopoDS_Vertex &vertex,
Standard_Real radius) {
return std::unique_ptr<TopoDS_Edge>(new TopoDS_Edge(make_fillet.AddFillet(vertex, radius)));
}

// BRepTools
inline std::unique_ptr<TopoDS_Wire> outer_wire(const TopoDS_Face &face) {
return std::unique_ptr<TopoDS_Wire>(new TopoDS_Wire(BRepTools::OuterWire(face)));
}

// Collections
inline void map_shapes(const TopoDS_Shape &S, const TopAbs_ShapeEnum T, TopTools_IndexedMapOfShape &M) {
TopExp::MapShapes(S, T, M);
}
151 changes: 145 additions & 6 deletions crates/opencascade-sys/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#[cxx::bridge]
pub mod ffi {
#[repr(u32)]
#[derive(Debug)]
pub enum TopAbs_ShapeEnum {
TopAbs_COMPOUND,
TopAbs_COMPSOLID,
Expand Down Expand Up @@ -74,6 +75,25 @@ pub mod ffi {
#[cxx_name = "construct_unique"]
pub fn new_list_of_shape() -> UniquePtr<TopTools_ListOfShape>;
pub fn shape_list_append_face(list: Pin<&mut TopTools_ListOfShape>, face: &TopoDS_Face);
pub fn Size(self: &TopTools_ListOfShape) -> i32;

#[cxx_name = "list_to_vector"]
pub fn shape_list_to_vector(
list: &TopTools_ListOfShape,
) -> UniquePtr<CxxVector<TopoDS_Shape>>;

type TopTools_IndexedMapOfShape;

#[cxx_name = "construct_unique"]
pub fn new_indexed_map_of_shape() -> UniquePtr<TopTools_IndexedMapOfShape>;
pub fn Extent(self: &TopTools_IndexedMapOfShape) -> i32;
pub fn FindKey(self: &TopTools_IndexedMapOfShape, index: i32) -> &TopoDS_Shape;

pub fn map_shapes(
shape: &TopoDS_Shape,
shape_type: TopAbs_ShapeEnum,
shape_map: Pin<&mut TopTools_IndexedMapOfShape>,
);

// Geometry
type Geom_TrimmedCurve;
Expand Down Expand Up @@ -131,6 +151,10 @@ pub mod ffi {
#[cxx_name = "construct_unique"]
pub fn new_vec(x: f64, y: f64, z: f64) -> UniquePtr<gp_Vec>;

pub fn X(self: &gp_Vec) -> f64;
pub fn Y(self: &gp_Vec) -> f64;
pub fn Z(self: &gp_Vec) -> f64;

// Segments
type GC_MakeSegment;
type GCE2d_MakeSegment;
Expand Down Expand Up @@ -159,33 +183,60 @@ pub mod ffi {
) -> UniquePtr<HandleGeomTrimmedCurve>;

// Shapes
type TopoDS_Shape;
type TopoDS_Vertex;
type TopoDS_Edge;
type TopoDS_Wire;
type TopoDS_Face;
type TopoDS_Shell;
type TopoDS_Solid;
type TopoDS_Shape;

pub fn cast_wire_to_shape(wire: &TopoDS_Wire) -> &TopoDS_Shape;
pub fn cast_face_to_shape(wire: &TopoDS_Face) -> &TopoDS_Shape;
pub fn cast_solid_to_shape(wire: &TopoDS_Solid) -> &TopoDS_Shape;
pub fn cast_compound_to_shape(wire: &TopoDS_Compound) -> &TopoDS_Shape;

pub fn TopoDS_cast_to_vertex(shape: &TopoDS_Shape) -> &TopoDS_Vertex;
pub fn TopoDS_cast_to_wire(shape: &TopoDS_Shape) -> &TopoDS_Wire;
pub fn TopoDS_cast_to_edge(shape: &TopoDS_Shape) -> &TopoDS_Edge;
pub fn TopoDS_cast_to_face(shape: &TopoDS_Shape) -> &TopoDS_Face;
pub fn TopoDS_cast_to_solid(shape: &TopoDS_Shape) -> &TopoDS_Solid;
pub fn TopoDS_cast_to_compound(shape: &TopoDS_Shape) -> &TopoDS_Compound;

#[cxx_name = "Move"]
pub fn translate(
self: Pin<&mut TopoDS_Shape>,
position: &TopLoc_Location,
raise_exception: bool,
);

#[cxx_name = "construct_unique"]
pub fn TopoDS_Shape_to_owned(shape: &TopoDS_Shape) -> UniquePtr<TopoDS_Shape>;
pub fn TopoDS_Vertex_to_owned(shape: &TopoDS_Vertex) -> UniquePtr<TopoDS_Vertex>;

#[cxx_name = "construct_unique"]
pub fn TopoDS_Vertex_to_owned(shape: &TopoDS_Vertex) -> UniquePtr<TopoDS_Vertex>;
pub fn TopoDS_Edge_to_owned(shape: &TopoDS_Edge) -> UniquePtr<TopoDS_Edge>;

#[cxx_name = "construct_unique"]
pub fn TopoDS_Wire_to_owned(shape: &TopoDS_Wire) -> UniquePtr<TopoDS_Wire>;

#[cxx_name = "construct_unique"]
pub fn TopoDS_Edge_to_owned(shape: &TopoDS_Edge) -> UniquePtr<TopoDS_Edge>;
pub fn TopoDS_Face_to_owned(shape: &TopoDS_Face) -> UniquePtr<TopoDS_Face>;

#[cxx_name = "construct_unique"]
pub fn TopoDS_Face_to_owned(shape: &TopoDS_Face) -> UniquePtr<TopoDS_Face>;
pub fn TopoDS_Shell_to_owned(shape: &TopoDS_Shell) -> UniquePtr<TopoDS_Shell>;

#[cxx_name = "construct_unique"]
pub fn TopoDS_Solid_to_owned(shape: &TopoDS_Solid) -> UniquePtr<TopoDS_Solid>;

#[cxx_name = "construct_unique"]
pub fn TopoDS_Compound_to_owned(shape: &TopoDS_Compound) -> UniquePtr<TopoDS_Compound>;

#[cxx_name = "construct_unique"]
pub fn TopoDS_Shape_to_owned(shape: &TopoDS_Shape) -> UniquePtr<TopoDS_Shape>;

pub fn IsNull(self: &TopoDS_Shape) -> bool;
pub fn IsEqual(self: &TopoDS_Shape, other: &TopoDS_Shape) -> bool;
pub fn ShapeType(self: &TopoDS_Shape) -> TopAbs_ShapeEnum;

type TopAbs_Orientation;
pub fn Orientation(self: &TopoDS_Shape) -> TopAbs_Orientation;
Expand All @@ -211,14 +262,27 @@ pub mod ffi {
pub fn Add(self: &TopoDS_Builder, shape: Pin<&mut TopoDS_Shape>, compound: &TopoDS_Shape);

// BRepBuilder
type BRepBuilderAPI_MakeVertex;
#[cxx_name = "construct_unique"]
pub fn BRepBuilderAPI_MakeVertex_gp_Pnt(
point: &gp_Pnt,
) -> UniquePtr<BRepBuilderAPI_MakeVertex>;

pub fn Vertex(self: Pin<&mut BRepBuilderAPI_MakeVertex>) -> &TopoDS_Vertex;

type BRepBuilderAPI_MakeEdge;
type TopoDS_Vertex;

#[cxx_name = "construct_unique"]
pub fn BRepBuilderAPI_MakeEdge_HandleGeomCurve(
geom_curve_handle: &HandleGeomCurve,
) -> UniquePtr<BRepBuilderAPI_MakeEdge>;

#[cxx_name = "construct_unique"]
pub fn BRepBuilderAPI_MakeEdge_gp_Pnt_gp_Pnt(
p1: &gp_Pnt,
p2: &gp_Pnt,
) -> UniquePtr<BRepBuilderAPI_MakeEdge>;

#[cxx_name = "construct_unique"]
pub fn BRepBuilderAPI_MakeEdge_CurveSurface2d(
curve_handle: &HandleGeom2d_Curve,
Expand Down Expand Up @@ -261,10 +325,19 @@ pub mod ffi {
only_plane: bool,
) -> UniquePtr<BRepBuilderAPI_MakeFace>;

pub fn Face(self: &BRepBuilderAPI_MakeFace) -> &TopoDS_Face;
pub fn Shape(self: Pin<&mut BRepBuilderAPI_MakeFace>) -> &TopoDS_Shape;
pub fn Build(self: Pin<&mut BRepBuilderAPI_MakeFace>, progress: &Message_ProgressRange);
pub fn IsDone(self: &BRepBuilderAPI_MakeFace) -> bool;

// BRepAdaptor
type BRepAdaptor_Curve;

#[cxx_name = "construct_unique"]
pub fn BRepAdaptor_Curve_ctor(edge: &TopoDS_Edge) -> UniquePtr<BRepAdaptor_Curve>;
pub fn FirstParameter(self: &BRepAdaptor_Curve) -> f64;
pub fn BRepAdaptor_Curve_value(curve: &BRepAdaptor_Curve, u: f64) -> UniquePtr<gp_Pnt>;

// Primitives
type BRepPrimAPI_MakePrism;

Expand Down Expand Up @@ -353,6 +426,22 @@ pub mod ffi {
pub fn Build(self: Pin<&mut BRepFilletAPI_MakeFillet>, progress: &Message_ProgressRange);
pub fn IsDone(self: &BRepFilletAPI_MakeFillet) -> bool;

type BRepFilletAPI_MakeFillet2d;

#[cxx_name = "construct_unique"]
pub fn BRepFilletAPI_MakeFillet2d_ctor(
face: &TopoDS_Face,
) -> UniquePtr<BRepFilletAPI_MakeFillet2d>;

pub fn BRepFilletAPI_MakeFillet2d_add_fillet(
make_fillet: Pin<&mut BRepFilletAPI_MakeFillet2d>,
vertex: &TopoDS_Vertex,
radius: f64,
) -> UniquePtr<TopoDS_Edge>;
pub fn Build(self: Pin<&mut BRepFilletAPI_MakeFillet2d>, progress: &Message_ProgressRange);
pub fn Shape(self: Pin<&mut BRepFilletAPI_MakeFillet2d>) -> &TopoDS_Shape;
pub fn IsDone(self: &BRepFilletAPI_MakeFillet2d) -> bool;

// Chamfers
type BRepFilletAPI_MakeChamfer;

Expand Down Expand Up @@ -425,6 +514,11 @@ pub mod ffi {
pub fn Shape(self: Pin<&mut BRepAlgoAPI_Cut>) -> &TopoDS_Shape;
pub fn Build(self: Pin<&mut BRepAlgoAPI_Cut>, progress: &Message_ProgressRange);
pub fn IsDone(self: &BRepAlgoAPI_Cut) -> bool;
pub fn Generated<'a>(
self: Pin<&'a mut BRepAlgoAPI_Cut>,
shape: &'a TopoDS_Shape,
) -> &'a TopTools_ListOfShape;
pub fn SectionEdges<'a>(self: Pin<&'a mut BRepAlgoAPI_Cut>) -> &'a TopTools_ListOfShape;

type BRepAlgoAPI_Common;

Expand Down Expand Up @@ -484,6 +578,16 @@ pub mod ffi {
#[cxx_name = "construct_unique"]
pub fn gp_Ax2d_ctor(point: &gp_Pnt2d, dir: &gp_Dir2d) -> UniquePtr<gp_Ax2d>;

// Geometry Querying
type GeomAPI_ProjectPointOnSurf;

#[cxx_name = "construct_unique"]
pub fn GeomAPI_ProjectPointOnSurf_ctor(
origin: &gp_Pnt,
surface: &HandleGeomSurface,
) -> UniquePtr<GeomAPI_ProjectPointOnSurf>;
pub fn LowerDistanceParameters(self: &GeomAPI_ProjectPointOnSurf, u: &mut f64, v: &mut f64);

// Transforms
type gp_Trsf;

Expand All @@ -496,6 +600,9 @@ pub mod ffi {
pub fn SetScale(self: Pin<&mut gp_Trsf>, point: &gp_Pnt, scale: f64);
pub fn SetTranslation(self: Pin<&mut gp_Trsf>, point1: &gp_Pnt, point2: &gp_Pnt);

#[cxx_name = "SetTranslationPart"]
pub fn set_translation_vec(self: Pin<&mut gp_Trsf>, translation: &gp_Vec);

type BRepBuilderAPI_Transform;

#[cxx_name = "construct_unique"]
Expand Down Expand Up @@ -577,6 +684,9 @@ pub mod ffi {
#[cxx_name = "construct_unique"]
pub fn TopLoc_Location_ctor() -> UniquePtr<TopLoc_Location>;

#[cxx_name = "construct_unique"]
pub fn TopLoc_Location_from_transform(transform: &gp_Trsf) -> UniquePtr<TopLoc_Location>;

type Handle_Poly_Triangulation;
pub fn IsNull(self: &Handle_Poly_Triangulation) -> bool;
#[cxx_name = "handle_try_deref"]
Expand Down Expand Up @@ -614,5 +724,34 @@ pub mod ffi {
pub fn BRepGProp_LinearProperties(shape: &TopoDS_Shape, props: Pin<&mut GProp_GProps>);
pub fn BRepGProp_SurfaceProperties(shape: &TopoDS_Shape, props: Pin<&mut GProp_GProps>);
pub fn BRepGProp_VolumeProperties(shape: &TopoDS_Shape, props: Pin<&mut GProp_GProps>);

type BRepGProp_Face;

#[cxx_name = "construct_unique"]
pub fn BRepGProp_Face_ctor(face: &TopoDS_Face) -> UniquePtr<BRepGProp_Face>;
pub fn Normal(
self: &BRepGProp_Face,
u: f64,
v: f64,
point: Pin<&mut gp_Pnt>,
normal: Pin<&mut gp_Vec>,
);

// BRepTools
pub fn outer_wire(face: &TopoDS_Face) -> UniquePtr<TopoDS_Wire>;

// Cleaning
type ShapeUpgrade_UnifySameDomain;

#[cxx_name = "construct_unique"]
pub fn ShapeUpgrade_UnifySameDomain_ctor(
shape: &TopoDS_Shape,
unify_edges: bool,
unify_faces: bool,
concat_b_splines: bool,
) -> UniquePtr<ShapeUpgrade_UnifySameDomain>;
pub fn AllowInternalEdges(self: Pin<&mut ShapeUpgrade_UnifySameDomain>, allow: bool);
pub fn Build(self: Pin<&mut ShapeUpgrade_UnifySameDomain>);
pub fn Shape(self: &ShapeUpgrade_UnifySameDomain) -> &TopoDS_Shape;
}
}
3 changes: 2 additions & 1 deletion crates/opencascade/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ repository = "https://github.com/bschwind/opencascade-rs"
[dependencies]
cxx = "1"
opencascade-sys = { version = "0.1", path = "../opencascade-sys" }
glam = "0.22"
glam = "0.24"
thiserror = "1"
Loading

0 comments on commit 24223a4

Please sign in to comment.