From bd6da5699ee63a0d568c940328cdb82cbfaac94a Mon Sep 17 00:00:00 2001 From: wmayer Date: Tue, 24 Sep 2019 17:19:15 +0200 Subject: [PATCH] extend texture mapping to meshes --- src/Mod/Mesh/App/MeshTexture.cpp | 71 ++++++++++++++++++++++++++++++++ src/Mod/Mesh/App/MeshTexture.h | 15 +++++-- 2 files changed, 82 insertions(+), 4 deletions(-) diff --git a/src/Mod/Mesh/App/MeshTexture.cpp b/src/Mod/Mesh/App/MeshTexture.cpp index 0018ef1a95..7f1b346991 100644 --- a/src/Mod/Mesh/App/MeshTexture.cpp +++ b/src/Mod/Mesh/App/MeshTexture.cpp @@ -46,6 +46,77 @@ MeshTexture::MeshTexture(const Mesh::MeshObject& mesh, const MeshCore::Material } } +void MeshTexture::apply(const Mesh::MeshObject& mesh, const App::Color& defaultColor, MeshCore::Material &material) +{ + // copy the color values because the passed material could be the same instance as 'materialRefMesh' + std::vector textureColor = materialRefMesh.diffuseColor; + material.diffuseColor.clear(); + material.binding = MeshCore::MeshIO::OVERALL; + + if (kdTree.get()) { + // the points of the current mesh + std::vector diffuseColor; + const MeshCore::MeshPointArray& points = mesh.getKernel().GetPoints(); + const MeshCore::MeshFacetArray& facets = mesh.getKernel().GetFacets(); + + if (binding == MeshCore::MeshIO::PER_VERTEX) { + diffuseColor.reserve(points.size()); + for (size_t index=0; indexFindExact(points[index]); + if (pos < countPointsRefMesh) { + diffuseColor.push_back(textureColor[pos]); + } + else { + diffuseColor.push_back(defaultColor); + } + } + + if (diffuseColor.size() == points.size()) { + material.diffuseColor.swap(diffuseColor); + material.binding = MeshCore::MeshIO::PER_VERTEX; + } + } + else if (binding == MeshCore::MeshIO::PER_FACE) { + // the values of the map give the point indices of the original mesh + std::vector pointMap; + pointMap.reserve(points.size()); + for (size_t index=0; indexFindExact(points[index]); + if (pos < countPointsRefMesh) { + pointMap.push_back(pos); + } + else { + pointMap.push_back(ULONG_MAX); + } + } + + // now determine the facet indices of the original mesh + if (pointMap.size() == points.size()) { + diffuseColor.reserve(facets.size()); + for (auto it : facets) { + unsigned long index1 = pointMap[it._aulPoints[0]]; + unsigned long index2 = pointMap[it._aulPoints[1]]; + unsigned long index3 = pointMap[it._aulPoints[2]]; + if (index1 != ULONG_MAX && index2 != ULONG_MAX && index3 != ULONG_MAX) { + std::vector found = refPnt2Fac->GetIndices(index1, index2, index3); + if (found.size() == 1) { + diffuseColor.push_back(textureColor[found.front()]); + } + } + else { + diffuseColor.push_back(defaultColor); + } + } + } + + if (diffuseColor.size() == facets.size()) { + material.diffuseColor.swap(diffuseColor); + material.binding = MeshCore::MeshIO::PER_FACE; + } + } + } +} + void MeshTexture::apply(const Mesh::MeshObject& mesh, MeshCore::Material &material) { // copy the color values because the passed material could be the same instance as 'materialRefMesh' diff --git a/src/Mod/Mesh/App/MeshTexture.h b/src/Mod/Mesh/App/MeshTexture.h index c0eff198da..45c9bd740a 100644 --- a/src/Mod/Mesh/App/MeshTexture.h +++ b/src/Mod/Mesh/App/MeshTexture.h @@ -36,8 +36,8 @@ namespace Mesh /*! The MeshTexture class. This algorithm is useful to update the material after a mesh has been modified - by removing points or facets. It can't be used if the coordinates of points have - changed or if new points have been added. + by removing points or facets. If the coordinates of points have changed or if + new points have been added then a pre-defined color will be set. @author Werner Mayer */ class MeshExport MeshTexture @@ -48,8 +48,15 @@ public: */ MeshTexture(const Mesh::MeshObject& mesh, const MeshCore::Material &material); /*! - The \a mesh must be a sub-set of the mesh passed to the constructor. This means - that points or facets can be removed but neither changed nor new points added. + Find common points or facets of this to the original mesh. For points or facets + that don't match \a defaultColor will be used instead, otherwise the color of the + original material is used. + */ + void apply(const Mesh::MeshObject& mesh, const App::Color& defaultColor, MeshCore::Material &material); + /*! + Find common points or facets of this to the original mesh and use the color of the original material. + If for a point of \a mesh no matching point of the original mesh can be found the texture mapping will + fail. */ void apply(const Mesh::MeshObject& mesh, MeshCore::Material &material);