C#ATIA

↑タイトル詐欺 主にFusion360API 偶にCATIA V5 VBA(絶賛ネタ切れ中)

ツールパスバッチ処理 時間測定

PowerMillは、ツールパス・バウンダリの計算はGUIが操作出来なくなる
以来からあるバッチ処理と、バックグランドで行うバッチ処理の二つの
方法があるのですが、何となく体感的にバックグランドの処理が
遅いように感じてます。

同一処理での時間測定を異なるバッチ処理方法で測定したかったの
ですが、バックグランド処理の時間測定方法がわからず・・・。
(知っている方教えて頂けると助かります)

Windowsに標準で入っているパフォーマンスモニターでCPUの負荷を確認して
みると・・・ バックグランドは1.5~2倍ぐらいの処理時間がかかってます。



又、以前見つけた(マニュアルにも記載有り)グラフィックスのロックですが、
どれ程の効果があるものか試す為、こんなマクロを作ってみました。

function main() {
	DIALOGS MESSAGE OFF
	DIALOGS ERROR OFF
	ECHO OFF DCPDEBUG UNTRACE COMMAND ACCEPT
	
	call ResetToolpath()
	graphics unlock
	print = "-- basic batch graphics_unlock --"
	call Sw_Start()
	BATCH PROCESS
	call Sw_GetTime()
	
	call ResetToolpath()
	graphics lock
	print = "-- basic batch graphics_lock --"
	call Sw_Start()
	BATCH PROCESS
	call Sw_GetTime()
	graphics unlock
	
	DIALOGS MESSAGE ON
	DIALOGS ERROR ON
	ECHO ON DCPDEBUG TRACE COMMAND ACCEPT	
}

function Sw_Start() {
	CLOCK RESET QUIT
	CLOCK ON QUIT	
}

function Sw_GetTime() {
	CLOCK OFF QUIT
	CLOCK PRINT QUIT
}

function ResetToolpath() {
	INVALIDATE TOOLPATH ALL
	Yes
	INVALIDATE BOUNDARY ALL
	Yes
}

既存のプロジェクトのツールパス・バウンダリを全て無効化し、
再度全てをバッチ処理させるだけのものです。

結果は・・・殆ど変わらないw

アクティブなブロックを未計算ツールパスに反映させる

恐らくどの3DCAMでも、類似した工程を製作する際は
予め作成しておいた雛形を流用するのだろうと思います。

PowerMillにもテンプレートオブジェクトと言う機能が有り、非常に
便利なのですが、ちょっと困る部分もあったりします。

テンプレートを呼び出した際、各ツールパスが切削領域を設定する
ブロックが記録した際サイズのままになってしまいます。
これを一つずつ修正するなんて、僕には有り得ないお話。

なので、アクティブなブロックを未計算ツールパスに反映させる
マクロを作ってみました。

//pm2017 macro sample_Active_Block_Copy.mac
//アクティブなブロックを未計算ツールパスに反映させる

function main() {
	//確認
	string msg = ''
	call Can_Exec() 
	
	//ブロックタイプ
	if block.type != "box"  {
		message wran  'ボックスタイプのブロックしか対応出来ません!!'
		macro abort
	}
	
	//ブロックサイズ
	real list Limits = {}
	call Get_BlockSize($Limits)
	string cmd = ''
	call Get_CmdString($Limits, $cmd)
	
	//未計算パス
	string list paths = extract(filter(folder('toolpath'), 'Computed == 0'), 'Name')
	if is_empty(paths)  {
		message wran  '未計算のツールパスが見つかりませんでした'
		macro abort
	}
	
 	//ユーザー選択
	call Lst_ToString($paths, crlf, $msg) 
	$msg = '以下のツールパス全て、ブロックを修正しますか?' + crlf + $msg
	bool yn = 0
	$yn = QUERY $msg
	if not $yn {
		//選択用ダミー作成
		call Create_DmyGroup($paths)
		if is_empty(folder('group')) {
			message error  'エラーです。中止します(エラー_Group)'
			macro abort
		}		
	
		$msg = '現在のブロックを反映する' + crlf + 'ツールパスを選択してください' 
		entity list grps =  input entity multiple group $msg
		DELETE GROUP ALL
		if is_empty(grps) {
			macro abort
		}	
		$paths = extract(grps , 'name')
	}
	
	//ブロックコピー
	call DialogOff()
	call Set_BlockSize($paths, $cmd)
	call DialogOn()
}

//コード取得
function Get_CmdString(real list Limits, output string OutTxt) {
	string txt = ''
	$txt =  $txt + 'EDIT BLOCK XMIN "' + string($Limits[0]) + '"' + crlf
	$txt =  $txt + 'EDIT BLOCK XMAX "' + string($Limits[1]) + '"' + crlf
	$txt =  $txt + 'EDIT BLOCK YMIN "' + string($Limits[2]) + '"' + crlf
	$txt =  $txt + 'EDIT BLOCK YMAX "' + string($Limits[3]) + '"' + crlf
	$txt =  $txt + 'EDIT BLOCK ZMIN "' + string($Limits[4]) + '"' + crlf
	$txt =  $txt + 'EDIT BLOCK ZMAX "' + string($Limits[5]) + '"' + crlf
	$OutTxt = $txt
}

//ブロックコピー
function Set_BlockSize(string list Lst, string Cmd) {
	foreach path in $Lst {
		ACTIVATE TOOLPATH $path
		EDIT BLOCK ALL UNLOCK
		EDIT BLOCKTYPE BOX
		EDIT BLOCK COORDINATE WORKPLANE
		call Exec_Cmd($cmd)
		EDIT BLOCK ALL LOCK
		EDIT TOOLPATH $path REAPPLYFROMGUI
	}
}

//コマンド
function Exec_Cmd(string cmd) {
	docommand $cmd
}

//ブロックサイズ取得
function Get_BlockSize(output real list OutLst) {
	real list lst = {}
	int dmy = 0
	real vlu = 0
	$dmy = add_last($lst, round(block.limits.xmin,4))
	$dmy = add_last($lst, round(block.limits.xmax,4))
	$dmy = add_last($lst, round(block.limits.ymin,4))
	$dmy = add_last($lst, round(block.limits.ymax,4))
	$dmy = add_last($lst, round(block.limits.zmin,4))
	$dmy = add_last($lst, round(block.limits.zmax,4))
	$OutLst = $lst
}

//選択用ダミー作成
function Create_DmyGroup(string list paths) {
	foreach txt in $paths {
		CREATE GROUP ;
		RENAME Group "1" $txt
	}
}

//条件確認
function Can_Exec() {
	if not (is_empty(folder('group'))) {
		string msg = 'グループフォルダをクリアします。' + crlf + '宜しいですか?'
		bool yn = 0
		$yn = QUERY $msg
		if not $yn {
			macro abort
		}
		DELETE GROUP ALL
	}
}

//ダイアログ類オン
function DialogOn() {
	GRAPHICS UNLOCK
	DIALOGS MESSAGE ON
	DIALOGS ERROR ON
	ECHO ON DCPDEBUG TRACE COMMAND ACCEPT
}

//ダイアログ類オフ
function DialogOff() {
	GRAPHICS LOCK
	DIALOGS MESSAGE OFF
	DIALOGS ERROR OFF
	ECHO OFF DCPDEBUG UNTRACE COMMAND ACCEPT
}

//リストから文字列
function Lst_ToString(string list Lst , string Delimiter , output string Outtxt) {
	string txt = ''
	foreach itm in $Lst {
		$txt = $txt + $itm + $Delimiter
	}
	int lng = length($txt) - length($Delimiter)
	$Outtxt = substring($txt , 0 , $lng)
	return
}

まずアクティブなブロックを決め(BOXタイプのみ)、マクロを実行すると
ブロックサイズを修正します。

実際に実行した動画はこちらです。

・・・何やっているか全くわからないと思います。

2回目にマクロを実行した際のプルダウンリストの動きは、前回の最後に
記載した方法で実現させています。
PowerMillマクロのダイアログ類 - C#ATIA
その為、"group" フォルダは犠牲にしています。

(ひょっとしたら全てを一度に直す機能が標準コマンドであるのかな?)

PowerMillマクロのダイアログ類

前回は、結局マニュアルに記載されていた関数のみでした。
今回こそは・・・、と思ったのですが、調べると今回も殆どがマニュアル
記載のものです。

PowerMillのマクロで処理した際、マクロユーザーに何らかのメッセージや選択を促す
ダイアログ類の覚書です。


〇エコーコマンド
どちらかと言うと、開発者用です。
VBAのイミディエイトウィンドウと同等なエコーコマンドへの出力です。
アクティブな工具名の出力です。

function main() {
	print = tool.name
}


〇message ~
OKボタンのみのダイアログです。

function main() {
	message info tool.name
	message warn tool.name
	message error tool.name
}


〇INFOBOX
これはマニュアルに記載されていないです。
ポスト処理やCADデータをインポートした際に現れるダイアログのようです。
messageダイアログより表現豊かで、これは表示されてもマクロの実行が
止まりませんでした。又、これはマクロから閉じる事も可能でした。

function main() {
	INFOBOX NEW "info box test"

	string txt = "HEADING STYLE : " + tool.name + crlf + crlf
	INFOBOX STYLE "HEADING"
	INFOBOX APPEND $txt

	$txt = "NORMAL STYLE : " + tool.name + crlf + crlf
	INFOBOX STYLE "NORMAL"
	INFOBOX APPEND  $txt

	$txt = "WARNING STYLE : " + to_xml(entity('Tool', tool.name))
	INFOBOX STYLE "WARNING"
	INFOBOX APPEND  $txt

	WAIT 3.0
	INFOBOX CLOSE
}

"WARNING STYLE : "の横のto_xml関数もマニュアルの記載が無く、パラメータをXMLフォーマットで
出力するようです。
WAIT関数もマニュアルの記載がありません。単位は秒のようです。
こちらのサンプルの方がイロイロと表現されています。
Delcam User Forum • View topic - Can you do images in a message box popup?


〇QUERY
'はい' 'いいえ' ボタンを持つダイアログです。

function main() {
	bool yn = 0
	string msg = ''
	$yn = QUERY 'このブログの記述は、信用出来ない?'
	if $yn {
		$msg = 'その通り!'
	} else {
		$msg = 'よく考えよう!'
	}
	message warn $msg
}


〇input
単純な入力用ダイアログです。
事前に受け取る変数に値を入力しておくと、デフォルトで設定されるようです。
(古いバージョンでは出来なかったような・・・)

function main() {
	int num = 23
	$num = input "何歳(数字で入力)"
	bool err = 0
	$err = error num
	string msg = ''
	if $err {
		$msg = '数字入力だって!!'
	} else {
		$msg = '多分、' + $num + '歳'
	}
	message warn $msg
}

上記のコードで文字を入力すると、通常は都合が悪く(int型に文字を代入)
エラーになるべきなのですが、PowerMillのマクロでは '0' が代入されてしまいます。
PowerMillのマクロでは例外処理が出来ないのですが、inputに関しては
上記のコードの方法でエラーを拾えるようです。


〇input entity ~
指定した組み込みフォルダ内のエンティティを選択肢としたセレクトボックスです。
inputでは、マクロユーザーの入力ミスに対してのチェックコードを用意する必要が
あると思いますが、こちらはその手間が省けるため、マクロの開発者・ユーザーの
負担が軽減できます。
事前に受け取る変数内に値を入れておけば、デフォルト値として表示されました。

function main() {
	string msg = "アクティブにする工具を選んでください" + crlf + "現在は " + tool.name
	string toolname = tool.name
	$toolname = input entity tool $msg
	activate tool $toolname
	message warn $toolname + " をアクティブツールにしました"
}

上記コードでは '工具フォルダ' から工具を選択させるようにしています。
f:id:kandennti:20170221191908p:plain


〇input entity multiple ~
input entity ~ は、プルダウンされたリストから1個しか選択出来ませんが、
こちらは複数選択が可能です。
事前に受け取る変数内に値を入れておいても、デフォルトでチェックが入った
状態にはなりませんでした。

function main() {
	string msg = "バックグランドで計算させるツールパスを選択してください" 
	entity list paths = input entity multiple toolpath $msg
	foreach path in $paths {
		INVALIDATE TOOLPATH $path.name
		EDIT TOOLPATH $path.name QUEUE
	}
	message info size($paths) + "個をバックグランドで計算登録しました"
}

上記のコードは、既に存在しているツールパスをプルダウンリストし、選択されたツールパスを
バックグランド計算に投げるコードです。(計算済みのものも強制的に計算させます)
f:id:kandennti:20170221191917p:plain


〇input choice
input entity multiple ~は組み込みフォルダ内の全てのエンティティが表示されて
しまいます。上記のコードの場合であれば、未計算のツールパスだけを選択肢
したいところです。 こちらは事前に処理しておいたリストを選択肢として
おくことが可能です。 リストの一番最初のものがデフォルト値となるようです。
戻り値はリストのインデックスです。

function main() {
	string list paths = extract(filter(folder('toolpath'), 'Computed == 0'), 'Name') 
	string msg = "バックグランドで計算させるツールパスを選択してください" 
	int idx = input choice $paths $msg
	string cmd = "EDIT TOOLPATH " + $paths[$idx] +" QUEUE"
	docommand $cmd
	message info $paths[$idx]  + "をバックグランドで計算登録しました"
}

上記のコードは、先日のfilter・extract関数で事前に未計算のツールパスのみを
探し出し、プルダウンリストとして表示させます。
f:id:kandennti:20170221191925p:plain
残念なのは、複数選択が出来ない事です。


フォーラムを見ても

//これはNGです
・・・
string list paths = extract(filter(folder('toolpath'), 'Computed == 0'), 'Name') 
string msg = "バックグランドで計算させるツールパスを選択してください" 
int idx = input choice multiple $paths $msg
・・・

の様に、リストの複数選択したいけど出来ないの? のような記載はありますが
どうも出来ないようです。
代案としては、どれか一つ組み込みフォルダを犠牲にして・・・と言う感じの
コードに僕はしてみましたけど。

PMillマクロの隠れ型・隠れ関数

PowerMillのマクロを作る際、参考となるものは、インストールフォルダ内に
'Macro Programming Guide' があり(日本語版はサポートに言ってもらおう!)
これと、Web上のフォーラムだけが頼りです。


'Macro Programming Guide'(以下マニュアル) によるとPowerMillマクロの
変数の型は string,int,real,bool があり、それらのコンテナとして
array,list がある(混合させるのはNG) となっています。

マニュアルには記載されていないのですが、実はもう一つ entity型がありました。
ツールパスやバウンダリ等のエンティティ用の変数の型です。
当然コンテナも entity list として利用が可能です。

先日あまりの苦しさで作ったライブラリ的なものを作成する際、entity型の
存在は何となくわかっていたのですが、利用方法が良くわかっていません
でした。 その為、指定したフォルダ内をバンバンループさせて、必要条件を
満たしたものだけを、エンティティ名のみをリストに突っ込んで返しています。
(後々の処理を考えると、エンティティそのものを返したかったのですが・・・。)


更に型のみならず、それらを扱う為の隠れ関数(マニュアルには記載されていない)
が多数存在。

例えばfilter関数(これずっと欲しかった・・・。)
第一引数はListやFolder(ArrayもOKかも)で、第二引数が抜き出す条件です。

ツールパスフォルダ内の全てのツールパスを抜き出す場合は、こんな感じです。

	entity list toolpaths = filter(folder('toolpath'), '')

全ての場合は空の文字列です。
(マニュアルにはフォルダ名を指定する場合のみ、大文字小文字を区別するので注意しろ
 と記載されているのですが、途中から仕様が変更されたようです)


これを、計算済みのツールパスのみのリストとして取得したい場合は

	entity list computedpaths = filter(folder('toolpath'), 'Computed == 1')

第二引数に条件となるものを文字列として渡すようです。


'message info' 等、マクロユーザーに表示させるためにはエンティティ型のままでは、
出来ない為、Tree上に表示させている名前を取得したいところです。

そこでまた隠し関数のextract関数の登場です。
第一引数はListやFolderで、第二引数は抜き出すパラメータ名です。
(他の言語のmapやfancみたいなもの・・・そこまではいかないですが)
先程のfilterと組み合わせると

	entity list computedpaths = filter(folder('toolpath'), 'Computed == 1')
	string list names = extract(computedpaths , 'Name') 

これで、namesには計算済みツールパスの名前が全部取得できます。
又、これは一行で書くことが出来ます。

	string list names = extract(filter(folder('toolpath'), 'Computed == 1'), 'Name') 


又、こちらでフォルダ名を取得していますが、空のフォルダ名は取得できていません
でした。
フォルダ名リストを取得する - C#ATIA

これも、get_folders関数と言う隠し関数が存在しており、あんなメンドクサイ
コードを書かずにこれだけで空フォルダも含めて、全て取得できます。

	string list dirs = get_folders('toolpath')

これらをもっと早く知りたかった。 もうこちらのライブラリ的なものが要らない
気がしてます(涙)
非常に個人的なPowerMillマクロ用ライブラリ - C#ATIA



昨日のGUIやグラフィックもそうですが、マニュアルに記載されていない関数等が
かなり多数存在しているようです。 どうもこれらは開発側が利用する為に
試験的に導入されたもののようで、動作保障が無いようです。
恐らくエラー時に動作が不安定で最悪ソフトが落ちる程度で、エラーにならない
処理での利用であれば大丈夫な気がしてます。

これらを旧Delcamさんのフォーラムには、中の人が沢山記載しており
非常に重宝しています。(特にロイドさんが)
Autodeskさんのところには登場していないようですが・・・。


追記です。
entity型はマニュアル(2017)に記載がありました。手元に全て印刷したものが
2013だったもので、すいません。
また、object型と言う型もあり、get_typename関数で型のタイプも
取得できるようです。 動的なコードが書けると言う事ですね。

更に追記です。
filter・extract・get_folders何れも、マニュアルに記載がありました。すいません

PowerMillマクロを高速化?

何時も忘れて何度もフォーラムを検索するのでメモ書きです。

何れもPowerMillの処理を高速化したり、マクロの停止を防ぐものです。

〇メッセージダイアログ
DIALOGS MESSAGE ON
DIALOGS MESSAGE OFF

〇エラーダイアログ
DIALOGS ERROR ON
DIALOGS ERROR OFF

〇エコーコマンド デバッグトレース
ECHO ON DCPDEBUG TRACE COMMAND ACCEPT
ECHO OFF DCPDEBUG UNTRACE COMMAND ACCEPT

〇グラフィックス
GRAPHICS LOCK
GRAPHICS UKLOCK

〇GUI
GUI ON
GUI OFF

最初の2つのダイアログOFFはメニューからも可能です。
エコーコマンドのやつは、以前書きましたが効果がよくわかっていないです。
グラフィック Lock/UnLock は、3D画面側の更新を止めてしまうものです。
GUI On/Off は、ソフトを非表示にするわけではなく、通常操作している
Treeの表示をするタブから、ブラウザのタブに切り替えます。


GUIは手動(エコーコマンドから)で入力すると、通常の状態に戻せない為
PowerMillを強制終了する以外方法が無い様なので、やらない方が
良いでしょう。 (外部から操作すれば戻るかも)

グラフィックについては、Excelのマクロでも高速化の為の手法と同じだろうと
思います。 こちらも手動でも可能でツールパスの計算時間も若干短くなる
ようです。(バックグランドに投げるようなものかも・・・)


先日のライブラリっぽいものを利用し、アペンドテストを書き換えた上で
上記の物を全部利用した動画がこちらです。

味気無い・・・Autodeskの宣伝みたいになってますね。

非常に個人的なPowerMillマクロ用ライブラリ

あまりに苦しいので、ライブラリ的なものを作りました。
PowerMillのマクロは、マクロの実行ファイル(.mac)以外に拡張子「.inc」に
することでライブラリとして使用できるんです。(エライ!)

//pmill macro Kantoku_PowerMill_Library ver0.0.2
//kpl.inc
//r2017で開発

// **** フォルダ ****
//指定した組み込みフォルダからエンティティの存在するフォルダネームリスト取得
//param : DirName (string)
//param : Name (string)
//param : OptIsNew(bool) - 指定の名前のフォルダが既存にあった場合新作するか? 0_新作しない 1_新作
//param : OptIsAct(bool) - 実行後フォルダをアクティブにするか?  0_非アクティブ1_アクティブ
//return : Outstr(string) - 新たに出来たフォルダ名
function Create_Folder(string DirName , string Name , bool OptIsNew , bool OptIsAct , output string Outstr) {
	string fullname = $DirName + '\' + $Name
	string list Before = get_folders($DirName)
	
	if member($Before, $fullname) {
		if not OptIsNew {
			if OptIsAct {
				ACTIVATE FOLDER $fullname
			}
			return
		} else {
			call Get_UnOverlap_Name($fullname , $Before, $fullname)
		}
	}
	
	CREATE FOLDER $DirName ; 
	string list After = get_folders($DirName)
	string list lst= subtract($After, $Before)
	string autoname = $lst[0]
	$Outstr = basename($fullname)
	RENAME FOLDER $autoname  $Outstr
	if OptIsAct {
		ACTIVATE FOLDER $fullname
	}
}

//重複しない名前を取得
//param : Name(string) - 候補名
//param : Lst(string list) - 比較リスト
//return : Outstr(string) - 重複の無い名前
function Get_UnOverlap_Name(string Name , string list Lst , output string Outstr) {
	string tmpname = $Name
	int cnt = 0
	bool fg = 0
	do {
		$fg = member($Lst, $tmpname) 
		if not $fg {
			break
		}
		$cnt = $cnt + 1
		$tmpname = $Name + '_' + String($cnt)
	} white 1
	$Outstr = $tmpname
}

// **** エンティティ ****

//指定した組み込みフォルダからエンティティの存在するフォルダネームリスト取得
//param : DirName (string)
//param : Calculate(int) - 計算FG -1以下_全て 0_未計算のみ 1以上_計算済のみ
//param : Leval (int) - フォルダの階層 組み込みフォルダは1 指定無しは0以下
//param : RemoveLst(string list) - 除外するフォルダ名リスト
//return : Outlst(string list)
function Get_Entitys_Dir(string Dirname , int Calculate , int Level , string list RemoveLst , output string list Outlst) {
	string list paths = {}
	call Get_Entitys_Path($Dirname , $Calculate , $Level , $paths ) 
	
	string list lst = {}
	string dirtxt = ''
	foreach itm in $paths  {
		$dirtxt = basename(dirname($itm ) ) 
		if not member($RemoveLst , $dirtxt) {
			int dmy = add_last($lst, $dirtxt)
		}
	}
	int dmy = remove_duplicates($lst)
	$Outlst = $lst
}

//指定した組み込みフォルダからベースネームリスト取得
//param : DirName (string)
//param : Calculate(int) - 計算FG -1以下_全て 0_未計算のみ 1以上_計算済のみ
//param : Leval (int) - フォルダの階層 組み込みフォルダは1 指定無しは0以下
//return : Outlst(string list)
function Get_Entitys_Base(string Dirname  , int Calculate , int Level  , output string list Outlst) {
	string list paths = {}
	call Get_Entitys_Path($Dirname , $Calculate , $Level , $paths ) 
	
	string list lst = {}
	string txt = ''
	foreach itm in $paths  {
		$txt = string(basename($itm))
		int dmy = add_last($lst, $txt )
	}
	$Outlst = $lst
}

//指定した組み込みフォルダからパスリスト取得
//param : DirName (string)
//param : Calculate(int) - 計算FG -1以下_全て 0_未計算のみ 1以上_計算済のみ
//param : Leval (int) - フォルダの階層 組み込みフォルダは1 指定無しは0以下
//return : Outlst(string list)
function Get_Entitys_Path(string Dirname , int Calculate , int Level , output string list Outlst) {
	string list ents = {}
	string ent = ''
	int cal = -1
	foreach itm in folder($Dirname)  {
		$ent = pathname($itm)
		if $Level > 0 {
			if size(tokens($ent, "\")) != $Level + 1 {
				continue
			}
		}
		if $Calculate > -1 {
			switch $itm.computed {
				case 0
					if Calculate > 0 {
						continue
					}
					break
				case 1
					if Calculate == 0 {
						continue
					}
					break
			}
		}
		int dmy = add_last($ents, $ent)
	}
	$Outlst = $ents
}

// **** その他 ****
//リストから文字列
//param : Lst (string list)
//param : Delimiter (string)
//return : Outtxt(string)
function Lst_ToString(string list Lst , string Delimiter , output string Outtxt) {
	string txt = ''
	foreach itm in $Lst {
		$txt = $txt + $itm + $Delimiter
	}
	int lng = length($txt) - length($Delimiter)
	$Outtxt = substring($txt , 0 , $lng)
	return
}

//ダンプ
function Dump(string list Lst) {
	string txt = ''
	call Lst_ToString($Lst , crlf , $txt )
	print = $txt
}

//ダイアログ類オン
function DialogOn() {
	DIALOGS MESSAGE ON
	DIALOGS ERROR ON
	ECHO ON DCPDEBUG TRACE COMMAND ACCEPT
}

//ダイアログ類オフ
function DialogOff() {
	DIALOGS MESSAGE OFF
	DIALOGS ERROR OFF
	ECHO OFF DCPDEBUG UNTRACE COMMAND ACCEPT
}

ver0.0.1 - 完成
ver0.0.2 - Get_Entitys_Dir関数に除外リスト追加



エンティティの名前の重複が許されない為、先日のマクロも何度も何度もリストを
取得しなくてはならない為、その辺中心に作っています。

これを利用するテストマクロがこちら。

//pmill macro クズユニットテスト

function Main() {
	call DialogOff()
	
	// **** エンティティ ****
	string list lst = {}
	print = "**path**"
	call Get_Entitys_Path('Toolpath' , 1, 0, $lst ) 
	call Dump($Lst )
	call Get_Entitys_Path('Boundary' , 1 , 0 , $lst ) 
	call Dump($Lst )
	
	print = "**base**"
	call Get_Entitys_Path('Toolpath' , 1,0 , $lst ) 
	call Dump($Lst )
	call Get_Entitys_Base('Boundary' , 1 , 0 , $lst ) 
	call Dump($Lst )
	
	print = "**dir**"
	call Get_Entitys_Dir('Toolpath' , 1 , 0 , $lst ) 
	call Dump($Lst )
	call Get_Entitys_Dir('Boundary' , 1 , 2 , $lst ) 
	call Dump($Lst )
	
	//**** フォルダ ****
	string Dirname = ''
	call Create_Folder('Toolpath' , 'Hoge' , 1 , 1 , $Dirname)
	print = $Dirname
	call Create_Folder('Toolpath' , 'Hoge' , 1 , 1 , $Dirname)
	print = $Dirname
	call Create_Folder('Boundary' , 'Hoge' , 1 , 1 , $Dirname)
	print = $Dirname
	call Create_Folder('Boundary' , 'Hoge' , 1 , 1 , $Dirname)
	print = $Dirname
	call Create_Folder('Tool' , 'Hoge' , 1 , 1 , $Dirname)
	print = $Dirname
	call Create_Folder('Tool' , 'Hoge' , 1 , 1 , $Dirname)
	print = $Dirname
	
	call DialogOn()
}

include kpl.inc

最後に記載した

 ・・・
include kpl.inc

で読み込んでます。最初じゃなくても大丈夫なんです。(エライ)
(最初だとエラーメッセージに表示された行がずれちゃうんです)

国内だとPowerMillユーザー少なそうだから、使う人いないだろうなぁ
(日本語のフォーラム作って欲しい・・・)

ダイアログオフが思った程、機能していない

上手く行かない と思っていたらこんな記述を発見。

PowerMILL 2017 Dialogs On\Off error when run macro. - Autodesk Community

要はこんな感じでコードを書いておくと、ダイアログが表示されなくなります。
・・・されなくなる、はずでした。

  DIALOGS MESSAGE OFF


困っていたのは、マクロの処理中にダイアログが出てきちゃって、マクロ自体が止まっちゃうの
です。こっちとしては処理中に他の作業を行いたいので、まとめてマクロで処理させたい
のに離れられなくなっちゃうんです。
10年ぐらいの前のバージョンのPowerMill7でも、機能していたのに・・・。

と、イロイロ探しながら悩んでいたら、マクロの記録をとったらしっかりと記載されて
いましたw


あまりに汚いコードなので、一部のみの公開です。
ダイアログが出て困っていたのは、ツールパスをアペンド(連結)させた際に出てくる
確認用のダイアログです。上手く以下なかった際の処理はこんな感じ。

コード的には

	DIALOGS MESSAGE OFF
	foreach Itm in $AppendLst {
		//アペンド処理
		EDIT TOOLPATH $CopyedName APPEND CONFIRM $Itm
	}
	DIALOGS MESSAGE ON

記録をとった上、修正したコードがこちら。

	foreach Itm in $AppendLst {
		EDIT TOOLPATH $CopyedName APPEND CONFIRM $Itm
		Yes //悩んだ末の解決策がこれだけ
	}

実際に上手く処理できるようになった動画はこちらです。

さっさと記録とれば良かった・・・。