【SU Ruby教程】圖元定義(5):表面

本篇教程繼續(xù)介紹另一種概念性圖元( conceptual entity )——表面。與上一篇教程相同,文中的示例可能會使用到本人自制的 Sel 模塊,在注釋中會解釋相應(yīng)語句的作用,測試時可以自行替換等價的表達。當然也可以直接參考此篇文章 [SU-2021-05],下載和使用此模塊。
圖元定義(5):表面
| 【本期目錄】 | |
| (1)表面的特性 ①表面的本質(zhì) ②表面的選擇 ③一些特性 | (3)表面的空間計算 ①點在表面上的投影 ②表面限制下落 |
(2)表面的創(chuàng)建 ①軟化邊線 ②通過曲線創(chuàng)建 ③PolygonMesh | (4)空間網(wǎng) Mesh ①Geom:: PolygonMesh ②Mesh 的獲取方式 ③Mesh 的用途 |
(1)表面的特性
①表面的本質(zhì)
作為概念性圖元,表面本身同樣不是繼承自 Drawingelement 類的實例,甚至也不像曲線那樣,擁有繼承自 Entity 類的 Curve 或 ArcCurve。這是因為表面的復雜程度和自由程度遠遠甚于曲線,很難用一個有序端點列表或者是諸如半徑、法向量等這些屬性來記錄,因此也就沒有必要單獨設(shè)計一個描述表面圖元的類了。
表面圖元實際上是多個相連的平面圖元的集合,這些平面圖元通過軟化的邊線相連。當點擊一個 Face 圖元時,如果這個平面能夠通過軟化邊線連接其他平面,那么選擇工具就會一并選擇符合條件的所有結(jié)果。因此點選一個平面時,實際上選區(qū)中包含多個平面,圖元信息中不顯示“N個平面”,而是直接顯示“表面”:

如果通過雙擊選擇表面,則會額外選擇表面的輪廓;如果是連續(xù)三次點擊,也就是“選擇所有與之相連的圖元”,此時就會看到如下的情況:

通過選區(qū)代碼工具 Sel.report 可以得知,此時的選區(qū)中有邊線和平面兩種圖元,而邊線中又可以分成軟化和非軟化的兩種圖元。其中軟化的邊線就是虛線表示的“隱藏”的邊線。
②表面的選擇
繪圖區(qū)自帶的選擇工具可以在用戶點選一個平面圖元時選中所有能通過軟化邊線相連的平面,如果是 ruby 腳本中已知一個平面圖元,也可以通過相同邏輯來獲得表面所包含的所有平面。這里提供一個實現(xiàn)方法:
module Selmodule Surfdef self.find_surface_by_face(face)surf=[face]len_old=0len=surf.lengthwhile len != len_old dosurf.to_a[len_old..-1].each{|f|f.edges.each{|e|if e.soft? thene.faces.each{|nf|surf<<nf unless surf.include?(nf)}end}}len_old=lenlen=surf.lengthendreturn surfendendend
注:這是選區(qū)代碼工具 Sel 中新增的一個方法,在已知一個平面圖元 f 時,可以通過 Sel<< Sel:: Surf. find_surface_by_face( f) 來選擇包含此圖元的表面。
③一些特性
由于表面其實是多個平面,因而很多對表面的操作屬于批量操作。例如在右鍵菜單中的“翻轉(zhuǎn)平面”,對于一個表面而言就是依次翻轉(zhuǎn)每一個平面圖元:

這與 sels. each( &:reverse!) 這樣的代碼是完全等價的。另外還有專門的統(tǒng)一平面方向的功能,這個相比于翻轉(zhuǎn)平面,功能實現(xiàn)上就稍微復雜,不過原理與上一部分的選擇的迭代是差不多的,此處就不舉例了。
不同于曲線,表面是一個比較寬松的空間概念。因此很多表面圖元可以被正確選擇,卻存在構(gòu)造上的缺陷。例如以下這種表面:

雖然點選其中一個平面圖元可以完整地獲取整個表面,但是其中卻存在多條未軟化的邊線,這樣不利于表面的呈現(xiàn),因此可以對這種表面進行修復:
module Selmodule Surfdef self.soft!Sel.sels.grep(Sel::F).each{|f|f.edges.each{|e|if e.faces.all?{|ff|Sel.sels.include?(ff)} and e.faces.length>1 thene.soft=trueend}}.lengthendendend
注:這也是選區(qū)代碼工具 Sel 中新增的一個方法,用于通過在選中的多個平面中盡可能地創(chuàng)建表面,具體的原理是枚舉每一條選中平面連接的邊線,如果與邊線相連的平面都在選區(qū)內(nèi),則軟化邊線。在此處恰好適用于有部分未軟化邊線表面的修復。
類似于以上方法,可以稍加修改將其改為設(shè)置整個表面為平滑光照表面,只需要將 .soft 改成 .smooth 即可。
(2)表面的創(chuàng)建
①軟化邊線
正如上一部分中修復表面內(nèi)未軟化邊線的方法,同樣可以使用 Sel:: Surf. soft! 來直接創(chuàng)建表面。這是最便捷的表面創(chuàng)建方法。當然這種方法基于已有的平面和邊線,如果是完全新建的圖元,則可以根據(jù)具體情況自行添加 .soft= true 的指令,完成復雜的表面設(shè)計。
不過通常來說這么做意義不大,表面的編輯很有可能使得不同的表面之間端點重合,而造成不必要的粘連,因此還是推薦在每一個表面圖元之上套上一個群組或是組件來隔離不同的表面,達到保護表面端點的作用。如果在群組內(nèi)創(chuàng)建表面,一般而言就不需要具體區(qū)分哪一些邊線需要軟化,就可以使用如下的代碼:
grp.definition.entities.grep(Sketchup::Edge).each{|edg|edg.soft=true}
②通過曲線創(chuàng)建
SketchUp 中更為常見的創(chuàng)建表面的方法其實來源于推拉工具和路徑跟隨。例如繪制一個圓形之后通過推拉,形成的圓柱的側(cè)面就是一個表面:
![]() | ![]() |
| 圓柱的側(cè)面有24個平面 | 半圓推拉的結(jié)果有12個平面 |
另外可以發(fā)現(xiàn),使用默認精度創(chuàng)建的圓與半圓推拉后的側(cè)面同樣也符合 24段 / 1圓周 的精度。而半圓推拉后曲面的邊緣是曲線端點的推拉結(jié)果。因此可以這樣理解:
推拉過程中,每一個端點都進行了平移,之后在新的高度上創(chuàng)建一個相同的圖形,并且依次連接每一對新舊端點,并依據(jù)端點之間的邊線創(chuàng)建平面。其中,新創(chuàng)建的邊線的 .soft? 屬性對標于所對應(yīng)新舊端點的 .curve_interior? .nil? 的值。
類似于推拉工具,路徑跟隨也是相似的原理,路徑中在曲線內(nèi)部的點對應(yīng)產(chǎn)生的平面邊線也是軟化的,不過在兩段路徑都是圓弧且端點處切線相同時,路徑跟隨不會創(chuàng)建非軟化的邊線,而推拉工具會,這是兩者在這一方面的一個微小區(qū)別。
③PolygonMesh
——此部分比較難以理解,可選擇跳過這一節(jié)。
在 Entities 類中有一個 .add_faces_from_mesh 方法,可以通過 Geom 模塊中一個很特殊的類型( PolygonMesh 類)來創(chuàng)建表面。Geom 模塊中定義的各種類幾乎已經(jīng)在教程的上一個部分“幾何與變換”中完全介紹了,此類是少有的例外。這個類型用來創(chuàng)建多面體,主要用來讀取和導出其他格式的空間數(shù)據(jù)文件。這個類的使用場景和具體構(gòu)造方法會在本篇的第四部分簡要介紹,而此處只需要關(guān)注段首提到的這個方法。
此方法有四個參數(shù),但只有第一個參數(shù)為必要參數(shù)。第一個參數(shù)需要提供一個 PolygonMesh 類實例,方法會根據(jù)此實例創(chuàng)建其所代表的所有邊線和平面。第二個參數(shù)具體規(guī)定邊線的顯隱、軟化和平滑狀態(tài),默認的參數(shù)為12,意為“全部軟化和平滑”。第3、4兩個參數(shù)分別是創(chuàng)建平面正面和背面的材質(zhì),默認為 nil,意為“默認材質(zhì)”。
其中第二個參數(shù)控制多面體的邊線是否軟化,因此可以通過此參數(shù)來創(chuàng)建多面體表面。這個參數(shù)使用二進制位來表示有關(guān)設(shè)置,共四位。第1位為1時表示“特定”的邊線隱藏,第2位為1是表示“特定”的邊線軟化,第3位為1時表示全部軟化(前面兩個設(shè)置此時無效),第4位為1時軟化的邊線同時也設(shè)置為平滑光照。從SU 2014版本開始,也可以使用常量來表示:
常量名/表達式 | 數(shù)值 | 效果 |
NO_SMOOTH_OR_HIDE | 0b0000 | 不隱藏邊線 |
HIDE_BASED_ON_INDEX | 0b0001 | 隱藏規(guī)定的邊線 |
SOFTEN_BASED_ON_INDEX | 0b0010 | 軟化規(guī)定的邊線 |
| 0b0011 | 與0b0010效果相同 | |
AUTO_SOFTEN | 0b0100 | 全部軟化 |
SMOOTH_SOFT_EDGES | 0b1000 | 軟化的邊線平滑光照, 與0b0000效果相同 |
HIDE_BASED_ON_INDEX | SMOOTH_SOFT_EDGES | 0b1001 | 與0b0001效果相同 |
SOFTEN_BASED_ON_INDEX | SMOOTH_SOFT_EDGES | 0b1010 | 軟化規(guī)定的邊線并平滑光照 |
| 0b1011 | 與0b1010效果相同 | |
AUTO_SOFTEN | SMOOTH_SOFT_EDGES | 0b1100 | 全部軟化并平滑光照 |
注:以上的常量名定義在 Geom 模塊 PolygonMesh 類之中,因此使用時需要額外作出限定,例如常量“ AUTO_SOFTEN ”實際應(yīng)寫成“ Geom:: PolygonMesh:: AUTO_SOFTEN ”。由于這些常數(shù)在各個二進制位中是正交的,因此多個常量的組合可以使用“位或”運算,也就是符號 |。
由于軟化邊線勢必會隱藏邊線,因此 0b**10 和 0b**11 并沒有區(qū)別;同樣地,當全部軟化時,軟化規(guī)定的邊線也被包含在內(nèi),因此 0b*100 和 0b*110、 0b*101 也沒有區(qū)別。

上文中的“規(guī)定的邊線”是在 PolygonMesh 實例創(chuàng)建過程中進行規(guī)定的,詳見本篇教程的第四部分。而如果使用 AUTO_SOFTEN 常量, .add_faces_from_mesh 方法創(chuàng)建的圖元也就是一個表面圖元。
注意,這種方法等同于調(diào)用多次 .add_face 方法,不會自動將平面打包成組,因此需要一些額外的工作來確保新圖形與原有模型之間沒有沖突。
(3)表面的空間計算
表面就是一系列的平面圖元,因此儲存一個表面圖元也只需要使用數(shù)組。如果使用選擇工具點選了一個表面,那么就可以用以下代碼將它儲存在數(shù)組變量中:
surf=Sketchup.active_model.selection.to_a# 或者在Sel腳本工具中這樣使用:surf=Sel.to_a
在遍歷“表面”中的每一個圖元時,如果不放心可以使用 .grep( Sketchup:: Face) 來進一步篩選平面圖元,但是通常這么做是沒有必要的,還會無端降低執(zhí)行效率。
表面常被用在地形建模、規(guī)則曲面和不規(guī)則形體中,以下就重點以第一種表面為例,提供一些與表面有關(guān)的空間計算方法。
①點在表面上的投影
地形建模通常重點關(guān)注Z軸方向上的點投影,因此這里提供一個垂直方向的投影到表面的方法以供參考。
def project_point_to_surface(point,surface)plumb_line=[point,[0,0,1]]pi=nilif surface.find{|f|pi=Geom.intersect_line_plane(plumb_line,f.plane)if pi.nil? then falseelsif f.classify_point(pi)==Sketchup::Face::PointOutside then falseelse true end}.nil? thenreturn(nil)elsereturn(pi)endend
此方法需要兩個參數(shù),第一個參數(shù) point 表示被投影的點,可以是長度為3的數(shù)組或者 Geom:: Point3d 類實例;第二個參數(shù) surface 表示表面,格式必須是只包含平面圖元的數(shù)組,否則就會報錯。方法的返回值是點 point 在表面 surface 上的投影,如果并不存在,則返回 nil。
其原理十分簡單,遍歷表面中的每一個平面圖元,分別過點 point 作一條鉛垂線 plumb_line,而后獲得其與平面圖元所在平面的交點 pi。判斷交點 pi 是否在平面圖元上,如果符合條件就返回這個交點 pi 的坐標,旋即退出整個計算過程。
這個方法僅限于在Z軸方向上不重復的表面,否則,Z軸上有多個鉛垂線交點時,就會返回第一個找到的交點,而忽略其他的。
②表面限制下落
經(jīng)常需要在地形表面上隨機覆蓋大量的組件,這時就需要使用這種限制下落方法,以達到所有組件都能正好下落在表面上。直接獲取單個組件或群組的底部中心點,然后沿用上一部分的方法計算其在表面上投影,隨后根據(jù)兩點創(chuàng)建變換對象就可以簡單地實現(xiàn)這個功能:
def falling_onto_surface(grp,surf)b=grp.boundsbc=b.center-Geom::Vector3d.new([0,0,b.depth])proj=project_point_to_surface(bc,surf)t=Geom::Transformation.new(proj-bc)grp.parent.entities.transform_entities(t,grp)end
使用一個簡單的迭代器就能批量調(diào)用這個下落方法:
list.each{|g|falling_onto_surface(g,surf)}以下是等距陣列組件在地形表面上的下落效果:


表面限定下落之后通過編輯組件以達到埋入的效果
(4)空間網(wǎng) Mesh
——此部分設(shè)計人員未必接觸得到,可選擇性地閱讀。
①Geom:: PolygonMesh
Geom 模塊中定義的類都是與空間關(guān)系有關(guān)的概念,而 PolygonMesh 也不例外,但是它與之前介紹的點、向量、范圍和變換等概念相比,更加復雜——是一系列點與其所組成的表面。它和“表面圖元”的關(guān)系就像 Geom:: Point3d 和 Sketchup:: Vertex 的關(guān)系一樣:前者是空間概念,可以脫離模型存在,不單獨保存在模型存檔中;后者是模型中明確的部件,能夠保存在文檔之中。
前文已經(jīng)介紹過 Entities 類中的 .add_faces_from_mesh 方法,其中的第一個參數(shù)便需要此類型的實例。嘗試以下代碼:
mesh = Geom::PolygonMesh.newoa=100ob=200ia=120ib=180mesh.add_point(Geom::Point3d.new(oa,oa,oa))mesh.add_point(Geom::Point3d.new(oa,oa,ob))mesh.add_point(Geom::Point3d.new(oa,ob,ob))mesh.add_point(Geom::Point3d.new(oa,ob,oa))mesh.add_point(Geom::Point3d.new(ob,oa,oa))mesh.add_point(Geom::Point3d.new(ob,oa,ob))mesh.add_point(Geom::Point3d.new(ob,ob,ob))mesh.add_point(Geom::Point3d.new(ob,ob,oa))mesh.add_point(Geom::Point3d.new(ia,ia,ia))mesh.add_point(Geom::Point3d.new(ia,ia,ib))mesh.add_point(Geom::Point3d.new(ia,ib,ib))mesh.add_point(Geom::Point3d.new(ia,ib,ia))mesh.add_point(Geom::Point3d.new(ib,ia,ia))mesh.add_point(Geom::Point3d.new(ib,ia,ib))mesh.add_point(Geom::Point3d.new(ib,ib,ib))mesh.add_point(Geom::Point3d.new(ib,ib,ia))mesh.add_polygon(4,3,2,1)mesh.add_polygon(5,6,7,8)mesh.add_polygon(1,2,6,5)mesh.add_polygon(2,3,7,6)mesh.add_polygon(3,4,8,7)mesh.add_polygon(1,5,8,4)mesh.add_polygon(12,11,10,9)mesh.add_polygon(13,14,15,16)mesh.add_polygon(9,10,14,13)mesh.add_polygon(10,11,15,14)mesh.add_polygon(11,12,16,15)mesh.add_polygon(9,13,16,12)ents=Sketchup.active_model.entitiesents.add_faces_from_mesh(mesh,Geom::PolygonMesh::NO_SMOOTH_OR_HIDE)
以上代碼,首先創(chuàng)建了一個新的實例,之后在實例中依次添加了16個頂點,再根據(jù)頂點序號創(chuàng)建12個平面。最終通過 .add_faces_from_mesh 方法將其繪制在當前模型中:
|
|
| 創(chuàng)建結(jié)果 | 剖切后的效果 |
使用 PolygonMesh 創(chuàng)建平面相當于將一次性創(chuàng)建所有它所包含的平面,對于上述的例子,也可以完全替換為 .add_face 方法的版本。不過,在已知點位的情況下,繪制簡單的立體圖形其實并不需要使用 PolygonMesh,它更適合用與復雜的立體圖形,更重要的是它支持調(diào)整不同平面之間的材質(zhì)坐標(UV坐標),不過材質(zhì)的內(nèi)容會在下一個大部分“圖元屬性”中再進行介紹,此處不會涉及。
此處關(guān)注一下 PolygonMesh 類的實例方法,包括以下三大類:(1)編輯頂點或平面;(2)查找頂點或平面點集;(3)材質(zhì)坐標。
編輯的方法包括之前例子中使用的 .add_point 和 .add_polygon 方法:前者根據(jù) Point3d 創(chuàng)建頂點,并且返回創(chuàng)建的頂點在 Mesh 中的編號;后者使用這些編號定位點坐標,創(chuàng)建 Mesh 中的各個平面,至少需要三個頂點編號,也支持更多共面的點。這里需要注意,不同于通常情況下數(shù)組的下標,這里頂點編號是從 1 開始的,編號 0 則作為異常值的返回結(jié)果。由于端點編號為非負整數(shù),因此在 .add_polygon 方法的參數(shù)中如果使用負數(shù)編號則表示此平面為隱藏邊線的平面,對應(yīng)上文中的“規(guī)定的邊線”。 .add_point 方法后跟兩個參數(shù),第一個參數(shù)為端點編號,第二個參數(shù)為 Point3d 類用于修改特定編號端點的位置。 .transform! 方法與其他空間類概念相同,后跟變換類參數(shù),用于變換整個空間網(wǎng)。
查找頂點的方法包括統(tǒng)計方法和具體的查找引用方法。 .count_points 和 .count_polygons 方法分別返回 Mesh 中定義了幾個頂點和幾個平面。 .normal_at 方法返回具體編號頂點所在處的法線,返回的是 Vector3d 類。 .point_at 方法返回具體編號端點的位置; .points 方法依編號順序返回所有的端點的坐標。需要特別指出, .points[0] 相當于 .point_at(1),兩者編號有1位的偏移。 .polygon_at 和 .polygons 方法與前兩個方法類似,不過返回的是組成平面的點編號數(shù)組,編號順序決定平面的朝向。 .polygon_points_at 方法在 .polygon_at 的基礎(chǔ)上返回每一個點的具體位置 。 .point_index 方法則根據(jù)具體位置查找對應(yīng)頂點的編號,未找到則返回 0。
以下兩組代碼組內(nèi)返回結(jié)果均相同:
# 返回頂點集mesh.points(1..mesh.count_points).map{|indx|mesh.point_at(indx)}# 返回編號為2的平面每一個點的空間位置mesh.polygon_points_at(2)mesh.polygon_at(2).map{|v|mesh.point_at(v)}mesh.polygons[1].map{|v|mesh.point_at(v)}mesh.polygons[1].map{|v|mesh.points[v-1]}
另外還有 .set_uv、 .uv_at 和 .uvs 三個方法,涉及材質(zhì)坐標,此處不展開。
②Mesh 的獲取方式
空間網(wǎng)有兩個獲取來源,一個是通過 PolygonMesh 類的構(gòu)造方法創(chuàng)建,即前文使用的 .new 方法;另一種則是通過 Face 類的 .mesh 方法獲得。
第一種方法會創(chuàng)建空白的 Mesh 對象,有兩個可省略的參數(shù),依次為端點數(shù)量和平面數(shù)量,這些參數(shù)并不會改變初始 Mesh 對象的定義,只會影響創(chuàng)建對象時預(yù)先加載的內(nèi)存大小。
第二種方法是基于模型中已有的平面圖元而創(chuàng)建的,并且創(chuàng)建的 Mesh 所有平面均為三角形,這對于移動不規(guī)則平面中的個別頂點非常有意義。
#打開組件內(nèi)的平面,只選擇一個平面圖元f=Sel.sels[0]#用f表示群組內(nèi)選中的平面ents=Sketchup.active_model.entitiesmtemp=f.mesh#按照相對坐標繪制:ents.add_faces_from_mesh(mtemp,0)#轉(zhuǎn)換為絕對坐標繪制:mtemp.transform!(Sel.sels[0].transformation)ents.add_faces_from_mesh(mtemp,0)
執(zhí)行以上代碼可以發(fā)現(xiàn),此方法為已存在的平面創(chuàng)建了一個特殊的 Mesh 結(jié)構(gòu),全部由三角形組成。需要注意,如果是群組或組件內(nèi)的平面,其坐標是相對于組件定義而言的,所以如果是組件內(nèi)的平面以此法在主模型中創(chuàng)建空間網(wǎng),就會不會和原平面重疊。
| ![]() |
相對坐標 | 根據(jù)群組屬性偏移后的坐標 |
另外, .mesh 方法之后有一個可省略的參數(shù),其數(shù)值含義也與二進制位有關(guān)。當?shù)?位為 1 時返回結(jié)果包含正面材質(zhì)坐標信息,當?shù)?位為 1 時包含背面材質(zhì)坐標信息,當?shù)?位為 1 時包含法線信息。此參數(shù)默認值為 0,表示返回的 Mesh 只儲存點位置信息。
三角網(wǎng)的好處在于,每一個頂點都沒有共面限制,可以任意移動位置,因此可以利用這一點,對已存在的平面進行變形,將其轉(zhuǎn)換成表面圖元。以下是一個示例:
def liftVertex(verx,face,height)raise ArgumentError("Param1 Must Be A Vertex.") unless verx.is_a?(Sketchup::Vertex)raise ArgumentError("Param2 Must Be A Face.") unless face.is_a?(Sketchup::Face)raise ArgumentError("Param3 Must Be Length or Any Other Numeric Data") unless height.respond_to?(:mm)raise ArgumentError("Vertex Must Be One of Face Vertices.") unless face.vertices.include?(verx)mesh=face.mesh#這里我只考慮了外環(huán)的情況circum=face.loops[0].edges.map(&:length).inject{|i,j|i+=j}vs=face.loops[0].vertices.to_av=vs.index(verx)cnt=vs.lengthls=[]for i in 0..cnt-1 doif i==v thenls<<0elselen=0toi= i>v ? v+cnt : vfor tmp in i..toi dolen+=face.loops[0].edges[tmp%cnt-1].lengthendif len>circum/2 then len=circum-len endls << lenendendls.each_with_index{|len,indx|ptr_index=mesh.point_index(vs[indx].position)posi=mesh.point_at(ptr_index)posi.transform!(Geom::Transformation.new([0,0,height*len/circum*2]))mesh.set_point(ptr_index,posi)}return meshend
此方法可以在給定一個平面、一個頂點和一個初始抬升高度的前提下,對平面進行沿周長方向遞減的抬升變形。可以在控制臺輸入如下代碼:
# sels,ents 定義如常face=sels[0]verx=sels[0].start# 將face和verx分別指向已存在的圖元mesh=liftVertex(verx,face,1000)ents.add_faces_from_mesh(mesh,12)# 12: Geom::PolygonMesh::AUTO_SOFTEN | Geom::PolygonMesh::SMOOTH_SOFT_EDGES
具體的效果如下:

③Mesh 的用途
空間網(wǎng)的使用場景并不是非常廣泛,官方給出的用途解釋是與 Sketchup:: Importer 一起使用,作為讀取其他格式文件的便捷工具,尤其是大部分三維模型文件都采取類似的邏輯構(gòu)建,因此在編寫轉(zhuǎn)化器時邏輯上會比較方便。
例如以下是一個簡單模型的 obj 文件(左),它是使用 Ruby 腳本通過 PolygonMesh 創(chuàng)建的(右),將此模型轉(zhuǎn)出成 obj 文件并與原代碼進行對比,可以發(fā)現(xiàn)基本完全能夠?qū)?yīng):

左側(cè) obj 格式中的 v 即定義點坐標,對應(yīng)右側(cè) ruby 的 .add_point;vt 是材質(zhì)坐標(UV坐標),vn 為法線數(shù)據(jù);f 則定義一個平面,對應(yīng) .add_polygon??臻g網(wǎng)有點坐標和平面點集就可以創(chuàng)建圖形,而法線和材質(zhì)信息是由 SketchUp 的默認設(shè)置確定的。而如果要導出為 obj 格式,文件格式需要這些數(shù)據(jù),在使用平面圖元的 .mesh 方法時,其后的參數(shù)就必須要包括法線和正反面UV坐標,也就是 7。
本篇教程原計劃是,簡要介紹表面這種“定義上地位尷尬又十分重要”的概念性圖元。考慮到篇幅較短,就決定把之前 Geom 模塊剩余的一個類 PolygonMesh 類一并介紹了。這兩個概念確實有很多相通之處,并且后者也可以用于創(chuàng)建各類表面,因此還算是比較巧合。其中的一些功能的代碼實現(xiàn)示例可能比較潦草,可讀性和功能穩(wěn)定性都或有缺憾,不過教程中的例子還是以啟發(fā)為主。
下一篇就進入最為繽紛絢麗的群組和組件了,這一部分教程之前在一些小靈感的作品中不斷地有出現(xiàn),可以先觀看這些篇目:
(完)
本文編號:SU-R14






