Hide menu
No Matches
Sheet Metal Unfolder Example

Demonstrates how to perform unfolding of 3D model and saves it as DXF 2D drawing.

The saving 2D DXF drawing feature is part of CAD Exchanger SDK, which is licensed separately from the Manufacturing Toolkit.


In this example demonstrates how to perform unfolding of 3D model using sheet metal unfolder tool (SheetMetal_Unfolder). For this purpose, used a console application that imports a model (can be of any supported format), collects unique parts, traverses through unique parts, creates and runs SheetMetal_Unfolder, prints information about flat pattern parameters into console and saves resulting unfolded shape as a 2D DXF drawing. Unfolding will be performed for each unique ModelData_Part, but only for the scope of accepted geometries.

Application needs 2 input arguments to run:

Usage: sheet_metal_unfolder <input_file> <output_file>, where:
<input_file> is a name of the file to be read
<output_folder> is a name of the folder where DXF files with drawing to be written

For more information about unfolding visit Sheet Metal Unfolding page.


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 or ModelData_Shell shapes in it.

void operator() (const ModelData_Part& thePart) override
auto aPartName = thePart.Name().IsEmpty() ? "noname" : thePart.Name();
auto aBRep = thePart.BRepRepresentation();
if (aBRep) {
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), aPartName, i);
} else if (aShape.Type() == ModelData_ST_Shell) {
cout << "Part #" << myPartIndex << " [\"" << aPartName << "\"] - shell #" << std::to_string (i) << " has:" << endl;
ProcessShell (ModelData_Shell::Cast (aShape), aPartName, i);

ProcessSolid and ProcessShell methods are used to run sheet metal unfolder for given entities.

void ProcessSolid (const ModelData_Solid& theSolid, const Base_UTF16String& thePartName, size_t theShapeIndex)
double aThickness = CalculateInitialThicknessValue (theSolid);
auto aFlatPattern = myUnfolder.Perform (theSolid, aThickness);
Base_UTF16String aFileName = DrawingFileName (thePartName, theShapeIndex, "solid");
PrintFlatPatternAndWriteToDrawing (aFlatPattern, aFileName);
void ProcessShell (const ModelData_Shell& theShell, const Base_UTF16String& thePartName, size_t theShapeIndex)
auto aFlatPattern = myUnfolder.Perform (theShell);
Base_UTF16String aFileName = DrawingFileName (thePartName, theShapeIndex, "shell");
PrintFlatPatternAndWriteToDrawing (aFlatPattern, aFileName);

To traverse only unique parts of the imported model, the ModelData_SceneGraphElementUniqueVisitor class is used.

PartProcessor aPartProcessor (aDrawingPath);
ModelData_SceneGraphElementUniqueVisitor aVisitor (aPartProcessor);
aModel.Accept (aVisitor);

SheetMetal_Unfolder tool need thickness of an imported model as an input parameter to perform unfolding for ModelData_Solid. For this purpose, in CalculateInitialThicknessValue approximate thickness value is computed.

double CalculateInitialThicknessValue (const ModelData_Shape& theShape)
double aVolume = ModelAlgo_ValidationProperty::ComputeVolume (theShape);
double aSurfaceArea = ModelAlgo_ValidationProperty::ComputeSurfaceArea (theShape);
double aThickness = aVolume / (aSurfaceArea / 2.);
return aThickness;
static double ComputeSurfaceArea(const ModelData_Model &theModel, bool theUseProperty=false, bool theStoreProperty=false)
Returns a surface area of a scene graph.
Definition: ModelAlgo_ValidationProperty.cxx:362
static double ComputeVolume(const ModelData_Model &theModel, bool theUseProperty=false, bool theStoreProperty=false)
Returns a volume of a scene graph.
Definition: ModelAlgo_ValidationProperty.cxx:402

Method PrintFlatPattern is used to explore and print flat pattern parameters.

void PrintFlatPattern (const SheetMetal_FlatPattern& theFlatPattern)
cout << " Flat Pattern with:" << endl;
cout << " length: " << theFlatPattern.Length() << " mm" << endl;
cout << " width: " << theFlatPattern.Width() << " mm" << endl;
cout << " thickness: " << theFlatPattern.Thickness() << " mm" << endl;
cout << " perimeter: " << theFlatPattern.Perimeter() << " mm" << endl;

Method WriteToDrawing is used to create ModelData_Drawing from the flat pattern and save it as 2D DXF file.

bool WriteToDrawing (const SheetMetal_FlatPattern& theFlatPattern, const Base_UTF16String& theFilePath)
ModelData_Drawing aDrawing = theFlatPattern.ToDrawing();
if (!aDrawing) {
return false;
ModelData_Model aDrawingModel;
aDrawingModel.SetDrawing (aDrawing);
ModelData_ModelWriter aWriter;
bool aRes = aWriter.Write (aDrawingModel, theFilePath);
return aRes;

Example output

Below is the example output for model from ./examples/models/Part2.stp.

Model: Part2

Part #0 ["Part2"] - solid #0 has:
    Flat Pattern with:
          length: 220.712 mm
          width: 167.838 mm
          thickness: 1 mm
          perimeter: 1121.37 mm
Original model
Unfolded view