C#ATIA

↑タイトル詐欺 主にCATIA V5 の VBA(最近はPMillマクロとFusion360APIが多い)

関数名

最近は忙しすぎて、ブログのネタになるような事をしてません。

こちらをチラッと読みました。

VBA 特定日付が、第何週目の何曜日なのかを求める関数 - t-hom’s diary

結構関数名に悩みます。リファクタリングすることで変数名の
ボキャブラリ不足を回避しているつもりですが、その反動で
関数名に悩みます。
(特にVBAは他言語に比べ、途中での関数名変更は敷居が高い)

で、こちらを偶に利用しています。
codic - プログラマーのためのネーミング辞書
それっぽい感じで出てくれるので。


・・・「翔んで埼玉」見ていない。家族で僕だけ。
僕は何時、翔べるのだろうか?

背景図を変更したい

Drawの背景図をマクロで用紙サイズ毎に変更したいのです。
「背景図を挿入」が使えるとありがたいのですが、出来なさそうです。
f:id:kandennti:20190312193007p:plain

昔、何かスプリクトで変更する動画を見た覚えが有るのですが、
これだったかな?
CATIA V5 Macro to insert frame and title block - YouTube
当時「すごいなぁ」と思いましたよ。

確か、この辺かな? Helpを見たのですが
Creating a Frame and a Title Block
ガッツリマクロかよ! って思ってそのまま流してしまいました。

結局、雛形的なDrawファイルからイロイロとコピペして、それなりに
値を修正するしかないのかな?
近い将来、必要になる気がしています。

始点の無い、片追い寸法

”片追い寸法” は正式な名称じゃないと思いますが、他の表現方法がわかりません。
こちらでは ”片矢印寸法” と表記(コマンド?)されていました。
片矢印寸法(dexdsid)

要はこんな感じの寸法です。
f:id:kandennti:20190312163850p:plain
始点がクリッピングされているような状態のものです。


まず累進寸法を作成。
f:id:kandennti:20190312163958p:plain

プロパティを開いて「寸法線」タブの「表現」を標準以外にする。
f:id:kandennti:20190312164019p:plain

寸法をアクティブにし黄色い部分を「情けないなぁ」と感じながら
チマチマ動かし、寸法線と寸法値のアンダーラインが重なる様にする。
f:id:kandennti:20190312164032p:plain

後はクリッピングで始点側を削除する。
f:id:kandennti:20190312164049p:plain


標準を変更すれば始点側の「0」の文字を消せるのですが、
それはちょっと許されないので、困っていました。
(標準では0が消えないんです・・・)

サポートさんその節はありがとうございます。
その際は解決には至りませんでしたが・・・。

本来の目的じゃない所に時間がかかるのは、どうかと思う。

指定ビュー内の2Dコンポーネントを削除する

「ビュー内の2Dコンポーネントを削除する方法」について御質問頂きました。

2Dコンポーネントについては、DrawingView内のComponentsプロパティの
コレクションが所有した状態になっています。

'vba 指定ビュー内の2Dコンポーネントを削除する
Option Explicit

Sub CATMain()

    Dim dDoc As DrawingDocument
    Set dDoc = CATIA.ActiveDocument
    
    'ビュー選択
    Dim msg As String
    msg = "2Dコンポーネントを削除するビューを選択してください / ESC-キャンセル"
    
    Dim sel 'As selection
    Set sel = dDoc.selection
    
    Dim status As String
    sel.Clear
    status = sel.SelectElement2(Array("DrawingView"), msg, False)
    If Not status = "Normal" Then Exit Sub
    
    Dim vi As DrawingView
    Set vi = sel.Item2(1).Value
    sel.Clear

    '2Dコンポーネント数確認
    If vi.Components.Count < 1 Then
        msg = vi.Name & " には、2Dコンポーネントが有りません"
        MsgBox msg
        Exit Sub
    End If
    
    '確認
    msg = vi.Name & " には、" & vi.Components.Count & _
        "個の2Dコンポーネントが有ります。" & vbCrLf & _
        "全て削除しますか?"
    
    If MsgBox(msg, vbQuestion + vbYesNo) = vbNo Then
        Exit Sub
    End If
    
    '2Dコンポーネント削除
    
    CATIA.HSOSynchronized = False
    
    Dim comp As DrawingComponent
    For Each comp In vi.Components
        sel.Add comp
    Next
    sel.Delete
    
    CATIA.HSOSynchronized = True
    
    '終わり
    MsgBox "done"
End Sub

同様に
テキスト : Texts
寸法 : Dimensions
等も検索を使用せずに同様の処理が可能です。

ストックモデルを利用している全てのツールパスの設定を未選択にする

邪魔なストックモデルを削除しようと思うのですが、相変わらず
依存が厳しく削除コマンドを行っても削除されません。
f:id:kandennti:20190307141324p:plain
削除しようとしているストックモデルを利用しているツールパスが
計算済みの為、削除出来ないような仕様になっています。

この様にストックモデルを利用している全てのツールパスの
設定を空欄にします。(赤印側)
f:id:kandennti:20190307141335p:plain
緑印の「ストックモデル」は後の作業の為、維持したままにします。

//pm2019macro
//Reset_RestRefarence.mac Ver0.0.1
//ストックモデルを利用しているツールパス取得

function Main () {

	//ストックモデルを利用しているツールパス取得
	entity list tps = {}
	call Get_HasRefStock_List($tps)
	
	//無効化
	call ExecInvalidateTP(reverse($tps))
	
	//削り残しストックモデルで未選択にする
	call ExecResetStockTP($tps)
	
	//終わり
	message info 'Done'
}

function ExecResetStockTP (entity list ents) {
	foreach tp in $ents {
		$tp.AreaClearance.Rest.ReferenceType = 'stockmodel'
		ACTIVATE TOOLPATH $tp.name FORM TOOLPATH
		EDIT PAR 'StockModelState.StockModel' ''
		EDIT TOOLPATH $tp.name REAPPLYFROMGUI
		YES
	}
}

function Get_HasRefStock_List (output entity list ents) {
	string filter = 'size(StockModelState.StockModel) > 0'
	$ents = filter(folder('toolpath') , $filter)
}

function GetComputedCount (entity list ents, output int out) {
	string filter = 'Computed == 1'
	$out = size(extract(filter($ents , $filter), 'name'))
}

function ExecInvalidateTP (entity list ents) {
	int st_cnt = 0
	call GetComputedCount($ents, $st_cnt)	
	int tmp1 = 0
	$tmp1 = $st_cnt
	int tmp2 = 0
	string tpname = ''
	do {
		foreach ent in $ents {
			invalidate toolpath $ent.name
		}
		call GetComputedCount($ents, $tmp2)
		if $tmp1 == $tmp2 {
			break
		}
		$tmp1 = $tmp2
	} while not $tmp1 == 0
}

もうちょっと作業が楽になって欲しい。


逆に全てのストックモデルを作成する際に使用しているツールパスを
全て取得する場合は、こんな感じです。

	entity list stocks = folder('stockmodel')
	object list states = flatten(extract($stocks, 'states'))
	entity list tps = flatten(extract($states, 'references'))

但し、何だか処理が重いです。

全てのツールパスの作業平面を変更

こちらの続きのような感じです。
全てのツールパスを無効に一発で! - C#ATIA

プロジェクト流用の為に、全てのツールパスの作業平面(CATIAの座標系)を
設定したいので、マクロにしました。

//pm2019macro
//Set_Axis.mac ver0.0.1
//全てのツールパスを無効にし作業平面をセットする

Function Main() {
	//無効
	call ExecUncalculated()	
	
	//作業平面選択
	string axis = ''
	call SelAxis($axis)
	
	//確認
	call UserConfirmation($axis)
	
	//Axis
	call SetAxis($axis)
		
	//終わり
	message info 'Done'
}

function ExecUncalculated () {
	int st_cnt = 0
	call GetComputedCount($st_cnt)	
	int tmp1 = 0
	$tmp1 = $st_cnt
	int tmp2 = 0
	do {
		INVALIDATE TOOLPATH ALL Yes
		call GetComputedCount($tmp2)
		if $tmp1 == $tmp2 {
			break
		}
		$tmp1 = $tmp2
	} while not $tmp1 == 0
}

function GetComputedCount (output int out) {
	string filter = 'Computed == 1'
	entity list tps = folder('toolpath')
	$out = size(extract(filter($tps , $filter), 'name'))
}

function SetAxis(string axis) {
	call Msgoff() 
	foreach tp in extract(folder('toolpath'), 'name') {
		ACTIVATE TOOLPATH $tp
		EDIT TPPAGE SWWorkplane
		ACTIVATE WORKPLANE $axis
		EDIT TOOLPATH $tp REAPPLYFROMGUI
	}
	call Msgon() 
}

function UserConfirmation(string axis) {
	int dmy = 0
	string list msglst = {'-- 作業平面 --'}
	if length(trim($axis)) < 1 {
		$dmy = add_last($msglst, '(無し)')
	} else {
		$dmy = add_last($msglst, $axis)
	}
	$dmy = add_last($msglst, '全てのツールパスにこの作業平面を設定しますか?')
	$dmy = add_last($msglst, '(全てのツールパスを無効にします)')
	string msg = join($msglst ,crlf)
	
	bool yn = 0
	$yn = query $msg
	if not $yn {
		macro abort
	}
}

function SelAxis(output string axis)  {
	string msg = '作業平面を選択してください'
	$axis = ''
	IF entity_exists('workplane', '') {
	   $axis = $entity('workplane', '').name
	} 
	$axis = input entity workplane $msg	
}

function Msgoff() {
	graphics lock
	dialogs message off
	dialogs error off
}

function Msgon() {
	graphics unlock
	dialogs error on
	dialogs error on
}

昨日のマクロはこの為の試作でした。

全てのツールパスを無効に一発で!

PowerMillの工程を使い回したい時がシバシバ有ります。
前にも書いたかも知れませんが。
既存の計算済みツールパスを全て無効にしてから始めたいので、
ツールパスのコンテキストメニューの「全て無効」コマンドを実行してます。
f:id:kandennti:20190306191458p:plain
恐らく他のCAMソフトでも類似した機能があるはずです。

ところが、PowerMillは依存関係が頑固で、一発で全て無効
にならない時が有ります。試しに1回実行すると
f:id:kandennti:20190306191508p:plain
電卓マークになっていないものは無効(未計算状態)になって
いません。複数回同じコマンドを繰り返せば全てが無効にはなります。


原因は、領域切削(荒加工です)の削り残し機能を使用すると
これが起きます。上記の画像では、ストックモデルを使用した領域切削
の設定になっています。(イロイロな方法がPowerMillにはあるんです!)
f:id:kandennti:20190306191517p:plain
使っていない人にはわからないですね。

・r10a_rough で加工しストックモデル化
 ↓
・ストックモデルを利用し r5a_roughを加工
 ↓
・r5a_vh で加工しストックモデルに追加
 ↓
・ストックモデルを利用し r2a_roughを加工

のような手順になってます。
これが標準的な方法かどうかわかっていませんが。
(ストックモデルはその都度コピーして依存をぶった切るのが
良いよ とかの記述は見たのですが、実質手間がかかる)

工程的な事は別として、PowerMillはこんな感じで安全よりに
設計されていて、頑固なまでに依存関係を保ちます。

これを一発で全て無効にする方法は無いものかと、サポートさんにも
問い合わせたのですが、そのようなコマンドが無くマクロで
行うしかないよ と教わりました。(その節はお世話になりました)

のですが、複数回「全て無効」コマンドを実行する為の回数が
状態によって異なるのですが、10回ぐらいループをまわすのみに
なっていた為、ちょっとイマイチだったので自作しました。

//pm2019macro
//Reset_Toolpath.mac ver0.0.1
//全て無効を一発で実現(しているように見せかける)

Function Main() {
	string msg = ''
	
	int st_cnt = 0
	call GetComputedCount($st_cnt)
	if $st_cnt == 0 {
		$msg = '計算済みツールパスは有りませんでした。'
		message info  $msg
		return
	}
	
	int ed_cnt = 0
	call ExecUncalculated($st_cnt, $ed_cnt)
	$msg = string($st_cnt - $ed_cnt) + '個、無効にしました。'
	
	//終了
	message info  $msg
}

function ExecUncalculated (int st_cnt, output int out) {
	int tmp1 = 0
	$tmp1 = $st_cnt
	int tmp2 = 0

	do {
		INVALIDATE TOOLPATH ALL Yes
		call GetComputedCount($tmp2)
		
		if $tmp1 == $tmp2 {
			break
		}
		
		$tmp1 = $tmp2
	} while not $tmp1 == 0
	
	$out = $tmp1
}

function GetComputedCount (output int out) {
	string filter = 'Computed == 1'
	entity list tps = folder('toolpath')
	$out = size(extract(filter($tps , $filter), 'name'))
}

「全て無効」コマンドの前後で計算済みのツールパスの数を取得し、
変化が無ければループを抜ける(それ以上やっても無意味)
ようにしました。


・・・Drawビューの原点を変更するマクロの説明書きを、書かなきゃな。