邱 營,楊 林
(沈陽工業(yè)大學(xué) 機(jī)械工程學(xué)院,遼寧 沈陽 110870)
我們可以通過任意一組數(shù)學(xué)方程來表示任意一條三維空間曲線,從而獲得曲線上任意一點(diǎn)的數(shù)據(jù),而制造過程中如電焊機(jī)器人的運(yùn)動(dòng)軌跡、機(jī)床加工過程中刀具的軌跡等所需要使用的空間曲線通常都是方程未知甚至無法求解的,獲取其插入點(diǎn)坐標(biāo)及主法線、副法線、切線數(shù)據(jù)變得非常困難。
目前市面上常用的建模軟件如AutoCAD、SolidWorks均未提供直接提取模型曲線或?qū)嶓w模型棱邊曲線數(shù)據(jù)的功能,而相應(yīng)的二次開發(fā)需要有編程基礎(chǔ)并耗費(fèi)時(shí)間學(xué)習(xí)API命令。NX12.0提供了一種方法,即使用“點(diǎn)集”命令在目標(biāo)曲線上插入需要數(shù)量的點(diǎn),再使用“焊接向?qū)А睂Ⅻc(diǎn)轉(zhuǎn)化為焊點(diǎn)后,使用“導(dǎo)出CSV”可以導(dǎo)出所選點(diǎn)的三維坐標(biāo),但此方法無法提取曲線上對(duì)應(yīng)點(diǎn)處的主法線、副法線、切線數(shù)據(jù)。
Revit2017及后續(xù)版本提供了Dynamo這一插件,不僅可以實(shí)現(xiàn)曲線三維坐標(biāo)的數(shù)據(jù)提取,而且可以提取曲線上對(duì)應(yīng)點(diǎn)的主法線、副法線、切線數(shù)據(jù)。此插件不需要編程基礎(chǔ)就可以使用,其程序編寫采用類似思維導(dǎo)圖的線框連接模式,更便于理解。
本文使用Revit的插件Dynamo,采用插入點(diǎn)的方式實(shí)現(xiàn)可控精度的多條曲線數(shù)據(jù)的提取。
本實(shí)驗(yàn)所使用的軟件平臺(tái)為Revit2017及Dynamo 2.0.2。在Revit2017中可以直接創(chuàng)建三維模型,如果使用其他建模軟件,可以將文件保存為sat(7.0版本以下)格式。在Revit2017插入選項(xiàng)欄中選擇“導(dǎo)入CAD”,文件類型選擇“.sat”。在“定位”中可以選擇“自動(dòng)—原點(diǎn)到原點(diǎn)”,這樣Revit會(huì)自動(dòng)使模型創(chuàng)建時(shí)的坐標(biāo)系與Revit內(nèi)置世界坐標(biāo)系重合,獲取的曲線坐標(biāo)就是創(chuàng)建模型時(shí)目標(biāo)曲線的真實(shí)坐標(biāo)。
在Revit2017中移動(dòng)模型非常簡單,但移動(dòng)模型后模型原點(diǎn)離開世界坐標(biāo)系原點(diǎn)且模型原點(diǎn)沒有標(biāo)識(shí)無法選取,多次移動(dòng)模型后將很難確定模型原點(diǎn)位置,且在Revit中模型只能繞Z軸方向旋轉(zhuǎn)。所以如果需要獲取的曲線坐標(biāo)對(duì)模型的位姿有要求,可以在建模時(shí)調(diào)整好位姿。
常用的曲線數(shù)據(jù)包括插入點(diǎn)、法線、切線、副法線坐標(biāo),模型導(dǎo)入Revit后,并沒有直接的命令獲取這些數(shù)據(jù),需要在Revit內(nèi)自帶的插件Dynamo中編寫可視化程序。
編制數(shù)據(jù)提取程序時(shí)的基本思路是:沿曲線以定弧長的方式插入一系列點(diǎn),并以之為原點(diǎn)建立以該點(diǎn)處曲線的法線、切線、副法線為X、Y、Z軸的坐標(biāo)系,再通過程序獲取已建立坐標(biāo)系的原點(diǎn)及X、Y、Z軸的向量坐標(biāo),程序流程如圖1所示。
本次實(shí)驗(yàn)需要獲取目標(biāo)曲線的曲線代號(hào)、插入點(diǎn)代號(hào)、插入點(diǎn)坐標(biāo)、法線坐標(biāo)、切線坐標(biāo)、副法線坐標(biāo)。
2.1.1 建立坐標(biāo)系
首先選取目標(biāo)曲線。在Dynamo界面左側(cè)點(diǎn)擊“Select Edges”命令,右側(cè)空白界面將出現(xiàn)可視化的命令塊。此命令可以在Revit界面點(diǎn)選實(shí)體模型的一條邊或多條邊,選中所有目標(biāo)曲線后在屬性欄上方點(diǎn)擊“完成”結(jié)束選取過程。
在選取閉合曲線時(shí),系統(tǒng)會(huì)自動(dòng)將閉合曲線分為兩段首尾相接的曲線,選擇曲線時(shí)需選中兩段,但無法手動(dòng)決定起點(diǎn)與終點(diǎn)。
使用命令“Curve.CoordinateSystemAtParameter”在曲線上插入一坐標(biāo)系。此命令的作用是在給定的一條或多條曲線、一個(gè)或多個(gè)參數(shù)位置輸出一個(gè)坐標(biāo)系,坐標(biāo)系原點(diǎn)為曲線上給定的對(duì)應(yīng)參數(shù)位置,X、Y、Z軸分別為主法線、切線、副法線。此命令的輸入有兩個(gè),分別為曲線和參數(shù)。曲線由“Select Edges”命令傳遞,而參數(shù)需要計(jì)算。
圖1 數(shù)據(jù)提取程序流程
大多數(shù)情況下,任意空間曲線的長度是未知的,直接給出插入點(diǎn)的數(shù)量可能會(huì)造成不同曲線上插入點(diǎn)的弧線距離差距過大。所以我們給定一個(gè)弧線距離的上限,在這里定義為精度,來控制插入點(diǎn)的數(shù)量。
使用“Code Block”命令塊,鍵入命令“0..1..#(Math.Floor(Curve.Length(曲線)/精度)+2);”,輸出一系列插入點(diǎn)參數(shù),傳遞給“Curve.CoordinateSystemAtParameter”命令塊。其中“曲線”和“精度”為此命令塊的輸入,“曲線”由“Select Edges”命令傳遞,“精度”由另一個(gè)輸入數(shù)值的“Code Block”命令塊傳遞。此命令可以保證相鄰插入點(diǎn)間弧線距離最接近且不超過給定精度值。圖2為插入坐標(biāo)系的數(shù)據(jù)。
圖2 插入坐標(biāo)系數(shù)據(jù)
圖2中,每一個(gè)子列表代表一條曲線上的數(shù)據(jù),每一項(xiàng)數(shù)據(jù)內(nèi)容包括:
(1) Origin:坐標(biāo)系原點(diǎn)坐標(biāo);
(2) XAxis:X軸坐標(biāo)及長度(這里為主法線);
(3) YAxis:Y軸坐標(biāo)及長度(這里為切線);
(4) ZAxis:Z軸坐標(biāo)及長度(這里為副法線);
(5) XScaleFactor:X軸比例因子;
(6) YScaleFactor:Y軸比例因子;
(7) ZScaleFactor:Z軸比例因子。
這些數(shù)據(jù)中,X、Y、Z軸坐標(biāo)向量都已經(jīng)單位化,長度為1,比例因子同樣為1。
2.1.2 提取坐標(biāo)系數(shù)據(jù)
插入坐標(biāo)系原點(diǎn)坐標(biāo)數(shù)據(jù)提取命令如圖3所示。其中“CoordinateSystem.Origin”用來輸出坐標(biāo)系原點(diǎn)給“Point.X”,“Point.X”用來提取輸入點(diǎn)的X坐標(biāo),坐標(biāo)系由“Curve.CoordinateSystemAtParameter”傳遞。Y、Z坐標(biāo)數(shù)據(jù)提取方法與之相同。
圖3 插入坐標(biāo)系原點(diǎn)坐標(biāo)提取命令
法線坐標(biāo)數(shù)據(jù)提取方法如圖4所示,“CoordinateSystem.XAxis”將給定坐標(biāo)系的X軸輸出為向量,“Vector.AsPoint”輸出與給定向量相同坐標(biāo)的點(diǎn),“Point.X”提取給定點(diǎn)的X坐標(biāo)。坐標(biāo)系的Y軸、Z軸的坐標(biāo)數(shù)據(jù)采用相同方法提取。
圖4 法線坐標(biāo)數(shù)據(jù)提取
2.1.3 數(shù)據(jù)整合
現(xiàn)在我們已經(jīng)獲得插入點(diǎn)、法線、切線、副法線坐標(biāo),數(shù)據(jù)以列表嵌套的方式存在,各個(gè)曲線的數(shù)據(jù)以子列表的形式互相獨(dú)立,使用“List.Flatten”命令展平這些子列表,使每一個(gè)列表中元素相對(duì)位置不變合成一個(gè)大列表,這樣在之后的列表之間的合并過程中才能以列表元素為單位運(yùn)算而不是以子列表為單位。
曲線代號(hào)、插入點(diǎn)代號(hào)的生成使用如圖5所示的“Code Block”命令塊,輸入命令“List.Flatten((1..#曲線數(shù)..1)..#插入點(diǎn)數(shù)..0);List.Flatten(1..#插入點(diǎn)數(shù)..1);”,其中第一個(gè)輸入“曲線數(shù)”由“Select Edges”傳遞給命令“List.Count”后傳遞而來;第二個(gè)輸入“插入點(diǎn)數(shù)”由“0..1..#(Math.Floor(Curve.Length(曲線)/精度)+2);” 傳遞給“List.Count”后而來。注意,此“List.Count”需要點(diǎn)擊輸入位置的箭頭,勾選使用級(jí)別,選擇“@L2”才能獲取對(duì)應(yīng)曲線插入點(diǎn)參數(shù)的個(gè)數(shù)。
圖5 曲線代號(hào)、插入點(diǎn)代號(hào)命令塊
此時(shí)我們獲得了曲線代號(hào)、插入點(diǎn)代號(hào)、插入點(diǎn)坐標(biāo)、法線坐標(biāo)、切線坐標(biāo)、副法線坐標(biāo),直接輸出列表數(shù)據(jù)到Excel表中時(shí),每個(gè)列表會(huì)占據(jù)一行,當(dāng)插入點(diǎn)數(shù)量較大或曲線數(shù)量較多時(shí)不方便觀察,同樣不方便添加表頭。
使用“List.Combine”命令合并我們所需要的列表數(shù)據(jù),使每一個(gè)小列表包含一個(gè)插入點(diǎn)的部分或全部數(shù)據(jù)。
使用“List.Combine”時(shí),需點(diǎn)擊命令框中的加號(hào)添加輸入口至所需要的個(gè)數(shù),而連接符“comb”需使用“List.Join”命令連接,同樣需點(diǎn)擊“List.Join”命令中的加號(hào)將輸入口增加至與“List.Combine”同樣數(shù)量,否則程序無法運(yùn)行?!癓ist.Join”命令的輸入不需要連接任何命令,如圖6所示, 合并后每一個(gè)子列表即是一個(gè)插入點(diǎn)的全部數(shù)據(jù),按順序分別是曲線代號(hào)、插入點(diǎn)代號(hào)、插入點(diǎn)坐標(biāo)、法線坐標(biāo)、切線坐標(biāo)、副法線坐標(biāo)。同理,也可以將插入點(diǎn)、法線數(shù)據(jù)等分別合并。
圖6 某一插入點(diǎn)數(shù)據(jù)
輸出Excel表如圖7所示。
圖7 輸出Excel表
“File Path”可以選擇Excel表保存位置,“sheetName”決定工作表名稱,“startRow”、“startCol”分別代表數(shù)據(jù)在Excel表中的起始行、列,“overWrite”輸入“true”選擇在運(yùn)算新的數(shù)據(jù)后覆蓋給定Excel表中的數(shù)據(jù)。
在將數(shù)據(jù)輸入到“data”輸入口之前我們使用命令“List.AddItemToFront”在數(shù)據(jù)最前端添加了一個(gè)表頭,表頭內(nèi)容由使用“List.Combine”結(jié)合數(shù)據(jù)時(shí)列表的輸入順序決定。若不需要表頭,可以直接將數(shù)據(jù)輸入到“data”輸入口。
示例模型如圖8所示。 圖8模型在SolidWorks中創(chuàng)建后保存為“.sat”格式導(dǎo)入Revit中,啟用程序選擇圖中3條曲線,將數(shù)據(jù)分別合并后輸出,部分運(yùn)算結(jié)果如圖9所示。圖9中,第1、2列均為曲線、插入點(diǎn)代號(hào),第3、4、5列分別為插入點(diǎn)坐標(biāo)、法線坐標(biāo)。
圖8 示例模型
圖9 插入點(diǎn)、法線數(shù)據(jù)
實(shí)際運(yùn)算結(jié)果表明,采用本文所述方法可以有效提取復(fù)雜空間曲線的插入點(diǎn)坐標(biāo)及主法線、副法線、切線數(shù)據(jù),精度可控,提取結(jié)果清晰。