debugged version
This commit is contained in:
parent
de752ec206
commit
04fd13bd8a
|
@ -1,15 +1,7 @@
|
||||||
#ifndef __VCGLIB_EXPORTERDAE
|
#ifndef __VCGLIB_EXPORTERDAE
|
||||||
#define __VCGLIB_EXPORTERDAE
|
#define __VCGLIB_EXPORTERDAE
|
||||||
|
|
||||||
#include <FCollada.h>
|
#include<wrap/io_trimesh/util_dae.h>
|
||||||
#include <FCDocument/FCDocument.h>
|
|
||||||
#include <FCDocument/FCDLibrary.h>
|
|
||||||
#include <FCDocument/FCDGeometry.h>
|
|
||||||
#include <FCDocument/FCDGeometryMesh.h>
|
|
||||||
#include <FCDocument/FCDGeometrySource.h>
|
|
||||||
#include <FCDocument/FCDGeometryPolygons.h>
|
|
||||||
#include <FCDocument/FCDSceneNode.h>
|
|
||||||
#include <FCDocument/FCDGeometryInstance.h>
|
|
||||||
|
|
||||||
namespace vcg {
|
namespace vcg {
|
||||||
namespace tri {
|
namespace tri {
|
||||||
|
@ -18,212 +10,45 @@ namespace io {
|
||||||
//FCollada Library assumes that SaveMeshType::ScalarType is always a float
|
//FCollada Library assumes that SaveMeshType::ScalarType is always a float
|
||||||
|
|
||||||
template<typename SaveMeshType>
|
template<typename SaveMeshType>
|
||||||
class ExporterDAE
|
class ExporterDAE : public UtilDAE
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static int Save(SaveMeshType &m, const char * filename)
|
|
||||||
{
|
|
||||||
unsigned int ncomp = sizeof(SaveMeshType::CoordType) / sizeof(SaveMeshType::ScalarType);
|
|
||||||
FCDocument* doc = new FCDocument();
|
|
||||||
FCDGeometryLibrary* geolib = doc->GetGeometryLibrary();
|
|
||||||
FCDGeometry* geo = geolib->AddEntity();
|
|
||||||
geo->SetDaeId("vcg-mesh");
|
|
||||||
FCDGeometryMesh* mesh = geo->CreateMesh();
|
|
||||||
|
|
||||||
FCDGeometrySource* vsource = mesh->AddVertexSource();
|
|
||||||
vsource->SetDaeId("vcg-position");
|
|
||||||
vsource->SetSourceType(FUDaeGeometryInput::POSITION);
|
|
||||||
FCDGeometryPolygons* polyset = mesh->AddPolygons();
|
|
||||||
//for(UInt32List::iterator it = polyinput->indices.begin();it != polyinput->indices.end();++it)
|
|
||||||
// *it = 100;
|
|
||||||
|
|
||||||
FloatList plist(m.vert.size() * ncomp);
|
|
||||||
|
|
||||||
SaveMeshType::CoordType point;
|
|
||||||
unsigned int ii = 0;
|
|
||||||
for(FloatList::iterator it = plist.begin();it != plist.end();++it)
|
|
||||||
{
|
|
||||||
if ((ii % ncomp) == 0)
|
|
||||||
{
|
|
||||||
point = m.vert[ii / ncomp].P();
|
|
||||||
}
|
|
||||||
(*it) = point[ii % ncomp];
|
|
||||||
++ii;
|
|
||||||
}
|
|
||||||
|
|
||||||
vsource->SetSourceData(plist,ncomp);
|
|
||||||
|
|
||||||
unsigned int jj = 0;
|
|
||||||
FCDGeometryPolygonsInput* ps = mesh->GetPolygons(0)->FindInput(FUDaeGeometryInput::POSITION);
|
|
||||||
//ps->indices.resize(m.face.size() * 3);
|
|
||||||
for(SaveMeshType::FaceIterator itf = m.face.begin();itf != m.face.end();++itf)
|
|
||||||
{
|
|
||||||
if( !(*itf).IsD() )
|
|
||||||
{
|
|
||||||
polyset->AddFace(3);
|
|
||||||
ps->indices[jj] = (itf->V(0) - &(m.vert[0]));
|
|
||||||
ps->indices[jj + 1] = (itf->V(1) - &(m.vert[0]));
|
|
||||||
ps->indices[jj + 2] = (itf->V(2) - &(m.vert[0]));
|
|
||||||
jj += 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FloatList nlist;
|
|
||||||
|
|
||||||
FCDGeometrySource* nsource = mesh->AddSource();
|
|
||||||
nsource->SetDaeId("vcg-wedgenormal");
|
|
||||||
nsource->SetSourceType(FUDaeGeometryInput::NORMAL);
|
|
||||||
//in the oldmesh format of vcg library normal is always a Point3
|
|
||||||
nlist.resize(m.face.size() * 3 * 3);
|
|
||||||
|
|
||||||
unsigned int cc = 0;
|
|
||||||
jj = 0;
|
|
||||||
|
|
||||||
FCDGeometryPolygonsInput* nm = polyset->AddInput(nsource,1);
|
|
||||||
//nm->semantic = FUDaeGeometryInput::NORMAL;
|
|
||||||
nm->indices.resize(m.face.size() * 3);
|
|
||||||
|
|
||||||
for(SaveMeshType::FaceIterator fit = m.face.begin();fit != m.face.end();++fit)
|
|
||||||
{
|
|
||||||
if( !(*fit).IsD() )
|
|
||||||
{
|
|
||||||
vcg::Point3<SaveMeshType::ScalarType> norm = (((fit->V(1))->P() - (fit->V(0))->P()) ^ ((fit->V(2))->P() - (fit->V(0))->P())).Normalize();
|
|
||||||
for(unsigned int vv = 0; vv < 3;++vv)
|
|
||||||
{
|
|
||||||
nm->indices[jj + vv] = cc / 3;
|
|
||||||
for(unsigned int hh = 0; hh < 3;++hh)
|
|
||||||
{
|
|
||||||
nlist[cc] = norm[hh];
|
|
||||||
++cc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
jj += 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nsource->SetSourceData(nlist,3);
|
|
||||||
|
|
||||||
FCDSceneNode* root = doc->AddVisualScene();
|
|
||||||
root->SetDaeId("vcg-scenenode");
|
|
||||||
FCDSceneNode* scenenod = root->AddChildNode();
|
|
||||||
scenenod->AddInstance(geo);
|
|
||||||
//root->
|
|
||||||
doc->WriteToFile(FUStringConversion::ToFString(filename));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int Save(SaveMeshType &m, const char * filename,AdditionalInfo*& in)
|
static int Save(SaveMeshType &m, const char * filename,AdditionalInfo*& in)
|
||||||
{
|
{
|
||||||
unsigned int ncomp = sizeof(SaveMeshType::CoordType) / sizeof(SaveMeshType::ScalarType);
|
/*unsigned int ncomp = sizeof(SaveMeshType::CoordType) / sizeof(SaveMeshType::ScalarType);*/
|
||||||
assert(in != NULL);
|
assert(in != NULL);
|
||||||
|
|
||||||
AdditionalInfoDAE* inf = static_cast<AdditionalInfoDAE*>(in);
|
AdditionalInfoDAE* inf = static_cast<AdditionalInfoDAE*>(in);
|
||||||
InfoDAE* info = inf->dae;
|
InfoDAE* info = inf->dae;
|
||||||
FCDGeometryLibrary* geolib = info->doc->GetGeometryLibrary();
|
QDomNodeList scenelst = info->doc->elementsByTagName("scene");
|
||||||
|
//removeChildNode(scenelst,"instance_visual_scene");
|
||||||
size_t dim = geolib->GetEntityCount();
|
for(int vsscn = 0;vsscn < scenelst.size();++vsscn)
|
||||||
|
|
||||||
for(unsigned int cont = 0;cont < dim;++cont)
|
|
||||||
{
|
{
|
||||||
delete geolib->GetEntity(cont);
|
QString url = scenelst.at(vsscn).toElement().attribute("url");
|
||||||
}
|
}
|
||||||
|
|
||||||
FCDGeometry* geo = geolib->AddEntity();
|
QDomElement vsnode = info->doc->createElement("instance_visual_scene");
|
||||||
geo->SetDaeId("vcg-mesh");
|
vsnode.setAttribute("url","#vcg-scene-node");
|
||||||
FCDGeometryMesh* mesh = geo->CreateMesh();
|
scenelst.at(0).appendChild(vsnode);
|
||||||
|
|
||||||
FCDGeometrySource* vsource = mesh->AddVertexSource();
|
QDomNodeList geolib = info->doc->elementsByTagName("library_geometries");
|
||||||
vsource->SetDaeId("vcg-position");
|
assert(geolib.size() == 1);
|
||||||
vsource->SetSourceType(FUDaeGeometryInput::POSITION);
|
removeChildNode(geolib.at(0));
|
||||||
FCDGeometryPolygons* polyset = mesh->AddPolygons();
|
|
||||||
FloatList plist(m.vert.size() * ncomp);
|
|
||||||
|
|
||||||
SaveMeshType::CoordType point;
|
|
||||||
unsigned int ii = 0;
|
|
||||||
for(FloatList::iterator it = plist.begin();it != plist.end();++it)
|
|
||||||
{
|
|
||||||
if ((ii % ncomp) == 0)
|
|
||||||
{
|
|
||||||
point = m.vert[ii / ncomp].P();
|
|
||||||
}
|
|
||||||
(*it) = point[ii % ncomp];
|
|
||||||
++ii;
|
|
||||||
}
|
|
||||||
|
|
||||||
vsource->SetSourceData(plist,ncomp);
|
/*QDomElement mshnode;
|
||||||
|
mshnode.setTagName("mesh");*/
|
||||||
|
QDomElement mshnode = info->doc->createElement("mesh");
|
||||||
|
geolib.at(0).appendChild(mshnode);
|
||||||
|
QString st = info->doc->toString();
|
||||||
|
|
||||||
unsigned int jj = 0;
|
|
||||||
FCDGeometryPolygonsInput* ps = mesh->GetPolygons(0)->FindInput(FUDaeGeometryInput::POSITION);
|
|
||||||
//ps->indices.resize(m.face.size() * 3);
|
|
||||||
for(SaveMeshType::FaceIterator itf = m.face.begin();itf != m.face.end();++itf)
|
|
||||||
{
|
|
||||||
if( !(*itf).IsD() )
|
|
||||||
{
|
|
||||||
polyset->AddFace(3);
|
|
||||||
ps->indices[jj] = (itf->V(0) - &(m.vert[0]));
|
|
||||||
ps->indices[jj + 1] = (itf->V(1) - &(m.vert[0]));
|
|
||||||
ps->indices[jj + 2] = (itf->V(2) - &(m.vert[0]));
|
|
||||||
jj += 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FloatList nlist;
|
QFile file(filename);
|
||||||
|
if (!file.open(QIODevice::ReadWrite | QIODevice::Truncate))
|
||||||
FCDGeometrySource* nsource = mesh->AddSource();
|
return 1;
|
||||||
nsource->SetDaeId("vcg-wedgenormal");
|
info->doc->setContent(&file);
|
||||||
nsource->SetSourceType(FUDaeGeometryInput::NORMAL);
|
file.write(st.toAscii());
|
||||||
//in the oldmesh format of vcg library normal is always a Point3
|
file.close();
|
||||||
nlist.resize(m.face.size() * 3 * 3);
|
|
||||||
|
|
||||||
unsigned int cc = 0;
|
|
||||||
jj = 0;
|
|
||||||
|
|
||||||
FCDGeometryPolygonsInput* nm = polyset->AddInput(nsource,1);
|
|
||||||
//nm->semantic = FUDaeGeometryInput::NORMAL;
|
|
||||||
nm->indices.resize(m.face.size() * 3);
|
|
||||||
|
|
||||||
for(SaveMeshType::FaceIterator fit = m.face.begin();fit != m.face.end();++fit)
|
|
||||||
{
|
|
||||||
if( !(*fit).IsD() )
|
|
||||||
{
|
|
||||||
vcg::Point3<SaveMeshType::ScalarType> norm = (((fit->V(1))->P() - (fit->V(0))->P()) ^ ((fit->V(2))->P() - (fit->V(0))->P())).Normalize();
|
|
||||||
for(unsigned int vv = 0; vv < 3;++vv)
|
|
||||||
{
|
|
||||||
nm->indices[jj + vv] = cc / 3;
|
|
||||||
for(unsigned int hh = 0; hh < 3;++hh)
|
|
||||||
{
|
|
||||||
nlist[cc] = norm[hh];
|
|
||||||
++cc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
jj += 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nsource->SetSourceData(nlist,3);
|
|
||||||
|
|
||||||
|
|
||||||
FCDSceneNode* root = info->doc->GetVisualSceneRoot ();
|
|
||||||
FCDSceneNodeTrackList& listchild = root->GetChildren();
|
|
||||||
std::vector<FCDSceneNodeTrackList::iterator> ve;
|
|
||||||
//size_t n = listchild.size();
|
|
||||||
for(FCDSceneNodeTrackList::iterator itlc = listchild.begin();itlc != listchild.end();++itlc)
|
|
||||||
{
|
|
||||||
FCDEntityInstanceContainer& li = (*itlc)->GetInstances();
|
|
||||||
for(FCDEntityInstanceContainer::iterator itli = li.begin();itli != li.end();++itli)
|
|
||||||
{
|
|
||||||
if ((*itli)->GetEntityType() == FCDEntity::GEOMETRY)
|
|
||||||
{
|
|
||||||
ve.push_back(itlc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(std::vector<FCDSceneNodeTrackList::iterator>::iterator itld = ve.begin();itld != ve.end();++itld)
|
|
||||||
listchild.erase((*itld));
|
|
||||||
ve.clear();
|
|
||||||
root->SetDaeId("vcg-scenenode");
|
|
||||||
FCDSceneNode* scenenod = root->AddChildNode();
|
|
||||||
scenenod->AddInstance(geo);
|
|
||||||
//root->
|
|
||||||
info->doc->WriteToFile(FUStringConversion::ToFString(filename));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,177 +3,20 @@
|
||||||
|
|
||||||
//importer for collada's files
|
//importer for collada's files
|
||||||
|
|
||||||
#include <wrap/io_trimesh/additionalinfo.h>
|
#include<wrap/io_trimesh/util_dae.h>
|
||||||
#include <vcg/complex/trimesh/update/normal.h>
|
|
||||||
#include <vcg/complex/trimesh/allocate.h>
|
|
||||||
#include<map>
|
|
||||||
|
|
||||||
#include<QtXml/QDomDocument>
|
|
||||||
#include<QtCore/QFile>
|
|
||||||
#include <QtCore/QStringList>
|
|
||||||
|
|
||||||
#include<vcg/space/point3.h>
|
|
||||||
#include<vcg/space/tcoord2.h>
|
|
||||||
#include<vcg/space/color4.h>
|
|
||||||
//#include <hgrd/hgrd.h>
|
|
||||||
|
|
||||||
namespace vcg {
|
namespace vcg {
|
||||||
namespace tri {
|
namespace tri {
|
||||||
namespace io {
|
namespace io {
|
||||||
|
|
||||||
|
|
||||||
class InfoDAE : public AdditionalInfo
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
InfoDAE()
|
|
||||||
{
|
|
||||||
mask = 0;
|
|
||||||
numvert = 0;
|
|
||||||
numface = 0;
|
|
||||||
doc = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
~InfoDAE()
|
|
||||||
{
|
|
||||||
delete doc;
|
|
||||||
texturefile.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
QDomDocument* doc;
|
|
||||||
std::vector<std::string> texturefile;
|
|
||||||
};
|
|
||||||
|
|
||||||
class AdditionalInfoDAE : public AdditionalInfo
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
vcg::tri::io::InfoDAE* dae;
|
|
||||||
|
|
||||||
AdditionalInfoDAE()
|
|
||||||
:AdditionalInfo()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~AdditionalInfoDAE()
|
|
||||||
{
|
|
||||||
delete dae;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename OpenMeshType>
|
template<typename OpenMeshType>
|
||||||
class ImporterDAE
|
class ImporterDAE : public UtilDAE
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//merge all meshes in the collada's file in the templeted mesh m
|
//merge all meshes in the collada's file in the templeted mesh m
|
||||||
//I assume the mesh
|
//I assume the mesh
|
||||||
|
|
||||||
enum DAEError
|
|
||||||
{
|
|
||||||
E_NOERROR, // 0
|
|
||||||
E_CANTOPEN, // 1
|
|
||||||
E_NOGEOMETRYLIBRARY, // 2
|
|
||||||
E_NOMESH, // 3
|
|
||||||
E_NOVERTEXPOSITION, // 4
|
|
||||||
E_NO3DVERTEXPOSITION, // 5
|
|
||||||
E_NO3DSCENE, // 6
|
|
||||||
E_INCOMPATIBLECOLLADA141FORMAT, //7
|
|
||||||
E_UNREFERENCEBLEDCOLLADAATTRIBUTE, // 8
|
|
||||||
E_NOTRIANGLES
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char *ErrorMsg(int error)
|
|
||||||
{
|
|
||||||
static const char * dae_error_msg[] =
|
|
||||||
{
|
|
||||||
"No errors",
|
|
||||||
"Can't open file",
|
|
||||||
"File without a geometry library",
|
|
||||||
"There isn't mesh in file",
|
|
||||||
"The meshes in file haven't the vertex position attribute",
|
|
||||||
"The importer assumes that the OpenMeshType uses a 3D point for the vertex position",
|
|
||||||
"There isn't any scene in Collada file",
|
|
||||||
"The input file is not compatible with COLLADA 1.41 standard format",
|
|
||||||
"Collada file is trying to referece an attribute that is not in the file",
|
|
||||||
"This version of Collada Importer support only triangular mesh file"
|
|
||||||
};
|
|
||||||
|
|
||||||
if(error>9 || error<0) return "Unknown error";
|
|
||||||
else return dae_error_msg[error];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
inline static void referenceToANodeAttribute(const QDomNode& n,const QString& attr,QString& url_st)
|
|
||||||
{
|
|
||||||
url_st = n.toElement().attribute(attr);
|
|
||||||
int sz = url_st.size() - 1;
|
|
||||||
url_st = url_st.right(sz);
|
|
||||||
assert(url_st.size() != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static QDomNode findNodeBySpecificAttributeValue(const QDomNode& n,const QString& tag,const QString& attrname,const QString& attrvalue)
|
|
||||||
{
|
|
||||||
QDomNode ndl = n.toElement();
|
|
||||||
return findNodeBySpecificAttributeValue((QDomDocument&) ndl,tag,attrname,attrvalue);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static QDomNode findNodeBySpecificAttributeValue(const QDomDocument& n,const QString& tag,const QString& attrname,const QString& attrvalue)
|
|
||||||
{
|
|
||||||
QDomNodeList ndl = n.elementsByTagName(tag);
|
|
||||||
int ndl_size = ndl.size();
|
|
||||||
assert(ndl_size != 0);
|
|
||||||
int ind = 0;
|
|
||||||
while(ind < ndl_size)
|
|
||||||
{
|
|
||||||
if (ndl.at(ind).toElement().attribute(attrname) == attrvalue)
|
|
||||||
return ndl.at(ind);
|
|
||||||
++ind;
|
|
||||||
}
|
|
||||||
return QDomNode();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static bool isThereTag(const QDomNode& n,const QString& tagname)
|
|
||||||
{
|
|
||||||
QDomNode ndl = n.toElement();
|
|
||||||
return isThereTag((QDomDocument&) n,tagname);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static bool isThereTag(const QDomDocument& n,const QString& tagname)
|
|
||||||
{
|
|
||||||
return ((n.toElement().elementsByTagName(tagname).size() > 0)? true : false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline static QDomNode attributeSourcePerSimplex(const QDomNode& n,const QDomDocument& startpoint,const QString& sem)
|
|
||||||
{
|
|
||||||
QDomNodeList vertattr = n.toElement().elementsByTagName("input");
|
|
||||||
for(int ind = 0;ind < vertattr.size();++ind)
|
|
||||||
{
|
|
||||||
if (vertattr.at(ind).toElement().attribute("semantic") == sem)
|
|
||||||
{
|
|
||||||
QString url;
|
|
||||||
referenceToANodeAttribute(vertattr.at(ind),"source",url);
|
|
||||||
return findNodeBySpecificAttributeValue(startpoint,"source","id",url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QDomNode();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static void valueStringList(QStringList& res,const QDomNode& srcnode,const QString& tag)
|
|
||||||
{
|
|
||||||
QDomNodeList list = srcnode.toElement().elementsByTagName(tag);
|
|
||||||
int list_size = list.size();
|
|
||||||
assert(list_size == 1);
|
|
||||||
QString nd = list.at(0).firstChild().nodeValue();
|
|
||||||
res = nd.split(" ");
|
|
||||||
if (res.last() == "")
|
|
||||||
res.removeLast();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
static int Open(OpenMeshType& m,const char* filename,AdditionalInfo*& addinfo)
|
static int Open(OpenMeshType& m,const char* filename,AdditionalInfo*& addinfo)
|
||||||
{
|
{
|
||||||
AdditionalInfoDAE* inf = new AdditionalInfoDAE();
|
AdditionalInfoDAE* inf = new AdditionalInfoDAE();
|
||||||
|
@ -190,7 +33,7 @@ namespace io {
|
||||||
return E_CANTOPEN;
|
return E_CANTOPEN;
|
||||||
}
|
}
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
info->doc = doc;
|
info->doc = doc;
|
||||||
QDomNodeList& scenes = info->doc->elementsByTagName("scene");
|
QDomNodeList& scenes = info->doc->elementsByTagName("scene");
|
||||||
int scn_size = scenes.size();
|
int scn_size = scenes.size();
|
||||||
|
@ -459,6 +302,7 @@ namespace io {
|
||||||
|
|
||||||
if (!geoinst_found)
|
if (!geoinst_found)
|
||||||
return E_NOGEOMETRYLIBRARY;
|
return E_NOGEOMETRYLIBRARY;
|
||||||
|
addinfo = inf;
|
||||||
return E_NOERROR;
|
return E_NOERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue