Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Change x-ref files base point to WCS (0,0,0) all at once

31 REPLIES 31
SOLVED
Reply
Message 1 of 32
igal1971
3009 Views, 31 Replies

Change x-ref files base point to WCS (0,0,0) all at once

Hi everyone!

Does anyone know where i can get a lisp routine on how to change xref files base point to WCS (0,0,0) all at once? Your help is highly appreciated.

I don't need to move it to 0,0 only to change base point (xref's must to remain in old places)

31 REPLIES 31
Message 2 of 32
marko_ribar
in reply to: igal1971

Smething like this link :

http://www.lee-mac.com/changeblockinsertion.html

 

Try it with xrefs, should work the same as with blocks...

Marko Ribar, d.i.a. (graduated engineer of architecture)
Message 3 of 32
igal1971
in reply to: marko_ribar

thank you Marko it's work great but lisp work only in one xref per session and i have a least 46 xref's and want to change it all at once How to do it?

Message 4 of 32
marko_ribar
in reply to: igal1971

Try this mod... Untested though...

 

;; Retains Xref Reference Position
(defun c:cxpr ( / ss entlst ) 
    (prompt "\nSelect Xref entities to process changing insertion points to WCS origin while retaining their position...")
    (setq ss (ssget '((0 . "INSERT"))))
    (setq entlst (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))
    (foreach ent entlst
        (if (eq (vla-get-isxref (vla-item (vla-get-blocks (LM:acdoc)) (LM:blockname (vlax-ename->vla-object ent)))) :vlax-true)
            (LM:changeblockbasepoint t ent)
        )
    )
    (princ)
)
 
;;----------------------------------------------------------------------;;
 
(defun LM:changeblockbasepoint ( flg ent / *error* bln cmd lck mat nbp vec )
 
    (defun *error* ( msg )
        (foreach lay lck (vla-put-lock lay :vlax-true))
        (if (= 'int (type cmd)) (setvar 'cmdecho cmd))
        (LM:endundo (LM:acdoc))
        (if (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*"))
            (princ (strcat "\nError: " msg))
        )
        (princ)
    )
 
    (if (and (= 'ename (type ent)) (setq nbp '(0.0 0.0 0.0)))
        (progn
            (setq mat (car (revrefgeom ent))
                  vec (mxv mat (mapcar '- (trans nbp 1 0) (trans (cdr (assoc 10 (entget ent))) ent 0)))
                  bln (LM:blockname (vlax-ename->vla-object ent))
            )
            (LM:startundo (LM:acdoc))
            (vlax-for lay (vla-get-layers (LM:acdoc))
                (if (= :vlax-true (vla-get-lock lay))
                    (progn
                        (vla-put-lock lay :vlax-false)
                        (setq lck (cons lay lck))
                    )
                )
            )
            (vlax-for obj (vla-item (vla-get-blocks (LM:acdoc)) bln)
                 (vlax-invoke obj 'move vec '(0.0 0.0 0.0))
            )
            (if flg
                (vlax-for blk (vla-get-blocks (LM:acdoc))
                    (if (= :vlax-false (vla-get-isxref blk))
                        (vlax-for obj blk
                            (if
                                (and
                                    (= "AcDbBlockReference" (vla-get-objectname obj))
                                    (= bln (LM:blockname obj))
                                    (vlax-write-enabled-p obj)
                                )
                                (vlax-invoke obj 'move '(0.0 0.0 0.0) (mxv (car (refgeom (vlax-vla-object->ename obj))) vec))
                            )
                        )
                    )
                )
            )
            (if (= 1 (cdr (assoc 66 (entget ent))))
                (progn
                    (setq cmd (getvar 'cmdecho))
                    (setvar 'cmdecho 0)
                    (vl-cmdf "_.attsync" "_N" bln)
                    (setvar 'cmdecho cmd)
                )
            )
            (foreach lay lck (vla-put-lock lay :vlax-true))
            (vla-regen  (LM:acdoc) acallviewports)
            (LM:endundo (LM:acdoc))
        )
    )
    (princ)
)
 
;; 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))))))
        )
    )
)
 
;; RevRefGeom (gile)
;; The inverse of RefGeom
 
(defun revrefgeom ( ent / ang enx mat ocs )
    (setq enx (entget ent)
          ang (cdr (assoc 050 enx))
          ocs (cdr (assoc 210 enx))
    )
    (list
        (setq mat
            (mxm
                (list
                    (list (/ 1.0 (cdr (assoc 41 enx))) 0.0 0.0)
                    (list 0.0 (/ 1.0 (cdr (assoc 42 enx))) 0.0)
                    (list 0.0 0.0 (/ 1.0 (cdr (assoc 43 enx))))
                )
                (mxm
                    (list
                        (list (cos ang)     (sin ang) 0.0)
                        (list (- (sin ang)) (cos ang) 0.0)
                       '(0.0 0.0 1.0)
                    )
                    (mapcar '(lambda ( v ) (trans v ocs 0 t))
                        '(
                             (1.0 0.0 0.0)
                             (0.0 1.0 0.0)
                             (0.0 0.0 1.0)
                         )
                    )
                )
            )
        )
        (mapcar '- (cdr (assoc 10 (tblsearch "block" (cdr (assoc 2 enx)))))
            (mxv mat (trans (cdr (assoc 10 enx)) ocs 0))
        )
    )
)
 
;; 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)
)
 
;; 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 Transpose  -  Doug Wilson
;; Args: m - nxn matrix
 
(defun trp ( m )
    (apply 'mapcar (cons 'list m))
)
 
;; Block Name  -  Lee Mac
;; Returns the true (effective) name of a supplied block reference
                        
(defun LM:blockname ( obj )
    (if (vlax-property-available-p obj 'effectivename)
        (defun LM:blockname ( obj ) (vla-get-effectivename obj))
        (defun LM:blockname ( obj ) (vla-get-name obj))
    )
    (LM:blockname obj)
)
 
;; Start Undo  -  Lee Mac
;; Opens an Undo Group.
 
(defun LM:startundo ( doc )
    (LM:endundo doc)
    (vla-startundomark doc)
)
 
;; End Undo  -  Lee Mac
;; Closes an Undo Group.
 
(defun LM:endundo ( doc )
    (while (= 8 (logand 8 (getvar 'undoctl)))
        (vla-endundomark doc)
    )
)
 
;; Active Document  -  Lee Mac
;; Returns the VLA Active Document Object
 
(defun LM:acdoc nil
    (eval (list 'defun 'LM:acdoc 'nil (vla-get-activedocument (vlax-get-acad-object))))
    (LM:acdoc)
)
 
;;----------------------------------------------------------------------;;
 
(vl-load-com) (princ)

 Marko

Marko Ribar, d.i.a. (graduated engineer of architecture)
Message 5 of 32
igal1971
in reply to: marko_ribar

works awesome. This is one I need
Thank you Marko
Message 6 of 32
igal1971
in reply to: igal1971

Hi Marco!

I tested your lisp solution and found a little problem: When you reload xref after invoking this routine it moved insted of fact that it must to Retain Xref Reference Position What the problem?

Message 7 of 32
marko_ribar
in reply to: igal1971


@igal1971 wrote:

Hi Marco!

I tested your lisp solution and found a little problem: When you reload xref after invoking this routine it moved insted of fact that it must to Retain Xref Reference Position What the problem?


Try to change this line :

 

(LM:changeblockbasepoint t ent)

 To this line :

 

(LM:changeblockbasepoint nil ent)

 HTH, M.R.

Marko Ribar, d.i.a. (graduated engineer of architecture)
Message 8 of 32
igal1971
in reply to: marko_ribar

unfortunaly it's not helped - xref moved imidiatly after invoking lisp but need to be retained in a previous position
Message 9 of 32
dicra
in reply to: igal1971

Hi,

 

I think that the problem is, because Lee Mac's command will change the xref insert position, but xref drawing is still the same.

So when you restart drawing, only insertion point of xref will be changed.

I think the only way is to change the insertion point, and then to change xref it self.

Igal, will that be the problem for you,  if xref drawings are changed?

Message 10 of 32
igal1971
in reply to: dicra

Hi dicra!

It's seems to be a Real problem because position of all xref's changed, but you don't see it until you reopen the drawing and then you see the catch...

Message 11 of 32
dicra
in reply to: igal1971

Igal, 

 

I can see the solution for your problem. But I'm not sure that it is going to bee ok for you.

There are two ways.

 

1. That, all original drawings of xref be changed. When you reopen drawing, it is going to load changed xref. (same as REFEDIT command!!!)

2. That you convert xref to block, and then to change insertion point.

 

If one of this solutions is good for, you, I could find the way to help you.

Other things, are beyond my knowledge and experience.

 

 

 

 

Message 12 of 32
igal1971
in reply to: dicra

Hi Dicra!

 Where is very simple way to do it manualy

1. bind xref as block

2. wblock this block with new insertion point and new name

3. open this file  explode internal block and make purge command

4. open main file with xrefs and make purge, after that insert modifyed xref

an so on for all xrefs with "problem" insertion poit....

Can you make a lisp in order to automate this algorithm?

 

Message 13 of 32
marko_ribar
in reply to: igal1971

If you don't have nested xrefs into xrefs, make backup of all files (master DWG + xrefs), and try this on master DWG just once...

 

;; Retains Xref Reference Position
(defun c:cxpr ( / ss entlst p pentlst f )
    (command "_.UCS" "_W")
    (prompt "\nSelect Xref entities to process changing insertion points to WCS origin while retaining their position...")
    (setq ss (ssget '((0 . "INSERT"))))
    (setq entlst (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))
    (foreach ent entlst
        (if (eq (vla-get-isxref (vla-item (vla-get-blocks (LM:acdoc)) (LM:blockname (vlax-ename->vla-object ent)))) :vlax-true)
            (progn
                (setq p (cdr (assoc 10 (entget ent))))
                (LM:changeblockbasepoint t ent)
                (setq pentlst (cons (cons p ent) pentlst))
            )
        )
    )
    (setq f (open "c:/scr.scr" "w"))
    (write-line "_.QSAVE" f)
    (foreach pent pentlst
        (write-line "_.OPEN" f)
        (write-line (strcat "\"" (findfile (vla-get-path (vlax-ename->vla-object (cdr pent)))) "\"") f)
        (write-line "_.-LAYER" f)
        (write-line "T" f)
        (write-line "*" f)
        (write-line "U" f)
        (write-line "*" f)
        (write-line "ON" f)
        (write-line "*" f)
        (write-line "" f)
        (write-line "_.MOVE" f)
        (write-line "ALL" f)
        (write-line "" f)
        (write-line "0,0,0" f)
        (write-line (strcat (rtos (caar pent)) "," (rtos (cadar pent)) "," (rtos (caddar pent))) f)
        (write-line "_.LAYERP" f)
        (write-line "_.QSAVE" f)
    )
    (write-line "_.CLOSEALL" f)
    (close f)
    (alert "After reopening master DWG, type (vl-file-delete \"c:/scr.scr\")")
    (command "_.SCRIPT" "c:/scr.scr")
    (princ)
)
 
;;----------------------------------------------------------------------;;
 
(defun LM:changeblockbasepoint ( flg ent / *error* bln cmd lck mat nbp vec )
 
    (defun *error* ( msg )
        (foreach lay lck (vla-put-lock lay :vlax-true))
        (if (= 'int (type cmd)) (setvar 'cmdecho cmd))
        (LM:endundo (LM:acdoc))
        (if (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*"))
            (princ (strcat "\nError: " msg))
        )
        (princ)
    )
 
    (if (and (= 'ename (type ent)) (setq nbp '(0.0 0.0 0.0)))
        (progn
            (setq mat (car (revrefgeom ent))
                  vec (mxv mat (mapcar '- (trans nbp 1 0) (trans (cdr (assoc 10 (entget ent))) ent 0)))
                  bln (LM:blockname (vlax-ename->vla-object ent))
            )
            (LM:startundo (LM:acdoc))
            (vlax-for lay (vla-get-layers (LM:acdoc))
                (if (= :vlax-true (vla-get-lock lay))
                    (progn
                        (vla-put-lock lay :vlax-false)
                        (setq lck (cons lay lck))
                    )
                )
            )
            (vlax-for obj (vla-item (vla-get-blocks (LM:acdoc)) bln)
                 (vlax-invoke obj 'move vec '(0.0 0.0 0.0))
            )
            (if flg
                (vlax-for blk (vla-get-blocks (LM:acdoc))
                    (if (= :vlax-false (vla-get-isxref blk))
                        (vlax-for obj blk
                            (if
                                (and
                                    (= "AcDbBlockReference" (vla-get-objectname obj))
                                    (= bln (LM:blockname obj))
                                    (vlax-write-enabled-p obj)
                                )
                                (vlax-invoke obj 'move '(0.0 0.0 0.0) (mxv (car (refgeom (vlax-vla-object->ename obj))) vec))
                            )
                        )
                    )
                )
            )
            (if (= 1 (cdr (assoc 66 (entget ent))))
                (progn
                    (setq cmd (getvar 'cmdecho))
                    (setvar 'cmdecho 0)
                    (vl-cmdf "_.attsync" "_N" bln)
                    (setvar 'cmdecho cmd)
                )
            )
            (foreach lay lck (vla-put-lock lay :vlax-true))
            (vla-regen  (LM:acdoc) acallviewports)
            (LM:endundo (LM:acdoc))
        )
    )
    (princ)
)
 
;; 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))))))
        )
    )
)
 
;; RevRefGeom (gile)
;; The inverse of RefGeom
 
(defun revrefgeom ( ent / ang enx mat ocs )
    (setq enx (entget ent)
          ang (cdr (assoc 050 enx))
          ocs (cdr (assoc 210 enx))
    )
    (list
        (setq mat
            (mxm
                (list
                    (list (/ 1.0 (cdr (assoc 41 enx))) 0.0 0.0)
                    (list 0.0 (/ 1.0 (cdr (assoc 42 enx))) 0.0)
                    (list 0.0 0.0 (/ 1.0 (cdr (assoc 43 enx))))
                )
                (mxm
                    (list
                        (list (cos ang)     (sin ang) 0.0)
                        (list (- (sin ang)) (cos ang) 0.0)
                       '(0.0 0.0 1.0)
                    )
                    (mapcar '(lambda ( v ) (trans v ocs 0 t))
                        '(
                             (1.0 0.0 0.0)
                             (0.0 1.0 0.0)
                             (0.0 0.0 1.0)
                         )
                    )
                )
            )
        )
        (mapcar '- (cdr (assoc 10 (tblsearch "block" (cdr (assoc 2 enx)))))
            (mxv mat (trans (cdr (assoc 10 enx)) ocs 0))
        )
    )
)
 
;; 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)
)
 
;; 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 Transpose  -  Doug Wilson
;; Args: m - nxn matrix
 
(defun trp ( m )
    (apply 'mapcar (cons 'list m))
)
 
;; Block Name  -  Lee Mac
;; Returns the true (effective) name of a supplied block reference
                        
(defun LM:blockname ( obj )
    (if (vlax-property-available-p obj 'effectivename)
        (defun LM:blockname ( obj ) (vla-get-effectivename obj))
        (defun LM:blockname ( obj ) (vla-get-name obj))
    )
    (LM:blockname obj)
)
 
;; Start Undo  -  Lee Mac
;; Opens an Undo Group.
 
(defun LM:startundo ( doc )
    (LM:endundo doc)
    (vla-startundomark doc)
)
 
;; End Undo  -  Lee Mac
;; Closes an Undo Group.
 
(defun LM:endundo ( doc )
    (while (= 8 (logand 8 (getvar 'undoctl)))
        (vla-endundomark doc)
    )
)
 
;; Active Document  -  Lee Mac
;; Returns the VLA Active Document Object
 
(defun LM:acdoc nil
    (eval (list 'defun 'LM:acdoc 'nil (vla-get-activedocument (vlax-get-acad-object))))
    (LM:acdoc)
)
 
;;----------------------------------------------------------------------;;
 
(vl-load-com) (princ)

 Basically the same code I already posted...

HTH, M.R.

Marko Ribar, d.i.a. (graduated engineer of architecture)
Message 14 of 32
marko_ribar
in reply to: marko_ribar

Small mod of main function :

 

;; Retains Xref Reference Position
(defun c:cxpr ( / ss entlst p pentlst f )
    (command "_.UCS" "_W")
    (prompt "\nSelect Xref entities to process changing insertion points to WCS origin while retaining their position...")
    (setq ss (ssget '((0 . "INSERT"))))
    (setq entlst (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))
    (foreach ent entlst
        (if (eq (vla-get-isxref (vla-item (vla-get-blocks (LM:acdoc)) (LM:blockname (vlax-ename->vla-object ent)))) :vlax-true)
            (progn
                (setq p (cdr (assoc 10 (entget ent))))
                (LM:changeblockbasepoint t ent)
                (setq pentlst (cons (cons p ent) pentlst))
            )
        )
    )
    (setq f (open "c:/scr.scr" "w"))
    (write-line "_.QSAVE" f)
    (foreach pent pentlst
        (write-line "_.OPEN" f)
        (if (vl-file-directory-p (vla-get-path (vlax-ename->vla-object (cdr pent))))
            (write-line (strcat "\"" (vla-get-path (vlax-ename->vla-object (cdr pent))) "\"") f)
            (write-line (strcat "\"" (findfile (strcat (getvar 'dwgprefix) (vla-get-path (vlax-ename->vla-object (cdr pent))))) "\"") f)
        )
        (write-line "_.-LAYER" f)
        (write-line "T" f)
        (write-line "*" f)
        (write-line "U" f)
        (write-line "*" f)
        (write-line "ON" f)
        (write-line "*" f)
        (write-line "" f)
        (write-line "_.MOVE" f)
        (write-line "ALL" f)
        (write-line "" f)
        (write-line "0,0,0" f)
        (write-line (strcat (rtos (caar pent) 2 50) "," (rtos (cadar pent) 2 50) "," (rtos (caddar pent) 2 50)) f)
        (write-line "_.LAYERP" f)
        (write-line "_.QSAVE" f)
    )
    (write-line "_.CLOSEALL" f)
    (close f)
    (alert "After reopening master DWG, type (vl-file-delete \"c:/scr.scr\")")
    (command "_.SCRIPT" "c:/scr.scr")
    (princ)
)

 

Marko Ribar, d.i.a. (graduated engineer of architecture)
Message 15 of 32
dicra
in reply to: igal1971

Marko, 

 

I was having some errors with your code, hope you don't mind, I made some changes.

Think I made the same thing, but whit out using script, and with vla functions.

 

igal,

 

Sorry I didn't answer immediately.

 

Please before using this function, please backup all external references and current drawing, because this lisp is modifying external references.

It moves objects in xref form point 0,0,0 to point which one is same as xref insertpoint in active drawing. On that way insertpoint in xref is 0,0,0 in active drawing, and objects of xref are on the same location as in active drawing. 

Because xref drawings are changed, please test this routine on example drawing, so that we be sure that this is what you wanted.

 

Only thing which I'm not sure about it, is because I made selection set of all objects in xref (vla-select newss acselectionsetall).

In that selection set are some vla-objects which are not entitys in drawing, I applied vla-move on all of them. 

I don' know if this is wrong, hope that some one more experience will answer.

 

Anyway, I didn't find any problems while I was using this routine, on my example drawing. 

 

;; Retains Xref Reference Position
(defun c:cxpr (/ ss entlst newss ssets v-ent pt1 pat docs)
  (prompt
    "\nSelect Xref entities to process changing insertion points to WCS origin while retaining their position..."
  )
  (setq ss (ssget '((0 . "INSERT"))))
  (setq entlst (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))
  (foreach ent entlst
    (if	(eq (vla-get-isxref
	      (vla-item	(vla-get-blocks (LM:acdoc))
			(LM:blockname (vlax-ename->vla-object ent))
	      )
	    )
	    :vlax-true
	)
      (progn

	
	(setq pt1 (cdr (assoc 10 (entget ent))))
	
	(LM:changeblockbasepoint t ent)

	
	
	(setq v-ent (vlax-ename->vla-object ent))
	(setq pat (vla-get-path v-ent))
	(setq docs (vla-get-Documents  (vlax-get-Acad-Object)))

	(setq x-open (vla-Open docs pat :vlax-false))
	
	(setq ssets (vla-get-selectionsets x-open))
	(setq newss (vla-add ssets "SS1"))
	(vla-select newss acselectionsetall)

	(vlax-for item newss (vla-move item (vlax-3d-point '(0 0 0)) (vlax-3d-point pt1)))

	(vla-delete (vla-item ssets "SS1"))
	
	(vla-close x-open)


      )						;end progn

    )
  )
  (princ)
)
;;----------------------------------------------------------------------;;
(defun LM:changeblockbasepoint
       (flg ent / *error* bln cmd lck mat nbp vec)
  (defun *error* (msg)
    (foreach lay lck (vla-put-lock lay :vlax-true))
    (if	(= 'int (type cmd))
      (setvar 'cmdecho cmd)
    )
    (LM:endundo (LM:acdoc))
    (if	(not (wcmatch (strcase msg t) "*break,*cancel*,*exit*"))
      (princ (strcat "\nError: " msg))
    )
    (princ)
  )
  (if (and (= 'ename (type ent)) (setq nbp '(0.0 0.0 0.0)))
    (progn
      (setq mat	(car (revrefgeom ent))
	    vec	(mxv mat
		     (mapcar '-
			     (trans nbp 1 0)
			     (trans (cdr (assoc 10 (entget ent))) ent 0)
		     )
		)
	    bln	(LM:blockname (vlax-ename->vla-object ent))
      )
      (LM:startundo (LM:acdoc))
      (vlax-for	lay (vla-get-layers (LM:acdoc))
	(if (= :vlax-true (vla-get-lock lay))
	  (progn
	    (vla-put-lock lay :vlax-false)
	    (setq lck (cons lay lck))
	  )
	)
      )
      (vlax-for	obj (vla-item (vla-get-blocks (LM:acdoc)) bln)
	(vlax-invoke obj 'move vec '(0.0 0.0 0.0))
      )
      (if flg
	(vlax-for blk (vla-get-blocks (LM:acdoc))
	  (if (= :vlax-false (vla-get-isxref blk))
	    (vlax-for obj blk
	      (if
		(and
		  (= "AcDbBlockReference" (vla-get-objectname obj))
		  (= bln (LM:blockname obj))
		  (vlax-write-enabled-p obj)
		)
		 (vlax-invoke
		   obj
		   'move
		   '(0.0 0.0 0.0)
		   (mxv (car (refgeom (vlax-vla-object->ename obj))) vec)
		 )
	      )
	    )
	  )
	)
      )
      (if (= 1 (cdr (assoc 66 (entget ent))))
	(progn
	  (setq cmd (getvar 'cmdecho))
	  (setvar 'cmdecho 0)
	  (vl-cmdf "_.attsync" "_N" bln)
	  (setvar 'cmdecho cmd)
	)
      )
      (foreach lay lck (vla-put-lock lay :vlax-true))
      (vla-regen (LM:acdoc) acallviewports)
      (LM:endundo (LM:acdoc))
    )
  )
  (princ)
)
;; 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)))))
	    )
    )
  )
)
;; RevRefGeom (gile)
;; The inverse of RefGeom
(defun revrefgeom (ent / ang enx mat ocs)
  (setq	enx (entget ent)
	ang (cdr (assoc 050 enx))
	ocs (cdr (assoc 210 enx))
  )
  (list
    (setq mat
	   (mxm
	     (list
	       (list (/ 1.0 (cdr (assoc 41 enx))) 0.0 0.0)
	       (list 0.0 (/ 1.0 (cdr (assoc 42 enx))) 0.0)
	       (list 0.0 0.0 (/ 1.0 (cdr (assoc 43 enx))))
	     )
	     (mxm
	       (list
		 (list (cos ang) (sin ang) 0.0)
		 (list (- (sin ang)) (cos ang) 0.0)
		 '(0.0 0.0 1.0)
	       )
	       (mapcar '(lambda (v) (trans v ocs 0 t))
		       '(
			 (1.0 0.0 0.0)
			 (0.0 1.0 0.0)
			 (0.0 0.0 1.0)
			)
	       )
	     )
	   )
    )
    (mapcar '-
	    (cdr (assoc 10 (tblsearch "block" (cdr (assoc 2 enx)))))
	    (mxv mat (trans (cdr (assoc 10 enx)) ocs 0))
    )
  )
)
;; 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)
)
;; 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 Transpose - Doug Wilson
;; Args: m - nxn matrix
(defun trp (m)
  (apply 'mapcar (cons 'list m))
)
;; Block Name - Lee Mac
;; Returns the true (effective) name of a supplied block reference
(defun LM:blockname (obj)
  (if (vlax-property-available-p obj 'effectivename)
    (defun LM:blockname (obj) (vla-get-effectivename obj))
    (defun LM:blockname (obj) (vla-get-name obj))
  )

  (LM:blockname obj)
)
;; Start Undo - Lee Mac
;; Opens an Undo Group.
(defun LM:startundo (doc)
  (LM:endundo doc)
  (vla-startundomark doc)
)
;; End Undo - Lee Mac
;; Closes an Undo Group.
(defun LM:endundo (doc)
  (while (= 8 (logand 8 (getvar 'undoctl)))
    (vla-endundomark doc)
  )
)
;; Active Document - Lee Mac
;; Returns the VLA Active Document Object
(defun LM:acdoc	nil
  (eval	(list 'defun
	      'LM:acdoc
	      'nil
	      (vla-get-activedocument (vlax-get-acad-object))
	)
  )
  (LM:acdoc)
)
;;----------------------------------------------------------------------;;
(vl-load-com)
(princ)

 

Hope this is what you are looking for.

cheers,

dicra

 

 

 

 

 

 

 

Message 16 of 32
igal1971
in reply to: dicra

Hi Marco Hi Dicra!

I tested all of your routines and have some comments

1. Marco's routine works properly but a little "dirty". I mean why we must to close all drawings? and if we close drawings why not to open it in the end of script session? Why not to wtite a temporaly script in temporaly acad directory in order not to "dirty" a root disk?

2. Dicra. your lisp is very slow just becouce of (vla-select newss acselectionsetall) I don't see any reason to add it to routine.. but the BIG problem is when you reopen master drawing in acad 2013 (i tested it on this "war-horse") xref moved..

Now we can use only Marco's version with some reservations:)

Message 17 of 32
igal1971
in reply to: igal1971

Marko! I "on the way" found another problem. When you have initialy rotated xref in a main drawing programm works not proprerly (xref moved after invoking lisp function and reopening main drawing) Can you fix it?

Message 18 of 32
marko_ribar
in reply to: igal1971

Ok, try this mod...

 

;; Retains Xref Reference Position
(defun c:cxpr ( / ss entlst pp p r ppentlst f )
    (command "_.UCS" "_W")
    (prompt "\nSelect Xref entities to process changing insertion points to WCS origin while retaining their position...")
    (setq ss (ssget '((0 . "INSERT"))))
    (setq entlst (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))
    (foreach ent entlst
        (if (eq (vla-get-isxref (vla-item (vla-get-blocks (LM:acdoc)) (LM:blockname (vlax-ename->vla-object ent)))) :vlax-true)
            (progn
                (setq p (cdr (assoc 10 (entget ent))))
                (setq r (cdr (assoc 50 (entget ent))))
                (LM:changeblockbasepoint t ent)
                (setq pp (polar '(0.0 0.0 0.0) (- (angle '(0.0 0.0 0.0) p) r) (distance '(0.0 0.0 0.0) p)))
                (setq ppentlst (cons (cons pp ent) ppentlst))
            )
        )
    )
    (setq f (open "c:/scr.scr" "w"))
    (write-line "_.QSAVE" f)
    (foreach ppent ppentlst
        (write-line "_.OPEN" f)
        (if (vl-file-directory-p (vla-get-path (vlax-ename->vla-object (cdr ppent))))
            (write-line (strcat "\"" (vla-get-path (vlax-ename->vla-object (cdr ppent))) "\"") f)
            (write-line (strcat "\"" (findfile (strcat (getvar 'dwgprefix) (vla-get-path (vlax-ename->vla-object (cdr ppent))))) "\"") f)
        )
        (write-line "_.-LAYER" f)
        (write-line "T" f)
        (write-line "*" f)
        (write-line "U" f)
        (write-line "*" f)
        (write-line "ON" f)
        (write-line "*" f)
        (write-line "" f)
        (write-line "_.MOVE" f)
        (write-line "ALL" f)
        (write-line "" f)
        (write-line "0,0,0" f)
        (write-line (strcat (rtos (caar ppent) 2 50) "," (rtos (cadar ppent) 2 50) "," (rtos (caddar ppent) 2 50)) f)
        (write-line "_.LAYERP" f)
        (write-line "_.QSAVE" f)
    )
    (write-line "_.CLOSEALL" f)
    (close f)
    (alert "After reopening master DWG, type (vl-file-delete \"c:/scr.scr\")")
    (command "_.SCRIPT" "c:/scr.scr")
    (princ)
)

 Cheers...

Marko Ribar, d.i.a. (graduated engineer of architecture)
Message 19 of 32
igal1971
in reply to: marko_ribar

when I launched a routine during the lisp process i received "error: bad argument type: stringp nil" (it was very simple file with one xref)
another point: I don't see any remembering to rotated xref in this part of routine. Am I wrong?
Message 20 of 32
marko_ribar
in reply to: igal1971

Yes, you're wrong, look for "r" variable - it stored rotation angle in radians which is then used to calculate position of new displacement point according to rotation and insertion point of xref... This new point is then used inside script... Master DWG should have then insertion point of xref in WCS origin and should keep rotation parameter of xref and no bad movement of xref should appear - it should be at original position... Sorry, I've checked my code again also on simple example and I can't replicate your error... Try to trace bug in VLIDE, and check all variables before starting script... Your error points to bug that some I suppose (write-line "string" f) string is nil... Its very simple code, you should be able to trace error... All strings should be "some value", or empty string ""...

Marko Ribar, d.i.a. (graduated engineer of architecture)

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost