I couldn't find a lisp in the web to space blocks evenly (clear spacing) and need help from this forum.
I want to space different block/s evenly, not from centers but clear spacing between blocks.
There could be any random blocks that are in any sequence or order. Insertion point of blocks could be different between blocks.
The first and last block location of that row are good, not to be move. The task is to space those blocks between the first and last.
Most blocks have a text (tag) which is not part of the block. When spacing the blocks, these texts should follow the block location and orientation.
This line of blocks can be orientated any direction define by the first and last block.
Attached is an example, what was Before and what I want in the After. The dimenson here is only to indicate where the clear spacing is measured.
Thanks
mcmk8
Solved! Go to Solution.
Solved by pbejse. Go to Solution.
I found @_Tharwat 's routine HERE
I dared to make a quick modification, hope you don't mind, Tharwat.
@Anonymous It makes a bounding box of each block, then it expends the selection window to left and up to cover labels. You can adjust the multiplying coefficients of width/hight of block (different for portrait/landscape shape of block).
;; Tharwat Al Shoufi ~ 15. Aug. 2013 ;; ;; http://www.cadtutor.net/forum/archive/index.php/t-81140.html?s=a3b7690756ca3b1605d385510014beb2 ;; Mod BeekeeCZ ~ 13. Jul. 2016 ;; (defun c:BlkDistribute (/ *error* EnoughSpace-p cm a b ss i sn x d l g pt lft r y h w sw stp k u x-d xXx dis) (defun *error* (x) (princ "\n") (if cm (setvar 'cmdecho cm) ) (princ "\n *Cancel*")) (defun EnoughSpace-p (ss d / l i q lf ur p) (setq l 0.) (repeat (setq i (sslength ss)) (vla-getboundingbox (vlax-ename->vla-object (ssname ss (setq i (1- i)))) 'lf 'ur) (setq l (+ (distance (setq p (vlax-safearray->list lf)) (list (car (vlax-safearray->list ur)) (cadr p) 0.)) l))) (list (< l d) l)) ; ****************************************************** (if (and (setq dis (getdist "\n Specify total length :")) (setq ss (ssget "_:L" '((0 . "INSERT")))) ;'((0 . "LWPOLYLINE") (-4 . "&=") (70 . 1)))) (if (car (setq g (EnoughSpace-p ss dis))) T (progn (alert "Total length is less than the total widths of Rectangles !!") nil)) ) (progn (setq cm (getvar 'cmdecho) g (/ (- dis (cadr g)) (1- (sslength ss)))) (setvar 'cmdecho 0) (repeat (setq i (sslength ss)) (setq sn (ssname ss (setq i (1- i)))) (vla-getboundingbox (vlax-ename->vla-object sn) 'lft 'r) (setq x (vlax-safearray->list lft)) (setq y (vlax-safearray->list r)) (setq d (distance x (list (car y) (cadr x)))) (setq h (distance y (list (car y) (cadr x)))) (setq w (if (> h d) ; high > width (list (polar x pi (* 0.8 d)) (polar y (/ pi 2) (* 0.2 (distance y (list (car y) (cadr x)))))) (list (polar x pi (* 0.2 d)) (polar y (/ pi 2) (* 0.6 (distance y (list (car y) (cadr x)))))))) (setq l (cons (list sn x w d) l))) (setq l (vl-sort l '(lambda (q p) (< (car (cadr q)) (car (cadr p))))) k 0 stp 0. a (car (cadr (nth 0 l))) b (last (nth 0 l))) (repeat (1- (length l)) (setq k (1+ k)) (vl-cmdf "_.move" (car (nth k l))) (if (setq sw (ssget "_c" (car (caddr (nth k l))) (cadr (caddr (nth k l))) '((0 . "*TEXT")))) (vl-cmdf sw)) (vl-cmdf "" "_non" (cadr (nth k l)) "_non" (list (+ a b g stp) (cadr (cadr (nth k l)))) ) (setq stp (+ (last (nth k l)) g stp))) (setvar 'cmdecho cm))) (princ) ) (vl-load-com)
Thanks BeekeeCZ (and Tharwat)
It work's wonder on horizontal arrangement, but Not in vertical arrangement.
Try the lisp after you rotate the Before arrangement in my dwg to vertical (90 deg).
Hope it's a simple fix.
Thanks
mcmk8
@Anonymous wrote:
Thanks BeekeeCZ (and Tharwat)
It work's wonder on horizontal arrangement, but Not in vertical arrangement.
Try the lisp after you rotate the Before arrangement in my dwg to vertical (90 deg).
Hope it's a simple fix.
Thanks
mcmk8
Hmm, I was designed for horizontal distribution. Here is version allows you vertical distribution as well.
;; Tharwat Al Shoufi ~ 15. Aug. 2013 ;; ;; http://www.cadtutor.net/forum/archive/index.php/t-81140.html?s=a3b7690756ca3b1605d385510014beb2 ;; Mod BeekeeCZ ~ 13. Jul. 2016 ;; (defun c:BlkDistribute (/ *error* EnoughSpace-p cm a b ss i sn x d l g pt lft r y h w sw stp k u x-d xXx dis) (defun *error* (x) (princ "\n") (if cm (setvar 'cmdecho cm) ) (princ "\n *Cancel*")) (defun EnoughSpace-p (ss d v / l i q lf ur p) (setq l 0.) (repeat (setq i (sslength ss)) (vla-getboundingbox (vlax-ename->vla-object (ssname ss (setq i (1- i)))) 'lf 'ur) (setq l (+ (distance (setq p (vlax-safearray->list lf)) (if v (list (car p) (cadr (vlax-safearray->list ur)) 0.) (list (car (vlax-safearray->list ur)) (cadr p) 0.))) l))) (list (< l d) l)) ; ****************************************************** (if (setq dis (getdist "\nSpecify total length for horizontal distribution <vertical>: ")) ; Horizontal distribution (if (and (setq ss (ssget "_:L" '((0 . "INSERT")))) (if (car (setq g (EnoughSpace-p ss dis nil))) T (progn (alert "Total length is less than the total widths of Blocks !!") nil)) ) (progn (setq cm (getvar 'cmdecho) g (/ (- dis (cadr g)) (1- (sslength ss)))) (setvar 'cmdecho 0) (repeat (setq i (sslength ss)) (setq sn (ssname ss (setq i (1- i)))) (vla-getboundingbox (vlax-ename->vla-object sn) 'ld 'ru) (setq x (vlax-safearray->list ld)) (setq y (vlax-safearray->list ru)) (setq d (distance x (list (car y) (cadr x)))) (setq h (distance y (list (car y) (cadr x)))) (setq w (if (> h d) ; high > width (list (polar x pi (* 0.8 d)) (polar y (/ pi 2) (* 0.2 (distance y (list (car y) (cadr x)))))) (list (polar x pi (* 0.2 d)) (polar y (/ pi 2) (* 0.6 (distance y (list (car y) (cadr x)))))))) (setq l (cons (list sn x w d) l))) (setq l (vl-sort l '(lambda (q p) (< (car (cadr q)) (car (cadr p))))) k 0 stp 0. a (car (cadr (nth 0 l))) b (last (nth 0 l))) (repeat (1- (length l)) (setq k (1+ k)) (vl-cmdf "_.move" (car (nth k l))) (if (setq sw (ssget "_c" (car (caddr (nth k l))) (cadr (caddr (nth k l))) '((0 . "*TEXT")))) (vl-cmdf sw)) (vl-cmdf "" "_non" (cadr (nth k l)) "_non" (list (+ a b g stp) (cadr (cadr (nth k l)))) ) (setq stp (+ (last (nth k l)) g stp))) (setvar 'cmdecho cm))) ; Vertical distribution (if (and (setq dis (getdist "\nSpecify total length for vertival distribution: ")) (setq ss (ssget "_:L" '((0 . "INSERT")))) (if (car (setq g (EnoughSpace-p ss dis T))) T (progn (alert "Total length is less than the total height of Blocks !!") nil)) ) (progn (setq cm (getvar 'cmdecho) g (/ (- dis (cadr g)) (1- (sslength ss)))) (setvar 'cmdecho 0) (repeat (setq i (sslength ss)) (setq sn (ssname ss (setq i (1- i)))) (vla-getboundingbox (vlax-ename->vla-object sn) 'ld 'ru) (setq x (vlax-safearray->list ld)) (setq y (vlax-safearray->list ru)) (setq d (distance x (list (car y) (cadr x)))) (setq h (distance y (list (car y) (cadr x)))) (setq w (if (> h d) ; high > width (list (polar x pi (* 0.8 d)) (polar y (/ pi 2) (* 0.2 (distance y (list (car y) (cadr x)))))) (list (polar x pi (* 0.2 d)) (polar y (/ pi 2) (* 0.6 (distance y (list (car y) (cadr x)))))))) (setq l (cons (list sn x w h) l))) (setq l (vl-sort l '(lambda (q p) (< (cadr (cadr q)) (cadr (cadr p))))) k 0 stp 0. a (cadr (cadr (nth 0 l))) b (last (nth 0 l))) (repeat (1- (length l)) (setq k (1+ k)) (vl-cmdf "_.move" (car (nth k l))) (if (setq sw (ssget "_c" (car (caddr (nth k l))) (cadr (caddr (nth k l))) '((0 . "*TEXT")))) (vl-cmdf sw)) (vl-cmdf "" "_non" (cadr (nth k l)) "_non" (list (car (cadr (nth k l))) ;(+ a b g stp) (+ a b g stp) ;(cadr (cadr (nth k l))) ) ) (setq stp (+ (last (nth k l)) g stp))) (setvar 'cmdecho cm)))) (princ) ) (vl-load-com)
Same logic as what BeekeeCZ posted (and Tharwat)
(defun c:demo (/ _BBbox coll opt e blockInfo sym firstB lastb np_ sp dist) ;;; pBe July 2014 ;; (defun _BBbox (e / ll ul ur lr) (vla-getboundingbox e 'll 'ur) (setq ll (vlax-safearray->list ll) ur (vlax-safearray->list ur) ) (list ll (distance ll (setq lr (list (car ur) (cadr ll) 0.0))) (distance ll (setq ul (list (car ll) (cadr ur) 0.0))) ul ur lr ) ) (if (setq coll nil ss (ssget "_:L" '((0 . "INSERT"))) ) (progn (initget "V H") (setq opt (getkword "\nChoose option [Vertical/Horizontal]<H>: ")) (setq opt (if (null opt) "H" opt )) (repeat (setq i (sslength ss)) (setq blockInfo (_BBbox (setq e (vlax-ename->vla-object (ssname ss (setq i (1- i))) )))) (setq coll (cons (list (car blockInfo) (cdr blockInfo) e) coll ) ) ) (setq sym (if (setq h (eq "H" opt)) '(< (caar a) (caar b)) '(< (cadar a) (cadar b)))) (setq coll (vl-sort coll '(lambda (a b) (eval sym))) coll2bs coll) (setq firstB (car coll) coll (cdr coll) lastB (last coll) coll (vl-remove lastB coll) ) (setq dist (/ (- (distance (if h (last (cadr firstb)) (caddr (Cadr firstb)) ) (car lastb) ) (apply '+ (mapcar (if h 'caadr 'cadadr ) coll))) (1+ (length coll)) ) ) (setq sp nil _np (lambda (m p d) (polar p (if m 0.0 (/ pi 2.0) ) d ))) (mapcar '(lambda (j k l) (setq sp (if sp sp (car j))) (vlax-invoke (last l) 'move (Car l) (setq sp (_np h sp (+ dist k))))) coll2bs (mapcar (if h 'caadr 'cadadr ) coll2bs ) coll ) ) ) (princ) )
Command: DEMO
Select objects: Specify opposite corner: 6 found
Select objects:
Choose option [Vertical/Horizontal]<H>:
HTH
This morning a friend of mine pointed out that the OP stated that TEXT/MTEXT entities should "follow the block location"
Attached is the lisp file with a little modification to include TEXT/MTEXT entities
Command: SBB
Select objects:
Specify first corner: Specify opposite corner: 32 found
Select objects:
Choose option [Vertical/Horizontal]<H>: H
HTH
Thanks for the help! It is never an attribute, only a slight chance of Mtext and 99% text.
Only want to evenly space the polyline portion. Thanks again!
@StanThe wrote:
Thanks for the help! It is never an attribute, only a slight chance of Mtext and 99% text.
Only want to evenly space the polyline portion. Thanks again!
I see, before we get started, Are these just regular and not Dynamic blocks? any of them rotated, mirrored or scaled?
Maybe something is doing wrong, but select the block and put a distance I get the following warning.
comand: blkdistribute
LinkedIn / AutoCAD Certified Professional
Si mi respuesta fue una solución para usted, por favor seleccione "Aceptar Solución", para que también sirva a otro usuarios.
Thank you very much for your time and talent!!! Works great!!! Now I have my work cut out for me to manipulate that to come up with the other lisps we need!!! Thanks again for your help!!!
I know that this is an old post, and you don't have to respond here you can respond directly to my email, walterjhowell1997@yahoo.com. I have used this lisp expression you've created and it does almost exactly what I want it to do, the only thing I would like to change is the spacing between the selected blocks. Would I be able to change a specific line of code to change how evenly the block are spaced from each other. Basically I want to use this as a way of creating a Riser diagram, and to be able to add text under the objects without overlapping would be perfect. So basically wondering how I would go about changing a piece of your lisp expression to fit my needs. If you would respond I would be very appreciative.
- Thank you.
Can't find what you're looking for? Ask the community or share your knowledge.