LISP ROUTINE - Select Blocks by Effective Name and Rotation, Change Custom Dynamic Properties

LISP ROUTINE - Select Blocks by Effective Name and Rotation, Change Custom Dynamic Properties

emreakyazicigsl
Advocate Advocate
3,674 Views
15 Replies
Message 1 of 16

LISP ROUTINE - Select Blocks by Effective Name and Rotation, Change Custom Dynamic Properties

emreakyazicigsl
Advocate
Advocate

Hey everyone, I'm seeking a LISP that selects blocks according to its name (effective name), its rotation as degrees. Then I want to change their custom dynamic properties (angle, position1x, position1y..) which I want to predefine all.

 

For example, I want to create a LISP that selects all

BLOCKNAME1 with

50· Rotation, then change

Angle 310 degrees

position1x 10

position1y 15 etc.

 

Thanks to @ronjonp, he/she created a LISP that selects blocks according to its effective block name, angle, att_tag and att_value which are predefined.

 

I'm going to attach a dwg and attach the LISP of @ronjonp below. I hope you may help. Thank you.

 

 

 

 

;; Thanks to @ronjonp

(defun c:foo (/ a o s)
  ;; RJP » 2021-07-20
  (cond	((setq s (ssget "_X" '((0 . "INSERT") (2 . "`*U*,BLOCKNAME1"))))
	 (foreach e (vl-remove-if 'listp (mapcar 'cadr (ssnamex s)))
	   (or (and ;; Blockname check
		    (= "BLOCKNAME1" (vla-get-effectivename (setq o (vlax-ename->vla-object e))))
		    ;; Get the 'angle1' dyn prop
		    (setq a (vl-some '(lambda (x)
					(if (= (vla-get-propertyname x) "Angle1")
					  x
					)
				      )
				     (vlax-invoke o 'getdynamicblockproperties)
			    )
		    )
		    ;; See of the angle is 'equal' to 50 degrees
		    (equal (angtof "50") (vlax-get a 'value) 1e-8)
		    ;; Check that the attribute with 'tag1' is equal to 'value123'
		    (= "VALUE1111111" (strcase (getpropertyvalue e "TAG1")))
	       )
	       (ssdel e s)
	   )
	 )
	 (sssetfirst nil s)
	)
  )
  (princ)
)

 

 

 

0 Likes
Accepted solutions (1)
3,675 Views
15 Replies
Replies (15)
Message 2 of 16

ronjonp
Advisor
Advisor

@emreakyazicigsl wrote:

Hey everyone, I'm seeking a LISP that selects blocks according to its name (effective name), its rotation as degrees. Then I want to change their custom dynamic properties (angle, position1x, position1y..) which I want to predefine all.

 

For example, I want to create a LISP that selects all

BLOCKNAME1 with

50· Rotation, then change

Angle 310 degrees

position1x 10

position1y 15 etc.

 

Thanks to @ronjonp, he/she created a LISP that selects blocks according to its effective block name, angle, att_tag and att_value which are predefined.

 

I'm going to attach a dwg and attach the LISP of @ronjonp below. I hope you may help. Thank you.


All you have to do is comment out the attribute check:

;; (= "VALUE1111111" (strcase (getpropertyvalue e "TAG1")))

Then when you have a selection modify the properties you need to change in the properties palette.

0 Likes
Message 3 of 16

emreakyazicigsl
Advocate
Advocate

Yes I tried but this LISP selects according to Angle (Dynamic Property), right now I need Rotation. Also I need to add the part of changing those dynamic properties too after the selection phase.

0 Likes
Message 4 of 16

ronjonp
Advisor
Advisor

@emreakyazicigsl wrote:

Yes I tried but this LISP selects according to Angle (Dynamic Property), right now I need Rotation. Also I need to add the part of changing those dynamic properties too after the selection phase.


This?

 

(defun c:foo (/ o s)
  ;; RJP » 2021-07-20
  (cond	((setq s (ssget "_X" '((0 . "INSERT") (2 . "`*U*,BLOCKNAME1"))))
	 (foreach e (vl-remove-if 'listp (mapcar 'cadr (ssnamex s)))
	   (or (and ;; Blockname check
		    (= "BLOCKNAME1" (vla-get-effectivename (setq o (vlax-ename->vla-object e))))
		    ;; See of the angle is 'equal' to 50 degrees
		    (equal 50. (vla-get-rotation o) 1e-8)
	       )
	       (ssdel e s)
	   )
	 )
	 (sssetfirst nil s)
	)
  )
  (princ)
)

 

Use the properties palette to make your property changes .. code is not required.

 

0 Likes
Message 5 of 16

emreakyazicigsl
Advocate
Advocate

@ronjonp wrote:

@emreakyazicigsl wrote:

Hey everyone, I'm seeking a LISP that selects blocks according to its name (effective name), its rotation as degrees. Then I want to change their custom dynamic properties (angle, position1x, position1y..) which I want to predefine all.

 

For example, I want to create a LISP that selects all

BLOCKNAME1 with

50· Rotation, then change

Angle 310 degrees

position1x 10

position1y 15 etc.

 

Thanks to @ronjonp, he/she created a LISP that selects blocks according to its effective block name, angle, att_tag and att_value which are predefined.

 

I'm going to attach a dwg and attach the LISP of @ronjonp below. I hope you may help. Thank you.


All you have to do is comment out the attribute check:

 

;; (= "VALUE1111111" (strcase (getpropertyvalue e "TAG1")))

 

Then when you have a selection modify the properties you need to change in the properties palette.


I didn't see this part. I know I can do it over there but I'm going to prepare for almost 1500 blocks with 8 different rotation status, therefore appyling only one time is too much important for me unfortunately.

0 Likes
Message 6 of 16

ronjonp
Advisor
Advisor

8 different rotation status and you're making the same change to them all?

0 Likes
Message 7 of 16

emreakyazicigsl
Advocate
Advocate

Not really. for example:

If BLOCKNAME1 & Rotation= 0 then

Angle:0

P1X = 0

P1Y = 60

P2X = 0

P2Y = 30

P3X = 0

P3Y = 40

P4X = 0

P4Y = 50

 

If BLOCKNAME1 & Rotation= 180 then

Angle:180

P1X = 0

P1Y = -60

P2X = 0

P2Y = -50

P3X = 0

P3Y = -40

P4X = 0

P4Y = -30

 

If BLOCKNAME1 & Rotation= 90 then

Angle:270

P1X = 60

P1Y = -60

P2X = 40

P2Y = 10

P3X = 40

P3Y = 0

P4X = 40

P4Y = -10

 

etc. There are lots of combination and blocks, therefore creating a LISP, then prepare every combination of (name&rotation) is much more effective then apply one by one in the long run.

 

 

Also I did a little change in your code, the angle was in radians I guess.

(defun c:foo (/ a o s)

(defun dtr (a)
(* pi (/ a 180.0))
)
(setq ang1 (dtr 50.0))

  ;; RJP » 2021-07-20
  (cond	((setq s (ssget "_X" '((0 . "INSERT") (2 . "`*U*,BLOCKNAME1"))))
	 (foreach e (vl-remove-if 'listp (mapcar 'cadr (ssnamex s)))
	   (or (and ;; Blockname check
		    (= "BLOCKNAME1" (vla-get-effectivename (setq o (vlax-ename->vla-object e))))
		    ;; See of the angle is 'equal' to 50 degrees
		    (equal ang1. (vla-get-rotation o) 1e-8)
		    ;; Check that the attribute with 'tag1' is equal to 'value123'
		    ;; (= "VALUE1111111" (strcase (getpropertyvalue e "TAG1")))
	       )
	       (ssdel e s)
	   )
	 )
	 (sssetfirst nil s)
	)
  )
  (princ)
)

 

0 Likes
Message 8 of 16

emreakyazicigsl
Advocate
Advocate

I tried to alter your code like that with LeeMac's LISP but that didn't work 😂

 

(defun c:foo2 (/ a o s p dynprops)
  ;; RJP » 2021-07-20

(defun dtr (a)
(* pi (/ a 180.0))
)
(setq ang1 (dtr 50.0)
(setq ang2 (dtr 88.0)
)

  (cond	((setq s (ssget "_X" '((0 . "INSERT") (2 . "`*U*,BLOCKNAME1"))))
	 (foreach e (vl-remove-if 'listp (mapcar 'cadr (ssnamex s)))
	   (or (and ;; Blockname check
		    (= "BLOCKNAME1" (vla-get-effectivename (setq o (vlax-ename->vla-object e))))
		    ;; See of the angle is 'equal' to 50 degrees
		    (equal ang1. (vla-get-rotation o) 1e-8)
		    ;; Check that the attribute with 'tag1' is equal to 'value123'
		    ;; (= "VALUE1111111" (strcase (getpropertyvalue e "TAG1")))
	       )
	       (ssdel e s)
	   )
	 )
	 (sssetfirst nil s)
	)
  )

  (setq dynprops (list

		   (cons "Angle1" ang2) 

		   '("Position1 X" . 10)			; all dyn-values are numbers - without ""
		   '("Position1 Y" . 10)

		   '("Position2 X" . 20)			; all dyn-values are numbers - without ""
		   '("Position2 Y" . 20)

		   '("Position3 X" . 30)			; all dyn-values are numbers - without ""
		   '("Position3 Y" . 30)

		   '("Position4 X" . 40)			; all dyn-values are numbers - without ""
		   '("Position4 Y" . 40)

		   ))

(LM:setdynprops p dynprops)


  (princ)
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Set Dynamic Block Properties  -  Lee Mac
;; Modifies values of Dynamic Block properties using a supplied association list.
;; blk - [vla] VLA Dynamic Block Reference object
;; lst - [lst] Association list of (( . ) ... )
;; Returns: nil

(defun LM:setdynprops ( blk lst / itm )
    (setq lst (mapcar '(lambda ( x ) (cons (strcase (car x)) (cdr x))) lst))
    (foreach x (vlax-invoke blk 'getdynamicblockproperties)
        (if (setq itm (assoc (strcase (vla-get-propertyname x)) lst))
            (vla-put-value x (vlax-make-variant (cdr itm) (vlax-variant-type (vla-get-value x)))))))

 

0 Likes
Message 9 of 16

ronjonp
Advisor
Advisor

@emreakyazicigsl wrote:

Not really. for example:

If BLOCKNAME1 & Rotation= 0 then

Angle:0

P1X = 0

P1Y = 60

P2X = 0

P2Y = 30

P3X = 0

P3Y = 40

P4X = 0

P4Y = 50

 

If BLOCKNAME1 & Rotation= 180 then

Angle:180

P1X = 0

P1Y = -60

P2X = 0

P2Y = -50

P3X = 0

P3Y = -40

P4X = 0

P4Y = -30

 

If BLOCKNAME1 & Rotation= 90 then

Angle:270

P1X = 60

P1Y = -60

P2X = 40

P2Y = 10

P3X = 40

P3Y = 0

P4X = 40

P4Y = -10

 

etc. There are lots of combination and blocks, therefore creating a LISP, then prepare every combination of (name&rotation) is much more effective then apply one by one in the long run.

 

 

Also I did a little change in your code, the angle was in radians I guess.

(defun c:foo (/ a o s)

(defun dtr (a)
(* pi (/ a 180.0))
)
(setq ang1 (dtr 50.0))

  ;; RJP » 2021-07-20
  (cond	((setq s (ssget "_X" '((0 . "INSERT") (2 . "`*U*,BLOCKNAME1"))))
	 (foreach e (vl-remove-if 'listp (mapcar 'cadr (ssnamex s)))
	   (or (and ;; Blockname check
		    (= "BLOCKNAME1" (vla-get-effectivename (setq o (vlax-ename->vla-object e))))
		    ;; See of the angle is 'equal' to 50 degrees
		    (equal ang1. (vla-get-rotation o) 1e-8)
		    ;; Check that the attribute with 'tag1' is equal to 'value123'
		    ;; (= "VALUE1111111" (strcase (getpropertyvalue e "TAG1")))
	       )
	       (ssdel e s)
	   )
	 )
	 (sssetfirst nil s)
	)
  )
  (princ)
)

 


You can also get radians from degrees like so: (angtof "50")

0 Likes
Message 10 of 16

ronjonp
Advisor
Advisor
Accepted solution

Based on these directions give this code a try .. although the results seem incorrect to me:


@emreakyazicigsl wrote:

Not really. for example:

If BLOCKNAME1 & Rotation= 0 then

Angle:0

P1X = 0

P1Y = 60

P2X = 0

P2Y = 30

P3X = 0

P3Y = 40

P4X = 0

P4Y = 50

 

If BLOCKNAME1 & Rotation= 180 then

Angle:180

P1X = 0

P1Y = -60

P2X = 0

P2Y = -50

P3X = 0

P3Y = -40

P4X = 0

P4Y = -30

 

If BLOCKNAME1 & Rotation= 90 then

Angle:270

P1X = 60

P1Y = -60

P2X = 40

P2Y = 10

P3X = 40

P3Y = 0

P4X = 40

P4Y = -10


(defun c:foo2 (/ lm:setdynprops dtr l o r s)
  ;; RJP » 2021-07-30
  ;; Set Dynamic Block Properties  -  Lee Mac
  ;; Modifies values of Dynamic Block properties using a supplied association list.
  ;; blk - [vla] VLA Dynamic Block Reference object
  ;; lst - [lst] Association list of (( . ) ... )
  ;; Returns: nil
  (defun lm:setdynprops	(blk lst / itm)
    (setq lst (mapcar '(lambda (x) (cons (strcase (car x)) (cdr x))) lst))
    (foreach x (vlax-invoke blk 'getdynamicblockproperties)
      (if (setq itm (assoc (strcase (vla-get-propertyname x)) lst))
	(vla-put-value x (vlax-make-variant (cdr itm) (vlax-variant-type (vla-get-value x))))
      )
    )
  )
  (defun dtr (a) (* pi (/ a 180.0)))
  (cond
    ((setq s (ssget "_X" '((0 . "INSERT") (2 . "`*U*,BLOCKNAME1"))))
     ;; Dynamic properties of 'BLOCKNAME1'
     (setq l '("Position1 X"	   "Position1 Y"       "Position2 X"	   "Position2 Y"
	       "Position3 X"	   "Position3 Y"       "Position4 X"	   "Position4 Y"
	      )
     )
     (foreach e	(vl-remove-if 'listp (mapcar 'cadr (ssnamex s)))
       (if (= "BLOCKNAME1" (strcase (vla-get-effectivename (setq o (vlax-ename->vla-object e)))))
	 (cond ((equal 0 (setq r (vla-get-rotation o)) 1e-8)
		(lm:setdynprops
		  o
		  (mapcar '(lambda (r j) (cons r j))
			  l
			  (list 0 (dtr 60) 0 (dtr 50) 0 (dtr 40) 0 (dtr 30))
		  )
		)
	       )
	       ((equal (angtof "90") r 1e-8)
		(lm:setdynprops
		  o
		  (mapcar '(lambda (r j) (cons r j))
			  l
			  (list (dtr 60) (dtr -60) (dtr 40) (dtr 10) (dtr 40) 0 (dtr 40) (dtr -10))
		  )
		)
	       )
	       ((equal (angtof "180") r 1e-8)
		(lm:setdynprops
		  o
		  (mapcar '(lambda (r j) (cons r j))
			  l
			  (list 0 (dtr -60) 0 (dtr -50) 0 (dtr -40) 0 (dtr -30))
		  )
		)
	       )
	 )
       )
     )
    )
  )
  (princ)
)

 

0 Likes
Message 11 of 16

emreakyazicigsl
Advocate
Advocate

Oh god thank you. There was a little error about positions, I fixed it.

 

((setq s (ssget "_X" '((0 . "INSERT") (2 . "`*U*,BLOCKNAME1"))))
;; Dynamic properties of 'BLOCKNAME1'
(setq l '("Angle1" "Position1 X" "Position1 Y" "Position2 X" "Position2 Y"
"Position3 X" "Position3 Y" "Position4 X" "Position4 Y"
)
)
(foreach e (vl-remove-if 'listp (mapcar 'cadr (ssnamex s)))
(if (= "BLOCKNAME1" (strcase (vla-get-effectivename (setq o (vlax-ename->vla-object e)))))
(cond ((equal 0 (setq r (vla-get-rotation o)) 1e-8)
(lm:setdynprops
o
(mapcar '(lambda (r j) (cons r j))
l
(list (dtr 90) 0 60 0 30 0 40 0 50)

 

 

You saved my day, I'm trully grateful to you. I can't bethank enough.

0 Likes
Message 12 of 16

ronjonp
Advisor
Advisor

Glad you we're able to modify the code and get it working. That's the beginning of becoming a programmer! 🍻

0 Likes
Message 13 of 16

emreakyazicigsl
Advocate
Advocate

Thank you even thought you look like kidding with me 😂 I'm preparing some basic stuff but these are much higher level than my current ability. You are trully expert on this issue, not regarding my beginner level.

0 Likes
Message 14 of 16

Sea-Haven
Mentor
Mentor

Just a question how many rotation angles is it just 0 90 180 & 270 ? Then a simple which one question or is there other angles ? If so if there is some relationship can the other values not be calculated for any angle ?

0 Likes
Message 15 of 16

jochem.beullens
Participant
Participant

Hello,

 

I have a similar problem. I have a lisp can match the rotation property of one block to another.

(defun C:BlkRot (/ ss1 matblk brot cnt blk obj)
(setq ss1 (ssget (list (cons 0 "INSERT"))))
(if ss1
(progn
(setq matblk (car (entsel "\nSelect Block to match: ")))
(setq brot (vlax-get-property
(vlax-ename->vla-object matblk) 'Rotation))
(setq cnt 0)
(while (< cnt (sslength ss1))
(setq blk (ssname ss1 cnt))
(setq obj (vlax-ename->vla-object blk))
(setq obj (vlax-put-property obj 'Rotation brot))
(setq cnt (1+ cnt))
)
)
)
(princ)
)

 

 

I want to adjust this lisp so I can match the custom property Angle1 from one block to another. I have blocks with dynmic parameters. If I use the rotation parameter it is not the rotation that changes but the property Angle1. The problem is that this property is a custom property and not so easy to get and set this value?

0 Likes
Message 16 of 16

Sea-Haven
Mentor
Mentor

Did you look at the dynamic block lisp by Lee-mac it has multiple functions so can get properties of a dynamic block such as a custom angle, not the block rotation.

0 Likes