Mesh: improve function to fix points on edge
This commit is contained in:
@@ -38,6 +38,7 @@
|
||||
#include "Info.h"
|
||||
#include "Grid.h"
|
||||
#include "TopoAlgorithm.h"
|
||||
#include "Triangulation.h"
|
||||
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
#include <Base/Sequencer.h>
|
||||
@@ -1197,25 +1198,77 @@ bool MeshEvalPointOnEdge::Evaluate ()
|
||||
const MeshFacet& face = facets[it];
|
||||
if (IsPointOnEdge(i, face)) {
|
||||
pointsIndices.push_back(i);
|
||||
if (face.HasOpenEdge())
|
||||
facetsIndices.push_back(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
return pointsIndices.empty();
|
||||
}
|
||||
|
||||
std::vector<PointIndex> MeshEvalPointOnEdge::GetIndices() const
|
||||
std::vector<PointIndex> MeshEvalPointOnEdge::GetPointIndices() const
|
||||
{
|
||||
return pointsIndices;
|
||||
}
|
||||
|
||||
std::vector<FacetIndex> MeshEvalPointOnEdge::GetFacetIndices() const
|
||||
{
|
||||
return facetsIndices;
|
||||
}
|
||||
|
||||
bool MeshFixPointOnEdge::Fixup ()
|
||||
{
|
||||
if (pointsIndices.empty()) {
|
||||
MeshEvalPointOnEdge eval(_rclMesh);
|
||||
eval.Evaluate();
|
||||
pointsIndices = eval.GetIndices();
|
||||
MeshEvalPointOnEdge eval(_rclMesh);
|
||||
eval.Evaluate();
|
||||
std::vector<PointIndex> pointsIndices = eval.GetPointIndices();
|
||||
std::vector<FacetIndex> facetsIndices = eval.GetFacetIndices();
|
||||
|
||||
if (!pointsIndices.empty()) {
|
||||
if (fillBoundary) {
|
||||
MarkBoundaries(facetsIndices);
|
||||
}
|
||||
|
||||
_rclMesh.DeletePoints(pointsIndices);
|
||||
|
||||
if (fillBoundary) {
|
||||
std::list<std::vector<PointIndex> > borderList;
|
||||
FindBoundaries(borderList);
|
||||
if (!borderList.empty())
|
||||
FillBoundaries(borderList);
|
||||
}
|
||||
}
|
||||
|
||||
_rclMesh.DeletePoints(pointsIndices);
|
||||
return true;
|
||||
}
|
||||
|
||||
void MeshFixPointOnEdge::MarkBoundaries(const std::vector<FacetIndex>& facetsIndices)
|
||||
{
|
||||
MeshAlgorithm meshalg(_rclMesh);
|
||||
meshalg.ResetFacetFlag(MeshFacet::TMP0);
|
||||
meshalg.SetFacetsFlag(facetsIndices, MeshFacet::TMP0);
|
||||
}
|
||||
|
||||
void MeshFixPointOnEdge::FindBoundaries(std::list<std::vector<PointIndex> >& borderList)
|
||||
{
|
||||
std::vector<FacetIndex> tmp;
|
||||
MeshAlgorithm meshalg(_rclMesh);
|
||||
meshalg.GetFacetsFlag(tmp, MeshFacet::TMP0);
|
||||
|
||||
if (!tmp.empty()) {
|
||||
//TODO: Implement a method to handle all facets in 'tmp'
|
||||
std::list<PointIndex> border;
|
||||
meshalg.GetMeshBorder(tmp.front(), border);
|
||||
if (!border.empty()) {
|
||||
borderList.emplace_back(border.begin(), border.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MeshFixPointOnEdge::FillBoundaries(const std::list<std::vector<PointIndex> >& borderList)
|
||||
{
|
||||
FlatTriangulator tria;
|
||||
tria.SetVerifier(new MeshCore::TriangulationVerifierV2);
|
||||
MeshTopoAlgorithm topalg(_rclMesh);
|
||||
std::list<std::vector<PointIndex> > failed;
|
||||
topalg.FillupHoles(1, tria, borderList, failed);
|
||||
}
|
||||
|
||||
@@ -762,12 +762,17 @@ public:
|
||||
*/
|
||||
bool Evaluate ();
|
||||
/**
|
||||
* Returns the indices of all corrupt facets.
|
||||
* Returns the indices of all points on edge.
|
||||
*/
|
||||
std::vector<PointIndex> GetIndices() const;
|
||||
std::vector<PointIndex> GetPointIndices() const;
|
||||
/**
|
||||
* Returns the indices of all facets with an open edge on that a point lies.
|
||||
*/
|
||||
std::vector<FacetIndex> GetFacetIndices() const;
|
||||
|
||||
private:
|
||||
std::vector<PointIndex> pointsIndices;
|
||||
std::vector<FacetIndex> facetsIndices;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -781,9 +786,7 @@ public:
|
||||
/**
|
||||
* Construction.
|
||||
*/
|
||||
MeshFixPointOnEdge (MeshKernel &rclM) : MeshValidation( rclM ) { }
|
||||
MeshFixPointOnEdge (MeshKernel &rclM, const std::vector<PointIndex>& points)
|
||||
: MeshValidation( rclM ), pointsIndices(points) { }
|
||||
MeshFixPointOnEdge (MeshKernel &rclM, bool fill = false) : MeshValidation( rclM ), fillBoundary(fill) { }
|
||||
/**
|
||||
* Destruction.
|
||||
*/
|
||||
@@ -794,7 +797,12 @@ public:
|
||||
bool Fixup ();
|
||||
|
||||
private:
|
||||
std::vector<PointIndex> pointsIndices;
|
||||
void MarkBoundaries(const std::vector<FacetIndex>& facetsIndices);
|
||||
void FindBoundaries(std::list<std::vector<PointIndex> >& borderList);
|
||||
void FillBoundaries(const std::list<std::vector<PointIndex> >& borderList);
|
||||
|
||||
private:
|
||||
bool fillBoundary;
|
||||
};
|
||||
|
||||
} // namespace MeshCore
|
||||
|
||||
@@ -1501,9 +1501,9 @@ bool MeshObject::hasPointsOnEdge() const
|
||||
return !nan.Evaluate();
|
||||
}
|
||||
|
||||
void MeshObject::removePointsOnEdge()
|
||||
void MeshObject::removePointsOnEdge(bool fillBoundary)
|
||||
{
|
||||
MeshCore::MeshFixPointOnEdge nan(_kernel);
|
||||
MeshCore::MeshFixPointOnEdge nan(_kernel, fillBoundary);
|
||||
nan.Fixup();
|
||||
}
|
||||
|
||||
|
||||
@@ -299,7 +299,7 @@ public:
|
||||
void removeInvalidPoints();
|
||||
void mergeFacets();
|
||||
bool hasPointsOnEdge() const;
|
||||
void removePointsOnEdge();
|
||||
void removePointsOnEdge(bool fillBoundary);
|
||||
//@}
|
||||
|
||||
/** @name Mesh segments */
|
||||
|
||||
@@ -296,9 +296,12 @@ for c in mesh.getSeparatecomponents():
|
||||
<UserDocu>Check if points lie on edges</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="removePointsOnEdge">
|
||||
<Methode Name="removePointsOnEdge" Keyword="true">
|
||||
<Documentation>
|
||||
<UserDocu>Remove points that lie on edges</UserDocu>
|
||||
<UserDocu>removePointsOnEdge(FillBoundary=False)
|
||||
Remove points that lie on edges.
|
||||
If FillBoundary is True then the holes by removing the affected facets
|
||||
will be re-filled.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="hasInvalidNeighbourhood" Const="true">
|
||||
|
||||
@@ -1102,12 +1102,14 @@ PyObject* MeshPy::hasPointsOnEdge(PyObject *args)
|
||||
return Py_BuildValue("O", (ok ? Py_True : Py_False));
|
||||
}
|
||||
|
||||
PyObject* MeshPy::removePointsOnEdge(PyObject *args)
|
||||
PyObject* MeshPy::removePointsOnEdge(PyObject *args, PyObject *kwds)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
PyObject *fillBoundary = Py_False;
|
||||
static char* keywords[] = {"FillBoundary", nullptr};
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O!", keywords, &PyBool_Type, &fillBoundary))
|
||||
return nullptr;
|
||||
try {
|
||||
getMeshObjectPtr()->removePointsOnEdge();
|
||||
getMeshObjectPtr()->removePointsOnEdge(PyObject_IsTrue(fillBoundary) ? true : false);
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
PyErr_SetString(Base::BaseExceptionFreeCADError, e.what());
|
||||
|
||||
Reference in New Issue
Block a user