Hello, I have a file to start from which has objects who are put randomly in the 3D space.
I need the lowest point of all the objects to be on z=0. The objects need to stay like they are, and on the same distance of eachother. I want the macro to find out what is the lowest point and move everything to z=0. No x or y movements need to be made.
No flattening has to be done either.
Solved! Go to Solution.
Solved by Paul_Gander. Go to Solution.
Try this:
(defun C:LZ0 (/ ss n zobj zmin); = move objects so Lowest Z coordinate is at 0 (command "_.ucs" ""); force to World Coordinate System (setq ss (ssget "_X" (list (cons 410 (getvar 'ctab))))); everything in current space (repeat (setq n (sslength ss)) (vla-getBoundingBox (vlax-ename->vla-object (ssname ss (setq n (1- n)))) 'minpt 'maxpt ); ...getBoundingBox (setq zobj (caddr (vlax-safearray->list minpt)) zmin (if zmin (min zmin zobj) zobj); lowest Z coordinate of anything so far ); setq ); repeat (command "_.move" ss "" (list 0 0 (- zmin)) "") (princ) ); defun
If the lowest initial point on anything is above Z=0, it Moves them all down; if it's below, it Moves them all up.
It can be changed to have the User select things instead of doing everything in the current space, to reset the UCS if it wasn't already in World Coordinates [or to do it differently and not change the UCS at all], and the usual other enhancements.
If anything is on a locked Layer, it won't be Moved, but the code could include unlocking all Layers if that's appropriate.
Hello,
Thanks for your reply, but I can't use LISP, because of OEM restrictions. I use 2013 Autocad.
Very annoying! Could this be done solely with macro commands?
I have a macro to flatten all points, but that is not what I want.
@Anonymous wrote:
.... Could this be done solely with macro commands?....
I don't know of a way to do that solely with macro-command [or Script] operations. The Moving part is easy enough, but I can't picture a way of the finding of the lowest point on anything that doesn't require either:
A. stepping though a selection set and looking at each object, and AutoLisp functions are the only way I know to do that; or
B. if you want everything in the drawing [not a limited selection], the Z coordinate of the EXTMIN System Variable will give you that lowest elevation, but that also requires AutoLisp to extract, with (caddr (getvar 'extmin)). I realize you can't use the following either, but for any who can use AutoLisp and who are looking for such a routine, what my earlier routine does could actually be done with just this:
(defun C:LZ0 (); = move objects so Lowest Z coordinate is at 0 (command "_.ucs" "" ; force to World Coordinate System "_.zoom" "_extents" ; to update EXTMIN System Variable, just in case "_.move" "_all" "" (list 0 0 (- (caddr (getvar 'extmin)))) "" "_.zoom" "_previous"
"_.ucs" "_previous" ); command (princ) ); defun
[The Zoom Extents is in there because the EXTMIN & EXTMAX System Variables are reset farther outboard whenever something beyond their former values is added/Moved/Copied/etc., but when something is Erased/Moved/Trimmed etc. to make the Extents smaller, the System Variables do not reflect that pulling in until a Zoom All or Zoom Extents happens. The routine also sets the UCS back, in case it wasn't already in the WCS, which should be added into the previous version, too.]
But something like the earlier routine with modification on the selection set would still be needed if a User selection is desired, rather than everything in the current space.
Those EXTMIN and EXTMAX are very good return values, but read only.
That's a pitty for Macro use.
I read you can compile lisp programs and that you can run every compiled lisp program on any version.
How can I do that exactly?
@Anonymous wrote:
Those EXTMIN and EXTMAX are very good return values, but read only. That's a pitty for Macro use.
I read you can compile lisp programs and that you can run every compiled lisp program on any version.
How can I do that exactly?
The pity isn't that EXTMIN/EXTMAX are read-only, but that there doesn't seem to be a way to read them in a command macro [or in a Script] without the use of the AutoLisp (getvar) function.
I haven't done compiling [I just use things in their .lsp file formats], but I had the impression it was a way of protecting distributed routines from alteration or extraction of their code content by the unauthorized, rather than a way to get AutoLisp routines to work in OEM or LT versions that can't otherwise use AutoLisp. Others with more experience in such things may chime in....
This macro is equivalent to @Kent1Cooper's second lisp routine (post 4) and uses a diesel expression to extract the z-value from the EXTMIN system variable:
^c^c_.ucs;_world;_.zoom;_extents;_.move;_all;;_none;0,0,$m=$(index,2,$(getvar,extmin));_none;0,0,0;_.zoom;_previous;_.ucs;_previous
This variation allows the user to select which objects get tested and moved:
^c^c_.select;$m=$(if,$(getvar,cmdactive),\)_.ucs;_world;_.isolateobjects;_previous;;_.zoom;_extents;_.move;_previous;;_none;0,0,"$m=$(index,2,$(getvar,extmin));_none;0,0,0;_.unisolateobjects;_.zoom;_previous;_.ucs;_previous"
Be aware however that the EXTMIN and EXTMAX values are not always accurate and can be a few hundredths of a unit different to the objects' actual outermost co-ordinates. I do not know of a better way of obtaining that information though.
Woow! I'm gonna try this one!
I was getting into Diesel expressions myself.
Hope I can use them 'cause of the OEM restrictions.
Thank you very much!!!
Hello, I did some fast testing on my file!
It works perfectly! Woow. Though not completely accurate for some reason like you mentioned, but that is not so important. It is z+ instead of z- and that is ok.
I'm very happy with it! Thank you very much!
The 2 in index. Does it mean 2 digits after the comma?
Can somebody point me out to a good site were I can learn to use DIESEL expressions?
Thank you!
@Anonymous wrote:
The 2 in index. Does it mean 2 digits after the comma?
Can somebody point me out to a good site were I can learn to use DIESEL expressions?
Thank you!
I assume it's like AutoLisp's (nth) function, in which the first item in a list is item 0, and item 2 in an XYZ point list is the third item, i.e. the Z coordinate.
>Here< is the Diesel Functions Reference. In addition to the links at the bottom to related topics, in the broader Customization Guide Reference, there are additional Diesel entries about halfway down.
Hello,
In addition to this macro, I want to do the same to the X and Y coordinates.
I made this one:
^c^c_.ucs;_world;_.zoom;_extents;_.move;_all;;_none;$m=$(index,0,$(getvar,extmin),$m=$(index,1,$(getvar,extmin),$m=$(index,2,$(getvar,extmin));_none;0,0,0;-view;top;_zoom;extents;
But only the Z axis works. What am I doing wrong here?
What do you mean OEM restrictions is it just that you can not do Appload. What does drag and drop do dragging a lisp from explorer.
A test copy and paste this to command line (alert "mylisp is working") alert box should appear I copy and paste from notepad every day when writing code.
@Anonymous schrieb:
$m=$(index,0,$(getvar,extmin),$m=$(index,1,$(getvar,extmin),$m=$(index,2,$(getvar,extmin))
extmin is x,y,z
you trie to seprate each
x y z
and put a comma between x-y and Y-z
x,y,z
hmm, the last line looks like the first line: x,y,z => x,y,z
Crazy! ?
Use $M=$(getvar,EXTMIN)
instead of
$m=$(index,0,$(getvar,extmin),$m=$(index,1,$(getvar,extmin),$m=$(index,2,$(getvar,extmin))
like this:
^C^C^C_.UCS;_world;_TREEDEPTH;$M=$(getvar,TREEDEPTH);_.MOVE;_all;;_none;$m=$(getvar,EXTMIN);_none;0,0,0;_.-VIEW;_top;_.ZOOM;_extents
One hint more: You should UNLOCK ALL LAYERS before,objects on locked layers can't be modify by commands like move.
Sebastian
Can't find what you're looking for? Ask the community or share your knowledge.