PDA

View Full Version : Attribute blocks scaling routine


gilsoto13
2009-08-03, 05:32 PM
Hi, Everyone.

This is my first post... and it's a question. I want to know if someone already figured this out. I don´t have much experience at programming, in fact, I just know how to add simple variables and commands to existing lisps. In this case I have this file, and I modified it to convert selected blocks to scale 1, 1, 1. but I would like to use it on attribute blocks, because this lisp doesn´t scale the attributes, It will just scale the entities inside the blocks and leave the attributes as they are.

I know it's possible to scale attribute blocks using the "properties dialog box", but I would like to know if someone can make it work in this lisp.

What I want specifically is a routine (or this routine) to read selected objects, filter blocks only, get each of their x scale factor, and scale each block to make that s scale value to become the current dimscale value.

I am getting close to it, I've just need to know how to automatically scale each block from the selection set individually by a "currentdimscale / currentblockscale" factor, i will develop it for sure... but someone may help... seems to be easy..



;;; BXY by David Harrington
;;; Edit block x,y and z values
;;;
;;; Main Program
;;;
(defun c:B1 (/ ss xs ys zs num x na lst editxyz_error olcmdecho old_err)
(defun editxyz_error (msg)
(if (or
(= msg "Function cancelled")
(/= msg "quit / exit abort")
)
(princ (strcat "Error: " msg))
)
(command ".UNDO" "E" "UNDO" "")
(setq *error* old_err
old_err nil
)
(setvar "CMDECHO" olcmdecho)
(princ)
)
(setq old_err *error*
olcmdecho (getvar "CMDECHO")
*error* editxyz_error
)
(setvar "CMDECHO" 0)
(princ "\n EDITXYZ - Edit block x, y and z values")
(command ".UNDO" "BE") (prompt "\nSelect Xrefs or Blocks to rescale: ")
(cond
((setq ss (ssget '((0 . "INSERT"))))
(setq num (sslength ss))
(setq x 0)
(repeat num
(setq na (ssname ss x))
(setq lst (entget na))
(setq lst (subst (cons 41 1) (assoc 41 lst) lst))
(setq lst (subst (cons 42 1) (assoc 42 lst) lst))
(setq lst (subst (cons 43 1) (assoc 43 lst) lst))
(entmod lst)
(entupd na)
(setq x (+ x 1))
)
)
)
(command ".UNDO" "E")
(setq *error* old_err)
(setvar "CMDECHO" olcmdecho)
(princ)
)

ccowgill
2009-08-03, 06:11 PM
Hi, Everyone.

This is my first post... and it's a question. I want to know if someone already figured this out. I don´t have much experience at programming, in fact, I just know how to add simple variables and commands to existing lisps. In this case I have this file, and I modified it to convert selected blocks to scale 1, 1, 1. but I would like to use it on attribute blocks, because this lisp doesn´t scale the attributes, It will just scale the entities inside the blocks and leave the attributes as they are.

I know it's possible to scale attribute blocks using the "properties dialog box", but I would like to know if someone can make it work in this lisp.

What I want specifically is a routine (or this routine) to read selected objects, filter blocks only, get each of their x scale factor, and scale each block to make that s scale value to become the current dimscale value.


;;; BXY by David Harrington
;;; Edit block x,y and z values
;;;
;;; Main Program
;;;
(defun c:B1 (/ ss xs ys zs num x na lst editxyz_error olcmdecho old_err)
(defun editxyz_error (msg)
(if (or
(= msg "Function cancelled")
(/= msg "quit / exit abort")
)
(princ (strcat "Error: " msg))
)
(command ".UNDO" "E" "UNDO" "")
(setq *error* old_err
old_err nil
)
(setvar "CMDECHO" olcmdecho)
(princ)
)
(setq old_err *error*
olcmdecho (getvar "CMDECHO")
*error* editxyz_error
)
(setvar "CMDECHO" 0)
(princ "\n EDITXYZ - Edit block x, y and z values")
(command ".UNDO" "BE") (prompt "\nSelect Xrefs or Blocks to rescale: ")
(cond
((setq ss (ssget '((0 . "INSERT"))))
(setq num (sslength ss))
(setq x 0)
(repeat num
(setq na (ssname ss x))
(setq lst (entget na))
(setq lst (subst (cons 41 1) (assoc 41 lst) lst))
(setq lst (subst (cons 42 1) (assoc 42 lst) lst))
(setq lst (subst (cons 43 1) (assoc 43 lst) lst))
(entmod lst)
(entupd na)
(setq x (+ x 1))
)
)
)
(command ".UNDO" "E")
(setq *error* old_err)
(setvar "CMDECHO" olcmdecho)
(princ)
)

looks like all you may need is to attsync at the end of the program, not real sure though.

gilsoto13
2009-08-03, 06:18 PM
looks like all you may need is to attsync at the end of the program, not real sure though.

i just checked it for one block, and it worked, but how to make this autocad command to work automatically for the whole selection set without using the command block by block after I used my routine?

gilsoto13
2009-08-03, 06:38 PM
looks like all you may need is to attsync at the end of the program, not real sure though.

You know... It may work if i can get the dwg block list in a row from autocad with comma delimited format so I can use it in combination with attsync / name option....

but how?

gilsoto13
2009-08-03, 10:51 PM
You know... It may work if i can get the dwg block list in a row from autocad with comma delimited format so I can use it in combination with attsync / name option....

but how?

Ok... it seems I finally got was I was looking for...

Just had to add the command "attsync" then "name" and then all with "*" and that works for updating all attribute in all blocks to their original size. This is the lisp...

Updates selected blocks (normal blocks, blocks with attributes and dynamic blocks) to current dimscale.


;;; BXY by David Harrington; Modified by Paulo Gil Soto (added annotation scale reset to 1:1)
;;; updates selected blocks x,y and z values to current Dimscale
;;;
;;; Main Program
;;;
(defun c:Bu (/ ss xs ys zs num x na lst editxyz_error olcmdecho old_err)
(defun editxyz_error (msg)
(if (or
(= msg "Function cancelled")
(/= msg "quit / exit abort")
)
(princ (strcat "Error: " msg))
)
(command ".UNDO" "E" "UNDO" "")
(setq *error* old_err
old_err nil
)
(setvar "CMDECHO" olcmdecho)
(princ)
)
(setq old_err *error*
olcmdecho (getvar "CMDECHO")
*error* editxyz_error
)
(setvar "CMDECHO" 0)
(setq dms (getvar "dimscale"))
(command ".UNDO" "BE") (prompt "\nSelect Blocks to match current dimscale: ")
(cond
((setq ss (ssget '((0 . "INSERT"))))
(command "-objectscale" ss "" "add" "1:1" "" "cannoscale" "1:1")
(setq num (sslength ss))
(setq x 0)
(repeat num
(setq na (ssname ss x))
(setq lst (entget na))
(setq lst (subst (cons 41 dms) (assoc 41 lst) lst))
(setq lst (subst (cons 42 dms) (assoc 42 lst) lst))
(setq lst (subst (cons 43 dms) (assoc 43 lst) lst))
(entmod lst)
(entupd na)
(setq x (+ x 1))
)
)
)
(command "attsync" "name" "*")
(command ".UNDO" "E")
(setq *error* old_err)
(setvar "CMDECHO" olcmdecho)
(princ)
)

gilsoto13
2009-08-05, 05:00 PM
You know, I have been using this lisp and it's a beauty, but now I realize that some blocks have negative x, y, z scale factor values (mirrored blocks) and I would like to preserve those values because usually the mirror was required for direction and it's necessary to preserve negative values when exist.

There are other block scaling routines but those routines use the
(command "scale" eachblockinsertion "insertionpoint" (/ newscale currentscale))

and when using those routines, they work until they find a negative value, then the routine stucks with this message

Value must be positive and nonzero.
; error: Function cancelled

Could there be a way to change each block's x,y,z value but preserving their original value sign (positive or negative)?

Anybody knows how?

gilsoto13
2009-08-06, 11:58 PM
You know, I have been using this lisp and it's a beauty, but now I realize that some blocks have negative x, y, z scale factor values (mirrored blocks) and I would like to preserve those values because usually the mirror was required for direction and it's necessary to preserve negative values when exist.

There are other block scaling routines but those routines use the
(command "scale" eachblockinsertion "insertionpoint" (/ newscale currentscale))

and when using those routines, they work until they find a negative value, then the routine stucks with this message

Value must be positive and nonzero.
; error: Function cancelled

Could there be a way to change each block's x,y,z value but preserving their original value sign (positive or negative)?

Anybody knows how?


I got the answer in another forum... here is the file

the bad thing is that I wanted it to use it with attributte blocks, and now I realized it will kinda mirror the attributes or something... so It preserves negative values in selected blocks but kinda mirror text making it unreadable (unless we can read from right to left)

These blocks I am trying to scale and preserve are dynamic, so I guess I will make a dynamic option to move the text around instead of mirroring, which is causing the need of preserving negative values... but I guess this is better now than modifying the values to positive,...

I appreciate your help too

mgonzales.224492
2009-08-11, 07:44 PM
kudos to you, that rutine is great, it helped me with my problem having blocks w/ attributes at a z elev and flatten was just screwing it up. thanks for thinking of this routine.

gilsoto13
2009-08-17, 04:38 AM
kudos to you, that rutine is great, it helped me with my problem having blocks w/ attributes at a z elev and flatten was just screwing it up. thanks for thinking of this routine.

Well, yes, and works as desired, but for mi case I needed to sincronize blocks with attributes, so I added that row in the lisp, But since my knowledgment of lisp is poor, I just sincronized all the blocks in the drawing. then using it, I found it was a problem for customized attributes in our border, the Lee Mac made a whole new routine for me to sincronize only selected blocks, but this routine will not preserve negative values, which I think was better for me.