Author Topic: Lisp to insert block then move attributed text a known distance & angle  (Read 771 times)

0 Members and 1 Guest are viewing this topic.

Sisyphus

  • Mosquito
  • Posts: 8
Hi All

Start Preface -
I'm having trouble with some lisp programming. I DID have a great manual on lisp programming that slow walked you through how to do various things, it came out back when Autocad still produced hard copy manuals with their releases (2002-2008?), so it was a while ago.
Now I can't find that blasted manual (I think that I lent it out to someone and they didn't return it).
Anyway, I can remember that it made a big deal of associate numbers and how to manipulate them to your advantage in lisps, converting to strings, angles in radians, etc.

Does anyone know if the old lisp manuals that were available with Acad. I found the 2013 version, the one that I am after was before 2013.
Failing that what is a nice, quick & dirty way of (re)learning simple Lisp programing (with examples)?
End Preface -

Question Part 1 - I want to insert a block then move the one of the attributes associated with that block a set distance and angle (vector).

I have a lisp where I select an insertion point and insert a block at that point, scale the block to the size that I want, put the block on a specific layer and change the visibility state to the one that I want. My problem is that when the block was created their were two attribute texts, one (TYPE) was justified as middle bottom and the other (T2) was justified as middle centre. I am having trouble with the "TYPE" attribute. When we are just manually cutting & pasting between drawings this is sort of okay (we sometimes need to alter the attribute position manually). We have used this block for about 8 years so I don't want to have to redefine the block & have some of our cad operators (who aren't that proficient) have to work out if they are using an old or new definition of the block to get the text right.

When I am using a lisp to insert the block I need to move the TYPE attributed text out 75units (1:100 dwg) at an angle perpendicular (90deg)  to the insertion angle. I will be using the LTscale variable as a scaling factor for the scale of the block and will be using it as a scaling factor for the length that the attribute has to move (if it is a 1:100 drawing the block will come in with an X/Y/Z scale of 1 and the attribute will need to move 75 units, 1:200 drawing the block will come in with an X/Y/Z scale of 2 and the attribute will need to move 150 units, 1:50 drawing the block will come in with an X/Y/Z scale of .5 and the attribute will need to move 37.5 units). When the company I work for was setting up their drafting standards nearly 40 years ago, the CAD manager did not use 100% of his brain and the LTscale is out by a factor of 10 (a 1:100 drawing has an LTscale of 1000, a 1:250 drawing has an LTscale of 2500, etc) so I have to fiddle with the scaling factor when bringing in the block, this is a minor pain.

Now what I want to do is what I've described above (insert the block at a selected insertion point, selected angle, scale the block appropriately, change the layer & the visibility state) then move the attributed text.
I do not know how to use a lisp to select the attributed text that I want to move. I do know that selecting "last" will select the last object in the drawing (i.e. the block that I have just inserted). I do not know how to select the attribute "TYPE" rather than the attribute "T2". I guess if there was no easier way of doing it the attribute selection could be done with a crossing (where I know what the x1, y1, x2, y2 values of the crossing would be be based on the block's insertion point, scale and angle).
I know that the length of the distance that I'd like to shift the text is going to be 75 x the scale of the block (or .075 x the LTscale of the drawing).
I think that assoc 50 will give me the angle of the block, and that value plus 90 will give me the angle that I want to move the attribute in. I am unsure if this value needs to be converted to radians.
If the command is asked for an initial point for moving the attribute text does it need to be the insertion point of the attribute or can I just get by with nominating a random point (0,0,0)?

Can someone please help me.

Copy of my data point/TV lisp (visibility state change cribbed from Lee Mac) that I want to move the attribute at the end of;
(defun C:COTV( / ATD COSM LTS SC)

;;;;; Collect OSMODE settings
(setq COSM (getvar 'osmode))
(setq ATD (getvar 'attdia))
(setq ATR (getvar 'attreq))

;;;;; Set OSMODE to ENDPOINT, MIDPOINT, CENTER, INTERSECTION, INSERTION, PERPENDICULAR & NEAREST only
(setq COSM (getvar 'osmode))
(setvar 'osmode 743)
(setvar 'attdia 0)
(setvar 'attreq 1)

;;;;; Collect current LTscale value and create Values for SC
(setq LTS (getvar 'LTSCALE))
(setq SC (* 0.001 LTS))


;;;;; Insert BLOCK ;;;
(command "insert" "COMMS OUTLET" PAUSE SC SC PAUSE "TV" "" "")
(command "change" "l" "" "p" "la" "COMMS" "")


;;;;; Return OSMODE to original values
(setvar 'osmode COSM)
(setvar 'attdia ATD)
(setvar 'attreq ATR)

;;;;; change visibility state
(defun CHGDYNPROP (Ename propname newval /  lo obj v vval sal tot i)
       ;; Changes a given variable in your block
       ;; Passed: Ename, Property Name, New value for Property
       ;;
       (setq obj (if (= (type Ename) 'vla-object)
    Ename
    (vlax-ename->vla-object Ename))
     v (vla-getdynamicblockproperties obj)
     vval (vlax-variant-value v)
     sal (vlax-safearray->list vval)
     tot (length sal)
     i 0)
       (while (< i tot)
         (if (= (vlax-get-property (nth i sal) "PropertyName") propname)
           (progn
             (vlax-put-property (nth i sal) "Value" newval)
             (setq i tot)
           )
           (setq i (1+ i))
         )
       )
     )
(CHGDYNPROP (entlast) "Visibility1" "Comms/Data (Blank)") ;Comms/Data (Blank) is the visibility state name
(princ)
)

Question Part 2 - I want to move the attribute associated with a previously inserted block a set distance and angle (vector).

Very similar to above but in this case the block may have been inserted into a file a year or two ago (with no text value). Now that the attribute has a value (either a number or a text value like "TV", "FOXTEL", etc) that attribute location is wonky and I need to move it out 75 units at 90 degrees (perpendicular) to the angle of the comms outlet block.

BIGAL

  • Swamp Rat
  • Posts: 1409
  • 40 + years of using Autocad
simple answer is use (Nentsel and pick the attribute.

Try this its Y up you need to expand to suit add a while etc to do multiple.

Code: [Select]
(defun c:wow ( / ent y inspt pt)
(setq Y 50)
(setq ent (vlax-ename->vla-object  (car (nentsel "\nPick an attribute "))))
(setq inspt (vlax-get ent 'insertionpoint))
(setq pt (list (car inspt)(+ y (cadr inspt)) 0.0))
(vlax-put ent 'insertionpoint pt)
)
(c:wow)

If its multiple blocks of same name maybe edit the block definition, then use attsync.

You can also use block name tag name offset X Y etc food for thought.
A man who never made a mistake never made anything

Sisyphus

  • Mosquito
  • Posts: 8
Thanks for the reply BigAl, much appreciated

framednlv

  • Newt
  • Posts: 64
Not to sidetrack what you are doing...
When I'm adjusting attribute rotation, I use torient to change them.  It seems to work okay with one or two characters, more than that you might need to reposition.