using System;
using System.Collections.Generic;
namespace feature_group
{
class FeatureComparer : IComparer<MTKBase_Feature>
{
{
bool anALessThanB = aComparator.Apply(theA, theB);
if (anALessThanB)
{
return -1;
}
bool aBLessThanA = aComparator.Apply(theB, theA);
if (aBLessThanA)
{
return 1;
}
return 0;
}
}
public struct Pair
{
public Pair(double theFirst, double theSecond)
{
First = theFirst;
Second = theSecond;
}
public double First { get; }
public double Second { get; }
public override string ToString() => $"{First} x {Second}";
}
public struct Dimension
{
public Dimension(double theL, double theW, double theD)
{
L = theL;
W = theW;
D = theD;
}
public double L { get; }
public double W { get; }
public double D { get; }
public override string ToString() => $"{L} x {W} x {D}";
}
public struct Direction
{
public Direction(double theX, double theY, double theZ)
{
X = theX;
Y = theY;
Z = theZ;
}
public double X { get; }
public double Y { get; }
public double Z { get; }
public override string ToString() => $"({FormattedString(X)}, {FormattedString(Y)}, {FormattedString(Z)})";
private string FormattedString(double theValue)
{
System.Globalization.CultureInfo aCI = new System.Globalization.CultureInfo("en-US");
return string.Format(aCI, "{0:0.00}", theValue);
}
}
class FeatureGroupManager
{
public FeatureGroupManager()
{
myGroups = new List<FeatureGroup>();
}
private class FeatureGroup
{
public FeatureGroup(string theName, string theSubgroupName, bool theHasParameters)
{
myName = theName;
mySubgroupName = theSubgroupName;
myHasParameters = theHasParameters;
myFeatureSubgroups = new FeatureMapType(new FeatureComparer());
}
public uint FeatureCount()
{
uint aCount = 0;
foreach (var i in myFeatureSubgroups)
{
aCount += i.Value;
}
return aCount;
}
public string myName;
public string mySubgroupName;
public bool myHasParameters;
public FeatureMapType myFeatureSubgroups;
}
private class FeatureGroupComparer : IComparer<FeatureGroup>
{
public int Compare(FeatureGroup theA, FeatureGroup theB)
{
string anAName = theA.myName;
string aBName = theB.myName;
if (anAName == aBName)
{
return 0;
}
FeatureMapType anAFeatureSubgroups = theA.myFeatureSubgroups;
FeatureMapType aBFeatureSubgroups = theB.myFeatureSubgroups;
if (anAFeatureSubgroups.Count == 0 || aBFeatureSubgroups.Count == 0)
{
return anAName.CompareTo(aBName);
}
foreach (var i in anAFeatureSubgroups)
{
anAFeature = i.Key;
break;
}
foreach (var i in aBFeatureSubgroups)
{
aBFeature = i.Key;
break;
}
FeatureComparer aFeatureComparator = new FeatureComparer();
return aFeatureComparator.Compare(anAFeature, aBFeature);
}
}
private List<FeatureGroup> myGroups;
public void AddFeature(
string theGroupName,
string theSubgroupName,
bool theHasParameters,
MTKBase_Feature theFeature)
{
int aRes = myGroups.FindIndex(theGroup => theGroup.myName == theGroupName);
if (aRes == -1)
{
myGroups.Add(new FeatureGroup(theGroupName, theSubgroupName, theHasParameters));
aRes = myGroups.Count - 1;
}
FeatureGroup aGroup = myGroups[aRes];
FeatureMapType aSubgroups = aGroup.myFeatureSubgroups;
if (aSubgroups.ContainsKey(theFeature))
{
++aSubgroups[theFeature];
}
else
{
aSubgroups[theFeature] = 1;
}
}
public void Print(string theFeatureType, Action<MTKBase_Feature> thePrintFeatureParameters)
{
myGroups.Sort(new FeatureGroupComparer());
uint aTotalCount = 0;
foreach (var i in myGroups)
{
uint aFeatureCount = i.FeatureCount();
aTotalCount += aFeatureCount;
Console.WriteLine($" {i.myName}: {aFeatureCount}");
if (!i.myHasParameters)
{
continue;
}
string aSubgroupName = i.mySubgroupName;
foreach (var j in i.myFeatureSubgroups)
{
Console.WriteLine($" {j.Value} {aSubgroupName} with");
thePrintFeatureParameters(j.Key);
}
}
Console.WriteLine($"\n Total {theFeatureType}: {aTotalCount}\n");
}
public static void PrintFeatureParameter<T>(string theName, T theValue, string theUnits)
{
Console.WriteLine($" {theName}: {theValue} {theUnits}");
}
}
}
Provides possibility to compare MTK based features depending on their type and parameters.
Definition: MTKBase_FeatureComparator.hxx:29
Describes a base class of MTK based features.
Definition: MTKBase_Feature.hxx:34
Defines classes, types, and global functions related to CAD Exchanger.
Definition: A3DSTestLib.hxx:22
using System;
namespace shape_processor
{
{
{
if (aBRep != null)
{
for (uint i = 0; i < aBodyList.
Size(); ++i)
{
while (aShapeIt.HasNext())
{
var aShape = aShapeIt.
Next();
{
Console.Write($"Part #{myPartIndex} [\"{aPartName}\"] - solid #{i} has:\n");
}
{
Console.Write($"Part #{myPartIndex} [\"{aPartName}\"] - shell #{i} has:\n");
}
}
++myPartIndex;
}
}
}
private uint myPartIndex = 0;
}
{
{
if (aBRep != null)
{
for (uint i = 0; i < aBodyList.Size(); ++i)
{
while (aShapeIt.HasNext())
{
var aShape = aShapeIt.Next();
{
Console.Write ($"Part #{myPartIndex} [\"{aPartName}\"] - solid #{i} has:\n");
}
}
++myPartIndex;
}
}
}
private uint myPartIndex = 0;
}
}
Defines a Unicode (UTF-16) string wrapping a standard string.
Definition: Base_UTF16String.hxx:34
bool IsEmpty() const
Returns true if the string is empty.
Definition: Base_UTF16String.cxx:233
Base_UTF16String Name() const
Definition: ModelData_BaseObject.cxx:218
Defines a root topological shape that can be owned by B-Rep representation.
Definition: ModelData_Body.hxx:28
Defines a list of bodies.
Definition: ModelData_BodyList.hxx:31
const ModelData_Body & Element(SizeType theIndex) const
Definition: ModelData_BodyList.cxx:177
Provides CAD Exchanger data model.
Definition: ModelData_Model.hxx:43
Defines a leaf node in the scene graph hiearchy.
Definition: ModelData_Part.hxx:35
ModelData_BRepRepresentation BRepRepresentation() const
Definition: ModelData_Part.cxx:360
Iterates over subshapes in a shape.
Definition: ModelData_Shape.hxx:41
Base class of topological shapes.
Definition: ModelData_Shape.hxx:37
Defines a connected set of faces.
Definition: ModelData_Shell.hxx:31
Defines a topological solid.
Definition: ModelData_Solid.hxx:31
ModelData_ShapeType
Defines shape type.
Definition: ModelData_ShapeType.hxx:25
using feature_group;
using shape_processor;
using System;
using System.Collections.Generic;
namespace feature_recognizer
{
class Program
{
static int Main(string[] args)
{
cadex.helpers.LoadLibrarySearchDirectory.SetupDllDirectory();
string aKey = LicenseKey.Value();
string anMTKKey = MTKLicenseKey.Value();
if (!LicenseManager.Activate(aKey))
{
Console.WriteLine("Failed to activate CAD Exchanger license.");
return 1;
}
if (!LicenseManager.Activate(anMTKKey))
{
Console.WriteLine("Failed to activate Manufacturing Toolkit license.");
return 1;
}
if (args.Length != 2)
{
Console.WriteLine("Usage: " +
$"{System.Reflection.Assembly.GetExecutingAssembly().Location} <input_file> <operation>, where:");
Console.WriteLine($" <input_file> is a name of the file to be read");
Console.WriteLine($" <operation> is a name of desired machining operation");
Console.WriteLine($"");
PrintSupportedOperations();
return 1;
}
string aSource = args[0];
{
Console.WriteLine($"Failed to read the file {aSource}");
return 1;
}
Console.WriteLine($"Model: {aModel.Name()}\n");
string anOperationStr = args[1];
{
Console.WriteLine($"Unsupported operation - {anOperationStr}");
Console.WriteLine($"Please use one of the following.");
PrintSupportedOperations();
return 1;
}
var aPartProcessor = new PartProcessor(anOperation);
aModel.Accept(aVisitor);
return 0;
}
class PartProcessor : SolidProcessor
{
{
myOperation = theOperation;
}
{
aParam.SetOperation(myOperation);
var aFeatureList = aRecognizer.Perform(theSolid);
PrintFeatures(aFeatureList);
}
}
static void PrintSupportedOperations()
{
Console.WriteLine($"Supported operations:");
Console.WriteLine($" milling:\t CNC Machining Milling feature recognition");
Console.WriteLine($" turning:\t CNC Machining Lathe+Milling feature recognition");
}
{
var aProcessDictionary = new Dictionary<string, Machining_OperationType>()
{
};
bool aRes = aProcessDictionary.TryGetValue(theOperationStr, out aProcess);
if (aRes)
{
return aProcess;
}
}
{
FeatureGroupManager aManager = new FeatureGroupManager();
for (uint i = 0; i < theFeatureList.
Size(); ++i)
{
{
aManager.AddFeature(FaceTypeToString(aTurningFace.
Type()),
"Turning Face(s)",
true, aFeature);
}
{
aManager.AddFeature(FaceTypeToString(aFace.
Type()),
"",
false, aFeature);
}
{
aManager.AddFeature("Countersink(s)", "Countersink(s)", true, aFeature);
}
{
aManager.AddFeature(HoleTypeToString(aHole.
Type()),
"Hole(s)",
true, aFeature);
}
{
aManager.AddFeature("Pocket(s)", "Pocket(s)", true, aFeature);
}
{
aManager.AddFeature("Boss(es)", "Boss(es)", true, aFeature);
}
}
Action<MTKBase_Feature> PrintFeatureParameters = theFeature =>
{
{
FeatureGroupManager.PrintFeatureParameter(
"radius", aTurningFace.
Radius(),
"mm");
}
{
}
{
Direction aDir = new Direction(anAxis.X(), anAxis.Y(), anAxis.Z());
FeatureGroupManager.PrintFeatureParameter(
"radius", aCountersink.
Radius(),
"mm");
FeatureGroupManager.PrintFeatureParameter(
"depth", aCountersink.
Depth(),
"mm");
FeatureGroupManager.PrintFeatureParameter("axis", aDir, "");
}
{
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, "");
}
{
Direction aDir = new Direction(anAxis.X(), anAxis.Y(), anAxis.Z());
FeatureGroupManager.PrintFeatureParameter(
"length", aPocket.
Length(),
"mm");
FeatureGroupManager.PrintFeatureParameter(
"width", aPocket.
Width(),
"mm");
FeatureGroupManager.PrintFeatureParameter(
"depth", aPocket.
Depth(),
"mm");
FeatureGroupManager.PrintFeatureParameter("axis", aDir, "");
}
{
FeatureGroupManager.PrintFeatureParameter(
"length", aBoss.
Length(),
"mm");
FeatureGroupManager.PrintFeatureParameter(
"width", aBoss.
Width(),
"mm");
FeatureGroupManager.PrintFeatureParameter(
"height", aBoss.
Height(),
"mm");
}
};
aManager.Print("features", PrintFeatureParameters);
}
{
switch (theType) {
case Machining_FaceType.Machining_FT_ConvexProfileEdgeMilling:
return "Convex Profile Edge Milling Face(s)";
case Machining_FaceType.Machining_FT_ConcaveFilletEdgeMilling:
return "Concave Fillet Edge Milling Face(s)";
default:
break;
}
return "Face(s)";
}
{
switch (theType) {
default:
break;
}
return "Hole(s)";
}
}
}
Describes a boss. In CNC Machining a boss is a protrusion or raised area on a workpiece that is creat...
Definition: MTKBase_Boss.hxx:27
double Length() const
Definition: MTKBase_Boss.cxx:89
static bool CompareType(const MTKBase_Feature &theFeature)
Returnstrue if theFeature is a Boss.
Definition: MTKBase_Boss.cxx:126
double Width() const
Definition: MTKBase_Boss.cxx:69
double Height() const
Definition: MTKBase_Boss.cxx:109
Defines a list of features.
Definition: MTKBase_FeatureList.hxx:37
size_t Size() const
Returns the number of elements in the list.
Definition: MTKBase_FeatureList.cxx:87
const MTKBase_Feature & Feature(size_t theIndex) const
Access specified element.
Definition: MTKBase_FeatureList.cxx:68
const ModelData_Axis3Placement & Axis() const
Definition: MTKBase_Hole.cxx:127
double Depth() const
Definition: MTKBase_Hole.cxx:98
double Radius() const
Definition: MTKBase_Hole.cxx:78
Describes a machining countersink.
Definition: Machining_Countersink.hxx:33
double Radius() const
Definition: Machining_Countersink.cxx:83
static bool CompareType(const MTKBase_Feature &theFeature)
Returns true if theFeature is a machining countersink.
Definition: Machining_Countersink.cxx:147
const ModelData_Axis3Placement & Axis() const
Definition: Machining_Countersink.cxx:132
double Depth() const
Definition: Machining_Countersink.cxx:103
Describes a face produced by a specified machining operation.
Definition: Machining_Face.hxx:38
static bool CompareType(const MTKBase_Feature &theFeature)
Returnstrue if theFeature is a machining face.
Definition: Machining_Face.cxx:231
Machining_FaceType Type() const
Definition: Machining_Face.cxx:216
Provides an interface to recognizing machining features tool.
Definition: Machining_FeatureRecognizer.hxx:43
Defines parameters used by Machining_FeatureRecognizer.
Definition: Machining_FeatureRecognizerParameters.hxx:39
Describes a machining hole of a specified type. Hole is a cylindrical feature that can be made by cut...
Definition: Machining_Hole.hxx:32
Machining_HoleType Type() const
Definition: Machining_Hole.cxx:142
static bool CompareType(const MTKBase_Feature &theFeature)
Returnstrue if theFeature is a machining hole.
Definition: Machining_Hole.cxx:157
Describes a machining pocket. A pocket is a feature obtained by milling the material inside an arbitr...
Definition: Machining_Pocket.hxx:32
double Width() const
Definition: Machining_Pocket.cxx:69
double Depth() const
Definition: Machining_Pocket.cxx:109
const ModelData_Axis1Placement & Axis() const
Definition: Machining_Pocket.cxx:138
static bool CompareType(const MTKBase_Feature &theFeature)
Returnstrue if theFeature is a machining Pocket.
Definition: Machining_Pocket.cxx:153
double Length() const
Definition: Machining_Pocket.cxx:89
Describes a face with radius produced by a specified machining operation. Cutting material from workp...
Definition: Machining_TurningFace.hxx:31
static bool CompareType(const MTKBase_Feature &theFeature)
Returns true if theFeature is a machining turning face.
Definition: Machining_TurningFace.cxx:87
double Radius() const
Definition: Machining_TurningFace.cxx:70
const ModelData_Direction & Direction() const
Returns a direction value.
Definition: ModelData_Axis1Placement.cxx:75
const ModelData_Direction & Axis() const
Returns a Z-direction of the axis placement.
Definition: ModelData_Axis3Placement.cxx:90
Defines a 3D direction.
Definition: ModelData_Direction.hxx:180
Reads any format that CAD Exchanger can import.
Definition: ModelData_ModelReader.hxx:33
Defines a visitor that visits each unique element only once.
Definition: ModelData_SceneGraphElementUniqueVisitor.hxx:33
Machining_OperationType
Defines an operation type in machining.
Definition: Machining_OperationType.hxx:29
Machining_HoleType
Defines a hole type in machining.
Definition: Machining_HoleType.hxx:29
Machining_FaceType
Describes a face produced by a specified machining operation.
Definition: Machining_FaceType.hxx:29