+ 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;
}
@ -1516,7 +1505,7 @@ bool MeshOutput::SaveAny(const char* FileName, MeshIO::Format format) const
{
// ask for write permission
Base::FileInfo file(FileName);
Base::FileInfo directory(file.dirPath());
Base::FileInfo directory(file.dirPath());
if ((file.exists() && !file.isWritable()) || !directory.exists() || !directory.isWritable())
throw Base::FileException("No write permission for file",FileName);
@ -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(),
@ -2629,15 +2654,15 @@ void MeshPointFacetAdjacency::Build()
}
pointFacetAdjacency.resize(numPoints);
for (std::size_t i = 0; i < numPoints; i++)
pointFacetAdjacency[i].reserve(numFacetAdjacency[i]);
for (std::size_t i = 0; i < numPoints; i++)
pointFacetAdjacency[i].reserve(numFacetAdjacency[i]);
std::size_t numFacets = facets.size();
for (std::size_t i = 0; i < numFacets; i++) {
for (int j = 0; j < 3; j++) {
pointFacetAdjacency[facets[i]._aulPoints[j]].push_back(i);
}
}
for (std::size_t i = 0; i < numFacets; i++) {
for (int j = 0; j < 3; j++) {
pointFacetAdjacency[facets[i]._aulPoints[j]].push_back(i);
}
}
}
void MeshPointFacetAdjacency::SetFacetNeighbourhood()
@ -2646,25 +2671,25 @@ void MeshPointFacetAdjacency::SetFacetNeighbourhood()
for (std::size_t index = 0; index < numFacets; index++) {
MeshFacet& facet1 = facets[index];
for (int i = 0; i < 3; i++) {
std::size_t n1 = facet1._aulPoints[i];
std::size_t n2 = facet1._aulPoints[(i+1)%3];
bool success = false;
const std::vector<std::size_t>& refFacets = pointFacetAdjacency[n1];
for (std::vector<std::size_t>::const_iterator it = refFacets.begin(); it != refFacets.end(); ++it) {
if (*it != index) {
MeshFacet& facet2 = facets[*it];
if (facet2.HasPoint(n2)) {
facet1._aulNeighbours[i] = *it;
success = true;
break;
}
}
}
if (!success) {
facet1._aulNeighbours[i] = ULONG_MAX;
}
std::size_t n1 = facet1._aulPoints[i];
std::size_t n2 = facet1._aulPoints[(i+1)%3];
bool success = false;
const std::vector<std::size_t>& refFacets = pointFacetAdjacency[n1];
for (std::vector<std::size_t>::const_iterator it = refFacets.begin(); it != refFacets.end(); ++it) {
if (*it != index) {
MeshFacet& facet2 = facets[*it];
if (facet2.HasPoint(n2)) {
facet1._aulNeighbours[i] = *it;
success = true;
break;
}
}
}
if (!success) {
facet1._aulNeighbours[i] = ULONG_MAX;
}
}
}
}

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;
};
/*!