writeDAE.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2016 Alec Jacobson <[email protected]>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #include "writeDAE.h"
  9. #include "../STR.h"
  10. #include <tinyxml2.h>
  11. #include <map>
  12. #include <list>
  13. template <typename DerivedV, typename DerivedF>
  14. IGL_INLINE bool igl::xml::writeDAE(
  15. const std::string & filename,
  16. const Eigen::MatrixBase<DerivedV> & V,
  17. const Eigen::MatrixBase<DerivedF> & F)
  18. {
  19. tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument();
  20. const auto & ele = [&doc](
  21. const std::string tag,
  22. // Can't just use `{}` as the default argument because of a clang-bug
  23. // http://stackoverflow.com/questions/17264067/
  24. const std::map<std::string,std::string> attribs =
  25. std::map<std::string,std::string>(),
  26. const std::string text="",
  27. const std::list<tinyxml2::XMLElement *> children =
  28. std::list<tinyxml2::XMLElement *>()
  29. )->tinyxml2::XMLElement *
  30. {
  31. tinyxml2::XMLElement * element = doc->NewElement(tag.c_str());
  32. for(const auto & key_value : attribs)
  33. {
  34. element->SetAttribute(key_value.first.c_str(),key_value.second.c_str());
  35. }
  36. if(!text.empty())
  37. {
  38. element->InsertEndChild(doc->NewText(text.c_str()));
  39. }
  40. for(auto & child : children)
  41. {
  42. element->InsertEndChild(child);
  43. }
  44. return element;
  45. };
  46. Eigen::IOFormat row_format(Eigen::FullPrecision,0," "," ","","","");
  47. doc->InsertEndChild(
  48. ele("COLLADA",
  49. {
  50. {"xmlns","http://www.collada.org/2005/11/COLLADASchema"},
  51. {"version","1.4.1"}
  52. },
  53. "",
  54. {
  55. ele("asset",{},"",
  56. {
  57. ele("unit",{{"meter","0.0254000"},{"name","inch"}}),
  58. ele("up_axis",{},"Y_UP")
  59. }),
  60. ele("library_visual_scenes",{},"",
  61. {
  62. ele("visual_scene",{{"id","ID2"}},"",
  63. {
  64. ele("node",{{"name","SketchUp"}},"",
  65. {
  66. ele("node",{{"id","ID3"},{"name","group_0"}},"",
  67. {
  68. ele("matrix",{},"1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1"),
  69. ele("instance_geometry",{{"url","#ID4"}},"",
  70. {
  71. ele("bind_material",{},"",{ele("technique_common")}),
  72. }),
  73. }),
  74. }),
  75. }),
  76. }),
  77. ele("library_geometries",{},"",
  78. {
  79. ele("geometry",{{"id","ID4"}},"",
  80. {
  81. ele("mesh",{},"",
  82. {
  83. ele("source",{{"id","ID7"}},"",
  84. {
  85. ele(
  86. "float_array",
  87. {{"count",STR(V.size())},{"id","ID10"}},
  88. STR(V.format(row_format))),
  89. ele("technique_common",{},"",
  90. {
  91. ele(
  92. "accessor",
  93. {{"count",STR(V.rows())},{"source","#ID8"},{"stride","3"}},
  94. "",
  95. {
  96. ele("param",{{"name","X"},{"type","float"}}),
  97. ele("param",{{"name","Y"},{"type","float"}}),
  98. ele("param",{{"name","Z"},{"type","float"}}),
  99. })
  100. })
  101. }),
  102. ele(
  103. "vertices",
  104. {{"id","ID9"}},
  105. "",
  106. {ele("input",{{"semantic","POSITION"},{"source","#ID7"}})}),
  107. ele(
  108. "triangles",
  109. {{"count",STR(F.rows())}},
  110. "",
  111. {
  112. ele("input",{{"semantic","VERTEX"},{"source","#ID9"}}),
  113. ele("p",{},STR(F.format(row_format))),
  114. })
  115. })
  116. })
  117. }),
  118. ele("scene",{},"",{ele("instance_visual_scene",{{"url","#ID2"}})}),
  119. }));
  120. // tinyxml2 seems **not** to print the <?xml ...?> header by default, but it
  121. // also seems that that's OK
  122. tinyxml2::XMLError error = doc->SaveFile(filename.c_str());
  123. bool ret = true;
  124. if(error != tinyxml2::XML_SUCCESS)
  125. {
  126. doc->PrintError();
  127. ret = false;
  128. }
  129. delete doc;
  130. return ret;
  131. }
  132. #ifdef IGL_STATIC_LIBRARY
  133. // Explicit template instantiation
  134. // generated by autoexplicit.sh
  135. template bool igl::xml::writeDAE<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
  136. #endif