Demonstrates how to perform recognition of machining features on a 3D model and print information about found features and their parameters in a console.
Overview
In this example demonstrates how to perform recognition of machining features on a 3D model using machining feature recognition tool (Machining_FeatureRecognizer). For this purpose, used a console application that imports a model, traverses through unique ModelData::Part , creates and runs Machining_FeatureRecognizer, groups and prints information about found features and their parameters into console. Machining feature recognition will be performed for each unique ModelData::Part , but only for the scope of accepted geometries.
Application needs 2 input arguments to run:
Usage: machining_feature_recognizer <input_file> <operation>, where:
<input_file> is a name of the file to be read
<operation> is a name of desired machining operation
Supported operations:
milling: CNC Machining Milling feature recognition
turning: CNC Machining Lathe+Milling feature recognition
For more information about feature recognition visit CNC Machining page.
Implementation
PartProcessor
class is inherited from SolidProcessor
and overrides ProcessSolid
method that are used to run Machining_FeatureRecognizer on given shape. The Machining_FeatureRecognizerParameters.SetOperation() method of the tool parameters is used to set the type of operation (Milling or LatheMilling). The operation type will be taking into account during recognition process and the recognition result will be different depending on it. Then PrintFeatures
method is used to print information about found features and their parameters in a console.
Visit Model Explore Helper Implementation page for more information about base SolidProcessor
class implementation.
class PartProcessor : public SolidProcessor
{
public:
PartProcessor (Machining_OperationType theOperation) : myOperation (theOperation)
{}
void ProcessSolid (const ModelData::Solid& theSolid) override
{
Machining_FeatureRecognizer aRecognizer;
aRecognizer.Parameters().SetOperation (myOperation);
auto aFeatureList = aRecognizer.Perform (theSolid);
PrintFeatures (aFeatureList);
}
private:
Machining_OperationType myOperation = Machining_OT_Undefined;
};
To traverse only unique parts of the imported model, the ModelData::ModelElementUniqueVisitor class is used.
PartProcessor aPartProcessor;
ModelData::ModelElementUniqueVisitor aVisitor (aPartProcessor);
aModel.Accept (aVisitor);
After performing feature recognition, the object of FeatureGroupManager
class is used to group and sort found machining features. For this purpose, there is a traverse through all found features and add each of them to FeatureGroupManager
with a specified name.
for (size_t i = 0; i < theFeatureList.Size(); i++) {
const auto& aFeature = theFeatureList[i];
if (aFeature.IsOfType<Machining_TurningFace>()) {
const auto& aTurningFace = static_cast<const Machining_TurningFace&> (aFeature);
aManager.AddFeature (FaceTypeToString (aTurningFace.Type()), "Turning Face(s)", true, aFeature);
} else if (aFeature.IsOfType<Machining_Face>()) {
const auto& aFace = static_cast<const Machining_Face&> (aFeature);
aManager.AddFeature (FaceTypeToString (aFace.Type()), "", false, aFeature);
} else if (aFeature.IsOfType<Machining_Countersink>()) {
aManager.AddFeature ("Countersink(s)", "Countersink(s)", true, aFeature);
} else if (aFeature.IsOfType<Machining_ThreadedHole>()) {
const auto& aThreadedHole = static_cast<const Machining_ThreadedHole&> (aFeature);
aManager.AddFeature ("Threaded " + HoleTypeToString (aThreadedHole.Type()), "Threaded Hole(s)", true, aFeature);
} else if (aFeature.IsOfType<Machining_Hole>()) {
const auto& aHole = static_cast<const Machining_Hole&> (aFeature);
aManager.AddFeature (HoleTypeToString (aHole.Type()), "Hole(s)", true, aFeature);
} else if (aFeature.IsOfType<Machining_Pocket>()) {
aManager.AddFeature ("Pocket(s)", "Pocket(s)", true, aFeature);
} else if (aFeature.IsOfType<MTKBase_Boss>()) {
aManager.AddFeature ("Boss(es)", "Boss(s)", true, aFeature);
} else if (aFeature.IsOfType<Machining_TurningGroove>()) {
const auto& aTurningGroove = static_cast<const Machining_TurningGroove&> (aFeature);
aManager.AddFeature (TurningGrooveTypeToString (aTurningGroove.Type()), "Turning Groove(s)", true, aFeature);
}
}
After adding all found features to FeatureGroupManager
, a Print
method of the manager is used to print information about found features and their parameters in a console. PrintFeatureParameters
is created to explore and print feature parameters. It uses as an input parameter of Print
method.
auto PrintFeatureParameters = [] (const MTKBase_Feature& theFeature)
{
if (theFeature.IsOfType<Machining_TurningFace>()) {
const auto& aTurningFace = static_cast<const Machining_TurningFace&> (theFeature);
FeatureGroupManager::PrintFeatureParameter ("radius", aTurningFace.Radius(), "mm");
} else if (theFeature.IsOfType<Machining_Face>()) {
} else if (theFeature.IsOfType<Machining_Countersink>()) {
const auto& aCountersink = static_cast<const Machining_Countersink&> (theFeature);
FeatureGroupManager::PrintFeatureParameter ("radius", aCountersink.Radius(), "mm");
FeatureGroupManager::PrintFeatureParameter ("depth", aCountersink.Depth(), "mm");
FeatureGroupManager::PrintFeatureParameter ("axis", aCountersink.Axis().Axis(), "");
} else if (theFeature.IsOfType<Machining_ThreadedHole>()) {
const auto& aThreadedHole = static_cast<const Machining_ThreadedHole&> (theFeature);
FeatureGroupManager::PrintFeatureParameter ("minor radius", aThreadedHole.MinorRadius(), "mm");
FeatureGroupManager::PrintFeatureParameter ("major radius", aThreadedHole.MajorRadius(), "mm");
FeatureGroupManager::PrintFeatureParameter ("thread length", aThreadedHole.ThreadLength(), "mm");
FeatureGroupManager::PrintFeatureParameter ("pitch", aThreadedHole.Pitch(), "mm");
FeatureGroupManager::PrintFeatureParameter ("depth", aThreadedHole.Depth(), "mm");
FeatureGroupManager::PrintFeatureParameter ("axis", aThreadedHole.Axis().Axis(), "");
} else if (theFeature.IsOfType<Machining_Hole>()) {
const auto& aHole = static_cast<const Machining_Hole&> (theFeature);
FeatureGroupManager::PrintFeatureParameter ("radius", aHole.Radius(), "mm");
FeatureGroupManager::PrintFeatureParameter ("depth", aHole.Depth(), "mm");
FeatureGroupManager::PrintFeatureParameter ("axis", aHole.Axis().Axis(), "");
} else if (theFeature.IsOfType<Machining_Pocket>()) {
const auto& aPocket = static_cast<const Machining_Pocket&> (theFeature);
FeatureGroupManager::PrintFeatureParameter ("length", aPocket.Length(), "mm");
FeatureGroupManager::PrintFeatureParameter ("width", aPocket.Width(), "mm");
FeatureGroupManager::PrintFeatureParameter ("depth", aPocket.Depth(), "mm");
FeatureGroupManager::PrintFeatureParameter ("axis", aPocket.Axis().Direction(), "");
} else if (theFeature.IsOfType<MTKBase_Boss>()) {
const auto& aBoss = static_cast<const MTKBase_Boss&> (theFeature);
FeatureGroupManager::PrintFeatureParameter ("length", aBoss.Length(), "mm");
FeatureGroupManager::PrintFeatureParameter ("width", aBoss.Width(), "mm");
FeatureGroupManager::PrintFeatureParameter ("height", aBoss.Height(), "mm");
} else if (theFeature.IsOfType<Machining_TurningGroove>()) {
const auto& aTurningGroove = static_cast<const Machining_TurningGroove&> (theFeature);
FeatureGroupManager::PrintFeatureParameter ("radius", aTurningGroove.Radius(), "mm");
FeatureGroupManager::PrintFeatureParameter ("depth", aTurningGroove.Depth(), "mm");
FeatureGroupManager::PrintFeatureParameter ("width", aTurningGroove.Width(), "");
}
};
aManager.Print ("features", PrintFeatureParameters);
Visit Feature Group Helper Implementation page for more information about FeatureGroupManager
class implementation.
Example output
Below is the example output for model from ./examples/models/Fresamento_CAM1_v3.stp
and operation set to Milling
.
The model | Example output |
| Model: Fresamento_CAM1_v3.stp
Part #0 ["Fresamento_CAM1"] - solid #0 has:
Concave Fillet Edge Milling Face(s): 14
14 Turning Face(s) with
radius: 5 mm
Convex Profile Edge Milling Face(s): 7
4 Turning Face(s) with
radius: 10 mm
3 Turning Face(s) with
radius: 15 mm
Curved Milled Face(s): 5
Flat Face Milled Face(s): 3
Flat Side Milled Face(s): 3
Countersink(s): 4
4 Countersink(s) with
radius: 7.5 mm
depth: 4.57781 mm
axis: (0.00, 1.00, 0.00)
Through Hole(s): 1
1 Hole(s) with
radius: 12.5 mm
depth: 25 mm
axis: (0.00, -1.00, 0.00)
Flat Bottom Hole(s): 3
3 Hole(s) with
radius: 7.5 mm
depth: 8 mm
axis: (0.00, -1.00, 0.00)
Blind Hole(s): 7
4 Hole(s) with
radius: 4.263 mm
depth: 31.3245 mm
axis: (0.00, -1.00, 0.00)
3 Hole(s) with
radius: 5 mm
depth: 25.0043 mm
axis: (0.00, -1.00, 0.00)
Pocket(s): 4
1 Pocket(s) with
length: 61.7043 mm
width: 49.2432 mm
depth: 20.132 mm
axis: (0.00, 1.00, 0.00)
1 Pocket(s) with
length: 100 mm
width: 65.3716 mm
depth: 21.2428 mm
axis: (0.00, 1.00, 0.00)
1 Pocket(s) with
length: 133.792 mm
width: 106.223 mm
depth: 25.7205 mm
axis: (0.00, 1.00, 0.00)
1 Pocket(s) with
length: 145.925 mm
width: 98.3509 mm
depth: 10.5556 mm
axis: (0.00, 1.00, 0.00)
Total features: 51
|
Another example below is an output for model from ./examples/models/senthi.step
and operation set to Lathe+Milling
.
The model | Example output |
| Model: senthi.step
Part #0 ["drawing no 1"] - solid #0 has:
Bore Face(s): 2
1 Turning Face(s) with
radius: 62.5 mm
1 Turning Face(s) with
radius: 65 mm
Turn Diameter Face(s): 7
1 Turning Face(s) with
radius: 50 mm
1 Turning Face(s) with
radius: 75 mm
1 Turning Face(s) with
radius: 80 mm
1 Turning Face(s) with
radius: 86 mm
1 Turning Face(s) with
radius: 90 mm
1 Turning Face(s) with
radius: 96.4288 mm
1 Turning Face(s) with
radius: 155 mm
Turn Face Face(s): 7
1 Turning Face(s) with
radius: 62.5 mm
1 Turning Face(s) with
radius: 70 mm
1 Turning Face(s) with
radius: 80 mm
1 Turning Face(s) with
radius: 82 mm
1 Turning Face(s) with
radius: 90 mm
2 Turning Face(s) with
radius: 155 mm
Turn Form Face(s): 3
1 Turning Face(s) with
radius: 55.3169 mm
1 Turning Face(s) with
radius: 72.5 mm
1 Turning Face(s) with
radius: 82.5 mm
Total features: 19
|
Files