Hide menu
Loading...
Searching...
No Matches
MTKConverter/main.cxx
Refer to the MTK Converter Example.

MTKConverter_PartProcessor.hxx

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, 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/Base/Uuid.hxx>
#include <cadex/Drawing/Sheet.hxx>
#include <cadex/ModelData/Model.hxx>
#include <cadex/ModelData/Part.hxx>
#include <vector>
namespace cadex::ModelData {
class Body;
class IndexedTriangleSet;
class MeshBody;
class Shell;
class Solid;
}
class MTKConverter_ProcessData
{
protected:
MTKConverter_ProcessData (const cadex::ModelData::Part& thePart) :
myPart (thePart)
{}
MTKConverter_ProcessData (const std::vector<cadex::Drawing::Sheet>& theSheets) :
mySourceSheets (theSheets)
{}
public:
virtual ~MTKConverter_ProcessData()
{}
std::vector<cadex::Drawing::Sheet> mySourceSheets;
};
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::vector<DataType> myData;
protected:
bool ProcessBRepBody (DataType& theProcessData, const cadex::ModelData::Body& theBody);
bool ProcessMeshBody (DataType& theProcessData, const cadex::ModelData::MeshBody& theBody);
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 ProcessMesh (DataType& theProcessData, const cadex::ModelData::IndexedTriangleSet& theMesh) = 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 ProcessMesh (DataType&, const cadex::ModelData::IndexedTriangleSet&) override
{}
void PostProcessPart (const cadex::ModelData::Part&) override
{}
};
#endif
Provides a base body class.
Definition Body.hxx:28
Defines a polygonal shape consisting of triangles.
Definition IndexedTriangleSet.hxx:32
Defines a body that represents a polygonal mesh (faceted or tessellated).
Definition MeshBody.hxx:30
Element visitor with empty implementation.
Definition ModelElementVisitor.hxx:63
Defines a leaf node in the scene graph hierarchy.
Definition Part.hxx:32
Defines a connected set of faces.
Definition Shell.hxx:30
Defines a topological solid.
Definition ModelData/Solid.hxx:30
Defines classes, types, enums, and functions related to topological entities and scene graph elements...

MTKConverter_PartProcessor.cxx

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, 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/IndexedTriangleSet.hxx>
#include <cadex/ModelData/MeshBody.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) {
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);
}
}
bool MTKConverter_PartProcessor::ProcessBRepBody (DataType& theProcessData, const ModelData::Body& theBody)
{
bool aBodyWasProcessed = false;
ModelData::ShapeIterator aShapeIt (theBody);
while (aShapeIt.HasNext()) {
const auto& aShape = aShapeIt.Next();
if (aShape.Type() == ModelData::ShapeType::Solid) {
ProcessSolid (theProcessData, ModelData::Solid::Cast (aShape));
aBodyWasProcessed = true;
} else if (aShape.Type() == ModelData::ShapeType::Shell) {
ProcessShell (theProcessData, ModelData::Shell::Cast (aShape));
aBodyWasProcessed = true;
}
}
return aBodyWasProcessed;
}
bool MTKConverter_PartProcessor::ProcessMeshBody (DataType& theProcessData, const ModelData::MeshBody& theBody)
{
bool aBodyWasProcessed = false;
for (const auto& aMeshShape : theBody.Shapes()) {
if (aMeshShape && aMeshShape.IsOfType<ModelData::IndexedTriangleSet>()) {
ProcessMesh (theProcessData, static_cast<const ModelData::IndexedTriangleSet&> (aMeshShape));
aBodyWasProcessed = true;
}
}
return aBodyWasProcessed;
}
Iterates over subshapes in a shape.
Definition ShapeIterator.hxx:30
Contains classes, namespaces, enums, types, and global functions related to Manufacturing Toolkit.
Definition LicenseManager_LicenseError.hxx:29

MTKConverter_DrawingProcessor.hxx

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, 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_DrawingProcessor_HeaderFile
#define _MTKConverter_DrawingProcessor_HeaderFile
#include <MTKConverter_PartProcessor.hxx>
#include <vector>
namespace cadex::Drawing {
class Drawing;
class Sheet;
}
class MTKConverter_DrawingProcessor
{
public:
typedef std::shared_ptr<MTKConverter_ProcessData> DataType;
virtual ~MTKConverter_DrawingProcessor()
{}
virtual bool Apply (const cadex::Drawing::Drawing& theDrawing) = 0;
static std::vector<cadex::Drawing::Sheet> ExtractDrawingSheets (const cadex::Drawing::Drawing& theDrawing);
static void AddSheets (const cadex::Drawing::Drawing& theSrc, cadex::Drawing::Drawing& theDst);
std::vector<DataType> myData;
};
#endif
Represents a single 2D drawing of a model.
Definition Drawing.hxx:30
Contains classes, types and enums related to drawings.

MTKConverter_DrawingProcessor.cxx

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, 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 <MTKConverter_DrawingProcessor.hxx>
#include <cadex/Drawing/Drawing.hxx>
using namespace cadex;
std::vector<Drawing::Sheet> MTKConverter_DrawingProcessor::ExtractDrawingSheets (const Drawing::Drawing& theDrawing)
{
std::vector<Drawing::Sheet> aSheets;
for (Drawing::Drawing::SheetIterator aSheetIt (theDrawing); aSheetIt.HasNext();) {
aSheets.push_back (aSheetIt.Next());
}
return aSheets;
}
void MTKConverter_DrawingProcessor::AddSheets (const Drawing::Drawing& theSrc, Drawing::Drawing& theDst)
{
if (!theSrc) {
return;
}
if (!theDst) {
theDst = theSrc;
return;
}
for (Drawing::Drawing::SheetIterator anIt (theSrc); anIt.HasNext();) {
theDst.AddSheet (anIt.Next());
}
}
Iterator over sheets of a drawing.
Definition Drawing.hxx:45
bool HasNext() const
Returns true if the iterator can be advanced with Next().
Definition Drawing.cxx:108
void AddSheet(const Sheet &theSheet)
Adds a sheet to the drawing.
Definition Drawing.cxx:63

MTKConverter_MachiningProcessor.hxx

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, 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::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:35
Machining_OperationType
Defines an operation type in machining.
Definition Machining_OperationType.hxx:27

MTKConverter_MachiningProcessor.cxx

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, 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:42
Describes deep pocket issue found during cnc machining milling design analysis.
Definition DFMMachining_DeepPocketIssue.hxx:29
Defines parameters used in cnc machining drilling design analysis.
Definition DFMMachining_DrillingAnalyzerParameters.hxx:30
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:34
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:41
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:105
Provides an interface to recognizing machining features tool.
Definition Machining_FeatureRecognizer.hxx:44
const Machining_FeatureRecognizerParameters & Parameters() const
Returns parameters.
Definition Machining_FeatureRecognizer.cxx:388
void SetOperation(Machining_OperationType theOperation)
Sets machining operation type.
Definition Machining_FeatureRecognizerParameters.cxx:220

MTKConverter_MoldingProcessor.hxx

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, 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_MoldingProcessor_HeaderFile
#define _MTKConverter_MoldingProcessor_HeaderFile
#include <cadex/ModelData/SheetBody.hxx>
#include <cadex/MTKBase_FeatureList.hxx>
#include <MTKConverter_PartProcessor.hxx>
namespace cadex::ModelData {
class Part;
class Solid;
}
class MTKConverter_MoldingData : public MTKConverter_ProcessData
{
public:
MTKConverter_MoldingData (const cadex::ModelData::Part& thePart) :
MTKConverter_ProcessData (thePart)
{}
};
class MTKConverter_MoldingProcessor : public MTKConverter_VoidPartProcessor
{
public:
MTKConverter_MoldingProcessor (cadex::ModelData::Model& theExtraDataModel) :
myExtraDataModel (theExtraDataModel)
{}
protected:
DataType CreateProcessData (const cadex::ModelData::Part& thePart) const override;
void ProcessSolid (DataType& theProcessData, const cadex::ModelData::Solid& theSolid) override;
void PostProcessPart (const cadex::ModelData::Part& thePart) override;
cadex::ModelData::Model& myExtraDataModel;
cadex::ModelData::SheetBody myCurrentNewFaces;
};
#endif
Provides MTK data model.
Definition Model.hxx:39
Provides a sheet body composed of faces and shells.
Definition SheetBody.hxx:32

MTKConverter_MoldingProcessor.cxx

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, 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/DFMMolding_Analyzer.hxx>
#include <cadex/DFMMolding_AnalyzerParameters.hxx>
#include <cadex/ModelData/Face.hxx>
#include <cadex/ModelData/SheetBody.hxx>
#include <cadex/ModelData/Shape.hxx>
#include <cadex/ModelData/Solid.hxx>
#include <cadex/Molding_Analyzer.hxx>
#include <cadex/Molding_Data.hxx>
#include <cadex/Molding_FeatureRecognizer.hxx>
#include <cadex/Molding_FeatureRecognizerParameters.hxx>
#include <cadex/MTKBase_FeatureList.hxx>
#include <cadex/MTKBase_ShapeFeature.hxx>
#include <MTKConverter_MoldingProcessor.hxx>
#include <unordered_set>
using namespace cadex;
MTKConverter_MoldingProcessor::DataType MTKConverter_MoldingProcessor::CreateProcessData (
const ModelData::Part& thePart) const
{
return std::make_shared<MTKConverter_MoldingData> (thePart);
}
static void AddNewFacesFromFeatures (
const MTKBase_FeatureList& theFeatureList,
const ModelData::Solid& theSolid,
ModelData::SheetBody& theNewFaces)
{
std::unordered_set<size_t> aFaceIdSet;
{
ModelData::ShapeIterator aFaceIt (theSolid, ModelData::ShapeType::Face);
while (aFaceIt.HasNext()) {
aFaceIdSet.insert (aFaceIt.Next().Id());
}
}
for (size_t i = 0; i < theFeatureList.Size(); ++i) {
const auto& aFeature = static_cast<const MTKBase_ShapeFeature&> (theFeatureList[i]);
ModelData::ShapeIterator aFaceIt (aFeature.Shape(), ModelData::ShapeType::Face);
while (aFaceIt.HasNext()) {
const auto& aFace = aFaceIt.Next();
if (aFaceIdSet.find (aFace.Id()) == aFaceIdSet.end()) {
theNewFaces.Append (ModelData::Face::Cast (aFace));
}
}
}
}
void MTKConverter_MoldingProcessor::ProcessSolid (DataType& theProcessData, const ModelData::Solid& theSolid)
{
auto aMoldingData = std::static_pointer_cast<MTKConverter_MoldingData> (theProcessData);
Molding_FeatureRecognizer aFeatureRecognizer;
Molding_Analyzer anAnalyzer;
anAnalyzer.AddTool (aFeatureRecognizer);
auto aData = anAnalyzer.Perform (theSolid);
if (aData.IsEmpty()) {
return;
}
// features
const auto& aFeatureList = aData.FeatureList();
AddNewFacesFromFeatures (aFeatureList, theSolid, myCurrentNewFaces);
aMoldingData->myFeatureList.Append (aFeatureList);
// issues
DFMMolding_Analyzer aAnalyzer (aParameters);
aMoldingData->myIssueList.Append (aAnalyzer.Perform (aData));
}
void MTKConverter_MoldingProcessor::PostProcessPart (const cadex::ModelData::Part& thePart)
{
if (myCurrentNewFaces.Shapes().empty()) {
return;
}
ModelData::Part anExtraDataPart (thePart.Name());
anExtraDataPart.SetUuid (thePart.Uuid());
anExtraDataPart.AddBody (myCurrentNewFaces);
myExtraDataModel.AddRoot (anExtraDataPart);
myCurrentNewFaces = ModelData::SheetBody();
}
Provides an interface to run DFM Molding analysis.
Definition DFMMolding_Analyzer.hxx:39
Defines parameters used in injection molding design analysis.
Definition DFMMolding_AnalyzerParameters.hxx:34
Describes a feature with assigned shape.
Definition MTKBase_ShapeFeature.hxx:35
UTF16String Name() const
Returns a name.
Definition ModelElement.cxx:54
cadex::Uuid Uuid() const
Returns an object uuid.
Definition ModelElement.cxx:75
Provides an interface to run several analyzer tools for different types of Molding processing.
Definition Molding_Analyzer.hxx:40
Molding_Data Perform(const ModelData::Solid &theSolid, const ProgressStatus &theProgressStatus=ProgressStatus())
Runs the analyzing process.
Definition Molding_Analyzer.cxx:79
void AddTool(const Molding_AnalyzerTool &theTool)
Adds additional tool to run during analyzing process.
Definition Molding_Analyzer.cxx:99
const MTKBase_FeatureList & FeatureList() const
Returns the feature list found during Molding feature recognizing process.
Definition Molding_Data.cxx:47
Provides an interface to recognizing molding features.
Definition Molding_FeatureRecognizer.hxx:36

MTKConverter_SheetMetalProcessor.hxx

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, 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>
#include <deque>
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 an interface to run several analyzer tools.
Definition SheetMetal_Analyzer.hxx:41
Contains specific information for sheet metal tools.
Definition SheetMetal_Data.hxx:35

MTKConverter_SheetMetalProcessor.cxx

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, 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 <cadex/Drawing/Drawing.hxx>
#include <MTKConverter_DrawingProcessor.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);
aDrawingParams.SetIsIgnoreBendingLines (true);
Drawing::Drawing aFlatPatternDrawing = aFlatPattern.ToDrawing (aDrawingParams);
if (aFlatPatternDrawing) {
for (Drawing::Drawing::SheetIterator aSheetIt (aFlatPatternDrawing); aSheetIt.HasNext();) {
auto aSheet = aSheetIt.Next();
aSheet.SetUuid (anSMData->myPart.Uuid());
}
Drawing::Drawing aDrawing = myUnfoldedModel.Drawing();
if (!aDrawing) {
myUnfoldedModel.SetDrawing (aFlatPatternDrawing);
} else {
MTKConverter_DrawingProcessor::AddSheets (aFlatPatternDrawing, aDrawing);
myUnfoldedModel.SetDrawing (aDrawing);
}
}
}
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:43
MTKBase_FeatureList Perform(const ModelData::Solid &theSolid, const cadex::ProgressStatus &theProgressStatus=cadex::ProgressStatus())
Runs DFM analysis process.
Definition DFMSheetMetal_Analyzer.cxx:1710
Describes interference issue for flat pattern found during sheet metal design analysis.
Definition DFMSheetMetal_FlatPatternInterferenceIssue.hxx:31
Describes non standard sheet size issue found during sheet metal design analysis.
Definition DFMSheetMetal_NonStandardSheetSizeIssue.hxx:29
Describes non standard sheet thickness issue found during sheet metal design analysis.
Definition DFMSheetMetal_NonStandardSheetThicknessIssue.hxx:27
Drawing()
Constructor.
Definition Drawing.hxx:33
bool IsEmpty() const
Returns true if the data is empty.
Definition SheetMetal_Data.cxx:83
const SheetMetal_FlatPattern & FlatPattern() const
Returns the sheet metal flat pattern received by running sheet metal unfolder.
Definition SheetMetal_Data.cxx:77
const MTKBase_FeatureList & FeatureList() const
Returns the feature list found during sheet metal feature recognizing process.
Definition SheetMetal_Data.cxx:68
Provides an interface to recognizing sheet metal features tool.
Definition SheetMetal_FeatureRecognizer.hxx:37
Defines parameters used to generate a drawing.
Definition SheetMetal_FlatPattern.hxx:44
ModelData::Shell UnfoldedShell() const
Returns the unfolded shell for flat pattern.
Definition SheetMetal_FlatPattern.cxx:235
Is used to unfold sheet metal models.
Definition SheetMetal_Unfolder.hxx:38

MTKConverter_NestingProcessor.hxx

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, 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_NestingProcessor_HeaderFile
#define _MTKConverter_NestingProcessor_HeaderFile
#include <cadex/Drawing/Drawing.hxx>
#include <cadex/Drawing/Sheet.hxx>
#include <cadex/Drawing/View.hxx>
#include <cadex/ModelData/Model.hxx>
#include <cadex/Nesting_Data.hxx>
#include <MTKConverter_Application.hxx>
#include <MTKConverter_DrawingProcessor.hxx>
#include <vector>
class MTKConverter_Report;
class MTKConverter_NestingData : public MTKConverter_ProcessData
{
public:
MTKConverter_NestingData (const std::vector<cadex::Drawing::Sheet>& theSheets);
std::vector<cadex::Drawing::View> myPatterns;
cadex::Drawing::Drawing myResultDrawing;
size_t myPatternCountTotal = 0;
cadex::Nesting_Data myNestingResult;
};
class MTKConverter_NestingProcessor : public MTKConverter_DrawingProcessor
{
public:
MTKConverter_NestingProcessor (
cadex::ModelData::Model& theProcessModel,
const MTKConverter_NestingParameters& theNestingParameters);
bool Apply (const cadex::Drawing::Drawing& theDrawing) override;
private:
typedef std::shared_ptr<MTKConverter_NestingData> DataType;
DataType CreateProcessData (const std::vector<cadex::Drawing::Sheet>& theSheets) const;
void Process (MTKConverter_NestingData& theNestingData) const;
bool ProcessAllSheets (const std::vector<cadex::Drawing::Sheet>& theSourceSheets);
bool ProcessPerSheet (const std::vector<cadex::Drawing::Sheet>& theSourceSheets);
private:
cadex::ModelData::Model& myProcessModel;
MTKConverter_NestingParameters myNestingParameters;
};
#endif
Contains information about nesting sheets.
Definition Nesting_Data.hxx:38

MTKConverter_NestingProcessor.cxx

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, 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/Base/Uuid.hxx>
#include <cadex/Drawing/Drawing.hxx>
#include <cadex/Drawing/Geometry.hxx>
#include <cadex/Drawing/Sheet.hxx>
#include <cadex/Drawing/View.hxx>
#include <cadex/Geom/Direction2d.hxx>
#include <cadex/Geom/Line2d.hxx>
#include <cadex/Geom/Point2d.hxx>
#include <cadex/Geom/Vector2d.hxx>
#include <cadex/Nesting_Computer.hxx>
#include <cadex/Nesting_Data.hxx>
#include <MTKConverter_NestingProcessor.hxx>
#include <iostream>
using namespace cadex;
namespace {
std::vector<Drawing::View> ExtractPatternViews (const Drawing::Sheet& theSheet)
{
std::vector<Drawing::View> aPatterns;
for (Drawing::Sheet::ViewIterator aViewIt (theSheet); aViewIt.HasNext();) {
aPatterns.push_back (aViewIt.Next());
}
return aPatterns;
}
void AssignSheetUuids (Drawing::Drawing& theDrawing)
{
for (Drawing::Drawing::SheetIterator aSheetIt (theDrawing); aSheetIt.HasNext();) {
auto aSheet = aSheetIt.Next();
aSheet.SetUuid (Uuid::CreateRandom());
}
}
void AddNestingSheetFrames (Drawing::Drawing& theDrawing)
{
auto aMakeTrimmedLine = [] (const Geom::Point2d& theStart, const Geom::Point2d& theEnd)
{
Geom::Line2d aLine (theStart, Geom::Direction2d (theEnd - theStart));
aLine.SetTrim (0.0, theStart.Distance (theEnd));
return aLine;
};
for (Drawing::Drawing::SheetIterator aSheetIt (theDrawing); aSheetIt.HasNext();) {
auto aSheet = aSheetIt.Next();
const double aWidth = aSheet.Width();
const double aHeight = aSheet.Height();
const Geom::Point2d aP1 (0.0, 0.0);
const Geom::Point2d aP2 (aWidth, 0.0);
const Geom::Point2d aP3 (aWidth, aHeight);
const Geom::Point2d aP4 (0.0, aHeight);
aFrameContour.AddCurve (aMakeTrimmedLine (aP1, aP2));
aFrameContour.AddCurve (aMakeTrimmedLine (aP2, aP3));
aFrameContour.AddCurve (aMakeTrimmedLine (aP3, aP4));
aFrameContour.AddCurve (aMakeTrimmedLine (aP4, aP1));
Drawing::View aFrameView;
aFrameView.Add (aFrameContour);
aSheet.AddView (aFrameView);
}
}
}
MTKConverter_NestingData::MTKConverter_NestingData (const std::vector<cadex::Drawing::Sheet>& theSheets) :
MTKConverter_ProcessData (theSheets)
{}
MTKConverter_NestingProcessor::MTKConverter_NestingProcessor (
ModelData::Model& theProcessModel,
const MTKConverter_NestingParameters& theNestingParameters) :
myProcessModel (theProcessModel),
myNestingParameters (theNestingParameters)
{}
MTKConverter_NestingProcessor::DataType MTKConverter_NestingProcessor::CreateProcessData (
const std::vector<Drawing::Sheet>& theSheets) const
{
return std::make_shared<MTKConverter_NestingData> (theSheets);
}
void MTKConverter_NestingProcessor::Process (MTKConverter_NestingData& theNestingData) const
{
Nesting_Computer aComputer;
aComputer.SetParameters (myNestingParameters.myComputerParameters);
aComputer.AddMaterial (
myNestingParameters.myMaterialParameters.myLength,
myNestingParameters.myMaterialParameters.myWidth,
myNestingParameters.myMaterialParameters.myCount);
theNestingData.myPatternCountTotal = theNestingData.myPatterns.size() * myNestingParameters.myPatternRepeatCount;
for (const auto& aPattern : theNestingData.myPatterns) {
aComputer.AddPattern (aPattern, myNestingParameters.myPatternRepeatCount);
}
theNestingData.myNestingResult = aComputer.Perform();
}
bool MTKConverter_NestingProcessor::ProcessAllSheets (const std::vector<Drawing::Sheet>& theSourceSheets)
{
auto aNestingData = CreateProcessData (theSourceSheets);
for (const auto& aSourceSheet : theSourceSheets) {
const auto aSheetPatterns = ExtractPatternViews (aSourceSheet);
aNestingData->myPatterns.insert (aNestingData->myPatterns.end(), aSheetPatterns.begin(), aSheetPatterns.end());
}
Process (*aNestingData);
Drawing::Drawing aResultNestingDrawing = aNestingData->myNestingResult.ToDrawing();
if (aResultNestingDrawing) {
AddNestingSheetFrames (aResultNestingDrawing);
AssignSheetUuids (aResultNestingDrawing);
aNestingData->myResultDrawing = aResultNestingDrawing;
}
myProcessModel.SetDrawing (aResultNestingDrawing);
myData.push_back (aNestingData);
return true;
}
bool MTKConverter_NestingProcessor::ProcessPerSheet (const std::vector<Drawing::Sheet>& theSourceSheets)
{
Drawing::Drawing aResultNestingDrawing;
for (const auto& aSourceSheet : theSourceSheets) {
auto aNestingData = CreateProcessData (std::vector<Drawing::Sheet> { aSourceSheet });
aNestingData->myPatterns = ExtractPatternViews (aSourceSheet);
Process (*aNestingData);
Drawing::Drawing aSourceNestingDrawing = aNestingData->myNestingResult.ToDrawing();
if (aSourceNestingDrawing) {
AddNestingSheetFrames (aSourceNestingDrawing);
AssignSheetUuids (aSourceNestingDrawing);
aNestingData->myResultDrawing = aSourceNestingDrawing;
MTKConverter_DrawingProcessor::AddSheets (aSourceNestingDrawing, aResultNestingDrawing);
}
myData.push_back (aNestingData);
}
myProcessModel.SetDrawing (aResultNestingDrawing);
return true;
}
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);
}
Describes drawing elements composed connected 2D curves.
Definition Drawing/Geometry.hxx:67
bool AddCurve(const Geom::Curve2d &theCurve)
Adds a trimmed curve or a B-spline curve to the element.
Definition Drawing/Geometry.cxx:186
Iterates over views of a drawing sheet.
Definition Sheet.hxx:72
bool HasNext() const
Returns true if the iterator can be advanced with Next().
Definition Sheet.cxx:212
Represents a single sheet of a model drawing.
Definition Sheet.hxx:30
Represents a view on a drawing sheet.
Definition View.hxx:37
void Add(const Element &theElement)
Adds an element to the view.
Definition View.cxx:150
void SetTrim(double theFirst, double theLast)
Trims curve with [theFirst, theLast] section.
Definition Curve2d.cxx:295
Defines a 2D Direction.
Definition Direction2d.hxx:30
Defines 2D line.
Definition Line2d.hxx:30
Defines a 3D point.
Definition Point2d.hxx:32
The nesting analyzing tool.
Definition Nesting_Computer.hxx:40
void AddMaterial(double theLength, double theWidth, size_t theQuantity)
Configure material in which the patterns will be nested.
Definition Nesting_Computer.cxx:86
Nesting_Data Perform(const cadex::ProgressStatus &theProgressStatus=cadex::ProgressStatus())
Runs analyzing process for loaded patterns and materials.
Definition Nesting_Computer.cxx:126
void AddPattern(const Drawing::View &theDrawing, size_t theQuantity)
Load pattern theDrawing and its quantity theQuantity that will be nested.
Definition Nesting_Computer.cxx:76

MTKConverter_WallThicknessProcessor.hxx

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, 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_WallThicknessProcessor_HeaderFile
#define _MTKConverter_WallThicknessProcessor_HeaderFile
#include <cadex/Geom/Point.hxx>
#include <cadex/ModelData/IndexedTriangleSet.hxx>
#include <cadex/WallThickness_Analyzer.hxx>
#include <cadex/WallThickness_AnalyzerParameters.hxx>
#include <MTKConverter_Application.hxx>
#include <MTKConverter_PartProcessor.hxx>
#include "../../helpers/mesh_colorizer.hxx"
#include <limits>
namespace cadex {
class WallThickness_Data;
}
typedef std::pair<cadex::Geom::Point, cadex::Geom::Point> PointPairType;
class MTKConverter_WallThicknessData : public MTKConverter_ProcessData
{
public:
MTKConverter_WallThicknessData (const cadex::ModelData::Part& thePart) :
MTKConverter_ProcessData (thePart)
{}
bool myIsInit = false;
double myMinThickness = std::numeric_limits<double>::infinity();
double myMaxThickness = -std::numeric_limits<double>::infinity();
double myAvgThickness = 0.;
size_t myThicknessPointCount = 0;
PointPairType myMinThicknessPoints;
PointPairType myMaxThicknessPoints;
};
class MTKConverter_WallThicknessProcessor : public MTKConverter_VoidPartProcessor
{
public:
MTKConverter_WallThicknessProcessor (
cadex::ModelData::Model& theExtraDataModel,
const MTKConverter_WallThicknessParameters& theWallThicknessParameters) :
myAnalyzer (theWallThicknessParameters.myAnalyzerParameters),
myExtraDataModel (theExtraDataModel),
myColorizer (theWallThicknessParameters.myColorSmoothness)
{}
private:
DataType CreateProcessData (const cadex::ModelData::Part& thePart) const override;
void ProcessSolid (DataType& theProcessData, const cadex::ModelData::Solid& theSolid) override;
void ProcessMesh (DataType& theProcessData, const cadex::ModelData::IndexedTriangleSet& theMesh) override;
void ProcessResult (
DataType& theProcessData,
const cadex::WallThickness_Data& theResult);
void PostProcessPart (const cadex::ModelData::Part& thePart) override;
cadex::ModelData::Model& myExtraDataModel;
MeshColorizer myColorizer;
};
#endif
The wall thickness analyzing tool.
Definition WallThickness_Analyzer.hxx:40
Contains information about minimum and maximum wall thicknesses.
Definition WallThickness_Data.hxx:40

MTKConverter_WallThicknessProcessor.cxx

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, 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/ModelAlgo/MeshGenerator.hxx>
#include <cadex/ModelData/MeshBody.hxx>
#include <cadex/ModelData/Solid.hxx>
#include <cadex/WallThickness_Data.hxx>
#include <MTKConverter_WallThicknessProcessor.hxx>
using namespace cadex;
using namespace cadex::ModelData;
MTKConverter_WallThicknessProcessor::DataType MTKConverter_WallThicknessProcessor::CreateProcessData (
const Part& thePart) const
{
return std::make_shared<MTKConverter_WallThicknessData> (thePart);
}
void MTKConverter_WallThicknessProcessor::ProcessSolid (DataType& theProcessData, const Solid& theSolid)
{
WallThickness_Data aData = myAnalyzer.Perform (theSolid);
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);
ProcessResult (theProcessData, theMesh, aData);
}
void MTKConverter_WallThicknessProcessor::ProcessResult (
DataType& theProcessData,
const cadex::WallThickness_Data& theResult)
{
if (theResult.IsEmpty()) {
return;
}
auto aWTData = std::static_pointer_cast<MTKConverter_WallThicknessData> (theProcessData);
aWTData->myIsInit = true;
if (aWTData->myMinThickness > theResult.MinThickness()) {
aWTData->myMinThickness = theResult.MinThickness();
theResult.PointsOfMinThickness (aWTData->myMinThicknessPoints.first, aWTData->myMinThicknessPoints.second);
}
if (aWTData->myMaxThickness < theResult.MaxThickness()) {
aWTData->myMaxThickness = theResult.MaxThickness();
theResult.PointsOfMaxThickness (aWTData->myMaxThicknessPoints.first, aWTData->myMaxThicknessPoints.second);
}
double aThicknessSum = 0.;
const auto& aThicknessList = theResult.ThicknessList();
if (!aThicknessList.IsEmpty()) {
size_t aThicknessListSize = aThicknessList.Size();
for (size_t i = 0; i < aThicknessListSize; ++i) {
aThicknessSum += aThicknessList[i];
}
size_t aPrevThicknessPointCount = aWTData->myThicknessPointCount;
size_t aTotalThicknessPointCount = aPrevThicknessPointCount + aThicknessListSize;
aWTData->myAvgThickness =
aWTData->myAvgThickness * (static_cast<double> (aPrevThicknessPointCount) / aTotalThicknessPointCount)
+ aThicknessSum / aTotalThicknessPointCount;
aWTData->myThicknessPointCount = aTotalThicknessPointCount;
}
myColoredITS.AddTriangles (myColorizer.Perform (theMesh, theResult));
}
void MTKConverter_WallThicknessProcessor::PostProcessPart (const Part& thePart)
{
if (myColoredITS.IsNull()) {
return;
}
Part anExtraDataPart (thePart.Name());
anExtraDataPart.SetUuid (thePart.Uuid());
MeshBody aMeshBody (myColoredITS);
anExtraDataPart.AddBody (aMeshBody);
myExtraDataModel.AddRoot (anExtraDataPart);
myColoredITS = IndexedTriangleSet();
}
size_t Size() const
Returns the number of elements in the list.
Definition MTKBase_DoubleList.cxx:88
Generates a polygonal mesh for a B-Rep body.
Definition MeshGenerator.hxx:38
void Generate(const ModelData::Model &theModel, bool theEnforceGeneration=true) const
Generates a mesh for the model.
Definition MeshGenerator.cxx:369
double MaxThickness() const
Returns the maximum wall thickness in mm.
Definition WallThickness_Data.cxx:164
bool IsEmpty() const
Returns true if WallThickness_Data is empty.
Definition WallThickness_Data.cxx:235
void PointsOfMaxThickness(Geom::Point &theFirstPoint, Geom::Point &theSecondPoint) const
Returns points of maximum thickness.
Definition WallThickness_Data.cxx:185
MTKBase_DoubleList ThicknessList() const
Returns full range of different thickness values found during wall thickness analysis.
Definition WallThickness_Data.cxx:195
double MinThickness() const
Returns the minimum wall thickness in mm.
Definition WallThickness_Data.cxx:158
void PointsOfMinThickness(Geom::Point &theFirstPoint, Geom::Point &theSecondPoint) const
Returns points of minimum thickness.
Definition WallThickness_Data.cxx:174

MTKConverter_Report.hxx

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, 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 <memory>
#include <vector>
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::vector<DataType> myData;
};
#endif
Defines a Unicode (UTF-16) string wrapping a standard string.
Definition UTF16String.hxx:29

MTKConverter_Report.cxx

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, 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/ModelData/Part.hxx>
#include <cadex/Utilities/JSONSerializer.hxx>
#include <MTKConverter_Report.hxx>
#include <MTKConverter_MachiningProcessor.hxx>
#include <MTKConverter_MoldingProcessor.hxx>
#include <MTKConverter_NestingProcessor.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::Geom {
inline std::ostream& operator<< (std::ostream& theStream, const Point& thePoint)
{
return theStream << "(" << thePoint.X() << ", " << thePoint.Y() << ", " << thePoint.Z() << ")";
}
}
namespace {
template<typename T>
void WriteParameter (JSONWriter& theWriter, const char* theParamName, const char* theParamUnits, const T& theParamValue)
{
theWriter.OpenSection();
theWriter.WriteData ("name", theParamName);
theWriter.WriteData ("units", theParamUnits);
theWriter.WriteData ("value", theParamValue);
theWriter.CloseSection();
}
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 WriteWallThicknessData (JSONWriter& theWriter, const std::shared_ptr<MTKConverter_WallThicknessData>& theWTData)
{
WriteThicknessNode (
theWriter,
"Minimum Thickness",
theWTData->myMinThickness,
theWTData->myMinThicknessPoints,
"minThickness");
WriteThicknessNode (
theWriter,
"Maximum Thickness",
theWTData->myMaxThickness,
theWTData->myMaxThicknessPoints,
"maxThickness");
theWriter.OpenArraySection ("parameters");
WriteParameter (theWriter, "Minimum Thickness", "mm", theWTData->myMinThickness);
WriteParameter (theWriter, "Maximum Thickness", "mm", theWTData->myMaxThickness);
WriteParameter (theWriter, "Average Thickness", "mm", theWTData->myAvgThickness);
theWriter.CloseArraySection();
}
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();
}
void WriteNestingData (
JSONWriter& theWriter,
const std::vector<Drawing::Sheet>& theResultSheets,
const std::vector<double>& theFreeSpaces,
size_t thePatternCountTotal,
const std::vector<size_t>& theNestedPatternCounts)
{
theWriter.OpenSection ("nesting");
theWriter.OpenArraySection ("sheets");
for (size_t i = 0; i < theResultSheets.size(); ++i) {
const auto& aResultSheet = theResultSheets[i];
const double aFreeSpace = (i < theFreeSpaces.size()) ? theFreeSpaces[i] : 0.0;
const size_t aNestedPatternCount = (i < theNestedPatternCounts.size()) ? theNestedPatternCounts[i] : 0;
theWriter.OpenSection();
theWriter.WriteData ("sheetId", aResultSheet.Uuid());
theWriter.OpenArraySection ("parameters");
WriteParameter (theWriter, "Sheet Length", "mm", aResultSheet.Height());
WriteParameter (theWriter, "Sheet Width", "mm", aResultSheet.Width());
WriteParameter (theWriter, "Free Space", "mm^2", aFreeSpace);
WriteParameter (theWriter, "Requested Pattern Count", "pcs", thePatternCountTotal);
WriteParameter (theWriter, "Nested Pattern Count", "pcs", aNestedPatternCount);
theWriter.CloseArraySection();
theWriter.CloseSection();
}
theWriter.CloseArraySection();
theWriter.CloseSection();
}
void WriteUuidArray (JSONWriter& theWriter, const char* theName, const std::vector<Uuid>& theUuids)
{
std::ostringstream aStream;
const std::string aCurrentIndent (theWriter.NestingLevel() * 4, ' ');
const std::string aArrayValueIndent ((theWriter.NestingLevel() + 1) * 4, ' ');
aStream << aCurrentIndent << "\"" << theName << "\": [";
if (!theUuids.empty()) {
aStream << "\n";
for (size_t i = 0; i < theUuids.size(); ++i) {
aStream << aArrayValueIndent << "\"" << theUuids[i] << "\"";
if (i + 1 < theUuids.size()) {
aStream << ",";
}
aStream << "\n";
}
aStream << aCurrentIndent;
}
aStream << "]";
theWriter.WriteRawData (aStream.str());
}
typedef std::shared_ptr<MTKConverter_ProcessData> DataType;
bool IsSheetProcessData (const DataType& theProcessData)
{
return static_cast<bool> (std::dynamic_pointer_cast<MTKConverter_NestingData> (theProcessData));
}
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) {
WriteWallThicknessData (theWriter, aWTD);
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);
}
}
void WriteSheetProcessData (JSONWriter& theWriter, const DataType& theProcessData)
{
bool aRes = false;
if (const auto aND = std::dynamic_pointer_cast<MTKConverter_NestingData> (theProcessData)) {
std::vector<Uuid> aSourceSheetUuids;
for (const auto& aSheet : aND->mySourceSheets) {
aSourceSheetUuids.push_back (aSheet.Uuid());
}
WriteUuidArray (theWriter, "sourceIds", aSourceSheetUuids);
const auto aResultSheets = MTKConverter_DrawingProcessor::ExtractDrawingSheets (aND->myResultDrawing);
std::vector<double> aSheetFreeSpaces;
std::vector<size_t> aNestedPatternCounts;
for (const auto& aSheet : aND->myNestingResult.Sheets()) {
aSheetFreeSpaces.push_back (aSheet.Scrap() * aSheet.SheetArea());
aNestedPatternCounts.push_back (aSheet.NestedParts());
}
if (!aResultSheets.empty()) {
theWriter.WriteData ("process", "Nesting");
WriteNestingData (
theWriter,
aResultSheets,
aSheetFreeSpaces,
aND->myPatternCountTotal,
aNestedPatternCounts);
aRes = true;
}
}
if (!aRes) {
theWriter.WriteData ("error", "An error occurred while processing the sheet.");
}
}
}
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 {
bool aHasPartProcessData = false;
bool aHasSheetProcessData = false;
for (const auto& aProcessData : myData) {
if (IsSheetProcessData (aProcessData)) {
aHasSheetProcessData = true;
} else {
aHasPartProcessData = true;
}
}
if (aHasPartProcessData) {
aWriter.OpenArraySection ("parts");
for (const auto& aProcessData : myData) {
if (IsSheetProcessData (aProcessData)) {
continue;
}
aWriter.OpenSection();
WritePartProcessData (aWriter, aProcessData);
aWriter.CloseSection();
}
aWriter.CloseArraySection();
}
if (aHasSheetProcessData) {
aWriter.OpenArraySection ("sheets");
for (const auto& aProcessData : myData) {
if (!IsSheetProcessData (aProcessData)) {
continue;
}
aWriter.OpenSection();
WriteSheetProcessData (aWriter, aProcessData);
aWriter.CloseSection();
}
aWriter.CloseArraySection();
}
}
aWriter.CloseSection();
return true;
}
bool IsEmpty() const
Returns true if the list empty.
Definition MTKBase_FeatureList.hxx:56
Serializes MTK entities into a JSON report.
Definition JSONSerializer.hxx:71
Configuration for JSON serialization.
Definition JSONSerializer.hxx:47
Contains classes, types, enums, and functions related to geometric entities.
ShapeType
Defines shape type.
Definition ShapeType.hxx:25
Contains utility classes that can be useful for debugging or configuring global settings.
@ Machining_OT_Milling
Milling operation type.
Definition Machining_OperationType.hxx:28
@ Machining_OT_LatheMilling
Lathe + Milling operation type.
Definition Machining_OperationType.hxx:29

MTKConverter_Application.hxx

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, 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
#include <cadex/ModelData/ModelReaderParameters.hxx>
#include <cadex/Nesting_ComputerParameters.hxx>
#include <cadex/WallThickness_AnalyzerParameters.hxx>
#include <cstddef>
enum class MTKConverter_ReturnCode
{
// General codes
Ok = 0,
UnknownError = 1,
GeneralException = 2,
NoValidLicense = 3,
InvalidArgumentsNumber = 4,
InvalidArgument = 5,
// Import errors
UnsupportedVersion = 100,
UnexpectedFormat = 101,
UnsupportedFileVariant = 102,
ImportError = 103,
// Process errors
ProcessError = 200,
// Export errors
ExportError = 300,
};
class MTKConverter_ImportParameters
{
public:
MTKConverter_ImportParameters()
{
myReaderParameters.SetReadPMI (false);
myReaderParameters.SetReadDrawing (false);
myReaderParameters.SetEnableAnalyticalRecognition (true);
}
};
class MTKConverter_NestingParameters
{
public:
enum class NestingMode
{
PerSheet = 0,
AllSheets = 1
};
class MaterialParameters
{
public:
double myLength = 500.0;
double myWidth = 500.0;
size_t myCount = 1;
};
MTKConverter_NestingParameters()
{
myComputerParameters.SetIterationCount (20);
myComputerParameters.SetGenerationSize (3);
myComputerParameters.SetMutationRate (2.0);
myComputerParameters.SetCurveTolerance (100.0);
myComputerParameters.SetPartToPartDistance (0);
myComputerParameters.SetPartToSheetBoundaryDistance (0);
myComputerParameters.SetRotationCount (4);
myComputerParameters.SetMirrorControl (false);
myComputerParameters.SetNestingInHoles (false);
}
MaterialParameters myMaterialParameters;
size_t myPatternRepeatCount = 4;
NestingMode myMode = NestingMode::PerSheet;
cadex::Nesting_ComputerParameters myComputerParameters;
};
class MTKConverter_WallThicknessParameters
{
public:
MTKConverter_WallThicknessParameters()
{
auto aVoxelizationParameters = myAnalyzerParameters.VoxelizationParameters();
aVoxelizationParameters.SetResolution (800);
};
double myColorSmoothness = 0.75;
};
class MTKConverter_ExportParameters
{
public:
bool myIsScreenshotGenerationEnabled = true;
bool myIsExportMTKEnabled = false;
};
class MTKConverter_Parameters
{
public:
MTKConverter_ImportParameters myImportParameters;
MTKConverter_NestingParameters myNestingParameters;
MTKConverter_WallThicknessParameters myWallThicknessParameters;
MTKConverter_ExportParameters myExportParameters;
};
class MTKConverter_Application
{
public:
MTKConverter_ReturnCode Run (int argc, char* argv[]) const;
void PrintUsage() const;
};
#endif
Defines parameters of the ModelReader.
Definition ModelReaderParameters.hxx:27
Defines parameters used in nesting process.
Definition Nesting_ComputerParameters.hxx:33
The wall thickness analyzer parameters.
Definition WallThickness_AnalyzerParameters.hxx:52

MTKConverter_Application.cxx

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, 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/Materials/Color.hxx>
#include <cadex/ModelData/Model.hxx>
#include <cadex/ModelData/ModelReader.hxx>
#include <cadex/ModelData/ModelReaderParameters.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_NestingProcessor.hxx>
#include <MTKConverter_Report.hxx>
#include <MTKConverter_SheetMetalProcessor.hxx>
#include <MTKConverter_WallThicknessProcessor.hxx>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>
#if defined(__GNUC__)
#include <sys/stat.h>
#elif !defined(_MSC_VER) || _MSC_VER > 1900
#include <filesystem>
#endif
using namespace cadex;
namespace {
enum class MTKConverter_ProcessType
{
Undefined = -1,
WallThickness = 0,
MachiningMilling,
MachiningTurning,
Molding,
SheetMetal,
Nesting
};
enum class MTKConverter_ArgumentType
{
Neutral,
Import,
Process,
Export
};
class MTKConverter_Argument
{
public:
MTKConverter_ArgumentType myArgumentType;
UTF16String myValue;
};
MTKConverter_ProcessType FindProcessType (const UTF16String& theProcessName)
{
static std::unordered_map<UTF16String, MTKConverter_ProcessType, UTF16StringHash> theProcessMap {
{ "wall_thickness", MTKConverter_ProcessType::WallThickness },
{ "machining_milling", MTKConverter_ProcessType::MachiningMilling },
{ "machining_turning", MTKConverter_ProcessType::MachiningTurning },
{ "molding", MTKConverter_ProcessType::Molding },
{ "sheet_metal", MTKConverter_ProcessType::SheetMetal },
{ "nesting", MTKConverter_ProcessType::Nesting }
};
auto aRes = theProcessMap.find (theProcessName);
if (aRes != theProcessMap.end()) {
return aRes->second;
}
return MTKConverter_ProcessType::Undefined;
}
MTKConverter_ReturnCode Import (
const UTF16String& theFilePath,
ModelData::Model& theModel,
const MTKConverter_ImportParameters& theImportParameters)
{
std::cout << "Importing " << theFilePath << "..." << std::flush;
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;
}
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: {
MTKConverter_MachiningProcessor aProcessor (Machining_OT_Milling);
return anApplyPartProcessorToModel (aProcessor);
}
case MTKConverter_ProcessType::MachiningTurning: {
MTKConverter_MachiningProcessor aProcessor (Machining_OT_LatheMilling);
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;
}
}
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 (Materials::Color (255, 255, 255)));
aWriter.SetParameters (aParameters);
bool aRes = aWriter.WriteFile (theModel, theFilePath);
return aRes;
}
MTKConverter_ReturnCode Export (
const UTF16String& theFolderPath,
const MTKConverter_ExportParameters& theExportParameters,
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_ReturnCode::Ok;
#else
#if defined(__GNUC__)
mkdir (theFolderPath.ToString().c_str(), 0755);
#else
std::filesystem::create_directory (theFolderPath.ToString());
#endif
auto anExportMTKWEB = [&theFolderPath] (const ModelData::Model& theModelToExport, const UTF16String& theBaseName)
{
UTF16String aPath = theFolderPath + "/" + theBaseName + ".mtkweb" + "/scenegraph.mtkweb";
if (!theModelToExport.Save (aPath, ModelData::Model::FileFormatType::MTKWEB)) {
std::cerr << std::endl << "ERROR: Failed to export " << aPath << ". Exiting" << std::endl;
return false;
}
return true;
};
auto anExportMTK = [&theFolderPath] (const ModelData::Model& theModelToExport, const UTF16String& theBaseName)
{
std::string aSanitizedBaseName = theBaseName.ToString();
// removing extra extensions from the export model name
std::replace (aSanitizedBaseName.begin(), aSanitizedBaseName.end(), '.', '_');
UTF16String aPath = theFolderPath + "/" + UTF16String (aSanitizedBaseName);
aPath += "_processed.mtk";
if (!theModelToExport.Save (aPath, ModelData::Model::FileFormatType::MTK)) {
std::cerr << std::endl << "ERROR: Failed to save MTK model " << aPath << ". Exiting" << std::endl;
return false;
}
return true;
};
UTF16String aModelBaseName = theModel.Name();
UTF16String aProcessedBaseName = theProcessModel.Name();
if (!anExportMTKWEB (theModel, aModelBaseName)) {
return MTKConverter_ReturnCode::ExportError;
}
UTF16String aThumbnailPath = theFolderPath + "/thumbnail.png";
if (theExportParameters.myIsScreenshotGenerationEnabled && !CreateOriginModelThumbnail (aThumbnailPath, theModel)) {
std::cerr << std::endl << "ERROR: Failed to create thumbnail " << aThumbnailPath << ". Exiting" << std::endl;
return MTKConverter_ReturnCode::ExportError;
}
if (!theProcessModel.IsEmpty() || theProcessModel.Drawing()) {
if (!anExportMTKWEB (theProcessModel, aProcessedBaseName)) {
return MTKConverter_ReturnCode::ExportError;
}
if (theExportParameters.myIsExportMTKEnabled) {
if (!anExportMTK (theProcessModel, aProcessedBaseName)) {
return MTKConverter_ReturnCode::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_ReturnCode::ExportError;
}
return MTKConverter_ReturnCode::Ok;
#endif
}
MTKConverter_ReturnCode ParseArguments (
int argc,
char* argv[],
MTKConverter_Parameters& theParameters,
std::vector<MTKConverter_Argument>& theArguments)
{
auto anAgrumentType = MTKConverter_ArgumentType::Neutral;
for (int i = 1; i < argc; ++i) {
const UTF16String anArgument = argv[i];
if (anArgument == "--no-screenshot") {
theParameters.myExportParameters.myIsScreenshotGenerationEnabled = false;
} else if (anArgument == "--export_mtk") {
theParameters.myExportParameters.myIsExportMTKEnabled = true;
} else if (anArgument == "--sheet_size") {
if (i + 2 >= argc) {
std::cerr << "ERROR: Missing values for --sheet_size. "
<< "Use --sheet_size <L> <W> with values > 0." << std::endl;
return MTKConverter_ReturnCode::InvalidArgument;
}
const double aSheetLength = std::atof (argv[++i]);
const double aSheetWidth = std::atof (argv[++i]);
if (aSheetLength <= 0.0 || aSheetWidth <= 0.0) {
std::cerr << "ERROR: Invalid sheet size. "
<< "Use --sheet_size <L> <W> with values > 0." << std::endl;
return MTKConverter_ReturnCode::InvalidArgument;
}
theParameters.myNestingParameters.myMaterialParameters.myLength = aSheetLength;
theParameters.myNestingParameters.myMaterialParameters.myWidth = aSheetWidth;
} else if (anArgument == "--pattern_count") {
if (i + 1 >= argc) {
std::cerr << "ERROR: Missing value for --pattern_count. "
<< "Use --pattern_count <N> with value > 0." << std::endl;
return MTKConverter_ReturnCode::InvalidArgument;
}
const int aPatternRepeatCount = std::atoi (argv[++i]);
if (aPatternRepeatCount <= 0) {
std::cerr << "ERROR: Invalid pattern count. "
<< "Use --pattern_count <N> with value > 0." << std::endl;
return MTKConverter_ReturnCode::InvalidArgument;
}
theParameters.myNestingParameters.myPatternRepeatCount = static_cast<size_t> (aPatternRepeatCount);
} else if (anArgument == "--nesting_mode") {
if (i + 1 >= argc) {
std::cerr << "ERROR: Missing value for --nesting_mode. "
<< "Use --nesting_mode per_sheet|all_sheets." << std::endl;
return MTKConverter_ReturnCode::InvalidArgument;
}
const UTF16String aNestingModeArg = argv[++i];
if (aNestingModeArg == "per_sheet") {
theParameters.myNestingParameters.myMode = MTKConverter_NestingParameters::NestingMode::PerSheet;
} else if (aNestingModeArg == "all_sheets") {
theParameters.myNestingParameters.myMode =
MTKConverter_NestingParameters::NestingMode::AllSheets;
} else {
std::cerr << "ERROR: Invalid nesting mode \"" << aNestingModeArg
<< "\". Use --nesting_mode per_sheet|all_sheets." << std::endl;
return MTKConverter_ReturnCode::InvalidArgument;
}
} else if (anArgument == "-i") {
anAgrumentType = MTKConverter_ArgumentType::Import;
} else if (anArgument == "-p") {
anAgrumentType = MTKConverter_ArgumentType::Process;
} else if (anArgument == "-e") {
anAgrumentType = MTKConverter_ArgumentType::Export;
} else {
switch (anAgrumentType) {
case MTKConverter_ArgumentType::Import:
theArguments.push_back (MTKConverter_Argument { MTKConverter_ArgumentType::Import, anArgument });
break;
case MTKConverter_ArgumentType::Process: {
const auto aProcessType = FindProcessType (anArgument);
if (aProcessType == MTKConverter_ProcessType::Undefined) {
std::cerr << "ERROR: Unknown process \"" << anArgument << "\"." << std::endl;
std::cerr << "Type " << argv[0] << " -h for recognized processes." << std::endl;
return MTKConverter_ReturnCode::InvalidArgument;
}
if (aProcessType == MTKConverter_ProcessType::Nesting) {
theParameters.myImportParameters.myReaderParameters.SetReadDrawing (true);
}
theArguments.push_back (MTKConverter_Argument { MTKConverter_ArgumentType::Process, anArgument });
break;
}
case MTKConverter_ArgumentType::Export:
theArguments.push_back (MTKConverter_Argument { MTKConverter_ArgumentType::Export, anArgument });
break;
case MTKConverter_ArgumentType::Neutral:
default:
std::cerr << "ERROR!: Invalid argument " << anArgument << ". Exiting" << std::endl;
std::cerr << "Type " << argv[0] << " -h for help." << std::endl;
return MTKConverter_ReturnCode::InvalidArgument;
}
}
}
if (theArguments.empty()) {
std::cerr << "ERROR: No commands specified. Use -i/-p/-e." << std::endl;
return MTKConverter_ReturnCode::InvalidArgument;
}
return MTKConverter_ReturnCode::Ok;
}
MTKConverter_ReturnCode Execute (
const std::vector<MTKConverter_Argument>& theArguments,
const MTKConverter_Parameters& theParameters)
{
ModelData::Model aProcessModel;
MTKConverter_Report aReport;
auto aResultCode = MTKConverter_ReturnCode::Ok;
for (const auto& anArgument : theArguments) {
if (aResultCode != MTKConverter_ReturnCode::Ok) {
break;
}
try {
switch (anArgument.myArgumentType) {
case MTKConverter_ArgumentType::Import:
aProcessModel = ModelData::Model();
aResultCode = Import (anArgument.myValue, aModel, theParameters.myImportParameters);
if (aResultCode == MTKConverter_ReturnCode::Ok) {
aModel.AssignUuids();
}
break;
case MTKConverter_ArgumentType::Process:
aResultCode = Process (anArgument.myValue, aModel, aReport, aProcessModel, theParameters);
break;
case MTKConverter_ArgumentType::Export:
aResultCode = Export (
anArgument.myValue,
theParameters.myExportParameters,
aModel,
aReport,
aProcessModel);
break;
default: aResultCode = MTKConverter_ReturnCode::InvalidArgument; break;
}
if (aResultCode == MTKConverter_ReturnCode::Ok) {
std::cout << "Done." << std::endl;
}
} catch (...) {
std::cerr << "Failed.\nERROR: Unhandled exception caught." << std::endl;
return MTKConverter_ReturnCode::GeneralException;
}
}
return aResultCode;
}
}
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_ReturnCode::Ok;
}
if (argc < 6) {
std::cerr << "Invalid number of arguments. Please use \"-h\" or \"--help\" for usage information." << std::endl;
return MTKConverter_ReturnCode::InvalidArgumentsNumber;
}
MTKConverter_Parameters aProcessParameters;
std::vector<MTKConverter_Argument> anArguments;
auto aParseRes = ParseArguments (argc, argv, aProcessParameters, anArguments);
if (aParseRes != MTKConverter_ReturnCode::Ok) {
return aParseRes;
}
return Execute (anArguments, aProcessParameters);
}
void MTKConverter_Application::PrintUsage() const
{
std::cout << "Usage:" << std::endl;
std::cout << "MTKConverter -i <import_file> -p <process> ... -e <export_target> [options]" << std::endl;
std::cout << std::endl << "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_target> - export folder name" << std::endl;
std::cout << std::endl << "Export Options:" << std::endl;
std::cout << " --no-screenshot - disable screenshot generation (optional)" << std::endl;
std::cout << " --export_mtk - additionally save process model as *.mtk in <export_target>"
<< std::endl;
std::cout << std::endl << "Example:" << std::endl;
std::cout << "MTKConverter -i C:\\models\\test.step -p machining_milling -e C:\\models\\out" << std::endl;
std::cout << "MTKConverter -i C:\\models\\test.step -p nesting -e C:\\models\\out --export_mtk" << std::endl;
std::cout
<< "MTKConverter -i C:\\models\\test.step -p sheet_metal -e C:\\models\\out -p nesting --nesting_mode all_sheets --sheet_size 500 500 --pattern_count 4 -e C:\\models\\out --export_mtk"
<< 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;
std::cout << " nesting :\t Nesting using source drawing or sheet metal unfolding drawing" << std::endl;
std::cout << " parameters :\t --sheet_size <L> <W> (default: 500 500)" << std::endl;
std::cout << " :\t --pattern_count <N> (default: 4)" << std::endl;
std::cout << " :\t --nesting_mode per_sheet|all_sheets (default: per_sheet)" << std::endl;
}
Defines a visitor that visits each unique element only once.
Definition ModelElementVisitor.hxx:90
UTF16String Name() const
Returns a model name.
Definition Model.cxx:255
void AssignUuids()
Assigns uuid's (persistent id's) to scene graph elements and part representations (if not assigned ye...
Definition Model.cxx:269
bool IsEmpty() const
Returns true if the model is empty.
Definition Model.cxx:174
void Accept(ModelElementVisitor &theVisitor) const
Accepts a visitor.
Definition Model.cxx:275
Reads supported formats, see Import section.
Definition ModelReader.hxx:32
void SetParameters(const ModelReaderParameters &theParameters)
Sets reader parameters.
Definition ModelReader.cxx:277
bool Read(const UTF16String &theFilePath, ModelData::Model &theModel)
Reads the file at the specified path into the specified model.
Definition ModelReader.cxx:303
Defines color background style.
Definition BackgroundStyle.hxx:37
Writes an image file with graphical content of a model.
Definition ImageWriter.hxx:43

main.cxx

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, 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 static_cast<int> (anApp.Run (argc, argv));
}