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) {
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;
}
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;
}
The mtk namespace is intended to become the primary namespace for MTK and replace direct use of the c...
Contains classes, namespaces, enums, types, and global functions related to Manufacturing Toolkit.
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();
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().ToString();
myShapeIndex = 0;
BodyList aBodyList = thePart.Bodies();
for (Body aBody : aBodyList) {
if (MeshBody.CompareType(aBody)) {
ProcessMeshBody(MeshBody.Cast(aBody), aPartName);
} else if (SolidBody.CompareType(aBody)) {
System.out.format("Part #%d [\"%s\"] - solid #%d has:\n", myPartIndex, aPartName, myShapeIndex);
ProcessSolid(SolidBody.Cast(aBody).Solid(), aPartName);
myShapeIndex++;
}
}
++myPartIndex;
}
public abstract void ProcessSolid(Solid theSolid, String thePartName);
public abstract void ProcessITS(IndexedTriangleSet theITS, String thePartName);
private void ProcessMeshBody(MeshBody theMeshBody, String thePartName) {
MeshShapeList aShapeList = theMeshBody.Shapes();
for (MeshShape aMeshShape : aShapeList) {
if (IndexedTriangleSet.CompareType(aMeshShape)) {
System.out.format("Part #%d [\"%s\"] - ITS #%d has:\n", myPartIndex, thePartName, myShapeIndex);
ProcessITS(IndexedTriangleSet.Cast(aMeshShape), thePartName);
myShapeIndex++;
}
}
}
protected long myPartIndex = 0;
protected long myShapeIndex = 0;
}
Defines classes, types, enums, and functions related to topological entities and scene graph elements...
import java.util.Map;
import java.util.HashMap;
import java.util.function.Consumer;
public class dfm_analyzer {
static {
try {
System.loadLibrary("MTKCore");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load.\n" + e);
System.exit(1);
}
}
public static void main(String[] args) {
if (args.length != 1) {
System.out.println("Usage: " + " <input_file>, where:");
System.out.println(" <input_file> is a name of the file to be read");
System.out.println("");
System.exit(1);
}
String aKey = MTKLicenseKey.Value();
if (!LicenseHelper.SetupRuntimeKey()) {
System.exit(1);
}
try {
LicenseManager.Activate(aKey);
} catch (LicenseError theException) {
LicenseManager.Deactivate();
System.out.println("Failed to activate Manufacturing Toolkit license: " + theException.what());
System.exit(1);
}
String aSource = args[0];
Model aModel = new Model();
ModelReader aReader = new ModelReader();
if (!aReader.Read(new UTF16String(aSource), aModel)) {
LicenseManager.Deactivate();
System.out.println("Failed to read the file " + aSource);
System.exit(1);
}
System.out.println("Model: " + aModel.Name() + "\n");
PartProcessor aPartProcessor = new PartProcessor();
ModelElementUniqueVisitor aVisitor = new ModelElementUniqueVisitor(aPartProcessor);
aModel.Accept(aVisitor);
LicenseManager.Deactivate();
}
static class PartProcessor extends SolidProcessor {
public PartProcessor() {
}
public void ProcessSolid(Solid theSolid) {
Molding_FeatureRecognizerParameters aRecognizerParameters = new Molding_FeatureRecognizerParameters();
aRecognizerParameters.SetMaxRibThickness(30.0);
aRecognizerParameters.SetMaxRibDraftAngle(0.2);
aRecognizerParameters.SetMaxRibTaperAngle(0.1);
Molding_FeatureRecognizer aRecognizer = new Molding_FeatureRecognizer(aRecognizerParameters);
Molding_Analyzer anAnalyzer = new Molding_Analyzer();
anAnalyzer.AddTool(aRecognizer);
Molding_Data aData = anAnalyzer.Perform(theSolid);
DFMMolding_AnalyzerParameters aParameters = new DFMMolding_AnalyzerParameters();
DFMMolding_Analyzer aDFMAnalyzer = new DFMMolding_Analyzer(aParameters);
MTKBase_FeatureList anIssueList = aDFMAnalyzer.Perform(aData);
Report.PrintIssues(anIssueList);
}
}
static class Report {
public static void PrintIssues(MTKBase_FeatureList theIssueList) {
FeatureGroupManager aManager = new FeatureGroupManager();
for (long i = 0; i < theIssueList.Size(); ++i) {
MTKBase_Feature anIssue = theIssueList.Feature(i);
if (DFMMolding_IrregularCoreDepthScrewBossIssue.CompareType(anIssue)) {
aManager.AddFeature("Irregular Core Depth Screw Boss Issue(s)", "Screw Boss(es)", true, anIssue);
} else if (DFMMolding_IrregularCoreDiameterScrewBossIssue.CompareType(anIssue)) {
aManager.AddFeature("Irregular Core Diameter Screw Boss Issue(s)", "Screw Boss(es)", true, anIssue);
} else if (DFMMolding_IrregularWallThicknessScrewBossIssue.CompareType(anIssue)) {
aManager.AddFeature("Irregular Wall Thickness Screw Boss Issue(s)", "Screw Boss(es)", true, anIssue);
} else if (DFMMolding_HighScrewBossIssue.CompareType(anIssue)) {
aManager.AddFeature("High Screw Boss Issue(s)", "Screw Boss(es)", true, anIssue);
} else if (DFMMolding_SmallBaseRadiusScrewBossIssue.CompareType(anIssue)) {
aManager.AddFeature("Small Base Radius Screw Boss Issue(s)", "Screw Boss(es)", true, anIssue);
} else if (DFMMolding_SmallDraftAngleScrewBossIssue.CompareType(anIssue)) {
aManager.AddFeature("Small Draft Angle Screw Boss Issue(s)", "Screw Boss(es)", true, anIssue);
} else if (DFMMolding_SmallHoleBaseRadiusScrewBossIssue.CompareType(anIssue)) {
aManager.AddFeature("Small Hole Base Radius Screw Boss Issue(s)", "Screw Boss(es)", true, anIssue);
} else if (DFMMolding_NonChamferedScrewBossIssue.CompareType(anIssue)) {
aManager.AddFeature("Non Chamfered Screw Boss Issue(s)", "Screw Boss(es)", false, anIssue);
} else if (DFMMolding_HighRibIssue.CompareType(anIssue)) {
aManager.AddFeature("High Rib Issue(s)", "Rib(s)", true, anIssue);
} else if (DFMMolding_IrregularThicknessRibIssue.CompareType(anIssue)) {
aManager.AddFeature("Irregular Thickness Rib Issue(s)", "Rib(s)", true, anIssue);
} else if (DFMMolding_SmallBaseRadiusRibIssue.CompareType(anIssue)) {
aManager.AddFeature("Small Base Radius Rib Issue(s)", "Rib(s)", true, anIssue);
} else if (DFMMolding_SmallDraftAngleRibIssue.CompareType(anIssue)) {
aManager.AddFeature("Small Draft Angle Rib Issue(s)", "Rib(s)", true, anIssue);
} else if (DFMMolding_SmallDistanceBetweenRibsIssue.CompareType(anIssue)) {
aManager.AddFeature("Small Distance Between Ribs Issue(s)", "Rib(s)", true, anIssue);
} else if (DFMMolding_IrregularWallThicknessIssue.CompareType(anIssue)) {
aManager.AddFeature("Irregular Wall Thickness Issue(s)", "Wall(s)", true, anIssue);
} else if (DFMMolding_LargeWallThicknessIssue.CompareType(anIssue)) {
aManager.AddFeature("Large Wall Thickness Issue(s)", "Wall(s)", true, anIssue);
} else if (DFMMolding_SmallWallThicknessIssue.CompareType(anIssue)) {
aManager.AddFeature("Small Wall Thickness Issue(s)", "Wall(s)", true, anIssue);
} else if (DFMMolding_SmallDraftAngleWallIssue.CompareType(anIssue)) {
aManager.AddFeature("Small Draft Angle Wall Thickness Issue(s)", "Wall(s)", true, anIssue);
} else if (DFMMolding_SmallDistanceBetweenBossesIssue.CompareType(anIssue)) {
aManager.AddFeature("Small Distance Between Bosses Issue(s)", "Boss(es)", true, anIssue);
}
}
Consumer<MTKBase_Feature> PrintFeatureParameters = theIssue ->
{
if (DFMMolding_IrregularCoreDepthScrewBossIssue.CompareType(theIssue)) {
DFMMolding_IrregularCoreDepthScrewBossIssue aICDSBIssue = DFMMolding_IrregularCoreDepthScrewBossIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("actual height", aICDSBIssue.ActualCoreDepth(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual core depth", aICDSBIssue.ActualHeight(), "mm");
} else if (DFMMolding_IrregularCoreDiameterScrewBossIssue.CompareType(theIssue)) {
DFMMolding_IrregularCoreDiameterScrewBossIssue aICDSBIssue = DFMMolding_IrregularCoreDiameterScrewBossIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected min core diameter", aICDSBIssue.ExpectedMinCoreDiameter(), "mm");
FeatureGroupManager.PrintFeatureParameter("expected max core diameter", aICDSBIssue.ExpectedMaxCoreDiameter(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual core diameter", aICDSBIssue.ActualCoreDiameter(), "mm");
} else if (DFMMolding_IrregularWallThicknessScrewBossIssue.CompareType(theIssue)) {
DFMMolding_IrregularWallThicknessScrewBossIssue aIWTSBIssue = DFMMolding_IrregularWallThicknessScrewBossIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected max thickness", aIWTSBIssue.ExpectedMaxThickness(), "mm");
FeatureGroupManager.PrintFeatureParameter("expected min thickness", aIWTSBIssue.ExpectedMinThickness(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual thickness", aIWTSBIssue.ActualThickness(), "mm");
} else if (DFMMolding_HighScrewBossIssue.CompareType(theIssue)) {
DFMMolding_HighScrewBossIssue aHSBIssue = DFMMolding_HighScrewBossIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected max height", aHSBIssue.ExpectedMaxHeight(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual height", aHSBIssue.ActualHeight(), "mm");
} else if (DFMMolding_SmallBaseRadiusScrewBossIssue.CompareType(theIssue)) {
DFMMolding_SmallBaseRadiusScrewBossIssue aSBRSBIssue = DFMMolding_SmallBaseRadiusScrewBossIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected min base radius", aSBRSBIssue.ExpectedMinBaseRadius(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual base radius", aSBRSBIssue.ActualBaseRadius(), "mm");
} else if (DFMMolding_SmallDraftAngleScrewBossIssue.CompareType(theIssue)) {
DFMMolding_SmallDraftAngleScrewBossIssue aSDASBIssue = DFMMolding_SmallDraftAngleScrewBossIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected min draft angle", ToDegrees(aSDASBIssue.ExpectedMinDraftAngle()), "deg");
FeatureGroupManager.PrintFeatureParameter("actual draft angle", ToDegrees(aSDASBIssue.ActualDraftAngle()), "deg");
} else if (DFMMolding_HighRibIssue.CompareType(theIssue)) {
DFMMolding_HighRibIssue aHRIssue = DFMMolding_HighRibIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected max height", aHRIssue.ExpectedMaxHeight(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual height", aHRIssue.ActualHeight(), "mm");
} else if (DFMMolding_IrregularThicknessRibIssue.CompareType(theIssue)) {
DFMMolding_IrregularThicknessRibIssue aITRIssue = DFMMolding_IrregularThicknessRibIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected min thickness", aITRIssue.ExpectedMinThickness(), "mm");
FeatureGroupManager.PrintFeatureParameter("expected max thickness", aITRIssue.ExpectedMaxThickness(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual thickness", aITRIssue.ActualThickness(), "mm");
} else if (DFMMolding_SmallBaseRadiusRibIssue.CompareType(theIssue)) {
DFMMolding_SmallBaseRadiusRibIssue aSBRRIssue = DFMMolding_SmallBaseRadiusRibIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected min base radius", aSBRRIssue.ExpectedMinBaseRadius(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual base radius", aSBRRIssue.ActualBaseRadius(), "mm");
} else if (DFMMolding_SmallDraftAngleRibIssue.CompareType(theIssue)) {
DFMMolding_SmallDraftAngleRibIssue aSDARIssue = DFMMolding_SmallDraftAngleRibIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected min draft angle", ToDegrees(aSDARIssue.ExpectedMinDraftAngle()), "deg");
FeatureGroupManager.PrintFeatureParameter("actual draft angle", ToDegrees(aSDARIssue.ActualDraftAngle()), "deg");
} else if (DFMMolding_SmallDistanceBetweenRibsIssue.CompareType(theIssue)) {
DFMMolding_SmallDistanceBetweenRibsIssue aSDBRIssue = DFMMolding_SmallDistanceBetweenRibsIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected min distance", aSDBRIssue.ExpectedMinDistanceBetweenRibs(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual distance", aSDBRIssue.ActualDistanceBetweenRibs(), "mm");
} else if (DFMMolding_SmallHoleBaseRadiusScrewBossIssue.CompareType(theIssue)) {
DFMMolding_SmallHoleBaseRadiusScrewBossIssue aSHBRSBIssue = DFMMolding_SmallHoleBaseRadiusScrewBossIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected min hole base radius", aSHBRSBIssue.ExpectedMinHoleBaseRadius(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual hole base radius", aSHBRSBIssue.ActualHoleBaseRadius(), "mm");
} else if (DFMMolding_NonChamferedScrewBossIssue.CompareType(theIssue)) {
} else if (DFMMolding_IrregularWallThicknessIssue.CompareType(theIssue)) {
DFMMolding_IrregularWallThicknessIssue aIWTIIssue = DFMMolding_IrregularWallThicknessIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected max thickness", aIWTIIssue.ExpectedMaxThickness(), "mm");
FeatureGroupManager.PrintFeatureParameter("expected min thickness", aIWTIIssue.ExpectedMinThickness(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual thickness", aIWTIIssue.ActualThickness(), "mm");
} else if (DFMMolding_LargeWallThicknessIssue.CompareType(theIssue)) {
DFMMolding_LargeWallThicknessIssue aLWTIIssue = DFMMolding_LargeWallThicknessIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected max thickness", aLWTIIssue.ExpectedMaxThickness(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual thickness", aLWTIIssue.ActualThickness(), "mm");
} else if (DFMMolding_SmallWallThicknessIssue.CompareType(theIssue)) {
DFMMolding_SmallWallThicknessIssue aSWTIIssue = DFMMolding_SmallWallThicknessIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected min thickness", aSWTIIssue.ExpectedMinThickness(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual thickness", aSWTIIssue.ActualThickness(), "mm");
} else if (DFMMolding_SmallDraftAngleWallIssue.CompareType(theIssue)) {
DFMMolding_SmallDraftAngleWallIssue aSDAWIssue = DFMMolding_SmallDraftAngleWallIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected min draft angle", ToDegrees(aSDAWIssue.ExpectedMinDraftAngle()), "deg");
FeatureGroupManager.PrintFeatureParameter("actual draft angle", ToDegrees(aSDAWIssue.ActualDraftAngle()), "deg");
} else if (DFMMolding_SmallDistanceBetweenBossesIssue.CompareType(theIssue)) {
DFMMolding_SmallDistanceBetweenBossesIssue aSDBBIssue = DFMMolding_SmallDistanceBetweenBossesIssue.Cast(theIssue);
FeatureGroupManager.PrintFeatureParameter("expected min distance", aSDBBIssue.ExpectedMinDistanceBetweenBosses(), "mm");
FeatureGroupManager.PrintFeatureParameter("actual distance", aSDBBIssue.ActualDistanceBetweenBosses(), "mm");
}
};
aManager.Print("issues", PrintFeatureParameters);
}
static double ToDegrees(double theAngleRad) {
return theAngleRad * 180 / Math.PI;
}
}
}