I am looking to create a utility that will count the vertices of a polyline and display the number in the form of a multileader attached to the last vertex, Maybe with the ability to add a code to the multileader by way of an attribute.
The reason for this is that at every vertex there will be a block depicting a tree, the code will identify the tree type, a schedule will then pick up the tree type and numbers & add them together to give me a tree schedule.
Can anyone help with this, i don't have much experience with lisp but i am keen to learn.
Solved! Go to Solution.
Solved by _Tharwat. Go to Solution.
Can you please upload an image of your desired result ?
What is the scale of your drawing ?
Thanks.
Tharwat
Tharwat,
Thankyou for your response.
Attached is an image of what i am looking to achieve.
The scale i work at is 1:1 in millimetres. Generally the output is 1:100 in paperspace
Hope this what you mean .
(defun c:Test (/ spc e l p1 p2 led)
; Tharwat 30. 07. 2011
(vl-load-com) (setq spc (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object)) ) ) (if (and (setq e (car (entsel "\n Select a Polyline :"))) (member (cdr (assoc 0 (entget e))) '("LWPOLYLINE" "POLYLINE") ) ) (progn (setq l (/ (length (vlax-get (vlax-ename->vla-object e) 'Coordinates)) 2 ) ) (setq p1 (vlax-curve-getendpoint e)) (setq p2 (polar p1 0.785398 1.0)) (setq led (vlax-invoke spc 'Addmleader (append p1 p2) 0)) (vla-put-textstring led (itoa l)) ) (princ "\n Missed the entity or it's not a Polyline !! ") ) (princ) )
Tharwat
That was quick. Thankyou.
I seem to get the following error though?
Command: test
; error: no function definition: VLAX-GET-ACAD-OBJECT
@TharwaT313 wrote:.....
(if
(and
(setq e (car (entsel "\n Select a Polyline :")))
(member (cdr (assoc 0 (entget e))) '("LWPOLYLINE" "POLYLINE"))
)
(progn
(setq l
(/
(length (vlax-get (vlax-ename->vla-object e) 'Coordinates))
2
)
)
....
For "heavy" Polylines [2D or 3D], the 'Coordinates VLA Property lists all three XYZ coordinates for each vertex. So if you might have that kind of Polyline, I think you would need to either:
A. use an (if) function to make that divisor 3 if it's a "POLYLINE" and 2 if it's a "LWPOLYLINE"; or
B. use some other method of finding the number of vertices instead, such as this, which works for any Polyline type:
(if
(and
(setq e (car (entsel "\n Select a Polyline :")))
(member (cdr (assoc 0 (entget e))) '("LWPOLYLINE" "POLYLINE"))
)
(progn
(setq l (1+ (fix (vlax-curve-getEndParam e))))
....
On the other hand, if you would never encounter "heavy" Polylines, test for only the "LWPOLYLINE" entity type, and just divide the 'Coordinates VLA Property by 2, or take another approach such as this:
(setq l (cdr (assoc 90 (entget e))))
Hi Geg .
You may have old version of Autocad so that's why the routine did not work for you .
Anyway here is another way of coding and with the same result .
(defun c:Test (/ e l p1 p2) ; Tharwat 30. 07. 2011 (vl-load-com) (if (and (setq e (car (entsel "\n Select a Polyline :"))) (member (cdr (assoc 0 (entget e))) '("LWPOLYLINE" "POLYLINE") ) ) (progn (if (eq (vla-get-objectname (vlax-ename->vla-object e)) "AcDb3dPolyline" ) (setq l (/ (length (vlax-get (vlax-ename->vla-object e) 'Coordinates)) 3 ) ) (setq l (/ (length (vlax-get (vlax-ename->vla-object e) 'Coordinates)) 2 ) ) ) (setq p1 (vlax-curve-getendpoint e)) (setq p2 (polar p1 0.785398 1.0)) (command "_.mleader" "_non" p1 "_non" p2 (itoa l)) ) (princ "\n Missed the entity or it's not a Polyline !! ") ) (princ) )
Tharwat
Thanks Kent .
I do understand what you mean and I would consider that your idea is another way of counting vertices and both are
working perfectely .
Tharwat
what part of the code determines the size of the mleader... it is being shown very tiny and I can't figure out what part of the code addresses the size of the mleader and text.
TIA
Steve
Hey Stevesfr, none of the code. Your current settings of your multileader style determines that. Adjust your settings to your current style and try again
Great tool, works perfectly.
As it happens i'm using AutoCAD 2011 64bit, it's probably the 64bit that stopped the original solution. I've been trying to learn VBSCRIPT, it took me a week to just get it to debug on a 64bit machine, nobody said the language had changed.
Thankyou so much for your time.
GegH1,
You received the error because the Visual LISP extensions hadn't been loaded with (vl-load-com).
Most users include this in their ACADDOC.lsp so that the Visual LISP functions are always available for programs that use them. This function only need be called once per drawing session to ensure the Visual LISP extensions are available throughout the session, which makes more sense than calling the function for each loaded program.
Another way to approach it:
(defun c:test ( / e s p )
(if (setq s (ssget '((0 . "*POLYLINE"))))
(while (setq e (ssname s 0))
(vl-cmdf "_.mleader" "_non"
(setq p (trans (vlax-curve-getendpoint e) 0 1)) "_non"
(polar p (/ pi 4.) (* 4 (getvar 'DIMTXT)))
(itoa (1+ (fix (vlax-curve-getendparam e))))
)
(ssdel e s)
)
)
(princ)
)
(vl-load-com)
Lee,
Thanks for that, The code seems a lot shorter.
It constantly amaizes me how many ways there are to skin a Cat in AutoCAD.
Lee .
Your routine would consider the rectanle LWpolyline ( square shapes ) as five points .
Tharwat
@ GegH1,
You're very welcome
There are indeed many ways to approach the same problem with AutoCAD, especially since the drawing database can be accessed using both Vanilla AutoLISP and Visual LISP, providing effectively two interfaces for most entities. Of course, some things are easier manipulated using Vanilla (such as dictionaries), whilst others are only possible through VL.
@ Tharwat,
Good spot This is because my code uses the value End Parameter (since the vertices of a Polyline have integer parameter values), however, my code didn't consider a closed polyline wherein the endpoint and startpoint are coincident.
This should fix that problem:
(defun c:test ( / e s p ) (if (setq s (ssget '((0 . "*POLYLINE")))) (while (setq e (ssname s 0)) (vl-cmdf "_.mleader" "_non" (setq p (trans (vlax-curve-getendpoint e) 0 1)) "_non" (polar p (/ pi 4.) (* 4 (getvar 'DIMTXT))) (itoa (+ (fix (vlax-curve-getendparam e)) (if (vlax-curve-isclosed e) 0 1))) ) (ssdel e s) ) ) (princ) ) (vl-load-com)
Also, you might want to consider UCS for your code
Can't find what you're looking for? Ask the community or share your knowledge.