add verifier class to check the result of the polygon triangulation
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user