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();