add verifier class to check the result of the polygon triangulation

This commit is contained in:
wmayer
2018-09-18 21:38:04 +02:00
parent ff6ed27ba9
commit 6b055ee899
4 changed files with 89 additions and 4 deletions

View File

@@ -761,6 +761,10 @@ bool MeshAlgorithm::FillupHole(const std::vector<unsigned long>& boundary,
MeshGeomFacet triangle;
triangle = cTria.GetTriangle(rPoints, facet);
TriangulationVerifier* verifier = cTria.GetVerifier();
if (!verifier)
return true;
// Now we have two adjacent triangles which we check for overlaps.
// Therefore we build a separation plane that must separate the two diametrically opposed points.
Base::Vector3f planeNormal = rTriangle.GetNormal() % (rTriangle._aclPoints[(ref_side+1)%3]-rTriangle._aclPoints[ref_side]);
@@ -768,9 +772,7 @@ bool MeshAlgorithm::FillupHole(const std::vector<unsigned long>& boundary,
Base::Vector3f ref_point = rTriangle._aclPoints[(ref_side+2)%3];
Base::Vector3f tri_point = triangle._aclPoints[(tri_side+2)%3];
float ref_dist = (ref_point - planeBase) * planeNormal;
float tri_dist = (tri_point - planeBase) * planeNormal;
if (ref_dist * tri_dist > 0.0f) {
if (!verifier->Accept(planeNormal, planeBase, ref_point, tri_point)) {
rFaces.clear();
rPoints.clear();
cTria.Discard();
@@ -778,7 +780,7 @@ bool MeshAlgorithm::FillupHole(const std::vector<unsigned long>& boundary,
}
// we know to have filled a polygon, now check for the orientation
if ( triangle.GetNormal() * rTriangle.GetNormal() <= 0.0f ) {
if (verifier->MustFlip(triangle.GetNormal(), rTriangle.GetNormal())) {
for (MeshFacetArray::_TIterator it = rFaces.begin(); it != rFaces.end(); ++it)
it->FlipNormal();
}

View File

@@ -39,13 +39,64 @@
using namespace MeshCore;
bool TriangulationVerifier::Accept(const Base::Vector3f& n,
const Base::Vector3f& p1,
const Base::Vector3f& p2,
const Base::Vector3f& p3) const
{
float ref_dist = (p2 - p1) * n;
float tri_dist = (p3 - p1) * n;
return (ref_dist * tri_dist <= 0.0f);
}
bool TriangulationVerifier::MustFlip(const Base::Vector3f& n1,
const Base::Vector3f& n2) const
{
return n1.Dot(n2) <= 0.0f;
}
bool TriangulationVerifierV2::Accept(const Base::Vector3f& n,
const Base::Vector3f& p1,
const Base::Vector3f& p2,
const Base::Vector3f& p3) const
{
float ref_dist = (p2 - p1) * n;
float tri_dist = (p3 - p1) * n;
float prod = ref_dist * tri_dist;
(void)prod;
return true;
}
bool TriangulationVerifierV2::MustFlip(const Base::Vector3f& n1,
const Base::Vector3f& n2) const
{
float dot = n1.Dot(n2);
(void)dot;
return false;
}
// ----------------------------------------------------------------------------
AbstractPolygonTriangulator::AbstractPolygonTriangulator()
{
_discard = false;
_verifier = new TriangulationVerifier();
}
AbstractPolygonTriangulator::~AbstractPolygonTriangulator()
{
delete _verifier;
}
TriangulationVerifier* AbstractPolygonTriangulator::GetVerifier() const
{
return _verifier;
}
void AbstractPolygonTriangulator::SetVerifier(TriangulationVerifier* v)
{
delete _verifier;
_verifier = v;
}
void AbstractPolygonTriangulator::SetPolygon(const std::vector<Base::Vector3f>& raclPoints)

View File

@@ -31,6 +31,30 @@ namespace MeshCore
{
class MeshKernel;
class MeshExport TriangulationVerifier
{
public:
TriangulationVerifier() {}
virtual ~TriangulationVerifier() {}
virtual bool Accept(const Base::Vector3f& n,
const Base::Vector3f& p1,
const Base::Vector3f& p2,
const Base::Vector3f& p3) const;
virtual bool MustFlip(const Base::Vector3f& n1,
const Base::Vector3f& n2) const;
};
class MeshExport TriangulationVerifierV2 : public TriangulationVerifier
{
public:
virtual bool Accept(const Base::Vector3f& n,
const Base::Vector3f& p1,
const Base::Vector3f& p2,
const Base::Vector3f& p3) const;
virtual bool MustFlip(const Base::Vector3f& n1,
const Base::Vector3f& n2) const;
};
class MeshExport AbstractPolygonTriangulator
{
public:
@@ -40,6 +64,12 @@ public:
/** Sets the polygon to be triangulated. */
void SetPolygon(const std::vector<Base::Vector3f>& raclPoints);
void SetIndices(const std::vector<unsigned long>& d) {_indices = d;}
/** Set a verifier object that checks if the generated triangulation
* can be accepted and added to the mesh kernel.
* The triangulator takes ownership of the passed verifier.
*/
void SetVerifier(TriangulationVerifier* v);
TriangulationVerifier* GetVerifier() const;
/** Usually the created faces use the indices of the polygon points
* from [0, n]. If the faces should be appended to an existing mesh
* they may need to be reindexed from the calling instance.
@@ -108,6 +138,7 @@ protected:
std::vector<MeshGeomFacet> _triangles;
std::vector<MeshFacet> _facets;
std::vector<unsigned long> _info;
TriangulationVerifier* _verifier;
};
/**

View File

@@ -1168,6 +1168,7 @@ PyObject* MeshPy::fillupHoles(PyObject *args)
}
MeshPropertyLock lock(this->parentProperty);
tria->SetVerifier(new MeshCore::TriangulationVerifierV2);
getMeshObjectPtr()->fillupHoles(len, level, *tria);
}
catch (const Base::Exception& e) {