Author Topic: Find insertion points of Nested Blocks  (Read 1215 times)

0 Members and 1 Guest are viewing this topic.

rayakmal

  • Newt
  • Posts: 53
Find insertion points of Nested Blocks
« on: June 05, 2018, 06:01:05 PM »
I modified BlockInfo.Lsp by Alan (CAB) to find insertion points of nested blocks, but the results I got are  definition of insertion blocks.
My question is how can I get the real world coordinates of insertion points of this nested blocks?
I know I have to utilize some kind coordinates transformation, can you give me a pointer for coordinates transformation especially for rotated blocks?

Any help is greatly appreciated. Thanks.

EDIT I: I used Refgeom (Gile) function as advised by Lee Mac, but I don't know how to apply the Transformation matrix.
EDIT II: PROBLEM SOLVED  :whistling: :whistling: :whistling:
Code: [Select]
;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
;;; FUNCTION BlockInfo.lsp
;;;   Send a block definition to text file "Block Data-[block name].txt"
;;;   You should view text file with word wrap off because
;;;   some of the lined are very long
;;;
;;; ARGUMENTS
;;;   none
;;;
;;; USAGE
;;;   BlockInfo
;;;
;;; PLATFORMS
;;; 2000+
;;;
;;; AUTHOR
;;; Copyright© 2004 Charles Alan Butler 
;;;   ab2draft@TampaBay.rr.com
;;;
;;; VERSION
;;; 1.1 Sep. 23, 2004
;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
;;;
;;; This routine may be used and copied for non-profit
;;;  purposes only. If you wish to include any of the file in a
;;;  commercial program, contact the author.
;;;
(defun c:BlockInfo (/
                       bname dxf data indent fname fn blkcnt indent
                   )
  ;;  extract the data from dotted pair
  (defun dxf (x) (cdr (assoc x data)))

  (if (setq bname (entsel "Pick a block: "))
    (if (and (setq data (entget (car bname)))
     (or (= "INSERT" (dxf 0))
         (= "DIMENSION" (dxf 0))
     )
) ;and
        (progn
          (setq parent_enm (car bname))
          (setq bname (dxf 2))
        );end progn
        (setq bname nil)
    ) ;if
    (if (and
         (setq bname (getstring t "\nEnter the block name: "))
         (setq ss (ssget "_X" (list '(0 . "INSERT")(cons 2 bname))))
         (setq ename (ssname ss 0)))
      (princ); got a block
      (setq bname nil); GETNAME FAILED
      ); if
  ) ;if
  (cond
    (bname
     (setq Fname (Strcat "Block Data-" bname ".txt"))
     (setq fn (open  fname "w"))
     (prt "===============================================")
     (prt "                 BlockInfo.lsp")
     (prt "               Charles Alan Butler")
     (prt "            ab2draft@TampaBay.rr.com")
     (prt "               09/23/2004 Ver 1.1")
     (prt "===============================================")
      ;;  Create current Date & Time
      (setq tmp (rtos (getvar 'cdate) 2 4))
      (setq tmp (strcat "     <<  File Date "
                       (substr tmp 5 2) "/" (substr tmp 7 2) "/"
                       (substr tmp 1 4) "@" (substr tmp 10 2) ":"
                       (substr tmp 12 2) " >>"
                   )
      )
     (prt tmp)
     (setq blkcnt 0
   indent "| "
     )
     (listb bname)
     (prt "*********** END OF PARENT BLOCK *************")
     (setq indent nil)
     (prt "===============================================")
     (prt "=             End of Routine                  =")
     (prt "===============================================")
     (close fn)
     (prompt (strcat "\nBlock data written to file: " fname))
    )
    (t (print " no block found."))
  ) ;cond
  (princ)
)

;;--------------------------------------
;;  do the actual line print to file   
(defun prt (txt)
  (if indent
    (princ indent fn)
  )
  (princ txt fn)
  (write-line "" fn)
)



;;--------------------------------------
;;  This sub routine does all the work 
(defun listb (bname / dxf data wait)
  ;; return value from a dotted pair
  (defun dxf (x) (cdr (assoc x data)))

  ;; begin the main program
  (if (= blkcnt 0)
    (setq header (strcat "         Parent Block : " bname))
    (setq header (strcat "          Sub Block "
(itoa blkcnt); number of nested levels
" : "
bname
)
    )
  )
  (prt "***********************************************")
  (prt header)
  (prt "***********************************************")
  (prt (setq data (entget(tblobjname "block" bname))))
  (prt "---------    Objects In Block  ----------------")
  (setq data (dxf -2)) ; get first entity
  (prt (setq data (entget data '("*")))) ; get assoc list
  (while data
    (if (= (dxf 0) "INSERT")
      (progn
(setq blkcnt (1+ blkcnt)
      indent (strcat indent "| ")
)
        (if (= (cdr (assoc 2 data)) "DRIVINGPILE")
          (progn
            (princ "\n. DXF-CODE 10 =  ")
            (princ (cdr (assoc 10 data)))
            (princ "\t is not an insertion point of nested block")
            ;; Lee Mac said, I need to use RefGeom (gile), but how?
            (setq Transmatrix_point (refgeom (cdr (assoc -1 data))))
            (princ "\n. Transformation data: ")
            (princ Transmatrix_point)
            (setq ipt (trans (cdr (assoc 10 data)) (cdr (assoc 210 data)) 0))
            (entmake
               (list
                 '(0 . "POINT")
                  (cons 10 (apply '(lambda ( m v ) (mapcar '+ (mxv m ipt) v)) (refgeom (cdr (assoc -1 (entget parent_enm))))))
               )
            )
          );end progn
        );end if
(listb (dxf 2))
(setq indent (substr indent 3))
(prt "************ END OF SUB BLOCK **************")
      )
    )
    (if (setq data (entnext (dxf -1)))
      (progn
         (prt (setq data (entget data '("*")))) ; get assoc list
      );end progn
    );end if
  ) ;while
  (princ)
)
(prompt "\nBlock Info Loaded, Enter BlockInfo to run.")
(princ)
;;;--- end of file -----------------------------------------




    ;; RefGeom (gile)
    ;; Returns a list whose first item is a 3x3 transformation matrix and
    ;; second item the object insertion point in its parent (xref, block or space)
     
    (defun refgeom ( ent / ang enx mat ocs )
        (setq enx (entget ent)
              ang (cdr (assoc 050 enx))
              ocs (cdr (assoc 210 enx))
        )
        (list
            (setq mat
                (mxm
                    (mapcar '(lambda ( v ) (trans v 0 ocs t))
                       '(
                            (1.0 0.0 0.0)
                            (0.0 1.0 0.0)
                            (0.0 0.0 1.0)
                        )
                    )
                    (mxm
                        (list
                            (list (cos ang) (- (sin ang)) 0.0)
                            (list (sin ang) (cos ang)     0.0)
                           '(0.0 0.0 1.0)
                        )
                        (list
                            (list (cdr (assoc 41 enx)) 0.0 0.0)
                            (list 0.0 (cdr (assoc 42 enx)) 0.0)
                            (list 0.0 0.0 (cdr (assoc 43 enx)))
                        )
                    )
                )
            )
            (mapcar '- (trans (cdr (assoc 10 enx)) ocs 0)
                (mxv mat (cdr (assoc 10 (tblsearch "block" (cdr (assoc 2 enx))))))
            )
        )
    )
   
    ;; Matrix Transpose  -  Doug Wilson
    ;; Args: m - nxn matrix
     
    (defun trp ( m )
        (apply 'mapcar (cons 'list m))
    )
     
    ;; Matrix x Matrix  -  Vladimir Nesterovsky
    ;; Args: m,n - nxn matrices
     
    (defun mxm ( m n )
        ((lambda ( a ) (mapcar '(lambda ( r ) (mxv a r)) m)) (trp n))
    )
     
    ;; Matrix x Vector  -  Vladimir Nesterovsky
    ;; Args: m - nxn matrix, v - vector in R^n
     
    (defun mxv ( m v )
        (mapcar '(lambda ( r ) (apply '+ (mapcar '* r v))) m)
    )



« Last Edit: June 06, 2018, 01:02:47 AM by rayakmal »

Lee Mac

  • Seagull
  • Posts: 12915
  • London, England
Re: Find insertion points of Nested Blocks
« Reply #1 on: June 06, 2018, 01:01:21 PM »
Happy to help!  :lol: