mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-28 19:21:20 -06:00
Building igl statically and moving to the dep scripts
Fixing dep build script on Windows and removing some warnings. Use bundled igl by default. Not building with the dependency scripts if not explicitly stated. This way, it will stay in Fix the libigl patch to include C source files in header only mode.
This commit is contained in:
parent
89e39e3895
commit
2ae2672ee9
1095 changed files with 181 additions and 5 deletions
269
src/libigl/igl/xml/ReAntTweakBarXMLSerialization.h
Normal file
269
src/libigl/igl/xml/ReAntTweakBarXMLSerialization.h
Normal file
|
|
@ -0,0 +1,269 @@
|
|||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#ifndef IGL_XML_REANTTWEAKBAR_XML_SERIALIZATION_H
|
||||
#define IGL_XML_REANTTWEAKBAR_XML_SERIALIZATION_H
|
||||
#include "../igl_inline.h"
|
||||
#include "serialize_xml.h"
|
||||
|
||||
#undef IGL_HEADER_ONLY
|
||||
#include "../anttweakbar/ReAntTweakBar.h"
|
||||
|
||||
// Forward declarations
|
||||
namespace igl
|
||||
{
|
||||
namespace anttweakbar
|
||||
{
|
||||
class ReTwBar;
|
||||
}
|
||||
};
|
||||
namespace tinyxml2
|
||||
{
|
||||
class XMLDocument;
|
||||
};
|
||||
|
||||
namespace igl
|
||||
{
|
||||
namespace xml
|
||||
{
|
||||
|
||||
// namespace
|
||||
// {
|
||||
|
||||
// IGL_INLINE bool save_ReAntTweakBar(::igl::anttweakbar::ReTwBar* bar, const char* file_name);
|
||||
// IGL_INLINE bool save_ReAntTweakBar(::igl::anttweakbar::ReTwBar* bar, tinyxml2::XMLDocument* doc);
|
||||
// IGL_INLINE bool load_ReAntTweakBar(::igl::anttweakbar::ReTwBar* bar, const char *file_name);
|
||||
// IGL_INLINE bool load_ReAntTweakBar(::igl::anttweakbar::ReTwBar* bar, tinyxml2::XMLDocument* doc);
|
||||
|
||||
|
||||
IGL_INLINE bool save_ReAntTweakBar(::igl::anttweakbar::ReTwBar* bar, const char* file_name)
|
||||
{
|
||||
const char * name_chars = TwGetBarName(bar->bar);
|
||||
std::string name = std::string(name_chars) + "_AntTweakBar";
|
||||
|
||||
const std::vector< ::igl::anttweakbar::ReTwRWItem>& rw_items = bar->get_rw_items();
|
||||
for(std::vector< ::igl::anttweakbar::ReTwRWItem>::const_iterator it = rw_items.begin(); it != rw_items.end(); it++)
|
||||
{
|
||||
std::string val = bar->get_value_as_string(it->var,it->type);
|
||||
//::igl::XMLSerializer::SaveObject(val,it->name,name,file_name,false);
|
||||
::igl::serialize_xml(val,it->name,file_name,false,false);
|
||||
}
|
||||
|
||||
char var[REANTTWEAKBAR_MAX_CB_VAR_SIZE];
|
||||
// Print all CB variables
|
||||
const std::vector< ::igl::anttweakbar::ReTwCBItem>& cb_items = bar->get_cb_items();
|
||||
for(std::vector< ::igl::anttweakbar::ReTwCBItem>::const_iterator it = cb_items.begin(); it != cb_items.end(); it++)
|
||||
{
|
||||
TwType type = it->type;
|
||||
//TwSetVarCallback setCallback = it->setCallback;
|
||||
TwGetVarCallback getCallback = it->getCallback;
|
||||
void * clientData = it->clientData;
|
||||
// I'm not sure how to do what I want to do. getCallback needs to be sure
|
||||
// that it can write to var. So var needs to point to a valid and big
|
||||
// enough chunk of memory
|
||||
getCallback(var,clientData);
|
||||
|
||||
std::string val = bar->get_value_as_string(var,type);
|
||||
//::igl::XMLSerializer::SaveObject(val,it->name,name,file_name,false);
|
||||
::igl::serialize_xml(val,it->name,file_name,false,false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*IGL_INLINE bool save_ReAntTweakBar(::igl::anttweakbar::ReTwBar* bar, tinyxml2::XMLDocument* doc)
|
||||
{
|
||||
std::vector<char**> buffer;
|
||||
|
||||
const char * name_chars = TwGetBarName(bar->bar);
|
||||
std::string name = std::string(name_chars) + "_AntTweakBar";
|
||||
::igl::XMLSerializer* s = new ::igl::XMLSerializer(name);
|
||||
|
||||
const std::vector< ::igl::anttweakbar::ReTwRWItem>& rw_items = bar->get_rw_items();
|
||||
for(std::vector< ::igl::anttweakbar::ReTwRWItem>::const_iterator it = rw_items.begin(); it != rw_items.end(); it++)
|
||||
{
|
||||
std::string val = bar->get_value_as_string(it->var,it->type);
|
||||
char** cval = new char*; // create char* on heap
|
||||
*cval = new char[val.size()+1];
|
||||
buffer.push_back(cval);
|
||||
strcpy(*cval,val.c_str());
|
||||
s->Add(*cval,it->name);
|
||||
}
|
||||
|
||||
char var[REANTTWEAKBAR_MAX_CB_VAR_SIZE];
|
||||
// Print all CB variables
|
||||
const std::vector< ::igl::anttweakbar::ReTwCBItem>& cb_items = bar->get_cb_items();
|
||||
for(std::vector< ::igl::anttweakbar::ReTwCBItem>::const_iterator it = cb_items.begin(); it != cb_items.end(); it++)
|
||||
{
|
||||
TwType type = it->type;
|
||||
//TwSetVarCallback setCallback = it->setCallback;
|
||||
TwGetVarCallback getCallback = it->getCallback;
|
||||
void * clientData = it->clientData;
|
||||
// I'm not sure how to do what I want to do. getCallback needs to be sure
|
||||
// that it can write to var. So var needs to point to a valid and big
|
||||
// enough chunk of memory
|
||||
getCallback(var,clientData);
|
||||
|
||||
std::string val = bar->get_value_as_string(var,type);
|
||||
char** cval = new char*; // create char* on heap
|
||||
*cval = new char[val.size()+1];
|
||||
buffer.push_back(cval);
|
||||
strcpy(*cval,val.c_str());
|
||||
s->Add(*cval,it->name);
|
||||
}
|
||||
|
||||
s->SaveToXMLDoc(name,doc);
|
||||
|
||||
// delete pointer buffers
|
||||
for(unsigned int i=0;i<buffer.size();i++)
|
||||
{
|
||||
delete[] *buffer[i];
|
||||
delete buffer[i];
|
||||
}
|
||||
|
||||
delete s;
|
||||
|
||||
return true;
|
||||
}*/
|
||||
|
||||
IGL_INLINE bool load_ReAntTweakBar(::igl::anttweakbar::ReTwBar* bar, const char *file_name)
|
||||
{
|
||||
char type_str[REANTTWEAKBAR_MAX_WORD];
|
||||
char value_str[REANTTWEAKBAR_MAX_WORD];
|
||||
TwType type;
|
||||
|
||||
const char * name_chars = TwGetBarName(bar->bar);
|
||||
std::string name = std::string(name_chars) + "_AntTweakBar";
|
||||
|
||||
const std::vector< ::igl::anttweakbar::ReTwRWItem>& rw_items = bar->get_rw_items();
|
||||
for(std::vector< ::igl::anttweakbar::ReTwRWItem>::const_iterator it = rw_items.begin(); it != rw_items.end(); it++)
|
||||
{
|
||||
char* val;
|
||||
//::igl::XMLSerializer::LoadObject(val,it->name,name,file_name);
|
||||
::igl::deserialize_xml(val,it->name,file_name);
|
||||
sscanf(val,"%s %[^\n]",type_str,value_str);
|
||||
|
||||
if(!bar->type_from_string(type_str,type))
|
||||
{
|
||||
printf("ERROR: %s type not found... Skipping...\n",type_str);
|
||||
continue;
|
||||
}
|
||||
|
||||
bar->set_value_from_string(it->name.c_str(),type,value_str);
|
||||
delete[] val;
|
||||
}
|
||||
|
||||
const std::vector< ::igl::anttweakbar::ReTwCBItem>& cb_items = bar->get_cb_items();
|
||||
for(std::vector< ::igl::anttweakbar::ReTwCBItem>::const_iterator it = cb_items.begin(); it != cb_items.end(); it++)
|
||||
{
|
||||
char* val;
|
||||
//::igl::XMLSerializer::LoadObject(val,it->name,name,file_name);
|
||||
::igl::deserialize_xml(val,it->name,file_name);
|
||||
sscanf(val,"%s %[^\n]",type_str,value_str);
|
||||
|
||||
if(!bar->type_from_string(type_str,type))
|
||||
{
|
||||
printf("ERROR: %s type not found... Skipping...\n",type_str);
|
||||
continue;
|
||||
}
|
||||
|
||||
bar->set_value_from_string(it->name.c_str(),type,value_str);
|
||||
delete[] val;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*IGL_INLINE bool load_ReAntTweakBar(::igl::anttweakbar::ReTwBar* bar, tinyxml2::XMLDocument* doc)
|
||||
{
|
||||
std::map<std::string,char*> variables;
|
||||
std::map<std::string,char*> cbVariables;
|
||||
|
||||
const char * name_chars = TwGetBarName(bar->bar);
|
||||
std::string name = std::string(name_chars) + "_AntTweakBar";
|
||||
::igl::XMLSerializer* s = new ::igl::XMLSerializer(name);
|
||||
|
||||
std::map<std::string,char*>::iterator iter;
|
||||
const std::vector< ::igl::anttweakbar::ReTwRWItem>& rw_items = bar->get_rw_items();
|
||||
for(std::vector< ::igl::anttweakbar::ReTwRWItem>::const_iterator it = rw_items.begin(); it != rw_items.end(); it++)
|
||||
{
|
||||
variables[it->name] = NULL;
|
||||
iter = variables.find(it->name);
|
||||
s->Add(iter->second,iter->first);
|
||||
}
|
||||
|
||||
// Add all CB variables
|
||||
const std::vector< ::igl::anttweakbar::ReTwCBItem>& cb_items = bar->get_cb_items();
|
||||
for(std::vector< ::igl::anttweakbar::ReTwCBItem>::const_iterator it = cb_items.begin(); it != cb_items.end(); it++)
|
||||
{
|
||||
cbVariables[it->name] = NULL;
|
||||
iter = cbVariables.find(it->name);
|
||||
s->Add(iter->second,iter->first);
|
||||
}
|
||||
|
||||
s->LoadFromXMLDoc(doc);
|
||||
|
||||
// Set loaded values
|
||||
char type_str[REANTTWEAKBAR_MAX_WORD];
|
||||
char value_str[REANTTWEAKBAR_MAX_WORD];
|
||||
TwType type;
|
||||
|
||||
for(iter = variables.begin(); iter != variables.end(); iter++)
|
||||
{
|
||||
if(iter->second == NULL)
|
||||
{
|
||||
printf("ERROR: '%s' entry not found... Skipping...\n",iter->first.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
sscanf(iter->second,"%s %[^\n]",type_str,value_str);
|
||||
|
||||
if(!bar->type_from_string(type_str,type))
|
||||
{
|
||||
printf("ERROR: Type '%s' of '%s' not found... Skipping...\n",type_str,iter->first.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
bar->set_value_from_string(iter->first.c_str(),type,value_str);
|
||||
}
|
||||
|
||||
for(iter = cbVariables.begin(); iter != cbVariables.end(); iter++)
|
||||
{
|
||||
if(iter->second == NULL)
|
||||
{
|
||||
printf("ERROR: '%s' entry not found... Skipping...\n",iter->first.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
sscanf(iter->second,"%s %[^\n]",type_str,value_str);
|
||||
|
||||
if(!bar->type_from_string(type_str,type))
|
||||
{
|
||||
printf("ERROR: Type '%s' of '%s' not found... Skipping...\n",type_str,iter->first.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
bar->set_value_from_string(iter->first.c_str(),type,value_str);
|
||||
}
|
||||
|
||||
// delete buffers
|
||||
for(iter = variables.begin(); iter != variables.end(); iter++)
|
||||
delete[] iter->second;
|
||||
|
||||
for(iter = cbVariables.begin(); iter != cbVariables.end(); iter++)
|
||||
delete[] iter->second;
|
||||
|
||||
delete s;
|
||||
|
||||
return true;
|
||||
}*/
|
||||
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
225
src/libigl/igl/xml/XMLSerializable.h
Normal file
225
src/libigl/igl/xml/XMLSerializable.h
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
#ifndef IGL_XML_XMLSERIALIZABLE_H
|
||||
#define IGL_XML_XMLSERIALIZABLE_H
|
||||
|
||||
#include "serialize_xml.h"
|
||||
#include "../igl_inline.h"
|
||||
#include "../serialize.h"
|
||||
|
||||
#include <tinyxml2.h>
|
||||
|
||||
|
||||
// Interface for xml-serializable class see serialize_xml.h
|
||||
|
||||
// Pretty sure all of these IGL_INLINE should be inline
|
||||
|
||||
namespace igl
|
||||
{
|
||||
namespace xml
|
||||
{
|
||||
// interface for user defined types
|
||||
struct XMLSerializableBase : public SerializableBase
|
||||
{
|
||||
virtual void Serialize(std::vector<char>& buffer) const = 0;
|
||||
virtual void Deserialize(const std::vector<char>& buffer) = 0;
|
||||
virtual void Serialize(tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element) const = 0;
|
||||
virtual void Deserialize(const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element) = 0;
|
||||
};
|
||||
|
||||
// Convenient interface for user defined types
|
||||
class XMLSerializable: public XMLSerializableBase
|
||||
{
|
||||
private:
|
||||
|
||||
template <typename T>
|
||||
struct XMLSerializationObject: public XMLSerializableBase
|
||||
{
|
||||
bool Binary;
|
||||
std::string Name;
|
||||
T* Object;
|
||||
|
||||
void Serialize(std::vector<char>& buffer) const {
|
||||
serialize(*Object,Name,buffer);
|
||||
}
|
||||
|
||||
void Deserialize(const std::vector<char>& buffer) {
|
||||
deserialize(*Object,Name,buffer);
|
||||
}
|
||||
|
||||
void Serialize(tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element) const {
|
||||
serialize_xml(*Object,Name,doc,element,Binary);
|
||||
}
|
||||
|
||||
void Deserialize(const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element) {
|
||||
deserialize_xml(*Object,Name,doc,element);
|
||||
}
|
||||
};
|
||||
|
||||
mutable bool initialized;
|
||||
mutable std::vector<XMLSerializableBase*> objects;
|
||||
|
||||
public:
|
||||
|
||||
// Override this function to add your member variables which should be serialized
|
||||
IGL_INLINE virtual void InitSerialization() = 0;
|
||||
|
||||
// Following functions can be overridden to handle the specific events.
|
||||
// Return false to prevent the de-/serialization of an object.
|
||||
IGL_INLINE virtual bool PreSerialization() const;
|
||||
IGL_INLINE virtual void PostSerialization() const;
|
||||
IGL_INLINE virtual bool PreDeserialization();
|
||||
IGL_INLINE virtual void PostDeserialization();
|
||||
|
||||
// Default implementation of XMLSerializableBase interface
|
||||
IGL_INLINE void Serialize(std::vector<char>& buffer) const;
|
||||
IGL_INLINE void Deserialize(const std::vector<char>& buffer);
|
||||
IGL_INLINE void Serialize(tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element) const;
|
||||
IGL_INLINE void Deserialize(const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element);
|
||||
|
||||
// Default constructor, destructor, assignment and copy constructor
|
||||
IGL_INLINE XMLSerializable();
|
||||
IGL_INLINE XMLSerializable(const XMLSerializable& obj);
|
||||
IGL_INLINE ~XMLSerializable();
|
||||
IGL_INLINE XMLSerializable& operator=(const XMLSerializable& obj);
|
||||
|
||||
// Use this function to add your variables which should be serialized
|
||||
template <typename T>
|
||||
IGL_INLINE void Add(T& obj,std::string name,bool binary = false);
|
||||
};
|
||||
|
||||
// IMPLEMENTATION
|
||||
|
||||
IGL_INLINE bool XMLSerializable::PreSerialization() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
IGL_INLINE void XMLSerializable::PostSerialization() const
|
||||
{
|
||||
}
|
||||
|
||||
IGL_INLINE bool XMLSerializable::PreDeserialization()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
IGL_INLINE void XMLSerializable::PostDeserialization()
|
||||
{
|
||||
}
|
||||
|
||||
IGL_INLINE void XMLSerializable::Serialize(std::vector<char>& buffer) const
|
||||
{
|
||||
if(this->PreSerialization())
|
||||
{
|
||||
if(initialized == false)
|
||||
{
|
||||
objects.clear();
|
||||
(const_cast<XMLSerializable*>(this))->InitSerialization();
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
for(unsigned int i=0;i<objects.size();i++)
|
||||
objects[i]->Serialize(buffer);
|
||||
|
||||
this->PostSerialization();
|
||||
}
|
||||
}
|
||||
|
||||
IGL_INLINE void XMLSerializable::Deserialize(const std::vector<char>& buffer)
|
||||
{
|
||||
if(this->PreDeserialization())
|
||||
{
|
||||
if(initialized == false)
|
||||
{
|
||||
objects.clear();
|
||||
(const_cast<XMLSerializable*>(this))->InitSerialization();
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
for(unsigned int i=0;i<objects.size();i++)
|
||||
objects[i]->Deserialize(buffer);
|
||||
|
||||
this->PostDeserialization();
|
||||
}
|
||||
}
|
||||
|
||||
IGL_INLINE void XMLSerializable::Serialize(tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element) const
|
||||
{
|
||||
if(this->PreSerialization())
|
||||
{
|
||||
if(initialized == false)
|
||||
{
|
||||
objects.clear();
|
||||
(const_cast<XMLSerializable*>(this))->InitSerialization();
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
for(unsigned int i=0;i<objects.size();i++)
|
||||
objects[i]->Serialize(doc,element);
|
||||
|
||||
this->PostSerialization();
|
||||
}
|
||||
}
|
||||
|
||||
IGL_INLINE void XMLSerializable::Deserialize(const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element)
|
||||
{
|
||||
if(this->PreDeserialization())
|
||||
{
|
||||
if(initialized == false)
|
||||
{
|
||||
objects.clear();
|
||||
(const_cast<XMLSerializable*>(this))->InitSerialization();
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
for(unsigned int i=0;i<objects.size();i++)
|
||||
objects[i]->Deserialize(doc,element);
|
||||
|
||||
this->PostDeserialization();
|
||||
}
|
||||
}
|
||||
|
||||
IGL_INLINE XMLSerializable::XMLSerializable()
|
||||
{
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
IGL_INLINE XMLSerializable::XMLSerializable(const XMLSerializable& obj)
|
||||
{
|
||||
initialized = false;
|
||||
objects.clear();
|
||||
}
|
||||
|
||||
IGL_INLINE XMLSerializable::~XMLSerializable()
|
||||
{
|
||||
initialized = false;
|
||||
objects.clear();
|
||||
}
|
||||
|
||||
|
||||
IGL_INLINE XMLSerializable& XMLSerializable::operator=(const XMLSerializable& obj)
|
||||
{
|
||||
if(this != &obj)
|
||||
{
|
||||
if(initialized)
|
||||
{
|
||||
initialized = false;
|
||||
objects.clear();
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
IGL_INLINE void XMLSerializable::Add(T& obj,std::string name,bool binary)
|
||||
{
|
||||
XMLSerializationObject<T>* object = new XMLSerializationObject<T>();
|
||||
object->Binary = binary;
|
||||
object->Name = name;
|
||||
object->Object = &obj;
|
||||
|
||||
objects.push_back(object);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
489
src/libigl/igl/xml/serialization_test.skip
Normal file
489
src/libigl/igl/xml/serialization_test.skip
Normal file
|
|
@ -0,0 +1,489 @@
|
|||
//
|
||||
// Copyright (C) 2014 Christian Schüller <schuellchr@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
//#ifndef IGL_SERIALIZATION_TEST_H
|
||||
//#define IGL_SERIALIZATION_TEST_H
|
||||
|
||||
//#include <igl/Timer.h>
|
||||
#include "serialize_xml.h"
|
||||
#include "XMLSerializable.h"
|
||||
|
||||
namespace igl
|
||||
{
|
||||
namespace xml
|
||||
{
|
||||
|
||||
struct Test1111
|
||||
{
|
||||
};
|
||||
|
||||
struct Test1 : public XMLSerializable
|
||||
{
|
||||
std::string ts;
|
||||
std::vector<Test1*> tvt;
|
||||
Test1* tt;
|
||||
|
||||
Test1()
|
||||
{
|
||||
tt = NULL;
|
||||
}
|
||||
|
||||
void InitSerialization()
|
||||
{
|
||||
Add(ts,"ts",false);
|
||||
Add(tvt,"tvt");
|
||||
Add(tt,"tt");
|
||||
}
|
||||
};
|
||||
|
||||
struct Test2: public XMLSerializableBase
|
||||
{
|
||||
char tc;
|
||||
int* ti;
|
||||
std::vector<short> tvb;
|
||||
float tf;
|
||||
|
||||
Test2()
|
||||
{
|
||||
tc = '1';
|
||||
ti = NULL;
|
||||
tf = 1.0004;
|
||||
tvb.push_back(2);
|
||||
tvb.push_back(3);
|
||||
}
|
||||
|
||||
void Serialize(tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element) const
|
||||
{
|
||||
serialize_xml(tc,"tc",doc,element);
|
||||
serialize_xml(ti,"ti",doc,element);
|
||||
serialize_xml(tvb,"tvb",doc,element);
|
||||
}
|
||||
void Deserialize(const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element)
|
||||
{
|
||||
deserialize_xml(tc,"tc",doc,element);
|
||||
deserialize_xml(ti,"ti",doc,element);
|
||||
deserialize_xml(tvb,"tvb",doc,element);
|
||||
}
|
||||
void Serialize(std::vector<char>& buffer) const
|
||||
{
|
||||
serialize(tc,"tc",buffer);
|
||||
serialize(ti,"ti",buffer);
|
||||
serialize(tvb,"tvb",buffer);
|
||||
serialize(tf,"tf",buffer);
|
||||
}
|
||||
void Deserialize(const std::vector<char>& buffer)
|
||||
{
|
||||
deserialize(tc,"tc",buffer);
|
||||
deserialize(ti,"ti",buffer);
|
||||
deserialize(tvb,"tvb",buffer);
|
||||
deserialize(tf,"tf",buffer);
|
||||
}
|
||||
};
|
||||
|
||||
void serialization_test()
|
||||
{
|
||||
std::string file("test");
|
||||
|
||||
bool tbIn = true,tbOut;
|
||||
char tcIn = 't',tcOut;
|
||||
unsigned char tucIn = 'u',tucOut;
|
||||
short tsIn = 6,tsOut;
|
||||
int tiIn = -10,tiOut;
|
||||
unsigned int tuiIn = 10,tuiOut;
|
||||
float tfIn = 1.0005,tfOut;
|
||||
double tdIn = 1.000000005,tdOut;
|
||||
|
||||
int* tinpIn = NULL,*tinpOut = NULL;
|
||||
float* tfpIn = new float,*tfpOut = NULL;
|
||||
*tfpIn = 1.11101;
|
||||
|
||||
std::string tstrIn("test12345"),tstrOut;
|
||||
|
||||
Test2 tObjIn,tObjOut;
|
||||
int ti = 2;
|
||||
tObjIn.ti = &ti;
|
||||
|
||||
|
||||
Test1 test1,test2,test3;
|
||||
test1.ts = "100";
|
||||
test2.ts = "200";
|
||||
test3.ts = "300";
|
||||
|
||||
Test1 testA, testC;
|
||||
testA.tt = &test1;
|
||||
testA.ts = "test123";
|
||||
testA.tvt.push_back(&test2);
|
||||
testA.tvt.push_back(&test3);
|
||||
|
||||
Test1 testB = testA;
|
||||
testB.ts = "400";
|
||||
testB.tvt.pop_back();
|
||||
|
||||
std::pair<int,bool> tPairIn(10,true);
|
||||
std::pair<int,bool> tPairOut;
|
||||
|
||||
std::vector<int> tVector1In ={1,2,3,4,5};
|
||||
std::vector<int> tVector1Out;
|
||||
|
||||
std::pair<int,bool> p1(10,1);
|
||||
std::pair<int,bool> p2(1,0);
|
||||
std::pair<int,bool> p3(10000,1);
|
||||
std::vector<std::pair<int,bool> > tVector2In ={p1,p2,p3};
|
||||
std::vector<std::pair<int,bool> > tVector2Out;
|
||||
|
||||
std::set<std::pair<int,bool> > tSetIn ={p1,p2,p3};
|
||||
std::set<std::pair<int,bool> > tSetOut;
|
||||
|
||||
std::map<int,bool> tMapIn ={p1,p2,p3};
|
||||
std::map<int,bool> tMapOut;
|
||||
|
||||
Eigen::Matrix<float,3,3> tDenseMatrixIn;
|
||||
tDenseMatrixIn << Eigen::Matrix<float,3,3>::Random();
|
||||
tDenseMatrixIn.coeffRef(0,0) = 1.00001;
|
||||
Eigen::Matrix<float,3,3> tDenseMatrixOut;
|
||||
|
||||
Eigen::Matrix<float,3,3,Eigen::RowMajor> tDenseRowMatrixIn;
|
||||
tDenseRowMatrixIn << Eigen::Matrix<float,3,3,Eigen::RowMajor>::Random();
|
||||
Eigen::Matrix<float,3,3,Eigen::RowMajor> tDenseRowMatrixOut;
|
||||
|
||||
Eigen::SparseMatrix<double> tSparseMatrixIn;
|
||||
tSparseMatrixIn.resize(3,3);
|
||||
tSparseMatrixIn.insert(0,0) = 1.3;
|
||||
tSparseMatrixIn.insert(1,1) = 10.2;
|
||||
tSparseMatrixIn.insert(2,2) = 100.1;
|
||||
tSparseMatrixIn.finalize();
|
||||
Eigen::SparseMatrix<double> tSparseMatrixOut;
|
||||
|
||||
// binary serialization
|
||||
|
||||
serialize(tbIn,file);
|
||||
deserialize(tbOut,file);
|
||||
assert(tbIn == tbOut);
|
||||
|
||||
serialize(tcIn,file);
|
||||
deserialize(tcOut,file);
|
||||
assert(tcIn == tcOut);
|
||||
|
||||
serialize(tucIn,file);
|
||||
deserialize(tucOut,file);
|
||||
assert(tucIn == tucOut);
|
||||
|
||||
serialize(tsIn,file);
|
||||
deserialize(tsOut,file);
|
||||
assert(tsIn == tsOut);
|
||||
|
||||
serialize(tiIn,file);
|
||||
deserialize(tiOut,file);
|
||||
assert(tiIn == tiOut);
|
||||
|
||||
serialize(tuiIn,file);
|
||||
deserialize(tuiOut,file);
|
||||
assert(tuiIn == tuiOut);
|
||||
|
||||
serialize(tfIn,file);
|
||||
deserialize(tfOut,file);
|
||||
assert(tfIn == tfOut);
|
||||
|
||||
serialize(tdIn,file);
|
||||
deserialize(tdOut,file);
|
||||
assert(tdIn == tdOut);
|
||||
|
||||
serialize(tinpIn,file);
|
||||
deserialize(tinpOut,file);
|
||||
assert(tinpIn == tinpOut);
|
||||
|
||||
serialize(tfpIn,file);
|
||||
deserialize(tfpOut,file);
|
||||
assert(*tfpIn == *tfpOut);
|
||||
tfpOut = NULL;
|
||||
|
||||
serialize(tstrIn,file);
|
||||
deserialize(tstrOut,file);
|
||||
assert(tstrIn == tstrOut);
|
||||
|
||||
// updating
|
||||
serialize(tbIn,"tb",file,true);
|
||||
serialize(tcIn,"tc",file);
|
||||
serialize(tiIn,"ti",file);
|
||||
tiIn++;
|
||||
serialize(tiIn,"ti",file);
|
||||
tiIn++;
|
||||
serialize(tiIn,"ti",file);
|
||||
deserialize(tbOut,"tb",file);
|
||||
deserialize(tcOut,"tc",file);
|
||||
deserialize(tiOut,"ti",file);
|
||||
assert(tbIn == tbOut);
|
||||
assert(tcIn == tcOut);
|
||||
assert(tiIn == tiOut);
|
||||
|
||||
serialize(tsIn,"tsIn",file,true);
|
||||
serialize(tVector1In,"tVector1In",file);
|
||||
serialize(tVector2In,"tsIn",file);
|
||||
deserialize(tVector2Out,"tsIn",file);
|
||||
for(unsigned int i=0;i<tVector2In.size();i++)
|
||||
{
|
||||
assert(tVector2In[i].first == tVector2Out[i].first);
|
||||
assert(tVector2In[i].second == tVector2Out[i].second);
|
||||
}
|
||||
tVector2Out.clear();
|
||||
|
||||
serialize(tObjIn,file);
|
||||
deserialize(tObjOut,file);
|
||||
assert(tObjIn.tc == tObjOut.tc);
|
||||
assert(*tObjIn.ti == *tObjOut.ti);
|
||||
for(unsigned int i=0;i<tObjIn.tvb.size();i++)
|
||||
assert(tObjIn.tvb[i] == tObjOut.tvb[i]);
|
||||
tObjOut.ti = NULL;
|
||||
|
||||
serialize(tPairIn,file);
|
||||
deserialize(tPairOut,file);
|
||||
assert(tPairIn.first == tPairOut.first);
|
||||
assert(tPairIn.second == tPairOut.second);
|
||||
|
||||
serialize(tVector1In,file);
|
||||
deserialize(tVector1Out,file);
|
||||
for(unsigned int i=0;i<tVector1In.size();i++)
|
||||
assert(tVector1In[i] == tVector1Out[i]);
|
||||
|
||||
serialize(tVector2In,file);
|
||||
deserialize(tVector2Out,file);
|
||||
for(unsigned int i=0;i<tVector2In.size();i++)
|
||||
{
|
||||
assert(tVector2In[i].first == tVector2Out[i].first);
|
||||
assert(tVector2In[i].second == tVector2Out[i].second);
|
||||
}
|
||||
|
||||
serialize(tSetIn,file);
|
||||
deserialize(tSetOut,file);
|
||||
assert(tSetIn.size() == tSetOut.size());
|
||||
|
||||
serialize(tMapIn,file);
|
||||
deserialize(tMapOut,file);
|
||||
assert(tMapIn.size() == tMapOut.size());
|
||||
|
||||
serialize(tDenseMatrixIn,file);
|
||||
deserialize(tDenseMatrixOut,file);
|
||||
assert((tDenseMatrixIn - tDenseMatrixOut).sum() == 0);
|
||||
|
||||
serialize(tDenseRowMatrixIn,file);
|
||||
deserialize(tDenseRowMatrixOut,file);
|
||||
assert((tDenseRowMatrixIn - tDenseRowMatrixOut).sum() == 0);
|
||||
|
||||
serialize(tSparseMatrixIn,file);
|
||||
deserialize(tSparseMatrixOut,file);
|
||||
assert((tSparseMatrixIn - tSparseMatrixOut).sum() == 0);
|
||||
|
||||
serialize(testB,file);
|
||||
deserialize(testC,file);
|
||||
assert(testB.ts == testC.ts);
|
||||
assert(testB.tvt.size() == testC.tvt.size());
|
||||
for(unsigned int i=0;i<testB.tvt.size();i++)
|
||||
{
|
||||
assert(testB.tvt[i]->ts == testC.tvt[i]->ts);
|
||||
assert(testB.tvt[i]->tvt.size() == testC.tvt[i]->tvt.size());
|
||||
assert(testB.tvt[i]->tt == testC.tvt[i]->tt);
|
||||
}
|
||||
assert(testB.tt->ts == testC.tt->ts);
|
||||
assert(testB.tt->tvt.size() == testC.tt->tvt.size());
|
||||
assert(testB.tt->tt == testC.tt->tt);
|
||||
testC = Test1();
|
||||
|
||||
// big data test
|
||||
/*std::vector<std::vector<float> > bigDataIn,bigDataOut;
|
||||
for(unsigned int i=0;i<10000;i++)
|
||||
{
|
||||
std::vector<float> v;
|
||||
for(unsigned int j=0;j<10000;j++)
|
||||
{
|
||||
v.push_back(j);
|
||||
}
|
||||
bigDataIn.push_back(v);
|
||||
}
|
||||
|
||||
Timer timer;
|
||||
timer.start();
|
||||
serialize(bigDataIn,file);
|
||||
timer.stop();
|
||||
std::cout << "ser: " << timer.getElapsedTimeInMilliSec() << std::endl;
|
||||
|
||||
timer.start();
|
||||
deserialize(bigDataOut,file);
|
||||
timer.stop();
|
||||
std::cout << "des: " << timer.getElapsedTimeInMilliSec() << std::endl;
|
||||
char c;
|
||||
std::cin >> c; */
|
||||
|
||||
// xml serialization
|
||||
|
||||
serialize_xml(tbIn,file);
|
||||
deserialize_xml(tbOut,file);
|
||||
assert(tbIn == tbOut);
|
||||
|
||||
serialize_xml(tcIn,file);
|
||||
deserialize_xml(tcOut,file);
|
||||
assert(tcIn == tcOut);
|
||||
|
||||
serialize_xml(tucIn,file);
|
||||
deserialize_xml(tucOut,file);
|
||||
assert(tucIn == tucOut);
|
||||
|
||||
serialize_xml(tsIn,file);
|
||||
deserialize_xml(tsOut,file);
|
||||
assert(tsIn == tsOut);
|
||||
|
||||
serialize_xml(tiIn,file);
|
||||
deserialize_xml(tiOut,file);
|
||||
assert(tiIn == tiOut);
|
||||
|
||||
serialize_xml(tuiIn,file);
|
||||
deserialize_xml(tuiOut,file);
|
||||
assert(tuiIn == tuiOut);
|
||||
|
||||
serialize_xml(tfIn,file);
|
||||
deserialize_xml(tfOut,file);
|
||||
assert(tfIn == tfOut);
|
||||
|
||||
serialize_xml(tdIn,file);
|
||||
deserialize_xml(tdOut,file);
|
||||
assert(tdIn == tdOut);
|
||||
|
||||
serialize_xml(tinpIn,file);
|
||||
deserialize_xml(tinpOut,file);
|
||||
assert(tinpIn == tinpOut);
|
||||
|
||||
serialize_xml(tfpIn,file);
|
||||
deserialize_xml(tfpOut,file);
|
||||
assert(*tfpIn == *tfpOut);
|
||||
|
||||
serialize_xml(tstrIn,file);
|
||||
deserialize_xml(tstrOut,file);
|
||||
assert(tstrIn == tstrOut);
|
||||
|
||||
// updating
|
||||
serialize_xml(tbIn,"tb",file,false,true);
|
||||
serialize_xml(tcIn,"tc",file);
|
||||
serialize_xml(tiIn,"ti",file);
|
||||
tiIn++;
|
||||
serialize_xml(tiIn,"ti",file);
|
||||
tiIn++;
|
||||
serialize_xml(tiIn,"ti",file);
|
||||
deserialize_xml(tbOut,"tb",file);
|
||||
deserialize_xml(tcOut,"tc",file);
|
||||
deserialize_xml(tiOut,"ti",file);
|
||||
assert(tbIn == tbOut);
|
||||
assert(tcIn == tcOut);
|
||||
assert(tiIn == tiOut);
|
||||
|
||||
serialize_xml(tsIn,"tsIn",file,false,true);
|
||||
serialize_xml(tVector1In,"tVector1In",file);
|
||||
serialize_xml(tVector2In,"tsIn",file);
|
||||
deserialize_xml(tVector2Out,"tsIn",file);
|
||||
for(unsigned int i=0;i<tVector2In.size();i++)
|
||||
{
|
||||
assert(tVector2In[i].first == tVector2Out[i].first);
|
||||
assert(tVector2In[i].second == tVector2Out[i].second);
|
||||
}
|
||||
tVector2Out.clear();
|
||||
|
||||
// binarization
|
||||
serialize_xml(tVector2In,"tVector2In",file,true);
|
||||
deserialize_xml(tVector2Out,"tVector2In",file);
|
||||
for(unsigned int i=0;i<tVector2In.size();i++)
|
||||
{
|
||||
assert(tVector2In[i].first == tVector2Out[i].first);
|
||||
assert(tVector2In[i].second == tVector2Out[i].second);
|
||||
}
|
||||
|
||||
serialize_xml(tObjIn,file);
|
||||
deserialize_xml(tObjOut,file);
|
||||
assert(tObjIn.tc == tObjOut.tc);
|
||||
assert(*tObjIn.ti == *tObjOut.ti);
|
||||
for(unsigned int i=0;i<tObjIn.tvb.size();i++)
|
||||
assert(tObjIn.tvb[i] == tObjOut.tvb[i]);
|
||||
|
||||
serialize_xml(tPairIn,file);
|
||||
deserialize_xml(tPairOut,file);
|
||||
assert(tPairIn.first == tPairOut.first);
|
||||
assert(tPairIn.second == tPairOut.second);
|
||||
|
||||
serialize_xml(tVector1In,file);
|
||||
deserialize_xml(tVector1Out,file);
|
||||
for(unsigned int i=0;i<tVector1In.size();i++)
|
||||
assert(tVector1In[i] == tVector1Out[i]);
|
||||
|
||||
serialize_xml(tVector2In,file);
|
||||
deserialize_xml(tVector2Out,file);
|
||||
for(unsigned int i=0;i<tVector2In.size();i++)
|
||||
{
|
||||
assert(tVector2In[i].first == tVector2Out[i].first);
|
||||
assert(tVector2In[i].second == tVector2Out[i].second);
|
||||
}
|
||||
|
||||
serialize_xml(tSetIn,file);
|
||||
deserialize_xml(tSetOut,file);
|
||||
assert(tSetIn.size() == tSetOut.size());
|
||||
|
||||
serialize_xml(tMapIn,file);
|
||||
deserialize_xml(tMapOut,file);
|
||||
assert(tMapIn.size() == tMapOut.size());
|
||||
|
||||
serialize_xml(tDenseMatrixIn,file);
|
||||
deserialize_xml(tDenseMatrixOut,file);
|
||||
assert((tDenseMatrixIn - tDenseMatrixOut).sum() == 0);
|
||||
|
||||
serialize_xml(tDenseRowMatrixIn,file);
|
||||
deserialize_xml(tDenseRowMatrixOut,file);
|
||||
assert((tDenseRowMatrixIn - tDenseRowMatrixOut).sum() == 0);
|
||||
|
||||
serialize_xml(tSparseMatrixIn,file);
|
||||
deserialize_xml(tSparseMatrixOut,file);
|
||||
assert((tSparseMatrixIn - tSparseMatrixOut).sum() == 0);
|
||||
|
||||
serialize_xml(testB,file);
|
||||
deserialize_xml(testC,file);
|
||||
assert(testB.ts == testC.ts);
|
||||
assert(testB.tvt.size() == testC.tvt.size());
|
||||
for(unsigned int i=0;i<testB.tvt.size();i++)
|
||||
{
|
||||
assert(testB.tvt[i]->ts == testC.tvt[i]->ts);
|
||||
assert(testB.tvt[i]->tvt.size() == testC.tvt[i]->tvt.size());
|
||||
assert(testB.tvt[i]->tt == testC.tvt[i]->tt);
|
||||
}
|
||||
assert(testB.tt->ts == testC.tt->ts);
|
||||
assert(testB.tt->tvt.size() == testC.tt->tvt.size());
|
||||
assert(testB.tt->tt == testC.tt->tt);
|
||||
|
||||
// big data test
|
||||
/*std::vector<std::vector<float> > bigDataIn,bigDataOut;
|
||||
for(unsigned int i=0;i<10000;i++)
|
||||
{
|
||||
std::vector<float> v;
|
||||
for(unsigned int j=0;j<10000;j++)
|
||||
{
|
||||
v.push_back(j);
|
||||
}
|
||||
bigDataIn.push_back(v);
|
||||
}
|
||||
|
||||
Timer timer;
|
||||
timer.start();
|
||||
serialize_xml(bigDataIn,"bigDataIn",file,seRIALIZE_BINARY);
|
||||
timer.stop();
|
||||
std::cout << "ser: " << timer.getElapsedTimeInMilliSec() << std::endl;
|
||||
|
||||
timer.start();
|
||||
deserialize_xml(bigDataOut,"bigDataIn",file);
|
||||
timer.stop();
|
||||
std::cout << "des: " << timer.getElapsedTimeInMilliSec() << std::endl;
|
||||
char c;
|
||||
std::cin >> c;*/
|
||||
|
||||
std::cout << "All tests run successfully!\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//#endif
|
||||
912
src/libigl/igl/xml/serialize_xml.cpp
Normal file
912
src/libigl/igl/xml/serialize_xml.cpp
Normal file
|
|
@ -0,0 +1,912 @@
|
|||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2014 Christian Schüller <schuellchr@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include "serialize_xml.h"
|
||||
#include "../STR.h"
|
||||
#include "../serialize.h"
|
||||
#include "XMLSerializable.h"
|
||||
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <iomanip>
|
||||
|
||||
namespace igl
|
||||
{
|
||||
namespace xml
|
||||
{
|
||||
template <typename T>
|
||||
IGL_INLINE void serialize_xml(
|
||||
const T& obj,
|
||||
const std::string& filename)
|
||||
{
|
||||
serialize_xml(obj,"object",filename,false,true);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
IGL_INLINE void serialize_xml(
|
||||
const T& obj,
|
||||
const std::string& objectName,
|
||||
const std::string& filename,
|
||||
bool binary,
|
||||
bool overwrite)
|
||||
{
|
||||
tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument();
|
||||
|
||||
if(overwrite == false)
|
||||
{
|
||||
// Check if file exists
|
||||
tinyxml2::XMLError error = doc->LoadFile(filename.c_str());
|
||||
if(error != tinyxml2::XML_SUCCESS)
|
||||
{
|
||||
doc->Clear();
|
||||
}
|
||||
}
|
||||
|
||||
tinyxml2::XMLElement* element = doc->FirstChildElement("serialization");
|
||||
if(element == NULL)
|
||||
{
|
||||
element = doc->NewElement("serialization");
|
||||
doc->InsertEndChild(element);
|
||||
}
|
||||
|
||||
serialize_xml(obj,objectName,doc,element,binary);
|
||||
|
||||
// Save
|
||||
tinyxml2::XMLError error = doc->SaveFile(filename.c_str());
|
||||
if(error != tinyxml2::XML_SUCCESS)
|
||||
{
|
||||
doc->PrintError();
|
||||
}
|
||||
|
||||
delete doc;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
IGL_INLINE void serialize_xml(
|
||||
const T& obj,
|
||||
const std::string& objectName,
|
||||
tinyxml2::XMLDocument* doc,
|
||||
tinyxml2::XMLElement* element,
|
||||
bool binary)
|
||||
{
|
||||
static_assert(
|
||||
serialization_xml::is_serializable<T>::value,
|
||||
"'igl::xml::serialize_xml': type is not serializable");
|
||||
|
||||
std::string name(objectName);
|
||||
serialization_xml::encodeXMLElementName(name);
|
||||
|
||||
tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
|
||||
|
||||
if(child != NULL)
|
||||
element->DeleteChild(child);
|
||||
|
||||
child = doc->NewElement(name.c_str());
|
||||
element->InsertEndChild(child);
|
||||
|
||||
if(binary)
|
||||
{
|
||||
std::vector<char> buffer;
|
||||
serialize(obj,name,buffer);
|
||||
std::string data =
|
||||
serialization_xml::base64_encode(
|
||||
reinterpret_cast<const unsigned char*>(
|
||||
buffer.data()),buffer.size());
|
||||
|
||||
child->SetAttribute("binary",true);
|
||||
|
||||
serialization_xml::serialize(data,doc,element,name);
|
||||
}
|
||||
else
|
||||
{
|
||||
serialization_xml::serialize(obj,doc,element,name);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
IGL_INLINE void deserialize_xml(T& obj,const std::string& filename)
|
||||
{
|
||||
deserialize_xml(obj,"object",filename);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
IGL_INLINE void deserialize_xml(T& obj,const std::string& objectName,const std::string& filename)
|
||||
{
|
||||
tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument();
|
||||
|
||||
tinyxml2::XMLError error = doc->LoadFile(filename.c_str());
|
||||
if(error != tinyxml2::XML_SUCCESS)
|
||||
{
|
||||
std::cerr << "File not found!" << std::endl;
|
||||
doc->PrintError();
|
||||
doc = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
tinyxml2::XMLElement* element = doc->FirstChildElement("serialization");
|
||||
if(element == NULL)
|
||||
{
|
||||
std::cerr << "Name of object not found! Initialized with default value." << std::endl;
|
||||
obj = T();
|
||||
}
|
||||
else
|
||||
{
|
||||
deserialize_xml(obj,objectName,doc,element);
|
||||
}
|
||||
|
||||
delete doc;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
IGL_INLINE void deserialize_xml(T& obj,const std::string& objectName,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element)
|
||||
{
|
||||
static_assert(serialization::is_serializable<T>::value,"'igl::xml::deserialize_xml': type is not deserializable");
|
||||
|
||||
std::string name(objectName);
|
||||
serialization_xml::encodeXMLElementName(name);
|
||||
|
||||
const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
|
||||
if(child != NULL)
|
||||
{
|
||||
bool isBinary = false;
|
||||
const tinyxml2::XMLAttribute* attr = child->FindAttribute("binary");
|
||||
if(attr != NULL)
|
||||
{
|
||||
std::string code;
|
||||
serialization_xml::deserialize(code,doc,element,name);
|
||||
std::string decoded = serialization_xml::base64_decode(code);
|
||||
|
||||
std::vector<char> buffer;
|
||||
std::copy(decoded.c_str(),decoded.c_str()+decoded.length(),std::back_inserter(buffer));
|
||||
|
||||
deserialize(obj,name,buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
serialization_xml::deserialize(obj,doc,element,name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace serialization_xml
|
||||
{
|
||||
// fundamental types
|
||||
|
||||
template <typename T>
|
||||
IGL_INLINE typename std::enable_if<std::is_fundamental<T>::value>::type serialize(const T& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name)
|
||||
{
|
||||
tinyxml2::XMLElement* child = getElement(doc,element,name.c_str());
|
||||
child->SetAttribute("val",obj);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
IGL_INLINE typename std::enable_if<std::is_fundamental<T>::value>::type deserialize(T& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name)
|
||||
{
|
||||
const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
|
||||
if(child != NULL)
|
||||
{
|
||||
getAttribute(child->Attribute("val"),obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
obj = T();
|
||||
}
|
||||
}
|
||||
|
||||
// std::string
|
||||
|
||||
IGL_INLINE void serialize(const std::string& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name)
|
||||
{
|
||||
tinyxml2::XMLElement* child = getElement(doc,element,name.c_str());
|
||||
child->SetAttribute("val",obj.c_str());
|
||||
}
|
||||
|
||||
IGL_INLINE void deserialize(std::string& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name)
|
||||
{
|
||||
const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
|
||||
if(child != NULL)
|
||||
{
|
||||
getAttribute(child->Attribute("val"),obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
obj = std::string("");
|
||||
}
|
||||
}
|
||||
|
||||
// Serializable
|
||||
|
||||
template <typename T>
|
||||
IGL_INLINE typename std::enable_if<std::is_base_of<XMLSerializableBase,T>::value>::type serialize(const T& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name)
|
||||
{
|
||||
// Serialize object implementing Serializable interface
|
||||
const XMLSerializableBase& object = dynamic_cast<const XMLSerializableBase&>(obj);
|
||||
|
||||
tinyxml2::XMLElement* child = getElement(doc,element,name.c_str());
|
||||
object.Serialize(doc,child);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
IGL_INLINE typename std::enable_if<std::is_base_of<XMLSerializableBase,T>::value>::type deserialize(T& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name)
|
||||
{
|
||||
const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
|
||||
|
||||
if(child != NULL)
|
||||
{
|
||||
obj.Deserialize(doc,child);
|
||||
}
|
||||
else
|
||||
{
|
||||
obj = T();
|
||||
}
|
||||
}
|
||||
|
||||
// STL containers
|
||||
|
||||
template <typename T1,typename T2>
|
||||
IGL_INLINE void serialize(const std::pair<T1,T2>& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name)
|
||||
{
|
||||
tinyxml2::XMLElement* pair = getElement(doc,element,name.c_str());
|
||||
serialize(obj.first,doc,pair,"first");
|
||||
serialize(obj.second,doc,pair,"second");
|
||||
}
|
||||
|
||||
template <typename T1,typename T2>
|
||||
IGL_INLINE void deserialize(std::pair<T1,T2>& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name)
|
||||
{
|
||||
const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
|
||||
if(child != NULL)
|
||||
{
|
||||
deserialize(obj.first,doc,child,"first");
|
||||
deserialize(obj.second,doc,child,"second");
|
||||
}
|
||||
else
|
||||
{
|
||||
obj.first = T1();
|
||||
obj.second = T2();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T1,typename T2>
|
||||
IGL_INLINE void serialize(const std::vector<T1,T2>& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name)
|
||||
{
|
||||
tinyxml2::XMLElement* vector = getElement(doc,element,name.c_str());
|
||||
vector->SetAttribute("size",(unsigned int)obj.size());
|
||||
|
||||
std::stringstream num;
|
||||
for(unsigned int i=0;i<obj.size();i++)
|
||||
{
|
||||
num.str("");
|
||||
num << "value" << i;
|
||||
serialize(obj[i],doc,vector,num.str());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T1,typename T2>
|
||||
IGL_INLINE void deserialize(std::vector<T1,T2>& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name)
|
||||
{
|
||||
obj.clear();
|
||||
|
||||
const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
|
||||
if(child != NULL)
|
||||
{
|
||||
unsigned int size = child->UnsignedAttribute("size");
|
||||
obj.resize(size);
|
||||
|
||||
std::stringstream num;
|
||||
for(unsigned int i=0;i<size;i++)
|
||||
{
|
||||
num.str("");
|
||||
num << "value" << i;
|
||||
|
||||
deserialize(obj[i],doc,child,num.str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
obj.clear();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
IGL_INLINE void serialize(const std::set<T>& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name)
|
||||
{
|
||||
tinyxml2::XMLElement* set = getElement(doc,element,name.c_str());
|
||||
set->SetAttribute("size",(unsigned int)obj.size());
|
||||
|
||||
std::stringstream num;
|
||||
typename std::set<T>::iterator iter = obj.begin();
|
||||
for(int i=0;iter!=obj.end();iter++,i++)
|
||||
{
|
||||
num.str("");
|
||||
num << "value" << i;
|
||||
serialize((T)*iter,doc,set,num.str());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
IGL_INLINE void deserialize(std::set<T>& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name)
|
||||
{
|
||||
obj.clear();
|
||||
|
||||
const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
|
||||
if(child != NULL)
|
||||
{
|
||||
unsigned int size = child->UnsignedAttribute("size");
|
||||
|
||||
std::stringstream num;
|
||||
typename std::set<T>::iterator iter = obj.begin();
|
||||
for(int i=0;i<size;i++)
|
||||
{
|
||||
num.str("");
|
||||
num << "value" << i;
|
||||
|
||||
T val;
|
||||
deserialize(val,doc,child,num.str());
|
||||
obj.insert(val);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
obj.clear();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T1,typename T2>
|
||||
IGL_INLINE void serialize(const std::map<T1,T2>& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name)
|
||||
{
|
||||
tinyxml2::XMLElement* map = getElement(doc,element,name.c_str());
|
||||
map->SetAttribute("size",(unsigned int)obj.size());
|
||||
|
||||
std::stringstream num;
|
||||
typename std::map<T1,T2>::const_iterator iter = obj.cbegin();
|
||||
for(int i=0;iter!=obj.end();iter++,i++)
|
||||
{
|
||||
num.str("");
|
||||
num << "value" << i;
|
||||
serialize((std::pair<T1,T2>)*iter,doc,map,num.str());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T1,typename T2>
|
||||
IGL_INLINE void deserialize(std::map<T1,T2>& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name)
|
||||
{
|
||||
obj.clear();
|
||||
|
||||
const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
|
||||
if(child != NULL)
|
||||
{
|
||||
unsigned int size = child->UnsignedAttribute("size");
|
||||
|
||||
std::stringstream num;
|
||||
typename std::map<T1,T2>::iterator iter = obj.begin();
|
||||
for(int i=0;i<size;i++)
|
||||
{
|
||||
num.str("");
|
||||
num << "value" << i;
|
||||
|
||||
std::pair<T1,T2> pair;
|
||||
deserialize(pair,doc,child,num.str());
|
||||
obj.insert(pair);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
obj.clear();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T,int R,int C,int P,int MR,int MC>
|
||||
IGL_INLINE void serialize(
|
||||
const Eigen::Matrix<T,R,C,P,MR,MC>& obj,
|
||||
const std::string& name,
|
||||
const std::function<std::string(const T &) >& to_string,
|
||||
tinyxml2::XMLDocument* doc,
|
||||
tinyxml2::XMLElement* element)
|
||||
{
|
||||
tinyxml2::XMLElement* matrix = getElement(doc,element,name.c_str());
|
||||
|
||||
const unsigned int rows = obj.rows();
|
||||
const unsigned int cols = obj.cols();
|
||||
|
||||
matrix->SetAttribute("rows",rows);
|
||||
matrix->SetAttribute("cols",cols);
|
||||
|
||||
std::stringstream ms;
|
||||
ms << "\n";
|
||||
for(unsigned int r=0;r<rows;r++)
|
||||
{
|
||||
for(unsigned int c=0;c<cols;c++)
|
||||
{
|
||||
ms << to_string(obj(r,c)) << ",";
|
||||
}
|
||||
ms << "\n";
|
||||
}
|
||||
|
||||
std::string mString = ms.str();
|
||||
if(mString.size() > 1)
|
||||
mString[mString.size()-2] = '\0';
|
||||
|
||||
matrix->SetAttribute("matrix",mString.c_str());
|
||||
}
|
||||
|
||||
// Eigen types
|
||||
template<typename T,int R,int C,int P,int MR,int MC>
|
||||
IGL_INLINE void serialize(
|
||||
const Eigen::Matrix<T,R,C,P,MR,MC>& obj,
|
||||
tinyxml2::XMLDocument* doc,
|
||||
tinyxml2::XMLElement* element,
|
||||
const std::string& name)
|
||||
{
|
||||
const std::function<std::string(const T &) > to_string =
|
||||
[](const T & v)->std::string
|
||||
{
|
||||
return
|
||||
STR(std::setprecision(std::numeric_limits<double>::digits10+2)<<v);
|
||||
};
|
||||
serialize(obj,name,to_string,doc,element);
|
||||
}
|
||||
template<typename T,int R,int C,int P,int MR,int MC>
|
||||
IGL_INLINE void deserialize(
|
||||
const tinyxml2::XMLDocument* doc,
|
||||
const tinyxml2::XMLElement* element,
|
||||
const std::string& name,
|
||||
const std::function<void(const std::string &,T &)> & from_string,
|
||||
Eigen::Matrix<T,R,C,P,MR,MC>& obj)
|
||||
{
|
||||
const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
|
||||
bool initialized = false;
|
||||
if(child != NULL)
|
||||
{
|
||||
const unsigned int rows = child->UnsignedAttribute("rows");
|
||||
const unsigned int cols = child->UnsignedAttribute("cols");
|
||||
|
||||
if(rows > 0 && cols > 0)
|
||||
{
|
||||
obj.resize(rows,cols);
|
||||
|
||||
const tinyxml2::XMLAttribute* attribute = child->FindAttribute("matrix");
|
||||
if(attribute != NULL)
|
||||
{
|
||||
std::string matTemp;
|
||||
getAttribute(attribute->Value(),matTemp);
|
||||
|
||||
std::string line,srows,scols;
|
||||
std::stringstream mats;
|
||||
mats << matTemp;
|
||||
|
||||
int r=0;
|
||||
std::string val;
|
||||
// for each line
|
||||
getline(mats,line);
|
||||
while(getline(mats,line))
|
||||
{
|
||||
// get current line
|
||||
std::stringstream liness(line);
|
||||
|
||||
for(unsigned int c=0;c<cols-1;c++)
|
||||
{
|
||||
// split line
|
||||
getline(liness,val,',');
|
||||
|
||||
// push pack the data if any
|
||||
if(!val.empty())
|
||||
{
|
||||
from_string(val,obj.coeffRef(r,c));
|
||||
}
|
||||
}
|
||||
|
||||
getline(liness,val);
|
||||
from_string(val,obj.coeffRef(r,cols-1));
|
||||
|
||||
r++;
|
||||
}
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!initialized)
|
||||
{
|
||||
obj = Eigen::Matrix<T,R,C,P,MR,MC>();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T,int R,int C,int P,int MR,int MC>
|
||||
IGL_INLINE void deserialize(
|
||||
Eigen::Matrix<T,R,C,P,MR,MC>& obj,
|
||||
const tinyxml2::XMLDocument* doc,
|
||||
const tinyxml2::XMLElement* element,
|
||||
const std::string& name)
|
||||
{
|
||||
const std::function<void(const std::string &,T &)> & from_string =
|
||||
[](const std::string & s,T & v)
|
||||
{
|
||||
getAttribute(s.c_str(),v);
|
||||
};
|
||||
deserialize(doc,element,name,from_string,obj);
|
||||
}
|
||||
|
||||
template<typename T,int P,typename I>
|
||||
IGL_INLINE void serialize(const Eigen::SparseMatrix<T,P,I>& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name)
|
||||
{
|
||||
tinyxml2::XMLElement* matrix = getElement(doc,element,name.c_str());
|
||||
|
||||
const unsigned int rows = obj.rows();
|
||||
const unsigned int cols = obj.cols();
|
||||
|
||||
matrix->SetAttribute("rows",rows);
|
||||
matrix->SetAttribute("cols",cols);
|
||||
|
||||
char buffer[200];
|
||||
std::stringstream ms;
|
||||
ms << "\n";
|
||||
for(int k=0;k<obj.outerSize();++k)
|
||||
{
|
||||
for(typename Eigen::SparseMatrix<T,P,I>::InnerIterator it(obj,k);it;++it)
|
||||
{
|
||||
tinyxml2::XMLUtil::ToStr(it.value(),buffer,200);
|
||||
ms << it.row() << "," << it.col() << "," << buffer << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
std::string mString = ms.str();
|
||||
if(mString.size() > 0)
|
||||
mString[mString.size()-1] = '\0';
|
||||
|
||||
matrix->SetAttribute("matrix",mString.c_str());
|
||||
}
|
||||
|
||||
template<typename T,int P,typename I>
|
||||
IGL_INLINE void deserialize(Eigen::SparseMatrix<T,P,I>& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name)
|
||||
{
|
||||
const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
|
||||
bool initialized = false;
|
||||
if(child != NULL)
|
||||
{
|
||||
const unsigned int rows = child->UnsignedAttribute("rows");
|
||||
const unsigned int cols = child->UnsignedAttribute("cols");
|
||||
|
||||
if(rows > 0 && cols > 0)
|
||||
{
|
||||
obj.resize(rows,cols);
|
||||
obj.setZero();
|
||||
|
||||
const tinyxml2::XMLAttribute* attribute = child->FindAttribute("matrix");
|
||||
if(attribute != NULL)
|
||||
{
|
||||
std::string matTemp;
|
||||
getAttribute(attribute->Value(),matTemp);
|
||||
|
||||
std::string line,srows,scols;
|
||||
std::stringstream mats;
|
||||
mats << matTemp;
|
||||
|
||||
std::vector<Eigen::Triplet<T,I> > triplets;
|
||||
int r=0;
|
||||
std::string val;
|
||||
|
||||
// for each line
|
||||
getline(mats,line);
|
||||
while(getline(mats,line))
|
||||
{
|
||||
// get current line
|
||||
std::stringstream liness(line);
|
||||
|
||||
// row
|
||||
getline(liness,val,',');
|
||||
int row = atoi(val.c_str());
|
||||
// col
|
||||
getline(liness,val,',');
|
||||
int col = atoi(val.c_str());
|
||||
// val
|
||||
getline(liness,val);
|
||||
T value;
|
||||
getAttribute(val.c_str(),value);
|
||||
|
||||
triplets.push_back(Eigen::Triplet<T,I>(row,col,value));
|
||||
|
||||
r++;
|
||||
}
|
||||
|
||||
obj.setFromTriplets(triplets.begin(),triplets.end());
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!initialized)
|
||||
{
|
||||
obj = Eigen::SparseMatrix<T,P,I>();
|
||||
}
|
||||
}
|
||||
|
||||
// pointers
|
||||
|
||||
template <typename T>
|
||||
IGL_INLINE typename std::enable_if<std::is_pointer<T>::value>::type serialize(const T& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name)
|
||||
{
|
||||
tinyxml2::XMLElement* pointer = getElement(doc,element,name.c_str());
|
||||
|
||||
bool isNullPtr = (obj == NULL);
|
||||
|
||||
pointer->SetAttribute("isNullPtr",isNullPtr);
|
||||
|
||||
if(isNullPtr == false)
|
||||
serialization_xml::serialize(*obj,doc,element,name);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
IGL_INLINE typename std::enable_if<std::is_pointer<T>::value>::type deserialize(T& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name)
|
||||
{
|
||||
const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
|
||||
if(child != NULL)
|
||||
{
|
||||
bool isNullPtr = child->BoolAttribute("isNullPtr");
|
||||
|
||||
if(isNullPtr)
|
||||
{
|
||||
if(obj != NULL)
|
||||
{
|
||||
std::cout << "deserialization: possible memory leak for '" << typeid(obj).name() << "'" << std::endl;
|
||||
obj = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(obj != NULL)
|
||||
std::cout << "deserialization: possible memory leak for '" << typeid(obj).name() << "'" << std::endl;
|
||||
|
||||
obj = new typename std::remove_pointer<T>::type();
|
||||
|
||||
serialization_xml::deserialize(*obj,doc,element,name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// helper functions
|
||||
|
||||
IGL_INLINE tinyxml2::XMLElement* getElement(tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name)
|
||||
{
|
||||
tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
|
||||
if(child == NULL)
|
||||
{
|
||||
child = doc->NewElement(name.c_str());
|
||||
element->InsertEndChild(child);
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
||||
IGL_INLINE void getAttribute(const char* src,bool& dest)
|
||||
{
|
||||
tinyxml2::XMLUtil::ToBool(src,&dest);
|
||||
}
|
||||
|
||||
IGL_INLINE void getAttribute(const char* src,char& dest)
|
||||
{
|
||||
dest = (char)atoi(src);
|
||||
}
|
||||
|
||||
IGL_INLINE void getAttribute(const char* src,std::string& dest)
|
||||
{
|
||||
dest = src;
|
||||
}
|
||||
|
||||
IGL_INLINE void getAttribute(const char* src,float& dest)
|
||||
{
|
||||
tinyxml2::XMLUtil::ToFloat(src,&dest);
|
||||
}
|
||||
|
||||
IGL_INLINE void getAttribute(const char* src,double& dest)
|
||||
{
|
||||
tinyxml2::XMLUtil::ToDouble(src,&dest);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
IGL_INLINE typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value>::type getAttribute(const char* src,T& dest)
|
||||
{
|
||||
unsigned int val;
|
||||
tinyxml2::XMLUtil::ToUnsigned(src,&val);
|
||||
dest = (T)val;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
IGL_INLINE typename std::enable_if<std::is_integral<T>::value && !std::is_unsigned<T>::value>::type getAttribute(const char* src,T& dest)
|
||||
{
|
||||
int val;
|
||||
tinyxml2::XMLUtil::ToInt(src,&val);
|
||||
dest = (T)val;
|
||||
}
|
||||
|
||||
// tinyXML2 related stuff
|
||||
static const int numForbiddenChars = 8;
|
||||
static const char forbiddenChars[] ={' ','/','~','#','&','>','<','='};
|
||||
|
||||
IGL_INLINE void replaceSubString(std::string& str,const std::string& search,const std::string& replace)
|
||||
{
|
||||
size_t pos = 0;
|
||||
while((pos = str.find(search,pos)) != std::string::npos)
|
||||
{
|
||||
str.replace(pos,search.length(),replace);
|
||||
pos += replace.length();
|
||||
}
|
||||
}
|
||||
|
||||
IGL_INLINE void encodeXMLElementName(std::string& name)
|
||||
{
|
||||
// must not start with a digit
|
||||
if(isdigit(*name.begin()))
|
||||
{
|
||||
name = ":::" + name;
|
||||
}
|
||||
|
||||
std::stringstream stream;
|
||||
for(int i=0;i<numForbiddenChars;i++)
|
||||
{
|
||||
std::string search;
|
||||
search = forbiddenChars[i];
|
||||
std::stringstream replaces;
|
||||
replaces << ":" << (int)forbiddenChars[i];
|
||||
std::string replace = replaces.str();
|
||||
|
||||
replaceSubString(name,search,replace);
|
||||
}
|
||||
}
|
||||
|
||||
IGL_INLINE void decodeXMLElementName(std::string& name)
|
||||
{
|
||||
if(name.find("::",0) == 0)
|
||||
name.replace(0,3,"");
|
||||
|
||||
for(auto chr : forbiddenChars)
|
||||
{
|
||||
std::stringstream searchs;
|
||||
searchs << ":" << (int)chr;
|
||||
std::string search = searchs.str();
|
||||
std::string replace;
|
||||
replace = chr;
|
||||
|
||||
replaceSubString(name,search,replace);
|
||||
}
|
||||
}
|
||||
|
||||
/* Copyright(C) 2004-2008 Ren<65> Nyffenegger
|
||||
|
||||
This source code is provided 'as-is',without any express or implied
|
||||
warranty.In no event will the author be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications,and to alter it and redistribute it
|
||||
freely,subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code.If you use this source code
|
||||
in a product,an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such,and must not be
|
||||
misrepresented as being the original source code.
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Ren<EFBFBD> Nyffenegger rene.nyffenegger@adp-gmbh.ch
|
||||
*/
|
||||
|
||||
static const std::string base64_chars =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
|
||||
static inline bool is_base64(unsigned char c) {
|
||||
return (isalnum(c) || (c == '+') || (c == '/'));
|
||||
}
|
||||
|
||||
std::string base64_encode(unsigned char const* bytes_to_encode,unsigned int in_len)
|
||||
{
|
||||
std::string ret;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
unsigned char char_array_3[3];
|
||||
unsigned char char_array_4[4];
|
||||
|
||||
while(in_len--) {
|
||||
char_array_3[i++] = *(bytes_to_encode++);
|
||||
if(i == 3) {
|
||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||
|
||||
for(i = 0; (i <4) ; i++)
|
||||
ret += base64_chars[char_array_4[i]];
|
||||
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(i)
|
||||
{
|
||||
for(j = i; j < 3; j++)
|
||||
char_array_3[j] = '\0';
|
||||
|
||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||
|
||||
for(j = 0; (j < i + 1); j++)
|
||||
ret += base64_chars[char_array_4[j]];
|
||||
|
||||
while((i++ < 3))
|
||||
ret += '=';
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string base64_decode(std::string const& encoded_string)
|
||||
{
|
||||
int in_len = encoded_string.size();
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int in_ = 0;
|
||||
unsigned char char_array_4[4],char_array_3[3];
|
||||
std::string ret;
|
||||
|
||||
// construct fast lookup table
|
||||
// added by Christian Sch<63>ller (schuellc@inf.ethz.ch)
|
||||
int charLookup[200];
|
||||
for(int i=0;i<(int)(base64_chars.length());i++)
|
||||
charLookup[(int)base64_chars[i]] = i;
|
||||
|
||||
while(in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
|
||||
char_array_4[i++] = encoded_string[in_]; in_++;
|
||||
if(i ==4) {
|
||||
for(i = 0; i <4; i++)
|
||||
char_array_4[i] = charLookup[char_array_4[i]]; // new fast lookup
|
||||
//char_array_4[i] = base64_chars.find(char_array_4[i]); // original version
|
||||
|
||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||
|
||||
for(i = 0; (i < 3); i++)
|
||||
ret += char_array_3[i];
|
||||
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(i) {
|
||||
for(j = i; j <4; j++)
|
||||
char_array_4[j] = 0;
|
||||
|
||||
for(j = 0; j <4; j++)
|
||||
char_array_4[j] = base64_chars.find(char_array_4[j]);
|
||||
|
||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||
|
||||
for(j = 0; (j < i - 1);
|
||||
j++) ret += char_array_3[j];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef IGL_STATIC_LIBRARY
|
||||
// Explicit template instantiation
|
||||
template void igl::xml::serialize_xml<std::vector<float, std::allocator<float> > >(std::vector<float, std::allocator<float> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, bool);
|
||||
template void igl::xml::deserialize_xml<std::vector<float, std::allocator<float> > >(std::vector<float, std::allocator<float> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&);
|
||||
#endif
|
||||
247
src/libigl/igl/xml/serialize_xml.h
Normal file
247
src/libigl/igl/xml/serialize_xml.h
Normal file
|
|
@ -0,0 +1,247 @@
|
|||
//
|
||||
// Copyright (C) 2014 Christian Sch<63>ller <schuellchr@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#ifndef IGL_XML_SERIALIZABLE_XML_H
|
||||
#define IGL_XML_SERIALIZABLE_XML_H
|
||||
// -----------------------------------------------------------------------------
|
||||
// Functions to save and load a serialization of fundamental c++ data types to
|
||||
// and from a xml file. STL containers, Eigen matrix types and nested data
|
||||
// structures are also supported. To serialize a user defined class implement
|
||||
// the interface XMLSerializable or XMLSerializableBase.
|
||||
//
|
||||
// See also: serialize.h
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#include "../igl_inline.h"
|
||||
|
||||
|
||||
#include <Eigen/Dense>
|
||||
#include <Eigen/Sparse>
|
||||
#include <tinyxml2.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
//#define SERIALIZE_XML(x) igl::xml::serialize_xml(x,#x,doc,element);
|
||||
//#define DESERIALIZE_XML(x) igl::xml::deserialize_xml(x,#x,,doc,element);
|
||||
|
||||
namespace igl
|
||||
{
|
||||
namespace xml
|
||||
{
|
||||
struct XMLSerializableBase;
|
||||
// serializes the given object either to a xml file or to the provided doc data
|
||||
//
|
||||
// Templates:
|
||||
// T type of the object to serialize
|
||||
// Inputs:
|
||||
// obj object to serialize
|
||||
// objectName unique object name,used for the identification
|
||||
// filename name of the file containing the serialization
|
||||
// binary set to true to serialize the object in binary format (faster for big data)
|
||||
// overwrite set to true to overwrite an existing xml file
|
||||
// element tinyxml2 virtual representation of the current xml node
|
||||
// Outputs:
|
||||
// doc contains current tinyxml2 virtual representation of the xml data
|
||||
//
|
||||
template <typename T>
|
||||
IGL_INLINE void serialize_xml(const T& obj,const std::string& filename);
|
||||
template <typename T>
|
||||
IGL_INLINE void serialize_xml(
|
||||
const T& obj,
|
||||
const std::string& objectName,
|
||||
const std::string& filename,
|
||||
bool binary = false,
|
||||
bool overwrite = false);
|
||||
template <typename T>
|
||||
IGL_INLINE void serialize_xml(
|
||||
const T& obj,
|
||||
const std::string& objectName,
|
||||
tinyxml2::XMLDocument* doc,
|
||||
tinyxml2::XMLElement* element,
|
||||
bool binary = false);
|
||||
|
||||
// deserializes the given data from a xml file or doc data back to the provided object
|
||||
//
|
||||
// Templates:
|
||||
// T type of the object to serialize
|
||||
// Inputs:
|
||||
//
|
||||
// objectName unique object name,used for the identification
|
||||
// filename name of the file containing the serialization
|
||||
// binary set to true to serialize the object in binary format (faster for big data)
|
||||
// overwrite set to true to overwrite an existing xml file
|
||||
// doc contains current tinyxml2 virtual representation of the xml data
|
||||
// element tinyxml2 virtual representation of the current xml node
|
||||
// Outputs:
|
||||
// obj object to load back serialization to
|
||||
//
|
||||
template <typename T>
|
||||
IGL_INLINE void deserialize_xml(T& obj,const std::string& filename);
|
||||
template <typename T>
|
||||
IGL_INLINE void deserialize_xml(T& obj,const std::string& objectName,const std::string& filename);
|
||||
template <typename T>
|
||||
IGL_INLINE void deserialize_xml(T& obj,const std::string& objectName,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element);
|
||||
|
||||
// internal functions
|
||||
namespace serialization_xml
|
||||
{
|
||||
// fundamental types
|
||||
template <typename T>
|
||||
IGL_INLINE typename std::enable_if<std::is_fundamental<T>::value>::type serialize(const T& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
|
||||
template <typename T>
|
||||
IGL_INLINE typename std::enable_if<std::is_fundamental<T>::value>::type deserialize(T& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
|
||||
|
||||
// std::string
|
||||
IGL_INLINE void serialize(const std::string& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
|
||||
IGL_INLINE void deserialize(std::string& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
|
||||
|
||||
// XMLSerializableBase
|
||||
template <typename T>
|
||||
IGL_INLINE typename std::enable_if<std::is_base_of<XMLSerializableBase,T>::value>::type serialize(const T& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
|
||||
template <typename T>
|
||||
IGL_INLINE typename std::enable_if<std::is_base_of<XMLSerializableBase,T>::value>::type deserialize(T& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
|
||||
|
||||
// STL containers
|
||||
template <typename T1, typename T2>
|
||||
IGL_INLINE void serialize(const std::pair<T1,T2>& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
|
||||
template <typename T1,typename T2>
|
||||
IGL_INLINE void deserialize(std::pair<T1,T2>& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
|
||||
|
||||
template <typename T1,typename T2>
|
||||
IGL_INLINE void serialize(const std::vector<T1,T2>& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
|
||||
template <typename T1,typename T2>
|
||||
IGL_INLINE void deserialize(std::vector<T1,T2>& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
|
||||
|
||||
template <typename T>
|
||||
IGL_INLINE void serialize(const std::set<T>& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
|
||||
template <typename T>
|
||||
IGL_INLINE void deserialize(std::set<T>& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
|
||||
|
||||
template <typename T1,typename T2>
|
||||
IGL_INLINE void serialize(const std::map<T1,T2>& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
|
||||
template <typename T1,typename T2>
|
||||
IGL_INLINE void deserialize(std::map<T1,T2>& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
|
||||
|
||||
// Eigen types
|
||||
|
||||
// Serialize a Dense Eigen Matrix to xml (in the matrix= attribute,
|
||||
// awkward...)
|
||||
//
|
||||
// Inputs:
|
||||
// obj MR by MC matrix of T types
|
||||
// name name of matrix
|
||||
// to_string function converting T to string
|
||||
// Outputs:
|
||||
// doc pointer to xml document
|
||||
// element pointer to xml element
|
||||
//
|
||||
template<typename T,int R,int C,int P,int MR,int MC>
|
||||
IGL_INLINE void serialize(
|
||||
const Eigen::Matrix<T,R,C,P,MR,MC>& obj,
|
||||
const std::string& name,
|
||||
const std::function<std::string(const T &) >& to_string,
|
||||
tinyxml2::XMLDocument* doc,
|
||||
tinyxml2::XMLElement* element);
|
||||
// De-Serialize a Dense Eigen Matrix from xml (in the matrix= attribute,
|
||||
// awkward...)
|
||||
//
|
||||
// Inputs:
|
||||
// doc pointer to xml document
|
||||
// element pointer to xml element
|
||||
// name name of matrix
|
||||
// from_string function string to T
|
||||
// Outputs:
|
||||
// obj MR by MC matrix of T types
|
||||
template<typename T,int R,int C,int P,int MR,int MC>
|
||||
IGL_INLINE void deserialize(
|
||||
const tinyxml2::XMLDocument* doc,
|
||||
const tinyxml2::XMLElement* element,
|
||||
const std::string& name,
|
||||
const std::function<void(const std::string &,T &)> & from_string,
|
||||
Eigen::Matrix<T,R,C,P,MR,MC>& obj);
|
||||
|
||||
// Legacy APIs
|
||||
template<typename T,int R,int C,int P,int MR,int MC>
|
||||
IGL_INLINE void serialize(
|
||||
const Eigen::Matrix<T,R,C,P,MR,MC>& obj,
|
||||
tinyxml2::XMLDocument* doc,
|
||||
tinyxml2::XMLElement* element,
|
||||
const std::string& name);
|
||||
template<typename T,int R,int C,int P,int MR,int MC>
|
||||
IGL_INLINE void deserialize(
|
||||
Eigen::Matrix<T,R,C,P,MR,MC>& obj,
|
||||
const tinyxml2::XMLDocument* doc,
|
||||
const tinyxml2::XMLElement* element,
|
||||
const std::string& name);
|
||||
|
||||
template<typename T,int P,typename I>
|
||||
IGL_INLINE void serialize(const Eigen::SparseMatrix<T,P,I>& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
|
||||
template<typename T,int P,typename I>
|
||||
IGL_INLINE void deserialize(Eigen::SparseMatrix<T,P,I>& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
|
||||
|
||||
// raw pointers
|
||||
template <typename T>
|
||||
IGL_INLINE typename std::enable_if<std::is_pointer<T>::value>::type serialize(const T& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
|
||||
template <typename T>
|
||||
IGL_INLINE typename std::enable_if<std::is_pointer<T>::value>::type deserialize(T& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
|
||||
|
||||
// helper functions
|
||||
tinyxml2::XMLElement* getElement(tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
|
||||
IGL_INLINE void getAttribute(const char* src,bool& dest);
|
||||
IGL_INLINE void getAttribute(const char* scr,char& dest);
|
||||
IGL_INLINE void getAttribute(const char* src,std::string& dest);
|
||||
IGL_INLINE void getAttribute(const char* src,float& dest);
|
||||
IGL_INLINE void getAttribute(const char* src,double& dest);
|
||||
template<typename T>
|
||||
IGL_INLINE typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value>::type getAttribute(const char* src,T& dest);
|
||||
template<typename T>
|
||||
IGL_INLINE typename std::enable_if<std::is_integral<T>::value && !std::is_unsigned<T>::value>::type getAttribute(const char* src,T& dest);
|
||||
IGL_INLINE void replaceSubString(std::string& str,const std::string& search,const std::string& replace);
|
||||
IGL_INLINE void encodeXMLElementName(std::string& name);
|
||||
IGL_INLINE void decodeXMLElementName(std::string& name);
|
||||
IGL_INLINE std::string base64_encode(unsigned char const* bytes_to_encode,unsigned int in_len);
|
||||
IGL_INLINE std::string base64_decode(std::string const& encoded_string);
|
||||
|
||||
// compile time type serializable check
|
||||
template <typename T>
|
||||
struct is_stl_container { static const bool value = false; };
|
||||
template <typename T1,typename T2>
|
||||
struct is_stl_container<std::pair<T1,T2> > { static const bool value = true; };
|
||||
template <typename T1,typename T2>
|
||||
struct is_stl_container<std::vector<T1,T2> > { static const bool value = true; };
|
||||
template <typename T>
|
||||
struct is_stl_container<std::set<T> > { static const bool value = true; };
|
||||
template <typename T1,typename T2>
|
||||
struct is_stl_container<std::map<T1,T2> > { static const bool value = true; };
|
||||
|
||||
template <typename T>
|
||||
struct is_eigen_type { static const bool value = false; };
|
||||
template <typename T,int R,int C,int P,int MR,int MC>
|
||||
struct is_eigen_type<Eigen::Matrix<T,R,C,P,MR,MC> > { static const bool value = true; };
|
||||
template <typename T,int P,typename I>
|
||||
struct is_eigen_type<Eigen::SparseMatrix<T,P,I> > { static const bool value = true; };
|
||||
|
||||
template <typename T>
|
||||
struct is_serializable {
|
||||
using T0 = typename std::remove_pointer<T>::type;
|
||||
static const bool value = std::is_fundamental<T0>::value || std::is_same<std::string,T0>::value || std::is_base_of<XMLSerializableBase,T0>::value
|
||||
|| is_stl_container<T0>::value || is_eigen_type<T0>::value;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef IGL_STATIC_LIBRARY
|
||||
#include "serialize_xml.cpp"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
138
src/libigl/igl/xml/writeDAE.cpp
Normal file
138
src/libigl/igl/xml/writeDAE.cpp
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2016 Alec Jacobson <alecjacobson@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#include "writeDAE.h"
|
||||
#include "../STR.h"
|
||||
#include <tinyxml2.h>
|
||||
#include <map>
|
||||
#include <list>
|
||||
|
||||
template <typename DerivedV, typename DerivedF>
|
||||
IGL_INLINE bool igl::xml::writeDAE(
|
||||
const std::string & filename,
|
||||
const Eigen::PlainObjectBase<DerivedV> & V,
|
||||
const Eigen::PlainObjectBase<DerivedF> & F)
|
||||
{
|
||||
using namespace std;
|
||||
using namespace Eigen;
|
||||
using namespace tinyxml2;
|
||||
|
||||
XMLDocument* doc = new XMLDocument();
|
||||
|
||||
const auto & ele = [&doc](
|
||||
const std::string tag,
|
||||
// Can't just use `{}` as the default argument because of a clang-bug
|
||||
// http://stackoverflow.com/questions/17264067/
|
||||
const std::map<std::string,std::string> attribs =
|
||||
std::map<std::string,std::string>(),
|
||||
const std::string text="",
|
||||
const std::list<XMLElement *> children =
|
||||
std::list<XMLElement *>()
|
||||
)->XMLElement *
|
||||
{
|
||||
XMLElement * element = doc->NewElement(tag.c_str());
|
||||
for(const auto & key_value : attribs)
|
||||
{
|
||||
element->SetAttribute(key_value.first.c_str(),key_value.second.c_str());
|
||||
}
|
||||
if(!text.empty())
|
||||
{
|
||||
element->InsertEndChild(doc->NewText(text.c_str()));
|
||||
}
|
||||
for(auto & child : children)
|
||||
{
|
||||
element->InsertEndChild(child);
|
||||
}
|
||||
return element;
|
||||
};
|
||||
|
||||
Eigen::IOFormat row_format(Eigen::FullPrecision,0," "," ","","","");
|
||||
doc->InsertEndChild(
|
||||
ele("COLLADA",
|
||||
{
|
||||
{"xmlns","http://www.collada.org/2005/11/COLLADASchema"},
|
||||
{"version","1.4.1"}
|
||||
},
|
||||
"",
|
||||
{
|
||||
ele("asset",{},"",
|
||||
{
|
||||
ele("unit",{{"meter","0.0254000"},{"name","inch"}}),
|
||||
ele("up_axis",{},"Y_UP")
|
||||
}),
|
||||
ele("library_visual_scenes",{},"",
|
||||
{
|
||||
ele("visual_scene",{{"id","ID2"}},"",
|
||||
{
|
||||
ele("node",{{"name","SketchUp"}},"",
|
||||
{
|
||||
ele("node",{{"id","ID3"},{"name","group_0"}},"",
|
||||
{
|
||||
ele("matrix",{},"1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1"),
|
||||
ele("instance_geometry",{{"url","#ID4"}},"",
|
||||
{
|
||||
ele("bind_material",{},"",{ele("technique_common")}),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
ele("library_geometries",{},"",
|
||||
{
|
||||
ele("geometry",{{"id","ID4"}},"",
|
||||
{
|
||||
ele("mesh",{},"",
|
||||
{
|
||||
ele("source",{{"id","ID7"}},"",
|
||||
{
|
||||
ele(
|
||||
"float_array",
|
||||
{{"count",STR(V.size())},{"id","ID10"}},
|
||||
STR(V.format(row_format))),
|
||||
ele("technique_common",{},"",
|
||||
{
|
||||
ele(
|
||||
"accessor",
|
||||
{{"count",STR(V.rows())},{"source","#ID8"},{"stride","3"}},
|
||||
"",
|
||||
{
|
||||
ele("param",{{"name","X"},{"type","float"}}),
|
||||
ele("param",{{"name","Y"},{"type","float"}}),
|
||||
ele("param",{{"name","Z"},{"type","float"}}),
|
||||
})
|
||||
})
|
||||
}),
|
||||
ele(
|
||||
"vertices",
|
||||
{{"id","ID9"}},
|
||||
"",
|
||||
{ele("input",{{"semantic","POSITION"},{"source","#ID7"}})}),
|
||||
ele(
|
||||
"triangles",
|
||||
{{"count",STR(F.rows())}},
|
||||
"",
|
||||
{
|
||||
ele("input",{{"semantic","VERTEX"},{"source","#ID9"}}),
|
||||
ele("p",{},STR(F.format(row_format))),
|
||||
})
|
||||
})
|
||||
})
|
||||
}),
|
||||
ele("scene",{},"",{ele("instance_visual_scene",{{"url","#ID2"}})}),
|
||||
}));
|
||||
// tinyxml2 seems **not** to print the <?xml ...?> header by default, but it
|
||||
// also seems that that's OK
|
||||
XMLError error = doc->SaveFile(filename.c_str());
|
||||
bool ret = true;
|
||||
if(error != XML_NO_ERROR)
|
||||
{
|
||||
doc->PrintError();
|
||||
ret = false;
|
||||
}
|
||||
delete doc;
|
||||
return ret;
|
||||
}
|
||||
38
src/libigl/igl/xml/writeDAE.h
Normal file
38
src/libigl/igl/xml/writeDAE.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2016 Alec Jacobson <alecjacobson@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#ifndef IGL_XML_WRITEDAE_H
|
||||
#define IGL_XML_WRITEDAE_H
|
||||
#include "../igl_inline.h"
|
||||
#include <string>
|
||||
#include <Eigen/Core>
|
||||
namespace igl
|
||||
{
|
||||
namespace xml
|
||||
{
|
||||
// Write a mesh to a Collada .dae scene file. The resulting scene contains
|
||||
// a single "geometry" suitable for solid operaions (boolean union,
|
||||
// intersection, etc.) in SketchUp.
|
||||
//
|
||||
// Inputs:
|
||||
// filename path to .dae file
|
||||
// V #V by 3 list of vertex positions
|
||||
// F #F by 3 list of face indices
|
||||
// Returns true iff success
|
||||
//
|
||||
template <typename DerivedV, typename DerivedF>
|
||||
IGL_INLINE bool writeDAE(
|
||||
const std::string & filename,
|
||||
const Eigen::PlainObjectBase<DerivedV> & V,
|
||||
const Eigen::PlainObjectBase<DerivedF> & F);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef IGL_STATIC_LIBRARY
|
||||
#include "writeDAE.cpp"
|
||||
#endif
|
||||
#endif
|
||||
33
src/libigl/igl/xml/write_triangle_mesh.cpp
Normal file
33
src/libigl/igl/xml/write_triangle_mesh.cpp
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2016 Alec Jacobson <alecjacobson@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#include "write_triangle_mesh.h"
|
||||
#include "../write_triangle_mesh.h"
|
||||
#include "../pathinfo.h"
|
||||
#include "writeDAE.h"
|
||||
|
||||
template <typename DerivedV, typename DerivedF>
|
||||
IGL_INLINE bool igl::xml::write_triangle_mesh(
|
||||
const std::string str,
|
||||
const Eigen::PlainObjectBase<DerivedV>& V,
|
||||
const Eigen::PlainObjectBase<DerivedF>& F,
|
||||
const bool ascii)
|
||||
{
|
||||
using namespace std;
|
||||
// dirname, basename, extension and filename
|
||||
string d,b,e,f;
|
||||
pathinfo(str,d,b,e,f);
|
||||
// Convert extension to lower case
|
||||
std::transform(e.begin(), e.end(), e.begin(), ::tolower);
|
||||
if(e == "dae")
|
||||
{
|
||||
return writeDAE(str,V,F);
|
||||
}else
|
||||
{
|
||||
return igl::write_triangle_mesh(str,V,F,ascii);
|
||||
}
|
||||
}
|
||||
45
src/libigl/igl/xml/write_triangle_mesh.h
Normal file
45
src/libigl/igl/xml/write_triangle_mesh.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2016 Alec Jacobson <alecjacobson@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#ifndef IGL_XML_WRITE_TRIANGLE_MESH_H
|
||||
#define IGL_XML_WRITE_TRIANGLE_MESH_H
|
||||
#include "../igl_inline.h"
|
||||
|
||||
#include <Eigen/Core>
|
||||
#include <string>
|
||||
|
||||
namespace igl
|
||||
{
|
||||
namespace xml
|
||||
{
|
||||
// write mesh to a file with automatic detection of file format. supported:
|
||||
// dae, or any of the formats supported by igl::write_triangle_mesh
|
||||
//
|
||||
// Templates:
|
||||
// Scalar type for positions and vectors (will be read as double and cast
|
||||
// to Scalar)
|
||||
// Index type for indices (will be read as int and cast to Index)
|
||||
// Inputs:
|
||||
// str path to file
|
||||
// V eigen double matrix #V by 3
|
||||
// F eigen int matrix #F by 3
|
||||
// Returns true iff success
|
||||
template <typename DerivedV, typename DerivedF>
|
||||
IGL_INLINE bool write_triangle_mesh(
|
||||
const std::string str,
|
||||
const Eigen::PlainObjectBase<DerivedV>& V,
|
||||
const Eigen::PlainObjectBase<DerivedF>& F,
|
||||
const bool ascii = true);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef IGL_STATIC_LIBRARY
|
||||
# include "write_triangle_mesh.cpp"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue