C#ATIA

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

PowerMillに同位置の作業平面を作る2

こちらの続きです。
PowerMillに同位置の作業平面を作る - C#ATIA

作った頃は 「使わないかも」と思っていたのですが、最近は作業方法を
変更し使うようになりました。

GetObject関数で起動中のPowerMillを拾い出して、ひたすら文字を
送り込んで同一の作業平面(CATIAの座標系)を作るのですが、
最近何度も困ったことに遭遇しました。


実際の作業では、複数のPowerMillを起動し片方はバッチ処理中で、片方は
次の準備を進めている状況が多いのですが、GetObject関数ではどちらの
PowerMillを取得するのかがわからないんです。
恐らく、先に起動した方を取得するのですが、このマクロが必要になるのが
大半が後から起動した方なんです。
(その為一度ソフトを終了し、再度起動すると言う アホみたいな事を何度も・・・)

ダイレクトに作業平面を作成するのではなく、CATIA側では必要な情報を
ファイルにエクスポートし、PowerMill側ではエクスポートファイルを元に作業平面を
作成した方が現実的な気がするので、そんなマクロを作成しました。

まず、CATIA側のエクスポートする為のマクロ

'vba Part_Pmill_Exp_AxisSystem_ver0.0.1  using-'KCL0.0.12'  by Kantoku
'パワーミル用に、指定した座標系データをエクスポート

Option Explicit
'**************
Const EXT = ".axis" '拡張子

Sub CATMain()
    'ドキュメントのチェック
    If Not CanExecute("PartDocument") Then Exit Sub
    
    'ドキュメントパス
    Dim Doc As PartDocument: Set Doc = CATIA.ActiveDocument
    Dim DocPath As String: DocPath = Doc.FullName
    If DocPath = Doc.Name Then
        MsgBox Doc.Name & " を一度保存してください"
        End
    End If
    Dim Paths As Variant: Paths = KCL.SplitPathName(DocPath)
          
    'エクスポートする座標系選択
    Dim Axis As AxisSystem
    Set Axis = KCL.SelectItem("座標系を選択して下さい", "AxisSystem")
    If KCL.IsNothing(Axis) Then Exit Sub

    '座標系データ取得
    Dim AxisCoord As Variant: AxisCoord = GetAxisCoord(Axis)
    
    'エクスポートファイルパス
    Dim ExpPath As String
    ExpPath = KCL.GetNewName(Paths(0) & "\" & AxisCoord(0) & EXT)
    
    'エクスポート
    Call KCL.WriteFile(ExpPath, Join(AxisCoord, ","))
    
    MsgBox "Done(" & AxisCoord(0) & ")"
End Sub


' *** Catia ***
'座標系データ取得
Private Function GetAxisCoord(ByVal Axis As AxisSystem) As Variant
    Dim Ax: Set Ax = Axis
    Dim Ori(2), VecX(2), VecY(2)
    Call Ax.GetOrigin(Ori)
    Call Ax.GetVectors(VecX, VecY)
    
    GetAxisCoord = Array(Axis.Name, _
                         Ori(0), Ori(1), Ori(2), _
                         VecX(0), VecX(1), VecX(2), _
                         VecY(0), VecY(1), VecY(2))
End Function

寂しいほどにすっきり。 Partファイルと同一フォルダに
(指定した座標系名).axis
のファイルが出来上がります。


続いて、PowerMill側のインポートするマクロ

//pm2018 macro
//Axis_import.mac ver0.0.1
//作業平面をインポート
//---------------------------------------------------------------------------------------------------
//ver0.0.1-完成
//---------------------------------------------------------------------------------------------------

Function Main( ){
	//ファイル選択
	string path = ''
	call SelFile($path)
	
	//ファイル読み込み
	string list axisInfo = {}
	call ReadFile($path, $axisInfo)
	
	//平面情報取得
	string list axis = {}
	call GetAxisInfo($axisInfo[0], $axis) 
	
	//平面作成
	string wpname = ''
	call CreateWorkPlane($axis, $wpname)
	
	message info  'Done ( ' + $wpname + ' )'
}

//作業平面作成
function CreateWorkPlane(string  list axis, output string out) {
	Call Msgoff()
	
	string wpname = remove_first($axis)
	real list v = {}
	foreach s in $axis {
		int dmy = add_last($v, real(s))
	}
	
	//作業平面作成・編集開始
	string newName = new_entity_name('Workplane')
	CREATE WORKPLANE ; EDITOR
	ACTIVATE WORKPLANE $newName
	MODE WORKPLANE_EDIT START $newName

	//リネーム
	call GetNewName('Workplane', $wpname, $out) 
	MODE WORKPLANE_EDIT NAME $out

	//原点
	MODE WORKPLANE_EDIT POSITION
	MODE POSITION WORKSPACE WORLD
	MODE POSITION PLANE XY
	MODE POSITION CARTESIAN X $v[0]
	MODE POSITION CARTESIAN Y $v[1]
	MODE POSITION CARTESIAN Z $v[2]
	POSITION APPLY
		
	//X軸
	MODE WORKPLANE_EDIT DIRECTION X
	MODE DIRECTION WORKSPACE WORLD
	MODE DIRECTION COMPONENT I $v[3]
	MODE DIRECTION COMPONENT J $v[4]
	MODE DIRECTION COMPONENT K $v[5]
	DIRECTION ACCEPT
		
	//Y軸
	MODE WORKPLANE_EDIT DIRECTION Y
	MODE DIRECTION WORKSPACE WORLD
	MODE DIRECTION COMPONENT I $v[6]
	MODE DIRECTION COMPONENT J $v[7]
	MODE DIRECTION COMPONENT K $v[8]
	DIRECTION ACCEPT
		
	//編集終了
	MODE WORKPLANE_EDIT FINISH ACCEPT

	Call Msgon()
}

//作業平面データ取得
function GetAxisInfo(string info, output string list out) {
	$out = tokens($info , ',')
	if size($out) != 10 {
		message info  '作業平面データの中身が異常です' + crlf + $info
		macro abort 
	}
}

//ファイルの選択
function SelFile(output string out) {
	string title = '作業平面データ選択'
	string filter = '作業平面データ(.Axis)|*.axis| ALL|*.*'
	
	//プロジェクトの一個上のパス取得 何か方法あるのかな?
	string s = project_pathname(0)
	int p1 = -1
	int p2 = 0
	while ($p2 > -1) {
		$p1 = position($s, '/', $p2)
		if $p1 < 0 {
			break
		}
		$p2 = $p1 + 1
	}
	string defpath = substring($s, 0, $p2 -1)
	
	$out = fileselect $title $filter $defpath
	if length($out) < 1 {
		macro abort 
	}
}

//ファイル読み込み
function ReadFile(string path, output string list out) {
	file open $path for read as f
	file read $out from f
	file close f
}

//新たな名前の取得
Function GetNewName(string folder , string name , output string out) {
	if entity_exists(entity($folder ,$name)) < 1 {
		$out = $name
	} else {
		$out = new_entity_name($folder ,$name)
	}
	return
}

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

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

プロジェクトファイルのあるファイルパスは関数があるので簡単なのですが、
その一つ上のファイルパスの取得方法が良くわからず、whileループで
グリグリ廻して取得してます。センス無いのですが他の方法が
思いつかなかったです。

動作は、二つになっただけで同じです。