|
46 | 46 | surfedge,
|
47 | 47 | extractloops,
|
48 | 48 | )
|
49 |
| -from iso2mesh.line import getplanefrom3pt |
| 49 | +from iso2mesh.line import getplanefrom3pt, polylinesimplify, polylinelen, polylineinterp |
50 | 50 |
|
51 | 51 | ##====================================================================================
|
52 | 52 | ## implementations
|
@@ -1127,6 +1127,8 @@ def slicesurf(node, face, *args):
|
1127 | 1127 | An N x 3 array defining the 3-D positions of the mesh.
|
1128 | 1128 | face : ndarray
|
1129 | 1129 | 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) |
1130 | 1132 |
|
1131 | 1133 | Returns:
|
1132 | 1134 | bcutpos : ndarray
|
@@ -1171,3 +1173,68 @@ def slicesurf(node, face, *args):
|
1171 | 1173 | bcutpos = bcutpos[bcutloop]
|
1172 | 1174 |
|
1173 | 1175 | 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