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"
#ifndef _PreComp_
# include <algorithm>
#endif
#include <CXX/Extensions.hxx>
@ -30,13 +31,13 @@
#include <Base/Console.h>
#include <Base/Interpreter.h>
#include <Base/FileInfo.h>
#include <Base/Tools.h>
#include <App/Application.h>
#include <App/Document.h>
#include <App/DocumentObjectPy.h>
#include <App/Property.h>
#include <Base/PlacementPy.h>
#include <CXX/Objects.hxx>
#include <Base/GeometryPyCXX.h>
#include <Base/VectorPy.h>
@ -299,10 +300,20 @@ private:
const MeshObject& mesh = static_cast<Mesh::Feature*>(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<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)) {
App::Property* shape = obj->getPropertyByName("Shape");
@ -314,10 +325,20 @@ private:
if (data) {
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<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
global_mesh.save(EncodedName.c_str());

View File

@ -39,6 +39,7 @@
#include <Base/Sequencer.h>
#include <Base/Stream.h>
#include <Base/Placement.h>
#include <Base/Tools.h>
#include <zipios++/gzipoutputstream.h>
#include <cmath>
@ -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,6 +1898,7 @@ bool MeshOutput::SaveOBJ (std::ostream &out) const
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 << " "
@ -1904,6 +1906,19 @@ bool MeshOutput::SaveOBJ (std::ostream &out) const
<< 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;
}

View File

@ -69,6 +69,12 @@ struct MeshExport Material
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
* in various formats.
@ -134,6 +140,10 @@ public:
virtual ~MeshOutput (void) { }
void SetObjectName(const std::string& n)
{ objectName = n; }
void SetGroups(const std::vector<Group>& 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<Group> _groups;
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);
if (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.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<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.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<unsigned long>& inds)

View File

@ -32,16 +32,22 @@
#include "Segment.h"
#include "Mesh.h"
#include "MeshPy.h"
#include <Mod/Mesh/App/MeshPy.h>
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)
: _mesh(mesh), _indices(inds), _modifykernel(mod)
: _mesh(mesh)
, _indices(inds)
, _save(false)
, _modifykernel(mod)
{
if (_modifykernel)
_mesh->updateMesh(inds);

View File

@ -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<unsigned long> _indices;
std::string _name;
bool _save;
bool _modifykernel;
public: