Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

how to change the insertpoint of a block,and keep the insert objects's place

203 views
Skip to first unread message

dream0001

unread,
Oct 4, 2004, 12:19:35 PM10/4/04
to
how to change the insertpoint of a block,and at the same time
let the "insert" object of the block keep them place (not to be move ).
sorry for my poor english

Rudy Tovar

unread,
Oct 4, 2004, 1:58:12 PM10/4/04
to
Change the "INSBASE" point variable.

--
MASi
Copyright 2004 by Cadentity
www.Cadentity.com


"dream0001" <nos...@address.withheld> wrote in message
news:29750813.109690680...@jiveforum1.autodesk.com...

Doug Broad

unread,
Oct 4, 2004, 1:55:28 PM10/4/04
to
Suggestion:

Make a new block with a different name and a
different insertion point if you don't want the existing
inserts to move.

Why are you moving the insertion points after the fact?

Regards,
Doug


"dream0001" <nos...@address.withheld> wrote in message
news:29750813.109690680...@jiveforum1.autodesk.com...

Casey Roberts

unread,
Oct 4, 2004, 1:56:57 PM10/4/04
to
Refedit?
(Redefine the block)

"dream0001" <nos...@address.withheld> wrote in message
news:29750813.109690680...@jiveforum1.autodesk.com...

dblaha

unread,
Oct 4, 2004, 2:12:06 PM10/4/04
to
If you want to change the insertion point of the block definition but keep the gemeomtry in the same location, not only will you have to redefine the block, you will also have to move all of the existing insertions of the block the same distance and direction that you moved the basepoint.

Dave

Douglas Barr

unread,
Oct 4, 2004, 2:32:24 PM10/4/04
to
He could always redefine the block with the original (renamed) block within
it, properly placed at its new insertion point. Once reinserted, the blocks
could all be exploded, the new blockname purged, the temporary blockname
renamed to its original name, and he'll have what he wants.

Sounds confusing, I bet, but it's simple. I've done so many times when
arraying blocks of chain links around a pline, which were at the wrong
insert points.


"dblaha" <nos...@address.withheld> wrote in message
news:27878136.109691355...@jiveforum2.autodesk.com...

Kent Cooper, AIA

unread,
Oct 4, 2004, 3:13:49 PM10/4/04
to
I don't think you can change the insertion base point of a block with
Refedit, except by just picking everything in it, and moving it all to the
desired position relative to the insertion point of the instance that you're
using to Refedit the thing. But I don't think you can tell where that is
from within Refedit, either.

Imagine, for example, that someone defined the block, using the "convert to
block" option, but didn't think about the base point, and left it at the
default 0,0,0 in the dialog box. They wouldn't even know they'd done it
unless they went to insert another one.

You'd have to determine the insertion point of a particular instance and
save or remember it, then in Refedit, move everything from the point you
want to be the base point to that insertion point. But you'd have to move
all insertions of that block the same distance back in the opposite
direction, after you were done.

Kent Cooper, AIA


"Casey Roberts" wrote...

Kent Cooper, AIA

unread,
Oct 4, 2004, 3:22:19 PM10/4/04
to
Changing "INSBASE" affects only the insertion of the drawing you're changing
it in, when it's inserted or xref'd in other drawings. It won't affect any
blocks inserted in the current drawing. IF the block in question is from an
external drawing file, you can change INSBASE in that drawing, but that by
itself won't update the insertion base point of the block definition in
another drawing that it's inserted in, only drawings in which it's xref'd.
For regular insertions in other drawings, you'd still have to update the
block definition from the external drawing with -INSERT
<blockname>=<drawingname>. And you'd still have to move all the insertions
to compensate for the changed base point.

Kent Cooper, AIA


"Rudy Tovar" wrote...
> Change the "INSBASE" point variable

Kent Cooper, AIA

unread,
Oct 4, 2004, 4:10:45 PM10/4/04
to
I'm not sure I'm understanding exactly what you're suggesting, but let me
think through a sequence of events here....

You have a block named WIDGET, with its insertion base point in the wrong
place. And let's assume you have this inserted more than once in the
drawing.

You rename it WIDGETOLD, and I'm assuming that's what you mean by "the
temporary blockname" because you talk about renaming to its original name
later. You now have several insertions of WIDGETOLD in the drawing, and no
WIDGET definition any more.

You create a new block named WIDGET (which I'm assuming is what you mean by
"the new blockname"), with the insertion point where you want it, and
containing an insertion of WIDGETOLD [that is, "with the original (renamed)
block within it"]. So far, so good.

I don't quite get what you mean by "Once reinserted....." If you let the
Block command do that with "convert to block", it doesn't have any effect on
all the WIDGETOLD locations elsewhere. Do you insert a WIDGET at every
WIDGETOLD location, matching the scales and rotation for each? Do you erase
the WIDGETOLD's?

I'm assuming for now that you don't do that. If "the blocks could all be
exploded", do you mean all the WIDGETOLD blocks throughout the drawing?
Everything would then be where you want it, but it wouldn't be in blocks any
more -- maybe that's acceptable. If, because you talk later about purging
the new blockname, you mean to explode the new WIDGET block, I can't see
what that does for you. If you do, you're left with the WIDGETOLD insertion
which was the contents of that exploded block, complete with its original
insertion point, not where you want it. Then you purge WIDGET out and
rename WIDGETOLD to WIDGET again? I don't think that fixes anything.

I think what you want to do is REFEDIT an instance of the new WIDGET block,
and within that, explode the WIDGETOLD block so its components become part
of the new WIDGET definition on their own, rather than as parts of a nested
block. That at least would mean that any future insertions of WIDGET would
work as you want, with the appropriate base point. But you'd still have the
old exploded WIDGETOLD's not being blocks. Or you could leave them, not
exploded, so they'd still be blocks, but with the WIDGETOLD definition
(which you then couldn't purge out of the drawing), and incorrect basepoint.

It seems to me the approach is fine if there's only one insertion of the
block when you do it, but I'm not seeing how it works when there are
multiples. And if there's only one, then I think simply exploding it and
redefining it would be simpler. What am I missing? Could you go through
the sequence in more detail?

Kent Cooper, AIA


"Douglas Barr" wrote...

Tony Tanzillo

unread,
Oct 4, 2004, 4:39:46 PM10/4/04
to
"dblaha" <nos...@address.withheld> wrote in message

> you will also have to move all of the existing insertions of the


> block the same distance and direction that you moved the basepoint.

> That would be the same distance and the opposite direction.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2004/2005
http://www.acadxtabs.com


Douglas Barr

unread,
Oct 4, 2004, 5:23:09 PM10/4/04
to
Hi Kent -

Drawing X has many insertions of block A, located at logical points which I
don't want to move. Instead, I would like the base point of all blocks A to
be changed.

a) Copy block A to the clipboard.
b) Paste it into a new blank drawing.

In the new drawing:
c) Rename block A >> B.
d) Redefine block B to have the proper base point. Use whatever method you
choose. (I don't use refedit)
e) Save this drawing as A, in same location as the other drawing.

Go back to original drawing X.
f) Insert A=.
g) Use filter, or whatever method desired, to select all instances of block
A.
h) Explode all blocks A.

Now block B resides at the right points, with the right base.
i) Purge blockname A.
j) Rename Blockname B >> A.

Easy as abcdefghij!
I have a simple routine that does such things without using refedit.
-doug

ps, I started to show you a visual. It ended up being all text.


"Kent Cooper, AIA" <kco...@schwamarchitects.com> wrote in message
news:4161ae2e$1_2@newsprd01...

dblaha

unread,
Oct 5, 2004, 7:56:15 AM10/5/04
to
If you refedit, this is true. But if you change the block outside of the drawing and then redefine it, the opposite (move it the same distance and direction) is true.

I may be crossing my i's and dotting my t's here, but if you change the insertion point by modifying the block outside the drawing and then bringing it in again, redefining the existing block definition and insertions in the drawing in the process (such as by right-clicking on the block's file in Design Center, dragging it into the drawing, choosing 'Insert as block...', clicking OK in the dialog and then selecting the option to 're-define' it), you would then need to move the insertions the same distance and direction that you moved the insertion point in the block.
But if you changed the insertion point by refediting the block within the drawing (by moving all the geometry of the block during the refedit), you would then need to move the block insertions that same distance but in the opposite direction.

At least that's what my coffee says...
Dave

Kent Cooper, AIA

unread,
Oct 5, 2004, 8:44:05 AM10/5/04
to
I think steps a) and b) have to be done in a particular way to make this
work. EITHER: you'd need to use COPYBASE in drawing X and use the insertion
point of block A as the base, and then paste it into the new blank drawing
at an insertion point of 0,0 (which will be the default INSBASE value in the
new drawing). OR: you could copy and paste by any means you want, as long
as you change INSBASE in the new drawing to be at the (old) insertion point
of block A, before you redefine that block.

Kent Cooper, AIA


"Douglas Barr" wrote...

GaryDF

unread,
Oct 5, 2004, 9:33:44 AM10/5/04
to
Now this is one of the sweetest routines I seen....nice one. There have been
times I could have really used this in the past. Thanks for sharing it.

Gary

"Joe Burke" <job...@hawaii.rr.com> wrote in message news:41629d78_3@newsprd01...
> Huw,
>
> Try this with your example drawing.
>
> The caveat here is the block you select at the first and second prompts must
not be
> rotated or scaled. IOW, insert an instance of the block that's not rotated or
scaled.
> Use that instance at the "Select block: " and "Select new insertion point: "
prompts.
>
> I think you'll find it does what you want, regardless of the rotation and/or
scaling
> of other instances of the block.
>
> Joe Burke
>
> ;; JB 10/4/2004
> ;; function: Move Block Insertion Point
> ;; returns T and regens if successful
> ;; designed for model space blocks
> (defun c:MoveBlockIP (/ doc blocks mspace blkref oldpt newpt
> blkdef nm vec ang scl modvec RotatePts ScalePts)
> (defun RotatePts (plst bp ang)
> (if (atom (car plst))
> (setq plst (list plst)))
> (mapcar '(lambda (p)
> (polar bp (+ (angle bp p) ang) (distance bp p))) plst)
> ) ;end
>
> (defun ScalePts (plst bp scale / veclst sclst res)
> (if (atom (car plst))
> (setq plst (list plst)))
> (setq veclst (mapcar '(lambda (p) (mapcar '- p bp)) plst))
> (setq sclst (mapcar '(lambda (v)
> (mapcar '(lambda (x) (* scale x)) v)) veclst))
> (mapcar '(lambda (v) (mapcar '+ v bp)) sclst)
> ) ;end
>
> (and
> (setq doc (vla-get-activedocument (vlax-get-acad-object)))
> (setq blocks (vla-get-blocks doc))
> (setq mspace (vla-get-ModelSpace doc))
> (setq blkref (vlax-ename->vla-object
> (car (entsel "\nSelect block: "))))
> (setq oldpt (vlax-get blkref 'InsertionPoint))
> (setq newpt (trans (getpoint "\nSelect new insertion point: ") 1 0))
> (setq nm (vlax-get blkref 'Name))
> (setq blkdef (vla-item blocks nm))
> (setq vec (mapcar '- oldpt newpt))
> ;; move objects in the block definition
> (vlax-for x blkdef
> (not (vlax-invoke x 'Move '(0.0 0.0 0.0) vec))
> )
> ;; move block references to proper location
> ;; with attention to scale and rotation
> ;; if scale applies, assume the block is uniformly scaled
> (vlax-for x mspace
> (if
> (and
> (equal "AcDbBlockReference" (vlax-get x 'ObjectName))
> (equal nm (vlax-get x 'Name))
> )
> (progn
> (setq ang (vlax-get x 'Rotation))
> (setq scl (vlax-get x 'XScaleFactor))
> (setq modvec (ScalePts vec '(0.0 0.0 0.0) scl))
> (setq modvec (RotatePts modvec '(0.0 0.0 0.0) ang))
> (not (vlax-invoke x 'Move (car modvec) '(0.0 0.0 0.0)))
> )
> T
> )
> ) ;for
> (not (vla-regen doc acActiveViewport))
> ) ;and
> ) ;end
>
>
>
>
>
> "Huw" <hg...@removethisbit.unimelb.edu.au.andremovethisbittoo> wrote in message
> news:41623432_2@newsprd01...
> I just tried this and can't get it to work.
>
> I have a drawing full of gas valve blocks, all with different rotations. The
block's
> insertion point is one corner of the valve symbol, whereas I need it to be the
> centre, on the line of the pipe.
>
> I think I'm going wrong at step d). I've tried every method I can think of, and
they
> all have the same effect at step f) i.e. the block jumps so that its centre is
now
> where its corner was, and it no longer sits on the line of the pipe.
>
> How do you redefine the base point?
>
> Sample attached.
>
> Many thanks for any help,
> Huw
>
>


petersciganek

unread,
Oct 5, 2004, 10:03:34 AM10/5/04
to
Here's what I have - sorry for the stack of functions but it's easier to post this than to push these into the original command. I just hope that all of the required functions are included...

bnpt should reset the block definition's insertion point regardless of the selected inserts scale/rotation and will move all inserts (including nested) in the drawing back to original position.


(defun c:bnpt ( / en p1 p2 a d bn)
(cond
((not (setq en (f:entselx "INSERT" "\nSelect Insert to reposition insertion point: "))))
((not (setq p2 (getpoint (setq p1 (f:assoc 10 (setq en (car en)))) "\nNew position for insertion point: "))))
(T
(setq p2 (f:insert_trans en p2)
a (angle p2 p1)
d (distance p2 p1)
p1 (f:ptx p1)
p2 (f:ptx p2)
bn (f:assoc 2 en)
);setq
(vlax-map-Collection (f:vltblobjname 'Blocks bn nil)
'(lambda (e)
(vla-Move e p2 p1)
)
)
(f:map_all:filter (list (cons 0 "INSERT")(cons 2 bn))
(lambda (e)
(vla-Move e (f:ptx (f:insert_polar e a d)) (vla-get-InsertionPoint e))
)
)
)
)
(princ));defun

(setq #000 (list 0.0 0.0 0.0))
(setq #000x (vlax-3d-point (list 0.0 0.0 0.0)))

(defun f:entselx (typ prm / e ini)
(if (listp prm)(setq ini (cadr prm) prm (car prm)))
(setvar "ERRNO" 0)
(while (and (not e) (/= (getvar "ERRNO") 52))
(if ini (initget ini))
(setq e (entsel prm))
(cond
((= (type e) 'STR))
((/= (f:assoc 0 (car e)) typ)
(setq e nil)
)
);cond
)
e)

(defun f:en (en)
(if (/= (type en) 'ENAME)
(vlax-vla-object->ename en)
en
)
)

(defun f:enx (en)
(if (= (type en) 'ENAME)
(vlax-ename->vla-object en)
en
)
)


(defun f:assoc (at lst / ret)
(cond
((= (type lst) 'ENAME)(setq lst (entget lst)))
((= (type lst) 'VLA-OBJECT)(setq lst (entget (f:en lst))))
)
(if (and (f:assocp lst)
(setq ret (assoc at lst))
);and
(cdr ret)
);if
)

(defun f:assocp (lst)
(and
lst
(listp lst)
(not (vl-some '(lambda (at) (not (vl-consp at))) lst))
)
)

(defun f:insert_trans (en pt / p)
(setq p (f:assoc 10 en)
pt (polar #000 (- (angle p pt) (f:assoc 50 en)) (distance p pt))
pt (list (/ (car pt) (f:assoc 41 en)) (/ (cadr pt) (f:assoc 42 en)) (/ (caddr pt) (f:assoc 43 en)))
);setq
(polar p (angle #000 pt) (distance #000 pt))
)

(defun f:insert_polar (en a d / pt)
(setq pt (polar #000 a d)
pt (list (* (f:assoc 41 en) (car pt)) (* (f:assoc 42 en) (cadr pt)) (* (f:assoc 43 en) (caddr pt)))
)
(polar (f:assoc 10 en) (+ (angle #000 pt) (f:assoc 50 en)) (distance #000 pt))
)

(defun f:ptx (pt)
(if (= (type pt) 'variant)
pt
(vlax-3d-point pt)
)
)

(defun f:vltblobjname (tbl nam doc)
(if (not doc)(setq doc (fx:doc)))
(if (and
(= (type doc) 'VLA-OBJECT)
(vlax-property-available-p doc tbl)
);and
(f:vlerr 'vla-Item (list (vlax-get-property doc tbl) nam) nil)
)
)

(defun fx:acad ()
(setq *AutoCAD-application-object*
(cond
(*AutoCAD-application-object*)
((vlax-get-acad-object))
(T nil)
)
)
)

(defun fx:doc ()
(setq *active-document*
(cond
(*active-document*)
((vla-get-ActiveDocument (fx:acad)))
(T nil)
)
)
)

(defun f:vlerr (fun lst tag / ret)


(if (vl-catch-all-error-p (setq ret (vl-catch-all-apply fun lst)))
(if tag
(progn (strcat "\n" (vl-catch-all-error-message ret)) nil)
nil
)
(if (not ret) (setq ret T) ret)
)
(if (= (type ret) 'VL-CATCH-ALL-APPLY-ERROR) (setq ret nil))


ret)

(defun f:map_all:filter (filt :fun / ret)
(if (setq ss (ssget "_X" filt))
(progn
(mapcar (function (lambda (e)
(setq ret (append ret (list (:fun (f:enx e)))))
))
(f:sstolst ss)
);mapcar
);progn
);if

(vlax-map-Collection (vla-get-Blocks (fx:doc))
(function (lambda (b)
(if (and
(= (vla-get-IsLayout b) :vlax-false)
(= (vla-get-IsXRef b) :vlax-false)
(not (wcmatch (vla-get-Name b) "*|*"))
);and
(vlax-map-Collection b
(function (lambda (e)
(if (f:apply_ssfilter e filt)
(setq ret (append ret (list (:fun e))))
);if
))
);map
);if
));function
);map
ret
)

(defun f:sstolst (ss / lst i l)
(if ss (progn
(setq l (sslength ss) i 0);setq
(while (< i l)
(setq lst (append lst (list (ssname ss i))) i (1+ i))
);while
));progn if
lst
)

(defun f:apply_ssfilter (en lst / ret val typ)
(setq ret T en (f:en en))
(mapcar '(lambda (at)
(if ret
(cond
((= (car at) 0)
(if (not (wcmatch (setq typ (strcase (f:assoc 0 en))) (strcase (cdr at))))
(setq ret nil)
)
);0
((member (car at) (list 8 2));layer or blockname
(if (not (and (= (car at) 2) (/= typ "INSERT")))
(if (not (wcmatch (strcase (f:assoc (car at) en)) (strcase (cdr at))))
(setq ret nil)
)
)
);layer blockname
((= (car at) -3)
(if (not (assoc -3 (entget en (cadr at))))
(setq ret nil)
)
);xdata appid - this will not work in a dbx dwg
((setq val (f:assoc (car at) en))
(setq ret (= val (cdr at)))
)
(T (setq ret nil))
);cond
);if
)
lst
)
ret
)


Peter

Douglas Barr

unread,
Oct 5, 2004, 10:08:35 AM10/5/04
to
It sounds to me that your new block doesn't have a nested block within it.
I'd try to explain it using some visuals, but all my wmf's grew the file to
150k.

Besides, it looks like Joe Burke has provided something to eliminate the
sweat.
-doug


Douglas Barr

unread,
Oct 5, 2004, 10:16:19 AM10/5/04
to
Hi Joe,
I just tried your routine on Huw's drawing.

When I set the new insert point at the center or the circle, it 'appears' to
be there, but when I zoom way in, it is on a point 'near' the center, but
not on it.

It does the same if I attempt to put it on an end point. Not a precise
location. Why? Or does it not misbehave when you do it?
-doug

Joe Burke

unread,
Oct 5, 2004, 10:34:01 AM10/5/04
to
Hi Doug,

I'm just guessing here.

Notice the location of objects in Huw's drawing. They are far away from 0,0. Maybe a
rounding error is creeping in?

I'll look into it tomorrow. Or maybe you can tell me if the problem you are seeing
goes away when the objects in Huw's drawing are moved close to 0,0?

Thanks
Joe Burke


"Douglas Barr" <dougatsweaterscapesdotcalm> wrote in message
news:4162acb9_2@newsprd01...

Joe Burke

unread,
Oct 5, 2004, 10:58:35 AM10/5/04
to
Thanks, Gary.

I hope it passes testing among the crew.

It isn't what I thought would work at first. Moving the block references
after-the-fact seems like a kludge. Not to mention, a bit code intensive.

Joe Burke

"GaryDF" <fow...@architettura-inc.com> wrote in message
news:4162a346$1_3@newsprd01...

Douglas Barr

unread,
Oct 5, 2004, 10:47:27 AM10/5/04
to
"Joe Burke" <job...@hawaii.rr.com> wrote in message
news:4162b0ed_1@newsprd01...

> Hi Doug,
>
> I'm just guessing here.
>
> Notice the location of objects in Huw's drawing. They are far away from
0,0. Maybe a
> rounding error is creeping in?
>
> I'll look into it tomorrow. Or maybe you can tell me if the problem you
are seeing
> goes away when the objects in Huw's drawing are moved close to 0,0?

I don't think that's the issue.
But to humor you, I moved his block so that its center was at world 0,0,0.
When I again used your routine, picking the center of his circle to be the
new insert point, it reconfigured the block with its insert not on center.

Here's how far off it is...
After setting "UCS" "E" one-of-the-blocks, the cicle's center IDs at:
X = -47.78480113 Y = -108.95377666 Z = 0.00000000

Rounding error? I dunno bout that.

Joe Burke

unread,
Oct 5, 2004, 11:54:00 AM10/5/04
to
Doug,

I'd like to hear what others report, before commenting on your point. Frankly, I'm
confused... which is nothing new.

Regards
Joe Burke

"Douglas Barr" <dougatsweaterscapesdotcalm> wrote in message

news:4162b405$1_1@newsprd01...

Jeff Mishler

unread,
Oct 5, 2004, 12:40:31 PM10/5/04
to
I just tried this out on HUW's drawing and one of mine. Provided the
directions are followed (use a block insert at 0 degrees rotation) I found
nothing wrong with it.....here's my ID dump:
Command: '_id Specify point: _cen of X = 3.21246107E+08 Y =
5.81521357E+09 Z = 0.00000000

Command: ID Specify point: _ins of X = 3.21246107E+08 Y =
5.81521357E+09 Z = 0.00000000

When I selected one of the blocks already in the drawing I could duplicate
the error.....but then I wouldn't be following directions...... ;-)
--
Jeff
check out www.cadvault.com


"Joe Burke" <job...@hawaii.rr.com> wrote in message

news:4162c3b3_1@newsprd01...

Douglas Barr

unread,
Oct 5, 2004, 1:15:55 PM10/5/04
to
"Joe Burke" <job...@hawaii.rr.com> wrote in message
news:4162c3b3_1@newsprd01...

> I'd like to hear what others report, before commenting on your point.
Frankly, I'm
> confused... which is nothing new.

I guess Jeff found the same problem in Huw's drawing.

Here's my solution to the original question - scales and rotations
of blocks remain the same, only the definition has changed.
-doug

;;; ReConfigureBlock
(defun c:rcb ()
(setvar "cmdecho" 0)
(princ "\nTouch block to reconfigure:")
(setq orig-name (cdr (assoc 2 (entget (car (entsel))))))
(princ "\nPoint to a blank place to work in:")
(setq workpoint (getpoint))
(command "-INSERT" orig-name workpoint "" "" "")
(command "explode" "L" "")
(princ "\nSelect new insertion point for block:")
(setq newpoint (getpoint))
(princ "\nRe-Select entities for block:")
(setq blockparts (ssget))
(cond
((not (tblsearch "block" "TEMP1"))(setq temp "TEMP1"))
((not (tblsearch "block" "TEMP2"))(setq temp "TEMP2"))
((not (tblsearch "block" "TEMP3"))(setq temp "TEMP3"))
)
(command "-block" temp newpoint blockparts "")
(command "-insert" temp newpoint "" "" "")
(command "-block" orig-name "Y" workpoint (entlast) "")
(setq orig-blocks (ssget "X" (list (cons 0 "INSERT")(cons 2 orig-name))))
(setq n 0)
(while (setq orig-block (ssname orig-blocks n))
(command "explode" orig-block)
(setq n (1+ n))
)
(command "-purge" "B" orig-name "N")
(command "rename" "B" temp orig-name)
(princ)
)


Huw

unread,
Oct 6, 2004, 1:39:23 AM10/6/04
to
Well, I tried all three routines posted...

Douglas' RCB worked, but moved all the blocks to layer 0 - a problem (for me) given that there can be valves on both High Pressure and Low Pressure layers. (I know, I didn't think to mention that before. Sorry)

Joe's MoveBlockIP moved the IP, but not to the picked location - the new location wasn't always repeatable either. If I used UNDO and tried again on the same block the new IP sometimes appeared in a different wrong place to the previous attempt. It seemed to be affected by middlebutton pans and zooms in between selecting the block and picking the desired new IP.

James' BlockSwap worked well, but did leave the sample new block to be deleted manually. There might have been a problem correctly selecting the old and new blocks had their geometry been identical, but my new block was smaller.

Please don't take any of this as criticism, it's all intended as useful feedback for you coders. Many thanks for all your interest, my problem is solved.

Huw

Huw

unread,
Oct 6, 2004, 1:48:46 AM10/6/04
to
> James' BlockSwap worked well, but did leave the sample new block to
> be deleted manually. There might have been a problem correctly
> selecting the old and new blocks had their geometry been identical,
> but my new block was smaller.

In fact it left both samples, but had resized the sample old block to match the new one and I didn't see it there underneath. That makes more sense and is obviously deliberate.

Douglas Barr

unread,
Oct 6, 2004, 8:14:03 AM10/6/04
to
"Huw" <hg...@removethisbit.unimelb.edu.au.andremovethisbittoo> wrote in
message news:4163850c_2@newsprd01...

> Well, I tried all three routines posted...

> Douglas' RCB worked, but moved all the blocks to layer 0 - a
> problem (for me) given that there can be valves on both High
> Pressure and Low Pressure layers. (I know, I didn't think to
> mention that before. Sorry)

My routine uses the standard 'explode' command. I attempted to instead use
the command 'xplode', asking the explosion to inherit properties, retaining
original layers for the entities within the block, but I can't get it to
utilize the command. Perhaps someone else knows how to get 'xplode' to work
within another lisp.
-doug

James Allen

unread,
Oct 6, 2004, 8:44:57 AM10/6/04
to
Actually, I forgot to add this line right before the regen line:

(vla-delete obj2)

I see no reason to keep the sample new block. Adding this line just before
the regen will clean it up.

Huw wrote:
>There might have been a problem correctly selecting the old and new blocks

had their geometry been identical,...

This had occurred to me. I chose to leave it to the user to use ctrl
(object cycling) if necessary while selecting. Of course if they are also
the same color, then even the cycling would be hard to use.

Thank you for the feedback. And you are very welcome.

James

Joe Burke

unread,
Oct 6, 2004, 8:45:46 AM10/6/04
to
Huw,

RE: "Joe's MoveBlockIP moved the IP, but not to the picked location". I suspect you
missed or forgot my instructions regarding the block used had to be not scaled or
rotated under the version I posted previously.

Whatever, here's a revised version which doesn't impose that restriction. You can
select a block regardless of scale and/or rotation. It's what I should have posted in
the first place. I just didn't have time to work out the details last night. There's
better error checking in this version. And the supporting functions are also revised.

Jeff,

If you have a chance, please test this one. TIA

Joe Burke

;; JB 10/5/2004 revised version 2
;; function: move a block's insertion point


;; designed for model space blocks
(defun c:MoveBlockIP (/ doc blocks mspace blkref oldpt newpt

blkdef nm refscl refang vec ang scl modvec RotatePt ScalePt)

(defun RotatePt (pt bp ang)
(polar bp (+ (angle bp pt) ang) (distance bp pt))
) ;end

(defun ScalePt (pt bp scale / vec scl)
(setq vec (mapcar '- pt bp))
(setq scl (mapcar '(lambda (x) (* x scale)) vec))
(mapcar '+ scl bp)
) ;end

(setq doc (vla-get-activedocument (vlax-get-acad-object))
blocks (vla-get-blocks doc)
mspace (vla-get-ModelSpace doc)
)

(while
(or
(not (setq blkref (car (entsel "\nSelect block: "))))
(not (setq blkref (vlax-ename->vla-object blkref)))
(not (equal "AcDbBlockReference" (vlax-get blkref 'ObjectName)))
(vlax-property-available-p blkref 'Path) ;exclude xrefs
)
(princ "\nMissed pick or wrong object type selected. ")
)

(setq nm (vlax-get blkref 'Name))
(setq blkdef (vla-item blocks nm))

;; assume uniform scaling
(setq refscl (vlax-get blkref 'XScaleFactor))
(setq refang (vlax-get blkref 'Rotation))


(setq oldpt (vlax-get blkref 'InsertionPoint))
(setq newpt (trans (getpoint "\nSelect new insertion point: ") 1 0))

(setq oldpt (ScalePt oldpt newpt (/ 1.0 refscl)))
(setq oldpt (RotatePt oldpt newpt (- refang)))


(setq vec (mapcar '- oldpt newpt))

;; move objects in the block definition
(vlax-for x blkdef

(vlax-invoke x 'Move '(0.0 0.0 0.0) vec)
)

;; move block references


(vlax-for x mspace
(if
(and
(equal "AcDbBlockReference" (vlax-get x 'ObjectName))
(equal nm (vlax-get x 'Name))
)
(progn
(setq ang (vlax-get x 'Rotation))

;; assume uniform scaling


(setq scl (vlax-get x 'XScaleFactor))

(setq modvec (ScalePt vec '(0.0 0.0 0.0) scl))
(setq modvec (RotatePt modvec '(0.0 0.0 0.0) ang))
(vlax-invoke x 'Move modvec '(0.0 0.0 0.0))
)
)
) ;for
(vla-regen doc acActiveViewport)
(princ)
) ;end


Joe Burke

unread,
Oct 6, 2004, 9:31:02 AM10/6/04
to
Hi James,

I looked at what you posted here. I haven't tried running it yet. Obviously there's
lot to digest in terms of what's going on.

One question for now. Did you develop all the MWE (I assume your company name)
functions on your own? Nothing implied. I'm just curious.

Regards
Joe Burke


"James Allen" <JamesA~AA~mwengrs~DD~com> wrote in message
news:41632e38_1@newsprd01...
> Here is something I have been working on for a while here that I believe
> also does the trick. I understand it's major overkill for the particular
> task at hand, but I figured I'd just post the whole thing in case others
> could use more of it.
>
> For anyone interested in trying it, my goal was to make it as general as
> possible, including 3D, but also to make it modular enough to be suitable
> for simpler tasks. For example, if you change the bit argument to
> MWE:TransformBlocks to 6 (as should be appropriate for this situation), then
> none of the 'modules' from MWE:GetSMatrix down are used at all. I have not
> yet made allowance for 'elevation' properties (e.g. in polylines) or block
> attributes but I would like to. And I am confident there is plenty of room
> for other improvement.
>
> Joe, if you're reading this:
> I came across your recent post with matrix transformations (@ptrans thread)
> and I like it. I am posting a response in that thread.
> --
> James Allen
> Malicoat-Winslow Engineers, P.C.
> Columbia, MO
>
>
>


Jeff Mishler

unread,
Oct 6, 2004, 1:09:48 PM10/6/04
to
"Joe Burke" <job...@hawaii.rr.com> wrote in message
news:4163e90c$1_2@newsprd01...

> Jeff,
>
> If you have a chance, please test this one. TIA
>
> Joe Burke
>
Joe, I tried this and it seems to work well. However, on a large drawing it
could take a long time to complete due to this:

(vlax-for x mspace
(if
(and
(equal "AcDbBlockReference" (vlax-get x 'ObjectName))
(equal nm (vlax-get x 'Name))
)

....blah
)

A filtered selection set would be MUCH faster and has the benefit of
modifying ALL inserted occurances, regardles of what space they are in.
[code]


;; JB 10/5/2004 revised version 2
;; function: move a block's insertion point
;; designed for model space blocks

;; modified 10/5/2004 by Jeff Mishler to accomodate All insertions,
;; regardless of space, and to only iterate a Selection Set.
(defun c:MBi (/ doc blocks mspace blkref oldpt newpt
blkdef nm refscl refang vec ang scl modvec RotatePt ScalePt ss)

;get selection set of blocks, added by JMM
(setq ss (active_ss_all (list '(0 . "INSERT") (cons 2 nm))))

;; move block references
(vlax-for x ss ;changed mspace to ss
;;; (if


;;; (and
;;; (equal "AcDbBlockReference" (vlax-get x 'ObjectName))
;;; (equal nm (vlax-get x 'Name))
;;; )
;;; (progn
(setq ang (vlax-get x 'Rotation))
;; assume uniform scaling
(setq scl (vlax-get x 'XScaleFactor))
(setq modvec (ScalePt vec '(0.0 0.0 0.0) scl))
(setq modvec (RotatePt modvec '(0.0 0.0 0.0) ang))
(vlax-invoke x 'Move modvec '(0.0 0.0 0.0))

(vla-update x);added JMM
;;; )
;;; )
) ;for
;(vla-regen doc acActiveViewport);commented JMM
(princ)
) ;end
[/code]

And the Active_ss_all routine I use to get an ActiveX slection set:
[code]
;;Selection set routine that allows filters that follow the standard (ssget)
filter rules.
;;by Jeff Mishler, December 2003
(defun active_ss_all (flist / code val ss)
(or *doc* (setq *doc* (vla-get-activedocument (vlax-get-acad-object))))
(vl-catch-all-apply 'vla-add
(list (vla-get-selectionsets *doc*) "activex_ss"))
(setq ss (vla-item (vla-get-selectionsets *doc*) "activex_ss"))
(vla-clear ss)
(if flist
(progn
(mapcar '(lambda (a)
(setq code (cons (car a) code))
(setq val (cons (cdr a) val))
)
flist
)
(setq code (vlax-safearray-fill
(vlax-make-safearray
vlax-vbinteger
(cons 0 (- (length code) 1))
)
code
)
val (vlax-safearray-fill
(vlax-make-safearray
vlax-vbvariant
(cons 0 (- (length val) 1))
)
val
)
)
(vlax-invoke-method ss 'select acSelectionSetAll nil nil code val)
)
(vla-select ss acSelectionSetAll )
)
(vla-highlight ss :vlax-true)
(if (> (vla-get-count ss) 0)
ss
nil
)
)
[/code]


James Allen

unread,
Oct 6, 2004, 1:58:40 PM10/6/04
to
Hi Joe.

Yes, MWE = company initials.

Did I develop them all? Yes. On my own? That I am more hesitant to claim.
But except for the matrix transpose line that I first noticed in your post
in the other thread, yes. And that line is a jewel IMHO

I am "self taught", but have had much help along the way, including much
from this newsgroup since I discovered it about two years ago. What I
posted I developed/wrote with no direct reference to other's code, except as
already noted. But I have no illusions that it is entirely unique either.

No implication taken.

James


Joe Burke

unread,
Oct 6, 2004, 5:09:30 PM10/6/04
to
Thanks, Jeff. Both for checking it does what it should, and the selection set
modification.

I'm on my way out so no time reply in detail. Just one question, have you run any
speed tests with a large drawing to compare the filtered selection method vs.
stepping through the model space collection? I haven't, but I will later today. You
know... sometimes what you assume is true and what's actually the case, are two
different things.

Thanks again
Joe Burke

James Allen

unread,
Oct 6, 2004, 6:20:33 PM10/6/04
to
Joe, I tested and it worked fine here as well. Unless of course there are
any nested in other blocks...<grin> I'm pretty sure that's not an issue for
most people, but I have to deal with it here.

Minor questions (I think) :
1. Are there particular times when one should use
(vlax-get obj '<prop>) over
(vla-get-<prop> obj)?
Or is that just a style preference?
2. Likewise with
"(vlax-property-available-p blkref 'Path) ;exclude xrefs" over
"(vla-get-isxref blkref) ;exclude xrefs".

James


Jeff Mishler

unread,
Oct 6, 2004, 6:20:44 PM10/6/04
to
Joe, I just ran a test on a drawing 1.6mb in size that contains 9039
entites, modelspace and all layouts combined. I had to modify both routines
to add (timein) & (timeout "MBI") as well as move the "New insertion point"
selection to right after the block selection. So the beginning looks like
this in both of our routines:

(princ "\nMissed pick or wrong object type selected. ")
)
(setq newpt (trans (getpoint "\nSelect new insertion point: ") 1 0))
(timein)

(setq nm (vlax-get blkref 'Name))
This way only the actual time is measured when there is no human
interaction.
The (timeout) I placed right at the end, before the final (princ)

Here's the results, using the same block both times. This block has been
inserted 8 times in MS and once in PS. All of them are updated with mine,
only the MS inserts are updated with yours.

Command: mbi

Select block:
Select new insertion point: _cen of
Command:
MBI-jmm ran in an Elapsed Time of: 0.11 seconds

Command:
Command: MoveBlockIP

Select block:
Select new insertion point: _cen of Regenerating model.

Command:
MBI-JB ran in an Elapsed Time of: 2.28 seconds

Command:

Here are the 2 small routines I used for checking the time:
(defun timein ()
(setq start-time (getvar "tdindwg"))
)
(defun timeout (cname / secs)
(setq secs (* (- (getvar "tdindwg") start-time) 86400))
(princ (strcat "\n" cname " ran in an Elapsed Time of: " (rtos secs 2 2) "
seconds"))
(princ)
)

--
Jeff
check out www.cadvault.com

"Joe Burke" <job...@hawaii.rr.com> wrote in message

news:41645f1a_2@newsprd01...

Luis Esquivel

unread,
Oct 6, 2004, 7:09:32 PM10/6/04
to
not Joe... but

> Minor questions (I think) :
> 1. Are there particular times when one should use
> (vlax-get obj '<prop>) over
> (vla-get-<prop> obj)?

vlax-get is an old function from vital lisp, the good of using this is that
for various objects you can get the property without care of variant
transalations.

> Or is that just a style preference?
> 2. Likewise with
> "(vlax-property-available-p blkref 'Path) ;exclude xrefs" over
> "(vla-get-isxref blkref) ;exclude xrefs".

is much easier to test for the 'path property [less code]

but can be both methods.


Huw

unread,
Oct 6, 2004, 7:23:24 PM10/6/04
to
> RE: "Joe's MoveBlockIP moved the IP, but not to the picked location".
> I suspect you missed or forgot my instructions regarding the block
> used had to be not scaled or rotated under the version I posted
> previously.

Yes, sorry. I got confused testing the 3 routines - when James' routine placed a sample block I think I mentally ticked that step, forgetting that it applied to your routine.

>
> Whatever, here's a revised version which doesn't impose that
> restriction. You can select a block regardless of scale and/or
> rotation. It's what I should have posted in the first place. I just
> didn't have time to work out the details last night. There's better
> error checking in this version. And the supporting functions are also
> revised.
>
> Jeff,
>
> If you have a chance, please test this one. TIA

Works nicely, thanks!

Huw

unread,
Oct 6, 2004, 7:33:21 PM10/6/04
to
I added that line, and the line

(vla-delete obj1)

before the regen line. I don't know autolisp, I just took a guess, but it seems to work fine - neither sample block was left. Thanks.

dream0001

unread,
Oct 7, 2004, 3:30:08 AM10/7/04
to
thanks for all of you.
now, i design a lisp by your help. share
;| c:chbkins = redefine block's insertpoint and keep the block reference place------------ok!!----lxx.2004.10
|;
(defun c:chbkins ( / *doc e p000 p1e p1 p2 p2x bkobj ss lst)
(while (not(and (princ "\nselect a blockref:")
(setq s (ssget ":S:E" '((0 . "INSERT"))))
)))
(setq *doc (vla-get-activedocument(vlax-get-acad-object))
p000 (list 0. 0. 0.)
e (ssname s 0)
bkn (xdxf e 2) ;;blockname
p1e (xdxf e 10) ;;insertpoint of wcs.
p1 (trans p1e e 1)
p2 (getpoint p1 "\nselect new insert point:"))
(if p2
(progn
(setq p2x (x-inspttrans e (trans p2 1 0)) ;new insertpoint of wcs.
bkobj (vla-item (vla-get-blocks *doc) bkn) ;;get the objs in the block define.
ss (ssget "x" (list '(0 . "INSERT") (cons 2 (xdxf e 2))))
)
;;redefine insertpoint
(vlax-for i bkobj (setq lst (cons i lst)))
(mapcar '(lambda (x) (vla-move x (ptx p2x) (ptx p000))) lst);;ok!
;;move bak to old place
(mapcar '(lambda (x)(vla-move(x2o x)(ptx (xdxf x 10))(ptx (x-insptbak x p2x))))(xss2lst ss))
)
)
(princ)
)
;;********************************************************************************
;;(x-inspttrans e pt) = get the new insertpoint in a block define-----ok!
(defun x-inspttrans (e pt / obj atts attv p ang xs ys zs ) ;;for wcs
(setq p000 (list 0. 0. 0.)
obj (vlax-ename->vla-object e)
p (xdxf e 10)
atts '(rotation xscalefactor yscalefactor zscalefactor)
attv (mapcar '(lambda(x)(vlax-get obj x)) atts))
(mapcar 'set '(ang xs ys zs) attv)
(setq pt (polar p000 (- (angle p pt) ang) (distance p pt))
pt (mapcar '/ pt (list xs ys zs)))
)
;;********************************************************************************
;;get the orignal insertpoint by pt wcs.------------------ok!
(defun x-insptbak (e pt / obj atts attv p ang xs ys zs) ;;for wcs
(setq p000 (list 0. 0. 0.)
p (xdxf e 10)
obj (vlax-ename->vla-object e)
atts '(rotation xscalefactor yscalefactor zscalefactor)
attv (mapcar '(lambda(x)(vlax-get obj x)) atts))
(mapcar 'set '(ang xs ys zs) attv)
(setq pt (mapcar '* pt (list xs ys zs))
pt (polar p (+ (angle p000 pt) ang) (distance p000 pt)))
)
;; trans point to vla point
(defun ptx (pt)

(if (= (type pt) 'variant)
pt
(vlax-3d-point pt)
)
)
;; get the dxf value
(defun xdxf (e id)
(cdr(assoc id (entget e)))
)
;;(xss2lst ss) = get the list of enames in the ssget
(defun xss2lst (ss / i lst)
(setq i -1)
(while (setq e (ssname ss (setq i (1+ i))))
(setq lst (cons (xdxf e -1) lst))
)(reverse lst)
)

James Allen

unread,
Oct 7, 2004, 8:41:27 AM10/7/04
to
Oh.

So you mean I can use
(vlax-get obj 'insertionpoint)
instead of
(vlax-safearray->list (vlax-variant-value (vla-get-insertionpoint obj)))

That's very nice.

I was confused about the xref thing, but that makes sense now. I *thought*
that the line I proposed was a one-for-one replacement, but I see now that
it DEFINITELY was not. I know about vlax-dump-object, but have exclusively
used the help reference for properties and methods; and help doesn't mention
that 'path is a blockREF property. Maybe I should start dumping objects
more if I really want to know.

Thank you Luis

James


James Allen

unread,
Oct 7, 2004, 8:51:51 AM10/7/04
to
I guess I figured there would be no need to *add* an old block, as there
must already be some present if you have a need for this. But by design
adding a new sample block was required, so automatically cleaning it up
afterwards seems reasonable. If it is positioned over an already existing
old block though, you wouldn't want to get rid of the old sample block.

James


Luis Esquivel

unread,
Oct 7, 2004, 10:13:07 AM10/7/04
to
> So you mean I can use
> (vlax-get obj 'insertionpoint)
> instead of
> (vlax-safearray->list (vlax-variant-value (vla-get-insertionpoint obj)))

Yes.

But I use the visual lisp way just in case for future compability [in the
case they upgrade Visual Lisp on the future releases [I am dreaming]].


And you are welcome.

LE.


Joe Burke

unread,
Oct 7, 2004, 11:42:42 AM10/7/04
to
James,

What Luis said is the reason I use vlax-put, vlax-get and vlax-invoke.

I've also seen posts by Michael Puckett, while Google searching, where he said he
found those functions to be more reliable than the vla-xxx versions. Though from what
I read, Michael didn't offer specific examples.

Joe Burke

Luis Esquivel

unread,
Oct 7, 2004, 12:04:00 PM10/7/04
to
>
> I've also seen posts by Michael Puckett, while Google searching, where he
said he
> found those functions to be more reliable than the vla-xxx versions.
Though from what
> I read, Michael didn't offer specific examples.
>
> Joe Burke

I might still have code I did with Vital Lisp... If I do, I will post some
portions here.


Joe Burke

unread,
Oct 7, 2004, 12:09:09 PM10/7/04
to
Hi Doug,

I guess I should know better... :-)

What I've posted wasn't intended as a finished solution. Rather an example of one way
it might be done. Notice my in-line comments, "assume uniform scaling" twice. Thanks
for the drawing example. I'll take a look at what needs to be added to handle Y and Z
scaling.

Joe Burke

>H Jeff & Joe-
>
> I just ran a test on 3 routines...
> I assembled a variety of 4 insertions of the same block, with varying
> scales, asymmetrical x-y-z, and some insertions not parallel to the current
> UCS.
> Then I arrayed the 4 25x25, totaling 2500 blocks.
>
> Joe's original MBI-JB took the least time, app. 3 seconds
> Your MBI-JMM took about 11 seconds
> My RCB took 19 seconds
>
> But both MBI's lost track of the correct insert point when the block was not
> uniformly scaled.
> My RCB did not disturb the scales. Everything stays the same, just the
> insert points move, as was the original intent. I also found that my routine
> does NOT drop all entities onto layer 0 (as Huw reported)... all entities
> within the block remain as they were, color & layer wise.
>
> I've attached 3 wmf images to show how things went wrong.
> -doug
>
>
>


Huw

unread,
Oct 7, 2004, 11:32:37 PM10/7/04
to
True. I had to add an old sample as well as a new, because none of my blocks were at 0° rotation. Although... (I'm going from memory now, so don't trust me) if the old sample was actually an existing block, adding (vla-delete obj2) before the regen line leaves you with one block not updated after you've run the routine, doesn't it?

Joe Burke

unread,
Oct 8, 2004, 6:43:15 AM10/8/04
to
Jeff,

I forgot to thank you for your speed comparison and code suggestions. So thanks. :-)

I have a new version I'll post soon. It uses a filtered selection set, though a bit
different than your approach. I think it deals with non-uniformly scaled blocks
correctly. That wasn't particularly easy given how I'm trying to do it.

Preliminary speed tests look good. Given Doug's example of 2500 blocks to process,
I'm seeing results in the range of less than 0.7 seconds. That's not counting regen
time, which shouldn't be needed if the function behaves properly.

Regards
Joe Burke


"Jeff Mishler" <jef...@cadvault.com> wrote in message news:41646fbe_2@newsprd01...

Joe Burke

unread,
Oct 8, 2004, 9:00:51 AM10/8/04
to
My best shot at it. What did I forget or miss... surely something. ;-)

Seems fast. Timer function included.

Joe Burke

;; JB version 3 10/7/2004
;; function: move a block's insertion point and fix all existing references
;; tested in a UCS with mirrored and non-uniformly scaled blocks

(defun c:MoveBlockIP (/ doc blocks blkref oldpt newpt blkdef nm vec ang
xscl yscl zscl newvec RotatePt ScalePtNonUniform)

;; arguments: point to rotate, base point, angle


(defun RotatePt (pt bp ang)
(polar bp (+ (angle bp pt) ang) (distance bp pt))
) ;end

;; arguments: point to scale, base point, X Y and Z scale factors
(defun ScalePtNonUniform (pt bp xscl yscl zscl / vec scl)


(setq vec (mapcar '- pt bp))

(setq scl (mapcar '* vec (list xscl yscl zscl)))


(mapcar '+ scl bp)
) ;end

(setq doc (vla-get-activedocument (vlax-get-acad-object))
blocks (vla-get-blocks doc)

)
(while
(or
(not (setq blkref (car (entsel "\nSelect block: "))))
(not (setq blkref (vlax-ename->vla-object blkref)))
(not (equal "AcDbBlockReference" (vlax-get blkref 'ObjectName)))
(vlax-property-available-p blkref 'Path) ;exclude xrefs
)

(princ "\nMissed pick or wrong object type. ")
)
(initget 1)


(setq newpt (trans (getpoint "\nSelect new insertion point: ") 1 0))

;(starttimer)

(setq nm (vlax-get blkref 'Name)
blkdef (vla-item blocks nm)
xscl (/ 1.0 (vlax-get blkref 'XScaleFactor))
yscl (/ 1.0 (vlax-get blkref 'YScaleFactor))
zscl (/ 1.0 (vlax-get blkref 'ZScaleFactor))
ang (vlax-get blkref 'Rotation)
oldpt (vlax-get blkref 'InsertionPoint)
oldpt (RotatePt oldpt newpt (- ang))
oldpt (ScalePtNonUniform oldpt newpt xscl yscl zscl)
vec (mapcar '- oldpt newpt)
)

;; move objects in the block definition
(vlax-for x blkdef
(vlax-invoke x 'Move '(0.0 0.0 0.0) vec)
)

;; move block references
(ssget "x" (list '(0 . "INSERT") (cons 2 nm)))
(vlax-for x (vlax-get doc 'ActiveSelectionSet)
(setq ang (vlax-get x 'Rotation)
xscl (vlax-get x 'XScaleFactor)
yscl (vlax-get x 'YScaleFactor)
zscl (vlax-get x 'ZScaleFactor)
newvec (mapcar '* vec (list xscl yscl zscl))
newvec (RotatePt newvec '(0.0 0.0 0.0) ang)
)
(vlax-invoke x 'Move newvec '(0.0 0.0 0.0))
) ;for

;(endtimer)

(vla-regen doc acActiveViewport)
(princ)
) ;end

;---------------------------------------------------------
(defun StartTimer ()
(setq *start* (getvar "date")))
(defun EndTimer (/ end)
(setq end (* 86400 (- (getvar "date") *start*)))
(princ (strcat "\nTimer: " (rtos end 2 8) " seconds\n")))
;---------------------------------------------------------


Douglas Barr

unread,
Oct 8, 2004, 9:55:15 AM10/8/04
to
BTW... my low-tech routine does handle it, because it isn't reinserting
blocks, it's redefining the block and leaving the original inserts alone.
Perhaps you could devise a more high-tech way to redefine the blocks than my
method? And get it down from 19 seconds to 3? (I'm guessing your timing
varies from mine because I'm working on a P4-1.6 machine)
-doug

"Douglas Barr" <dougatsweaterscapesdotcalm> wrote in message
news:41669b5e_3@newsprd01...
> Hi Joe -
> WMF's attached... it still doesn't know how to handle asymmetrical blocks,
> doesn't like blocks inserted at odd angles to the screen apparently,
either.
> -doug


>
> "Joe Burke" <job...@hawaii.rr.com> wrote in message

> news:41668fa2$1_1@newsprd01...

Joe Burke

unread,
Oct 8, 2004, 10:43:57 AM10/8/04
to
Hi Doug,

Thanks for the feedback. I think my ignorance is showing.

I don't understand what you mean when you say "asymmetrical blocks". Does that
translate to non-uniformly scaled blocks? Worse, I'm at total loss when you say,
"blocks inserted at odd angles to the screen". I don't do 3D work, so the idea just
doesn't compute on my end.

Please know, I'm not questioning what you said. I simply don't understand it.

BTW, speed comparisons seem mostly irrelevant to me when it comes to a function like
this. It's much more important the function handles all cases correctly.

I haven't had time to study your program or James'. I will over the weekend.

Regards
Joe Burke

"Douglas Barr" <dougatsweaterscapesdotcalm> wrote in message
news:41669b5e_3@newsprd01...
> Hi Joe -
> WMF's attached... it still doesn't know how to handle asymmetrical blocks,
> doesn't like blocks inserted at odd angles to the screen apparently, either.
> -doug
>

> "Joe Burke" <job...@hawaii.rr.com> wrote in message

> news:41668fa2$1_1@newsprd01...

Douglas Barr

unread,
Oct 8, 2004, 10:55:04 AM10/8/04
to
I kinda mis-spoke. I meant non-uniformly inserted blocks, not
asymmetrically. As for the odd angles comment, I just meant blocks whose
z-axis is not comin' right at ya. Like the 3d-looking block on the right. In
fact, all the blocks are the same... both circles have z-depth, but the
insertions other than the 'isometric-looking' one just appear to be 2-d
non-z type blocks.

If I follow YOUR routine correctly, it's replacing every block with a new
insertion, having determined original location and rotation of the existing
blocks, and duplicating all that with the new insertion.

MY routine simply redefines the block, leaving every pre-existing block
alone, at its original location, rotation, layer, xyz-scaling, even
attributes shouldn't change, if there are any differences within them.

Mine is slow, comparatively. But it does work.
-doug

"Joe Burke" <job...@hawaii.rr.com> wrote in message

news:4166a7c3$1_2@newsprd01...

Joe Burke

unread,
Oct 8, 2004, 11:03:21 AM10/8/04
to
BTW Doug,

I'm aware the polar function used in my RotatePt function is just 2D. So that's
obvious a concern in terms of doing things right in 3D.

Joe Burke


Douglas Barr

unread,
Oct 8, 2004, 11:11:57 AM10/8/04
to
Hey Joe...
(where ya goin with that gun in your hand?)<groan>

Below is a routine I once wrote to replace a block with another one, at same
rotation, location, layer, etc. It works in 3d, since it sets UCS to the
existing block's UCS, then inserts at 0,0,0.

Again, not very sophisticated, but it does the job.
-doug

"Joe Burke" <job...@hawaii.rr.com> wrote in message

news:4166ac4d_1@newsprd01...

(defun c:bkr ()
(setq osm (getvar "osmode"))
(setvar "osmode" 0)
(prompt "\nChoose the block you need replaced: ")
(setq ae (entsel))
(setq aa (entget (car ae)))
(setq aaa (cdr (assoc 2 aa)))
(setq x (cdr (assoc 41 aa)))
(setq y (cdr (assoc 42 aa)))
(setq z (cdr (assoc 43 aa)))
(setq ab (strcat "\nThat is block " aaa ". "))
(princ ab)
(prompt "\nType the name of the block to replace it:<")
(if (not a)
(setq a "--")
(setq oldb a)
)
(princ a)
(prompt "> ")
(setq a (strcase (getstring)))
(if (= a "")
(setq a oldb)
)
(setq bb (strcat "\nAbout to replace block " aaa " with block " a " -
proceed? "))
(princ bb)
(setq c (getstring))
(setq d (cdr (assoc 8 aa)))
(if (or (= c "N")(= c "n"))
(prompt "\nPlease try again later. ")
(progn
(command "ucs" "e" ae)
(command "erase" ae "")
(command "-layer" "s" d "")
(command "insert" a "0,0,0" "x" x y z "")
(command "ucs" "p")
(command "redraw")
(setq f (strcat "\nBlock " a " successfully inserted in place of block "
aaa ". "))
(princ f)
)
)
(setvar "osmode" osm)
(princ)
)


Joe Burke

unread,
Oct 8, 2004, 11:27:03 AM10/8/04
to
Doug,

Regarding this:

> If I follow YOUR routine correctly, it's replacing every block with a new
> insertion, having determined original location and rotation of the existing
> blocks, and duplicating all that with the new insertion.

No. That's exactly the kind of thing I'm trying to avoid.

All versions I've posted try to do two basic things. First, move the objects inside
the block definition. Second, repair the breakage for existing references by moving
them back to where they were originally. Nothing is created or erased given this
approach. Which is a point I've been keep in my back pocket while we talk.

Regards
Joe Burke


Douglas Barr

unread,
Oct 8, 2004, 11:40:01 AM10/8/04
to
Gotcha.
I don't read VL very well... if at all.
I guess the only thing your routine doesn't do is establish the UCS prior to
redefining the block, and setting the UCS prior to moving each insertion.
And maybe the z isn't adjusted too.

It's not really that different than mine, (if I read it correctly<g>) it
just goes a ho lot faster! Is that the nature of VL?
-doug

"Joe Burke" <job...@hawaii.rr.com> wrote in message

news:4166b1d9$1_2@newsprd01...

Joe Burke

unread,
Oct 8, 2004, 12:23:38 PM10/8/04
to
Doug,

Aside... the idea I could move objects within a block definition relative to its
origin (0,0) was a total surprise to me. You know... one of those things you try
while thinking, "this won't work".

Regarding UCS issues, I think I took care of that. Notice (trans 1 0) at the getpoint
"Select new insertion point: " prompt. That's all that's needed here since all the
ActiveX/vlisp stuff operates in WCS. There's no need to mess with the UCS within the
program. Rather just make sure all data is in WCS. And getpoint is the possible
odd-ball.

Regards
Joe Burke


"Douglas Barr" <dougatsweaterscapesdotcalm> wrote in message

news:4166b4d2$1_1@newsprd01...

James Allen

unread,
Oct 8, 2004, 6:27:42 PM10/8/04
to
"...none of my blocks were at 0° rotation."
I think you are thinking of Joe's original version. Mine doesn't care how
the old and new samples are placed relative to world, just relative to each
other. And I believe his new version lifted that restriction as well.

"...adding (vla-delete obj2) ... leaves you with one block not updated ...,
doesn't it?"
Not necessarily. Let me try to make sense of this.
1. You pick the old sample (obj1) and then the new sample (obj2).
2. From these the routine determines the relative 'mapping' that will take
place.
3. You select what you want to convert (ss), or "ReplaceAll" if you intend
to effectively redefine the block.
4. The routine then converts every block in ss.

It doesn't automatically assume that obj1 is part of ss, so if you don't
select obj1 (again) in step 3 or use the "ReplaceAll" option, then you are
correct. However many instances of the old block you did not select
(potentially including obj1) will not be converted. But, if all you did
before running this was put obj2 over an *existing* obj1 and then include
obj1 in step 3, then obj2 is all you would want deleted. I hope that makes
more sense.

James


Huw

unread,
Oct 10, 2004, 10:39:47 PM10/10/04
to
> It doesn't automatically assume that obj1 is part of ss, so if you
> don't select obj1 (again) in step 3 or use the "ReplaceAll" option,
> then you are correct. However many instances of the old block you
> did not select (potentially including obj1) will not be converted.
> But, if all you did before running this was put obj2 over an
> *existing* obj1 and then include obj1 in step 3, then obj2 is all you
> would want deleted. I hope that makes more sense.

Thanks. Now it makes perfect sense. I wasn't thinking straight.

Joe Burke

unread,
Oct 11, 2004, 8:15:40 AM10/11/04
to
Hi James,

Up front, I think if you feel a need to pursue a topic, you should. Regardless of
whether it seems others are still interested or not. You just never know where a
comment might lead... or who's bell it may ring.

I gave some thought to your point about nested blocks, which I hadn't seriously
considered before. What I was doing in previous posts would cause some serious
breakage if the selected block is nested in other blocks. The block definition would
be modified, but nested references would not be moved due to the selection set
method. It only returns primary objects.

Thinking back, I believe the reason I didn't initially use Jeff's selection set idea
was because I thought I'd have to parse the model space collection eventually. IOW,
find some way to also move nested references. BTW, blocks in paper space are of no
concern to me personally.

So I'll offer this version which at least prevents making a mess when the selected
block is nested in other block definitions. See the new IsNested function. Not well
tested, but seems OK.

All of this may be moot given the methods you and Doug suggested. I still haven't
found time to study those. I must confess, any method which creates and destroys
seems less appealing than one which simply modifies existing objects. That was my
goal from the beginning. Though I certainly don't think that's the only way to do it.

Regards
Joe Burke

;; revised version 10/10/2004
;; exit if selected block is nested in other blocks
(defun c:MoveBlockIP (/ *error* doc blocks blkref oldpt newpt blkdef


nm vec ang xscl yscl zscl newvec

RotatePt ScalePtNonUniform IsNested)

(defun *error* (msg)
(if msg (princ msg))
(princ)
) ;end

;; arguments: point to rotate, base point, angle
(defun RotatePt (pt bp ang)
(polar bp (+ (angle bp pt) ang) (distance bp pt))
) ;end

;; arguments: point to scale, base point, X Y and Z scale factors
(defun ScalePtNonUniform (pt bp xscl yscl zscl / vec scl)
(setq vec (mapcar '- pt bp))
(setq scl (mapcar '* vec (list xscl yscl zscl)))
(mapcar '+ scl bp)
) ;end

;; argument: block name
;; return T if block name is nested in other blocks, otherwise nil
(defun IsNested (blknm)
(vlax-for x blocks
(vlax-for item x
(if
(and
(vlax-property-available-p item 'Name)
(equal blknm (vlax-get item 'Name))
)
T
)
)
)
) ;end

(setq doc (vla-get-activedocument (vlax-get-acad-object))
blocks (vla-get-blocks doc))

(while
(or
(not (setq blkref (car (entsel "\nSelect block: "))))
(not (setq blkref (vlax-ename->vla-object blkref)))
(not (equal "AcDbBlockReference" (vlax-get blkref 'ObjectName)))
(vlax-property-available-p blkref 'Path) ;exclude xrefs
)
(princ "\nMissed pick or wrong object type. ")
)

(setq nm (vlax-get blkref 'Name))

;; exit here if block is nested
(if (IsNested nm)
(progn
(princ "\nSelected block is nested. Exiting... ")
(exit)
)
)

(initget 1)
(setq newpt (trans (getpoint "\nSelect new insertion point: ") 1 0))

(setq blkdef (vla-item blocks nm)

(vla-regen doc acActiveViewport)
(*error* nil)
) ;end


Joe Burke

unread,
Oct 11, 2004, 9:10:53 AM10/11/04
to
BTW James,

I was tempted to get into matrix transformations here. I decided against it, thinking
such would just obscure the primary topic.

Others have mentioned vla-explode with NUS blocks under recent versions doesn't work
as expected.

Forgive me if I'm repeating myself. I don't think speed is an issue here. It's an
issue with a function which may be repeated often. This one is not one of those. As I
see it, speed is totally subservient to doing the thing right in all cases.

Regards
Joe Burke


Joe Burke

unread,
Oct 12, 2004, 6:41:20 AM10/12/04
to
Hi James,

Somehow I missed your attachment RCB2 while reading this before. Nice work! Seems to
work perfectly, as far as I've tested it. Guess I might as well junk my stuff. :-)

One suggestion. I think it would be helpful to highlight the selected block before
asking for new insertion point. Something like this.

(setq obj (vlax-ename->vla-object
(car (entsel "\nTouch block to reconfigure:"))))
(vla-highlight obj :vlax-true)
(setq npt (getpoint "\nSelect new insertion point for block:")
etc...

So it's clear when dealing with nested blocks, which block's insertion point is being
modified. Someone, like me, might think they can pick a nested block.

I also wonder about moving the block's origin point. That was something I played with
early on. I had some trouble getting a handle on exactly what it meant it terms of
what we are doing. Then I thought why not move the objects in the block definition,
which leaves the origin at 0,0,0. Obviously that's what I did eventually.

Whether the distinction between the two methods makes any difference in practice is
questionable. I guess some programmer, like us, might assume a block's origin is
always 0,0,0 since AFAIK there's no way to create a block with an origin other than
that using standard tools.

Something makes me uneasy about the idea. Given the fact there is an alternate method
which leaves origin point at 0,0,0.

BTW, I encountered some problems with RCB1. I haven't looked at it closely. When it
worked, it seemed to change the layer of modified blocks to the current layer. When
it didn't work, for some unknown reason (nested blocks?), I got this:

Unknown command "RCB1". Press F1 for help.
No unreferenced blocks found.
; error: Automation Error. Duplicate record name

I'm also looking at your MWE:BlockTrans function. Needs some quiet time to study.
Don't know when that will happen. But it's actually of more interest to me than this
subject.

Regards
Joe Burke


Kent Cooper, AIA

unread,
Oct 12, 2004, 9:20:32 AM10/12/04
to
Am I missing something here? Of course you can create a block with an
origin other than 0,0,0 using standard tools:

[in A2K4]
Command: -block
Enter block name or [?]: <..give it something..>
Specify insertion base point: <..wherever you want..>

The dialog box offers 0,0,0 as a default, but there's the Pick Point button,
also in Wblock.

Somehow -wblock still gives you a file dialog box if FILEDIA is 1, but if
it's 0, then:

Command: -WBLOCK
Enter name of output file: <..give it something..>
Enter name of existing block or
[= (block=output file)/* (whole drawing)] <define new drawing>: <..Enter..>
Specify insertion base point: <..wherever you want..>

Or are you talking about something different than what I think of as
"creating a block"?
--
Kent Cooper, AIA


"Joe Burke" wrote...
...


> Whether the distinction between the two methods makes any difference in
> practice is questionable. I guess some programmer, like us, might assume a
> block's origin is always 0,0,0 since AFAIK there's no way to create a
> block with an origin other than that using standard tools.

...


Doug Broad

unread,
Oct 12, 2004, 10:53:18 AM10/12/04
to
MP,
There is no such bug for blocks, only for external references.

In addition, AutoCAD 2005 automatically adjusts the insertion point
during wblock commands. (Earlier versions did not adjust).

Regards,
Doug

"MP" <nos...@Thanks.com> wrote in message news:416bdde4$1_3@newsprd01...
>
> "Kent Cooper, AIA" <kco...@schwamarchitects.com> wrote in message
> news:416bda1e$1_3@newsprd01...


> > Am I missing something here? Of course you can create a block with an
> > origin other than 0,0,0 using standard tools:
>

> you can, but it's not the best idea. (imho)
> a block created elsewhere than 0,0 will not honor trim, extend, and
> sometimes osnaps
> a quick macro to move objects to 0,0 first, then block them, then move the
> block back to where you started will eliminate this bug.
>
>
>


James Allen

unread,
Oct 12, 2004, 9:56:22 AM10/12/04
to
Thank you Joe.

Good point about the highlighting. I should do more of that in general. I
did think about handling a missed pick, but neglected that as well.

Regarding origin, I agree with you. One of my goals writing what I posted
was to see how "simple" I could make it and still work. I do think moving
the nested ents is the better way to go though and would be pretty easy to
add. I don't know if you'd call this standard, but you can use the base
command to change the insertion base point in a file that will be used as a
block. I'm not sure what purpose this would serve, but I do remember our
company's old block library having all sorts of random base points (origins)
for some reason. Among other things, I changed all their base points to
0,0,0.

What you describe with RCB1 sounds right. It's like inserting Blk1 and then
redefining Blk2 to only contain Blk1. Blk1's non-geometric properties are
exactly the same in every insertion of Blk2, so when you explode all Blk2's,
what's left is identical throughout. That's the inherent problem. The
genius (and yet so simple) is that it effectively redefines the insertion
point w/o visibly moving the block. The error message you quoted looks like
nested references. Exploding (ssget "x") doesn't cut it. There are still
unexploded references, so the purge fails.

"...But it's actually of more interest to me than this subject." Big ditto!
From what you've posted, I think you've already got most of what is
significant there. The quasi-formulas in the comments reveal the heart of
it. Most of the rest is just input initialization and path picking.

James


Kent Cooper, AIA

unread,
Oct 12, 2004, 11:34:33 AM10/12/04
to
Well, knock me over with a feather.... In over 20 years working with
AutoCAD, I have never, ever defined blocks that way (it never even occurred
to me), and I've never, ever been aware of the problems you describe (except
for most of those years when it wasn't possible to trim or extend to blocks
at all). What's more, I've been sitting here wasting time trying to make it
not work, in both A2K and A2K4, without success except in situations that
also don't work with 0,0-based blocks.

I can't trim or extend to polylines within blocks, ONLY when the block is
not uniformly scaled (even then, I can trim and extend to arcs and circles
and lines in the blocks). [Express Tools' Trim to Nested Entities in A2K4
does make it work for all of those things.] BUT the same things also fail
when I define the block with a 0,0 insertion point, so that doesn't support
your "bug." (It could certainly be considered a bug on its own, but the
insertion base point has nothing to do with it, at least for me.)

On Osnap, I haven't been able to do tangent or perpendicular or quadrant
Osnap to curves (including polylines, arcs and circles), or intersections
involving polyline segments (even straight-line segments), again ONLY in
non-uniformly-scaled block insertions. (It does snap to midpoints and
endpoints and center-points of the curves.) But again, that's equally the
case if I define the blocks with a 0,0 insertion point.

Of course I haven't tried every kind of entity in blocks, or every type of
osnap on every kind of thing. But in no case has defining a block with its
insertion point at 0,0 made any difference.

Do other people have the problems MP describes?
--
Kent Cooper, AIA


"MP" wrote...
>
> "Kent Cooper, AIA" wrote...


>> Am I missing something here? Of course you can create a block with an
>> origin other than 0,0,0 using standard tools:
>

Douglas Barr

unread,
Oct 12, 2004, 12:28:58 PM10/12/04
to
Hi James et al...

I just HAD to leave your first paragraph in my reply. <big self-serving
grin>

"James Allen" <JamesA~AA~mwengrs~DD~com> wrote in message
news:4169b7a3_1@newsprd01...
> Hi again Joe and Doug, and whoever else may be watching. I'm back again
> because once I realized the simple brilliance of Doug's approach my mind
> just wouldn't let it rest. So here I am again.

I believe your RCB2 is the grand prize winner. Nice routine.

As for your RCB1, it took 3:47 to reconfigure my 2500 block array. My
version of RCB took what I previously thought to be an interminable 0:19.
Wow, what a speed demon it is now!

Does this sort of thing happen with VL every time?
-doug


Jason Piercey

unread,
Oct 12, 2004, 12:35:33 PM10/12/04
to
Doug,

Yes this bug does (still) exist. This has to do with entmake
and not using 0,0 as the block definitions insertion point.

Use this to create the block, then draw a line through it
and try to trim. Replace the insertion point with 0,0 and it
works as expected.

(entmake
'(
(0 . "BLOCK")
(100 . "AcDbEntity")
(8 . "0")
(100 . "AcDbBlockBegin")
(70 . 0)
(10 1.0 1.0 0.0)
(2 . "test")
)
)

(entmake
'(
(0 . "CIRCLE")
(100 . "AcDbEntity")
(8 . "0")
(100 . "AcDbCircle")
(10 1.0 1.0 0.0)
(40 . 0.5)
)
)

(entmake '((0 . "endblk")))


--
Autodesk Discussion Group Facilitator

"Doug Broad" <dbro...@spam-nash.cc.nc.us> wrote in message
news:416bf0b8$1_1@newsprd01...

Jason Piercey

unread,
Oct 12, 2004, 1:57:56 PM10/12/04
to
I stumbled onto that by accident a couple of years
ago. Was making blocks on the fly, using a picked
point for the block definition, then noticed problems
with trimming. Drove me crazy for a while!


--
Autodesk Discussion Group Facilitator

"Doug Broad" <dbro...@spam-nash.cc.nc.us> wrote in message

news:416c19df$1_3@newsprd01...
> Thanks for the illustration Jason.
>
> Guess it depends on how you make the block. I have never
> run across that error because, when entmaking blocks, I've never
> seen an advantage in using an IP other than 0,0. The error is
> interesting however.
>
> Now compare that to a block made with the block command.
> The block command must do the translation automatically because
> I have never had a problem using the block command and picking
> any insertion point and having trim work correctly.
>
> I just tested it with a rectangle 3,3 4,4 and block "box" with IP 3,3.
> A table search on the block table shows the ip as 0,0,0 indicating
> the translation occurs.
>
> So when using entmake, IP must be 0,0,0 for trim to work. Thanks.
>
> Regards,
> Doug


MP

unread,
Oct 12, 2004, 12:21:01 PM10/12/04
to
I stand corrected..
:-)

"Doug Broad" <dbro...@spam-nash.cc.nc.us> wrote in message

news:416bf0b8$1_1@newsprd01...

Joe Burke

unread,
Oct 12, 2004, 3:26:10 PM10/12/04
to
Hi Kent,

A block's "origin" as defined in the block table/collection is always 0,0,0
regardless of whether you pick a point or accept the default 0,0,0 when creating the
block.

Try this on blocks created either way.

(defun c:test ( / blocks obj )
(setq blocks
(vla-get-blocks
(vla-get-activedocument
(vlax-get-acad-object))))
(setq obj (vlax-ename->vla-object
(car (entsel "\nSelect block: "))))
(vlax-get
(vla-item blocks
(vlax-get obj 'Name)) 'Origin)
)

My point regarding James' RCB2 function was that after it modifies a block, the
origin is not 0,0,0.

Joe Burke

Douglas Barr

unread,
Oct 12, 2004, 3:14:02 PM10/12/04
to
"James Allen" <JamesA~AA~mwengrs~DD~com> wrote in message
news:416c260a$1_2@newsprd01...
> Thank you Doug. I'm confused by your reported times though. Are you
saying
> RCB was THAT much quicker than RCB1? (0:19 vs 3:47)

I tested them twice each. Yours did indeed take almost 4 minutes.

At first I thought your RCB2 had simply hung up my computer, because it
stopped with the command line
"Select new insertion point for block:" displayed. I then brought up the
textscreen (F2), and then I could see that it was working, slowly repainting
the screen with new blocks over the textscreen... visibly taking about 1
second to replace about 10 blocks.
-doug


James Allen

unread,
Oct 13, 2004, 9:05:53 AM10/13/04
to
That's really weird. I am curious what would make THAT much difference. If
you don't mind helping educate me a little bit...

Can you tell if the hangup is in the explode loop or not?
...
(ssget "x" (list '(0 . "INSERT") (cons 2 name)))
(vlax-for obj (vla-get-activeselectionset doc)
(vl-cmdf "._explode" (vlax-vla-object->ename obj) "")
)
...

If so, what kind of results do you get with one of these variations or your
version of the same loop?
...
;;Variation 1
(ssget "x" (list '(0 . "INSERT") (cons 2 name)))
(vlax-for obj (vla-get-activeselectionset doc)
(vl-cmdf "._explode" (vlax-vla-object->ename obj) "")
(vlax-release-object obj)
)
...
...
;; Variation 2
(setq ss (ssget "x" (list '(0 . "INSERT") (cons 2 name)))
cnt (if ss (sslength ss) 0)
)
(repeat cnt
(setq cnt (1- cnt))
(vl-cmdf "._explode" (ssname ss cnt) "");; Or "command"
)
...
James


Douglas Barr

unread,
Oct 14, 2004, 2:55:37 PM10/14/04
to
Hi James ~

> Can you tell if the hangup is in the explode loop or not?

Not certain if it's the explode or not, though in my own routine, the
explode is essentially all there is.

> If so, what kind of results do you get with one of these variations or
your
> version of the same loop?

Here's the entire routine you wrote, with variations which I alternately
commented in & out.
I note below what the timing was for each variation. (counting
one-america-two-america...<g>)

;;; ReConfigureBlock
;;; Doug's approach using vl- methods (mostly)
(defun c:rcb1 (/ doc obj name opt blk npt orgn tname blks tblk lst)
(setvar "cmdecho" 0)
(setq doc (vla-get-activedocument (vlax-get-acad-object)))
(vla-startundomark doc)
(setq obj (car (entsel "\nTouch block to reconfigure:"))
obj (vlax-ename->vla-object obj)
name (vla-get-name obj)
opt (getpoint "\nPoint to a blank place to work in:")
blk (vla-get-block (vla-get-activelayout doc))
npt (vlax-3d-point (trans opt 1 0))
obj (vla-insertblock blk npt name 1 1 1 0)
npt (getpoint "\nSelect new insertion point for block:")
opt (vlax-3d-point (mapcar '- npt opt))
npt (vlax-3d-point (trans npt 1 0))
orgn (vlax-3d-point '(0 0 0))
tname (strcat "RCB-Old-" name)
blks (vla-get-blocks doc)
blk (vla-add blks orgn tname)
tblk (vla-item blks name)
lst (vlax-invoke obj 'explode)
)
(prompt "\n")
(vla-delete obj)
(mapcar '(lambda (obj) (vla-move obj npt orgn)) lst)
(vlax-invoke doc 'copyobjects lst blk)
(mapcar 'vla-delete lst)
(vlax-for obj tblk (vla-delete obj))
(vla-insertblock tblk opt tname 1 1 1 0)

;********** ORIGINAL VERSION *****************


(ssget "x" (list '(0 . "INSERT") (cons 2 name)))
(vlax-for obj (vla-get-activeselectionset doc)
(vl-cmdf "._explode" (vlax-vla-object->ename obj) "")
)

Testing it on a 576-block drawing, it took 55 seconds to complete.

;********** VARIATION 1 **********************
;(ssget "x" (list '(0 . "INSERT") (cons 2 name)))


;(vlax-for obj (vla-get-activeselectionset doc)
; (vl-cmdf "._explode" (vlax-vla-object->ename obj) "")
; (vlax-release-object obj)
; )

Again, 576 blocks took 44 seconds, but the blocks were skewy as heck.

;********** VARIATION 2 **********************
;(setq ss (ssget "x" (list '(0 . "INSERT") (cons 2 name)))


; cnt (if ss (sslength ss) 0)
;)
;(repeat cnt
; (setq cnt (1- cnt))
; (vl-cmdf "._explode" (ssname ss cnt) "");; Or "command"
;)

This time it took 44 seconds again, but all blocks behaved properly.

;********** CLOSING CODE***************

(vl-cmdf "._purge" "B" name "N")
(vla-put-name blk name)
(vla-endundomark doc)
(princ)
)
;*********** END OF ROUTINE *****************

My own RCB routine took 6.5 seconds for 576 blocks, your RCB2 took about
1.5.
-doug


James Allen

unread,
Oct 15, 2004, 7:16:03 PM10/15/04
to
Wow, do I feel silly now! LOL Taking the extra "" out of the explode calls
makes just a wee bit of difference... Sorry 'bout the little detour Doug.

(vl-cmdf "._explode" (vlax-vla-object->ename obj)); was ... obj) "")

I cobbled together a file with 768 inserts and tested using Joe's posted
timer function (and the appropriate ""'s removed).

5.94s ;rcb
3.85s ;rcb1-original
6.92s ;rcb1-var1
4.62s ;rcb1-var2-vl-cmdf
4.89s ;rcb1-var2-command
2.20s ;rcb2

There was one thing of genuine interest to me here. For anyone looking for
empirical data on vlax-release-object, notice that the only difference from
rcb1-original to rcb1-var1 was the ADDITION of vlax-release-object to the
explode loop. I've seen people say it never hurts... Weell, I'm not so
sure about that.

Thank you Doug.

James


Joe Burke

unread,
Oct 19, 2004, 7:34:10 AM10/19/04
to
Hi James,

I thought something like that extra "" was the cause of the slow times Doug reported.
Just didn't have time to investigate.

Interesting regarding the vlax-release-object call. I'm never sure when I should do
that, other than when working with ODBX files. With those the result of not doing it
is clear. An attempt to open the file normally results in "read only" if you don't
release in code.

Joe Burke

"James Allen" <JamesA~AA~mwengrs~DD~com> wrote in message

news:41703c87_1@newsprd01...

0 new messages