Rotate attributes selected blocks to horizontal equal to WCS/ UCS view

Rotate attributes selected blocks to horizontal equal to WCS/ UCS view

sander.van.pelt
Advocate Advocate
1,705 Views
7 Replies
Message 1 of 8

Rotate attributes selected blocks to horizontal equal to WCS/ UCS view

sander.van.pelt
Advocate
Advocate

Hello everybody,

 

I am using the lisp below to rotate the attributes of a block automatically to horizontal in the current view (WCS or UCS) if I rotate a block.  But now I have to rotate the attributes of multiple blocks to horizontal only.

We have received many drawings from third parties. In these drawings, one block and his attributes are rotated 45 degrees, the other 63 degrees etc. The blocks and attributes do have a lot of different angles. The position/ rotation of these blocks are oke.
I can use my own lisp by selecting all these blocks, select a basepoint, rotate them for example 90 degrees, and after that, rotate them 270 degrees. All the attributes are placed horizontal now.

But is there somebody who can help me with a lisp which only rotates the attributes of the selected blocks to horizontal or (for maybe in the future) to another angle/ let me choose from 2 options, horizontal or angle.
A lisp that ensures that I don't have to rotate everything twice.

Thanks

 

(defun c:RB ( / ss i vla-blockent)
  (if (setq ss (ssget "_:L"))
    (progn
      (command "_.ROTATE" ss "")
      (while (> (getvar 'CMDACTIVE) 0)
        (command PAUSE))
      (repeat (setq i (sslength ss))
        (setq vla-blockent (vlax-ename->vla-object (ssname ss (setq i (1- i)))))
        (if (eq (vla-get-hasattributes vla-blockent) :vlax-true)
          (foreach att (vlax-invoke vla-blockent 'getattributes)
            (vla-put-rotation att 0)))))
    (princ "\nNothing selected."))
  (princ)
)
(vl-load-com)

 

0 Likes
1,706 Views
7 Replies
Replies (7)
Message 2 of 8

john.uhden
Mentor
Mentor

We civils Dview;Twist a lot, so years ago I wrote HTEXT (horizontal) and ATEXT (align) for Text, Mtext, and Dimensions.

Never thought about doing it for attributes.  Maybe I'll give it a shot.  Yes, I think it would be easy.

To confirm... I think you wanted to rotate all the attributes in a block reference.  Is that correct, or just individually selected attributes?

John F. Uhden

0 Likes
Message 3 of 8

sander.van.pelt
Advocate
Advocate

Hi John,
It is indeed about rotating all the attributes of a block.

What will remain a problem (I think), is that I will have to check all attributes of the selected blocks for readability because their justification will remain in the same place relative to the insert point of the block.
For example, the image shows what happens when I use my own lisp. The attributes (left justification) are partly overlap eachother or overlap the block partly.

Knipsel.PNG

0 Likes
Message 4 of 8

john.uhden
Mentor
Mentor

Another thought...

If your blocks are rather circular like the one in your image, with its insertion point at the center, then we could reposition the attributes to have the same dx,dy as if the block were not rotated (wrt the view).

Have you checked to see what ATTSYNC does?

John F. Uhden

0 Likes
Message 5 of 8

john.uhden
Mentor
Mentor

Another nother thought...

If your blocks are really that uniform and circular. then why not just (command "_.rotate") the block insertion?

Or you can use (vlax-put block 'rotation ang).

John F. Uhden

0 Likes
Message 6 of 8

Sea-Haven
Mentor
Mentor

I think like John you need to look at a dx dy for the attributes so as you rotate the block  you also maintain a distance between them and a rotation. You can run lisp in BEDIT sometimes a bit easier than entmoding the block definition.

 

SeaHaven_1-1638585521895.png

 

 

 

0 Likes
Message 7 of 8

sander.van.pelt
Advocate
Advocate

Hello John and Sea-Haven

Unfortunately not all blocks in my industry (HVAC) have the same shapes. Of course, the sizes of these blocks also differ. This is very clearly visible in my added image. There you can see air ducts, fans, duct dampers, reheaters and central heating pipes. In the pictureyou see a fairly empty representation of a floor plan with these blocks.


Knipsel.PNG


What I forgot to mention in my 1st post is that I can't edit the blocks. I have to place the blocks via another software/ add-in called StabiCad. The names of all these blocks placed via StabiCad also start with a "*".
I can change the color of a block or his attributes, but if I place a new block, the colors change back into their original colors.
Each of these blocks contains at least 3 attributes. The blocks on my 1st image, round air vents, contain 8 which I could fill in. However, the first 2 or 3 are important here.


If I use "Attsync", then the attributes jump back in the same corner as the block. For example, if a block is rotated 180 degrees, and the text is horizontally readable, in fact rotated 0 degrees, the text jumps back to rotated 180 degrees. So upside down.
Because my scale is now 1:50, the text height also jumps back to 1.8. This while this should remain 90.

Use ATTSYNC or BEDIT can't solve the problem.

0 Likes
Message 8 of 8

john.uhden
Mentor
Mentor

@sander.van.pelt 

It appears from your image that there's no simple solution as to where to always place the horizontal attributes, but these two commands may reduce your fatigue.

The first (c:HAT) makes all attributes within selected inserts horizontal on the screen.

The second (c:ATTMOVE or c:AM) is an oldie that makes it easier to move attributes.

(defun c:HAT ( / *error* vars vals ss i obj)
  (gc)
  (vl-load-com)
  (prompt "\nHAT v1.0 (c)2021, John F. Uhden")
  (defun *error* (|err)
    (mapcar 'setvar vars vals)
    (vla-endundomark *doc*)
    (cond
      ((not err))
      ((wcmatch (strcase |err) "*CANCEL*,*QUIT*")
        (vl-exit-with-error "\r                                              ")
      )
      (1 (vl-exit-with-error (strcat "\r*ERROR*: " |err)))
    )
    (princ)
  )
  ;;-------------------------------------------
  ;; Initialize drawing and program variables:
  ;;
  (setq *acad* (vlax-get-acad-object))
  (setq *doc* (vlax-get *acad* 'ActiveDocument))
  (vla-endundomark *doc*)
  (vla-startundomark *doc*)
  (setq vars '("cmdecho"))
  (setq vals (mapcar 'getvar vars))
  (setvar "cmdecho" 0)
  (command "_.expert" (getvar "expert")) ;; dummy command
  ;;------------------
  ;; Begin the action
  (and
    (setq ss (ssget '((0 . "INSERT")(66 . 1))))
    (repeat (setq i (sslength ss))
      (setq obj (vlax-ename->vla-object (ssname ss (setq i (1- i)))))
      (foreach att (vlax-invoke obj 'getattributes)
        (vlax-put att 'rotation (- (* 2 pi)(getvar "viewtwist")))
      )
    )
  )
  (*error* nil)
)

(defun C:ATTMOVE ( / *error* |e |etyp |pick)
   ;; Program allows user to repeatedly pick an attribute and change its position.
   (gc)
   (vl-load-com)
   (prompt "\nATTMOVE v15.00 (c)1994-2000, John F. Uhden")
  (defun *error* (|err)
    (mapcar 'setvar vars vals)
    (vla-endundomark *doc*)
    (cond
      ((not err))
      ((wcmatch (strcase |err) "*CANCEL*,*QUIT*")
        (vl-exit-with-error "\r                                              ")
      )
      (1 (vl-exit-with-error (strcat "\r*ERROR*: " |err)))
    )
    (princ)
  )
  ;;-------------------------------------------
  ;; Initialize drawing and program variables:
  ;;
  (setq *acad* (vlax-get-acad-object))
  (setq *doc* (vlax-get *acad* 'ActiveDocument))
  (vla-endundomark *doc*)
  (vla-startundomark *doc*)
  (setq vars '("cmdecho"))
  (setq vals (mapcar 'getvar vars))
  (setvar "cmdecho" 0)
  (command "_.expert" (getvar "expert")) ;; dummy command
   (setvar "errno" 0)
   ;;-------------------------------------------------------
   ;; Begin user action by picking attributes one at a time:
   ;;
   (while (/= (getvar "errno") 52)
      (setq |etyp nil)
      (if (setq |pick (nentsel "\nSelect attribute: "))
         (setq |e (car |pick)
            |etyp (cdr (assoc 0 (entget |e)))
         )
      )
      (if (= |etyp "ATTRIB")
         (if (> (length |pick) 2)
            (prompt " Attribute belongs to a nested block.")
            (progn
              (command "_.attedit" "_Y" "" "" "" |e)
              (prompt "\nText insertion point: ")
              (command "_P" pause "")
              (entupd |e)
            )
         )
         (if |etyp (prompt (strcat "Entity is a(n) " |etyp)))
      )
   )
   (*error* nil)
)
(defun c:AM ()(c:ATTMOVE))

 

John F. Uhden

0 Likes