Skip to content

Commit

Permalink
Added centroids as a mesh property.
Browse files Browse the repository at this point in the history
  • Loading branch information
Xorgon committed Apr 20, 2022
1 parent 988630f commit 462286c
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 4 deletions.
12 changes: 10 additions & 2 deletions stl/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,13 +313,16 @@ def remove_empty_areas(cls, data):
squared_areas = (normals ** 2).sum(axis=1)
return data[squared_areas > AREA_SIZE_THRESHOLD ** 2]

def update_normals(self, update_areas=True):
'''Update the normals and areas for all points'''
def update_normals(self, update_areas=True, update_centroids=True):
'''Update the normals, areas, and centroids for all points'''
normals = numpy.cross(self.v1 - self.v0, self.v2 - self.v0)

if update_areas:
self.update_areas(normals)

if update_centroids:
self.update_centroids()

self.normals[:] = normals

def get_unit_normals(self):
Expand All @@ -343,6 +346,9 @@ def update_areas(self, normals=None):
areas = .5 * numpy.sqrt((normals ** 2).sum(axis=1))
self.areas = areas.reshape((areas.size, 1))

def update_centroids(self):
self.centroids = numpy.mean([self.v0, self.v1, self.v2], axis=0)

def check(self):
'''Check the mesh is valid or not'''
return self.is_closed()
Expand Down Expand Up @@ -582,6 +588,8 @@ def _set(self, value):
doc='Mesh maximum value')
areas = property(_get_or_update('areas'), _set('areas'),
doc='Mesh areas')
centroids = property(_get_or_update('centroids'), _set('centroids'),
doc='Mesh centroids')
units = property(_get_or_update('units'), _set('units'),
doc='Mesh unit vectors')

Expand Down
21 changes: 19 additions & 2 deletions tests/test_mesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def test_units_1d():
mesh.update_units()

assert mesh.areas == 0
assert numpy.allclose(mesh.centroids, [[1, 0, 0]])
utils.array_equals(mesh.normals, [0, 0, 0])
utils.array_equals(mesh.units, [0, 0, 0])
utils.array_equals(mesh.get_unit_normals(), [0, 0, 0])
Expand All @@ -35,6 +36,9 @@ def test_units_2d():
mesh.update_units()

assert numpy.allclose(mesh.areas, [0.5, 0.5])
assert numpy.allclose(mesh.centroids, [
[1 / 3, 1 / 3, 0],
[2 / 3, 2 / 3, 0]])
assert numpy.allclose(mesh.normals, [
[0.0, 0.0, 1.0],
[0.0, 0.0, -1.0]])
Expand All @@ -54,6 +58,7 @@ def test_units_3d():
mesh.update_units()

assert (mesh.areas - 2 ** .5) < 0.0001
assert numpy.allclose(mesh.centroids, [1 / 3, 1 / 3, 1 / 3])
assert numpy.allclose(mesh.normals, [0.0, -1.0, 1.0])
assert numpy.allclose(mesh.units[0], [0.0, -0.70710677, 0.70710677])
assert numpy.allclose(numpy.linalg.norm(mesh.units, axis=-1), 1)
Expand Down Expand Up @@ -183,11 +188,23 @@ def test_empty_areas():
mesh.areas[2] = 2
assert numpy.allclose(mesh.areas, [[0.5], [1.0], [2.0]])

mesh.update_normals(update_areas=False)
mesh.centroids[1] = [1, 2, 3]
mesh.centroids[2] = [4, 5, 6]
assert numpy.allclose(mesh.centroids, [[1 / 3, 1 / 3, 0],
[1, 2, 3],
[4, 5, 6]])

mesh.update_normals(update_areas=False, update_centroids=False)
assert numpy.allclose(mesh.areas, [[0.5], [1.0], [2.0]])
assert numpy.allclose(mesh.centroids, [[1 / 3, 1 / 3, 0],
[1, 2, 3],
[4, 5, 6]])

mesh.update_normals(update_areas=True)
mesh.update_normals(update_areas=True, update_centroids=True)
assert numpy.allclose(mesh.areas, [[0.5], [0.0], [0.0]])
assert numpy.allclose(mesh.centroids, [[1 / 3, 1 / 3, 0],
[2 / 3, 1 / 3, 0],
[2 / 3, 1 / 3, 0]])

mesh = Mesh(data, remove_empty_areas=True)
assert mesh.data.size == 1
Expand Down

0 comments on commit 462286c

Please sign in to comment.