Skip to content

Commit b0c5ca0

Browse files
committed
FIX: Add test for normals
1 parent 45fd932 commit b0c5ca0

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

surfer/tests/test_utils.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,36 @@
1010
data_path = pjoin(subj_dir, subject_id)
1111

1212

13+
def _slow_compute_normals(rr, tris):
14+
"""Efficiently compute vertex normals for triangulated surface"""
15+
# first, compute triangle normals
16+
r1 = rr[tris[:, 0], :]
17+
r2 = rr[tris[:, 1], :]
18+
r3 = rr[tris[:, 2], :]
19+
tri_nn = np.cross((r2 - r1), (r3 - r1))
20+
21+
# Triangle normals and areas
22+
size = np.sqrt(np.sum(tri_nn * tri_nn, axis=1))
23+
zidx = np.where(size == 0)[0]
24+
size[zidx] = 1.0 # prevent ugly divide-by-zero
25+
tri_nn /= size[:, np.newaxis]
26+
27+
# accumulate the normals
28+
nn = np.zeros((len(rr), 3))
29+
for p, verts in enumerate(tris):
30+
nn[verts] += tri_nn[p, :]
31+
size = np.sqrt(np.sum(nn * nn, axis=1))
32+
size[size == 0] = 1.0 # prevent ugly divide-by-zero
33+
nn /= size[:, np.newaxis]
34+
return nn
35+
36+
1337
@utils.requires_fsaverage
1438
def test_surface():
1539
"""Test IO for Surface class"""
1640
for subjects_dir in [None, subj_dir]:
1741
surface = utils.Surface('fsaverage', 'lh', 'inflated',
18-
subjects_dir=subjects_dir)
42+
subjects_dir=subjects_dir)
1943
surface.load_geometry()
2044
surface.load_label('BA1')
2145
surface.load_curvature()
@@ -25,3 +49,7 @@ def test_surface():
2549
surface.apply_xfm(xfm)
2650
x_ = surface.x
2751
assert_array_almost_equal(x + 2, x_)
52+
53+
# normals
54+
nn = _slow_compute_normals(surface.coords, surface.faces)
55+
assert_array_almost_equal(nn, surface.nn)

surfer/utils.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,6 @@ def _fast_cross_3d(x, y):
171171
def _compute_normals(rr, tris):
172172
"""Efficiently compute vertex normals for triangulated surface"""
173173
# first, compute triangle normals
174-
t0 = time.time()
175174
r1 = rr[tris[:, 0], :]
176175
r2 = rr[tris[:, 1], :]
177176
r3 = rr[tris[:, 2], :]
@@ -197,6 +196,9 @@ def _compute_normals(rr, tris):
197196
vals = np.r_[np.zeros((1, 3)), np.cumsum(tri_nn[reord, :], 0)]
198197
idx = np.cumsum(np.r_[0, counts])
199198
nn += vals[idx[1:], :] - vals[idx[:-1], :]
199+
size = np.sqrt(np.sum(nn * nn, axis=1))
200+
size[size == 0] = 1.0 # prevent ugly divide-by-zero
201+
nn /= size[:, np.newaxis]
200202
return nn
201203

202204

0 commit comments

Comments
 (0)