LISP to keep the rotation of dynamic blocks and make them static

LISP to keep the rotation of dynamic blocks and make them static

karpki
Advocate Advocate
3,098 Views
22 Replies
Message 1 of 23

LISP to keep the rotation of dynamic blocks and make them static

karpki
Advocate
Advocate

Hi, Friends,

 

There are dynamic blocks with the only rotation function in the drawing, see sample in the attachment.

The task is to make them static and keep angled as they are.

So steps probably should be like these

1. to get the list of rotation angles of blocks XX selecting one of them. Selection is needed cause there can be a range of different blocks.  

I'm not sure but may be by kind of this procedure 

(setq obj (car (vl-remove-if-not '(lambda (x) (= (vla-get-propertyname x) "_Angle1"))
(vlax-safearray->list(vlax-variant-value (vla-getdynamicblockproperties obj)))))

 

2. to edit the block XX by killing dynamic functions f.e. by this list of commands _bedit;ai_selall;_copybase;0;0;delete;_pasteclip;0;_bclose;;

 

3. to rotate each of XX blocks by the angle taken in p. 1

this is the most hard part I think 

 

Does it look possible ? Do you have kind of ready lisp or suggestions ?

0 Likes
Accepted solutions (2)
3,099 Views
22 Replies
Replies (22)
Message 2 of 23

ronjonp
Advisor
Advisor

Maybe this?

 

(defun c:foo (/ bn n s)
  (cond	((setq s (ssget ":L" '((0 . "INSERT"))))
	 (setq bn "YourBlockName-")
	 (setq n 0)
	 (foreach e (vl-remove-if 'listp (mapcar 'cadr (ssnamex s)))
	   (while (tblobjname "block" (strcat bn (itoa (setq n (1+ n))))))
	   (vla-converttostaticblock (vlax-ename->vla-object e) (strcat bn (itoa n)))
	 )
	)
  )
  (princ)
)

 

0 Likes
Message 3 of 23

karpki
Advocate
Advocate

Thanks for the answer! Respect to coder!

Lisp works quite good BUT changes names! 

 

This is very important to keep block names as they are cause original names are in use for counting amounts and contains specific and needed info.

 

Lets imagine if drawing contain 5 unique blocks by 100 pcs of each as a result of this lisp I will have 500 different blocks instead of 5!

 

0 Likes
Message 4 of 23

ronjonp
Advisor
Advisor

@karpki 

Your thread title is a bit misleading then: LISP to keep the rotation of dynamic blocks and make them static

What is the purpose of making static blocks ( is it even needed )?

Do you want to count blocks based on rotation?

Your example drawing only has one block definition in it so counting them is quite easy.

 

Here is a guess at what you want. Creates block definitions based on rotation ( although I feel this is bad practice ).

 

(defun c:foo (/ nm o r s)
  ;; RJP » 2021-02-17
  ;; Appends a block rotation to the name and converts it and others to static
  (cond
    ((setq s (ssget ":L" '((0 . "INSERT"))))
     (foreach e	(vl-remove-if 'listp (mapcar 'cadr (ssnamex s)))
       (setq nm (vla-get-effectivename (setq o (vlax-ename->vla-object e))))
       (foreach	p (vlax-invoke o 'getdynamicblockproperties)
	 ;; This check is specific to the 'RT-SP' block in example drawing
	 (or (= "Origin" (vla-get-propertyname p)) (setq r (vlax-get p 'value)))
       )
       (if (= 'real (type r))
	 (if (tblobjname
	       "block"
	       (setq nm (vl-string-right-trim "0" (strcat nm "-" (rtos (* (/ r pi) 180.0) 2 8))))
	     )
	   (vla-put-name o nm)
	   ;; (entmod (append (entget e) (list (cons 2 nm))))
	   (vla-converttostaticblock (vlax-ename->vla-object e) nm)
	 )
       )
     )
    )
  )
  (princ)
)

 

Result:

 

Block...........Count
---------------------
RT-SP-135.......1
RT-SP-45........2
RT-SP-90........2
RT-SP-0.........9
RT-SP-270.......3

 

 

0 Likes
Message 5 of 23

karpki
Advocate
Advocate

I count it with the lisp attached. If to keep them dynamic I got *Uxxx instead of the block names

0 Likes
Message 6 of 23

ВeekeeCZ
Consultant
Consultant

Really?

You want to have a LISP to destroy your drawing just because you have another LISP that can't handle what you need.

Message 7 of 23

pbejse
Mentor
Mentor
Accepted solution

@karpki wrote:

Hi, Friends,

 

There are dynamic blocks with the only rotation function in the drawing, see sample in the attachment.

Does it look possible ? Do you have kind of ready lisp or suggestions ?


Retrieve the current angle value from DP, assigned the value the rotation of all target objects BEFORE you "kill" the dynamic property of the block.

(defun c:stripOfRotationValue (/ ss i dp)
(setq aDocblocks  (Vla-get-blocks (vla-get-ActiveDocument (vlax-get-acad-object)))) 
(setq bn '(  "RT-SP" ))
  (if (setq ss (ssget ":L" '((0 . "INSERT"))))
    (repeat (setq i (sslength ss))
      (setq e (vlax-ename->vla-object (ssname ss (setq i (1- i)))))
      (if (and
	    (member (strcase (vla-get-effectivename e)) bn )
	    (setq
	      dp (vl-some '(lambda (d)
			     (if (eq "????1" (vla-get-PropertyName d))
			       (list (vlax-get d 'Value) d)
			     )
			   )
			  (vlax-invoke e 'getdynamicblockproperties)
		 )
	    )
	  )
	(progn
	  (vlax-put (cadr dp) 'Value 0.0)
	  (vlax-put e 'Rotation (Car dp))
	)
      )
    )
  )(princ)
)

Replace the "????1" with the correct Dynamic property name. it appears like that on my workstation.

 

Message 8 of 23

karpki
Advocate
Advocate

Dear pbejse

3 then auto start that code

The sample block name RT-SP is written in the code and code works only with this block name.

There are tens or hundreds of them normally in the working drawing, that's why I'm asking

With Best regards! 

And with respect to your coding talant!

0 Likes
Message 9 of 23

ronjonp
Advisor
Advisor

Just use this to count your blocks. The last code I provided is going to make your life harder in the long run.

 

Also .. that code 'count3' you posted works fine in my test ?

ronjonp_0-1613663173083.png

 

0 Likes
Message 10 of 23

pbejse
Mentor
Mentor

@karpki wrote:

Dear pbejse

3 then auto start that code

The sample block name RT-SP is written in the code and code works only with this block name.

There are tens or hundreds of them normally in the working drawing, that's why I'm asking


What you do is  add the block names on the bncoll variable

Add the PropertyName names on DpName variable

The "_X" as ssget filter will select all the blcoks on the drawing 

(defun c:stripOfRotationValue (/ blknameColl aDocblocks ss i dp bn)
(setq blknameColl nil
       aDocblocks  (Vla-get-blocks (vla-get-ActiveDocument (vlax-get-acad-object))))
  
(setq bncoll '(  "RT-SP" "OTHERBLOCK" "ANOTHERBLOCK"))
(setq DpName '( "????1"  "_ANGLE1" "ANGLE700"))
  
  (if (setq ss (ssget "_X" '((0 . "INSERT"))))
    (repeat (setq i (sslength ss))
      (setq e (vlax-ename->vla-object (ssname ss (setq i (1- i)))))
      
      (if (and
	    (member (strcase (vla-get-effectivename e))  bncoll)
	    (setq dp (vl-some '(lambda (d)
			     (if (member  (vla-get-PropertyName d) DpName)
			       (list (vlax-get d 'Value) d)
			     )
			   )
			  (vlax-invoke e 'getdynamicblockproperties)
		 )
	    )
	    )
	(progn
	  (vlax-put (cadr dp) 'Value 0.0)
	  (vlax-put e 'Rotation (Car dp))
	)
      )
    )
    )
    (princ)
)

or you can make an assocaition list. the first being the block name paired with the target dynamic property name

 

(defun c:stripOfRotationValue (/ blknameColl aDocblocks ss i dp bn)
(setq blknameColl nil
       aDocblocks  (Vla-get-blocks (vla-get-ActiveDocument (vlax-get-acad-object))))
  
(setq pairs'(("RT-SP" "????1")
	      ("OTHERBLOCK" "_ANGLE1")
	      ("ANOTHERBLOCK" "ANGLE700")))
  
  (if (setq ss (ssget "_X" '((0 . "INSERT"))))
    (repeat (setq i (sslength ss))
      (setq e (vlax-ename->vla-object (ssname ss (setq i (1- i)))))
      
      (if (and
	    (setq data (assoc  (strcase (vla-get-effectivename e))   pairs))
	    (setq dp (vl-some '(lambda (d)
			     (if (eq   (vla-get-PropertyName d) (Cadr data))
			       (list (vlax-get d 'Value) d)
			     )
			   )
			  (vlax-invoke e 'getdynamicblockproperties)
		 )
	    )
	    )
	(progn
	  (vlax-put (cadr dp) 'Value 0.0)
	  (vlax-put e 'Rotation (Car dp))
	)
      )
    )
    )
    (princ)
)

HTH

 

0 Likes
Message 11 of 23

karpki
Advocate
Advocate

Sorry for mixing up 

And thank you for noticing! The lsp given was wrong cause it was just moded 1 day ago by pbejse ! Sorry!

But there are tens of reasons happens every day.

Just one more reason for fast explain: replacing one block with another one. This action breaks all the picture if blocks were turned not by rotation function but dynamic function way!

Thanks!

 

 

0 Likes
Message 12 of 23

karpki
Advocate
Advocate

karpki_1-1613671342597.png

 

just has checked amount of blocks in the open project, and this is not a big project..

 

The end of a list:

 

karpki_0-1613671099954.png

Problem also that in each project the ranges of blocks are totally different 

 

Please! Make it working via "select the block" prompt

 

0 Likes
Message 13 of 23

pbejse
Mentor
Mentor

@karpki wrote:

Please! Make it working via "select the block" prompt

I cannot fix what i cannot  understand nor see  @karpki 

 

 

Message 14 of 23

karpki
Advocate
Advocate

OK. I respect your opinion. Everybody of us has different practice and experience. I also can't often understand others.

 

Will use your first reduction just changing the name in the code!

Thank you! You are my hero of the day!

0 Likes
Message 15 of 23

karpki
Advocate
Advocate

Or better I will do it by myself one day

 

I hope!

 

Good night!

0 Likes
Message 16 of 23

pbejse
Mentor
Mentor

@karpki wrote:

Or better I will do it by myself one day

 

I hope!

 

Good night!


Thats the spirit @karpki . You will get the hang of it. 

Good job

0 Likes
Message 17 of 23

karpki
Advocate
Advocate
  • Hi, I have merged different codes to one Lisp according steps I mentioned before. Could you please look at this compilation. There are few mistakes I can't handle. Comments are inside. 
0 Likes
Message 18 of 23

pbejse
Mentor
Mentor
Accepted solution

@karpki wrote:
  • Hi, I have merged different codes to one Lisp according steps I mentioned before. Could you please look at this compilation. There are few mistakes I can't handle. Comments are inside. 

I see what you're doing, if the reason behind "killing" the dynamic block is for your block count to work so it does not read the Anonymous Name but the actual block name, I'm afraid you are in for a surprise.

 

Either we modify your block count to read anonymous names or revise the code to "re-insert" the block after killing like you had originally with no modifying the angle dp.

 

See attached for your modified posted, i added/change soem bits for it to work. We will come back later to discusss what i mentioned above.

 

Message 19 of 23

karpki
Advocate
Advocate

Hi,

Thanks for changes!

First attempt was with the "ssget mistake"

I  changed "I" to "_I" here:

    (if (setq ss2 (ssget "_I" '((0 . "INSERT"))))

So after this change mistake has disappeared.

-------------

But after killing blocks, they are not at the right angels - all zeroes.

karpki_0-1614100943821.png

 

How to rotate them back according dynamicblockproperty values taken in step 2 ?

 

Best regards

K

 

0 Likes
Message 20 of 23

karpki
Advocate
Advocate

In last many years there were a lot of why I need it.

And yes I have given a wrong example about counting. Cause this was solved.

Few more words

We're often replacing blocks in the plan or totally changing content inside the block, when the name of the block should be kept same. Because it's not just a name but means something - kind a code. There are a lot of different cases happens why we do it often before the project is done. And if rotation is originally given by dynamic function, all those blocks (f/e/ 100 pcs per floor) lose their angles and I have to rotate them manually.

Our computers are quite old. Sometimes we got plans with a huge amount of such blocks. We have to redraw them or kill them and only this simplifying makes our old machines working quite well.  Of curse there are not only rotation functions. But only rotation issue can be solved as I have offered. It will help a lot if this lisp will work.

And yes cause my practice I hate dynamic blocks!

0 Likes