Need lisp to move all to 0,0,0, then back to original coords later

Need lisp to move all to 0,0,0, then back to original coords later

mpa-la
Advocate Advocate
7,578 Views
27 Replies
Message 1 of 28

Need lisp to move all to 0,0,0, then back to original coords later

mpa-la
Advocate
Advocate

I use photometric software that glitches out if you work too far from 0.  All the cad files I use are in a coordinate system far from zero, so I have to move everything to get the photometric program to work.  I have created a lisp routine that moves everything from a specific point towards zero, then a reversal program that moves everything back.  This works for most of my projects which are within a limited geographic area, but if I'm working on a project elsewhere, it doesn't work.  Many many of my projects get xrefed together, and I work with consultants that use a specific coordinate system, so moving things permanently to zero is not an option.  I want a lisp routine where I can snap to some object in the drawing, and it moves everything in the drawing so that object point I snapped to is now at zero.  Later on I could reverse the process with a "reverse" command that would refer back to that point and put it back where it came from.  I was thinking maybe it could place a text entity at the snap point with the coordinates in it, then when you issue the reverse command, it uses the insert point of the text, and the text values of the object to move it back where it belongs.  That is my "I don't know how to write lisps" theory, there is probably a much better way.  Any ideas, or anything already out there?

 

Here's the lisp I currently use if anyone is interested.

;--------* Move town objects toward zero for visual
;
(defun c:mfv (/ fvm)
(prompt "\nSelect objects to move closer to zero")
(setq fvm (ssget))
(command "move" fvm "" "0,0,0" "@-640000,-1623000")
(princ)
)
(princ)
;
;--------* Move town objects back to original coords
;
(defun c:btv (/ tvc)
(prompt "\nselect objects to move away from zero")
(setq tvc (ssget))
(command "move" tvc "" "0,0,0" "@640000,1623000")
(princ)
)
(princ)

0 Likes
7,579 Views
27 Replies
Replies (27)
Message 2 of 28

Sea-Haven
Mentor
Mentor

There is another post about move and it can be done simply.

 

 

(command "move" "all" "" (setq appoint (getpoint "Pick point near object")) '(0.0 0.0))
 
(command "move" "all" "" '(0.0 0.0) appoint)

 

0 Likes
Message 3 of 28

dbhunia
Advisor
Advisor

In that case I suggest you to maintain a separate "LOG File (say a TEXT File)" for each Drawing, containing the "ENTITY HANDLE" of ALL selected objects of that "SELECTION SET" corresponding to the "BASE POINT" for each run of "mfv". Like.......

 

base_point1,Handle1,Handle2,Handle3......(For 1st MOVE operation)

base_point2,Handle4,Handle5,Handle6......(For 2nd MOVE operation)

so on.......


Now whenever you run "btv", first go through the each line of the PARTICULAR "LOG File" for that PARTICULAR Drawing & Read/Get each "ENTITY HANDLE" corresponding to the "BASE POINT" of that line & put back the ENTITY to its original location.......

 

 


Debashis Bhunia
Co-Founder of Geometrifying Trigonometry(C)
________________________________________________
Walking is the First step of Running, Technique comes Next....
0 Likes
Message 4 of 28

mpa-la
Advocate
Advocate

@Anonymous.heaven, how do you move it back to where it came from?  That's the part I can't figure out.

0 Likes
Message 5 of 28

mpa-la
Advocate
Advocate

@dbhuniaI don't know how to write real lisps, I can only really write ones that function like macros.  What you're proposing sounds interesting, but way above my pay grade.  I feel like a standalone solution (no log file connected to specific dwg) would be more functional in my situation.  I create lots of new dwgs from the photometric program that need to get moved back to the right coordinates.

0 Likes
Message 6 of 28

ronjonp
Mentor
Mentor

Could you copy them to 0,0 run your calcs then delete? Do you have a sample dawing?

 

Scratch that .. try this. See if this works for you. It consolidates two commands by remembering a global point that gets set 🙂 Move your stuff to 0,0,0 with 'mfv' run your software then 'mfv' again and pick the items to move back home.

(defun c:mfv (/ fvm)
  (if *globalpoint*
    (princ "\nSelect objects to move back to their happy place :)")
    (princ "\nSelect objects to move closer to zero")
  )
  (if (setq fvm (ssget ":L"))
    (if	*globalpoint*
      (progn (command "_.Move" fvm "" '(0 0 0) *globalpoint*) (setq *globalpoint* nil))
      (command "_.Move" fvm "" (setq *globalpoint* (getvar 'viewctr)) '(0 0 0))
    )
  )
  (princ)
)

 

0 Likes
Message 7 of 28

dbhunia
Advisor
Advisor

@mpa-la  you post a sample file ........ I shall see it in morning.......

 

 


Debashis Bhunia
Co-Founder of Geometrifying Trigonometry(C)
________________________________________________
Walking is the First step of Running, Technique comes Next....
0 Likes
Message 8 of 28

mpa-la
Advocate
Advocate

@ronjonpIt doesn't seem to be working.  I tried it on the attached drawing (which is far from 0,0,0) and it just moves stuff over a little.  Plus, it has to work if the drawing has been closed or renamed.

0 Likes
Message 9 of 28

mpa-la
Advocate
Advocate

@dbhuniaThe drawings I need to do this with are nothing special, but here you go.  It will have to work if the drawing is closed, reopened, or renamed.

0 Likes
Message 10 of 28

Moshe-A
Mentor
Mentor

@mpa-la  hi,

 

Here is my version and it is based on using anonymous groups.

you start with MGRP (Move Group) command which let you Select objects + Base point

the point is than saved in the description field of the group definition.

 

When you want to restore, invoke RGRP (Restore Group) command.

the program scan the groups in database and each group that has a point in it's description is restored back.

than the group definition is deleted.

 

Some notes to remember:

1. Run the commands in WCS only.

2. Feel free to modify the group (add or remove objects) but do not delete the group or explode it. if you explode? the restore is on you manually.

3. You can run the restore command even after reopening the drawing but not after WBLOCK the drawing, cause as far as i know, groups are vanished after wblock 😀

 

enjoy

moshe

 

 

 

; Move group
(defun c:Mgrp (/ point->string  ; local function
	        ss base)

 (defun point->string (pt)
  (substr (apply
            'strcat
            (mapcar
              '(lambda (n)
                (strcat "," (rtos n 2))
               )
              pt 
            )
         )
  2)
 ); point->string 

 (setvar "cmdecho" 0)
 (command "._undo" "_begin")
  
 (if (and
       (setq ss (ssget))
       (setq base (getpoint "\nBase point to move: "))
     )
  (progn
   (initcommandversion) 
   (command "._group" "_description" (point->string  base) "_si" ss) 
   (command ".move" "_si" "_last" "_none" base "_none" "0,0,0")
  ); progn
 ); if

 (command "._undo" "_end")
 (setvar "cmdecho" 1)

 (princ) 
); c:Mgrp


; Restore group
(defun c:Rgrp (/ is_point string->point ; local functions
	         tbl0 tbl1 elist desc base grp_name)

 ; return T if str is a number 
 (defun is_point (str)
  (not
   (vl-some
    '(lambda (n)
      (not
       (or
        (= n 44)
        (= n 46)
        (and
         (>= n 48) 
         (<= n 57)
        )
       ); or
      ); not
    ); lambda
    (vl-string->list str)
   ); vl-some
  ); not
 ); is_point
  
 ; convert a string to point, return a point or nil if fail 
 (defun string->point (str / p lst)
  (while (setq p (vl-string-position 44 str))
   (setq lst (cons (atof (substr str 1 p)) lst))
   (setq str (substr str (+ p 2)))
  ); while

  (setq lst (cons (atof str) lst))
   
  (if (or
	(= (vl-list-length lst) 2)  
	(= (vl-list-length lst) 3)
      )	
   (reverse lst)
  )
 ); string->point

 (setvar "cmdecho" 0)
 (command "._undo" "_begin")
  
 (foreach item (setq tbl0 (dictsearch (namedobjdict) "acad_group"))
  (if (= (car item) 3)
   (progn
    (setq tbl1 (member item tbl0))
    (setq elist (entget (cdr (cadr tbl1))))
    (if (and
	  (is_point (setq desc (cdr (assoc '300 elist))))
	  (setq base (string->point desc))
	)
     (progn
      (setq grp_name (cdr item)) 
      (command "._move" "_si" "_group" grp_name "_none" "0,0,0" "_none" base)
      (command "._group" "_explode" grp_name)
     ); progn
    ); if  
   ); progn
  ); if
 ); foreach

 (command "._undo" "_end")
 (setvar "cmdecho" 1)

 (princ) 
); c:Rgrp

 

 

0 Likes
Message 11 of 28

ronjonp
Mentor
Mentor

@mpa-la wrote:

@ronjonpIt doesn't seem to be working.  I tried it on the attached drawing (which is far from 0,0,0) and it just moves stuff over a little.  Plus, it has to work if the drawing has been closed or renamed.


The issue I see with that drawing is the base has been changed to: -647812.8597,-1629482.4426,0.0000

 

If you change it to 0,0,0 it works but still does not keep the point over sessiosn. Perhaps what @Moshe-A  posted will work for you.

 

Have you thought about contacting the authors of your photometric software to report this bug?

0 Likes
Message 12 of 28

mpa-la
Advocate
Advocate

@ronjonpAhh, you're right.  I wonder how that happened, I started that from scratch...

0 Likes
Message 13 of 28

mpa-la
Advocate
Advocate

@ronjonpAnd, I've been using that sofware for years and years, and all they have to say about the coordinate thing is "Sorry, maybe they'll fix it in the next version". 

0 Likes
Message 14 of 28

dbhunia
Advisor
Advisor

 @mpa-la  I told you the process keeping this thing in mind ..................... It will work if the drawing is closed, reopened, or renamed. 

 

Now it is 02:00 AM here ............... will see it later, if the post still remains open.....


Debashis Bhunia
Co-Founder of Geometrifying Trigonometry(C)
________________________________________________
Walking is the First step of Running, Technique comes Next....
0 Likes
Message 15 of 28

ronjonp
Mentor
Mentor

What is the name of the software?

0 Likes
Message 16 of 28

mpa-la
Advocate
Advocate

@Moshe-AThat is an interesting approach.  One thing I didn't mention about my process for the sake of simplicity, but it looks like it's an important factor.  I make a separate sacrificial base drawing that I move to zero, import that into the photometric software, do my light layout, then all I export out of the photometric software is the light locations, and they go into a dwg by themselves.  It's those "new" objects that I have to move back to the original drawing coordinates so that I can then insert them into my actual project base in their correct locations.  I was planning on just copying the object I was using to "anchor" the move out of the sacrificial base, pasting it to original coordinates into the drawing with the lights, then using that to move it back to the correct coordinate system.  For that reason, I don't think your method will work for me.  I'm sorry I wasn't more specific from the outset.

0 Likes
Message 17 of 28

mpa-la
Advocate
Advocate

@ronjonpVisual 3D

0 Likes
Message 18 of 28

Moshe-A
Mentor
Mentor

@mpa-la ,

 

pity for me 😂

Message 19 of 28

Sea-Haven
Mentor
Mentor

The second line in what I posted is the put it back just did not wrap them in defuns etc.

 

Have you thought about putting a dummy block on a no plot layer which has two attributes X & Y that are the 1st pick point, when you push it back it can erase that block. Just edit the two lines of code to add the insert block, read X Y from block etc. You can create the block if not exist, like wise purge it out after delete.

0 Likes
Message 20 of 28

dbhunia
Advisor
Advisor

Try this...... (This is an example, what I was talking) need more workout for this lisp.......

 

(defun C:Move_To (/ SS Point_From List Obj_Hnd Dest_File Text_Write Dest_File_Path)
	(setvar 'cmdecho 0)
	(prompt "\nSelect objects to move closer to zero")
	(setq SS (ssget))
	(setq Point_From (getpoint "\nSelect Base Point: "))
	(setq List (cons Point_From List))
	(setq Text_Write (strcat (rtos (car Point_From)) "#" (rtos (cadr Point_From)) "#" (rtos (caddr Point_From))))
	(foreach e (vl-remove-if 'listp (mapcar 'cadr (ssnamex SS)))
		(setq Obj_Hnd (cdr (assoc 5 (entget e))))
		(setq List (cons Obj_Hnd List))
		(setq Text_Write (strcat Text_Write "," Obj_Hnd))
	)
	(setq Dest_File_Path "D:/Move_Object_Logger.txt");;Set the terget Folder for Logger (Keep it same for both)
	(if (setq Dest_File (open Dest_File_Path "A"))
		(progn
			(write-line Text_Write Dest_File)
			(close Dest_File)
		)
	)
	(command "move" SS "" Point_From "0,0,0")
	(setvar 'cmdecho 1)
(princ)
)
(defun C:Move_Back (/ Dest_File_Path Dest_File Line Pos Point_To Obj_Hnd_Str Hnd Obj_Hnd_List Ent)
	(setvar 'cmdecho 0)
	(setq Dest_File_Path "D:/Move_Object_Logger.txt");;Set the terget Folder for Logger (Keep it same for both)
	(if (setq Dest_File (open Dest_File_Path "R"))
		(progn
			(while (setq Line (read-line Dest_File))
				(setq Pos (vl-string-search "," Line))
				(setq Point_To (substr Line 1 Pos))
				(setq Obj_Hnd_Str (substr Line (+ 2 Pos) (1+ (strlen Line))))
				(while (vl-string-search "#" Point_To)
					 (setq Point_To (vl-string-subst "," "#" Point_To))
				)
				(setq Obj_Hnd_List nil)
				(while (vl-string-search "," Obj_Hnd_Str)
					(setq Pos (vl-string-search "," Obj_Hnd_Str))
					(setq Hnd (substr Obj_Hnd_Str 1 Pos))
					(setq Obj_Hnd_Str (vl-string-subst "" (strcat Hnd ",") Obj_Hnd_Str))
					(setq Obj_Hnd_List (cons Hnd Obj_Hnd_List))
				)
				(setq Obj_Hnd_List (cons Obj_Hnd_Str Obj_Hnd_List))
				(foreach Hnd_To_Move Obj_Hnd_List
					(if (entget (setq Ent (handent Hnd_To_Move)))
						(command "_.move" Ent "" "_none" "0,0,0" "_none" Point_To)
					)
				)
			)
			(close Dest_File)
			(vl-file-delete Dest_File_Path)
		)
	)
(setvar 'cmdecho 1)
(princ)
)

Limitations.......

 

1   will not work in multiple Model/Paper Space.

2   If you think, at a time you should work on multiple drawing ...... and at end of the day you should use this lisp to move back all objects........then you have to maintain different Logger for each drawing.

3   For the above case you have to change the logger file name or Folder for each drawing.

4   If you rename any drawing it will work, but you have to mention the exact Logger file Name & Location corresponding to that drawing.

5   If your Drawing is linked with any database & you update the drawing then HANDLE may change in that case this lisp will bounce (As I do not know Visual 3D).

6   If you remove any moved object and purge the drawing ......... continue your work ........ for that case if CAD assign the HANDLE of the deleted Block to another Object then lisp will miss behave.

.......

 

There is more while you want to Restore Back all the moved objects after Closing/Renaming the drawing.......

 

 


Debashis Bhunia
Co-Founder of Geometrifying Trigonometry(C)
________________________________________________
Walking is the First step of Running, Technique comes Next....
0 Likes