54
Chương IV SketchUp Scripting by [email protected] 54 Các phép bi ến đổi hình học thêm đối tượng hình học

Chuong 4,5 va 6 Pluin cho SketchUp

Embed Size (px)

DESCRIPTION

Huong dan tao pugin cho SketcjUp

Citation preview

Page 1: Chuong 4,5 va 6 Pluin cho SketchUp

Chương IV SketchUp Scripting by [email protected]

54

Các phép biến đổi hình học và

thêm đối tượng hình học

Page 2: Chuong 4,5 va 6 Pluin cho SketchUp

Chương IV SketchUp Scripting by [email protected]

55

Một trong những điểm mạnh của SketchUp là một khi bạn đã xây dựng được một mô hình thì bạn có thể chỉnh sửa các đối tượng hình học của nó như di chuyển một con đường, scale một cửa sổ, hoặc xoay một cái cột hiên nhà. Để thực hiện các hoạt động này trong mã hóa, bạn phải tạo một đối tượng biến đổi để định rõ cách thức mà một đối tượng hoặc nhiều đối tượng hình học sẽ được thay đổi. Có ba loại cơ bản của phép biến đổi và phần đầu của chương này trình bày chi tiết từng loại.

Phần thứ hai của chương này trình bày việc bổ sung các thành phần khác để bạn có thể thêm vào một dự án SketchUp. Chương trước cho thấy cách thức làm thế nào để thêm được đoạn thẳng và bề mặt, nhưng chương này đi xa hơn nữa và giải thích cách sử dụng các đối tượng văn bản, đối tượng hình ảnh, và các đối tượng lưới đa giác. Tất cả chúng sẽ được bổ sung thêm vào một dự án SketchUp chứ không phải chỉ có đoạn thẳng và bề mặt đơn giản như ở chương trước.

4.1 Các phép biến đổi. Ngôi nhà trong hình sau có một vấn đề. Cửa đi và cửa sổ thì nhìn khá ổn, nhưng mái cần

phải thay đổi. Cụ thể, đoạn thẳng nằm ở giữa mái cần phải được nâng lên để các mái nhà có thể có hình dạng mái dốc quen thuộc như mô tả ở hình bên phải.

Nếu như bạn đang sử dụng giao diện đồ họa của SketchUp thì tất cả mọi việc bạn cần

phải làm là chọn công cụ Move từ thành công cụ, kích chọn vào đoạn thẳng nằm giữa mái và di chuyển con chuột đi thẳng lên trên. Nhưng làm thế nào để bạn có thể làm được những điều tương tự như vậy ở trong mã hóa? Cho đến nay, chúng ta đã biết cách tạo ra đoạn thẳng và bề mặt, nhưng chưa hề biết cách làm thế nào để di chuyển các đối tượng này sau khi chúng đã được tạo ra.

Lớp Entities cung cấp phương thức transform_entities cho chính mục đích này. Phương thức này chấp nhận hai tham số: một đối tượng Entity hoặc một mảng các đối tượng Entity và một đối tượng biến đổi. Ví dụ, nếu đối tượng Edge đại diện cho đoạn thẳng giữa mái có tên là roof_line, các dòng mã sau nâng nó lên 5 đơn vị đo cùng chiều với trục z dương so với vị trí ban đầu:

ents = Sketchup.active_model.entities

tr = Geom::Transformation.translation [0, 0, 5]

ents.transform_entities tr, roof_line

Trong dòng mã thứ hai, tiếp đầu ngữ Geom :: là cần thiết bởi vì lớp biến đổi- Transformation được chứa đựng trong các mô-đun Geom. Chương 8 sẽ giải thích các mô-đun và cách thức chúng làm việc.

Mục tiêu của phần này là để giải thích làm thế nào để tạo các đối tượng như tr và sử dụng chúng trong mã hóa. Trong ví dụ này, tr là một đối tượng biến đổi dùng để di chuyển roof_line tới một vị trí khác. Một đối tượng biến đổi là sự thể hiện chuyển động của một đối

Page 3: Chuong 4,5 va 6 Pluin cho SketchUp

Chương IV SketchUp Scripting by [email protected]

56

tượng Entity và sự chuyển động này có thể được đặt vào trong một hoặc nhiều các trường hợp sau :

translation – di chuyển một đối tượng với một khoảng cách xác định theo một chiều nhất định. Trong SketchUp công cụ Move thực hiện việc di chuyển.

rotation – di chuyển một đối tượng thông qua một góc được đưa ra, được đo từ một gốc. Trong SketchUp, công cụ Rotate thực hiện công việc này .

scaling – tăng hoặc giảm kích thước của một đối tượng dọc theo khoảng cách của nó từ gốc. Trong SketchUp, công cụ Scale thực hiện công việc này .

Lớp Transformation cung cấp nhiều phương thức để tạo ra các đối tượng biến đổi mới và thường là có ít nhất hai cách để tạo ra đối tượng này. Nói chung, đối tượng biến đổi có thể được tạo ra bằng cách gọi ra phương thức new hoặc bằng cách gọi ra một phương thức tạo ra một loại đối tượng biến đổi cụ thể nào đó.

Chương này giải thích làm thế nào để tạo và sử dụng các đối tượng biến đổi, nhưng bỏ qua nền tảng toán học. Lý thuyết toán học thường là không cần thiết cho việc mã hóa, nhưng nó trở nên quan trọng khi bạn cần phải gỡ lỗi các hoạt động của phép biến đổi hoặc tạo ra chúng trong quá trình thực thi một kịch bản. Nền tảng toán học của vectơ, ma trận và chuyển đổi sẽ được trình bày trong Phụ lục B: Hình học nâng cao.

4.1.1 Phép tịnh tiến-translation. Một dịch chuyển tịch tiến trong SketchUp sẽ di chuyển một đối tượng Edge với một

khoảng cách xác định theo một chiều nhất định. Để xác định một dịch chuyển tịnh tiến trong không gian ba chiều, bạn cần phải tạo một mảng gồm ba phần tử. Mỗi một phần tử thuộc mảng này sẽ được thêm vào một phần tử tương ứng trong mảng tọa độ của Entity để tạo ra một mảng bao gồm các tọa độ mới cho Entity đó.

Ví dụ, để di chuyển một hình dạng từ vị trí [ 1, 2, 3] tới [ 3 , 2, 1 ], bạn dịch chuyển tịnh tiến nó bằng cách sử dụng mảng [ 2 , 0 , -2 ]. Lựa chọn mảng này là do [ 1+2, 2+0, 3 - 2 ] = [ 3 , 2, 1 ], đây là vị trí kết thúc mong muốn. Vì mảng có chứa ba phần tử xác định chiều và khoảng cách nên nó được gọi là một vector dịch chuyển tịnh tiến.

API SketchUp cung cấp ba cách sau để tạo ra một đối tượng biến đổi-Transformation nhằm thực hiện dịch chuyển tịch tiến:

1. Gọi ra Geom::Transformation.new với một vector dịch chuyển tịch tiến

2. Gọi ra Geom::Transformation.translation với một vector dịch chuyển tịch tiến

3. Chỉ sử dụng một vector dịch chuyển tịnh tiến .

Đoạn mã trong tập tin kịch bản sau cho thấy cách thức hoạt động của từng phương thức một. Nó sẽ tạo ra một bề mặt hình vuông và dịch chuyển tịnh tiến nó ba lần. Đầu tiên, nó dịch chuyển tịnh tiến bề mặt này 4 đơn vị đo theo chiều dương của trục x ( nghĩa là dịch chuyển dọc theo trục x dương và vị trí mới cách vị trí cũ 4 đơn vị đo), sau đó là 6 đơn vị theo chiều dương của trục y và cuối cùng là 3 đơn vị theo chiều âm của trục x.

translate.rb

# Create the face

ents = Sketchup.active_model.entities

Page 4: Chuong 4,5 va 6 Pluin cho SketchUp

Chương IV SketchUp Scripting by [email protected]

57

tran_face = ents.add_face [-1, -1, 0], [-1, 1, 0],[1, 1, 0], [1, -1, 0]

# Translate four units in the +x direction

t = Geom::Transformation.new [4, 0, 0] ents.transform_entities t, tran_face

# Translate six units in the +y direction

t = Geom::Transformation.translation [0, 6, 0] ents.transform_entities t, tran_face

# Translate three units in the -x direction ents.transform_entities [-3, 0, 0], tran_face

Sơ đồ sau cho thấy kết quả lần lượt thực hiện từng hoạt động dịch chuyển tịnh tiến. Lưu

ý rằng bạn có thể thay thế ba vectơ dịch chuyển tịnh tiến trên bằng một vector dịch chuyển tịnh tiến duy nhất: [ 1, 6, 0] để bề mặt ở vị trí ban đầu khi tạo ra được dịch chuyển tới vị trí cuối cùng.

Việc sử dụng dòng lệnh cuối cùng rõ ràng là không tạo ra một đối tượng biến đổi, nhưng lại sử dụng vector dịch chuyển tịnh tiến. Đây tuy là cách dễ nhất để thực hiện dịch chuyển tịnh tiến nhưng nó có một nhược điểm: bạn phải viết lại vector dịch chuyển tịnh tiến mỗi khi bạn muốn thực hiện dịch chuyển. Bằng cách tạo ra một đối tượng biến đổi, bạn có thể thực hiện dịch chuyển tịnh tiến nhiều lần với vector đó mà không cần phải viết lại.

4.1.2 Phép xoay-Rotation. Để xoay một hình, bạn cần phải xác định ba phần thông tin: Điểm gốc để phép xoay thực

hiện (một điểm), trục xoay (một vector) và góc xoay (một giá trị thập phân). Nếu bạn đã từng vẽ một cung tròn bằng một cái compa, bạn có thể tưởng tượng điểm gốc của phép xoay chính là tâm của cung ( hoặc là điểm mà chân trụ của compa cắm xuống) và trục quay chính là chân trụ của compa và góc xoay chính là góc chắn ở tâm của cung tròn. Hai tham số đầu tiên ( điểm gốc và trục xoay) có thể được xác định là các mảng có ba phần tử. Tham số cuối cùng (góc xoay) là giá trị của góc xoay với đơn vị đo góc là radian.

Có hai cách tạo ra một đối tượng biến đổi để thực hiện phép xoay:

[4, 0, 0]

[0, 6, 0]

[-3, 0, 0]

Page 5: Chuong 4,5 va 6 Pluin cho SketchUp

Chương IV SketchUp Scripting by [email protected]

58

1. Gọi ra Geom::Transformation.new với điểm gốc, trục xoay và góc xoay.

2. Gọi ra Geom::Transformation.rotation với điểm gốc, trục xoay và góc xoay.

Ví dụ, các đối tượng biến đổi sau dùng để xoay một đối tượng Entity một góc 30 ° quanh trục xoay z với điểm gốc tại gốc tọa độ [ 0, 0, 0].

tr = Geom::Transformation.new [0, 0, 0], [0, 0, 1], 30.degrees

hoặc tr = Geom::Transformation.rotation [0, 0, 0],[0, 0, 1],30.degrees

Nếu giá trị góc xoay là dương, đối tượng Entity xoay ngược chiều kim đồng. Có nghĩa là, nếu bạn từ trên trục xoay nhìn xuống mặt phẳng xoay ( mặt phẳng đi qua điểm gốc và vuông góc với trục xoay ) thì đối tượng Entity sẽ di chuyển sang vị trí mới theo một chiều ngược chiều kim đồng so với vị trí ban đầu. Hình sau, nhìn xuống từ trục z xuống mặt phẳng xoy và thấy cách thức mà đối tượng sẽ xoay với một trong các đối tượng biến đổi tạo ra ở trên :

Nếu giá trị góc xoay là ấm, đối tượng Entity xoay cùng chiều kim đồng.

Đối với các phép xoay phức tạp, bạn có thể xác định các thực hiện xoay quanh ba trục tọa độ của nó bởi các phương thức rotx , roty và Rotz. Ví dụ với đối tượng biến đổi tr được tạo ra ở trên thì điều này được thể hiện như sau:

tr.rotx

0

tr.roty

0

tr.rotz

30

Những góc xoay được trả về với đơn vị đo góc là độ. Bạn có thể thay đổi sang giá trị có đơn vị đo góc là radia bằng cách thêm một phương thức chuyển đổi đơn vị như tr.rotz.degrees.

Đoạn mã trong tập tin kịch bản sau sẽ tạo ra một bề mặt hình vuông, sau đó xoay bề mặt đó một góc 600 quanh trục z. theo chiều kim đồng hồ với điểm gốc là [0, 0, 0].

Rotation.rb

# Create the face

Page 6: Chuong 4,5 va 6 Pluin cho SketchUp

Chương IV SketchUp Scripting by [email protected]

59

ents = Sketchup.active_model.entities

rota_face = ents.add_face [3, -1, 0], [5, -1, 0],[5, 1, 0], [3, 1, 0]

# Rotation about z direction, origin, 60 degree

tr = Geom::Transformation.new [0, 0, 0], [0, 0, 1], 60.degrees

ents.transform_entities tr, rota_face

Sơ đồ sau cho thấy kết quả được thực hiện.

4.1.3 Phép qui mô-Scale. Trong SketchUp, công cụ Scale dùng để thay đổi kích thước của một hình và vị trí của

nó lại không thay đổi. Nhưng khi bạn tạo một đối tượng biến đổi scale thì việc scale sẽ ảnh hưởng đến cả kích thước của hình và vị trí tương đối của nó so với một điểm gốc. Theo mặc định thì điểm gốc là gốc tọa độ [ 0, 0, 0]. Ví dụ, các dòng mã sau giảm kích thước của hình Shape để nó chỉ bằng một nửa kích thước ban đầu và di chuyển nó tới vị trí nằm giữa vị trí ban đầu và gốc tọa độ [ 0, 0, 0]. Vị trí của hình là nói đến vị trí điểm trọng tâm của hình.

ents = Sketchup.active_model.entities

t = Geom::Transformation.new 0.5

ents.transform_entities t, shape

Một đối tượng biến đổi tương tự có thể được tạo ra với phương thức scaling của lớp Transformation. Các dòng mã sau đây cho ra kết quả tương tự như ví dụ trước :

ents = Sketchup.active_model.entities

t = Geom::Transformation.scaling 0.5

ents.transform_entities t, shape

Đối số 0.5 được gọi là tỉ lệ scale. Nếu gọi khoảng cách từ trọng tâm của hình ban đầu đến gốc tọa độ là L và tỉ lệ scale là n

thì: - Nếu n > 1: hình ban đầu sẽ được phóng to lên n lần và khoảng cách từ điểm trọng tâm

của hình sau khi được phóng to và di chuyển tới vị trí mới tới gốc tọa độ sẽ là L2 = n*L. Là hình bên phải ở dưới đây.

600

Page 7: Chuong 4,5 va 6 Pluin cho SketchUp

Chương IV SketchUp Scripting by [email protected]

60

- Nếu n < 1: hình ban đầu sẽ được thu nhỏ n lần và khoảng cách từ điểm trọng tâm của hình sau khi được thu nhỏ và di chuyển tới vị trí mới tới gốc tọa độ sẽ là L1 = L/n. Là hình bên bên trái ở dưới đây.

Tùy thuộc vào các đối số của nó, phương thức scaling có thể làm nhiều thứ hơn là chỉ

thu nhỏ hoặc phóng to một Entity. Để thay đổi điểm gốc (trùng với gốc tọa độ) của scale, bạn có thể một điểm gốc mới ở phía trước đối số tỉ lệ scale. Ví dụ, dòng mã sau đây tăng gấp đôi kích thước của một Entity và scale nó quanh điểm gốc mới [ 5 , 5, 5 ] :

t = Geom::Transformation.scaling [5, 5, 5], 2

Khi đó sự scale và di chuyển của hình cũng phụ thuộc vào tỉ lệ scale và vị trí tương đối giữa vị trí điểm trọng tâm ban đầu và điểm gốc mới.

Ngoài việc xác định điểm gốc mới, bạn cũng có thể thiết lập tỉ số scale riêng rẽ cho từng

trục tọa độ một. Để làm điều này, gọi ra Transformation.scaling với ba đối số (không nằm trong một mảng). Những đối số này sẽ được hiểu là tỉ lệ scale theo các trục x, y và z. Ví dụ, đối tượng biến đổi sau sẽ làm giảm kích thước theo trục x còn một nửa, phóng to kích thước theo trục y lên ba lần, và không thay đổi kích thước theo trục z:

t = Geom::Transformation.scaling 0.5, 3, 1

(0.5,3,1)

Page 8: Chuong 4,5 va 6 Pluin cho SketchUp

Chương IV SketchUp Scripting by [email protected]

61

Cuối cùng là bạn có thể tạo ra đối tượng biến đổi xác định cả điểm gốc mới và các tỉ lệ scale riêng rẽ cho từng trục. Đối số điểm gốc mới luôn luôn phải được xác định đầu tiên, do đó, ví dụ sẽ như sau :

t = Geom::Transformation.scaling [5, 5, 5], 0.5, 3, 1

Dòng mã này sẽ scale đối tượng tương tự như ví dụ trên, nhưng trong trường hợp này thì vị trí của đối tượng sẽ giống như trường hợp điểm gốc mới [ 5 , 5, 5 ] ở trên.

4.1.4 Kết hợp các phép biến đổi Cho đến giờ, tất cả các đối tượng biến đổi được tạo ra mới chỉ thực hiện duy nhất một

nhiệm vụ của một kiểu biến đổi như: dịch chuyển tịnh tiến, xoay hoặc scale. Tuy nhiên , chúng ta có thể kết hợp các đối tượng chuyển đổi với nhau bằng phép toán * . Ví dụ, nếu đối tượng biến đổi t_tran dịch chuyển tịnh tiến một Entity và t_rot xoay một Entity, dòng mã sau đây tạo ra một đối tượng biến đổi kết hợp, đầu tiên nó dịch chuyển tịnh tiến một Entity bằng t_tran và sau đó xoay nó với t_rot :

t_prod = t_rot * t_tran

Đối tượng biến đổi ở phía ngoài cùng bên phải luôn luôn được thực hiện đầu tiên. Trong trường hợp này, đối tượng biến đổi tổng hợp t_prod sẽ thực thi t_tran đầu tiên và t_rot là thứ hai. Nếu bạn đảo ngược thứ tự của chúng thì t_prod sẽ thực thi t_rot đầu tiên và thứ hai là t_tran tạo ra một sự biến đổi hoàn toàn khác so với trên.

Điều này có thể gây nhầm lẫn, vì vậy chúng ta hãy xem một ví dụ khác: Ví dụ t1, t2 , t3 và t4 là các đối tượng biến đổi và t_prod được đưa ra bởi dòng mã sau đây :

t_prod = t1 * t2 * t3 * t4

Nếu bạn biến đổi một Entity với t_prod, việc đối tượng biến đổi t4 sẽ được thực thi đầu tiên, sau đó là t3 , tiếp theo là t2 và cuối cùng là t1.

Để hiểu lý do tại sao đối tượng biến đổi ngoài cùng bên phải được thực thi đầu tiên và lý do tại sao phép toán nhân * được sử dụng để kết hợp nhiều đối tượng biến đổi lại với nhau, bạn phải hiểu rằng toán học là cơ sở của các hoạt động này. Mỗi đối tượng biến đổi về cơ bản là một ma trận có chứa đựng mười sáu giá trị thập phân. Những giá trị này xác định một ma trận tịnh tiến, xoay, scale hoặc thực hiện một sự kết hợp của chúng. Phụ lục B thảo luận về chủ đề này một cách chi tiết, và mặc dù chủ đề là không dễ hiểu, nó rất hữu ích khi bạn đang cố gắng để gỡ lỗi một biến đổi kết hợp.

4.1.5 Phép biến đổi hệ trục tọa độ Giả sử bạn đang mô hình hóa một chiếc xe với bốn cái bánh. Khi bạn xoay xe, nên cho

toàn bộ chiếc xe xoay quanh điểm gốc của chiếc xe. Nhưng khi bạn xoay bất kỳ chiếc bánh xe nào của nó, vòng xoay nên được liên quan đến trục của bánh xe. Như vậy, với mục đích biến đổi như thế nên mỗi bánh xe cần phải có điểm gốc và trục xoay của riêng nó. Và hệ tọa độ riêng biệt này được goi là hệ trục tọa độ địa phương-local coordinate system của bánh xe. Hệ tọa độ của toàn bộ chiếc xe gọi là hệ trục tọa độ tổng thể-global coordinate system.

Có một số cách để tạo ra một đối tượng biến đổi để có thể biến đổi một hệ trục tọa độ sang hệ trục tọa độ khác. Chúng được đưa ra như sau:

1. Gọi ra Geom::Transformation.new với một điểm gốc tọa độ mới và trục z mới

2. Gọi ra Geom::Transformation.new với một điểm gốc tọa độ mới và trục x mới, trục y mới.

3. Gọi ra Geom::Transformation.new với trục x mới, y mới,z mới và gốc tọa độ mới

4. Gọi ra Geom::Transformation.axes với gốc tọa độ mới, trục x mới, y mới và z mới.

Page 9: Chuong 4,5 va 6 Pluin cho SketchUp

Chương IV SketchUp Scripting by [email protected]

62

Đối tượng biến đổi sau đây biến đổi hệ trục tọa độ tổng thể thành một hệ trục tọa độ có gốc tọa độ tại [ 10 , 4, 6 ] và một trục z cùng chiều với vector [ 4, 3, 3 ]:

t = Geom::Transformation.new [10, 4, 6], [4, 3, 3]

Trong trường hợp này, các trục x và trục y được để tùy ý. Để kiểm chứng rằng điểm gốc và trục đã được thiết lập chính xác, gọi ra các phương thức origin, xaxis, yaxis, và zaxis như sau:

t.origin

10, 4, 6]

t.xaxis

[-0.6, 0.8, 0]

t.yaxis

[-0.411597, -0.308697, 0.857493]

t.zaxis

[0.685994, 0.514496, 0.514496]

Kết quả trả về của trục z là vector không bằng với tham số vector dùng để tạo ra đối tượng biến đổi và điều này có vẻ kỳ lạ. Tuy nhiên, vector kết quả trả về của trục z có cùng chiều với vector [ 4, 3, 3 ], sự khác biệt là các vector kết quả trả về của trục z có tính chiều dài của nó. Phụ lục B sẽ giải thích chủ đề về độ dài véc tơ, chiều vector và cho thấy cách chúng được tính toán như thế nào.

Để hiểu rõ hơn về việc kết hợp các phép biến đổi, bạn có thể bỏ qua và tiến tới chương 12. Hoạt động cấu trúc khung xương phụ thuộc nhiều vào cách sử dụng hệ trục tọa độ địa phường và hệ trục tọa độ tổng thể để tạo ra một hệ thống chuyển động có phân cấp.

4.2 Text Trong giao diện sử dụng của SketchUp có hai công cụ để tạo ra văn là: công cụ Text và

các công cụ 3D Text. Nói chung, công cụ Text thêm các ghi chú đơn giản trong dự án SketchUp , và nó đặc biệt hữu ích cho việc cung cấp dữ liệu về kích thước (như diện tích, thể tích…). Các dòng Text này trong dự án SketchUp thường bắt đầu bằng một mũi tên và mà bạn có thể thiết lập vị trí của nó ở bất cứ chỗ nào. Khi bạn tạo một Text hai chiều trong mã hóa, kết quả trả về một đối tượng Text.

Khi nói đến Text ba chiều (3D Text), mã hóa sẽ trở nên phức tạp hơn. Trước tiên, là thêm các tham số cần được xác định, chẳng hạn như font chữ, kích thước font và căn chỉnh văn bản. Thứ hai, phương thức được sử dụng để tạo ra 3D Text không trả về một đối tượng Text mà là một cái gì đó hoàn toàn khác.

4.2.1 2D Text

Cũng như đối tượng bề mặt được tạo ra bởi add_face , các đối tượng Text sẽ được tạo ra bởi phương thức add_text của lớp Entities. Khi bạn gọi phương thức này, bạn cần phải xác định tối thiểu hai thông số: nội dung của Text sẽ được hiển thị và vị trí mà Text tạo ra sẽ được đặt vào. Ví dụ, lệnh sau đây trả về một đối tượng Text hiển thị dòng chữ “Hello, world!” và nó được chèn ở gốc tọa độ tức điểm [ 0, 0, 0] :

Page 10: Chuong 4,5 va 6 Pluin cho SketchUp

Chương IV SketchUp Scripting by [email protected]

63

ents = Sketchup.active_model.entities

example_text = ents.add_text "Hello, world!", [0, 0, 0]

Nội dung của Text luôn luôn đặt ở vị trí đối diện với người dùng, kích thước font và kiểu font của nó được xác định trong hộp thoại Model Info/Text ( chọn Window>Model Info trên menu chính của SketchUp). Hình sau cho thấy nội dung Text được hiển thị như thế nào trong khung nhìn 3 chiều:

Tại thời điểm viết cuốn sách này, không có cách nào để thay đổi được kiểu font và kích

thước font của Text 2 chiều chiều thông qua đối tượng Text trong mã hóa. Tuy nhiên, bạn có thể thêm một đoạn thẳng có đầu mũi tên được gọi là đường neo-leader vào trước nội dung hiển thị của Text trong dự án SketchUp. Để thêm một leader cho Text, gọi ra add_text với ba tham số. Giống như ở trên, tham số đầu tiên sẽ xác định nội dung được hiển thị. Nhưng bây giờ tham số thứ hai sẽ thiết lập vị trí của đầu mũi tên của -leader và tham số thứ ba xác định vector đoạn thẳng của leader.

ents = Sketchup.active_model.entities

example_text=ents.add_text "Hello, world!",[0,0,0],[2,2,0]

Hình sau cho thấy kết quả hiển thị khi đính kèm thêm một leader. Mặc dù vị trí của dòng hiển thị nội dung của Text đã thay đổi nhưng nó vẫn đối diện với người dùng.

Khi bạn có được đối tượng Text được trả về bởi phương thức add_text thì bạn có thể gọi ra bất kỳ phương thức nào được cung cấp chó lớp Text. Các phương thức này kiểm soát cách thức mà text và leader sẽ được thể hiện trong SketchUp, và chúng được ra như sau:

• text= - Thiết lập nội dung Text sẽ được hiển thị

• point= - Xác định vị trí đặt dòng Text hiển thị hoặc điểm đặt của đầu mũi tên của leather

• vector= - xác định vector đoạn thẳng của leader

• line_weight= - Xác định chiều dầy của đoạn thẳng thuộc leader

Page 11: Chuong 4,5 va 6 Pluin cho SketchUp

Chương IV SketchUp Scripting by [email protected]

64

• arrow_type= - Cấu hình sự hiển thị của đầu mũi tên thuộc leader trong dự án SketchUp. Nếu là 0 thì không có đầu mũi tên này, nếu là 1 thì thay đầu mũi tên là đường chéo, nếu là 2 thì thay đầu mũi tên bằng dấu chấm “.”, nếu là 3 thì là đầu mũi tên đặc và 4 thì là đầu mũi tên hở.

• leader_type= - Cấu hình kiểu hiển thị của leader trong dự án SketchUp. 0 nghĩa là

leader bị ẩn, 1 nghĩa là leader ở chế độ view-based, 2 nghĩa là leader ở chế độ pushpin. Xem lại hộp thoại Model Info/Text/Leader lines/Leader ( chọn Window>Model Info trên menu chính của SketchUp).

Đoạn mã sau tạo một đối tượng Text kèm theo một leader cho nó, và sau đó cấu hình các sự hiển thị của Text và leader trong dự án SketchUp: ents = Sketchup.active_model.entities

new_text = ents.add_text "Old Text Message!", [1,1,0], [3,0,0]

new_text.text = "New Text Message!"

# Pushpin-style leader

new_text.leader_type = 2

new_text.line_weight = 4

# Dotted arrow-Thay mũi tên là dấu chấm

new_text.arrow_type = 2

Kết quả Text sẽ được thay thế nội dung ban đầu là Old Text Message thành New Text Message!và kiểu hiển thị của leader là pushpin. Chiều dầy của đoạn thẳng thuộc leader là 4 pixel và đầu mũi tên của nó được thay thế bằng một dấu chấm.

4.2.2 3D Text 2D Text là tuyệt vời cho các ghi chú và dữ liệu liên quan đến kích thước, nhưng nếu text

là muốn nói đến dùng để trang trí hoặc cần phải được định hướng hoặc cần đùn ép theo một cách cụ thể thì bạn sẽ phải làm việc trong không gian ba chiều. Đây là thứ khó khăn để thực hiện trong mã hóa vì không có đối tượng cụ thể cho 3D text mà chỉ có một đối tượng Text để đại diện cho 2D text.

Cách duy nhất để tạo ra 3D text trong mã hóa là bằng cách gọi ra phương thức add_3d_text trong lớp Entities. Để gọi ra phương thức này, bạn cần cung cấp mười tham số:

1. string – Chuỗi văn bản sẽ xuất hiện.

2. alignment – canh dòng ngang: TextAlignRight, TextAlignLeft hoặc TextAlignCenter

Page 12: Chuong 4,5 va 6 Pluin cho SketchUp

Chương IV SketchUp Scripting by [email protected]

65

3. fontName – Tên của font dùng cho chuỗi văn bản sẽ xuất hiện (ví dụ., Times, Arial)

4. bold – Lựa chọn có in đậm chuỗi văn bản hay không (true hoặc false)

5. italic - Lựa chọn có in nghiên chuỗi văn bản hay không (true hoặc false)

6. height – Chiều cao của các chữ trong chuỗi văn bản

7. tolerance – Dung sai để tạo ra đường cong trong chữ thuộc chuỗi văn bản (mặc định là 0.0 sẽ tạo ra chất lượng cao nhất cho chuỗi văn bản )

8. baseZ – Vị trí của chuỗi văn bản theo trục z ( cao độ của nó)

9. filled – Lựa chọn các chữ trong chuỗi văn bản sẽ được phủ đầy ( tức là các bề mặt trong các đường biên bao quanh chữ) (true hoặc false)

10. extrusion – chiều sâu của các ký tự 3D (chỉ với lựa chọn của tham số filled là true)

Theo mặc định, các 3D text khi được hiển thị trong dự án SketchUp luôn được đặt ở trong góc ¼ của mặt phẳng xy tạo bởi chiều x và y dương. Bạn có thể thay đổi vị trí của nó theo chiều trục z bằng tham số baseZ, nhưng một khi bạn đã tạo ra 3D text trong dự án SketchUp thì bạn có thể thay đổi vị trí của nó bằng cách sử dụng một đối tượng biến đổi và phương thức transform_entities.

Đoạn mã trong tập tin kịch bản sau đây phương thức add_3d_text được gọi ra ba lần để tạo ra các 3D text với cách căn dòng, phông chữ và các giá trị tolerance khác nhau. Trong các trường hợp, chiều cao của các chuỗi văn bản luôn được thiết lập là 10 .

text_3d.rb

# Access the Entities container

ents = Sketchup.active_model.entities

# Draw in Times New Roman, left-aligned, tolerance = 100

string1 = "This text is printed in \n \ left-aligned Times New Roman \n with a tolerance of 100."

ents.add_3d_text string1, TextAlignLeft, "Times", false, false, 10, 100, 0, true, 10

ents.transform_entities [0, 60, 0], ents.to_a

# Draw in bold Arial, center-aligned, tolerance = 10

string2 = "This text is printed in \n \ center-aligned bold Arial \n with a tolerance of 10."

ents.add_3d_text string2, TextAlignCenter, "Arial", true, false, 10, 10, 0, true, 10

ents.transform_entities [0, 60, 0], ents.to_a

# Draw in outline, italicized Courier New, tolerance = 1

string3 = "This text outline is printed in \n \ right-aligned, italicized \n Courier New with a tolerance of 1."

Page 13: Chuong 4,5 va 6 Pluin cho SketchUp

Chương IV SketchUp Scripting by [email protected]

66

ents.add_3d_text string3, TextAlignRight, "Courier New", false, true, 10, 1, 0, false, 10

Hình sau cho thấy kết quả việc thực thi kịch bản trên. Lưu ý rằng khả năng đọc được của

chuỗi văn bản được cải thiện khi giá trị dung sai-tolerance của nó giảm. Hơn nữa, khối văn bản thứ ba được dựng ra khi giá trị thiết lập của tham số filled là false nên nó không được đùn ép thành các khối 3D như các khối văn bản khác .

Trong khi phương thức add_text trả về một đối tượng Text, add_3d_text trả về

trạng thái thực hiện của phương thức: true hoặc false. Hơn nữa, add_3d_text không tạo ra một đối tượng duy nhất mà nó tạo ra hàng trăm và hàng ngàn cạnh và bề mặt riêng. Vì lý do này, cách duy nhất để di chuyển các khối văn bản được tạo ra là gọi ra phương thức transform_entities của đối tượng Entities hiện hành cho tất cả cạnh và bề mặt chứa đựng trong khối văn bản tạo ra.

4.3 Hình ảnh-Image Có hai cách để tạo ra một hình ảnh trong dự án SketchUp từ một tập tin ảnh: như một hoa

văn-Texture hoặc như là một hình ảnh-Image. Texture sẽ được trình bày trong chương 6, là hình ảnh được áp lên trên các bề mặt trong dự án SketchUp. Chúng chỉ tính chất vật liệu của các mô hình trong dự án và thường được sử dụng để hiển thị các mô hình đó được làm từ cái gì, ví dụ Texture gỗ được áp lên bề mặt của mô hình để nói lên rằng mô hình đó được làm từ vật liệu gố.

Một hình ảnh là một Entity độc lập như các đối tượng đoạn thẳng và bề mặt. Nó được tạo ra bằng phương thức add_image của lớp Entities với ba tham số: Đường dẫn cùng với tên của tập tin hình ảnh được chèn, vị trí điểm mà hình ảnh sẽ được đặt lên và chiều rộng mong muốn của hình ảnh trong dự án SketchUp.

SketchUp chấp nhận các định dạng file sau của tập tin hình ảnh: *. jpg , *.Png, *. Bmp, *.tga và *.bmp. Theo mặc định tỷ lệ giữa chiều cao/chiều rộng của tập tin hình ảnh chèn gốc sẽ được giữ nguyên không đổi, nhưng bạn có thể thay đổi được tỉ lệ chiều cao/chiều rộng ban đầu bằng cách thêm một tham số tùy chọn thứ tư để xác định chiều cao của nó khi được chèn trong dự án SketchUp.

Page 14: Chuong 4,5 va 6 Pluin cho SketchUp

Chương IV SketchUp Scripting by [email protected]

67

Ví dụ, đoạn mã sau tạo một hình ảnh từ một tập tin gọi là lorca.png trong thư mục con Ch4 của thư mục Plugins của nơi mà SketchUp được cài trên máy tính của bạn. Hình ảnh được chèn đặt ở điểm [ 5 , 0, 0 ] và chiều rộng của nó được thiết lập là 20 . ents = Sketchup.active_model.entities

path = Sketchup.find_support_file "Ch4/lorca.png", "Plugins"

im1 = ents.add_image path, [5, 0, 0], 20

( Nếu tập tin hình ảnh có đường dẫn là “C:/CH4/lorca.png” thì bạn có thể thực hiện dòng lệnh như sau: im1 = ents.add_image “C:/CH4/lorca.png”, [5, 0, 0], 20 mà không cần dòng lệnh thứ hai như trên).

Hình ảnh sau khi được chèn trong dự án SketchUp luôn luôn được đặt song song với mặt phẳng xy. Để thay đổi sự định hướng này của nó, gọi ra phương thức transform! của lớp Image với một đối tượng biến đổi thực hiện biến đổi xoay.

Thêm tham số thứ tư để thay đổi tỷ lệ chiều cao/chiều rộng của hình ảnh được chèn. Dòng lệnh sau sẽ tạo ra một hình ảnh trong dự án SketchUp với có chiều cao gấp đôi chiều rộng của nó và sau đó thực hiện phép biến đổi xoay để nó nằm trong mặt phẳng xz : im2 = ents.add_image path, [25, 0, 0], 20, 40

tr = Geom::Transformation.new [0, 0, 0], [1, 0, 0], 90.degrees

ents.transform_entities tr, im2

Hình sau thể hiện im1 và im2 được hiển thị như thế nào trong dự án SketchUp:

Một khi bạn đã tạo ra một đối tượng hình ảnh-Image, bạn có thể gọi ra cá phương thức

của nó và các phương thức này mà chủ yếu trả về thông tin kích thước của hình ảnh. Ví dụ, bạn có thể gọi ra height, width, pixelheight hoặc pixelwidth để thiết lập hoặc lấy ra kích thước của hình ảnh với đơn vị là inch hoặc pixel. Phương thức normal vector pháp tuyến của mặt phẳng chứa bức ảnh. Phương thức Path cung cấp đường dẫn đầy đủ đến tập tin hình ảnh gốc dùng để chèn vào trong dự án SketchUp.

4.4 Lưới đa giác-Polygonmesh SketchUp là tuyệt vời cho để dựng các kết cấu kiến trúc như nhà ở và các hình bị vát

mép, nhưng đối với những kết cấu không bình thường như bàn tay của bạn thì sao? Bạn có thể tạo ra các mô hình đó với các vòng cung và các phân đoạn đoạn thẳng, nhưng nó dễ dàng hơn khi bạn xác định một loạt các điểm và tạo nên các bề mặt đa giác giữa chúng. Tập hợp các bề mặt đa giác này thường được gọi là lưới đa giác-Polygonmesh. Trong SketchUp, các lưới đa giác được đại diện bởi các đối tượng được tạo ra từ lớp PolygonMesh.

Page 15: Chuong 4,5 va 6 Pluin cho SketchUp

Chương IV SketchUp Scripting by [email protected]

68

Lớp PolygonMesh khác với tất cả các lớp khác mà chúng ta đã gặp phải. Lớp Entities không có phương thức add_mesh hoặc add_polygonmesh. Khi bạn muốn hiển thị một lưới đa giác trong dự án SketchUp, bạn phải gọi ra phương thức add_faces_from_mesh của lớp Entities với tên của đối tượng PolygonMesh. Lệnh này sẽ đọc các đa giác có trong lưới và mỗi đa giác sẽ được tạo ra một bề mặt trong nó.

Một PolygonMesh về cơ bản là một mảng chứa các đa giác, và mỗi đa giác là một mảng bao gồm nhiều điểm. Quá trình làm việc với các đối tượng PolygonMesh bao gồm ba bước:

1. Tạo ra một đối tượng PolygonMesh mới với phương thức Geom::PolygonMesh.new. Phương thức này chấp nhập một tham số tùy chọn xác định số lượng các điểm và các đa giác trong lưới.

2. Gọi ra add_point để thêm một điểm vào trong lưới và/hoặc gọi ra add_polygon để thêm một đa giác với tham số là các điểm của nó.

3. Gọi ra add_faces_from_mesh để tạo các bề mặt trong lưới và hiển thị chúng trong dự án SketchUp.

Phần khó nhất của việc thực hiện với các đối tượng PolygonMesh là phương thức add_polygon, phương thức này có yêu cầu thêm một mảng mới bao gồm các điểm thuộc đa giác thêm vào. Mỗi tham số của add_polygon phải là một điểm, nhưng không giống như các phương thức khác, những điểm không thể được chỉ định bằng các mảng có ba phần tử đơn giản. Thay vào đó, chúng phải được chỉ định bởi đối tượng Geom :: Point3D.

Lưu ý: Geom là một mô-đun, ngoài lớp Transformation thì nó còn chứa các lớp PolygonMesh và Point3D . Vì lý do này, khi bạn muốn tạo ra đối tượng PolygonMesh mới và các Point3D mới thì bạn phải gọi ra Geom :: PolygonMesh.new và Geom :: Point3d.new. Chương 8 sẽ trình bày chi tiết về các mô-đun và Phụ lục B thảo luận thêm về các lớp khác ở trong các mô-đun Geom.

Đoạn mã trong tập tin kịch bản sau tạo ra 12 đối tượng điểm Geom::Point3d và gọi ra phương thức add_polygon để tạo ra một khối có 20 mặt đa giác nối tiếp nhau từ các điểm đó. Cuối cùng, phương thức add_faces_from_mesh để tạo các bề mặt cho các đa giác đó và hiển thị chúng trong dự án.

mesh.rb

# GR is the Golden Ratio: (1 + sqrt(5))/2

GR = 1.618

# Create the points in the mesh

pt0 = Geom::Point3d.new 0, 1, GR

pt1 = Geom::Point3d.new 0, -1, GR

pt2 = Geom::Point3d.new GR, 0, 1

pt3 = Geom::Point3d.new -GR, 0, 1

pt4 = Geom::Point3d.new 1, -GR, 0

Page 16: Chuong 4,5 va 6 Pluin cho SketchUp

Chương IV SketchUp Scripting by [email protected]

69

pt5 = Geom::Point3d.new -1, -GR, 0

pt6 = Geom::Point3d.new 0, 1, -GR

pt7 = Geom::Point3d.new 0, -1, -GR

pt8 = Geom::Point3d.new GR, 0, -1

pt9 = Geom::Point3d.new -GR, 0, -1

pt10 = Geom::Point3d.new 1, GR, 0

pt11 = Geom::Point3d.new -1, GR, 0

# The PolygonMesh contains 12 points and 20 triangular faces

pm = Geom::PolygonMesh.new 12, 20

# Top half

pm.add_polygon pt0, pt1, pt2 pm.add_polygon pt0, pt1, pt3 pm.add_polygon pt1, pt4, pt5 pm.add_polygon pt1, pt4, pt2 pm.add_polygon pt1, pt3, pt5

# Middle

pm.add_polygon pt4, pt5, pt7 pm.add_polygon pt2, pt8, pt4 pm.add_polygon pt10, pt11, pt0 pm.add_polygon pt3, pt9, pt5 pm.add_polygon pt2, pt8, pt10 pm.add_polygon pt2, pt0, pt10 pm.add_polygon pt9, pt5, pt7 pm.add_polygon pt7, pt8, pt4 pm.add_polygon pt11, pt9, pt3 pm.add_polygon pt11, pt3, pt0

# Bottom half

pm.add_polygon pt6, pt7, pt8 pm.add_polygon pt6, pt7, pt9 pm.add_polygon pt6, pt10, pt11 pm.add_polygon pt6, pt10, pt8 pm.add_polygon pt6, pt9, pt11

# Draw the Faces in the mesh

ents = Sketchup.active_model.entities ents.add_faces_from_mesh pm

Sự định hướng của các điểm trong một đa giác ( theo chiều kim đồng hồ hoặc ngược

chiều kim đồng hồ ) quyết định chiều của vector pháp tuyến của bề mặt đa giác đó là hướng vào phía trong hay ra ngoài khối. Điều này được thể hiện trong hình sau, trong đó mô tả các khối hai mươi mặt hình thành từ đa giác Một số bề mặt đa giác quay vào trong ( tức mặt trước của nó hướng vào trong khối) do chiều của vector pháp tuyến của nó hướng vào trong và một số bề mặt

Page 17: Chuong 4,5 va 6 Pluin cho SketchUp

Chương IV SketchUp Scripting by [email protected]

70

đa giác quay ra ngoài ( tức mặt trước của nó hướng ra ngoài khối) do chiều của vector pháp tuyến của nó hướng ra ngoài.

Một khi bạn đã tạo ra và thiết lập cấu hình đa giác thì cũng có thể gọi ra các phương thức

để cung cấp các thông tin về các đa giác thành phần và các điểm thuộc lưới:

• points hoặc polygons – trả về mảng chứa các điểm chứa các điểm hoặc các đa giác thuộc lưới.

• count_points hoặc count_polygons – trả về số lượng các điểm hoặc các đa giác thuộc lưới

• point_at hoặc polygon_at – trả về điểm hoặc đa giác tương ứng với số thứ tự (index) của nó trong lưới được đưa ra

• normal_at – trả về vector pháp tuyến của bề mặt đa giác tương ứng với số thứ tự (index) của nó trong lưới được đưa ra

• uv_at – trả về tọa độ UV của các Texture phủ lên trên bề mặt đa giác tương ứng với số thứ tự (index) của nó trong lưới được đưa ra.

• uvs – trả về mảng các tọa độ UV Texture liên quan đến lưới

Ví dụ, các dòng mã sau:

pm.points

pm.normal_at 3

pm.uv_at (1,1)

Hai phương thức cuối cùng liên quan đến việc lập bản đồ kết cấu Texture, điều đó vượt xa phạm vi của cuốn sách này. Texture cơ bản là hình ảnh gắn liền với các đối tượng trong một dự án và chương 6 sẽ giải thích làm thế nào để tạo ra chúng và áp chúng lên các bề mặt, đối tượng.

4.5 Kết thúc chương Chương này bắt đầu với một sự trình bày về một trong những khía cạnh quan trọng nhất

của SketchUp: Phép biến đổi. Với biến đổi, chúng ta có thể thực hiện trong mã hóa các hoạt động tương tự công cụ Rotate, Scale và Move trong giao diện sử dụng của SketchUp. Ba loại biến đổi cơ bản của phép biến đổi là dịch chuyển tịnh tiến, xoay và quy mô scale. Có thể kết hợp nhiều biến đổi lại với nhau bằng phép toán * và thứ tự xắp xếp của chúng trong biến đổi kết hợp rất quan trọng. Trong khi chương này chỉ tập trung trình bày về việc tạo ra và sử dụng các phép biến đổi, phụ lục B sẽ trình bày về các nền tảng toán học cơ bản của nó.

Ngoài ra, chương này đã trình bày thêm ba đối tượng trong SketchUp mà chúng chưa được mô tả trong Chương 3, đó là các đối tượng: Text, hình ảnh- Image và lưới đa giác

Page 18: Chuong 4,5 va 6 Pluin cho SketchUp

Chương IV SketchUp Scripting by [email protected]

71

PolygonMesh. Thật đơn giản khi làm việc với các đối tượng văn bản hai chiều 2D Text, nhưng văn bản ba chiều thì không đơn giản chút nào-bạn phải cấu hình các thuộc tính của nó như: tolerance, canh dòng và các các chữ có được phủ đầy bên trong nó không. Đối tượng Image rất dễ hiểu khi làm việc với nó, miễn là bạn nhớ cách biến đổi vị trí của chúng từ vị trí ban đầu. Đối tượng PolygonMesh là những hình dạng phức tạp nhất trong SketchUp, vì mỗi điểm và đa giác phải được xác định một cách riêng biệt. Tuy nhiên, với các đối tượng PolygonMesh, bạn có thể tạo ra các mô hình phức tạp hơn nhiều so với việc chỉ sử dụng cạnh và bề mặt để xây dựng mô hình.

Page 19: Chuong 4,5 va 6 Pluin cho SketchUp

Chương V SketchUp Scripting by [email protected]

72

Bài học thứ hai về Ruby:

Cấu trúc điều khiển

và truy xuất tập tin

Page 20: Chuong 4,5 va 6 Pluin cho SketchUp

Chương V SketchUp Scripting by [email protected]

73

Chương này trình bày một vấn đề ngắn gọn nhưng quan trọng về hai tính năng bậc trung của Ruby: cấu trúc điều khiển và truy xuất tập tin. Chủ đề đầu tiên liên quan đến việc kiểm soát sự thực thi của mã với điều kiện và sự thực thi của mã với vòng lặp. Chủ đề thứ hai có liên quan với các tập tin: làm thế nào để tạo ra chúng, ghi lên chúng, đọc từ chúng và xóa chúng đi. Trình bày này cũng giải thích việc truy xuất thư mục của Ruby và SketchUp để truy xuất file cụ thể.

5.1 Thực thi có điều kiện: if và case Cho đến nay, tất cả các lệnh trong tập tin kịch bản Ruby mà chúng ta đã gặp phải là được

thực thi theo trình tự. Có nghĩa là, lệnh đầu tiên được thực thi, sau đó là lệnh tiếp theo và tiếp theo, và cứ như vậy cho đến lệnh cuối của kịch bản. Tuy không thường xuyên nhưng bạn có lẽ sẽ muốn sử dụng điều kiện để xác định xem các lệnh nào đó sẽ được thực hiện hay không. Ví dụ, bạn muốn một kịch bản sẽ thực thi một tập hợp các lệnh nếu một hình nào đó nằm trong mặt phẳng xy hoặc một tập hợp các lệnh khác nếu nó không nằm.

Ruby cung cấp hai cách chính để thiết lập các điều kiện: câu lệnh if và câu lệnh case. Câu lệnh if kiểm tra xem một điều kiện có đúng-true hay không, và nếu là đúng thì các lệnh tiếp theo câu lệnh if sẽ được thực thi. Câu lệnh case kiểm tra một biến và thực thi các lệnh khác nhau tùy thuộc vào giá trị của biến.

5.1.1 Phép toán logic và câu lệnh if: Bài học Ruby đầu tiên trong cuốn sách này giải thích con số và các phép toán số. Trong

Ruby, một phép toán số chấp nhận một hoặc hai số và trả về một số. Bây giờ chúng ta sẽ xem xét một loại mới của phép toán: phép toán logic-logical operator. Bật hộp thoại Ruby console trong SketchUp và gõ lệnh sau :

20 > 10

Nhấn phím Enter và kết quả hiển thị sẽ là true bởi vì 20 lớn hơn 10. Bây giờ hãy thử câu lệnh sau :

"S" == "E"

Nhấn phím Enter và kết quả hiển thị sẽ là false bởi vì “S” không thể bằng “E”.

Trong Ruby, true và false là những giá trị được tạo ra bởi các phép toán logic. Bảng sau liệt kê > , == và các phép toán tương tự khác. Các ví dụ sử dụng trong cột thứ ba luôn luôn trả về true.

Phép toán Miêu tả Ví dụ

== Bằng nhau 6 * 8 == 48

!= Không bằng nhau "J" != "X"

< Nhỏ hơn 24 < 30

> Lớn hơn "B" > "A"

<= Nhỏ hơn hoặc bằng 22 <= 22

>= Lớn hơn hoặc bằng "X" >= "W"

! Hàm luận lý đảo ngược ( NOT) !(2 + 2 == 5)

&& Hàm luận lý và ( AND) 3 * 5 == 15 && 5 * 2 == 10

|| Hàm luận lý hoặc ( OR) "A" == "A" || "J" == "K"

Phép toán logic là đặc biệt hữu ích khi kết hợp với câu lệnh if của Ruby. Câu lệnh này bắt đầu bằng cách kiểm tra điều kiện là kết quả của một phép toán logic. Nếu phép toán logic

Page 21: Chuong 4,5 va 6 Pluin cho SketchUp

Chương V SketchUp Scripting by [email protected]

74

không trả về về false hoặc nil thì các lệnh sau câu lệnh if sẽ được thực thi cho tới lệnh cuối cùng nằm trước từ khóa end. Nếu phép toán logic trả về false hoặc nil, các lệnh sau câu lệnh if được bỏ qua. Các dòng mã sau đây là một ví dụ đơn giản: if 6 * 8 == 48

puts "Six times eight equals forty-eight."

puts "Therefore, this statement will be printed."

end

Nếu bạn đặt những dòng mã trên trong một tập tin kịch bản Ruby và thực thi kịch bản. Do điều kiện là phép toán logic trả về một giá trị true. Vì vậy, các lệnh nằm giữa if và end sẽ được thực thi, và trong giao diện của hộp thoại Ruby console sẽ hiển thị hai dòng văn bản.

Nếu bạn thực thi đoạn mã sau trong một tập tin kịch bản, điều kiện là phép toán logic sẽ trả về giá trị false. Điều này có nghĩa các lệnh nằm giữa if và end sẽ không được thực thi. if "M" <= "F"

puts "This statement will not be printed."

end

Hàm luận lý ! trong bảng trên đảo ngược giá trị trả về của một phép toán logic, chuyển đổi true thành false hoặc chuyển false thành true. Phép toán logic phải được đặt bên trong dấu ngoặc đơn, như thể hiện trong đoạn mã sau: if !(6 * 8 == 48)

puts "The ! operator makes the condition false."

puts "These lines of text won't be displayed."

end

Hàm luận lý && và ||kết hợp với kết quả của hai phép toán logic để trả về một kết quả duy nhất. Hàm luân lý && trả về true nếu cả phép toán logic đều trả về giá trị true. Hàm luân lý || trả về true nếu một trong hai hoặc cả hai phép toán logic trả về giá trị true.

Các đoạn mã sau đây cho thấy cách thức mà các hàm luận lý này làm việc trong thực tế. Các phép toán logic không cần phải đặt trong dấu ngoặc đơn, nhưng tôi đã đặt để cho bạn đọc mã thấy dễ hơn. if ("B" > "A") || (14 == 9 * 2)

puts "The first expression is true but the second is false."

puts "Therefore, the || operator returns true."

puts "These statements will be displayed."

end

Page 22: Chuong 4,5 va 6 Pluin cho SketchUp

Chương V SketchUp Scripting by [email protected]

75

if ("B" > "A") && (14 == 9 * 2)

puts "The first expression is true but the second is false."

puts "Therefore, the && operator returns false."

puts "These statements will not be displayed."

end

Câu lệnh if có thể được sử dụng để xác định xem một đối tượng tồn tại hay không. Ví dụ bạn đã cố gắng để tạo ra một đối tượng bề mặt bởi phương thức add_face của lớp Entities:

face1 = Sketchup.active_model.entities.add_face p1, p2, p3

Nếu phương thức trên hoàn thành thực thi và thành công thì face1 sẽ là một đối tượng Face, và nếu không thành công thì face1 sẽ là nil. Trong Ruby, nil có nghĩa là các đối tượng không được tạo ra thành công, hay chính xác hơn là các đối tượng này không tồn tại. Câu lệnh if sẽ trả lời là nil hoặc false. Các đoạn mã sau đây kiểm tra face1 có tồn tại hay không: if face1

puts "If you can read this, add_face completed successfully."

puts "If not, face equals nil and you won't read this."

end

5.1.2 Câu lệnh if…else và if…elsif…else: Câu lệnh if thực thi các lệnh tiếp sau nó mỗi khi điều kiện không phải false hoặc nil.

Khi một câu lệnh if có thêm câu lệnh else tiếp sau nó thì có một tập hợp các lệnh khác sẽ được thực thi khi điều kiện trả về false hoặc nil. Hãy tưởng tượng về nó như sau: if chỉ cho khối xử lí thực thi một hướng nào đó nếu điều kiện là hợp lệ, else chỉ cho khối xử lý thực thi theo một hướng khác nếu điều kiện là không hợp lệ. Ví dụ, đoạn mã sau đây kiểm tra xem đối tượng new_edge có được tạo thành công hay không. Nếu tồn tại, thông báo “Successful!” được hiển thị. Nếu không, thông báo “Nil!” được hiển thị. if new_edge

puts "Successful!"

else

puts "Nil!"

end

Các lệnh nằm giữa if và else và các lệnh nằm giữa else và end sẽ không bao giờ xảy ra trường hợp mà cả hai đều được thực thi. Hoặc là tập hợp lệnh đầu tiên hoặc là thứ hai sẽ được thực thi chứ bao giờ là cả hai.

Page 23: Chuong 4,5 va 6 Pluin cho SketchUp

Chương V SketchUp Scripting by [email protected]

76

Một câu lệnh If .. else có thể được lồng bên trong một câu lệnh if..else khác để kiểm tra nhiều điều kiện. Điều này được thể hiện trong đoạn mã sau: if x > 5

puts "x is greater than 5."

else

if x < 5

puts "x is less than 5."

else

puts "x equals 5."

end

end

Việc lồng các câu lệnh if..else vào nhau có thể trở nên lộn xộn, đặc biệt có rất nhiều các điều kiện hơn nữa được thêm vào. Chính vì lý do này, Ruby cung cấp thêm một câu lệnh if..elsif..else để làm cho bạn thấy dễ dàng hơn. Điều này được thể hiện trong đoạn mã sau: if day < 7

puts "First week."

elsif day < 14

puts "Second week."

elsif day < 21

puts "Third week."

elsif day < 28

puts "Fourth week."

else

puts "After the fourth week."

end

Như thể hiện trên đoạn mã trên, elsif vận hành như if và bạn có thể thêm bao nhiêu câu lệnh elsif cũng được nếu bạn muốn.

Page 24: Chuong 4,5 va 6 Pluin cho SketchUp

Chương V SketchUp Scripting by [email protected]

77

Trong Ruby, câu lệnh if trả về một giá trị bằng giá trị của lệnh sau cùng của nó được thực thi. Đây là khác biệt so với câu lệnh if trong nhiều ngôn ngữ khác, chúng không trả về một giá trị nào cả. Cách tốt nhất để hiểu được điều này là nhìn vào một ví dụ: result = if 3 * 4 == 12

"truth"

end

Trong trường hợp này, lệnh cuối cùng thực thi chỉ đơn giản là "truth.". Do đó, vì điều kiện phép toán logic là hợp lệ, nên result được thiết lập bằng "truth.". Đoạn mã trong tập tin kịch bản sau cho thấy giá trị trả về của một câu lệnh if.. elsif .. else được thiết lập là một biến và giá trị của nó tùy thuộc vào thiết lập thời gian hiện tại trong máy tinh của bạn.

season.rb

# Obtain the current month m = Time.new.month

# Set s equal to the current season in the Northern Hemisphere

s = if m < 4

"winter"

elsif m < 7

"spring"

elsif m < 10

"summer"

else

"fall"

end

# Display the value of s puts s

Bạn có thể thêm rất nhiều lựa chọn elsif nếu bạn muốn, nhưng Ruby lại cung cấp một

cách thuận tiện hơn để kiểm tra nhiều điều kiện trong mã hóa. Điều này được thực hiện với câu lệnh case và nó sẽ được trình bày trong phần tiếp theo.

5.1.3 Câu lệnh case: Giống như câu lệnh if.. elsif ..else trong đoạn mã trên, các lệnh thực thi trong

một câu lệnh case phụ thuộc vào giá trị của một biến. Câu lệnh case bắt đầu với từ khóa case và theo sau nó thông thường là tên của một biến. Tiếp theo, từ khóa when đứng trước các các giá trị khác nhau được thiết lập cho biến. Nếu biến bằng bất kỳ một giá trị nào của nó thì các lệnh sau từ khóa when tương ứng với giá trị đó sẽ được thực thi cho đến khi gặp từ khóa when tiếp theo hoặc gặp từ khóa end.

Page 25: Chuong 4,5 va 6 Pluin cho SketchUp

Chương V SketchUp Scripting by [email protected]

78

Nếu mà nó nghe có vẻ khó hiểu, một ví dụ của đoạn mã sau sẽ làm cho nó rõ ràng hơn. Câu lệnh case sau đây kiểm tra biến letter và sẽ hiển thị các chuỗi khác nhau tùy thuộc vào giá trị của biến. case letter

when "A"

puts "First letter"

when "M", "N"

puts "Middle letter"

when "Z"

puts "Last letter"

end

Từ khóa when thứ hai kiểm tra giá trị của biến letter với hai giá trị và chúng cách nhau bằng dấu phẩy. Một câu lệnh case cũng có thể kiểm tra xem giá trị của một biến có nằm trong một phạm vi (range) các giá trị hay không như thể hiện trong đoạn mã sau: case temp_in_C

when -273

puts "Absolute zero"

when -273..20

puts "Cold"

when 20..25

puts "Comfortable"

when 25..10_000

puts "Hot"

else

puts "You must be joking!"

end

Câu lệnh else ở dưới cùng cuối cung cấp một phương án tổng thể. Nếu không có bất kỳ lệnh nào trước nó được thực thi, câu lệnh case sẽ hiển thị You must be joking!.

Hai chức năng cuối cùng của câu lệnh case cần phải được đề cập đến. Đầu tiên, giống như một câu lệnh if, một câu lệnh case trả về giá trị của lệnh sau cùng của nó được thực thi. Thứ hai, từ khóa then có thể được chèn vào sau when và đặt chúng lên trên cùng một dòng. Vì vậy, ví dụ đoạn mã trước đó có thể được viết lại như sau: ans = case temp_in_C

when -273 then "Absolute zero"

Page 26: Chuong 4,5 va 6 Pluin cho SketchUp

Chương V SketchUp Scripting by [email protected]

79

when -273..20 then "Cold"

when 20..25 then "Comfortable"

when 25..10_000 then "Hot"

else "You must be joking!"

end

puts ans

Không giống như các từ khóa when đặt ở phía trước nó, câu lệnh else không yêu cầu từ khóa then. Câu lệnh else và lệnh có thể được đặt trực tiếp trên cùng một dòng.

5.2 Thực thi có vòng lặp: while, until và for Các câu lệnh while, until và for của Ruby được gọi là câu lệnh lặp hoặc vòng lặp

bởi vì chúng có thể thực thi một tập hợp các lệnh và lặp đi lặp lại chúng nhiều lần. Câu lệnh lặp rất quan trọng khi bạn cần xử lý tất cả các phần tử của một mảng hoặc lặp lại tất cả các giá trị nằm trong một phạm vi-range. Ví dụ, nếu bạn cần gán tất cả các vector trong một mảng có một trăm phần tử, một vòng lặp có thể ( nên có ) được sử dụng thay vì một trăm dòng lệnh riêng biệt.

5.2.1 Vòng lặp: while và until Cũng giống câu lệnh if thực thi các lệnh theo một phép toán logic, câu lệnh while của

Ruby thực thi các lệnh lặp đi lặp lại cho đến khi một phép toán logic trả về true. Điều này được thể hiện trong đoạn mã sau: x = 5

while x > 0 # Continue loop as long as x > 0

print x, " " # Print the value of x

x -= 1 # Reduce x by 1

end

Nếu bạn đặt đoạn mã này trong một tập tin kịch bản và thực thi nó, trong giao diện Ruby console sẽ hiển thị : 5 4 3 2 1. Biến x ban đầu được gán bằng 5, vì điều kiện x>0 trả về true nên hai lệnh bên trong vòng lặp được thực thi. Lệnh thứ hai là x-=1 ( nghĩa là x=x-1) sẽ giảm giá trị của biến x đi 1 đơn vị nên biến x lúc này được gán là 4 vẫn thõa mãn điều kiện x>0, và hai lệnh trên lại được thực hiện thêm lần nữa. Cứ như vậy cho đến khi biến x giảm về bằng 0 thì điều kiện x>0 không còn đúng nữa, tức trả về false và vòng lặp kết thúc.

Điều quan trọng là phải hiểu rằng các lệnh bên trong một vòng lặp có thể kiểm soát số vòng lặp lại của chính nó. Nếu không có sự kiểm soát này thì vòng lặp hoặc là sẽ không bao giờ ngừng hoặc là sẽ không bao giờ bắt đầu. Ví dụ, câu lệnh while sau đây lặp sự hiển thị Looping! vô thời hạn. x = 5

while x > 0 # Never stops because x never changes

Page 27: Chuong 4,5 va 6 Pluin cho SketchUp

Chương V SketchUp Scripting by [email protected]

80

puts "Looping!"

end

Một vòng lặp không bao giờ kết thúc được gọi là một vòng lặp vô hạn. Điều này thường là kết quả của một lỗi nào đó.

Chức năng câu lệnh until của Ruby tương tự như câu lệnh while, nhưng đảo ngược lại. Vòng lặp while thực thi các lệnh nếu điều kiện là phép toán logic của nó trả về true và tiếp tục thực thi chúng miễn là phép toán logic trả về false. Vòng lặp until thì làm ngược lại: nó bắt đầu thực thi các lệnh nếu phép toán logic về false và tiếp tục thực thi cho đến khi phép toán logic của nó trả về true.

Một ví dụ sẽ làm rõ cách thức làm việc này. Vòng lặp until sau đây bắt đầu bởi vì biến y gán là “A” nên không bằng "E". Lệnh thứ hai trong vòng lặp thiết lập y bằng chữ cái tiếp theo của “A” ( từ "A" đến "B", "B" đến "C" và cứ như vậy ) và vòng lặp tiếp tục cho đến khi y được gán bằng "E". Điều đó nghĩa là vòng lặp tiếp tục cho đến khi phép toán logic y=="E" trả về true. y = "A"

until y == "E" # Continue loop until y equals "E"

print y, " "

y = y.next # Set y equal to the next letter

end

Nếu bạn đặt đọa mã này trong một tập tin kịch bản và thực thi nó, hộp thoại Ruby console của SketchUp sẽ hiển thị : A B C D.

Không có hướng dẫn rõ ràng về bạn nên sử dụng câu lệnh while hay until trong mã hóa. Cả hai đều phục vụ cùng một mục đích, do đó việc chọn cái nào hoàn toàn phụ thuộc vào vấn đề thuận tiện cho bạn khi sử dụng.

5.2.2 Vòng lặp for Vòng lặp while hoặc until lặp đi lặp lại sự thực thi các câu lệnh cho đến khi điều

kiện là phép toán logic trả về false hoặc true. Trong Ruby, một vòng for sẽ lặp lặp đi lặp lại các lệnh miễn là biến nằm trong một phạm vi-range các giá trị nhất định. Trong Ruby, phạm vi các giá trị được xác định bằng một trong hai cách sau: start..end (bắt đầu .. kết thúc) hoặc start...end. Cách đầu tiên ( có hai dấu chấm ) sẽ bao gồm cả giá trị end nhưng trong cách thứ hai ( có ba dấu chấm ) thì không. Sự khác biệt này được thể hiện trong các ví dụ sau: for count1 in 0..5

print count1, " "

end

for count2 in 0...5

Page 28: Chuong 4,5 va 6 Pluin cho SketchUp

Chương V SketchUp Scripting by [email protected]

81

print count2, " "

end

Trong vòng lặp đầu tiên, hộp thoại Ruby console sẽ hiển thị 0 1 2 3 4 5. Trong vòng lặp thứ hai, nó sẽ hiển thị 0 1 2 3 4. Mỗi vòng lặp bắt đầu với câu lệnh for và kết thúc là end. Từ khóa in dùng để ngăn cách giữa biến với phạm vi.

Các giá trị tạo nên phạm vi-range có thể là các số nguyên hoặc chuỗi, trừ các số thập phân thì không được. Có nghĩa là, "ABC".."CBA" là một phạm vi được chấp nhận trong một vòng lặp, nhưng 0.0 .. 5.0 thì không được chấp nhận. Các mảng trong ruby cũng có thể được sử dụng như trong ví dụ sau: alph_array = ["alpha", "bravo", "charlie", "delta"]

for aword in alph_array

print aword, " "

end

Hộp thoại Ruby console sẽ hiển thị alpha bravo charlie delta.

5.3 Biến lặp-Iterator và khối-Block Cho đến nay, các cấu trúc lệnh mà chúng ta đã xem xét (if, case, while, until,

for) gần tương tự với các cấu trúc lệnh trong các ngôn ngữ khác như C , C++ và Java. Bây giờ chúng ta sẽ xem xét biến lặp và khối, chúng không giống bất thứ gì ở trong C và C++. Tôi thấy đây là chủ đề rất khó để hiểu khi lần đầu tiên tôi học Ruby, nhưng tôi đã hiểu và trình bày một sự đánh giá tuyệt vời về khả năng của chúng.

Một biến lặp của Ruby là một kiểu phương thức đặc biệt có sẵn cho các mảng và đối tượng chứa đựng. Biến lặp thực hiện các nhiệm vụ về cơ bản là giống như vòng lặp for, nhưng làm việc với nó thì dễ dàng hơn. Một sự so sánh sẽ làm rõ điều này. Trong đoạn mã sau, biến lặp lặp thông qua một mảng có năm phần tử và hiển thị tên của từng phần tử: for name in five_array

print name, " "

end

Kết quả tương tự có thể được thực hiện chỉ với một dòng mã : five_array.each {|element| puts element}

Khi lệnh này được thực thi, phương thức each ra lệnh cho trình biên dịch của Ruby xử lý các câu lệnh trong dấu ngoặc nhọn { } cho mỗi phần tử trong mảng five_array. Có nghĩa là, nó ra lệnh cho trình biên dịch xử lý {|element| puts element} năm lần.

Một cái tên được đặt trong hai đường thẳng đứng || ( ở ví dụ này là |element|)được gọi là một phần giữ chỗ placeholder - nó nhận giá trị của từng phần tử mảng một khi biến lặp thực thi. Và trong trường hợp này, mỗi phần tử của five_array được thực thi thành công sẽ được gọi là element. Vì vậy, lệnh gọi ra puts element cho từng phần tử một thuộc mảng five_array để hiển thị giá trị của element trong phần giữ chỗ.

Page 29: Chuong 4,5 va 6 Pluin cho SketchUp

Chương V SketchUp Scripting by [email protected]

82

Không có gì đặc biệt về cái tên element trong ví dụ này, vì đoạn mã sau khi được thực thi sẽ trả về cùng một kết quả như trên:

five_array.each {|e| puts e}

Trong các đoạn mã trên, phương thức each được gọi là biến lặp và câu lệnh trong dấu ngoặc nhọn được gọi là khối. Khi biến lặp thực thi, câu lệnh khối sẽ được thực thi nhiều lần, mỗi lần thực thi là cho một phần tử thuộc mảng. Nhưng each không phải là biến lặp duy nhất trong lớp Array. Ba biến lặp hữu ích nhất được liệt kê như sau:

1. collect – thay đổi từng phần tử trong một mảng và trả về một mảng được cập nhật các thay đổi

2. each_index – đặt chỉ số vị trí index của từng phần tử mảng vào phần giữ chỗ, Index chứ không phải là giá trị của phần tử.

3. find – áp dụng một phép toán logic cho từng phần tử và trả về phần tử đầu tiên ( không phải là phần tử ở đầu mảng) mà kết quả của nó trả về một giá trị true.

Đoạn mã trong tập tin kịch bản sau minh họa cách thức chúng được sử dụng trong mã. Tôi đề nghị bạn nên thử nghiệm với chúng để tăng thêm sự hiểu biết của mình. Nếu sử dụng đúng cách, biến lặp có thể giúp bạn tiết kiệm rất nhiều thời gian mã hóa!

iterator_demo.rb

# Define the array

five_array = ["one", "two", "three", "four", "five"]

# Print the element indices

print "The array indices: "

five_array.each_index { |index| print index.to_s + " "}

# Capitalize the name of each element and add "o'clock" five_array = five_array.collect { |name| name.capitalize + " o'clock" }

# Print the new element names

print "\n\nThe array elements: "

five_array.each { |name| print name + " "}

# Print the first element whose first letter is less than "G"

print "\n\nFirst element less than G: "

puts five_array.find { |name| name < "G"}

Thực thi kịch bản trên sẽ tạo được kết quả sau: The array indices: 0 1 2 3 4

The array elements: One o'clock Two o'clock Three o'clock Four o'clock Five o'clock

Page 30: Chuong 4,5 va 6 Pluin cho SketchUp

Chương V SketchUp Scripting by [email protected]

83

First element less than G: Four o'clock

Biến lặp và khối là đặc biệt quan trọng trong SketchUp, nơi chứa đựng tất cả hình dạng, vật liệu, lớp và page của dự án SketchUp trong một mảng giống như cái công tơ nơ. Phần tiếp theo cung cấp các ví dụ về cách thức sử dùng biến lặp để dễ dàng tìm và xử lý các yếu tố của mô hình trong SketchUp.

5.4 Biến lặp và tập hợp các yếu tố của mô hình trong SketchUp Nhìn qua Phụ lục A, bạn sẽ nhận thấy rằng rất nhiều các tên lớp trong API SketchUp là

số nhiều - Entities, Materials, Pages, Layers, Styles, RenderingOptions và nhiều hơn nữa. Các tập hợp này có thể được truy xuất như các mảng, có nghĩa là các phần tử của chúng có thể thường được truy xuất bằng cách sử dụng biến lặp giống như each.

Lặp đi lặp lại qua một đối tượng Entities của model là một nhu cầu thường xuyên: bạn có thể cần phải thu thập tất cả các đối tượng đỉnh-Vertex, ẩn tất cả các cạnh-Edge hay tìm kiếm các bề mặt-Face mà vector pháp tuyến của nó theo một hướng nhất định. Những nhiệm vụ này có thể được thực hiện với vòng lặp for, nhưng chúng có thể được thực hiện bằng một cách đơn giản hơn với biến lặp và các khối. Phần này trình bày các ví dụ về ba công việc thường xuyên sử dụng biến lặp.

5.4.1 Tìm kiếm một bề mặt theo một hướng nhất định Giả sử bạn đã tạo ra một khối ba chiều với rất nhiều mặt -Face và cạnh-Edge, và bạn

muốn tìm bề mặt-Face mà vector pháp tuyến của nó cùng chiều với trục x dương. Quá trình này bao gồm ba bước :

1. Truy xuất đối tượng Entities của model.

2. Đối với mỗi yếu tố mô hình, định rõ nếu typename của nó là Face.

3. Đối với Face, định rõ nếu vector pháp tuyến của nó là [1, 0, 0].

Đoạn mã trong tập tin kịch bản sau thể hiện cách sử dụng biến lặp trong mã hóa:

find_face.rb

# Create the figure

ents = Sketchup.active_model.entities

face = ents.add_face [-1, -1, 0],[-1, 1, 0],[1, 1, 0],[1, -1, 0]

face.pushpull 1

# Find the face that points in the x-direction

xface = ents.find {|ent| ent.typename == "Face" && ent.normal == [1, 0, 0]}

puts "The face is: " + xface.to_s

Phương thức find kết hợp hai sự so sánh. Đầu tiên kiểm tra xem Entity có phải là

một Face hay không và thứ hai là kiểm tra xem vector pháp tuyến của Face đó có phải là [1, 0, 0] hay không. Bạn không thể đảo ngược thứ tự của các phép toán logic này, nếu bạn cố gắng để

Page 31: Chuong 4,5 va 6 Pluin cho SketchUp

Chương V SketchUp Scripting by [email protected]

84

có được vector pháp tuyến của một Entity thì Entity có thể không phải là Face và một lỗi sẽ xảy ra.

5.4.2 Tập hợp các đối tượng Vertex (đỉnh) trong một mảng

Khi bạn xuất ra một mô hình SketchUp sang định dạng file khác, SketchUp thường xuyên liệt kê các điểm có trong dự án SketchUp đó. Đoạn mã trong tập tin kịch bản sau tạo ra một mô hình, biến lặp thông qua từng Edge một để tìm đối tượng Vertex (đỉnh) của nó.

find_vertices.rb

# Create the figure

ents = Sketchup.active_model.entities

face = ents.add_face [-1, -1, 0],[-1, 1, 0],[1, 1, 0],[1, -1, 0]

face.pushpull 1

# Create and populate the array

vertex_array = []

ents.each {|ent|

if ent.typename == "Edge"

vertex_array = vertex_array | ent.vertices

end

}

vertex_array.each {|pt| puts "Point: " + pt.position.to_s}

Trong trường hợp này, mảng chỉ chứa các đối tượng Vertex duy nhất. Điều này là do

kết hợp phép toán | để ngăn ngừa mảng vertex_array nhận các đối tượng Verter bị trùng lặp.

5.4.3 Làm mượt các cạnh của một đối tượng

Trong SketchUp, bạn có thể làm mượt các cạnh của một đối tượng bằng cách chọn đối tượng, kích chuột phải và chọn Soften/Smooth Edges trên menu ngữ cảnh xuất hiên. Nó không phải là đơn giản trong mã hóa, nhưng trong tập tin kịch bản sau biến lặp thông qua từng cạnh-Edge trong model, định rõ nếu điểm đầu và cuối của nó mang hoành độ dương thì thiết lập thuộc tính Edge's smooth của nó là true.

smooth_edges.rb

# Create the figure

ents = Sketchup.active_model.entities

face = ents.add_face [-1, -1, 0],[-1, 1, 0],[1, 1, 0],[1, -1, 0]

Page 32: Chuong 4,5 va 6 Pluin cho SketchUp

Chương V SketchUp Scripting by [email protected]

85

face.pushpull 1

# Smooth the edges with positive x-values

ents.each {|ent|

if ent.typename == "Edge" &&

ent.start.position.x > 0 && ent.end.position.x > 0

ent.smooth = true;

end

}

Nếu bạn thực thi kịch bản này, bạn có thể xác minh rằng nó đã làm việc một cách chính

xác bằng cách mở hộp thoại Entity Info và nhấp vào từng cạnh thuộc đối tượng. Chỉ có các cạnh mà điểm đầu và cuối của nó là hoành độ dương thì sẽ được làm mượt-smooth.

5.5 Làm việc với tập tin trong Ruby Khi trải nghiệm của bạn về SketchUp nhiều lên thì bạn sẽ thấy rằng mình đã thực hiện

với rất nhiều loại tập tin khác nhau, chẳng hạn như tập tin dự án (*.skp), tập tin vật liệu (*.skm), tập tin phong cách ( *.style) và các tập tin component (*.skp). Bạn cũng có thể thường xuyên muốn nhập vào hoặc xuất ra các mô hình từ các phần mềm đồ họa khác. Vì lý do này, điều quan trọng là phải biết làm thế nào để tìm kiếm, đọc và chỉnh sửa các tập tin .

Ruby cung cấp hai lớp cơ sở cho các hoạt động của tập tin : Dir và File. Lớp đầu tiên đại diện cho đường dẫn của thư mục làm việc hiện tại và nội dung bên trong thư mục. Lớp thứ hai cung cấp các phương thức để tạo, đọc và chỉnh sửa các tập tin mới và hiện có. Phần này tìm hiểu cả hai, và cho thấy các phương thức trong mô-đun Sketchup được sử dụng để cho nó dễ dàng truy xuất các tập tin theo đường dẫn liên quan đến thư mục cấp cao của SketchUp.

5.5.1 Tạo và mở tập tin

Các phương thức new và open trong lớp File được gọi ra theo cùng một cách và thực thi các nhiệm vụ tương tự nhau: Chúng đều tạo và mở một tập tin mới hoặc mở một tập tin hiện có, và chúng đều trả về một đối tượng File. Cả hai phương thức đều yêu cầu hai tham số chuỗi-String: tên của tập tin và dấu hiệu xác định chế độ hoạt động của tập tin khi nó được mở ra. Bảng sau liệt kê các chế độ có sẵn .

Dấu hiệu Chế độ Miêu tả r Chỉ đọc Mở một tập tin hiện có chỉ để đọc dữ liệu từ đầu tập tin đó ( đây là chế độ mặc

định) r+ Đọc-ghi Mở một tập tin hiện có để đọc từ đầu tập tin đó hoặc ghi dữ liệu lên trên đầu w Chỉ ghi Xóa các nội dung bên trong một tập tin hiện có hoặc tạo một nội dunng mới.

Mở tập tin để ghi dữ liệu vào đầu tập tin. w+ Đọc-ghi Xóa các nội dung bên trong một tập tin hiện có hoặc tạo một nội dunng mới.

Mở tập tin để đọc hoặc ghi dữ liệu vào đầu tập tin. a Chỉ ghi Tạo ra một tập tin mới hoặc mở một tập tin hiên có. Ghi dữ liệu vào cuối tập

tin. a+ Đọc- ghi Tạo ra một tập tin mới hoặc mở một tập tin hiên có. Đọc hoặc ghi dữ liệu vào

cuối tập tin.

Page 33: Chuong 4,5 va 6 Pluin cho SketchUp

Chương V SketchUp Scripting by [email protected]

86

Chú ý đến sự khác biệt giữa chế độ w/w+ với chế độ a/a+. Chế độ w/w+ bắt đầu ghi vào đầu của tập tin và xóa nội dung hiện có của tập tin nếu nó có. Chế độ a/a+ ghi dữ liệu vào cuối của tập tin và không xóa nội dung hiện có của tập tin.

Ví dụ, lệnh sau đây tạo ra một tập tin gọi là new_file.txt, mở nó trong chế độ đọc-ghi, và trả về một đối tượng File:

new_file = File.new "new_file.txt", "w+"

Kết quả tương tự có thể được thực hiện với phương thức open như sau: new_file = File.open "new_file.txt", "w+"

Nếu tập tin cần mở bằng open mà không tồn tại thì nó sẽ tạo ta tập tin mới.

Việc sử dụng chế độ mặc định của File.open và File.new để mở một tập tin hiện có trong chế độ chỉ đọc. Ví dụ, mỗi lệnh sau đây sẽ mở ra tập tin old_file.txt chỉ để đọc.

file = File.new "old_file.txt", "r"

file = File.open "old_file.txt", "r"

file = File.new "old_file.txt"

file = File.open "old_file.txt"

Nếu bạn gọi ra new hoặc open với chế độ r hoặc r+ thì yêu cầu các tập tin được gọi phải có mặt trong thư mục hiện hành. Nếu bạn cố thử để tạo ra một tập tin bằng cách sử dụng các chế độ này, bạn sẽ nhận được một lỗi ENOINT vì các tập tin không tồn tại.

Một khi bạn đã tạo ra một tập tin, bạn có thể thiết lập các quyền hạn cho nó bằng phương thức chmod. Phương thức này chấp nhận một giá trị số theo quy ước được thiết lập bởi các quyền hạn truy xuất tập tin UNIX. Nghĩa là giá trị số này bao gồm ba giá trị bát phân (octal): các quyền hạn cho chủ sở hữu, các quyền hạn cho nhóm, và các quyền hạn cho người dùng khác. Một giá trị bát phân bao gồm ba giá trị nhị phân (binary) và mỗi giá trị nhị phân là 1 bit. • Bit đầu tiên của một giá trị bát phân xác định xem tập tin có thể đọc được không. • Bit thứ hai của một giá trị bát phân xác định xem tập tin có thể ghi lên được không.

• Bit thứ ba của một giá trị bát phân xác định xem tập tin có thể thực thi được không

Trong nhị phân (0 và 1) thì 0 là không được và 1 là được quyền. Bảng chuyển đổi một số từ nhị phân sang bát phân.

000 --> 0

001 --> 1

010 --> 2

011 --> 3

100 --> 4

101 --> 5

110 --> 6

111 --> 7

Ví dụ, bạn muốn tạo ra một tập tin gọi là ex_file và bạn muốn chủ sở hữu (là bạn) có quyền đọc, ghi và thực thi ( 111 = 7). Bạn muốn các thành viên của nhóm có quyền đọc và thực

Page 34: Chuong 4,5 va 6 Pluin cho SketchUp

Chương V SketchUp Scripting by [email protected]

87

thi ( 101 = 5) và những người dùng khác chỉ có quyền đơn giản là đọc ( 100 = 4). Trong trường hợp này, bạn sẽ thực hiện các lệnh :

new_file = File.new "ex_file", "w+"

new_file.chmod 754

Hoạt động thực tế của phương thức chmod phụ thuộc vào các chính sách trong hệ điều hành của bạn.

5.5.2 Đọc dữ liệu từ tập tin

Khi một tập tin đã được mở trong chế độ đọc hoặc đọc-ghi, có rất nhiều phương thức sẵn có để truy xuất dữ liệu của nó. Chúng khác nhau tùy theo bản chất của dữ liệu được đọc - byte hoặc các dòng văn bản, và xem hoạt động đó cần được thực thi một lần hay nhiều lần. Hầu hết các phương thức sẵn có được liệt kê như sau:

• getc/readchar – đọc một byte từ tập tin

• read – đọc nhiều byte từ tập tin và lưu trữ chúng trong biến trung gian nào đó

• each_byte – biến lặp thông qua các byte trong tập tin

• gets/readline – đọc một dòng văn bản tập tin

• each/each_line – biến lặp thông qua các dòng văn bản trong tập tin

• readlines – tạo ra một mảng từ các dòng văn bản trong tập tin

Cả hai phương thức getc và phương thức readchar đều trả về giá trị số của byte được đọc. Phương thức chr chuyển đổi số này sang ký tự tương ứng của nó. Ví dụ, nếu từ đầu tiên trong một tập tin là That, phương thức getc và readchar sẽ trả về các kết quả sau :

file.getc

84 # Corresponds to 'T'

file.getc.chr

h

file.readchar

97 # Corresponds to 'a'

file.readchar.chr

t

Hoạt động đọc sẽ bắt đầu từ đầu của tập tin ( ở trên là bắt đầu từ ký tự T) và thực thi đọc một ký tự cho một lần lệnh, lần lệnh thứ hai sẽ đọc ký tự tiếp theo. Phương thức rewind thiết lập lại vị trí sẽ được đọc hoặc ghi tiếp theo ( có thể gọi là vị trí con trỏ) trở về vị trí bắt đầu ở đầu tập tin.

Trong đoạn mã sau thiết lập lại vị trí con trỏ trở về đầu của một tập tin đang mở có chứa duy nhất từ That. Nó gọi ra read để lưu trữ bốn byte trong một biến trung gian nào đó và sau đó cộng các trị số byte của chúng lại với nhau bằng cách sử dụng phương thức each_byte:

file.rewind

Page 35: Chuong 4,5 va 6 Pluin cho SketchUp

Chương V SketchUp Scripting by [email protected]

88

buff = file.read

That

file.rewind

sum = 0

file.each_byte {|b| sum = sum + b}

sum

401

( Vì từ That có tổng các trị số byte là 84+104+97+116=401)

Nếu không có tham số kèm theo, phương thức read đọc tất cả các byte có trong một tập tin và trả chúng về dưới dạng một chuỗi-String. Nó có thể mang theo hai tham số tùy chọn, tham số đầu tiên xác định có bao nhiêu byte cần được đọc, tham số thứ hai xác định một biến kiểu chuỗi-String hiện có để giữ các byte được đọc. Ví dụ, lệnh sau đây đọc ba byte từ đối tượng file và đặt chúng trong một biến kiểu chuỗi gọi là buffer:

buffer = ""

file.read 3, buffer

Hai phương thức gets và readline đều trả về một chuỗi chứa các ký tự từ vị trí con trỏ đến cuối dòng hiện tại. Tương tự như vậy, phương thức each và each_line là biến lặp thông qua các dòng trong tập tin. Phương thức readlines tạo một mảng từ các dòng trong tập tin, và được sử dụng như sau:

arr = file.readlines

["One\n", "Two\n", "Three\n", "Four\n"]

Điều này cho phép bạn truy xuất vào dữ liệu tập tin bằng cách sử dụng thứ tự của dòng. Bạn có thể thâm một tham số cho phương thức này như hình sau đây :

arr = file.readlines ","

["One\nTwo\nThree\nFour\n"]

5.5.3 Ghi dữ liệu lên tập tin

Trong lớp File, các phương thức sẵn có để ghi dữ liệu tương tự như các phương thức dùng để đọc dữ liệu, nhưng có một chút sự khác biệt giữa các ký tự được ghi và dòng văn bản. Các phương thức cơ bản được đưa ra như sau:

• putc – ghi một byte hoặc một ký tự lên tập tin

• print/write – ghi một chuỗi lên tập tin (không có dòng mới )

• puts - ghi một chuỗi lên tập tin (thêm dòng mới)

• printf – ghi một chuỗi được định dạng lên tập tin

Page 36: Chuong 4,5 va 6 Pluin cho SketchUp

Chương V SketchUp Scripting by [email protected]

89

Phương thức putc có thể chấp nhận tham số là một số ( số thập phân từ 0 đến 255-trong mã ASCII ) tương ứng với một byte hoặc một ký tự. Ví dụ, hai lệnh sau đây đều ghi ký tự A lên tập tin được đại diện bởi đối tượng file:

file.putc 65 # 65 is the ASCII code for the character A

file.putc "A"

Phương thức print, write và puts tương tự, và ghi một chuỗi vào tập tin. Sau khi ghi thì phương thức print trả về nil và phương thức write trả về số lượng ký tự của chuỗi trong hộp thoại Ruby console. Phương thức puts chèn một dòng mới sau mỗi tham số (ví dụ: file.puts “Ah”,”cd”)và nó có thể chấp nhận tham số là một mảng có các phần tử là chuỗi. Điều này được thể hiện bằng các lệnh sau: colors = ["Red", "Yellow", "Green", "Blue"]

file.puts colors

Lệnh thứ hai sẽ ghi mỗi phần tử của mảng colors là một dòng riêng biệt trong tập tin.

Phương thức cuối cùng được liệt kê printf sử dụng các mã hóa định dạng để ghi một chuỗi được định dạng lên tập tin. Các mã hóa gần như là giống như việc sử dụng printf trong ngôn ngữ lập trình C .

5.5.4 Đóng và xóa một tập tin

Phương thức close lưu giữ lại tất cả các hoạt động ghi lên tập tin và ngăn chặn hoạt động đọc và ghi thêm nữa lên tập tin đó, nghĩa là nó giải phóng cho tập tin và không tiếp tục truy xuất nữa. Phương thức delete xóa bỏ các tập tin trên máy tính của bạn. Điều này được thể hiện trong các ví dụ sau:

File.delete "example.txt"

Một tập tin cần phải được đóng trước khi nó có thể bị xóa. Nếu bạn cố gắng để xóa một tập tin đang mở, bạn sẽ nhận được một lỗi nói rõ rằng quyền hạn đó đã bị từ chối.

Đoạn mã trong tập tin kịch bản sau cho thấy cách mà phương thức close và delete được sử dụng. Kịch bản ghi lên một tập tin, đọc từ tập tin, đóng tập tin và xóa tập tin đó.

file_ops.rb

# Create/open a file in read-write mode

f = File.open "example.txt", "w+"

# Write an array of five Strings to the file

nums = ["One", "Two", "Three", "Four", "Five"]

f.puts nums

# Rewind the file, read its lines, and print the third line

f.rewind

arr = f.readlines

puts arr[2]

Page 37: Chuong 4,5 va 6 Pluin cho SketchUp

Chương V SketchUp Scripting by [email protected]

90

# Close the file

f.close

puts "Closed? " + f.closed?.to_s

# Delete the file File.delete "example.txt"

puts "Exists? " + File.exists?("example.txt").to_s

Lưu ý tới sự khác biệt trong cách sử dụng giữa các phương thức close và delete.

Phương thức close hoạt động trên một đối tượng File nên nó được gọi ra là f.close. Cũng như File.new và File.open, delete là một phương thức lớp ( xem lại khái niệm ở chương 2) nên có nghĩa là nó phải được gọi ra như sau File.delete.

5.5.5 Thư mục của tập tin Trong từng ví dụ trên, các tập tin đã được tạo ra hoặc mở từ bên trong “thư mục làm

việc”-woking directory. Đây là nền tảng của tất cả các đường dẫn có liên quan tới chúng, chẳng hạn như ../../Sample.txt. Lớp Dir cung cấp phương thức để truy xuất vào thư mục làm việc, tạo thư mục mới và thống kê những thứ được chứa đựng bên trong của thư mục hiện có.

Phương thức pwd (viết tắt của Print Working Directory ) hiển thị đường dẫn chi tiết của “thư mục làm việc” hiện tại:

Dir.pwd

C:/Documents and Settings/******/Desktop (Win XP) C:/Windows/System32 ( Win7 64b)

Phương thức chdir dùng để thay đổi thư mục làm việc tới thư mục khác.

Trong khi các tập tin thường được tạo ra bởi File.new và File.open thì thư mục được tạo ra với Dir.mkdir. Nếu nó thành công trong việc tạo ra một thư mục mới, phương thức này trả về 0 và nó không phải là một đối tượng. Để có được một đối tượng Dir đại diện cho một thư mục, bạn cần phải sử dụng Dir.new ngay sau Dir.mkdir. Điều này được thể hiện trong các ví dụ sau:

Dir.mkdir "folder"

0

new_dir = Dir.new "folder"

new_dir.class

Dir

Nếu bạn gọi Dir.new với tham số là tên của một thư mục không tồn tại, bạn sẽ nhận được một lỗi nói rằng không có thư mục đó.

Để tạo một thư mục mới trong một địa chỉ nào đó hãy làm theo cách sau:

Dir.mkdir "C:/folder" để tạo ra thực mục folder trông ổ đĩa C

Phương thức Close sẽ đóng đối tượng Dir và ngăn chặn các hoạt động đọc tên các tập tin của nó thêm nữa. Phương thức Dir.rmdir xóa một thư mục trên máy tính của bạn, nhưng chỉ dành cho các thư mục rỗng .Nếu thư mục không rỗng, rmdir tạo ra một lỗi.

Page 38: Chuong 4,5 va 6 Pluin cho SketchUp

Chương V SketchUp Scripting by [email protected]

91

5.5.6 Truy xuất tập tin trong một thư mục

Một khi bạn có một đối tượng Dir đang mở, bạn có thể đọc tên các tập tin trong thư mục theo cách tương tự như bạn đọc văn bản từ một tập tin văn bản. Có nghĩa là, bạn có thể gọi ra phương thức read để đọc lần lượt tên tập tin có trong thư mục. Hơn nữa, phương thức entries trong lớp Dir hoạt động giống như phương thức readlines của lớp File, nhưng thay vì tạo ra một mảng từ các dòng văn bản của tập tin, nó tạo ra một mảng từ tên của các tập tin được chứa đựng trong thư mục .

Một ví dụ sẽ làm rõ điều này. Một thư mục gọi là colors có chứa ba tập tin có tên là: red, yellow và blue. Đoạn mã sau tạo một đối tượng Dir và tạo ra một mảng với các phần tử là chuỗi từ tên của các tập tin trong nó:

color_dir = Dir.new "colors"

arr = color_dir.entries

[".", "..", "blue", "red", "yellow"]

arr2 = color_dir.entries

[]

Lần thứ hai gọi entries ra thì kết quả trả về một mảng rỗng, vì lần gọi ra trước đó đã đọc toàn bộ tên các file có trong thư mục. Phương thức rewind sẽ đặt con trỏ lên đầu của danh sách thư mục.

Ngoài entries, bạn có thể gọi ra biến lặp thông qua tên các tập tin trong thư mục. Đoạn mã trong tập tin kịch bản sau tạo ra một thư mục gọi là colors và chèn các tập tin được gọi là red, yellow và blue. Sau đó, sử dụng each để tạo và khởi chạy một mảng các đối tượng File từ tên của các tập tin có trong thư mục colors:

dir_demo.rb

# Create the directory and its files

Dir.mkdir "colors"

File.new("./colors/red", "w+").close

File.new("./colors/yellow", "w+").close

File.new("./colors/blue", "w+").close

# Create a Dir object and populate the file array

color_dir = Dir.new "colors"

file_array = []

color_dir.each {|f|

if f[0].chr != "."

file_array << File.new("./colors/" + f)

end

Page 39: Chuong 4,5 va 6 Pluin cho SketchUp

Chương V SketchUp Scripting by [email protected]

92

}

# Display the names of the files in the file array

file_array.each {|f| puts f.path}

# Close and delete the files

file_array.each {|f|

filename = f.path

f.close

File.delete filename

puts "Deleted " + filename

}

# Close and delete the directory

color_dir.close

Dir.rmdir "colors"

Đoạn mã này tạo một đối tượng File cho mỗi tập tin mà tên của đối tượng đầu tiên

không phải là dấu chấm như kết quả ở ví dụ phần 5.5.6 [".", "..", "blue", "red", "yellow". Hai tên file là “.” và “..” đại diện cho thư mục hiện tại và một thư mục cha mà các file đó nằm trong. Bạn không thể tạo các đối tượng File từ các thư mục đặc biệt này.

Sau khi các tập tin được tạo ra, các biến lặp của kịch bản này thông qua từng đối tượng File trong mảng và sử dụng phương thức path để có được tên của chúng. Sau đó, nó đóng từng đối tượng File và gọi ra File.delete để xóa bỏ các tập tin này trên máy tính của bạn. Cuối cùng, nó đóng và xóa thư mục colors.

5.6 Truy xuất tập tin của SketchUp

Ngoài các phương thức trong lớp Dir và File của Ruby, bạn cũng có thể truy xuất các tập tin và thư mục bằng cách sử dụng mô-đun Sketchup. Bốn phương thức quan trọng được liệt kê như sau:

1. file_new – Mở SketchUp với một đối tượng model mới ( tức tạo một dự án SketchUp mới).

2. open_file - Mở SketchUp với một đối tượng model trong tập tin hiện có ( tức là mở một dự án SketchUp đang được lưu trên máy tính).

3. find_support_file - Trả về đường dẫn tới một tập tin trong thư mục cấp cao nhất của nó

4. find_support_files - Trả về các đường dẫn tới các tập tin trong thư mục cấp cao nhất của nó.

Hai phương thức đầu tiên thay đổi đối tượng model hiện tại của SketchUp. Phương thức file_new mở SketchUp với một đối tượng model trống rỗng, và nó không tạo ra một tập tin để lưu model này, vì vậy nó phải được lưu với phương thức Model.save.

Page 40: Chuong 4,5 va 6 Pluin cho SketchUp

Chương V SketchUp Scripting by [email protected]

93

Phương thức Model.save lưu đối tượng model thành một tập tin nhưng không mở chúng trong SketchUp. Để mở tập tin lưu nó, bạn cần phải gọi ra phương thức thứ hai open_file. Đoạn mã trong tập tin kịch bản sau cho thấy cách thức mà những phương thức này làm việc cùng nhau. Nó sẽ mở ra một đối tượng model trống rỗng và thêm một hình dạng vào trong nó. Sau đó, nó lưu thành tập tin example.skp và mở tập tin này trong SketchUp.

su_file.rb

# Create a new design

Sketchup.file_new

ents = Sketchup.active_model.entities

face = ents.add_face [-1, -1, 0],[-1, 1, 0],[1, 1, 0],[1, -1, 0]

face.pushpull 1

# Save the design and open it in SketchUp

Sketchup.active_model.save "example.skp"

Sketchup.open_file "example.skp"

Trong khi cài đặt, SketchUp tạo ra một thư mục gọi là Google SketchUp # , trong đó #

là số của phiên bản SketchUp ( đây là thư mục của các bản tính từ bản 8 quay về trước, còn bản 2013 thì tên thư mục là SketchUp 2013). Chúng ta sẽ xem thư mục này là thư mục cấp cao của SketchUp. Hai phương thức về tập tin trong mô-đun Sketchup là find_support_file và find_support_files đều trả về đường dẫn có liên quan đến thư mục cấp cao này.

Phương thức find_support_file chấp nhận hai tham số: tên của tập tin sẽ được tìm và thư mục nằm trong thư mục cấp cao chứa tập tin. Ví dụ, lệnh sau đây cung cấp đường dẫn đến tập tin Blinds/Blinds_Weave.skm trong thư mục Materials của thư mục cấp cao SketchUp 2013:

Sketchup.find_support_file "Blinds/Blinds_Weave.skm", "Materials"

C:/Program Files (x86)/SketchUp/SketchUp 2013/

Materials/Blinds/Blinds_Weave.skm

( Ví dụ cho SketchUp 2013 trên Win 7-64bit)

Trở về phương pháp nil nếu tập tin không thể tìm thấy .

Một công việc phổ biến trong SketchUp là tìm đường dẫn đến thư mục Plugins của nó. Công việc này được thực hiện với lệnh sau đây:

Sketchup.find_support_file "Plugins", ""

Để tìm thư mục Ch5 trong thư mục cấp cao Plugins thì bạn phải sử dụng như sau: Sketchup.find_support_file "Ch5", "Plugins"

Phương thức find_support_files hoạt động giống như find_support_file , nhưng tham số chấp nhận một “đuôi tập tin” (ví dụ: skm, rb, rbs…) và trả về một mảng bao gồm

Page 41: Chuong 4,5 va 6 Pluin cho SketchUp

Chương V SketchUp Scripting by [email protected]

94

các đường dẫn của các tập tin có đuôi như thế trong thư mục được chỉ định. Ví dụ, lệnh sau đây trả về một mảng chứa các đường dẫn cho tất cả các tập tin *. skm trong thư mục Materials/Blinds. Sketchup.find_support_files "skm", "Materials/Blinds"

Nếu tham số “đuôi tập tin” để trống, phương thức này sẽ trả về một mảng bao gồm các đường dẫn của tất cả các tập tin và các thư mục con trong thư mục được chỉ định. Sketchup.find_support_files "", "Plugins"

5.7 Kết thúc chương

Chương này đã đi quá sâu vào những thứ mà tôi gọi là chủ đề về hai tính năng bậc trung của Ruby : cấu trúc điều khiển và hoạt động tập tin. Các đối tượng này sẽ đóng một vai trò quan trọng trong các chương tiếp theo. Biến lặp và khối đặc biệt quan trọng, câu lệnh làm cho nó có thể lặp liên tục thông qua các phần tử của một tập hợp hoặc mảng mà chỉ với một dòng mã. Một khi bạn bắt đầu sử dụng biến lặp và khối một cách thuần thục, bạn sẽ không bao giờ quay trở lại cấu trúc lệnh for và while nữa.

Phần thứ hai của chương này trình bày về truy xuất tập tin trong cả Ruby và SketchUp. Lớp File của Ruby cung cấp phương thức để thực hiện các hoạt động cơ bản về tập tin: tạo, mở, đọc, ghi, đóng và xóa. Lớp Dir cung cấp phương thức truy xuất vào thư mục và xác định tên của các tập tin bên trong chúng. Cuối cùng, các mô-đun Sketchup cung cấp hai cặp phương thức liên quan đến tập tin, cặp phương thức đầu tiên mở phần mềm SketchUp với một tập tin mới hoặc hiện có và cặp thứ hai trả về đường dẫn đến các tập tin nằm trong thư mục cấp cao của SketchUp.

Page 42: Chuong 4,5 va 6 Pluin cho SketchUp

Chương VI SketchUp Scripting by [email protected]

95

Mầu sắc, texture và vật liệu

Page 43: Chuong 4,5 va 6 Pluin cho SketchUp

Chương VI SketchUp Scripting by [email protected]

96

Tại thời điểm này, bạn đã có những khái niệm khá đầy đủ về cách thức tạo ra các đối tượng mô hình của SketchUp trong mã hóa, chẳng hạn như cạnh và bề mặt. Chương này sẽ chỉ cho bạn biết cách làm thế nào để thiết lập sự hiển thị của chúng trong dự án SketchUp. Cụ thể, chương này giải thích làm thế nào để tạo các đối tượng vật liệu-Material và áp chúng lên các đối tượng mô hình mà chúng ta đã bắt gặp trong các chương trước. Mặc dù tên là vật liệu- Material nhưng các đối tượng này không chỉ rõ tính chất vật lý, tỷ trọng hoặc trọng lượng riêng. Mục đích duy nhất của một Material trong SketchUp là cấu hình sự hiển thị bên ngoài của các đối tượng mô hình trong dự án.

Có ba cách để chỉ rõ nét đặc trưng của một vật liệu: bằng màu sắc-Color, bằng hoa văn-Texture và Color với Texture. Một Color cấu tạo từ ba màu thành phần là đỏ, xanh lá cây và xanh nước biển cùng với độ mờ đục của nó. Một Texture là một hình ảnh được lặp đi lặp lại từ bên này đến bên kia của một bề mặt giống như một hoa văn của giấy dán tường. Lưu ý rằng Texture không có mối liên hệ với Image đã được trình bày trong chương 4.

6.1 Vật liệu. Chương 3 giải thích model của SketchUp đã lưu trữ các đối tượng Entity trong một

đối tượng chứa đựng Entities như thế nào. Tương tự như vậy, các đối tượng Material được lưu trữ trong một đối tượng Materials. Phần này giải thích cả đối tượng Material lẫn lớp Materials, nhưng trước khi chúng ta bắt đầu mã hóa thì điều quan trọng là phải xem lại cách thức mà vật liệu được quản lý trong giao diện sử dụng của SketchUp.

6.1.1 Vật liệu và quản lý chúng trong giao diện sử dụng của SketchUp. Trong thư mục cấp cao của SketchUp, bạn sẽ tìm thấy một thư mục có tên Materials

chứa các thư mục con nằm trong nó. Mỗi một thư mục con chứa nhiều tập tin vật liệu ( *.skm ) và chúng có thể được sử dụng để chỉ định tính chất vật liệu của các đối tượng mô hình trong dự án SketchUp. Hộp thoại Materials trong SketchUp là nơi mà bạn có thể lựa chọn chúng trong số các vật liệu có sẵn này.

Nếu bạn không hiểu rõ các vật liệu của SketchUp, tôi khuyên bạn nên thực hiện các bước

sau: 1. Mở phần mềm SketchUp, kích chọn công cụ Rectangle và tạo ra một bề mặt hình chữ

nhật với kích thước bất kỳ.

Page 44: Chuong 4,5 va 6 Pluin cho SketchUp

Chương VI SketchUp Scripting by [email protected]

97

2. Trên menu chính của SketchUp, mở hộp thoại Materials bằng cách chọn Window> Materials. Trong hình trên hiển thị các bộ sưu tập mẫu vật liệu. Sự hiển thị này tương ứng với thư mục cấp cao Materials của SketchUp, và các bộ sưu tập được hiển thị trong hộp thoại tương ứng với thư mục con của Materials. Mỗi một bộ sưu tập đều có chứa một nhóm các mẫu vật liệu khác nhau.

3. Trong hộp thoại, kích chọn vào bộ sưu tập có tên là Asphalt and Concrete. Khi đó một loạt các hình ảnh thu nhỏ (Thumbnail) sẽ xuất hiện. Di chuyển con trỏ chuột lên hình ảnh trên cùng phía bên trái, một tooltip xuất hiện hiển thị tên của mẫu vật liệu: Asphalt_new. Kích chuột vào hình ảnh này để Asphalt_new là loại vật liệu hiện hành.

4. Kích vào hình chữ nhật bạn đã dựng trong không gian làm việc của SketchUp. Vật liệu mà bạn chọn ở bước trên sẽ được áp cho toàn bộ bề mặt.

5.Trong hộp thoại Materials, chọn bộ sưu tập Color-Named. Các mẫu vật liệu bên trong bộ sưu tập Asphalt and Concrete dựa trên hình ảnh ( hay chính xác là Texture), nhưng các mẫu vật liệu trong bộ sưu tập này được dựa trên màu sắc có tên, chẳng hạn như as 0006_Pink.

6. Kích chuột vào một trong các mẫu vật liệu mầu sắc. Khi đó vật liệu màu sắc này sẽ thay thế Asphalt_new làm vật liệu hiện hành. Nếu bạn kích vào bề mặt hình chữ nhật thì bề mặt này sẽ có màu sắc mà bạn đã chọn.

7. Trong hộp thoại Materials kích vào biểu tượng để mở ra hộp thoại Create materials…, cho phép bạn đặt tên cho một loại vật liệu mới và cấu hình màu sắc và kết cấu-texture của nó.

Bạn có thể cấu hình mầu sắc cho vật liệu bằng bánh xe màu sắc (Color wheel) và thanh trượt màu sắc cua nó. Hoặc bạn có thể cấu hình màu sắc của nó theo các định dạng sau:

• HLS : Hue-tông màu, Lightness-độ sáng, Saturation-độ bão hòa màu. Hay còn được gọi là HSL.

• HSB - Hue-tông màu, Saturation-độ bão hòa màu, Brightness -độ chói.

• RGB – Red-đỏ, Green-xanh lá cây, Blue-xanh nước biển

Trong hộp thoại, phần Texture nằm bên dưới phần Color. Nếu bạn đánh dấu vào hộp chọn Use texture image, một hộp thoại sẽ xuất hiện yêu cầu một tập tin hình ảnh để sử dụng làm một texture. Khi bạn đã chọn một hình ảnh, bạn có thể thay đổi tỉ lệ kích thước của nó hoặc hiệu chỉnh màu sắc của nó. Nếu bạn nhấp vào hộp chọn Colorize, màu sắc bạn đã chọn trong phần Color sẽ được áp cho Texture.

8. Nhập một cái tên cho mẫu vật liệu mới, thiết lập các thông số trong phần Color và Texture tùy thích theo ý muốn của bạn, và cuối cùng là nhấn OK. Khi đó mẫu vật liệu mới vừa được tạo xong này sẽ được thêm vào trong dự án SketchUp hiện hành. Để xác minh điều này,

hãy nhấp vào biểu tượng ngôi nhà và xem các vật liệu hiện đang được sử dụng trong dự án. 9. Kích chuột phải vào mẫu vật liệu mà bạn đã tạo ra và chọn Save As từ menu ngữ cảnh

xuất hiện. Chọn một thư mục trên máy tính và nhấn nút Save. Điều này sẽ tạo ra một tập tin có có đuôi là skm chứa đựng các thông tin về mẫu vật liệu đó.

Khi bạn làm việc với các vật liệu của SketchUp, có ba điểm cần nhớ : 1. Một vật liệu có thể được chỉ định bởi một mầu sắc, một texture hoặc đồng thời cả hai. 2. Mầu sắc được xác định bằng tên hoặc bằng số. Textures được xác định bằng hình ảnh. 3. Vật liệu được lưu thành tập tin *.skm. Một vật liệu cần được nạp vào dự án trước khi nó

được sử dụng.

Page 45: Chuong 4,5 va 6 Pluin cho SketchUp

Chương VI SketchUp Scripting by [email protected]

98

6.1.2 Tạo và áp một vật liệu trong mã hóa

Các đối tượng Material trong một dự án SketchUp được lưu trữ trong một đối tượng Materials. Để thêm vật liệu mới, bạn cần truy xuất vào đối tượng Materials của dự án và gọi ra phương thức add của nó cùng với tham số là tên của vật liệu. Ví dụ, lệnh sau đây gọi ra được đối tượng Materials hiện hành và thêm một vật liệu mới có tên là New Material:

mats = Sketchup.active_model.materials

new_mat = mats.add "New Material"

Khi bạn thêm một vật liệu mới, nó sẽ trở thành “vật liệu hiện hành”. Khi bạn kích chọn công cụ Paint Bucket trong SketchUp thì vật liệu hiện hành là vật liệu đang được gán lên công cụ này và đặt nó trong trạng thái sẵn sàng sử dụng. Và khi kích công cụ Paint Bucket lên một bề mặt thì bề mặt đó được áp vật liệu hiện hành. Bạn có thể thiết lập một vật liệu nào đó là vật liệu hiện hành bởi phương thức current= của lớp Materials. Bạn có thể tìm ra đối tượng vật liệu đang hiện hành trong dự án với phương thức current.

Trong mã hóa, vật liệu hiện hành là không quan trọng. Bạn có thể áp bất kỳ loại vật liệu nào có trong Materials lên bất kỳ Drawingelement nào trong dự án. Như đã giải thích trong Chương 3, Drawingelement là lớp cha của Edge, Face, ComponentInstance, ComponentDefinition, Group, Image và Text. Đây là những loại đối tượng duy nhất mà sự hiển thị tính chất vật liệu của chúng có thể được chỉ định bởi các đối tượng Material.

Phương thức material= của lớp Drawingelement dùng để áp một vật liệu. Tham số có thể là biến đã được gán cho đối tượng Material hoặc tên của đối tượng Material. Ví dụ, cả hai lệnh này đều áp vật liệu New Material được tạo ra ở ví dụ trên cho đối tượng mô hình face:

face.material = new_mat Thông qua biến

face.material = "New Material" Trực tiếp

Phương thức material của lớp Drawingelement trả về đối tượng Material của đối tượng mô hình. Phương thức name và display_name của lớp Material trả về tên của đối tượng Material được gán cho đối tượng mô hình. Các dòng mã sau đây cho thấy cách thức mà những phương thức này làm việc với nhau để trả lại tên các vật liệu liên quan đến đối tượng mô hình face:

face.material.name

New Material

face.material.display_name

New Material

Lớp Material cũng chứa một phương thức gọi là materialType trả về một trong ba giá trị:

• 0 – Vật liệu được chỉ định bởi một mầu sắc

• 1 - Vật liệu được chỉ định bởi một Texture

• 2 – Vật liệu được chỉ định bởi cả mầu sắc và Texture

Ví dụ, biến lặp trong đoạn mã sau đây thông qua từng đối tượng Material có trong dự án SketchUp và hiển thị tên cùng với giá trị của loại chỉ định của nó :

Page 46: Chuong 4,5 va 6 Pluin cho SketchUp

Chương VI SketchUp Scripting by [email protected]

99

mats = Sketchup.active_model.materials

mats.each do |mat|

puts "Material name = " + mat.name + ", type = " +

mat.materialType.to_s

end

Ba dòng tiếp sau đây có thể được tạo ra từ đoạn mã trên: Material name = DimGray, type = 0

Material name = Charcoal, type = 0

Material name = [Asphalt_New], type = 1

Như đã hiển thị, Material được chỉ định bởi màu sắc có Type=0 và tên của chúng không nằm trong cái gì cả. Material được chỉ định bởi Textures có Type=1 và tên của chúng được đặt trong dấu ngoặc vuông. Hai phần tiếp theo sẽ giải thích cách thức mà SketchUp quản lý màu sắc và Textures, và làm thế nào bạn để có thể sử dụng chúng để tạo ra vật liệu mới trong mã hóa.

6.2 Mầu sắc. SketchUp cung cấp một lớp Color, chỉ dùng khi bạn quan tâm với các tính năng cao cấp

như pha trộn, bình thường có thể bạn sẽ không cần nó. Bạn có thể tạo ra các đối tượng Color trực tiếp nếu bạn biết “tên màu” của các màu sắc được dùng trong SketchUp hoặc các giá trị cường độ màu thành phần đỏ, xanh lá cây và xanh nước biển (theo hệ màu RGB) của nó. Ví dụ, đoạn mã sau tạo một vật liệu-Material có tên là purple_mat, thiết lập màu sắc của nó là màu tím, và áp nó vào một đối tượng nhóm (group) có tên là purple_group:

purple_mat = Sketchup.active_model.materials.add "Purple"

purple_mat.color = [128, 0, 128] # The color purple

purple_group.material = purple_mat

Phương thức color của lớp Material chấp nhận một đối tượng màu, nhưng nó cũng chấp nhận các mảng giống như [ 128, 0 , 128 ] ở dòng lệnh thứ hai. Phần tử đầu tiên xác định cường độ màu đỏ trong màu sắc, phần tử thứ hai xác định cường độ màu xanh lá cây và phần tử cuối cùng xác định cường độ màu xanh nước biển. Hệ thống màu RGB là pha trộn giữa ba màu đỏ, xanh lá cây và xanh nước biển. Nghĩa là màu sắc được tạo ra bằng cách thêm các thành phần màu đỏ, xanh lá cây và màu nước biển lên trên một nền màu đen, chính vì vậy là [ 0, 0, 0] là màu đen và [ 255, 255, 255 ] là màu trắng.

Các lệnh ở phía trên cho bạn thấy một cách để áp một vật liệu chỉ định bởi màu sắc lên một đối tượng mô hình Drawingelement, nhưng có một cách thức thực hiện nhanh hơn là:

purple_group.material = [128, 0, 128]

Ở đây, mảng [ 128, 0 , 128 ] đã được thay thế cho đối tượng Material bắt buộc phải có của phương thức material. Khi lệnh này được thực thi, SketchUp tự động tạo ra một đối tượng Material với màu sắc được chỉ định, cung cấp cho nó một cái tên chung chung như Material3 và thêm nó vào trong dự án. Theo cách này, bạn có thể áp trực tiếp các vật liệu chỉ

Page 47: Chuong 4,5 va 6 Pluin cho SketchUp

Chương VI SketchUp Scripting by [email protected]

100

định bởi màu sắc cho một Drawingelement mà không cần truy xuất vào đối tượng Material.

Phương thức color trong lớp Material trả về một đối tượng mầu-Color chỉ định cho vật liệu. Các phương thức red, green và blue trong lớp Color trả về cường độ các thành phần màu trong nó. Ví dụ, các lệnh sau đây cung cấp thông tin liên quan đến vật liệu của đối tượng purple_group:

purple_group.material.color

Color(128, 0, 128, 255)

purple_group.material.color.red

128

purple_group.material.color.green

0

purple_group.material.color.blue

128

6.2.1 Xác định màu bằng tên. Nhiều trình duyệt web và .NET framework của Microsoft's dựa trên một tập hợp bao gồm

các cái tên để xác định màu sắc, và SketchUp cũng hỗ trợ chúng. Chúng thường được gọi là bộ tên màu X11 vì chúng được sử dụng trong hệ thống X Window ( hệ thống cửa sổ dùng để hiển thị đồ họa). Ví dụ, tên màu X11 cho giá trị [ 128, 0 , 128 ] của hệ màu RGB là Purple-màu tím, và các lệnh sau đây đều đạt kết quả như nhau:

purple_group.material = [128, 0, 128]

purple_group.material = "Purple"

Bạn có thể xem chi tiết về các tên màu và mối liên hệ giữa nó với các giá trị trong hệ màu RGB tại: http://vi.hexacolorpedia.com/color-names.html .

Tất cả các tên màu phổ biến đều có sẵn trong SketchUp, chẳng hạn như Blue và Turquoise. Có tổng cộng 140 tên màu, và bạn có thể xem một danh sách đầy đủ các tên màu này bằng cách thực hiện lệnh sau:

Sketchup::Color.names

Các tên màu đều có sự phân biệt giữa chữ hoa và chữ in thường, và chúng có sử dụng quy ước đặt tên CamelCase. Có nghĩa là, chữ cái đầu tiên trong tất cả các từ cấu tạo nên tên màu là được phải viết hoa và không có khoảng trống giữa các từ. Ví dụ, SketchUp sẽ nhận ra tên màu là YellowGreen, PeachPuff và MidnightBlue, nhưng không ra midnightblue hoặc Midnightblue.

6.2.2 Các cách xác định màu khác. Mảng màu tiêu chuẩn gồm ba phần tử là ba số nguyên từ 0 đến 255, nhưng còn có những

cách khác để xác định các màu theo dạng số. Bạn có thể chỉ định một giá trị thập lục phân (hexadecimal ) sáu chữ số với một lệnh như sau:

purple_group.material = 0x800080

Page 48: Chuong 4,5 va 6 Pluin cho SketchUp

Chương VI SketchUp Scripting by [email protected]

101

Trong trường hợp này, hai chữ số đầu tiên xác định các cường độ màu đỏ ( 80 trong hệ thập lục phân tương ứng 128 trong hệ số 24 bit ), hai chữ số tiếp theo đại diện cho cường độ màu xanh lá cây và hai chữ số cuối cùng xác định cường độ màu nước biển của màu. Bạn cũng có thể sử dụng giá trị thập phân tương đương của 0x800080 là 8388736, nhưng điều này là rất khó khăn khi tính toán.

Hoặc bạn không cần phải sử dụng các số nguyên từ 0 đến 255. Mỗi màu có thể được xác định với một giá trị thập phân từ 0.0 tới 1.0. Trong trường hợp này, thì [ 0.0 , 0.0, 0.0 ] là màu đen và [1.0 , 1.0 , 1.0 ] là màu trắng. Để tính toán ra một mảng gồm có các phần tử thập phân từ một mảng có các phần tử là số nguyên, hãy chia các phần tử của mảng số nguyên cho 255. Ví dụ, các lệnh sau thiết lập vật liệu của purple_group được chỉ định là màu tím bằng cách sử dụng các giá trị thập phân:

purple_group.material = [0.5, 0.0, 0.5]

Cuối cùng, bạn có thể xác định các màu bằng cách sử dụng các mảng gồm bốn phần tử, trong đó phần tử ban đầu là cường độ của các màu thành phần ( đỏ, xanh lá cây và xanh nước biển) và phần tử thứ tư là một giá trị thập phân nằm từ 0.0 tới 1.0 hoặc một số nguyên từ 0 đến 255. Giá trị của phần tử thứ tư này xác định độ mờ đục của màu. Thuộc tính này, hay còn được gọi là alpha là chủ đề của phần trình bày tiếp theo.

6.2.3 Độ mờ đục của màu. Cho đến nay, tất cả các vật liệu mà chúng ta đã tạo ra đều không trong suốt, khi bạn đặt

một đối tượng mô hình ở phía trước một đối tượng mô hình khác thì các đối tượng phía sau bị che khuất hoàn toàn. Nhưng bạn có thể làm cho một vật liệu trở nên trong suốt bằng cách thay đổi giá trị alpha của nó. Theo mặc định, tất cả các màu mà bạn tạo ra có một giá trị alpha là 255 ( số nguyên ) hoặc 1.0 ( số thập phân). Để làm cho một liệu trở nên trong mờ hoặc trong suốt thì bạn cần phải giảm giá trị này. Khi giá trị alpha của vật liệu bằng 0 thì vật liệu đó hoàn toàn trong suốt.

Hình sau cho thấy các giá trị alpha đã thay đổi sự xuất hiện của đối tượng bề mặt trong dự án như thế nào. Tất cả bốn hình vuông đều là màu đen, nhưng việc giảm giá trị alpha đã làm cho một số hình này xuất hiện màu xám. Khi giá trị alpha giảm xuống bằng 0.0 thì hình vuông trở nên trong suốt .

Bạn có thể chỉ định một giá trị alpha đặt làm vị trí thứ tư trong một mảng RGB hoặc gọi ra phương thức alpha được cung cấp bởi lớp Color. Nhưng trong kinh nghiệm của tôi,

Page 49: Chuong 4,5 va 6 Pluin cho SketchUp

Chương VI SketchUp Scripting by [email protected]

102

cách duy nhất để thay đổi giá trị alpha của vật liệu là bằng cách gọi phương thức alpha của đối tượng Material. Phương thức này chấp nhận một giá trị thập phân nằm từ 0.0 (trong suốt) đến 1.0 ( đục).

Ví dụ, đoạn mã sau gán một màu-Color với một giá trị alpha của nó là 128 cho một Material. Có một sự khác biệt rõ ràng giữa hai cách thức sử dụng phương thức alpha: red_mat = Sketchup.active_model.materials.add "Red"

red_col = Sketchup::Color.new 255, 0, 0, 128

red_col.alpha

128

red_mat.color = red_col

red_mat.alpha

1.0 # Opaque

red_mat.alpha = 0.5

red_mat.alpha

0.5 # Translucent

Như đã thể hiện, nếu bạn muốn thay đổi giá trị alpha của một Material, bạn phải gọi phương thức alpha của lớp Material với giá trị nằm giữa 0.0 và 1.0 .

6.2.4 Pha trộn màu. Quá trình pha trộn chấp nhận hai màu và tạo ra một màu thứ ba có thành phần là giá trị

trung bình có trọng số của các thành phần trong màu đầu vào. Bạn có thể thực hiện pha trộn theo một trong hai cách. Cách đầu tiên, bạn có thể gọi ra phương thức Color.blend với tham số là hai màu và một trọng số. Bạn cũng có thể truy xuất vào một đối tượng Color cụ thể và gọi phương thức pha trộn của nó. Ví dụ, đoạn mã sau sử dụng cả hai phương thức để tạo ra màu tím từ màu xanh và màu đỏ :

blue = Sketchup::Color.new 0, 0, 255

red = Sketchup::Color.new 255, 0, 0

purple1 = Sketchup::Color.blend blue, red , 0.5

Color(127, 0, 127, 255)

purple2 = blue.blend red, 0.5

Color(127, 0, 127, 255)

Page 50: Chuong 4,5 va 6 Pluin cho SketchUp

Chương VI SketchUp Scripting by [email protected]

103

Trong đoạn mã trên trong số là 0.5, nếu trọng số được thiết lập là 0 trong các câu lệnh trên thì màu kết quả của sự pha trộn sẽ là màu đỏ và nếu trọng số được thiết lập là 1 thì màu kết quả sẽ là màu xanh.

6.3 Texture. Nếu bạn đã từng dán giấy dán tường, bạn sẽ biết là nó gây nhức đầu đến mức nào. Trước

tiên, bạn phải đo kích thước của bức tường và quét hồ dán vào mặt sau của giấy dán tường. Tiếp theo, bạn phải trải giấy dán tường một cách cẩn thận lên trên mặt tường, và nếu có sai lệch hoặc có những chỗ bị phồng rộp lên thì bạn phải bóc tất cả mọi thứ ra và bắt đầu lại. Thật thoải mái và dễ chịu khi nhìn vào một bức tường có dán giấy dán tường hơn là một bức tường trống không, nhưng tôi thường băn khoăn liệu nó có xứng đáng với công sức đã bỏ ra.

Trong Sketchup, Texture thực hiện một chức năng tương tự như giấy dán tường, nhưng quá trình áp chúng khó xảy ra lỗi. Trước tiên, bạn tạo một đối tượng Texture từ một tập tin hình ảnh và sử dụng Texture đó để tạo ra một vật liệu-Material. Sau đó, bạn cũng áp vật liệu này lên bề mặt giống như lúc bạn thực hiện với vật liệu được chỉ định bởi một màu ở phần trước. Bạn không phải lo lắng về kích thước vì nếu ảnh nhỏ hơn bề mặt, nó sẽ được lặp đi lặp lại để lấp đầy bề mặt. Và trên tất cả là không có chỗ nào bị phồng rộp lên!

6.3.1 Tạo và áp một Texture mới. Đối tượng Texture được tạo ra bằng phương thức texture của lớp Material.

Phương thức này chấp nhận tham số là tên của một tập tin hình ảnh và SketchUp chấp nhận các định dạng tập tin sau:

• JPEG images (*.jpg/*.jpeg)

• Portable network graphic images (*.png)

• Photoshop images (*.psd)

• Tagged image files (*.tif)

• Targa files (*.tga)

• Windows bitmaps (*.bmp)

Một hình ảnh đen trắng kích thước 15x15 có tên là checker.jpg nằm trong thư mục CH6 kèm theo cuốn sách này. Nếu thư mục này được đặt trong thư mục cấp cao plugins của SketchUp, các lệnh sau đây tạo ra một Texture từ hình ảnh đó: mats = Sketchup.active_model.materials

new_mat = mats.add "Texture Test"

save_path = Sketchup.find_support_file "Ch6/checker.jpg",

"Plugins"

new_mat.texture = save_path

text = new_mat.texture

Một khi bạn đã tạo ra một Texture, bạn có thể gọi ra phương thức lớp của nó để có được thông tin cơ bản về hình ảnh tạo ra nó: text.filename

Page 51: Chuong 4,5 va 6 Pluin cho SketchUp

Chương VI SketchUp Scripting by [email protected]

104

../Ch6/checker.jpg

text.image_width

15

text.average_color

Color(126, 126, 126, 255)

Lớp Texture có chứa hai cặp phương thức trả về kích thước: image_width/ image_height và width/height. Những phương thức này không thể thay thế cho nhau được. Cặp đầu tiên xác định kích thước của hình ảnh texture theo đơn vị pixel. Cặp thứ hai xác định kích thước của hình ảnh đó theo đơn vị inch.

Ngoài ra việc có được các thông tin cơ bản của nó, bạn có thể áp Texture lên một đối tượng Edge, Face, ComponentInstance, ComponentDefinition, Group, Image hoặc Text. Áp một vật liệu được chỉ định bởi một Texture tương tự như áp một vật liệu được chỉ định bởi một màu. Dòng mã sau đây tạo ra một Texture từ tập tin checker.jpg và áp lên bề mặt có tên là new_face:

new_face.material.texture = "checker.jpg"

Hình phía bên trái của hình sau cho bề mặt trước khi được áp. Hình phía bên phải cho thấy bề mặt sau khi được áp vật liệu được chỉ định bởi một Texture.

Khi bạn tạo ra một vật liệu, bạn không cần phải băn khoăn về việc lựa chọn cái nào giữa

một mầu và một Texture mà bạn có thể kết hợp cả hai. Đoạn mã trong tập tin kịch bản sau tạo ra một vật liệu được chỉ bịnh bởi một Texture được dựa trên tập tin hình ảnh checker.jpg và mầu DodgerBlue. Sau đó, áp vật liệu đó lên một bề mặt.

colortexture.rb

# Create the new material

mats = Sketchup.active_model.materials

ct_mat = mats.add "Color_Texture"

# Assign the texture and color

Page 52: Chuong 4,5 va 6 Pluin cho SketchUp

Chương VI SketchUp Scripting by [email protected]

105

ct_mat.texture = Sketchup.find_support_file "Ch6/checker.jpg", "Plugins"

ct_mat.color = "DodgerBlue"

# Draw a Face and set its material

ents = Sketchup.active_model.entities

face = ents.add_face [1, -1, 1], [1, 1, 1], [-1, 1, 1], [-1, -1, 1]

face.material = ct_mat

# Display the average color

puts "The average color is " + ct_mat.texture.average_color.to_s

puts "The material type is " + ct_mat.materialType.to_s

Khi tập tin kịch bản này được thực thi, kết quả được hiển thị như sau:

The average color is Color(30, 144, 255, 255)

The material type is 2

Trong kịch bản trên, vật liệu ct_mat đầu tiên được chỉ định bởi một Texture và tiếp theo là chỉ định bởi một màu. Thứ tự này rất là quan trọng. Nếu màu được chỉ định đầu tiên thì nó sẽ bị bỏ qua khi Texture được chỉ định ở bước tiếp theo. Bằng cách chỉ định màu ở bước thứ hai thì bản chất của kết cấu được thay đổi. Đây là lý do tại sao mà màu của đối tượng Texture được tạo ra cũng giống với màu đã được chỉ định (DodgerBlue = [30,144,255]). Bạn cũng có thể có được những kết quả tương tự bằng cách chọn Colorize trong hộp thoại Create Material… của SketchUp.

6.3.2 Lưu Texture thành tập tin. Sau khi bạn thêm màu cho một Texture và thay đổi kích thước của nó, bạn có thể lưu nó

thành một tập tin bằng cách sử dụng TextureWriter của SketchUp. Sau đó, bạn có thể truy xuất và sửa đổi các texture đó bằng các phần mềm chỉnh sửa ảnh ( như Photoshop, Paint…).

Để có được một TextureWriter, bạn cần phải gọi ra phương thức create_texture_writer cung cấp bởi module Sketchup. Một khi bạn đã lưu, bạn có thể lưu trữ một texture của Entity vào một tập tin bằng cách gọi phương thức write của TextureWriter. Ví dụ, các dòng lệnh sau truy xuất một TextureWriter và sử dụng nó để ghi Texture của new_group ( một Entity) thành tập tin group_texture.jpg trong thư mục plugins cấp cao :

Page 53: Chuong 4,5 va 6 Pluin cho SketchUp

Chương VI SketchUp Scripting by [email protected]

106

tw = Sketchup.create_texture_writer

path = Sketchup.find_support_file "group_texture.jpg", "Plugins"

tw.write new_group, path

Để lưu một Texture của một bề mặt thành một tập tin, bạn cần phải xác định phía của bề mặt có chứa texture mà bạn quan tâm tới (mặt phía trước-front face hay mặt phía sau-back face). Để lưu Texture trên mặt phía trước của một bề mặt thì bạn thêm một tham số thứ hai cho phương thức write với giá trị thiết lập là true. Để lưu Texture trên mặt phía sau thì thiết lập tham số thứ hai là false. Ví dụ, các phương thức sau đây lưu Texture thuộc mặt sau của bề mặt new_face thành tập tin face_texture.jpg. tw.write new_face, false, "face_texture.jpg"

Phương thức write trả về một trong ba giá trị sau:

• 0 - Texture đã được lưu thành tập tin thành công.

• 1 - Texture đã không được lưu thành tập tin do định dạng tập tin không hợp lệ

• 2 - Texture đã không được lưu thành tập tin mà không biết lý do tại sao.

Bạn cũng có thể chọn nhiều đối tượng Entity và lưu các Texture của chúng thành các các tập tin. Việc này có hai bước: Đầu tiên, đặt các đối tượng vào TextureWriter bằng cách sử dụng phương thức load. Tiếp theo, gọi ra write_all với tên của thư mục mà chúng sẽ được được lưu trữ. Điều này được thể hiện trong đoạn mã của tập tin kịch bản sau, tạo ra hai bề mặt và áp một vật liệu cho cả hai. Sau đó nó lưu cả hai Texture thuộc chúng vào một thư mục.

texturewriter.rb

# Create two faces

ents = Sketchup.active_model.entities

face1 = ents.add_face [1, -1, 1], [1, 1, 1], [-1, 1, 1], [-1, -1, 1]

face2 = ents.add_face [6, -1, 1], [6, 1, 1], [4, 1, 1], [4, -1, 1]

# Create materials for the two faces

mats = Sketchup.active_model.materials

mat1 = mats.add "Mat1"

mat2 = mats.add "Mat2"

mat1.texture = Sketchup.find_support_file "Ch6/diamond.jpg", "Plugins"

mat2.texture = Sketchup.find_support_file "Ch6/brick.jpg", "Plugins"

face1.material = mat1

face2.material = mat2

Page 54: Chuong 4,5 va 6 Pluin cho SketchUp

Chương VI SketchUp Scripting by [email protected]

107

# Create the texture writer

tw = Sketchup.create_texture_writer

tw.load face1, true

tw.load face2, true

path = Sketchup.find_support_file "Plugins", ""

tw.write_all path + "/Ch6/figs", true

Các dòng lệnh cuối cùng cho thấy cách thức mà TextureWriter được sử dụng. Cả

hai phương thức load đều yêu cầu một tham số thứ hai bởi vì tham số đầu tiên là một đối tượng bề mặt- Face. Trong trường hợp này, true có nghĩa là texture trên mặt trước của bề mặt sẽ được nạp vào TextureWriter. Nếu tham số đầu tiên không phải là một bề mặt thì tham số thứ hai không cần thêm vào.

6.4 Kết thúc chương. Vật liệu là một trong những khía cạnh thú vị nhất của SketchUp, và nếu bạn có ý định tạo

ra một sự trình diễn có đầy đủ các đặc điểm của SketchUp thì đây là một chủ đề quan trọng cần hiểu rõ. Rất may, không có nhiều điều để học: Một vật liệu chỉ đơn giản là một màu sắc hoặc texture (hoặc kết hợp cả hai ) có thể được áp lên các đối tượng hình học có trong một dự án SketchUp.

Màu sắc là loại vật liệu rất dễ dàng thực hiện. Nếu bạn thiết lập vật liệu của một Drawingelement là một mảng RGB hoặc là một tên màu phổ biến nào đó thì SketchUp sẽ nhận ra màu sắc đó và tạo ra một vật liệu mới. Tiếp theo, SketchUp sẽ thêm vật liệu được chỉ định bởi màu sắc đó vào đối tượng chứa đựng Materials của dự án SketchuUp và áp nó lên bề mặt của đối tượng hình học. Tất cả việc cần làm chỉ là một dòng mã.

Texture có phần rắc rối hơn bởi vì bạn cần phải cung cấp vị trí của một tập tin hình ảnh. Cũng như màu sắc, hình ảnh Texture có thể được sử dụng trực tiếp để tạo ra vật liệu. Khi bạn thiết lập vật liệu của một đối tượng hình học là một hình ảnh Texture, SketchUp sẽ thêm vật liệu này vào đối tượng model và áp lên trên đối tượng hình học.

Một khi bạn đã áp một Texture lên một đối tượng hình học nào đó trong dự án SketchUp thì bạn có thể thay đổi kích thước và màu sắc của nó. Sau đó, bạn có thể lưu Texture đã được sửa đổi thành một tập tin bằng cách truy xuất vào đối tượng TextureWriter. Có thể nạp các Texture đã được áp trên một hoặc nhiều đối tượng hình học trong dự án SketchUp và lưu chúng vào một thư mục nào đó trên máy tính.