Overview
This tutorial provides basic instructions on how to use the AMCAX STEP Reader (hereafter referred to as Reader or TopoShape Reader) and AMCAX STEP Writer (hereafter referred to as Writer). In addition, this module also provides the AMCAX STEP Mesh Reader (hereafter referred to as Mesh Reader) for converting read data into Mesh format. However, an interface for exporting Mesh data using the STEP protocol is currently not available.
Required Knowledge
The developers need to have some basic knowledge including the modern C++ programming language, 3D geometric modeling concepts, and the B-Rep topology structure. In specific, the AMCAX kernel and the AMCAX STEP Reader / Writer are designed and implemented using C++ 17 standard, and STL containers and algorithms are used as basic data structures and utilities. The geometric entities are represented by a Boundary-Representation (B-Rep) structure, including geometry objects and topology structures.
The Reader Section
Import The Header Files
TopoShape Reader
The AMCAXStep module provides a header file for Reader:
Class used for translating STEP file to TopoShape objects.
Mesh Reader
And there is also a header file for Mesh Reader. You need to make sure the macro for traits is defined before importing the header file:
#define AMCAXMeshing_Enable_CommonTraits
Class for reading STEP file and convert solid to mesh.
Or, if the macro is already defined in compiler flags:
You only need to include the corresponding header file to use Mesh Reader.
Declare And Construct A Reader Instance
The STEP Reader does not provide static functions, so all calls must be made using an instance. To read a STEP file, a reader instance is required.
TopoShape Reader
When constructing, you need to pass a filename (std::string) or input stream (std::istream) as a parameter:
std::ifstream ifs("/path/to/input.step");
if (!ifs.is_open())
{
return 1;
}
Class used for translating STEP file to TopoShape objects.
Definition: StepReader.hpp:26
Or
Mesh Reader
Similarly, you can construct a Mesh Reader instance with following code:
MeshReader reader(ifs);
Class for reading STEP file and convert solid to mesh.
Definition: StepMeshReader.hpp:26
Or
MeshReader reader("/path/to/input.step");
(Optional) Configure The Scaling Behavior
By default, Reader will use millimeter as the unit length and scale all imported graphics according to the input length factor. This behavior can be configured via following code:
reader.SetUnit(AMCAX::STEP::StepLengthUnit::PresetLengthUnit::NOSCALE);
The input length factor can be accessed via GetUnit() or StepData::Factors()/StepMeshData::Factors() after calling Read().
(Optional) Progress And Callback
For Both Reader and Mesh Reader, an optional user-defined callback function will be called during the process. The interface for them are almost identical:
TopoShape Reader
reader.SetProgressCallback(
{
std::cout << " State: " << int(state) << std::endl;
if (c2.type == AMCAX::STEP::StepProgressCarrier::U64_TYPE && c2.payload.u64)
{
std::cout << " Carrier1: " << c1.payload.u64 << std::endl;
std::cout << " Carrier2: " << c2.payload.u64 << std::endl;
}
});
A class used for representing the states in the progress of the STEP process.
Definition: StepProgress.hpp:53
A carrier for carrying data the progress of the STEP process.
Definition: StepProgress.hpp:17
Usually, the value of c1 (if provided) represents the amount of shapes that have already been imported. While the value of c2 (if provided) represents the total amount of shapes that will be or have already been processed. You can find more information in the documentation of the header file.
Mesh Reader
reader.SetProgressCallback(
{
std::cout << " State: " << int(state) << std::endl;
if (c2.type == AMCAX::STEP::StepProgressCarrier::U64_TYPE && c2.payload.u64)
{
std::cout << " Carrier1: " << c1.payload.u64 << std::endl;
std::cout << " Carrier2: " << c2.payload.u64 << std::endl;
}
});
Class used for reporting the state of the STEP process.
Definition: StepMeshProgress.hpp:16
You can find more information in the documentation for both StepProgress and StepMeshProgress.
Start The Actual Reading Process
After finishing the optional configurings of the reader, it is now ready for translating the STEP input to AMCAX shape format:
bool topo_success = reader.Read();
For both Reader and Mesh Reader, this is the step where the STEP input being translated to AMCAX TopoShape. Usually, it will call a few milliseconds to several minutes to complete the entire process. If a std::istream was passed to the constructor, the user needs to ensure that the life cycle of the istream will not expire before this function is executed. Read() will return false if failed to translate the STEP input.
(Mesh Only) Convert TopoShape to Mesh
After the STEP input being translated to TopoShape, you may now convert the TopoShape objects to Mesh format.
bool mesh_success = reader.ToMesh();
Or, you can use ToMesh(const double). The parameter will be used when executing the triangulation operation.
Get Translation Results.
Declaration A Container For Storing The Results
TopoShape Reader
StepDataList is an alias of std::vector<std::shared_ptr<StepData>>. It is defined in <step/StepData.hpp>, which is transitively included from <step/StepReader.hpp>.
AMCAX::STEP::StepDataList shapes;
Mesh Reader
As a derived class of Reader, Mesh Reader uses a derived class of StepDataList, StepMeshDataList, to transfer the results.
AMCAX::STEP::StepMeshDataList<AMCAX::Meshing::Mesh::TriSoupTraits_Coord> shapes;
It was an alias of std::vector<std::shared_ptr<StepMeshData<Traits>>>, while StepMeshData is a template that is defined in <step/mesh/StepMeshData.hpp>.
Get the Result From Reader
shapes = reader.GetShapes();
TopoShape Reader
If the translating process succeed, one or more StepData may be added to the result-containing container variable, shapes.
However, you still cannot obtain the imported TopoShape objects just yet. This is because StepData is, instead of a shape representation, it is a represention of the Product_Definition entity, which is the unit used to represent assembly.
Each StepData object mainly contains:
- The name and description of current product node.
- The shape representations that are related to current product node. (no less than 0)
- The child Product nodes of current product node. (no less than 0)
- Properties of shape representations and their sub-shapes.
- The transformation used in the process of assembling into parent nodes. Check out <step/StepData.hpp> for more information.
Mesh Reader
In addition to the member variables of StepData, StepMeshData also contains:
- Mesh data for each TopoSolid in current product node. Check out <step/mesh/StepMeshData.hpp> for more information.
(Optional, TopoShape Only) Converting The Tree Structured StepData To A One-Dimensional Array
The user may want to convert the tree structured output to a one-dimensional array. This can be done with following code:
All node will have and only have exactly one TopoShape object.
(TopoShape Only) Get The Properties Of Sub-Shapes
Once a specific TopoShape is obtained, its sub-shapes can be retrieved using interfaces provided by the AMCAX kernel, such as TopoIterator, TopoExplorer, and TopoExplorerTool. The following code snippet demonstrates how to retrieve the name and other information of a sub-shape:
std::shared_ptr<AMCAX::STEP::StepData> treeroot = shapes[0];
for (auto& pr : solidSet)
{
const TopoShape& solid = pr->first;
std::string subname = treeroot->PartName()[solid];
}
Class for representation Color RGBA.
Definition: ShapeRGBA.hpp:18
Base class of shape, containing an underlying shape with a location and an orientation.
Definition: TopoShape.hpp:15
(Mesh Only) Get The properties And Mesh Data Of Sub-Shapes
Following code is an example of accessing Mesh data and its corresponding Property data.
std::shared_ptr<AMCAX::STEP::StepMeshData<AMCAX::Meshing::Mesh::TriSoupTraits_Coord>> root = shapes[0];
std::vector<std::vector<AMCAX::STEP::StepMesh<AMCAX::Meshing::Mesh::TriSoupTraits_Coord>>> meshes = root->Meshes();
std::cout << meshes.size() << '\n';
std::vector<AMCAX::STEP::StepMesh<AMCAX::Meshing::Mesh::TriSoupTraits_Coord>>& meshes0 = meshes[0];
std::cout << meshes0.size() << '\n';
std::vector<AMCAX::STEP::StepMesh<AMCAX::Meshing::Mesh::TriSoupTraits_Coord>>& meshes1 = meshes[1];
std::cout << meshes1.size() << '\n';
for (auto& pr : solidSet0)
{
int solidIndex = pr->second;
std::string name = root->PartName()[solid];
}
Class for reading STEP file and convert solid to mesh.
Definition: StepMesh.hpp:32
(Optional, Mesh Only) Converting StepMeshData To StepData
Sometimes the user may want to
using MeshDataList = AMCAX::STEP::StepMeshDataList<AMCAX::Meshing::Mesh::TriSoupTraits_Coord>;
MeshDataList smdl = reader.GetShapes();
AMCAX::STEP::StepDataList sdl;
sdl.reserve(smdl.size());
for (auto& smdptr : smdl)
{
sdl.push_back(smdptr->ToStepData());
}
(TopoShape Only) The Writer Section
Import The Header Files
The AMCAXStep module provides a header file for Writer.
Class used for translating TopoShape objects to STEP file.
Declare And Construct A Writer Instance.
To export a STEP file, a writer instance is required.
Class used for translating TopoShape objects to STEP file.
Definition: StepWriter.hpp:25
Same to Reader, you can also construct Writer with a std::istream:
std::ofstream ofs("/path/to/output.step");
if (!ofs.is_open())
{
return 1;
}
(Optional) Configure The Scaling Behavior
Under any circumstances Writer will export the shape representation without rescaling it. However, this may cause some problem if the shape was created with a length unit other than millimeter. You can configure the output unit with following code:
writer.SetUnit(AMCAX::STEP::StepLengthUnit::PresetLengthUnit::CENTIMETRE);
Even though having different length units for different shapes is possible, it's recommanded to use a consistent length unit.
(Optional) Progress And Callback
For Writer, a optional user-defined callback function will be called during the process. It is configurable via the interface below:
writer.SetProgressCallback(
{
std::cout << " State: " << int(state) << std::endl;
if (c2.type == AMCAX::STEP::StepProgressCarrier::U64_TYPE && c2.payload.u64)
{
std::cout << " Carrier1: " << c1.payload.u64 << std::endl;
std::cout << " Carrier2: " << c2.payload.u64 << std::endl;
}
});
Start Writing
The Header Section
Each valid STEP file requires a header section.
This function will also setup the writer and output a few essential entities. Make sure it is called exactly once before writing any shapes.
The Data Section
You can either pass a StepData to the writer or pass a TopoShape to it. Note that
AMCAX::STEP::StepDataList shape_part_0 = {shapes.begin(), shapes.begin() + shapes.size() - 2};
std::shared_ptr<AMCAX::STEP::StepData> shape_part_1 = shapes[shapes.size() - 2];
writer.WriteShapes(shape_part_0);
writer.WriteShape(shape_part_1);
writer.WriteShape(shape_last);
The Footer Section
Each valid STEP file requires a footer section.
Simplified Interface
In AMCAX::STEP::StepDataTool, there are several simplified interface for importing from, and exporting to STEP file. Check out <step/StepDataTool.hpp> for more information.
Click here example01 to get the complete source code of the Reader, and download it according to your learning needs. Click here example02 to get the complete source code of the Mesh Reader, and download it according to your learning needs.
Appendix
#include <iostream>
void printProductName(const std::shared_ptr<AMCAX::STEP::StepData> node, int indent = 0)
{
for (int i = 0; i < indent; ++i)
{
std::cout << "| ";
}
std::cout << node->ProductName() << std::endl;
for (const std::shared_ptr<AMCAX::STEP::StepData> child : node->Children())
{
printProductName(child, indent + 1);
}
}
void printSubName(const std::shared_ptr<AMCAX::STEP::StepData> node, int indent = 0)
{
for (int i = 0; i < indent; ++i)
{
std::cout << "| ";
}
std::unordered_map<AMCAX::TopoShape, std::string> partname = node->PartName();
{
{
if (auto it = partname.find(iter.Value()); it != partname.end())
{
std::cout << it->second << std::endl;
}
else
{
std::cout << "No PartName" << std::endl;
}
}
}
for (const std::shared_ptr<AMCAX::STEP::StepData> child : node->Children())
{
printSubName(child, indent + 1);
}
}
int main()
{
AMCAX::STEP::StepDataList shapes;
reader.SetUnit(AMCAX::STEP::StepLengthUnit::PresetLengthUnit::METRE);
bool topo_success = reader.Read();
if (!topo_success)
{
return -1;
}
shapes = reader.GetShapes();
for (std::shared_ptr<AMCAX::STEP::StepData> root : shapes)
{
printProductName(root);
printSubName(root);
}
writer.SetUnit(AMCAX::STEP::StepLengthUnit::PresetLengthUnit::METRE);
writer.Init();
writer.WriteShapes(shapes);
writer.Done();
}
Class of iterator for B-Rep structure.
Class of iterator for B-Rep structure.
Definition: TopoIterator.hpp:14
AMCAX_API bool More() const
Does the iterator has more shape.