Spaces:
Sleeping
Sleeping
Upload endograft_script.py
Browse files- endograft_script.py +117 -113
endograft_script.py
CHANGED
|
@@ -2,104 +2,107 @@ import vtk
|
|
| 2 |
import numpy as np
|
| 3 |
import tempfile
|
| 4 |
|
| 5 |
-
def arc_length(
|
| 6 |
-
|
| 7 |
-
for i in range(1, len(
|
| 8 |
-
|
| 9 |
-
return
|
| 10 |
|
| 11 |
def compute_parallel_frames(centerline):
|
| 12 |
frames = []
|
| 13 |
|
| 14 |
-
|
| 15 |
-
|
| 16 |
|
| 17 |
-
|
| 18 |
-
if abs(np.dot(
|
| 19 |
-
|
| 20 |
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
|
| 25 |
-
frames.append((
|
| 26 |
|
| 27 |
-
for
|
| 28 |
-
|
| 29 |
-
|
| 30 |
|
| 31 |
-
|
| 32 |
-
|
| 33 |
|
| 34 |
-
if np.linalg.norm(
|
| 35 |
-
frames.append((
|
| 36 |
continue
|
| 37 |
|
| 38 |
-
|
| 39 |
-
angle = np.arccos(np.clip(np.dot(
|
| 40 |
|
| 41 |
-
def
|
| 42 |
-
return (
|
| 43 |
|
| 44 |
-
frames.append((
|
| 45 |
|
| 46 |
return frames
|
| 47 |
|
| 48 |
-
def project_point_to_surface(
|
| 49 |
-
|
|
|
|
|
|
|
|
|
|
| 50 |
closest = [0.0, 0.0, 0.0]
|
| 51 |
cellId = vtk.mutable(0)
|
| 52 |
subId = vtk.mutable(0)
|
| 53 |
dist2 = vtk.mutable(0.0)
|
| 54 |
|
| 55 |
-
locator.FindClosestPoint(
|
| 56 |
return np.array(closest)
|
| 57 |
|
| 58 |
-
def
|
|
|
|
| 59 |
|
| 60 |
-
idx = np.searchsorted(arc_lengths, query_distance)
|
| 61 |
if idx <= 0:
|
| 62 |
return centerline[0], frames[0]
|
| 63 |
if idx >= len(centerline):
|
| 64 |
return centerline[-1], frames[-1]
|
| 65 |
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
|
| 70 |
-
|
| 71 |
|
| 72 |
-
|
| 73 |
-
|
| 74 |
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
|
| 83 |
-
return
|
| 84 |
|
| 85 |
-
# Fabric
|
| 86 |
-
def create_component_fabric(centerline, frames,
|
| 87 |
# shift centerline sampling
|
| 88 |
shifted_centerline = centerline.copy()
|
| 89 |
|
| 90 |
-
|
| 91 |
|
| 92 |
pts = vtk.vtkPoints()
|
| 93 |
polys = vtk.vtkCellArray()
|
| 94 |
rings = []
|
| 95 |
|
| 96 |
-
A =
|
| 97 |
n_sections = 180
|
| 98 |
n_theta = 64
|
| 99 |
|
| 100 |
for i in range(n_sections):
|
| 101 |
-
|
| 102 |
-
|
| 103 |
|
| 104 |
ring = []
|
| 105 |
|
|
@@ -107,14 +110,14 @@ def create_component_fabric(centerline, frames, start_position, length, diameter
|
|
| 107 |
theta = 2 * np.pi * j / n_theta
|
| 108 |
axial_offset = 0.0
|
| 109 |
|
| 110 |
-
if i == 0 and
|
| 111 |
axial_offset = A * np.sin(waves * theta) - A
|
| 112 |
|
| 113 |
-
|
| 114 |
r = diameter / 2.0
|
| 115 |
-
|
| 116 |
|
| 117 |
-
ring.append(pts.InsertNextPoint(
|
| 118 |
|
| 119 |
rings.append(ring)
|
| 120 |
|
|
@@ -135,13 +138,14 @@ def create_component_fabric(centerline, frames, start_position, length, diameter
|
|
| 135 |
|
| 136 |
# Struts
|
| 137 |
|
| 138 |
-
def create_proximal_bare_stent(centerline, frames,
|
| 139 |
-
peak_spacing=7.0, component_type="proximal", wire_radius=0.35, waves=8, samples=240
|
|
|
|
| 140 |
|
| 141 |
-
|
| 142 |
append = vtk.vtkAppendPolyData()
|
| 143 |
|
| 144 |
-
# build fabric normals & locator
|
| 145 |
normal_gen = vtk.vtkPolyDataNormals()
|
| 146 |
normal_gen.SetInputData(main_fabric)
|
| 147 |
normal_gen.ComputePointNormalsOn()
|
|
@@ -150,35 +154,38 @@ def create_proximal_bare_stent(centerline, frames, fabric_start_distance, main_d
|
|
| 150 |
normal_gen.Update()
|
| 151 |
fabric_normals = normal_gen.GetOutput().GetPointData().GetNormals()
|
| 152 |
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
|
|
|
| 156 |
|
| 157 |
-
A =
|
| 158 |
r = main_diam_mm / 2.0
|
| 159 |
gap = peak_spacing
|
| 160 |
step = A + gap
|
| 161 |
|
| 162 |
n_crowns = int(np.ceil(length / step))
|
| 163 |
-
|
| 164 |
-
if ((component_type == "distal" or component_type == "extension") and (len(
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
#
|
| 168 |
-
|
|
|
|
|
|
|
| 169 |
extra_top = -1e-10 # peak at -7.5
|
| 170 |
|
| 171 |
if component_type == "proximal":
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
|
| 176 |
|
| 177 |
elif component_type == "distal":
|
| 178 |
-
|
| 179 |
|
| 180 |
else:
|
| 181 |
-
|
| 182 |
|
| 183 |
pts = vtk.vtkPoints()
|
| 184 |
lines = vtk.vtkCellArray()
|
|
@@ -189,22 +196,22 @@ def create_proximal_bare_stent(centerline, frames, fabric_start_distance, main_d
|
|
| 189 |
# keep ONLY negative or positive half of sine
|
| 190 |
if component_type == "proximal":
|
| 191 |
axial_offset = A_extra * min(0.0, np.sin(waves * theta))
|
| 192 |
-
|
| 193 |
-
+ (r + wire_radius) * (np.cos(theta)*
|
| 194 |
-
+ axial_offset *
|
| 195 |
elif (component_type == "distal" and length != 0):
|
| 196 |
axial_offset = A_extra * max(0.0, np.sin(waves * theta))
|
| 197 |
|
| 198 |
-
|
| 199 |
-
+ (r + wire_radius) * (np.cos(theta)*
|
| 200 |
-
+ axial_offset *
|
| 201 |
else:
|
| 202 |
continue
|
| 203 |
|
| 204 |
-
radial = (np.cos(theta)*
|
| 205 |
radial /= np.linalg.norm(radial)
|
| 206 |
|
| 207 |
-
pos =
|
| 208 |
pts.InsertNextPoint(pos)
|
| 209 |
|
| 210 |
if i > 0:
|
|
@@ -225,17 +232,14 @@ def create_proximal_bare_stent(centerline, frames, fabric_start_distance, main_d
|
|
| 225 |
tube.Update()
|
| 226 |
|
| 227 |
append.AddInputData(tube.GetOutput())
|
| 228 |
-
|
| 229 |
-
#
|
| 230 |
-
|
| 231 |
-
cell_locator = vtk.vtkCellLocator()
|
| 232 |
-
cell_locator.SetDataSet(main_fabric)
|
| 233 |
-
cell_locator.BuildLocator()
|
| 234 |
|
| 235 |
-
for
|
| 236 |
-
|
| 237 |
|
| 238 |
-
|
| 239 |
lines = vtk.vtkCellArray()
|
| 240 |
|
| 241 |
for i in range(samples + 1):
|
|
@@ -243,19 +247,19 @@ def create_proximal_bare_stent(centerline, frames, fabric_start_distance, main_d
|
|
| 243 |
|
| 244 |
axial_offset = A * (1 + np.sin(waves * theta)) / 2.0
|
| 245 |
|
| 246 |
-
|
| 247 |
-
+ (r + wire_radius) * (np.cos(theta)*
|
| 248 |
-
+ axial_offset *
|
| 249 |
|
| 250 |
-
|
| 251 |
|
| 252 |
-
pid =
|
| 253 |
-
|
| 254 |
-
|
| 255 |
|
| 256 |
-
|
| 257 |
|
| 258 |
-
|
| 259 |
|
| 260 |
if i > 0:
|
| 261 |
l = vtk.vtkLine()
|
|
@@ -264,7 +268,7 @@ def create_proximal_bare_stent(centerline, frames, fabric_start_distance, main_d
|
|
| 264 |
lines.InsertNextCell(l)
|
| 265 |
|
| 266 |
poly = vtk.vtkPolyData()
|
| 267 |
-
poly.SetPoints(
|
| 268 |
poly.SetLines(lines)
|
| 269 |
|
| 270 |
tube = vtk.vtkTubeFilter()
|
|
@@ -279,9 +283,9 @@ def create_proximal_bare_stent(centerline, frames, fabric_start_distance, main_d
|
|
| 279 |
append.Update()
|
| 280 |
return append.GetOutput()
|
| 281 |
|
| 282 |
-
def create_component_stents(centerline, frames,
|
| 283 |
|
| 284 |
-
stents = create_proximal_bare_stent(centerline, frames,
|
| 285 |
|
| 286 |
return stents
|
| 287 |
|
|
@@ -299,7 +303,7 @@ def merge_components(proximal, extension, distal):
|
|
| 299 |
|
| 300 |
return clean
|
| 301 |
|
| 302 |
-
def create_endograft(centerline, diameter,
|
| 303 |
frames = compute_parallel_frames(centerline)
|
| 304 |
peak_to_peak = 15.0
|
| 305 |
|
|
@@ -307,11 +311,11 @@ def create_endograft(centerline, diameter, proximal_length, extension_length, di
|
|
| 307 |
# PROXIMAL COMPONENT
|
| 308 |
# -------------------------
|
| 309 |
|
| 310 |
-
|
| 311 |
|
| 312 |
-
|
| 313 |
|
| 314 |
-
|
| 315 |
|
| 316 |
|
| 317 |
# -------------------------
|
|
@@ -322,8 +326,8 @@ def create_endograft(centerline, diameter, proximal_length, extension_length, di
|
|
| 322 |
else:
|
| 323 |
prox_extension_overlap = 2*peak_to_peak + extension_gap
|
| 324 |
|
| 325 |
-
extension_start =
|
| 326 |
-
extension_fabric = create_component_fabric(centerline, frames, extension_start, extension_length, diameter,
|
| 327 |
|
| 328 |
extension_stents = create_component_stents(centerline, frames, extension_start, extension_length, diameter, extension_fabric, peak_spacing=extension_gap, component_type="extension")
|
| 329 |
|
|
@@ -331,14 +335,14 @@ def create_endograft(centerline, diameter, proximal_length, extension_length, di
|
|
| 331 |
# DISTAL COMPONENT
|
| 332 |
# -------------------------
|
| 333 |
distal_overlap = 3*peak_to_peak + 2*distal_gap
|
| 334 |
-
distal_start =
|
| 335 |
-
distal_fabric = create_component_fabric(centerline, frames, distal_start, distal_length, diameter,
|
| 336 |
distal_stents = create_component_stents(centerline, frames, distal_start, distal_length, diameter, distal_fabric, peak_spacing=distal_gap, component_type="distal")
|
| 337 |
# -------------------------
|
| 338 |
# MERGE COMPONENTS
|
| 339 |
# -------------------------
|
| 340 |
-
fabric_part = merge_components(
|
| 341 |
-
stent_part = merge_components(
|
| 342 |
|
| 343 |
endograft = vtk.vtkAppendPolyData()
|
| 344 |
|
|
|
|
| 2 |
import numpy as np
|
| 3 |
import tempfile
|
| 4 |
|
| 5 |
+
def arc_length(cl):
|
| 6 |
+
s = np.zeros(len(cl))
|
| 7 |
+
for i in range(1, len(cl)):
|
| 8 |
+
s[i] = s[i-1] + np.linalg.norm(cl[i] - cl[i-1])
|
| 9 |
+
return s
|
| 10 |
|
| 11 |
def compute_parallel_frames(centerline):
|
| 12 |
frames = []
|
| 13 |
|
| 14 |
+
t0 = centerline[1] - centerline[0]
|
| 15 |
+
t0 /= np.linalg.norm(t0)
|
| 16 |
|
| 17 |
+
ref = np.array([0, 0, 1])
|
| 18 |
+
if abs(np.dot(t0, ref)) > 0.9:
|
| 19 |
+
ref = np.array([1, 0, 0])
|
| 20 |
|
| 21 |
+
n0 = np.cross(t0, ref)
|
| 22 |
+
n0 /= np.linalg.norm(n0)
|
| 23 |
+
b0 = np.cross(t0, n0)
|
| 24 |
|
| 25 |
+
frames.append((t0, n0, b0))
|
| 26 |
|
| 27 |
+
for i in range(1, len(centerline)):
|
| 28 |
+
ti = centerline[i] - centerline[i-1]
|
| 29 |
+
ti /= np.linalg.norm(ti)
|
| 30 |
|
| 31 |
+
t_prev, n_prev, b_prev = frames[-1]
|
| 32 |
+
v = np.cross(t_prev, ti)
|
| 33 |
|
| 34 |
+
if np.linalg.norm(v) < 1e-6:
|
| 35 |
+
frames.append((ti, n_prev, b_prev))
|
| 36 |
continue
|
| 37 |
|
| 38 |
+
v /= np.linalg.norm(v)
|
| 39 |
+
angle = np.arccos(np.clip(np.dot(t_prev, ti), -1, 1))
|
| 40 |
|
| 41 |
+
def rot(vec):
|
| 42 |
+
return (vec * np.cos(angle) + np.cross(v, vec) * np.sin(angle) + v * np.dot(v, vec) * (1 - np.cos(angle)))
|
| 43 |
|
| 44 |
+
frames.append((ti, rot(n_prev), rot(b_prev)))
|
| 45 |
|
| 46 |
return frames
|
| 47 |
|
| 48 |
+
def project_point_to_surface(p, surface_poly):
|
| 49 |
+
locator = vtk.vtkCellLocator()
|
| 50 |
+
locator.SetDataSet(surface_poly)
|
| 51 |
+
locator.BuildLocator()
|
| 52 |
+
|
| 53 |
closest = [0.0, 0.0, 0.0]
|
| 54 |
cellId = vtk.mutable(0)
|
| 55 |
subId = vtk.mutable(0)
|
| 56 |
dist2 = vtk.mutable(0.0)
|
| 57 |
|
| 58 |
+
locator.FindClosestPoint(p, closest, cellId, subId, dist2)
|
| 59 |
return np.array(closest)
|
| 60 |
|
| 61 |
+
def sample_centerline_by_s(centerline, s_cl, frames, s):
|
| 62 |
+
idx = np.searchsorted(s_cl, s)
|
| 63 |
|
|
|
|
| 64 |
if idx <= 0:
|
| 65 |
return centerline[0], frames[0]
|
| 66 |
if idx >= len(centerline):
|
| 67 |
return centerline[-1], frames[-1]
|
| 68 |
|
| 69 |
+
s0, s1 = s_cl[idx-1], s_cl[idx]
|
| 70 |
+
P0, P1 = centerline[idx-1], centerline[idx]
|
| 71 |
+
t = (s - s0) / (s1 - s0 + 1e-12)
|
| 72 |
|
| 73 |
+
P = (1 - t) * P0 + t * P1
|
| 74 |
|
| 75 |
+
t0, N0, B0 = frames[idx-1]
|
| 76 |
+
t1, N1, B1 = frames[idx]
|
| 77 |
|
| 78 |
+
t_vec = (1 - t) * t0 + t * t1
|
| 79 |
+
N_vec = (1 - t) * N0 + t * N1
|
| 80 |
+
B_vec = (1 - t) * B0 + t * B1
|
| 81 |
|
| 82 |
+
t_vec /= np.linalg.norm(t_vec)
|
| 83 |
+
N_vec /= np.linalg.norm(N_vec)
|
| 84 |
+
B_vec /= np.linalg.norm(B_vec)
|
| 85 |
|
| 86 |
+
return P, (t_vec, N_vec, B_vec)
|
| 87 |
|
| 88 |
+
# Fabric
|
| 89 |
+
def create_component_fabric(centerline, frames, start_s, length, diameter, start_amp_pp=2.0, waves=8):
|
| 90 |
# shift centerline sampling
|
| 91 |
shifted_centerline = centerline.copy()
|
| 92 |
|
| 93 |
+
s_cl = arc_length(centerline)
|
| 94 |
|
| 95 |
pts = vtk.vtkPoints()
|
| 96 |
polys = vtk.vtkCellArray()
|
| 97 |
rings = []
|
| 98 |
|
| 99 |
+
A = start_amp_pp / 2.0
|
| 100 |
n_sections = 180
|
| 101 |
n_theta = 64
|
| 102 |
|
| 103 |
for i in range(n_sections):
|
| 104 |
+
s_base = start_s + length * i / (n_sections - 1)
|
| 105 |
+
P_base, (t, N, B) = sample_centerline_by_s(centerline, s_cl, frames, s_base)
|
| 106 |
|
| 107 |
ring = []
|
| 108 |
|
|
|
|
| 110 |
theta = 2 * np.pi * j / n_theta
|
| 111 |
axial_offset = 0.0
|
| 112 |
|
| 113 |
+
if i == 0 and start_amp_pp > 0:
|
| 114 |
axial_offset = A * np.sin(waves * theta) - A
|
| 115 |
|
| 116 |
+
P = P_base + axial_offset * t
|
| 117 |
r = diameter / 2.0
|
| 118 |
+
pos = P + r * (np.cos(theta) * N + np.sin(theta) * B)
|
| 119 |
|
| 120 |
+
ring.append(pts.InsertNextPoint(pos))
|
| 121 |
|
| 122 |
rings.append(ring)
|
| 123 |
|
|
|
|
| 138 |
|
| 139 |
# Struts
|
| 140 |
|
| 141 |
+
def create_proximal_bare_stent(centerline, frames, fabric_start_s, main_diam_mm, length, main_fabric, peak_to_peak=15.0,
|
| 142 |
+
peak_spacing=7.0, component_type="proximal", wire_radius=0.35, waves=8, samples=240
|
| 143 |
+
):
|
| 144 |
|
| 145 |
+
s_cl = arc_length(centerline)
|
| 146 |
append = vtk.vtkAppendPolyData()
|
| 147 |
|
| 148 |
+
# --- build fabric normals & locator ONCE ---
|
| 149 |
normal_gen = vtk.vtkPolyDataNormals()
|
| 150 |
normal_gen.SetInputData(main_fabric)
|
| 151 |
normal_gen.ComputePointNormalsOn()
|
|
|
|
| 154 |
normal_gen.Update()
|
| 155 |
fabric_normals = normal_gen.GetOutput().GetPointData().GetNormals()
|
| 156 |
|
| 157 |
+
locator = vtk.vtkPointLocator()
|
| 158 |
+
locator.SetDataSet(main_fabric)
|
| 159 |
+
locator.BuildLocator()
|
| 160 |
+
# -----------------------------------------
|
| 161 |
|
| 162 |
+
A = peak_to_peak # peak-peak amplitude = 15
|
| 163 |
r = main_diam_mm / 2.0
|
| 164 |
gap = peak_spacing
|
| 165 |
step = A + gap
|
| 166 |
|
| 167 |
n_crowns = int(np.ceil(length / step))
|
| 168 |
+
s_peaks = [fabric_start_s + 1.0 + i * step for i in range(n_crowns)]
|
| 169 |
+
if ((component_type == "distal" or component_type == "extension") and (len(s_peaks) > 4)):
|
| 170 |
+
s_peaks = s_peaks[3:]
|
| 171 |
+
|
| 172 |
+
# =========================================================
|
| 173 |
+
# ===== EXTRA CLIPPED HALF sin =================
|
| 174 |
+
# =========================================================
|
| 175 |
+
A_extra = peak_to_peak / 2.0 # 7.5 mm height
|
| 176 |
extra_top = -1e-10 # peak at -7.5
|
| 177 |
|
| 178 |
if component_type == "proximal":
|
| 179 |
+
P0 = centerline[0]
|
| 180 |
+
t0, N0, B0 = frames[0]
|
| 181 |
+
P = P0 + extra_top * t0 # extrapolate backward
|
| 182 |
+
t, N, B = t0, N0, B0
|
| 183 |
|
| 184 |
elif component_type == "distal":
|
| 185 |
+
P, (t, N, B) = sample_centerline_by_s(centerline, s_cl, frames, fabric_start_s + length - extra_top)
|
| 186 |
|
| 187 |
else:
|
| 188 |
+
P, (t, N, B) = sample_centerline_by_s(centerline, s_cl, frames, extra_top)
|
| 189 |
|
| 190 |
pts = vtk.vtkPoints()
|
| 191 |
lines = vtk.vtkCellArray()
|
|
|
|
| 196 |
# keep ONLY negative or positive half of sine
|
| 197 |
if component_type == "proximal":
|
| 198 |
axial_offset = A_extra * min(0.0, np.sin(waves * theta))
|
| 199 |
+
raw_pos = (P
|
| 200 |
+
+ (r + wire_radius) * (np.cos(theta)*N + np.sin(theta)*B)
|
| 201 |
+
+ axial_offset * t)
|
| 202 |
elif (component_type == "distal" and length != 0):
|
| 203 |
axial_offset = A_extra * max(0.0, np.sin(waves * theta))
|
| 204 |
|
| 205 |
+
raw_pos = (P
|
| 206 |
+
+ (r + wire_radius) * (np.cos(theta)*N + np.sin(theta)*B)
|
| 207 |
+
+ axial_offset * t)
|
| 208 |
else:
|
| 209 |
continue
|
| 210 |
|
| 211 |
+
radial = (np.cos(theta)*N + np.sin(theta)*B)
|
| 212 |
radial /= np.linalg.norm(radial)
|
| 213 |
|
| 214 |
+
pos = P + (r + wire_radius) * radial + axial_offset * t
|
| 215 |
pts.InsertNextPoint(pos)
|
| 216 |
|
| 217 |
if i > 0:
|
|
|
|
| 232 |
tube.Update()
|
| 233 |
|
| 234 |
append.AddInputData(tube.GetOutput())
|
| 235 |
+
# =========================================================
|
| 236 |
+
# ================= NORMAL FULL struts ====================
|
| 237 |
+
# =========================================================
|
|
|
|
|
|
|
|
|
|
| 238 |
|
| 239 |
+
for s0 in s_peaks:
|
| 240 |
+
P, (t, N, B) = sample_centerline_by_s(centerline, s_cl, frames, s0)
|
| 241 |
|
| 242 |
+
pts = vtk.vtkPoints()
|
| 243 |
lines = vtk.vtkCellArray()
|
| 244 |
|
| 245 |
for i in range(samples + 1):
|
|
|
|
| 247 |
|
| 248 |
axial_offset = A * (1 + np.sin(waves * theta)) / 2.0
|
| 249 |
|
| 250 |
+
raw_pos = (P
|
| 251 |
+
+ (r + wire_radius) * (np.cos(theta)*N + np.sin(theta)*B)
|
| 252 |
+
+ axial_offset * t)
|
| 253 |
|
| 254 |
+
surf_p = project_point_to_surface(raw_pos, main_fabric)
|
| 255 |
|
| 256 |
+
pid = locator.FindClosestPoint(surf_p)
|
| 257 |
+
n = np.array(fabric_normals.GetTuple(pid))
|
| 258 |
+
n /= np.linalg.norm(n)
|
| 259 |
|
| 260 |
+
pos = surf_p + wire_radius * n
|
| 261 |
|
| 262 |
+
pts.InsertNextPoint(pos)
|
| 263 |
|
| 264 |
if i > 0:
|
| 265 |
l = vtk.vtkLine()
|
|
|
|
| 268 |
lines.InsertNextCell(l)
|
| 269 |
|
| 270 |
poly = vtk.vtkPolyData()
|
| 271 |
+
poly.SetPoints(pts)
|
| 272 |
poly.SetLines(lines)
|
| 273 |
|
| 274 |
tube = vtk.vtkTubeFilter()
|
|
|
|
| 283 |
append.Update()
|
| 284 |
return append.GetOutput()
|
| 285 |
|
| 286 |
+
def create_component_stents(centerline, frames, fabric_start_s, length, diameter, fabric, peak_to_peak=15.0, peak_spacing=7.0, component_type="proximal"):
|
| 287 |
|
| 288 |
+
stents = create_proximal_bare_stent(centerline, frames, fabric_start_s, diameter, length, fabric, peak_to_peak, peak_spacing, component_type)
|
| 289 |
|
| 290 |
return stents
|
| 291 |
|
|
|
|
| 303 |
|
| 304 |
return clean
|
| 305 |
|
| 306 |
+
def create_endograft(centerline, diameter, prox_length,extension_length, distal_length, prox_gap, extension_gap, distal_gap):
|
| 307 |
frames = compute_parallel_frames(centerline)
|
| 308 |
peak_to_peak = 15.0
|
| 309 |
|
|
|
|
| 311 |
# PROXIMAL COMPONENT
|
| 312 |
# -------------------------
|
| 313 |
|
| 314 |
+
prox_start = 0.0
|
| 315 |
|
| 316 |
+
prox_fabric = create_component_fabric(centerline, frames, prox_start, prox_length, diameter, start_amp_pp=2.0)
|
| 317 |
|
| 318 |
+
prox_stents = create_component_stents(centerline, frames, prox_start, prox_length, diameter, prox_fabric, peak_spacing=prox_gap, component_type="proximal")
|
| 319 |
|
| 320 |
|
| 321 |
# -------------------------
|
|
|
|
| 326 |
else:
|
| 327 |
prox_extension_overlap = 2*peak_to_peak + extension_gap
|
| 328 |
|
| 329 |
+
extension_start = prox_length - prox_extension_overlap
|
| 330 |
+
extension_fabric = create_component_fabric(centerline, frames, extension_start, extension_length, diameter, start_amp_pp=0.0)
|
| 331 |
|
| 332 |
extension_stents = create_component_stents(centerline, frames, extension_start, extension_length, diameter, extension_fabric, peak_spacing=extension_gap, component_type="extension")
|
| 333 |
|
|
|
|
| 335 |
# DISTAL COMPONENT
|
| 336 |
# -------------------------
|
| 337 |
distal_overlap = 3*peak_to_peak + 2*distal_gap
|
| 338 |
+
distal_start = prox_length + extension_length - prox_extension_overlap - distal_overlap
|
| 339 |
+
distal_fabric = create_component_fabric(centerline, frames, distal_start, distal_length, diameter, start_amp_pp=0.0)
|
| 340 |
distal_stents = create_component_stents(centerline, frames, distal_start, distal_length, diameter, distal_fabric, peak_spacing=distal_gap, component_type="distal")
|
| 341 |
# -------------------------
|
| 342 |
# MERGE COMPONENTS
|
| 343 |
# -------------------------
|
| 344 |
+
fabric_part = merge_components(prox_fabric, extension_fabric, distal_fabric)
|
| 345 |
+
stent_part = merge_components(prox_stents, extension_stents, distal_stents)
|
| 346 |
|
| 347 |
endograft = vtk.vtkAppendPolyData()
|
| 348 |
|