diff --git a/src/Mod/Mesh/App/Core/MeshIO.cpp b/src/Mod/Mesh/App/Core/MeshIO.cpp index 25e3341b02..497dc4fcb7 100644 --- a/src/Mod/Mesh/App/Core/MeshIO.cpp +++ b/src/Mod/Mesh/App/Core/MeshIO.cpp @@ -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 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::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::INVALID)); if (countInvalidFacets > 0) { + + // adjust the material array if needed + if (materialArray && materialArray->binding == MeshIO::PER_FACE && + materialArray->diffuseColor.size() == facetArray.size()) { + std::vector 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 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& refFacets = pointFacetAdjacency[n1]; - for (std::vector::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& refFacets = pointFacetAdjacency[n1]; + for (std::vector::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; + } } } } diff --git a/src/Mod/Mesh/App/Core/MeshIO.h b/src/Mod/Mesh/App/Core/MeshIO.h index 04a9d2d372..b3b20e7f69 100644 --- a/src/Mod/Mesh/App/Core/MeshIO.h +++ b/src/Mod/Mesh/App/Core/MeshIO.h @@ -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; }; /*!