diff --git a/src/Base/Matrix.cpp b/src/Base/Matrix.cpp index ba936e13f..18072b6b0 100644 --- a/src/Base/Matrix.cpp +++ b/src/Base/Matrix.cpp @@ -587,6 +587,16 @@ void Matrix_invert (Matrix a, Matrix inva) Matrix_gauss(temp,inva); } +void Matrix4D::inverseOrthogonal(void) +{ + Base::Vector3d c(dMtrx4D[0][3],dMtrx4D[1][3],dMtrx4D[2][3]); + transpose(); + c = this->operator * (c); + dMtrx4D[0][3] = -c.x; dMtrx4D[3][0] = 0; + dMtrx4D[1][3] = -c.y; dMtrx4D[3][1] = 0; + dMtrx4D[2][3] = -c.z; dMtrx4D[3][2] = 0; +} + void Matrix4D::inverseGauss (void) { double matrix [16]; diff --git a/src/Base/Matrix.h b/src/Base/Matrix.h index 333ae860a..b6aa5349d 100644 --- a/src/Base/Matrix.h +++ b/src/Base/Matrix.h @@ -135,6 +135,8 @@ public: void transform (const Vector3f& rclVct, const Matrix4D& rclMtrx); void transform (const Vector3d& rclVct, const Matrix4D& rclMtrx); void inverse (void); + /// if matrix is orthogonal a special way of getting the inverse is used + void inverseOrthogonal(void); void inverseGauss (void); void transpose (void); //@} diff --git a/src/Gui/CommandStd.cpp b/src/Gui/CommandStd.cpp index dba6d5f71..4bb0148a2 100644 --- a/src/Gui/CommandStd.cpp +++ b/src/Gui/CommandStd.cpp @@ -576,7 +576,7 @@ void CreateStdCommands(void) rcCmdMgr.addCommand(new StdCmdOnlineHelpWebsite()); rcCmdMgr.addCommand(new StdCmdFreeCADWebsite()); rcCmdMgr.addCommand(new StdCmdPythonWebsite()); - rcCmdMgr.addCommand(new StdCmdMeasurementSimple()); + //rcCmdMgr.addCommand(new StdCmdMeasurementSimple()); //rcCmdMgr.addCommand(new StdCmdDownloadOnlineHelp()); //rcCmdMgr.addCommand(new StdCmdDescription()); } diff --git a/src/Gui/MouseSelection.cpp b/src/Gui/MouseSelection.cpp index 97262f601..a4733b545 100644 --- a/src/Gui/MouseSelection.cpp +++ b/src/Gui/MouseSelection.cpp @@ -345,11 +345,24 @@ int PolyPickerSelection::mouseButtonEvent( const SoMouseButtonEvent * const e, c m_iXnew = pos.x(); m_iYnew = pos.y(); m_iXold = pos.x(); m_iYold = pos.y(); } - + } break; + default: + { + } break; + } + } + // release + else { + switch (button) + { + case SoMouseButtonEvent::BUTTON2: + { QCursor cur = _pcView3D->getWidget()->cursor(); _pcView3D->getWidget()->setCursor(m_cPrevCursor); -// _pcView3D->getGLWidget()->releaseMouse(); + // The pop-up menu should be shown when releasing mouse button because + // otherwise the navigation style doesn't get the UP event and gets into + // an inconsistent state. int id = popupMenu(); if (id == Finish || id == Cancel) { releaseMouseModel(); diff --git a/src/Mod/Complete/Gui/Workbench.cpp b/src/Mod/Complete/Gui/Workbench.cpp index 149f50ea5..d51928c2f 100644 --- a/src/Mod/Complete/Gui/Workbench.cpp +++ b/src/Mod/Complete/Gui/Workbench.cpp @@ -452,7 +452,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const view->setCommand("View"); *view << "Std_ViewFitAll" << "Separator" << "Std_ViewAxo" << "Separator" << "Std_ViewFront" << "Std_ViewRight" << "Std_ViewTop" << "Separator" << "Std_ViewRear" << "Std_ViewLeft" - << "Std_ViewBottom"; + << "Std_ViewBottom" << "Separator" << "Std_MeasureDistance"; // Part Design Gui::ToolBarItem* part_design = new Gui::ToolBarItem( root ); diff --git a/src/Mod/Mesh/App/Mesh.cpp b/src/Mod/Mesh/App/Mesh.cpp index dec5da73b..928c57edd 100644 --- a/src/Mod/Mesh/App/Mesh.cpp +++ b/src/Mod/Mesh/App/Mesh.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include "Core/Builder.h" #include "Core/MeshKernel.h" @@ -46,6 +47,8 @@ #include "Core/Degeneration.h" #include "Core/Segmentation.h" #include "Core/SetOperations.h" +#include "Core/Triangulation.h" +#include "Core/Trim.h" #include "Core/Visitor.h" #include "Mesh.h" @@ -812,6 +815,80 @@ void MeshObject::crossSections(const std::vector& planes, st } } +void MeshObject::cut(const std::vector& polygon, MeshObject::CutType type) +{ + MeshCore::FlatTriangulator tria; + tria.SetPolygon(polygon); + // this gives us the inverse matrix + Base::Matrix4D inv = tria.GetTransformToFitPlane(); + // compute the matrix for the coordinate transformation + Base::Matrix4D mat = inv; + mat.inverseOrthogonal(); + + std::vector poly = tria.ProjectToFitPlane(); + + Base::ViewProjMatrix proj(mat); + Base::Polygon2D polygon2d; + for (std::vector::const_iterator it = poly.begin(); it != poly.end(); ++it) + polygon2d.Add(Base::Vector2D(it->x, it->y)); + + MeshCore::MeshAlgorithm meshAlg(this->_kernel); + std::vector check; + + bool inner; + switch (type) { + case INNER: + inner = true; + break; + case OUTER: + inner = false; + break; + } + + MeshCore::MeshFacetGrid meshGrid(this->_kernel); + meshAlg.CheckFacets(meshGrid, &proj, polygon2d, inner, check); + if (!check.empty()) + this->deleteFacets(check); +} + +void MeshObject::trim(const std::vector& polygon, MeshObject::CutType type) +{ + MeshCore::FlatTriangulator tria; + tria.SetPolygon(polygon); + // this gives us the inverse matrix + Base::Matrix4D inv = tria.GetTransformToFitPlane(); + // compute the matrix for the coordinate transformation + Base::Matrix4D mat = inv; + mat.inverseOrthogonal(); + + std::vector poly = tria.ProjectToFitPlane(); + + Base::ViewProjMatrix proj(mat); + Base::Polygon2D polygon2d; + for (std::vector::const_iterator it = poly.begin(); it != poly.end(); ++it) + polygon2d.Add(Base::Vector2D(it->x, it->y)); + MeshCore::MeshTrimming trim(this->_kernel, &proj, polygon2d); + std::vector check; + std::vector triangle; + + switch (type) { + case INNER: + trim.SetInnerOrOuter(MeshCore::MeshTrimming::INNER); + break; + case OUTER: + trim.SetInnerOrOuter(MeshCore::MeshTrimming::OUTER); + break; + } + + MeshCore::MeshFacetGrid meshGrid(this->_kernel); + trim.CheckFacets(meshGrid, check); + trim.TrimFacets(check, triangle); + if (!check.empty()) + this->deleteFacets(check); + if (!triangle.empty()) + this->_kernel.AddFacets(triangle); +} + MeshObject* MeshObject::unite(const MeshObject& mesh) const { MeshCore::MeshKernel result; @@ -1423,7 +1500,7 @@ MeshObject* MeshObject::meshFromSegment(const std::vector& indice return new MeshObject(kernel, _Mtrx); } -std::vector MeshObject::getSegmentsFromType(MeshObject::Type type, const Segment& aSegment, +std::vector MeshObject::getSegmentsFromType(MeshObject::GeometryType type, const Segment& aSegment, float dev, unsigned long minFacets) const { std::vector segm; diff --git a/src/Mod/Mesh/App/Mesh.h b/src/Mod/Mesh/App/Mesh.h index 3d884517f..441db4de3 100644 --- a/src/Mod/Mesh/App/Mesh.h +++ b/src/Mod/Mesh/App/Mesh.h @@ -66,7 +66,8 @@ class MeshExport MeshObject : public Data::ComplexGeoData TYPESYSTEM_HEADER(); public: - enum Type {PLANE, CYLINDER, SPHERE}; + enum GeometryType {PLANE, CYLINDER, SPHERE}; + enum CutType {INNER, OUTER}; // typedef needed for cross-section typedef std::pair TPlane; @@ -198,6 +199,8 @@ public: Base::Vector3d getPointNormal(unsigned long) const; void crossSections(const std::vector&, std::vector §ions, float fMinEps = 1.0e-2f, bool bConnectPolygons = false) const; + void cut(const std::vector& polygon, CutType); + void trim(const std::vector& polygon, CutType); //@} /** @name Selection */ @@ -266,7 +269,7 @@ public: const Segment& getSegment(unsigned long) const; Segment& getSegment(unsigned long); MeshObject* meshFromSegment(const std::vector&) const; - std::vector getSegmentsFromType(Type, const Segment& aSegment, float dev, unsigned long minFacets) const; + std::vector getSegmentsFromType(GeometryType, const Segment& aSegment, float dev, unsigned long minFacets) const; //@} /** @name Primitives */ diff --git a/src/Mod/Mesh/App/MeshPy.xml b/src/Mod/Mesh/App/MeshPy.xml index 116979807..d8dc7c78e 100644 --- a/src/Mod/Mesh/App/MeshPy.xml +++ b/src/Mod/Mesh/App/MeshPy.xml @@ -327,6 +327,24 @@ for c in mesh.getSeparatecomponents(): Get a list of facet indices and intersection points + + + Cuts the mesh with a given closed polygon +cut(list, int) -> None +The argument list is an array of points, a polygon +The argument int is the mode: 0=inner, 1=outer + + + + + + Trims the mesh with a given closed polygon +trim(list, int) -> None +The argument list is an array of points, a polygon +The argument int is the mode: 0=inner, 1=outer + + + diff --git a/src/Mod/Mesh/App/MeshPyImp.cpp b/src/Mod/Mesh/App/MeshPyImp.cpp index a2a1e6302..6d7c542f4 100644 --- a/src/Mod/Mesh/App/MeshPyImp.cpp +++ b/src/Mod/Mesh/App/MeshPyImp.cpp @@ -35,12 +35,12 @@ #include "MeshPy.cpp" #include "MeshProperties.h" #include "Core/Algorithm.h" +#include "Core/Triangulation.h" #include "Core/Iterator.h" #include "Core/Degeneration.h" #include "Core/Elements.h" #include "Core/Grid.h" #include "Core/MeshKernel.h" -#include "Core/Triangulation.h" #include "Core/Segmentation.h" #include "Core/Curvature.h" @@ -1280,6 +1280,46 @@ PyObject* MeshPy::foraminate(PyObject *args) } } +PyObject* MeshPy::cut(PyObject *args) +{ + PyObject* poly; + int mode; + if (!PyArg_ParseTuple(args, "O!i", &PyList_Type, &poly, &mode)) + return NULL; + + Py::List list(poly); + std::vector polygon; + polygon.reserve(list.size()); + for (Py::List::iterator it = list.begin(); it != list.end(); ++it) { + Base::Vector3d pnt = Py::Vector(*it).toVector(); + polygon.push_back(Base::convertTo(pnt)); + } + + getMeshObjectPtr()->cut(polygon, MeshObject::CutType(mode)); + + Py_Return; +} + +PyObject* MeshPy::trim(PyObject *args) +{ + PyObject* poly; + int mode; + if (!PyArg_ParseTuple(args, "O!i", &PyList_Type, &poly, &mode)) + return NULL; + + Py::List list(poly); + std::vector polygon; + polygon.reserve(list.size()); + for (Py::List::iterator it = list.begin(); it != list.end(); ++it) { + Base::Vector3d pnt = Py::Vector(*it).toVector(); + polygon.push_back(Base::convertTo(pnt)); + } + + getMeshObjectPtr()->trim(polygon, MeshObject::CutType(mode)); + + Py_Return; +} + PyObject* MeshPy::smooth(PyObject *args) { int iter=1; diff --git a/src/Mod/Part/App/TopoShape.cpp b/src/Mod/Part/App/TopoShape.cpp index d8a5a13e2..1d50d9b13 100644 --- a/src/Mod/Part/App/TopoShape.cpp +++ b/src/Mod/Part/App/TopoShape.cpp @@ -145,6 +145,7 @@ # include # include # include +# include # include #include @@ -696,7 +697,7 @@ void TopoShape::exportStep(const char *filename) const STEPControl_Writer aWriter; Handle_Message_ProgressIndicator pi = new ProgressIndicator(100); - aWriter.WS()->MapReader()->SetProgress(pi); + aWriter.WS()->MapWriter()->SetProgress(pi); pi->NewScope(100, "Writing STEP file..."); pi->Show();