文字的處理


如果要建立文字的 3D 實體,Workplane 提供了 text 方法,例如,來個 Hello, World:

import cadquery as cq

t1 = (cq.Workplane()
        .text(
            'Hello, World', 
            fontsize = 10, 
            distance = 5, 
            font = 'Arial Black'
        )
     )

t2 = (cq.Workplane()
        .text(
            '哈囉!世界!', 
            fontsize = 10, 
            distance = 5, 
            fontPath = r'C:\Windows\Fonts\SourceHanSansTC-Bold.otf'
        )
        .translate((0, 10, 0))
     )

在字型指定的部份,如果使用 font 指定字型名稱無效的話,試著指定 fontPath 至字型檔案所在位置,例如在 Windows 上,若要使用思源黑體等自行安裝的字型,就必須指定 fontPath。執行後會建立以下的 3D 實體:

文字的處理

透過 Workplane 使用方法操作鏈風格時,若堆疊中已經有其他實體,呼叫 text 後建立的文字 3D 實體,會被用來進行減集,因為 textcut 預設是 True

import cadquery as cq

t1 = (cq.Workplane()
        .box(100, 20, 10)
        .text(
            'Hello, World', 
            fontsize = 12, 
            distance = 5, 
            font = 'Arial Black'
         )
     )

這會顯示以下結果:

文字的處理

Workplane 沒有 2D 概念的文字處理方法,不過可以建立 3D 的文字實體,透過 wires 方法取得構成文字的線,然後進一步處理,例如,來個扭來扭去的文字:

import cadquery as cq

path = (cq.Workplane('XZ')
          .radiusArc((5, 5), 30)
          .radiusArc((0, 15), -30)
          .radiusArc((-5, 20), -50)
       )

t = (cq.Workplane()
       .text(
           'Hi', 
           fontsize = 12, 
           distance = 1, 
           font = 'Arial Black'
       )
       .wires('<Z')
       .toPending()
       .sweep(path)
    )

範例中的路徑是隨意構造的,來看看執行的效果:

文字的處理

也可以透過 faces 方法取得面,然後根據〈Face 布林操作〉中談過的內容,可以從取得面中獲得 outerWireinnerWires,然後進一步處理,例如,建立文字的輪廓:

import cadquery as cq
from cadquery import Face

t = 'Orz'
fontsize = 12
height = 2
font = 'Arial Black'
offset = 2

t = (cq.Workplane()
       .text(t, fontsize = fontsize, distance = height, font = font)
    )

# 取得 XY 上的文字面
faces = t.faces('<Z').vals() 
# 對於每個文字面的外圍線 offset
wires = [wire 
            # 對於每個文字面
            for face in faces
                # 取得外圍的線進行 offset            
                for wire in face.outerWire().offset2D(offset)
        ]

# 將這些線化為面進行聯集
unioned = Face.makeFromWires(wires[0])
for i in range(1, len(wires)):
    unioned = unioned.fuse(Face.makeFromWires(wires[i])).clean()


tag = (cq.Workplane()
         # 建立輪廓並擠出
         .add(unioned.Wires()).toPending()
         .extrude(height / 2)
         # 加上 3D 文字
         .add(t)
       )
	   
show_object(tag)

這會構成以下的結果:

文字的處理

進一步地,可以試著將以上範例延伸,建立一個文字盒,這個任務就留給你了,以下是列印出來的文字盒:

文字的處理