【入門編】【上級プロ向け】DrawingViewのバウンディングボックス幾何学演算による「ビュー同士の完全非干渉オートレイアウト」 – SolidWorks VBA解析バイブル

スポンサーリンク
スポンサーリンク

マクロ記録の先へ:幾何学演算で手に入れる「ビューが重ならない」理想の図面自動レイアウト術

こんにちは。自動化の世界へようこそ。

「マクロの記録」ボタンを押して、録画されたコードを眺めて「ふーん、こうやって動いてるんだ」と思ったことはありませんか? もしそうなら、あなたは今、自動化エンジニアとしての最初の一歩を踏み出したばかりです。

しかし、現場で本当に求められるのは、記録された「決まった動き」ではありません。
「アセンブリの部品数が増えて、ビューのサイズが変わってしまったけれど、図面が重ならないように自動で整列してほしい」
そんな、状況に応じて判断を変える、知的なプログラムです。

今日は、プロの現場で使われる「幾何学演算」の考え方を取り入れ、ビュー同士が絶対に干渉しない、魔法のようなオートレイアウト・エンジンの作り方を伝授しましょう。

1. なぜ「座標の指定」だけでは失敗するのか?

初学者が最初に陥る罠があります。それは、「ビューの中心座標を 100mm, 100mm に置く」といった、静的な数値指定です。

図面の世界は、想像以上に動的です。

  • 部品の形状が変われば、ビューの大きさ(外形)が変わる。
  • 寸法線を追加すれば、ビューの占有範囲が広がる。
  • アセンブリの構成が変われば、投影される図形の密度が変わる。

もし、あなたが「ビューAは座標(0,0)に置く。ビューBは(100,0)に置く」というコードを書いたとしましょう。もしビューAが巨大化して、横幅が150mmになったらどうなるでしょうか? ビューAとビューBは、無残にも重なってしまいます。

これを解決する鍵が、「バウンディングボックス(Bounding Box)」の概念です。

2. 核心概念:バウンディングボックスによる「不可侵領域」の定義

「バウンディングボックス」とは、ある物体をすっぽりと包み込む「最小の直立長方形」のことです。

図面におけるビューのバウンディングボックスを計算するということは、「そのビューが、寸法線や注記を含めて、結局どれくらいの面積を占有しているのか?」をプログラムに理解させることを意味します。

理想的な配置アルゴリズムの思考プロセス

1. 計測: 1つ目のビューのバウンディングボックス(左端、右端、上端、下端の座標)を取得する。
2. 予測: 「次に置くべき位置」を、`現在のビューの右端座標 + 安全マージン` として計算する。
3. 配置: 計算した座標に、次のビューを配置する。
4. 反復: これをすべてのビューに対して繰り返す。

この「前のビューの大きさを測ってから、次の場所を決める」という動的なプロセスこそが、プロの自動化です。

3. 実践:ビュー非干渉レイアウト・エンジン

それでは、実際に使えるVBAコードを見ていきましょう。
ここでは、シート上のすべてのビューを、左から右へ、重ならないように順番に並べるエンジンを実装します。

Option Explicit

' ==============================================================================
' テーマ:DrawingViewのバウンディングボックスによる非干渉レイアウト
' 概要:ビューの実際の占有範囲を計算し、重ならないように横一列に整列させる
' ==============================================================================

Sub AutoLayoutDrawingViews()
    Dim swApp As SldWorks.SldWorks
    Dim swModel As SldWorks.ModelDoc2
    Dim swDraw As SldWorks.DrawingDoc
    Dim swSheet As SldWorks.Sheet
    Dim swView As SldWorks.View
    Dim vViews As Variant
    Dim i As Integer
    
    ' 座標計算用の変数
    Dim box As Variant ' GetBoundingBoxの結果を受け取る配列
    Dim margin As Double ' ビュー間の安全マージン (m)
    Dim currentX As Double
    Dim currentY As Double
    Dim viewWidth As Double
    Dim viewHeight As Double
    
    ' --- 設定エリア ---
    Set swApp = Application.SldWorks
    Set swModel = swApp.ActiveDoc
    
    ' 図面ファイルが開かれているかチェック
    If swModel Is Nothing Or swModel.GetType <> swDocDRAWING Then
        MsgBox "図面ファイルを開いてから実行してください。", vbCritical
        Exit Sub
    End If
    
    Set swDraw = swModel
    Set swSheet = swDraw.GetCurrentSheet
    
    ' マージンの設定 (例: 20mm = 0.02m)
    ' SolidWorksの内部単位は常に「メートル」であることを忘れないでください!
    margin = 0.02 
    
    ' 配置を開始する初期位置 (シートの左下付近)
    currentX = 0.05 
    currentY = 0.1 ' シートの下から100mmの位置から開始
    ' ------------------

    ' 全ビューを取得
    vViews = swDraw.GetViews
    
    ' 注意:GetViewsは「シート自体」も含む場合があるため、
    ' 実際のループではビューのプロパティを確認してスキップする制御が必要です。
    
    ' ※簡易化のため、ビューの配列を直接ループします
    ' 実際には、最初のビュー(シートそのもの)を飛ばす処理が必要です
    
    ' 描画更新を一時停止(パフォーマンス向上のため)
    swModel.ActiveView.EnableGraphicsUpdate = False

    ' 配列の要素数を確認
    Dim viewCount As Integer
    viewCount = UBound(vViews)
    
    ' 最初のビュー(シート)はインデックス0にあることが多いため、1から開始
    For i = 1 To viewCount
        Set swView = vViews(i)
        
        ' 1. ビューのバウンディングボックスを取得
        ' box(0) = MinX, box(1) = MinY, box(2) = MaxX, box(3) = MaxY
        box = swView.GetBoundingBox
        
        ' 2. ビューの幅と高さを計算
        viewWidth = box(2) - box(0)
        viewHeight = box(3) - box(1)
        
        ' 3. ビューを現在の計算座標に移動させる
        ' 注意:ビューの座標指定は「中心」ではなく「左下」や「中心」など
        ' APIの仕様に合わせて、中心座標を計算してセットします。
        Dim centerX As Double
        Dim centerY As Double
        centerX = currentX + (viewWidth / 2)
        centerY = currentY + (viewHeight / 2)
        
        ' ビューの位置を更新
        swView.SetPosition centerX, centerY
        
        ' 4. 次のビューのための「開始X座標」を更新
        ' 「現在のビューの右端 + マージン」を次の開始点にする
        currentX = currentX + viewWidth + margin
        
        ' もし横に並べすぎてシートをはみ出しそうなら、改行するロジックをここに追加できます
        ' (今回はシンプルに横一列の例)
        
        Debug.Print "View " & i & " placed at: " & centerX & ", " & centerY
    Next i

    ' 再描画して結果を表示
    swModel.EditRebuild3
    swModel.ActiveView.EnableGraphicsUpdate = True
    
    MsgBox "レイアウト完了!", vbInformation
End Sub

4. 伝説のアーキテクトからのアドバイス:陥りやすい「3つの罠」

このコードを動かす際、あるいは自分で拡張する際に、必ず突き当たる壁があります。これを知っているだけで、デバッグ時間は半分になります。

① 単位の罠(Meter vs Millimeter)

SolidWorks APIの内部単位は、常に「メートル (m)」です。
マクロの記録では `0.1` と書いてあるところが、設計図面上では `100mm` を意味しています。
「なぜかビューが豆粒みたいに小さくなった!」「どこか遠くに飛んでいった!」と思ったら、まず単位を確認してください。

② 再構築(Rebuild)の罠

バウンディングボックスの計算は、「今、画面に見えている状態」に基づきます。
もし、プログラムの途中でビューのスケールを変えたり、寸法を追加したりした場合は、必ず `swModel.EditRebuild3` を実行して、幾何学情報を更新させてください。再構築せずに計算すると、古い(間違った)サイズで計算してしまいます。

③ 座標系の罠

`GetBoundingBox` が返す値は、「シートの原点」からの絶対座標です。
一方で、ビューの配置操作(`SetPosition`)が「ビューの中心」を指すのか「左下」を指すのかは、APIのメソッドによって異なります。

  • `View.GetPosition` / `SetPosition` は、多くの場合「ビューの中心」を操作します。
  • `GetBoundingBox` は「四隅の座標」を返します。

この「中心」と「端」の差を計算(`viewWidth / 2`)するのが、幾何学演算の醍醐味です。

5. まとめ:ここをクリアすれば、あなたはもう「記録」の奴隷ではない

「マクロの記録」は、いわば「答え」を書き写しているだけです。
しかし、今回学んだ「バウンディングボックスを使った幾何学演算」は、「答えの出し方(ロジック)」を組み立てる技術です。

  • 測る(GetBoundingBox)
  • 計算する(Width + Margin)
  • 動かす(SetPosition)

このサイクルをマスターすれば、ビューの配置だけでなく、部品の自動選定、注記の自動整列、さらには複雑な検査図面の自動生成まで、あなたの手でコントロールできるようになります。

一歩ずつ、コードの裏側にある「数学的な意味」を理解していってください。その先に、真の自動化エンジニアとしての景色が待っていますよ。

応援しています。頑張ってくださいね!

タイトルとURLをコピーしました