support groups for export to obj format

This commit is contained in:
wmayer 2016-07-24 16:16:42 +02:00
parent 1101623760
commit 3d95e9ac4b
6 changed files with 107 additions and 14 deletions

View File

@ -22,6 +22,7 @@
#include "PreCompiled.h" #include "PreCompiled.h"
#ifndef _PreComp_ #ifndef _PreComp_
# include <algorithm>
#endif #endif
#include <CXX/Extensions.hxx> #include <CXX/Extensions.hxx>
@ -30,13 +31,13 @@
#include <Base/Console.h> #include <Base/Console.h>
#include <Base/Interpreter.h> #include <Base/Interpreter.h>
#include <Base/FileInfo.h> #include <Base/FileInfo.h>
#include <Base/Tools.h>
#include <App/Application.h> #include <App/Application.h>
#include <App/Document.h> #include <App/Document.h>
#include <App/DocumentObjectPy.h> #include <App/DocumentObjectPy.h>
#include <App/Property.h> #include <App/Property.h>
#include <Base/PlacementPy.h> #include <Base/PlacementPy.h>
#include <CXX/Objects.hxx>
#include <Base/GeometryPyCXX.h> #include <Base/GeometryPyCXX.h>
#include <Base/VectorPy.h> #include <Base/VectorPy.h>
@ -299,10 +300,20 @@ private:
const MeshObject& mesh = static_cast<Mesh::Feature*>(obj)->Mesh.getValue(); const MeshObject& mesh = static_cast<Mesh::Feature*>(obj)->Mesh.getValue();
MeshCore::MeshKernel kernel = mesh.getKernel(); MeshCore::MeshKernel kernel = mesh.getKernel();
kernel.Transform(mesh.getTransform()); kernel.Transform(mesh.getTransform());
if (global_mesh.countFacets() == 0)
unsigned long countFacets = global_mesh.countFacets();
if (countFacets == 0)
global_mesh.setKernel(kernel); global_mesh.setKernel(kernel);
else else
global_mesh.addMesh(kernel); global_mesh.addMesh(kernel);
// now create a segment for the added mesh
std::vector<unsigned long> indices;
indices.resize(global_mesh.countFacets() - countFacets);
std::generate(indices.begin(), indices.end(), Base::iotaGen<unsigned long>(countFacets));
Segment segm(&global_mesh, indices, true);
segm.setName(obj->Label.getValue());
global_mesh.addSegment(segm);
} }
else if (obj->getTypeId().isDerivedFrom(partId)) { else if (obj->getTypeId().isDerivedFrom(partId)) {
App::Property* shape = obj->getPropertyByName("Shape"); App::Property* shape = obj->getPropertyByName("Shape");
@ -312,12 +323,22 @@ private:
std::vector<Data::ComplexGeoData::Facet> aTopo; std::vector<Data::ComplexGeoData::Facet> aTopo;
const Data::ComplexGeoData* data = static_cast<App::PropertyComplexGeoData*>(shape)->getComplexData(); const Data::ComplexGeoData* data = static_cast<App::PropertyComplexGeoData*>(shape)->getComplexData();
if (data) { if (data) {
data->getFaces(aPoints, aTopo,fTolerance); data->getFaces(aPoints, aTopo, fTolerance);
mesh->addFacets(aTopo, aPoints); mesh->addFacets(aTopo, aPoints);
if (global_mesh.countFacets() == 0)
unsigned long countFacets = global_mesh.countFacets();
if (countFacets == 0)
global_mesh = *mesh; global_mesh = *mesh;
else else
global_mesh.addMesh(*mesh); global_mesh.addMesh(*mesh);
// now create a segment for the added mesh
std::vector<unsigned long> indices;
indices.resize(global_mesh.countFacets() - countFacets);
std::generate(indices.begin(), indices.end(), Base::iotaGen<unsigned long>(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 // export mesh compound
global_mesh.save(EncodedName.c_str()); global_mesh.save(EncodedName.c_str());

View File

@ -39,6 +39,7 @@
#include <Base/Sequencer.h> #include <Base/Sequencer.h>
#include <Base/Stream.h> #include <Base/Stream.h>
#include <Base/Placement.h> #include <Base/Placement.h>
#include <Base/Tools.h>
#include <zipios++/gzipoutputstream.h> #include <zipios++/gzipoutputstream.h>
#include <cmath> #include <cmath>
@ -338,7 +339,7 @@ bool MeshInput::LoadOBJ (std::istream &rstrIn)
} }
else if (boost::regex_match(line.c_str(), what, rx_g)) { else if (boost::regex_match(line.c_str(), what, rx_g)) {
new_segment = true; 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)) { else if (boost::regex_match(line.c_str(), what, rx_f3)) {
// starts a new segment // starts a new segment
@ -1897,12 +1898,26 @@ bool MeshOutput::SaveOBJ (std::ostream &out) const
seq.next(true); // allow to cancel seq.next(true); // allow to cancel
} }
// facet indices (no texture and normal indices) if (_groups.empty()) {
for (MeshFacetArray::_TConstIterator it = rFacets.begin(); it != rFacets.end(); ++it) { // facet indices (no texture and normal indices)
out << "f " << it->_aulPoints[0]+1 << " " for (MeshFacetArray::_TConstIterator it = rFacets.begin(); it != rFacets.end(); ++it) {
<< it->_aulPoints[1]+1 << " " out << "f " << it->_aulPoints[0]+1 << " "
<< it->_aulPoints[2]+1 << std::endl; << it->_aulPoints[1]+1 << " "
seq.next(true); // allow to cancel << it->_aulPoints[2]+1 << std::endl;
seq.next(true); // allow to cancel
}
}
else {
for (std::vector<Group>::const_iterator gt = _groups.begin(); gt != _groups.end(); ++gt) {
out << "g " << Base::Tools::escapedUnicodeFromUtf8(gt->name.c_str()) << std::endl;
for (std::vector<unsigned long>::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; return true;

View File

@ -69,6 +69,12 @@ struct MeshExport Material
std::vector<App::Color> diffuseColor; std::vector<App::Color> diffuseColor;
}; };
struct MeshExport Group
{
std::vector<unsigned long> indices;
std::string name;
};
/** /**
* The MeshInput class is able to read a mesh object from an input stream * The MeshInput class is able to read a mesh object from an input stream
* in various formats. * in various formats.
@ -134,6 +140,10 @@ public:
virtual ~MeshOutput (void) { } virtual ~MeshOutput (void) { }
void SetObjectName(const std::string& n) void SetObjectName(const std::string& n)
{ objectName = n; } { objectName = n; }
void SetGroups(const std::vector<Group>& g) {
_groups = g;
}
void Transform(const Base::Matrix4D&); void Transform(const Base::Matrix4D&);
/** Set custom data to the header of a binary STL. /** Set custom data to the header of a binary STL.
* If the data exceeds 80 characters then the characters too much * If the data exceeds 80 characters then the characters too much
@ -181,6 +191,7 @@ protected:
Base::Matrix4D _transform; Base::Matrix4D _transform;
bool apply_transform; bool apply_transform;
std::string objectName; std::string objectName;
std::vector<Group> _groups;
static std::string stl_header; static std::string stl_header;
}; };

View File

@ -340,6 +340,20 @@ void MeshObject::save(const char* file, MeshCore::MeshIO::Format f,
MeshCore::MeshOutput aWriter(this->_kernel, mat); MeshCore::MeshOutput aWriter(this->_kernel, mat);
if (objectname) if (objectname)
aWriter.SetObjectName(objectname); aWriter.SetObjectName(objectname);
// go through the segment list and put them to the exporter when
// the "save" flag is set
std::vector<MeshCore::Group> 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.Transform(this->_Mtrx);
aWriter.SaveAny(file, f); aWriter.SaveAny(file, f);
} }
@ -351,6 +365,20 @@ void MeshObject::save(std::ostream& str, MeshCore::MeshIO::Format f,
MeshCore::MeshOutput aWriter(this->_kernel, mat); MeshCore::MeshOutput aWriter(this->_kernel, mat);
if (objectname) if (objectname)
aWriter.SetObjectName(objectname); aWriter.SetObjectName(objectname);
// go through the segment list and put them to the exporter when
// the "save" flag is set
std::vector<MeshCore::Group> 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.Transform(this->_Mtrx);
aWriter.SaveFormat(str, f); aWriter.SaveFormat(str, f);
} }
@ -1566,6 +1594,8 @@ MeshObject* MeshObject::createCube(float length, float width, float height, floa
void MeshObject::addSegment(const Segment& s) void MeshObject::addSegment(const Segment& s)
{ {
addSegment(s.getIndices()); addSegment(s.getIndices());
this->_segments.back().setName(s.getName());
this->_segments.back().save(s.isSaved());
} }
void MeshObject::addSegment(const std::vector<unsigned long>& inds) void MeshObject::addSegment(const std::vector<unsigned long>& inds)

View File

@ -32,16 +32,22 @@
#include "Segment.h" #include "Segment.h"
#include "Mesh.h" #include "Mesh.h"
#include "MeshPy.h" #include <Mod/Mesh/App/MeshPy.h>
using namespace Mesh; 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<unsigned long>& inds, bool mod) Segment::Segment(MeshObject* mesh, const std::vector<unsigned long>& inds, bool mod)
: _mesh(mesh), _indices(inds), _modifykernel(mod) : _mesh(mesh)
, _indices(inds)
, _save(false)
, _modifykernel(mod)
{ {
if (_modifykernel) if (_modifykernel)
_mesh->updateMesh(inds); _mesh->updateMesh(inds);

View File

@ -50,6 +50,9 @@ public:
void setName(const std::string& n) { _name = n; } void setName(const std::string& n) { _name = n; }
const std::string& getName() const { return _name; } const std::string& getName() const { return _name; }
void save(bool on) { _save = on; }
bool isSaved() const { return _save; }
// friends // friends
friend class MeshObject; friend class MeshObject;
@ -57,6 +60,7 @@ private:
MeshObject* _mesh; MeshObject* _mesh;
std::vector<unsigned long> _indices; std::vector<unsigned long> _indices;
std::string _name; std::string _name;
bool _save;
bool _modifykernel; bool _modifykernel;
public: public: