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))