# 擴充 Workplane

• 區域座標系
• 點、邊、線、面、殼、實體等物件
• 操作堆疊
• Pending 區域

``````from cadquery import (
Vector,
Wire,
Workplane
)

def _makePolygon(points, forConstruction):
return Wire.makePolygon((
Vector(*p) for p in points + [points[0]]
),
forConstruction
)
``````

``````def makePolygon(self, listOfXYTuple, forConstruction = False):
p = _makePolygon(listOfXYTuple, forConstruction)
return self.eachpoint(lambda loc: p.moved(loc), True)

Workplane.makePolygon = makePolygon
``````

`makePolygon``_makePolygon` 建立了多邊形線之後，透過 `eachpoint` 方法，這個方法會逐一傳入 `Location` 實例，代表 `Workplane` 管理中，可作為後續 CadQuery 物件建立時的中心座標點。

`points``[(0, 0), (10, 10), (0, 20), (-5, 5)]`，使用 `Workplane().makePolygon(points)`，就會在 XY 平面上建立一個多邊形線；然而，可以進一步地：

``````polygons = (Workplane('YZ')
.rect(25, 25, forConstruction = True).vertices().
makePolygon([(0, 0), (10, 10), (0, 20), (-5, 5)])
)
``````

``````from cadquery import (
Vector,
Edge,
Wire,
Solid,
Shell,
Face,
Workplane
)

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
)
)

def polyhedron(self, points, faces, combine = True, clean = True):
poly = _polyhedron(points, faces)
poly_all = self.eachpoint(lambda loc: poly.moved(loc), True)

if not combine:
return poly_all
else:
return self.union(poly_all, clean = clean)

Workplane.polyhedron = polyhedron
``````

``````tetrahedron_pts = (
(5, -5, -5),
(-5, 5, -5),
(5, 5, 5),
(-5, -5, 5)
)

tetrahedron_faces = (
(0, 1, 2),
(0, 3, 1),
(1, 3, 2),
(0, 2, 3)
)

pyramid_pts = (
(5, 5, 0),
(5, -5, 0),
(-5, -5, 0),
(-5, 5,0),
(0, 0, 5)
)

pyramid_faces = (
(0, 1, 2, 3),
(4, 1, 0),
(4, 2, 1),
(4, 3, 2),
(4, 0,3),
)

solid = (Workplane()
.polyhedron(tetrahedron_pts, tetrahedron_faces)
.polyhedron(pyramid_pts, pyramid_faces)
)
``````

Face 布林操作〉實現的相關函式，主要是基於 `Face` 或是 `Compound`，雖說在 `Workplane` 上，增加一組方法，像是 `drawCircle``drawRect` 等，令其產生 `Face``Compound` 等，然後加以管理，以便後續鏈狀操作時，可以用來進行擠出、取得線等動作也是可以，不過會是比較大的工程，另一方面，這其實是在增加 `Workplane` 管理物件上的職責。

``````from cadquery import (
Workplane,
DirectionSelector
)

def intersect2D(self, toIntersect):
# 建立新的 Workplane，消耗其 pending 區域
toExtruded = (
# plane 特性是 Plane 實例，包含了平面方向等資訊
Workplane(toIntersect.plane)
.toPending()
)
intersected = self.extrude(1).intersect(toExtruded.extrude(1))
# 取得平面負 z 方向的面
planeZdir = DirectionSelector(-self.plane.zDir)
return intersected.faces(planeZdir).wires().toPending()

Workplane.intersect2D = intersect2D

r1 = cq.Workplane('YZ').rect(10, 10)
r2 = cq.Workplane('YZ').center(5, 5).rect(10, 10)
r3 = cq.Workplane('YZ').center(-2, -2).rect(10, 10)
r4 = r1.intersect2D(r2).intersect2D(r3)

show_object(r1)
show_object(r2)
show_object(r3)
show_object(r4.extrude(1))
``````