實作 polyhedron
November 26, 2021在〈操作 BREP 實例〉中,基於頂點與面索引,建立了一個方塊,雖然算是蠻低階的操作,然而,若能搭配一些演算,自動地生成頂點與面索引,進一步地再基於頂點與面索引來建立實體,兩者結合,可以讓模型建立具有極高的彈性。
polyhedron 函式
在 OpenSCAD 中有個 polyhedron
模組,就可以基於頂點與面索引建立 3D 模型,也因為有這個模組,我的 dotSCAD 才能提供更多高階操作,甚至是具有「軟」表面的模型。
那麼,就來將〈操作 BREP 實例〉中最後一個範例重構,定義一個 polyhedron
函式:
from cadquery import Vector, Edge, Wire, Solid, Shell, Face
def polyhedron(points, faces):
def _edges(vectors, face_indices):
leng_vertices = len(face_indices)
return (
Edge.makeLine(
vectors[face_indices[i]],
vectors[face_indices[(i + 1) % leng_vertices]]
)
for i in range(leng_vertices)
)
vectors = [Vector(*p) for p in points]
return Solid.makeSolid(
Shell.makeShell(
Face.makeFromWires(
Wire.assembleEdges(
_edges(vectors, face_indices)
)
)
for face_indices in faces
)
)
這個函式的 points
、faces
可以接受頂點與面索引清單,型態只要是可迭代物件,faces
要求共平面、逆時針順序,最後傳回一個 Solid
實體。
應用 polyhedron
例如,〈操作 BREP 實例〉中最後一個範例,有了 polyhedron
,就可以如下建立:
# 結合方才的 polyhedron
points = (
(10, -10, 0),
(10, 10, 0),
(-10, 10, 0),
(-10, -10, 0),
(10, -10, 10),
(10, 10, 10),
(-10, 10, 10),
(-10, -10, 10)
)
faces = (
(0, 3, 2, 1),
(4, 5, 6, 7),
(0, 1, 5, 4),
(3, 7, 6, 2),
(0, 4, 7, 3),
(1, 2, 6, 5)
)
solid = polyhedron(points, faces)
show_object(solid)
執行結果如下:
faces
只要共平面就可以了,例如,底下的金字塔混合了三角面與四邊形面:
# 結合方才的 polyhedron
points = (
# XY 平面上四個頂點
(10, 10, 0), (10, -10, 0), (-10, -10, 0), (-10, 10,0),
# 金字塔尖端
(0, 0, 10)
)
faces = (
# 底部的四邊形
(0, 1, 2, 3),
(4, 1, 0), (4, 2, 1), (4, 3, 2), (4, 0,3), # 四個三角面
)
solid = polyhedron(points, faces)
show_object(solid)
這會建立以下的模型:
若不確定頂點間是否形成共平面,那麼就全部使用三角面;既然如此,就來個全部都是三角面的正四面體:
# 結合方才的 polyhedron
points = (
(5, -5, -5), (-5, 5, -5), (5, 5, 5), (-5, -5, 5)
)
faces = (
(0, 1, 2), (0, 3, 1), (1, 3, 2), (0, 2, 3)
)
solid = polyhedron(points, faces)
show_object(solid)
這會建立以下的模型: