Mesh() is not a namedtuple to improve performance
This commit is contained in:
parent
a679a81432
commit
6812edb8b3
2 changed files with 18 additions and 21 deletions
|
@ -2,7 +2,7 @@ import operator
|
||||||
import os
|
import os
|
||||||
import pickle
|
import pickle
|
||||||
import threading
|
import threading
|
||||||
from collections import Counter, deque
|
from collections import Counter, deque, namedtuple
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
|
||||||
|
@ -391,20 +391,15 @@ class LevelRenderData:
|
||||||
return pickle.dump(self, open(self._level_filename(pk), 'wb'))
|
return pickle.dump(self, open(self._level_filename(pk), 'wb'))
|
||||||
|
|
||||||
|
|
||||||
class Mesh:
|
class Mesh(namedtuple('Mesh', ('top', 'sides', 'bottom'))):
|
||||||
__slots__ = ('top', 'sides', 'bottom')
|
empty_faces = np.empty((0, 3, 3)).astype(np.int32)
|
||||||
|
|
||||||
def __init__(self, top=None, sides=None, bottom=None):
|
|
||||||
self.top = np.empty((0, 3, 3), dtype=np.int32) if top is None else top
|
|
||||||
self.sides = np.empty((0, 3, 3), dtype=np.int32) if sides is None else sides
|
|
||||||
self.bottom = np.empty((0, 3, 3), dtype=np.int32) if bottom is None else bottom
|
|
||||||
|
|
||||||
def tolist(self):
|
def tolist(self):
|
||||||
return self.top, self.sides, self.bottom
|
return self.top, self.sides, self.bottom
|
||||||
|
|
||||||
def __mul__(self, other):
|
def __mul__(self, other):
|
||||||
return Mesh(top=np.rint(self.top*other).astype(np.int32),
|
return Mesh(top=np.rint(self.top*other).astype(np.int32),
|
||||||
sides=np.rint(self.sides*other if other[2] != 0 else np.empty((0, 3, 3))).astype(np.int32),
|
sides=np.rint(self.sides*other if other[2] != 0 else self.empty_faces),
|
||||||
bottom=np.rint(self.bottom*other).astype(np.int32))
|
bottom=np.rint(self.bottom*other).astype(np.int32))
|
||||||
|
|
||||||
def __add__(self, other):
|
def __add__(self, other):
|
||||||
|
@ -413,9 +408,9 @@ class Mesh:
|
||||||
np.rint(self.bottom+other).astype(np.int32))
|
np.rint(self.bottom+other).astype(np.int32))
|
||||||
|
|
||||||
def filter(self, top=True, sides=True, bottom=True):
|
def filter(self, top=True, sides=True, bottom=True):
|
||||||
return Mesh(top=self.top if top else None,
|
return Mesh(top=self.top if top else self.empty_faces,
|
||||||
sides=self.sides if sides else None,
|
sides=self.sides if sides else self.empty_faces,
|
||||||
bottom=self.bottom if bottom else None)
|
bottom=self.bottom if bottom else self.empty_faces)
|
||||||
|
|
||||||
|
|
||||||
class LevelGeometries:
|
class LevelGeometries:
|
||||||
|
@ -699,15 +694,15 @@ class LevelGeometries:
|
||||||
# remove faces that have identical upper and lower coordinates
|
# remove faces that have identical upper and lower coordinates
|
||||||
geom_faces = geom_faces[(upper[geom_faces]-lower[geom_faces]).any(axis=1)]
|
geom_faces = geom_faces[(upper[geom_faces]-lower[geom_faces]).any(axis=1)]
|
||||||
|
|
||||||
mesh = Mesh()
|
|
||||||
|
|
||||||
# top faces
|
# top faces
|
||||||
if top:
|
if top:
|
||||||
mesh.top = self._filter_faces(np.dstack((self.vertices[geom_faces], upper[geom_faces])))
|
top = self._filter_faces(np.dstack((self.vertices[geom_faces], upper[geom_faces])))
|
||||||
|
else:
|
||||||
|
top = Mesh.empty_faces
|
||||||
|
|
||||||
# side faces
|
# side faces
|
||||||
if sides:
|
if sides:
|
||||||
mesh.sides = self._filter_faces(np.vstack((
|
sides = self._filter_faces(np.vstack((
|
||||||
# upper
|
# upper
|
||||||
np.dstack((self.vertices[boundaries[:, (1, 0, 0)]],
|
np.dstack((self.vertices[boundaries[:, (1, 0, 0)]],
|
||||||
np.hstack((upper[boundaries[:, (1, 0)]], lower[boundaries[:, (0,)]])))),
|
np.hstack((upper[boundaries[:, (1, 0)]], lower[boundaries[:, (0,)]])))),
|
||||||
|
@ -715,14 +710,18 @@ class LevelGeometries:
|
||||||
np.dstack((self.vertices[boundaries[:, (0, 1, 1)]],
|
np.dstack((self.vertices[boundaries[:, (0, 1, 1)]],
|
||||||
np.hstack((lower[boundaries[:, (0, 1)]], upper[boundaries[:, (1,)]]))))
|
np.hstack((lower[boundaries[:, (0, 1)]], upper[boundaries[:, (1,)]]))))
|
||||||
)))
|
)))
|
||||||
|
else:
|
||||||
|
sides = Mesh.empty_faces
|
||||||
|
|
||||||
# bottom faces
|
# bottom faces
|
||||||
if bottom:
|
if bottom:
|
||||||
mesh.bottom = self._filter_faces(
|
bottom = self._filter_faces(
|
||||||
np.flip(np.dstack((self.vertices[geom_faces], lower[geom_faces])), axis=1)
|
np.flip(np.dstack((self.vertices[geom_faces], lower[geom_faces])), axis=1)
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
bottom = Mesh.empty_faces
|
||||||
|
|
||||||
return tuple((mesh, ))
|
return tuple((Mesh(top, sides, bottom), ))
|
||||||
|
|
||||||
def build_mesh(self, interpolator=None):
|
def build_mesh(self, interpolator=None):
|
||||||
rings = tuple(chain(*(get_rings(geom) for geom in self.get_geometries())))
|
rings = tuple(chain(*(get_rings(geom) for geom in self.get_geometries())))
|
||||||
|
|
|
@ -52,9 +52,7 @@ class Base3DEngine(RenderEngine):
|
||||||
return vertices
|
return vertices
|
||||||
|
|
||||||
def _place_geometry(self, geometry: HybridGeometry, append=None, offset=True):
|
def _place_geometry(self, geometry: HybridGeometry, append=None, offset=True):
|
||||||
vertices = np.vstack(tuple(chain(*(
|
vertices = np.vstack(tuple(chain(*chain(geometry.faces, *geometry.add_faces.values()))))
|
||||||
mesh.tolist() for mesh in chain(geometry.faces, *geometry.add_faces.values())
|
|
||||||
))))
|
|
||||||
if offset:
|
if offset:
|
||||||
vertices = vertices / 1000 * self.np_scale + self.np_offset
|
vertices = vertices / 1000 * self.np_scale + self.np_offset
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue