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

Discussion in 'AutoCAD' started by dream0001, Oct 4, 2004.

  1. dream0001

    dream0001 Guest

    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
    dream0001, Oct 4, 2004
    1. Advertisements

  2. dream0001

    Doug Broad Guest


    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?

    Doug Broad, Oct 4, 2004
    1. Advertisements

  3. Refedit?
    (Redefine the block)
    Casey Roberts, Oct 4, 2004
  4. dream0001

    Rudy Tovar Guest

    Change the "INSBASE" point variable.
    Rudy Tovar, Oct 4, 2004
  5. dream0001

    dblaha Guest

    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.

    dblaha, Oct 4, 2004
  6. dream0001

    Douglas Barr Guest

    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.

    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.
    Douglas Barr, Oct 4, 2004
  7. 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
    Kent Cooper, AIA, Oct 4, 2004
  8. 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
    Kent Cooper, AIA, Oct 4, 2004
  9. 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

    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
    Kent Cooper, AIA, Oct 4, 2004
    Tony Tanzillo, Oct 4, 2004
  11. dream0001

    Douglas Barr Guest

    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
    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.

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

    Douglas Barr, Oct 4, 2004
  12. dream0001

    dblaha Guest

    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...
    dblaha, Oct 5, 2004
  13. 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

    Kent Cooper, AIA, Oct 5, 2004
  14. dream0001

    Joe Burke Guest


    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

    (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
    (equal "AcDbBlockReference" (vlax-get x 'ObjectName))
    (equal nm (vlax-get x 'Name))
    (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)))
    ) ;for
    (not (vla-regen doc acActiveViewport))
    ) ;and
    ) ;end

    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,
    Joe Burke, Oct 5, 2004
  15. dream0001

    GaryDF Guest

    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.

    GaryDF, Oct 5, 2004
  16. 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)
    ((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: "))))
    (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)
    (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))

    (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))
    ((= (type e) 'STR))
    ((/= (f:assoc 0 (car e)) typ)
    (setq e nil)

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

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

    (defun f:assoc (at lst / ret)
    ((= (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))
    (cdr ret)

    (defun f:assocp (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)))
    (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)
    (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)
    (f:vlerr 'vla-Item (list (vlax-get-property doc tbl) nam) nil)

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

    (defun fx:doc ()
    (setq *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)
    (if (not ret) (setq ret T) ret)
    (if (= (type ret) 'VL-CATCH-ALL-APPLY-ERROR) (setq ret nil))


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

    (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) "*|*"))
    (vlax-map-Collection b
    (function (lambda (e)
    (if (f:apply_ssfilter e filt)
    (setq ret (append ret (list :)fun e))))

    (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))
    ));progn if

    (defun f:apply_ssfilter (en lst / ret val typ)
    (setq ret T en (f:en en))
    (mapcar '(lambda (at)
    (if ret
    ((= (car at) 0)
    (if (not (wcmatch (setq typ (strcase (f:assoc 0 en))) (strcase (cdr at))))
    (setq ret nil)
    ((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))

    petersciganek, Oct 5, 2004
  17. dream0001

    Douglas Barr Guest

    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

    Besides, it looks like Joe Burke has provided something to eliminate the
    Douglas Barr, Oct 5, 2004
  18. dream0001

    Douglas Barr Guest

    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?
    Douglas Barr, Oct 5, 2004
  19. dream0001

    Joe Burke Guest

    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?

    Joe Burke
    Joe Burke, Oct 5, 2004
  20. dream0001

    Douglas Barr Guest

    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.
    Douglas Barr, Oct 5, 2004
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.