ahyin Posted December 8, 2011 Posted December 8, 2011 Dear All, I would to to convert the some polylines to region, but one of them can't make it. After checking with is polyline, I found that the polyline cross itself. Is it possible to check this kind of polyline by lisp because it is very small in the corner? Thanks! (defun c:test () (setq cset (ssget "_A" (list '(0 . "lwpolyline") (cons 410 (getvar "CTAB")) ))) (setq ctr 0 sobj 0 oobj 0) (repeat (sslength cset) (setq item (ssname cset ctr)) (if (= (vlax-property-available-p (vlax-ename->vla-object item ) "closed" T) T) (progn (setq lastitem (entlast)) (command "region" item "") (setq drawitem (entlast)) (if (not (equal lastitem drawitem)) (progn (alert "object converted to region") (setq sobj (1+ sobj)) )progn (progn (alert "This object unable convert to region") (setq oobj (1+ oobj)) )prgon )if );progn (alert "All object can't convert to region") );if (setq ctr (1+ ctr)) );repeat ) Quote
Tharwat Posted December 8, 2011 Posted December 8, 2011 Try this .... (defun c:test (/ spc selectionset) ;;; Tharwat 08. Dec. 2011 ;;; (vl-load-com) (cond ((not acdoc) (setq acdoc (vla-get-activedocument (vlax-get-acad-object))) ) ) (setq spc (if (> (vla-get-activespace acdoc) 0) (vla-get-modelspace acdoc) (vla-get-paperspace acdoc) ) ) (if (setq ss (ssget "_:L" (list '(0 . "LWPOLYLINE") '(-4 . "&=") '(70 . 1) (cons 410 (getvar "CTAB")) ) ) ) (progn (vlax-for obj (setq selectionset (vla-get-ActiveSelectionSet acdoc)) (vlax-invoke spc 'addregion (list obj)) ) (vla-delete selectionset) ) (princ) ) (princ) ) Quote
Lee Mac Posted December 8, 2011 Posted December 8, 2011 The following function will return points of self-intersection of an LWPolyline, else nil if the LWPolyline does not intersect itself. [color=GREEN];; Get Self-Intersections - Lee Mac - 2011 - www.lee-mac.com[/color] [color=GREEN];; Returns a list of self-intersections points of an LWPolyline.[/color] ([color=BLUE]defun[/color] _GetSelfIntersections ( obj [color=BLUE]/[/color] _LWVertices _Group3D ) ([color=BLUE]defun[/color] _LWVertices ( l z ) ([color=BLUE]if[/color] l ([color=BLUE]cons[/color] ([color=BLUE]list[/color] ([color=BLUE]car[/color] l) ([color=BLUE]cadr[/color] l) z) (_LWVertices ([color=BLUE]cddr[/color] l) z))) ) ([color=BLUE]defun[/color] _Group3D ( l ) ([color=BLUE]if[/color] l ([color=BLUE]cons[/color] ([color=BLUE]list[/color] ([color=BLUE]car[/color] l) ([color=BLUE]cadr[/color] l) ([color=BLUE]caddr[/color] l)) (_Group3D ([color=BLUE]cdddr[/color] l)))) ) ( ([color=BLUE]lambda[/color] ( l ) ([color=BLUE]vl-remove-if[/color] ([color=BLUE]function[/color] ([color=BLUE]lambda[/color] ( a ) ([color=BLUE]vl-some[/color] ([color=BLUE]function[/color] ([color=BLUE]lambda[/color] ( b ) ([color=BLUE]equal[/color] a b 1e-)) l) ) ) (_Group3D ([color=BLUE]vlax-invoke[/color] obj 'intersectwith obj [color=BLUE]acextendnone[/color])) ) ) (_LWVertices ([color=BLUE]vlax-get[/color] obj 'coordinates) ([color=BLUE]vlax-get[/color] obj 'elevation)) ) ) The above will fail for points of self-intersection which lie directly on LWPolyline vertices. Quote
marko_ribar Posted December 8, 2011 Posted December 8, 2011 (edited) This one will check also old 2dpolylines and 3dpolylines and append overlapping vertexes to list with intersecting points... Based on Lee's code and my contribution for vertexes lists of all *POLYLINE objects... Code updated to support vertexes that lie on polyline and intersect it by its position that have real, not fixed parameter. [EDIT] : Also note that with this code you can check if pline has been correctly generated... If there are no self-intersections and this code returns nil, then pline was correctly generated (if closed with "C" - close option)... If it reports points, pline is self-crossing or has duplicate vertexes on the same location... My next code - posted below in post #7 won't notify these verexes, just those that self-intersects or location of point that is intersection of plines segments self-crossings... (defun _GetSelfIntersections ( obj / _Vertices _Group3D ) (vl-load-com) (defun _Vertices ( pl / nvert pt ptlst n ) (if (eq 1 (logand 1 (cdr (assoc 70 (entget (vlax-vla-object->ename pl)))))) (setq nvert (fix (vlax-curve-getendparam pl))) (setq nvert (+ (fix (vlax-curve-getendparam pl)) 1)) ) (setq n 0.0) (repeat nvert (setq pt (vlax-curve-getpointatparam pl n)) (setq ptlst (cons pt ptlst)) (setq n (+ n 1.0)) ) (setq ptlst (reverse ptlst)) ptlst ) (defun _Group3D ( l ) (if l (cons (list (car l) (cadr l) (caddr l)) (_Group3D (cdddr l)))) ) (defun _Duplicates ( l / lst lstrem ) (setq lstrem (acet-list-remove-duplicates (setq lst l) 1e-6)) (foreach el lstrem (if (not (vl-member-if '(lambda ( x ) (equal el x 1e-6) ) (cdr (vl-member-if '(lambda ( x ) (equal el x 1e-6) ) lst ) ) ) ) (setq lst (vl-remove-if '(lambda ( x ) (equal el x 1e-6) ) lst ) ) ) ) lst ) (append ( (lambda ( l ) (vl-remove-if (function (lambda ( a ) (vl-some (function (lambda ( b ) (equal a b 1e-)) l) ) ) (_Group3D (vlax-invoke obj 'intersectwith obj acextendnone)) ) ) (_Vertices obj) ) (if (_Duplicates (_Vertices obj)) (acet-list-remove-duplicates (_Duplicates (_Vertices obj)) 1e-6)) ) ) Test : (_GetSelfIntersections (vlax-ename->vla-object (ssname (ssget "_+.:E:S:L" '((0 . "*POLYLINE"))) 0))) M.R. Edited August 27, 2013 by marko_ribar code changed Quote
ahyin Posted December 9, 2011 Author Posted December 9, 2011 Thanks for Tharwat , Lee Mac and Marko_ribar of your program code, I will test it. Quote
marko_ribar Posted December 9, 2011 Posted December 9, 2011 (edited) If you want to do checks on POLYLINE only for region creation, you don't need to check for overlapping vertexes that are in pline creation array, only for those that intersects with other ones... In that case this will return list of points that intersect, and if it returns nil, region is possible to create... [EDIT]: Code updated to include open/closed spline entities (defun _GetSelfIntersections ( obj / _Vertices _Group3D ) (vl-load-com) (defun _Vertices ( pl / nvert pt ptlst n ) (if (eq 1 (logand 1 (cdr (assoc 70 (entget (vlax-vla-object->ename pl)))))) (setq nvert (fix (vlax-curve-getendparam pl))) (setq nvert (+ (fix (vlax-curve-getendparam pl)) 1)) ) (setq n 0.0) (repeat nvert (setq pt (vlax-curve-getpointatparam pl n)) (setq ptlst (cons pt ptlst)) (setq n (+ n 1.0)) ) (setq ptlst (reverse ptlst)) ([highlight]acet-list-remove-adjacent-dups[/highlight] ptlst) ) (defun _Group3D ( l ) (if l (cons (list (car l) (cadr l) (caddr l)) (_Group3D (cdddr l)))) ) (defun _Duplicates ( l / lst lstrem ) (setq lstrem (acet-list-remove-duplicates (setq lst l) 1e-6)) (foreach el lstrem (if (not (vl-member-if '(lambda ( x ) (equal el x 1e-6) ) (cdr (vl-member-if '(lambda ( x ) (equal el x 1e-6) ) lst ) ) ) ) (setq lst (vl-remove-if '(lambda ( x ) (equal el x 1e-6) ) lst ) ) ) ) lst ) (append ( (lambda ( l ) (vl-remove-if (function (lambda ( a ) (vl-some (function (lambda ( b ) (equal a b 1e-)) l) ) ) (_Group3D (vlax-invoke obj 'intersectwith obj acextendnone)) ) ) (_Vertices obj) ) (if (_Duplicates (_Vertices obj)) (acet-list-remove-duplicates (_Duplicates (_Vertices obj)) 1e-6)) ) ) Test : (_GetSelfIntersections (vlax-ename->vla-object (car (entsel)))) M.R. Edited August 27, 2013 by marko_ribar Code changed Quote
Tharwat Posted December 10, 2011 Posted December 10, 2011 The following function will return points of self-intersection of an LWPolyline, else nil if the LWPolyline does not intersect itself. [color=GREEN];; Get Self-Intersections - Lee Mac - 2011 - www.lee-mac.com[/color] [color=GREEN];; Returns a list of self-intersections points of an LWPolyline.[/color] ([color=BLUE]defun[/color] _GetSelfIntersections ( obj [color=BLUE]/[/color] _LWVertices _Group3D ) ([color=BLUE]defun[/color] _LWVertices ( l z ) ([color=BLUE]if[/color] l ([color=BLUE]cons[/color] ([color=BLUE]list[/color] ([color=BLUE]car[/color] l) ([color=BLUE]cadr[/color] l) z) (_LWVertices ([color=BLUE]cddr[/color] l) z))) ) ([color=BLUE]defun[/color] _Group3D ( l ) ([color=BLUE]if[/color] l ([color=BLUE]cons[/color] ([color=BLUE]list[/color] ([color=BLUE]car[/color] l) ([color=BLUE]cadr[/color] l) ([color=BLUE]caddr[/color] l)) (_Group3D ([color=BLUE]cdddr[/color] l)))) ) ( ([color=BLUE]lambda[/color] ( l ) ([color=BLUE]vl-remove-if[/color] ([color=BLUE]function[/color] ([color=BLUE]lambda[/color] ( a ) ([color=BLUE]vl-some[/color] ([color=BLUE]function[/color] ([color=BLUE]lambda[/color] ( b ) ([color=BLUE]equal[/color] a b 1e-)) l) ) ) (_Group3D ([color=BLUE]vlax-invoke[/color] obj 'intersectwith obj [color=BLUE]acextendnone[/color])) ) ) (_LWVertices ([color=BLUE]vlax-get[/color] obj 'coordinates) ([color=BLUE]vlax-get[/color] obj 'elevation)) ) ) The above will fail for points of self-intersection which lie directly on LWPolyline vertices. Fantastic result . Would you please re-write the code in another way without the use of lambda ( maybe repeat function works in this case ) if that not bothering ?? Thank you . Quote
Recommended Posts
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.