Announcements
Attention for Customers without Multi-Factor Authentication or Single Sign-On - OTP Verification rolls out April 2025. Read all about it here.

Update xref insertion to 0,0,0

bsanada
Advocate

Update xref insertion to 0,0,0

bsanada
Advocate
Advocate

We have a master drawing that pulls in several hundred xrefs and most xrefs do not have a 0,0,0 insertion point.  I am looking for a lisp routine that would create a copy of each xref drawing with an updated insertion point allowing each drawing to be inserted using 0,0,0.  There may be a couple ways to skin this cat but my intitial thought would be to bind the xrefs and then wblock them back out.

0 Likes
Reply
Accepted solutions (1)
1,457 Views
56 Replies
Replies (56)

pendean
Community Legend
Community Legend

XREFs and blocks always have a 0,0,0 insertion point, you literally can't avoid it: if I may ask, do you mean and are you by chance just assuming the point 0,0,0 always means your content from the XREFs are always going to align?

0 Likes

bsanada
Advocate
Advocate

For reference the project involves a 3D arrangement of equipment in a factory.  Our overall model xreferences each piece of equipment into a master file, but the insertion point of each piece of xreferenced eqiupment is not 0,0,0 to have the equipment in the proper location in the overal general arrangement.  The individual equipment files have a random insertion point and the xrefs are being moved around to fit the arrangment in the master file.  I am looking for a way to update the insertion points in the equipment files so they can be inserted at 0,0,0.

0 Likes

cadffm
Consultant
Consultant

Hi,

your idea is not so bad, just in details not the best way.

 

You insert all, you move* each to the place you need (hoping it is just the position, not the rotation)

and a Tool would edit the xref files.

 

Good workflow, I like it and will take a look.

 

*You have to move, because a program can't know where the right position is.

 

 

 

Sebastian

0 Likes

pendean
Community Legend
Community Legend

Thanks for the extra info: sadly it does not change anything, unless you can share DWG examples of a "factory" and a couple of "pieces" for someone to confirm.

0 Likes

paullimapa
Mentor
Mentor

Any reason for making a copy of the xref dwgs?  That would defeat the purpose of the use of xrefs. The idea is to make the change once and not twice. You might as well bind the xrefs as block inserts in the master dwg and then modify each of the block inserts base points. 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes

paullimapa
Mentor
Mentor

FYI after converting all xrefs to block inserts in master dwg then you can use Lee Macs CBPR command to change all the bound blocks insert point to master dwgs 0,0,0


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes

bsanada
Advocate
Advocate

Thank you,this seems like it would be a useful part of the solution.  I will check it out.

0 Likes

paullimapa
Mentor
Mentor

You’re welcome and hope that works out for you…cheers!!!


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes

Kent1Cooper
Consultant
Consultant

I would:

1.  Draw a LINE from some identifiable point in each Xref in the master drawing, to the master drawing's 0,0.

2.  Ctrl-X remove it from the master drawing and put it in the clipboard.

3.  OPEN the Xref'd file.

4.  Ctrl-V paste that Line in, and MOVE it to have the appropriate end at that same identifiable point.

5.  Use the BASE command to set the insertion point of that drawing to the other end of that Line.

6.  ERASE the Line.

7.  QSAVE & CLOSE the Xref'd drawing, and reload it in the master drawing.

8.  MOVE it from its new insertion point to 0,0 [you can grip-edit, or just type in Properties].

 

Kent Cooper, AIA
0 Likes

Moshe-A
Mentor
Mentor

@bsanada  hi,

 

check this XREFOUT command.

 

Run this only on master.dwg after you exactly placed all your xrefs.

the command starts by asking the folder to save the xrefs. of course you could select the origin folder and override the origin xrefs but it's recommended to place them in a new.

 

thank you Lee Mac for the amazing (LM:browseforfolder) function.

 

before run, it is recommended to manually try to bind each xref to reduce failures at run time.

 

to achieve what you want, xrefout do:

1. set xref scale to 1x1

2. set xref rotation to 0

3. xref bind

4. explode blocks

5. turn all layers on

6. gather all exploded objects to SS  selection set.

7. write out block (WBLOCK)

 

Cause you said i have several hundred xrefs this could be long process... a progress bar is used.

 

if it work without errors, your master drawing should be left intact 😀

 

enjoy

Moshe

 

 

;; Browse for Folder  -  Lee Mac
;; Displays a dialog prompting the user to select a folder.
;; msg - [str] message to display at top of dialog
;; dir - [str] [optional] root directory (or nil)
;; bit - [int] bit-coded flag specifying dialog display settings
;; Returns: [str] Selected folder filepath, else nil.

(defun LM:browseforfolder ( msg dir bit / err fld pth shl slf )
    (setq err
        (vl-catch-all-apply
            (function
                (lambda ( / app hwd )
                    (if (setq app (vlax-get-acad-object)
                              shl (vla-getinterfaceobject app "shell.application")
                              hwd (vl-catch-all-apply 'vla-get-hwnd (list app))
                              fld (vlax-invoke-method shl 'browseforfolder (if (vl-catch-all-error-p hwd) 0 hwd) msg bit dir)
                        )
                        (setq slf (vlax-get-property fld 'self)
                              pth (vlax-get-property slf 'path)
                              pth (vl-string-right-trim "\\" (vl-string-translate "/" "\\" pth))
                        )
                    )
                )
            )
        )
    )
    (if slf (vlax-release-object slf))
    (if fld (vlax-release-object fld))
    (if shl (vlax-release-object shl))
    (if (vl-catch-all-error-p err)
        (prompt (vl-catch-all-error-message err))
        pth
    )
)


; Save xref back to disk to 0,0,0
(defun c:xrefout (/ is_acetutil_modula_exist objects_counter get_last_ent       ; local functions
                    adoc blocks folder ctr pbar_ctr AcDbEntity AcDbBlkTblRec    ; local variable
                    xname xrefname newxrefname ename ss xn xname)               ; local variables
  
  ; check if aceutil.arx is loaded?
 (defun is_acetutil_modula_exist ()
  (if (null (member "acetutil.arx" (arx)))
   (progn
    (setq *isAcetUtil* :vlax-false)
    (vlr-beep-reaction)
    (prompt "\nacetutil.arx modula is not loaded.")
   )
   (setq *isAcetUtil* :vlax-true)
  )
 ); is_acetutil_modula_exist
  
  
 ; return cumulate number of objects in xrefs
 (defun objects_counter (/ counter AcDbBlkTblRec)
  (setq counter -1)
  (vlax-for AcDbBlkTblRec blocks
   (if (and
         (eq (vla-get-isXref AcDbBlkTblRec) :vlax-true)
         ; make sure it is attached
         (ssget "_x" (list '(0 . "insert") (cons '2 (vla-get-name AcDbBlkTblRec))))
       )
    (setq counter (+ counter (vla-get-count AcDbBlkTblRec)))
   )  
  ); vlax-for
   
  counter
 ); objects_counter

  
 ; make sure last entity is exist
 ; even if drawing is empty
 (defun get_last_entity ()
  (command "._point" "0,0,0")
  (entlast)
 ); get_last_entity
   
  
 : Here start c:xrefout
 (setq adoc (vla-get-activedocument (vlax-get-acad-object)))
 (vla-startundomark adoc)
  
 (setq blocks (vla-get-blocks adoc))
  
 (setvar "cmdecho" 0)
 (setvar "expert"  5)
 
 (if (setq folder (LM:browseforfolder "Select a folder" (getvar "dwgprefix") 0))
  (progn 
   (is_acetutil_modula_exist) 
   (setq ctr (objects_counter))
   
   ; init progress meter
   (if (eq *isAcetUtil* :vlax-true)
    (progn
     ; progress bar init requires bigger value 
     (acet-ui-progress-init "Processing" ctr)
     (setq pbar_ctr -1) ; progress bar counter
    ); progn
   ); if    

   (vlax-for AcDbEntity (vla-get-modelspace adoc)
    (if (and
         (eq (vla-get-objectname AcDbEntity) "AcDbBlockReference")
         (not (wcmatch (setq xname (vla-get-name AcDbEntity)) "`*U*"))  ; not anonymous block
         (null (member (strcase xname) lst))                            ; not processed yet
         (setq AcDbBlkTblRec (vla-item blocks xname))                   ; get BTR
         (eq (vla-get-isXref AcDbBlkTblRec) :vlax-true)                 ; is it xref?
         (setq xrefname (vla-get-path AcDbBlkTblRec))
         (setq newxrefname (strcat folder "\\" (vl-filename-base xrefname) ".dwg"))
        )
     (progn
      (vlax-release-object AcDbBlkTblRec)
      (setq AcDbBlkTblRec nil)
       
      ; update progress meter 
      (if (eq *isAcetUtil* :vlax-true)
       (progn 
        (setq pbar_ctr (1+ pbar_ctr)) ; inc progress bar
        (acet-ui-progress-safe pbar_ctr)
       ); progn
      ); if
         
      (command "._undo" "_begin")
      (setq ss (ssadd) ename (get_last_entity))
       
      ; make sure the xref will be saved at X=1,Y=1,Z=1,R=0
      (vla-put-XScaleFactor AcDbEntity 1.0)
      (vla-put-YScaleFactor AcDbEntity 1.0)
      (vla-put-ZScaleFactor AcDbEntity 1.0)
      (vla-put-rotation     AcDbEntity 0.0)
           
      (command "._xref" "_bind" xname)
      (command "._explode" (vlax-vla-object->ename AcDbEntity))
      ; make sure all objects selected
      (command "._layer" "_thaw" "*" "_on" "*" "_unlock" "*" "") 
      
      ; collecting all objects
      (while (setq ename (entnext ename))
       (ssadd ename ss)  
      ); while

      ; write out wblock\xref
      (command "._wblock" (strcat folder "\\" xname) "" "0,0,0" "_si" ss)
      (command "._undo" "_end")
      (command "._u") ; restore actions
       
      (setq lst (cons (strcase xname) lst))
     ); progn
     ; else
     (if (and
          AcDbBlkTblRec
          (eq (type AcDbBlkTblRec) VLA-Object)
         )
      (progn
       (vlax-release-object AcDbBlkTblRec)
       (setq AcDbBlkTblRec nil)
      ); progn
     ); if
    ); if
            
    (vlax-release-object AcDbEntity)         
   ); vlax-for
    
   (if (eq *isAcetUtil* :vlax-true)
    (acet-ui-progress-done); close progress meter
   )
  ); progn
 ); if
  
 (setvar "expert"  0)
 (setvar "cmdecho" 1)
  
 (vlax-release-object blocks)
  
 (vla-endundomark adoc)
 (vlax-release-object adoc)

 (princ "\nDone.")
 (princ)
); c:xrefout

 

 

0 Likes

bsanada
Advocate
Advocate

This sounds very promising.  I will test it out when I get a chance. Thanks!

0 Likes

bsanada
Advocate
Advocate

I tested this on a file and received the following error "; error: bad argument type: fixnump: 0".  I did confirm all xrefs would bind without any issues before trying to run this routine.

 

Thanks - Brad

0 Likes

john.uhden
Mentor
Mentor

@bsanada ,

I am not offering any code, but here is the way I would attack the issue...

  1. Create a list of all the xrefs including their full paths.
  2. Make sure that SDI is 0.
  3. Set a bulletin board variable to, say, "Fixing insbases"
  4. Open each xref in the list, which will temporarily make each the active drawing.
  5. Check the bulletin board value to see if the conversion is in progress.
    If not, then quit that xref drawing; otherwise
  6. (setvar "insbase" '(0 0 0)
  7. Save and close the xref drawing.
    This will return focus to the host drawing and make it active again.
  8. Reload the xref.
  9. Repeat steps 4 though 8 for each xref.
  10. Set the bulletin board value to nil.

John F. Uhden

0 Likes

Moshe-A
Mentor
Mentor

@bsanada hi,

 

Sorry it did not work and i think i know why and gave a fix so try again 🙏

 

Moshe

 

0 Likes

Moshe-A
Mentor
Mentor

@john.uhden hi,

 

Brad do not wants just setting each xref insertion point to 0,0,0 but it wants the 0,0,0 of the master.dwg

for this he needs to attach each xref inside master, position it in right place and then wblock out as master 0,0,0

 

hope i am not wrong 🙏

 

Moshe

 

0 Likes

bsanada
Advocate
Advocate

No luck with the update routine.  I did some manual testing and ran into a few issues.  Below are the steps I took and the challenges.

  1. Open the master drawing and bound the xrefs.
  2. Used Lee Macs CBPR command to reset insertion points to 0,0.
    1. Issue - You have to run the command on each xref individually, it doesn't seem to have an option to process all the blocks at once.  I expect the complication would be not processing nested blocks.
    2. Issue - We do have some xrefs that are rotated and this routing does not reset the rotation to 0.  Perhaps this routine could be updated to reset rotation to 0 as well.
    3. Issue - There are a handful of exceptions where the same xref is inserted multiple times in different locations.  This will likely complicate things in any solution.  Perhaps this is what is causing the XREFOUT routine to crash.
    4. It is a bit painful trying to sort through which blocks you have processed and which ones still need it.
  3. Wblocked out the previously bound xrefs.
    1. The xrefs have a lot of nested blocks so it takes some effort sorting through the list to find the correct block to export.
  4. Erased all blocks and reattached the nested blocks with 0,0,0 insertion.
    1. This worked well other than the ones that were rotated.

Question - Are there options for only selecting top level blocks and not nested blocks?  It seems like this function would be required in order to run the CBRP command globally and also for an option to automatically Wblock the files out without processing all the nested block (I have a routine to do this but it does include the nested blocks).

 

Thanks,
Brad

0 Likes

Moshe-A
Mentor
Mentor

@bsanada ,

 

if you want to solve this, this is the time to post some sample files cause i'm testing it on my simple files and it works smoothly.

as i said earlier, xrefout does set the attached xref to 1x1 and rotation angle to 0 before exploding to make sure the xref

is in it's origin state before attaching it.

 

Moshe

 

 

 

0 Likes

bsanada
Advocate
Advocate

Let me see if I can modify the drawing to replicate the issue without sending confidential information.

0 Likes

bsanada
Advocate
Advocate

Here are the sample files I am trying to work with. 00-For Testing RN-XGG-06_Peeling-3D-EQ.dwg is the master file pulling the xrefs together.

 

Thanks,
Brad

0 Likes