diff --git a/src/Base/Builder3D.cpp b/src/Base/Builder3D.cpp index 8d219ad42f..ba4cd430b0 100644 --- a/src/Base/Builder3D.cpp +++ b/src/Base/Builder3D.cpp @@ -991,6 +991,24 @@ std::vector InventorLoader::convert(const std::vector& data) co return points; } +std::vector InventorLoader::convert(const std::vector& data) const +{ + std::vector faces; + faces.reserve(data.size()); + int32_t coordIndex = 0; + for (const auto it : data) { + if (it == 3) { + faces.emplace_back(coordIndex, coordIndex+1, coordIndex+2); + } + else if (it == 4) { + faces.emplace_back(coordIndex, coordIndex+1, coordIndex+2); + faces.emplace_back(coordIndex, coordIndex+2, coordIndex+3); + } + coordIndex += it; + } + return faces; +} + std::vector> InventorLoader::split(const std::vector& data) { std::vector> splitdata; @@ -1005,9 +1023,8 @@ std::vector> InventorLoader::split(const std::vector InventorLoader::convert(const std::vector& data) const +std::vector InventorLoader::convert(const std::vector>& coordIndex) const { - std::vector> coordIndex = split(data); std::vector faces; faces.reserve(coordIndex.size()); for (const auto it : coordIndex) { @@ -1034,10 +1051,17 @@ void InventorLoader::readCoords() points = convert(data); } -void InventorLoader::readFaceSet() +void InventorLoader::readIndexedFaceSet() { auto data = readData("coordIndex"); + faces = convert(split(data)); +} + +void InventorLoader::readFaceSet() +{ + auto data = readData("numVertices"); faces = convert(data); + isnonindexed = true; } bool InventorLoader::read() @@ -1061,6 +1085,10 @@ bool InventorLoader::read() readCoords(); } else if (line.find("IndexedFaceSet {") != std::string::npos) { + readIndexedFaceSet(); + break; + } + else if (line.find("FaceSet {") != std::string::npos) { readFaceSet(); break; } diff --git a/src/Base/Builder3D.h b/src/Base/Builder3D.h index c94b70dcf5..19f949ed74 100644 --- a/src/Base/Builder3D.h +++ b/src/Base/Builder3D.h @@ -362,6 +362,12 @@ public: /// Checks if the loaded data are valid bool isValid() const; + /// Returns true if the data come from a non-indexed node as SoFaceSet. + /// This means that the read points contain duplicates. + bool isNonIndexed() const { + return isnonindexed; + } + /// Return the vectors of an SoNormal node const std::vector& getVector() { return vector; @@ -380,14 +386,17 @@ public: private: void readNormals(); void readCoords(); + void readIndexedFaceSet(); void readFaceSet(); template std::vector readData(const char*) const; std::vector convert(const std::vector&) const; std::vector convert(const std::vector&) const; + std::vector convert(const std::vector>&) const; static std::vector> split(const std::vector&); private: + bool isnonindexed = false; std::vector vector; std::vector points; std::vector faces; diff --git a/src/Mod/Mesh/App/Core/MeshIO.cpp b/src/Mod/Mesh/App/Core/MeshIO.cpp index 61075d3b89..b75777f418 100644 --- a/src/Mod/Mesh/App/Core/MeshIO.cpp +++ b/src/Mod/Mesh/App/Core/MeshIO.cpp @@ -29,6 +29,7 @@ #include "MeshIO.h" #include "Algorithm.h" #include "Builder.h" +#include "Degeneration.h" #include #include @@ -1517,6 +1518,12 @@ bool MeshInput::LoadInventor (std::istream &inp) meshAdj.SetFacetNeighbourhood(); this->_rclMesh.Adopt(meshPoints, meshFacets); + if (loader.isNonIndexed()) { + if (!MeshEvalDuplicatePoints(this->_rclMesh).Evaluate()) { + MeshFixDuplicatePoints(this->_rclMesh).Fixup(); + } + } + return true; }