diff --git a/src/Mod/Path/Gui/Resources/panels/TaskPathSimulator.ui b/src/Mod/Path/Gui/Resources/panels/TaskPathSimulator.ui
index 1b8734d1c8..d8ec9ab93e 100644
--- a/src/Mod/Path/Gui/Resources/panels/TaskPathSimulator.ui
+++ b/src/Mod/Path/Gui/Resources/panels/TaskPathSimulator.ui
@@ -187,10 +187,10 @@
1
- 100
+ 50
- 100
+ 50
Qt::Horizontal
diff --git a/src/Mod/Path/PathScripts/PathSimulatorGui.py b/src/Mod/Path/PathScripts/PathSimulatorGui.py
index 3666e83b1b..466f970792 100644
--- a/src/Mod/Path/PathScripts/PathSimulatorGui.py
+++ b/src/Mod/Path/PathScripts/PathSimulatorGui.py
@@ -4,10 +4,12 @@ _filePath = os.path.dirname(os.path.abspath(__file__))
import FreeCAD
import Path
import Part
+import Mesh
import PathSimulator
import math
from FreeCAD import Vector, Base
from PathScripts.PathGeom import PathGeom
+
if FreeCAD.GuiUp:
import FreeCADGui
from PySide import QtGui, QtCore
@@ -43,7 +45,9 @@ class PathSimulation:
QtCore.QObject.connect(self.timer, QtCore.SIGNAL("timeout()"), self.PerformCut)
self.stdrot = FreeCAD.Rotation(Vector(0,0,1),0)
self.iprogress = 0
- self.numCommands = 0;
+ self.numCommands = 0
+ self.simperiod = 20
+ self.accuracy = 0.1
def Connect(self, but, sig):
QtCore.QObject.connect(but, QtCore.SIGNAL("clicked()"), sig)
@@ -89,8 +93,11 @@ class PathSimulation:
return 0
self.stock = self.job.Stock.Shape
if (self.isVoxel):
- self.voxSim.BeginSimulation(self.stock,0.5)
- self.cutMaterial.Mesh = self.voxSim.GetResultMesh()
+ maxlen = self.stock.BoundBox.XLength
+ if (maxlen < self.stock.BoundBox.YLength):
+ maxlen = self.stock.BoundBox.YLength
+ self.voxSim.BeginSimulation(self.stock, 0.01 * self.accuracy * maxlen)
+ (self.cutMaterial.Mesh, self.cutMaterialIn.Mesh) = self.voxSim.GetResultMesh()
else:
self.cutMaterial.Shape = self.stock
self.busy = False
@@ -127,11 +134,16 @@ class PathSimulation:
# Add cut material
if self.isVoxel:
self.cutMaterial = FreeCAD.ActiveDocument.addObject("Mesh::FeaturePython","CutMaterial")
+ self.cutMaterialIn = FreeCAD.ActiveDocument.addObject("Mesh::FeaturePython","CutMaterialIn")
+ self.cutMaterialIn.ViewObject.Proxy = 0
+ self.cutMaterialIn.ViewObject.show()
+ self.cutMaterialIn.ViewObject.ShapeColor = (1.0, 0.85, 0.45, 0.0)
else:
self.cutMaterial = FreeCAD.ActiveDocument.addObject("Part::FeaturePython","CutMaterial")
self.cutMaterial.Shape = self.job.Stock.Shape
self.cutMaterial.ViewObject.Proxy = 0
self.cutMaterial.ViewObject.show()
+ self.cutMaterial.ViewObject.ShapeColor = (0.5, 0.25, 0.25, 0.0)
# Add cut path solid for debug
if self.debug:
@@ -140,7 +152,7 @@ class PathSimulation:
self.cutSolid.ViewObject.hide()
self.SetupSimulation()
- self.resetSimulation = False
+ self.resetSimulation = True
FreeCAD.ActiveDocument.recompute()
#self.dialog.show()
@@ -212,7 +224,7 @@ class PathSimulation:
self.curpos = self.voxSim.ApplyCommand(self.curpos, cmd)
if not self.disableAnim:
self.cutTool.Placement = self.curpos #FreeCAD.Placement(self.curpos, self.stdrot)
- self.cutMaterial.Mesh = self.voxSim.GetResultMesh()
+ (self.cutMaterial.Mesh, self.cutMaterialIn.Mesh) = self.voxSim.GetResultMesh()
self.icmd += 1
self.iprogress += 1
self.UpdateProgress()
@@ -397,11 +409,16 @@ class PathSimulation:
def onSpeedBarChange(self):
form = self.taskForm.form
+ self.simperiod = 1000 / form.sliderSpeed.value()
form.labelGPerSec.setText(str(form.sliderSpeed.value()) + " G/s")
+ #if (self.timer.isActive()):
+ self.timer.setInterval(self.simperiod)
+
def onAccuracyBarChange(self):
form = self.taskForm.form
- form.labelAccuracy.setText(str(1.1 - 0.1 * form.sliderAccuracy.value()) + "%")
+ self.accuracy = 1.1 - 0.1 * form.sliderAccuracy.value()
+ form.labelAccuracy.setText(str(self.accuracy) + "%")
def GuiBusy(self, isBusy):
form = self.taskForm.form
@@ -435,11 +452,11 @@ class PathSimulation:
def SimPlay(self):
self.disableAnim = False
self.GuiBusy(True)
- self.timer.start(20)
+ self.timer.start(self.simperiod)
def ViewShape(self):
if self.isVoxel:
- self.cutMaterial.Mesh = self.voxSim.GetResultMesh()
+ (self.cutMaterial.Mesh, self.cutMaterialIn.Mesh) = self.voxSim.GetResultMesh()
else:
self.cutMaterial.Shape = self.stock
@@ -455,15 +472,26 @@ class PathSimulation:
FreeCAD.ActiveDocument.removeObject(self.cutTool.Name)
self.cutTool = None
+ def RemoveInnerMaterial(self):
+ if self.cutMaterialIn is not None:
+ if self.isVoxel and self.cutMaterial is not None:
+ mesh = Mesh.Mesh()
+ mesh.addMesh(self.cutMaterial.Mesh)
+ mesh.addMesh(self.cutMaterialIn.Mesh)
+ self.cutMaterial.Mesh = mesh
+ FreeCAD.ActiveDocument.removeObject(self.cutMaterialIn.Name)
+ self.cutMaterialIn = None
+
def RemoveMaterial(self):
- if self.cutMaterial is None:
- return
- FreeCAD.ActiveDocument.removeObject(self.cutMaterial.Name)
- self.cutMaterial = None
+ if self.cutMaterial is not None:
+ FreeCAD.ActiveDocument.removeObject(self.cutMaterial.Name)
+ self.cutMaterial = None
+ self.RemoveInnerMaterial()
def accept(self):
self.EndSimulation()
+ self.RemoveInnerMaterial()
self.RemoveTool()
def cancel(self):
diff --git a/src/Mod/Path/PathSimulator/App/PathSimPyImp.cpp b/src/Mod/Path/PathSimulator/App/PathSimPyImp.cpp
index c8da4261e4..33a01b7279 100644
--- a/src/Mod/Path/PathSimulator/App/PathSimPyImp.cpp
+++ b/src/Mod/Path/PathSimulator/App/PathSimPyImp.cpp
@@ -89,10 +89,15 @@ PyObject* PathSimPy::GetResultMesh(PyObject * args)
return 0;
cStock *stock = getPathSimPtr()->m_stock;
- Mesh::MeshObject *mesh = new Mesh::MeshObject();
- Mesh::MeshPy *meshpy = new Mesh::MeshPy(mesh);
- stock->Tesselate(*mesh);
- return meshpy;
+ Mesh::MeshObject *meshOuter = new Mesh::MeshObject();
+ Mesh::MeshPy *meshOuterpy = new Mesh::MeshPy(meshOuter);
+ Mesh::MeshObject *meshInner = new Mesh::MeshObject();
+ Mesh::MeshPy *meshInnerpy = new Mesh::MeshPy(meshInner);
+ stock->Tesselate(*meshOuter, *meshInner);
+ PyObject *tuple = PyTuple_New(2);
+ PyTuple_SetItem(tuple, 0, meshOuterpy);
+ PyTuple_SetItem(tuple, 1, meshInnerpy);
+ return tuple;
}
diff --git a/src/Mod/Path/PathSimulator/App/VolSim.cpp b/src/Mod/Path/PathSimulator/App/VolSim.cpp
index f885cf88b4..55465d718d 100644
--- a/src/Mod/Path/PathSimulator/App/VolSim.cpp
+++ b/src/Mod/Path/PathSimulator/App/VolSim.cpp
@@ -183,7 +183,10 @@ int cStock::TesselTop(int xp, int yp)
Point3D pbr(xp + x_size, yp, z);
Point3D ptl(xp, yp + y_size, z);
Point3D ptr(xp + x_size, yp + y_size, z);
- AddQuad(pbl, pbr, ptr, ptl);
+ if (abs(m_pz + m_lz - z) < SIM_EPSILON)
+ AddQuad(pbl, pbr, ptr, ptl, facetsOuter);
+ else
+ AddQuad(pbl, pbr, ptr, ptl, facetsInner);
}
if (farRect)
@@ -324,7 +327,7 @@ int cStock::TesselBot(int xp, int yp)
Point3D pbr(xp + x_size, yp, m_pz);
Point3D ptl(xp, yp + y_size, m_pz);
Point3D ptr(xp + x_size, yp + y_size, m_pz);
- AddQuad(pbl, ptl, ptr, pbr);
+ AddQuad(pbl, ptl, ptr, pbr, facetsOuter);
if (farRect)
return -1;
@@ -342,6 +345,10 @@ int cStock::TesselSidesX(int yp)
if (yp > 0)
lastz2 = std::max(m_stock[0][yp - 1], m_pz);
+ std::vector *facets = &facetsInner;
+ if (yp == 0 || yp == m_y)
+ facets = &facetsOuter;
+
//bool lastzclip = (lastz - m_pz) < m_res;
int lastpoint = 0;
for (int x = 1; x <= m_x; x++)
@@ -361,7 +368,7 @@ int cStock::TesselSidesX(int yp)
Point3D pbr(x, yp, lastz1);
Point3D ptl(lastpoint, yp, lastz2);
Point3D ptr(x, yp, lastz2);
- AddQuad(pbl, ptl, ptr, pbr);
+ AddQuad(pbl, ptl, ptr, pbr, *facets);
}
lastz1 = newz1;
lastz2 = newz2;
@@ -379,6 +386,10 @@ int cStock::TesselSidesY(int xp)
if (xp > 0)
lastz2 = std::max(m_stock[xp - 1][0], m_pz);
+ std::vector *facets = &facetsInner;
+ if (xp == 0 || xp == m_x)
+ facets = &facetsOuter;
+
//bool lastzclip = (lastz - m_pz) < m_res;
int lastpoint = 0;
for (int y = 1; y <= m_y; y++)
@@ -398,7 +409,7 @@ int cStock::TesselSidesY(int xp)
Point3D pbl(xp, y, lastz1);
Point3D ptr(xp, lastpoint, lastz2);
Point3D ptl(xp, y, lastz2);
- AddQuad(pbl, ptl, ptr, pbr);
+ AddQuad(pbl, ptl, ptr, pbr, *facets);
}
lastz1 = newz1;
lastz2 = newz2;
@@ -421,7 +432,7 @@ void cStock::SetFacetPoints(MeshCore::MeshGeomFacet & facet, Point3D & p1, Point
facet.CalcNormal();
}
-void cStock::AddQuad(Point3D & p1, Point3D & p2, Point3D & p3, Point3D & p4)
+void cStock::AddQuad(Point3D & p1, Point3D & p2, Point3D & p3, Point3D & p4, std::vector & facets)
{
MeshCore::MeshGeomFacet facet;
SetFacetPoints(facet, p1, p2, p3);
@@ -430,14 +441,15 @@ void cStock::AddQuad(Point3D & p1, Point3D & p2, Point3D & p3, Point3D & p4)
facets.push_back(facet);
}
-void cStock::Tesselate(Mesh::MeshObject & mesh)
+void cStock::Tesselate(Mesh::MeshObject & meshOuter, Mesh::MeshObject & meshInner)
{
// reset attribs
for (int y = 0; y < m_y; y++)
for (int x = 0; x < m_x; x++)
m_attr[x][y] = 0;
- facets.clear();
+ facetsOuter.clear();
+ facetsInner.clear();
for (int y = 0; y < m_y; y++)
{
@@ -462,8 +474,10 @@ void cStock::Tesselate(Mesh::MeshObject & mesh)
TesselSidesX(y);
for (int x = 0; x <= m_x; x++)
TesselSidesY(x);
- mesh.addFacets(facets);
- facets.clear();
+ meshOuter.addFacets(facetsOuter);
+ meshInner.addFacets(facetsInner);
+ facetsOuter.clear();
+ facetsInner.clear();
}
diff --git a/src/Mod/Path/PathSimulator/App/VolSim.h b/src/Mod/Path/PathSimulator/App/VolSim.h
index c3ce9e503a..5c55aedb10 100644
--- a/src/Mod/Path/PathSimulator/App/VolSim.h
+++ b/src/Mod/Path/PathSimulator/App/VolSim.h
@@ -85,36 +85,6 @@ struct cLineSegment
float lenXY;
};
-struct Model3D
-{
- Model3D(float px, float py, float res) : pos_x(px), pos_y(py), resolution(res) {}
- void SetFacetPoints(MeshCore::MeshGeomFacet & facet, Point3D & p1, Point3D & p2, Point3D & p3)
- {
- facet._aclPoints[0][0] = p1.x * resolution + pos_x;
- facet._aclPoints[0][1] = p1.y * resolution + pos_y;
- facet._aclPoints[0][2] = p1.z;
- facet._aclPoints[1][0] = p2.x * resolution + pos_x;
- facet._aclPoints[1][1] = p2.y * resolution + pos_y;
- facet._aclPoints[1][2] = p2.z;
- facet._aclPoints[2][0] = p3.x * resolution + pos_x;
- facet._aclPoints[2][1] = p3.y * resolution + pos_y;
- facet._aclPoints[2][2] = p3.z;
- facet.CalcNormal();
- }
-
- inline void AddQuad(Point3D & p1, Point3D & p2, Point3D & p3, Point3D & p4)
- {
- MeshCore::MeshGeomFacet facet;
- SetFacetPoints(facet, p1, p2, p3);
- mesh.addFacet(facet);
- SetFacetPoints(facet, p1, p3, p4);
- mesh.addFacet(facet);
- }
-
- float pos_x, pos_y, resolution;
- Mesh::MeshObject mesh;
-};
-
class cSimTool
{
public:
@@ -167,7 +137,7 @@ class cStock
public:
cStock(float px, float py, float pz, float lx, float ly, float lz, float res);
~cStock();
- void Tesselate(Mesh::MeshObject & mesh);
+ void Tesselate(Mesh::MeshObject & meshOuter, Mesh::MeshObject & meshInner);
void CreatePocket(float x, float y, float rad, float height);
void ApplyLinearTool(Point3D & p1, Point3D & p2, cSimTool &tool);
void ApplyCircularTool(Point3D & p1, Point3D & p2, Point3D & cent, cSimTool &tool, bool isCCW);
@@ -179,7 +149,7 @@ private:
float FindRectTop(int & xp, int & yp, int & x_size, int & y_size, bool scanHoriz);
void FindRectBot(int & xp, int & yp, int & x_size, int & y_size, bool scanHoriz);
void SetFacetPoints(MeshCore::MeshGeomFacet & facet, Point3D & p1, Point3D & p2, Point3D & p3);
- void AddQuad(Point3D & p1, Point3D & p2, Point3D & p3, Point3D & p4);
+ void AddQuad(Point3D & p1, Point3D & p2, Point3D & p3, Point3D & p4, std::vector & facets);
int TesselTop(int x, int y);
int TesselBot(int x, int y);
int TesselSidesX(int yp);
@@ -191,7 +161,8 @@ private:
float m_res; // resoulution
float m_plane; // stock plane height
int m_x, m_y; // stock array size
- std::vector facets;
+ std::vector facetsOuter;
+ std::vector facetsInner;
};
class cVolSim