Browse Source

added python module comiso
added 504


Former-commit-id: 88cf5cc8126fb58d161da3ef8bc41bc9fda55878

Daniele Panozzo 9 years ago
parent
commit
73f00b0f44
4 changed files with 163 additions and 0 deletions
  1. 108 0
      python/504_NRosyDesign.py
  2. 2 0
      python/py_igl.cpp
  3. 41 0
      python/py_igl/comiso/py_nrosy.cpp
  4. 12 0
      python/py_igl/py_local_basis.cpp

+ 108 - 0
python/504_NRosyDesign.py

@@ -0,0 +1,108 @@
+import igl
+from math import atan2,pi,cos,sin
+
+# Mesh
+V = igl.eigen.MatrixXd()
+F = igl.eigen.MatrixXi()
+
+# Constrained faces id
+b = igl.eigen.MatrixXi()
+
+# Constrained faces representative vector
+bc = igl.eigen.MatrixXd()
+
+# Degree of the N-RoSy field
+N = 4;
+
+# Converts a representative vector per face in the full set of vectors that describe
+# an N-RoSy field
+def representative_to_nrosy(V, F, R, N, Y):
+    B1 = igl.eigen.MatrixXd()
+    B2 = igl.eigen.MatrixXd()
+    B3 = igl.eigen.MatrixXd()
+
+    igl.local_basis(V,F,B1,B2,B3)
+
+    Y.resize(F.rows()*N, 3)
+
+    for i in range (0,F.rows()):
+        x = R.row(i) * B1.row(i).transpose()
+        y = R.row(i) * B2.row(i).transpose()
+        angle = atan2(y[0],x[0])
+
+        for j in range(0,N):
+            anglej = angle + 2*pi*j/float(N)
+            xj = cos(anglej)
+            yj = sin(anglej)
+            Y.setRow(i*N+j, xj * B1.row(i) + yj * B2.row(i))
+
+# Plots the mesh with an N-RoSy field and its singularities on top
+# The constrained faces (b) are colored in red.
+def plot_mesh_nrosy(viewer, V, F, N, PD1, S, b):
+    # Clear the mesh
+    viewer.data.clear()
+    viewer.data.set_mesh(V,F)
+
+    # Expand the representative vectors in the full vector set and plot them as lines
+    avg = igl.avg_edge_length(V, F)
+    Y = igl.eigen.MatrixXd()
+    representative_to_nrosy(V, F, PD1, N, Y)
+
+    B = igl.eigen.MatrixXd()
+    igl.barycenter(V,F,B)
+
+    Be = igl.eigen.MatrixXd(B.rows()*N,3)
+    for i in range(0,B.rows()):
+        for j in range(0,N):
+            Be.setRow(i*N+j,B.row(i))
+
+    viewer.data.add_edges(Be,Be+Y*(avg/2),igl.eigen.MatrixXd([[0,0,1]]))
+
+    # Plot the singularities as colored dots (red for negative, blue for positive)
+    for i in range(0,S.size()):
+        if S[i] < -0.001:
+            viewer.data.add_points(V.row(i),igl.eigen.MatrixXd([[1,0,0]]))
+        elif S[i] > 0.001:
+            viewer.data.add_points(V.row(i),igl.eigen.MatrixXd([[0,1,0]]));
+
+    # Highlight in red the constrained faces
+    C = igl.eigen.MatrixXd.Constant(F.rows(),3,1)
+    for i in range(0,b.size()):
+        C.setRow(b[i], igl.eigen.MatrixXd([[1, 0, 0]]))
+    viewer.data.set_colors(C)
+
+# It allows to change the degree of the field when a number is pressed
+def key_down(viewer, key, modifier):
+    global N
+    if key >= ord('1') and key <= ord('9'):
+        N = key - '0'
+
+    R = igl.eigen.MatrixXd()
+    S = igl.eigen.MatrixXd()
+
+    igl.comiso.nrosy(V,F,b,bc,igl.eigen.MatrixXi(),igl.eigen.MatrixXd(),igl.eigen.MatrixXd(),N,0.5,R,S)
+    plot_mesh_nrosy(viewer,V,F,N,R,S,b)
+
+    return False
+
+# Load a mesh in OFF format
+igl.readOFF("../tutorial/shared/bumpy.off", V, F);
+
+# Threshold faces with high anisotropy
+b  = igl.eigen.MatrixXi([[0]])
+bc = igl.eigen.MatrixXd([[1,1,1]])
+
+viewer = igl.viewer.Viewer()
+
+# Interpolate the field and plot
+key_down(viewer, '4', 0)
+
+# Plot the mesh
+viewer.data.set_mesh(V, F)
+viewer.callback_key_down = key_down
+
+# Disable wireframe
+viewer.core.show_lines = False
+
+# Launch the viewer
+viewer.launch()

+ 2 - 0
python/py_igl.cpp

@@ -39,6 +39,7 @@
 #include <igl/boundary_loop.h>
 #include <igl/map_vertices_to_circle.h>
 #include <igl/lscm.h>
+#include <igl/local_basis.h>
 
 void python_export_igl(py::module &m)
 {
@@ -79,4 +80,5 @@ void python_export_igl(py::module &m)
 #include "py_igl/py_boundary_loop.cpp"
 #include "py_igl/py_map_vertices_to_circle.cpp"
 #include "py_igl/py_lscm.cpp"
+#include "py_igl/py_local_basis.cpp"
 }

+ 41 - 0
python/py_igl/comiso/py_nrosy.cpp

@@ -0,0 +1,41 @@
+m.def("nrosy", []
+(
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& F,
+  const Eigen::MatrixXi& b,
+  const Eigen::MatrixXd& bc,
+  const Eigen::MatrixXi& b_soft,
+  const Eigen::MatrixXd& w_soft,
+  const Eigen::MatrixXd& bc_soft,
+  const int N,
+  const double soft,
+  Eigen::MatrixXd& R,
+  Eigen::MatrixXd& S
+)
+{
+  assert_is_VectorX("b",b);
+  assert_is_VectorX("b_soft",b_soft);
+  assert_is_VectorX("w_soft",w_soft);
+  Eigen::VectorXd St;
+  igl::comiso::nrosy(V,F,b,bc,b_soft,w_soft,bc_soft,N,soft,R,St);
+  S = St;
+}, __doc_igl_comiso_nrosy,
+py::arg("V"), py::arg("F"), py::arg("b"), py::arg("bc"), py::arg("b_soft"), py::arg("w_soft"), py::arg("bc_soft"), py::arg("N"), py::arg("soft"), py::arg("R"), py::arg("S"));
+
+m.def("nrosy", []
+(
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& F,
+  const Eigen::MatrixXi& b,
+  const Eigen::MatrixXd& bc,
+  const int N,
+  Eigen::MatrixXd& R,
+  Eigen::MatrixXd& S
+)
+{
+  assert_is_VectorX("b",b);
+  Eigen::VectorXd St;
+  igl::comiso::nrosy(V,F,b,bc,N,R,St);
+  S = St;
+}, __doc_igl_comiso_nrosy,
+py::arg("V"), py::arg("F"), py::arg("b"), py::arg("bc"), py::arg("N"), py::arg("R"), py::arg("S"));

+ 12 - 0
python/py_igl/py_local_basis.cpp

@@ -0,0 +1,12 @@
+m.def("local_basis", []
+(
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& F,
+  Eigen::MatrixXd& B1,
+  Eigen::MatrixXd& B2,
+  Eigen::MatrixXd& B3
+)
+{
+  return igl::local_basis(V,F,B1,B2,B3);
+}, __doc_igl_local_basis,
+py::arg("V"), py::arg("F"), py::arg("B1"), py::arg("B2"), py::arg("B3"));