CNC DFM: undercut recognition in MTK
Learn why undercuts make it difficult to manufacture a part via CNC milling, and how to detect them with MTK
We have just released a new DFM check - undercut recognition — in the MTK release 2025.7. This post provides more details on this new product feature.
Undercuts are regions a tool cannot reach from a chosen approach direction (e.g., Z+ on a 3-axis mill). Catching them early prevents impossible quotes, broken tools, and back-and-forth with customers. This post explains how MTK detects undercuts on solid B-Rep models, what you get in the API, and how to wire it into your DFM and pricing pipeline.

Problem (why this is hard)
Most CAD files aren’t authored for manufacturability checks. Local blends hide access issues, trims are imperfect, and the same part can be machinable or not depending on fixture and approach. Manual visual checks don’t scale when you’re quoting batches.
Inputs and assumptions
- Geometry: solid B-Rep only (i.e. faces, edges, vertices). Mesh-based analysis is not included in this release.
- Formats: B-Rep formats (STEP, Parasolid, Solidworks and other formats with B-Rep inside).
How it works (high-level)
- Undercut recognition works on a set of recognized pockets. So pocket recognition (as part of a broader CNC feature recognition) is a prerequisite to the algorithm.
- Each pocket is processed independently and its axis is used to identfy those inaccessible regions that constiture the undercut.

Output (what you get back)
Each detected undercut returns an associated pocket (that was initially recognized and was used a ‘context’ for undercut detection) and a list of B-Rep faces that form it. Those faces are a subset of pocket faces.
When using persistent representation (.mtkweb) faces are represented via a face ID’s list.
JSON (illustrative)
"dfm": {
"name": "Design for Manufacturing",
"totalFeatureCount" : "1",
"featureGroups": [
{
"name": "Undercut Issue(s)",
"color": "(200, 105, 49)",
"totalGroupFeatureCount": "1",
"features": [
{
"shapeIDCount": "3",
"shapeIDs": [
{ "id": "150" },
{ "id": "144" },
{ "id": "280" }
]
}
]
}
]
}
Performance
Performance costs to detect undercuts are really Incremental. The major price is paid during the pocket recognition.
API Quickstart
Refer to a general DFM analyzer example in the documentation
C++ (illustrative)
void ProcessSolid (const ModelData::Solid& theSolid) override
{
// Find features
Machining_Data aData;
Machining_FeatureRecognizer aRecognizer;
aRecognizer.Parameters().SetOperation (myOperation);
aRecognizer.Perform (theSolid, aData);
...
// Run milling analyzer for found features
DFMMachining_MillingAnalyzerParameters aMillingParameters;
DFMMachining_Analyzer aMillingAnalyzer (aMillingParameters);
MTKBase_FeatureList aMillingIssueList = aMillingAnalyzer.Perform (theSolid, aData);
CombineFeatureLists (anIssueList, aMillingIssueList);
...
}
void PrintIssues (const MTKBase_FeatureList& theIssueList)
{
FeatureGroupManager aManager;
//group by parameters to provide more compact information about issues
for (size_t i = 0; i < theIssueList.Size(); ++i) {
const auto& anIssue = theIssueList[i];
if (anIssue.IsOfType<DFMMachining_SmallDiameterHoleIssue>()) {
...
} else if (anIssue.IsOfType<DFMMachining_UndercutIssue>()) {
aManager.AddFeature ("Undercut Issue(s)", "", false, anIssue);
}
...
}
...
}
Python (illustrative)
def ProcessSolid(self, theSolid: mtk.ModelData_Solid):
# Find features
aData = mtk.Machining_Data()
aRecognizer = mtk.Machining_FeatureRecognizer()
aRecognizer.Parameters().SetOperation(self.myOperation)
aRecognizer.Perform (theSolid, aData)
# Run milling analyzer for found features
aMillingParameters = mtk.DFMMachining_MillingAnalyzerParameters()
aMillingAnalyzer = mtk.DFMMachining_Analyzer(aMillingParameters)
aMillingIssueList = aMillingAnalyzer.Perform(theSolid, aData)
# Combine issue lists
self.CombineFeatureLists(anIssueList, aMillingIssueList)
...
PrintIssues(anIssueList)
def PrintIssues(theIssueList: mtk.MTKBase_FeatureList):
aManager = feature_group.FeatureGroupManager()
#group by parameters to provide more compact information about features
for anIssue in theIssueList:
if mtk.DFMMachining_SmallDiameterHoleIssue.CompareType(anIssue):
aManager.AddFeature("Small Diameter Hole Issue(s)", "Hole(s)", True, anIssue)
elif mtk.DFMMachining_UndercutIssue.CompareType(anIssue):
aManager.AddFeature("Undercut Issue(s)", "", False, anIssue)
...
aManager.Print ("issues", PrintFeatureParameters)

How detecting undercuts helps you
- Faster “no-go” decisions for CNC milling.
- Fewer surprises after CAM starts.
- Clear, visual explanations for customers on why reorientation or redesign is needed.
Limitations
- Solid B-Rep only; no mesh analysis.
- Undercuts are detected in the context of pockets. So complex pockets may fail to be recognized (where the pocket itself is ambigous or consists of multiple ‘islands’)
Conclusion
Undercuts are a classic “looks fine in CAD, fails in the shop” problem. MTK’s undercut recognition turns that into a clear, early signal — directly on your solid B-Rep — so quotes and DFM reviews stay grounded in manufacturable reality.
Next steps
Check out documentation. Submit evaluation requst. Or just drop me a direct email. We’ll be happy to discuss your project to see how MTK could help you.