Hide menu
Loading...
Searching...
No Matches
Sheet Metal DFM Analyzer Example

Demonstrates how to perform sheet metal design analysis on a 3D model and print information about found issues and their parameters in a console.

Overview

In this example demonstrates how to perform sheet metal design analysis on a 3D model using sheet metal dfm analyzer tool (DFMSheetMetal_Analyzer). For this purpose, used a console application that imports a model (can be of any supported format), traverses through unique parts, creates and runs DFMSheetMetal_Analyzer, groups and prints information about found issues and their parameters into console. Sheet metal design analysis will be performed for each unique ModelData_Part, but only for the scope of accepted geometries.


Application needs 1 input argument to run:

Usage: sheet_metal_dfm_analyzer <input_file>, where:
<input_file> is a name of the file to be read


For more information about sheet metal design analysis visit Design for Manufacturing (DFM) page.

Implementation

PartProcessor class is inherited from ShapeProcessor and overrides ProcessSolid and ProcessShell methods that are used to run DFMSheetMetal_Analyzer on given shapes. Then PrintIssues method is used to print information about found issues and their parameters in a console.
Visit Model Explore Helper Implementation page for more information about base ShapeProcessor class implementation.

class PartProcessor : public ShapeProcessor
{
public:
void ProcessSolid (const ModelData_Solid& theSolid) override
{
double aThickness = CalculateInitialThicknessValue (theSolid);
auto anIssueList = myAnalyzer.Perform (theSolid, aThickness);
PrintIssues (anIssueList);
}
void ProcessShell (const ModelData_Shell& theShell) override
{
auto anIssueList = myAnalyzer.Perform (theShell);
PrintIssues (anIssueList);
}
private:
DFMSheetMetal_Analyzer myAnalyzer;
};

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

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

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

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

After performing design analysis, the object of FeatureGroupManager class is used to group and sort found issues. For this purpose, there is a traverse through all found issues and add each of them to FeatureGroupManager with a specified name.

for (size_t i = 0; i < theIssueList.Size(); ++i) {
const auto& anIssue = theIssueList[i];
if (anIssue.IsOfType<DFMSheetMetal_SmallRadiusBendIssue>()) {
aManager.AddFeature ("Small Radius Bend Issue(s)", "Bend(s)", true, anIssue);
} else if (anIssue.IsOfType<DFMSheetMetal_SmallDiameterHoleIssue>()) {
aManager.AddFeature ("Small Diameter Hole Issue(s)", "Hole(s)", true, anIssue);
} else if (anIssue.IsOfType<DFMSheetMetal_FlatPatternInterferenceIssue>()) {
aManager.AddFeature ("Flat Pattern Interference Issue(s)", "", false, anIssue);
} else if (anIssue.IsOfType<DFMSheetMetal_IrregularSizeBendReliefIssue>()) {
aManager.AddFeature ("Irregular Size Bend Relief Issue(s)", "Bend(s)", true, anIssue);
} else if (anIssue.IsOfType<DFMSheetMetal_LargeDepthBeadIssue>()) {
aManager.AddFeature ("Large Depth Bead Issue(s)", "Bead(s)", true, anIssue);
} else if (anIssue.IsOfType<DFMSheetMetal_InconsistentRadiusBendIssue>()) {
aManager.AddFeature ("Inconsistent Radius Bend Issue(s)", "Bend(s)", true, anIssue);
} else if (anIssue.IsOfType<DFMSheetMetal_SmallLengthFlangeIssue>()) {
aManager.AddFeature ("Small Length Flange Issue(s)", "Flange(s)", true, anIssue);
} else if (anIssue.IsOfType <DFMSheetMetal_IrregularSizeNotchIssue>()) {
aManager.AddFeature ("Irregular Size Notch Issue(s)", "Notch(s)", true, anIssue);
} else if (anIssue.IsOfType <DFMSheetMetal_IrregularSizeTabIssue>()) {
aManager.AddFeature ("Irregular Size Tab Issue(s)", "Tab(s)", true, anIssue);
} else if (anIssue.IsOfType<DFMSheetMetal_SmallDistanceBetweenFeaturesIssue>()) {
const auto& aSDBFIssue = static_cast<const DFMSheetMetal_SmallDistanceBetweenFeaturesIssue&> (anIssue);
aManager.AddFeature (SmallDistanceIssueName (aSDBFIssue), "Distance(s)", true, anIssue);
} else if (anIssue.IsOfType<DFMSheetMetal_NonStandardSheetThicknessIssue>()) {
aManager.AddFeature ("Non Standard Sheet Thickness Issue(s)", "Sheet Thickness(s)", true, anIssue);
} else if (anIssue.IsOfType<DFMSheetMetal_NonStandardSheetSizeIssue>()) {
aManager.AddFeature ("Non Standard Sheet Size Issue(s)", "Sheet Size(s)", true, anIssue);
}
}

After adding all found issues to FeatureGroupManager, a Print method of the manager is used to print information about found issues and their parameters in a console. PrintFeatureParameters is created to explore and print issue parameters. It uses as an input parameter of Print method.

auto PrintFeatureParameters = [] (const MTKBase_Feature& theIssue)
{
if (theIssue.IsOfType<DFMSheetMetal_SmallRadiusBendIssue>()) {
const auto& aSRBIssue = static_cast<const DFMSheetMetal_SmallRadiusBendIssue&> (theIssue);
FeatureGroupManager::PrintFeatureParameter ("expected min radius", aSRBIssue.ExpectedMinRadius(), "mm");
FeatureGroupManager::PrintFeatureParameter ("actual radius", aSRBIssue.ActualRadius(), "mm");
} else if (theIssue.IsOfType<DFMSheetMetal_SmallDiameterHoleIssue>()) {
const auto& aSDHIssue = static_cast<const DFMSheetMetal_SmallDiameterHoleIssue&> (theIssue);
FeatureGroupManager::PrintFeatureParameter ("expected min diameter", aSDHIssue.ExpectedMinDiameter(), "mm");
FeatureGroupManager::PrintFeatureParameter ("actual diameter", aSDHIssue.ActualDiameter(), "mm");
} else if (theIssue.IsOfType<DFMSheetMetal_SmallDistanceBetweenFeaturesIssue>()) {
const auto& aSDBFIssue = static_cast<const DFMSheetMetal_SmallDistanceBetweenFeaturesIssue&> (theIssue);
FeatureGroupManager::PrintFeatureParameter (
"expected min distance", aSDBFIssue.ExpectedMinDistanceBetweenFeatures(), "mm");
FeatureGroupManager::PrintFeatureParameter (
"actual distance", aSDBFIssue.ActualDistanceBetweenFeatures(), "mm");
} else if (theIssue.IsOfType<DFMSheetMetal_FlatPatternInterferenceIssue>()) {
//no parameters
} else if (theIssue.IsOfType<DFMSheetMetal_IrregularSizeBendReliefIssue>()) {
const auto& aISBRIssue = static_cast<const DFMSheetMetal_IrregularSizeBendReliefIssue&> (theIssue);
const auto& anExpectedRelief = aISBRIssue.ExpectedMinBendRelief();
const auto& aFirstActualRelief = aISBRIssue.FirstActualRelief();
const auto& aSecondActualRelief = aISBRIssue.SecondActualRelief();
FeatureGroupManager::PrintFeatureParameter (
"expected min relief size (LxW)",
std::make_pair (anExpectedRelief.Length(), anExpectedRelief.Width()),
"mm");
if (aFirstActualRelief && aSecondActualRelief) {
FeatureGroupManager::PrintFeatureParameter (
"first actual relief size (LxW)",
std::make_pair (aFirstActualRelief.Length(), aFirstActualRelief.Width()),
"mm");
FeatureGroupManager::PrintFeatureParameter (
"second actual relief size (LxW)",
std::make_pair (aSecondActualRelief.Length(), aSecondActualRelief.Width()),
"mm");
} else if (!aFirstActualRelief) {
FeatureGroupManager::PrintFeatureParameter (
"actual relief size (LxW)",
std::make_pair (aSecondActualRelief.Length(), aSecondActualRelief.Width()),
"mm");
} else {
FeatureGroupManager::PrintFeatureParameter (
"actual relief size (LxW)",
std::make_pair (aFirstActualRelief.Length(), aFirstActualRelief.Width()),
"mm");
}
} else if (theIssue.IsOfType<DFMSheetMetal_LargeDepthBeadIssue>()) {
const auto& aLDBIssue = static_cast<const DFMSheetMetal_LargeDepthBeadIssue&> (theIssue);
FeatureGroupManager::PrintFeatureParameter ("expected max depth", aLDBIssue.ExpectedMaxDepth(), "mm");
FeatureGroupManager::PrintFeatureParameter ("actual depth", aLDBIssue.ActualDepth(), "mm");
} else if (theIssue.IsOfType<DFMSheetMetal_InconsistentRadiusBendIssue>()) {
const auto& aIRBIssue = static_cast<const DFMSheetMetal_InconsistentRadiusBendIssue&> (theIssue);
FeatureGroupManager::PrintFeatureParameter ("expected max radius", aIRBIssue.ExpectedRadius(), "mm");
FeatureGroupManager::PrintFeatureParameter ("actual radius", aIRBIssue.ActualRadius(), "mm");
} else if (theIssue.IsOfType<DFMSheetMetal_SmallLengthFlangeIssue>()) {
const auto& aSLFIssue = static_cast<const DFMSheetMetal_SmallLengthFlangeIssue&> (theIssue);
FeatureGroupManager::PrintFeatureParameter ("expected min length", aSLFIssue.ExpectedMinLength(), "mm");
FeatureGroupManager::PrintFeatureParameter ("actual length", aSLFIssue.ActualLength(), "mm");
} else if (theIssue.IsOfType <DFMSheetMetal_IrregularSizeNotchIssue>()) {
const auto& aISNIssue = static_cast<const DFMSheetMetal_IrregularSizeNotchIssue&> (theIssue);
FeatureGroupManager::PrintFeatureParameter (
"expected size (LxW)",
std::make_pair (aISNIssue.ExpectedLength(), aISNIssue.ExpectedWidth()),
"mm");
FeatureGroupManager::PrintFeatureParameter (
"actual size (LxW)",
std::make_pair (aISNIssue.ActualLength(), aISNIssue.ActualWidth()),
"mm");
} else if (theIssue.IsOfType <DFMSheetMetal_IrregularSizeTabIssue>()) {
const auto& aISTIssue = static_cast<const DFMSheetMetal_IrregularSizeTabIssue&> (theIssue);
FeatureGroupManager::PrintFeatureParameter (
"expected size (LxW)",
std::make_pair (aISTIssue.ExpectedLength(), aISTIssue.ExpectedWidth()),
"mm");
FeatureGroupManager::PrintFeatureParameter (
"actual size (LxW)",
std::make_pair (aISTIssue.ActualLength(), aISTIssue.ActualWidth()),
"mm");
} else if (theIssue.IsOfType<DFMSheetMetal_NonStandardSheetThicknessIssue>()) {
const auto& aNSSTIssue = static_cast<const DFMSheetMetal_NonStandardSheetThicknessIssue&> (theIssue);
FeatureGroupManager::PrintFeatureParameter (
"nearest standard sheet thickness", aNSSTIssue.NearestStandardSheetThickness(), "mm");
FeatureGroupManager::PrintFeatureParameter (
"actual sheet thickness", aNSSTIssue.ActualSheetThickness(), "mm");
} else if (theIssue.IsOfType<DFMSheetMetal_NonStandardSheetSizeIssue>()) {
const auto& aNSSSIssue = static_cast<const DFMSheetMetal_NonStandardSheetSizeIssue&> (theIssue);
const auto& aNearestStandardSize = aNSSSIssue.NearestStandardSheetSize();
const auto& anActualSize = aNSSSIssue.ActualSheetSize();
FeatureGroupManager::PrintFeatureParameter (
"nearest standard sheet size (LxW)",
std::make_pair (aNearestStandardSize.Length(), aNearestStandardSize.Width()),
"mm");
FeatureGroupManager::PrintFeatureParameter (
"actual sheet size (LxW)",
std::make_pair (anActualSize.Length(), anActualSize.Width()),
"mm");
}
};
aManager.Print ("issues", PrintFeatureParameters);

Visit Feature Group Helper Implementation page for more information about FeatureGroupManager class implementation.

Example output

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

The model Example output
Model: Power_box_Chasis

Part #0 ["power box sheetmetal"] - solid #0 has:
    Large Depth Bead Issue(s): 1
        1 Bead(s) with
          expected max depth: 0.36 mm
          actual depth: 5 mm
    Non Standard Sheet Size Issue(s): 1
        1 Sheet Size(s) with
          nearest standard sheet size (LxW): 600 x 200 mm
          actual sheet size (LxW): 335.412 x 178.73 mm
    Non Standard Sheet Thickness Issue(s): 1
        1 Sheet Thickness(s) with
          nearest standard sheet thickness: 0.8 mm
          actual sheet thickness: 0.6 mm
    Small Distance Between Hole And Edge Issue(s): 8
        8 Distance(s) with
          expected min distance: 1.2 mm
          actual distance: 1 mm

    Total issues: 11

Files