在我上一篇文章【高性能 Web CAD Viewer:Batched Geometry 助你輕鬆渲染百萬實體】中,我分享了 CAD-Viewer (Gitlab 或 Github) 如何透過將 CAD 圖紙中的實體進行幾何合併,在瀏覽器中實現快速渲染。這篇文章主要關注「如何高效繪製」,減少繪製調用並利用 GPU 友好的數據佈局。
然而,Batched Geometry 只是故事的一部分。要真正有意義地渲染 CAD 圖紙,我們還需要一個結構良好的渲染場景結構來統一管理所有內容。
這就是 CAD-Viewer 中 AcTrScene 類的作用。它充當 CAD 的邏輯數據模型(Layout、Layer、Entity)與渲染引擎的 GPU 友好表示(批處理幾何)之間的橋樑。本文將深入介紹 AcTrScene
如何組織 CAD 圖紙的可視內容,並通過具體實例進行詳細解釋。
讀完後,你不僅會了解如何快速繪製,還會理解如何保持渲染場景清晰、結構化和可擴展——即使圖紙非常複雜。
注意:
首先,讓我們了解場景的基本結構:
Scene (AcTrScene)
└── Layout (AcTrLayout) # 紙張空間或模型空間
└── Layer (AcTrLayer) # 繪圖圖層
└── Batched Group (AcTrBatchedGroup)
├── Line Batches # 線條、圓弧、樣條、射線...
├── Mesh Batches # 填充、網格字體等
└── Point Batches # 點
Scene (AcTrScene
)
isOn
、isFrozen
、顏色等屬性)Layout (AcTrLayout
)
Model
或紙張空間 Layout1
)Layer (AcTrLayer
)
Batched Group (AcTrBatchedGroup
)
為了解釋如何將 DWG 圖紙的結構轉化為相應的渲染場景結構,我們使用以下圖紙示例:
圖層:
0
(CAD 預設圖層;在主圖紙中為空)L1
(主要幾何)L2
(標註)模型空間中的 Entity:
L1
中的 Polyline(牆輪廓)L1
中的 Hatch(地面圖案)L2
中的 Point(測量標記)L1
中的 Insert(塊引用):Insert(塊引用)所引用的塊包含:
0
圖層中的 CircleL2
圖層中的 MText渲染引擎(如 Three.js 和 WebGPU)無法直接理解 LINE
、CIRCLE
、HATCH
或 INSERT
等 CAD Entity。cad-viewer
將所有 CAD Entity 轉換為三種基本 Geometry,以便 GPU 高效渲染:
此轉換在批處理之前進行,同時解決塊和圖層繼承等複雜問題。
常見 Entity 的處理方式如下表所示:
AutoCAD 支持兩種不同的文本技術:
轉換流程:
詳解:
單個 MTEXT
對象可以包含多種字體。字體混合使用 TrueType/OpenType 和 SHX 字體時:
MTEXT
可以同時為 Line Batches 和 Mesh Batches 貢獻幾何示例:
MTEXT
正文使用 TrueType(如 Arial)→ 存入 Mesh Batch場景結構示意:
Scene
└── Layout (模型空間)
└── Layer L2
└── Batched Group
├── Line Batches ← MTEXT 的 SHX 部分
├── Mesh Batches ← MTEXT 的 TrueType 部分
AutoCAD 的 TABLE
Entity 包含了:
轉換流程:
詳解:
TABLE
可擴展為數百到上千個 Geometry塊參考類似可重用子圖紙的實例。它引入圖層繼承和可見性規則,影響內容的轉換。
AutoCAD 行為規則:
0
圖層 → 繼承塊參考圖層轉換流程:
示意圖:
Layout (模型空間)
└── Layer L1
└── Batched Group
├── Line Batches ← 塊內 SHX 字體、邊界線
├── Mesh Batches ← 塊內 TrueType 字體、填充
└── Point Batches ← 塊內標記點
這確保了即使塊跨多個圖層或包含混合字體,最終渲染也能保持準確。
根據這些規則,在 AutoCAD 中看起來「在一起」的 Entity,可能會在場景中被拆分到多個圖層、多個 Batched Geometry中:
正是這種精細化的組織,使 cad-viewer 能夠利用 GPU 實例化技術,並在複雜註釋和可重用內容豐富的圖紙中保持高幀率。
以下是示例圖紙的場景結構:
Scene (AcTrScene)
├── Layout: Model Space (AcTrLayout)
│ ├── Layer "0" (AcTrLayer)
│ │ └── Batched Group
│ │ ├── Line Batches # (空)
│ │ ├── Mesh Batches # (空)
│ │ └── Point Batches # (空)
│ │
│ ├── Layer "L1" (AcTrLayer)
│ │ └── Batched Group
│ │ ├── Line Batches
│ │ │ └── [Polyline geometry] # 牆體輪廓
│ │ │ └── [Polyline geometry] # 來自塊的圓
│ │ ├── Mesh Batches
│ │ │ └── [Hatch geometry] # 地面圖案
│ │ └── Point Batches # (空)
│ │
│ └── Layer "L2" (AcTrLayer)
│ └── Batched Group
│ ├── Line Batches # (空)
│ ├── Mesh Batches
│ │ └── [Text geometry] # 來自塊
│ └── Point Batches
│ └── [Point entity] # 測量標記
│
└── Layout: Paper Space (AcTrLayout) # 此示例為空
├── Layer "0" (AcTrLayer) # 存在但為空
├── Layer "L1" (AcTrLayer) # 存在但為空
└── Layer "L2" (AcTrLayer) # 存在但為空
理解轉換後的場景
AcTrLayer
對象。AcTrLayer
包含一個 AcTrBatchedGroup
,只包含渲染所需的圖元類型。此結構反映了 CAD 的圖層語義,同時經過優化以提升渲染性能:使用相同圖層、圖元類型和材質的實體可以合併為單個批次繪製,從而最小化繪製調用(draw calls)。
在 DWG 文件中:
isOn
、isFrozen
、顏色等。在場景中:
AcTrLayer
實例。AcTrLayer
對象。AcTrScene
中,而不是每個 AcTrLayer
,確保切換可見性或凍結圖層時,對所有佈局都一致生效。AcTrLayer
只是特定佈局中批次的容器。這種分離方式讓我們可以保持渲染數據的佈局友好性,同時維護 CAD 一致的全局圖層行為。
塊引用(INSERT 實體)是 CAD 渲染中最微妙的部分之一。AutoCAD 的行為說明了原因:
假設塊包含:
你將該塊插入到層 L1(塊引用所在的層)。
情況 1:關閉圖層 L1
結果:整個塊隱藏。
情況 2:關閉圖層 L2
結果:塊引用可見,但內容中在 L2 的部分消失。
渲染塊引用時,
這確保渲染遵循 CAD 的可見性語義,同時將幾何放置在 GPU 批處理的合適位置。
在上一篇文章中,我們重點討論了如何使用 Batched Geometry 以提升性能。本篇文章探討了如何將 CAD Entity 轉換為可渲染圖元,並在場景中組織它們。
如果想深入實現,或親自嘗試,可查看我的開源專案源代碼: