diff --git a/src/Mod/Path/PathSimulator/App/AppPathSimulator.cpp b/src/Mod/Path/PathSimulator/App/AppPathSimulator.cpp index 60cc760025..9acf340097 100644 --- a/src/Mod/Path/PathSimulator/App/AppPathSimulator.cpp +++ b/src/Mod/Path/PathSimulator/App/AppPathSimulator.cpp @@ -67,6 +67,7 @@ PyMOD_INIT_FUNC(PathSimulator) try { Base::Interpreter().runString("import Part"); Base::Interpreter().runString("import Path"); + Base::Interpreter().runString("import Mesh"); } catch (const Base::Exception& e) { PyErr_SetString(PyExc_ImportError, e.what()); diff --git a/src/Mod/Path/PathSimulator/App/CMakeLists.txt b/src/Mod/Path/PathSimulator/App/CMakeLists.txt index 45d37fa534..d9fd8eb86b 100644 --- a/src/Mod/Path/PathSimulator/App/CMakeLists.txt +++ b/src/Mod/Path/PathSimulator/App/CMakeLists.txt @@ -14,6 +14,7 @@ include_directories( set(PathSimulator_LIBS Path Part + Mesh FreeCADApp ) diff --git a/src/Mod/Path/PathSimulator/App/PathSimPy.xml b/src/Mod/Path/PathSimulator/App/PathSimPy.xml index 4de8b7f8c6..d6228ed39b 100644 --- a/src/Mod/Path/PathSimulator/App/PathSimPy.xml +++ b/src/Mod/Path/PathSimulator/App/PathSimPy.xml @@ -25,8 +25,18 @@ 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 + + SetCurrentTool(tool):\n + Set the current Path Tool for the subsequent simulator operations.\n + + + + + + + GetResultMesh():\n + Return the current mesh result of the simulation.\n + diff --git a/src/Mod/Path/PathSimulator/App/PathSimPyImp.cpp b/src/Mod/Path/PathSimulator/App/PathSimPyImp.cpp index c5767ba70a..2b530cd2aa 100644 --- a/src/Mod/Path/PathSimulator/App/PathSimPyImp.cpp +++ b/src/Mod/Path/PathSimulator/App/PathSimPyImp.cpp @@ -23,6 +23,8 @@ #include "PreCompiled.h" #include "Mod/Path/PathSimulator/App/PathSim.h" +#include +#include // inclusion of the generated files (generated out of PathSimPy.xml) #include "PathSimPy.h" @@ -49,19 +51,47 @@ int PathSimPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/) } -PyObject* PathSimPy::BeginSimulation(PyObject * /*args*/, PyObject * /*kwds*/) +PyObject* PathSimPy::BeginSimulation(PyObject * args, PyObject * kwds) { - PyErr_SetString(PyExc_NotImplementedError, "Not yet implemented"); - return 0; + static char *kwlist[] = { "stock", "resolution", NULL }; + PyObject *pObjStock; + float resolution; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!f", kwlist, &(Part::TopoShapePy::Type), &pObjStock, &resolution)) + return 0; + PathSim *sim = getPathSimPtr(); + Part::TopoShape *stock = static_cast(pObjStock)->getTopoShapePtr(); + sim->BeginSimulation(stock, resolution); + Py_IncRef(Py_None); + return Py_None; } PyObject* PathSimPy::SetCurrentTool(PyObject * /*args*/) { - PyErr_SetString(PyExc_NotImplementedError, "Not yet implemented"); - return 0; + PyErr_SetString(PyExc_NotImplementedError, "Not yet implemented"); + return 0; } +PyObject* PathSimPy::GetResultMesh(PyObject * args) +{ + if (!PyArg_ParseTuple(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; +} + +/* test script +import PathSimulator +sim = PathSimulator.PathSim() +stock = Part.makeBox(20,20,5) +sim.BeginSimulation(stock,0.1) +msh = sim.GetResultMesh() +Mesh.show(msh) + +*/ diff --git a/src/Mod/Path/PathSimulator/App/PreCompiled.h b/src/Mod/Path/PathSimulator/App/PreCompiled.h index c1a83a5430..4e604df386 100644 --- a/src/Mod/Path/PathSimulator/App/PreCompiled.h +++ b/src/Mod/Path/PathSimulator/App/PreCompiled.h @@ -31,6 +31,7 @@ # define PathSimulatorExport __declspec(dllexport) # define PathExport __declspec(dllexport) # define PartExport __declspec(dllimport) +# define MeshExport __declspec(dllimport) #else // for Linux # define PathSimulatorAppExport #endif diff --git a/src/Mod/Path/PathSimulator/App/VolSim.cpp b/src/Mod/Path/PathSimulator/App/VolSim.cpp index 07af032652..1317928366 100644 --- a/src/Mod/Path/PathSimulator/App/VolSim.cpp +++ b/src/Mod/Path/PathSimulator/App/VolSim.cpp @@ -20,6 +20,7 @@ * * ***************************************************************************/ +#include "PreCompiled.h" #include #include "VolSim.h" @@ -151,7 +152,7 @@ float cStock::FindRectTop(int & xp, int & yp, int & x_size, int & y_size, bool s return z; } -int cStock::TesselTop(Model3D *model, int xp, int yp) +int cStock::TesselTop(Mesh::MeshObject & mesh, int xp, int yp) { int x_size, y_size; float z = FindRectTop(xp, yp, x_size, y_size, true); @@ -182,7 +183,7 @@ int cStock::TesselTop(Model3D *model, 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); - model->AddQuad(pbl, pbr, ptr, ptl); + AddQuad(mesh, pbl, pbr, ptr, ptl); } if (farRect) @@ -294,7 +295,7 @@ void cStock::FindRectBot(int & xp, int & yp, int & x_size, int & y_size, bool sc } -int cStock::TesselBot(Model3D *model, int xp, int yp) +int cStock::TesselBot(Mesh::MeshObject & mesh, int xp, int yp) { int x_size, y_size; FindRectBot(xp, yp, x_size, y_size, true); @@ -323,7 +324,7 @@ int cStock::TesselBot(Model3D *model, 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); - model->AddQuad(pbl, ptl, ptr, pbr); + AddQuad(mesh, pbl, ptl, ptr, pbr); if (farRect) return -1; @@ -332,7 +333,7 @@ int cStock::TesselBot(Model3D *model, int xp, int yp) } -int cStock::TesselSidesX(Model3D *model, int yp) +int cStock::TesselSidesX(Mesh::MeshObject & mesh, int yp) { float lastz1 = m_pz; if (yp < m_y) @@ -356,14 +357,11 @@ int cStock::TesselSidesX(Model3D *model, int yp) { if (abs(newz1 - lastz1) < m_res && abs(newz2 - lastz2) < m_res) continue; - Point3D pbl(lastpoint, yp, lastz1); - Point3D pbr(x, yp, lastz1); - Point3D ptl(lastpoint, yp, lastz2); - Point3D ptr(x, yp, lastz2); - if (lastz2 > lastz1) - model->AddQuad(pbl, pbr, ptr, ptl); - else - model->AddQuad(pbl, ptl, ptr, pbr); + Point3D pbl(lastpoint, yp, lastz1); + Point3D pbr(x, yp, lastz1); + Point3D ptl(lastpoint, yp, lastz2); + Point3D ptr(x, yp, lastz2); + AddQuad(mesh, pbl, ptl, ptr, pbr); } lastz1 = newz1; lastz2 = newz2; @@ -372,7 +370,7 @@ int cStock::TesselSidesX(Model3D *model, int yp) return 0; } -int cStock::TesselSidesY(Model3D *model, int xp) +int cStock::TesselSidesY(Mesh::MeshObject & mesh, int xp) { float lastz1 = m_pz; if (xp < m_x) @@ -400,10 +398,7 @@ int cStock::TesselSidesY(Model3D *model, int xp) Point3D pbl(xp, y, lastz1); Point3D ptr(xp, lastpoint, lastz2); Point3D ptl(xp, y, lastz2); - if (lastz2 > lastz1) - model->AddQuad(pbl, pbr, ptr, ptl); - else - model->AddQuad(pbl, ptl, ptr, pbr); + AddQuad(mesh, pbl, ptl, ptr, pbr); } lastz1 = newz1; lastz2 = newz2; @@ -412,30 +407,38 @@ int cStock::TesselSidesY(Model3D *model, int xp) return 0; } -void cStock::AdjustCoordinates(Model3D *model) +void cStock::SetFacetPoints(MeshCore::MeshGeomFacet & facet, Point3D & p1, Point3D & p2, Point3D & p3) { - for (int i = 0; i < model->triangles.size(); i++) - { - for (int j = 0; j < 3; j++) - { - Point3D & t = model->triangles[i].points[j]; - t.x = (float)t.x * m_res + m_px; - t.y = (float)t.y * m_res + m_py; - } - } + facet._aclPoints[0][0] = p1.x * m_res + m_px; + facet._aclPoints[0][1] = p1.y * m_res + m_py; + facet._aclPoints[0][2] = p1.z; + facet._aclPoints[1][0] = p2.x * m_res + m_px; + facet._aclPoints[1][1] = p2.y * m_res + m_py; + facet._aclPoints[1][2] = p2.z; + facet._aclPoints[2][0] = p3.x * m_res + m_px; + facet._aclPoints[2][1] = p3.y * m_res + m_py; + facet._aclPoints[2][2] = p3.z; + facet.CalcNormal(); } - -Model3D *cStock::Tesselate() +void cStock::AddQuad(Mesh::MeshObject & mesh, 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); +} + +void cStock::Tesselate(Mesh::MeshObject & mesh) { - Model3D *model = new Model3D(); for (int y = 0; y < m_y; y++) { for (int x = 0; x < m_x; x++) { int attr = m_attr[x][y]; if ((attr & SIM_TESSEL_TOP) == 0) - x += TesselTop(model, x, y); + x += TesselTop(mesh, x, y); } } for (int y = 0; y < m_y; y++) @@ -445,15 +448,13 @@ Model3D *cStock::Tesselate() if ((m_stock[x][y] - m_pz) < m_res) m_attr[x][y] |= SIM_TESSEL_BOT; if ((m_attr[x][y] & SIM_TESSEL_BOT) == 0) - x += TesselBot(model, x, y); + x += TesselBot(mesh, x, y); } } for (int y = 0; y <= m_y; y++) - TesselSidesX(model, y); + TesselSidesX(mesh, y); for (int x = 0; x <= m_x; x++) - TesselSidesY(model, x); - AdjustCoordinates(model); - return model; + TesselSidesY(mesh, x); } diff --git a/src/Mod/Path/PathSimulator/App/VolSim.h b/src/Mod/Path/PathSimulator/App/VolSim.h index 1af34a137a..accc247164 100644 --- a/src/Mod/Path/PathSimulator/App/VolSim.h +++ b/src/Mod/Path/PathSimulator/App/VolSim.h @@ -27,6 +27,7 @@ #define PATHSIMULATOR_VolSim_H #include +#include #define SIM_EPSILON 0.00001 #define SIM_TESSEL_TOP 1 @@ -82,15 +83,32 @@ struct cLineSegment struct Model3D { - Model3D() {} - std::vector triangles; + 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) { - Triangle3D t1(p1, p2, p3); - Triangle3D t2(p1, p3, p4); - triangles.push_back(t1); - triangles.push_back(t2); + 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 @@ -145,22 +163,23 @@ class cStock public: cStock(float px, float py, float pz, float lx, float ly, float lz, float res); ~cStock(); - Model3D *Tesselate(); - 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); - inline Point3D & ToInner(Point3D & p) { + void Tesselate(Mesh::MeshObject & mesh); + 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); + inline Point3D & ToInner(Point3D & p) { return Point3D((p.x - m_px) / m_res, (p.y - m_py) / m_res, p.z); } 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); - int TesselTop(Model3D *model, int x, int y); - int TesselBot(Model3D *model, int x, int y); - int TesselSidesX(Model3D *model, int yp); - int TesselSidesY(Model3D *model, int xp); - void AdjustCoordinates(Model3D *model); + void SetFacetPoints(MeshCore::MeshGeomFacet & facet, Point3D & p1, Point3D & p2, Point3D & p3); + void AddQuad(Mesh::MeshObject & mesh, Point3D & p1, Point3D & p2, Point3D & p3, Point3D & p4); + int TesselTop(Mesh::MeshObject & mesh, int x, int y); + int TesselBot(Mesh::MeshObject & mesh, int x, int y); + int TesselSidesX(Mesh::MeshObject & mesh, int yp); + int TesselSidesY(Mesh::MeshObject & mesh, int xp); Array2D m_stock; Array2D m_attr; float m_px, m_py, m_pz; // stock zero position