Expand description
StepBuilder — the convenience authoring layer over the strict
Ap242Author constructors.
new lays down the skeleton every exporter needs
(application protocol, product contexts, units —
new_with to choose them);
finish assembles everything added so far and
returns the Part 21 text.
The core is parts and their shape. part adds one
product with its full definition chain
(part_with also sets part number / version /
descriptions). Topology mirrors the kernel’s own —
vertex → edge →
face → solid, with analytic
surfaces and curves as plain inputs (SurfaceInput, CurveInput,
ProfileInput). Assemblies are one
place(parent, child, at) call per placed
instance, the child’s definition shared between them.
Everything else is one call each. mesh attaches a
display mesh (vertex array + index triangles), optionally linked to the
b-rep solid it renders. style colours a solid or
a single face, with optional transparency; layer,
hide, and hide_layer
manage presentation layers and default visibility.
contributor,
approve, document,
and security attach PLM records to a part’s
version, with people as shared
person_and_org handles.
header fills the Part 21 file header.
Anything the builder does not cover is still reachable:
author hands out the underlying Ap242Author,
and ids cross freely between the two levels.
The minimal flow — a planar part handed over from a kernel:
use step_io::build::{CurveInput, FaceBoundInput, Frame, SurfaceInput};
let mut b = step_io::StepBuilder::new().unwrap();
let plate = b.part("plate").unwrap();
let vs: Vec<_> = kernel.points.iter()
.map(|p| b.vertex(*p).unwrap())
.collect();
let es: Vec<_> = kernel.edges.iter()
.map(|e| b.edge(vs[e.start], vs[e.end], CurveInput::Line).unwrap())
.collect();
let fs: Vec<_> = kernel.faces.iter()
.map(|f| {
let plane = Frame { origin: f.origin, axis: f.normal, ref_dir: f.x_dir };
let bound = f.bound.iter().map(|&i| (es[i], true)).collect();
b.face(SurfaceInput::Plane(plane), true, vec![FaceBoundInput::outer(bound)])
.unwrap()
})
.collect();
b.solid(plate, "plate body", fs).unwrap();
std::fs::write("plate.step", b.finish().unwrap()).unwrap();The full tour — assembly, display mesh, presentation, metadata, header:
use step_io::build::{
ApprovalInput, Frame, HeaderInput, MeshInput, MeshNormalsInput, PersonOrg,
Rgb, StyleTarget,
};
let mut b = step_io::StepBuilder::new().unwrap();
b.header(&HeaderInput {
file_name: Some("car.step".into()),
organizations: vec!["ACME".into()],
originating_system: Some("MyKernel 2.1".into()),
..Default::default() // timestamp auto-stamped
});
let car = b.part("car").unwrap();
let wheel = b.part("wheel").unwrap();
let wheel_faces = faces(&mut b); // b-rep translated as in the minimal flow
let body = b.solid(wheel, "wheel body", wheel_faces).unwrap();
// One placed instance per call; the wheel's definition is shared.
let z = [0.0, 0.0, 1.0];
let x = [1.0, 0.0, 0.0];
b.place(car, wheel, Frame { origin: [900.0, 700.0, 300.0], axis: z, ref_dir: x }).unwrap();
b.place(car, wheel, Frame { origin: [900.0, -700.0, 300.0], axis: z, ref_dir: x }).unwrap();
// Display mesh (the kernel's tessellation) linked to the b-rep it renders.
b.mesh(wheel, "wheel mesh", &MeshInput {
points: kernel.mesh_points,
triangles: kernel.mesh_triangles,
normals: MeshNormalsInput::None,
}, Some(body.into())).unwrap();
// Presentation: colour/transparency, layers, default visibility.
b.style(StyleTarget::Solid(body), Rgb { red: 0.8, green: 0.2, blue: 0.1 }, None).unwrap();
let hidden = b.layer("REFERENCE", vec![StyleTarget::Solid(body)]).unwrap();
b.hide_layer(hidden);
// PLM metadata on the part's version.
let john = b.person_and_org(&PersonOrg {
person_id: "p1".into(),
first_name: Some("John".into()),
last_name: Some("Doe".into()),
organization: "ACME".into(),
}).unwrap();
b.contributor(wheel, "creator", john).unwrap();
b.approve(wheel, &ApprovalInput {
status: "approved".into(),
level: "final".into(),
approvers: vec![(john, "approver".into())],
date: None,
}).unwrap();
let text = b.finish().unwrap();Re-exports§
pub use crate::scene::NurbsCurve;pub use crate::scene::NurbsSurface;pub use crate::scene::Rgb;
Structs§
- Approval
Input - One approval for
StepBuilder::approve: a status word (customarily"approved"), a level, any number of approvers with their roles, and an optional approval date. - Date
Time Input - A calendar date with wall-clock time (no time zone — emitted as UTC).
- Document
Input - An external document reference for
StepBuilder::document. - Face
Bound Input - One face bound for
StepBuilder::face: the loop’s edges with their per-edge direction, whether this is the outer bound, and the bound’s own orientation flag. - Frame
- A right-handed placement frame:
originplus theaxis(local Z) andref_dir(local X) directions — the builder’s input forAXIS2_PLACEMENT_3D. Directions are passed through as given (kernels supply unit vectors); geometric well-formedness is the caller’s responsibility. - Header
Input - Part 21 HEADER fields for
StepBuilder::header. Everything defaults to empty except the pieces the builder supplies itself: the timestamp (current UTC time unless overridden) and the preprocessor stamp (alwaysstep-io <version>). - Mesh
Input - A display mesh for
StepBuilder::mesh: a vertex array plus 0-based index triangles — the plain form kernels and renderers already hold. - Part
- Handle for a part created by
StepBuilder::part— an index into the builder that created it. Passing it to a different builder panics (out of range) or silently targets the wrong part (in range). - Part
Options - Optional overrides for
StepBuilder::part_with— every field defaults to the plainpartbehaviour. - Person
Org - A person at an organization, for
StepBuilder::person_and_org. - Step
Builder - Ergonomic writer for the standard AP242 file shape: shared contexts and
units up front, one product chain per
part, everything bound and emitted byfinish. - Units
Input - Unit setup for
StepBuilder::new_with; the default is what plainnewuses (millimetre, 1e-7 uncertainty). - Vertex
- Handle for a vertex created by
StepBuilder::vertex— an index into the builder that created it (a different builder’s handle panics or targets the wrong vertex). The builder keeps the vertex position so straight edges can derive their line geometry.
Enums§
- Curve
Input - Curve input for
StepBuilder::edge.NurbsCurvemirrors the read-sideto_nurbs()type; seeSurfaceInputfor the rational/non-rational split. - Length
Unit - The file’s length unit, chosen at
StepBuilder::new_withtime (a unit context is a file-global entity every shape references). - Mesh
Normals Input - Normals for a
MeshInput, mirroring what the read side exposes: none, one for the whole mesh, or one per vertex (row count must match the point count — a mismatch is the caller’s responsibility). - Profile
Input - A profile curve for the swept surfaces — plain geometry, no vertices
(unlike
CurveInput::Line, which derives from edge vertices). - Solid
Ref - Which solid a display mesh tessellates (
StepBuilder::mesh): a plainsolidor one with voids (solid_with_voids). The id types convert withInto, soSome(body.into())works for either. - Style
Target - What a
StepBuilder::stylecall colours: a whole solid (with or without voids) or one face — the targets the read-sideSceneresolves styles for. - Surface
Input - Surface input for
StepBuilder::face: the stored analytic forms, plus NURBS for everything else —NurbsSurfaceis the same typeSurface::to_nurbs()returns on the read side, so read-side output can be fed straight back in. Non-rational data (all weights1.0) becomes a plainB_SPLINE_SURFACE_WITH_KNOTS; rational data becomes the customary multi-part complex instance. - Void
Shell Normals - Which way the face normals of the void shells passed to
StepBuilder::solid_with_voidspoint. The caller declares this so step-io can orient each cavity’sORIENTED_CLOSED_SHELLcorrectly without evaluating geometry. See that method for how to choose.