Demonstrates how to compute minimum and maximum wall thickness of a 3D model and print the result in a console.
Overview
In this example demonstrates how to compute minimum and maximum wall thickness of a 3D model using wall thickness analysis tool (WallThickness_Analyzer). For this purpose, used a console application that imports a model (can be of any supported format), traverses through unique parts, creates and runs WallThickness_Analyzer and prints the computing result into console. Wall thickness analysis will be performed for each unique ModelData_Part, but only for the scope of accepted geometries.
Application needs 1 or 2 input arguments to run:
Usage: wall_thickness_analyzer <input_file> <input_resolution>, where:
<input_file> is a name of the file to be read
<input_resolution> is an optional argument that determine accuracy of wall thickness calculation. The larger the value, the higher the accuracy of the calculations, but greatly increase computation time and memory usage. Should be at least 100.
For more information about wall thickness visit Wall thickness calculation page.
Implementation
To explore the model and process parts, it's need to create an inheritor from the VoidElementVisitor and override the part processing method void operator() (const ModelData_Part& thePart)
. For this purpose, the PartProcessor
class was created. In operator()
method a ModelData_Part is examined for the presence of ModelData_BRepRepresentation and ModelData_Solid shapes in it or ModelData_PolyRepresentation and ModelData_IndexedTriangleSet in it.
void operator() (const ModelData_Part& thePart) override
{
auto aPartName = thePart.Name().IsEmpty() ? "noname" : thePart.Name();
if (auto aBRep = thePart.BRepRepresentation()) {
const auto& aBodyList = aBRep.Get();
for (size_t i = 0, n = aBodyList.Size(); i < n; ++i) {
const auto& aBody = aBodyList[i];
ModelData_Shape::Iterator aShapeIt (aBody);
while (aShapeIt.HasNext()) {
const auto& aShape = aShapeIt.Next();
if (aShape.Type() == ModelData_ST_Solid) {
cout << "Part #" << myPartIndex++ << " [\"" << aPartName << "\"] - solid #" << std::to_string (i) << " has:" << endl;
ProcessSolid (ModelData_Solid::Cast (aShape));
}
}
}
} else if (auto aPolyRep = thePart.PolyRepresentation (ModelData_RM_Poly)) {
const auto& aPolyList = aPolyRep.Get();
for (size_t i = 0; i < aPolyList.Size(); ++i) {
const auto& aPVS = aPolyList[i];
if (aPVS.IsOfType<ModelData_IndexedTriangleSet>()) {
cout << "Part #" << myPartIndex++ << " [\"" << aPartName << "\"] - mesh #" << std::to_string (i) << " has:" << endl;
ProcessMesh (static_cast<const ModelData_IndexedTriangleSet&> (aPVS));
}
}
}
}
ProcessSolid
and ProcessMesh
methods are used to run wall thickness analysis for given entities.
void ProcessSolid (const ModelData_Solid& theSolid)
{
auto aWTData = myAnalyzer.Perform (theSolid, myResolution);
PrintWTData (aWTData);
}
void ProcessMesh (const ModelData_IndexedTriangleSet& theMesh)
{
auto aWTData = myAnalyzer.Perform (theMesh, myResolution);
PrintWTData (aWTData);
}
PrintWTData
method is used to retrieve minimum and maximum thickness from computed WallThickness_Data and print these values to console.
void PrintWTData (const WallThickness_Data& theData)
{
if (!theData.IsEmpty()) {
cout << " Min thickness = " << theData.MinThickness() << " mm" << endl;
cout << " Max thickness = " << theData.MaxThickness() << " mm\n" << endl;
} else {
cerr << " Failed to analyze the wall thickness of this entity.\n";
}
}
To traverse only unique parts of the imported model, the ModelData_SceneGraphElementUniqueVisitor class is used.
PartProcessor aPartProcessor;
ModelData_SceneGraphElementUniqueVisitor aVisitor (aPartProcessor);
aModel.Accept (aVisitor);
Example output
Below is the example output for model from ./examples/models/barrel.stp
and resolution set to 1000.
The model | Example output |
| Model: barrel
Part #0 ["barrel"] - solid #0 has:
Min thickness = 4.526479 mm
Max thickness = 10.036917 mm
|
Files