Tom_D Posted August 7, 2012 Posted August 7, 2012 I am looking for a simple Lisp routine to change the Z value of all parts of all selected entities to a particular value. It would be used with simple contour information (a bunch of lines, polylines, or text). Ideally the command would ask for the selection set (or use set already selected), then ask for the new elevation (125'6" for example). Thanks, Tom Quote
BlackBox Posted August 8, 2012 Posted August 8, 2012 Seems pretty simple, and you've already planned out the routine... All you have left is to write the code. Test for an implied selection, and if none exist, prompt the user for a new selection set, and an elevation difference. Then iterate the selection set moving the selection set. Which part are you hung up on my friend? Quote
Tom_D Posted August 8, 2012 Author Posted August 8, 2012 it is this part: "Then iterate the selection set moving the selection set." I can do the rest. Tom Quote
BIGAL Posted August 8, 2012 Posted August 8, 2012 Rather than give you the code heres the commandsto be used start with Sslength ss then repeat then Sname ss x move obj 0,0,0 0,0,z end repeat also maybe foreach Quote
Tom_D Posted August 8, 2012 Author Posted August 8, 2012 My struggle is the exact code for setting the Z value in the entity,especially for entities that have multiple vertices (Lines and Polylines). Isense nested loops: outer for each entity, inner for each vertex. Quote
Dadgad Posted August 8, 2012 Posted August 8, 2012 You could do this with the CHANGE command pretty easily, if I am not mistaken. Command: CHANGE Select objects: Specify opposite corner: 210 found Select objects: Specify change point or [Properties]: p Enter property to change [Color/Elev/LAyer/LType/ltScale/LWeight/Thickness/TRansparency/Material/Annotative]: e Specify new elevation : 127 Quote
Tom_D Posted August 8, 2012 Author Posted August 8, 2012 THX. I'll give it a try (a bit too easy - I should have though of it). I assumed it needed to be much more entity and vertex specific. I'll let you know how it goes. Probably tomorrow... Quote
BlackBox Posted August 8, 2012 Posted August 8, 2012 Tom, this can be done simply by MOVE command. Consider moving an SS from 0,0,0 to 0,0,10. To better learn what you need to do to properly code, simply perform the task manually then transcribe into code based on your input. Be sure to test the code in multiple situations to remove any bugs. HTH Quote
Tom_D Posted August 8, 2012 Author Posted August 8, 2012 Both the Move and Change/Elev commands work. The Move command is more complicated because one needs to figure out the elevation of the entity to begin with. The limitation of the Change command is that it doesn't do anything if there are multiple Z values in an entity (a vertically sloped line for example). For the short term, the Change approach is working. I just need to run flatten first. Ideally I'd like to find a solution where I could actually change the Z values rather than deal with each entity as a whole. Thx... Quote
David Bethel Posted August 8, 2012 Posted August 8, 2012 As you are finding out, your's isn't a simple problem. CHANGE has some major limitations: It cannot deal with entities that have varying Z axis values (LINES 3DFACES, HEAVY POLYLINES MESHES, 3DPOLYLINES ) The entity must be in the current UCS With MOVE you must 1st figure out the current elevation and then calculate the new one. Again entities with various elevations must be dealt with, LWPOLYLINE have their own properties ( group 38 ) (entmod) could also do the trick, you just have to watch out for sequential entities ( INSERTs with ATTRIBute and heavy POLYLINES ) (and (setq ss (ssget)) (while (setq en (ssname ss 0)) (setq ed (entget en)) ;;;DO YOUR THING HERE.... (ssdel en ss))) Hope this helps you getting a little further along. -David Quote
Tom_D Posted August 9, 2012 Author Posted August 9, 2012 For the time being I am going with the easy route - using Change / Elev. Here is the code, with several variations (on my system, the code is all in a single file: SetZ.lsp): SZ - Sets selected entities to the specified elevation SZC - Sets selected entities to the specified elevation, Changes the modified entities to the current layer SZ100 - Sets selected entities to Elevation 100' SZ150 - Sets selected entities to Elevation 150' SZ200 - Sets selected entities to Elevation 200' SZc100 - Sets selected entities to Elevation 100', Changes modified entities to current layer SZc150 - Sets selected entities to Elevation 150', Changes modified entities to current layer SZc200 - Sets selected entities to Elevation 200', Changes modified entities to current layer LSZ - reloads SetZ.lsp if in one of the Support File paths Tom ;;================== ;; ;; SZ - Set Z to user input value ;; ;; Changes Elevations of selected entities ;; (not "Z" values per se) ;; If the Z values are not all the same, no action. ;; ;; Written by Tom Deering ;; ; Rev0 2012-08-08 Initial Code ; ; ;;================== ; (defun c:SZ (/ current_layer ss1 s) ; Set Z (princ "\nSet Z for selected entities...\n") (setvar "cmdecho" 0) (setq ss1 (ssget)) (if ss1 (progn (setq s (getstring "New Elevation? >")) ; Set selected to new elevation (command ".change" ss1 "" "P" "E" s "") (princ (strcat "\nEntities changed to elevation: " s )) ) ) ; (princ) ) ; ; (defun c:SZc (/ current_layer ss1 s) ;Set Z with Change to Current Layer (setq current_layer (getvar "clayer")) (princ "\nSet Z for selected entities, w/ Change to curr layer...\n") (setvar "cmdecho" 0) (setq ss1 (ssget)) (if ss1 (progn (setq s (getstring "New Elevation? >")) ; Set selected to new elevation (command ".change" ss1 "" "P" "E" s "") ;Change to current layer (command ".change" ss1 "" "P" "LA" current_layer "") (princ (strcat "\nEntities changed to elevation: " s "\nEntities changed to current layer: " current_layer)) ) ) ; (princ) ) ; ; (defun _SZCx ( elev / current_layer ss1 s) ;To Be Called from Driver Function: (defun c:SZC100 () (_SZCx "100'") (princ) ) (setq current_layer (getvar "clayer")) (princ (strcat "\nSetting Z to: " elev "(w/change to curr layer)") ) (setvar "cmdecho" 0) (setq ss1 (ssget)) (if ss1 (progn (setq s elev) ; Set selected to new elevation (command ".change" ss1 "" "P" "E" s "") ;Change to current layer (command ".change" ss1 "" "P" "LA" current_layer "") (princ (strcat "\nEntities changed to elevation: " s "\nEntities changed to current layer: " current_layer)) ) ) ; (princ) ) ; ; (defun _SZx ( elev / current_layer ss1 s) ;To Be Called from Driver Function: (defun c:SZC100 () (_SZx "100'") (princ) ) (princ (strcat "\nSetting Z to: " elev "(w/change to curr layer)") ) (setvar "cmdecho" 0) (setq ss1 (ssget)) (if ss1 (progn (setq s elev) ; Set selected to new elevation (command ".change" ss1 "" "P" "E" s "") (princ (strcat "\nEntities changed to elevation: " s )) ) ) ; (princ) ) ; ; ; ;Functions to set to specific elevations ; ;Set Z - no layer change (defun c:SZ100 () (_SZx "100'") (princ) ) (defun c:SZ150 () (_SZx "150'") (princ) ) (defun c:SZ200 () (_SZx "200'") (princ) ) ; ;Set Z - Change modified to cuttent layer (defun c:SZC100 () (_SZCx "100'") (princ) ) (defun c:SZC150 () (_SZCx "150'") (princ) ) (defun c:SZC200 () (_SZCx "200'") (princ) ) ; ; ; Command to reload this file (defun c:LSZ ( / s) (setvar "cmdecho" 0) (setq s "SetZ.lsp") (if (findfile s) (progn (load s) (princ (strcat "\n" s " reloaded...\n")) ) (princ (strcat "\n" s " NOT reloaded...\n")) ) ; (princ) ) ; ; (princ) Quote
BlackBox Posted August 9, 2012 Posted August 9, 2012 Beware of s = nil, and you might consider using an error handler to restore CMDECHO if the user cancels, or right clicks when prompted for s. Quote
Tom_D Posted August 9, 2012 Author Posted August 9, 2012 Thanks, I know I skimped on the error detection, I'll keep and eye out on how it gets used (distribution will be quite small). Tom Quote
BIGAL Posted August 10, 2012 Posted August 10, 2012 Re s=nil (setq s (getstring "New Elevation? >")) (if (= s nil)(setq s 0.0)) ; if user presses the enter key Quote
BlackBox Posted August 10, 2012 Posted August 10, 2012 Thanks, I know I skimped on the error detection, I'll keep and eye out on how it gets used (distribution will be quite small). Tom Here's a fun little example... No need to manipulate the CMDECHO system variable, as this code uses Visual LISP's Move Method in lieu of the Move or Change Commands. (vl-load-com) (defun c:SELEV () (c:SetElevation)) (defun c:SetElevation (/ *error*) (princ "\rSETELEVATION ") (defun *error* (msg) (if acDoc (vla-endundomark acDoc) ) (cond ((not msg)) ; Normal exit ((member msg '("Function cancelled" "quit / exit abort"))) ; <esc> or (quit) ((princ (strcat "\n** Error: " msg " ** "))) ; Fatal error, display it ) (princ) ) ((lambda (acDoc / ss el startPoint endPoint) (vla-startundomark acDoc) (if (and (setq ss (ssget "_:L")) (setq el (getreal "\nAmount to add to all elevations: ")) (setq startPoint (vlax-3d-point '(0. 0. 0.))) (setq endPoint (vlax-3d-point (list 0. 0. el))) ) (progn (vlax-for x (setq ss (vla-get-activeselectionset acDoc)) (vla-move x startPoint endPoint) ) (vla-delete ss) (*error* nil) ) (cond (ss (*error* "No amount specified")) ((*error* "Nothing selected")) ) ) ) (vla-get-activedocument (vlax-get-acad-object)) ) ) Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.