Đến nội dung


Hình ảnh
- - - - -

Có vấn đề với việc tạo TextStyle bằng lisp


  • Please log in to reply
5 replies to this topic

#1 Nộ Thiên

Nộ Thiên

    biết lệnh ddedit

  • Members
  • PipPipPipPip
  • 297 Bài viết
Điểm đánh giá: 133 (tàm tạm)

Đã gửi 15 April 2008 - 12:50 PM

Mình có 1 đọan lisp tạo textstyle như sau:

;;;\\\\\\\\\-----Kiem tra TextStyle, neu chua co thi tao moi -----\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
(defun chStyle (Tenstyle tenfont)
(if (null (setq item (tblsearch "style" tenstyle)))
(command "-style" tenstyle tenfont "0" "1" "0" "n" "n")
)
)

Đọan code trên nó chạy đúng với đa số các lọai front. Nhưng với 1 số font thì bị lỗi.
Sau khi tìm hiểu thì phát hiện ra nguyênnhân như sau.

Có hiệu ứng vertical
Hình đã gửi

Kg có hiệu ứng Vertical (đọan code trên chỉ đúng với lọai này)
Hình đã gửi

Như vậy vấn đề đặt ra là làm thế nào để đọan code trên mang tính tổng quát (đúng với mọi font)???
  • 0

#2 crazylisp

crazylisp

    biết vẽ line

  • CADViet Team
  • PipPip
  • 20 Bài viết
Điểm đánh giá: 14 (tàm tạm)

Đã gửi 23 April 2008 - 10:44 PM

Không thấy ai trả lời, crazy tôi xin ké một tí.

Để giải quyết triệt để vấn đề này, chúng ta sẽ cố tạo mới một textstyle bằng hàm entmake. Khó khăn là làm sao để biết được hàm entmake cần những dữ liệu gì. Ta sẽ dùng hàm entget để lấy và xem dữ liệu của text style. Nhưng làm sao để lấy được ename của đối tượng textstyle để sử dụng hàm entget. Ta dùng hàm tblobjname để tìm ename của một text style có sẵn.

Khi ta dùng lệnh (entget (tblobjname "style" "standard")) để xem dữ liệu chứa text style, sẽ có kết quả:
((-1 . <Entity name: 7ef8fc88>) (0 . "STYLE") (330 . <Entity name: 7ef8fc18>)
(5 . "11") (100 . "AcDbSymbolTableRecord") (100 . "AcDbTextStyleTableRecord")
(2 . "Standard") (70 . 0) (40 . 0.0) (41 . 1.0) (50 . 0.0) (71 . 0) (42 . 0.2)
(3 . "txt") (4 . ""))
Vậy là trong mục 2 chứa tên style, mục 3 chứa fontname.

Công việc của chúng ta bây giờ rất đơn giản, dùng hàm entmake để tạo đối tượng có dữ liệu như ở trên nhưng mục 2 là tên style, mục 3 là fontstyle. Đoạn mã đó như sau:
(setq
DuLieu (entget (tblobjname "style" "standard"))
DuLieu (subst (cons 2 Tenstyle) (assoc 2 DuLieu) DuLieu)
DuLieu (subst (cons 3 tenfont) (assoc 3 DuLieu) DuLieu)
)
(entmake DuLieu)


Kết hợp với đoạn mã của Nộ Thiên, ta có đoạn mã như sau:
(defun chStyle (Tenstyle tenfont)
(if (null (setq item (tblsearch "style" tenstyle)))
(progn
(setq DuLieu (entget (tblobjname "style" "standard"))
DuLieu (subst (cons 2 Tenstyle) (assoc 2 DuLieu) DuLieu)
DuLieu (subst (cons 3 tenfont) (assoc 3 DuLieu) DuLieu))
(entmake DuLieu)
)
)
)

Chúc vui vẻ.
  • 1

#3 ssg

ssg

    biết lệnh adcenter

  • Vip
  • PipPipPipPipPipPipPip
  • 1228 Bài viết
Điểm đánh giá: 1087 (rất tốt)

Đã gửi 24 April 2008 - 09:15 AM

Để giải quyết triệt để vấn đề này, chúng ta sẽ cố tạo mới một textstyle bằng hàm entmake. Khó khăn là làm sao để biết được hàm entmake cần những dữ liệu gì. Ta sẽ dùng hàm entget để lấy và xem dữ liệu của text style. Nhưng làm sao để lấy được ename của đối tượng textstyle để sử dụng hàm entget. Ta dùng hàm tblobjname để tìm ename của một text style có sẵn...

Hoàn toàn đồng ý với bạn, các vấn đề tương tự như trên dùng entmake là hợp lý nhất. Tuy nhiên, không cần phải "dựa hơi" style có sẵn, có vẻ không "chính quy" lắm. Mình ví dụ, nếu ai đó đổi tên Standard thành MyStandard chẳng hạn thì hàm chStyle của bạn không tạo được style?
Bạn tham khảo đoạn sau:

;;;--------------------------------------------------------------------------
(defun emk_style (MyStyle MyFont MyFlag)
(entmake (list
(cons 0 "STYLE")
(cons 100 "AcDbSymbolTableRecord")
(cons 100 "AcDbTextStyleTableRecord")
(cons 2 MyStyle)
(cons 3 MyFont)
(cons 70 MyFlag)
))
)
;;;--------------------------------------------------------------------------
(defun C:VD()
(emk_style "MyStyle1" "txt" 0)
(emk_style "MyStyle2" "txt" 4)
)
;;;--------------------------------------------------------------------------

Chạy VD sẽ tạo 2 style: MyStyle1 bỉnh thường và MyStyle2 có hiệu ứng Vertical như ý bạn Nộ Thiên.
Mình đã thử emk_style với nhiều tổ hợp mã DXF khác nhau. Các mã 0, 100, 100, 2, 3, 70 như trên là bắt buộc, nghĩa là tối thiểu cần phải có để tạo thành style. Bạn lưu ý: các code 100 là bắt buộc trong đa số trường hợp để tạo các đối tượng Symbol Table bằng entmake.
Ngoài các code tối thiểu trên, có thể bổ sung các code khác theo ý đồ và nhu cầu sử dụng. Bạn có thể tham khảo DXF Reference trong Help để biết cụ thể hơn.
Ngoài ra, theo mình, không nên đưa các biểu thức điều kiện như (if (null (setq item (tblsearch "style" tenstyle)))... vào các function mang tính public như cái chúng ta đang xây dựng. Các điều kiện như vậy nên đặt trong chương trình chính khi áp dụng, dễ xử lý tình huống một cách triệt để hơn.
  • 1

#4 Nộ Thiên

Nộ Thiên

    biết lệnh ddedit

  • Members
  • PipPipPipPip
  • 297 Bài viết
Điểm đánh giá: 133 (tàm tạm)

Đã gửi 24 April 2008 - 12:10 PM

Hoàn toàn đồng ý với bạn, các vấn đề tương tự như trên dùng entmake là hợp lý nhất. Tuy nhiên, không cần phải "dựa hơi" style có sẵn, có vẻ không "chính quy" lắm. Mình ví dụ, nếu ai đó đổi tên Standard thành MyStandard chẳng hạn thì hàm chStyle của bạn không tạo được style?
Bạn tham khảo đoạn sau:


;;;--------------------------------------------------------------------------
(defun emk_style (MyStyle MyFont MyFlag)
(entmake (list
(cons 0 "STYLE")
(cons 100 "AcDbSymbolTableRecord")
(cons 100 "AcDbTextStyleTableRecord")
(cons 2 MyStyle)
(cons 3 MyFont)
(cons 70 MyFlag)
))
)
;;;--------------------------------------------------------------------------
(defun C:VD()
(emk_style "MyStyle1" "txt" 0)
(emk_style "MyStyle2" "txt" 4)
)
;;;--------------------------------------------------------------------------

Chạy VD sẽ tạo 2 style: MyStyle1 bỉnh thường và MyStyle2 có hiệu ứng Vertical như ý bạn Nộ Thiên.
Mình đã thử emk_style với nhiều tổ hợp mã DXF khác nhau. Các mã 0, 100, 100, 2, 3, 70 như trên là bắt buộc, nghĩa là tối thiểu cần phải có để tạo thành style. Bạn lưu ý: các code 100 là bắt buộc trong đa số trường hợp để tạo các đối tượng Symbol Table bằng entmake.
Ngoài các code tối thiểu trên, có thể bổ sung các code khác theo ý đồ và nhu cầu sử dụng. Bạn có thể tham khảo DXF Reference trong Help để biết cụ thể hơn.
Ngoài ra, theo mình, không nên đưa các biểu thức điều kiện như (if (null (setq item (tblsearch "style" tenstyle)))... vào các function mang tính public như cái chúng ta đang xây dựng. Các điều kiện như vậy nên đặt trong chương trình chính khi áp dụng, dễ xử lý tình huống một cách triệt để hơn.

Đúng là mình bị "ì" rồi. Quên mất là còn khả năng tạo textstyle bằng entmake. Thank so much.

không nên đưa các biểu thức điều kiện như (if (null (setq item (tblsearch "style" tenstyle)))...

Còn cái này cũng do "ì" mà ra bởi vì nguồn gốc của nó do hàm public (chlayer) mà ra. Chứ nếu viết nó độc lập thì mình đã đặt tên hàm là (creatstyle) rồi chứ kg phải (chstyle).

(emk_style "MyStyle1" "VNI-Helve-Condense" 0)

Cái dòng code trên có gì đó kg ổn, kg biết SSG có nhận thấy kg vì:
Nếu tetstyle bằng lệnh của CAD thì kg bao giờ có thể tick vào "Vertical" đc.
Nhưng với dòng code trên thì có thể. Kg biết có rắc rối chi về sau kg. Cái này để test sau vậy.
Một lần nữa gửi lời cảm ơn đến 2 bạn: Crazylisp và Ssg
  • 0

#5 hungfrank

hungfrank

    biết pan

  • Members
  • Pip
  • 7 Bài viết
Điểm đánh giá: -1 (bình thường)

Đã gửi 30 August 2008 - 02:41 PM

xin hỏi các bác còn 1 vấn đề nhỏ là Fontstyle thì thiết lập thế nào?Em tạo 1 style "CHU TO" có fontstyle = bold bằng style dialog nhưng không biết là cái fontstyle nó chứa ở đâu khi sử dụng hàm enget:
(entget (tblobjname "style" "CHU TO"))
((-1 . <Entity name: 7ef73058>) (0 . "STYLE") (330 . <Entity name: 7ef71d18>)
(5 . "83") (100 . "AcDbSymbolTableRecord") (100 . "AcDbTextStyleTableRecord")
(2 . "CHU TO") (70 . 0) (40 . 0.0) (41 . 1.0) (50 . 0.0) (71 . 0) (42 . 450.0)
(3 . "VHARIALB.ttf") (4 . ""))
so sánh với cái standard thì chỉ khác 2,3 và 42
  • 0

#6 Snowman

Snowman

    biết lệnh mirror

  • Members
  • PipPipPip
  • 155 Bài viết
Điểm đánh giá: 90 (tàm tạm)

Đã gửi 30 August 2008 - 03:09 PM

xin hỏi các bác còn 1 vấn đề nhỏ là Fontstyle thì thiết lập thế nào?Em tạo 1 style "CHU TO" có fontstyle = bold bằng style dialog nhưng không biết là cái fontstyle nó chứa ở đâu khi sử dụng hàm enget:
(entget (tblobjname "style" "CHU TO"))
((-1 . <Entity name: 7ef73058>) (0 . "STYLE") (330 . <Entity name: 7ef71d18>)
(5 . "83") (100 . "AcDbSymbolTableRecord") (100 . "AcDbTextStyleTableRecord")
(2 . "CHU TO") (70 . 0) (40 . 0.0) (41 . 1.0) (50 . 0.0) (71 . 0) (42 . 450.0)
(3 . "VHARIALB.ttf") (4 . ""))
so sánh với cái standard thì chỉ khác 2,3 và 42

Mính vừa test thử và thấy điểm đặc biệt là ở đây:
Cùng một style CHUTO, với font .VNARIAL.ttf
Fontstyle BOLD ITALIC cho kết quả :
((-1 . <Entity name: 7ef91048>) (0 . "STYLE") (330 . <Entity name: 7ef8fc18>)
(5 . "B9") (100 . "AcDbSymbolTableRecord") (100 . "AcDbTextStyleTableRecord")
(2 . "Chuto") (70 . 0) (40 . 0.0) (41 . 1.0) (50 . 0.0) (71 . 0) (42 . 0.2) (3
. "VNARIABI.ttf")
(4 . ""))


Fontstyle ITALIC cho kết quả :
((-1 . <Entity name: 7ef91048>) (0 . "STYLE") (330 . <Entity name: 7ef8fc18>)
(5 . "B9") (100 . "AcDbSymbolTableRecord") (100 . "AcDbTextStyleTableRecord")
(2 . "Chuto") (70 . 0) (40 . 0.0) (41 . 1.0) (50 . 0.0) (71 . 0) (42 . 0.2) (3
. "VNARIALI.ttf")
(4 . ""))



Fontstyle regular cho kết quả :
((-1 . <Entity name: 7ef91048>) (0 . "STYLE") (330 . <Entity name: 7ef8fc18>)
(5 . "B9") (100 . "AcDbSymbolTableRecord") (100 . "AcDbTextStyleTableRecord")
(2 . "Chuto") (70 . 0) (40 . 0.0) (41 . 1.0) (50 . 0.0) (71 . 0) (42 . 0.2) (3
. "VNARIAL.ttf")
(4 . ""))


Vậy là có thể kết luận được cách đặt fontstyle chính là ở tên của font file (mỗi font style tương ứng với một file font).
Còn tên riêng của các file (tên font) đó như thế nào thì ...chỉ có test thử và lưu lại thôi (vì tên font file trong Win ko giống như vậy)
  • 0

. - ' * ' - .. - ... "Sống trong đời sống cần có một tấm lòng..." . - ' * ' - .. -
-----------------------------------------------------------------------------------

Hình đã gửi Hình đã gửi