Browse Source

dae collada writer

Former-commit-id: 32e54e78370c7d0e26528b61fa26ca3519f3ef58
Alec Jacobson 9 years ago
parent
commit
f6734f70be

+ 134 - 0
include/igl/xml/writeDAE.cpp

@@ -0,0 +1,134 @@
+// 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,
+    const std::map<std::string,std::string> attribs = {},
+    const std::string text="",
+    const std::list<XMLElement *> children = {}
+    )->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;
+}

+ 36 - 0
include/igl/xml/writeDAE.h

@@ -0,0 +1,36 @@
+// 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
+#ifndef IGL_STATIC_LIBRARY
+#include "../igl_inline.h"
+#include <string>
+#include <Eigen/Core>
+namespace igl
+{
+  namespace xml
+  {
+    // Write a mesh to a Collada .dae scene file
+    //
+    // 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);
+  }
+}
+
+#include "writeDAE.cpp"
+#endif
+#endif

+ 32 - 0
include/igl/xml/write_triangle_mesh.cpp

@@ -0,0 +1,32 @@
+// 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 "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 - 0
include/igl/xml/write_triangle_mesh.h

@@ -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
+