Skip to content

Commit 76b524a

Browse files
committed
[brain2mesh] accelerate brain2mesh, binsurface avoid meshcheckrepair
1 parent 6cb39f6 commit 76b524a

File tree

9 files changed

+49
-40
lines changed

9 files changed

+49
-40
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
* **Copyright**: (C) Qianqian Fang (2024-2025) <q.fang at neu.edu>
66
* **License**: GNU Public License V3 or later
7-
* **Version**: 0.4.0
7+
* **Version**: 0.4.1
88
* **URL**: [https://pypi.org/project/iso2mesh/](https://pypi.org/project/iso2mesh/)
99
* **Homepage**: [https://iso2mesh.sf.net](https://iso2mesh.sf.net)
1010
* **Github**: [https://github.com/NeuroJSON/pyiso2mesh](https://github.com/NeuroJSON/pyiso2mesh)

iso2mesh/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@
177177
thinbinvol,
178178
)
179179

180-
__version__ = "0.4.0"
180+
__version__ = "0.4.1"
181181
__all__ = [
182182
"advancefront",
183183
"barycentricgrid",

iso2mesh/brain2mesh.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -673,8 +673,8 @@ def normalizer(x):
673673

674674
# Generate brain_f if requested
675675
brain_f = np.array([])
676-
# if len(sys._getframe().f_back.f_code.co_names) > 2: # Check if brain_f is requested
677-
# brain_f = layersurf(brain_el)
676+
if cfg.get("face", False): # Check if brain_f is requested
677+
brain_f = layersurf(brain_el)[0]
678678

679679
return brain_n, brain_el, brain_f
680680

@@ -1387,7 +1387,7 @@ def brain1020(
13871387
# At this point, initpoints contains {nz, iz, lpa, rpa, cz0}
13881388
# Plot the head mesh
13891389
if showplot:
1390-
hh = plotmesh(node, face, alpha=0.6, color="wheat", linewidth=0)
1390+
hh = plotmesh(node, face, alpha=0, color="wheat", linewidth=0.1)
13911391
ax = hh["ax"][0]
13921392
ax.set_xlabel("X")
13931393
ax.set_ylabel("Y")

iso2mesh/core.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ def vol2surf(img, ix, iy, iz, opt, dofix=0, method="cgalsurf", isovalues=None):
331331
else:
332332
levelmask = newimg >= isovalues[i]
333333

334-
levelno, levelel = binsurface(levelmask)
334+
levelno, levelel = binsurface(levelmask, clean=False)
335335

336336
if levelel.size > 0:
337337
if opt.get("autoregion", 0):
@@ -694,7 +694,7 @@ def surf2vol(node, face, xi, yi, zi, **kwargs):
694694
return img.astype(np.uint8)
695695

696696

697-
def binsurface(img, nface=3):
697+
def binsurface(img, nface=3, **kwargs):
698698
"""
699699
node, elem = binsurface(img, nface)
700700
@@ -787,7 +787,7 @@ def binsurface(img, nface=3):
787787
xi, yi, zi = np.unravel_index(id, newdim, order="F")
788788
node = np.column_stack([xi, yi, zi])
789789

790-
if nface == 3:
790+
if nface == 3 and kwargs.get("clean", True):
791791
node, elem = meshcheckrepair(node, elem)
792792

793793
return node, elem

iso2mesh/modify.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ def meshcheckrepair(node, elem, opt=None, **kwargs):
378378
if status:
379379
raise RuntimeError(f"jmeshlib command failed: {output}")
380380
node, elem = readoff(mwpath("post_sclean.off"))
381+
elem = np.flipud(elem)
381382

382383
if opt == "meshfix":
383384
exesuff = fallbackexeext(getexeext(), "meshfix")

iso2mesh/plot.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,15 @@ def plotmesh(node, *args, **kwargs):
428428
if getattr(idx, "size", None) == 0:
429429
print("Warning: nothing to plot")
430430
return None
431-
handles = plottetra(node, elem[idx, :], opt, *args, **kwargs)
431+
if "alpha" not in kwargs and selector:
432+
faceselect, elemid = volface(elem[idx, :4])
433+
if elem.shape[1] > 4:
434+
faceselect = np.hstack(
435+
(faceselect, elem[idx[elemid - 1], 4].reshape(-1, 1))
436+
)
437+
handles = plotsurf(node, faceselect, opt, *args, **kwargs)
438+
else:
439+
handles = plottetra(node, elem[idx, :], opt, *args, **kwargs)
432440

433441
if not "hold" in extraarg or not extraarg["hold"] or extraarg["hold"] == "off":
434442
plt.draw()

iso2mesh/trait.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,9 @@ def surfedge(f, junction=None):
142142

143143
openedge = edges[ix[qx], :]
144144

145-
elemid = None
146-
elemid, _ = np.unravel_index(ix[qx], f.shape)
145+
elemid, _ = np.unravel_index(ix[qx], f.shape, order="F")
147146

148-
return openedge, elemid
147+
return openedge, elemid + 1
149148

150149

151150
# _________________________________________________________________________________________________________
@@ -495,11 +494,11 @@ def layersurf(elem, **kwargs):
495494
# Process each label
496495
for i in range(len(labels)):
497496
if outsideislower == ">=" and labels[i] not in innermost:
498-
newface = volface(elem[elem[:, 4] >= labels[i], :4])
497+
newface = volface(elem[elem[:, 4] >= labels[i], :4])[0]
499498
elif outsideislower == "<=" and labels[i] not in innermost:
500-
newface = volface(elem[elem[:, 4] <= labels[i], :4])
499+
newface = volface(elem[elem[:, 4] <= labels[i], :4])[0]
501500
else:
502-
newface = volface(elem[elem[:, 4] == labels[i], :4])
501+
newface = volface(elem[elem[:, 4] == labels[i], :4])[0]
503502

504503
# Add label to faces
505504
newface = np.hstack((newface, np.full((newface.shape[0], 1), labels[i])))

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
setup(
77
name="iso2mesh",
88
packages=["iso2mesh"],
9-
version="0.4.0",
9+
version="0.4.1",
1010
license="GPLv3+",
1111
description="One-liner 3D Surface and Tetrahedral Mesh Generation Toolbox",
1212
long_description=readme,

test/run_test.py

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,24 +1112,24 @@ def __init__(self, *args, **kwargs):
11121112
def test_binsurface(self):
11131113
no, fc = binsurface(self.im)
11141114
expected_fc = [
1115-
[10, 4, 1],
1116-
[7, 10, 1],
1117-
[12, 6, 5],
1118-
[11, 5, 4],
1119-
[2, 3, 9],
1120-
[1, 2, 8],
1121-
[11, 12, 5],
1122-
[10, 11, 4],
1123-
[2, 9, 8],
1124-
[1, 8, 7],
1125-
[8, 9, 12],
1126-
[7, 8, 11],
1127-
[6, 3, 2],
1128-
[5, 2, 1],
1129-
[8, 12, 11],
1130-
[7, 11, 10],
1131-
[5, 6, 2],
11321115
[4, 5, 1],
1116+
[5, 6, 2],
1117+
[7, 11, 10],
1118+
[8, 12, 11],
1119+
[5, 2, 1],
1120+
[6, 3, 2],
1121+
[7, 8, 11],
1122+
[8, 9, 12],
1123+
[1, 8, 7],
1124+
[2, 9, 8],
1125+
[10, 11, 4],
1126+
[11, 12, 5],
1127+
[1, 2, 8],
1128+
[2, 3, 9],
1129+
[11, 5, 4],
1130+
[12, 6, 5],
1131+
[7, 10, 1],
1132+
[10, 4, 1],
11331133
]
11341134
self.assertEqual(fc.tolist(), expected_fc)
11351135

@@ -1168,7 +1168,7 @@ def test_v2s(self):
11681168
def test_v2m(self):
11691169
no, el, fc = v2m(self.im, 0.5, 0.03, 10)
11701170
self.assertAlmostEqual(sum(elemvolume(no, fc[:, :3])), 5.01, 2)
1171-
self.assertAlmostEqual(sum(elemvolume(no, el[:, :4])), 0.8786, 4)
1171+
self.assertAlmostEqual(sum(elemvolume(no, el[:, :4])), 0.8786654361973504, 4)
11721172

11731173
def test_cgalv2m(self):
11741174
no, el, fc = v2m(
@@ -1184,11 +1184,12 @@ def test_cgalv2m(self):
11841184
@unittest.skipIf(sys.platform.startswith("darwin"), "skip cgals2m")
11851185
def test_cgals2m(self):
11861186
node, elem, face = cgals2m(self.no[:, :3], self.fc[:, :3], 1, 50)
1187+
11871188
self.assertAlmostEqual(
1188-
sum(elemvolume(node[:, :3], face[:, :3])) * 0.001, 2.464594888865948, 3
1189+
sum(elemvolume(node[:, :3], face[:, :3])) * 0.001, 2.456809397314205, 3
11891190
)
11901191
self.assertAlmostEqual(
1191-
sum(elemvolume(node[:, :3], elem[:, :4])) * 0.001, 3.9983115207040685, 2
1192+
sum(elemvolume(node[:, :3], elem[:, :4])) * 0.001, 3.983804447661502, 2
11921193
)
11931194

11941195
def test_v2s_label(self):
@@ -1252,7 +1253,7 @@ def test_surf2volz(self):
12521253
np.arange(19, 42, 1),
12531254
np.arange(19, 42, 1),
12541255
)
1255-
self.assertAlmostEqual(np.sum(vol.astype(np.float32)) * 0.001, 1.099, 2)
1256+
self.assertAlmostEqual(np.sum(vol.astype(np.float32)) * 0.001, 1.125, 2)
12561257

12571258
def test_surf2vol(self):
12581259
vol = surf2vol(
@@ -1262,7 +1263,7 @@ def test_surf2vol(self):
12621263
np.arange(19, 42, 1),
12631264
np.arange(19, 42, 1),
12641265
)
1265-
self.assertAlmostEqual(np.sum(vol.astype(np.float32)) * 0.001, 1.704, 2)
1266+
self.assertAlmostEqual(np.sum(vol.astype(np.float32)) * 0.001, 1.72, 2)
12661267

12671268
def test_surf2vol_fill(self):
12681269
vol = surf2vol(
@@ -1273,11 +1274,11 @@ def test_surf2vol_fill(self):
12731274
np.arange(19, 42, 0.5),
12741275
fill=1,
12751276
)
1276-
self.assertAlmostEqual(np.sum(vol.astype(np.float32)) * 0.0001, 3.5536, 2)
1277+
self.assertAlmostEqual(np.sum(vol.astype(np.float32)) * 0.0001, 3.5391, 2)
12771278

12781279
def test_s2v(self):
12791280
vol = s2v(self.no, self.fc, 100, fill=1)
1280-
self.assertAlmostEqual(np.sum(vol.astype(np.float32)) * 0.00001, 6.0827, 2)
1281+
self.assertAlmostEqual(np.sum(vol.astype(np.float32)) * 0.00001, 6.0598097, 2)
12811282

12821283
def test_mesh2mask(self):
12831284
node = np.array([[0, 0], [2, 0], [2, 1], [0, 1], [1, 0.5]])

0 commit comments

Comments
 (0)