improve the check for collapsing edges to avoid to introduce non-manifolds into a mesh

This commit is contained in:
wmayer
2019-04-24 09:49:33 +02:00
parent b2efb0ed25
commit 4841be663d
5 changed files with 40 additions and 0 deletions

View File

@@ -1746,6 +1746,24 @@ std::set<unsigned long> MeshRefPointToFacets::NeighbourPoints(const std::vector<
return nb;
}
std::set<unsigned long> MeshRefPointToFacets::NeighbourPoints(unsigned long pos) const
{
std::set<unsigned long> p;
const std::set<unsigned long>& vf = _map[pos];
for (std::set<unsigned long>::const_iterator it = vf.begin(); it != vf.end(); ++it) {
unsigned long p1, p2, p3;
_rclMesh.GetFacetPoints(*it, p1, p2, p3);
if (p1 != pos)
p.insert(p1);
if (p2 != pos)
p.insert(p2);
if (p3 != pos)
p.insert(p3);
}
return p;
}
void MeshRefPointToFacets::Neighbours (unsigned long ulFacetInd, float fMaxDist, MeshCollector& collect) const
{
std::set<unsigned long> visited;

View File

@@ -375,6 +375,7 @@ public:
const std::set<unsigned long>& operator[] (unsigned long) const;
MeshFacetArray::_TConstIterator GetFacet (unsigned long) const;
std::set<unsigned long> NeighbourPoints(const std::vector<unsigned long>& , int level) const;
std::set<unsigned long> NeighbourPoints(unsigned long) const;
void Neighbours (unsigned long ulFacetInd, float fMaxDist, MeshCollector& collect) const;
Base::Vector3f GetNormal(unsigned long) const;
void AddNeighbour(unsigned long, unsigned long);

View File

@@ -576,6 +576,13 @@ bool MeshRemoveNeedles::Fixup()
vf.erase(neighbour);
ce._changeFacets.insert(ce._changeFacets.begin(), vf.begin(), vf.end());
// get adjacent points
std::set<unsigned long> vv;
vv = vf_it.NeighbourPoints(ce._fromPoint);
ce._adjacentFrom.insert(ce._adjacentFrom.begin(), vv.begin(),vv.end());
vv = vf_it.NeighbourPoints(ce._toPoint);
ce._adjacentTo.insert(ce._adjacentTo.begin(), vv.begin(),vv.end());
if (topAlg.IsCollapseEdgeLegal(ce)) {
topAlg.CollapseEdge(ce);
for (auto it : ce._removeFacets) {

View File

@@ -75,6 +75,8 @@ struct MeshExport EdgeCollapse
{
unsigned long _fromPoint;
unsigned long _toPoint;
std::vector<unsigned long> _adjacentFrom; // adjacent points to _fromPoint
std::vector<unsigned long> _adjacentTo; // adjacent points to _toPoint
std::vector<unsigned long> _removeFacets;
std::vector<unsigned long> _changeFacets;
};

View File

@@ -955,6 +955,18 @@ bool MeshTopoAlgorithm::CollapseEdge(unsigned long ulFacetPos, unsigned long ulN
bool MeshTopoAlgorithm::IsCollapseEdgeLegal(const EdgeCollapse& ec) const
{
// http://stackoverflow.com/a/27049418/148668
// Check connectivity
//
std::vector<unsigned long> commonPoints;
std::set_intersection(ec._adjacentFrom.begin(), ec._adjacentFrom.end(),
ec._adjacentTo.begin(), ec._adjacentTo.end(),
std::back_insert_iterator<std::vector<unsigned long> >(commonPoints));
if (commonPoints.size() > 2) {
return false;
}
// Check geometry
std::vector<unsigned long>::const_iterator it;
for (it = ec._changeFacets.begin(); it != ec._changeFacets.end(); ++it) {
MeshFacet f = _rclMesh._aclFacetArray[*it];