Source code for plato.draw.povray.ConvexSpheropolyhedra

import numpy as np

from ... import draw
from ... import mesh as pmesh
from ... import geometry
from ... import math as pmath

[docs]class ConvexSpheropolyhedra(draw.ConvexSpheropolyhedra): __doc__ = draw.ConvexSpheropolyhedra.__doc__ def render(self, rotation=(1, 0, 0, 0), name_suffix='', translation=(0, 0, 0), **kwargs): rotation = np.asarray(rotation) (positions, orientations, colors) = pmesh.unfoldProperties([ self.positions, self.orientations, self.colors]) quat_magnitude = np.linalg.norm(orientations, axis=-1, keepdims=True) lines = [] decomp = geometry.convexDecomposition(self.vertices) mesh = pmesh.convexSpheropolyhedronMesh(self.vertices, self.radius) meshStr = 'mesh2 {{vertex_vectors {{{} {}}} ' \ 'face_indices {{{} {}}}}}'.format( len(mesh.image), ' '.join('<{},{},{}>'.format(*v) for v in mesh.image), len(mesh.indices), ' '.join('<{},{},{}>'.format(*v) for v in mesh.indices)) edges = ['cylinder {{<{0[0]},{0[1]},{0[2]}> <{1[0]},{1[1]},{1[2]}> ' '{2}}}'.format( decomp.vertices[i], decomp.vertices[j], np.asscalar(self.radius)) for (i, j) in decomp.edges] spheres = ['sphere {{<{0[0]},{0[1]},{0[2]}> {1}}}'.format( v, np.asscalar(self.radius)) for v in decomp.vertices] shapeName = 'spoly{}'.format(name_suffix) shapedef = '#declare {} = union {{\n{}\n}}'.format( shapeName, '\n'.join(elt for elt in [meshStr] + edges + spheres)) lines.append(shapedef) qs = pmath.quatquat(rotation[np.newaxis, :], orientations/quat_magnitude) rotmat = np.array([[1 - 2*qs[:, 2]**2 - 2*qs[:, 3]**2, 2*(qs[:, 1]*qs[:, 2] - qs[:, 3]*qs[:, 0]), 2*(qs[:, 1]*qs[:, 3] + qs[:, 2]*qs[:, 0])], [2*(qs[:, 1]*qs[:, 2] + qs[:, 3]*qs[:, 0]), 1 - 2*qs[:, 1]**2 - 2*qs[:, 3]**2, 2*(qs[:, 2]*qs[:, 3] - qs[:, 1]*qs[:, 0])], [2*(qs[:, 1]*qs[:, 3] - qs[:, 2]*qs[:, 0]), 2*(qs[:, 1]*qs[:, 0] + qs[:, 2]*qs[:, 3]), 1 - 2*qs[:, 1]**2 - 2*qs[:, 2]**2]]) rotmat = rotmat.transpose([2, 1, 0]).reshape((-1, 9)) rotmat[:] *= quat_magnitude[:, 0, np.newaxis]**2 positions = pmath.quatrot(rotation[np.newaxis, :], positions) positions += translation for (p, m, c) in zip(positions, rotmat, colors[:, :3]): args = [shapeName] + m.tolist() + p.tolist() + c.tolist() lines.append('object {{{} matrix <{},{},{},{},{},{},{},{},{},' '{},{},{}> pigment {{color <{},{},{}>}}}}'.format( *args)) return lines