Refer to the Molding 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;
}
Contains classes, namespaces, enums, types, and global functions related to Manufacturing Toolkit.
Definition LicenseManager_LicenseError.hxx:30
 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().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();
                    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
 feature_recognizer.java 
 
 
import java.util.HashMap;
import java.util.function.Consumer;
 
public class feature_recognizer {
    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();
 
        
        if (!LicenseManager.Activate(aKey)) {
            System.out.println("Failed to activate Manufacturing Toolkit license.");
            System.exit(1);
        }
 
        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 aSource = args[0];
 
        Model aModel = new Model();
        ModelReader aReader = new ModelReader();
 
        
        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");
 
        PartProcessor aPartProcessor = new PartProcessor();
        ModelElementUniqueVisitor aVisitor = new ModelElementUniqueVisitor(aPartProcessor);
        aModel.Accept(aVisitor);
    }
 
    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);
            MTKBase_FeatureList aFeatureList = aRecognizer.Perform(theSolid);
            Report.PrintFeatures(aFeatureList);
        }
    }
 
    static class Report {
        public static void PrintFeatures(MTKBase_FeatureList theFeatureList) {
            FeatureGroupManager aManager = new FeatureGroupManager();
 
            
            for (long i = 0; i < theFeatureList.Size(); ++i) {
                MTKBase_Feature aFeature = theFeatureList.Feature(i);
                if (Molding_ScrewBoss.CompareType(aFeature)) {
                    Molding_ScrewBoss aScrewBoss = Molding_ScrewBoss.Cast(aFeature);
                    aManager.AddFeature("Boss(es)", "Screw Boss(es)", true, aScrewBoss);
                } else if (MTKBase_Boss.CompareType(aFeature)) {
                    MTKBase_Boss aBoss = MTKBase_Boss.Cast(aFeature);
                    aManager.AddFeature("Boss(es)", "Boss(es)", true, aBoss);
                } else if (Molding_Rib.CompareType(aFeature)) {
                    Molding_Rib aRib = Molding_Rib.Cast(aFeature);
                    aManager.AddFeature("Rib(s)", "Rib(s)", true, aRib);
                }
            }
 
            Consumer<MTKBase_Feature> PrintFeatureParameters = (theFeature) ->
            {
                if (Molding_ScrewBoss.CompareType(theFeature)) {
                    Molding_ScrewBoss aScrewBoss = Molding_ScrewBoss.Cast(theFeature);
                    FeatureGroupManager.PrintFeatureParameter("outer radius", aScrewBoss.OuterRadius(), "mm");
                    FeatureGroupManager.PrintFeatureParameter("inner radius", aScrewBoss.InnerRadius(), "mm");
                    FeatureGroupManager.PrintFeatureParameter("draft angle", ToDegrees(aScrewBoss.DraftAngle()), "deg");
                } else if (MTKBase_Boss.CompareType(theFeature)) {
                    MTKBase_Boss aBoss = MTKBase_Boss.Cast(theFeature);
                    FeatureGroupManager.PrintFeatureParameter("length", aBoss.Length(), "mm");
                    FeatureGroupManager.PrintFeatureParameter("height", aBoss.Height(), "mm");
                    FeatureGroupManager.PrintFeatureParameter("width", aBoss.Width(), "mm");
                } else if (Molding_Rib.CompareType(theFeature)) {
                    Molding_Rib aRib = Molding_Rib.Cast(theFeature);
                    FeatureGroupManager.PrintFeatureParameter("length", aRib.Length(), "mm");
                    FeatureGroupManager.PrintFeatureParameter("height", aRib.Height(), "mm");
                    FeatureGroupManager.PrintFeatureParameter("thickness", aRib.Thickness(), "mm");
                    FeatureGroupManager.PrintFeatureParameter("draft angle", ToDegrees(aRib.DraftAngle()), "deg");
                }
            };
            aManager.Print("features", PrintFeatureParameters);
        }
 
        static double ToDegrees(double theAngleRad) {
            return theAngleRad * 180 / Math.PI;
        }
    }
}