TopExp_Explorer

Struct TopExp_Explorer 

Source
pub struct TopExp_Explorer { /* private fields */ }

Implementations§

Source§

impl TopExp_Explorer

Source

pub fn More(&self) -> bool

Examples found in repository?
examples/bottle.rs (line 86)
24pub fn main() {
25    let height = 70.0;
26    let width = 50.0;
27    let thickness = 30.0;
28
29    // Define the points making up the bottle's profile.
30    let point_1 = new_point(-width / 2.0, 0.0, 0.0);
31    let point_2 = new_point(-width / 2.0, -thickness / 4.0, 0.0);
32    let point_3 = new_point(0.0, -thickness / 2.0, 0.0);
33    let point_4 = new_point(width / 2.0, -thickness / 4.0, 0.0);
34    let point_5 = new_point(width / 2.0, 0.0, 0.0);
35
36    // Define the arcs and segments of the profile.
37    let arc = GC_MakeArcOfCircle_point_point_point(&point_2, &point_3, &point_4);
38    let segment_1 = GC_MakeSegment_point_point(&point_1, &point_2);
39    let segment_2 = GC_MakeSegment_point_point(&point_4, &point_5);
40
41    let mut edge_1 = BRepBuilderAPI_MakeEdge_HandleGeomCurve(
42        &new_HandleGeomCurve_from_HandleGeom_TrimmedCurve(&GC_MakeSegment_Value(&segment_1)),
43    );
44
45    let mut edge_2 = BRepBuilderAPI_MakeEdge_HandleGeomCurve(
46        &new_HandleGeomCurve_from_HandleGeom_TrimmedCurve(&GC_MakeArcOfCircle_Value(&arc)),
47    );
48
49    let mut edge_3 = BRepBuilderAPI_MakeEdge_HandleGeomCurve(
50        &new_HandleGeomCurve_from_HandleGeom_TrimmedCurve(&GC_MakeSegment_Value(&segment_2)),
51    );
52
53    let mut wire = BRepBuilderAPI_MakeWire_edge_edge_edge(
54        edge_1.pin_mut().Edge(),
55        edge_2.pin_mut().Edge(),
56        edge_3.pin_mut().Edge(),
57    );
58
59    let x_axis = gp_OX();
60
61    let mut transform = new_transform();
62    transform.pin_mut().set_mirror_axis(x_axis);
63
64    // We're calling Shape() here instead of Wire(), hope that's okay.
65    let mut brep_transform =
66        BRepBuilderAPI_Transform_ctor(wire.pin_mut().Shape(), &transform, false);
67    let mirrored_shape = brep_transform.pin_mut().Shape();
68    let mirrored_wire = TopoDS_cast_to_wire(mirrored_shape);
69
70    let mut make_wire = BRepBuilderAPI_MakeWire_ctor();
71    make_wire.pin_mut().add_wire(wire.pin_mut().Wire());
72    make_wire.pin_mut().add_wire(mirrored_wire);
73
74    let wire_profile = make_wire.pin_mut().Wire();
75
76    let mut face_profile = BRepBuilderAPI_MakeFace_wire(wire_profile, false);
77    let prism_vec = new_vec(0.0, 0.0, height);
78    // We're calling Shape here instead of Face(), hope that's also okay.
79    let mut body =
80        BRepPrimAPI_MakePrism_ctor(face_profile.pin_mut().Shape(), &prism_vec, false, true);
81
82    let mut make_fillet = BRepFilletAPI_MakeFillet_ctor(body.pin_mut().Shape());
83    let mut edge_explorer =
84        TopExp_Explorer_ctor(body.pin_mut().Shape(), TopAbs_ShapeEnum::TopAbs_EDGE);
85
86    while edge_explorer.More() {
87        let edge = TopoDS_cast_to_edge(edge_explorer.Current());
88        make_fillet.pin_mut().add_edge(thickness / 12.0, edge);
89        edge_explorer.pin_mut().Next();
90    }
91
92    let body_shape = make_fillet.pin_mut().Shape();
93
94    // Make the bottle neck
95    let neck_location = new_point(0.0, 0.0, height);
96    let neck_axis = gp_DZ();
97    let neck_coord_system = gp_Ax2_ctor(&neck_location, neck_axis);
98
99    let neck_radius = thickness / 4.0;
100    let neck_height = height / 10.0;
101
102    let mut cylinder = BRepPrimAPI_MakeCylinder_ctor(&neck_coord_system, neck_radius, neck_height);
103    let cylinder_shape = cylinder.pin_mut().Shape();
104
105    let mut fuse_neck = BRepAlgoAPI_Fuse_ctor(body_shape, cylinder_shape);
106    let body_shape = fuse_neck.pin_mut().Shape();
107
108    // Make the bottle hollow
109    let mut face_explorer = TopExp_Explorer_ctor(body_shape, TopAbs_ShapeEnum::TopAbs_FACE);
110    let mut z_max = -1.0;
111    let mut top_face: Option<UniquePtr<TopoDS_Face>> = None;
112
113    while face_explorer.More() {
114        let shape = ExplorerCurrentShape(&face_explorer);
115        let face = TopoDS_cast_to_face(&shape);
116
117        let surface = BRep_Tool_Surface(face);
118        let dynamic_type = DynamicType(&surface);
119        let name = type_name(dynamic_type);
120
121        if name == "Geom_Plane" {
122            let plane_handle = new_HandleGeomPlane_from_HandleGeomSurface(&surface);
123            let plane_location = handle_geom_plane_location(&plane_handle);
124
125            let plane_z = plane_location.Z();
126            if plane_z > z_max {
127                z_max = plane_z;
128                top_face = Some(TopoDS_Face_to_owned(face));
129            }
130        }
131
132        face_explorer.pin_mut().Next();
133    }
134
135    let top_face = top_face.unwrap();
136
137    let mut faces_to_remove = new_list_of_shape();
138    shape_list_append_face(faces_to_remove.pin_mut(), &top_face);
139
140    let mut solid_maker = BRepOffsetAPI_MakeThickSolid_ctor();
141    MakeThickSolidByJoin(
142        solid_maker.pin_mut(),
143        body_shape,
144        &faces_to_remove,
145        -thickness / 50.0,
146        1.0e-3,
147    );
148
149    let body_shape = solid_maker.pin_mut().Shape();
150
151    // Create the threading
152    let cylinder_axis = gp_Ax3_from_gp_Ax2(&neck_coord_system);
153    let cylinder_1 = Geom_CylindricalSurface_ctor(&cylinder_axis, neck_radius * 0.99);
154    let cylinder_1 = cylinder_to_surface(&cylinder_1);
155    let cylinder_2 = Geom_CylindricalSurface_ctor(&cylinder_axis, neck_radius * 1.05);
156    let cylinder_2 = cylinder_to_surface(&cylinder_2);
157
158    let a_pnt = new_point_2d(std::f64::consts::TAU, neck_height / 2.0);
159    let a_dir = gp_Dir2d_ctor(std::f64::consts::TAU, neck_height / 4.0);
160    let thread_axis = gp_Ax2d_ctor(&a_pnt, &a_dir);
161
162    let a_major = std::f64::consts::TAU;
163    let a_minor = neck_height / 10.0;
164
165    let ellipse_1 = Geom2d_Ellipse_ctor(&thread_axis, a_major, a_minor);
166    let ellipse_1_handle = ellipse_to_HandleGeom2d_Curve(&ellipse_1);
167    let ellipse_2 = Geom2d_Ellipse_ctor(&thread_axis, a_major, a_minor / 4.0);
168    let ellipse_2_handle = ellipse_to_HandleGeom2d_Curve(&ellipse_2);
169    let arc_1 = Geom2d_TrimmedCurve_ctor(&ellipse_1_handle, 0.0, std::f64::consts::PI);
170    let arc_1 = HandleGeom2d_TrimmedCurve_to_curve(&arc_1);
171    let arc_2 = Geom2d_TrimmedCurve_ctor(&ellipse_2_handle, 0.0, std::f64::consts::PI);
172    let arc_2 = HandleGeom2d_TrimmedCurve_to_curve(&arc_2);
173
174    let ellipse_point_1 = ellipse_value(&ellipse_1, 0.0);
175    let ellipse_point_2 = ellipse_value(&ellipse_1, std::f64::consts::PI);
176    let thread_segment = GCE2d_MakeSegment_point_point(&ellipse_point_1, &ellipse_point_2);
177    let thread_segment = HandleGeom2d_TrimmedCurve_to_curve(&thread_segment);
178
179    let mut edge_1_on_surface_1 = BRepBuilderAPI_MakeEdge_CurveSurface2d(&arc_1, &cylinder_1);
180    let mut edge_2_on_surface_1 =
181        BRepBuilderAPI_MakeEdge_CurveSurface2d(&thread_segment, &cylinder_1);
182    let mut edge_1_on_surface_2 = BRepBuilderAPI_MakeEdge_CurveSurface2d(&arc_2, &cylinder_2);
183    let mut edge_2_on_surface_2 =
184        BRepBuilderAPI_MakeEdge_CurveSurface2d(&thread_segment, &cylinder_2);
185
186    let mut threading_wire_1 = BRepBuilderAPI_MakeWire_edge_edge(
187        edge_1_on_surface_1.pin_mut().Edge(),
188        edge_2_on_surface_1.pin_mut().Edge(),
189    );
190    let mut threading_wire_2 = BRepBuilderAPI_MakeWire_edge_edge(
191        edge_1_on_surface_2.pin_mut().Edge(),
192        edge_2_on_surface_2.pin_mut().Edge(),
193    );
194
195    // TODO - does calling Shape() work here instead of Wire()?
196    BRepLibBuildCurves3d(threading_wire_1.pin_mut().Shape());
197    BRepLibBuildCurves3d(threading_wire_2.pin_mut().Shape());
198
199    let is_solid = true;
200    let mut threading_loft = BRepOffsetAPI_ThruSections_ctor(is_solid);
201    threading_loft.pin_mut().AddWire(threading_wire_1.pin_mut().Wire());
202    threading_loft.pin_mut().AddWire(threading_wire_2.pin_mut().Wire());
203    threading_loft.pin_mut().CheckCompatibility(false);
204
205    let threading_shape = threading_loft.pin_mut().Shape();
206
207    // Build the resulting compound
208    let mut compound = TopoDS_Compound_ctor();
209    let builder = BRep_Builder_ctor();
210    let builder = BRep_Builder_upcast_to_topods_builder(&builder);
211    builder.MakeCompound(compound.pin_mut());
212
213    let mut compound_shape = TopoDS_Compound_as_shape(compound);
214    builder.Add(compound_shape.pin_mut(), body_shape);
215    builder.Add(compound_shape.pin_mut(), threading_shape);
216
217    let final_shape = compound_shape;
218
219    // Export to an STL file
220    let mut stl_writer = StlAPI_Writer_ctor();
221    let triangulation = BRepMesh_IncrementalMesh_ctor(&final_shape, 0.01);
222    let success = write_stl(stl_writer.pin_mut(), triangulation.Shape(), "bottle.stl".to_owned());
223
224    println!("Done! Success = {success}");
225}
Source

pub fn Next(self: Pin<&mut Self>)

Examples found in repository?
examples/bottle.rs (line 89)
24pub fn main() {
25    let height = 70.0;
26    let width = 50.0;
27    let thickness = 30.0;
28
29    // Define the points making up the bottle's profile.
30    let point_1 = new_point(-width / 2.0, 0.0, 0.0);
31    let point_2 = new_point(-width / 2.0, -thickness / 4.0, 0.0);
32    let point_3 = new_point(0.0, -thickness / 2.0, 0.0);
33    let point_4 = new_point(width / 2.0, -thickness / 4.0, 0.0);
34    let point_5 = new_point(width / 2.0, 0.0, 0.0);
35
36    // Define the arcs and segments of the profile.
37    let arc = GC_MakeArcOfCircle_point_point_point(&point_2, &point_3, &point_4);
38    let segment_1 = GC_MakeSegment_point_point(&point_1, &point_2);
39    let segment_2 = GC_MakeSegment_point_point(&point_4, &point_5);
40
41    let mut edge_1 = BRepBuilderAPI_MakeEdge_HandleGeomCurve(
42        &new_HandleGeomCurve_from_HandleGeom_TrimmedCurve(&GC_MakeSegment_Value(&segment_1)),
43    );
44
45    let mut edge_2 = BRepBuilderAPI_MakeEdge_HandleGeomCurve(
46        &new_HandleGeomCurve_from_HandleGeom_TrimmedCurve(&GC_MakeArcOfCircle_Value(&arc)),
47    );
48
49    let mut edge_3 = BRepBuilderAPI_MakeEdge_HandleGeomCurve(
50        &new_HandleGeomCurve_from_HandleGeom_TrimmedCurve(&GC_MakeSegment_Value(&segment_2)),
51    );
52
53    let mut wire = BRepBuilderAPI_MakeWire_edge_edge_edge(
54        edge_1.pin_mut().Edge(),
55        edge_2.pin_mut().Edge(),
56        edge_3.pin_mut().Edge(),
57    );
58
59    let x_axis = gp_OX();
60
61    let mut transform = new_transform();
62    transform.pin_mut().set_mirror_axis(x_axis);
63
64    // We're calling Shape() here instead of Wire(), hope that's okay.
65    let mut brep_transform =
66        BRepBuilderAPI_Transform_ctor(wire.pin_mut().Shape(), &transform, false);
67    let mirrored_shape = brep_transform.pin_mut().Shape();
68    let mirrored_wire = TopoDS_cast_to_wire(mirrored_shape);
69
70    let mut make_wire = BRepBuilderAPI_MakeWire_ctor();
71    make_wire.pin_mut().add_wire(wire.pin_mut().Wire());
72    make_wire.pin_mut().add_wire(mirrored_wire);
73
74    let wire_profile = make_wire.pin_mut().Wire();
75
76    let mut face_profile = BRepBuilderAPI_MakeFace_wire(wire_profile, false);
77    let prism_vec = new_vec(0.0, 0.0, height);
78    // We're calling Shape here instead of Face(), hope that's also okay.
79    let mut body =
80        BRepPrimAPI_MakePrism_ctor(face_profile.pin_mut().Shape(), &prism_vec, false, true);
81
82    let mut make_fillet = BRepFilletAPI_MakeFillet_ctor(body.pin_mut().Shape());
83    let mut edge_explorer =
84        TopExp_Explorer_ctor(body.pin_mut().Shape(), TopAbs_ShapeEnum::TopAbs_EDGE);
85
86    while edge_explorer.More() {
87        let edge = TopoDS_cast_to_edge(edge_explorer.Current());
88        make_fillet.pin_mut().add_edge(thickness / 12.0, edge);
89        edge_explorer.pin_mut().Next();
90    }
91
92    let body_shape = make_fillet.pin_mut().Shape();
93
94    // Make the bottle neck
95    let neck_location = new_point(0.0, 0.0, height);
96    let neck_axis = gp_DZ();
97    let neck_coord_system = gp_Ax2_ctor(&neck_location, neck_axis);
98
99    let neck_radius = thickness / 4.0;
100    let neck_height = height / 10.0;
101
102    let mut cylinder = BRepPrimAPI_MakeCylinder_ctor(&neck_coord_system, neck_radius, neck_height);
103    let cylinder_shape = cylinder.pin_mut().Shape();
104
105    let mut fuse_neck = BRepAlgoAPI_Fuse_ctor(body_shape, cylinder_shape);
106    let body_shape = fuse_neck.pin_mut().Shape();
107
108    // Make the bottle hollow
109    let mut face_explorer = TopExp_Explorer_ctor(body_shape, TopAbs_ShapeEnum::TopAbs_FACE);
110    let mut z_max = -1.0;
111    let mut top_face: Option<UniquePtr<TopoDS_Face>> = None;
112
113    while face_explorer.More() {
114        let shape = ExplorerCurrentShape(&face_explorer);
115        let face = TopoDS_cast_to_face(&shape);
116
117        let surface = BRep_Tool_Surface(face);
118        let dynamic_type = DynamicType(&surface);
119        let name = type_name(dynamic_type);
120
121        if name == "Geom_Plane" {
122            let plane_handle = new_HandleGeomPlane_from_HandleGeomSurface(&surface);
123            let plane_location = handle_geom_plane_location(&plane_handle);
124
125            let plane_z = plane_location.Z();
126            if plane_z > z_max {
127                z_max = plane_z;
128                top_face = Some(TopoDS_Face_to_owned(face));
129            }
130        }
131
132        face_explorer.pin_mut().Next();
133    }
134
135    let top_face = top_face.unwrap();
136
137    let mut faces_to_remove = new_list_of_shape();
138    shape_list_append_face(faces_to_remove.pin_mut(), &top_face);
139
140    let mut solid_maker = BRepOffsetAPI_MakeThickSolid_ctor();
141    MakeThickSolidByJoin(
142        solid_maker.pin_mut(),
143        body_shape,
144        &faces_to_remove,
145        -thickness / 50.0,
146        1.0e-3,
147    );
148
149    let body_shape = solid_maker.pin_mut().Shape();
150
151    // Create the threading
152    let cylinder_axis = gp_Ax3_from_gp_Ax2(&neck_coord_system);
153    let cylinder_1 = Geom_CylindricalSurface_ctor(&cylinder_axis, neck_radius * 0.99);
154    let cylinder_1 = cylinder_to_surface(&cylinder_1);
155    let cylinder_2 = Geom_CylindricalSurface_ctor(&cylinder_axis, neck_radius * 1.05);
156    let cylinder_2 = cylinder_to_surface(&cylinder_2);
157
158    let a_pnt = new_point_2d(std::f64::consts::TAU, neck_height / 2.0);
159    let a_dir = gp_Dir2d_ctor(std::f64::consts::TAU, neck_height / 4.0);
160    let thread_axis = gp_Ax2d_ctor(&a_pnt, &a_dir);
161
162    let a_major = std::f64::consts::TAU;
163    let a_minor = neck_height / 10.0;
164
165    let ellipse_1 = Geom2d_Ellipse_ctor(&thread_axis, a_major, a_minor);
166    let ellipse_1_handle = ellipse_to_HandleGeom2d_Curve(&ellipse_1);
167    let ellipse_2 = Geom2d_Ellipse_ctor(&thread_axis, a_major, a_minor / 4.0);
168    let ellipse_2_handle = ellipse_to_HandleGeom2d_Curve(&ellipse_2);
169    let arc_1 = Geom2d_TrimmedCurve_ctor(&ellipse_1_handle, 0.0, std::f64::consts::PI);
170    let arc_1 = HandleGeom2d_TrimmedCurve_to_curve(&arc_1);
171    let arc_2 = Geom2d_TrimmedCurve_ctor(&ellipse_2_handle, 0.0, std::f64::consts::PI);
172    let arc_2 = HandleGeom2d_TrimmedCurve_to_curve(&arc_2);
173
174    let ellipse_point_1 = ellipse_value(&ellipse_1, 0.0);
175    let ellipse_point_2 = ellipse_value(&ellipse_1, std::f64::consts::PI);
176    let thread_segment = GCE2d_MakeSegment_point_point(&ellipse_point_1, &ellipse_point_2);
177    let thread_segment = HandleGeom2d_TrimmedCurve_to_curve(&thread_segment);
178
179    let mut edge_1_on_surface_1 = BRepBuilderAPI_MakeEdge_CurveSurface2d(&arc_1, &cylinder_1);
180    let mut edge_2_on_surface_1 =
181        BRepBuilderAPI_MakeEdge_CurveSurface2d(&thread_segment, &cylinder_1);
182    let mut edge_1_on_surface_2 = BRepBuilderAPI_MakeEdge_CurveSurface2d(&arc_2, &cylinder_2);
183    let mut edge_2_on_surface_2 =
184        BRepBuilderAPI_MakeEdge_CurveSurface2d(&thread_segment, &cylinder_2);
185
186    let mut threading_wire_1 = BRepBuilderAPI_MakeWire_edge_edge(
187        edge_1_on_surface_1.pin_mut().Edge(),
188        edge_2_on_surface_1.pin_mut().Edge(),
189    );
190    let mut threading_wire_2 = BRepBuilderAPI_MakeWire_edge_edge(
191        edge_1_on_surface_2.pin_mut().Edge(),
192        edge_2_on_surface_2.pin_mut().Edge(),
193    );
194
195    // TODO - does calling Shape() work here instead of Wire()?
196    BRepLibBuildCurves3d(threading_wire_1.pin_mut().Shape());
197    BRepLibBuildCurves3d(threading_wire_2.pin_mut().Shape());
198
199    let is_solid = true;
200    let mut threading_loft = BRepOffsetAPI_ThruSections_ctor(is_solid);
201    threading_loft.pin_mut().AddWire(threading_wire_1.pin_mut().Wire());
202    threading_loft.pin_mut().AddWire(threading_wire_2.pin_mut().Wire());
203    threading_loft.pin_mut().CheckCompatibility(false);
204
205    let threading_shape = threading_loft.pin_mut().Shape();
206
207    // Build the resulting compound
208    let mut compound = TopoDS_Compound_ctor();
209    let builder = BRep_Builder_ctor();
210    let builder = BRep_Builder_upcast_to_topods_builder(&builder);
211    builder.MakeCompound(compound.pin_mut());
212
213    let mut compound_shape = TopoDS_Compound_as_shape(compound);
214    builder.Add(compound_shape.pin_mut(), body_shape);
215    builder.Add(compound_shape.pin_mut(), threading_shape);
216
217    let final_shape = compound_shape;
218
219    // Export to an STL file
220    let mut stl_writer = StlAPI_Writer_ctor();
221    let triangulation = BRepMesh_IncrementalMesh_ctor(&final_shape, 0.01);
222    let success = write_stl(stl_writer.pin_mut(), triangulation.Shape(), "bottle.stl".to_owned());
223
224    println!("Done! Success = {success}");
225}
Source

pub fn Current(&self) -> &TopoDS_Shape

Examples found in repository?
examples/bottle.rs (line 87)
24pub fn main() {
25    let height = 70.0;
26    let width = 50.0;
27    let thickness = 30.0;
28
29    // Define the points making up the bottle's profile.
30    let point_1 = new_point(-width / 2.0, 0.0, 0.0);
31    let point_2 = new_point(-width / 2.0, -thickness / 4.0, 0.0);
32    let point_3 = new_point(0.0, -thickness / 2.0, 0.0);
33    let point_4 = new_point(width / 2.0, -thickness / 4.0, 0.0);
34    let point_5 = new_point(width / 2.0, 0.0, 0.0);
35
36    // Define the arcs and segments of the profile.
37    let arc = GC_MakeArcOfCircle_point_point_point(&point_2, &point_3, &point_4);
38    let segment_1 = GC_MakeSegment_point_point(&point_1, &point_2);
39    let segment_2 = GC_MakeSegment_point_point(&point_4, &point_5);
40
41    let mut edge_1 = BRepBuilderAPI_MakeEdge_HandleGeomCurve(
42        &new_HandleGeomCurve_from_HandleGeom_TrimmedCurve(&GC_MakeSegment_Value(&segment_1)),
43    );
44
45    let mut edge_2 = BRepBuilderAPI_MakeEdge_HandleGeomCurve(
46        &new_HandleGeomCurve_from_HandleGeom_TrimmedCurve(&GC_MakeArcOfCircle_Value(&arc)),
47    );
48
49    let mut edge_3 = BRepBuilderAPI_MakeEdge_HandleGeomCurve(
50        &new_HandleGeomCurve_from_HandleGeom_TrimmedCurve(&GC_MakeSegment_Value(&segment_2)),
51    );
52
53    let mut wire = BRepBuilderAPI_MakeWire_edge_edge_edge(
54        edge_1.pin_mut().Edge(),
55        edge_2.pin_mut().Edge(),
56        edge_3.pin_mut().Edge(),
57    );
58
59    let x_axis = gp_OX();
60
61    let mut transform = new_transform();
62    transform.pin_mut().set_mirror_axis(x_axis);
63
64    // We're calling Shape() here instead of Wire(), hope that's okay.
65    let mut brep_transform =
66        BRepBuilderAPI_Transform_ctor(wire.pin_mut().Shape(), &transform, false);
67    let mirrored_shape = brep_transform.pin_mut().Shape();
68    let mirrored_wire = TopoDS_cast_to_wire(mirrored_shape);
69
70    let mut make_wire = BRepBuilderAPI_MakeWire_ctor();
71    make_wire.pin_mut().add_wire(wire.pin_mut().Wire());
72    make_wire.pin_mut().add_wire(mirrored_wire);
73
74    let wire_profile = make_wire.pin_mut().Wire();
75
76    let mut face_profile = BRepBuilderAPI_MakeFace_wire(wire_profile, false);
77    let prism_vec = new_vec(0.0, 0.0, height);
78    // We're calling Shape here instead of Face(), hope that's also okay.
79    let mut body =
80        BRepPrimAPI_MakePrism_ctor(face_profile.pin_mut().Shape(), &prism_vec, false, true);
81
82    let mut make_fillet = BRepFilletAPI_MakeFillet_ctor(body.pin_mut().Shape());
83    let mut edge_explorer =
84        TopExp_Explorer_ctor(body.pin_mut().Shape(), TopAbs_ShapeEnum::TopAbs_EDGE);
85
86    while edge_explorer.More() {
87        let edge = TopoDS_cast_to_edge(edge_explorer.Current());
88        make_fillet.pin_mut().add_edge(thickness / 12.0, edge);
89        edge_explorer.pin_mut().Next();
90    }
91
92    let body_shape = make_fillet.pin_mut().Shape();
93
94    // Make the bottle neck
95    let neck_location = new_point(0.0, 0.0, height);
96    let neck_axis = gp_DZ();
97    let neck_coord_system = gp_Ax2_ctor(&neck_location, neck_axis);
98
99    let neck_radius = thickness / 4.0;
100    let neck_height = height / 10.0;
101
102    let mut cylinder = BRepPrimAPI_MakeCylinder_ctor(&neck_coord_system, neck_radius, neck_height);
103    let cylinder_shape = cylinder.pin_mut().Shape();
104
105    let mut fuse_neck = BRepAlgoAPI_Fuse_ctor(body_shape, cylinder_shape);
106    let body_shape = fuse_neck.pin_mut().Shape();
107
108    // Make the bottle hollow
109    let mut face_explorer = TopExp_Explorer_ctor(body_shape, TopAbs_ShapeEnum::TopAbs_FACE);
110    let mut z_max = -1.0;
111    let mut top_face: Option<UniquePtr<TopoDS_Face>> = None;
112
113    while face_explorer.More() {
114        let shape = ExplorerCurrentShape(&face_explorer);
115        let face = TopoDS_cast_to_face(&shape);
116
117        let surface = BRep_Tool_Surface(face);
118        let dynamic_type = DynamicType(&surface);
119        let name = type_name(dynamic_type);
120
121        if name == "Geom_Plane" {
122            let plane_handle = new_HandleGeomPlane_from_HandleGeomSurface(&surface);
123            let plane_location = handle_geom_plane_location(&plane_handle);
124
125            let plane_z = plane_location.Z();
126            if plane_z > z_max {
127                z_max = plane_z;
128                top_face = Some(TopoDS_Face_to_owned(face));
129            }
130        }
131
132        face_explorer.pin_mut().Next();
133    }
134
135    let top_face = top_face.unwrap();
136
137    let mut faces_to_remove = new_list_of_shape();
138    shape_list_append_face(faces_to_remove.pin_mut(), &top_face);
139
140    let mut solid_maker = BRepOffsetAPI_MakeThickSolid_ctor();
141    MakeThickSolidByJoin(
142        solid_maker.pin_mut(),
143        body_shape,
144        &faces_to_remove,
145        -thickness / 50.0,
146        1.0e-3,
147    );
148
149    let body_shape = solid_maker.pin_mut().Shape();
150
151    // Create the threading
152    let cylinder_axis = gp_Ax3_from_gp_Ax2(&neck_coord_system);
153    let cylinder_1 = Geom_CylindricalSurface_ctor(&cylinder_axis, neck_radius * 0.99);
154    let cylinder_1 = cylinder_to_surface(&cylinder_1);
155    let cylinder_2 = Geom_CylindricalSurface_ctor(&cylinder_axis, neck_radius * 1.05);
156    let cylinder_2 = cylinder_to_surface(&cylinder_2);
157
158    let a_pnt = new_point_2d(std::f64::consts::TAU, neck_height / 2.0);
159    let a_dir = gp_Dir2d_ctor(std::f64::consts::TAU, neck_height / 4.0);
160    let thread_axis = gp_Ax2d_ctor(&a_pnt, &a_dir);
161
162    let a_major = std::f64::consts::TAU;
163    let a_minor = neck_height / 10.0;
164
165    let ellipse_1 = Geom2d_Ellipse_ctor(&thread_axis, a_major, a_minor);
166    let ellipse_1_handle = ellipse_to_HandleGeom2d_Curve(&ellipse_1);
167    let ellipse_2 = Geom2d_Ellipse_ctor(&thread_axis, a_major, a_minor / 4.0);
168    let ellipse_2_handle = ellipse_to_HandleGeom2d_Curve(&ellipse_2);
169    let arc_1 = Geom2d_TrimmedCurve_ctor(&ellipse_1_handle, 0.0, std::f64::consts::PI);
170    let arc_1 = HandleGeom2d_TrimmedCurve_to_curve(&arc_1);
171    let arc_2 = Geom2d_TrimmedCurve_ctor(&ellipse_2_handle, 0.0, std::f64::consts::PI);
172    let arc_2 = HandleGeom2d_TrimmedCurve_to_curve(&arc_2);
173
174    let ellipse_point_1 = ellipse_value(&ellipse_1, 0.0);
175    let ellipse_point_2 = ellipse_value(&ellipse_1, std::f64::consts::PI);
176    let thread_segment = GCE2d_MakeSegment_point_point(&ellipse_point_1, &ellipse_point_2);
177    let thread_segment = HandleGeom2d_TrimmedCurve_to_curve(&thread_segment);
178
179    let mut edge_1_on_surface_1 = BRepBuilderAPI_MakeEdge_CurveSurface2d(&arc_1, &cylinder_1);
180    let mut edge_2_on_surface_1 =
181        BRepBuilderAPI_MakeEdge_CurveSurface2d(&thread_segment, &cylinder_1);
182    let mut edge_1_on_surface_2 = BRepBuilderAPI_MakeEdge_CurveSurface2d(&arc_2, &cylinder_2);
183    let mut edge_2_on_surface_2 =
184        BRepBuilderAPI_MakeEdge_CurveSurface2d(&thread_segment, &cylinder_2);
185
186    let mut threading_wire_1 = BRepBuilderAPI_MakeWire_edge_edge(
187        edge_1_on_surface_1.pin_mut().Edge(),
188        edge_2_on_surface_1.pin_mut().Edge(),
189    );
190    let mut threading_wire_2 = BRepBuilderAPI_MakeWire_edge_edge(
191        edge_1_on_surface_2.pin_mut().Edge(),
192        edge_2_on_surface_2.pin_mut().Edge(),
193    );
194
195    // TODO - does calling Shape() work here instead of Wire()?
196    BRepLibBuildCurves3d(threading_wire_1.pin_mut().Shape());
197    BRepLibBuildCurves3d(threading_wire_2.pin_mut().Shape());
198
199    let is_solid = true;
200    let mut threading_loft = BRepOffsetAPI_ThruSections_ctor(is_solid);
201    threading_loft.pin_mut().AddWire(threading_wire_1.pin_mut().Wire());
202    threading_loft.pin_mut().AddWire(threading_wire_2.pin_mut().Wire());
203    threading_loft.pin_mut().CheckCompatibility(false);
204
205    let threading_shape = threading_loft.pin_mut().Shape();
206
207    // Build the resulting compound
208    let mut compound = TopoDS_Compound_ctor();
209    let builder = BRep_Builder_ctor();
210    let builder = BRep_Builder_upcast_to_topods_builder(&builder);
211    builder.MakeCompound(compound.pin_mut());
212
213    let mut compound_shape = TopoDS_Compound_as_shape(compound);
214    builder.Add(compound_shape.pin_mut(), body_shape);
215    builder.Add(compound_shape.pin_mut(), threading_shape);
216
217    let final_shape = compound_shape;
218
219    // Export to an STL file
220    let mut stl_writer = StlAPI_Writer_ctor();
221    let triangulation = BRepMesh_IncrementalMesh_ctor(&final_shape, 0.01);
222    let success = write_stl(stl_writer.pin_mut(), triangulation.Shape(), "bottle.stl".to_owned());
223
224    println!("Done! Success = {success}");
225}

Trait Implementations§

Source§

impl ExternType for TopExp_Explorer

Source§

type Kind = Opaque

Source§

type Id

A type-level representation of the type’s C++ namespace and type name. Read more
Source§

impl UniquePtrTarget for TopExp_Explorer

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.