Skip to content

Commit

Permalink
address cache performance regression in path objects
Browse files Browse the repository at this point in the history
  • Loading branch information
mikedh committed Nov 15, 2018
1 parent a9cbdae commit 9390447
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 24 deletions.
10 changes: 9 additions & 1 deletion tests/test_paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,5 +436,13 @@ def check_Path2D(path):


if __name__ == '__main__':
g.trimesh.util.attach_to_log()
from pyinstrument import Profiler
prof = Profiler()
prof.start()

# g.trimesh.util.attach_to_log()
g.unittest.main()

prof.stop()
txt = prof.output_text(unicode=True, color=True)
print(txt)
37 changes: 23 additions & 14 deletions trimesh/path/entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,12 @@ def __hash__(self):

def _bytes(self):
# give consistent ordering of points for hash
direction = [1, -1][int(self.points[0] > self.points[-1])]
hashable = (self.__class__.__name__.encode('utf-8') +
self.points[::direction].tobytes())
return hashable
if self.points[0] > self.points[-1]:
return (self.__class__.__name__.encode('utf-8') +
self.points.tobytes())
else:
return (self.__class__.__name__.encode('utf-8') +
self.points[::-1].tobytes())


class Line(Entity):
Expand Down Expand Up @@ -230,6 +232,13 @@ def explode(self):
exploded = [Line(i) for i in points]
return exploded

def _bytes(self):
# give consistent ordering of points for hash
if self.points[0] > self.points[-1]:
return b'Line' + self.points.tobytes()
else:
return b'Line' + self.points[::-1].tobytes()


class Arc(Entity):

Expand Down Expand Up @@ -273,11 +282,11 @@ def is_valid(self):
return len(np.unique(self.points)) == 3

def _bytes(self):
direction = [1, -1][int(self.points[0] > self.points[-1])]
hashable = (self.__class__.__name__.encode('utf-8') +
bytes(bool(self.closed)) +
self.points[::direction].tobytes())
return hashable
# give consistent ordering of points for hash
if self.points[0] > self.points[-1]:
return b'Arc' + bytes(self.closed) + self.points.tobytes()
else:
return b'Arc' + bytes(self.closed) + self.points[::-1].tobytes()

def discrete(self, vertices, scale=1.0):
"""
Expand Down Expand Up @@ -428,11 +437,11 @@ def discrete(self, vertices, count=None, scale=1.0):
return self._orient(discrete)

def _bytes(self):
direction = [1, -1][int(self.points[0] > self.points[-1])]
hashable = (self.__class__.__name__.encode('utf-8') +
self.knots[::direction].tobytes() +
self.points[::direction].tobytes())
return hashable
# give consistent ordering of points for hash
if self.points[0] > self.points[-1]:
return b'BSpline' + self.knots.tobytes() + self.points.tobytes()
else:
return b'BSpline' + self.knots[::-1].tobytes() + self.points[::-1].tobytes()

def to_dict(self):
"""
Expand Down
32 changes: 24 additions & 8 deletions trimesh/path/path.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

from .. import util
from .. import units
from .. import graph
from .. import caching
from .. import grouping
from .. import transformations
Expand Down Expand Up @@ -132,11 +133,10 @@ def crc(self):
crc: int, CRC of entity points and vertices
"""
# first CRC the points in every entity
target = caching.crc32(bytes().join(
e._bytes()
for e in self.entities))
target = caching.crc32(bytes().join(e._bytes()
for e in self.entities))
# add the CRC for the vertices
target += self.vertices.crc()
target ^= self.vertices.crc()
return target

def md5(self):
Expand All @@ -147,11 +147,12 @@ def md5(self):
------------
md5: str, two appended MD5 hashes
"""
# first MD5 the points in every entity
target = '{}{}'.format(
util.md5_object(bytes().join(e._bytes()
for e in self.entities)),
self.vertices.md5())

target = util.md5_object(bytes().join(
e._bytes()
for e in self.entities))
target += self.vertices.md5()
return target

@caching.cache_decorator
Expand Down Expand Up @@ -336,6 +337,21 @@ def vertex_graph(self):
graph, closed = traversal.vertex_graph(self.entities)
return graph

@caching.cache_decorator
def vertex_nodes(self):
"""
Get a list of which vertex indices are nodes,
which are either endpoints or points where the
entity makes a direction change.
Returns
--------------
nodes : (n, 2) int
Indexes of self.vertices which are nodes
"""
nodes = np.vstack([e.nodes for e in self.entities])
return nodes

def apply_transform(self, transform):
"""
Apply a transformation matrix to the current path in- place
Expand Down
2 changes: 1 addition & 1 deletion trimesh/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '2.35.28'
__version__ = '2.35.29'

0 comments on commit 9390447

Please sign in to comment.