303_LaplaceEquation.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  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. # 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 = ["glfw"]
  16. check_dependencies(dependencies)
  17. V = igl.eigen.MatrixXd()
  18. F = igl.eigen.MatrixXi()
  19. igl.readOFF(TUTORIAL_SHARED_PATH + "camelhead.off", V, F)
  20. # Find boundary edges
  21. E = igl.eigen.MatrixXi()
  22. igl.boundary_facets(F, E)
  23. # Find boundary vertices
  24. b = igl.eigen.MatrixXi()
  25. IA = igl.eigen.MatrixXi()
  26. IC = igl.eigen.MatrixXi()
  27. igl.unique(E, b, IA, IC)
  28. # List of all vertex indices
  29. vall = igl.eigen.MatrixXi()
  30. vin = igl.eigen.MatrixXi()
  31. igl.coloni(0, V.rows() - 1, vall)
  32. # List of interior indices
  33. igl.setdiff(vall, b, vin, IA)
  34. # Construct and slice up Laplacian
  35. L = igl.eigen.SparseMatrixd()
  36. L_in_in = igl.eigen.SparseMatrixd()
  37. L_in_b = igl.eigen.SparseMatrixd()
  38. igl.cotmatrix(V, F, L)
  39. igl.slice(L, vin, vin, L_in_in)
  40. igl.slice(L, vin, b, L_in_b)
  41. # Dirichlet boundary conditions from z-coordinate
  42. bc = igl.eigen.MatrixXd()
  43. Z = V.col(2)
  44. igl.slice(Z, b, bc)
  45. # Solve PDE
  46. solver = igl.eigen.SimplicialLLTsparse(-L_in_in)
  47. Z_in = solver.solve(L_in_b * bc)
  48. # slice into solution
  49. igl.slice_into(Z_in, vin, Z)
  50. # Alternative, short hand
  51. mqwf = igl.min_quad_with_fixed_data()
  52. # Linear term is 0
  53. B = igl.eigen.MatrixXd()
  54. B.setZero(V.rows(), 1)
  55. # Empty constraints
  56. Beq = igl.eigen.MatrixXd()
  57. Aeq = igl.eigen.SparseMatrixd()
  58. # Our cotmatrix is _negative_ definite, so flip sign
  59. igl.min_quad_with_fixed_precompute(-L, b, Aeq, True, mqwf)
  60. igl.min_quad_with_fixed_solve(mqwf, B, bc, Beq, Z)
  61. # Pseudo-color based on solution
  62. C = igl.eigen.MatrixXd()
  63. igl.jet(Z, True, C)
  64. # Plot the mesh with pseudocolors
  65. viewer = igl.glfw.Viewer()
  66. viewer.data().set_mesh(V, F)
  67. viewer.data().show_lines = False
  68. viewer.data().set_colors(C)
  69. viewer.launch()