Skip to content

Commit

Permalink
add iges import export
Browse files Browse the repository at this point in the history
  • Loading branch information
fidoriel committed Dec 3, 2024
1 parent 3534fe9 commit 5c8b5cf
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 6 deletions.
1 change: 1 addition & 0 deletions crates/opencascade-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const OCCT_LIBS: &[&str] = &[
"TKBRep",
"TKPrim",
"TKDESTEP",
"TKDEIGES",
"TKDESTL",
"TKMesh",
"TKShHealing",
Expand Down
20 changes: 19 additions & 1 deletion crates/opencascade-sys/include/wrapper.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@
#include <Geom_Plane.hxx>
#include <Geom_Surface.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <IGESControl_Reader.hxx>
#include <IGESControl_Writer.hxx>
#include <Law_Function.hxx>
#include <Law_Interpol.hxx>
#include <NCollection_Array1.hxx>
Expand Down Expand Up @@ -361,7 +363,15 @@ inline IFSelect_ReturnStatus read_step(STEPControl_Reader &reader, rust::String
return reader.ReadFile(theFileName.c_str());
}

inline std::unique_ptr<TopoDS_Shape> one_shape(const STEPControl_Reader &reader) {
inline IFSelect_ReturnStatus read_iges(IGESControl_Reader &reader, rust::String theFileName) {
return reader.ReadFile(theFileName.c_str());
}

inline std::unique_ptr<TopoDS_Shape> one_shape_step(const STEPControl_Reader &reader) {
return std::unique_ptr<TopoDS_Shape>(new TopoDS_Shape(reader.OneShape()));
}

inline std::unique_ptr<TopoDS_Shape> one_shape_iges(const IGESControl_Reader &reader) {
return std::unique_ptr<TopoDS_Shape>(new TopoDS_Shape(reader.OneShape()));
}

Expand All @@ -370,10 +380,18 @@ inline IFSelect_ReturnStatus transfer_shape(STEPControl_Writer &writer, const To
return writer.Transfer(theShape, STEPControl_AsIs);
}

inline void compute_model(IGESControl_Writer &writer) { writer.ComputeModel(); }

inline bool add_shape(IGESControl_Writer &writer, const TopoDS_Shape &theShape) { return writer.AddShape(theShape); }

inline IFSelect_ReturnStatus write_step(STEPControl_Writer &writer, rust::String theFileName) {
return writer.Write(theFileName.c_str());
}

inline bool write_iges(IGESControl_Writer &writer, rust::String theFileName) {
return writer.Write(theFileName.c_str());
}

inline bool write_stl(StlAPI_Writer &writer, const TopoDS_Shape &theShape, rust::String theFileName) {
return writer.Write(theShape, theFileName.c_str());
}
Expand Down
22 changes: 21 additions & 1 deletion crates/opencascade-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1146,35 +1146,55 @@ pub mod ffi {

// Data Import
type STEPControl_Reader;
type IGESControl_Reader;
type IFSelect_ReturnStatus;

#[cxx_name = "construct_unique"]
pub fn STEPControl_Reader_ctor() -> UniquePtr<STEPControl_Reader>;

#[cxx_name = "construct_unique"]
pub fn IGESControl_Reader_ctor() -> UniquePtr<IGESControl_Reader>;

pub fn read_step(
reader: Pin<&mut STEPControl_Reader>,
filename: String,
) -> IFSelect_ReturnStatus;
pub fn read_iges(
reader: Pin<&mut IGESControl_Reader>,
filename: String,
) -> IFSelect_ReturnStatus;
pub fn TransferRoots(
self: Pin<&mut STEPControl_Reader>,
progress: &Message_ProgressRange,
) -> i32;
pub fn one_shape(reader: &STEPControl_Reader) -> UniquePtr<TopoDS_Shape>;
pub fn TransferRoots(
self: Pin<&mut IGESControl_Reader>,
progress: &Message_ProgressRange,
) -> i32;
pub fn one_shape_step(reader: &STEPControl_Reader) -> UniquePtr<TopoDS_Shape>;
pub fn one_shape_iges(reader: &IGESControl_Reader) -> UniquePtr<TopoDS_Shape>;

// Data Export
type STEPControl_Writer;
type IGESControl_Writer;

#[cxx_name = "construct_unique"]
pub fn STEPControl_Writer_ctor() -> UniquePtr<STEPControl_Writer>;

#[cxx_name = "construct_unique"]
pub fn IGESControl_Writer_ctor() -> UniquePtr<IGESControl_Writer>;

pub fn transfer_shape(
writer: Pin<&mut STEPControl_Writer>,
shape: &TopoDS_Shape,
) -> IFSelect_ReturnStatus;
pub fn add_shape(writer: Pin<&mut IGESControl_Writer>, shape: &TopoDS_Shape) -> bool;
pub fn compute_model(writer: Pin<&mut IGESControl_Writer>);
pub fn write_step(
writer: Pin<&mut STEPControl_Writer>,
filename: String,
) -> IFSelect_ReturnStatus;
pub fn write_iges(writer: Pin<&mut IGESControl_Writer>, filename: String) -> bool;

type StlAPI_Writer;

Expand Down
4 changes: 4 additions & 0 deletions crates/opencascade/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,14 @@ pub enum Error {
StlWriteFailed,
#[error("failed to read STEP file")]
StepReadFailed,
#[error("failed to read IGES file")]
IgesReadFailed,
#[error("failed to read KiCAD PCB file: {0}")]
KicadReadFailed(#[from] kicad_parser::Error),
#[error("failed to write STEP file")]
StepWriteFailed,
#[error("failed to write IGES file")]
IgesWriteFailed,
#[error("failed to triangulate Shape")]
TriangulationFailed,
#[error("encountered a face with no triangulation")]
Expand Down
38 changes: 37 additions & 1 deletion crates/opencascade/src/primitives/shape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ impl Shape {

reader.pin_mut().TransferRoots(&ffi::Message_ProgressRange_ctor());

let inner = ffi::one_shape(&reader);
let inner = ffi::one_shape_step(&reader);

Ok(Self { inner })
}
Expand All @@ -518,6 +518,42 @@ impl Shape {
Ok(())
}

pub fn read_iges(path: impl AsRef<Path>) -> Result<Self, Error> {
let mut reader = ffi::IGESControl_Reader_ctor();

let status = ffi::read_iges(reader.pin_mut(), path.as_ref().to_string_lossy().to_string());

reader.pin_mut().TransferRoots(&ffi::Message_ProgressRange_ctor());

if status != ffi::IFSelect_ReturnStatus::IFSelect_RetDone {
return Err(Error::IgesReadFailed);
}

let inner = ffi::one_shape_iges(&reader);

Ok(Self { inner })
}

pub fn write_iges(&self, path: impl AsRef<Path>) -> Result<(), Error> {
let mut writer = ffi::IGESControl_Writer_ctor();

let success = ffi::add_shape(writer.pin_mut(), &self.inner);

if !success {
return Err(Error::IgesWriteFailed);
}

ffi::compute_model(writer.pin_mut());
let success =
ffi::write_iges(writer.pin_mut(), path.as_ref().to_string_lossy().to_string());

if success {
Ok(())
} else {
Err(Error::IgesWriteFailed)
}
}

#[must_use]
pub fn union(&self, other: &Shape) -> BooleanShape {
let mut fuse_operation = ffi::BRepAlgoAPI_Fuse_ctor(&self.inner, &other.inner);
Expand Down
6 changes: 3 additions & 3 deletions docs/writing_bindings.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,13 +191,13 @@ Standard_EXPORT TopoDS_Shape OneShape() const;
Unfortunately, this returns a bare `TopoDS_Shape` so we can't directly bind to it, we'll have to create a wrapper C++ function.

```rust
pub fn one_shape(reader: &STEPControl_Reader) -> UniquePtr<TopoDS_Shape>;
pub fn one_shape_step(reader: &STEPControl_Reader) -> UniquePtr<TopoDS_Shape>;
```

and

```c++
inline std::unique_ptr<TopoDS_Shape> one_shape(const STEPControl_Reader &reader) {
inline std::unique_ptr<TopoDS_Shape> one_shape_step(const STEPControl_Reader &reader) {
return std::unique_ptr<TopoDS_Shape>(new TopoDS_Shape(reader.OneShape()));
}
```
Expand Down Expand Up @@ -233,7 +233,7 @@ pub fn from_step_file<P: AsRef<Path>>(path: P) -> Shape {
read_step(reader.pin_mut(), path.as_ref().to_string_lossy().to_string());
reader.pin_mut().TransferRoots(&Message_ProgressRange_ctor());

let inner = one_shape(&reader);
let inner = one_shape_step(&reader);

// Assuming a Shape struct has a UniquePtr<TopoDS_Shape> field called `inner`
Shape { inner }
Expand Down
3 changes: 3 additions & 0 deletions examples/src/write_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ struct Args {
enum Format {
Step,
Stl,
Iges,
}

fn main() {
Expand All @@ -38,6 +39,7 @@ fn main() {
});

match format {
Format::Iges => model.write_iges(args.output).unwrap(),
Format::Step => model.write_step(args.output).unwrap(),
Format::Stl => model.write_stl(args.output).unwrap(),
}
Expand All @@ -47,6 +49,7 @@ fn determine_format(extension: &OsStr) -> Option<Format> {
match extension.to_ascii_lowercase().as_bytes() {
b"step" | b"stp" => Some(Format::Step),
b"stl" => Some(Format::Stl),
b"iges" | b"igs" => Some(Format::Iges),
_ => None,
}
}

0 comments on commit 5c8b5cf

Please sign in to comment.