- Refer to the Sheet Metal Feature Recognizer Example
feature_group.java
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.
shape_processor.java
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...
feature_recognizer.java
import java.util.function.Consumer;
public class feature_recognizer {
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.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 ShapeProcessor {
public PartProcessor() {
myRecognizer = new SheetMetal_FeatureRecognizer();
}
public void ProcessSolid(Solid theSolid) {
MTKBase_FeatureList aFeatureList = myRecognizer.Perform(theSolid);
Report.PrintFeatures(aFeatureList);
}
public void ProcessShell(Shell theShell) {
MTKBase_FeatureList aFeatureList = myRecognizer.Perform(theShell);
Report.PrintFeatures(aFeatureList);
}
private SheetMetal_FeatureRecognizer myRecognizer;
}
static class Report {
public static void PrintFeatures(MTKBase_FeatureList theFeatureList) {
GroupByParameters(theFeatureList);
Consumer<MTKBase_Feature> PrintFeatureParameters = theFeature ->
{
if (SheetMetal_FormingFeature.CompareType(theFeature)) {
SheetMetal_FormingFeature aFormingFeature = SheetMetal_FormingFeature.Cast(theFeature);
cadex.Geom.Direction anAxis = aFormingFeature.Axis().Direction();
Direction aDir = new Direction(anAxis.X(), anAxis.Y(), anAxis.Z());
FeatureGroupManager.PrintFeatureParameter("depth", aFormingFeature.Depth(), "mm");
FeatureGroupManager.PrintFeatureParameter("length", aFormingFeature.Length(), "mm");
FeatureGroupManager.PrintFeatureParameter("axis", aDir, "");
} else if (SheetMetal_Bead.CompareType(theFeature)) {
SheetMetal_Bead aBead = SheetMetal_Bead.Cast(theFeature);
FeatureGroupManager.PrintFeatureParameter("depth", aBead.Depth(), "mm");
} else if (SheetMetal_Cutout.CompareType(theFeature)) {
SheetMetal_Cutout aCutout = SheetMetal_Cutout.Cast(theFeature);
FeatureGroupManager.PrintFeatureParameter("perimeter", aCutout.Perimeter(), "mm");
} else if (SheetMetal_Louver.CompareType(theFeature)) {
SheetMetal_Louver aLouver = SheetMetal_Louver.Cast(theFeature);
FeatureGroupManager.PrintFeatureParameter("depth", aLouver.Depth(), "mm");
} else if (SheetMetal_Bridge.CompareType(theFeature)) {
SheetMetal_Bridge aBridge = SheetMetal_Bridge.Cast(theFeature);
FeatureGroupManager.PrintFeatureParameter("length", aBridge.Length(), "mm");
FeatureGroupManager.PrintFeatureParameter("depth", aBridge.Depth(), "mm");
} else if (SheetMetal_Hole.CompareType(theFeature)) {
SheetMetal_Hole aHole = SheetMetal_Hole.Cast(theFeature);
cadex.Geom.Direction anAxis = aHole.Axis().Axis();
Direction aDir = new Direction(anAxis.X(), anAxis.Y(), anAxis.Z());
FeatureGroupManager.PrintFeatureParameter("radius", aHole.Radius(), "mm");
FeatureGroupManager.PrintFeatureParameter("depth", aHole.Depth(), "mm");
FeatureGroupManager.PrintFeatureParameter("axis", aDir, "");
} else if (SheetMetal_Bend.CompareType(theFeature)) {
SheetMetal_Bend aBend = SheetMetal_Bend.Cast(theFeature);
FeatureGroupManager.PrintFeatureParameter("radius", aBend.Radius(), "mm");
FeatureGroupManager.PrintFeatureParameter("angle", ToDegrees(aBend.Angle()), "deg");
FeatureGroupManager.PrintFeatureParameter("length", aBend.Length(), "mm");
FeatureGroupManager.PrintFeatureParameter("width", aBend.Width(), "mm");
} else if (SheetMetal_Notch.CompareType(theFeature)) {
SheetMetal_Notch aNotch = SheetMetal_Notch.Cast(theFeature);
FeatureGroupManager.PrintFeatureParameter("length", aNotch.Length(), "mm");
FeatureGroupManager.PrintFeatureParameter("width", aNotch.Width(), "mm");
if (SheetMetal_StraightNotch.CompareType(aNotch)) {
SheetMetal_StraightNotch aStraightNotch = SheetMetal_StraightNotch.Cast(aNotch);
FeatureGroupManager.PrintFeatureParameter("corner fillet radius", aStraightNotch.CornerFilletRadius(), "mm");
} else if (SheetMetal_VNotch.CompareType(aNotch)) {
SheetMetal_VNotch aVNotch = SheetMetal_VNotch.Cast(aNotch);
FeatureGroupManager.PrintFeatureParameter("angle", ToDegrees(aVNotch.Angle()), "deg");
}
} else if (SheetMetal_Tab.CompareType(theFeature)) {
SheetMetal_Tab aTab = SheetMetal_Tab.Cast(theFeature);
FeatureGroupManager.PrintFeatureParameter("length", aTab.Length(), "mm");
FeatureGroupManager.PrintFeatureParameter("width", aTab.Width(), "mm");
}
};
myManager.Print("features", PrintFeatureParameters);
}
private static void GroupByParameters(MTKBase_FeatureList theFeatures) {
for (long i = 0; i < theFeatures.Size(); ++i) {
MTKBase_Feature aFeature = theFeatures.Feature(i);
if (SheetMetal_FormingFeature.CompareType(aFeature)) {
myManager.AddFeature("Forming Feature(s)", "Forming Feature(s)", true, aFeature);
} else if (SheetMetal_Bead.CompareType(aFeature)) {
myManager.AddFeature("Bead(s)", "Bead(s)", true, aFeature);
} else if (SheetMetal_Cutout.CompareType(aFeature)) {
myManager.AddFeature("Cutout(s)", "Cutout(s)", true, aFeature);
} else if (SheetMetal_Louver.CompareType(aFeature)) {
myManager.AddFeature("Louver(s)", "", true, aFeature);
} else if (SheetMetal_Bridge.CompareType(aFeature)) {
myManager.AddFeature("Bridge(s)", "Bridge(s)", true, aFeature);
} else if (SheetMetal_Hole.CompareType(aFeature)) {
SheetMetal_Hole aHole = SheetMetal_Hole.Cast(aFeature);
myManager.AddFeature(HoleName(aHole), "Hole(s)", true, aFeature);
} else if (SheetMetal_Bend.CompareType(aFeature)) {
SheetMetal_Bend aBend = SheetMetal_Bend.Cast(aFeature);
myManager.AddFeature(BendName(aBend), "Bend(s)", true, aFeature);
} else if (SheetMetal_Notch.CompareType(aFeature)) {
SheetMetal_Notch aNotch = SheetMetal_Notch.Cast(aFeature);
myManager.AddFeature(NotchName(aNotch), "Notch(es)", true, aFeature);
} else if (SheetMetal_Tab.CompareType(aFeature)) {
myManager.AddFeature("Tab(s)", "Tab(s)", true, aFeature);
} else if (SheetMetal_CompoundBend.CompareType(aFeature)) {
SheetMetal_CompoundBend aCompoundBend = SheetMetal_CompoundBend.Cast(aFeature);
GroupByParameters(aCompoundBend.FeatureList());
}
}
}
private static String HemTypeToString(SheetMetal_HemBendType theType) {
switch (theType) {
case SheetMetal_HBT_Flattened:
return "Flattened Hem Bend(s)";
case SheetMetal_HBT_Open:
return "Open Hem Bend(s)";
case SheetMetal_HBT_Teardrop:
return "Teardrop Hem Bend(s)";
case SheetMetal_HBT_Rope:
return "Rope Hem Bend(s)";
case SheetMetal_HBT_Rolled:
return "Rolled Hem Bend(s)";
default:
break;
}
return "Hem Bend(s)";
}
private static String BendName(SheetMetal_Bend theBend) {
if (SheetMetal_HemBend.CompareType(theBend)) {
SheetMetal_HemBend aHemBend = SheetMetal_HemBend.Cast(theBend);
return HemTypeToString(aHemBend.Type());
} else if (SheetMetal_CurvedBend.CompareType(theBend)) {
return "Curved Bend(s)";
}
return "Bend(s)";
}
private static String HoleName(SheetMetal_Hole theHole) {
if (SheetMetal_ComplexHole.CompareType(theHole)) {
return "Complex Hole(s)";
}
return "Hole(s)";
}
private static String NotchName(SheetMetal_Notch theNotch) {
if (SheetMetal_StraightNotch.CompareType(theNotch)) {
return "Straight Notch(es)";
} else if (SheetMetal_VNotch.CompareType(theNotch)) {
return "V Notch(es)";
}
return "Notch(es)";
}
private static double ToDegrees(double theAngleRad) {
return theAngleRad * 180 / Math.PI;
}
private static FeatureGroupManager myManager = new FeatureGroupManager();
}
}