;;---------------------=={ Extract Nested Block }==---------------------;;
;;                                                                      ;;
;;  This program allows the user to convert a nested block into a       ;;
;;  primary block inserted at the same position for each reference of   ;;
;;  the nested block, retaining the same scale, rotation, orientation   ;;
;;  and all other properties possessed by the original nested block.    ;;
;;                                                                      ;;
;;  Upon selection of a nested block, the program will convert all      ;;
;;  references of the nested block and then proceed to remove the       ;;
;;  nested block from the primary block definition in which it resides. ;;
;;                                                                      ;;
;;  The program is compatible with uniformly-scaled nested standard     ;;
;;  blocks, nested dynamic blocks & nested xrefs, nested to any depth.  ;;
;;                                                                      ;;
;;  However, the program is incompatible with blocks nested within      ;;
;;  dynamic blocks or xrefs, and the program will ignore                ;;
;;  non-uniformly-scaled block references.                              ;;
;;                                                                      ;;
;;----------------------------------------------------------------------;;
;;  Author:  Lee Mac, Copyright © 2013  -  www.lee-mac.com              ;;
;;----------------------------------------------------------------------;;
;;  Version 1.0    -    04-04-2012                                      ;;
;;                                                                      ;;
;;  - First release.                                                    ;;
;;----------------------------------------------------------------------;;
;;  Version 1.1    -    09-09-2013                                      ;;
;;                                                                      ;;
;;  - Program modified to prohibit selection of nested blocks residing  ;;
;;    on locked layers or blocks nested within dynamic blocks or xrefs. ;;
;;                                                                      ;;
;;  - Program will now ignore non-uniformly scaled block references     ;;
;;    without returning an error.                                       ;;
;;----------------------------------------------------------------------;;
;·ÖÀë¿éÀïÃæµÄÇ¶Ì×¿é[lm_enb]
(defun c:lm_enb ( / old_cmd enb:copy enb:getreferences enb:isxref sel LM:acdoc )
;; Active Document  -  Lee Mac
;; Returns the VLA Active Document Object
(mai_last_com "lm_enb")

(defun LM:acdoc nil
    (eval (list 'defun 'LM:acdoc 'nil (vlax-get (vlax-get-acad-object) 'activedocument)))
    (LM:acdoc)
)

(defun enb:copy ( ent par )
    (eval
        (list 'defun 'enb:copy '( ent par )
            (list 'car
                (list 'vlax-invoke (LM:acdoc) ''copyobjects '(list (vlax-ename->vla-object ent))
                    (if (vlax-method-applicable-p (LM:acdoc) 'objectidtoobject32)
                        (list 'vla-objectidtoobject32 (LM:acdoc) '(vlax-get (vlax-ename->vla-object par) 'ownerid32))
                        (list 'vla-objectidtoobject   (LM:acdoc) '(vlax-get (vlax-ename->vla-object par) 'ownerid))
                    )
                )
            )
        )
    )
    (enb:copy ent par)
)

(defun enb:getreferences ( blk / ent enx lst )
    (if (setq ent (tblobjname "block" blk))
        (foreach dxf (entget (mai_dxf 330 ent))
            (if (and
                    (= 331 (car dxf))
                    (setq ent (cdr dxf))
                    (setq enx (entget ent))
                    (setq enx (entget (mai_dxf 330 enx)))
                )
                (setq blk (mai_dxf 2 enx)
                      lst (if (wcmatch (strcase blk) "`**_SPACE")
                              (cons (list ent) lst)
                              (append (mapcar '(lambda(x) (cons ent x)) (enb:getreferences blk)) lst)
                          )
                )
            )
        )
    )
    lst
)

(defun enb:isxref ( ent )
    (= 4 (logand 4 (mai_dxf 70 (tblsearch "block" (mai_dxf 2 ent)))))
)


    (mini_start nil)
    (while
        (progn (setvar 'errno 0) (setq sel (nentselp "\nÑ¡ÔñÐèÒªÌáÈ¡µÄ¿éÀïÃæÇ¶Ì×¿é:"))
            (cond
                (   (= 7 (getvar 'errno))
                    (princ "\n¿ÕÑ¡£¬ÔÙÀ´Ò»´Î.")
                )
                (   (null sel) nil)
                (   (null (cadr (setq sel (last sel))))
                    (princ "\nÑ¡ÔñµÄ²»ÊÇ¿éÀïÃæÇ¶Ì×¿é.")
                )
                (   (= 4 (logand 4 (mai_dxf 70 (tblsearch "layer" (mai_dxf 8 (car sel))))))
                    (princ "nÑ¡ÔñµÄ¿éËùÔÚÍ¼²ã±»Ëø¶¨.")
                )
                (   (vl-some 'enb:isxref (cdr sel))
                    (princ "\nÑ¡ÔñµÄ¿é°üº¬Íâ²¿²ÎÕÕ£¬²»Ö§³Ö.")
                )
                (   (vl-some 'mai_IsDynamicBlock (cdr sel))
                    (princ "\nÑ¡ÔñµÄ¿é°üº¬¶¯Ì¬¿é£¬²»Ö§³Ö.")
                )
            )
        )
    )
    (if sel
        (progn
            (foreach lst (enb:getreferences (mai_dxf 2 (cadr sel)))
                (apply
                   '(lambda ( mat vec / obj )
                        (foreach ent (cdr (reverse lst))
                            (apply
                                '(lambda ( m v )
                                        (setq vec (mapcar '+ vec (mai_mxv mat v))
                                              mat (mai_mxm mat m)
                                        )
                                )
                                (mai_blk_matrix ent)
                            )
                        )
                        (if
                            (vl-catch-all-error-p
                                (vl-catch-all-apply 'vla-transformby
                                    (list (setq obj (enb:copy (car sel) (last lst)))
                                        (vlax-tmatrix
                                            (append
                                                (mapcar '(lambda ( m v ) (append m (list v))) mat vec)
                                               '((0.0 0.0 0.0 1.0))
                                            )
                                        )
                                    )
                                )
                            )
                            (vla-delete obj)
                        )
                    )
                    (mai_blk_matrix (last lst))
                )
            )
            (vla-delete (vlax-ename->vla-object (car sel)))
            (vla-regen  (LM:acdoc) acactiveviewport)
        )
    )
    (mai_end)
)
