Jump to content

Recommended Posts

Posted

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

Posted

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?

Posted

it is this part: "Then iterate the selection set moving the selection set." I can do the rest.

 

Tom

Posted

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

Posted

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.

Posted

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

Posted

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

Posted

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

Posted

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

Posted

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

Posted

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)

Posted

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.

 

:thumbsup:

Posted

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

Posted

Re s=nil

 

(setq s (getstring "New Elevation? >"))
(if (= s nil)(setq s 0.0)) ; if user presses the enter key

Posted
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))
 )
)

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...