+ fix reading of meshes with textures when vertexes are isolated

This commit is contained in:
wmayer 2016-05-25 12:22:01 +02:00
parent 8cfabdb579
commit d51ea4c96b
2 changed files with 98 additions and 64 deletions

View File

@ -344,9 +344,13 @@ bool MeshInput::LoadOBJ (std::istream &rstrIn)
this->_rclMesh.Clear(); // remove all data before
MeshKernel tmp;
tmp.Adopt(meshPoints,meshFacets);
this->_rclMesh.Merge(tmp);
MeshCleanup meshCleanup(meshPoints,meshFacets);
if (_material)
meshCleanup.SetMaterial(_material);
meshCleanup.RemoveInvalids();
MeshPointFacetAdjacency meshAdj(meshPoints.size(),meshFacets);
meshAdj.SetFacetNeighbourhood();
this->_rclMesh.Adopt(meshPoints,meshFacets);
return true;
}
@ -486,29 +490,14 @@ bool MeshInput::LoadOFF (std::istream &rstrIn)
}
this->_rclMesh.Clear(); // remove all data before
// Don't use Assign() because Merge() checks which points are really needed.
// This method sets already the correct neighbourhood
unsigned long ct = meshPoints.size();
std::list<unsigned long> removeFaces;
for (MeshFacetArray::_TConstIterator it = meshFacets.begin(); it != meshFacets.end(); ++it) {
bool ok = true;
for (int i=0;i<3;i++) {
if (it->_aulPoints[i] >= ct) {
Base::Console().Warning("Face index %lu out of range\n", it->_aulPoints[i]);
ok = false;
}
}
if (!ok)
removeFaces.push_front(it-meshFacets.begin());
}
for (std::list<unsigned long>::iterator it = removeFaces.begin(); it != removeFaces.end(); ++it)
meshFacets.erase(meshFacets.begin() + *it);
MeshKernel tmp;
tmp.Adopt(meshPoints,meshFacets);
this->_rclMesh.Merge(tmp);
MeshCleanup meshCleanup(meshPoints,meshFacets);
if (_material)
meshCleanup.SetMaterial(_material);
meshCleanup.RemoveInvalids();
MeshPointFacetAdjacency meshAdj(meshPoints.size(),meshFacets);
meshAdj.SetFacetNeighbourhood();
this->_rclMesh.Adopt(meshPoints,meshFacets);
return true;
}
@ -978,16 +967,15 @@ bool MeshInput::LoadPLY (std::istream &inp)
}
this->_rclMesh.Clear(); // remove all data before
#if 1
MeshCleanup(meshPoints,meshFacets).RemoveInvalids();
MeshCleanup meshCleanup(meshPoints,meshFacets);
if (_material)
meshCleanup.SetMaterial(_material);
meshCleanup.RemoveInvalids();
MeshPointFacetAdjacency meshAdj(meshPoints.size(),meshFacets);
meshAdj.SetFacetNeighbourhood();
this->_rclMesh.Adopt(meshPoints,meshFacets);
#else
MeshKernel tmp;
tmp.Adopt(meshPoints,meshFacets);
this->_rclMesh.Merge(tmp);
#endif
return true;
}
@ -1036,11 +1024,12 @@ bool MeshInput::LoadMeshNode (std::istream &rstrIn)
}
this->_rclMesh.Clear(); // remove all data before
// Don't use Assign() because Merge() checks which points are really needed.
// This method sets already the correct neighbourhood
MeshKernel tmp;
tmp.Adopt(meshPoints,meshFacets);
this->_rclMesh.Merge(tmp);
MeshCleanup meshCleanup(meshPoints,meshFacets);
meshCleanup.RemoveInvalids();
MeshPointFacetAdjacency meshAdj(meshPoints.size(),meshFacets);
meshAdj.SetFacetNeighbourhood();
this->_rclMesh.Adopt(meshPoints,meshFacets);
return true;
}
@ -2519,6 +2508,7 @@ bool MeshOutput::SaveVRML (std::ostream &rstrOut) const
MeshCleanup::MeshCleanup(MeshPointArray& p, MeshFacetArray& f)
: pointArray(p)
, facetArray(f)
, materialArray(0)
{
}
@ -2526,6 +2516,11 @@ MeshCleanup::~MeshCleanup()
{
}
void MeshCleanup::SetMaterial(Material* mat)
{
materialArray = mat;
}
void MeshCleanup::RemoveInvalids()
{
// first mark all points as invalid
@ -2562,6 +2557,21 @@ void MeshCleanup::RemoveInvalidFacets()
std::size_t countInvalidFacets = std::count_if(facetArray.begin(), facetArray.end(),
std::bind2nd(MeshIsFlag<MeshFacet>(), MeshFacet::INVALID));
if (countInvalidFacets > 0) {
// adjust the material array if needed
if (materialArray && materialArray->binding == MeshIO::PER_FACE &&
materialArray->diffuseColor.size() == facetArray.size()) {
std::vector<App::Color> colors;
colors.reserve(facetArray.size() - countInvalidFacets);
for (std::size_t index = 0; index < facetArray.size(); index++) {
if (facetArray[index].IsValid()) {
colors.push_back(materialArray->diffuseColor[index]);
}
}
materialArray->diffuseColor.swap(colors);
}
MeshFacetArray copy_facets(facetArray.size() - countInvalidFacets);
// copy all valid facets to the new array
std::remove_copy_if(facetArray.begin(), facetArray.end(), copy_facets.begin(),
@ -2598,6 +2608,21 @@ void MeshCleanup::RemoveInvalidPoints()
// delete point, number of valid points
std::size_t validPoints = pointArray.size() - countInvalidPoints;
// adjust the material array if needed
if (materialArray && materialArray->binding == MeshIO::PER_VERTEX &&
materialArray->diffuseColor.size() == pointArray.size()) {
std::vector<App::Color> colors;
colors.reserve(validPoints);
for (std::size_t index = 0; index < pointArray.size(); index++) {
if (pointArray[index].IsValid()) {
colors.push_back(materialArray->diffuseColor[index]);
}
}
materialArray->diffuseColor.swap(colors);
}
MeshPointArray copy_points(validPoints);
// copy all valid facets to the new array
std::remove_copy_if(pointArray.begin(), pointArray.end(), copy_points.begin(),

View File

@ -191,6 +191,14 @@ public:
MeshCleanup(MeshPointArray& p, MeshFacetArray& f);
~MeshCleanup();
/*!
\brief Set the material array.
In case the material array sets the colors per vertex and
\ref RemoveInvalids() removes points from the array the
material array will be adjusted.
*/
void SetMaterial(Material* mat);
/*!
\brief Remove unreferenced and invalid facets.
*/
@ -209,6 +217,7 @@ private:
private:
MeshPointArray& pointArray;
MeshFacetArray& facetArray;
Material* materialArray;
};
/*!