Hide menu
Loading...
Searching...
No Matches
MTK Converter Example

Demonstrates how to generate view and manufacturing information files for the imported model, that can be easily acessed through web interface for downstream analysis.

Overview

The example demonstrates how to create a console application to convert your STEP model to compressed *.mtkweb format, generate useful manufacturing information about it with chosen data processor into *.json file). The model will be imported by ModelData.ModelReader . Then the choosen by input parameter certain part processor class will analyze a model. The list of possible analysis can be found in table below.

Process tools description
Process Tools Supported representation Description
CNC Machining Machining_FeatureRecognizer BRep Recognize features such as machining faces, holes, etc.
DFMMachining_Analyzer

Analyse possible CNC Machining milling – drilling / milling / turning design issues.

Sheet Metal SheetMetal_FeatureRecognizer Recognize features such as bends, cutouts, holes, etc.
SheetMetal_Unfolder Unfold sheet metal models.
DFMSheetMetal_Analyzer

Analyse possible Sheet Metal design issues.

Molding Molding_FeatureRecognizer Recognize features such as ribs, bosses, screw bosses, etc.
DFMMolding_Analyzer

Analyse possible Molding design issues.

Finally, the converted *.mtkweb model will be saved to ${export_dir}/model.mtkweb and all computed process data to ${export_dir}/process_data.json

Running the example

Application needs 6 following input arguments to run:

Usage: MTKConverter -i <import_file> -p <process> -e <export_folder> where:
<import_file> -- filename of a model, that will be imported
<process> -- what analysis should be performed on model
<export_folder> -- export folder name where an output will be saved


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
sheet_metal Sheet Metal Feature recognition, unfolding and DFM analysis
molding Molding Feature recognition and DFM analysis

Example:

MTKConverter -i C:\\models\\test.step -p machining_milling -e C:\\models\\test

Implementation

The ModelData.ModelReader is used to import the models.

private MTKConverter_ReturnCode Import(string theFilePath, Model theModel)
{
UTF16String aFilePath = new UTF16String(theFilePath);
Console.Write($"Importing {theFilePath}...");
ModelReader aReader = new ModelReader();
if (!aReader.Read (aFilePath, theModel)) {
Console.WriteLine($"\nERROR: Failed to import {theFilePath}. Exiting");
return MTKConverter_ReturnCode.MTKConverter_RC_ImportError;
}
return MTKConverter_ReturnCode.MTKConverter_RC_OK;
}

Then Process method was created for a model analysis with chosen by process_param_table value processor. The ModelData.Model.AssignUuids() method is used to assign persistent id's to unique parts of the model. These id's will be used to connect parts with process data saved in json file. The processor is a MTKConverter_PartProcessor class, that can analyse all parts of the imported model. The ProcessType method can parse a process_param_table parameter value to choose MTKConverter_PartProcessor class, which will run relative analyzer tools. The ModelData.ModelElementUniqueVisitor
is used to traverse and retrieve only unique parts of the imported model.

private MTKConverter_ReturnCode Process(string theProcess, Model theModel,
MTKConverter_Report theReport, Model theProcessModel)
{
Console.Write($"Processing {theProcess}...");
theModel.AssignUuids();
MTKConverter_ProcessType aProcessType = ProcessType(theProcess);
switch (aProcessType)
{
case MTKConverter_ProcessType.MTKConverter_PT_MachiningMilling:
{
MTKConverter_MachiningProcessor aProcessor = new MTKConverter_MachiningProcessor(Machining_OperationType.Machining_OT_Milling);
ApplyProcessorToModel(theModel, theReport, aProcessor);
break;
}
case MTKConverter_ProcessType.MTKConverter_PT_MachiningTurning:
{
MTKConverter_MachiningProcessor aProcessor = new MTKConverter_MachiningProcessor(Machining_OperationType.Machining_OT_LatheMilling);
ApplyProcessorToModel(theModel, theReport, aProcessor);
break;
}
case MTKConverter_ProcessType.MTKConverter_PT_Molding:
{
MTKConverter_MoldingProcessor aProcessor = new MTKConverter_MoldingProcessor();
ApplyProcessorToModel(theModel, theReport, aProcessor);
break;
}
case MTKConverter_ProcessType.MTKConverter_PT_SheetMetal:
{
UTF16String aProcessModelName = new UTF16String(theModel.Name() + "_unfolded");
theProcessModel.SetName(aProcessModelName);
MTKConverter_SheetMetalProcessor aProcessor = new MTKConverter_SheetMetalProcessor(theProcessModel);
ApplyProcessorToModel(theModel, theReport, aProcessor);
break;
}
case MTKConverter_ProcessType.MTKConverter_PT_Undefined:
default: return MTKConverter_ReturnCode.MTKConverter_RC_InvalidArgument;
}
return MTKConverter_ReturnCode.MTKConverter_RC_OK;
}
Machining_OperationType
Defines an operation type in machining.
Definition Machining_OperationType.cs:19

Before we dive into how the model is processed with MTKConverter_PartProcessor class after the ApplyProcessorToModel was ran, the inheritance hierarchy should be observed.

  • First, the MTKConverter_PartProcessor class, which inherits from ModelData.ModelElementVoidVisitor , was created with the overridden void operator()(const ModelData::Part& thePart) method to traverse the model and collect each ModelData.Part . Then, ModelData.Solid and ModelData.Shell are extracted using ModelData.ModelElementVoidVisitor . The ProcessSolid, ProcessShell is developed to analyze the certain shapes of ModelData.Part . Additionally, some analyses require post-processing, which is handled by the PostPartProcess method. These four methods will be described in detail later.

    public override void Apply(Part thePart)
    {
    BodyList aBodyList = thePart.Bodies();
    for (int i = 0; i < aBodyList.Count; ++i)
    {
    Body aBody = aBodyList[i];
    var aShapeIt = new ShapeIterator(aBody);
    while (aShapeIt.HasNext())
    {
    var aShape = aShapeIt.Next();
    if (aShape.Type() == ShapeType.Solid)
    {
    ProcessSolid(thePart, Solid.Cast(aShape));
    }
    else if (aShape.Type() == ShapeType.Shell)
    {
    ProcessShell(thePart, Shell.Cast(aShape));
    }
    }
    }
    PostPartProcess(thePart);
    }

    MTKConverter_VoidPartProcessor was inherited from MTKConverter_PartProcessor at first with empty defined methods for processing, because not all processor can analyse Shell, Mesh and requires postprocessing. Then for each process different class, inherited from MTKConverter_VoidPartProcessor, was developed. The table below demonstrates what classes were created for each process and which methods were overriden.

    Processor classes
    Process Class ProcessSolid ProcessShell ProcessMesh PostPartProcess
    CNC Machining MTKConverter_MachiningProcessor + - - -
    Sheet Metal MTKConverter_SheetMetalProcessor + - +
    Molding MTKConverter_MoldingProcessor + - -

  • Let's take the MTKConverter_SheetMetalProcessor as example, because it supports almost all methods of MTKConverter_PartProcessor. It uses SheetMetal_Analyzer for shape processing. In constructor both supported tools (SheetMetal_FeatureRecognizer, SheetMetal_Unfolder) were added to SheetMetal_Analyzer. Analyzer classes can be used to run all tools together, however it should be mentioned, that such tools allow separated calls. The example of such separate call for SheetMetal_Unfolder can be found here.

    public MTKConverter_SheetMetalProcessor(Model theUnfoldedModel) : base()
    {
    myAnalyzer = new SheetMetal_Analyzer();
    myAnalyzer.AddTool(new SheetMetal_FeatureRecognizer());
    myAnalyzer.AddTool(new SheetMetal_Unfolder());
    myUnfoldedModel = theUnfoldedModel;
    myCurrentUnfoldedBody = new SheetBody();
    }

    The Perform method of SheetMetal_Analyzer will be called to run analysis with added tools for Solid and Shell respectively.

    public override void ProcessSolid(Part thePart, Solid theSolid)
    {
    SheetMetal_Data anSMData = myAnalyzer.Perform(theSolid);
    UpdateProcessData(anSMData, thePart);
    }
    public override void ProcessShell(Part thePart, Shell theShell)
    {
    SheetMetal_Data anSMData = myAnalyzer.Perform(theShell);
    UpdateProcessData(anSMData, thePart);
    }

    PostPartProcess method will be called once the analyse is done.

    public override void PostPartProcess(Part thePart)
    {
    if (myCurrentUnfoldedBody.IsNull())
    {
    return;
    }
    Part anUnfoldedPart = new Part(thePart.Name());
    anUnfoldedPart.SetUuid(thePart.GetUuid());
    anUnfoldedPart.AddBody(myCurrentUnfoldedBody);
    myUnfoldedModel.AddRoot(anUnfoldedPart);
    myCurrentUnfoldedBody = new SheetBody();
    }

    Finally, after the processing, the model will be converted to *.mtkweb format.

    private MTKConverter_ReturnCode Export(string theFolderPath, Model theModel,
    MTKConverter_Report theReport, Model theProcessModel)
    {
    Console.Write($"Exporting {theFolderPath}...");
    UTF16String aModelPath = new UTF16String(theFolderPath + "/" + theModel.Name() + ".mtkweb" + "/scenegraph.mtkweb");
    if (!theModel.Save(aModelPath, Model.FileFormatType.MTKWEB))
    {
    Console.WriteLine($"\nERROR: Failed to export {aModelPath}. Exiting");
    return MTKConverter_ReturnCode.MTKConverter_RC_ExportError;
    }
    return MTKConverter_ReturnCode.MTKConverter_RC_OK;
    }

    An unfolded representation, if the SheetMetal process was performed also will be converted to *.mtkweb format and saved.

    if (!theProcessModel.IsEmpty())
    {
    UTF16String aProcessModelPath = new UTF16String(theFolderPath + "/" + theProcessModel.Name() + ".mtkweb" + "/scenegraph.mtkweb");
    if (!theProcessModel.Save(aProcessModelPath, Model.FileFormatType.MTKWEB))
    {
    Console.WriteLine($"\nERROR: Failed to export {aProcessModelPath}. Exiting");
    return MTKConverter_ReturnCode.MTKConverter_RC_ExportError;
    }
    }


    A result of processing will be saved to a json file with the custom MTKConverter_Report class. However, other premade solutions can be used too.

    Directory.CreateDirectory (theFolderPath);
    UTF16String aJsonPath = new UTF16String(theFolderPath + "/process_data.json");
    if (!theReport.WriteToJSON(aJsonPath))
    {
    Console.WriteLine($"\nERROR: Failed to create JSON file {aJsonPath}. Exiting");
    return MTKConverter_ReturnCode.MTKConverter_RC_ExportError;
    }
    return MTKConverter_ReturnCode.MTKConverter_RC_OK;

    WriteToJSON() in MTKConverter_Report generates a compact JSON report for each part. It writes sections with JSONWriter (see examples/helpers) and serializes features and DFM issues using Utilities.JSONSerializer :

    • WriteFeatures() writes the featureRecognition and dfm sections.
    • Features and issues are sorted and grouped during serialization with MTKBase_FeatureComparator.
    • Shape IDs come from the part’s BRepRepresentation, so JSON items 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 new features or issues. For production, use Utilities.JSONSerializer .

    All features have the same to text export pattern, therefore only the example for Machining_Countersink was present.

    else if (Machining_Countersink.CompareType(aFeature))
    {
    Machining_Countersink aCountersink = Machining_Countersink.Cast(aFeature);
    cadex.Direction aDir = aCountersink.Axis().Axis();
    string aFeatureData = WriteFeatureDataToString(
    "Radius", "mm", aCountersink.Radius(),
    "Depth", "mm", aCountersink.Depth(),
    "Axis", "", new Direction (aDir.X(), aDir.Y(), aDir.Z()),
    theShapeIdVector);
    theManager.AddGroupData("Countersink(s)", "(55, 125, 34)", aFeatureData, theCount);
    }
    Contains classes, namespaces, enums, types, and global functions related to Manufacturing Toolkit.
    Definition BaseObject.cs:12

Example output

Below are outputs for different processes.

Machining Milling

The ./examples/models/Fresamento_CAM1_v3.stp model can be used to run machining_milling process.

Original Model
Processed Model

Output

{
"version": "1",
"parts": [
{
"partId": "e31092b7-fc4e-4c02-8021-c0bbbcd21bfa",
"process": "CNC Machining Milling",
"featureRecognition": {
"name": "Feature Recognition",
"totalFeatureCount": "51",
"featureGroups": [
{
"name": "Concave Fillet Edge Milling Face(s)",
"color": "(129, 127, 38)",
"totalGroupFeatureCount": "14",
"subGroupCount": "1",
"subGroups": [
{
"parametersCount": "1",
"parameters": [
{
"name": "Radius",
"units": "mm",
"value": "5.00"
}
],
"featureCount": "14",
"features": [
{
"shapeIDCount": "1",
"shapeIDs": [
{
"id": "555"
}
]
},
...
{
"shapeIDCount": "1",
"shapeIDs": [
{
"id": "669"
}
]
}
]
}
]
},
...
"dfm": {
"name": "Design for Manufacturing",
"totalFeatureCount": "23",
"featureGroups": [
{
"name": "Deep Hole(s)",
"color": "(0, 35, 245)",
"totalGroupFeatureCount": "4",
"subGroupCount": "1",
"subGroups": [
{
"parametersCount": "2",
"parameters": [
{
"name": "Expected Maximum Depth",
"units": "mm",
"value": "29.84"
},
{
"name": "Actual Depth",
"units": "mm",
"value": "31.32"
}
],
"featureCount": "4",
"features": [
{
"shapeIDCount": "2",
"shapeIDs": [
{
"id": "435"
},
{
"id": "423"
}
]
},
{
"shapeIDCount": "2",
"shapeIDs": [
{
"id": "450"
},
{
"id": "438"
}
]
},
{
"shapeIDCount": "2",
"shapeIDs": [
{
"id": "465"
},
{
"id": "453"
}
]
},
{
"shapeIDCount": "2",
"shapeIDs": [
{
"id": "480"
},
{
"id": "468"
}
]
}
]
}
]
},
...

Machining Turning

The ./examples/models/senthi.step model can be used to run machining_turning process. The processing result has the same structure as for a Machining milling, thus it was omitted.

Original Model
Processed Model

Sheet Metal

The ./examples/models/Part2.stp is suitable to run SheetMetal process. The first part of a json file is the same as in Machining milling and turning, but it also contains the infromation about unfolding analysis.

Original Model
Unfolded Model

Output

...
"featureRecognitionUnfolded": {
"name": "Feature Recognition",
"parametersCount": "3",
"parameters": [
{
"name": "Length",
"units": "mm",
"value": "220.71"
},
{
"name": "Width",
"units": "mm",
"value": "167.84"
},
{
"name": "Thickness",
"units": "mm",
"value": "1.00"
}
]
},
"dfmUnfolded": {
"name": "Design for Manufacturing",
"totalFeatureCount": "1",
"featureGroups": [
{
"name": "Non Standard Sheet Size(s)",
"color": "(0, 0, 0)",
"totalGroupFeatureCount": "1",
"subGroupCount": "1",
"subGroups": [
{
"parametersCount": "2",
"parameters": [
{
"name": "Nearest Standard Size (LxW)",
"units": "mm",
"value": "300.00 x 200.00"
},
{
"name": "Actual Size (LxW)",
"units": "mm",
"value": "220.71 x 167.84"
}
],
"featureCount": "1",
"features": [
{
"shapeIDCount": "0",
"shapeIDs": []
}
]
}
]
}
]
}
}
]
}

Files