Đến nội dung


Hình ảnh
- - - - -

Lisp đưa đối tượng về vị trí cũ sau khi move?


  • Please log in to reply
41 replies to this topic

#21 thiep

thiep

    biết dimbaseline

  • Members
  • PipPipPipPipPip
  • 369 Bài viết
Điểm đánh giá: 260 (khá)

Đã gửi 10 October 2009 - 10:49 AM

Chào Tue_nv, theo mình thì lisp của Tue vẫn còn phải yêu cầu điểm base point và secon point. Còn ý tưởng của Hai_1401 là chỉ pick vào đối tượng nào vừa bị move thì đối tượng đó về lại vị trí cũ trước khi bị move. Phải không Hai_1410? Đây mới là vấn đề nan giải, bó tay Thiep!
Còn hàm ACET-SS-DRAG-MOVE, trả về 1 điểm pick sau cùng (p2), nó thể hiện 1 hình ảnh động giống như lệnh move, và như vậy sau khi có được điểm p2 mà hàm ACET-SS-DRAG-MOVE trả về, ta dùng lệnh move các đối tượng theo 2 điểm. Nếu ta không sử dụng điểm p2 này vào lệnh move, ví dụ dùng lệnh move vơi 1 điểm và 1 khoảng cách, thì không cần phải sử dụng hàm ACET-SS-DRAG-MOVE nữa.
khi đặt ở chế độ Ortho, thì cusor trên màn hình chỉ đi ngang hay đi đứng thôi và khi pick điểm thì điểm chỉ ở hàng ngang hay hàng đứng thôi.
Thân chào Tue_nv

Chào Hai_1410 và Tue_nv, nói là bó tay, nhưng mình vẫn suy nghĩ để giải quyết bài toán này. Và qua 1 đêm ngủ chập chờn, sáng nay mình viết 1 đoạn lisp này đây:
(defun dxf (id en) (cdr (assoc id (entget en))))
(defun c:unmove (/ en1 p1 en2 p2 en)
(setq en1 (entlast)
p1 (dxf 10 en1))
(command "undo" 1)
(setq en2 (entlast)
p2 (dxf 10 en2))
(command "redo")
(while (setq en (car (entsel "\nPick a obj to undo move: ")))
(command "move" en "" p1 p2)
)
(princ)
)

  • 2

#22 nataca

nataca

    biết lệnh adcenter

  • Members
  • PipPipPipPipPipPipPip
  • 712 Bài viết
Điểm đánh giá: 553 (tốt)

Đã gửi 10 October 2009 - 10:56 AM

Chào Hai_1410 và Tue_nv, nói là bó tay, nhưng mình vẫn suy nghĩ để giải quyết bài toán này. Và qua 1 đêm ngủ chập chờn, sáng nay mình viết 1 đoạn lisp này đây:

(defun dxf (id en) (cdr (assoc id (entget en))))
(defun c:unmove (/ en1 p1 en2 p2 en)
(setq en1 (entlast)
p1 (dxf 10 en1))
(command "undo" 1)
(setq en2 (entlast)
p2 (dxf 10 en2))
(command "redo")
(while (setq en (car (entsel "\nPick a obj to undo move: ")))
(command "move" en "" p1 p2)
)
(princ)
)

Cách dùng Undo của bạn là một ý tưởng hay. Tuy nhiên nó chỉ đúng với 1 đối tượng (nếu vậy thì dùng luôn lệnh Undo luôn có phải nhanh hơn không). Ý bạn Hai_1410 là Move một số đối tượng nhưng trong số đó có chọn nhầm vài đối tượng không cần Move.
  • 2

#23 thiep

thiep

    biết dimbaseline

  • Members
  • PipPipPipPipPip
  • 369 Bài viết
Điểm đánh giá: 260 (khá)

Đã gửi 10 October 2009 - 11:08 AM

Cách dùng Undo của bạn là một ý tưởng hay. Tuy nhiên nó chỉ đúng với 1 đối tượng (nếu vậy thì dùng luôn lệnh Undo luôn có phải nhanh hơn không). Ý bạn Hai_1410 là Move một số đối tượng nhưng trong số đó có chọn nhầm vài đối tượng không cần Move.

Chào nataca, vâng, 1 số đối tượng không cần move và nó lỡ bị move rồi, bây giờ dùng lisp của Thiep sẽ đưa nó về vị trí cũ. Vẫn đúng với nhiều đối tượng vừa bị move chứ nataca?
  • 0

#24 hai_1401

hai_1401

    biết lệnh rotate

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

Đã gửi 10 October 2009 - 11:10 AM

Chào Hai_1410 và Tue_nv, nói là bó tay, nhưng mình vẫn suy nghĩ để giải quyết bài toán này. Và qua 1 đêm ngủ chập chờn, sáng nay mình viết 1 đoạn lisp này đây:

(defun dxf (id en) (cdr (assoc id (entget en))))
(defun c:unmove (/ en1 p1 en2 p2 en)
(setq en1 (entlast)
p1 (dxf 10 en1))
(command "undo" 1)
(setq en2 (entlast)
p2 (dxf 10 en2))
(command "redo")
(while (setq en (car (entsel "\nPick a obj to undo move: ")))
(command "move" en "" p1 p2)
)
(princ)
)

Cảm ơn anh Thiệp đã nhiệt tình giúp đỡ, em đã dùng thử qua và thấy lisp anh viết đã gần như là đạt được mong muốn, tuy nhiên nếu có thể thì anh có thể fix lại những đặc điểm này giúp em được không ạ:
- Sau khi dùng lệnh Move, nếu như mình dùng chế độ zoom bản vẽ hoặc ấn phím ESC (Cancel) thì sau đó lệnh Unmove của lisp không còn tác dụng.
- Mỗi lần move chỉ được 1 đối tượng, có cách nào có thể select nhiều Object để unmove thì hay quá.
Nhờ các anh xem giúp, em xin cảm ơn :bigsmile:
  • 0

#25 nataca

nataca

    biết lệnh adcenter

  • Members
  • PipPipPipPipPipPipPip
  • 712 Bài viết
Điểm đánh giá: 553 (tốt)

Đã gửi 10 October 2009 - 11:31 AM

Chào nataca, vâng, 1 số đối tượng không cần move và nó lỡ bị move rồi, bây giờ dùng lisp của Thiep sẽ đưa nó về vị trí cũ. Vẫn đúng với nhiều đối tượng vừa bị move chứ nataca?

Uhm đúng rồi. Mình nhầm :bigsmile: . Cái này tận dụng phương của một đối tượng trong nhóm đối tượng làm chuẩn vì nhóm đối tượng cùng bị move với 1 vector. Ah, Thiep chú ý khi Move thì ename của đối tượng không bị đổi.
  • 0

#26 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

  • Moderator
  • PipPipPipPipPipPipPip
  • 4296 Bài viết
Điểm đánh giá: 3804 (đỉnh cao)

Đã gửi 10 October 2009 - 12:28 PM

Chào Hai_1410 và Tue_nv, nói là bó tay, nhưng mình vẫn suy nghĩ để giải quyết bài toán này. Và qua 1 đêm ngủ chập chờn, sáng nay mình viết 1 đoạn lisp này đây:

(defun dxf (id en) (cdr (assoc id (entget en))))
(defun c:unmove (/ en1 p1 en2 p2 en)
(setq en1 (entlast)
p1 (dxf 10 en1))
(command "undo" 1)
(setq en2 (entlast)
p2 (dxf 10 en2))
(command "redo")
(while (setq en (car (entsel "\nPick a obj to undo move: ")))
(command "move" en "" p1 p2)
)
(princ)
)

Chào thiep. Không thể dùng cái này được
(command "undo" 1)
....
-> (command "redo")

Vì khi ta zoom hoặc Pan bằng chuột giưã -> để kéo rê hoặc phóng to thu nhỏ
thì khi (command "redo") sẽ trả về hành động mà ta Zoom hoặc Pan -> chứ không phải trả về hành động Move

Command: u INTELLIPAN
Command: U INTELLIPAN

-> Reply trả lởi bài viết của thiep ở dưới :
Zoom hoặc PAN bằng chuột giữa để kéo rê hoặc phóng to thu nhỏ đối tượng thì làm sao để biết mình sử dụng lệnh bao nhiêu lần hở Thiep?????
  • 0

#27 thiep

thiep

    biết dimbaseline

  • Members
  • PipPipPipPipPip
  • 369 Bài viết
Điểm đánh giá: 260 (khá)

Đã gửi 10 October 2009 - 12:29 PM

Cảm ơn anh Thiệp đã nhiệt tình giúp đỡ, em đã dùng thử qua và thấy lisp anh viết đã gần như là đạt được mong muốn, tuy nhiên nếu có thể thì anh có thể fix lại những đặc điểm này giúp em được không ạ:
- Sau khi dùng lệnh Move, nếu như mình dùng chế độ zoom bản vẽ hoặc ấn phím ESC (Cancel) thì sau đó lệnh Unmove của lisp không còn tác dụng.
- Mỗi lần move chỉ được 1 đối tượng, có cách nào có thể select nhiều Object để unmove thì hay quá.
Nhờ các anh xem giúp, em xin cảm ơn :bigsmile:

Tại Hai_1410 nói "vừa mới move" nên lisp chỉ đúng cho trường hợp "vừa mới move", nghĩa là sau khi enter lệnh MOVE thì không có lệnh nào được gọi tiếp. Còn sau lệnh move User đã enter N lệnh thì dùng lisp đã update sau:
(defun dxf (id en) (cdr (assoc id (entget en))))
(defun c:unmove (/ en1 p1 en2 p2 ss)
(setq k (cond (k)
(0)
)
)
(setq oldk k)
(setq
k (getint
(strcat "\nNumber of command entered after move: <"
(itoa oldk)
"> : "
)
)
)
(if (null k)
(setq k oldk)
)
(setq en1 (entlast)
p1 (dxf 10 en1)
)
(command ".undo" (+ k 1))
(setq en2 (entlast)
p2 (dxf 10 en2)
)
(repeat (+ k 1) (command ".redo"))
(princ "\n<<< Pick objects to undo move >>>")
(setq ss (ssget))
(command ".move" ss "" p1 p2)
(princ)
)

Hai nên nhớ bấm Esc cũng là đã enter 1 lệnh rồi đó.
  • 2

#28 thiep

thiep

    biết dimbaseline

  • Members
  • PipPipPipPipPip
  • 369 Bài viết
Điểm đánh giá: 260 (khá)

Đã gửi 10 October 2009 - 01:33 PM

Chào thiep. Không thể dùng cái này được

(command "undo" 1)
....
-> (command "redo")

Vì khi ta zoom hoặc Pan bằng chuột giưã -> để kéo rê hoặc phóng to thu nhỏ
thì khi (command "redo") sẽ trả về hành động mà ta Zoom hoặc Pan -> chứ không phải trả về hành động Move

Command: u INTELLIPAN
Command: U INTELLIPAN

-> Reply trả lởi bài viết của thiep ở dưới :
Zoom hoặc PAN bằng chuột giữa để kéo rê hoặc phóng to thu nhỏ đối tượng thì làm sao để biết mình sử dụng lệnh bao nhiêu lần hở Thiep?????

Rep: Chào Tue_NV, khi dùng bánh xe lăn thì cad hiểu đã phát ra 1 lệnh chính thức, bấm vào chuột trái để chọn đối tượng kiểu windows thì coi như cũng đã phát ra 1 lệnh rồi. Các trường hợp này, mình phải nhớ đã pick bao nhiêu lần mới được.
  • 0

#29 hai_1401

hai_1401

    biết lệnh rotate

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

Đã gửi 10 October 2009 - 02:20 PM

Tại Hai_1410 nói "vừa mới move" nên lisp chỉ đúng cho trường hợp "vừa mới move", nghĩa là sau khi enter lệnh MOVE thì không có lệnh nào được gọi tiếp. Còn sau lệnh move User đã enter N lệnh thì dùng lisp đã update sau:

(defun dxf (id en) (cdr (assoc id (entget en))))
(defun c:unmove (/ en1 p1 en2 p2 ss)
(setq k (cond (k)
(0)
)
)
(setq oldk k)
(setq
k (getint
(strcat "\nNumber of command entered after move: <"
(itoa oldk)
"> : "
)
)
)
(if (null k)
(setq k oldk)
)
(setq en1 (entlast)
p1 (dxf 10 en1)
)
(command ".undo" (+ k 1))
(setq en2 (entlast)
p2 (dxf 10 en2)
)
(repeat (+ k 1) (command ".redo"))
(princ "\n<<< Pick objects to undo move >>>")
(setq ss (ssget))
(command ".move" ss "" p1 p2)
(princ)
)

Hai nên nhớ bấm Esc cũng là đã enter 1 lệnh rồi đó.

Cảm ơn anh Thiệp! Nếu mình dùng lisp này thì sau lệnh move mình phải để ý xem mình đã thực hiện được bao nhiêu thao tác để còn unmove đối tượng.
Nếu có một cách nào đó để cad hiểu được những đối tượng ngay phía sau lệnh move hoặc mình có thể TRỪ hết số lần enter đi chỉ để mặc định số lần nào đó thôi (để mình khỏi phải nhớ số lần enter) thì lisp sẽ trở nên vô cùng toàn diện :bigsmile: (tính em hơi cầu toàn, mong các anh đừng trách :bigsmile: )
  • 0

#30 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

  • Moderator
  • PipPipPipPipPipPipPip
  • 4296 Bài viết
Điểm đánh giá: 3804 (đỉnh cao)

Đã gửi 15 October 2009 - 09:20 PM

Rep: Chào Tue_NV, khi dùng bánh xe lăn thì cad hiểu đã phát ra 1 lệnh chính thức, bấm vào chuột trái để chọn đối tượng kiểu windows thì coi như cũng đã phát ra 1 lệnh rồi. Các trường hợp này, mình phải nhớ đã pick bao nhiêu lần mới được.

Chào Thiep
Mình thấy đoạn Code có 2 nhược điểm lớn như sau :
1 . Phải nhớ số lần thực hiện lệnh
2 . Khi phát lệnh move -> thực hiện Unmove thì Lisp sẽ đưa đối tượng về vị trí cũ sau khi move. Tuy nhiên, ta muốn unmove nhiều lần thì Lisp không thể làm được.

Cụ thể như thế này :
Ta Move 1 tập hợp chọn là SS -> ta Unmove 1 tập hợp chọn là SS1 là tập hợp con của SS,
và sau khi Unmove SS1 thì ta nhận thấy trong tập hợp con còn lại SS2 (SS - SS1),
ta thấy có 1 số đối tượng trong SS2 có 1 số đối tượng bị Move nhầm -> ta lại thực hiện Unmove trong tập hợp chọn SS2 thì lúc này Lisp không thể làm được
  • 2

#31 thiep

thiep

    biết dimbaseline

  • Members
  • PipPipPipPipPip
  • 369 Bài viết
Điểm đánh giá: 260 (khá)

Đã gửi 16 October 2009 - 12:00 PM

Chào Thiep
Mình thấy đoạn Code có 2 nhược điểm lớn như sau :
1 . Phải nhớ số lần thực hiện lệnh
2 . Khi phát lệnh move -> thực hiện Unmove thì Lisp sẽ đưa đối tượng về vị trí cũ sau khi move. Tuy nhiên, ta muốn unmove nhiều lần thì Lisp không thể làm được.

Cụ thể như thế này :
Ta Move 1 tập hợp chọn là SS -> ta Unmove 1 tập hợp chọn là SS1 là tập hợp con của SS,
và sau khi Unmove SS1 thì ta nhận thấy trong tập hợp con còn lại SS2 (SS - SS1),
ta thấy có 1 số đối tượng trong SS2 có 1 số đối tượng bị Move nhầm -> ta lại thực hiện Unmove trong tập hợp chọn SS2 thì lúc này Lisp không thể làm được

Chào Tue-NV cảm ơn Tue đã thấy những khuyết điểm của lisp unmove này. Thiep còn phát hiện thêm 1 vài khuyết điểm nữa. Lisp này chỉ là để chữa cháy thôi, nếu để chạy ngon thì phải đầu tư nhiều mã hơn nữa. Chắc là bó tay và bó luôn cả chân nữa thôi.
  • 2

#32 hai_1401

hai_1401

    biết lệnh rotate

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

Đã gửi 16 October 2009 - 06:44 PM

Chào Tue-NV cảm ơn Tue đã thấy những khuyết điểm của lisp unmove này. Thiep còn phát hiện thêm 1 vài khuyết điểm nữa. Lisp này chỉ là để chữa cháy thôi, nếu để chạy ngon thì phải đầu tư nhiều mã hơn nữa. Chắc là bó tay và bó luôn cả chân nữa thôi.

Anh Thiệp đừng nói thế, nghe nản nản, hix
  • 0

#33 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

  • Moderator
  • PipPipPipPipPipPipPip
  • 4296 Bài viết
Điểm đánh giá: 3804 (đỉnh cao)

Đã gửi 16 October 2009 - 09:25 PM

Chào Tue-NV cảm ơn Tue đã thấy những khuyết điểm của lisp unmove này. Thiep còn phát hiện thêm 1 vài khuyết điểm nữa. Lisp này chỉ là để chữa cháy thôi, nếu để chạy ngon thì phải đầu tư nhiều mã hơn nữa. Chắc là bó tay và bó luôn cả chân nữa thôi.

Chào bạn thiep và hai1401
Tue_NV có ý như thế này :

1. Trong ACAD bạn đặt lệnh tắt của lệnh MoveM (trong file acad.pgp) -> Nay mình xây dựng lệnh M của Lisp có tính năng giống y như lệnh MOVE của CAD (lần này thì giống lệnh MOVE của CAD y như 2 giọt nước đấy bạn Hai1401 à)
-> Như vậy bạn sử dụng lệnh M (để MOVE) nhé

2. Tue_NV xây dựng lại Lisp UM (unmove) -> có chức năng đưa đối tượng về vị trí cũ sau khi move
Lisp này xây dựng dựa trên cơ sở là : khi ta move thì tên (ename) của Entity không đổi (nội dung về điểm chèn thay đổi nhưng tên (ename) thì không đổi trước và sau khi Move -> dựa vào đặc điểm này ta có thể UM (unmove) đối tượng làm nhiều lần trên ý tưởng của Tue_NV :

Cụ thể như thế này :
Ta Move 1 tập hợp chọn là SS -> ta Unmove 1 tập hợp chọn là SS1 là tập hợp con của SS,
và sau khi Unmove SS1 thì ta nhận thấy trong tập hợp con còn lại SS2(SS - SS1) , ta thấy có 1 số đối tượng trong SS2 có 1 số đối tượng bị Move nhầm -> ta lại thực hiện Unmove trong tập hợp chọn SS2 thì lúc này Lisp sẽ làm được.

Tức là ta UM (unmove cho đến khi nào) mà số phần tử trong tập hợp chọn SS2 bằng 0 thì không thể UM được nữa -> Cái này theo đúng như ý của User. Hơn nữa, khi Un (unmove) các đối tượng không bị move nhầm thì các đối tượng này không có tác dụng gì cả (theo đúng ý của user luôn) :bigsmile:
Các bạn hãy thử Code này và cho biết ý kiến nhé :

(defun c:m()
(setq ss (ssget))
(command "line" '(0 0 0) '(1 1 1) "")
(setq ss (ssadd (entlast) ss))

(command "move" ss "")
(while (< 0 (getvar "CMDACTIVE")) (command pause))

(setq dc (cdr(assoc 10 (entget (entlast)))))
(setq ss (ssdel (entlast) ss))
(entdel (entlast))
(setq kc (distance '(0 0 0) dc))
(setq ang (angle dc '(0 0 0) ))
(princ)
)
;
(defun c:um(/ ssg po lis)
(prompt "\n Chon doi tuong Move nham :")
(setq ssg (ssget) i 0 j 0)

(while (< i (sslength ss))
(setq lis (append lis (list (ssname ss i))))
(setq i (1+ i))
)

(while (< j (sslength ssg))
(if (/= (member (ssname ssg j) lis) nil)
(progn
(setq ss (ssdel (ssname ssg j) ss))
(setq po (polar '(0 0 0) ang kc))
(setq ssg (ssadd (ssname ssg j) ssg))
)
(princ "\n Doi tuong chon khong phai Move nham")
)
(setq j (1+ j))
)
(command "move" ssg "" '(0 0 0) po)
(princ)
)

  • 4

#34 hai_1401

hai_1401

    biết lệnh rotate

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

Đã gửi 16 October 2009 - 10:36 PM

Chào bạn thiep và hai1401
Tue_NV có ý như thế này :

1. Trong ACAD bạn đặt lệnh tắt của lệnh MoveM (trong file acad.pgp) -> Nay mình xây dựng lệnh M của Lisp có tính năng giống y như lệnh MOVE của CAD (lần này thì giống lệnh MOVE của CAD y như 2 giọt nước đấy bạn Hai1401 à)
-> Như vậy bạn sử dụng lệnh M (để MOVE) nhé

2. Tue_NV xây dựng lại Lisp UM (unmove) -> có chức năng đưa đối tượng về vị trí cũ sau khi move
Lisp này xây dựng dựa trên cơ sở là : khi ta move thì tên (ename) của Entity không đổi (nội dung về điểm chèn thay đổi nhưng tên (ename) thì không đổi trước và sau khi Move -> dựa vào đặc điểm này ta có thể UM (unmove) đối tượng làm nhiều lần trên ý tưởng của Tue_NV :

Tức là ta UM (unmove cho đến khi nào) mà số phần tử trong tập hợp chọn SS2 bằng 0 thì không thể UM được nữa -> Cái này theo đúng như ý của User. Hơn nữa, khi Un (unmove) các đối tượng không bị move nhầm thì các đối tượng này không có tác dụng gì cả (theo đúng ý của user luôn) :cry:
Các bạn hãy thử Code này và cho biết ý kiến nhé :


(defun c:m()
(setq ss (ssget))
(command "line" '(0 0 0) '(1 1 1) "")
(setq ss (ssadd (entlast) ss))

(command "move" ss "")
(while (< 0 (getvar "CMDACTIVE")) (command pause))

(setq dc (cdr(assoc 10 (entget (entlast)))))
(setq ss (ssdel (entlast) ss))
(entdel (entlast))
(setq kc (distance '(0 0 0) dc))
(setq ang (angle dc '(0 0 0) ))
(princ)
)
;
(defun c:um(/ ssg po lis)
(prompt "\n Chon doi tuong Move nham :")
(setq ssg (ssget) i 0 j 0)

(while (< i (sslength ss))
(setq lis (append lis (list (ssname ss i))))
(setq i (1+ i))
)

(while (< j (sslength ssg))
(if (/= (member (ssname ssg j) lis) nil)
(progn
(setq ss (ssdel (ssname ssg j) ss))
(setq po (polar '(0 0 0) ang kc))
(setq ssg (ssadd (ssname ssg j) ssg))
)
(princ "\n Doi tuong chon khong phai Move nham")
)
(setq j (1+ j))
)
(command "move" ssg "" '(0 0 0) po)
(princ)
)

Anh Tuệ ơi, em mới dùng qua thôi nhưng thấy lisp anh viết đã đúng hoàn toàn với ý của em, thật là tuyệt vời, chưa thấy có lỗi nào hoặc bất cập nào xảy đến cả. Vô cùng cảm ơn anh đã quan tâm viết lisp này giúp em :cry: :bigsmile: :bigsmile:
  • 1

#35 study_forever

study_forever

    biết vẽ line

  • Members
  • PipPip
  • 22 Bài viết
Điểm đánh giá: 0 (bình thường)

Đã gửi 18 October 2009 - 01:06 AM

Chào bạn thiep và hai1401
Tue_NV có ý như thế này :

1. Trong ACAD bạn đặt lệnh tắt của lệnh MoveM (trong file acad.pgp) -> Nay mình xây dựng lệnh M của Lisp có tính năng giống y như lệnh MOVE của CAD (lần này thì giống lệnh MOVE của CAD y như 2 giọt nước đấy bạn Hai1401 à)
-> Như vậy bạn sử dụng lệnh M (để MOVE) nhé

2. Tue_NV xây dựng lại Lisp UM (unmove) -> có chức năng đưa đối tượng về vị trí cũ sau khi move
Lisp này xây dựng dựa trên cơ sở là : khi ta move thì tên (ename) của Entity không đổi (nội dung về điểm chèn thay đổi nhưng tên (ename) thì không đổi trước và sau khi Move -> dựa vào đặc điểm này ta có thể UM (unmove) đối tượng làm nhiều lần trên ý tưởng của Tue_NV :

Tức là ta UM (unmove cho đến khi nào) mà số phần tử trong tập hợp chọn SS2 bằng 0 thì không thể UM được nữa -> Cái này theo đúng như ý của User. Hơn nữa, khi Un (unmove) các đối tượng không bị move nhầm thì các đối tượng này không có tác dụng gì cả (theo đúng ý của user luôn) :bigsmile:
Các bạn hãy thử Code này và cho biết ý kiến nhé :


(defun c:m()
(setq ss (ssget))
(command "line" '(0 0 0) '(1 1 1) "")
(setq ss (ssadd (entlast) ss))

(command "move" ss "")
(while (< 0 (getvar "CMDACTIVE")) (command pause))

(setq dc (cdr(assoc 10 (entget (entlast)))))
(setq ss (ssdel (entlast) ss))
(entdel (entlast))
(setq kc (distance '(0 0 0) dc))
(setq ang (angle dc '(0 0 0) ))
(princ)
)
;
(defun c:um(/ ssg po lis)
(prompt "\n Chon doi tuong Move nham :")
(setq ssg (ssget) i 0 j 0)

(while (< i (sslength ss))
(setq lis (append lis (list (ssname ss i))))
(setq i (1+ i))
)

(while (< j (sslength ssg))
(if (/= (member (ssname ssg j) lis) nil)
(progn
(setq ss (ssdel (ssname ssg j) ss))
(setq po (polar '(0 0 0) ang kc))
(setq ssg (ssadd (ssname ssg j) ssg))
)
(princ "\n Doi tuong chon khong phai Move nham")
)
(setq j (1+ j))
)
(command "move" ssg "" '(0 0 0) po)
(princ)
)

Bác Tuệ có thể thừa thắng xông lên bằng cách xem giúp qua cho em 2 yêu cầu nho nhỏ sau đây mà em nghĩ là sẽ tương đồng với cái lisp mà bác đã viết ko ạ, em vô cùng cảm ơn:
- Lisp có nội dung như sau: Sau khi di chuyển rất nhiều đối tượng bằng 1 lệnh MOVE ta lại thấy sót vài đối tượng chưa MOVE cùng, nếu lại nhặt vài đối tượng đó để MOVE tiếp thì rất có thể bản vẽ sẽ không còn được như ban đầu. Lisp này có chức năng MOVE các đối tượng còn sót đó theo phương, hướng và khoảng cách như đã MOVE các đối tượng trước (để bản vẽ không bị thay đổi bất cứ 1 thứ j)
- Bác Tuệ đã chính tay viết cái lisp để có thể làm việc với các đối tượng được COPY SAU CÙNG.

(defun c:cc( / ss frome toe cur obj po1 po2)
(setvar "grips" 0)
(Command "undo" "be")
(setq frome (entlast));; chon doi tuong cuoi cung truoc khi Copy

(Prompt "\nChon doi tuong :")
(setq obj (ssget))
(sssetfirst obj obj)

(setq po1 (getpoint "\n Base point : "))
(setq po2 (getpoint po1 "\n Specify second point of displacement : "))
(Command "Copy" "p" "" po1 po2)


(setq toe (entlast));; chon doi tuong cuoi cung sau khi Copy

(setq cur frome; khoi tao
ss (ssadd)
)
(while (not (eq cur toe));; chon cac doi tuong tu frome den toe
(setq
cur (entnext cur)
ss (ssadd cur ss)
)
)

(sssetfirst ss ss);; highlight ket qua

(setq po1 po2)

(while

(setq po2 (getpoint po1 "\n Specify second point of displacement : "))
(setq frome (entlast))
(Command "Copy" ss "" po1 po2)
(setq toe (entlast))

(setq cur frome; khoi tao
ss (ssadd)
)
(while (not (eq cur toe));; chon cac doi tuong tu frome den toe
(setq
cur (entnext cur)
ss (ssadd cur ss)
)
)
(setq po1 po2)
(sssetfirst ss ss);; highlight ket qua
)

(setvar "grips" 1)
(Command "undo" "end")
(princ)
)

Tuy nhiên em thấy lisp này có lệnh COPY bác tự đặt ra có nhiều đặc điểm giống với cái lệnh MOVE mà bác Hai_1401 đã nói ở trên: "tuy nhiên khi em dùng lệnh này thì thấy 1 điều, đó là với lệnh Move của cad, sau khi mình chọn bắt điểm (BASE POINT) và trong lúc chờ điểm đặt (SECOND POINT) thì tại con trỏ sẽ hiện lên ảnh của các đối tượng mình vừa chọn, tuy nhiên khi em dùng lệnh MNH trong lisp trên thì hoàn toàn ko thấy". Do đó, bác Tuệ có thế viết lại giùm em đoạn CODE để có thể biến lệnh COPY trong lisp giống y như lệnh COPY trong Cad ko ạ?
Xin cảm ơn các bác :bigsmile:
  • 0

#36 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

  • Moderator
  • PipPipPipPipPipPipPip
  • 4296 Bài viết
Điểm đánh giá: 3804 (đỉnh cao)

Đã gửi 18 October 2009 - 05:31 AM

Bác Tuệ có thể thừa thắng xông lên bằng cách xem giúp qua cho em 2 yêu cầu nho nhỏ sau đây mà em nghĩ là sẽ tương đồng với cái lisp mà bác đã viết ko ạ, em vô cùng cảm ơn:
- Lisp có nội dung như sau: Sau khi di chuyển rất nhiều đối tượng bằng 1 lệnh MOVE ta lại thấy sót vài đối tượng chưa MOVE cùng, nếu lại nhặt vài đối tượng đó để MOVE tiếp thì rất có thể bản vẽ sẽ không còn được như ban đầu. Lisp này có chức năng MOVE các đối tượng còn sót đó theo phương, hướng và khoảng cách như đã MOVE các đối tượng trước (để bản vẽ không bị thay đổi bất cứ 1 thứ j)

Chào 'study_forever'
Đây là Lisp MSOT -> Move các đối tượng còn sót lại (chưa MOVE cùng với đối tượng trước đó)
Tue_NV bổ sung vào Lisp nhé :
1. Lệnh M : move các đối tượng của bản vẽ : giống lệnh M (Move) của CAD như 2 giọt nước
2. Lệnh UM (Unmove) : đưa các đối tượng Move nhầm về vị trí cũ
3 . Lệnh MSOT : Move các đối tượng còn sót lại (chưa MOVE cùng với đối tượng trước đó)
Các bạn hãy sử dụng thử và cho mình biết ý kiến nhé :

(defun c:m()
(setq ss (ssget))
(command "line" '(0 0 0) '(1 1 1) "")
(setq ss (ssadd (entlast) ss))

(command "move" ss "")
(while (< 0 (getvar "CMDACTIVE")) (command pause))

(setq dc (cdr(assoc 10 (entget (entlast)))))
(setq ss (ssdel (entlast) ss))
(entdel (entlast))
(setq kc (distance '(0 0 0) dc))
(setq ang (angle dc '(0 0 0) ))
(princ)
)
;
(defun c:um(/ ssg po lis)
(prompt "\n Chon doi tuong Move nham :")
(setq ssg (ssget) i 0 j 0)

(while (< i (sslength ss))
(setq lis (append lis (list (ssname ss i))))
(setq i (1+ i))
)

(while (< j (sslength ssg))
(if (/= (member (ssname ssg j) lis) nil)
(progn
(setq ss (ssdel (ssname ssg j) ss))
(setq po (polar '(0 0 0) ang kc))
(setq ssg (ssadd (ssname ssg j) ssg))
)
(princ "\n Doi tuong chon khong phai Move nham")
)
(setq j (1+ j))
)
(command "move" ssg "" '(0 0 0) po)
(princ)
)
;
(defun c:msot(/ ssg po lis)
(prompt "\n Chon doi tuong Move sot :")
(setq ssg (ssget) i 0 j 0)

(while (< i (sslength ss))
(setq lis (append lis (list (ssname ss i))))
(setq i (1+ i))
)

(while (< j (sslength ssg))
(if (= (member (ssname ssg j) lis) nil)
(progn
(setq po (polar '(0 0 0) (+ pi ang) kc))
(setq ssg (ssadd (ssname ssg j) ssg))
)
(princ "\n Doi tuong chon da Move roi")
)
(setq j (1+ j))
)
(command "move" ssg "" '(0 0 0) po)
(princ)
)

@study : Với yêu cầu 2 thì Tue_NV yêu cầu bạn post bài đúng chổ. Đây là bài viết về Move chứ không phải bài viết về copy. Mong bạn hiểu. Bạn post đoạn code trên ở chổ nào thì trả về đúng chổ cũ của nó. Mình sẽ trả lời bạn nếu bạn post bài đúng chổ. Bạn đồng ý chứ?
Hãy edit lại bài viết trên của bạn và trả về vị trí của nó
  • 3

#37 study_forever

study_forever

    biết vẽ line

  • Members
  • PipPip
  • 22 Bài viết
Điểm đánh giá: 0 (bình thường)

Đã gửi 18 October 2009 - 11:11 PM

Chào 'study_forever'
Đây là Lisp MSOT -> Move các đối tượng còn sót lại (chưa MOVE cùng với đối tượng trước đó)
Tue_NV bổ sung vào Lisp nhé :
1. Lệnh M : move các đối tượng của bản vẽ : giống lệnh M (Move) của CAD như 2 giọt nước
2. Lệnh UM (Unmove) : đưa các đối tượng Move nhầm về vị trí cũ
3 . Lệnh MSOT : Move các đối tượng còn sót lại (chưa MOVE cùng với đối tượng trước đó)
Các bạn hãy sử dụng thử và cho mình biết ý kiến nhé :


(defun c:m()
(setq ss (ssget))
(command "line" '(0 0 0) '(1 1 1) "")
(setq ss (ssadd (entlast) ss))

(command "move" ss "")
(while (< 0 (getvar "CMDACTIVE")) (command pause))

(setq dc (cdr(assoc 10 (entget (entlast)))))
(setq ss (ssdel (entlast) ss))
(entdel (entlast))
(setq kc (distance '(0 0 0) dc))
(setq ang (angle dc '(0 0 0) ))
(princ)
)
;
(defun c:um(/ ssg po lis)
(prompt "\n Chon doi tuong Move nham :")
(setq ssg (ssget) i 0 j 0)

(while (< i (sslength ss))
(setq lis (append lis (list (ssname ss i))))
(setq i (1+ i))
)

(while (< j (sslength ssg))
(if (/= (member (ssname ssg j) lis) nil)
(progn
(setq ss (ssdel (ssname ssg j) ss))
(setq po (polar '(0 0 0) ang kc))
(setq ssg (ssadd (ssname ssg j) ssg))
)
(princ "\n Doi tuong chon khong phai Move nham")
)
(setq j (1+ j))
)
(command "move" ssg "" '(0 0 0) po)
(princ)
)
;
(defun c:msot(/ ssg po lis)
(prompt "\n Chon doi tuong Move sot :")
(setq ssg (ssget) i 0 j 0)

(while (< i (sslength ss))
(setq lis (append lis (list (ssname ss i))))
(setq i (1+ i))
)

(while (< j (sslength ssg))
(if (= (member (ssname ssg j) lis) nil)
(progn
(setq po (polar '(0 0 0) (+ pi ang) kc))
(setq ssg (ssadd (ssname ssg j) ssg))
)
(princ "\n Doi tuong chon da Move roi")
)
(setq j (1+ j))
)
(command "move" ssg "" '(0 0 0) po)
(princ)
)

@study : Với yêu cầu 2 thì Tue_NV yêu cầu bạn post bài đúng chổ. Đây là bài viết về Move chứ không phải bài viết về copy. Mong bạn hiểu. Bạn post đoạn code trên ở chổ nào thì trả về đúng chổ cũ của nó. Mình sẽ trả lời bạn nếu bạn post bài đúng chổ. Bạn đồng ý chứ?
Hãy edit lại bài viết trên của bạn và trả về vị trí của nó

Cảm ơn bác đã giúp đỡ em về cái lisp trên, lisp dùng rất tốt!
Về vấn đề bác nói ở trên em xin trình bày là, hôm trước em đã tìm kiếm rất nhiều trên diễn đàn nhưng ko thấy cái Topic cũ của bác, chỉ còn cái lisp là em đã lưu trong máy thôi. Hôm nay nghe bác góp ý em đã cố gắng liên hệ với thằng bạn em có bài trong Topic cũ đó, nó phải giở mục lịch sử bài viết của nó ra mới thấy được cái Topic này, vì thế em đã gửi yêu cầu trong bài viết ở đó, đồng thời xin phép được bỏ phần yêu cầu ở bài viết trên. Em xin cảm ơn.
Link bài viết ấy đây ạ
  • 0

#38 hai_1401

hai_1401

    biết lệnh rotate

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

Đã gửi 19 October 2009 - 08:04 PM

Chào 'study_forever'
Đây là Lisp MSOT -> Move các đối tượng còn sót lại (chưa MOVE cùng với đối tượng trước đó)
Tue_NV bổ sung vào Lisp nhé :
1. Lệnh M : move các đối tượng của bản vẽ : giống lệnh M (Move) của CAD như 2 giọt nước
2. Lệnh UM (Unmove) : đưa các đối tượng Move nhầm về vị trí cũ
3 . Lệnh MSOT : Move các đối tượng còn sót lại (chưa MOVE cùng với đối tượng trước đó)
Các bạn hãy sử dụng thử và cho mình biết ý kiến nhé :


(defun c:m()
(setq ss (ssget))
(command "line" '(0 0 0) '(1 1 1) "")
(setq ss (ssadd (entlast) ss))

(command "move" ss "")
(while (< 0 (getvar "CMDACTIVE")) (command pause))

(setq dc (cdr(assoc 10 (entget (entlast)))))
(setq ss (ssdel (entlast) ss))
(entdel (entlast))
(setq kc (distance '(0 0 0) dc))
(setq ang (angle dc '(0 0 0) ))
(princ)
)
;
(defun c:um(/ ssg po lis)
(prompt "\n Chon doi tuong Move nham :")
(setq ssg (ssget) i 0 j 0)

(while (< i (sslength ss))
(setq lis (append lis (list (ssname ss i))))
(setq i (1+ i))
)

(while (< j (sslength ssg))
(if (/= (member (ssname ssg j) lis) nil)
(progn
(setq ss (ssdel (ssname ssg j) ss))
(setq po (polar '(0 0 0) ang kc))
(setq ssg (ssadd (ssname ssg j) ssg))
)
(princ "\n Doi tuong chon khong phai Move nham")
)
(setq j (1+ j))
)
(command "move" ssg "" '(0 0 0) po)
(princ)
)
;
(defun c:msot(/ ssg po lis)
(prompt "\n Chon doi tuong Move sot :")
(setq ssg (ssget) i 0 j 0)

(while (< i (sslength ss))
(setq lis (append lis (list (ssname ss i))))
(setq i (1+ i))
)

(while (< j (sslength ssg))
(if (= (member (ssname ssg j) lis) nil)
(progn
(setq po (polar '(0 0 0) (+ pi ang) kc))
(setq ssg (ssadd (ssname ssg j) ssg))
)
(princ "\n Doi tuong chon da Move roi")
)
(setq j (1+ j))
)
(command "move" ssg "" '(0 0 0) po)
(princ)
)

@study : Với yêu cầu 2 thì Tue_NV yêu cầu bạn post bài đúng chổ. Đây là bài viết về Move chứ không phải bài viết về copy. Mong bạn hiểu. Bạn post đoạn code trên ở chổ nào thì trả về đúng chổ cũ của nó. Mình sẽ trả lời bạn nếu bạn post bài đúng chổ. Bạn đồng ý chứ?
Hãy edit lại bài viết trên của bạn và trả về vị trí của nó

Nếu có thể anh Tuệ có thể giúp em viết cái lisp để copy những đối tượng mà copy sót (như với move sót ấy ạ), em xin cảm ơn anh :bigsmile:
  • 0

#39 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 20 October 2009 - 08:37 AM

Em vừa mới move nhiều đối tượng A,B,C... trong đó có move nhầm 1 số đối tượng ko cần phải move là B,C... em muốn có 1 cái lisp để đưa các đối tượng này về vị trí cũ mong các bác giúp đỡ :bigsmile:

Ssg có chiêu này, bạn dùng thử xem có hợp ý không?

;;;--------------------------------------------------
(defun C:MM()
(command "move" (ssget) "" (setq p1 (getpoint)) pause)
(setq p2 (getvar "lastpoint"))
(princ)
)
;;;--------------------------------------------------
(defun C:MN( )
(command "move" (ssget) "" p2 p1)
(princ)
)
;;;--------------------------------------------------

- Lệnh MM: hoạt động không khác gì lệnh move (M) của Acad
- Lệnh MN: chọn những chú nào bị nhầm, trả về nguyên quán! Lưu ý rằng, nó chỉ có tác dụng đúng với các đối tượng được move bởi MM, và phải thực hiện liền ngay sau đó. Để lâu ssg không dám chắc chúng nó có chịu quay về chỗ cũ không, hay là lang thang đâu đó không biết!
- Nếu bạn thường xuyên bị... nhầm thì đổi luôn Move của Acad thành MM
  • 4

#40 nataca

nataca

    biết lệnh adcenter

  • Members
  • PipPipPipPipPipPipPip
  • 712 Bài viết
Điểm đánh giá: 553 (tốt)

Đã gửi 20 October 2009 - 08:48 AM

Ssg có chiêu này, bạn dùng thử xem có hợp ý không?


;;;--------------------------------------------------
(defun C:MM()
(command "move" (ssget) "" (setq p1 (getpoint)) pause)
(setq p2 (getvar "lastpoint"))
(princ)
)
;;;--------------------------------------------------
(defun C:MN( )
(command "move" (ssget) "" p2 p1)
(princ)
)
;;;--------------------------------------------------

- Lệnh MM: hoạt động không khác gì lệnh move (M) của Acad
- Lệnh MN: chọn những chú nào bị nhầm, trả về nguyên quán! Lưu ý rằng, nó chỉ có tác dụng đúng với các đối tượng được move bởi MM, và phải thực hiện liền ngay sau đó. Để lâu ssg không dám chắc là nó có quay về chỗ cũ không, hay là lang thang đâu đó không biết!
- Nếu bạn thường xuyên bị... nhầm thì đổi luôn Move của Acad thành MM

Chiêu này của bác hơi bị lợi hại . Từ khoá của chiêu này là biến lastpoint :bigsmile:
  • 1