スケッチ内にあるマーク(Mark)の座標を取得する|CATIAマクロの作成方法
今回の記事は「お問い合わせ」でいただいた内容です。
送って頂いた内容は以下のようなマクロです。
まず自分がやりたいことを説明します。
①Bodyの中にHole を作ります
②Plane上にpointを数点作り、それらをsketchに投影してUserPatternでHoleを複製します
③DrawingTableにX,Y座標とHoleの直径と深さを出力するマクロを作りたいと思っています。
ここから質問なのですが、UserPatternで選択している 複数pointのX,Y座標を取得することはできるのでしょうか 。色々と調べてUserPattern(object)のFea tureToLocatePositions を使いましたが複数point情報は取得することはできませんでした。sketch(object)のGeometricElementsでplane上のpointまで辿り着けるかと思いましたがmark.1というところで行き止まりになってしまって独学では限界が来てしまいました。
CATIA VBAで座標を取得するには多くの場合「GetCoordinates」というメソッドを使います。
このメソッドは「Point」や「Point2D」のような"点"のオブジェクトにしか用意されていません。しかしながら今回取得したいマーク(Mark)はオブジェクトタイプが「Geometry2D」のためこのメソッドが用意されていません。
こういった場合の対処法はいくつかありますが、ここではマークのオブジェクトタイプを「Geometry2D」から「Point2D」に変換して「GetCoordinatesメソッド」で座標を取得していきます。(ほかにもMeasurableオブジェクトを使っていくつかの値を取得し、計算で座標を導くこともできると思います)
マクロの機能
今回作成したのはスケッチ内にある「マーク(Mark)」の座標を取得するマクロです。上画像の場合、「投影.1~4」の4つの点の"スケッチ平面上"でのXY座標をすべて取得します。
具体的な機能は以下のとおりです。
(スケッチ内には投影した点のみしか存在しない前提)
・座標はスケッチ平面上でのX,Y座標
・コード内の「coords」コレクション内に全座標が格納される
今回のマクロは最終的に結果はイミディエイトウィンドウ上に表示されます。
ドキュメント内で作業は行いますが最終的にドキュメント内には何も残らないので、イミディエイトウィンドウもしくはデバックモードで「coords」コレクション内の中身を確認して下さい。
サンプルコード
マクロのコードは以下のとおりです。
Option Explicit
Sub CATMain()
'アクティブドキュメント/Selection定義
If TypeName(CATIA.ActiveDocument) <> "PartDocument" Then
MsgBox "このマクロはPartDocument専用です。" & vbLf & _
"アセンブリーワークベンチに切り替えて実行してください。"
Exit Sub
End If
Dim doc As PartDocument: Set doc = CATIA.ActiveDocument
Dim sel As Variant: Set sel = doc.Selection
sel.Clear
'ユーザーパターン選択
Dim filter: filter = Array("UserPattern")
Dim msg As String: msg = "ユーザーパターンを選択して下さい。"
Dim status As String
status = sel.SelectElement2(filter, msg, False)
If status <> "Normal" Then
MsgBox "キャンセルしました。"
Exit Sub
End If
'ユーザーパターン取得
Dim up As UserPattern
Set up = sel.Item(1).Value
'ユーザーパターン内のスケッチを取得
Dim sk As Sketch
Set sk = up.FeatureToLocatePositions
'スケッチを複製
With sel
.Clear
.Add sk 'ユーザーパターン内のスケッチを選択
.Copy 'スケッチをコピー
.Clear
.Add up.Parent 'ユーザーパターンの親ボディーを選択
.Paste 'スケッチをボディーに貼り付け
End With
Dim skIso As Sketch
Set skIso = sel.Item(1).Value
skIso.Name = "座標取得用スケッチ(残っていたら削除してください)"
'複製したスケッチを分離(Isolate)
CATIA.StartCommand ("分離") '英語環境:「Isolate」
'分離したスケッチから点の座標をすべて取得
Dim coords As Collection
Set coords = New Collection
Dim coord()
Dim p 'As Point2D
For Each p In skIso.GeometricElements
If TypeName(p) = "Point2D" Then
ReDim coord(1)
Call p.GetCoordinates(coord)
coords.Add coord(0)
coords.Add coord(1)
End If
Next p
'座標取得用のスケッチを削除
sel.Add skIso
sel.Delete
'coords内の座標を使った処理
Dim i As Long
For i = 1 To coords.Count Step 2
Debug.Print (i + 1) / 2 & "番目 MarkのX座標: " & coords.Item(i)
Debug.Print (i + 1) / 2 & "番目 MarkのY座標: " & coords.Item(i + 1)
Next i
End Sub
コード解説
アクティブドキュメント/Selection定義
'アクティブドキュメント/Selection定義
If TypeName(CATIA.ActiveDocument) <> "PartDocument" Then
MsgBox "このマクロはPartDocument専用です。" & vbLf & _
"アセンブリーワークベンチに切り替えて実行してください。"
Exit Sub
End If
Dim doc As PartDocument: Set doc = CATIA.ActiveDocument
Dim sel As Variant: Set sel = doc.Selection
sel.Clear
まずはじめにアクティブドキュメントを定義をします。
今回のマクロはCATPartのみ有効なものなので、アクティブドキュメントがCATPart以外の場合はTypeName関数を使った条件分岐でマクロを終了するようにしています。つまり、アクティブドキュメントがCATPartの場合のみ変数「doc」にアクティブドキュメントを代入し、マクロの処理を続けます。
アクティブドキュメントが定義出来たら、あわせて「Selectionオブジェクト」も定義します。
ユーザーパターン/スケッチ選択
'ユーザーパターン選択
Dim filter: filter = Array("UserPattern")
Dim msg As String: msg = "ユーザーパターンを選択して下さい。"
Dim status As String
status = sel.SelectElement2(filter, msg, False)
If status <> "Normal" Then
MsgBox "キャンセルしました。"
Exit Sub
End If
'ユーザーパターン取得
Dim up As UserPattern
Set up = sel.Item(1).Value
'ユーザーパターン内のスケッチを取得
Dim sk As Sketch
Set sk = up.FeatureToLocatePositions
つぎに「SelectElement2メソッド」を使ってユーザーが選択した任意の「ユーザーパターン」を取得します。
ユーザーパターンを取得したら「UserPatternオブジェクト」の「FeatureToLocatePositionsプロパティ」を使ってユーザーパターン内にあるスケッチを取得します。
座標取得用のスケッチを作成
'スケッチを複製
With sel
.Clear
.Add sk 'ユーザーパターン内のスケッチを選択
.Copy 'スケッチをコピー
.Clear
.Add up.Parent 'ユーザーパターンの親ボディーを選択
.Paste 'スケッチをボディーに貼り付け
End With
Dim skIso As Sketch
Set skIso = sel.Item(1).Value
skIso.Name = "座標取得用スケッチ(残っていたら削除してください)"
'複製したスケッチを分離(Isolate)
CATIA.StartCommand ("分離") '英語環境:「Isolate」
次に座標取得用のスケッチを作成します。
作成方法は先ほど取得したスケッチを複製して"分離(Isolate)"するだけです。
スケッチを分離すると下画像のように「エッジを使用」内がすべて"形状"として変換されます。
これにより分離したスケッチ内の点を取得すると「Point2D」として取得することができます。
つまり冒頭でいっていた「GetCoordinatesメソッド」で座標を取得することが可能になった訳です。
分離したスケッチから点の座標をすべて取得
'分離したスケッチから点の座標をすべて取得
Dim coords As Collection
Set coords = New Collection
Dim coord()
Dim p 'As Point2D
For Each p In skIso.GeometricElements
If TypeName(p) = "Point2D" Then
ReDim coord(1)
Call p.GetCoordinates(coord)
coords.Add coord(0)
coords.Add coord(1)
End If
Next p
'座標取得用のスケッチを削除
sel.Add skIso
sel.Delete
最後に先ほど作成した座標取得用のスケッチを使い、点の座標をすべて取得していきます。
点の座標は「Point2Dオブジェクト」の「GetCoordinatesメソッド」を使います。
上記コードでは「coord(0)」がX座標、「coord(1)」がY座標となっています。
これをまとめて「coords」というコレクションに順に格納していきます。
これにより任意の点座標をいつでも呼び出せることが可能になります。
ちなみにcoordsコレクションの中身は下記のようになっています。
coords.Item(2) = 1番目の点のY座標
coords.Item(3) = 2番目の点のX座標
coords.Item(4) = 2番目の点のY座標
: :
coords.Item(i) = ((i + 1) / 2)番目の点のX座標
coords.Item(i+1) = ((i + 1) / 2)番目の点のY座標
分離したスケッチから点の座標をすべて取得
'coords内の座標を使った処理
Dim i As Long
For i = 1 To coords.Count Step 2
Debug.Print (i + 1) / 2 & "番目 MarkのX座標: " & coords.Item(i)
Debug.Print (i + 1) / 2 & "番目 MarkのY座標: " & coords.Item(i + 1)
Next i
座標の取得はできたので、あとはその座標を使った処理を書くだけです。
今回はcoordsコレクション内に格納されている座標をイミディエイトウィンドウに出力するだけの簡単な処理を行っています。
あとは「Debug.Print」を任意の処理に書き換えてください。
(今回のお問い合わせ内容でいえばDrawingTableへの出力のように)
まとめ
今回はスケッチ内にあるマーク(Mark)の座標を取得する方法についての内容でした。
「CATIA.StartCommand」は少し不安定なところもあるのであまり使いたくはありませんが、「Point2D」に変換するための妥協策です。(他にもいい案はあるかもしれません)
今回重要なのは「マーク(Mark)」をいかにしてPointに変換するかです。
マクロの答えは1つではないので、その他の方法もまだ眠っていると思います。
いろいろ試行錯誤し知識を得て、様々な方法を編み出してみてください。
(冒頭でもいっていたMeasurableオブジェクトを使うのも1つの手ですが、スケッチ平面が基準の座標取得と考えるとあまり得策ではないです)











