From f3789ebfade831cb2e60346a6a13e3086efaa706 Mon Sep 17 00:00:00 2001 From: Daniel Wood Date: Wed, 29 Apr 2020 19:32:25 +0100 Subject: [PATCH 01/15] Handle Legacy and Toolbits in simulation fixes #4326 pass the tool or toolbit shape into the simulation --- src/Mod/Path/PathScripts/PathSimulatorGui.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathSimulatorGui.py b/src/Mod/Path/PathScripts/PathSimulatorGui.py index 428dcc394c..a6a7d2770f 100644 --- a/src/Mod/Path/PathScripts/PathSimulatorGui.py +++ b/src/Mod/Path/PathScripts/PathSimulatorGui.py @@ -125,13 +125,17 @@ class PathSimulation: except Exception: self.tool = None - # if hasattr(self.operation, "ToolController"): - # self.tool = self.operation.ToolController.Tool if (self.tool is not None): - toolProf = self.CreateToolProfile(self.tool, Vector(0, 1, 0), Vector(0, 0, 0), float(self.tool.Diameter) / 2.0) - self.cutTool.Shape = Part.makeSolid(toolProf.revolve(Vector(0, 0, 0), Vector(0, 0, 1))) + if isinstance(self.tool, Path.Tool): + # handle legacy tools + toolProf = self.CreateToolProfile(self.tool, Vector(0, 1, 0), Vector(0, 0, 0), float(self.tool.Diameter) / 2.0) + self.cutTool.Shape = Part.makeSolid(toolProf.revolve(Vector(0, 0, 0), Vector(0, 0, 1))) + else: + # handle tool bits + self.cutTool.Shape = self.tool.Shape + self.cutTool.ViewObject.show() - self.voxSim.SetCurrentTool(self.tool) + self.voxSim.SetToolShape(self.cutTool.Shape, 0.05 * self.accuracy) self.icmd = 0 self.curpos = FreeCAD.Placement(self.initialPos, self.stdrot) # self.cutTool.Placement = FreeCAD.Placement(self.curpos, self.stdrot) From 0d3d7157f8828be68d01b4abce9345f32b9780b3 Mon Sep 17 00:00:00 2001 From: Daniel Wood Date: Wed, 29 Apr 2020 19:33:47 +0100 Subject: [PATCH 02/15] pass the tool shape to the CSimTool and handle the shape internally --- src/Mod/Path/PathSimulator/App/PathSim.cpp | 59 +--------------------- src/Mod/Path/PathSimulator/App/PathSim.h | 3 +- 2 files changed, 3 insertions(+), 59 deletions(-) diff --git a/src/Mod/Path/PathSimulator/App/PathSim.cpp b/src/Mod/Path/PathSimulator/App/PathSim.cpp index 64afa13f67..621efe5b99 100644 --- a/src/Mod/Path/PathSimulator/App/PathSim.cpp +++ b/src/Mod/Path/PathSimulator/App/PathSim.cpp @@ -33,7 +33,6 @@ #include #include "PathSim.h" -//#include "VolSim.h" using namespace Base; using namespace PathSimulator; @@ -54,69 +53,15 @@ PathSim::~PathSim() delete m_tool; } - void PathSim::BeginSimulation(Part::TopoShape * stock, float resolution) { Base::BoundBox3d bbox = stock->getBoundBox(); m_stock = new cStock(bbox.MinX, bbox.MinY, bbox.MinZ, bbox.LengthX(), bbox.LengthY(), bbox.LengthZ(), resolution); } -void PathSim::SetCurrentTool(Tool * tool) +void PathSim::SetToolShape(const TopoDS_Shape& toolShape, float resolution) { - cSimTool::Type tp = cSimTool::FLAT; - float angle = 180; - switch (tool->Type) - { - case Tool::BALLENDMILL: - tp = cSimTool::ROUND; - break; - - case Tool::CHAMFERMILL: - tp = cSimTool::CHAMFER; - angle = tool->CuttingEdgeAngle; - break; - - case Tool::UNDEFINED: - case Tool::DRILL: - tp = cSimTool::CHAMFER; - angle = tool->CuttingEdgeAngle; - if (angle > 180) - { - angle = 180; - } - break; - case Tool::CENTERDRILL: - tp = cSimTool::CHAMFER; - angle = tool->CuttingEdgeAngle; - if (angle > 180) - { - angle = 180; - } - break; - case Tool::COUNTERSINK: - case Tool::COUNTERBORE: - case Tool::REAMER: - case Tool::TAP: - case Tool::ENDMILL: - tp = cSimTool::FLAT; - angle = 180; - break; - case Tool::SLOTCUTTER: - case Tool::CORNERROUND: - case Tool::ENGRAVER: - tp = cSimTool::CHAMFER; - angle = tool->CuttingEdgeAngle; - if (angle > 180) - { - angle = 180; - } - break; - default: - tp = cSimTool::FLAT; - angle = 180; - break; - } - m_tool = new cSimTool(tp, tool->Diameter / 2.0, angle); + m_tool = new cSimTool(toolShape, resolution); } Base::Placement * PathSim::ApplyCommand(Base::Placement * pos, Command * cmd) diff --git a/src/Mod/Path/PathSimulator/App/PathSim.h b/src/Mod/Path/PathSimulator/App/PathSim.h index 5ad93dbb99..90be142766 100644 --- a/src/Mod/Path/PathSimulator/App/PathSim.h +++ b/src/Mod/Path/PathSimulator/App/PathSim.h @@ -31,7 +31,6 @@ #include #include #include -#include #include #include "VolSim.h" @@ -51,7 +50,7 @@ namespace PathSimulator ~PathSim(); void BeginSimulation(Part::TopoShape * stock, float resolution); - void SetCurrentTool(Tool * tool); + void SetToolShape(const TopoDS_Shape& toolShape, float resolution); Base::Placement * ApplyCommand(Base::Placement * pos, Command * cmd); public: From 9fa1a3e8cec532723118f0f2cd6f5fb4766abe6d Mon Sep 17 00:00:00 2001 From: Daniel Wood Date: Wed, 29 Apr 2020 19:34:50 +0100 Subject: [PATCH 03/15] Allow passing the tool shape from python --- src/Mod/Path/PathSimulator/App/PathSimPy.xml | 8 +++----- src/Mod/Path/PathSimulator/App/PathSimPyImp.cpp | 10 ++++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Mod/Path/PathSimulator/App/PathSimPy.xml b/src/Mod/Path/PathSimulator/App/PathSimPy.xml index 1449f5b20e..7225318f21 100644 --- a/src/Mod/Path/PathSimulator/App/PathSimPy.xml +++ b/src/Mod/Path/PathSimulator/App/PathSimPy.xml @@ -23,12 +23,10 @@ Create a path simulator object\n Start a simulation process on a box shape stock with given resolution\n - + - - SetCurrentTool(tool):\n - Set the current Path Tool for the subsequent simulator operations.\n - + SetToolShape(shape):\n +Set the shape of the tool to be used for simulation\n diff --git a/src/Mod/Path/PathSimulator/App/PathSimPyImp.cpp b/src/Mod/Path/PathSimulator/App/PathSimPyImp.cpp index eaec6d454a..708cc4b9a1 100644 --- a/src/Mod/Path/PathSimulator/App/PathSimPyImp.cpp +++ b/src/Mod/Path/PathSimulator/App/PathSimPyImp.cpp @@ -69,13 +69,15 @@ PyObject* PathSimPy::BeginSimulation(PyObject * args, PyObject * kwds) return Py_None; } -PyObject* PathSimPy::SetCurrentTool(PyObject * args) +PyObject* PathSimPy::SetToolShape(PyObject * args) { - PyObject *pObjTool; - if (!PyArg_ParseTuple(args, "O!", &(Path::ToolPy::Type), &pObjTool)) + PyObject *pObjToolShape; + float resolution; + if (!PyArg_ParseTuple(args, "O!f", &(Part::TopoShapePy::Type), &pObjToolShape, &resolution)) return 0; PathSim *sim = getPathSimPtr(); - sim->SetCurrentTool(static_cast(pObjTool)->getToolPtr()); + const TopoDS_Shape& toolShape = static_cast(pObjToolShape)->getTopoShapePtr()->getShape(); + sim->SetToolShape(toolShape, resolution); Py_IncRef(Py_None); return Py_None; } From 19f3f9ebddad39c154364e989a48aa235abd3534 Mon Sep 17 00:00:00 2001 From: Daniel Wood Date: Wed, 29 Apr 2020 19:41:42 +0100 Subject: [PATCH 04/15] Extract the shape of the tool from the solid shape --- src/Mod/Path/PathSimulator/App/VolSim.cpp | 121 +++++++++++++++++----- src/Mod/Path/PathSimulator/App/VolSim.h | 32 +++--- 2 files changed, 111 insertions(+), 42 deletions(-) diff --git a/src/Mod/Path/PathSimulator/App/VolSim.cpp b/src/Mod/Path/PathSimulator/App/VolSim.cpp index 2ba4450586..e313e12fc8 100644 --- a/src/Mod/Path/PathSimulator/App/VolSim.cpp +++ b/src/Mod/Path/PathSimulator/App/VolSim.cpp @@ -21,6 +21,10 @@ ***************************************************************************/ #include "PreCompiled.h" +#include + +#include +#include #ifndef _PreComp_ # include @@ -712,42 +716,103 @@ void Point3D::UpdateCmd(Path::Command & cmd) //************************************************************************************************************ // Simulation tool //************************************************************************************************************ -float cSimTool::GetToolProfileAt(float pos) // pos is -1..1 location along the radius of the tool (0 is center) -{ - switch (type) - { - case FLAT: - return 0; +cSimTool::cSimTool(const TopoDS_Shape& toolShape, float res){ + + Bnd_Box boundBox; + BRepBndLib::Add(toolShape, boundBox); - case CHAMFER: + boundBox.SetGap(0.0); + Standard_Real xMin, yMin, zMin, xMax, yMax, zMax; + boundBox.Get(xMin, yMin, zMin, xMax, yMax, zMax); + radius = (xMax - xMin) / 2; + length = zMax - zMin; + // Report the size of the bounding box + //Base::Console().Log("PathSim::SetToolShape: radius: %f length: %f\n", radius, length); + + Base::Vector3d pnt; + pnt.x = 0; + pnt.y = 0; + pnt.z = 0; + //float res = 0.025; // resolution + Base::Console().Log("PathSim::SetToolShape: res: %f\n", res); + + int radValue = (int)(radius / res) + 1; + + // Measure the performance of the profile extraction + auto start = std::chrono::high_resolution_clock::now(); + + for (int x = 0; x < radValue; x++) { - if (pos < 0) return -chamRatio * pos; - return chamRatio * pos; + // find the face of the tool by checking z points accross the + // radius to see if the point is inside the shape + pnt.x = x * res; + bool inside = isInside(toolShape, pnt); + + // move down until the point is outside the shape + while(inside && std::abs(pnt.z) < length ){ + //Base::Console().Log("PathSim::BeginSimulation: Pnt Inside: X Pos %f\n", pnt.x); + pnt.z -= res; + inside = isInside(toolShape, pnt); + } + + // move up until the point is first inside the shape and record the position + while (!inside && pnt.z < length) + { + pnt.z += res; + inside = isInside(toolShape, pnt); + + if (inside){ + toolShapePoint shapePoint; + shapePoint.radiusPos = pnt.x; + shapePoint.heightPos = pnt.z; + m_toolShape.push_back(shapePoint); + //Base::Console().Log("PathSim::BeginSimulation: Add height profile X: radius: %f height: %f\n", pnt.x, pnt.z); + break; + } + } } - case ROUND: - pos *= radius; - return radius - sqrt(dradius - pos * pos); - break; - } - return 0; + // Report the performance of the profile extraction + auto stop = std::chrono::high_resolution_clock::now(); + auto duration = std::chrono::duration_cast(stop - start); + Base::Console().Log("cSimTool::cSimTool - Tool Profile Extraction Took: %i ms\n", duration.count() / 1000); + } -void cSimTool::InitTool() // pos is 0..1 location along the radius of the tool +float cSimTool::GetToolProfileAt(float pos) // pos is -1..1 location along the radius of the tool (0 is center) { - switch (type) - { - case CHAMFER: - chamRatio = radius * tan((90.0 - tipAngle / 2) * 3.1415926535 / 180); - break; - - case ROUND: - dradius = radius * radius; - break; - - case FLAT: - break; + float radPos = std::abs(pos) * radius; + toolShapePoint test; test.radiusPos = radPos; + auto it = std::lower_bound(m_toolShape.begin(), m_toolShape.end(), test, toolShapePoint::less_than()); + float diff = std::abs(radPos - it->radiusPos); + + if (diff > 0.05){ + Base::Console().Log("requested pos: %f rad: %f diff: %f\n", radPos, it->radiusPos, diff); } + + return it->heightPos; +} + +bool cSimTool::isInside(const TopoDS_Shape& toolShape, Base::Vector3d pnt) +{ + double tolerance = 0.011; + bool checkFace = true; + TopAbs_State stateIn = TopAbs_IN; + + try { + BRepClass3d_SolidClassifier solidClassifier(toolShape); + gp_Pnt vertex = gp_Pnt(pnt.x, pnt.y, pnt.z); + solidClassifier.Perform(vertex, tolerance); + bool inside = (solidClassifier.State() == stateIn); + if (checkFace && solidClassifier.IsOnAFace()){ + inside = true; + //Base::Console().Log("PathSim::isInside: Touching Face: True\n"); + } + return inside; + }catch (...) { + return false; + } + } cVolSim::cVolSim() : stock(nullptr) diff --git a/src/Mod/Path/PathSimulator/App/VolSim.h b/src/Mod/Path/PathSimulator/App/VolSim.h index 39fb371adf..cc1ae06f69 100644 --- a/src/Mod/Path/PathSimulator/App/VolSim.h +++ b/src/Mod/Path/PathSimulator/App/VolSim.h @@ -34,6 +34,18 @@ #define SIM_TESSEL_TOP 1 #define SIM_TESSEL_BOT 2 #define SIM_WALK_RES 0.6 // step size in pixel units (to make sure all pixels in the path are visited) + +struct toolShapePoint { + float radiusPos; + float heightPos; + + struct less_than{ + bool operator()(const toolShapePoint &a, const toolShapePoint &b){ + return a.radiusPos < b.radiusPos; + } + }; +}; + struct Point3D { Point3D() : x(0), y(0), z(0), sina(0), cosa(0) {} @@ -88,22 +100,15 @@ struct cLineSegment class cSimTool { public: - enum Type { - FLAT = 0, - CHAMFER, - ROUND - }; - cSimTool() : type(FLAT), radius(0), tipAngle(0), dradius(0), chamRatio(0) {} - cSimTool(Type t, float rad, float tipang = 180) : type(t), radius(rad), tipAngle(tipang) { InitTool(); } + cSimTool(const TopoDS_Shape& toolShape, float res); ~cSimTool() {} - void InitTool(); - Type type; - float radius; - float tipAngle; - float dradius; - float chamRatio; float GetToolProfileAt(float pos); + bool isInside(const TopoDS_Shape& toolShape, Base::Vector3d pnt); + + std::vector< toolShapePoint > m_toolShape; + float radius; + float length; }; template @@ -131,7 +136,6 @@ private: int height; }; - class cStock { public: From a6563c117048fc3a9edffe0301efd9fed11c4b77 Mon Sep 17 00:00:00 2001 From: Daniel Wood Date: Wed, 29 Apr 2020 21:31:07 +0100 Subject: [PATCH 05/15] Remove and silence some debug prints --- src/Mod/Path/PathSimulator/App/VolSim.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/Mod/Path/PathSimulator/App/VolSim.cpp b/src/Mod/Path/PathSimulator/App/VolSim.cpp index e313e12fc8..3c8cab6d21 100644 --- a/src/Mod/Path/PathSimulator/App/VolSim.cpp +++ b/src/Mod/Path/PathSimulator/App/VolSim.cpp @@ -726,15 +726,11 @@ cSimTool::cSimTool(const TopoDS_Shape& toolShape, float res){ boundBox.Get(xMin, yMin, zMin, xMax, yMax, zMax); radius = (xMax - xMin) / 2; length = zMax - zMin; - // Report the size of the bounding box - //Base::Console().Log("PathSim::SetToolShape: radius: %f length: %f\n", radius, length); Base::Vector3d pnt; pnt.x = 0; pnt.y = 0; pnt.z = 0; - //float res = 0.025; // resolution - Base::Console().Log("PathSim::SetToolShape: res: %f\n", res); int radValue = (int)(radius / res) + 1; @@ -784,11 +780,11 @@ float cSimTool::GetToolProfileAt(float pos) // pos is -1..1 location along the float radPos = std::abs(pos) * radius; toolShapePoint test; test.radiusPos = radPos; auto it = std::lower_bound(m_toolShape.begin(), m_toolShape.end(), test, toolShapePoint::less_than()); - float diff = std::abs(radPos - it->radiusPos); + //float diff = std::abs(radPos - it->radiusPos); - if (diff > 0.05){ - Base::Console().Log("requested pos: %f rad: %f diff: %f\n", radPos, it->radiusPos, diff); - } + //if (diff > 0.05){ + // Base::Console().Log("requested pos: %f rad: %f diff: %f\n", radPos, it->radiusPos, diff); + //} return it->heightPos; } From b2c2cad07d1914e9ab7d0ddb6aa8711886fdaf2d Mon Sep 17 00:00:00 2001 From: Daniel Wood Date: Thu, 30 Apr 2020 12:52:11 +0100 Subject: [PATCH 06/15] use the tool resolution to determin face position --- src/Mod/Path/PathSimulator/App/VolSim.cpp | 11 +++++------ src/Mod/Path/PathSimulator/App/VolSim.h | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Mod/Path/PathSimulator/App/VolSim.cpp b/src/Mod/Path/PathSimulator/App/VolSim.cpp index 3c8cab6d21..4c6bd6ec82 100644 --- a/src/Mod/Path/PathSimulator/App/VolSim.cpp +++ b/src/Mod/Path/PathSimulator/App/VolSim.cpp @@ -742,20 +742,20 @@ cSimTool::cSimTool(const TopoDS_Shape& toolShape, float res){ // find the face of the tool by checking z points accross the // radius to see if the point is inside the shape pnt.x = x * res; - bool inside = isInside(toolShape, pnt); + bool inside = isInside(toolShape, pnt, res); // move down until the point is outside the shape while(inside && std::abs(pnt.z) < length ){ //Base::Console().Log("PathSim::BeginSimulation: Pnt Inside: X Pos %f\n", pnt.x); pnt.z -= res; - inside = isInside(toolShape, pnt); + inside = isInside(toolShape, pnt, res); } // move up until the point is first inside the shape and record the position while (!inside && pnt.z < length) { pnt.z += res; - inside = isInside(toolShape, pnt); + inside = isInside(toolShape, pnt, res); if (inside){ toolShapePoint shapePoint; @@ -789,16 +789,15 @@ float cSimTool::GetToolProfileAt(float pos) // pos is -1..1 location along the return it->heightPos; } -bool cSimTool::isInside(const TopoDS_Shape& toolShape, Base::Vector3d pnt) +bool cSimTool::isInside(const TopoDS_Shape& toolShape, Base::Vector3d pnt, float res) { - double tolerance = 0.011; bool checkFace = true; TopAbs_State stateIn = TopAbs_IN; try { BRepClass3d_SolidClassifier solidClassifier(toolShape); gp_Pnt vertex = gp_Pnt(pnt.x, pnt.y, pnt.z); - solidClassifier.Perform(vertex, tolerance); + solidClassifier.Perform(vertex, res); bool inside = (solidClassifier.State() == stateIn); if (checkFace && solidClassifier.IsOnAFace()){ inside = true; diff --git a/src/Mod/Path/PathSimulator/App/VolSim.h b/src/Mod/Path/PathSimulator/App/VolSim.h index cc1ae06f69..0487db7eb2 100644 --- a/src/Mod/Path/PathSimulator/App/VolSim.h +++ b/src/Mod/Path/PathSimulator/App/VolSim.h @@ -104,7 +104,7 @@ public: ~cSimTool() {} float GetToolProfileAt(float pos); - bool isInside(const TopoDS_Shape& toolShape, Base::Vector3d pnt); + bool isInside(const TopoDS_Shape& toolShape, Base::Vector3d pnt, float res); std::vector< toolShapePoint > m_toolShape; float radius; From 2ae9967b0f6793cddd7ec2fd56f0a5012c70da09 Mon Sep 17 00:00:00 2001 From: Daniel Wood Date: Wed, 29 Apr 2020 19:41:42 +0100 Subject: [PATCH 07/15] Extract the shape of the tool from the solid shape --- src/Mod/Path/PathSimulator/App/VolSim.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Mod/Path/PathSimulator/App/VolSim.cpp b/src/Mod/Path/PathSimulator/App/VolSim.cpp index 4c6bd6ec82..cd1840ce19 100644 --- a/src/Mod/Path/PathSimulator/App/VolSim.cpp +++ b/src/Mod/Path/PathSimulator/App/VolSim.cpp @@ -780,24 +780,25 @@ float cSimTool::GetToolProfileAt(float pos) // pos is -1..1 location along the float radPos = std::abs(pos) * radius; toolShapePoint test; test.radiusPos = radPos; auto it = std::lower_bound(m_toolShape.begin(), m_toolShape.end(), test, toolShapePoint::less_than()); - //float diff = std::abs(radPos - it->radiusPos); + float diff = std::abs(radPos - it->radiusPos); - //if (diff > 0.05){ - // Base::Console().Log("requested pos: %f rad: %f diff: %f\n", radPos, it->radiusPos, diff); - //} + if (diff > 0.05){ + Base::Console().Log("requested pos: %f rad: %f diff: %f\n", radPos, it->radiusPos, diff); + } return it->heightPos; } -bool cSimTool::isInside(const TopoDS_Shape& toolShape, Base::Vector3d pnt, float res) +bool cSimTool::isInside(const TopoDS_Shape& toolShape, Base::Vector3d pnt) { + double tolerance = 0.011; bool checkFace = true; TopAbs_State stateIn = TopAbs_IN; try { BRepClass3d_SolidClassifier solidClassifier(toolShape); gp_Pnt vertex = gp_Pnt(pnt.x, pnt.y, pnt.z); - solidClassifier.Perform(vertex, res); + solidClassifier.Perform(vertex, tolerance); bool inside = (solidClassifier.State() == stateIn); if (checkFace && solidClassifier.IsOnAFace()){ inside = true; From cdcac55e18980d960e06b81a274d7c5a9e128eea Mon Sep 17 00:00:00 2001 From: Daniel Wood Date: Wed, 29 Apr 2020 21:31:07 +0100 Subject: [PATCH 08/15] Remove and silence some debug prints --- src/Mod/Path/PathSimulator/App/VolSim.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Mod/Path/PathSimulator/App/VolSim.cpp b/src/Mod/Path/PathSimulator/App/VolSim.cpp index cd1840ce19..732be19a67 100644 --- a/src/Mod/Path/PathSimulator/App/VolSim.cpp +++ b/src/Mod/Path/PathSimulator/App/VolSim.cpp @@ -780,11 +780,11 @@ float cSimTool::GetToolProfileAt(float pos) // pos is -1..1 location along the float radPos = std::abs(pos) * radius; toolShapePoint test; test.radiusPos = radPos; auto it = std::lower_bound(m_toolShape.begin(), m_toolShape.end(), test, toolShapePoint::less_than()); - float diff = std::abs(radPos - it->radiusPos); + //float diff = std::abs(radPos - it->radiusPos); - if (diff > 0.05){ - Base::Console().Log("requested pos: %f rad: %f diff: %f\n", radPos, it->radiusPos, diff); - } + //if (diff > 0.05){ + // Base::Console().Log("requested pos: %f rad: %f diff: %f\n", radPos, it->radiusPos, diff); + //} return it->heightPos; } From 4c7c000e69cd35fe5d4d453987ae628389ba2acb Mon Sep 17 00:00:00 2001 From: Daniel Wood Date: Thu, 30 Apr 2020 12:52:11 +0100 Subject: [PATCH 09/15] use the tool resolution to determin face position --- src/Mod/Path/PathSimulator/App/VolSim.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Mod/Path/PathSimulator/App/VolSim.cpp b/src/Mod/Path/PathSimulator/App/VolSim.cpp index 732be19a67..4c6bd6ec82 100644 --- a/src/Mod/Path/PathSimulator/App/VolSim.cpp +++ b/src/Mod/Path/PathSimulator/App/VolSim.cpp @@ -789,16 +789,15 @@ float cSimTool::GetToolProfileAt(float pos) // pos is -1..1 location along the return it->heightPos; } -bool cSimTool::isInside(const TopoDS_Shape& toolShape, Base::Vector3d pnt) +bool cSimTool::isInside(const TopoDS_Shape& toolShape, Base::Vector3d pnt, float res) { - double tolerance = 0.011; bool checkFace = true; TopAbs_State stateIn = TopAbs_IN; try { BRepClass3d_SolidClassifier solidClassifier(toolShape); gp_Pnt vertex = gp_Pnt(pnt.x, pnt.y, pnt.z); - solidClassifier.Perform(vertex, tolerance); + solidClassifier.Perform(vertex, res); bool inside = (solidClassifier.State() == stateIn); if (checkFace && solidClassifier.IsOnAFace()){ inside = true; From 6dd3e8b7a2ce0e6d78fd719fbddba716c11c6a6d Mon Sep 17 00:00:00 2001 From: Daniel Wood Date: Wed, 29 Apr 2020 19:41:42 +0100 Subject: [PATCH 10/15] Extract the shape of the tool from the solid shape --- src/Mod/Path/PathSimulator/App/VolSim.cpp | 45 +++++------------------ 1 file changed, 9 insertions(+), 36 deletions(-) diff --git a/src/Mod/Path/PathSimulator/App/VolSim.cpp b/src/Mod/Path/PathSimulator/App/VolSim.cpp index 4c6bd6ec82..d6f9281999 100644 --- a/src/Mod/Path/PathSimulator/App/VolSim.cpp +++ b/src/Mod/Path/PathSimulator/App/VolSim.cpp @@ -731,34 +731,8 @@ cSimTool::cSimTool(const TopoDS_Shape& toolShape, float res){ pnt.x = 0; pnt.y = 0; pnt.z = 0; - - int radValue = (int)(radius / res) + 1; - - // Measure the performance of the profile extraction - auto start = std::chrono::high_resolution_clock::now(); - - for (int x = 0; x < radValue; x++) - { - // find the face of the tool by checking z points accross the - // radius to see if the point is inside the shape - pnt.x = x * res; - bool inside = isInside(toolShape, pnt, res); - - // move down until the point is outside the shape - while(inside && std::abs(pnt.z) < length ){ - //Base::Console().Log("PathSim::BeginSimulation: Pnt Inside: X Pos %f\n", pnt.x); - pnt.z -= res; - inside = isInside(toolShape, pnt, res); - } - - // move up until the point is first inside the shape and record the position - while (!inside && pnt.z < length) - { - pnt.z += res; - inside = isInside(toolShape, pnt, res); - - if (inside){ - toolShapePoint shapePoint; + //float res = 0.025; // resolution + Base::Console().Log("PathSim::SetToolShape: res: %f\n", res); shapePoint.radiusPos = pnt.x; shapePoint.heightPos = pnt.z; m_toolShape.push_back(shapePoint); @@ -780,24 +754,25 @@ float cSimTool::GetToolProfileAt(float pos) // pos is -1..1 location along the float radPos = std::abs(pos) * radius; toolShapePoint test; test.radiusPos = radPos; auto it = std::lower_bound(m_toolShape.begin(), m_toolShape.end(), test, toolShapePoint::less_than()); - //float diff = std::abs(radPos - it->radiusPos); + float diff = std::abs(radPos - it->radiusPos); - //if (diff > 0.05){ - // Base::Console().Log("requested pos: %f rad: %f diff: %f\n", radPos, it->radiusPos, diff); - //} + if (diff > 0.05){ + Base::Console().Log("requested pos: %f rad: %f diff: %f\n", radPos, it->radiusPos, diff); + } return it->heightPos; } -bool cSimTool::isInside(const TopoDS_Shape& toolShape, Base::Vector3d pnt, float res) +bool cSimTool::isInside(const TopoDS_Shape& toolShape, Base::Vector3d pnt) { + double tolerance = 0.011; bool checkFace = true; TopAbs_State stateIn = TopAbs_IN; try { BRepClass3d_SolidClassifier solidClassifier(toolShape); gp_Pnt vertex = gp_Pnt(pnt.x, pnt.y, pnt.z); - solidClassifier.Perform(vertex, res); + solidClassifier.Perform(vertex, tolerance); bool inside = (solidClassifier.State() == stateIn); if (checkFace && solidClassifier.IsOnAFace()){ inside = true; @@ -806,8 +781,6 @@ bool cSimTool::isInside(const TopoDS_Shape& toolShape, Base::Vector3d pnt, float return inside; }catch (...) { return false; - } - } cVolSim::cVolSim() : stock(nullptr) From 455c04f978bb13a7477f108b9e191a344452bced Mon Sep 17 00:00:00 2001 From: Daniel Wood Date: Wed, 29 Apr 2020 21:31:07 +0100 Subject: [PATCH 11/15] Remove and silence some debug prints --- src/Mod/Path/PathSimulator/App/VolSim.cpp | 38 +++++++++++++++++++---- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/src/Mod/Path/PathSimulator/App/VolSim.cpp b/src/Mod/Path/PathSimulator/App/VolSim.cpp index d6f9281999..fbc32c1915 100644 --- a/src/Mod/Path/PathSimulator/App/VolSim.cpp +++ b/src/Mod/Path/PathSimulator/App/VolSim.cpp @@ -731,8 +731,34 @@ cSimTool::cSimTool(const TopoDS_Shape& toolShape, float res){ pnt.x = 0; pnt.y = 0; pnt.z = 0; - //float res = 0.025; // resolution - Base::Console().Log("PathSim::SetToolShape: res: %f\n", res); + + int radValue = (int)(radius / res) + 1; + + // Measure the performance of the profile extraction + auto start = std::chrono::high_resolution_clock::now(); + + for (int x = 0; x < radValue; x++) + { + // find the face of the tool by checking z points accross the + // radius to see if the point is inside the shape + pnt.x = x * res; + bool inside = isInside(toolShape, pnt); + + // move down until the point is outside the shape + while(inside && std::abs(pnt.z) < length ){ + //Base::Console().Log("PathSim::BeginSimulation: Pnt Inside: X Pos %f\n", pnt.x); + pnt.z -= res; + inside = isInside(toolShape, pnt); + } + + // move up until the point is first inside the shape and record the position + while (!inside && pnt.z < length) + { + pnt.z += res; + inside = isInside(toolShape, pnt); + + if (inside){ + toolShapePoint shapePoint; shapePoint.radiusPos = pnt.x; shapePoint.heightPos = pnt.z; m_toolShape.push_back(shapePoint); @@ -754,11 +780,11 @@ float cSimTool::GetToolProfileAt(float pos) // pos is -1..1 location along the float radPos = std::abs(pos) * radius; toolShapePoint test; test.radiusPos = radPos; auto it = std::lower_bound(m_toolShape.begin(), m_toolShape.end(), test, toolShapePoint::less_than()); - float diff = std::abs(radPos - it->radiusPos); + //float diff = std::abs(radPos - it->radiusPos); - if (diff > 0.05){ - Base::Console().Log("requested pos: %f rad: %f diff: %f\n", radPos, it->radiusPos, diff); - } + //if (diff > 0.05){ + // Base::Console().Log("requested pos: %f rad: %f diff: %f\n", radPos, it->radiusPos, diff); + //} return it->heightPos; } From f8e42225060dfa3fa34b84473c6665c4e2edb269 Mon Sep 17 00:00:00 2001 From: Daniel Wood Date: Thu, 30 Apr 2020 12:52:11 +0100 Subject: [PATCH 12/15] use the tool resolution to determin face position --- src/Mod/Path/PathSimulator/App/VolSim.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Mod/Path/PathSimulator/App/VolSim.cpp b/src/Mod/Path/PathSimulator/App/VolSim.cpp index fbc32c1915..ed696aec84 100644 --- a/src/Mod/Path/PathSimulator/App/VolSim.cpp +++ b/src/Mod/Path/PathSimulator/App/VolSim.cpp @@ -742,20 +742,20 @@ cSimTool::cSimTool(const TopoDS_Shape& toolShape, float res){ // find the face of the tool by checking z points accross the // radius to see if the point is inside the shape pnt.x = x * res; - bool inside = isInside(toolShape, pnt); + bool inside = isInside(toolShape, pnt, res); // move down until the point is outside the shape while(inside && std::abs(pnt.z) < length ){ //Base::Console().Log("PathSim::BeginSimulation: Pnt Inside: X Pos %f\n", pnt.x); pnt.z -= res; - inside = isInside(toolShape, pnt); + inside = isInside(toolShape, pnt, res); } // move up until the point is first inside the shape and record the position while (!inside && pnt.z < length) { pnt.z += res; - inside = isInside(toolShape, pnt); + inside = isInside(toolShape, pnt, res); if (inside){ toolShapePoint shapePoint; @@ -789,16 +789,15 @@ float cSimTool::GetToolProfileAt(float pos) // pos is -1..1 location along the return it->heightPos; } -bool cSimTool::isInside(const TopoDS_Shape& toolShape, Base::Vector3d pnt) +bool cSimTool::isInside(const TopoDS_Shape& toolShape, Base::Vector3d pnt, float res) { - double tolerance = 0.011; bool checkFace = true; TopAbs_State stateIn = TopAbs_IN; try { BRepClass3d_SolidClassifier solidClassifier(toolShape); gp_Pnt vertex = gp_Pnt(pnt.x, pnt.y, pnt.z); - solidClassifier.Perform(vertex, tolerance); + solidClassifier.Perform(vertex, res); bool inside = (solidClassifier.State() == stateIn); if (checkFace && solidClassifier.IsOnAFace()){ inside = true; From 9bdba32f54b73e57ca36509f8fa0ec23e5defe64 Mon Sep 17 00:00:00 2001 From: Daniel Wood Date: Mon, 4 May 2020 20:19:25 +0100 Subject: [PATCH 13/15] check the toolbit shape is valid --- src/Mod/Path/PathScripts/PathSimulatorGui.py | 4 ++++ src/Mod/Path/PathSimulator/App/VolSim.cpp | 10 +++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Mod/Path/PathScripts/PathSimulatorGui.py b/src/Mod/Path/PathScripts/PathSimulatorGui.py index a6a7d2770f..0045d5ed61 100644 --- a/src/Mod/Path/PathScripts/PathSimulatorGui.py +++ b/src/Mod/Path/PathScripts/PathSimulatorGui.py @@ -134,6 +134,10 @@ class PathSimulation: # handle tool bits self.cutTool.Shape = self.tool.Shape + if not self.cutTool.Shape.isValid() or self.cutTool.Shape.isNull(): + self.EndSimulation() + raise RuntimeError("Path Simulation: Error in tool geometry - {}".format(self.tool.Name)) + self.cutTool.ViewObject.show() self.voxSim.SetToolShape(self.cutTool.Shape, 0.05 * self.accuracy) self.icmd = 0 diff --git a/src/Mod/Path/PathSimulator/App/VolSim.cpp b/src/Mod/Path/PathSimulator/App/VolSim.cpp index ed696aec84..c9cb49bcbf 100644 --- a/src/Mod/Path/PathSimulator/App/VolSim.cpp +++ b/src/Mod/Path/PathSimulator/App/VolSim.cpp @@ -23,6 +23,7 @@ #include "PreCompiled.h" #include +#include #include #include @@ -717,7 +718,14 @@ void Point3D::UpdateCmd(Path::Command & cmd) // Simulation tool //************************************************************************************************************ cSimTool::cSimTool(const TopoDS_Shape& toolShape, float res){ - + + BRepCheck_Analyzer aChecker(toolShape); + bool shapeIsValid = aChecker.IsValid() ? true : false; + + if(!shapeIsValid){ + throw Base::RuntimeError("Path Simulation: Error in tool geometry"); + } + Bnd_Box boundBox; BRepBndLib::Add(toolShape, boundBox); From 3003a16cc691829873899427ca905a8b76b5ab89 Mon Sep 17 00:00:00 2001 From: Daniel Wood Date: Mon, 4 May 2020 20:20:52 +0100 Subject: [PATCH 14/15] Clean up debug prints --- src/Mod/Path/PathSimulator/App/VolSim.cpp | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/Mod/Path/PathSimulator/App/VolSim.cpp b/src/Mod/Path/PathSimulator/App/VolSim.cpp index c9cb49bcbf..85185814bf 100644 --- a/src/Mod/Path/PathSimulator/App/VolSim.cpp +++ b/src/Mod/Path/PathSimulator/App/VolSim.cpp @@ -743,7 +743,7 @@ cSimTool::cSimTool(const TopoDS_Shape& toolShape, float res){ int radValue = (int)(radius / res) + 1; // Measure the performance of the profile extraction - auto start = std::chrono::high_resolution_clock::now(); + //auto start = std::chrono::high_resolution_clock::now(); for (int x = 0; x < radValue; x++) { @@ -754,7 +754,6 @@ cSimTool::cSimTool(const TopoDS_Shape& toolShape, float res){ // move down until the point is outside the shape while(inside && std::abs(pnt.z) < length ){ - //Base::Console().Log("PathSim::BeginSimulation: Pnt Inside: X Pos %f\n", pnt.x); pnt.z -= res; inside = isInside(toolShape, pnt, res); } @@ -770,16 +769,15 @@ cSimTool::cSimTool(const TopoDS_Shape& toolShape, float res){ shapePoint.radiusPos = pnt.x; shapePoint.heightPos = pnt.z; m_toolShape.push_back(shapePoint); - //Base::Console().Log("PathSim::BeginSimulation: Add height profile X: radius: %f height: %f\n", pnt.x, pnt.z); break; } } } // Report the performance of the profile extraction - auto stop = std::chrono::high_resolution_clock::now(); - auto duration = std::chrono::duration_cast(stop - start); - Base::Console().Log("cSimTool::cSimTool - Tool Profile Extraction Took: %i ms\n", duration.count() / 1000); + //auto stop = std::chrono::high_resolution_clock::now(); + //auto duration = std::chrono::duration_cast(stop - start); + //Base::Console().Log("cSimTool::cSimTool - Tool Profile Extraction Took: %i ms\n", duration.count() / 1000); } @@ -788,11 +786,6 @@ float cSimTool::GetToolProfileAt(float pos) // pos is -1..1 location along the float radPos = std::abs(pos) * radius; toolShapePoint test; test.radiusPos = radPos; auto it = std::lower_bound(m_toolShape.begin(), m_toolShape.end(), test, toolShapePoint::less_than()); - //float diff = std::abs(radPos - it->radiusPos); - - //if (diff > 0.05){ - // Base::Console().Log("requested pos: %f rad: %f diff: %f\n", radPos, it->radiusPos, diff); - //} return it->heightPos; } @@ -809,11 +802,11 @@ bool cSimTool::isInside(const TopoDS_Shape& toolShape, Base::Vector3d pnt, float bool inside = (solidClassifier.State() == stateIn); if (checkFace && solidClassifier.IsOnAFace()){ inside = true; - //Base::Console().Log("PathSim::isInside: Touching Face: True\n"); } return inside; }catch (...) { return false; + } } cVolSim::cVolSim() : stock(nullptr) From ed30e0421b1ed5f7237137d8354472fc2aa6eaa0 Mon Sep 17 00:00:00 2001 From: Daniel Wood Date: Mon, 4 May 2020 20:21:32 +0100 Subject: [PATCH 15/15] Try and catch errors when getting the tool profile --- src/Mod/Path/PathSimulator/App/VolSim.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Mod/Path/PathSimulator/App/VolSim.cpp b/src/Mod/Path/PathSimulator/App/VolSim.cpp index 85185814bf..bc46e76b47 100644 --- a/src/Mod/Path/PathSimulator/App/VolSim.cpp +++ b/src/Mod/Path/PathSimulator/App/VolSim.cpp @@ -783,11 +783,14 @@ cSimTool::cSimTool(const TopoDS_Shape& toolShape, float res){ float cSimTool::GetToolProfileAt(float pos) // pos is -1..1 location along the radius of the tool (0 is center) { - float radPos = std::abs(pos) * radius; - toolShapePoint test; test.radiusPos = radPos; - auto it = std::lower_bound(m_toolShape.begin(), m_toolShape.end(), test, toolShapePoint::less_than()); - - return it->heightPos; + try{ + float radPos = std::abs(pos) * radius; + toolShapePoint test; test.radiusPos = radPos; + auto it = std::lower_bound(m_toolShape.begin(), m_toolShape.end(), test, toolShapePoint::less_than()); + return it->heightPos; + }catch(...){ + return 0; + } } bool cSimTool::isInside(const TopoDS_Shape& toolShape, Base::Vector3d pnt, float res)