improve mesh validation functions
This commit is contained in:
@@ -701,6 +701,34 @@ bool MeshFixDeformedFacets::Fixup()
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool MeshFixMergeFacets::Fixup()
|
||||
{
|
||||
MeshCore::MeshRefPointToPoints vv_it(_rclMesh);
|
||||
MeshCore::MeshRefPointToFacets vf_it(_rclMesh);
|
||||
unsigned long countPoints = _rclMesh.CountPoints();
|
||||
|
||||
std::vector<MeshFacet> newFacets;
|
||||
newFacets.reserve(countPoints/20); // 5% should be sufficient
|
||||
|
||||
MeshTopoAlgorithm topAlg(_rclMesh);
|
||||
for (unsigned long i=0; i<countPoints; i++) {
|
||||
if (vv_it[i].size() == 3 && vf_it[i].size() == 3) {
|
||||
VertexCollapse vc;
|
||||
vc._point = i;
|
||||
const std::set<unsigned long>& adjPts = vv_it[i];
|
||||
vc._circumPoints.insert(vc._circumPoints.begin(), adjPts.begin(), adjPts.end());
|
||||
const std::set<unsigned long>& adjFts = vf_it[i];
|
||||
vc._circumFacets.insert(vc._circumFacets.begin(), adjFts.begin(), adjFts.end());
|
||||
topAlg.CollapseVertex(vc);
|
||||
}
|
||||
}
|
||||
|
||||
topAlg.Cleanup();
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool MeshEvalDentsOnSurface::Evaluate()
|
||||
{
|
||||
this->indices.clear();
|
||||
|
||||
@@ -398,6 +398,32 @@ private:
|
||||
float fEpsilon;
|
||||
};
|
||||
|
||||
/**
|
||||
* The MeshFixMergeFacets class removes vertexes which have three adjacent vertexes and is referenced by three facets.
|
||||
* Usually all the three facets that reference this vertex are not well-formed. If the number of adjacent vertexes
|
||||
* is equal to the number of adjacent facets the affected vertex never lies on the boundary and thus it's safe to delete
|
||||
* and replace the three facets with a single facet.
|
||||
* Effectively this algorithm does the opposite of \ref MeshTopoAlgorithm::InsertVertex
|
||||
* @author Werner Mayer
|
||||
*/
|
||||
class MeshExport MeshFixMergeFacets : public MeshValidation
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Construction.
|
||||
*/
|
||||
MeshFixMergeFacets (MeshKernel &rclM)
|
||||
: MeshValidation(rclM) { }
|
||||
/**
|
||||
* Destruction.
|
||||
*/
|
||||
~MeshFixMergeFacets () { }
|
||||
/**
|
||||
* Removes deformed facets.
|
||||
*/
|
||||
bool Fixup ();
|
||||
};
|
||||
|
||||
/**
|
||||
* If an adjacent point (A) of a point (P) can be projected onto a triangle shared
|
||||
* by (P) but not by (A) then we have a local dent. The topology is not affected.
|
||||
|
||||
@@ -79,6 +79,13 @@ struct MeshExport EdgeCollapse
|
||||
std::vector<unsigned long> _changeFacets;
|
||||
};
|
||||
|
||||
struct MeshExport VertexCollapse
|
||||
{
|
||||
unsigned long _point;
|
||||
std::vector<unsigned long> _circumPoints;
|
||||
std::vector<unsigned long> _circumFacets;
|
||||
};
|
||||
|
||||
/**
|
||||
* The MeshPoint class represents a point in the mesh data structure. The class inherits from
|
||||
* Vector3f and provides some additional information such as flag state and property value.
|
||||
|
||||
@@ -835,6 +835,72 @@ void MeshTopoAlgorithm::Cleanup()
|
||||
_needsCleanup = false;
|
||||
}
|
||||
|
||||
bool MeshTopoAlgorithm::CollapseVertex(const VertexCollapse& vc)
|
||||
{
|
||||
if (vc._circumFacets.size() != vc._circumPoints.size())
|
||||
return false;
|
||||
|
||||
if (vc._circumFacets.size() != 3)
|
||||
return false;
|
||||
|
||||
if (!_rclMesh._aclPointArray[vc._point].IsValid())
|
||||
return false; // the point is marked invalid from a previous run
|
||||
|
||||
MeshFacet& rFace1 = _rclMesh._aclFacetArray[vc._circumFacets[0]];
|
||||
MeshFacet& rFace2 = _rclMesh._aclFacetArray[vc._circumFacets[1]];
|
||||
MeshFacet& rFace3 = _rclMesh._aclFacetArray[vc._circumFacets[2]];
|
||||
|
||||
// get the point that is not shared by rFace1
|
||||
unsigned long ptIndex = ULONG_MAX;
|
||||
std::vector<unsigned long>::const_iterator it;
|
||||
for (it = vc._circumPoints.begin(); it != vc._circumPoints.end(); ++it) {
|
||||
if (!rFace1.HasPoint(*it)) {
|
||||
ptIndex = *it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ptIndex == ULONG_MAX)
|
||||
return false;
|
||||
|
||||
unsigned long neighbour1 = ULONG_MAX;
|
||||
unsigned long neighbour2 = ULONG_MAX;
|
||||
|
||||
const std::vector<unsigned long>& faces = vc._circumFacets;
|
||||
// get neighbours that are not part of the faces to be removed
|
||||
for (int i=0; i<3; i++) {
|
||||
if (std::find(faces.begin(), faces.end(), rFace2._aulNeighbours[i]) == faces.end()) {
|
||||
neighbour1 = rFace2._aulNeighbours[i];
|
||||
}
|
||||
if (std::find(faces.begin(), faces.end(), rFace3._aulNeighbours[i]) == faces.end()) {
|
||||
neighbour2 = rFace3._aulNeighbours[i];
|
||||
}
|
||||
}
|
||||
|
||||
// adjust point and neighbour indices
|
||||
rFace1.Transpose(vc._point, ptIndex);
|
||||
rFace1.ReplaceNeighbour(vc._circumFacets[1], neighbour1);
|
||||
rFace1.ReplaceNeighbour(vc._circumFacets[2], neighbour2);
|
||||
|
||||
if (neighbour1 != ULONG_MAX) {
|
||||
MeshFacet& rFace4 = _rclMesh._aclFacetArray[neighbour1];
|
||||
rFace4.ReplaceNeighbour(vc._circumFacets[1], vc._circumFacets[0]);
|
||||
}
|
||||
if (neighbour2 != ULONG_MAX) {
|
||||
MeshFacet& rFace5 = _rclMesh._aclFacetArray[neighbour2];
|
||||
rFace5.ReplaceNeighbour(vc._circumFacets[2], vc._circumFacets[0]);
|
||||
}
|
||||
|
||||
// the two facets and the point can be marked for removal
|
||||
rFace2.SetInvalid();
|
||||
rFace3.SetInvalid();
|
||||
_rclMesh._aclPointArray[vc._point].SetInvalid();
|
||||
|
||||
_needsCleanup = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MeshTopoAlgorithm::CollapseEdge(unsigned long ulFacetPos, unsigned long ulNeighbour)
|
||||
{
|
||||
MeshFacet& rclF = _rclMesh._aclFacetArray[ulFacetPos];
|
||||
|
||||
@@ -111,6 +111,11 @@ public:
|
||||
*/
|
||||
void SplitFacet(unsigned long ulFacetPos, const Base::Vector3f& rP1,
|
||||
const Base::Vector3f& rP2);
|
||||
/**
|
||||
* Collapse a vertex. At the moment only removing inner vertexes referenced
|
||||
* by three facets is supposrted.
|
||||
*/
|
||||
bool CollapseVertex(const VertexCollapse& vc);
|
||||
/**
|
||||
* Collapses the common edge of two adjacent facets. This operation removes
|
||||
* one common point of the collapsed edge and the facets \a ulFacetPos and
|
||||
|
||||
Reference in New Issue
Block a user