How many object under polyline

How many object under polyline

islerahmet06
Contributor Contributor
1,700 Views
18 Replies
Message 1 of 19

How many object under polyline

islerahmet06
Contributor
Contributor

Hello,

 

I was digging forum but couldn't find anything, I am sorry if someone asked before

 

How can I know that how many objects are there in polyline, (how many line, how many arc etc)

islerahmet06_0-1643234834812.png

for example, there are 5 line and 1 arc in this polyline.

 

Thanks in advance.

0 Likes
Accepted solutions (3)
1,701 Views
18 Replies
Replies (18)
Message 2 of 19

john.uhden
Mentor
Mentor
Accepted solution

This ought to tell you...

(defun c:howmany ( / e ent n)
  (and
    (setq e (car (entsel "\nSelect a polyline: ")))
    (setq ent (entget e))
    (or
      (= (cdr (assoc 0 ent)) "LWPOLYLINE")
      (prompt " \nObject selected is not an LWPOLYLINE.")
    )
    (setq n (cdr (assoc 90 ent)))
    (or
      (= (logand (cdr (assoc 70 ent)) 1) 1)
      (setq n (1- n))
    )
    (princ (strcat "\nPolyline has " (itoa n) " segments."))
  )
  (princ)
)

John F. Uhden

0 Likes
Message 3 of 19

Kent1Cooper
Consultant
Consultant
Accepted solution

 

(vl-load-com); if needed
(defun C:PLSC ; = PolyLine Segment Count
  (/ pl pldata segs bulges arcs lines)
  (if
    (and
      (setq pl (car (entsel "\nSelect LWPolyline for segment line/arc count: ")))
      (setq pldata (entget pl))
      (member '(0 . "LWPOLYLINE") pldata); LW only for this approach
    ); and
    (progn ; then
      (setq
        segs (fix (vlax-curve-getEndParam pl)); whether open or closed
        bulges (vl-remove-if-not '(lambda (x) (= (car x) 42)) pldata)
      ); setq
      (if (not (vlax-curve-isClosed pl)) (setq bulges (cdr (reverse bulges))))
        ; remove last bulge factor if open
      (setq
        arcs (length (vl-remove '(42 . 0.0) bulges)); quantity of non-zero bulges [arc segments]
        lines (- segs arcs); the rest
      ); setq
      (prompt (strcat "\nPolyline has " (itoa lines) " line segments and " (itoa arcs) " arc segments."))
    ); progn
    (prompt "\nSelected object is not a LWPolyline."); else
  ); if
  (princ)
)

 

EDIT:  Just corrected an accidental colon that should have been a semicolon.

Of course, this assumes no coincident vertices [two at the same place with a zero-length segment].

Kent Cooper, AIA
Message 4 of 19

Sea-Haven
Mentor
Mentor
Accepted solution
0 Likes
Message 5 of 19

hak_vz
Advisor
Advisor
(defun c:pl-segs-type(/ *error* pick_poly eo e narcs i ncords nsegs nline)
	(defun *error* ( msg )
		(if (not (member msg '("Function cancelled" "quit / exit abort")))
			(princ (strcat "\nError: " msg))
		)
		(princ)
	)
	(defun pick_poly ()
		(setq e (car(entsel "\nSelect polyline >")))
		(cond
			((and (not e) (= (getvar 'Errno) 7)) (pick_poly))
			((and e (not (= (cdr(assoc 0 (entget e))) "LWPOLYLINE"))) (pick_poly))
		)
		e
	)
	(setq
		eo (vlax-ename->vla-object (pick_poly))
		ncords (length(vlax-get eo 'coordinates))
		nsegs (fix (* 0.5 ncords))
		narcs 0
		nline 0
		i -1
	)
	(if (> (vlax-get eo 'Closed) -1) (setq nsegs (1- nsegs)))
	(while (<(setq i (1+ i)) nsegs)(if (> (abs(vla-GetBulge eo i)) 0.0) (setq narcs (1+ narcs))))
	(setq nline (- nsegs narcs))
	(if (and (> narcs 0)(< narcs nsegs))(princ (strcat "\n" (itoa nline) " line and " (itoa narcs) " arc.")))
	(if (= narcs nsegs)(princ (strcat "\n" (itoa narcs) " arc.")))
	(if (= narcs 0)(princ (strcat "\n" (itoa nsegs) " line.")))
    (princ)
)

 

 

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
0 Likes
Message 6 of 19

Kent1Cooper
Consultant
Consultant

@islerahmet06 wrote:

....

How can I know that how many objects are there in polyline, (how many line, how many arc etc)

....


Since we haven't yet seen any response to suggestions to date, I will raise further questions:

 

What do you mean by "know"?  Do you just want the information reported at the command line as in most suggestions so far?  Or drawn in as text, similar to your image, and if so, do you want the segments labeled/numbered, or is all that just for illustration of what you mean by quantities of each segment type?  Or are you looking for something more elaborate such as the table in the routine at the link in Message 4?  Put into a spreadsheet or text file?  Something else?

 

And what is "etc" [whatever that is, if anything, not being shown in your image]?  Details such as in that routine linked in Message 4?  Or do you really only want the number of line and arc segments, with actually no "etc" required?

 

3D Polylines?  [They can only be of all line segments.]

 

Would you want something [though not quantity of line and arc segments] reported about Fit- or Spline-curved "heavy" 2D ones?  What about "heavy" ones that are only of ordinary line and arc segments but just happen to be "heavy" instead of "lightweight" [the result would need to be arrived at differently]?

Kent Cooper, AIA
0 Likes
Message 7 of 19

Kent1Cooper
Consultant
Consultant

Another approach occurred to me, that's not limited to LWPolylines:  EXPLODE the Polyline, and just count how many Lines and Arcs are in the result, then UNDO back past the EXPLODE.

 

(defun C:PLSC ; = PolyLine Segment Count
  (/ pl segs lss lines arcs)
  (if
    (and
      (setq pl (car (entsel "\nSelect Polyline for segment line/arc count: ")))
      (wcmatch (cdr (assoc 0 (entget pl))) "*POLYLINE"); LW or heavy incl. 3D
    ); and
    (progn ; then
      (command "_.undo" "_mark" "_.explode" pl)
      (setq
        segs (sslength (ssget "_P"))
        lss (ssget "_P" '((0 . "LINE")))
        lines (if lss (sslength lss) 0)
        arcs (- segs lines)
      ); setq
      (command "_.undo" "_back")
      (prompt (strcat "\nPolyline has " (itoa lines) " line segments and " (itoa arcs) " arc segments."))
    ); progn
    (prompt "\nNo Polyline selected."); else
  ); if
  (princ)
)

 

But it should probably have added to it a check for whether a "heavy" Polyline is Spline-curved.  It gives a "result" from one of those, but a meaningless one.  It also gives a result for Fit-curved ones that might be of some use, but maybe those should be disallowed, too.

And it should have an *error* handler to ensure un-Exploding if something goes wrong.

I can add those if it seems better than other suggestions, for handling more than only lightweight Polylines.

Kent Cooper, AIA
0 Likes
Message 8 of 19

Kent1Cooper
Consultant
Consultant

 

(defun C:PLSCL ; = PolyLine Segment-type Count and Labeling
  (/ plsel plent plobj par lines arcs)
  (if
    (and
      (setq plsel (entsel "\nSelect Polyline for segment-type count and labeling: "))
      (wcmatch (cdr (assoc 0 (entget (setq plent (car plsel))))) "*POLYLINE")
    ); and
    (progn ; then
      (setq
        plobj (vlax-ename->vla-object plent)
        par 0 lines 0 arcs 0
      ); setq
      (repeat (fix (vlax-curve-getEndParam plent))
        (setq lineseg (= (vla-getBulge plobj par) 0.0))
        (command "_.text" "_mc" "_non" (vlax-curve-getPointAtParam plobj (+ par 0.5)) "" 0
          (strcat ; text content
            (if lineseg "L" "A")
            (itoa (set (if lineseg 'lines 'arcs) (1+ (if lineseg lines arcs))))
          ); strcat
        ); if
        (setq par (1+ par))
      ); repeat
      (prompt (strcat "\nPolyline has " (itoa lines) " line segments and " (itoa arcs) " arc segments."))
    ); progn [then]
    (prompt "\nNo Polyline selected."); else
  ); if
  (princ)
); defun

 

adds labeling the line and arc segments with L1, L2, A1, L3, A2, etc.:

Kent1Cooper_0-1643313986067.png

It currently uses whatever the current Text Style and height are -- specifying those could be built into it.  If the current or built-in-specified Style has a fixed height, omit the "".

It handles "heavy" 2D Polylines, but doesn't handle 3D Polylines [the (vla-getBulge) function fails], so those could be prohibited if necessary.

Kent Cooper, AIA
0 Likes
Message 9 of 19

islerahmet06
Contributor
Contributor

hello, I have a cnc styrofoam cutting device, I need to convert my drawings to gcode for this device, normally I can only convert drawings containing lines, but I could not create the code when there was a circle or arc in the part, I did not give too much information here because I only wanted to get the information I needed. I like to do the work myself, and I don't like to have someone else do my own work,

I think it is not nice to write here and ask people for help when needed without doing any research.

 

Thank you to everyone who helped with the issue.

 

here is my lisp before I asked. 

 

(DEFUN c:gcode ()
(vla-startundomark (setq doc (vla-get-activedocument (vlax-get-acad-object))))
(setq filename (getstring "\n dosya adı giriniz"))
(setq file (open (strcat "C:\\Users\\Amet\\Desktop\\CNC\\Gcode\\Gcode\\" filename ".csv") "w"))
(SETQ POLY (ENTGET (CAR (ENTSEL "\nSelect a polyline: "))))
;(SETQ POLY (REVERSE POLY))
(setq aa_c 0)
(setq SON nil)
(setq ALIST nil)
(setq XESKI 0)
(setq YESKI 0)
(setq XKISMI "")
(setq YKISMI "")
(setq aa_say (length POLY))
(while (< aa_c aa_say)


(setq POL (nth aa_c POLY))

(if (= (CAR POL) 10)
( progn (if (/= XESKI (CADR POL)) (setq XKISMI (STRCAT "X" (RTOS (CADR POL)))))
(if (/= YESKI (CADDR POL)) (setq YKISMI (STRCAT " Y" (RTOS (CADDR POL)))))
(setq ALIST (STRCAT XKISMI YKISMI ))
(write-line ALIST file)
(setq XESKI (CADR POL))
(setq YESKI (CADDR POL))
(setq XKISMI "")
(setq YKISMI "")
)
)

(setq aa_c (+ aa_c 1))
)
(close file)
(vla-endundomark doc)
)

 

I will keep develop this lisp.

0 Likes
Message 10 of 19

john.uhden
Mentor
Mentor

@islerahmet06 

No need for any apologies.

My first two mottos:

1.  You've go to start somewhere (which you did).

2.  If you don't know, ask (which you did).

 

We are all happy that we helped you to help yourself.

BTW, you shouldn't have given me any credit.  I was too lazy to report arcs vs. straights.

John F. Uhden

0 Likes
Message 11 of 19

Sea-Haven
Mentor
Mentor

You say no arcs must be straights for cnc so convert arc to facets. You could use a fuzz factor of divide arc by a small length gives number required so no need to manually enter.

 

; converts an arc to plines
; by Alanh updated March 2021

(defun c:arcch ( / oldsnap ent obj div totlen arclen chrdpt lst num newpt)
(vl-load-com)
(setq oldsnap (getvar "osmode"))
(setvar "osmode" 0)
(setq oldecho (getvar "cmdecho"))
(setvar "cmdecho" 0)

(while (setq ent (entsel "\nPick arc: "))
(setq obj (vlax-ename->vla-object (car ent)))
(if (= div nil) (setq div (getint "\nEnter number of chords: ")))
      
(setq  endpt (vlax-curve-getEndPoint obj)
     totlen (vlax-curve-getDistAtPoint obj endpt)
     arclen (/ totlen div)
     chrdpt (vlax-curve-getStartPoint obj)
     num 1     
)
(setq lst '())
(setq lst (list chrdpt))
(repeat div
  (setq newpt (vlax-curve-getPointatDist obj (* arclen num)))
  (setq lst (cons  newpt lst))
  (setq num (+ num 1))
) ;repeat

(entmakex (append (list (cons 0 "LWPOLYLINE")
                         (cons 100 "AcDbEntity")
                         (cons 100 "AcDbPolyline")
                         (cons 90 (length lst))
                         (cons 70 0))
                   (mapcar (function (lambda (p) (cons 10 p))) lst))
)

) ; end while

(setvar "cmdecho" oldecho)
(setvar "osmode" oldsnap)

(princ)
)

 

 

0 Likes
Message 12 of 19

john.uhden
Mentor
Mentor

@Kent1Cooper 

I tried to give you a "Like" but the button didn't cooperate.

John F. Uhden

0 Likes
Message 13 of 19

islerahmet06
Contributor
Contributor

Thanks a lot,
So may I have some more help 🙂

I have added sample drawing and gcode which belong to this drawing.
I want to create this gcode via lisp.

0 Likes
Message 14 of 19

islerahmet06
Contributor
Contributor

here is the code

0 Likes
Message 15 of 19

pbejse
Mentor
Mentor

@islerahmet06 wrote:

...for example, there are 5 line and 1 arc in this polyline.

 

Thanks in advance.


(defun c:whut ( / arc e l p)
  (if  (setq	arc 0
	e   (car (entsel))
  )
  (progn
	  (repeat (setq	p (fix (vlax-curve-getEndParam
				 (setq e (vlax-ename->vla-object e )))) l p
		  )
	    (setq arc (If (zerop (vla-getbulge e (setq p (1- p))))
			arc (1+ arc)
		      )
		    )
		  )
  	(princ (strcat "\n"
		       (itoa (- l arc)) " Line(s) and " (itoa arc)
		       " Arc segment(s)"
		       )	 
		 )
	  )
    )
  (princ)
)

HTH

Message 16 of 19

Sea-Haven
Mentor
Mentor

I exploded the dxf and ran the arc to pline and that worked need to add a delete arc once done. Simple addition.

 

Not sure how your joining all the objects with the small line between arc into a big pline do you have something already ?

 

What length do you want for the facet when converting arcs ? Can add also as well as do all arcs 1 go.

 

SeaHaven_0-1643500611996.png

 

0 Likes
Message 17 of 19

Sea-Haven
Mentor
Mentor

I had another play. Used a exploded version so pline arcs are now straights.  Bpoly may join all the bits together just not sure without a lot of testing. To smooth reduce facet = 5

 

; converts an arc to a series of straights
; By alan H 2012
; info@alanh.com.au
; modifed for styrofoam cutting Arch to Chords 3.lsp

(vl-load-com)
(defun C:arc2chords ( / ss ncrd oldsnap ent endpt obj totlen arclen stpt num newpt ang cenpt x)

(setq oldsnap (getvar "osmode"))
(setvar 'osmode 0)

(setq facet 5) ;change to suit

(prompt "\nPick Arcs ")
(setq ss (ssget (list (cons 0 "Arc"))))

(repeat (setq x (sslength ss))
(setq obj (vlax-ename->vla-object (ssname ss (setq x (1- x)) )))

(setq totlen (vla-get-ArcLength obj))
(setq ncrd (fix (+ 1 (/ totlen facet))))
(setq arclen (/ totlen ncrd))
(setq stpt (vlax-curve-getStartPoint obj))
(setq  endpt (vlax-curve-getEndPoint obj))

(setq num 1)
(command "_Pline" )
(while (= (getvar "cmdactive") 1 ) 
(command stpt)
(repeat (-  ncrd 1)
(command (vlax-curve-getPointatDist obj (* arclen num)))
(setq num (+ num 1))
)
(command endpt)
(command "")
)

(vla-delete obj)

)
(setvar "osmode" oldsnap)

(princ)
)
(c:arc2chords)

 

0 Likes
Message 18 of 19

Sea-Haven
Mentor
Mentor

A bit more after running bpoly just Copy Last say to side then run this it should show how the pline is made up. I added a start and end line need to do more about working out how bpoly assigns start point for your shape is most top most left point. Not sure about CW or CCW.

(defun wow ( / )
(setq lst (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget (car (entsel "\pick pline"))))))
(setq x 0)
(setq pt1 (nth x lst))
(repeat (- (length lst) 1)
(setq pt2 (nth (setq x (1+ x)) lst))
(command "line" pt1 pt2 "")
(command "redraw")
(command "delay" 5)
(setq pt1 pt2)
)
(princ)
)
(wow)

SeaHaven_0-1643520539617.png

 

 

0 Likes
Message 19 of 19

islerahmet06
Contributor
Contributor

Hi,

 

We can not explode this pline because of wire, machine must keep this route, if we explode pline, the sort of the codes may change, we must have this coordinates at the same sort.

0 Likes