Jump to content

Recommended Posts

Posted

Hello All!

 

Im not really fluid with Autocad, neither with Lisp. :oops:

 

 

I need to measure the distance from a given line to a spline (poly) curve, in regulary intervals. Need to do around 100 per spline, so to do this per hand is a little bit boring.

 

Didnt find any solution now, maybe somebody can enlighten me.

 

See attached sketch

 

 

acad1.png

 

Thanks a lit - Tom

Posted

Do you use:

  • a fixed distance between the dimensions
  • a fixed amount of dimensions

 

The second option sound impractical for me (when it goes for the execution of the project).

Posted

The measurement lines are always in 90degrees to the basis line (the red or green one in the example).

 

The distance between the dimensions is always the same (like 100mm).

 

Thanks!

Posted

P.S. Starting point for measurements is the starting point of the basis line. Then every X mm till the basis line ends. I could also provide more data like X=distance, Z=number of measurements

 

Tom

Posted

updated the sketch to make it more clear

Posted (edited)

The code below assumes that the drawing is 2D (in the WCS) and the base line is horizontal.

(defun KGA_List_Divide_3 (lst / ret)
 (repeat (/ (length lst) 3)
   (setq ret (cons (list (car lst) (cadr lst) (caddr lst)) ret))
   (setq lst (cdddr lst))
 )
 (reverse ret)
)

(defun KGA_Sys_ObjectOwner (obj)
 (vla-objectidtoobject (vla-get-database obj) (vla-get-ownerid obj))
)

(defun DimCurveAtPoint (curve pt / space tmp)
 (setq space (KGA_Sys_ObjectOwner curve))
 (setq tmp (vlax-invoke space 'addxline pt (mapcar '+ '(0.0 1.0 0.0) pt)))
 (foreach int (KGA_List_Divide_3 (vlax-invoke curve 'intersectwith tmp acextendnone))
   (vlax-invoke space 'adddimaligned pt int pt)
 )
 (vla-delete tmp)
)

(defun c:DimCurve ( / baseEntselLst basePtLst curve dist doc pt vec)
 (setq doc (vla-get-activedocument (vlax-get-acad-object)))
 (vla-endundomark doc)
 (vla-startundomark doc)
 (if
   (and
     (setq curve (car (entsel "\nSelect curve: ")))
     (setq baseEntselLst (entsel "\nSelect base line near start point: "))
     (setq dist (getdist "\nDistance between dimensions: "))
   )
   (progn
     (setq pt (cadr baseEntselLst))
     (setq basePtLst
       (list
         (vlax-curve-getstartpoint (car baseEntselLst))
         (vlax-curve-getendpoint (car baseEntselLst))
       )
     )
     (if (> (distance pt (car basePtLst)) (distance pt (cadr basePtLst)))
       (setq basePtLst (reverse basePtLst))
     )
     (setq curve (vlax-ename->vla-object curve))
     (setq pt (car basePtLst))
     (setq vec
       (list
         (if (> (caar basePtLst) (caadr basePtLst)) (- dist) dist)
         0.0
         0.0
       )
     )
     (repeat (fix (/ (apply 'distance basePtLst) dist))
       (DimCurveAtPoint curve pt)
       (setq pt (mapcar '+ pt vec))
     )
   )
 )
 (vla-endundomark doc)
 (princ)
)

Edited by Roy_043
Posted

Thanks Roy!

 

Cannot get the code running. I have to remove the following lines, otherwise i will not be asked for the parameters. And like this .. its not working ;)

 

;(setq doc (vla-get-activedocument (vlax-get-acad-object)))

;(vla-endundomark doc)

;(vla-startundomark doc)

 

What do i miss? Im using ACad 2017 Mac.

 

Thanks - Tom

Posted

Hmm, it seems there are ActiveX commands in ALisp not supported on non windows platform. Didnt know that there is a different command set as well. Pure Lisp stuff was working .. till now

:(

Posted
Hmm, it seems there are ActiveX commands in ALisp not supported on non windows platform.

 

No ActiveX ? - now that sounds interesting :D

 

However its still possible to write a solution that works on polyline with straight segments (well even with bulges - if someone already have a subfunction to calculate the intersection between arc/bulge and straight line).

So you'd need to reconsider using a polyline or atleast converting that spline onto one.

Posted

Well im not sure. I found a Autodesk Doc which stated that ActiveX is not present on non Windows platforms.

 

https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2016/ENU/AutoCAD-AutoLISP/files/GUID-FC6FC3E3-ED3E-4E4D-9766-8E4D037241A5-htm.html

 

AutoCAD objects are structured in a hierarchical fashion, with the Application object at the root.

 

Note: ActiveX support in AutoLISP is limited to Windows only.

 

 

On the other hand the actual Docs state it different:

 

https://knowledge.autodesk.com/support/autocad-for-mac/learn-explore/caas/CloudHelp/cloudhelp/2016/ENU/AutoCAD-MAC-Core/files/GUID-BC26675C-A124-4612-81AB-3087AE06F5AC-htm.html

 

The newest way of creating entities is by using the ActiveX functions within VLISP. ActiveX has several advantages over entmake and command .

 

Hmmm....

Posted

Cannot believe it, it seems the alisp part is very different between win & mac versions :(

 

 

; error: no function definition: VLAX-CURVE-GETSTARTPOINT

 

and on the autodesk web page:

 

Returns the start point (in WCS) of the curve

 

Supported Platforms: Windows only

 

grrr, im not amused

Posted

You're going to find that the Mac version is pretty hobbled if you're expecting to use lisp routines that use curve functions.

Posted

Doesnt look so good:

 

The programming interfaces that the program supports are:

 

Windows and Mac OS

AutoLISP ®

ObjectARX™

Windows only

ActiveX ® Automation

Managed .NET

VBA (Visual Basic ® for Applications)

Visual LISP™

JavaScript

Posted
You're going to find that the Mac version is pretty hobbled if you're expecting to use lisp routines that use curve functions.

 

Yes, looks like. This is a bummer. Maybe i need to look into Rhino ... too lazy to start from 0 again but there are some other things too where the mac autocad lags behind & has troubles.

Posted

Just to confirm Roy's code is working flawlessly:

 

DimCurve.gif

 

But one thing I had to change was:

 

(repeat ([color="red"]1+[/color] (fix (/ (apply 'distance basePtLst) dist)))

 

Since it was skipping the last dimension (say 100 units increment, and the last dimension was 150 units before the line's endpoint).

Posted

Thanks a lot Roy & Grrr!!!!

 

 

Amazing, exactly what i was looking for.

 

Will try to install a Win AutoCad on a virtual machine so i can use this function cause AutoCad Mac seems to be a nogo!

 

Cheers - Tom

Posted

Good catch Grrr. Thanks. I also forgot to include (vl-load-com).

New version of the code with these issues fixed:

(vl-load-com)

(defun KGA_List_Divide_3 (lst / ret)
 (repeat (/ (length lst) 3)
   (setq ret (cons (list (car lst) (cadr lst) (caddr lst)) ret))
   (setq lst (cdddr lst))
 )
 (reverse ret)
)

(defun KGA_Sys_ObjectOwner (obj)
 (vla-objectidtoobject (vla-get-database obj) (vla-get-ownerid obj))
)

(defun DimCurveAtPoint (curve pt / space tmp)
 (setq space (KGA_Sys_ObjectOwner curve))
 (setq tmp (vlax-invoke space 'addxline pt (mapcar '+ '(0.0 1.0 0.0) pt)))
 (foreach int (KGA_List_Divide_3 (vlax-invoke curve 'intersectwith tmp acextendnone))
   (vlax-invoke space 'adddimaligned pt int pt)
 )
 (vla-delete tmp)
)

(defun c:DimCurve ( / baseEntselLst basePtLst curve dist doc pt vec)
 (setq doc (vla-get-activedocument (vlax-get-acad-object)))
 (vla-endundomark doc)
 (vla-startundomark doc)
 (if
   (and
     (setq curve (car (entsel "\nSelect curve: ")))
     (setq baseEntselLst (entsel "\nSelect base line near start point: "))
     (setq dist (getdist "\nDistance between dimensions: "))
   )
   (progn
     (setq pt (cadr baseEntselLst))
     (setq basePtLst
       (list
         (vlax-curve-getstartpoint (car baseEntselLst))
         (vlax-curve-getendpoint (car baseEntselLst))
       )
     )
     (if (> (distance pt (car basePtLst)) (distance pt (cadr basePtLst)))
       (setq basePtLst (reverse basePtLst))
     )
     (setq curve (vlax-ename->vla-object curve))
     (setq pt (car basePtLst))
     (setq vec
       (list
         (if (> (caar basePtLst) (caadr basePtLst)) (- dist) dist)
         0.0
         0.0
       )
     )
     (repeat (1+ (fix (/ (apply 'distance basePtLst) dist))) ; Thanks Grrr.
       (DimCurveAtPoint curve pt)
       (setq pt (mapcar '+ pt vec))
     )
   )
 )
 (vla-endundomark doc)
 (princ)
)

Posted

You can also solve this without any code:

 

  1. Draw a vertical line from the start of the base line to a point beyond the top (or bottom) of the curve.
  2. Create an mtext with a field that displays the length of the line.
  3. Array the vertical line and the mtext.
  4. Trim all vertical lines using the curve as the cutting entity. Use the _Fence option to efficiently select all lines to be trimmed.
  5. Use the _UpdateFields command.

Posted

Thanks a lot Roy, will try that.

 

Did install ACad on a virtual machine and your code works perfect. Thanks a lot, saves me a lot of time!!!!

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