|
@@ -0,0 +1,78 @@
|
|
|
+import sys, os
|
|
|
+
|
|
|
+# Add the igl library to the modules search path
|
|
|
+sys.path.insert(0, os.getcwd() + "/../")
|
|
|
+import pyigl as igl
|
|
|
+
|
|
|
+from shared import TUTORIAL_SHARED_PATH, check_dependencies, print_usage
|
|
|
+
|
|
|
+dependencies = ["embree", "viewer"]
|
|
|
+check_dependencies(dependencies)
|
|
|
+
|
|
|
+
|
|
|
+def key_down(viewer, key, modifier):
|
|
|
+ global facetwise, is_showing_reoriented, FF
|
|
|
+ if key == ord('F') or key == ord('f'):
|
|
|
+ facetwise = (facetwise + 1) % 2
|
|
|
+ elif key == ord('S') or key == ord('s'):
|
|
|
+ scramble_colors()
|
|
|
+ elif key == ord(' '):
|
|
|
+ is_showing_reoriented = ~is_showing_reoriented
|
|
|
+
|
|
|
+ viewer.data.clear()
|
|
|
+ viewer.data.set_mesh(V, FF[facetwise] if is_showing_reoriented else F)
|
|
|
+ viewer.data.set_colors(RGBcolors[facetwise])
|
|
|
+
|
|
|
+ return True
|
|
|
+
|
|
|
+def scramble_colors():
|
|
|
+ global C, viewer, RGBcolors
|
|
|
+ for p in range(2):
|
|
|
+ R = igl.eigen.MatrixXi()
|
|
|
+ igl.randperm(C[p].maxCoeff() + 1, R)
|
|
|
+ C[p] = igl.slice(R, igl.eigen.MatrixXi(C[p]))
|
|
|
+ HSV = igl.eigen.MatrixXd(C[p].rows(), 3)
|
|
|
+ HSV.setCol(0, 360.0 * C[p].castdouble() / C[p].maxCoeff())
|
|
|
+ HSVright = igl.eigen.MatrixXd(HSV.rows(), 2)
|
|
|
+ HSVright.setConstant(1.0)
|
|
|
+ HSV.setRightCols(2, HSVright)
|
|
|
+ igl.hsv_to_rgb(HSV, RGBcolors[p])
|
|
|
+ viewer.data.set_colors(RGBcolors[facetwise])
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+if __name__ == "__main__":
|
|
|
+ keys = {"space": "toggle between original and reoriented faces",
|
|
|
+ "F,f": "toggle between patchwise and facetwise reorientation",
|
|
|
+ "S,s": "scramble colors"}
|
|
|
+ print_usage(keys)
|
|
|
+
|
|
|
+ V = igl.eigen.MatrixXd()
|
|
|
+ F = igl.eigen.MatrixXi()
|
|
|
+ C = [igl.eigen.MatrixXi(), igl.eigen.MatrixXi()]
|
|
|
+ RGBcolors = [igl.eigen.MatrixXd(), igl.eigen.MatrixXd()]
|
|
|
+ FF = [igl.eigen.MatrixXi(), igl.eigen.MatrixXi()]
|
|
|
+ is_showing_reoriented = False
|
|
|
+ facetwise = 0
|
|
|
+
|
|
|
+ igl.read_triangle_mesh(TUTORIAL_SHARED_PATH + "truck.obj", V, F)
|
|
|
+
|
|
|
+ # Compute patches
|
|
|
+ for p in range(2):
|
|
|
+ I = igl.eigen.MatrixXi()
|
|
|
+ igl.embree.reorient_facets_raycast(V, F, F.rows() * 100, 10, p == 1, False, False, I, C[p])
|
|
|
+ # apply reorientation
|
|
|
+ FF[p].conservativeResize(F.rows(), F.cols())
|
|
|
+ for i in range(I.rows()):
|
|
|
+ if I[i]:
|
|
|
+ FF[p].setRow(i, F.row(i).rowwiseReverse())
|
|
|
+ else:
|
|
|
+ FF[p].setRow(i, F.row(i))
|
|
|
+
|
|
|
+ # Plot the generated mesh
|
|
|
+ viewer = igl.viewer.Viewer()
|
|
|
+ viewer.data.set_mesh(V, FF[facetwise] if is_showing_reoriented else F)
|
|
|
+ viewer.data.set_face_based(True)
|
|
|
+ scramble_colors()
|
|
|
+ viewer.callback_key_down = key_down
|
|
|
+ viewer.launch()
|