Overview
This tutorial introduces the basic usage of AMCAX STEP Reader and AMCAX STEP Writer.
Prerequisites
Developers should have the following background knowledge:
- Modern C++ programming (C++17 or later)
- 3D geometric modeling
- B-Rep topology structure
The AMCAX kernel and STEPReader / STEPWriter are developed in C++17, making extensive use of STL containers and algorithms.
Import Section
Include headers
Represents a product in the STEP standard with geometry and style information.
Class for translating STEP files into TopoShape objects, with support for styles.
Currently, the STEP module provides 3 types of Reader variants:
- STEPReader: basic version, only supports translating a STEP file into TopoShape.
- STEPStyledReader: supports reading more complete data (recommended).
- STEPLabelReader: supports additional annotation information.
This tutorial will use STEPStyledReader for demonstration.
Create a Reader object
Reader does not provide static functions; all operations are performed through class instances. You can pass a std::istream, such as cin, ifstream, etc. The Reader does not manage its lifecycle.
std::ifstream ifs("/path/to/input.STEP", std::ios::binary);
if (!ifs.is_open()) {
return 1;
}
Class for translating STEP files into TopoShape objects, with support for styles.
Definition STEPStyledReader.hpp:34
You can also pass a file path directly:
(Optional) Set units
Since the kernel has no concept of units, units in imported data need to be handled via Reader by applying scaling. By default, 1 millimeter is assumed. You can disable scaling or change units with:
reader.SetTargetUnit(AMCAX::STEP::STEPLengthUnit::Presets::NOSCALE);
After parsing, you can obtain the original file’s unit via STEPStyledReader::GetUnit() or STEPStyledProduct::Factors().
(Optional) Set progress reporting
A callback function can be used to receive progress updates:
reader.SetProgressCallback(
std::cout << " State: " << int(state) << std::endl;
std::cout << " Message1: " << c1.payload.u64 << std::endl;
std::cout << " Message2: " << c2.payload.u64 << std::endl;
}
});
Encapsulates a specific state value in the STEP process (reader or writer).
Definition STEPProgress.hpp:56
Message object used to report progress values in the STEP process.
Definition STEPProgress.hpp:18
@ U64_TYPE
Payload contains uint64_t.
Definition STEPProgress.hpp:30
Message1 indicates the processed shape index, Message2 indicates the total shape count. In multithreaded scenarios, Message1 may not be sequential.
Read file
Although the Reader object opens the file upon construction, reading and translation actually begin only when reader::Read() is called.
bool topo_success = reader.Read();
Read() is blocking until parsing finishes, returning false on failure. When initialized with std::istream, the stream must remain valid during parsing.
(Optional) Event callback
You can provide a STEPDataCallback to receive intermediate results during parsing:
bool topo_success = reader.Read([&reader](AMCAX::STEP::DataEvent e,
const std::shared_ptr<AMCAX::STEP::STEPStyledProduct>& p,
size_t rep_idx) {
switch (e) {
case AMCAX::STEP::DataEvent::ProductReady:
break;
case AMCAX::STEP::DataEvent::ShapeReady:
break;
case AMCAX::STEP::DataEvent::LabelReady:
break;
default:;
}
});
Note: The callback runs in the parser thread; heavy logic may reduce performance.
Prepare result container
std::vector<std::shared_ptr<AMCAX::STEP::STEPStyledProduct>> products;
For the simpler STEPReader or STEPLabelReader (with AMCAXAF::Label), there are corresponding STEPProduct or STEPLabelProduct types.
Retrieve results
products = std::move(reader.GetProducts());
products contains multiple STEPStyledProduct, each corresponding to a Product entity in the STEP file.
Shadow nodes
Shadow nodes only contain translation/rotation information, checkable with IsShadow():
using ProductPtr = std::shared_ptr<STEPStyledProduct>;
void ConvertToNormal(ProductPtr& root) {
if (root->IsShadow()) {
root->MarkNormal();
}
for (size_t i = 0; i < root->ChildrenSize(); ++i) {
ConvertToNormal(root->ChildAt(i));
}
}
(Optional) Flatten tree structure
If only the position of each Topology Shape matters and assembly hierarchy is irrelevant, STEPTool provides functions to flatten the hierarchy into a 1-D array.
Get sub-shape properties
auto treeroot = products[0];
const auto& props = treeroot->PropertyAt(0);
{
auto solid = exp.Current();
auto it = props.find(solid);
if (it != props.end()) {
const ShapeRGBA& color = property.GetColor();
if (color) {
}
}
}
Represents a property attached to a STEP entity (e.g., name, style, visibility).
Definition ShapeProperty.hpp:28
Class of a tool for exploring the B-Rep structure.
Definition TopoExplorer.hpp:14
AMCAX_API bool More() const noexcept
Does the explorer have more shapes.
Base class of shape, containing an underlying shape with a location and an orientation.
Definition TopoShape.hpp:15
Extract overall TopoShape
Use OneShape() or STEPTool::MakeCompound() to obtain a complete TopoShape:
for (auto node : reader.GetProducts()) {
TopoShape s1 = node->OneShape(false);
TopoShape s2 = node->OneShape(true);
}
Export Section
Include header
Class for exporting TopoShape objects and related data to STEP files.
Unlike Reader, the Writer is not split into variants; all types of Products can be written directly.
Create Writer object
Class for exporting TopoShape objects and related data to STEP files.
Definition STEPWriter.hpp:34
Or using an output stream:
std::ofstream ofs("/path/to/output.STEP");
(Optional) Set units
Although STEPWriter does not rescale data, since the kernel has no unit concept, you must manually specify what units to write in the STEP file. Default is 1 millimeter.
writer.SetOutputUnit(AMCAX::STEP::STEPLengthUnit::Presets::CENTIMETRE);
(Optional) Set progress callback
Like Reader, Writer provides a two-parameter progress callback:
writer.SetProgressCallback(
{
std::cout << " State: " << int(state) << std::endl;
std::cout << " Message1: " << c1.payload.u64 << std::endl;
std::cout << " Message2: " << c2.payload.u64 << std::endl;
}
});
Export Product or TopoShape
Export individually:
for (auto& p : products) {
writer.WriteShape(p);
}
for (auto& s : std::vector{ TopoShape{} }) {
writer.WriteShape(s);
}
Or export an entire array at once:
writer.WriteShapes(products);
Since the Writer always favors maintaining the tree structure of Products, both ways produce the same output structure.
Export Label
STEP format allows attaching custom attributes to shapes. The kernel uses the Label format for property data.
writer.WriteShape(root);
The class of Label.
Definition Label.hpp:27
Finalize export
After exporting, it is recommended to call the following to append the STEP file footer and close the file:
If the user does not explicitly call Done(), STEPWriter’s destructor ensures the same operation is performed.
Simplified interface
If you only need the final Topology Shape, you can use simplified methods in STEPTool:
}
AMCAX_API bool IsNull() const noexcept
Is the shape null.
Click here example01 to download the complete Reader source code as example01.
Appendix Example
#include <iostream>
void printProductName(const std::shared_ptr<AMCAX::STEP::STEPStyledProduct>& node, int indent = 0)
{
for (int i = 0; i < indent; ++i) {
std::cout << "| ";
if (node->IsShadow()) {
std::cout << "SHADOW: " << node->ProductName() << std::endl;
}
else {
std::cout << node->ProductName() << std::endl;
for (auto& child : node->Children()) {
printProductName(child, indent + 1);
}
}
}
}
void printSolidName(const std::shared_ptr<AMCAX::STEP::STEPStyledProduct>& node, int indent = 0)
{
for (size_t i = 0; i < node->ShapesSize(); ++i)
{
const auto& origShape = node->ShapeAt(i);
const auto& props = node->PropertyAt(i);
SolidExp.
More(); SolidExp.Next())
{
const auto& solid = SolidExp.Current();
auto it = props.find(solid);
if (it != props.end() && it->second.NameHasValue())
{
std::string name = it->second.GetName();
std::cout << '\"' << name << '\"' << std::endl;
}
}
}
for (auto& child : node->Children())
{
printSolidName(child, indent + 1);
}
}
int main()
{
std::vector<std::shared_ptr<AMCAX::STEP::STEPStyledProduct>> products;
reader.SetTargetUnit(AMCAX::STEP::STEPLengthUnit::Presets::METRE);
bool topo_success = reader.Read();
if (!topo_success) return -1;
products = reader.GetProducts();
for (auto root : products)
{
printProductName(root);
printSolidName(root);
}
writer.SetOutputUnit(AMCAX::STEP::STEPLengthUnit::Presets::METRE);
writer.WriteShapes(products);
writer.Done();
}
Class of a tool for exploring the B-Rep structure.
Class of iterator for B-Rep structure.