1. 程式人生 > >在OpenCASCAD腳本中拾取定位

在OpenCASCAD腳本中拾取定位

command 得到 entity shade 不知道 查詢 模擬 sha markdown

DRAWEXE系OpenCASCADE中的腳本支撐項目,通過對TCL腳本語言的擴展可以便捷使用OpenCASCADE。

腳本顯示方面的命令分兩種:一種在組名DRAW Graphic Commands內,啟用DRAWEXE之後立即加載可用,只能顯示線框,不能渲染面;另外一種在組名ZeViewer內,是對AIS Viewer的擴展,可以線框或Shaded渲染。前一種太簡單,這裏主要討論後一種,在窗口之內按Ctrl+鼠標左鍵,縮放,Ctrl+鼠標中鍵,平移,Ctrl+鼠標右鍵,旋轉,這樣對於交互顯示來說就很重要了。

問題來源

在瀏覽OpenCASCADE腳本命令實現的時候,可以發現除explode之外,還有nexplode命令。看註釋相比explode,nexplode命令可以穩定命名爆炸出來的對象,該命令實現內部在計算質心之類的東西,然後通過質心的排序依次命名訪問TopoDS_Shape下邊的面、邊、頂點之類的對象,而explode僅僅是按按遍歷次序來的。

我感覺這種模式也不好用,能一下子就明白面、邊、頂點質心之類的屬性排序出來是怎樣的嗎,不能吧。比對ACIS裏對Scheme語言的擴展,采用拾取定位清晰很多,不過如果還依靠真實地在窗口裏邊鼠標點擊選擇,有點失去腳本便捷的優勢,如果能夠實際鼠標點擊,拾取到所需要的,那就更好了,這個在OCCT裏邊也可以做到嗎?

如何不通過實際鼠標點擊,拾取到給定邊緣

例舉以下語句:

box b1 0 0 -20 8 40 40
vselmode b1 2 1
set str1 [vconvert 8 40 0 window]
scan $str1 "Window Xp,Yp: %d %d" a b
vselect $a $b

vnbselected
vpickselected e2

上面vselmode語句是定義拾取邊緣,vselect則是模擬鼠標點擊拾取的過程,vconvert則是將三維點轉換成為當前窗口像素點,這樣才知道在哪個位置發起拾取,vnbselected返回拾取的數量,vpickselected會捆綁拾取的對象至名字e2。

TCL腳本使用感受

最後說的自己使用TCL腳本的感受,TCL腳本對變量類型的擴充性不強,至少在OCCT裏是這樣,變量就是數量型,數組型,字符串型,列表型,字典型;後面的列表和字典也挺字符串的,OCCT是通過捆綁命名與Draw_Drawable3D派生類實例來對類型進行擴展,比如pi對應的是Draw_Number,賦值,所以得通過命令dval pi才能得到pi的值,並不能直接賦予pi。

再一個就是Tcl只支持參數的傳值調用,不支持指針和引用類型,看教材的介紹要通過進行多一輪的替換,來模擬出引用的行為。有個專門的命令upvar命令。

然後,在實際使用中,我曾經想將explode爆炸出來的對象,搞成一個列表,再編寫一個find_edge之類的過程,通過查詢邊緣的頂點與給定值比較精確定位邊緣,搞一個通用的過程函數方便使用,但是傳過去的邊緣數組,在foreach循環裏無法依據名字返回捆綁的邊緣,無法使用,百絲不得其解呀,後面再去翻TCL腳本語言教程,看到傳值,估計是這個原因吧,但是還是得不到理想的結果呀,而且不知道為什麽whatis $edge可以得到邊緣,再explode $edge v就不行了。

相比之下,ACIS的Scheme語言就好得多,(entity:edges s1)返回一個列表,存儲s1裏邊的所有邊緣,真的是邊緣類型,OpenCASCADE的TCL裏邊用set elist [list {*}[explode b1 e]]語句也可以將b1裏邊的邊緣打包成為列表,但是要註意的是elist列表裏邊的東西全是字符串的名字哦,它們不是邊緣,只是在OCCT裏邊該名字捆綁了一個Draw_Drawable3D派生類實例,你可以對應過來用。

除此之外,Scheme語言對命令命名還支持‘:‘、‘?‘這些,可以較好對命令明確地分組,也容易理解些(比如edge?就是查詢是否為邊緣類型)。了解到這個我當時覺得開了眼界,只可惜ACIS是不開源的。

在OpenCASCAD腳本中拾取定位