From 8af9ef7f075c6172988c14097b2c9ebb8f7a7c3f Mon Sep 17 00:00:00 2001 From: Paul McCarthy <pauldmccarthy@gmail.com> Date: Fri, 12 Apr 2019 15:21:02 +0100 Subject: [PATCH] RF: Mesh class potentially stores teo copies of triangles with opposite winding order, to account for the possibility that different vertex sets require different orders. --- fsl/data/mesh.py | 56 +++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/fsl/data/mesh.py b/fsl/data/mesh.py index f5ca20ade..e581c9603 100644 --- a/fsl/data/mesh.py +++ b/fsl/data/mesh.py @@ -98,6 +98,12 @@ class Mesh(notifier.Notifier, meta.Meta): selectedVertices vertexSets + .. note:: Internally the ``Mesh`` class may store two versions of the + triangles, with opposite unwinding orders. It keeps track of the + required triangle unwinding order for each vertex set, so that + the :meth:`indices` method will return the appropriate copy for + the currently selected vertex set. + **Vertex data** @@ -183,19 +189,17 @@ class Mesh(notifier.Notifier, meta.Meta): self.__name = name self.__dataSource = dataSource - self.__indices = np.asarray(indices).reshape((-1, 3)) - self.__nvertices = self.__indices.max() + 1 - - # This attribute is used to store - # the currently selected vertex set, - # used as a kety into all of the - # dictionaries below. - self.__selected = None - - # Flag used to keep track of whether - # the triangle winding order has been - # "fixed" - see the addVertices method. - self.__fixed = False + self.__nvertices = indices.max() + 1 + self.__selected = None + + # We potentially store two copies of + # the indices, with opposite unwinding + # orders. The vindices dict stores refs + # to one or the other for each vertex + # set. + self.__indices = np.asarray(indices).reshape((-1, 3)) + self.__fixedIndices = None + self.__vindices = collections.OrderedDict() # All of these are populated # in the addVertices method @@ -287,7 +291,7 @@ class Mesh(notifier.Notifier, meta.Meta): @property def indices(self): """The ``(M, 3)`` triangles of this mesh. """ - return self.__indices + return self.__vindices[self.__selected] @property @@ -297,7 +301,7 @@ class Mesh(notifier.Notifier, meta.Meta): """ selected = self.__selected - indices = self.__indices + indices = self.__vindices[selected] vertices = self.__vertices[selected] fnormals = self.__faceNormals.get(selected, None) @@ -315,7 +319,7 @@ class Mesh(notifier.Notifier, meta.Meta): """ selected = self.__selected - indices = self.__indices + indices = self.__vindices[selected] vertices = self.__vertices[selected] vnormals = self.__vertNormals.get(selected, None) @@ -334,10 +338,8 @@ class Mesh(notifier.Notifier, meta.Meta): ``((xlow, ylow, zlow), (xhigh, yhigh, zhigh))`` """ - lo = self.__loBounds[self.__selected] hi = self.__hiBounds[self.__selected] - return lo, hi @@ -411,26 +413,26 @@ class Mesh(notifier.Notifier, meta.Meta): self.nvertices)) self.__vertices[key] = vertices + self.__vindices[key] = self.__indices self.__loBounds[key] = lo self.__hiBounds[key] = hi if select: self.vertices = key - # indices already fixed? - if fixWinding and (not self.__fixed): - indices = self.indices - normals = self.normals - needsFix = needsFixing(vertices, indices, normals, lo, hi) - self.__fixed = True + if fixWinding: + indices = self.__indices + normals = self.normals + needsFix = needsFixing(vertices, indices, normals, lo, hi) # See needsFixing documentation if needsFix: - indices[:, [1, 2]] = indices[:, [2, 1]] + if self.__fixedIndices is None: + self.__fixedIndices = indices[:, [0, 2, 1]] - for k, fn in self.__faceNormals.items(): - self.__faceNormals[k] = fn * -1 + self.__vindices[ key] = self.__fixedIndices + self.__faceNormals[key] = normals * -1 return vertices -- GitLab