Demonstrates how to run manufacturing analyses, convert a model to MTKWEB, and export JSON.
Overview
MTKConverter is a console example that imports a CAD model, runs one or more manufacturing processes, and exports:
-
the original model as
<export_target>/scenegraph.mtkweb,
-
process_data.json with manufacturing data,
-
thumbnail.png for the source model unless screenshot generation is disabled,
-
an additional processed model when the selected process produces one.
The example supports both part-oriented and drawing-oriented workflows.
-
Part-oriented workflows write data to the top-level
parts array in JSON.
-
Drawing-oriented nesting workflows write data to the top-level
sheets array.
The supported processes are listed below.
Process tools description
| Process | Toolkit components | Supported representation | Description |
| CNC Machining | Machining_FeatureRecognizer | BRep solids | Recognizes holes, milling faces, and other machining features . |
| DFMMachining_Analyzer | Reports machining DFM issues for drilling, milling, and turning. |
| Molding | Molding_FeatureRecognizer | Recognizes ribs, bosses, and other molding features. |
| DFMMolding_Analyzer | Reports molding DFM issues such as draft-angle and wall thickness problems. |
| Sheet Metal | SheetMetal_FeatureRecognizer | BRep solids and shells | Recognizes bends, holes, cutouts, and other sheet metal features. |
| SheetMetal_Unfolder | Creates an unfolded representation and an associated drawing. |
| DFMSheetMetal_Analyzer | Reports sheet metal DFM issues for both the folded and unfolded states. |
| Wall Thickness | WallThickness_Analyzer | BRep solids and mesh bodies | Computes minimum, maximum, and average wall thickness and creates an extra colorized model for visualization. |
| Nesting | Nesting_Computer | Drawing sheets | Creates nested layouts from source drawing sheets or from sheet metal flat-pattern drawing. |
- Note
- Thumbnail and screenshot generation uses OpenGL 2.1 or newer with FBO support. On Linux it typically requires an X11 display; on headless machines use Xvfb or disable screenshots with
--no-screenshot.
Running the example
The command line is interpreted as a sequence of actions:
MTKConverter -i <import_file> -p <process> ... -e <export_target> [options]
-i, -p, and -e may appear multiple times. This allows the example to import once, run several processes, and export intermediate or final results in one run.
Possible process parameter values
| Parameter value | Process | Description |
| machining_milling | CNC Machining | Milling feature recognition and DFM analysis. |
| machining_turning | Lathe+Milling feature recognition and DFM analysis. |
| molding | Molding | Feature recognition and DFM analysis. |
| sheet_metal | Sheet Metal | Feature recognition, unfolding, and DFM analysis. |
| wall_thickness | Wall Thickness | Computes minimum, maximum, and average thickness and exports a colorized extra model. |
| nesting | Nesting | Nesting from a source drawing or, when available, from the unfolded drawing produced by sheet_metal. |
Optional arguments
| Option | Description |
| --no-screenshot | Disables thumbnail.png generation. |
| --export_mtk | Additionally saves the processed model as <import file>_<process>_processed.mtk. |
| --sheet-size <L> <W> | Sets nesting sheet size in millimeters. Default is 500 x 500. |
| --pattern-count <N> | Sets how many copies of every drawing pattern must be nested. Default is 4. |
| --nesting-mode per-sheet | all-sheets | Runs nesting independently for each source sheet or for all sheets together. Default is per-sheet. |
Examples
The following examples show how to run different MTKConverter processes and export their results.
Machining Milling:
MTKConverter.exe -i C:\\models\\test.step -p machining_milling -e C:\\models\\machining_milling
Sheet metal followed by nesting of the unfolded drawing:
MTKConverter.exe -i C:\\models\\test.step -p sheet_metal -e C:\\models\\sheet_metal_nesting -p nesting -e C:\\models\\sheet_metal_nesting --nesting-mode all-sheets --sheet-size 500 500 --pattern-count 4 --export_mtk
Wall thickness:
MTKConverter.exe -i C:\\models\\test.step -p wall_thickness -e C:\\models\\wall_thickness
Nesting directly from a source drawing:
MTKConverter.exe -i C:\\models\\test.mtk -p nesting -e C:\\models\\nesting --sheet-size 1000 500
Implementation
The example is organized around three stages:
-
Import() reads the source model with ModelData::ModelReader . If nesting is requested, drawing import is enabled before execution.
-
Process() selects and invokes either a part processor or a deawing processor to handle the requested process.
-
Export() writes the source model, the optional processed model, and process_data.json.
Import
The import stage reads the source model and configures reader parameters through MTKConverter_ImportParameters.
MTKConverter_ReturnCode Import (
const UTF16String& theFilePath,
ModelData::Model& theModel,
const MTKConverter_ImportParameters& theImportParameters)
{
std::cout << "Importing " << theFilePath << "..." << std::flush;
ModelData::ModelReader aReader;
aReader.SetParameters (theImportParameters.myReaderParameters);
if (!aReader.Read (theFilePath, theModel)) {
std::cerr << std::endl << "ERROR: Failed to import " << theFilePath << ". Exiting" << std::endl;
return MTKConverter_ReturnCode::ImportError;
}
return MTKConverter_ReturnCode::Ok;
}
Process
Part-oriented processing uses ModelData::ModelElementUniqueVisitor so that every unique part gets a persistent Uuid. These UUIDs are reused in JSON and in process models. Nesting is handled separately through a drawing processor because it works on drawing sheets rather than 3D parts.
MTKConverter_ReturnCode Process (
const UTF16String& theProcess,
ModelData::Model& theModel,
MTKConverter_Report& theReport,
ModelData::Model& theProcessModel,
const MTKConverter_Parameters& theParameters = MTKConverter_Parameters())
{
std::cout << "Processing " << theProcess << "..." << std::flush;
auto anApplyPartProcessorToModel = [&theModel, &theReport] (MTKConverter_PartProcessor& theProcessor)
{
ModelData::ModelElementUniqueVisitor aVisitor (theProcessor);
theModel.Accept (aVisitor);
for (const auto& i : theProcessor.myData) {
theReport.AddData (i);
}
return MTKConverter_ReturnCode::Ok;
};
auto anApplyDrawingProcessorToModel =
[&theModel, &theProcessModel, &theReport] (MTKConverter_DrawingProcessor& theProcessor)
{
Drawing::Drawing aDrawing = theProcessModel.Drawing();
if (!aDrawing) {
aDrawing = theModel.Drawing();
}
if (!aDrawing) {
std::cerr << std::endl
<< "ERROR: Drawing is required, but none was found in the process/source model." << std::endl;
return MTKConverter_ReturnCode::ProcessError;
}
if (!theProcessor.Apply (aDrawing)) {
return MTKConverter_ReturnCode::ProcessError;
}
for (const auto& i : theProcessor.myData) {
theReport.AddData (i);
}
return MTKConverter_ReturnCode::Ok;
};
switch (FindProcessType (theProcess)) {
case MTKConverter_ProcessType::WallThickness: {
theProcessModel.SetName ("extra");
MTKConverter_WallThicknessProcessor
aProcessor (theProcessModel, theParameters.myWallThicknessParameters);
return anApplyPartProcessorToModel (aProcessor);
}
case MTKConverter_ProcessType::MachiningMilling: {
return anApplyPartProcessorToModel (aProcessor);
}
case MTKConverter_ProcessType::MachiningTurning: {
return anApplyPartProcessorToModel (aProcessor);
}
case MTKConverter_ProcessType::Molding: {
theProcessModel.SetName (theModel.Name() + "_extra");
MTKConverter_MoldingProcessor aProcessor (theProcessModel);
return anApplyPartProcessorToModel (aProcessor);
}
case MTKConverter_ProcessType::SheetMetal: {
theProcessModel.SetName (theModel.Name() + "_unfolded");
MTKConverter_SheetMetalProcessor aProcessor (theProcessModel);
return anApplyPartProcessorToModel (aProcessor);
}
case MTKConverter_ProcessType::Nesting: {
theProcessModel.SetName (theModel.Name() + "_nested");
MTKConverter_NestingProcessor aProcessor (theProcessModel, theParameters.myNestingParameters);
return anApplyDrawingProcessorToModel (aProcessor);
}
default: return MTKConverter_ReturnCode::InvalidArgument;
}
}
@ Machining_OT_Milling
Milling operation type.
Definition Machining_OperationType.hxx:28
@ Machining_OT_LatheMilling
Lathe + Milling operation type.
Definition Machining_OperationType.hxx:29
Part processor
MTKConverter_PartProcessor traverses each part and handles both BRep bodies and mesh bodies (for wall thickness).
void MTKConverter_PartProcessor::operator() (const ModelData::Part& thePart)
{
bool aPartWasProcessed = false;
auto aProcessData = CreateProcessData (thePart);
const auto& aBodies = thePart.Bodies();
for (const auto& aBody : aBodies) {
if (aBody.IsOfType<ModelData::MeshBody>()) {
const auto& aMeshBody = static_cast<const ModelData::MeshBody&> (aBody);
if (ProcessMeshBody (aProcessData, aMeshBody)) {
aPartWasProcessed = true;
}
} else if (ProcessBRepBody (aProcessData, aBody)) {
aPartWasProcessed = true;
}
}
if (aPartWasProcessed) {
PostProcessPart (thePart);
myData.push_back (aProcessData);
}
}
Sheet Metal processing
MTKConverter_SheetMetalProcessor runs feature recognition and unfolding together, stores the unfolded shell in a separate process model, and also converts the flat pattern to a drawing. That drawing can then be reused by the subsequent nesting step.
myUnfoldedModel (theUnfoldedModel)
{
myAnalyzer.AddTool (SheetMetal_FeatureRecognizer());
myAnalyzer.AddTool (SheetMetal_Unfolder());
}
void MTKConverter_SheetMetalProcessor::ProcessSolid (DataType& theProcessData, const ModelData::Solid& theSolid)
{
auto anSMData = myAnalyzer.Perform (theSolid);
Process (theProcessData, anSMData);
}
Provides MTK data model.
Definition Model.hxx:39
Wall Thickness processing
The processor computes scalar thickness values with WallThickness_Analyzer, then converts the result to a colorized mesh so that the process model can be visualized in MTKWEB or saved as MTK.
void MTKConverter_WallThicknessProcessor::ProcessSolid (DataType& theProcessData, const Solid& theSolid)
{
WallThickness_Data aData = myAnalyzer.Perform (theSolid, myWallThicknessParameters.myResolution);
auto aMesh = ModelAlgo::MeshGenerator().Generate (theSolid, false);
if (aMesh) {
ProcessResult (theProcessData, static_cast<const ModelData::IndexedTriangleSet&> (aMesh), aData);
}
}
void MTKConverter_WallThicknessProcessor::ProcessMesh (
DataType& theProcessData,
{
WallThickness_Data aData = myAnalyzer.Perform (theMesh, myWallThicknessParameters.myResolution);
ProcessResult (theProcessData, theMesh, aData);
}
Defines a polygonal shape consisting of triangles.
Definition IndexedTriangleSet.hxx:32
Nesting processing
Nesting is implemented through MTKConverter_DrawingProcessor. It extracts source sheets, gathers the views that act as patterns, runs Nesting_Computer, and stores the resulting drawing in the process model. If sheet_metal is executed before nesting, the nesting step first tries to use the drawing stored in the current process model, so chaining works when the sheet metal step produced a flat-pattern drawing.
bool MTKConverter_NestingProcessor::Apply (const Drawing::Drawing& theDrawing)
{
myData.clear();
const auto aSourceSheets = MTKConverter_DrawingProcessor::ExtractDrawingSheets (theDrawing);
if (aSourceSheets.empty()) {
std::cerr << std::endl << "ERROR: Nesting requires at least one sheet in the source drawing." << std::endl;
return false;
}
if (myNestingParameters.myMode == MTKConverter_NestingParameters::NestingMode::AllSheets) {
return ProcessAllSheets (aSourceSheets);
}
return ProcessPerSheet (aSourceSheets);
}
Export and Reporting
The export stage always writes the source model as MTKWEB and process_data.json. If the selected process created an additional model or drawing, that process model is exported too. When --export_mtk is enabled, the process model is also saved as MTK.
UTF16String aJsonPath = theFolderPath + "/process_data.json";
if (!theReport.WriteToJSON (aJsonPath)) {
std::cerr << std::endl << "ERROR: Failed to create JSON file " << aJsonPath << ". Exiting" << std::endl;
return MTKConverter_ReturnCode::ExportError;
}
MTKConverter_Report::WriteToJSON() writes a single JSON report whose structure depends on the selected process:
-
Part-oriented process results are written to the top-level
parts array.
-
Nesting results are written to the top-level
sheets array.
-
Feature Recognition and DFM data are serialized with Utilities::JSONSerializer .
-
Wall Thickness and Nesting sections are written explicitly.
For feature-based results, shape IDs are taken from the part B-Rep representation, so JSON entries can be mapped back to model shapes.
- Note
- A public sample serializer is available in
examples/helpers for reference only and is updated infrequently, so it may not reflect newly added features or issues. For production use, prefer Utilities::JSONSerializer .
Example output
The export folder always contains process_data.json and the source .mtkweb model. Depending on the selected process, it can also contain:
-
thumbnail.png,
-
extra.mtkweb for wall thickness visualization,
-
<model_name>_extra.mtkweb for molding visualization data,
-
<model_name>_unfolded.mtkweb for sheet metal results,
-
<model_name>_nested.mtkweb for nesting results.
When --export_mtk is enabled, the processed model is also saved as <processed_name>_processed.mtk.
thumbnail.png is skipped when --no-screenshot is used.
Below are representative outputs for different processes. The JSON samples are intentionally shortened, but they preserve the actual structure generated by the current example.
Machining Milling
The ./examples/models/Fresamento_CAM1_v3.stp model can be used to run machining_milling.
Output
{
"version": "1",
"parts": [
{
"partId": "5cbb91d0-f69e-4e22-aefa-e1e7791fc3d5",
"process": "CNC Machining Milling",
"featureRecognition": {
"name": "Feature Recognition",
"totalFeatureCount": "44",
"featureGroups": [
{
"name": "Concave Fillet Edge Milling Face(s)",
"color": "(129, 127, 38)",
"subGroups": [
{
"parameters": [
{
"name": "Radius",
"units": "mm",
"value": "5.00"
}
],
"features": [
...
]
}
]
},
...
]
},
"dfm": {
"name": "Design for Manufacturing",
"featureGroups": [
...
]
}
}
]
}
Machining Turning
The ./examples/models/senthi.step model can be used to run machining_turning. The JSON structure is the same as for machining milling, but the process name becomes CNC Machining Lathe+Milling and the feature/DFM content reflects the turning workflow.
Output
{
"version": "1",
"parts": [
{
"partId": "b9a9325d-63c7-48a9-993e-eb1cc826f967",
"process": "CNC Machining Lathe+Milling",
"featureRecognition": {
"name": "Feature Recognition",
"totalFeatureCount": "245",
"featureGroups": [
...
]
},
"dfm": {
"name": "Design for Manufacturing",
"featureGroups": [
...
]
}
}
]
}
Molding
The process keeps the same top-level parts structure, but the recognized features and DFM issues are molding-specific.
Output
{
"version": "1",
"parts": [
{
"partId": "1e43ec6c-9742-40b1-90b5-038f028eb8bb",
"process": "Molding Analysis",
"featureRecognition": {
"name": "Feature Recognition",
"featureGroups": [
{
"name": "Rib(s)",
"subGroups": [
{
"parameters": [
{ "name": "Length", "units": "mm", "value": "1.00" },
{ "name": "Height", "units": "mm", "value": "0.71" },
{ "name": "Thickness", "units": "mm", "value": "1.00" },
{ "name": "Draft Angle", "units": "deg", "value": "0.00" }
],
"features": [
...
]
}
]
}
]
},
"dfm": {
"name": "Design for Manufacturing",
"featureGroups": [
{
"name": "Small Draft Angle Rib(s)",
"subGroups": [
...
]
},
{
"name": "Small Wall(s)",
"subGroups": [
...
]
}
]
}
}
]
}
Sheet Metal
The ./examples/models/Part2.stp model is suitable for sheet_metal. In addition to the regular feature-recognition and DFM sections, the result also contains unfolded information.
Output
{
"version": "1",
"parts": [
{
"partId": "37e0442d-8adc-4e01-a11d-bc008b90cbd8",
"process": "Sheet Metal",
"featureRecognition": {
"name": "Feature Recognition",
"totalFeatureCount": "118",
"featureGroups": [
...
]
},
"dfm": {
"name": "Design for Manufacturing",
"featureGroups": [
...
]
},
"featureRecognitionUnfolded": {
"name": "Feature Recognition",
"parametersCount": "4",
"parameters": [
{ "name": "Length", "units": "mm", "value": "182.16" },
{ "name": "Width", "units": "mm", "value": "179.58" },
{ "name": "Thickness", "units": "mm", "value": "1.00" },
{ "name": "Perimeter", "units": "mm", "value": "1135.61" }
]
},
"dfmUnfolded": {
"name": "Design for Manufacturing",
"featureGroups": [
{
"name": "Non Standard Sheet Size(s)",
"subGroups": [
{
"parameters": [
{
"name": "Nearest Standard Size (LxW)",
"units": "mm",
"value": "300.00 x 200.00"
},
{
"name": "Actual Size (LxW)",
"units": "mm",
"value": "182.16 x 179.58"
}
],
"features": [
{
"shapeIDCount": "0",
"shapeIDs": []
}
]
}
]
}
]
}
}
]
}
Wall Thickness
Wall Thickness entries are stored in the parts array. Each entry contains the part UUID, the extreme thickness values, the point pairs where these values were found, and a compact parameter list.
Output
{
"version": "1",
"parts": [
{
"partId": "4b15cb5f-3fe7-4434-b036-7ecf3df80bc7",
"process": "Wall Thickness Analysis",
"minThickness": {
"name": "Minimum Thickness",
"units": "mm",
"value": "3.00",
"firstPoint": "(-68.74, 24.82, -20.58)",
"secondPoint": "(-62.97, 22.00, -19.03)"
},
"maxThickness": {
"name": "Maximum Thickness",
"units": "mm",
"value": "7.21",
"firstPoint": "(45.89, 29.00, 35.20)",
"secondPoint": "(47.65, 29.00, 32.77)"
},
"parameters": [
{
"name": "Minimum Thickness",
"units": "mm",
"value": "3.00"
},
{
"name": "Maximum Thickness",
"units": "mm",
"value": "7.21"
},
{
"name": "Average Thickness",
"units": "mm",
"value": "4.95"
}
]
}
]
}
Nesting
Nesting results are stored in the top-level sheets array rather than in parts. Every item references source sheets through sourceIds and contains one or more generated result sheets.
Output
{
"version": "1",
"sheets": [
{
"sourceIds": [
"ba687c4a-b6ee-4ab2-a2e8-512d07494d97"
],
"process": "Nesting",
"nesting": {
"sheets": [
{
"sheetId": "383da9d8-d3d2-4268-8a63-f909aa8d4264",
"parameters": [
{
"name": "Sheet Length",
"units": "mm",
"value": "370.00"
},
{
"name": "Sheet Width",
"units": "mm",
"value": "370.00"
},
{
"name": "Requested Pattern Count",
"units": "pcs",
"value": "4"
},
{
"name": "Nested Pattern Count",
"units": "pcs",
"value": "4"
}
]
}
]
}
}
]
}
When a run contains both part-oriented processes and nesting, both top-level arrays can appear in the same process_data.json.
Files