Lisp to obtain Attribute value to Rotate Block

Lisp to obtain Attribute value to Rotate Block

Anonymous
Not applicable
3,884 Views
23 Replies
Message 1 of 24

Lisp to obtain Attribute value to Rotate Block

Anonymous
Not applicable

I have used many Lisp programs over the years, but have done very little programming. I am trying to find or create a Lisp program which will automatically rotate a block to the angle specified in an attribute contained in the block. In other words - if I change the attribute angle to 53 degrees, I want the block to rotate around its insertion point to an angle of 53 degrees. Eventually, I would like the program to work in 2 ways:  1.) By changing the attribute as I described, or 2.) By specifying the angle when inserting the block (which will place the block at the appropriate angle and change the att txt to the angle spec'd on insertion.  Any help with this would be GREATLY appreciated.

 

Dustin

0 Likes
3,885 Views
23 Replies
Replies (23)
Message 2 of 24

dlanorh
Advisor
Advisor
How accurate will the stored angle be? Have you factored in that; to Autocad, East is 0 (zero) radians, when it comes to rotation angles?

I am not one of the robots you're looking for

0 Likes
Message 3 of 24

Anonymous
Not applicable

The angle will only be whole numbers....no decimal places or m/s/d.....There is a catch however. In the application I am using X= 0 degress, however, X points north in the 90 degree direction....and the angles go clockwise instead of counter clockwise as normal.....so - for instance, an "Azimuth angle" of 60degrees - (which is what is in the tag in the attribute) - is actually pointing at 30 degrees....because Azimuth angles are measurements from the North direction - which correlates to: Azimuth of 60degrees is 60degrees away from North..... North is pointing at 90d....so rotation of 60 degrees away from North (90) is the actual world angle of 30degrees......At any rate, I can program that part with a piece of code.....I just need a Lisp routine which will pull the field angle from the attribute, then rotate the block around its insertion point so that it is at the correct angle. 

0 Likes
Message 4 of 24

dlanorh
Advisor
Advisor

@Anonymous wrote:

The angle will only be whole numbers....no decimal places or m/s/d.....There is a catch however. In the application I am using X= 0 degress, however, X points north in the 90 degree direction....and the angles go clockwise instead of counter clockwise as normal.....so - for instance, an "Azimuth angle" of 60degrees - (which is what is in the tag in the attribute) - is actually pointing at 30 degrees....because Azimuth angles are measurements from the North direction - which correlates to: Azimuth of 60degrees is 60degrees away from North..... North is pointing at 90d....so rotation of 60 degrees away from North (90) is the actual world angle of 30degrees......At any rate, I can program that part with a piece of code.....I just need a Lisp routine which will pull the field angle from the attribute, then rotate the block around its insertion point so that it is at the correct angle. 


 

That's the reason i asked the question Robot tongue

 

Is this any block that has the required attribute TAG Name, or a specific block?

 

What is the attributes TAG name?

 

I am not one of the robots you're looking for

0 Likes
Message 5 of 24

Anonymous
Not applicable

IT WOULD BE FOR A HANDFUL OF DIFFERENT BLOCKS THAT HAVE THAT SAME TAG.....BUT THE ATTRIBUTE IS IN EACH SEPERATE BLOCK....SO WE PLACE ONE BLOCK AND EDIT THE ATT FIELD TO SAY 20DEG....THEN ANOTHER ONE OF THE SAME BLOCK -  WILL BE ROTATED AT 30DEG AND WE WILL EDIT THAT BLOCKS ATT FIELD TO BE 30DEG.....SO THE ATT WOULD NOT GOVERN ALL OF THE BLOCKS, ONLY THE INDIVIDUAL BLOCK.

0 Likes
Message 6 of 24

dlanorh
Advisor
Advisor

@Anonymous wrote:

IT WOULD BE FOR A HANDFUL OF DIFFERENT BLOCKS THAT HAVE THAT SAME TAG.....BUT THE ATTRIBUTE IS IN EACH SEPERATE BLOCK....SO WE PLACE ONE BLOCK AND EDIT THE ATT FIELD TO SAY 20DEG....THEN ANOTHER ONE OF THE SAME BLOCK -  WILL BE ROTATED AT 30DEG AND WE WILL EDIT THAT BLOCKS ATT FIELD TO BE 30DEG.....SO THE ATT WOULD NOT GOVERN ALL OF THE BLOCKS, ONLY THE INDIVIDUAL BLOCK.


I understand that, but the attribute must have a tag "name". If I don't know the name of the tag, i can't search a block to see if it has that tag  and if it does extract the relevant textstring, or conversly fill the block attributes textstring with its inserted rotation.

 

Post an example drawing (AutoCAD 2010 format) containing all the blocks that have the same "rotation data" tag.

I am not one of the robots you're looking for

0 Likes
Message 7 of 24

Anonymous
Not applicable

Well, there are 4 or 5 blocks which have this same attribute tag within them. And, there are actually some other types of equipment blocks that I could modify the lisp routines to work with. Anyway, I have attached a few pics which show an assembly dwg with the antenna blocks I am referring to....the 2nd pic has one of the blocks with an exploded block showing the Att. Tags...and the insertion point. The 3rd is just another block which has the same Att. Tag -  and would be used with the Lisp routine. The long centerline extending from the center of the circle is the line for which the Azimuth angle would correlate....As shown - that line is -310degrees from North, or "Azimuth 0" - which as I stated earlier is 90degrees in normal degrees. Hopefully all of that makes sense. Thanks for replying...I really appreciate your help with this.

 

DustinAnnotation 2019-06-19 184540.pngAnnotation 2019-06-19 193246.pngAnnotation 2019-06-19 195418.png

0 Likes
Message 8 of 24

dlanorh
Advisor
Advisor

I have a lisp almost finished, but without having a drawing just containing an example of each block I cannot test if the lisp works correctly.

 

Does the "EXISTING_LTE_CDMA_W_CALLOUT" block also have a left and right option, or is something else controlling the text readability?

 

I also don't know if these are standard text attributes or MText attributes, which will change how the azimuth is extracted from the text string (mtext attributes contain format information as part of the text string) .

I am not one of the robots you're looking for

0 Likes
Message 9 of 24

Anonymous
Not applicable

Good question...as I am relatively new to this company, I did not create these blocks - so I am not sure if it is MTEXT or TEXT....And I am realizing the issue with the text rotation....basically, if the block is between (real world degrees) 0 deg to 89deg or 271deg to 0deg, I want the text facing up towards the right as shown on the "right" LTE block....if the block rotation is 90deg to 270deg, I want the text as shown on the "left" LE block. Strangely - whoever created these blocks made a left & right for the LTE block, but only made one block for the CDMA, and they have just been mirroring the CDMA block -  which orients the text opposite as desired). Of course the issue - I assume - is that 2 Lisp routines would have to be created for the  LTE blocks...1 for the Left block, 1 for the Right block.....Ideally, I would like to have one block which would just reorient the text  after Azimuth angle 179deg (which is real world angle 271deg).....after Azimuth 179deg, the text would switch directions. I realize that that is more complicated and would require recreating the block and attribute text....So I am not sure what to do. Hopefully, all of that makes sense. I am attaching the block dwg's for you. I really appreciate your help.  

0 Likes
Message 10 of 24

dlanorh
Advisor
Advisor

Sorry, but i can't open or insert these drawings as I run AutoCAD 2012 and these were created with a later version. Could you please open them, save as AutoCAD 2010 and re-post.

 

Thanks

 

 

I am not one of the robots you're looking for

0 Likes
Message 11 of 24

Anonymous
Not applicable

I opened them and saved them as 2010 acad files...but an error came up about Proxy Graphics...saying that some objects were not compatible with older versions....Not sure what that would be - they should just be basic blocks with attributes....I saved them anyway....Try these and see if you can open them.

0 Likes
Message 12 of 24

Anonymous
Not applicable

I also exploded them and saved them as 2010 files...Not sure if that helps....but here they are.

0 Likes
Message 13 of 24

dlanorh
Advisor
Advisor

Many thanks, I can now open the drawings. I didn't need the exploded versions, but thanks anyway.

 

We have a problem in that the initial insertion rotation of the blocks has them angled. This complicates calculating the angle the block needs to be rotated, and would further complicate a lisp to insert the block. I'll see what i can do tomorrow and over the weekend, work permitting.

I am not one of the robots you're looking for

0 Likes
Message 14 of 24

Anonymous
Not applicable

I should clarify that I just wblocked that block so you could see it....The true block is actually pointing straight up at 90deg....(which is again = Azimuth 0deg)....the calculation for the angle of the block would basically be X=0 , X being the real world angle of the block, and whatever angle is put in the Azimuth field would be 0 - "azimuth field" .....so if the Azimuth is 60......the lisp routine would rotate the block -60 from its "home" position - which is at real world 90deg. Sorry about sending you a block that is not the actual true block.

0 Likes
Message 15 of 24

Anonymous
Not applicable

This is what the actual blocks look like....with 0,0 of each block being the center of the circle on the bottom of each.....The text is just the the Attribute defaults.....So this would be the blocks at "0 rotation"Annotation 2019-06-20 142719.png

0 Likes
Message 16 of 24

Anonymous
Not applicable

Actually, thinking about it more, - the angle of the block is simply 90deg-Azimuth field.....so if the Azimuth angle is 50deg......the true angle of the block would be 90-50=40deg..... That way the arrow line on the block would be at 40deg rotated around the insertion point....which is the center of the circle at the base.....Using that method, the lisp would not need to specify a rotation of reference, it would always be the calculated angle .....However, I would probably need to change the block so that it was at true 0deg normally.......Then the lisp simply takes 90-" Azimuth field" and rotates the block to that angle. Then the only troubling issue is the text orientation once the block is rotated <89 and >271.....Hopefully all of that makes sense....

0 Likes
Message 17 of 24

dlanorh
Advisor
Advisor

@Anonymous wrote:

I should clarify that I just wblocked that block so you could see it....The true block is actually pointing straight up at 90deg....(which is again = Azimuth 0deg)....the calculation for the angle of the block would basically be X=0 , X being the real world angle of the block, and whatever angle is put in the Azimuth field would be 0 - "azimuth field" .....so if the Azimuth is 60......the lisp routine would rotate the block -60 from its "home" position - which is at real world 90deg. Sorry about sending you a block that is not the actual true block.


Hmm. I'll have to look at my units setting perhaps that is causing the "5G..._RIGHT" block to point east as default. That aside i have completed and tested the lisp. I have tweaked the two blocks and made them dynamic. The dynamic property is a rotation property with two possible rotations 0 and 180. I have done this to make both blocks have readable attribute text no matter the rotation. The rotation property is related to the arrow so the text will always be aligned to it, and has no manual dynamic grip making it invisible if the block is selected. This means you can replace the "_left" and "_right" 5G blocks with a single block and you won't have to mirror the "CDMA" block. I have named these blocks

 

"Existing_LTE_CDMA_w_callout_D" and "5G_LTE_antenna_w_callout_D"

 

In my tests the lisp successfully replaced the old left and right 5G blocks with the new, transfering all the attribute values and placed the block on the correct matching layer. If the azimuth is between 180 and 360 it automatically rotates the attributes using the dynamic rotation parameter so as to keep the text readable.

 

It did the same with the CDMA blocks, both normal and mirrored.

 

I'm off to bed now but will adjust my unit settings and re-test tomorrow. Attached are the tweaked blocks, but the orientations may need adjusting after testing tomorrow.

 

 

I am not one of the robots you're looking for

0 Likes
Message 18 of 24

Anonymous
Not applicable

Thank you very very much...I really appreciate that! I actually don't care how the original block is rotated in it's home state, as long as changing the attribute field rotates it to the right position. If it needs tweaked or modified, please let me know. Also - I pulled that block out of an older dwg - and its possible that the block in our network has been updated....But - like I said - I don't really care what position the actual block is....as long as it works with the Lisp routine. That is awesome. Thank you so much. I will try it out.

 

Dustin 

0 Likes
Message 19 of 24

Moshe-A
Mentor
Mentor

@Anonymous  hi,

 

check this version that has 2 command:

AZSET  for setting to azimuth attribute according the block rotation.

AZROT for rotating the block according the azimuth appears in attribute value.

the (align_attrib) function is than called for each block to make sure attributes is in read state but this causes the attributes to be a little position shifted cause the attributes alignment are not in middle center justify so a block modification is needed here.

 

you should add the block names to the (ssget) filter - do you know how?

 

of course this lisp could be upgrade to use reactors to react to an attribute change and rotate change but adding object reactors to AutoCAD increase the system nervousness which i do not recommend Smiley LOL

 

enjoy

moshe

 

 

 

(defun az:azimuth (action / align_attrib fetch_digits deg2rad ; local functions
		            ss extval ang newval)

 (defun align_attrib (ent / subent sube rot)
  (setq subent (entnext ent) sube (entget subent))
  (while (/= (cdr (assoc '0 sube)) "SEQEND")
   (setq rot (cdr (assoc '50 sube)))
   (if (and (> rot (/ pi 2)) (< rot (* pi 1.5))) 
    (entmod (subst (cons '50 (+ rot pi)) (assoc '50 sube) sube))
   )
   (setq subent (entnext subent) sube (entget subent))	    
  ); while
 ); align_attrib
  
 (defun fetch_digits (str)
  (vl-list->string 
    (vl-remove-if-not
     '(lambda (n)
       (and (>= n 48) (<= n 57))  
      )  
     (vl-string->list str)
    )
  )
 ); fetch_digits 
  
 ; convert degrees to radians 
 (defun deg2rad (d)
  (* (/ d 360.0) pi 2)
 ); deg2rad

 ; here start az:azimuth 
 (if (setq ss (ssget '((0 . "insert")))) ; add block names to filter
  (foreach ename (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))
   (setq extval (getpropertyvalue ename "azimuth"))
    
   (cond
    ((eq action 'SETT)
     (setq ang (cdr (assoc '50 (entget ename))))
     (setq newval (angtos (- (/ pi 2) ang) 0 0))
     (setpropertyvalue ename "azimuth" (vl-string-subst newval (fetch_digits extval) extval))
    ); case
    ((eq action 'ROT)
     (setq ang (deg2rad (atoi (fetch_digits extval))))
     (setpropertyvalue ename "rotation" (- (/ pi 2) ang))  
    ); case	 
   ); cond

   (align_attrib ename) 
  ); foreach  
 ); if
 (princ)   
)  
   
(defun c:AZset ()
 (az:azimuth 'SETT) 
)

(defun c:AZrot ()
 (az:azimuth 'ROT) 
)

 

 

 

0 Likes
Message 20 of 24

dlanorh
Advisor
Advisor

Attached are the lisp routines in a single file. They are not extensively tested.

 

There are three main routines

 

c:foo (renameable if required) This replaces the old blocks with the new blocks. The new blocks must be in the drawing as it checks. You can replace all the old blocks or a selection of old blocks but be aware the all option may fail if blocks are on a locked layer. The routine makes use of dynamic mode and the dynamic prompt to ask whether you want to All or Select. This is reset on exit if you don't normally use it. The routine uses the existing azimuth attribute value to set the rotation when inserting the new block.

 

c:tat This is basically an attribute text toggle and will only work with the new blocks on unlocked layers. It rotates the three attributes 180 degrees

 

c:r2az Again this will only work with the new blocks. It allows a selection set of selected blocks on unlocked layers to be rotated to a specified azimuth. You supply the azimuth as an integer and it rotates the new blocks to the correct azimuth and updates the Azimuth attribute text. It automatically takes care of rotating the attribute text if it is required.

 

Any problems, errors etc let me know.

 

I am not one of the robots you're looking for

0 Likes