Automatic placement of blocks

Automatic placement of blocks

yu85.info
Collaborator Collaborator
754 Views
7 Replies
Message 1 of 8

Automatic placement of blocks

yu85.info
Collaborator
Collaborator

Hi, I have a really hard task regarding the positions of blocks in a drawing.

I need to move each block with the block name - "OLD" to the position of the block named - "NEW"

Now, some of them are in the same position but a lot of them are slightly near them. The blocks match by an attribute "POINT". 

Can anyone help me with an automatic way to reposition all of the OLD blocks to match the position of the NEW blocks just near them?

I have attached a DWG file with the blocks and separated them by name and by layer. 

Thank you all on advance    

0 Likes
Accepted solutions (1)
755 Views
7 Replies
Replies (7)
Message 2 of 8

ВeekeeCZ
Consultant
Consultant

These things are fairly simple to do, you should teach yourself to do that.

 

(vl-load-com)

(defun c:MoveOldToNew ( / s i o n a e)

  (if (setq s (ssget '((0 . "INSERT") (8 . "NEW,OLD") (66 . 1))))
    (repeat (setq i (sslength s))
      (setq e (ssname s (setq i (1- i))))
      (if (not (vl-catch-all-error-p (setq x (vl-catch-all-apply 'getpropertyvalue (list e "POINT")))))
	(if (= "OLD" (cdr (assoc 8 (entget e))))
	  (setq o (cons (cons x e) o))
	  (setq n (cons (cons x e) n))))))
  (foreach e o
    (if (setq a (assoc (car e) n))
      (setpropertyvalue (cdr e) "Position" (getpropertyvalue (cdr a) "Position"))))
  (princ)
  )

 

Message 3 of 8

yu85.info
Collaborator
Collaborator

Thank you for your help. If it is fine by you I still have a  problem. I forgot to mention that in the drawing there are some  OLD blocks with the same number in the field POINT. They are not close to each other but the do exist in the same drawing. So when I try to use your lisp and choose the entire drawing in one time it deletes all of the OLD blocks.

Can you kindly help me with that please?

0 Likes
Message 4 of 8

ВeekeeCZ
Consultant
Consultant
Accepted solution

Then it's up to you to specify the "close" distance to consider.

 

(vl-load-com)

(defun c:MoveOldToNew ( / s i o n a e c l op np)

  (if (and (setq s (ssget '((0 . "INSERT") (8 . "NEW,OLD") (66 . 1))))
	   (setq c (getdist "\nSpecify max distance to consider: "))
	   )
    (repeat (setq i (sslength s))
      (setq e (ssname s (setq i (1- i))))
      (if (not (vl-catch-all-error-p (setq x (vl-catch-all-apply 'getpropertyvalue (list e "POINT")))))
	(if (= "OLD" (cdr (assoc 8 (entget e))))
	  (setq o (cons (cons x e) o))
	  (setq n (cons (cons x e) n))))))
  (foreach e o
    (if (and (setq l (vl-remove-if '(lambda (x) (/= (car x) (car e))) n))
	     (setq op (getpropertyvalue (cdr e) "Position"))
	     (setq l (vl-sort l '(lambda (x1 x2) (< (distance op (getpropertyvalue (cdr x1) "Position"))
						    (distance op (getpropertyvalue (cdr x2) "Position"))))))
	     (< (distance (setq np (getpropertyvalue (cdar l) "Position")) op) c))
      (setpropertyvalue (cdr e) "Position" np)))
  (princ)
  )

 

Message 5 of 8

yu85.info
Collaborator
Collaborator

I really apologize but it seems that the lisp ask me to to input the precise distance between the blocks in order that it will work and not the max distance (even though it does write "Specify max distance to consider"). In any case the maximum distance in not over than 2 meters (the units drawing is in METERS)

Thank you again very much sir    

0 Likes
Message 6 of 8

ВeekeeCZ
Consultant
Consultant

Ok, I see what's wrong. Try the updated code.

Message 7 of 8

yu85.info
Collaborator
Collaborator

AMAZING!!! Thank you so much sir for your time and patience.

0 Likes
Message 8 of 8

ВeekeeCZ
Consultant
Consultant

Good. From all the points of the same number it takes the closest one, if it's within the max distance.

0 Likes