Răsfoiți Sursa

bounding box and cdt

Former-commit-id: c89a32d01443b1e7b83157741e865a8f5728ca40
Alec Jacobson 10 ani în urmă
părinte
comite
7f360c14cf

+ 85 - 0
include/igl/bounding_box.cpp

@@ -0,0 +1,85 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 "bounding_box.h"
+#include <iostream>
+
+template <typename DerivedV, typename DerivedBV, typename DerivedBF>
+IGL_INLINE void igl::bounding_box(
+  const Eigen::PlainObjectBase<DerivedV>& V,
+  Eigen::PlainObjectBase<DerivedBV>& BV,
+  Eigen::PlainObjectBase<DerivedBF>& BF)
+{
+  using namespace std;
+
+  const int dim = V.cols();
+  const auto & minV = V.colwise().minCoeff();
+  const auto & maxV = V.colwise().maxCoeff();
+  // 2^n vertices
+  BV.resize((1<<dim),dim);
+
+  // Recursive lambda to generate all 2^n combinations
+  const std::function<void(const int,const int,int*,int)> combos =
+  [&BV,&minV,&maxV,&combos](
+    const int dim,
+    const int i,
+    int * X,
+    const int pre_index)
+  {
+    for(X[i] = 0;X[i]<2;X[i]++)
+    {
+      int index = pre_index*2+X[i];
+      if((i+1)<dim)
+      {
+        combos(dim,i+1,X,index);
+      }else
+      {
+        for(int d = 0;d<dim;d++)
+        {
+          BV(index,d) = (X[d]?minV[d]:maxV[d]);
+        }
+      }
+    }
+  };
+
+  Eigen::VectorXi X(dim);
+  combos(dim,0,X.data(),0);
+  switch(dim)
+  {
+    case 2:
+      BF.resize(4,2);
+      BF<<
+        3,1,
+        1,0,
+        0,2,
+        2,3;
+      break;
+    case 3:
+      BF.resize(12,3);
+      BF<<
+        2,0,6,
+        0,4,6,
+        5,4,0,
+        5,0,1,
+        6,4,5,
+        5,7,6,
+        3,0,2,
+        1,0,3,
+        3,2,6,
+        6,7,3,
+        5,1,3,
+        3,7,5;
+      break;
+    default:
+      assert(false && "Unsupported dimension.");
+      break;
+  }
+}
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template specialization
+#endif

+ 33 - 0
include/igl/bounding_box.h

@@ -0,0 +1,33 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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_BOUNDING_BOX_H
+#define IGL_BOUNDING_BOX_H
+#include "igl_inline.h"
+#include <Eigen/Core>
+namespace igl
+{
+  // Build a triangle mesh of the bounding box of a given list of vertices
+  // 
+  // Inputs:
+  //   V  #V by dim list of rest domain positions
+  // Outputs:
+  //   BV  2^dim by dim list of bounding box corners positions
+  //   BF  #BF by dim list of simplex facets 
+  template <typename DerivedV, typename DerivedBV, typename DerivedBF>
+  IGL_INLINE void bounding_box(
+    const Eigen::PlainObjectBase<DerivedV>& V,
+    Eigen::PlainObjectBase<DerivedBV>& BV,
+    Eigen::PlainObjectBase<DerivedBF>& BF);
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "bounding_box.cpp"
+#endif
+
+#endif
+

+ 1 - 1
include/igl/cotmatrix_entries.h

@@ -1,6 +1,6 @@
 // This file is part of libigl, a simple c++ geometry processing library.
 // 
-// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
+// Copyright (C) 2014 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 

+ 66 - 0
include/igl/tetgen/cdt.cpp

@@ -0,0 +1,66 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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 "cdt.h"
+#include "../bounding_box.h"
+#include "../writeOBJ.h"
+
+template <
+  typename DerivedV, 
+  typename DerivedF, 
+  typename DerivedTV, 
+  typename DerivedTT, 
+  typename DerivedTF>
+IGL_INLINE bool igl::cdt(
+  const Eigen::PlainObjectBase<DerivedV>& V,
+  const Eigen::PlainObjectBase<DerivedF>& F,
+  const igl::CDTParam & param,
+  Eigen::PlainObjectBase<DerivedTV>& TV,
+  Eigen::PlainObjectBase<DerivedTT>& TT,
+  Eigen::PlainObjectBase<DerivedTF>& TF)
+{
+  using namespace Eigen;
+  using namespace std;
+  typedef Eigen::PlainObjectBase<DerivedV> MatrixXS;
+  typedef Eigen::PlainObjectBase<DerivedF> MatrixXI;
+  // Effective input mesh
+  MatrixXS U;
+  MatrixXI G;
+  if(param.use_bounding_box)
+  {
+    // Construct bounding box mesh
+    MatrixXS BV;
+    MatrixXI BF;
+    bounding_box(V,BV,BF);
+    // scale bounding box
+    const RowVector3d mid = 
+     (BV.colwise().minCoeff() + BV.colwise().maxCoeff()).eval()*0.5;
+    BV.rowwise() -= mid;
+    assert(param.bounding_box_scale >= 1.);
+    BV.array() *= param.bounding_box_scale;
+    BV.rowwise() += mid;
+    // Append bounding box to mesh
+    U.resize(V.rows()+BV.rows(),V.cols());
+    U<<V,BV;
+    BF.array() += V.rows();
+    G.resize(F.rows()+BF.rows(),F.cols());
+    G<<F,BF;
+  }else
+  {
+    // needless copies
+    U = V;
+    G = F;
+  }
+  // effective flags;
+  string flags = param.flags + (param.use_bounding_box ? "" : "c");
+  writeOBJ("UG.obj",U,G);
+  return tetrahedralize(U,G,flags,TV,TT,TF);
+}
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template specialization
+#endif

+ 66 - 0
include/igl/tetgen/cdt.h

@@ -0,0 +1,66 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 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_CDT_H
+#define IGL_CDT_H
+#include "../igl_inline.h"
+
+#include <Eigen/Core>
+#include <string>
+#ifndef TETLIBRARY
+#define TETLIBRARY 
+#endif
+#include "tetgen.h" // Defined REAL
+
+namespace igl
+{
+  struct CDTParam
+  {
+    // Tetgen can compute mesh of convex hull of input (i.e. "c") but often
+    // chokes. One workaround is to force it to mesh the entire bounding box.
+    // {false}
+    bool use_bounding_box = false;
+    // Scale the bounding box a bit so that vertices near it do not give tetgen
+    // problems. {1.01}
+    double bounding_box_scale = 1.01;
+    // Flags to tetgen. Do not include the "c" flag here! {"Y"}
+    std::string flags = "Y";
+  };
+  // Create a constrained delaunay tesselation containing convex hull of the
+  // given **non-selfintersecting** mesh.
+  //
+  // Inputs:
+  //    V  #V by 3 list of input mesh vertices
+  //    F  #F by 3 list of input mesh facets
+  //    param  see above
+  //    TV  #TV by 3 list of output mesh vertices (V come first)
+  //    TT  #TT by 3 list of tetrahedra indices into TV.
+  //    TF  #TF by 3 list of facets from F potentially subdivided.
+  // 
+  template <
+    typename DerivedV, 
+    typename DerivedF, 
+    typename DerivedTV, 
+    typename DerivedTT, 
+    typename DerivedTF>
+  IGL_INLINE bool cdt(
+    const Eigen::PlainObjectBase<DerivedV>& V,
+    const Eigen::PlainObjectBase<DerivedF>& F,
+    const igl::CDTParam & param,
+    Eigen::PlainObjectBase<DerivedTV>& TV,
+    Eigen::PlainObjectBase<DerivedTT>& TT,
+    Eigen::PlainObjectBase<DerivedTF>& TF);
+}
+
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "cdt.cpp"
+#endif
+
+#endif
+
+