123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- # This file is part of libigl, a simple c++ geometry processing library.
- #
- # Copyright (C) 2017 Sebastian Koch <s.koch@tu-berlin.de> and Daniele Panozzo <daniele.panozzo@gmail.com>
- #
- # This Source Code Form is subject to the terms of the Mozilla Public License
- # v. 2.0. If a copy of the MPL was not distributed with this file, You can
- # obtain one at http://mozilla.org/MPL/2.0/.
- import sys, os
- import numpy as np
- # 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
- dependencies = ["viewer"]
- check_dependencies(dependencies)
- # Input mesh
- V = igl.eigen.MatrixXd()
- F = igl.eigen.MatrixXi()
- data = igl.StreamlineData()
- state = igl.StreamlineState()
- treat_as_symmetric = True
- # animation params
- anim_t = 0
- anim_t_dir = 1
- 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(), 3 * N)
- for i in range(0, F.rows()):
- x = R.row(i) * B1.row(i).transpose()
- y = R.row(i) * B2.row(i).transpose()
- angle = np.arctan2(y, x)
- for j in range(0, N):
- anglej = angle + np.pi * float(j) / float(N)
- xj = float(np.cos(anglej))
- yj = float(np.sin(anglej))
- Y.setBlock(i, j * 3, 1, 3, xj * B1.row(i) + yj * B2.row(i))
- def pre_draw(viewer):
- if not viewer.core.is_animating:
- return False
- global anim_t
- global start_point
- global end_point
- igl.streamlines_next(V, F, data, state)
- value = (anim_t % 100) / 100.0
- if value > 0.5:
- value = 1 - value
- value /= 0.5
- r, g, b = igl.parula(value)
- viewer.data.add_edges(state.start_point, state.end_point, igl.eigen.MatrixXd([[r, g, b]]))
- anim_t += anim_t_dir
- return False
- def key_down(viewer, key, modifier):
- if key == ord(' '):
- viewer.core.is_animating = not viewer.core.is_animating
- return True
- return False
- def main():
- # Load a mesh in OFF format
- igl.readOFF(TUTORIAL_SHARED_PATH + "bumpy.off", V, F)
- # Create a Vector Field
- temp_field = igl.eigen.MatrixXd()
- b = igl.eigen.MatrixXi([[0]])
- bc = igl.eigen.MatrixXd([[1, 1, 1]])
- S = igl.eigen.MatrixXd() # unused
- degree = 3
- igl.comiso.nrosy(V, F, b, bc, igl.eigen.MatrixXi(), igl.eigen.MatrixXd(), igl.eigen.MatrixXd(), 1, 0.5, temp_field, S)
- temp_field2 = igl.eigen.MatrixXd()
- representative_to_nrosy(V, F, temp_field, degree, temp_field2)
- # Initialize tracer
- igl.streamlines_init(V, F, temp_field2, treat_as_symmetric, data, state)
- # Setup viewer
- viewer = igl.viewer.Viewer()
- viewer.data.set_mesh(V, F)
- viewer.callback_pre_draw = pre_draw
- viewer.callback_key_down = key_down
- viewer.core.show_lines = False
- viewer.core.is_animating = False
- viewer.core.animation_max_fps = 30.0
- # Paint mesh grayish
- C = igl.eigen.MatrixXd()
- C.setConstant(viewer.data.V.rows(), 3, .9)
- viewer.data.set_colors(C)
- # Draw vector field on sample points
- state0 = state.copy()
- igl.streamlines_next(V, F, data, state0)
- v = state0.end_point - state0.start_point
- v = v.rowwiseNormalized()
- viewer.data.add_edges(state0.start_point,
- state0.start_point + 0.059 * v,
- igl.eigen.MatrixXd([[1.0, 1.0, 1.0]]))
- print("Press [space] to toggle animation")
- viewer.launch()
- if __name__ == "__main__":
- main()
|