Skip to content

Commit 414fbe8

Browse files
committed
[test] add cgalmesh v2m test, accept radbound/distbound via opt
1 parent b723d24 commit 414fbe8

File tree

6 files changed

+44
-31
lines changed

6 files changed

+44
-31
lines changed

README.md

Lines changed: 5 additions & 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>, Edward Xu (2024) <xu.ed at northeastern.edu>
66
* License: GNU Public License V3 or later
7-
* Version: 0.2.1
7+
* Version: 0.2.2
88
* URL: [https://pypi.org/project/iso2mesh/](https://pypi.org/project/iso2mesh/)
99
* Github: [https://github.com/NeuroJSON/pyiso2mesh](https://github.com/NeuroJSON/pyiso2mesh)
1010

@@ -130,6 +130,10 @@ i2m.plotmesh(no, el, 'x < 0', shade=False, edgecolor='r')
130130
# creating and plotting polyhedral solids (PLCs)
131131
mesh = i2m.latticegrid([0,1],[0,1,2], [0,2])
132132
i2m.plotmesh(mesh[0], mesh[1], alpha=0.5, linestyle='--')
133+
134+
# mesh and label PLC based domains using tetgen1.5
135+
mesh2 = i2m.s2m(mesh[0], mesh[1], 1, 0.03, method='tetgen1.5')
136+
i2m.plotmesh(mesh2[0], mesh2[1], alpha=0.5)
133137
```
134138

135139
`pyiso2mesh` subdivides all functions into sub-modules (**core, geometry, plot,

iso2mesh/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@
137137
barycentricgrid,
138138
)
139139

140-
__version__ = "0.2.1"
140+
__version__ = "0.2.2"
141141
__all__ = [
142142
"advancefront",
143143
"barycentricgrid",

iso2mesh/core.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,7 @@ def cgalv2m(vol, opt, maxvol):
793793
if not isinstance(opt, dict):
794794
ssize = opt
795795

796-
if isinstance(opt, dict) and len(opt) == 1:
796+
if isinstance(opt, dict):
797797
ssize = opt.get("radbound", ssize)
798798
ang = opt.get("angbound", ang)
799799
approx = opt.get("distbound", approx)
@@ -806,7 +806,7 @@ def cgalv2m(vol, opt, maxvol):
806806

807807
cmd = f'"{mcpath("cgalmesh", exesuff)}" "{mwpath("pre_cgalmesh.inr")}" "{mwpath("post_cgalmesh.mesh")}" {ang} {ssize} {approx} {reratio} {maxvol} {randseed}'
808808

809-
os.system(cmd)
809+
status, str_output = subprocess.getstatusoutput(cmd)
810810

811811
if not os.path.exists(mwpath("post_cgalmesh.mesh")):
812812
raise RuntimeError(f"Output file was not found. Command failed: {cmd}")

iso2mesh/trait.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -373,21 +373,21 @@ def elemvolume(node, elem, option=None):
373373
"""
374374

375375
# Convert 1-based indices to 0-based for Python indexing
376-
v1 = node[elem[:, 0] - 1, :]
377-
v2 = node[elem[:, 1] - 1, :]
378-
v3 = node[elem[:, 2] - 1, :]
376+
v1 = node[elem[:, 0] - 1, :3]
377+
v2 = node[elem[:, 1] - 1, :3]
378+
v3 = node[elem[:, 2] - 1, :3]
379379

380380
edge1 = v2 - v1
381381
edge2 = v3 - v1
382382

383-
if elem.shape[1] == node.shape[1]:
383+
if elem.shape[1] == 3:
384384
# Triangle area in 2D or area in 3D projected onto a plane
385385
det12 = np.cross(edge1, edge2)
386386
det12 = np.sum(det12 * det12, axis=1)
387387
vol = 0.5 * np.sqrt(det12)
388388
return vol
389389

390-
v4 = node[elem[:, 3] - 1, :]
390+
v4 = node[elem[:, 3] - 1, :3]
391391
edge3 = v4 - v1
392392

393393
# Compute signed volume of tetrahedron

setup.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
setup(
77
name="iso2mesh",
88
packages=["iso2mesh"],
9-
version="0.2.1",
9+
version="0.2.2",
1010
license='GPLv3+',
1111
description="Image-based 3D Surface and Volumetric Mesh Generator",
1212
long_description=readme,
@@ -16,16 +16,14 @@
1616
maintainer="Qianqian Fang",
1717
url="https://github.com/NeuroJSON/pyiso2mesh",
1818
keywords=[
19-
"JSON",
20-
"iso2mesh",
21-
"UBJSON",
22-
"Biso2mesh",
23-
"Openiso2mesh",
24-
"NeuroJSON",
25-
"JNIfTI",
26-
"JMesh",
27-
"Encoder",
28-
"Decoder",
19+
"Iso2Mesh",
20+
"Mesh generation",
21+
"FEM",
22+
"MATLAB",
23+
"Mesh-based Monte Carlo",
24+
"CGAL",
25+
"Tetgen",
26+
"CSG",
2927
],
3028
platforms="any",
3129
install_requires=["numpy>=1.8.0", "matplotlib"],

test/run_test.py

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -596,11 +596,11 @@ def test_surfboolean_second(self):
596596
no3, el3 = surfboolean(self.no1, self.el1, "second", self.no2, self.el2)
597597
no3, el3 = meshcheckrepair(no3, el3, "dup", tolerance=1e-4)
598598
node, elem, _ = s2m(no3, el3, 1, 100, "tetgen", np.array([2.6, 2.6, 2.6]))
599-
self.assertEqual(
600-
round(sum(elemvolume(node, elem[elem[:, 4] == 1, :4])), 5), 7.973
599+
self.assertAlmostEqual(
600+
sum(elemvolume(node, elem[elem[:, 4] == 1, :4])), 7.973, 5
601601
)
602-
self.assertEqual(
603-
round(sum(elemvolume(node, elem[elem[:, 4] == 0, :4])), 5), 0.027
602+
self.assertAlmostEqual(
603+
sum(elemvolume(node, elem[elem[:, 4] == 0, :4])), 0.027, 5
604604
)
605605

606606
def test_surfboolean_resolve(self):
@@ -609,14 +609,14 @@ def test_surfboolean_resolve(self):
609609
node, elem, _ = s2m(
610610
no3, el3, 1, 100, "tetgen", np.array([[1.5, 1.5, 1.5], [2.6, 2.6, 2.6]])
611611
)
612-
self.assertEqual(
613-
round(sum(elemvolume(node, elem[elem[:, 4] == 0, :4])), 5), 0.027
612+
self.assertAlmostEqual(
613+
sum(elemvolume(node, elem[elem[:, 4] == 0, :4])), 0.027, 5
614614
)
615-
self.assertEqual(
616-
round(sum(elemvolume(node, elem[elem[:, 4] == 1, :4])), 5), 0.973
615+
self.assertAlmostEqual(
616+
sum(elemvolume(node, elem[elem[:, 4] == 1, :4])), 0.973, 5
617617
)
618-
self.assertEqual(
619-
round(sum(elemvolume(node, elem[elem[:, 4] == 2, :4])), 5), 7.973
618+
self.assertAlmostEqual(
619+
sum(elemvolume(node, elem[elem[:, 4] == 2, :4])), 7.973, 5
620620
)
621621

622622
def test_surfboolean_self(self):
@@ -683,13 +683,24 @@ def test_binsurface0(self):
683683

684684
def test_v2s(self):
685685
no, fc, _, _ = v2s(self.im, 0.5, 0.03)
686-
self.assertAlmostEqual(round(sum(elemvolume(no, fc[:, :3])), 2), 5.01)
686+
self.assertAlmostEqual(sum(elemvolume(no, fc[:, :3])), 5.01, 2)
687687

688688
def test_v2m(self):
689689
no, el, fc = v2m(self.im, 0.5, 0.03, 10)
690690
self.assertAlmostEqual(round(sum(elemvolume(no, fc[:, :3])), 2), 5.01)
691691
self.assertAlmostEqual(round(sum(elemvolume(no, el[:, :4])), 4), 0.8786)
692692

693+
def test_cgalv2m(self):
694+
no, el, fc = v2m(
695+
self.im.astype(np.uint8),
696+
[],
697+
{"radbound": 0.03, "distbound": 0.2},
698+
10,
699+
"cgalmesh",
700+
)
701+
self.assertEqual(removedupelem(fc[:, :3]).shape[0], 0)
702+
self.assertAlmostEqual(sum(elemvolume(no[:, :3], el[:, :4])), 0.7455, 4)
703+
693704

694705
if __name__ == "__main__":
695706
unittest.main()

0 commit comments

Comments
 (0)