Spaces:
Sleeping
Sleeping
| ''' | |
| Max-Planck-Gesellschaft zur Foerderung der Wissenschaften e.V. (MPG) is holder of all proprietary rights on this | |
| computer program. | |
| You can only use this computer program if you have closed a license agreement with MPG or you get the right to use | |
| the computer program from someone who is authorized to grant you that right. | |
| Any use of the computer program without a valid license is prohibited and liable to prosecution. | |
| Copyright 2019 Max-Planck-Gesellschaft zur Foerderung der Wissenschaften e.V. (MPG). acting on behalf of its | |
| Max Planck Institute for Intelligent Systems and the Max Planck Institute for Biological Cybernetics. | |
| All rights reserved. | |
| More information about VOCA is available at http://voca.is.tue.mpg.de. | |
| For comments or questions, please email us at [email protected] | |
| ''' | |
| from __future__ import division | |
| import os | |
| # os.environ['PYOPENGL_PLATFORM'] = 'osmesa' # Uncommnet this line while running remotely | |
| import cv2 | |
| import pyrender | |
| import trimesh | |
| import tempfile | |
| import numpy as np | |
| import matplotlib as mpl | |
| import matplotlib.cm as cm | |
| def get_unit_factor(unit): | |
| if unit == 'mm': | |
| return 1000.0 | |
| elif unit == 'cm': | |
| return 100.0 | |
| elif unit == 'm': | |
| return 1.0 | |
| else: | |
| raise ValueError('Unit not supported') | |
| def render_mesh_helper(mesh, t_center, rot=np.zeros(3), tex_img=None, v_colors=None, | |
| errors=None, error_unit='m', min_dist_in_mm=0.0, max_dist_in_mm=3.0, z_offset=1.0, xmag=0.5, | |
| y=0.7, z=1, camera='o', r=None): | |
| camera_params = {'c': np.array([0, 0]), | |
| 'k': np.array([-0.19816071, 0.92822711, 0, 0, 0]), | |
| 'f': np.array([5000, 5000])} | |
| frustum = {'near': 0.01, 'far': 3.0, 'height': 800, 'width': 800} | |
| v, f = mesh | |
| v = cv2.Rodrigues(rot)[0].dot((v - t_center).T).T + t_center | |
| texture_rendering = tex_img is not None and hasattr(mesh, 'vt') and hasattr(mesh, 'ft') | |
| if texture_rendering: | |
| intensity = 0.5 | |
| tex = pyrender.Texture(source=tex_img, source_channels='RGB') | |
| material = pyrender.material.MetallicRoughnessMaterial(baseColorTexture=tex) | |
| # Workaround as pyrender requires number of vertices and uv coordinates to be the same | |
| temp_filename = '%s.obj' % next(tempfile._get_candidate_names()) | |
| mesh.write_obj(temp_filename) | |
| tri_mesh = trimesh.load(temp_filename, process=False) | |
| try: | |
| os.remove(temp_filename) | |
| except: | |
| print('Failed deleting temporary file - %s' % temp_filename) | |
| render_mesh = pyrender.Mesh.from_trimesh(tri_mesh, material=material) | |
| elif errors is not None: | |
| intensity = 0.5 | |
| unit_factor = get_unit_factor('mm') / get_unit_factor(error_unit) | |
| errors = unit_factor * errors | |
| norm = mpl.colors.Normalize(vmin=min_dist_in_mm, vmax=max_dist_in_mm) | |
| cmap = cm.get_cmap(name='jet') | |
| colormapper = cm.ScalarMappable(norm=norm, cmap=cmap) | |
| rgba_per_v = colormapper.to_rgba(errors) | |
| rgb_per_v = rgba_per_v[:, 0:3] | |
| elif v_colors is not None: | |
| intensity = 0.5 | |
| rgb_per_v = v_colors | |
| else: | |
| intensity = 6. | |
| rgb_per_v = None | |
| color = np.array([0.3, 0.5, 0.55]) | |
| if not texture_rendering: | |
| tri_mesh = trimesh.Trimesh(vertices=v, faces=f, vertex_colors=rgb_per_v) | |
| render_mesh = pyrender.Mesh.from_trimesh(tri_mesh, | |
| smooth=True, | |
| material=pyrender.MetallicRoughnessMaterial( | |
| metallicFactor=0.05, | |
| roughnessFactor=0.7, | |
| alphaMode='OPAQUE', | |
| baseColorFactor=(color[0], color[1], color[2], 1.0) | |
| )) | |
| scene = pyrender.Scene(ambient_light=[.2, .2, .2], bg_color=[255, 255, 255]) | |
| if camera == 'o': | |
| ymag = xmag * z_offset | |
| camera = pyrender.OrthographicCamera(xmag=xmag, ymag=ymag) | |
| elif camera == 'i': | |
| camera = pyrender.IntrinsicsCamera(fx=camera_params['f'][0], | |
| fy=camera_params['f'][1], | |
| cx=camera_params['c'][0], | |
| cy=camera_params['c'][1], | |
| znear=frustum['near'], | |
| zfar=frustum['far']) | |
| elif camera == 'y': | |
| camera = pyrender.PerspectiveCamera(yfov=(np.pi / 2.0)) | |
| scene.add(render_mesh, pose=np.eye(4)) | |
| camera_pose = np.eye(4) | |
| camera_pose[:3, 3] = np.array([0, 0.7, 1.0 - z_offset]) | |
| scene.add(camera, pose=[[1, 0, 0, 0], | |
| [0, 1, 0, y], # 0.25 | |
| [0, 0, 1, z], # 0.2 | |
| [0, 0, 0, 1]]) | |
| angle = np.pi / 6.0 | |
| # pos = camera_pose[:3,3] | |
| pos = np.array([0, 0.7, 2.0]) | |
| if False: | |
| light_color = np.array([1., 1., 1.]) | |
| light = pyrender.DirectionalLight(color=light_color, intensity=intensity) | |
| light_pose = np.eye(4) | |
| light_pose[:3, 3] = np.array([0, 0.7, 2.0]) | |
| scene.add(light, pose=light_pose.copy()) | |
| else: | |
| light = pyrender.PointLight(color=np.array([1.0, 1.0, 1.0]) * 0.2, intensity=2) | |
| light_pose = np.eye(4) | |
| light_pose[:3, 3] = [0, -1, 1] | |
| scene.add(light, pose=light_pose) | |
| light_pose[:3, 3] = [0, 1, 1] | |
| scene.add(light, pose=light_pose) | |
| light_pose[:3, 3] = [-1, 1, 2] | |
| scene.add(light, pose=light_pose) | |
| spot_l = pyrender.SpotLight(color=np.ones(3), intensity=15.0, | |
| innerConeAngle=np.pi / 3, outerConeAngle=np.pi / 2) | |
| light_pose[:3, 3] = [-1, 2, 2] | |
| scene.add(spot_l, pose=light_pose) | |
| light_pose[:3, 3] = [1, 2, 2] | |
| scene.add(spot_l, pose=light_pose) | |
| # light_pose[:3,3] = cv2.Rodrigues(np.array([angle, 0, 0]))[0].dot(pos) | |
| # scene.add(light, pose=light_pose.copy()) | |
| # | |
| # light_pose[:3,3] = cv2.Rodrigues(np.array([-angle, 0, 0]))[0].dot(pos) | |
| # scene.add(light, pose=light_pose.copy()) | |
| # | |
| # light_pose[:3,3] = cv2.Rodrigues(np.array([0, -angle, 0]))[0].dot(pos) | |
| # scene.add(light, pose=light_pose.copy()) | |
| # | |
| # light_pose[:3,3] = cv2.Rodrigues(np.array([0, angle, 0]))[0].dot(pos) | |
| # scene.add(light, pose=light_pose.copy()) | |
| # pyrender.Viewer(scene) | |
| flags = pyrender.RenderFlags.SKIP_CULL_FACES | |
| # try: | |
| # r = pyrender.OffscreenRenderer(viewport_width=frustum['width'], viewport_height=frustum['height']) | |
| color, _ = r.render(scene, flags=flags) | |
| # r.delete() | |
| # except: | |
| # print('pyrender: Failed rendering frame') | |
| # color = np.zeros((frustum['height'], frustum['width'], 3), dtype='uint8') | |
| return color[..., ::-1] | |