improve mesh healing functions
This commit is contained in:
@@ -362,8 +362,8 @@ public:
|
||||
std::vector<unsigned long> GetIndices() const;
|
||||
|
||||
private:
|
||||
float fMinAngle;
|
||||
float fMaxAngle;
|
||||
float fMinAngle; /**< If an angle of a facet is lower than fMinAngle it's considered as deformed. */
|
||||
float fMaxAngle; /**< If an angle of a facet is higher than fMaxAngle it's considered as deformed. */
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -392,9 +392,9 @@ public:
|
||||
bool Fixup ();
|
||||
|
||||
private:
|
||||
float fMinAngle;
|
||||
float fMaxAngle;
|
||||
float fMaxSwapAngle;
|
||||
float fMinAngle; /**< If an angle of a facet is lower than fMinAngle it's considered as deformed. */
|
||||
float fMaxAngle; /**< If an angle of a facet is higher than fMaxAngle it's considered as deformed. */
|
||||
float fMaxSwapAngle; /**< A swap edge is only allowed if the angle of both normals doesn't exceed fMaxSwapAngle */
|
||||
float fEpsilon;
|
||||
};
|
||||
|
||||
|
||||
@@ -46,6 +46,16 @@ Returns true if the facet is degenerated, otherwise false.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="isDeformed">
|
||||
<Documentation>
|
||||
<UserDocu>isDegenerated(MinAngle, MaxAngle) -> boolean
|
||||
Returns true if the facet is deformed, otherwise false.
|
||||
A triangle is considered deformed if an angle is less than MinAngle
|
||||
or higher than MaxAngle.
|
||||
The two angles are given in radian.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Attribute Name="Index" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>The index of this facet in the MeshObject</UserDocu>
|
||||
|
||||
@@ -146,6 +146,25 @@ PyObject* FacetPy::isDegenerated(PyObject *args)
|
||||
return Py::new_reference_to(Py::Boolean(tria.IsDegenerated(fEpsilon)));
|
||||
}
|
||||
|
||||
PyObject* FacetPy::isDeformed(PyObject *args)
|
||||
{
|
||||
float fMinAngle;
|
||||
float fMaxAngle;
|
||||
if (!PyArg_ParseTuple(args, "ff", &fMinAngle, &fMaxAngle))
|
||||
return NULL;
|
||||
|
||||
FacetPy::PointerType face = this->getFacetPtr();
|
||||
if (!face->isBound()) {
|
||||
throw Py::RuntimeError("Unbound facet");
|
||||
}
|
||||
|
||||
float fCosOfMinAngle = cos(fMinAngle);
|
||||
float fCosOfMaxAngle = cos(fMaxAngle);
|
||||
const MeshCore::MeshKernel& kernel = face->Mesh->getKernel();
|
||||
MeshCore::MeshGeomFacet tria = kernel.GetFacet(face->Index);
|
||||
return Py::new_reference_to(Py::Boolean(tria.IsDeformed(fCosOfMinAngle, fCosOfMaxAngle)));
|
||||
}
|
||||
|
||||
Py::List FacetPy::getPoints(void) const
|
||||
{
|
||||
FacetPy::PointerType face = this->getFacetPtr();
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "Core/Degeneration.h"
|
||||
#include "Core/TopoAlgorithm.h"
|
||||
#include "Core/Triangulation.h"
|
||||
#include <Base/Tools.h>
|
||||
|
||||
using namespace Mesh;
|
||||
|
||||
@@ -237,7 +238,7 @@ PROPERTY_SOURCE(Mesh::FixDeformations, Mesh::FixDefects)
|
||||
|
||||
FixDeformations::FixDeformations()
|
||||
{
|
||||
ADD_PROPERTY(MaxAngle ,(0.1f));
|
||||
ADD_PROPERTY(MaxAngle ,(5.0f));
|
||||
}
|
||||
|
||||
FixDeformations::~FixDeformations()
|
||||
@@ -253,7 +254,8 @@ App::DocumentObjectExecReturn *FixDeformations::execute(void)
|
||||
Mesh::PropertyMeshKernel* kernel = static_cast<Mesh::PropertyMeshKernel*>(prop);
|
||||
std::unique_ptr<MeshObject> mesh(new MeshObject);
|
||||
*mesh = kernel->getValue();
|
||||
mesh->validateDeformations(static_cast<float>(MaxAngle.getValue()),
|
||||
float maxAngle = Base::toRadians(MaxAngle.getValue());
|
||||
mesh->validateDeformations(maxAngle,
|
||||
static_cast<float>(Epsilon.getValue()));
|
||||
this->Mesh.setValuePtr(mesh.release());
|
||||
}
|
||||
|
||||
@@ -20,6 +20,13 @@ set(MeshGui_LIBS
|
||||
FreeCADGui
|
||||
)
|
||||
|
||||
generate_from_xml(ViewProviderMeshPy)
|
||||
|
||||
SET(MeshGui_XML_SRCS
|
||||
ViewProviderMeshPy.xml
|
||||
)
|
||||
SOURCE_GROUP("XML" FILES ${MeshGui_XML_SRCS})
|
||||
|
||||
set(Mesh_MOC_HDRS
|
||||
DlgEvaluateMeshImp.h
|
||||
DlgEvaluateSettings.h
|
||||
@@ -117,6 +124,7 @@ SET(ViewProvider_SRCS
|
||||
ViewProviderCurvature.h
|
||||
ViewProviderDefects.cpp
|
||||
ViewProviderDefects.h
|
||||
ViewProviderMeshPyImp.cpp
|
||||
ViewProviderMeshFaceSet.cpp
|
||||
ViewProviderMeshFaceSet.h
|
||||
ViewProviderTransform.cpp
|
||||
@@ -127,6 +135,7 @@ SET(ViewProvider_SRCS
|
||||
SOURCE_GROUP("ViewProvider" FILES ${ViewProvider_SRCS})
|
||||
|
||||
SET(MeshGui_SRCS
|
||||
${MeshGui_XML_SRCS}
|
||||
${Dialogs_SRCS}
|
||||
${Inventor_SRCS}
|
||||
${resource_SRCS}
|
||||
|
||||
@@ -93,6 +93,7 @@
|
||||
#include <Mod/Mesh/App/Core/Visitor.h>
|
||||
#include <Mod/Mesh/App/Mesh.h>
|
||||
#include <Mod/Mesh/App/MeshFeature.h>
|
||||
#include <Mod/Mesh/Gui/ViewProviderMeshPy.h>
|
||||
#include <zipios++/gzipoutputstream.h>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
@@ -2046,6 +2047,14 @@ void ViewProviderMesh::highlightSegments(const std::vector<App::Color>& colors)
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* ViewProviderMesh::getPyObject()
|
||||
{
|
||||
if (!pyViewObject)
|
||||
pyViewObject = new ViewProviderMeshPy(this);
|
||||
pyViewObject->IncRef();
|
||||
return pyViewObject;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------
|
||||
|
||||
PROPERTY_SOURCE(MeshGui::ViewProviderIndexedFaceSet, MeshGui::ViewProviderMesh)
|
||||
|
||||
@@ -136,6 +136,8 @@ public:
|
||||
bool exportToVrml(const char* filename, const MeshCore::Material&, bool binary=false) const;
|
||||
void exportMesh(const char* filename, const char* fmt=0) const;
|
||||
void setupContextMenu(QMenu*, QObject*, const char*);
|
||||
/// Get the python wrapper for that ViewProvider
|
||||
PyObject* getPyObject();
|
||||
|
||||
/** @name Editing */
|
||||
//@{
|
||||
|
||||
42
src/Mod/Mesh/Gui/ViewProviderMeshPy.xml
Normal file
42
src/Mod/Mesh/Gui/ViewProviderMeshPy.xml
Normal file
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
|
||||
<PythonExport
|
||||
Father="ViewProviderDocumentObjectPy"
|
||||
Name="ViewProviderMeshPy"
|
||||
Twin="ViewProviderMesh"
|
||||
TwinPointer="ViewProviderMesh"
|
||||
Include="Mod/Mesh/Gui/ViewProvider.h"
|
||||
Namespace="MeshGui"
|
||||
FatherInclude="Gui/ViewProviderDocumentObjectPy.h"
|
||||
FatherNamespace="Gui">
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="Werner Mayer" EMail="wmayer@users.sourceforge.net" />
|
||||
<UserDocu>This is the ViewProvider base class</UserDocu>
|
||||
</Documentation>
|
||||
<Methode Name="setSelection">
|
||||
<Documentation>
|
||||
<UserDocu>Select list of facets</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="addSelection">
|
||||
<Documentation>
|
||||
<UserDocu>Add list of facets to selection</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="removeSelection">
|
||||
<Documentation>
|
||||
<UserDocu>Remove list of facets from selection</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="invertSelection">
|
||||
<Documentation>
|
||||
<UserDocu>Invert the selection</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="clearSelection">
|
||||
<Documentation>
|
||||
<UserDocu>Clear the selection</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
</PythonExport>
|
||||
</GenerateModel>
|
||||
137
src/Mod/Mesh/Gui/ViewProviderMeshPyImp.cpp
Normal file
137
src/Mod/Mesh/Gui/ViewProviderMeshPyImp.cpp
Normal file
@@ -0,0 +1,137 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2018 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <sstream>
|
||||
#endif
|
||||
|
||||
#include <Mod/Mesh/Gui/ViewProvider.h>
|
||||
|
||||
// inclusion of the generated files (generated out of ViewProviderMeshPy.xml)
|
||||
#include "ViewProviderMeshPy.h"
|
||||
#include "ViewProviderMeshPy.cpp"
|
||||
|
||||
using namespace MeshGui;
|
||||
|
||||
// returns a string which represents the object e.g. when printed in python
|
||||
std::string ViewProviderMeshPy::representation(void) const
|
||||
{
|
||||
std::stringstream str;
|
||||
str << "<View provider object at " << getViewProviderDocumentObjectPtr() << ">";
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
PyObject* ViewProviderMeshPy::setSelection(PyObject *args)
|
||||
{
|
||||
PyObject* obj;
|
||||
if (!PyArg_ParseTuple(args, "O", &obj))
|
||||
return 0;
|
||||
|
||||
Py::Sequence list(obj);
|
||||
std::vector<unsigned long> selection;
|
||||
selection.reserve(list.size());
|
||||
for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
|
||||
Py::Long index(*it);
|
||||
unsigned long value = static_cast<unsigned long>(index);
|
||||
selection.push_back(value);
|
||||
}
|
||||
|
||||
ViewProviderMesh* vp = getViewProviderMeshPtr();
|
||||
vp->setSelection(selection);
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* ViewProviderMeshPy::addSelection(PyObject *args)
|
||||
{
|
||||
PyObject* obj;
|
||||
if (!PyArg_ParseTuple(args, "O", &obj))
|
||||
return 0;
|
||||
|
||||
Py::Sequence list(obj);
|
||||
std::vector<unsigned long> selection;
|
||||
selection.reserve(list.size());
|
||||
for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
|
||||
Py::Long index(*it);
|
||||
unsigned long value = static_cast<unsigned long>(index);
|
||||
selection.push_back(value);
|
||||
}
|
||||
|
||||
ViewProviderMesh* vp = getViewProviderMeshPtr();
|
||||
vp->addSelection(selection);
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* ViewProviderMeshPy::removeSelection(PyObject *args)
|
||||
{
|
||||
PyObject* obj;
|
||||
if (!PyArg_ParseTuple(args, "O", &obj))
|
||||
return 0;
|
||||
|
||||
Py::Sequence list(obj);
|
||||
std::vector<unsigned long> selection;
|
||||
selection.reserve(list.size());
|
||||
for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
|
||||
Py::Long index(*it);
|
||||
unsigned long value = static_cast<unsigned long>(index);
|
||||
selection.push_back(value);
|
||||
}
|
||||
|
||||
ViewProviderMesh* vp = getViewProviderMeshPtr();
|
||||
vp->removeSelection(selection);
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* ViewProviderMeshPy::invertSelection(PyObject *args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return 0;
|
||||
|
||||
ViewProviderMesh* vp = getViewProviderMeshPtr();
|
||||
vp->invertSelection();
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* ViewProviderMeshPy::clearSelection(PyObject *args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return 0;
|
||||
|
||||
ViewProviderMesh* vp = getViewProviderMeshPtr();
|
||||
vp->clearSelection();
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PyObject *ViewProviderMeshPy::getCustomAttributes(const char* /*attr*/) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ViewProviderMeshPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user