邱 營,楊 林
(沈陽工業大學 機械工程學院,遼寧 沈陽 110870)
我們可以通過任意一組數學方程來表示任意一條三維空間曲線,從而獲得曲線上任意一點的數據,而制造過程中如電焊機器人的運動軌跡、機床加工過程中刀具的軌跡等所需要使用的空間曲線通常都是方程未知甚至無法求解的,獲取其插入點坐標及主法線、副法線、切線數據變得非常困難。
目前市面上常用的建模軟件如AutoCAD、SolidWorks均未提供直接提取模型曲線或實體模型棱邊曲線數據的功能,而相應的二次開發需要有編程基礎并耗費時間學習API命令。NX12.0提供了一種方法,即使用“點集”命令在目標曲線上插入需要數量的點,再使用“焊接向導”將點轉化為焊點后,使用“導出CSV”可以導出所選點的三維坐標,但此方法無法提取曲線上對應點處的主法線、副法線、切線數據。
Revit2017及后續版本提供了Dynamo這一插件,不僅可以實現曲線三維坐標的數據提取,而且可以提取曲線上對應點的主法線、副法線、切線數據。此插件不需要編程基礎就可以使用,其程序編寫采用類似思維導圖的線框連接模式,更便于理解。
本文使用Revit的插件Dynamo,采用插入點的方式實現可控精度的多條曲線數據的提取。
本實驗所使用的軟件平臺為Revit2017及Dynamo 2.0.2。在Revit2017中可以直接創建三維模型,如果使用其他建模軟件,可以將文件保存為sat(7.0版本以下)格式。在Revit2017插入選項欄中選擇“導入CAD”,文件類型選擇“.sat”。在“定位”中可以選擇“自動—原點到原點”,這樣Revit會自動使模型創建時的坐標系與Revit內置世界坐標系重合,獲取的曲線坐標就是創建模型時目標曲線的真實坐標。
在Revit2017中移動模型非常簡單,但移動模型后模型原點離開世界坐標系原點且模型原點沒有標識無法選取,多次移動模型后將很難確定模型原點位置,且在Revit中模型只能繞Z軸方向旋轉。所以如果需要獲取的曲線坐標對模型的位姿有要求,可以在建模時調整好位姿。
常用的曲線數據包括插入點、法線、切線、副法線坐標,模型導入Revit后,并沒有直接的命令獲取這些數據,需要在Revit內自帶的插件Dynamo中編寫可視化程序。
編制數據提取程序時的基本思路是:沿曲線以定弧長的方式插入一系列點,并以之為原點建立以該點處曲線的法線、切線、副法線為X、Y、Z軸的坐標系,再通過程序獲取已建立坐標系的原點及X、Y、Z軸的向量坐標,程序流程如圖1所示。
本次實驗需要獲取目標曲線的曲線代號、插入點代號、插入點坐標、法線坐標、切線坐標、副法線坐標。
2.1.1 建立坐標系
首先選取目標曲線。在Dynamo界面左側點擊“Select Edges”命令,右側空白界面將出現可視化的命令塊。此命令可以在Revit界面點選實體模型的一條邊或多條邊,選中所有目標曲線后在屬性欄上方點擊“完成”結束選取過程。
在選取閉合曲線時,系統會自動將閉合曲線分為兩段首尾相接的曲線,選擇曲線時需選中兩段,但無法手動決定起點與終點。
使用命令“Curve.CoordinateSystemAtParameter”在曲線上插入一坐標系。此命令的作用是在給定的一條或多條曲線、一個或多個參數位置輸出一個坐標系,坐標系原點為曲線上給定的對應參數位置,X、Y、Z軸分別為主法線、切線、副法線。此命令的輸入有兩個,分別為曲線和參數。曲線由“Select Edges”命令傳遞,而參數需要計算。

圖1 數據提取程序流程
大多數情況下,任意空間曲線的長度是未知的,直接給出插入點的數量可能會造成不同曲線上插入點的弧線距離差距過大。所以我們給定一個弧線距離的上限,在這里定義為精度,來控制插入點的數量。
使用“Code Block”命令塊,鍵入命令“0..1..#(Math.Floor(Curve.Length(曲線)/精度)+2);”,輸出一系列插入點參數,傳遞給“Curve.CoordinateSystemAtParameter”命令塊。其中“曲線”和“精度”為此命令塊的輸入,“曲線”由“Select Edges”命令傳遞,“精度”由另一個輸入數值的“Code Block”命令塊傳遞。此命令可以保證相鄰插入點間弧線距離最接近且不超過給定精度值。圖2為插入坐標系的數據。

圖2 插入坐標系數據
圖2中,每一個子列表代表一條曲線上的數據,每一項數據內容包括:
(1) Origin:坐標系原點坐標;
(2) XAxis:X軸坐標及長度(這里為主法線);
(3) YAxis:Y軸坐標及長度(這里為切線);
(4) ZAxis:Z軸坐標及長度(這里為副法線);
(5) XScaleFactor:X軸比例因子;
(6) YScaleFactor:Y軸比例因子;
(7) ZScaleFactor:Z軸比例因子。
這些數據中,X、Y、Z軸坐標向量都已經單位化,長度為1,比例因子同樣為1。
2.1.2 提取坐標系數據
插入坐標系原點坐標數據提取命令如圖3所示。其中“CoordinateSystem.Origin”用來輸出坐標系原點給“Point.X”,“Point.X”用來提取輸入點的X坐標,坐標系由“Curve.CoordinateSystemAtParameter”傳遞。Y、Z坐標數據提取方法與之相同。

圖3 插入坐標系原點坐標提取命令
法線坐標數據提取方法如圖4所示,“CoordinateSystem.XAxis”將給定坐標系的X軸輸出為向量,“Vector.AsPoint”輸出與給定向量相同坐標的點,“Point.X”提取給定點的X坐標。坐標系的Y軸、Z軸的坐標數據采用相同方法提取。

圖4 法線坐標數據提取
2.1.3 數據整合
現在我們已經獲得插入點、法線、切線、副法線坐標,數據以列表嵌套的方式存在,各個曲線的數據以子列表的形式互相獨立,使用“List.Flatten”命令展平這些子列表,使每一個列表中元素相對位置不變合成一個大列表,這樣在之后的列表之間的合并過程中才能以列表元素為單位運算而不是以子列表為單位。
曲線代號、插入點代號的生成使用如圖5所示的“Code Block”命令塊,輸入命令“List.Flatten((1..#曲線數..1)..#插入點數..0);List.Flatten(1..#插入點數..1);”,其中第一個輸入“曲線數”由“Select Edges”傳遞給命令“List.Count”后傳遞而來;第二個輸入“插入點數”由“0..1..#(Math.Floor(Curve.Length(曲線)/精度)+2);” 傳遞給“List.Count”后而來。注意,此“List.Count”需要點擊輸入位置的箭頭,勾選使用級別,選擇“@L2”才能獲取對應曲線插入點參數的個數。

圖5 曲線代號、插入點代號命令塊
此時我們獲得了曲線代號、插入點代號、插入點坐標、法線坐標、切線坐標、副法線坐標,直接輸出列表數據到Excel表中時,每個列表會占據一行,當插入點數量較大或曲線數量較多時不方便觀察,同樣不方便添加表頭。
使用“List.Combine”命令合并我們所需要的列表數據,使每一個小列表包含一個插入點的部分或全部數據。
使用“List.Combine”時,需點擊命令框中的加號添加輸入口至所需要的個數,而連接符“comb”需使用“List.Join”命令連接,同樣需點擊“List.Join”命令中的加號將輸入口增加至與“List.Combine”同樣數量,否則程序無法運行。“List.Join”命令的輸入不需要連接任何命令,如圖6所示, 合并后每一個子列表即是一個插入點的全部數據,按順序分別是曲線代號、插入點代號、插入點坐標、法線坐標、切線坐標、副法線坐標。同理,也可以將插入點、法線數據等分別合并。

圖6 某一插入點數據
輸出Excel表如圖7所示。

圖7 輸出Excel表
“File Path”可以選擇Excel表保存位置,“sheetName”決定工作表名稱,“startRow”、“startCol”分別代表數據在Excel表中的起始行、列,“overWrite”輸入“true”選擇在運算新的數據后覆蓋給定Excel表中的數據。
在將數據輸入到“data”輸入口之前我們使用命令“List.AddItemToFront”在數據最前端添加了一個表頭,表頭內容由使用“List.Combine”結合數據時列表的輸入順序決定。若不需要表頭,可以直接將數據輸入到“data”輸入口。
示例模型如圖8所示。 圖8模型在SolidWorks中創建后保存為“.sat”格式導入Revit中,啟用程序選擇圖中3條曲線,將數據分別合并后輸出,部分運算結果如圖9所示。圖9中,第1、2列均為曲線、插入點代號,第3、4、5列分別為插入點坐標、法線坐標。

圖8 示例模型

圖9 插入點、法線數據
實際運算結果表明,采用本文所述方法可以有效提取復雜空間曲線的插入點坐標及主法線、副法線、切線數據,精度可控,提取結果清晰。