Autolisp: OSNAP and dist command

Autolisp: OSNAP and dist command

Anonymous
Not applicable
2,923 Views
28 Replies
Message 1 of 29

Autolisp: OSNAP and dist command

Anonymous
Not applicable

Good morning,

 

I'm back with this weird thing happening.

 

I'm measuring distance from a point on XY and the imprint of a line from that point (200 units tall) with a solid tall 152.40 units.

Strangely in my computer works just fine measuring 152.40 and on other two computers it shows 200.

 

I think OSNAP is not snapping on the solid on theirs, but checked the options and they look the same to me.

 

Can anyone help? Thanks in advance.

 

below is my code:

(defun C:DAVIDE(/ var val p c solidSS ent linevar)

    (setq var '("Osmode" "Expert")
          val  (mapcar 'getvar var))
    (mapcar 'setvar var '(0 1))

; TURN OFF SOLID LAYER
    (command "_.-layer" "OFF" "IMAGINARY SURFACE" "" "")

; ENTER LAT, LON OF THE POINT OF INTEREST
    (command "geomarklatlong" PAUSE PAUSE " ")

; SELECT NODE JUST CREATED
    (setq p (cdr (assoc 10 (entget(ENTLAST)))))

; DRAW LINE 200 UNITS TALL ORTHO TO XY FROM NODE
    (command "_.line" p (list (car p) (cadr p) (+ (caddr p) 200)) "")
    (setq linevar (ssget "_L"))
    (mapcar 'setvar var val)

; TURN ON SOLID LAYER
    (command "_.-layer" "ON" "IMAGINARY SURFACE" "")

; IMPRINT LINE WITH SOLID
    (setq solidSS (ssget "X" (list '(0 . "3DSOLID")(cons 8 "IMAGINARY SURFACE")))) ; this will get a selection set containing the solid
    (setq ent (ssname solidSS 0)) ; retrieve first entity in the list (there should be only 1)
    (command "_.imprint" ent linevar "_Y" "")

; SELECT IMPRINTED POINT
    (setq c (getvar "lastpoint"))

; CALCULATE DISTANCE FROM ORIGINAL POINT TO THE IMPRINTED POINT
    (command "dist" p c)
    (if (> (getvar 'distance) 152.40)
   (alert (strcat "Error"))
 (alert (strcat "Max heigth is :  " (rtos (getvar 'distance) 2 3) " mt  or  " (rtos (* 3.2808399 (getvar 'distance)) 2 3) " ft")))
    (princ)
)

0 Likes
Accepted solutions (1)
2,924 Views
28 Replies
Replies (28)
Message 2 of 29

DannyNL
Advisor
Advisor

Try this.

 

I've added OSNAPCOORD to your system variables to be set to 1 (keyboard entry overrides running object snap at all time) and moved your restore of the system variables to the end of your code. In your own code you are currently measuring distance after you restored the system variables (incl. object snaps), which could mess things up.

 

(defun C:DAVIDE(/ var val p c solidSS ent linevar)
    (setq var '("Osmode" "Expert" "Osnapcoord")
          val  (mapcar 'getvar var))
    (mapcar 'setvar var '(0 1 1))
; TURN OFF SOLID LAYER
    (command "_.-layer" "OFF" "IMAGINARY SURFACE" "" "")
; ENTER LAT, LON OF THE POINT OF INTEREST
    (command "geomarklatlong" PAUSE PAUSE " ")
; SELECT NODE JUST CREATED
    (setq p (cdr (assoc 10 (entget(ENTLAST)))))
; DRAW LINE 200 UNITS TALL ORTHO TO XY FROM NODE
    (command "_.line" p (list (car p) (cadr p) (+ (caddr p) 200)) "")
    (setq linevar (ssget "_L"))
    
; TURN ON SOLID LAYER
    (command "_.-layer" "ON" "IMAGINARY SURFACE" "")
; IMPRINT LINE WITH SOLID
    (setq solidSS (ssget "X" (list '(0 . "3DSOLID")(cons 8 "IMAGINARY SURFACE")))) ; this will get a selection set containing the solid
    (setq ent (ssname solidSS 0)) ; retrieve first entity in the list (there should be only 1)
    (command "_.imprint" ent linevar "_Y" "")
; SELECT IMPRINTED POINT
    (setq c (getvar "lastpoint"))
; CALCULATE DISTANCE FROM ORIGINAL POINT TO THE IMPRINTED POINT
    (command "dist" p c)
    (if (> (getvar 'distance) 152.40)
   (alert (strcat "Error"))
   (alert (strcat "Max heigth is :  " (rtos (getvar 'distance) 2 3) " mt  or  " (rtos (* 3.2808399 (getvar 'distance)) 2 3) " ft")))
   (mapcar 'setvar var val)
   (princ)
)
Message 3 of 29

Anonymous
Not applicable

thanks Danny,

 

now it is not working in mine either 😞

It's measuring to the end of the line instead to the imprint.

0 Likes
Message 4 of 29

DannyNL
Advisor
Advisor

That is strange. Almost sounds that your code is depending on some OSNAPS being set/used instead of bare coordinates.

The modification I've made didn't change a thing in measuring except to make sure you would use the exact coordinates instead of altered coordinates by OSNAPS.

 

Can you post a sample drawing with before and after and exactly what should be measured, so I'm able to test the code on my side in the way you want it to be used?

0 Likes
Message 5 of 29

Anonymous
Not applicable

And this is exactly the problem. I need it to use the altered coordinates of the OSNAP.

0 Likes
Message 6 of 29

DannyNL
Advisor
Advisor

In your original code you also set OSMODE to 0 and this means you turn off all running object snaps. Also OSNAPCOORD needs to be 0 to ensure that OSNAPS are applied to used coordinates.

 

So the reason why it probably works (or worked) on your PC is because you have all the necessary settings by default and your colleagues probably don't. Never assume all PC's you want to run a routine on have the same settings, but always make sure to set these in the routine and restore the old values at exit.

 

What are the OSNAPS you are depending on?

If that is clear we can set the value of OSMODE to the right setting it needs at the beginning of the routine.

Message 7 of 29

Anonymous
Not applicable

Thanks again Danny,

 

I'm not very familiar with AutoCAD, I'm a programmer.

 

I need to measure the height of a solid in a point created with geomarklatlong.

That is why I create the first point with geomarklatlong, then create a vertical line (200 units tall) to imprint the solid.

And at the end measure the distance from the original point to the imprint.

For some reason in my computer it measure the right distance and in theirs it measure the distance do the end of the line instead of to the imprint.

 

I need this to work for everyone so I probably need to set the OSNAPS and OSMODE in the code.

 

I hope this helps.

 

0 Likes
Message 8 of 29

DannyNL
Advisor
Advisor

David,

 

OK, that's no problem and we'll try to get the code working on any PC you want Smiley Happy

 

Can you maybe post a sample drawing for testing purposes (just erase everything if needed and only leave what is necessary for testing).

And do you know what value OSMODE has before you run the command? Just type in OSMODE on the command line and it will give you an integer value in return.

 

I can guess what values are needed but with the sample drawing and OSMODE value I'll be able to know for sure.

0 Likes
Message 9 of 29

Anonymous
Not applicable

Below the drawing and the lisp code.

 

Thanks!

0 Likes
Message 10 of 29

DannyNL
Advisor
Advisor

I'm noticing Civil 3D proxy objects in the drawing. As I don't have Civil 3D available, any chance you can convert these to normal 3D solids?

0 Likes
Message 11 of 29

DannyNL
Advisor
Advisor

Never mind.....my graphics card was playing funny tricks and switching to another visual style solved the display issues.

I'll try to look into it.

0 Likes
Message 12 of 29

Anonymous
Not applicable

Awesome , thanks!

0 Likes
Message 13 of 29

DannyNL
Advisor
Advisor

Ok, I'm getting an error in the imprint step as the solid and line doe not intersect.

What values are you using for the GEOMARKLONG as whatever I'm trying the location point and line are drawn far away from the solid that exists in the drawing?

0 Likes
Message 14 of 29

Anonymous
Not applicable

try

37.407391

14.917833

 

0 Likes
Message 15 of 29

DannyNL
Advisor
Advisor

Ok, I'm 99,.9% sure it has to do with the set OSNAP on your and your colleagues system. I'm not sure yet what the OSNAP setting should be, because I'm getting different results depending on how far I'm zoomed in to the solid.

 

Can you tell me a bit more why you need to imprint the line in the solid?

Do you need it for reference later or do you just want to measure the height of the solid? Because in the example you provided the solid is 152.4 in height,  the line that is drawn is 200 and the imprinted line will get the same height of the solid of 152.4. So the measurement of the imprinted line/edge is the same as the height of the solid.

 

If you only need to get the height of the solid and all solids you are working with have a flat top surface like in the provided example, there may be an easier way to get the info you need.

0 Likes
Message 16 of 29

Anonymous
Not applicable

Hi Danny,

 

you got the point. I need to know the height of the solid in any given point (given by the user with lat long coordinates). The max height is 152.40 but it is not all the same height (as you can see from the picture attached). that is why i was doing it this way.

0 Likes
Message 17 of 29

Anonymous
Not applicable

If it helps you troubleshooting the issue, after running your code it is NOT working on my computer anymore. Even after using  my original code. So we must have set some variable back to default (like on my coworkers computers) and we have to figure out which ones were and what were the values that made the code work.

0 Likes
Message 18 of 29

DannyNL
Advisor
Advisor

David,

 

Now knowing what you are exactly looking for I'm not sure if there is a solution.

 

As far as I can tell the times you did get the right height were just a lucky shot. I'm not able to get any reliable measurement each and every time as the distance measured will be heavily dependent on how far you are zoomed in or not.

The LASTPOINT variable doesn't have the right coordinate at any point during execution and never holds a coordinate which will measure a height of 152.4 as in the example. So the times you did get the right height reported were basically a coincidence and can not be trusted 100% in all circumstances.

 

Although the endpoints of the imprinted edge can be selected manually with the endpoint object snap, so far I'm unable to do so automatically as there is no LISP way to select an edge in a solid without any user interaction.

I'll look a bit further but this is something that might be impossible to achieve with LISP and will need some more powerful .NET coding.

0 Likes
Message 19 of 29

DannyNL
Advisor
Advisor
Accepted solution

OK, new approach and I think I have a solution.

 

As it is not possible to select an edge within a solid with LISP, I've switched from using a line to a second solid. The code below will draw a cylinder at the marker point with a height of 500. A copy of the original existing solid is subtracted from this new cylinder. I know the original height and the new height of the cylinder. By subtracting these values you know the height of the original solid at that location.

 

This should work independent on zoom factor and/or object snaps. Please let me know if you see any problems.

 

(defun C:DAVIDE(/ var val p base_height ref temp_copy solidSS height)
    (setq var '("Osmode" "Expert")
          val  (mapcar 'getvar var))
    (mapcar 'setvar var '(0 1))
; ENTER LAT, LON OF THE POINT OF INTEREST
    (command "geomarklatlong" PAUSE PAUSE " ")
; SELECT NODE JUST CREATED
    (setq p (cdr (assoc 10 (entget(ENTLAST)))))
; DRAW REFERENCE CYLINDER WIT BASE HEIGHT
    (setq base_height 500)
    (command "_cylinder" p 0.1 base_height)
    (setq ref (entlast))
; RETRIEVE SOLID
    (setq solidSS (ssget "X" (list '(0 . "3DSOLID")(cons 8 "IMAGINARY SURFACE")))) ; this will get a selection set containing the solid
; COPY ORIGINAL SOLID TO TEMPORARY SOLID TO EXTRACT    
    (vla-Copy (vlax-ename->vla-object (ssname solidSS 0))) ; retrieve first entity in the list (there should be only 1)
    (setq temp_copy (entlast))
; SUBTRACT COPIED SOLID FROM REFERENCE CYLINDER
    (command "subtract" ref "" temp_copy "")
; GET HEIGHT OF REMAINING REFERENCE CYLINDER AND SUBTRACT FROM BASE HEIGHT
    (vla-GetBoundingBox (vlax-ename->vla-object ref) 'BoxPoint1 'BoxPoint2)
    (setq height (- base_height (- (nth 2 (vlax-safearray->list BoxPoint2)) (nth 2 (vlax-safearray->list BoxPoint1)))))
; ERASE REFERENCE CYLINDER   
    (command "_erase" ref "")
; DISPLAY MEASURED HEIGHT OR ERROR IF > 152.4   
    (if (> height 152.40)
      (alert (strcat "Error"))
      (alert (strcat "Max heigth is :  " (rtos height 2 3) " mt  or  " (rtos (* 3.2808399 height) 2 3) " ft"))
    )
    (mapcar 'setvar var val)
    (princ)
)

f

0 Likes
Message 20 of 29

Anonymous
Not applicable

Hi Danny,

 

thanks a lot for investing your time to help me out.

 

I just tried your code and no matter what point I use in my drawing it keeps showing zero distance.

 

Any idea what is going on? Anything I have to set?

0 Likes