add bbox check to getClearedArea to filter out irrelevant gcode
This commit is contained in:
@@ -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> Area::getClearedArea(const Toolpath *path, double diameter, double zmax) {
|
||||
std::shared_ptr<Area> 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> 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<Area> clearedArea = make_shared<Area>(¶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 {
|
||||
|
||||
@@ -242,7 +242,7 @@ public:
|
||||
const std::vector<double>& heights = std::vector<double>(),
|
||||
const TopoDS_Shape& plane = TopoDS_Shape());
|
||||
|
||||
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);
|
||||
std::shared_ptr<Area> getRestArea(std::vector<std::shared_ptr<Area>> clearedAreas, double diameter);
|
||||
TopoDS_Shape toTopoShape();
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#include <Base/GeometryPyCXX.h>
|
||||
#include <Base/PyWrapParseTupleAndKeywords.h>
|
||||
#include <Mod/Part/App/OCCError.h>
|
||||
#include <Mod/Part/App/TopoShapePy.h>
|
||||
@@ -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<PathPy*>(pyPath);
|
||||
std::shared_ptr<Area> clearedArea = getAreaPtr()->getClearedArea(path->getToolpathPtr(), diameter, zmax);
|
||||
const Py::BoundingBox bbox(pyBbox, false);
|
||||
std::shared_ptr<Area> 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
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user