Author Topic: Changing a blocks x value without using mirror command (via assoc numbers?)  (Read 1603 times)

0 Members and 1 Guest are viewing this topic.

Sisyphus

  • Mosquito
  • Posts: 8
Hi All

I've been using CAD for a few years and I'm trying to refine a lisp program that I'm working on. I have used The Swamp a few years ago (I can't remember my username or password) and find it to be a great resource and pretty friendly.

I'm a draftsman and I'm trying to get a lisp to insert a dynamic block at the correct scale, put it on the right layer, change the visibility state of the block and then mirror the blocks x value (changes it from "+x" to "-x").

This lisp is mainly designed for engineers to use who want a "1 click" solution. They want to select an insertion point and let the lisp do the rest of the work for them. They don't want to waste their time selecting a mirror point.
I was thinking if I could use ENTGET to get the associate number of the block (using "last" to select it) then I could change the value from a positive to a negative and that would be my 1 click solution.

I will be loading and running the lisp from the tool palettes so I'll have a separate lisp for a mirrored insert rather than having an inquiry in the lisp asking if you want the block mirrored or not.

Here is a copy of my lisp and a typical drawing that I'd be using it in.

The block is a circuit breaker.

In the drawing on the right side of the busbars (3 vertical lines) the block can come in with it's x value as a positive. The lisp works fine for that.

I need to have a separate lisp that selects an insertion point (normally an intersection) and does what the normal lisp does then mirrors it's x value.

Code - Auto/Visual Lisp: [Select]
  1. (defun C:SCHCB1M( / ATD ATR COSM LTS SC)
  2.  
  3. ;;;;; Collect OSMODE settings
  4. (setq COSM (getvar 'osmode))
  5. (setq ATD (getvar 'attdia))
  6. (setq ATR (getvar 'attreq))
  7.  
  8. ;;;;; Set OSMODE to INTERSECTION & NEAREST only
  9. (setq COSM (getvar 'osmode))
  10. (setvar 'osmode 544)
  11. (setvar 'attdia 0)
  12. (setvar 'attreq 0)
  13.  
  14. ;;;;; Collect current LTscale value and create Values for SC
  15. (setq LTS (getvar 'LTSCALE))
  16. (setq SC (* 0.001 LTS))
  17.  
  18.  
  19. ;;;;; Insert BLOCK ;;;
  20. (command "insert" "Sch Breaker" PAUSE SC SC PAUSE "")
  21. (command "change" "l" "" "p" "la" "SCHEM" "")
  22.  
  23.  
  24. ;;;;; Return OSMODE to original values
  25. (setvar 'osmode COSM)
  26. (setvar 'attdia ATD)
  27. (setvar 'attreq ATR)
  28.  
  29. ;;;;; change visibility state
  30. (defun CHGDYNPROP (Ename propname newval /  lo obj v vval sal tot i)
  31.        ;; Changes a given variable in your block
  32.        ;; Passed: Ename, Property Name, New value for Property
  33.        ;;
  34.        (setq obj (if (= (type Ename) 'vla-object)
  35.     Ename
  36.     (vlax-ename->vla-object Ename))
  37.      v (vla-getdynamicblockproperties obj)
  38.      vval (vlax-variant-value v)
  39.      sal (vlax-safearray->list vval)
  40.      tot (length sal)
  41.      i 0)
  42.        (while (< i tot)
  43.          (if (= (vlax-get-property (nth i sal) "PropertyName") propname)
  44.            (progn
  45.              (vlax-put-property (nth i sal) "Value" newval)
  46.              (setq i tot)
  47.            )
  48.            (setq i (1+ i))
  49.          )
  50.        )
  51.      )
  52. (CHGDYNPROP (entlast) "Visibility1" "Circuit Breaker Single Phase") ;Circuit Breaker Single Phase is the visibility state name
  53. )

Can anyone help me?

Thanks in advance
Sisyphus


EDIT (John): Switched to code tags for better presentation.
« Last Edit: January 21, 2022, 10:17:58 AM by JohnK »

steve.carson

  • Newt
  • Posts: 108
Minimally tested, but this should multiply the current x-scale factor by -1 of the last entity:

Code - Auto/Visual Lisp: [Select]
  1. (vlax-put (vlax-ename->vla-object (entlast)) 'XScaleFactor (* -1.0 (vlax-get (vlax-ename->vla-object (entlast)) 'XScaleFactor)))

Sisyphus

  • Mosquito
  • Posts: 8
Thanks for the reply Steve. I'll give it a try.

(also the bit in the lisp to change the visibility state was a crib of Lee Mac's work and I would have been lost without it)

Lee Mac

  • Seagull
  • Posts: 12912
  • London, England
How about changing it at the point of insertion? i.e. Changing this -
Code - Auto/Visual Lisp: [Select]
  1. (command "insert" "Sch Breaker" PAUSE SC SC PAUSE "")

To:
Code - Auto/Visual Lisp: [Select]
  1. (command "insert" "Sch Breaker" "\\" (- SC) SC "\\" "")

(I also changed pause to "\\" as I don't like relying upon the global definition of the pause symbol)

Glad to hear that you found my code as a useful example when working with visibility states, thank you for the nod  :-)

BIGAL

  • Swamp Rat
  • Posts: 1409
  • 40 + years of using Autocad
Thanks to Lee,  for a dynamic block you can get all the visibility states of the block, so I pass those to my Library Multi radio buttons.lsp so this allows the choice of which visibility state as part of the insertion routine. This is very handy in some situations where the visibility is constantly changing for each insertion.



Just ask if you want the code.
A man who never made a mistake never made anything

Sisyphus

  • Mosquito
  • Posts: 8
Thank you all for your replies. Your answers let me get it to do what I asked it to do..

But there is a small problem. The attribute text is middle left justified which works if you bring it in on the right (you can have 32A, 20A D-CURVE, REFER NOTE 1 whatever and the text flows out to the right). Usually we mirror the block to get it on to the left hand side of the bus bar and the middle left justified text becomes middle right justified (which is how I want it to be on the left hand side).
Now that I use the lisp to bring in the block with a -ve X value to mirror the block the att text still remains MR justified.

It turns out that It'll work better if I mirror the last block from right to left, not bring it with a -ve scale factor.  :x :x :x poor thinking/wording on my part.

I guess if I do an ENTGET on the assoc numbers of the block when it comes in on the right I can then use the MIRROR command on the last object with two points (original xy and original x&y+100) and it'll work to flip it to the left (and the attribute text will be MR justified).

I guess the other way is to fiddle with the mirrored block on the left and justify it's attribute text to middle right. That seems more complicated to me than a simple mirror command.

Big Al -
I'm always interested to learn. ATM I've got about 60 lisps for about 12 blocks (diff visibility states) which I'm happy with.
Maybe there is a more elegant way to do it. Does your lisp (via LM) recognize a variable (say rotation) and then adjust the vis state to accommodate it?

BIGAL

  • Swamp Rat
  • Posts: 1409
  • 40 + years of using Autocad
The Multi radio buttons.lsp is a library routine and takes a list of radio button labels, so can be say from 2 or more eg Yes No, that are displayed in a dcl, you can have horizontal or vertical which is limited to around 20 due to screen size more may work. A 2 column version is available as a version 1 .

You read the visibility states from the Dynamic block using Lee's great code and make a list of the states, you then pick a option then use Lee's code again to set the visibility, it just removes the insert then pick the visibility option from the block.

This is an example for a house window sets the opening direction.
Code: [Select]
(setq blk (vlax-ename->vla-object (entlast)))
(LM:setdynpropvalue blk "Width" wid)
(LM:setdynpropvalue blk "Height" ht )

(setq visval (LM:getvisibilityparametername blk ))
(setq winlst (LM:getdynpropallowedvalues  blk visval))
(setq winlst (cons "Please Choose" winlst))
(if (not AH:Butts2)(load "Multi Radio buttons.lsp"))
(if (not AHbut)(setq AHbut 1))
(setq ans (ah:butts 1 "v"  winlst))
(LM:SetVisibilityState blk ans)




« Last Edit: January 25, 2022, 10:15:02 PM by BIGAL »
A man who never made a mistake never made anything