team-3/src/c3nav/mapdata/render/engines/base3d.py
2017-11-14 13:37:37 +01:00

44 lines
1.6 KiB
Python

from itertools import chain
from typing import Optional
import numpy as np
from c3nav.mapdata.render.data import HybridGeometry
from c3nav.mapdata.render.engines.base import FillAttribs, RenderEngine, StrokeAttribs
# noinspection PyAbstractClass
class Base3DEngine(RenderEngine):
is_3d = True
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.vertices = []
self.np_scale = np.array((self.scale, self.scale, self.scale))
self.np_offset = np.array((-self.minx * self.scale, -self.miny * self.scale, 0))
def _add_geometry(self, geometry, fill: Optional[FillAttribs], stroke: Optional[StrokeAttribs], **kwargs):
if fill is not None:
self.vertices.append(self._place_geometry(geometry))
@staticmethod
def _append_to_vertices(vertices, append=None):
if append is not None:
append = np.array(append, dtype=np.float32).flatten()
vertices = np.dstack((
vertices,
append.reshape(1, append.size).repeat(vertices.shape[0]*3, 0).reshape((-1, 3, append.size))
))
return vertices
def _place_geometry(self, geometry: HybridGeometry, append=None, offset=True):
vertices = np.vstack(tuple(chain(*(
mesh.tolist() for mesh in chain(geometry.faces, *geometry.add_faces.values())
))))
if offset:
vertices = vertices / 1000 * self.np_scale + self.np_offset
else:
vertices = vertices / 1000
return self._append_to_vertices(vertices, append)