Hide menu
Loading...
Searching...
No Matches
machining/dfm_analyzer/dfm_analyzer.java

Refer to the CNC Machining DFM Analyzer Example

feature_group.java

// ****************************************************************************
// $Id$
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2025, CADEX. All rights reserved.
//
// This file is part of the Manufacturing Toolkit software.
//
// You may use this file under the terms of the BSD license as follows:
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ****************************************************************************
import cadex.*;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;
import java.util.function.Consumer;
class FeatureComparator implements Comparator<MTKBase_Feature>
{
@Override
public int compare(MTKBase_Feature theA, MTKBase_Feature theB)
{
MTKBase_FeatureComparator aComparator = new MTKBase_FeatureComparator();
boolean anALessThanB = aComparator.Apply(theA, theB);
if (anALessThanB)
{
return -1;
}
boolean aBLessThanA = aComparator.Apply(theB, theA);
if (aBLessThanA)
{
return 1;
}
return 0;
}
}
class Pair
{
public Pair(double theFirst, double theSecond)
{
this.First = theFirst;
this.Second = theSecond;
}
public String toString()
{
return String.format("%f x %f", First, Second);
}
public double First;
public double Second;
}
class Dimension
{
public Dimension(double theL, double theW, double theD)
{
this.L = theL;
this.W = theW;
this.D = theD;
}
public String toString()
{
return String.format("%f x %f x %f", L, W, D);
}
public double L;
public double W;
public double D;
}
class Direction
{
public Direction(double theX, double theY, double theZ)
{
this.X = theX;
this.Y = theY;
this.Z = theZ;
}
public String toString()
{
return "(" + FormattedString(X) + ", " + FormattedString(Y) + ", " + FormattedString(Z) + ")";
}
private String FormattedString(double theValue)
{
DecimalFormat aDF = new DecimalFormat("0.00");
return aDF.format(theValue);
}
public double X;
public double Y;
public double Z;
}
class FeatureMap extends TreeMap<MTKBase_Feature, Long>
{
public FeatureMap()
{
super (new FeatureComparator());
}
}
class FeatureGroupManager
{
public FeatureGroupManager()
{
myGroups = new ArrayList<FeatureGroup>();
}
public void AddFeature(String theGroupName, String theSubgroupName, boolean theHasParameters, MTKBase_Feature theFeature)
{
//find or create
int aRes = -1;
for (int i = 0; i < myGroups.size(); ++i)
{
FeatureGroup aGroup = myGroups.get(i);
if (aGroup.myName == theGroupName)
{
aRes = i;
break;
}
}
if (aRes == -1)
{
myGroups.add(new FeatureGroup(theGroupName, theSubgroupName, theHasParameters));
aRes = myGroups.size() - 1;
}
//update
FeatureGroup aGroup = myGroups.get(aRes);
FeatureMap aSubgroups = aGroup.myFeatureSubgroups;
if (aSubgroups.containsKey(theFeature))
{
aSubgroups.put(theFeature, aSubgroups.get (theFeature) + 1);
}
else
{
aSubgroups.put(theFeature, 1L);
}
}
public void Print(String theFeatureType, Consumer<MTKBase_Feature> thePrintFeatureParameters)
{
Collections.sort(myGroups, new FeatureGroupComparator());
long aTotalCount = 0;
for (FeatureGroup aGroup : myGroups)
{
long aFeatureCount = aGroup.FeatureCount();
aTotalCount += aFeatureCount;
System.out.format(" %s: %d\n", aGroup.myName, aFeatureCount);
if (!aGroup.myHasParameters)
{
continue;
}
String aSubgroupName = aGroup.mySubgroupName;
for (Map.Entry<MTKBase_Feature, Long> aFeatureSubgroup : aGroup.myFeatureSubgroups.entrySet())
{
System.out.format(" %d %s with\n", aFeatureSubgroup.getValue(), aSubgroupName);
thePrintFeatureParameters.accept(aFeatureSubgroup.getKey());
}
}
System.out.format("\n Total %s: %d\n", theFeatureType, aTotalCount);
}
public static <T> void PrintFeatureParameter(String theName, T theValue, String theUnits)
{
System.out.format(" %s: %s %s\n", theName, theValue, theUnits);
}
private class FeatureGroup
{
public FeatureGroup(String theName, String theSubgroupName, boolean theHasParameters)
{
myName = theName;
mySubgroupName = theSubgroupName;
myHasParameters = theHasParameters;
myFeatureSubgroups = new FeatureMap();
}
public long FeatureCount()
{
long aCount = 0;
for (Map.Entry<MTKBase_Feature, Long> aFeatureSubgroup : myFeatureSubgroups.entrySet())
{
aCount += aFeatureSubgroup.getValue();
}
return aCount;
}
public String myName;
public String mySubgroupName;
public boolean myHasParameters;
public FeatureMap myFeatureSubgroups;
}
private class FeatureGroupComparator implements Comparator<FeatureGroup>
{
@Override
public int compare(FeatureGroup theA, FeatureGroup theB)
{
String anAName = theA.myName;
String aBName = theB.myName;
if (anAName == aBName)
{
return 0;
}
FeatureMap anAFeatureSubgroups = theA.myFeatureSubgroups;
FeatureMap aBFeatureSubgroups = theB.myFeatureSubgroups;
if (anAFeatureSubgroups.isEmpty() || aBFeatureSubgroups.isEmpty())
{
return anAName.compareTo(aBName);
}
MTKBase_Feature anAFeature = anAFeatureSubgroups.firstKey();
MTKBase_Feature aBFeature = aBFeatureSubgroups.firstKey();
FeatureComparator aFeatureComparator = new FeatureComparator();
return aFeatureComparator.compare(anAFeature, aBFeature);
}
}
private ArrayList<FeatureGroup> myGroups;
}
Defines classes, namespaces, enums, types, and global functions related to Manufacturing Toolkit.
Definition LicenseManager_LicenseError.hxx:30

shape_processor.java

// ****************************************************************************
// $Id$
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2025, CADEX. All rights reserved.
//
// This file is part of the Manufacturing Toolkit software.
//
// You may use this file under the terms of the BSD license as follows:
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ****************************************************************************
import cadex.*;
import cadex.ModelData.*;
import cadex.Collections.*;
abstract class ShapeProcessor extends ModelElementVoidVisitor
{
public void Apply(Part thePart) {
String aPartName = thePart.Name().IsEmpty() ? "noname" : thePart.Name().Data();
BodyList aBodyList = thePart.Bodies();
for (int i = 0; i < aBodyList.size(); ++i) {
Body aBody = aBodyList.get(i);
ShapeIterator aShapeIt = new ShapeIterator(aBody);
while (aShapeIt.HasNext()) {
Shape aShape = aShapeIt.Next();
if (aShape.Type() == ShapeType.Solid) {
System.out.format("Part #%d [\"%s\"] - solid #%d has:\n", myPartIndex, aPartName, i);
ProcessSolid(Solid.Cast(aShape));
} else if (aShape.Type() == ShapeType.Shell) {
System.out.format("Part #%d [\"%s\"] - shell #%d has:\n", myPartIndex, aPartName, i);
ProcessShell(Shell.Cast(aShape));
}
}
}
++myPartIndex;
}
public abstract void ProcessSolid(Solid theSolid);
public abstract void ProcessShell(Shell theShell);
private long myPartIndex = 0;
}
abstract class SolidProcessor extends ModelElementVoidVisitor
{
public void Apply(Part thePart) {
String aPartName = thePart.Name().IsEmpty() ? "noname" : thePart.Name().Data();
// Looking for a suitable body
BodyList aBodyList = thePart.Bodies();
for (int i = 0; i < aBodyList.size(); ++i) {
Body aBody = aBodyList.get(i);
ShapeIterator aShapeIt = new ShapeIterator(aBody);
while (aShapeIt.HasNext()) {
Shape aShape = aShapeIt.Next();
if (aShape.Type() == ShapeType.Solid) {
System.out.format("Part #%d [\"%s\"] - solid #%d has:\n", myPartIndex, aPartName, i);
ProcessSolid(Solid.Cast(aShape));
}
}
}
++myPartIndex;
}
public abstract void ProcessSolid(Solid theSolid);
private long myPartIndex = 0;
}
abstract class SolidAndMeshProcessor extends ModelElementVoidVisitor
{
public void Apply(Part thePart)
{
String aPartName = thePart.Name().IsEmpty() ? "noname" : thePart.Name().Data();
BodyList aBodyList = thePart.Bodies();
for (int i = 0; i < aBodyList.size(); ++i)
{
Body aBody = aBodyList.get(i);
ShapeIterator aShapeIt = new ShapeIterator(aBody);
while (aShapeIt.HasNext())
{
Shape aShape = aShapeIt.Next();
if (aShape.Type() == ShapeType.Solid)
{
System.out.format("Part #%d [\"%s\"] - solid #%d has:\n", myPartIndex, aPartName, i);
ProcessSolid(Solid.Cast(aShape), aPartName, i);
}
}
}
++myPartIndex;
}
public abstract void ProcessSolid(Solid theSolid, String thePartName, long theShapeIndex);
protected long myPartIndex = 0;
}
Defines classes, types, enums, and functions related to topological entities and scene graph elements...
ShapeType
Defines shape type.
Definition ShapeType.hxx:27

dfm_analyzer.java

// ****************************************************************************
// $Id$
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2025, CADEX. All rights reserved.
//
// This file is part of the Manufacturing Toolkit software.
//
// You may use this file under the terms of the BSD license as follows:
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ****************************************************************************
import cadex.*;
import cadex.ModelData.*;
import java.util.Map;
import java.util.HashMap;
import java.util.function.Consumer;
public class dfm_analyzer {
static {
try {
System.loadLibrary("CadExMTK");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load.\n" + e);
System.exit(1);
}
}
public static void main(String[] args) {
String aKey = MTKLicenseKey.Value();
// Activate the license (the key must be defined in MTKLicenseKey.java)
if (!LicenseManager.Activate(aKey)) {
System.out.println("Failed to activate Manufacturing Toolkit license.");
System.exit(1);
}
if (args.length != 2) {
System.out.println("Usage: " + " <input_file> <operation>, where:");
System.out.println(" <input_file> is a name of the file to be read");
System.out.println(" <operation> is a name of desired machining operation");
System.out.println("");
PrintSupportedOperations();
System.exit(1);
}
String aSource = args[0];
Model aModel = new Model();
ModelReader aReader = new ModelReader();
// Reading the file
if (!aReader.Read(new UTF16String(aSource), aModel)) {
System.out.println("Failed to read the file " + aSource);
System.exit(1);
}
System.out.println("Model: " + aModel.Name() + "\n");
String anOperationStr = args[1];
Machining_OperationType anOperation = OperationType(anOperationStr);
if (anOperation == Machining_OperationType.Machining_OT_Undefined)
{
System.out.println("Unsupported operation - " + anOperationStr);
System.out.println("Please use one of the following.");
PrintSupportedOperations();
System.exit(1);
}
PartProcessor aPartProcessor = new PartProcessor(anOperation);
ModelElementUniqueVisitor aVisitor = new ModelElementUniqueVisitor(aPartProcessor);
aModel.Accept(aVisitor);
}
private static void PrintSupportedOperations()
{
System.out.println("Supported operations:");
System.out.println(" milling:\t CNC Machining Milling feature recognition");
System.out.println(" turning:\t CNC Machining Lathe+Milling feature recognition");
}
private static Machining_OperationType OperationType(String theOperationStr)
{
HashMap<String, Machining_OperationType> aProcessMap = new HashMap<>();
aProcessMap.put("milling", Machining_OperationType.Machining_OT_Milling);
aProcessMap.put("turning", Machining_OperationType.Machining_OT_LatheMilling);
Machining_OperationType aProcess = aProcessMap.getOrDefault(theOperationStr, Machining_OperationType.Machining_OT_Undefined);
return aProcess;
}
static class PartProcessor extends SolidProcessor
{
public PartProcessor(Machining_OperationType theOperation)
{
myOperation = theOperation;
}
public void ProcessSolid(Solid theSolid)
{
// Find features
Machining_Data aData = new Machining_Data();
Machining_FeatureRecognizerParameters aParam = new Machining_FeatureRecognizerParameters();
aParam.SetOperation(myOperation);
Machining_FeatureRecognizer aRecognizer = new Machining_FeatureRecognizer(aParam);
aRecognizer.Perform(theSolid, aData);
// Run drilling analyzer for found features
DFMMachining_DrillingAnalyzerParameters aDrillingParameters = new DFMMachining_DrillingAnalyzerParameters();
DFMMachining_Analyzer aDrillingAnalyzer = new DFMMachining_Analyzer(aDrillingParameters);
MTKBase_FeatureList anIssueList = aDrillingAnalyzer.Perform(theSolid, aData);
// Run milling analyzer for found features
DFMMachining_MillingAnalyzerParameters aMillingParameters = new DFMMachining_MillingAnalyzerParameters();
DFMMachining_Analyzer aMillingAnalyzer = new DFMMachining_Analyzer(aMillingParameters);
MTKBase_FeatureList aMillingIssueList = aMillingAnalyzer.Perform(theSolid, aData);
// Combine issue lists
CombineFeatureLists(anIssueList, aMillingIssueList);
MTKBase_FeatureList aTurningIssueList = new MTKBase_FeatureList();
if (myOperation == Machining_OperationType.Machining_OT_LatheMilling)
{
// Run turning analyzer for found features
DFMMachining_TurningAnalyzerParameters aTurninigParameters = new DFMMachining_TurningAnalyzerParameters();
DFMMachining_Analyzer aTurningAnalyzer = new DFMMachining_Analyzer(aTurninigParameters);
aTurningIssueList = aTurningAnalyzer.Perform(theSolid, aData);
// Combine issue lists
CombineFeatureLists(anIssueList, aTurningIssueList);
}
Report.PrintIssues(anIssueList);
}
private void CombineFeatureLists(MTKBase_FeatureList theFirst, MTKBase_FeatureList theSecond)
{
for (long i = 0; i < theSecond.Size(); ++i) {
MTKBase_Feature aFeature = theSecond.Feature(i);
if (myOperation == Machining_OperationType.Machining_OT_LatheMilling
&& DFMMachining_MillingIssue.CompareType(aFeature)
&& !DFMMachining_DeepPocketIssue.CompareType(aFeature))
{
continue;
}
theFirst.Append(aFeature);
}
}
private Machining_OperationType myOperation = Machining_OperationType.Machining_OT_Undefined;
}
static class Report {
public static void PrintIssues(MTKBase_FeatureList theIssueList) {
FeatureGroupManager aManager = new FeatureGroupManager();
//group by parameters to provide more compact information about issues
for (long i = 0; i < theIssueList.Size(); ++i)
{
MTKBase_Feature anIssue = theIssueList.Feature (i);
//drilling
if (DFMMachining_SmallDiameterHoleIssue.CompareType(anIssue))
{
aManager.AddFeature("Small Diameter Hole Issue(s)", "Hole(s)", true, anIssue);
}
else if (DFMMachining_DeepHoleIssue.CompareType(anIssue))
{
aManager.AddFeature("Deep Hole Issue(s)", "Hole(s)", true, anIssue);
}
else if (DFMMachining_NonStandardDiameterHoleIssue.CompareType(anIssue))
{
aManager.AddFeature("Non Standard Diameter Hole Issue(s)", "Hole(s)", true, anIssue);
}
else if (DFMMachining_NonStandardDrillPointAngleBlindHoleIssue.CompareType(anIssue))
{
aManager.AddFeature("Non Standard Drill Point Angle Blind Hole Issue(s)", "Hole(s)", true, anIssue);
}
else if (DFMMachining_FlatBottomHoleIssue.CompareType(anIssue))
{
aManager.AddFeature("Flat Bottom Hole Issue(s)", "", false, anIssue);
}
else if (DFMMachining_NonPerpendicularHoleIssue.CompareType(anIssue))
{
aManager.AddFeature("Non Perpendicular Hole Issue(s)", "", false, anIssue);
}
else if (DFMMachining_IntersectingCavityHoleIssue.CompareType(anIssue))
{
aManager.AddFeature("Intersecting Cavity Hole Issue(s)", "", false, anIssue);
}
else if (DFMMachining_PartialHoleIssue.CompareType(anIssue))
{
aManager.AddFeature("Partial Hole Issue(s)", "Hole(s)", true, anIssue);
}
//milling
else if (DFMMachining_NonStandardRadiusMilledPartFloorFilletIssue.CompareType(anIssue))
{
aManager.AddFeature("Non Standard Radius Milled Part Floor Fillet Issue(s)", "Floor Fillet(s)", true, anIssue);
}
else if (DFMMachining_DeepPocketIssue.CompareType(anIssue))
{
aManager.AddFeature("Deep Pocket Issue(s)", "Pocket(s)", true, anIssue);
}
else if (DFMMachining_HighBossIssue.CompareType(anIssue))
{
aManager.AddFeature("High Boss Issue(s)", "Boss(es)", true, anIssue);
}
else if (DFMMachining_LargeMilledPartIssue.CompareType(anIssue))
{
aManager.AddFeature("Large Milled Part Issue(s)", "Part(s)", true, anIssue);
}
else if (DFMMachining_SmallRadiusMilledPartInternalCornerIssue.CompareType(anIssue))
{
aManager.AddFeature("Small Radius Milled Part Internal Corner Issue(s)", "Internal Corner(s)", true, anIssue);
}
else if (DFMMachining_NonPerpendicularMilledPartShapeIssue.CompareType(anIssue))
{
aManager.AddFeature("Non Perpendicular Milled Part Shape Issue(s)", "Shape(s)", true, anIssue);
}
else if (DFMMachining_MilledPartExternalEdgeFilletIssue.CompareType(anIssue))
{
aManager.AddFeature("Milled Part External Edge Fillet Issue(s)", "", false, anIssue);
}
else if (DFMMachining_InconsistentRadiusMilledPartFloorFilletIssue.CompareType(anIssue))
{
aManager.AddFeature("Inconsistent Radius Milled Part Floor Fillet Issue(s)", "Floor Fillet(s)", true, anIssue);
}
else if (DFMMachining_NarrowRegionInPocketIssue.CompareType(anIssue))
{
aManager.AddFeature("Narrow Region In Pocket Issue(s)", "Region(s)", true, anIssue);
}
else if (DFMMachining_LargeDifferenceRegionsSizeInPocketIssue.CompareType(anIssue))
{
aManager.AddFeature("Large Difference Regions Size In Pocket Issue(s)", "Region Size(s)", true, anIssue);
}
else if (DFMMachining_SmallWallThicknessIssue.CompareType(anIssue))
{
aManager.AddFeature("Small Wall Thickness Issue(s)", "Wall(s)", true, anIssue);
}
//turning
else if (DFMMachining_IrregularTurnedPartOuterDiameterProfileReliefIssue.CompareType(anIssue))
{
aManager.AddFeature("Irregular Turned Part Outer Diameter Profile Relief Issue(s)", "Outer Diameter Profile Relief(s)", true, anIssue);
}
else if (DFMMachining_SmallRadiusTurnedPartInternalCornerIssue.CompareType(anIssue))
{
aManager.AddFeature("Small Radius Turned Part Internal Corner Issue(s)", "Internal Corner(s)", true, anIssue);
}
else if (DFMMachining_LargeTurnedPartIssue.CompareType(anIssue))
{
aManager.AddFeature("Large Turned Part Issue(s)", "Part(s)", true, anIssue);
}
else if (DFMMachining_LongSlenderTurnedPartIssue.CompareType(anIssue))
{
aManager.AddFeature("Long Slender Turned Part Issue(s)", "Part(s)", true, anIssue);
}
else if (DFMMachining_SmallDepthBlindBoredHoleReliefIssue.CompareType(anIssue))
{
aManager.AddFeature("Small Depth Blind Bored Hole Relief Issue(s)", "Blind Bored Hole(s)", true, anIssue);
}
else if (DFMMachining_DeepBoredHoleIssue.CompareType(anIssue))
{
aManager.AddFeature("Deep Bored Hole Issue(s)", "Bored Hole(s)", true, anIssue);
}
else if (DFMMachining_SquareEndKeywayIssue.CompareType(anIssue))
{
aManager.AddFeature("Square End Keyway Issue(s)", "", false, anIssue);
}
else if (DFMMachining_NonSymmetricalAxialSlotIssue.CompareType(anIssue))
{
aManager.AddFeature("Non Symmetrical Axial Slot Issue(s)", "", false, anIssue);
}
}
//print
Consumer<MTKBase_Feature> PrintFeatureParameters = theIssue ->
{
//drilling
if (DFMMachining_SmallDiameterHoleIssue.CompareType(theIssue))
{
DFMMachining_SmallDiameterHoleIssue aSDHIssue = DFMMachining_SmallDiameterHoleIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected min diameter", aSDHIssue.ExpectedMinDiameter(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual diameter", aSDHIssue.ActualDiameter(), "mm");
}
else if (DFMMachining_DeepHoleIssue.CompareType(theIssue))
{
DFMMachining_DeepHoleIssue aDHIssue = DFMMachining_DeepHoleIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected max depth", aDHIssue.ExpectedMaxDepth(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual depth", aDHIssue.ActualDepth(), "mm");
}
else if (DFMMachining_NonStandardDiameterHoleIssue.CompareType(theIssue))
{
DFMMachining_NonStandardDiameterHoleIssue aNSDHIssue = DFMMachining_NonStandardDiameterHoleIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("nearest standard diameter", aNSDHIssue.NearestStandardDiameter(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual diameter", aNSDHIssue.ActualDiameter(), "mm");
}
else if (DFMMachining_NonStandardDrillPointAngleBlindHoleIssue.CompareType(theIssue))
{
DFMMachining_NonStandardDrillPointAngleBlindHoleIssue aNSDHIssue = DFMMachining_NonStandardDrillPointAngleBlindHoleIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("nearest standard angle", ToDegrees(aNSDHIssue.NearestStandardAngle()), "deg");
FeatureGroupManager.PrintFeatureParameter("actual angle", ToDegrees(aNSDHIssue.ActualAngle()), "deg");
}
else if (DFMMachining_FlatBottomHoleIssue.CompareType(theIssue))
{
//no parameters
}
else if (DFMMachining_NonPerpendicularHoleIssue.CompareType(theIssue))
{
//no parameters
}
else if (DFMMachining_IntersectingCavityHoleIssue.CompareType(theIssue))
{
//no parameters
}
else if (DFMMachining_PartialHoleIssue.CompareType(theIssue))
{
DFMMachining_PartialHoleIssue aPHIssue = DFMMachining_PartialHoleIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected min material percent", aPHIssue.ExpectedMinMaterialPercent(), "");
FeatureGroupManager.PrintFeatureParameter("actual material percent", aPHIssue.ActualMaterialPercent(), "");
}
//milling
else if (DFMMachining_NonStandardRadiusMilledPartFloorFilletIssue.CompareType(theIssue))
{
DFMMachining_NonStandardRadiusMilledPartFloorFilletIssue aNSRMPFFIssue = DFMMachining_NonStandardRadiusMilledPartFloorFilletIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("nearest standard radius", aNSRMPFFIssue.NearestStandardRadius(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual radius", aNSRMPFFIssue.ActualRadius(), "mm");
}
else if (DFMMachining_DeepPocketIssue.CompareType(theIssue))
{
DFMMachining_DeepPocketIssue aDPIssue = DFMMachining_DeepPocketIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected max depth", aDPIssue.ExpectedMaxDepth(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual depth", aDPIssue.ActualDepth(), "mm");
}
else if (DFMMachining_HighBossIssue.CompareType(theIssue))
{
DFMMachining_HighBossIssue aHBIssue = DFMMachining_HighBossIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected max height", aHBIssue.ExpectedMaxHeight(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual height", aHBIssue.ActualHeight(), "mm");
}
else if (DFMMachining_LargeMilledPartIssue.CompareType(theIssue))
{
DFMMachining_LargeMilledPartIssue aLMPIssue = DFMMachining_LargeMilledPartIssue.Cast(theIssue);
DFMMachining_MilledPartSize anExpectedSize = aLMPIssue.ExpectedMaxMilledPartSize();
DFMMachining_MilledPartSize anActualSize = aLMPIssue.ActualMilledPartSize();
FeatureGroupManager.PrintFeatureParameter(
"expected max size (LxWxH)",
new Dimension(anExpectedSize.Length(), anExpectedSize.Width(), anExpectedSize.Height()),
"mm");
FeatureGroupManager.PrintFeatureParameter(
"actual size (LxWxH)",
new Dimension(anActualSize.Length(), anActualSize.Width(), anActualSize.Height()),
"mm");
}
else if (DFMMachining_SmallRadiusMilledPartInternalCornerIssue.CompareType(theIssue))
{
DFMMachining_SmallRadiusMilledPartInternalCornerIssue aSRMPICIssue = DFMMachining_SmallRadiusMilledPartInternalCornerIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected min radius", aSRMPICIssue.ExpectedMinRadius(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual radius", aSRMPICIssue.ActualRadius(), "mm");
}
else if (DFMMachining_NonPerpendicularMilledPartShapeIssue.CompareType(theIssue))
{
DFMMachining_NonPerpendicularMilledPartShapeIssue aNPMPSIssue = DFMMachining_NonPerpendicularMilledPartShapeIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("actual angle", ToDegrees(aNPMPSIssue.ActualAngle()), "deg");
}
else if (DFMMachining_MilledPartExternalEdgeFilletIssue.CompareType(theIssue))
{
//no parameters
}
else if (DFMMachining_InconsistentRadiusMilledPartFloorFilletIssue.CompareType(theIssue))
{
DFMMachining_InconsistentRadiusMilledPartFloorFilletIssue aIRMPFFIssue =
DFMMachining_InconsistentRadiusMilledPartFloorFilletIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected radius", aIRMPFFIssue.ExpectedRadius(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual radius", aIRMPFFIssue.ActualRadius(), "mm");
}
else if (DFMMachining_NarrowRegionInPocketIssue.CompareType(theIssue))
{
DFMMachining_NarrowRegionInPocketIssue aSMNRDIssue =
DFMMachining_NarrowRegionInPocketIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected minimum region size", aSMNRDIssue.ExpectedMinRegionSize(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual region size", aSMNRDIssue.ActualRegionSize(), "mm");
}
else if (DFMMachining_LargeDifferenceRegionsSizeInPocketIssue.CompareType(theIssue))
{
DFMMachining_LargeDifferenceRegionsSizeInPocketIssue aLMNRRIssue =
DFMMachining_LargeDifferenceRegionsSizeInPocketIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected regions maximum to minimum size ratio", aLMNRRIssue.ExpectedMaxRegionsMaxToMinSizeRatio(), "");
FeatureGroupManager.PrintFeatureParameter("actual regions maximum to minimum size ratio", aLMNRRIssue.ActualMaxRegionsMaxToMinSizeRatio(), "");
}
else if (DFMMachining_SmallWallThicknessIssue.CompareType(theIssue))
{
DFMMachining_SmallWallThicknessIssue aSWTIssue =
DFMMachining_SmallWallThicknessIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected min wall thickness", aSWTIssue.ExpectedMinThickness(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual wall thickness", aSWTIssue.ActualThickness(), "mm");
}
//turning
else if (DFMMachining_IrregularTurnedPartOuterDiameterProfileReliefIssue.CompareType(theIssue))
{
DFMMachining_IrregularTurnedPartOuterDiameterProfileReliefIssue anITPODPRIssue = DFMMachining_IrregularTurnedPartOuterDiameterProfileReliefIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter(
"expected max incline angle", ToDegrees(anITPODPRIssue.ExpectedMaxFaceInclineAngle()), "deg");
FeatureGroupManager.PrintFeatureParameter(
"actual incline angle", ToDegrees(anITPODPRIssue.ActualFaceInclineAngle()), "deg");
}
else if (DFMMachining_SmallRadiusTurnedPartInternalCornerIssue.CompareType(theIssue))
{
DFMMachining_SmallRadiusTurnedPartInternalCornerIssue aSRTPICIssue = DFMMachining_SmallRadiusTurnedPartInternalCornerIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected min radius", aSRTPICIssue.ExpectedMinRadius(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual radius", aSRTPICIssue.ActualRadius(), "mm");
}
else if (DFMMachining_LargeTurnedPartIssue.CompareType(theIssue))
{
DFMMachining_LargeTurnedPartIssue aLTPIssue = DFMMachining_LargeTurnedPartIssue.Cast(theIssue);
DFMMachining_TurnedPartSize anExpectedSize = aLTPIssue.ExpectedMaxTurnedPartSize();
DFMMachining_TurnedPartSize anActualSize = aLTPIssue.ActualTurnedPartSize();
FeatureGroupManager.PrintFeatureParameter(
"expected max size (LxR)",
new Pair(anExpectedSize.Length(), anExpectedSize.Radius()),
"mm");
FeatureGroupManager.PrintFeatureParameter(
"actual size (LxR)",
new Pair(anActualSize.Length(), anActualSize.Radius()),
"mm");
}
else if (DFMMachining_LongSlenderTurnedPartIssue.CompareType(theIssue))
{
DFMMachining_LongSlenderTurnedPartIssue aLSTPIssue = DFMMachining_LongSlenderTurnedPartIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected min length", aLSTPIssue.ExpectedMaxLength(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual length", aLSTPIssue.ActualLength(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual min diameter", aLSTPIssue.ActualMinDiameter(), "mm");
}
else if (DFMMachining_SmallDepthBlindBoredHoleReliefIssue.CompareType(theIssue))
{
DFMMachining_SmallDepthBlindBoredHoleReliefIssue aSDBBHRIssue = DFMMachining_SmallDepthBlindBoredHoleReliefIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected min relief depth", aSDBBHRIssue.ExpectedMinReliefDepth(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual relief depth", aSDBBHRIssue.ActualReliefDepth(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual diameter", aSDBBHRIssue.ActualDiameter(), "mm");
}
else if (DFMMachining_DeepBoredHoleIssue.CompareType(theIssue))
{
DFMMachining_DeepBoredHoleIssue aDBHIssue = DFMMachining_DeepBoredHoleIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected max depth", aDBHIssue.ExpectedMaxDepth(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual depth", aDBHIssue.ActualDepth(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual diameter", aDBHIssue.ActualDiameter(), "mm");
}
else if (DFMMachining_SquareEndKeywayIssue.CompareType(theIssue))
{
//no parameters
}
else if (DFMMachining_NonSymmetricalAxialSlotIssue.CompareType(theIssue))
{
//no parameters
}
};
aManager.Print("issues", PrintFeatureParameters);
}
static double ToDegrees(double theAngleRad)
{
return theAngleRad * 180 / Math.PI;
}
}
}