diff --git a/src/Mod/Mesh/App/AppMeshPy.cpp b/src/Mod/Mesh/App/AppMeshPy.cpp index f10317f6d..c09c29316 100644 --- a/src/Mod/Mesh/App/AppMeshPy.cpp +++ b/src/Mod/Mesh/App/AppMeshPy.cpp @@ -22,6 +22,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ +# include #endif #include @@ -30,13 +31,13 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include @@ -299,10 +300,20 @@ private: const MeshObject& mesh = static_cast(obj)->Mesh.getValue(); MeshCore::MeshKernel kernel = mesh.getKernel(); kernel.Transform(mesh.getTransform()); - if (global_mesh.countFacets() == 0) + + unsigned long countFacets = global_mesh.countFacets(); + if (countFacets == 0) global_mesh.setKernel(kernel); else global_mesh.addMesh(kernel); + + // now create a segment for the added mesh + std::vector indices; + indices.resize(global_mesh.countFacets() - countFacets); + std::generate(indices.begin(), indices.end(), Base::iotaGen(countFacets)); + Segment segm(&global_mesh, indices, true); + segm.setName(obj->Label.getValue()); + global_mesh.addSegment(segm); } else if (obj->getTypeId().isDerivedFrom(partId)) { App::Property* shape = obj->getPropertyByName("Shape"); @@ -312,12 +323,22 @@ private: std::vector aTopo; const Data::ComplexGeoData* data = static_cast(shape)->getComplexData(); if (data) { - data->getFaces(aPoints, aTopo,fTolerance); + data->getFaces(aPoints, aTopo, fTolerance); mesh->addFacets(aTopo, aPoints); - if (global_mesh.countFacets() == 0) + + unsigned long countFacets = global_mesh.countFacets(); + if (countFacets == 0) global_mesh = *mesh; else global_mesh.addMesh(*mesh); + + // now create a segment for the added mesh + std::vector indices; + indices.resize(global_mesh.countFacets() - countFacets); + std::generate(indices.begin(), indices.end(), Base::iotaGen(countFacets)); + Segment segm(&global_mesh, indices, true); + segm.setName(obj->Label.getValue()); + global_mesh.addSegment(segm); } } } @@ -327,6 +348,12 @@ private: } } + // if we have more than one segment set the 'save' flag + if (global_mesh.countSegments() > 1) { + for (unsigned long i = 0; i < global_mesh.countSegments(); ++i) { + global_mesh.getSegment(i).save(true); + } + } // export mesh compound global_mesh.save(EncodedName.c_str()); diff --git a/src/Mod/Mesh/App/Core/MeshIO.cpp b/src/Mod/Mesh/App/Core/MeshIO.cpp index 5e100922e..b628607fd 100644 --- a/src/Mod/Mesh/App/Core/MeshIO.cpp +++ b/src/Mod/Mesh/App/Core/MeshIO.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -338,7 +339,7 @@ bool MeshInput::LoadOBJ (std::istream &rstrIn) } else if (boost::regex_match(line.c_str(), what, rx_g)) { new_segment = true; - _groupNames.push_back(what[1].first); + _groupNames.push_back(Base::Tools::escapedUnicodeToUtf8(what[1].first)); } else if (boost::regex_match(line.c_str(), what, rx_f3)) { // starts a new segment @@ -1897,12 +1898,26 @@ bool MeshOutput::SaveOBJ (std::ostream &out) const seq.next(true); // allow to cancel } - // facet indices (no texture and normal indices) - for (MeshFacetArray::_TConstIterator it = rFacets.begin(); it != rFacets.end(); ++it) { - out << "f " << it->_aulPoints[0]+1 << " " - << it->_aulPoints[1]+1 << " " - << it->_aulPoints[2]+1 << std::endl; - seq.next(true); // allow to cancel + if (_groups.empty()) { + // facet indices (no texture and normal indices) + for (MeshFacetArray::_TConstIterator it = rFacets.begin(); it != rFacets.end(); ++it) { + out << "f " << it->_aulPoints[0]+1 << " " + << it->_aulPoints[1]+1 << " " + << it->_aulPoints[2]+1 << std::endl; + seq.next(true); // allow to cancel + } + } + else { + for (std::vector::const_iterator gt = _groups.begin(); gt != _groups.end(); ++gt) { + out << "g " << Base::Tools::escapedUnicodeFromUtf8(gt->name.c_str()) << std::endl; + for (std::vector::const_iterator it = gt->indices.begin(); it != gt->indices.end(); ++it) { + const MeshFacet& f = rFacets[*it]; + out << "f " << f._aulPoints[0]+1 << " " + << f._aulPoints[1]+1 << " " + << f._aulPoints[2]+1 << std::endl; + seq.next(true); // allow to cancel + } + } } return true; diff --git a/src/Mod/Mesh/App/Core/MeshIO.h b/src/Mod/Mesh/App/Core/MeshIO.h index 99c76f13b..daad6c55a 100644 --- a/src/Mod/Mesh/App/Core/MeshIO.h +++ b/src/Mod/Mesh/App/Core/MeshIO.h @@ -69,6 +69,12 @@ struct MeshExport Material std::vector diffuseColor; }; +struct MeshExport Group +{ + std::vector indices; + std::string name; +}; + /** * The MeshInput class is able to read a mesh object from an input stream * in various formats. @@ -134,6 +140,10 @@ public: virtual ~MeshOutput (void) { } void SetObjectName(const std::string& n) { objectName = n; } + void SetGroups(const std::vector& g) { + _groups = g; + } + void Transform(const Base::Matrix4D&); /** Set custom data to the header of a binary STL. * If the data exceeds 80 characters then the characters too much @@ -181,6 +191,7 @@ protected: Base::Matrix4D _transform; bool apply_transform; std::string objectName; + std::vector _groups; static std::string stl_header; }; diff --git a/src/Mod/Mesh/App/Mesh.cpp b/src/Mod/Mesh/App/Mesh.cpp index c95292995..a2dbe2a1e 100644 --- a/src/Mod/Mesh/App/Mesh.cpp +++ b/src/Mod/Mesh/App/Mesh.cpp @@ -340,6 +340,20 @@ void MeshObject::save(const char* file, MeshCore::MeshIO::Format f, MeshCore::MeshOutput aWriter(this->_kernel, mat); if (objectname) aWriter.SetObjectName(objectname); + + // go through the segment list and put them to the exporter when + // the "save" flag is set + std::vector groups; + for (std::size_t index = 0; index < this->_segments.size(); index++) { + if (this->_segments[index].isSaved()) { + MeshCore::Group g; + g.indices = this->_segments[index].getIndices(); + g.name = this->_segments[index].getName(); + groups.push_back(g); + } + } + aWriter.SetGroups(groups); + aWriter.Transform(this->_Mtrx); aWriter.SaveAny(file, f); } @@ -351,6 +365,20 @@ void MeshObject::save(std::ostream& str, MeshCore::MeshIO::Format f, MeshCore::MeshOutput aWriter(this->_kernel, mat); if (objectname) aWriter.SetObjectName(objectname); + + // go through the segment list and put them to the exporter when + // the "save" flag is set + std::vector groups; + for (std::size_t index = 0; index < this->_segments.size(); index++) { + if (this->_segments[index].isSaved()) { + MeshCore::Group g; + g.indices = this->_segments[index].getIndices(); + g.name = this->_segments[index].getName(); + groups.push_back(g); + } + } + aWriter.SetGroups(groups); + aWriter.Transform(this->_Mtrx); aWriter.SaveFormat(str, f); } @@ -1566,6 +1594,8 @@ MeshObject* MeshObject::createCube(float length, float width, float height, floa void MeshObject::addSegment(const Segment& s) { addSegment(s.getIndices()); + this->_segments.back().setName(s.getName()); + this->_segments.back().save(s.isSaved()); } void MeshObject::addSegment(const std::vector& inds) diff --git a/src/Mod/Mesh/App/Segment.cpp b/src/Mod/Mesh/App/Segment.cpp index 4d1c0a7f5..18ffc6fc7 100644 --- a/src/Mod/Mesh/App/Segment.cpp +++ b/src/Mod/Mesh/App/Segment.cpp @@ -32,16 +32,22 @@ #include "Segment.h" #include "Mesh.h" -#include "MeshPy.h" +#include using namespace Mesh; -Segment::Segment(MeshObject* mesh, bool mod) : _mesh(mesh), _modifykernel(mod) +Segment::Segment(MeshObject* mesh, bool mod) + : _mesh(mesh) + , _save(false) + , _modifykernel(mod) { } Segment::Segment(MeshObject* mesh, const std::vector& inds, bool mod) - : _mesh(mesh), _indices(inds), _modifykernel(mod) + : _mesh(mesh) + , _indices(inds) + , _save(false) + , _modifykernel(mod) { if (_modifykernel) _mesh->updateMesh(inds); diff --git a/src/Mod/Mesh/App/Segment.h b/src/Mod/Mesh/App/Segment.h index a8ffc8d5e..26f8876e9 100644 --- a/src/Mod/Mesh/App/Segment.h +++ b/src/Mod/Mesh/App/Segment.h @@ -50,6 +50,9 @@ public: void setName(const std::string& n) { _name = n; } const std::string& getName() const { return _name; } + void save(bool on) { _save = on; } + bool isSaved() const { return _save; } + // friends friend class MeshObject; @@ -57,6 +60,7 @@ private: MeshObject* _mesh; std::vector _indices; std::string _name; + bool _save; bool _modifykernel; public: