Skip to content

Commit c259973

Browse files
committed
[port] add slicesurf3, update port function table
1 parent 9b150ac commit c259973

File tree

2 files changed

+74
-7
lines changed

2 files changed

+74
-7
lines changed

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -279,12 +279,12 @@ tracked in https://github.com/NeuroJSON/pyiso2mesh/issues/1
279279
|`regpt2surf.m` | ⭕️ tested | |`rotmat2vec.m` | ⭕️ tested |
280280
|`affinemap.m` | ⭕️ tested | |`varargin2struct.m` | ⭕️ tested |
281281
| > Polyline handling| | |`jsonopt.m` | ⭕️ tested |
282-
| `slicesurf.m` | ⭕️ tested | | ⭕️ `mergestruct.m` | ⭕️ tested |
283-
| `slicesurf3.m` | ⭕️ tested | | ⭕️ `orthdisk.m` | ⭕️ tested |
284-
| `polylinelen.m` | ⭕️ tested | | ⭕️ `nestbracket2dim.m` | ⭕️ tested |
285-
| `polylinesimplify.m` | ⭕️ tested | | ⭕️ `memmapstream.m` | ⭕️ tested |
286-
| `polylineinterp.m` | ⭕️ tested | | ⭕️ `aos2soa.m` | ⭕️ tested |
287-
| `closestnode.m` | ⭕️ tested | | ⭕️ `soa2aos.m` | ⭕️ tested |
282+
| `slicesurf.m` | ⭕️ tested | | ⭕️ `mergestruct.m` | ⭕️ tested |
283+
| `slicesurf3.m` | ⭕️ tested | | ⭕️ `orthdisk.m` | ⭕️ tested |
284+
| `polylinelen.m` | ⭕️ tested | | ⭕️ `nestbracket2dim.m` | ⭕️ tested |
285+
| `polylinesimplify.m` | ⭕️ tested | | ⭕️ `memmapstream.m` | ⭕️ tested |
286+
| `polylineinterp.m` | ⭕️ tested | | ⭕️ `aos2soa.m` | ⭕️ tested |
287+
| `closestnode.m` | ⭕️ tested | | ⭕️ `soa2aos.m` | ⭕️ tested |
288288
| > Mesh resampling and optimization| |
289289
|`meshresample.m` | ✅ tested |
290290
|`remeshsurf.m` | ✅ tested |

iso2mesh/modify.py

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
surfedge,
4747
extractloops,
4848
)
49-
from iso2mesh.line import getplanefrom3pt
49+
from iso2mesh.line import getplanefrom3pt, polylinesimplify, polylinelen, polylineinterp
5050

5151
##====================================================================================
5252
## implementations
@@ -1127,6 +1127,8 @@ def slicesurf(node, face, *args):
11271127
An N x 3 array defining the 3-D positions of the mesh.
11281128
face : ndarray
11291129
An N x 3 integer array specifying the surface triangle indices (1-based in MATLAB, so subtract 1 if needed).
1130+
*args : list
1131+
Additional slicing parameters (e.g., slicing plane equation passed to qmeshcut)
11301132
11311133
Returns:
11321134
bcutpos : ndarray
@@ -1171,3 +1173,68 @@ def slicesurf(node, face, *args):
11711173
bcutpos = bcutpos[bcutloop]
11721174

11731175
return bcutpos, bcutloop, bcutvalue
1176+
1177+
1178+
def slicesurf3(node, elem, p1, p2, p3, step=None, minangle=None):
1179+
"""
1180+
slicesurf3(node, elem, p1, p2, p3, step=None, minangle=None)
1181+
1182+
Slice a closed surface by a plane and extract landmark nodes along the intersection
1183+
from p1 to p3, splitting at p2 into left and right segments.
1184+
1185+
Parameters:
1186+
node : ndarray (N, 3)
1187+
3D coordinates of the mesh nodes
1188+
elem : ndarray (M, 3)
1189+
Triangle surface indices (1-based)
1190+
p1, p2, p3 : ndarray (3,)
1191+
3D coordinates of key points on the curve
1192+
step : float, optional
1193+
Percentage (0-100) spacing for landmark nodes
1194+
minangle : float, optional
1195+
Minimum angle to trigger curve simplification
1196+
1197+
Returns:
1198+
leftpt : ndarray
1199+
Landmarks on the left half (from p2 to p1)
1200+
leftcurve : ndarray
1201+
All points on the left half curve
1202+
rightpt : ndarray, optional
1203+
Landmarks on the right half (from p2 to p3)
1204+
rightcurve : ndarray, optional
1205+
All points on the right half curve
1206+
"""
1207+
1208+
# Slice full curve through p1-p2-p3
1209+
fullcurve, _, _ = slicesurf(node, elem, np.vstack((p1, p2, p3)))
1210+
1211+
# Optional simplification
1212+
if minangle is not None and minangle > 0:
1213+
fullcurve, _ = polylinesimplify(fullcurve, minangle)
1214+
1215+
# Reorder fullcurve from p1 -> p2 -> p3
1216+
fulllen, fullcurve, _ = polylinelen(fullcurve, p1, p3, p2)
1217+
1218+
# Extract left side: from p2 to p1
1219+
leftlen, leftcurve, _ = polylinelen(fullcurve, p2, p1)
1220+
if step is not None:
1221+
positions = (
1222+
np.arange(step, 100 - step * 0.5 + 1e-5, step) * 0.01 * np.sum(leftlen)
1223+
)
1224+
_, _, leftpt = polylineinterp(leftlen, positions, leftcurve)
1225+
else:
1226+
leftpt = leftcurve
1227+
1228+
# Only compute right if needed
1229+
if step is not None or True: # mimic (nargout > 2)
1230+
rightlen, rightcurve = polylinelen(fullcurve, p2, p3)
1231+
if step is not None:
1232+
positions = (
1233+
np.arange(step, 100 - step * 0.5 + 1e-5, step) * 0.01 * np.sum(rightlen)
1234+
)
1235+
_, _, rightpt = polylineinterp(rightlen, positions, rightcurve)
1236+
else:
1237+
rightpt = rightcurve
1238+
return leftpt, leftcurve, rightpt, rightcurve
1239+
1240+
return leftpt, leftcurve

0 commit comments

Comments
 (0)