Skip to content

Commit

Permalink
fix metadata slowdown
Browse files Browse the repository at this point in the history
  • Loading branch information
mikedh committed Jan 2, 2019
1 parent 6793f0b commit 718232b
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 22 deletions.
2 changes: 1 addition & 1 deletion trimesh/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -985,7 +985,7 @@ def merge_vertices(self, distance=None):
distance : float or None
If specified overrides tol.merge
"""
grouping.merge_vertices_hash(self, distance=distance)
grouping.merge_vertices(self, distance=distance)

def update_vertices(self, mask, inverse=None):
"""
Expand Down
11 changes: 10 additions & 1 deletion trimesh/exchange/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,16 @@ def encode(item, dtype=None):
return util.array_to_encoded(item,
dtype=dtype,
encoding=encoding)
export = {'metadata': util.tolist(mesh.metadata),

# metadata keys we explicitly want to preserve
# sometimes there are giant datastructures we don't
# care about in metadata which causes exports to be
# extremely slow, so skip all but known good keys
meta_keys = ['units', 'file_name', 'file_path']
metadata = {k: v for k, v in mesh.metadata.items()
if k in meta_keys}

export = {'metadata': metadata,
'faces': encode(mesh.faces),
'face_normals': encode(mesh.face_normals),
'vertices': encode(mesh.vertices)}
Expand Down
11 changes: 5 additions & 6 deletions trimesh/exchange/gltf.py
Original file line number Diff line number Diff line change
Expand Up @@ -569,8 +569,11 @@ def _parse_materials(header, views):
# mime = img['mimeType']
try:
# load the buffer into a PIL image
# flip top- bottom to move origin to lower-left:
# https://github.com/KhronosGroup/glTF/issues/1021
images[i] = PIL.Image.open(
util.wrap_as_stream(blob))
util.wrap_as_stream(blob)).transpose(
PIL.Image.FLIP_TOP_BOTTOM)
except BaseException:
log.error('failed to load image!',
exc_info=True)
Expand Down Expand Up @@ -695,13 +698,9 @@ def _read_buffers(header,
if 'material' not in p:
log.warning('texcoord without material!')
else:
# move Y origin from top (GLTF) to bottom (us)
uv = access[p['attributes']['TEXCOORD_0']].copy()
uv[:, 1] = 1.0 - uv[:, 1]

# create a texture visual
kwargs['visual'] = visual.texture.TextureVisuals(
uv=uv,
uv=access[p['attributes']['TEXCOORD_0']],
material=materials[p['material']])

# create a unique mesh name per- primitive
Expand Down
10 changes: 5 additions & 5 deletions trimesh/grouping.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@
log.warning('Scipy unavailable')


def merge_vertices_hash(mesh, distance=None):
def merge_vertices(mesh, distance=None):
"""
Removes duplicate vertices, based on integer hashes of
each row.
Parameters
-------------
mesh : Trimesh object
Mesh to merge vertices of
distance : float, or None
If not specified uses tol.merge
mesh : Trimesh object
Mesh to merge vertices on
distance : float or None
If not specified uses tol.merge
"""
if distance is not None:
digits = util.decimal_to_digits(distance)
Expand Down
3 changes: 1 addition & 2 deletions trimesh/scene/scene.py
Original file line number Diff line number Diff line change
Expand Up @@ -565,8 +565,7 @@ def export(self, file_type=None):
break
else:
# if file_type is not a dict, try to export everything in the
# scene as that value (probably a single string, like
# 'ply')
# the scene as that value like 'ply'
export_type = file_type
exported = {'data': geometry.export(file_type=export_type),
'file_type': export_type}
Expand Down
64 changes: 57 additions & 7 deletions trimesh/visual/texture.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,35 +16,81 @@ def __init__(self,
Store a material and UV coordinates for a mesh.
If passed just UV coordinates and a single image it will
create a SimpleMaterial for the image.
Parameters
--------------
uv : (n, 2) float
UV coordinates for the mesh
material : Material
Store images and properties
image : PIL.Image
Can be passed to automatically create material
"""

# store values we care about and hash
self._data = caching.DataStore()
# cache calculated values
self._cache = caching.Cache(self._data.fast_hash)

# should be (n, 2) float, where (n == len(mesh.vertices))
self.uv = np.asanyarray(uv, dtype=np.float64)
# should be (n, 2) float
self.uv = uv

# if an image is passed create a SimpleMaterial
if material is None and image is not None:
# if an image is passed create a SimpleMaterial
self.material = SimpleMaterial(image=image)
else:
# may be None
self.material = material

def _verify_crc(self):
"""
Dump the cache if anything in self._data has changed.
"""
self._cache.verify()

def crc(self):
"""
Get a CRC of the stored data.
Returns
--------------
crc : int
Hash of items in self._data
"""
return self._data.crc()

@property
def uv(self):
"""
Get the stored UV coordinates.
Returns
------------
uv : (n, 2) float
Pixel position per- vertex
"""
return self._data['uv']

@uv.setter
def uv(self, values):
"""
Set the UV coordinates.
Parameters
--------------
values : (n, 2) float
Pixel locations on a texture per- vertex
"""
self._data['uv'] = np.asanyarray(values, dtype=np.float64)

def copy(self):
"""
Return a copy of the current TextureVisuals object.
Returns
----------
copied : TextureVisuals
Contains the same information as self
Contains the same information in a new object
"""
copied = TextureVisuals(
uv=self.uv.copy(),
Expand All @@ -69,7 +115,10 @@ def to_color(self):
return vis

def face_subset(self, face_index):
pass
"""
Get a copy of
"""
return self.copy()

def update_vertices(self, mask):
"""
Expand All @@ -85,7 +134,8 @@ def update_faces(self, mask):


class Material(object):
pass
def __init__(self, *args, **kwargs):
raise NotImplementedError('material must be subclassed!')


class SimpleMaterial(Material):
Expand Down Expand Up @@ -196,7 +246,7 @@ def uv_to_color(uv, image):

# access colors from pixel locations
# make sure image is RGBA before getting values
colors = np.asarray(image.convert('RGBA'))[y, x]
colors = np.asanyarray(image.convert('RGBA'))[y, x]

# conversion to RGBA should have corrected shape
assert colors.ndim == 2 and colors.shape[1] == 4
Expand Down

0 comments on commit 718232b

Please sign in to comment.