TheSwamp
Code Red => AutoLISP (Vanilla / Visual) => Topic started 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
-
Could you share a little more info, Ron?
-
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?
(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
-
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.
-
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?
-
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
(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)
)
-
The one Ron posted worked on my computer just fine, but I only changed one xref.
-
Daron,
Thanks for the comments. This is what I tried but it does not rename?
(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
-
(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.
-
This seems to work :) and it's much faster.
(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)
)
-
Ron, does this do anything to speed it up a bit?
(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.
-
Good to see the entmod finally submitted to your will.
-
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
-
That's huge. Is that also with how I broke it down?
-
Daron,
This was your code:
< Elapsed time: 118.484 seconds. >
-
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.
-
Daron,
Thanks for taking an interest :)
-
No problem.
-
Does this do anything for your speed?
(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)
)
-
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
-
Cool.
I'll have some time tomorrow afternoon if you don't figure it out by then.
-
Ron,
Does the vla-put-name version have the same problem?
-
Ron,
Does the vla-put-name version have the same problem?
It does not....but it's rrreeeeaaaalllly slow?
-
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!
-
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.
-
You have not figured this one out yet CAB? :-P I'm stumped :?