TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: ronjonp on May 12, 2008, 03:40:54 PM

Title: entmod name of xref block definition (2 .
Post by: ronjonp on May 12, 2008, 03:40:54 PM
I can't seem to get it to work?

I was using (vla-put-name (vla-item blkcol "nameofblock") "blabla") and it seemed to work fine...but was really slow on drawings that had many xrefs in them.

Thanks,

Ron
Title: Re: entmod name of xref block definition (2 .
Post by: daron on May 13, 2008, 11:04:35 AM
Could you share a little more info, Ron?
Title: Re: entmod name of xref block definition (2 .
Post by: ronjonp on May 13, 2008, 12:21:19 PM
Daron,

I had put this together a while back to match the xref name to the name of the file because we were getting many files where they had been renamed. I was thinking if I used entmod (not even sure if it would work) it might speed this process up in drawings with super huge amounts of block definitions.

I was trying to use entmod with substr and (entget (tblobjname "block" "xrname")) to do this but it does not seem to work?

Code: [Select]
(defun c:matchxrnametofilename (/ p pos)
  (vlax-map-collection
    (vla-get-blocks
      (vla-get-activedocument (vlax-get-acad-object))
    )
    '(lambda (x)
       (if (= (vla-get-isxref x) :vlax-true)
(progn
   (setq p (strcase (vla-get-path x) T))
   (if (setq pos (vl-string-position 92 p 0 t))
     (setq p (vl-filename-base (substr p (+ 2 pos))))
     (setq p (vl-filename-base p))
   )
   (vl-catch-all-error-p
     (vl-catch-all-apply
       'vla-put-name
       (list x (vl-filename-base p))
     )
   )
)
       )
     )
  )
  (princ)
)

Thanks,

Ron
Title: Re: entmod name of xref block definition (2 .
Post by: daron on May 14, 2008, 09:13:39 AM
Not sure if this will help or do anything to help speed things up, but the first thing that strikes me is your call to (vla-get-activedocuments and vlax-get-acad-objects). Your code looks nice, but you leave the object in the collection and the more you loop through it, the more object calls you create, thus degrading your performance. See if using (vlax-release-object obj) will help speed things up a bit.
Title: Re: entmod name of xref block definition (2 .
Post by: daron on May 14, 2008, 09:31:16 AM
Hmm. I've tested it on one block and I can't see that it would help to do as suggested above, unless you are calling it on several drawings and it degrades over time. Without a complete rewrite, I don't see entmod working. I could be wrong, though. What have you tried with it?
Title: Re: entmod name of xref block definition (2 .
Post by: GDF on May 14, 2008, 09:53:55 AM
Ron

Same problem here with mismatched xref names. I for one, would like to see your routine work. The one I have below is klunky.


Gary

Code: [Select]
(defun Basename  (fname)
  (While (WCmatch fname "*[:/\\]*") (Setq fname (Substr fname 2)))
  (While (WCmatch fname "*`.*")
    (Setq fname (Substr fname 1 (1- (Strlen fname)))))
  fname)
;;;(Basename (getvar "dwgname"))

(defun C:XNAM (/ blkent flag oldname newname)
  (setvar "cmdecho" 0)
  (setq flag T)
  (while (setq blkent (tblnext "block" flag)) 
    (setq flag nil)   
    (if
      (and (= (logand (cdr (assoc 70 blkent)) 4) 4)
   (/= (strcase
(setq newname (Basename (cdr (assoc 1 blkent))))
       )
   )
   (strcase (setq oldname (cdr (assoc 2 blkent))))
      )     
      (command "rename" "block" oldname newname)
    )
  )
  (princ)
)
Title: Re: entmod name of xref block definition (2 .
Post by: daron on May 14, 2008, 10:12:35 AM
The one Ron posted worked on my computer just fine, but I only changed one xref.
Title: Re: entmod name of xref block definition (2 .
Post by: ronjonp on May 14, 2008, 10:24:18 AM
Daron,

Thanks for the comments. This is what I tried but it does not rename?

Code: [Select]
(defun c:matchxrnametofilename (/ b blk n p pos xr xrlist)
  (while (setq b (tblnext "block" (not b)))
    (and
      (assoc 1 b)
      (setq xrlist (cons b xrlist))
    )
  )
  (if xrlist
    (foreach xr xrlist
      (setq blk (entget (tblobjname "block" (cdr (assoc 2 xr))))
    p (strcase (cdr (assoc 1 blk)) t)
      )
      (if (setq pos (vl-string-position 92 p 0 t))
(setq p (vl-filename-base (substr p (+ 2 pos))))
(setq p (vl-filename-base p))
      )
      (entmod (subst (cons 2 p) (assoc 2 blk) blk))
    )
  )
  (princ)
)

Gary,

That code above does work and I've been using it for a couple of years...the issue I recently had was it was slow with a particular drawing that had many (15000+) block definitions.

Thanks,

Ron
Title: Re: entmod name of xref block definition (2 .
Post by: daron on May 14, 2008, 10:27:35 AM
Quote
(15000+) block definitions.
??? That would definitely cause a slow down. I'll look into this some more. There's got to be a way to remove the *wheat from the chaff before executing the renaming different than how you are.


*native blocks from xrefs.
Title: Re: entmod name of xref block definition (2 .
Post by: ronjonp on May 14, 2008, 10:44:31 AM
This seems to work :) and it's much faster.

Code: [Select]
(defun c:matchxrnametofilename (/ b blk p xrlist)
  (while (setq b (tblnext "block" (not b)))
    (and
      (assoc 1 b)
      (setq xrlist (cons (cdr (assoc 2 b)) xrlist))
    )
  )
  (if xrlist
    (foreach xr xrlist
      (setq blk (tblobjname "block" xr)
    p (strcase (cdr (assoc 1 (entget blk))) t)
    blk (entget (cdr (assoc 330 (entget blk))))
      )
      (entmod
(subst (cons 2 (vl-filename-base p)) (assoc 2 blk) blk)
      )
    )
  )
  (princ)
)
Title: Re: entmod name of xref block definition (2 .
Post by: daron on May 14, 2008, 10:46:25 AM
Ron, does this do anything to speed it up a bit?
Code: [Select]
(defun c:matchxrnametofilename (/ *acad *dwg* blocks xrefs names)
   (setq *acad (vlax-get-acad-object)
*dwg* (vla-get-activedocument *acad)
blocks (vla-get-blocks *dwg*)
   )
   (vlax-for
i blocks
      (if (= (vla-get-isxref i) :vlax-true)
(setq xrefs (append xrefs (list i)))
      )
   )
   (setq names (mapcar
  '(lambda (x / p pos)
      (setq p (vla-get-path x))
      (if (setq pos (vl-string-position 92 p 0 t))
(setq p (vl-filename-base (substr p (+ 2 pos))))
(setq p (vl-filename-base p))
      )
   )
  xrefs
       )
   )
   (mapcar
      '(lambda (x y)
  (vl-catch-all-error-p
     (vl-catch-all-apply
'vla-put-name
(list x (vl-filename-base y))
     )
  )
       )
      xrefs
      names
   )
   (mapcar 'vlax-release-object (list blocks *dwg* *acad))
   (princ)
)

or is it slower?

I know the two mapcars could be combined, but I wanted to see if it would help to make autocad to one process at a time. Also, I took out vlax-map-collection. I'm not sure if that will disable the function entirely, but if it does, you can probably replace it. Either way, test it how it is or combine the mapcars, but only after figuring out if you need the map-collection. If I understand it correctly, the map-collection is just an activeX mapcar, so my hope is that the mapcars should be fine. Either way, let us know.
Title: Re: entmod name of xref block definition (2 .
Post by: daron on May 14, 2008, 10:48:04 AM
Good to see the entmod finally submitted to your will.
Title: Re: entmod name of xref block definition (2 .
Post by: ronjonp on May 14, 2008, 11:20:48 AM
FWIW...here's the difference in speed between the two on my drawing with 18500 block definitions:

 < Elapsed time: 37.672 seconds. > vla
 < Elapsed time: 2.828 seconds. > entmod

 :-o
Title: Re: entmod name of xref block definition (2 .
Post by: daron on May 14, 2008, 12:09:33 PM
That's huge. Is that also with how I broke it down?
Title: Re: entmod name of xref block definition (2 .
Post by: ronjonp on May 14, 2008, 12:25:11 PM
Daron,

This was your code:

< Elapsed time: 118.484 seconds. >
Title: Re: entmod name of xref block definition (2 .
Post by: daron on May 14, 2008, 01:05:40 PM
Wow. Even worse. I would've thought breaking it up would've sped it up some. Sorry to put you through that. Go native lisp.
Title: Re: entmod name of xref block definition (2 .
Post by: ronjonp on May 14, 2008, 01:16:17 PM
Daron,

Thanks for taking an interest :)
Title: Re: entmod name of xref block definition (2 .
Post by: daron on May 14, 2008, 03:09:13 PM
No problem.
Title: Re: entmod name of xref block definition (2 .
Post by: CAB on May 14, 2008, 09:36:49 PM
Does this do anything for your speed?
Code: [Select]
(defun c:matchxrnametofilename (/ blk path elst xname bname)
  (while (setq blk (tblnext "block" (not blk)))
    (and
      (setq path (cdr (assoc 1 blk))) ; has a path
      (setq xname (strcase (vl-filename-base path) t))
      (setq elst (entget (tblobjname "block" (setq bname (cdr(assoc 2 blk))))))
      (setq elst (entget (cdr (assoc 330 elst))))
      (/= xname (strcase bname t))
      (entmod (subst (cons 2 xname) (cons 2 bname) elst))
    )
  )
  (princ)
)
Title: Re: entmod name of xref block definition (2 .
Post by: ronjonp on May 14, 2008, 11:14:43 PM
Even faster CAB :) < Elapsed time: 1.547 seconds. >

I've run into another issue....after running this code, XOPEN does not recognize the xrefs selected ("object selected is not an xref")...it's almost like they become unresolved?

Ron
Title: Re: entmod name of xref block definition (2 .
Post by: CAB on May 14, 2008, 11:30:00 PM
Cool.

I'll have some time tomorrow afternoon if you don't figure it out by then.
Title: Re: entmod name of xref block definition (2 .
Post by: CAB on May 15, 2008, 02:27:23 PM
Ron,
Does the vla-put-name version have the same problem?
Title: Re: entmod name of xref block definition (2 .
Post by: ronjonp on May 15, 2008, 02:57:48 PM
Ron,
Does the vla-put-name version have the same problem?

It does not....but it's rrreeeeaaaalllly slow?
Title: Re: entmod name of xref block definition (2 .
Post by: CAB on May 15, 2008, 03:02:23 PM
Yea, just wanted to verify that it was the entmod version that had the problem.
Must be something else that needs to be renamed as well!
Title: Re: entmod name of xref block definition (2 .
Post by: ronjonp on May 15, 2008, 03:09:31 PM
The strange thing is it will unresolve the xref even if the entmod is not changing anything using my code (name already matches)? You can see the problem right away when using CLASSICXREF...the XREF palette does not refresh the changes.
Title: Re: entmod name of xref block definition (2 .
Post by: ronjonp on May 16, 2008, 09:49:28 AM
You have not figured this one out yet CAB? :-P I'm stumped  :?