Skip to content

Commit fc6b069

Browse files
authored
write multiple shapes to one STEP file (#226)
* add writing multiple shapes to one STEP file - Add write_all_step to transfers multiple shapes to a single step writer - Refactor write_step to delegate to write_all_step - Add StepWriteNoShapes error for empty input - Add StepWriteTransferFailed error to distinguish transfer failures * fix clippy errors
1 parent 625666c commit fc6b069

2 files changed

Lines changed: 66 additions & 3 deletions

File tree

crates/opencascade/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ pub enum Error {
2121
IgesReadFailed,
2222
#[error("failed to read KiCAD PCB file: {0}")]
2323
KicadReadFailed(#[from] kicad_parser::Error),
24+
#[error("at least one shape is required to write a STEP file")]
25+
StepWriteNoShapes,
26+
#[error("failed to transfer shape to STEP writer")]
27+
StepWriteTransferFailed,
2428
#[error("failed to write STEP file")]
2529
StepWriteFailed,
2630
#[error("failed to write IGES file")]

crates/opencascade/src/primitives/shape.rs

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -568,12 +568,28 @@ impl Shape {
568568
}
569569

570570
pub fn write_step(&self, path: impl AsRef<Path>) -> Result<(), Error> {
571+
Self::write_all_step(std::iter::once(self), path)
572+
}
573+
574+
pub fn write_all_step<T: AsRef<Shape>>(
575+
shapes: impl IntoIterator<Item = T>,
576+
path: impl AsRef<Path>,
577+
) -> Result<(), Error> {
571578
let mut writer = ffi::step_control::STEPControl_Writer_new();
579+
let mut count = 0;
572580

573-
let status = ffi::step_control::transfer_shape(writer.pin_mut(), &self.inner);
581+
for shape in shapes {
582+
let status = ffi::step_control::transfer_shape(writer.pin_mut(), &shape.as_ref().inner);
574583

575-
if status != ffi::if_select::IFSelect_ReturnStatus::IFSelect_RetDone {
576-
return Err(Error::StepWriteFailed);
584+
if status != ffi::if_select::IFSelect_ReturnStatus::IFSelect_RetDone {
585+
return Err(Error::StepWriteTransferFailed);
586+
}
587+
588+
count += 1;
589+
}
590+
591+
if count == 0 {
592+
return Err(Error::StepWriteNoShapes);
577593
}
578594

579595
let status = ffi::step_control::write_step(
@@ -1019,4 +1035,47 @@ mod tests {
10191035
let shape = face_shape();
10201036
let _solid = shape.expect_solid();
10211037
}
1038+
1039+
#[test]
1040+
fn test_write_step() {
1041+
let shape = solid_shape();
1042+
let path = std::env::temp_dir().join("test_write_step.step");
1043+
let result = shape.write_step(&path);
1044+
assert!(result.is_ok());
1045+
assert!(path.exists());
1046+
assert!(path.metadata().unwrap().len() > 0);
1047+
let _ = std::fs::remove_file(&path);
1048+
}
1049+
1050+
#[test]
1051+
fn test_write_all_step_one_shape() {
1052+
let shape = solid_shape();
1053+
let path = std::env::temp_dir().join("test_write_all_step_one.step");
1054+
let result = Shape::write_all_step([&shape], &path);
1055+
assert!(result.is_ok());
1056+
assert!(path.exists());
1057+
assert!(path.metadata().unwrap().len() > 0);
1058+
let _ = std::fs::remove_file(&path);
1059+
}
1060+
1061+
#[test]
1062+
fn test_write_all_step_multiple_shapes() {
1063+
let s1 = Shape::box_centered(10.0, 10.0, 10.0);
1064+
let s2 = Shape::sphere(5.0).at(glam::DVec3::new(20.0, 0.0, 0.0)).build();
1065+
let s3 = Shape::cylinder_radius_height(3.0, 15.0);
1066+
let path = std::env::temp_dir().join("test_write_all_step_multi.step");
1067+
let result = Shape::write_all_step([&s1, &s2, &s3], &path);
1068+
assert!(result.is_ok());
1069+
assert!(path.exists());
1070+
assert!(path.metadata().unwrap().len() > 0);
1071+
let _ = std::fs::remove_file(&path);
1072+
}
1073+
1074+
#[test]
1075+
fn test_write_all_step_empty() {
1076+
let path = std::env::temp_dir().join("test_write_all_step_empty.step");
1077+
let result = Shape::write_all_step(std::iter::empty::<&Shape>(), &path);
1078+
assert!(result.is_err());
1079+
assert!(!path.exists());
1080+
}
10221081
}

0 commit comments

Comments
 (0)