Skip to content

Commit e07af95

Browse files
committed
different thicknesses
1 parent 515496c commit e07af95

File tree

1 file changed

+134
-86
lines changed

1 file changed

+134
-86
lines changed

scripts/dem_vault_rv.py

Lines changed: 134 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,82 @@ def break_boundary(mesh: Mesh, breakpoints: list[int]) -> tuple[list[list[int]],
5050
return borders, breakpoints
5151

5252

53-
def make_block():
54-
pass
53+
def make_block(basemesh: Mesh, idos: Mesh, face: int) -> Mesh:
54+
vertices = basemesh.face_vertices(face)
55+
normals = [basemesh.vertex_normal(vertex) for vertex in vertices]
56+
thickness = basemesh.vertices_attribute("thickness", keys=vertices)
5557

58+
bottom = idos.vertices_points(vertices)
59+
top = [point + vector * t for point, vector, t in zip(bottom, normals, thickness)]
60+
61+
frame = Frame(*bestfit_frame_numpy(top))
62+
plane = Plane.from_frame(frame)
63+
64+
flattop = []
65+
for a, b in zip(bottom, top):
66+
b = plane.intersection_with_line(Line(a, b))
67+
flattop.append(b)
68+
69+
sides = []
70+
for (a, b), (aa, bb) in zip(pairwise(bottom + bottom[:1]), pairwise(flattop + flattop[:1])):
71+
sides.append([a, b, bb, aa])
72+
73+
polygons = [bottom[::-1], flattop] + sides
74+
75+
block: Mesh = Mesh.from_polygons(polygons)
76+
block.update_default_face_attributes(is_support=False, is_interface=False)
77+
block.attributes["frame"] = frame
78+
block.attributes["is_support"] = False
79+
80+
return block
81+
82+
83+
def make_block_referenced(basemesh: Mesh, idos: Mesh, face: int) -> Mesh:
84+
N = basemesh._max_vertex + 1
85+
86+
vertices = basemesh.face_vertices(face)
87+
normals = [basemesh.vertex_normal(vertex) for vertex in vertices]
88+
thickness = basemesh.vertices_attribute("thickness", keys=vertices)
89+
90+
bottom = idos.vertices_points(vertices)
91+
top = [point + vector * t for point, vector, t in zip(bottom, normals, thickness)]
92+
93+
frame = Frame(*bestfit_frame_numpy(top))
94+
plane = Plane.from_frame(frame)
95+
96+
flattop = []
97+
for a, b in zip(bottom, top):
98+
b = plane.intersection_with_line(Line(a, b))
99+
flattop.append(b)
100+
101+
block: Mesh = Mesh()
102+
103+
for vertex, point in zip(vertices, bottom):
104+
# use the same identifiers for the vertices of the bottom face
105+
key = vertex
106+
block.add_vertex(key=key, x=point[0], y=point[1], z=point[2])
107+
108+
for vertex, point in zip(vertices, flattop):
109+
# offset the identifiers of the top face by "N"
110+
key = vertex + N
111+
block.add_vertex(key=key, x=point[0], y=point[1], z=point[2])
112+
113+
block.add_face(vertices[::-1])
114+
block.add_face([vertex + N for vertex in vertices])
115+
116+
for u, v in pairwise(vertices + vertices[:1]):
117+
block.add_face([u, v, v + N, u + N])
118+
119+
block.update_default_face_attributes(is_support=False, is_interface=False)
120+
121+
block.attributes["n"] = N
122+
block.attributes["frame"] = frame
123+
block.attributes["is_support"] = False
56124

57-
def make_block_referenced():
58-
pass
125+
return block
59126

60127

61-
def trimesh_remesh_python_with_projection(trimesh: Mesh):
128+
def trimesh_remesh_python_with_projection(trimesh: Mesh, target_length: float, kmax: int = 300) -> None:
62129
def project(mesh: Mesh, k: int, args) -> None:
63130
for vertex in mesh.vertices():
64131
if mesh.is_vertex_on_boundary(vertex):
@@ -82,8 +149,8 @@ def project(mesh: Mesh, k: int, args) -> None:
82149

83150
trimesh_remesh_python(
84151
trimesh,
85-
length,
86-
kmax=300,
152+
target_length,
153+
kmax=kmax,
87154
callback=project,
88155
)
89156

@@ -100,6 +167,23 @@ def project(mesh: Mesh, k: int, args) -> None:
100167
thrustobject = rv_scene.find_by_name("ThrustDiagram")
101168
thrustdiagram: FormDiagram = thrustobject.mesh
102169

170+
# =============================================================================
171+
# Global Parameters
172+
# =============================================================================
173+
174+
THICKNESS_SUPPORTS1 = 30
175+
THICKNESS_SUPPORTS2 = 20
176+
THICKNESS_BORDER = 10
177+
THICKNESS_TOP = 10
178+
179+
LENGTH_FACTOR = 0.9
180+
181+
MAX_CHAMFER_ANGLE = 145
182+
CHAMFER_OFFSET = 2
183+
184+
SUPPORT_PADDING = 5
185+
SUPPORT_DEPTH = 70
186+
103187
# =============================================================================
104188
# Mesh
105189
#
@@ -113,7 +197,7 @@ def project(mesh: Mesh, k: int, args) -> None:
113197
for face in list(mesh.faces_where(_is_loaded=False)):
114198
mesh.delete_face(face)
115199

116-
length = sum(mesh.edge_length(edge) for edge in mesh.edges()) / mesh.number_of_edges()
200+
average_length = sum(mesh.edge_length(edge) for edge in mesh.edges()) / mesh.number_of_edges()
117201

118202
# =============================================================================
119203
# Mesh: Borders
@@ -142,16 +226,24 @@ def project(mesh: Mesh, k: int, args) -> None:
142226
# - use a percentage of the average edge length of the original mesh as target length
143227
# =============================================================================
144228

229+
target_edge_length = LENGTH_FACTOR * average_length
230+
145231
M = trimesh.to_vertices_and_faces()
146-
V, F = trimesh_remesh(M, target_edge_length=0.9 * length, number_of_iterations=100)
232+
V, F = trimesh_remesh(
233+
M,
234+
target_edge_length=target_edge_length,
235+
number_of_iterations=100,
236+
)
147237

148238
trimesh = Mesh.from_vertices_and_faces(V, F)
149239

150240
# =============================================================================
151241
# Trimesh: Remeshing w/o CGAL
152242
# =============================================================================
153243

154-
# trimesh_remesh_python_with_projection(trimesh)
244+
# target_edge_length = 1.0 * average_length
245+
246+
# trimesh_remesh_python_with_projection(trimesh, target_edge_length)
155247

156248
# =============================================================================
157249
# Dual
@@ -298,23 +390,23 @@ def project(mesh: Mesh, k: int, args) -> None:
298390

299391
for support in supports_by_height[:4]:
300392
points.append(mesh.vertex_attributes(support, "xy"))
301-
values.append(50)
393+
values.append(THICKNESS_SUPPORTS1)
302394

303395
for support in supports_by_height[4:]:
304396
points.append(mesh.vertex_attributes(support, "xy"))
305-
values.append(30)
397+
values.append(THICKNESS_SUPPORTS2)
306398

307399
for border in mesh.attributes["borders"]:
308400
if len(border) > 4:
309401
midspan = border[len(border) // 2]
310402
points.append(mesh.vertex_attributes(midspan, "xy"))
311-
values.append(15)
403+
values.append(THICKNESS_BORDER)
312404

313405
vertices_by_height = sorted(mesh.vertices(), key=lambda v: mesh.vertex_attribute(v, "z"))
314406

315407
for vertex in vertices_by_height[-5:]:
316408
points.append(mesh.vertex_attributes(vertex, "xy"))
317-
values.append(10)
409+
values.append(THICKNESS_TOP)
318410

319411
# =============================================================================
320412
# Blocks: Thickness interpolation sampling
@@ -327,7 +419,7 @@ def project(mesh: Mesh, k: int, args) -> None:
327419
dual.vertex_attribute(vertex, "thickness", t)
328420

329421
# =============================================================================
330-
# Blocks
422+
# Blocks: Idos
331423
# =============================================================================
332424

333425
idos: Mesh = dual.copy()
@@ -337,79 +429,31 @@ def project(mesh: Mesh, k: int, args) -> None:
337429
thickness = dual.vertex_attribute(vertex, name="thickness")
338430
idos.vertex_attributes(vertex, names="xyz", values=point - normal * (0.5 * thickness))
339431

432+
# =============================================================================
433+
# Blocks
434+
# =============================================================================
435+
340436
blocks: list[Mesh] = []
341437

342438
for face in dual.faces():
343-
vertices = dual.face_vertices(face)
344-
normals = [dual.vertex_normal(vertex) for vertex in vertices]
345-
thickness = dual.vertices_attribute("thickness", keys=vertices)
346-
347-
bottom = idos.vertices_points(vertices)
348-
top = [point + vector * t for point, vector, t in zip(bottom, normals, thickness)]
349-
350-
frame = Frame(*bestfit_frame_numpy(top))
351-
plane = Plane.from_frame(frame)
352-
353-
flattop = []
354-
for a, b in zip(bottom, top):
355-
b = plane.intersection_with_line(Line(a, b))
356-
flattop.append(b)
357-
358-
# make the block
359-
# this is a more complicated version of making a block
360-
# it keeps the vertex keys of the bottom face the same as the ones of the corresponding face of the dual
361-
# and uses vertex + max_vertex + 1 for the top
362-
n = dual._max_vertex + 1
363-
364-
block: Mesh = Mesh()
365-
366-
for vertex, point in zip(vertices, bottom):
367-
key = block.add_vertex(key=vertex, x=point[0], y=point[1], z=point[2])
368-
369-
for vertex, point in zip(vertices, flattop):
370-
key = block.add_vertex(key=vertex + n, x=point[0], y=point[1], z=point[2])
371-
372-
block.add_face(vertices[::-1])
373-
block.add_face([vertex + n for vertex in vertices])
374-
for u, v in pairwise(vertices + vertices[:1]):
375-
uu = u + n
376-
vv = v + n
377-
block.add_face([u, v, vv, uu])
378-
379-
block.update_default_edge_attributes(is_vertical=False)
380-
block.update_default_face_attributes(is_support=False, is_interface=False)
381-
block.attributes["n"] = n
382-
block.attributes["frame"] = frame
383-
block.attributes["is_support"] = False
384-
439+
block = make_block(dual, idos, face)
385440
dual.face_attribute(face, name="block", value=block)
386441

387-
# identify support faces
442+
# identify support faces and interfaces
443+
vertices = dual.face_vertices(face)
388444
for index, (u, v) in enumerate(pairwise(vertices + vertices[:1])):
389-
is_support = dual.edge_attribute((u, v), name="is_support")
390-
if is_support:
391-
face = 2 + index
392-
block.face_attribute(face, name="is_support", value=True)
393-
block.attributes["is_support"] = True
445+
# the first two faces are bottom and top
446+
# then come the side faces in same order as the cycle of pairwise vertices
447+
# => face = index + 2
448+
face = index + 2
394449

395-
# identify interfaces
396-
for index, (u, v) in enumerate(pairwise(vertices + vertices[:1])):
450+
is_support = dual.edge_attribute((u, v), name="is_support")
397451
is_interface = dual.edge_attribute((u, v), name="is_interface")
398-
if is_interface:
399-
face = 2 + index
400-
block.face_attribute(face, name="is_interface", value=True)
401-
402-
# identify vertical edges
403-
vertices = block.face_vertices(0)
404-
for vertex in vertices:
405-
nbrs = block.vertex_neighbors(vertex)
406-
nbr = None
407-
for test in nbrs:
408-
if test not in vertices:
409-
nbr = test
410-
break
411-
if nbr is not None:
412-
block.edge_attribute((vertex, nbr), name="is_vertical", value=True)
452+
453+
block.face_attribute(face, name="is_support", value=is_support)
454+
block.face_attribute(face, name="is_interface", value=is_interface)
455+
456+
block.attributes["is_support"] = True
413457

414458
blocks.append(block)
415459

@@ -435,11 +479,11 @@ def project(mesh: Mesh, k: int, args) -> None:
435479
right = plane.projected_point(dual.vertex_point(nbr))
436480
v1 = (left - plane.point).unitized()
437481
v2 = (right - plane.point).unitized()
438-
if v1.angle(v2, degrees=True) > 120:
482+
if v1.angle(v2, degrees=True) > MAX_CHAMFER_ANGLE:
439483
continue
440484

441485
direction = (v1 + v2).unitized()
442-
cutter = Plane(plane.point, direction).offset(1)
486+
cutter = Plane(plane.point, direction).offset(CHAMFER_OFFSET)
443487

444488
face = dual.halfedge_face((vertex, nbr))
445489
temp: Mesh = face_block[face]
@@ -490,15 +534,15 @@ def project(mesh: Mesh, k: int, args) -> None:
490534
yaxis = zaxis.cross(xaxis)
491535
frame = Frame(point, xaxis, yaxis)
492536
plane = Plane.from_frame(frame)
493-
offset = plane.offset(70)
537+
offset = plane.offset(SUPPORT_DEPTH)
494538

495539
bottom = [
496540
P0 + dual.vertex_normal(border[0]) * 0.5 * dual.vertex_attribute(border[0], name="thickness"),
497541
P1 + dual.vertex_normal(border[-1]) * 0.5 * dual.vertex_attribute(border[-1], name="thickness"),
498542
P1 - dual.vertex_normal(border[-1]) * 0.5 * dual.vertex_attribute(border[-1], name="thickness"),
499543
P0 - dual.vertex_normal(border[0]) * 0.5 * dual.vertex_attribute(border[0], name="thickness"),
500544
]
501-
bottom = offset_polygon(bottom, -5)
545+
bottom = offset_polygon(bottom, -SUPPORT_PADDING)
502546
top = [
503547
offset.intersection_with_line(Line.from_point_and_vector(bottom[0], R0)),
504548
offset.intersection_with_line(Line.from_point_and_vector(bottom[1], R1)),
@@ -539,11 +583,15 @@ def project(mesh: Mesh, k: int, args) -> None:
539583
# Viz: Reactions
540584
# =============================================================================
541585

586+
reactions = []
587+
542588
for vertex in mesh.vertices_where(is_support=True):
543589
point = mesh.vertex_point(vertex)
544590
residual = Vector(*mesh.vertex_attributes(vertex, names=["_rx", "_ry", "_rz"]))
545591
reaction = Line.from_point_and_vector(point, residual * 0.001)
546-
viewer.scene.add(reaction, linewidth=5, linecolor=Color.green())
592+
reactions.append(reaction)
593+
594+
viewer.scene.add(reactions, linewidth=5, linecolor=Color.green(), name="Reactions")
547595

548596
# =============================================================================
549597
# Viz: Blocks
@@ -574,7 +622,7 @@ def project(mesh: Mesh, k: int, args) -> None:
574622
# Viz: Cut blocks
575623
# =============================================================================
576624

577-
viewer.scene.add(list(face_block.values()))
625+
viewer.scene.add(list(face_block.values()), name="Chamfered Blocks")
578626

579627
# =============================================================================
580628
# Viz: Show

0 commit comments

Comments
 (0)