Hide menu
Loading...
Searching...
No Matches
MTKConverter/main.cxx

Refer to the MTK Converter Example

MTKConverter_PartProcessor.hxx

// ****************************************************************************
// $Id$
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2025, CADEX. All rights reserved.
//
// This file is part of the Manufacturing Toolkit software.
//
// This file may be used under the terms and conditions of the License
// Agreement supplied with the software.
//
// This file is provided "AS IS" WITH NO WARRANTY OF ANY KIND, EITHER EXPRESSED
// OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE WARRANTY OF DESIGN,
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// ****************************************************************************
#ifndef _MTKConverter_PartProcessor_HeaderFile
#define _MTKConverter_PartProcessor_HeaderFile
#include <cadex/ModelData/Model.hxx>
#include <cadex/ModelData/Part.hxx>
#include <deque>
namespace cadex {
namespace ModelData {
class Shell;
class Solid;
}
}
class MTKConverter_ProcessData
{
protected:
MTKConverter_ProcessData (const cadex::ModelData::Part& thePart) : myPart (thePart)
{}
public:
virtual ~MTKConverter_ProcessData() {}
};
class MTKConverter_PartProcessor : public cadex::ModelData::ModelElementVoidVisitor
{
public:
typedef std::shared_ptr<MTKConverter_ProcessData> DataType;
void operator() (const cadex::ModelData::Part& thePart) override;
virtual ~MTKConverter_PartProcessor() {}
std::deque<DataType> myData;
protected:
virtual DataType CreateProcessData (const cadex::ModelData::Part& thePart) const = 0;
virtual void ProcessSolid (DataType& theProcessData, const cadex::ModelData::Solid& theSolid) = 0;
virtual void ProcessShell (DataType& theProcessData, const cadex::ModelData::Shell& theShell) = 0;
virtual void PostProcessPart (const cadex::ModelData::Part& thePart) = 0;
};
class MTKConverter_VoidPartProcessor : public MTKConverter_PartProcessor
{
protected:
void ProcessSolid (DataType&, const cadex::ModelData::Solid&) override {}
void ProcessShell (DataType&, const cadex::ModelData::Shell&) override {}
void PostProcessPart (const cadex::ModelData::Part&) override {}
};
#endif
Element visitor with empty implementation.
Definition ModelElementVisitor.hxx:64
Defines a leaf node in the scene graph hierarchy.
Definition Part.hxx:34
Defines a connected set of faces.
Definition Shell.hxx:32
Defines a topological solid.
Definition Solid.hxx:32
Contains classes, namespaces, enums, types, and global functions related to Manufacturing Toolkit.
Definition LicenseManager_LicenseError.hxx:30

MTKConverter_PartProcessor.cxx

// ****************************************************************************
// $Id$
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2025, CADEX. All rights reserved.
//
// This file is part of the Manufacturing Toolkit software.
//
// This file may be used under the terms and conditions of the License
// Agreement supplied with the software.
//
// This file is provided "AS IS" WITH NO WARRANTY OF ANY KIND, EITHER EXPRESSED
// OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE WARRANTY OF DESIGN,
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// ****************************************************************************
#include <cadex/ModelData/Body.hxx>
#include <cadex/ModelData/Shell.hxx>
#include <cadex/ModelData/Solid.hxx>
#include <MTKConverter_PartProcessor.hxx>
using namespace cadex;
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) {
ModelData::ShapeIterator aShapeIt (aBody);
while (aShapeIt.HasNext()) {
const auto& aShape = aShapeIt.Next();
if (aShape.Type() == ModelData::ShapeType::Solid) {
ProcessSolid (aProcessData, ModelData::Solid::Cast (aShape));
aPartWasProcessed = true;
} else if (aShape.Type() == ModelData::ShapeType::Shell) {
ProcessShell (aProcessData, ModelData::Shell::Cast (aShape));
aPartWasProcessed = true;
}
}
}
if (aPartWasProcessed) {
PostProcessPart (thePart);
myData.push_back (aProcessData);
}
}
Iterates over subshapes in a shape.
Definition ShapeIterator.hxx:32

MTKConverter_MachiningProcessor.hxx

// ****************************************************************************
// $Id$
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2025, CADEX. All rights reserved.
//
// This file is part of the Manufacturing Toolkit software.
//
// This file may be used under the terms and conditions of the License
// Agreement supplied with the software.
//
// This file is provided "AS IS" WITH NO WARRANTY OF ANY KIND, EITHER EXPRESSED
// OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE WARRANTY OF DESIGN,
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// ****************************************************************************
#ifndef _MTKConverter_MachiningProcessor_HeaderFile
#define _MTKConverter_MachiningProcessor_HeaderFile
#include <cadex/Machining_OperationType.hxx>
#include <cadex/MTKBase_FeatureList.hxx>
#include <MTKConverter_PartProcessor.hxx>
namespace cadex {
namespace ModelData {
class Part;
class Solid;
}
}
class MTKConverter_MachiningData : public MTKConverter_ProcessData
{
public:
MTKConverter_MachiningData (const cadex::ModelData::Part& thePart) : MTKConverter_ProcessData (thePart)
{}
};
class MTKConverter_MachiningProcessor : public MTKConverter_VoidPartProcessor
{
public:
MTKConverter_MachiningProcessor (cadex::Machining_OperationType theOperation) : myOperation (theOperation)
{}
protected:
DataType CreateProcessData (const cadex::ModelData::Part& thePart) const override;
void ProcessSolid (DataType& theProcessData, const cadex::ModelData::Solid& theSolid) override;
};
#endif
Defines a list of features.
Definition MTKBase_FeatureList.hxx:36
Machining_OperationType
Defines an operation type in machining.
Definition Machining_OperationType.hxx:28

MTKConverter_MachiningProcessor.cxx

// ****************************************************************************
// $Id$
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2025, CADEX. All rights reserved.
//
// This file is part of the Manufacturing Toolkit software.
//
// This file may be used under the terms and conditions of the License
// Agreement supplied with the software.
//
// This file is provided "AS IS" WITH NO WARRANTY OF ANY KIND, EITHER EXPRESSED
// OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE WARRANTY OF DESIGN,
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// ****************************************************************************
#include <cadex/DFMMachining_Analyzer.hxx>
#include <cadex/DFMMachining_DeepPocketIssue.hxx>
#include <cadex/DFMMachining_DrillingAnalyzerParameters.hxx>
#include <cadex/DFMMachining_MillingAnalyzerParameters.hxx>
#include <cadex/DFMMachining_TurningAnalyzerParameters.hxx>
#include <cadex/Machining_Analyzer.hxx>
#include <cadex/Machining_Data.hxx>
#include <cadex/Machining_FeatureRecognizer.hxx>
#include <cadex/Machining_FeatureRecognizerParameters.hxx>
#include <cadex/ModelData/Solid.hxx>
#include <cadex/MTKBase_FeatureList.hxx>
#include <MTKConverter_MachiningProcessor.hxx>
using namespace cadex;
MTKConverter_MachiningProcessor::DataType
MTKConverter_MachiningProcessor::CreateProcessData (const ModelData::Part& thePart) const
{
return std::make_shared<MTKConverter_MachiningData> (thePart);
}
void MTKConverter_MachiningProcessor::ProcessSolid (DataType& theProcessData, const ModelData::Solid& theSolid)
{
auto aMachiningData = std::static_pointer_cast<MTKConverter_MachiningData> (theProcessData);
aMachiningData->myOperation = myOperation;
Machining_FeatureRecognizer aFeatureRecognizer;
aFeatureRecognizer.Parameters().SetOperation (myOperation);
Machining_Analyzer anAnalyzer;
anAnalyzer.AddTool (aFeatureRecognizer);
auto aData = anAnalyzer.Perform (theSolid);
if (aData.IsEmpty()) {
return;
}
//features
aMachiningData->myFeatureList.Append (aData.FeatureList());
//issues
DFMMachining_Analyzer aDrillingAnalyzer (aDrillingParameters);
aMachiningData->myIssueList.Append (aDrillingAnalyzer.Perform (theSolid, aData));
DFMMachining_Analyzer aMillingAnalyzer (aMillingParameters);
MTKBase_FeatureList aMillingIssueList = aMillingAnalyzer.Perform (theSolid, aData);
for (size_t i = 0; i < aMillingIssueList.Size(); ++i) {
const auto& anIssue = aMillingIssueList[i];
if (myOperation == Machining_OT_LatheMilling
&& !anIssue.IsOfType<DFMMachining_DeepPocketIssue>()) {
continue;
}
aMachiningData->myIssueList.Append (anIssue);
}
if (myOperation == Machining_OT_LatheMilling) {
DFMMachining_Analyzer aTurningAnalyzer (aTurninigParameters);
MTKBase_FeatureList aTurningIssueList = aTurningAnalyzer.Perform (theSolid, aData);
for (size_t i = 0; i < aTurningIssueList.Size(); ++i) {
const auto& anIssue = aTurningIssueList[i];
aMachiningData->myIssueList.Append (anIssue);
}
}
}
Provides an interface to run DFM Machining analysis.
Definition DFMMachining_Analyzer.hxx:43
Describes deep pocket issue found during cnc machining milling design analysis.
Definition DFMMachining_DeepPocketIssue.hxx:30
Defines parameters used in cnc machining drilling design analysis.
Definition DFMMachining_DrillingAnalyzerParameters.hxx:31
Defines parameters used in cnc machining milling design analysis.
Definition DFMMachining_MillingAnalyzerParameters.hxx:36
Defines parameters used in cnc machining turning design analysis.
Definition DFMMachining_TurningAnalyzerParameters.hxx:35
size_t Size() const
Returns the number of elements in the list.
Definition MTKBase_FeatureList.cxx:94
void Append(const MTKBase_Feature &theFeature)
Adds a feature to the list.
Definition MTKBase_FeatureList.cxx:56
Provides an interface to run several analyzer tools for different types of machining processing.
Definition Machining_Analyzer.hxx:42
Machining_Data Perform(const ModelData::Solid &theSolid, const cadex::ProgressStatus &theProgressStatus=cadex::ProgressStatus())
Runs the analyzing process.
Definition Machining_Analyzer.cxx:82
void AddTool(const Machining_AnalyzerTool &theTool)
Adds additional tool to run during analyzing process.
Definition Machining_Analyzer.cxx:102
Provides an interface to recognizing machining features tool.
Definition Machining_FeatureRecognizer.hxx:45
const Machining_FeatureRecognizerParameters & Parameters() const
Returns parameters.
Definition Machining_FeatureRecognizer.cxx:320
void SetOperation(Machining_OperationType theOperation)
Definition Machining_FeatureRecognizerParameters.cxx:221

MTKConverter_SheetMetalProcessor.hxx

// ****************************************************************************
// $Id$
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2025, CADEX. All rights reserved.
//
// This file is part of the Manufacturing Toolkit software.
//
// This file may be used under the terms and conditions of the License
// Agreement supplied with the software.
//
// This file is provided "AS IS" WITH NO WARRANTY OF ANY KIND, EITHER EXPRESSED
// OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE WARRANTY OF DESIGN,
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// ****************************************************************************
#ifndef _MTKConverter_SheetMetalProcessor_HeaderFile
#define _MTKConverter_SheetMetalProcessor_HeaderFile
#include <cadex/ModelData/SheetBody.hxx>
#include <cadex/ModelData/Shell.hxx>
#include <cadex/MTKBase_FeatureList.hxx>
#include <cadex/SheetMetal_Analyzer.hxx>
#include <cadex/SheetMetal_Data.hxx>
#include <cadex/SheetMetal_FlatPattern.hxx>
#include <MTKConverter_PartProcessor.hxx>
class MTKConverter_UnfoldedPartData
{
public:
MTKConverter_UnfoldedPartData()
{}
bool IsInit() const { return !myFlatPatterns.empty(); }
std::deque<cadex::SheetMetal_FlatPattern> myFlatPatterns;
};
class MTKConverter_SheetMetalData : public MTKConverter_ProcessData
{
public:
MTKConverter_SheetMetalData (const cadex::ModelData::Part& thePart);
bool myIsSheetMetalPart = false;
MTKConverter_UnfoldedPartData myUnfoldedPartData;
};
class MTKConverter_SheetMetalProcessor : public MTKConverter_VoidPartProcessor
{
public:
MTKConverter_SheetMetalProcessor (cadex::ModelData::Model& theUnfoldedModel);
protected:
DataType CreateProcessData (const cadex::ModelData::Part& thePart) const override;
void ProcessSolid (DataType& theProcessData, const cadex::ModelData::Solid& theSolid) override;
void ProcessShell (DataType& theProcessData, const cadex::ModelData::Shell& theShell) override;
void PostProcessPart (const cadex::ModelData::Part& thePart) override;
void Process (DataType& theProcessData, const cadex::SheetMetal_Data& theData);
cadex::ModelData::Model& myUnfoldedModel;
cadex::ModelData::SheetBody myCurrentUnfoldedBody;
};
#endif
Provides MTK data model.
Definition Model.hxx:40
Provides a sheet body composed of faces and shells.
Definition SheetBody.hxx:34
Provides an interface to run several analyzer tools.
Definition SheetMetal_Analyzer.hxx:42
Contains specific information for sheet metal tools.
Definition SheetMetal_Data.hxx:36

MTKConverter_SheetMetalProcessor.cxx

// ****************************************************************************
// $Id$
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2025, CADEX. All rights reserved.
//
// This file is part of the Manufacturing Toolkit software.
//
// This file may be used under the terms and conditions of the License
// Agreement supplied with the software.
//
// This file is provided "AS IS" WITH NO WARRANTY OF ANY KIND, EITHER EXPRESSED
// OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE WARRANTY OF DESIGN,
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// ****************************************************************************
#include <cadex/DFMSheetMetal_Analyzer.hxx>
#include <cadex/DFMSheetMetal_FlatPatternInterferenceIssue.hxx>
#include <cadex/DFMSheetMetal_NonStandardSheetSizeIssue.hxx>
#include <cadex/DFMSheetMetal_NonStandardSheetThicknessIssue.hxx>
#include <cadex/Geom/Transformation.hxx>
#include <cadex/Measurements/BoundingBox.hxx>
#include <cadex/Measurements/ValidationProperties.hxx>
#include <cadex/Measurements/ValidationPropertyData.hxx>
#include <cadex/ModelData/Box.hxx>
#include <cadex/ModelData/Shell.hxx>
#include <cadex/ModelData/SheetBody.hxx>
#include <cadex/ModelData/Solid.hxx>
#include <cadex/SheetMetal_Analyzer.hxx>
#include <cadex/SheetMetal_Data.hxx>
#include <cadex/SheetMetal_FeatureRecognizer.hxx>
#include <cadex/SheetMetal_FlatPattern.hxx>
#include <cadex/SheetMetal_Unfolder.hxx>
#include <MTKConverter_SheetMetalProcessor.hxx>
#include <vector>
using namespace cadex;
MTKConverter_SheetMetalData::MTKConverter_SheetMetalData (const cadex::ModelData::Part& thePart) :
MTKConverter_ProcessData (thePart)
{}
MTKConverter_SheetMetalProcessor::MTKConverter_SheetMetalProcessor (cadex::ModelData::Model& theUnfoldedModel) :
myUnfoldedModel (theUnfoldedModel)
{
myAnalyzer.AddTool (SheetMetal_FeatureRecognizer());
myAnalyzer.AddTool (SheetMetal_Unfolder());
}
MTKConverter_SheetMetalProcessor::DataType
MTKConverter_SheetMetalProcessor::CreateProcessData (const ModelData::Part& thePart) const
{
return std::make_shared<MTKConverter_SheetMetalData> (thePart);
}
void MTKConverter_SheetMetalProcessor::ProcessSolid (DataType& theProcessData,
const ModelData::Solid& theSolid)
{
auto anSMData = myAnalyzer.Perform (theSolid);
Process (theProcessData, anSMData);
}
void MTKConverter_SheetMetalProcessor::ProcessShell (DataType& theProcessData,
const ModelData::Shell& theShell)
{
auto anSMData = myAnalyzer.Perform (theShell);
Process (theProcessData, anSMData);
}
void MTKConverter_SheetMetalProcessor::PostProcessPart (const ModelData::Part& thePart)
{
if (myCurrentUnfoldedBody.Shapes().empty()) {
return;
}
ModelData::Part anUnfoldedPart (thePart.Name());
anUnfoldedPart.SetUuid (thePart.Uuid());
anUnfoldedPart.AddBody (myCurrentUnfoldedBody);
myUnfoldedModel.AddRoot (anUnfoldedPart);
myCurrentUnfoldedBody = ModelData::SheetBody();
}
void MTKConverter_SheetMetalProcessor::Process (DataType& theProcessData,
const SheetMetal_Data& theData)
{
if (theData.IsEmpty()) {
return;
}
auto anSMData = std::static_pointer_cast<MTKConverter_SheetMetalData> (theProcessData);
anSMData->myIsSheetMetalPart = true;
anSMData->myFeatureList.Append (theData.FeatureList());
const auto& aFlatPattern = theData.FlatPattern();
auto anUnfoldedShell = aFlatPattern ? aFlatPattern.UnfoldedShell() : ModelData::Shell();
auto& anUnfoldedData = anSMData->myUnfoldedPartData;
if (anUnfoldedShell) {
myCurrentUnfoldedBody.Append (anUnfoldedShell);
anUnfoldedData.myFlatPatterns.push_back (aFlatPattern);
}
DFMSheetMetal_Analyzer aDFMAnalyzer;
auto anIssueList = aDFMAnalyzer.Perform (theData);
for (size_t i = 0; i < anIssueList.Size(); ++i) {
const auto& anIssue = anIssueList[i];
if (anUnfoldedData.IsInit()
anUnfoldedData.myIssueList.Append (anIssue);
} else {
anSMData->myIssueList.Append (anIssue);
}
}
}
Provides an interface to run DFM Sheet Metal analysis.
Definition DFMSheetMetal_Analyzer.hxx:44
MTKBase_FeatureList Perform(const ModelData::Solid &theSolid, const cadex::ProgressStatus &theProgressStatus=cadex::ProgressStatus())
Definition DFMSheetMetal_Analyzer.cxx:1578
Describes interference issue for flat pattern found during sheet metal design analysis.
Definition DFMSheetMetal_FlatPatternInterferenceIssue.hxx:32
Describes non standard sheet size issue found during sheet metal design analysis.
Definition DFMSheetMetal_NonStandardSheetSizeIssue.hxx:30
Describes non standard sheet thickness issue found during sheet metal design analysis.
Definition DFMSheetMetal_NonStandardSheetThicknessIssue.hxx:28
UTF16String Name() const
Returns a name.
Definition ModelElement.cxx:55
cadex::Uuid Uuid() const
Returns an object uuid.
Definition ModelElement.cxx:76
bool IsEmpty() const
Returns true if the data is empty.
Definition SheetMetal_Data.cxx:83
const SheetMetal_FlatPattern & FlatPattern() const
Definition SheetMetal_Data.cxx:77
const MTKBase_FeatureList & FeatureList() const
Definition SheetMetal_Data.cxx:68
Provides an interface to recognizing sheet metal features tool. Is used for recognition of features s...
Definition SheetMetal_FeatureRecognizer.hxx:38
ModelData::Shell UnfoldedShell() const
Returns the unfolded shell for flat pattern.
Definition SheetMetal_FlatPattern.cxx:226
Is used to unfold sheet metal models.
Definition SheetMetal_Unfolder.hxx:39

MTKConverter_Report.hxx

// ****************************************************************************
// $Id$
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2025, CADEX. All rights reserved.
//
// This file is part of the Manufacturing Toolkit software.
//
// This file may be used under the terms and conditions of the License
// Agreement supplied with the software.
//
// This file is provided "AS IS" WITH NO WARRANTY OF ANY KIND, EITHER EXPRESSED
// OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE WARRANTY OF DESIGN,
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// ****************************************************************************
#ifndef _MTKConverter_Report_HeaderFile
#define _MTKConverter_Report_HeaderFile
#include <deque>
#include <memory>
namespace cadex {
class UTF16String;
}
class MTKConverter_ProcessData;
class MTKConverter_Report
{
public:
typedef std::shared_ptr<MTKConverter_ProcessData> DataType;
void AddData (const DataType& theData) { myData.push_back (theData); }
bool WriteToJSON (const cadex::UTF16String& thePath) const;
private:
std::deque<DataType> myData;
};
#endif
Defines a Unicode (UTF-16) string wrapping a standard string.
Definition UTF16String.hxx:30

MTKConverter_Report.cxx

// ****************************************************************************
// $Id$
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2025, CADEX. All rights reserved.
//
// This file is part of the Manufacturing Toolkit software.
//
// This file may be used under the terms and conditions of the License
// Agreement supplied with the software.
//
// This file is provided "AS IS" WITH NO WARRANTY OF ANY KIND, EITHER EXPRESSED
// OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE WARRANTY OF DESIGN,
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// ****************************************************************************
#ifndef _USE_MATH_DEFINES
#define _USE_MATH_DEFINES
#endif
#include <cadex/Utilities/JSONSerializer.hxx>
#include <MTKConverter_Report.hxx>
#include <MTKConverter_MachiningProcessor.hxx>
#include <MTKConverter_MoldingProcessor.hxx>
#include <MTKConverter_SheetMetalProcessor.hxx>
#include <MTKConverter_WallThicknessProcessor.hxx>
#include <../../helpers/JSONWriter.hxx>
#include <fstream>
#include <iomanip>
#include <sstream>
using namespace cadex;
using namespace cadex::Utilities;
namespace cadex {
namespace Geom {
inline std::ostream& operator<< (std::ostream& theStream, const Point& thePoint)
{
return theStream << "(" << thePoint.X() << ", " << thePoint.Y() << ", " << thePoint.Z() << ")";
}
}}
namespace {
bool WriteFeatures (JSONWriter& theWriter,
const char* theGroupName,
const char* theSubgroupName,
const MTKBase_FeatureList& theFeatures,
const char* theMessageForEmptyList)
{
theWriter.OpenSection (theSubgroupName);
theWriter.WriteData ("name", theGroupName);
if (theFeatures.IsEmpty()) {
theWriter.WriteData ("message", theMessageForEmptyList);
} else {
aParams.SetStartIndentLevel (theWriter.NestingLevel());
JSONSerializer aJSONSerializer (aParams);
auto aFeaturesJSON = aJSONSerializer.Serialize (theFeatures);
theWriter.WriteRawData (aFeaturesJSON);
}
theWriter.CloseSection();
return true;
}
const char* MachiningProcessName (Machining_OperationType theOperation)
{
switch (theOperation) {
case Machining_OT_Milling: return "CNC Machining Milling";
case Machining_OT_LatheMilling: return "CNC Machining Lathe+Milling";
default:
break;
}
return "CNC Machining";
}
bool HasShapes (const std::vector<ModelData::Body>& theBodies, ModelData::ShapeType theType)
{
for (const auto& aBody : theBodies) {
ModelData::ShapeIterator aShapeIt (aBody, theType);
if (aShapeIt.HasNext()) {
return true;
}
}
return false;
}
void WriteThicknessNode (JSONWriter& theWriter,
const char* theParamName,
double theParamValue,
const PointPairType& thePoints,
const char* theNodeName)
{
std::stringstream aStream;
aStream << std::fixed << std::setprecision (2);
JSONWriter aWriter (aStream, 3);
aWriter.OpenSection (theNodeName);
aWriter.WriteData ("name", theParamName);
aWriter.WriteData ("units", "mm");
aWriter.WriteData ("value", theParamValue);
aWriter.WriteData ("firstPoint", thePoints.first);
aWriter.WriteData ("secondPoint", thePoints.second);
aWriter.CloseSection();
theWriter.WriteRawData (aStream.str());
}
void WriteUnfoldedPartFeatures (JSONWriter& theWriter,
const MTKConverter_UnfoldedPartData& theData)
{
theWriter.OpenSection ("featureRecognitionUnfolded");
theWriter.WriteData ("name", "Feature Recognition");
if (theData.IsInit()) {
aParams.SetStartIndentLevel (4);
JSONSerializer aJSONSerializer (aParams);
auto aFeaturesJSON = aJSONSerializer.Serialize (theData.myFlatPatterns[0]);
theWriter.WriteRawData (aFeaturesJSON);
} else {
theWriter.WriteData ("message", "Unfolded part wasn't generated.");
}
theWriter.CloseSection();
}
typedef std::shared_ptr<MTKConverter_ProcessData> DataType;
void WritePartProcessData (JSONWriter& theWriter, const DataType& theProcessData)
{
bool aRes = false;
theWriter.WriteData ("partId", theProcessData->myPart.Uuid());
std::string anErrorMsg = "An error occurred while processing the part.";
if (theProcessData) {
if (auto aMD = std::dynamic_pointer_cast<MTKConverter_MachiningData> (theProcessData)) {
theWriter.WriteData ("process", MachiningProcessName (aMD->myOperation));
const auto& aBodies = aMD->myPart.Bodies();
if (!aMD->myFeatureList.IsEmpty()) {
WriteFeatures (theWriter, "Feature Recognition", "featureRecognition", aMD->myFeatureList, "");
WriteFeatures (theWriter, "Design for Manufacturing", "dfm", aMD->myIssueList,
"Part contains no DFM improvement suggestions.");
aRes = true;
} else if (aBodies.empty() || !HasShapes (aBodies, ModelData::ShapeType::Solid)) {
anErrorMsg = "The part can't be analyzed due to lack of: "
"BRep representation or solids in BRep representation.";
}
} else if (auto aWTD = std::dynamic_pointer_cast<MTKConverter_WallThicknessData> (theProcessData)) {
theWriter.WriteData ("process", "Wall Thickness Analysis");
const auto& aBodies = aWTD->myPart.Bodies();
if (aWTD->myIsInit) {
WriteThicknessNode (theWriter, "Minimum Thickness", aWTD->myMinThickness, aWTD->myMinThicknessPoints, "minThickness");
WriteThicknessNode (theWriter, "Maximum Thickness", aWTD->myMaxThickness, aWTD->myMaxThicknessPoints, "maxThickness");
aRes = true;
} else if ((aBodies.empty() || !HasShapes (aBodies, ModelData::ShapeType::Solid))) {
anErrorMsg = "The part can't be analyzed due to lack of: "
"BRep representation, solids in BRep representation.";
}
} else if (auto aMoldingData = std::dynamic_pointer_cast<MTKConverter_MoldingData> (theProcessData)) {
const auto& aBodies = aMoldingData->myPart.Bodies();
if (!aMoldingData->myFeatureList.IsEmpty()) {
theWriter.WriteData ("process", "Molding Analysis");
WriteFeatures (theWriter, "Feature Recognition", "featureRecognition", aMoldingData->myFeatureList, "");
WriteFeatures (theWriter, "Design for Manufacturing", "dfm", aMoldingData->myIssueList,
"Part contains no DFM improvement suggestions.");
aRes = true;
} else if (aBodies.empty() || !HasShapes (aBodies, ModelData::ShapeType::Solid)) {
anErrorMsg = "The part can't be analyzed due to lack of: "
"BRep representation or solids in BRep representation.";
}
} else if (auto aSMD = std::dynamic_pointer_cast<MTKConverter_SheetMetalData> (theProcessData)) {
theWriter.WriteData ("process", "Sheet Metal");
const auto& aBodies = aSMD->myPart.Bodies();
if (aSMD->myIsSheetMetalPart) {
WriteFeatures (theWriter, "Feature Recognition", "featureRecognition", aSMD->myFeatureList,
"Part contains no features.");
WriteFeatures (theWriter, "Design for Manufacturing", "dfm", aSMD->myIssueList,
"Part contains no DFM improvement suggestions.");
const auto& anUnfoldedPartData = aSMD->myUnfoldedPartData;
WriteUnfoldedPartFeatures (theWriter, anUnfoldedPartData);
if (anUnfoldedPartData.IsInit()) {
WriteFeatures (theWriter, "Design for Manufacturing", "dfmUnfolded", anUnfoldedPartData.myIssueList,
"Unfolded part contains no DFM improvement suggestions.");
}
aRes = true;
} else if (aBodies.empty() || (!HasShapes (aBodies, ModelData::ShapeType::Solid) && !HasShapes (aBodies, ModelData::ShapeType::Shell))) {
anErrorMsg = "The part can't be analyzed due to lack of: "
"BRep representation, solids and shells in BRep representation.";
} else {
anErrorMsg = "The part wasn't recognized as a sheet metal part.";
}
} else {
anErrorMsg = "Unrecognized process";
}
}
if (!aRes) {
theWriter.WriteData ("error", anErrorMsg);
}
}
}
bool MTKConverter_Report::WriteToJSON (const UTF16String& thePath) const
{
std::ofstream aFile (thePath.ToString());
if (!aFile) {
return false;
}
JSONWriter aWriter (aFile);
aWriter.OpenSection();
aWriter.WriteData ("version", "1");
if (myData.empty()) {
aWriter.WriteData ("error", "The model doesn't contain any parts.");
} else {
aWriter.OpenArraySection ("parts");
for (const auto& aProcessData : myData) {
aWriter.OpenSection();
WritePartProcessData (aWriter, aProcessData);
aWriter.CloseSection();
}
aWriter.CloseArraySection();
}
aWriter.CloseSection();
return true;
}
bool IsEmpty() const
Definition MTKBase_FeatureList.hxx:51
Serializes MTK entities into a JSON report.
Definition JSONSerializer.hxx:70
Configuration for JSON serialization.
Definition JSONSerializer.hxx:49
ShapeType
Defines shape type.
Definition ShapeType.hxx:27
Contains utility classes that can be useful for debugging or configuring global settings.
@ Machining_OT_Milling
Milling operation type.
Definition Machining_OperationType.hxx:29
@ Machining_OT_LatheMilling
Lathe + Milling operation type.
Definition Machining_OperationType.hxx:30

MTKConverter_Application.hxx

// ****************************************************************************
// $Id$
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2025, CADEX. All rights reserved.
//
// This file is part of the Manufacturing Toolkit software.
//
// This file may be used under the terms and conditions of the License
// Agreement supplied with the software.
//
// This file is provided "AS IS" WITH NO WARRANTY OF ANY KIND, EITHER EXPRESSED
// OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE WARRANTY OF DESIGN,
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// ****************************************************************************
#ifndef _MTKConverter_Application_HeaderFile
#define _MTKConverter_Application_HeaderFile
enum MTKConverter_ReturnCode
{
// General codes
MTKConverter_RC_OK = 0,
MTKConverter_RC_UnknownError = 1,
MTKConverter_RC_GeneralException = 2,
MTKConverter_RC_NoValidLicense = 3,
MTKConverter_RC_InvalidArgumentsNumber = 4,
MTKConverter_RC_InvalidArgument = 5,
// Import errors
MTKConverter_RC_UnsupportedVersion = 100,
MTKConverter_RC_UnexpectedFormat = 101,
MTKConverter_RC_UnsupportedFileVariant = 102,
MTKConverter_RC_ImportError = 103,
// Process errors
MTKConverter_RC_ProcessError = 200,
// Export errors
MTKConverter_RC_ExportError = 300,
};
class MTKConverter_Application
{
public:
MTKConverter_Application();
MTKConverter_ReturnCode Run (int argc, char *argv[]) const;
void PrintUsage() const;
};
#endif

MTKConverter_Application.cxx

// ****************************************************************************
// $Id$
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2025, CADEX. All rights reserved.
//
// This file is part of the Manufacturing Toolkit software.
//
// This file may be used under the terms and conditions of the License
// Agreement supplied with the software.
//
// This file is provided "AS IS" WITH NO WARRANTY OF ANY KIND, EITHER EXPRESSED
// OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE WARRANTY OF DESIGN,
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// ****************************************************************************
#include <cadex/ModelData/Model.hxx>
#include <cadex/ModelData/ModelReader.hxx>
#include <cadex/View/Color.hxx>
#include <cadex/View/ImageWriter.hxx>
#include <cadex/View/ImageWriterParameters.hxx>
#include <MTKConverter_Application.hxx>
#include <MTKConverter_MachiningProcessor.hxx>
#include <MTKConverter_MoldingProcessor.hxx>
#include <MTKConverter_Report.hxx>
#include <MTKConverter_SheetMetalProcessor.hxx>
#include <MTKConverter_WallThicknessProcessor.hxx>
#include <cstring>
#include <iostream>
#include <unordered_map>
#if defined(__GNUC__)
#include <sys/stat.h>
#elif !defined(_MSC_VER) || _MSC_VER > 1900
#include <filesystem>
#endif
using namespace cadex;
namespace {
enum MTKConverter_ProcessType
{
MTKConverter_PT_Undefined = -1,
MTKConverter_PT_WallThickness = 0,
MTKConverter_PT_MachiningMilling,
MTKConverter_PT_MachiningTurning,
MTKConverter_PT_Molding,
MTKConverter_PT_SheetMetal
};
MTKConverter_ProcessType ProcessType (const UTF16String& theProcessName)
{
static std::unordered_map<UTF16String, MTKConverter_ProcessType, UTF16StringHash> aProcessMap
{
{"wall_thickness" , MTKConverter_PT_WallThickness},
{"machining_milling", MTKConverter_PT_MachiningMilling},
{"machining_turning", MTKConverter_PT_MachiningTurning},
{"molding" , MTKConverter_PT_Molding},
{"sheet_metal" , MTKConverter_PT_SheetMetal}
};
auto aRes = aProcessMap.find (theProcessName);
if (aRes != aProcessMap.end()) {
return aRes->second;
}
return MTKConverter_PT_Undefined;
}
MTKConverter_ReturnCode Import (const UTF16String& theFilePath, ModelData::Model& theModel)
{
std::cout << "Importing " << theFilePath << "..." << std::flush;
if (!aReader.Read (theFilePath, theModel)) {
std::cerr << std::endl << "ERROR: Failed to import " << theFilePath << ". Exiting" << std::endl;
return MTKConverter_RC_ImportError;
}
return MTKConverter_RC_OK;
}
bool CreateOriginModelThumbnail (const UTF16String& theFilePath, const ModelData::Model& theModel)
{
auto aParameters = aWriter.Parameters();
aParameters.SetImageHeight (800);
aParameters.SetImageWidth (600);
aParameters.SetViewCameraProjection (View::CameraProjectionType::Perspective);
aParameters.SetViewCameraPosition (View::CameraPositionType::Default);
aParameters.SetViewIsFitAll (true);
aParameters.SetViewAntialiasing (View::AntialiasingMode::High);
aParameters.SetViewBackground (View::ColorBackgroundStyle (View::Color (255, 255, 255)));
aWriter.SetParameters (aParameters);
bool aRes = aWriter.WriteFile (theModel, theFilePath);
return aRes;
}
MTKConverter_ReturnCode Process (const UTF16String& theProcess,
ModelData::Model& theModel,
MTKConverter_Report& theReport,
ModelData::Model& theProcessModel)
{
std::cout << "Processing " << theProcess << "..." << std::flush;
theModel.AssignUuids();
auto ApplyProcessorToModel = [&theModel, &theReport] (MTKConverter_PartProcessor& theProcessor) {
ModelData::ModelElementUniqueVisitor aVisitor (theProcessor);
theModel.Accept (aVisitor);
for (const auto& i : theProcessor.myData) {
theReport.AddData (i);
}
};
auto aProcessType = ProcessType (theProcess);
switch (aProcessType) {
case MTKConverter_PT_WallThickness:
{
MTKConverter_WallThicknessProcessor aProcessor (800);
ApplyProcessorToModel (aProcessor);
break;
}
case MTKConverter_PT_MachiningMilling:
{
MTKConverter_MachiningProcessor aProcessor (Machining_OT_Milling);
ApplyProcessorToModel (aProcessor);
break;
}
case MTKConverter_PT_MachiningTurning:
{
MTKConverter_MachiningProcessor aProcessor (Machining_OT_LatheMilling);
ApplyProcessorToModel (aProcessor);
break;
}
case MTKConverter_PT_Molding:
{
theProcessModel.SetName (theModel.Name() + "_extra");
MTKConverter_MoldingProcessor aProcessor (theProcessModel);
ApplyProcessorToModel (aProcessor);
break;
}
case MTKConverter_PT_SheetMetal:
{
theProcessModel.SetName (theModel.Name() + "_unfolded");
MTKConverter_SheetMetalProcessor aProcessor (theProcessModel);
ApplyProcessorToModel (aProcessor);
break;
}
case MTKConverter_PT_Undefined:
default : return MTKConverter_RC_InvalidArgument;
}
return MTKConverter_RC_OK;
}
MTKConverter_ReturnCode Export (const UTF16String& theFolderPath,
const bool theToGenerateScreenshot,
const ModelData::Model& theModel,
const MTKConverter_Report& theReport,
const ModelData::Model& theProcessModel)
{
std::cout << "Exporting " << theFolderPath << "..." << std::flush;
#if defined(_MSC_VER) && _MSC_VER < 1910
(void)theReport;
(void)theModel;
(void)theProcessModel;
std::cout << "Use the Microsoft Visual C++ 2019 (VC14.2) compiler or newer." << std::flush;
return MTKConverter_RC_OK;
#else
#if defined(__GNUC__)
mkdir (theFolderPath.ToString().c_str(), 0755);
#else
std::filesystem::create_directory (theFolderPath.ToString());
#endif
UTF16String aModelPath = theFolderPath + "/" + theModel.Name() + ".mtkweb" + "/scenegraph.mtkweb";
if (!theModel.Save (aModelPath, ModelData::Model::FileFormatType::MTKWEB)) {
std::cerr << std::endl << "ERROR: Failed to export " << aModelPath << ". Exiting" << std::endl;
return MTKConverter_RC_ExportError;
}
UTF16String aThumbnailPath = theFolderPath + "/thumbnail.png";
if (theToGenerateScreenshot && !CreateOriginModelThumbnail (aThumbnailPath, theModel)) {
std::cerr << std::endl << "ERROR: Failed to create thumbnail " << aThumbnailPath << ". Exiting" << std::endl;
return MTKConverter_RC_ExportError;
}
if (!theProcessModel.IsEmpty()) {
UTF16String aProcessModelPath = theFolderPath + "/" + theProcessModel.Name() + ".mtkweb" + "/scenegraph.mtkweb";
if (!theProcessModel.Save (aProcessModelPath, ModelData::Model::FileFormatType::MTKWEB)) {
std::cerr << std::endl << "ERROR: Failed to export " << aProcessModelPath << ". Exiting" << std::endl;
return MTKConverter_RC_ExportError;
}
}
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_RC_ExportError;
}
return MTKConverter_RC_OK;
#endif
}
}
MTKConverter_Application::MTKConverter_Application()
{
}
MTKConverter_ReturnCode MTKConverter_Application::Run (int argc, char *argv[]) const
{
if (argc == 1 || (
!strcmp (argv[1], "-?") || !strcmp (argv[1], "/?") ||
!strcmp (argv[1], "-h") || !strcmp (argv[1], "--help"))) {
PrintUsage();
return MTKConverter_RC_OK;
}
if (argc < 6) {
std::cerr << "Invalid number of arguments. Please use \"-h\" or \"--help\" for usage information." << std::endl;
return MTKConverter_RC_InvalidArgumentsNumber;
}
//parse and execute command line
enum Mode { NeutralMode, ImportMode, ProcessMode, ExportMode };
ModelData::Model aProcessModel;
auto aMode = NeutralMode;
MTKConverter_Report aReport;
auto aRes = MTKConverter_RC_OK;
bool aToGenerateScreenshot = true;
for(int i = 1; (i < argc) && (aRes == MTKConverter_RC_OK); ++i) {
const UTF16String anArgument = argv[i];
if (anArgument == "--no-screenshot") {
aToGenerateScreenshot = false;
} else if(anArgument == "-i") {
aMode = ImportMode;
} else if (anArgument == "-p") {
aMode = ProcessMode;
} else if (anArgument == "-e") {
aMode = ExportMode;
} else {
try {
if (aMode == ImportMode) {
aRes = Import (anArgument, aModel);
} else if (aMode == ProcessMode) {
aRes = Process (anArgument, aModel, aReport, aProcessModel);
} else if(aMode == ExportMode) {
aRes = Export (anArgument, aToGenerateScreenshot, aModel, aReport, aProcessModel);
} else {
std::cerr << "ERROR!: Invalid argument " << anArgument << ". Exiting" << std::endl;
std::cerr << "Type " << argv[0] << " -h for help." << std::endl;
return MTKConverter_RC_InvalidArgument;
}
std::cout << "Done." << std::endl;
} catch (...) {
std::cerr << "Failed.\nERROR: Unhandled exception caught." << std::endl;
return MTKConverter_RC_GeneralException;
}
}
}
return aRes;
}
void MTKConverter_Application::PrintUsage() const
{
std::cout << "Usage:" << std::endl;
std::cout << "MTKConverter -i <import_file> -p <process> --no-screenshot -e <export_folder>" << std::endl << std::endl;
std::cout << "Arguments:" << std::endl;
std::cout << " <import_file> - import file name" << std::endl;
std::cout << " <process> - manufacturing process or algorithm name" << std::endl;
std::cout << " <export_folder> - export folder name" << std::endl;
std::cout << " --no-screenshot - disable screenshot generation (optional)" << std::endl;
std::cout << "Example:" << std::endl;
std::cout << "MTKConverter -i C:\\models\\test.step -p machining_milling -e C:\\models\\test" << std::endl;
std::cout << std::endl << "Recognized processes:" << std::endl;
std::cout << " wall_thickness :\t Wall Thickness analysis" << std::endl;
std::cout << " machining_milling:\t CNC Machining Milling feature recognition and DFM analysis" << std::endl;
std::cout << " machining_turning:\t CNC Machining Lathe+Milling feature recognition and DFM analysis" << std::endl;
std::cout << " molding :\t Molding feature recognition and DFM analysis" << std::endl;
std::cout << " sheet_metal :\t Sheet Metal feature recognition, unfolding and DFM analysis" << std::endl;
}
Defines a visitor that visits each unique element only once.
Definition ModelElementVisitor.hxx:91
void SetName(const UTF16String &theName)
Sets a model name.
Definition Model.cxx:245
UTF16String Name() const
Returns a model name.
Definition Model.cxx:254
void AssignUuids()
Assigns uuid's (persistent id's) to scene graph elements and part representations (if not assigned ye...
Definition Model.cxx:268
bool IsEmpty() const
Returns true if the model is empty.
Definition Model.cxx:173
void Accept(ModelElementVisitor &theVisitor) const
Accepts a visitor.
Definition Model.cxx:274
Reads supported formats, see Import section.
Definition ModelReader.hxx:33
bool Read(const UTF16String &theFilePath, ModelData::Model &theModel)
Reads the file at the specified path into the specified model.
Definition ModelReader.cxx:281
Defines color background style.
Definition BackgroundStyle.hxx:45
Defines an RGBA color.
Definition Color.hxx:32
Writes an image file with graphical content of a model.
Definition ImageWriter.hxx:41

main.cxx

// ****************************************************************************
// $Id$
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2025, CADEX. All rights reserved.
//
// This file is part of the Manufacturing Toolkit software.
//
// You may use this file under the terms of the BSD license as follows:
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ****************************************************************************
#include <cadex/LicenseManager_Activate.h>
#include <MTKConverter_Application.hxx>
#include <iostream>
#include "../../mtk_license.cxx"
using namespace cadex;
using namespace std;
int main (int argc, char* argv[])
{
auto aKey = MTKLicenseKey::Value();
// Activate the license (aKey must be defined in mtk_license.cxx)
if (!CADExLicense_Activate (aKey)) {
cerr << "Failed to activate Manufacturing Toolkit license." << endl;
return 1;
}
MTKConverter_Application anApp;
return anApp.Run (argc, argv);
}