From 4cb991cf476a2eb4e4b171e8f63b56b791aeb3c4 Mon Sep 17 00:00:00 2001 From: David Kaufman Date: Mon, 8 Jan 2024 14:33:19 -0500 Subject: [PATCH] add bbox check to getClearedArea to filter out irrelevant gcode --- src/Mod/Path/App/Area.cpp | 47 ++++++++++++++++------------------ src/Mod/Path/App/Area.h | 2 +- src/Mod/Path/App/AreaPyImp.cpp | 16 ++++++++---- src/Mod/Path/Path/Op/Area.py | 5 ++-- 4 files changed, 37 insertions(+), 33 deletions(-) diff --git a/src/Mod/Path/App/Area.cpp b/src/Mod/Path/App/Area.cpp index 30d680ff12..7c9ed4ce00 100644 --- a/src/Mod/Path/App/Area.cpp +++ b/src/Mod/Path/App/Area.cpp @@ -503,24 +503,26 @@ private: CArea pathSegments; double maxZ; double radius; + Base::BoundBox3d bbox; void line(const Base::Vector3d &last, const Base::Vector3d &next) { if (last.z <= maxZ && next.z <= maxZ) { - CCurve curve; - curve.append(CVertex{{last.x, last.y}}); - curve.append(CVertex{{next.x, next.y}}); - pathSegments.append(curve); - count++; - } else { - // printf("SKIP!"); + Base::BoundBox2d segBox = {}; + segBox.Add({last.x, last.y}); + segBox.Add({next.x, next.y}); + if (bbox.Intersect(segBox)) { + CCurve curve; + curve.append(CVertex{{last.x, last.y}}); + curve.append(CVertex{{next.x, next.y}}); + pathSegments.append(curve); + } } } public: - int count = 0; - - ClearedAreaSegmentVisitor(double maxZ, double radius) : maxZ(maxZ), radius(radius) + ClearedAreaSegmentVisitor(double maxZ, double radius, Base::BoundBox3d bbox) : maxZ(maxZ), radius(radius), bbox(bbox) { + bbox.Enlarge(radius); } CArea getClearedArea() @@ -581,7 +583,6 @@ public: curve.append(CVertex{{last.x, last.y}}); curve.append(CVertex{ccw ? 1 : -1, {next.x, next.y}, {center.x, center.y}}); pathSegments.append(curve); - count++; // Base::Vector3d prev = last; // for (Base::Vector3d p : pts) { // line(prev, p); @@ -597,10 +598,10 @@ public: (void)id; (void)q; // always within the bounds of p printf("g8x UNHANDLED\n"); - // processPt(last); - // processPts(pts); - // processPts(p); - // processPt(next); + processPt(last); + processPts(pts); + processPts(p); + processPt(next); (void)last; (void)pts; (void)p; @@ -608,10 +609,8 @@ public: } void g38(int id, const Base::Vector3d &last, const Base::Vector3d &next) override { + // probe operation; clears nothing (void)id; - printf("g38 UNHANDLED\n"); - // processPt(last); - // processPt(next); (void)last; (void)next; } @@ -628,7 +627,7 @@ private: } }; -std::shared_ptr Area::getClearedArea(const Toolpath *path, double diameter, double zmax) { +std::shared_ptr Area::getClearedArea(const Toolpath *path, double diameter, double zmax, Base::BoundBox3d bbox) { build(); // Precision losses in arc/segment conversions (multiples of Accuracy): @@ -658,20 +657,18 @@ std::shared_ptr Area::getClearedArea(const Toolpath *path, double diameter printf("\n"); printf("GCode walker:\n"); - ClearedAreaSegmentVisitor visitor(zmax, diameter/2 + buffer); + ClearedAreaSegmentVisitor visitor(zmax, diameter/2 + buffer, bbox); PathSegmentWalker walker(*path); walker.walk(visitor, Base::Vector3d(0, 0, zmax + 1)); - printf("Count: %d\n", visitor.count); printf("\n"); printf("\n"); std::shared_ptr clearedArea = make_shared(¶ms); - //clearedArea->myTrsf = myTrsf; clearedArea->myTrsf = {}; - if (visitor.count > 0) { - //gp_Trsf trsf(myTrsf.Inverted()); - TopoDS_Shape clearedAreaShape = Area::toShape(visitor.getClearedArea(), false/*, &trsf*/); + const CArea ca = visitor.getClearedArea(); + if (ca.m_curves.size() > 0) { + TopoDS_Shape clearedAreaShape = Area::toShape(ca, false); clearedArea->add(clearedAreaShape, OperationCompound); clearedArea->build(); } else { diff --git a/src/Mod/Path/App/Area.h b/src/Mod/Path/App/Area.h index 8056f4a3da..e79a62577d 100644 --- a/src/Mod/Path/App/Area.h +++ b/src/Mod/Path/App/Area.h @@ -242,7 +242,7 @@ public: const std::vector& heights = std::vector(), const TopoDS_Shape& plane = TopoDS_Shape()); - std::shared_ptr getClearedArea(const Toolpath *path, double diameter, double zmax); + std::shared_ptr getClearedArea(const Toolpath *path, double diameter, double zmax, Base::BoundBox3d bbox); std::shared_ptr getRestArea(std::vector> clearedAreas, double diameter); TopoDS_Shape toTopoShape(); diff --git a/src/Mod/Path/App/AreaPyImp.cpp b/src/Mod/Path/App/AreaPyImp.cpp index a0a85b930b..bbe4182c23 100644 --- a/src/Mod/Path/App/AreaPyImp.cpp +++ b/src/Mod/Path/App/AreaPyImp.cpp @@ -22,6 +22,7 @@ #include "PreCompiled.h" +#include #include #include #include @@ -150,8 +151,8 @@ static const PyMethodDef areaOverrides[] = { }, { "getClearedArea",nullptr,0, - "getClearedArea(path, diameter, zmax):\n" - "Gets the area cleared when a tool of the specified diameter follows the gcode represented in the path, ignoring cleared space above zmax.\n", + "getClearedArea(path, diameter, zmax, bbox):\n" + "Gets the area cleared when a tool of the specified diameter follows the gcode represented in the path, ignoring cleared space above zmax and path segments that don't affect space within bbox.\n", }, { "getRestArea",nullptr,0, @@ -407,16 +408,21 @@ PyObject* AreaPy::makeSections(PyObject *args, PyObject *keywds) PyObject* AreaPy::getClearedArea(PyObject *args) { PY_TRY { - PyObject *pyPath; + PyObject *pyPath, *pyBbox; double diameter, zmax; - if (!PyArg_ParseTuple(args, "Odd", &pyPath, &diameter, &zmax)) + if (!PyArg_ParseTuple(args, "OddO", &pyPath, &diameter, &zmax, &pyBbox)) return nullptr; if (!PyObject_TypeCheck(pyPath, &(PathPy::Type))) { PyErr_SetString(PyExc_TypeError, "path must be of type PathPy"); return nullptr; } + if (!PyObject_TypeCheck(pyBbox, &(Base::BoundBoxPy::Type))) { + PyErr_SetString(PyExc_TypeError, "bbox must be of type BoundBoxPy"); + return nullptr; + } const PathPy *path = static_cast(pyPath); - std::shared_ptr clearedArea = getAreaPtr()->getClearedArea(path->getToolpathPtr(), diameter, zmax); + const Py::BoundingBox bbox(pyBbox, false); + std::shared_ptr clearedArea = getAreaPtr()->getClearedArea(path->getToolpathPtr(), diameter, zmax, bbox.getValue()); auto pyClearedArea = Py::asObject(new AreaPy(new Area(*clearedArea, true))); return Py::new_reference_to(pyClearedArea); } PY_CATCH_OCC diff --git a/src/Mod/Path/Path/Op/Area.py b/src/Mod/Path/Path/Op/Area.py index 5f9e3a759f..e88440f55f 100644 --- a/src/Mod/Path/Path/Op/Area.py +++ b/src/Mod/Path/Path/Op/Area.py @@ -242,7 +242,8 @@ class ObjectOp(PathOp.ObjectOp): if hasattr(obj, "UseRestMachining") and obj.UseRestMachining: restSections = [] for section in sections: - z = section.getShape().BoundBox.ZMin + bbox = section.getShape().BoundBox + z = bbox.ZMin sectionClearedAreas = [] for op in self.job.Operations.Group: print(op.Name) @@ -252,7 +253,7 @@ class ObjectOp(PathOp.ObjectOp): if hasattr(op, "Active") and op.Active and op.Path: tool = op.Proxy.tool if hasattr(op.Proxy, "tool") else op.ToolController.Proxy.getTool(op.ToolController) diameter = tool.Diameter.getValueAs("mm") - sectionClearedAreas.append(area.getClearedArea(op.Path, diameter, z+0.001)) + sectionClearedAreas.append(section.getClearedArea(op.Path, diameter, z+0.001, bbox)) # debugZ = -1.5 # if debugZ -.1 < z and z < debugZ + .1: # debugObj = obj.Document.addObject("Part::Feature", "Debug_{}_{}".format(debugZ, op.Name))