From cc7850393514323f9c1d26189997a13ebd46e786 Mon Sep 17 00:00:00 2001 From: wmayer Date: Sun, 24 Jul 2016 00:23:45 +0200 Subject: [PATCH] improve groups handling of obj mesh format --- src/Mod/Mesh/App/AppMeshPy.cpp | 22 ++++++++++++++++------ src/Mod/Mesh/App/Core/MeshIO.cpp | 26 +++++++++++++++----------- src/Mod/Mesh/App/Core/MeshIO.h | 6 +++++- src/Mod/Mesh/App/Mesh.cpp | 16 ++++++++++++---- src/Mod/Mesh/App/Mesh.h | 2 +- src/Mod/Mesh/App/Segment.h | 7 ++++++- 6 files changed, 55 insertions(+), 24 deletions(-) diff --git a/src/Mod/Mesh/App/AppMeshPy.cpp b/src/Mod/Mesh/App/AppMeshPy.cpp index 018a9b230..f10317f6d 100644 --- a/src/Mod/Mesh/App/AppMeshPy.cpp +++ b/src/Mod/Mesh/App/AppMeshPy.cpp @@ -167,10 +167,15 @@ private: unsigned long segmct = mesh.countSegments(); if (segmct > 1) { for (unsigned long i=0; i segm(mesh.meshFromSegment(mesh.getSegment(i).getIndices())); + const Segment& group = mesh.getSegment(i); + std::string groupName = group.getName(); + if (groupName.empty()) + groupName = file.fileNamePure(); + + std::auto_ptr segm(mesh.meshFromSegment(group.getIndices())); Mesh::Feature *pcFeature = static_cast - (pcDoc->addObject("Mesh::Feature", file.fileNamePure().c_str())); - pcFeature->Label.setValue(file.fileNamePure().c_str()); + (pcDoc->addObject("Mesh::Feature", groupName.c_str())); + pcFeature->Label.setValue(groupName.c_str()); pcFeature->Mesh.swapMesh(*segm); pcFeature->purgeTouched(); } @@ -227,10 +232,15 @@ private: unsigned long segmct = mesh.countSegments(); if (segmct > 1) { for (unsigned long i=0; i segm(mesh.meshFromSegment(mesh.getSegment(i).getIndices())); + const Segment& group = mesh.getSegment(i); + std::string groupName = group.getName(); + if (groupName.empty()) + groupName = file.fileNamePure(); + + std::auto_ptr segm(mesh.meshFromSegment(group.getIndices())); Mesh::Feature *pcFeature = static_cast - (pcDoc->addObject("Mesh::Feature", file.fileNamePure().c_str())); - pcFeature->Label.setValue(file.fileNamePure().c_str()); + (pcDoc->addObject("Mesh::Feature", groupName.c_str())); + pcFeature->Label.setValue(groupName.c_str()); pcFeature->Mesh.swapMesh(*segm); pcFeature->purgeTouched(); } diff --git a/src/Mod/Mesh/App/Core/MeshIO.cpp b/src/Mod/Mesh/App/Core/MeshIO.cpp index 3ce412685..5e100922e 100644 --- a/src/Mod/Mesh/App/Core/MeshIO.cpp +++ b/src/Mod/Mesh/App/Core/MeshIO.cpp @@ -255,6 +255,7 @@ bool MeshInput::LoadSTL (std::istream &rstrIn) /** Loads an OBJ file. */ bool MeshInput::LoadOBJ (std::istream &rstrIn) { + boost::regex rx_g("^g\\s+([\\x21-\\x7E]+)\\s*$"); boost::regex rx_p("^v\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)\\s*$"); @@ -284,7 +285,6 @@ bool MeshInput::LoadOBJ (std::istream &rstrIn) std::string line; float fX, fY, fZ; unsigned int i1=1,i2=1,i3=1,i4=1; - MeshGeomFacet clFacet; MeshFacet item; if (!rstrIn || rstrIn.bad() == true) @@ -295,19 +295,20 @@ bool MeshInput::LoadOBJ (std::istream &rstrIn) return false; MeshIO::Binding rgb_value = MeshIO::OVERALL; - bool readvertices=false; + bool new_segment = true; while (std::getline(rstrIn, line)) { - for (std::string::iterator it = line.begin(); it != line.end(); ++it) - *it = tolower(*it); + // when a group name comes don't make it lower case + if (!line.empty() && line[0] != 'g') { + for (std::string::iterator it = line.begin(); it != line.end(); ++it) + *it = tolower(*it); + } if (boost::regex_match(line.c_str(), what, rx_p)) { - readvertices = true; fX = (float)std::atof(what[1].first); fY = (float)std::atof(what[4].first); fZ = (float)std::atof(what[7].first); meshPoints.push_back(MeshPoint(Base::Vector3f(fX, fY, fZ))); } else if (boost::regex_match(line.c_str(), what, rx_c)) { - readvertices = true; fX = (float)std::atof(what[1].first); fY = (float)std::atof(what[4].first); fZ = (float)std::atof(what[7].first); @@ -322,7 +323,6 @@ bool MeshInput::LoadOBJ (std::istream &rstrIn) rgb_value = MeshIO::PER_VERTEX; } else if (boost::regex_match(line.c_str(), what, rx_t)) { - readvertices = true; fX = (float)std::atof(what[1].first); fY = (float)std::atof(what[4].first); fZ = (float)std::atof(what[7].first); @@ -336,10 +336,14 @@ bool MeshInput::LoadOBJ (std::istream &rstrIn) meshPoints.back().SetProperty(prop); rgb_value = MeshIO::PER_VERTEX; } + else if (boost::regex_match(line.c_str(), what, rx_g)) { + new_segment = true; + _groupNames.push_back(what[1].first); + } else if (boost::regex_match(line.c_str(), what, rx_f3)) { // starts a new segment - if (readvertices) { - readvertices = false; + if (new_segment) { + new_segment = false; segment++; } @@ -353,8 +357,8 @@ bool MeshInput::LoadOBJ (std::istream &rstrIn) } else if (boost::regex_match(line.c_str(), what, rx_f4)) { // starts a new segment - if (readvertices) { - readvertices = false; + if (new_segment) { + new_segment = false; segment++; } diff --git a/src/Mod/Mesh/App/Core/MeshIO.h b/src/Mod/Mesh/App/Core/MeshIO.h index ea0b3a315..99c76f13b 100644 --- a/src/Mod/Mesh/App/Core/MeshIO.h +++ b/src/Mod/Mesh/App/Core/MeshIO.h @@ -70,7 +70,7 @@ struct MeshExport Material }; /** - * The MeshInput class is able to read a mesh object from a input stream + * The MeshInput class is able to read a mesh object from an input stream * in various formats. */ class MeshExport MeshInput @@ -81,6 +81,9 @@ public: MeshInput (MeshKernel &rclM, Material* m) : _rclMesh(rclM), _material(m){} virtual ~MeshInput (void) { } + const std::vector& GetGroupNames() const { + return _groupNames; + } /// Loads the file, decided by extension bool LoadAny(const char* FileName); @@ -114,6 +117,7 @@ public: protected: MeshKernel &_rclMesh; /**< reference to mesh data structure */ Material* _material; + std::vector _groupNames; }; /** diff --git a/src/Mod/Mesh/App/Mesh.cpp b/src/Mod/Mesh/App/Mesh.cpp index b29cdf595..c95292995 100644 --- a/src/Mod/Mesh/App/Mesh.cpp +++ b/src/Mod/Mesh/App/Mesh.cpp @@ -362,7 +362,7 @@ bool MeshObject::load(const char* file, MeshCore::Material* mat) if (!aReader.LoadAny(file)) return false; - swapKernel(kernel); + swapKernel(kernel, aReader.GetGroupNames()); return true; } @@ -373,16 +373,17 @@ bool MeshObject::load(std::istream& str, MeshCore::MeshIO::Format f, MeshCore::M if (!aReader.LoadFormat(str, f)) return false; - swapKernel(kernel); + swapKernel(kernel, aReader.GetGroupNames()); return true; } -void MeshObject::swapKernel(MeshCore::MeshKernel& kernel) +void MeshObject::swapKernel(MeshCore::MeshKernel& kernel, + const std::vector& g) { _kernel.Swap(kernel); // Some file formats define several objects per file (e.g. OBJ). // Now we mark each object as an own segment so that we can break - // the object into its orriginal objects again. + // the object into its original objects again. this->_segments.clear(); const MeshCore::MeshFacetArray& faces = _kernel.GetFacets(); MeshCore::MeshFacetArray::_TConstIterator it; @@ -407,6 +408,13 @@ void MeshObject::swapKernel(MeshCore::MeshKernel& kernel) this->_segments.push_back(Segment(this,segment,true)); } + // apply the group names to the segments + if (this->_segments.size() == g.size()) { + for (std::size_t index = 0; index < this->_segments.size(); index++) { + this->_segments[index].setName(g[index]); + } + } + #ifndef FC_DEBUG try { MeshCore::MeshEvalNeighbourhood nb(_kernel); diff --git a/src/Mod/Mesh/App/Mesh.h b/src/Mod/Mesh/App/Mesh.h index 878f46309..30d1506b0 100644 --- a/src/Mod/Mesh/App/Mesh.h +++ b/src/Mod/Mesh/App/Mesh.h @@ -376,7 +376,7 @@ private: void deletedFacets(const std::vector& remFacets); void updateMesh(const std::vector&); void updateMesh(); - void swapKernel(MeshCore::MeshKernel& m); + void swapKernel(MeshCore::MeshKernel& m, const std::vector& g); private: Base::Matrix4D _Mtrx; diff --git a/src/Mod/Mesh/App/Segment.h b/src/Mod/Mesh/App/Segment.h index 62e9c1c66..a8ffc8d5e 100644 --- a/src/Mod/Mesh/App/Segment.h +++ b/src/Mod/Mesh/App/Segment.h @@ -25,6 +25,7 @@ #define MESH_SEGMENT_H #include +#include #include "Facet.h" #include "Core/Iterator.h" @@ -41,17 +42,21 @@ public: void addIndices(const std::vector& inds); void removeIndices(const std::vector& inds); const std::vector& getIndices() const; - bool isEmpty() const { return _indices.empty(); }; + bool isEmpty() const { return _indices.empty(); } const Segment& operator = (const Segment&); bool operator == (const Segment&) const; + void setName(const std::string& n) { _name = n; } + const std::string& getName() const { return _name; } + // friends friend class MeshObject; private: MeshObject* _mesh; std::vector _indices; + std::string _name; bool _modifykernel; public: