709_VectorFieldVisualizer.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #!/usr/bin/env python
  2. #
  3. # This file is part of libigl, a simple c++ geometry processing library.
  4. #
  5. # Copyright (C) 2017 Sebastian Koch <s.koch@tu-berlin.de> and Daniele Panozzo <daniele.panozzo@gmail.com>
  6. #
  7. # This Source Code Form is subject to the terms of the Mozilla Public License
  8. # v. 2.0. If a copy of the MPL was not distributed with this file, You can
  9. # obtain one at http://mozilla.org/MPL/2.0/.
  10. import sys, os
  11. import numpy as np
  12. # Add the igl library to the modules search path
  13. sys.path.insert(0, os.getcwd() + "/../")
  14. import pyigl as igl
  15. from shared import TUTORIAL_SHARED_PATH, check_dependencies
  16. dependencies = ["glfw"]
  17. check_dependencies(dependencies)
  18. # Input mesh
  19. V = igl.eigen.MatrixXd()
  20. F = igl.eigen.MatrixXi()
  21. data = igl.StreamlineData()
  22. state = igl.StreamlineState()
  23. treat_as_symmetric = True
  24. # animation params
  25. anim_t = 0
  26. anim_t_dir = 1
  27. def representative_to_nrosy(V, F, R, N, Y):
  28. B1 = igl.eigen.MatrixXd()
  29. B2 = igl.eigen.MatrixXd()
  30. B3 = igl.eigen.MatrixXd()
  31. igl.local_basis(V, F, B1, B2, B3)
  32. Y.resize(F.rows(), 3 * N)
  33. for i in range(0, F.rows()):
  34. x = R.row(i) * B1.row(i).transpose()
  35. y = R.row(i) * B2.row(i).transpose()
  36. angle = np.arctan2(y, x)
  37. for j in range(0, N):
  38. anglej = angle + np.pi * float(j) / float(N)
  39. xj = float(np.cos(anglej))
  40. yj = float(np.sin(anglej))
  41. Y.setBlock(i, j * 3, 1, 3, xj * B1.row(i) + yj * B2.row(i))
  42. def pre_draw(viewer):
  43. if not viewer.core.is_animating:
  44. return False
  45. global anim_t
  46. global start_point
  47. global end_point
  48. igl.streamlines_next(V, F, data, state)
  49. value = (anim_t % 100) / 100.0
  50. if value > 0.5:
  51. value = 1 - value
  52. value /= 0.5
  53. r, g, b = igl.parula(value)
  54. viewer.data().add_edges(state.start_point, state.end_point, igl.eigen.MatrixXd([[r, g, b]]))
  55. anim_t += anim_t_dir
  56. return False
  57. def key_down(viewer, key, modifier):
  58. if key == ord(' '):
  59. viewer.core.is_animating = not viewer.core.is_animating
  60. return True
  61. return False
  62. def main():
  63. # Load a mesh in OFF format
  64. igl.readOFF(TUTORIAL_SHARED_PATH + "bumpy.off", V, F)
  65. # Create a Vector Field
  66. temp_field = igl.eigen.MatrixXd()
  67. b = igl.eigen.MatrixXi([[0]])
  68. bc = igl.eigen.MatrixXd([[1, 1, 1]])
  69. S = igl.eigen.MatrixXd() # unused
  70. degree = 3
  71. igl.comiso.nrosy(V, F, b, bc, igl.eigen.MatrixXi(), igl.eigen.MatrixXd(), igl.eigen.MatrixXd(), 1, 0.5, temp_field, S)
  72. temp_field2 = igl.eigen.MatrixXd()
  73. representative_to_nrosy(V, F, temp_field, degree, temp_field2)
  74. # Initialize tracer
  75. igl.streamlines_init(V, F, temp_field2, treat_as_symmetric, data, state)
  76. # Setup viewer
  77. viewer = igl.glfw.Viewer()
  78. viewer.data().set_mesh(V, F)
  79. viewer.callback_pre_draw = pre_draw
  80. viewer.callback_key_down = key_down
  81. viewer.core.show_lines = False
  82. viewer.core.is_animating = False
  83. viewer.core.animation_max_fps = 30.0
  84. # Paint mesh grayish
  85. C = igl.eigen.MatrixXd()
  86. C.setConstant(viewer.data().V.rows(), 3, .9)
  87. viewer.data().set_colors(C)
  88. # Draw vector field on sample points
  89. state0 = state.copy()
  90. igl.streamlines_next(V, F, data, state0)
  91. v = state0.end_point - state0.start_point
  92. v = v.rowwiseNormalized()
  93. viewer.data().add_edges(state0.start_point,
  94. state0.start_point + 0.059 * v,
  95. igl.eigen.MatrixXd([[1.0, 1.0, 1.0]]))
  96. print("Press [space] to toggle animation")
  97. viewer.launch()
  98. if __name__ == "__main__":
  99. main()