support groups for export to obj format
This commit is contained in:
parent
1101623760
commit
3d95e9ac4b
|
@ -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());
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user