507_PolyVectorField.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. # This file is part of libigl, a simple c++ geometry processing library.
  2. #
  3. # Copyright (C) 2017 Sebastian Koch <s.koch@tu-berlin.de> and Daniele Panozzo <daniele.panozzo@gmail.com>
  4. #
  5. # This Source Code Form is subject to the terms of the Mozilla Public License
  6. # v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. # obtain one at http://mozilla.org/MPL/2.0/.
  8. import sys, os
  9. import random
  10. from math import cos,sin,pi
  11. # Add the igl library to the modules search path
  12. sys.path.insert(0, os.getcwd() + "/../")
  13. import pyigl as igl
  14. from shared import TUTORIAL_SHARED_PATH, check_dependencies
  15. dependencies = ["embree", "viewer"]
  16. check_dependencies(dependencies)
  17. # Input mesh
  18. V = igl.eigen.MatrixXd()
  19. F = igl.eigen.MatrixXi()
  20. # Per face bases
  21. B1 = igl.eigen.MatrixXd()
  22. B2 = igl.eigen.MatrixXd()
  23. B3 = igl.eigen.MatrixXd()
  24. # Face barycenters
  25. B = igl.eigen.MatrixXd()
  26. # Scale for visualizing the fields
  27. global_scale = 1
  28. # Random length factor
  29. rand_factor = 5
  30. samples = igl.eigen.MatrixXi()
  31. def readSamples(fname):
  32. samples = igl.eigen.MatrixXi()
  33. numSamples = 0
  34. fp = open(fname, 'r')
  35. numSamples = int(fp.readline())
  36. samples.resize(numSamples,1)
  37. for i in range(0,numSamples):
  38. samples[i] = int(fp.readline())
  39. fp.close()
  40. return samples
  41. # Create a random set of tangent vectors
  42. def random_constraints(b1, b2, n):
  43. r = igl.eigen.MatrixXd(1,n*3)
  44. for i in range(0,n):
  45. a = random.random()*2*pi
  46. s = 1 + random.random() * rand_factor
  47. t = s * (cos(a) * b1 + sin(a) * b2)
  48. r.setBlock(0,i*3,1,3,t)
  49. return r
  50. def key_down(viewer, key, modifier):
  51. if key < ord('1') or key > ord('8'):
  52. return False
  53. viewer.data.lines.resize(0,9)
  54. num = key - ord('0')
  55. # Interpolate
  56. print("Interpolating " + repr(num * 2) + "-PolyVector field")
  57. b = igl.eigen.MatrixXi([[4550, 2321, 5413, 5350]]).transpose()
  58. bc = igl.eigen.MatrixXd(b.size(),num*3)
  59. for i in range(0,b.size()):
  60. t = random_constraints(B1.row(b[i]),B2.row(b[i]),num)
  61. bc.setRow(i,t)
  62. # Interpolated PolyVector field
  63. pvf = igl.eigen.MatrixXd()
  64. igl.n_polyvector(V, F, b, bc, pvf)
  65. # Highlight in red the constrained faces
  66. C = igl.eigen.MatrixXd.Constant(F.rows(),3,1)
  67. for i in range(0,b.size()):
  68. C.setRow(b[i],igl.eigen.MatrixXd([[1, 0, 0]]))
  69. viewer.data.set_colors(C)
  70. for n in range(0,num):
  71. VF = igl.eigen.MatrixXd.Zero(F.rows(),3)
  72. for i in range(0,b.size()):
  73. VF.setRow(b[i],bc.block(i,n*3,1,3))
  74. for i in range(0,samples.rows()):
  75. VF.setRow(samples[i],pvf.block(samples[i],n*3,1,3))
  76. c = VF.rowwiseNorm()
  77. C2 = igl.eigen.MatrixXd()
  78. igl.jet(c,1,1+rand_factor,C2)
  79. viewer.data.add_edges(B - global_scale*VF, B + global_scale*VF , C2)
  80. return False
  81. # Load a mesh in OBJ format
  82. igl.readOBJ("../../tutorial/shared/lilium.obj", V, F)
  83. samples = readSamples("../../tutorial/shared/lilium.samples.0.2")
  84. # Compute local basis for faces
  85. igl.local_basis(V,F,B1,B2,B3)
  86. # Compute face barycenters
  87. igl.barycenter(V, F, B)
  88. # Compute scale for visualizing fields
  89. global_scale = 0.2*igl.avg_edge_length(V, F)
  90. # Make the example deterministic
  91. random.seed(0)
  92. viewer = igl.viewer.Viewer()
  93. viewer.data.set_mesh(V, F)
  94. viewer.callback_key_down = key_down
  95. viewer.core.show_lines = False
  96. key_down(viewer,ord('2'),0)
  97. viewer.launch()