DXFをPythonなどから解析するとき、LINEやCIRCLEの次に難しく感じやすいのがDIMENSIONです。
寸法は画面上では、
- 寸法線
- 補助線
- 矢印
- 数値
- 記号
がまとまった1つの要素に見えます。
しかしDXF内部では、単純な線や文字だけではなく、寸法種類、幾何学的な定義点、寸法スタイル、表示用ブロックなどを組み合わせて表現します。
そのため、
DIMENSIONを発見
↓
コード70で寸法種類を判定
↓
定義点を取得
↓
寸法スタイルを確認
↓
必要なら表示用ブロックを参照
という順序で理解すると整理しやすくなります。
この記事では、DIMENSIONエンティティを将来DXFパーサー、寸法検査、図面解析へ利用できる形で整理します。
DIMENSIONは複数種類の寸法を共通エンティティで扱う
DXFでは、線形寸法、角度寸法、直径寸法、半径寸法などをDIMENSIONエンティティとして扱います。
AutodeskのDXF Referenceでは、DIMENSIONはまず共通コードを持ち、その後に寸法種類固有のコードが続く構造です。
代表的な共通コードは次のとおりです。
| コード | 意味 |
|---|---|
| 2 | 寸法図形を構成するブロック名 |
| 3 | 寸法スタイル名 |
| 10 / 20 / 30 | 定義点 |
| 11 / 21 / 31 | 寸法文字の中央点 |
| 70 | 寸法種類とフラグ |
| 51 | 水平方向に関する角度 |
| 53 | 寸法文字の追加回転 |
| 210 / 220 / 230 | 押し出し方向 |
最初に重要なのは、コード70、2、3、10、11です。
コード70で寸法種類を判定する
コード70はDIMENSIONの種類を表します。
基本値は、
| 値 | 寸法種類 |
|---|---|
| 0 | 回転・水平・垂直の線形寸法 |
| 1 | 平行寸法 |
| 2 | 角度寸法 |
| 3 | 直径寸法 |
| 4 | 半径寸法 |
| 5 | 3点角度寸法 |
| 6 | 座標寸法 |
です。
ただしコード70は単純な列挙値だけではありません。
32、64、128などのビット値が加算される場合があります。
たとえば、
70
32
だから「種類32の寸法」という意味ではありません。
基本寸法種類とフラグを分けて読む必要があります。
Autodeskは、32を寸法専用のブロック参照に関するビット値として定義しています。
したがってコードでは、値そのものを直接比較するだけでなくビット処理を行います。
dimension_type = value & 0b111
のように基本種類を分離する考え方が使えます。
実際に扱うビット範囲は仕様を確認して実装します。
コード2は寸法表示用ブロックへの参照
DIMENSIONの特徴の一つが、コード2です。
コード2には、寸法図形を構成するエンティティ群を格納したブロック名が入ります。
つまり寸法は、
DIMENSION
↓
コード2
↓
BLOCK定義
↓
線・矢印・文字など
という関係を持つ場合があります。
この構造を理解すると、以前扱ったBLOCK/INSERTの知識とDIMENSIONがつながります。
ただし、ここで注意したいのは、
寸法の意味を知るために表示用ブロックだけを解析するのは適切ではない
という点です。
ブロックは表示結果に近い情報です。
寸法種類や定義点などの意味情報はDIMENSION自身が持っています。
したがって、
意味解析
→ DIMENSION
表示再現
→ BLOCKも利用
と役割を分ける方が扱いやすくなります。
寸法用ブロックは匿名ブロックになることがある
DXFのBLOCKには、匿名ブロックを表すフラグがあります。
AutodeskのBLOCK仕様では、コード70のビット1は、ハッチング、連想寸法など内部処理によって生成された匿名ブロックを示します。
そのためDXFを解析していると、ユーザーが名前を付けた覚えのないブロックが存在することがあります。
寸法を扱う場合は、
ユーザー定義ブロック
と、
CAD内部生成ブロック
を区別して考える必要があります。
ブロック数を単純に「部品数」と解釈する処理では、こうした匿名ブロックがノイズになる可能性があります。
コード10は定義点
共通DIMENSIONコードの10/20/30は定義点です。
Autodeskではこの点をWCS座標として定義しています。
ただし、DIMENSIONではコード10だけで寸法のすべての幾何形状が決まるわけではありません。
寸法種類によって13、14、15などの定義点が追加されます。
そのため、
point = entity[10]
だけでは十分ではありません。
寸法種類を判定した後に、その種類に必要な座標を読み取ります。
線形寸法ではコード13と14が重要
線形・回転寸法では、
- 13 / 23 / 33
- 14 / 24 / 34
が定義点として使用されます。
2D図面なら概念的には、
P1 = (13, 23)
P2 = (14, 24)
という2点です。
この2点は、寸法補助線の基準となる対象側の位置を表します。
つまり線形寸法では、
対象点1
対象点2
寸法線位置
寸法文字位置
のように複数の空間情報を保持しています。
この構造を使えば、単に表示された寸法値を読むだけではなく、どの2点を寸法対象としているかを解析できる可能性があります。
コード50は回転寸法の角度
線形・回転寸法ではコード50が寸法の角度に使われます。
たとえば水平寸法と垂直寸法では方向が異なります。
DXFの角度値を内部で扱うときは、度とラジアンを混同しない設計が重要です。
from math import radians
angle_rad = radians(angle_deg)
と変換して、内部ではラジアンへ統一する方法もあります。
データとして保存するなら、
{
"dimension_line_angle": {
"value": 90.0,
"unit": "deg"
}
}
のように単位を明示すると安全です。
コード11は寸法文字の中央点
コード11/21/31は寸法文字の中央点です。Autodeskではこの点をOCS座標として定義しています。
ここはコード10との座標系の違いに注意が必要です。
共通DIMENSIONコードでは、
- 10系の一部:WCS
- 11系など:OCS
が混在します。
単純なXY平面上の図面では問題が表面化しにくいですが、一般的なDXFパーサーを作るなら座標系を記録しておく方がよいでしょう。
たとえば、
{
"definition_point": {
"coords": [100.0, 50.0, 0.0],
"coordinate_system": "WCS"
},
"text_midpoint": {
"coords": [120.0, 60.0, 0.0],
"coordinate_system": "OCS"
}
}
のように保持できます。
コード3は寸法スタイル名
コード3には寸法スタイル名が入ります。
寸法スタイルは、寸法の表示方法をまとめた設定です。
たとえば、
- 文字高さ
- 矢印
- 単位表現
- 小数点以下桁数
- 補助線
- 公差表示
などに関係します。
つまりDIMENSIONエンティティ自身の座標だけでは、最終的な外観を完全には決定できません。
DIMENSION
↓
style name
↓
DIMSTYLE
↓
表示ルール
という参照が必要です。
DXFを「意味データ」として解析するだけならスタイルを完全再現する必要はありませんが、CADビューアを作るなら重要になります。
直径・半径寸法ではコード15を使う
直径寸法や半径寸法では、コード15/25/35が定義点として使用されます。
Autodeskの仕様では、半径・直径寸法ではコード40にリーダー長も保持されます。
ここで重要なのは、
寸法種類によって同じグループコード体系だけでは処理できない
ことです。
したがってパーサーでは、
match dimension_type:
case 0:
parse_linear_dimension(...)
case 1:
parse_aligned_dimension(...)
case 3:
parse_diameter_dimension(...)
case 4:
parse_radius_dimension(...)
のように種類ごとの処理へ分岐する設計が自然です。
グループコードの順番を決め打ちしない
DXFパーサーでは、仕様書に掲載されている順序へ依存しないことが重要です。
Autodeskは、将来バージョンで新しいグループコードが追加される可能性があるため、グループコードの並び順を前提にせず、未知コードを無視できる表駆動型の実装を推奨しています。
したがって、
# 悪い例
# 70の次は必ず2、その次は10
という実装は避けます。
代わりに、
for code, value in groups:
if code == 70:
...
elif code == 2:
...
elif code == 10:
...
のようにコード番号を判定します。
さらに同じコードが複数回現れる可能性を考慮し、元データは順序付きのペア列として保持しておく方が安全です。
DIMENSIONを正規化する
DXFの生データをそのまま後工程で使うより、共通モデルへ変換すると再利用しやすくなります。
たとえば線形寸法なら、
dimension = {
"entity_type": "DIMENSION",
"dimension_type": "linear",
"style": "STANDARD",
"definition_points": [
[0.0, 0.0, 0.0],
[100.0, 0.0, 0.0]
],
"text_midpoint": [50.0, 20.0, 0.0],
"graphics_block": "*D1",
"angle_deg": 0.0
}
のようにできます。
DXF固有のコード番号を後工程から隠すことで、
DXF
↓
パーサー
↓
正規化DIMENSION
↓
寸法検査
↓
JSON / DB
↓
Web表示
と処理を分離できます。
寸法値を文字列だけから取得しない
寸法を解析するときにありがちな方法が、表示されている文字だけを取得することです。
しかし寸法文字は、
- 寸法スタイル
- 単位設定
- 丸め
- 公差
- 上書き文字
などの影響を受ける可能性があります。
そのため、
表示文字 = 幾何学的な実測値
と常に考えるのは危険です。
図面検査ツールを作るなら、
幾何定義点から計算した値
と、
表示されている寸法値
を分けて扱う設計が有効です。
たとえば、
{
"measured_value": 100.0,
"display_text": "100",
"is_overridden": false
}
のような構造です。
これにより、将来的に「寸法値の上書き」を検出する仕組みへ発展させられます。
寸法解析は図面チェックへ発展できる
DIMENSIONを正規化できると、単なるDXF表示以上の用途があります。
たとえば、
- 寸法数の集計
- 寸法種類の分類
- 寸法スタイルの統一確認
- 未使用・異常な寸法スタイル検出
- 特定範囲の寸法抽出
- 幾何形状と寸法値の比較
- 上書き寸法の検出
- 寸法データのDB化
などです。
特に、
図形
+
寸法定義
+
文字
+
レイヤー
を関連付けられるようになると、DXFを「線の集合」ではなく、設計意図を含む構造データとして扱えるようになります。
最初は線形寸法だけに限定して実装する
DIMENSIONは種類が多いため、最初から全種類を実装すると複雑になります。
実装順としては、
Phase 1
DIMENSIONを検出
Phase 2
コード70で種類判定
Phase 3
線形寸法だけ解析
Phase 4
平行寸法
Phase 5
径・半径寸法
Phase 6
角度・座標寸法
Phase 7
DIMSTYLEと表示用ブロックを解決
くらいに分けると検証しやすくなります。
まず線形寸法で、
- 定義点
- 文字位置
- 角度
- スタイル
- ブロック名
を正しく取得できれば、DIMENSION解析の基本構造は作れます。
まとめ
DXFのDIMENSIONを読むときは、単なる文字や線の集合としてではなく、寸法の意味を持ったエンティティとして扱うことが重要です。
最初に押さえたいのは、
- コード70:寸法種類
- コード2:寸法表示用ブロック名
- コード3:寸法スタイル名
- コード10:共通定義点
- コード11:寸法文字中央点
- コード13・14:線形寸法などの定義点
- コード50:回転寸法の角度
- コード15:径・半径寸法などの定義点
です。
そして処理は、
DIMENSION検出
↓
種類判定
↓
定義点取得
↓
寸法スタイル取得
↓
必要ならブロック解決
↓
正規化
と段階化します。
この構造を作っておけば、DXFビューアだけでなく、寸法チェック、設計データ抽出、図面DB化、自動検査へ発展させることができます。
参考情報
- Autodesk AutoCAD DXF Reference — DIMENSION
- Autodesk AutoCAD DXF Reference — Common Dimension Group Codes
- Autodesk AutoCAD DXF Reference — Linear and Rotated Dimension Group Codes
- Autodesk AutoCAD DXF Reference — Radial and Diameter Dimension Group Codes
- Autodesk AutoCAD DXF Reference — BLOCK

