🔧 阿川の電商水電行
Shopify 顧問、維護與客製化
💡
小任務 / 單次支援方案
單次處理 Shopify 修正/微調
⭐️
維護方案
每月 Shopify 技術支援 + 小修改 + 諮詢
🚀
專案建置
Shopify 功能導入、培訓 + 分階段交付

打造高性能二维圖紙渲染引擎系列(二):創建結構化和可擴展的渲染場景

在我上一篇文章【高性能 Web CAD Viewer:Batched Geometry 助你輕鬆渲染百萬實體】中,我分享了 CAD-Viewer (GitlabGithub) 如何透過將 CAD 圖紙中的實體進行幾何合併,在瀏覽器中實現快速渲染。這篇文章主要關注「如何高效繪製」,減少繪製調用並利用 GPU 友好的數據佈局。

然而,Batched Geometry 只是故事的一部分。要真正有意義地渲染 CAD 圖紙,我們還需要一個結構良好的渲染場景結構來統一管理所有內容。

這就是 CAD-ViewerAcTrScene 類的作用。它充當 CAD 的邏輯數據模型(Layout、Layer、Entity)與渲染引擎的 GPU 友好表示(批處理幾何)之間的橋樑。本文將深入介紹 AcTrScene 如何組織 CAD 圖紙的可視內容,並通過具體實例進行詳細解釋。

讀完後,你不僅會了解如何快速繪製,還會理解如何保持渲染場景清晰、結構化和可擴展——即使圖紙非常複雜。

注意:

1. 場景結構

首先,讓我們了解場景的基本結構:

Scene (AcTrScene)
 └── Layout (AcTrLayout)       # 紙張空間或模型空間
     └── Layer (AcTrLayer)     # 繪圖圖層
         └── Batched Group (AcTrBatchedGroup)
             ├── Line Batches  # 線條、圓弧、樣條、射線...
             ├── Mesh Batches  # 填充、網格字體等
             └── Point Batches # 點

Scene (AcTrScene)

  • 整個圖紙的根管理器
  • 保存所有 Layout 以及 Layer 的信息(存儲 isOnisFrozen、顏色等屬性)

Layout (AcTrLayout)

  • 表示 CAD 佈局(例如模型空間 Model 或紙張空間 Layout1

Layer (AcTrLayer)

  • 容納特定 Layout 中該 Layer 上的 Entity
  • 不存儲 Layer 屬性(Layer 屬性保存在場景管理的 Layer 列表中)

Batched Group (AcTrBatchedGroup)

  • 保存該 Layout 中該 Layer 的 Batched Geometry
  • 根據類型(Line/Mesh/Point)和材質 ID 進一步分組

2. 一個簡潔的 DWG 示例

為了解釋如何將 DWG 圖紙的結構轉化為相應的渲染場景結構,我們使用以下圖紙示例:

圖層:

  • 0(CAD 預設圖層;在主圖紙中為空)
  • L1(主要幾何)
  • L2(標註)

模型空間中的 Entity:

  • L1 中的 Polyline(牆輪廓)
  • L1 中的 Hatch(地面圖案)
  • L2 中的 Point(測量標記)
  • L1 中的 Insert(塊引用):

Insert(塊引用)所引用的塊包含:

  • 0 圖層中的 Circle
  • L2 圖層中的 MText

3. 將 AutoCAD Entity 轉換為可渲染的 Geometry

渲染引擎(如 Three.js 和 WebGPU)無法直接理解 LINECIRCLEHATCHINSERT 等 CAD Entity。cad-viewer 將所有 CAD Entity 轉換為三種基本 Geometry,以便 GPU 高效渲染:

  • Line:用於線狀 Entity,如 Polyline、Arc、Circle(轉換為多段線)、其他 Entity 的邊
  • Mesh:用於填充類型的 Entity,如 Hatch、使用 TrueType/OpenType 字體的字符
  • Point:用於點類型的 Entity

此轉換在批處理之前進行,同時解決塊和圖層繼承等複雜問題。

常見 Entity 的處理方式如下表所示:

table.jpg

3.1 Text 和 MText

AutoCAD 支持兩種不同的文本技術:

text.jpg

轉換流程:

  1. 從 AutoCAD 讀取文本字符串、位置、旋轉、樣式和字體類型
  2. 如果字符使用 TrueType/OpenType 字體,獲取字符輪廓、三角化並存儲為 Mesh 到對應的 Mesh Batch
  3. 如果字符使用 SHX 字體,解析每個字符的筆劃並存儲為線段到 Line Batch

詳解:

  • SHX 筆劃字體避免複雜三角化,渲染 CAD 圖紙通常更快
  • CAD 使用者通常在大幅技術圖紙中使用 SHX 字體,因為縮放後仍清晰且輕量

單個 MTEXT 對象可以包含多種字體。字體混合使用 TrueType/OpenType 和 SHX 字體時:

  • 一個 MTEXT 可以同時為 Line Batches 和 Mesh Batches 貢獻幾何
  • 因此,它可分布到多個批處理

示例:

  • MTEXT 正文使用 TrueType(如 Arial)→ 存入 Mesh Batch
  • 工程符號使用 SHX(如 simplex.shx)→ 存入 Line Batch

場景結構示意:

Scene
 └── Layout (模型空間)
     └── Layer L2
         └── Batched Group
             ├── Line Batches      ← MTEXT 的 SHX 部分
             ├── Mesh Batches      ← MTEXT 的 TrueType 部分

3.2 Table Entity

AutoCAD 的 TABLE Entity 包含了:

  • 表格結構:行列網格
  • 單元格文本:通常為多行文字且包含字體樣式
  • 邊框與單元格線

轉換流程:

  1. 解析表格:計算每個單元格角的位置,提取邊框線
  2. 轉換:
    • 所有邊框線 → 存入 Line Primitives
    • 單元格文字 → TrueType 轉 Mesh Geometry,SHX 轉 Line Geometry
  3. 應用每個單元格的格式(字體大小、對齊)

詳解:

  • 與單個 Polyline 或 Hatch 不同,TABLE 可擴展為數百到上千個 Geometry
  • 透過按材質和 Geometry 類型創建相應的 Batched Geometry 來處理表格的邊框和單元格文字,即使大表格也能高效渲染

3.3 Insert Entity

塊參考類似可重用子圖紙的實例。它引入圖層繼承和可見性規則,影響內容的轉換。

AutoCAD 行為規則:

  • 塊 Entity 在 0 圖層 → 繼承塊參考圖層
  • 塊 Entity 在其他圖層 → 保持原圖層
  • 關閉塊參考圖層 → 整個塊隱藏
  • 關閉塊內使用的圖層 → 僅隱藏對應 Entity

轉換流程:

  1. 解析塊定義,根據插入的縮放、旋轉、位置轉換 Entity
  2. 對塊內每個 Entity:
    • 根據繼承規則確定有效圖層
    • 轉換為 Line、Mesh 或 Point Geometry
  3. 將所有轉換後的 Geometry 加入該 Layout 中有效圖層的 Batched Groups

示意圖:

Layout (模型空間)
 └── Layer L1
     └── Batched Group
         ├── Line Batches ← 塊內 SHX 字體、邊界線
         ├── Mesh Batches ← 塊內 TrueType 字體、填充
         └── Point Batches ← 塊內標記點

這確保了即使塊跨多個圖層或包含混合字體,最終渲染也能保持準確。

3.4 總結

根據這些規則,在 AutoCAD 中看起來「在一起」的 Entity,可能會在場景中被拆分到多個圖層、多個 Batched Geometry中:

  • 一個單獨的 INSERT 可能會生成多個 Line GeometryMesh GeometryPoint Geometry,分散在 多個圖層 的 Batched Geometry 中。
  • 一個 TABLE 會展開成許多 Line GeometryMesh Geometry,分散在 單個圖層 的多個 Batched Geometry 中。
  • 一個 TEXT 對象可能會變成多個 Line Geometry(如果是 SHX 字體)或 Mesh Geometry(如果是 TrueType 字體),分散在 單個圖層 的多個 Batched Geometry 中。

正是這種精細化的組織,使 cad-viewer 能夠利用 GPU 實例化技術,並在複雜註釋和可重用內容豐富的圖紙中保持高幀率。

4. 示例圖紙的場景結構

以下是示例圖紙的場景結構:

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) # 存在但為空

理解轉換後的場景

  • 每個佈局(Layout)都有自己的一組 AcTrLayer 對象。
  • 每個 AcTrLayer 包含一個 AcTrBatchedGroup,只包含渲染所需的圖元類型。
  • 塊引用中的圓進入 L1 的 Line Batches 中。
  • 塊中的文本進入 L2 的 Mesh Batches。
  • Point 保持在 L2 的 Point Batches 中。
  • Hatch 和 Polyline 保留在 L1 的 Batches 中。

此結構反映了 CAD 的圖層語義,同時經過優化以提升渲染性能:使用相同圖層、圖元類型和材質的實體可以合併為單個批次繪製,從而最小化繪製調用(draw calls)。

5. 場景中的圖層 vs. DWG 文件中的圖層

在 DWG 文件中:

  • 圖層是全局的:只有一組圖層,每個圖層都有屬性,如 isOnisFrozen、顏色等。

在場景中:

  • 每個佈局為每個 DWG 圖層創建自己的 AcTrLayer 實例。
  • 因此,兩個佈局(Model, Paper)和三個圖層(0, L1, L2)會生成 6 個 AcTrLayer 對象。
  • 實際的圖層屬性存儲在 AcTrScene 中,而不是每個 AcTrLayer,確保切換可見性或凍結圖層時,對所有佈局都一致生效。
  • 每個 AcTrLayer 只是特定佈局中批次的容器。

這種分離方式讓我們可以保持渲染數據的佈局友好性,同時維護 CAD 一致的全局圖層行為。

6. 處理塊引用(INSERT)——棘手部分

塊引用(INSERT 實體)是 CAD 渲染中最微妙的部分之一。AutoCAD 的行為說明了原因:

假設塊包含:

  • E1 在層 0
  • E2 在層 L1
  • E3 在層 L2

你將該塊插入到層 L1(塊引用所在的層)。

情況 1:關閉圖層 L1

  • 塊引用本身在 L1。
  • 關閉 L1 後,整個塊引用消失,無論其內容在哪個圖層。

結果:整個塊隱藏。

情況 2:關閉圖層 L2

  • 塊引用仍在 L1(L1 保持開啟)。
  • 塊內:
    • E1(在 0)→ 繼承塊的圖層 L1,可見
    • E2(在 L1)→ 可見
    • E3(在 L2)→ 隱藏

結果:塊引用可見,但內容中在 L2 的部分消失。

cad-viewer 的處理方式

渲染塊引用時,

  • 插入對象自身的圖層影響整個塊的可見性。
  • 內部實體根據繼承規則確定的有效圖層貢獻幾何到相應的批次中。

這確保渲染遵循 CAD 的可見性語義,同時將幾何放置在 GPU 批處理的合適位置。

7. 為什麼這種場景結構可行

  • 性能:按佈局 → 圖層 → 批次類型 → 材質分組,最小化繪製調用和 GPU 狀態切換。
  • 可擴展性:場景結構在圖紙變大、變複雜時仍能很好地擴展,同時與 CAD 概念緊密對應。
  • 一致性:圖層屬性統一存儲在場景級別,應用一致。
  • 可維護性:開發者可以輕鬆從 CAD 概念(Layout、Layer、Entity)導航到渲染數據。

8. 结束语

在上一篇文章中,我們重點討論了如何使用 Batched Geometry 以提升性能。本篇文章探討了如何將 CAD Entity 轉換為可渲染圖元,並在場景中組織它們。

  • 轉換步驟是 CAD 语义與 GPU 效率之間的橋樑。
  • 理解它後,帶有佈局、圖層和批次的場景結構圖會更直觀。
  • 轉換 + 場景組織 + Batched Geometrycad-viewer 既忠實於 AutoCAD 數據模型,又高度優化用於 Web CAD 瀏覽。

如果想深入實現,或親自嘗試,可查看我的開源專案源代碼:


原文出處:https://juejin.cn/post/7561612065707212846


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝26   💬9   ❤️7
656
🥈
我愛JS
📝4   💬13   ❤️7
284
🥉
御魂
💬1  
4
#4
2
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次
🔧 阿川の電商水電行
Shopify 顧問、維護與客製化
💡
小任務 / 單次支援方案
單次處理 Shopify 修正/微調
⭐️
維護方案
每月 Shopify 技術支援 + 小修改 + 諮詢
🚀
專案建置
Shopify 功能導入、培訓 + 分階段交付