Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Take two objects and swap their positions?

16 REPLIES 16
Reply
Message 1 of 17
pteague
8949 Views, 16 Replies

Take two objects and swap their positions?

Hey everyone. Newb here. I have been searching for some information on how to pass objects into a function so I can mess with their properties. Somehow I haven't been very successful. Anyway...What I want to do is take two items (light fixtures) and swap their positions on the drawing. It seems like it must be really simple, but I'm just not finding the key puzzle pieces to do it. It seems like if I could figure out how to pull two objects into the function (whether by selecting them and running the function or by selecting them after I run the function) I could very easily save the coordinates of one to variables and then just swap them. Any thoughts?
16 REPLIES 16
Message 2 of 17
Anonymous
in reply to: pteague

What I would do is extract the insertions points, block names, xyz factors (if applicable), delete the objects (blocks), then reinsert the correct block at the correct insertion point unless you need any other special needs.  I have something for text but not blocks.

Message 3 of 17
dgorsman
in reply to: pteague

Depends on what the "objects" are.  Most AutoCAD entities have a location/base point that can be modified, effectively "moving" the object.  If these are blocks, no need to delete anything; just store the first insertion point, change the insertion point of the second object to the insertion point of the first, then change the insertion point of the first object to the stored location.  If these are custom objects from third-party software, you may not have the means to do this.

 

Have a look into the (entget...), (subst...), and (entmod...) functions.  If you are feeling inquisitive, have a look into using calls to vla-methods to do this with VLISP; less code overall but requires a better understanding of what is being done.

----------------------------------
If you are going to fly by the seat of your pants, expect friction burns.
"I don't know" is the beginning of knowledge, not the end.


Message 4 of 17
Anonymous
in reply to: dgorsman

But it also depends on how much code you want to type.  Your route adds more code in my opinion and you forgot to add the entupd function also in your post.  But to each his own.  You can have multiple programs that do the same thing.  But the true test if it works for you because that is the only thing that matters.

Message 5 of 17
Kent1Cooper
in reply to: pteague


@pjtjr wrote:
....What I want to do is take two items (light fixtures) and swap their positions on the drawing. ....

If they're Blocks, with the same kind of relationship to their insertion points so that you can use those as displacement definition points, then in simplest terms, you can do this:

 

(defun C:BS (/ b1 b2 b1ins b2ins) ; = Block Swap
  (setq
    b1 (car (entsel "\nSelect first Block: "))
    b2 (car (entsel "\nSelect second Block: "))
    b1ins (cdr (assoc 10 (entget b1)))
    b2ins (cdr (assoc 10 (entget b2)))
  )
  (command
    "_.move" b1 "" "none" b1ins "none" b2ins
    "_.move" b2 "" "none" b2ins "none" b1ins
  )
)

 

If they're something else, or if their relationships to their insertion points are too different, you could do something like find the middle of the bounding box of each, and use those to define the displacement, or maybe some other approaches.

Kent Cooper, AIA
Message 6 of 17
Anonymous
in reply to: Kent1Cooper

Just what I was thinking of but except you used move.  Nice, simple code and no need to wear out your fingers typing cause I am a terrible typist.  Fat finger syndrome.

Message 7 of 17
pteague
in reply to: Kent1Cooper

Kent, That is exactly what I was thinking. Just don't have the grasp on lisp to put it down that way. The blocks I'm dealing with are pretty simple so there shouldn't be an issue with the insertion point stuff. Thanks again.
Message 8 of 17
Kent1Cooper
in reply to: Anonymous


@Anonymous wrote:

What I would do is extract the insertions points, block names, xyz factors (if applicable), delete the objects (blocks), then reinsert the correct block at the correct insertion point.....


If you do it that way, you would also need to extract their rotation angles and Layers.  And if they have any Attributes, you would need to extract their values, and assign them again in the reinsertions somehow.  All of those complications are why I would be inclined to simply Move them.  That way, you don't need to get anything from them except their insertion points.  Scales and rotation and Layers and Attributes are retained, their Block names are irrelevant, draw order is unaffected if that matters, even something weirder such as that they were Inserted in different Coordinate Systems wouldn't matter, etc., etc.  But it does depend on the insertion points being valid as displacement definers.  Still, even if they're not, using something like the middles of their bounding boxes to Move them would still work without the need to extract and re-use any other information from them.

Kent Cooper, AIA
Message 9 of 17
Kent1Cooper
in reply to: pteague


@pjtjr wrote:
Kent, That is exactly what I was thinking. Just don't have the grasp on lisp to put it down that way. The blocks I'm dealing with are pretty simple so there shouldn't be an issue with the insertion point stuff. Thanks again.

You're welcome.  If you want to get more sophisticated about it, you can add an entity-type and/or a locked-Layer check on the selection, and error handling, and all that other stuff.

Kent Cooper, AIA
Message 10 of 17
pteague
in reply to: Kent1Cooper

My next question would be: How do I make the function work with two blocks that I have already selected?

Message 11 of 17
Anonymous
in reply to: Kent1Cooper

You are correct, Sir.  I was just looking at it as the OP stated them (blocks) being simple light fixtures and me assuming that they would be on the same layer and such.

Message 12 of 17
Kent1Cooper
in reply to: pteague


@pjtjr wrote:

My next question would be: How do I make the function work with two blocks that I have already selected?


If you have them in a selection set made with (ssget) or (ssadd) or something [let's call it ss], and there's nothing else in that selection set:

 

  (setq
    b1 (ssname ss 0))
    b2 (ssname ss 1))
....

 

and the rest the same.

 

If you have their entity names separately stored in variables, just remove the lines setting b1 & b2, and replace b1 & b2 in the rest of the code with the variable names you've already got.

Kent Cooper, AIA
Message 13 of 17
alanjt_
in reply to: Kent1Cooper

I used VL to avoid the issue of annotative blocks in some cad versions.

 

(defun c:Test (/ ss lst)
  (vl-load-com)
  (if (setq ss (ssget "_:L" '((0 . "INSERT"))))
    (if (eq (sslength ss) 2)
      (mapcar 'vla-put-insertionpoint
              (setq lst (mapcar '(lambda (i) (vlax-ename->vla-object (ssname ss i))) '(0 1)))
              (mapcar 'vla-get-insertionpoint (reverse lst))
      )
      (princ "Selection amount must be equal to 2!")
    )
  )
  (princ)
)

Message 14 of 17
tony1935e
in reply to: pteague

So....WE NEED THIS TO BE A COMMAND. WE NEED TO SWITCH OBJECT LOCATIONS ON THE FLY. HOW SIMPLE. HOW STUPID WE ARENT MAKING THINGS BETTER. OFFERING CONVOLUTED SOLUTIONS IS NOT HELPFUL. MAKE IT SO.

WE ALSO SOMETIMES NEED TO LIVE SORT WITH CLIENTS... NEEDING TO CHANGE COLORS to keep from convoluting that process.

Simple commands we dont have at our disposal. Thank you for not trying.
Message 15 of 17
Kent1Cooper
in reply to: tony1935e


@tony1935e wrote:
....WE NEED THIS TO BE A COMMAND. ....

AutoCAD may not yet have made a swapping command, but others have.  For instance, go here, and either use the one it's about at the top of the page [if it suits you] or get my latest Swap.lsp file attached at the fifth comment [which overcomes shortcomings of the top-of-page routine noted in earlier comments].  You can swap whole selection sets, not just individual objects, and of any type(s) [not just the Blocks that are the thrust of most of this thread].  And if either selection consists of just one object with some logical reference point [such as a Block's insertion point, or a Circle's center], you can just hit Enter to accept that offered default as the Swap reference location if you like, rather than picking a reference point.

 

[By the way, if your ranting is intended to prod AutoDesk into incorporating something like this into AutoCAD, this is not the place to do it.  This is a User Forum -- we're just other users like you.  There is some degree of participation by AutoDesk employees, but mostly along the lines of help in usage, not in the product-development arena.]

Kent Cooper, AIA
Message 16 of 17
tony1935e
in reply to: tony1935e

excellent! 🙂 I will go forth and do what is needed to get this all set up
using this. one of those wake up and rant rants lol.
Sincerely,

*Anthony, **ADB CAD Design*
*Phone: 480.297.1071*
*Email: adbcaddesign@gmail.com *
*Web: http://adbcaddesign.weebly.com/*
Message 17 of 17
Jt-Coco
in reply to: alanjt_

excellent !, it helps me a lot

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost