Scale action but with X and Y scale independent

Scale action but with X and Y scale independent

Anonymous
Not applicable
7,334 Views
8 Replies
Message 1 of 9

Scale action but with X and Y scale independent

Anonymous
Not applicable

Hi, and sorry if this is as simple as it should be. despite using AutoCAD for 30 years I have never got into dynamic blocks.

 

I have a block, it's actually an exploded letter (see screen grab below).

 

squowse_0-1607088694803.png

 

 

I wish to be able to scale it dynamically using grips.

Ideally 1 grip in bottom left for base position, 1 grip in top right for scale.

But - and this is what I can't work out how to do - I want to be able to scale it in the X and Y dimensions independently. But not by typing in the properties panel, but by using the grips on screen to snap to an existing "bounding box".

I hope that has explained it what I want to do?

 

I have been messing about with linear parameters, XY parameter, scale action, stretch action but cannot get the simple functionality described above.

 

Please, please, please can someone put me out of my misery!

 

I'm using AutoCAD 2018 if that makes a difference.

Accepted solutions (1)
7,335 Views
8 Replies
Replies (8)
Message 2 of 9

h_s_walker
Mentor
Mentor

Attached is a drawing which will guide you. It uses an XY Parameter, and a couple of stretch actions, one linked to the "X" distance and one linked to the "Y" distance, also note you need to change the overrides of the stretch actions to either read "X distance" or "Y distance" and not "XY distance". See the image below

Capture.JPG

Howard Walker
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Left Handed and Proud

Message 3 of 9

Anonymous
Not applicable

Hi, thanks for your time. Following what you have done is more practice with these dynamic blocks.

 

What you have in your drawing1 is like the STRETCH command, but what I want is to be able to SCALE the block. But I want the scale x and y axes to be able to be set independently. By grips.

 

So I think I need a scale action, not a stretch action.

 

 

 

0 Likes
Message 4 of 9

h_s_walker
Mentor
Mentor
Accepted solution

You can't do it that way. Scale within a block will act like a normal scale. If you want to scale the x and y properties independently  you need to do it from the properties

Howard Walker
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Left Handed and Proud

0 Likes
Message 5 of 9

Anonymous
Not applicable

Thanks for your time Howard.

I have come to that somewhat surprising conclusion.

I say "surprising" because the dynamic blocks feature seems incredibly powerful, so I am surprised the first thing I want to do isn't there!

I have found a lisp routine "FIT.LSP" that will do for now. There are way too many prompts but I may improve it in the future to automatically recognise the bounding box.

I'll leave it here in case anyone else needs it. It was a little hard to find as the website xordesign is now gone. Thanks Stian!

 

 

;; This is an autolisp command programmed by stian haugli / www.xordesign.com
;; Tested and working with autocad Up To version 2010.
;; This tool scales any selection of 2D elements to fit a custom X/Y boundry, hence
;; stretching your drawing unequally in X/Y direction. Very handy indeed.
;; This LISP is free - Enjoy - but we ask you kindly to link to our page rather
;; than distributing the source. Thank you for your understanding
;; London UK MAY 2009, SH


(princ "\n Finally a Good XY Scaling tool for Autocad. Provided by www.xordesign.com ")
(princ "\n Type FIT to start ")



(defun TBLOCK (pp1 sset / tell ent ent_get entu ent_getu blk)

        (if sset (progn
             (entmake (list 
                       '(0 . "BLOCK")
                       '(2 . "*U")
                       '(70 . 1)
                       pp1
                       ))
             (setq tell 0)
             (setq ent (ssname sset tell))
             (while ent
               (setq ent_get (entget ent))
               (if (/= (cdr (assoc 0 ent_get)) "POLYLINE")(progn
                      (setq ent_getu (cdr ent_get))
                      (entdel ent)
                      (entmake ent_getu))
                   (progn
                     (setq entu ent
                           ent_getu (cdr ent_get))
                     (while (/= (cdr (assoc 0 ent_getu)) "SEQEND")
                      (setq ent_getu (cdr (entget entu)))
                      (entmake ent_getu)
                      (setq entu (entnext entu))
                      );while
                      (entdel ent)                   
                   )
               );if
               (setq tell (+ tell 1))
               (setq ent (ssname sset tell))
             )       
             (setq blk (entmake (list '(0 . "ENDBLK"))))
             (entmake (list '(0 . "INSERT")
                             (cons 2 blk)
                             pp1 ))
          );progn
        );if

        (princ)
)
(defun FitErr (msg)

  	(princ "\n *FIT ERROR* : ")
  	; resetting environment
	(if (= worldset 1) (progn
	  	(command "._ucs" "p")
	));if
        (command "._Undo" "end")
  	(if ab (progn
		(setvar "angbase" ab)
	));if
        (setvar "cmdecho" 1)
	(princ msg)
  	; restoring old error handler
	(if olderr (setq *error* olderr))
  	(princ)
)
  
(defun c:FIT (/ p1 xp1 xp2 yp1 yp2 x1 y1 z1 xyz xx yy blk_innh p2 selset ab olderr worldset)

	(princ "\n FIT - A free tool by www.xordesign.com")

  	; setting up error handling
  	(setq olderr *error*)
  	(setq *error* FitErr)

  	; collecting data
  	(setq selset (ssget))

        (Setq p1 (getpoint "\n Base point : "))
           (Setq xpp1 (getpoint "\n X: Specify Reference width and direction (A Point Please): " p1 ))
	     (setq xp1 (distance p1 xpp1))

           (Setq xp2 (getdist (strcat "\n X: Specify new width <" (rtos xp1 2 (getvar "luprec")) ">: ") p1 ))
	     (if (= xp2 nil)(progn 
					(setq xp2 xp1)
				   );progn
		);if

           (Setq yp1 (getdist (strcat "\n Y: Specify Reference height <" (rtos 1.00 2 (getvar "luprec")) ">: ") p1 ))
	     (if (= yp1 nil)(progn 
					(setq yp1 1.0)
				   );progn
		);if

           (Setq yp2 (getdist (strcat "\n Y: Specify new height <" (rtos yp1 2 (getvar "luprec")) ">: ") p1 ))
	     (if (= yp2 nil)(progn 
					(setq yp2 yp1)
				   );progn
		);if


(if (and xp1 (not (and (= xp1 xp2) (= yp1 yp2)))) (progn

	; adjusting environment
      (setvar "cmdecho" 0)
	(setq ab (getvar "angbase"))
	(setq worldset 0)
  	(setvar "angbase" 0)

  	; setting undo sequence
	(command "._Undo" "begin")

  	; converting points from UCS to WCS
  	(setq p1 (trans p1 1 0))
	(setq xpp1 (trans xpp1 1 0))

	; switching to WCS
	(if (= (getvar "worlducs") 0) (progn
	  	(Command "._UCS" "W")
            (setq worldset 1)
	) (progn ;else
            (setq worldset 0)
	));if
	

  	; computing factors
           (setq x1 (car p1))
           (setq y1 (cadr p1))
           (setq z1 (caddr p1))
            (setq xyz (list 10 x1 y1 z1))
             (setq xx (/ xp2 xp1))
             (setq yy (/ yp2 yp1))
             (setq x1 (- x1 (* x1 (- xx 1.0))))
             (Setq y1 (- y1 (* y1 (- yy 1.0))))

  	; rotating objects to "0" angle
	     (command "._rotate" selset "" "none" p1 "r" "none" p1 "none" xpp1 "0")

	; making a block out of it...
  	     (tblock xyz selset)
	; and rotating the entire block back to the inital angle
  	     (command "._rotate" "l" "" "none" p1 "none" xpp1) 

  	; finally modifying the block scale factors

  	     (setq blk (ssname (ssget "l") 0))
             (setq blk_innh (entget blk))
             (setq blk_innh  (subst (cons 41 xx) (assoc 41 blk_innh) blk_innh))      
             (setq blk_innh  (subst (cons 42 YY) (assoc 42 blk_innh) blk_innh))      
             (entmod blk_innh)	        

	(princ "\n Explode to ungroup ")

  	; and resetting the environment back to normal


	(if (= worldset 1)(progn 
	 	(command "._ucs" "p")
	));if

      (command "._Undo" "end")
	
 		; a completely unnecessary Ctrl C 
		(command)
		(command) 

  	(setvar "angbase" ab)
      (setvar "cmdecho" 1)
	; restoring old errorhandler
  	(if olderr (progn 
		(setq *error* olderr)
	));if
); progn
	(progn
	(princ "\n Nothing to do - No changes made")
	);progn
);if
		


	; and exits..
  	(princ)

);defun

(princ)

 

 

 

Message 6 of 9

CurtisClarkCA
Enthusiast
Enthusiast

Thank you!! This is exactly what I was looking for.

 

Followup question for you! Are you able to make that same block work with a rotate parameter (& action) as well?

 

When I try to assign a rotate command on top of all that, it does work. BUT the scale values end up all wrong in the properties.

 

For example, step by step:

- I create a 1x1 rectangle block your way

- in the drawing I test it - by scaling it to a 2x3 block by updating the values in the properties, or by selecting and moving the grip. The grip and rectangle each do what they are supposed to in each case, and the properties still read 2.000 x 3.000.  So far so good.

- I go back into the block and add a simple rotate parameter and action, selecting all objects (including the grips and parameters).

- back in the drawing, rotating the block seems to work fine. The rectangle and grips end up where they should. The problem is that the properties now read something like 0.474 x 3.574. So, it is reading back the properties of the grip relative to the block's basepoint in model space, rather than relative to the block's basepoint in... 'block space'(?) Hopefully I'm making sense.

 

The problem doesnt happen if I forget the rotate action and instead rotate the block manually with the rotate command. Which makes sense to me, as then it understands the entire block instance has been rotated. I could do that, but of course it would save a lot of time to be able to just click and rotate with a dynamic block grip, hence the question. I'm basically trying to make a rectangular septic tank block, which has both properties showing the X and Y, but also a handy rotate function.

0 Likes
Message 7 of 9

h_s_walker
Mentor
Mentor

@CurtisClarkCA Unfortunately you cannot rotate an XY parameter it will always stay horizontal / vertical. You will need to add two linear parameters with stretch actions added to them. Linear parameters can be rotated.

Howard Walker
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Left Handed and Proud

Message 8 of 9

CurtisClarkCA
Enthusiast
Enthusiast

I will try that! Thank you!

0 Likes
Message 9 of 9

CurtisClarkCA
Enthusiast
Enthusiast

@h_s_walker , It works perfectly!

 

Now I have a grip on each corner of the rectangle. One is the block basepoint. One is to stretch the X, another to stretch the Y, and finally one to rotate the rectangle.

 

When rotated, the rectangle's properties read the same X and Y distances as before it was rotated, which is perfect. And when I stretch the X and Y grips, they still remain constrained to their original X and Y plane so that the rectangle doesn't skew. 

 

It's perfect, and thank you, thank you, thank you!

 

Followup edit:

Also you can have the X and Y grips overlap so that they stretch both directions at the same time! I initially had trouble where in the block editor the selectable menus for the two Actions themselves were overlapping when I created them in place. But just now I discovered that you can create one of them on the adjacent corner (so the menus don't overlap) and then move the action and its grip over to the same corner afterwards, and the menus stay where they were - independantly selectable! So it is even faster to throw simple rectangles (with actual readable dimensions in the properties) all over my drawing now.

 

0 Likes