This is in response to a post on the AutoDesk forum.
http://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/insert-a-new-block-based-on-the-size-of-an-old-block-width-and/m-p/5946907#U5946907Refer to that thread for intent.
I'm posting here for code clarity.
The code is for proof of concept and doesn't handle situations where the original block is inserted mirrored.
It is possible to change code from single selection to multiple selection , but not today
Source:
;;;-----------------------------------------------------------
(defun c:BlockInsertBySize151211
(/ *error*
;| TODO Make these local after testing
_singleSelection
_GetBlockData
_SwapBlock
_SwapLayerForOldInstance
;;
g:OriginalBlocksData
g:OriginalBlocksNames
;|
;;
;|
G:BLOCKNAME
G:ENT
G:INSERTION
G:NEWBLOCKNAME
G:NEWLAYERNAME
G:OLDLAYER
G:ROTATION
|;
)
;;-----------------------------------------------------------
(defun *error* (msg
) (Default
*error
* msg
)) ;;-----------------------------------------------------------
'("SAMPLE BLOCK" "T" 72 42.25)
'("SK1" "T" 72 42.25)
'("SK2" "WS" 31.1875 29)
'("SK3" "ST" 43 22)
'("SK4" "SH" 43 22)
'("SK5" "T" 15 15)
'("SK6" "S" 72 24)
)
g:OriginalBlocksData
)
)
;;-----------------------------------------------------------
(defun _singleSelection
(/ selection ename
) (setq g:blockName
(dxf
2 g:ent
)) (= "INSERT" (dxf 0 g:ent))
(member g:blockName g:OriginalBlocksNames
) )
(_GetBlockData g:ent)
)
)
;;-----------------------------------------------------------
(defun _GetBlockData
(ent
/ Data xScale yScale zScale width height
) (setq g:insertion
(dxf
10 ent
) g:oldlayer (dxf 8 ent)
g:rotation (dxf 50 ent)
xScale (dxf 41 ent)
yScale (dxf 42 ent)
zScale (dxf 43 ent)
)
(setq Data
(dxf g:blockName g:OriginalBlocksData
) )
(if (= g:blockName
"SK5") ; It's a circle (kdub:roundnearest height 1 0)
"R"
)
)
;; else it's a rectangle
(kdub:roundnearest height 1 0)
(kdub:roundnearest width 1 0)
)
)
)
)
;;-----------------------------------------------------------
(defun _SwapBlock
( / newblkent
) )
g:newBlockName
"S"
1.0
"R"
(kdub:rtd g:rotation)
g:insertion
)
;; else
g:newBlockName
"\n Routine will exit"
)
)
g:newBlockName
"\n Routine will exit"
)
)
)
)
;;Change to correct Layer
)
;;-----------------------------------------------------------
(defun _SwapLayerForOldInstance
(/ Lay
) )
;;-----------------------------------------------------------
(_singleSelection)
(_SwapBlock)
(_SwapLayerForOldInstance)
)
Library code:
;;; Return linked value from association list
;;; Convert Angles from DEGREES to RADIANS
(defun kdub:dtr
(ang
) (* (/ ang
180.0) pi
))
;;; Convert Angles from RADIANS to DEGREES
(defun kdub:rtd
(ang
) (/ (* ang
180.0) pi
)) ;;;---------------------------------------------------------------------------
;;;---------------------------------------------------------------------------
;;* kdub:roundNearest (numVal roundTo displayPrecision)
;; Round a numeric positive number to the NEAREST 'rounded' number
;; and format to n digits
;; kwb@theSwamp 20070814
;|
(kdub:roundnearest 5.7 1 0) ;-> "6"
(kdub:roundnearest 6.3 1 0) ;-> "6"
(kdub:roundnearest 6.3 0.5 2) ;-> "6.50"
(kdub:roundnearest 6.2 0.5 3) ;-> "6.000"
|;
(defun kdub:roundnearest
(numval roundto displayprecision
/ remnum
) (rtos (if (>= (* 2 remnum
) roundto
) (+ numval (- roundto remnum))
(- numval remnum)
)
2
displayprecision
)
)
;;;-----------------------------------------------------------
(defun Default
*error
* (msg
) '("console break" "function cancelled" "quit / exit abort")
)
(princ "\nFunction Cancelled.") )
" :- "
msg
)
)
)
)
)
ADDED:
Code revised to add new block on specific layer :
Code attachment :