To Find Self Intersection of LWPOLYLINE

To Find Self Intersection of LWPOLYLINE

MehtaRajesh
Advocate Advocate
11,964 Views
123 Replies
Message 1 of 124

To Find Self Intersection of LWPOLYLINE

MehtaRajesh
Advocate
Advocate

Hi,

I am posting useful function to find Self Intersection for selected LWPOLYLINE.
You might be having other options, but I find this one as a quickest and Simple


(defun IsSelfIntersect (l / vcnt vcnt1 crossresult pt1 pt2 pt3 pt4)
(setq vcnt 0)
(setq crossresult F)
(repeat (1- (length l))
 (setq pt1 (nth vcnt l))
   (setq pt2 (nth (1+ vcnt) l))
   (setq vcnt1 vcnt)
 (setq isdone "T")
 (while isdone
  (if (and (nth (+ 2 vcnt) l) (nth (+ 3 vcnt) l))
  (progn
   (setq pt3 (nth (+ 2 vcnt) l))
   (setq pt4 (nth (+ 3 vcnt) l))
       (if (inters pt1 pt2 pt3 pt4)
   (progn
      (setq crossresult T)
   );progn
   );if
  );progn
  (progn
   (setq isdone nil)
  );progn
  );if
    (setq vcnt (1+ vcnt))
 );while
   (setq vcnt (1+ vcnt1)) 
);repeat
crossresult
);defun

Below Function to get the Coordinate list of LWPOLYLINE

(defun lwptslw (lst / pair rtn)
  (while (setq pair (assoc 10 lst))
    (setq rtn (cons (cdr pair) rtn)
   lst (cdr (member pair lst))
    )
  )
  (reverse rtn)
)

USAGE:
Command: (IsSelfIntersect (LWPTSLW (ENTGET (CAR (ENTSEL "\nSelect Lwpolyline to find Self Intersectioni")))))

Regards,
Rajesh

0 Likes
11,965 Views
123 Replies
Replies (123)
Message 41 of 124

john.uhden
Mentor
Mentor

@АлексЮстасу ,

Don't you know?  "There's no cheating in AutoLisp."  🤔

John F. Uhden

0 Likes
Message 42 of 124

АлексЮстасу
Advisor
Advisor

@john.uhden,

 

;; Обнаружение самопересечений замкнутых lwpolylines
;; М. Брагин, 25-11-2024
(defun self-inters-overls ( obj / mspace regn)
  (setq mspace (vla-get-ModelSpace (vla-get-ActiveDocument (vlax-get-acad-object)))) 
  (setq regn (vlax-safearray-fill (vlax-make-safearray vlax-vbObject '(0 . 0)) (list obj)))
  (if (vl-catch-all-error-p
	(setq regn (vl-catch-all-apply
		    (function (lambda () (car (vlax-safearray->list (vlax-variant-value (vla-AddRegion mspace regn)))))))))
    T
    (vla-Delete regn)
  )
) ; _ defun self-inters-overls

 

It's cheating, firstly, because it's not actually a lisp, but an AutoCAD command action.
Secondly, because it is only for closed polylines.
Third, because it does not find intersections themselves, but only T or nil.
Fourth, and this is directed at Autodesk, it is unfair that AutoCAD functions have very fast self-intersection detection tools built in, but they are not available to users. It is possible that they cannot be reproduced as well on lisp.

 

It would be nice to come up with a similarly funny way for non-closed polylines. We haven't been able to do that yet.

 

And, of course, need to find the points of the self-intersections themselves...

 


-- Alexander, private person, pacifist, english only with translator 🙂 --

Object-modeling _ odclass-odedit.com _ Help

0 Likes
Message 43 of 124

marko_ribar
Advisor
Advisor

Hi, there...

I took some time to mod. your posted code... Note that in BricsCAD, (vl-catch-all-error-p) don't detect error in creation of region(s), so I implemented checking if there are more regions created than 1 - this means that polyline is self intersecting... Then those regions are removed and original curve is left like it was before sub was initiated - closed or open... So, here is my intervention :

 

(defun self-inters-overls ( obj / space openflg reg regs rtn )

  (or (not (vl-catch-all-error-p (vl-catch-all-apply (function vlax-get-acad-object) nil))) (vl-load-com))

  (setq space (vla-get-Block (vla-get-ActiveLayout (vla-get-ActiveDocument (vlax-get-acad-object)))))
  (if (not (vl-catch-all-error-p (vl-catch-all-apply (function vlax-curve-getstartpoint) (list obj))))
    (progn
      (if (= (type obj) (quote ename))
        (setq obj (vlax-ename->vla-object obj))
      )
      (if (not (vlax-curve-isclosed obj))
        (progn
          (vla-put-closed obj :vlax-true)
          (setq openflg t)
        )
      )
      (setq reg (vlax-safearray-fill (vlax-make-safearray vlax-vbObject '(0 . 0)) (list obj)))
      (if
        (vl-catch-all-error-p
          (setq regs
            (vl-catch-all-apply
              (function
                (lambda nil
                  (vlax-safearray->list (vlax-variant-value (vla-AddRegion space reg)))
                )
              )
            )
          )
        )
        (setq rtn t)
        (progn
          (if (> (length regs) 1)
            (setq rtn t)
            (setq rtn nil)
          )
          (foreach reg regs
            (vla-Delete reg)
          )
        )
      )
      (if openflg
        (vla-put-closed obj :vlax-false)
      )
      rtn
    )
    (prompt "\nProvided argument for this sub-function not appropriate : \"obj\" argument must be AcDbCurve...")
  )
)

I hope that this helps...

Regards, M.R.

Marko Ribar, d.i.a. (graduated engineer of architecture)
Message 44 of 124

АлексЮстасу
Advisor
Advisor

@marko_ribar,

Thanks, this extends the applicability of the function to BricsCAD users as well.

Though, reduces the anecdotal nature of this ‘solution’ in three actions. 🙂

 

Do you have any idea how to do a similar thing for detecting self-overlaps for non-closed polylines? What AutoCAD function/command would help to do this?

 

The task of showing self-intersection and self-overlap points is always important. Finding them manually is very time consuming. And not all of them can be found.

 


-- Alexander, private person, pacifist, english only with translator 🙂 --

Object-modeling _ odclass-odedit.com _ Help

0 Likes
Message 45 of 124

bergerF5EFQ
Participant
Participant

@АлексЮстасу wrote:

Do you have any idea how to do a similar thing for detecting self-overlaps for non-closed polylines? What AutoCAD function/command would help to do this?

 


Hi Alexander,

 

this is very simple: create a copy of the polyline, explode the copy, and apply the method 'IntersectWith to all the new entities. After that delete the new entities.

 

Regards, Tom

0 Likes
Message 46 of 124

АлексЮстасу
Advisor
Advisor

Hi, @bergerF5EFQ,

 

The problem of finding and showing users all self-intersections and self-overlaps of polylines is now divided into three subproblems:
1. finding and showing users all self-intersections and self-overlaps for closed and non-closed polylines,
2. the running time even for very long polylines (4000-5000 vertices) should not be more than 10-20 seconds,
3. for polylines with coordinates in millions (8200000.0,5700000.0 or etc.) there should be no wrong answers.

 

We have solved the first one - see #24. We know this is unprofessionally made code, and runs very slowly. But it is the only one so far that finds all self-intersections and self-overlaps and shows them to users.
For the second and third, we tried in the code in #42 to use the AutoCAD command just because it works very fast and error free with coordinates in the millions. But this action is limited only to closed polylines.


If you make your programme with copy , explode, ‘IntersectWith, delete, you will most likely solve neither the second nor the third subproblem.

 


-- Alexander, private person, pacifist, english only with translator 🙂 --

Object-modeling _ odclass-odedit.com _ Help

0 Likes
Message 47 of 124

marko_ribar
Advisor
Advisor

Hi Alexander...

I changed my code, so that now should accept both closed and opened polylines and I tested it with many small samples... It should give correct answer if polyline is with self intersections... Still not 100% sure the results is correct, so I leave to you and others for further testings...

(defun self-inters-overls ( obj / space objo objc regc rego regs rtn )

  (or (not (vl-catch-all-error-p (vl-catch-all-apply (function vlax-get-acad-object) nil))) (vl-load-com))

  (setq space (vla-get-Block (vla-get-ActiveLayout (vla-get-ActiveDocument (vlax-get-acad-object)))))
  (if (not (vl-catch-all-error-p (vl-catch-all-apply (function vlax-curve-getstartpoint) (list obj))))
    (progn
      (if (= (type obj) (quote ename))
        (setq obj (vlax-ename->vla-object obj))
      )
      (setq objo (vla-copy obj))
      (if (vlax-curve-isclosed objo)
        (vla-put-closed objo :vlax-false)
      )
      (setq objc (vla-copy obj))
      (if (not (vlax-curve-isclosed objc))
        (vla-put-closed objc :vlax-true)
      )
      (setq rego (vlax-safearray-fill (vlax-make-safearray vlax-vbObject '(0 . 0)) (list objo)))
      (setq regc (vlax-safearray-fill (vlax-make-safearray vlax-vbObject '(0 . 0)) (list objc)))
      (if
        (vl-catch-all-error-p
          (setq regs
            (vl-catch-all-apply
              (function
                (lambda nil
                  (vlax-safearray->list (vlax-variant-value (vla-AddRegion space rego)))
                )
              )
            )
          )
        )
        (setq rtn nil)
        (progn
          (if (and (not (vlax-curve-isclosed obj)) (> (length regs) 1))
            (setq rtn t)
          )
          (if (and (= (type regs) (quote list)) (vl-every (function (lambda ( x ) (= (type x) (quote vla-object)))) regs))
            (foreach reg regs
              (vla-Delete reg)
            )
          )
        )
      )
      (setq regs nil)
      (if
        (vl-catch-all-error-p
          (setq regs
            (vl-catch-all-apply
              (function
                (lambda nil
                  (vlax-safearray->list (vlax-variant-value (vla-AddRegion space regc)))
                )
              )
            )
          )
        )
        (princ)
        (progn
          (if (and (vlax-curve-isclosed obj) (> (length regs) 1))
            (setq rtn t)
          )
          (if (and (= (type regs) (quote list)) (vl-every (function (lambda ( x ) (= (type x) (quote vla-object)))) regs))
            (foreach reg regs
              (vla-Delete reg)
            )
          )
        )
      )
      (vla-Delete objo)
      (vla-Delete objc)
      rtn
    )
    (prompt "\nProvided argument for this sub-function not appropriate : \"obj\" argument must be AcDbCurve...")
  )
)

 

HTH.

Regards, M.R.

Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 48 of 124

bergerF5EFQ
Participant
Participant

Hello Alexander,

I am quite sure that the dirty solution with creating and exploding a copy of the polyline and running 'IntersectWith will be under 10-20 seconds for polylines up to 5000 vertices. Polylines with vertices in the millions should also produce reliable results, but since the processing time will grow exponentially with the number of vertices, it will certainly take some time.

Regards, Tom

 

 

0 Likes
Message 49 of 124

АлексЮстасу
Advisor
Advisor

@bergerF5EFQ,

Many programmes have already been written with copy, explode, ‘IntersectWith, delete. Including one by Lee Mac. But so far none of them finds everything, and for polylines with thousands of vertices they work for many tens of seconds.
I didn't mean millions of vertices, but coordinates with values in millions (x8200000.0,y5700000.0 or etc.) - see my attached dwg above.


-- Alexander, private person, pacifist, english only with translator 🙂 --

Object-modeling _ odclass-odedit.com _ Help

0 Likes
Message 50 of 124

bergerF5EFQ
Participant
Participant

Interesting, since I have not yet seen a polyline that doesn't work with 'IntersectWith. I did not find your dwg (but i didn't search intensively).

 

And yes: coordinates with values in millions are often the cause of severe problems. Even functions like SSGET can then cause unpredictable results, or commands like HATCH. I guess this has to do with functions and commands which internally work with the display list, which is made of integer coordinates.

 

 

0 Likes
Message 51 of 124

АлексЮстасу
Advisor
Advisor

@marko_ribar,

test-nc-2_self-inters-overls.png


-- Alexander, private person, pacifist, english only with translator 🙂 --

Object-modeling _ odclass-odedit.com _ Help

0 Likes
Message 52 of 124

АлексЮстасу
Advisor
Advisor

@bergerF5EFQ,

The way with ‘IntersectWith has been tried many times already.
See dwg in my first reply to you in #46.

 


-- Alexander, private person, pacifist, english only with translator 🙂 --

Object-modeling _ odclass-odedit.com _ Help

0 Likes
Message 53 of 124

marko_ribar
Advisor
Advisor

Hi Alexander,

I've updated my latest posted code and all I can say is that it only works well with BricsCAD... AutoCAD don't make regions as expected neither if curve is opened, nor if it's closed... But, all in all, it's somewhat better coded IMHO...

Regards, M.R.

Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 54 of 124

АлексЮстасу
Advisor
Advisor

@marko_ribar,

After the update, everything is nil at all.

test-nc-21_self-inters-overls.png


-- Alexander, private person, pacifist, english only with translator 🙂 --

Object-modeling _ odclass-odedit.com _ Help

0 Likes
Message 55 of 124

marko_ribar
Advisor
Advisor

@АлексЮстасу 

Look I already told... In BricsCAD it works well, but in AutoCAD not...

Regards...

Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 56 of 124

marko_ribar
Advisor
Advisor

Here, this one should work under AutoCAD... But I cheated - I used intersectwith method... Now not sure if it'll work under BricsCAD... Just checked - it works...

(defun self-inters-overls ( obj / vertlst selfintlst space objo objc regc rego regs rtn )

  (or (not (vl-catch-all-error-p (vl-catch-all-apply (function vlax-get-acad-object) nil))) (vl-load-com))

  (defun vertlst ( obj )
    (mapcar (function cdr) (vl-remove-if (function (lambda ( x ) (/= (car x) 10))) (entget (if (= (type obj) (quote vla-object)) (vlax-vla-object->ename obj) obj))))
  )

  (defun selfintlst ( obj / lst rtn )
    (setq lst (vlax-invoke (if (= (type obj) (quote ename)) (vlax-ename->vla-object obj) obj) (quote intersectwith) (if (= (type obj) (quote ename)) (vlax-ename->vla-object obj) obj) acextendnone))
    (repeat (/ (length lst) 3)
      (setq rtn (cons (trans (list (car lst) (cadr lst) (caddr lst)) 0 (if (= (type obj) (quote vla-object)) (vlax-vla-object->ename obj) obj)) rtn))
      (setq lst (cdddr lst))
    )
    (reverse rtn)
  )

  (setq space (vla-get-Block (vla-get-ActiveLayout (vla-get-ActiveDocument (vlax-get-acad-object)))))
  (if (not (vl-catch-all-error-p (vl-catch-all-apply (function vlax-curve-getstartpoint) (list obj))))
    (progn
      (if (= (type obj) (quote ename))
        (setq obj (vlax-ename->vla-object obj))
      )
      (setq objo (vla-copy obj))
      (if (vlax-curve-isclosed objo)
        (vla-put-closed objo :vlax-false)
      )
      (setq objc (vla-copy obj))
      (if (not (vlax-curve-isclosed objc))
        (vla-put-closed objc :vlax-true)
      )
      (setq rego (vlax-safearray-fill (vlax-make-safearray vlax-vbObject '(0 . 0)) (list objo)))
      (setq regc (vlax-safearray-fill (vlax-make-safearray vlax-vbObject '(0 . 0)) (list objc)))
      (if
        (vl-catch-all-error-p
          (setq regs
            (vl-catch-all-apply
              (function
                (lambda nil
                  (vlax-safearray->list (vlax-variant-value (vla-AddRegion space rego)))
                )
              )
            )
          )
        )
        (setq rtn nil)
        (progn
          (if (> (length regs) 1)
            (setq rtn t)
          )
          (if (and (= (type regs) (quote list)) (vl-every (function (lambda ( x ) (= (type x) (quote vla-object)))) regs))
            (foreach reg regs
              (vla-Delete reg)
            )
          )
        )
      )
      (setq regs nil)
      (if
        (vl-catch-all-error-p
          (setq regs
            (vl-catch-all-apply
              (function
                (lambda nil
                  (vlax-safearray->list (vlax-variant-value (vla-AddRegion space regc)))
                )
              )
            )
          )
        )
        (if (vlax-curve-isclosed obj)
          (setq rtn t)
          (if (vl-remove-if (function (lambda ( x ) (vl-some (function (lambda ( y ) (equal (list (car x) (cadr x)) (list (car y) (cadr y)) 1e-6))) (vertlst obj)))) (selfintlst obj))
            (setq rtn t)
            (setq rtn nil)
          )
        )
        (progn
          (if (and (vlax-curve-isclosed obj) (> (length regs) 1))
            (setq rtn t)
            (if (vl-remove-if (function (lambda ( x ) (vl-some (function (lambda ( y ) (equal (list (car x) (cadr x)) (list (car y) (cadr y)) 1e-6))) (vertlst obj)))) (selfintlst obj))
              (setq rtn t)
              (setq rtn nil)
            )
          )
          (if (and (= (type regs) (quote list)) (vl-every (function (lambda ( x ) (= (type x) (quote vla-object)))) regs))
            (foreach reg regs
              (vla-Delete reg)
            )
          )
        )
      )
      (vla-Delete objo)
      (vla-Delete objc)
      rtn
    )
    (prompt "\nProvided argument for this sub-function not appropriate : \"obj\" argument must be AcDbCurve...")
  )
)

 

HTH.

M.R.

Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 57 of 124

marko_ribar
Advisor
Advisor

Or to make it further more simplified with intersectwith method... Here is the code for pulling out intersecting points (not sure for overlapping ones)... So this version don't use region dummy method - it's straight forward with intersectwith...

(defun c:self-inters-overls ( / *error* self-inters-overls ent lst )

  (or
    (not
      (vl-catch-all-error-p
        (vl-catch-all-apply
          (function vlax-get-acad-object) nil
        )
      )
    )
    (vl-load-com)
  )

  (defun *error* ( m )
    (if (and m (wcmatch (strcase m) "*EXIT*"))
      (princ)
      (if m
        (progn
          (prompt m)
          (princ)
        )
        (princ)
      )
    )
    (if lst
      (progn
        (prompt "\n")
        (read (vl-princ-to-string lst))
      )
    )
  )

  (defun self-inters-overls ( obj / vertlst selfintlst )

    (defun vertlst ( obj / ent enx lst )
      (if (= (type obj) (quote vla-object))
        (setq ent (vlax-vla-object->ename obj))
        (setq ent obj)
      )
      (cond
        ( (= (cdr (assoc 0 (setq enx (entget ent)))) "LWPOLYLINE")
          (mapcar (function cdr)
            (vl-remove-if
              (function
                (lambda ( x )
                  (/= (car x) 10)
                )
              )
              enx
            )
          )
        )
        ( (= (cdr (assoc 0 enx)) "POLYLINE")
          (while (setq ent (entnext ent))
            (if (= (cdr (assoc 0 (setq enx (entget ent)))) "VERTEX")
              (setq lst
                (cons
                  (cdr (assoc 10 enx))
                  lst
                )
              )
            )
          )
          (reverse lst)
        )
        ( (= (cdr (assoc 0 enx)) "SPLINE")
          (mapcar (function cdr)
            (vl-remove-if
              (function
                (lambda ( x )
                  (or
                    (/= (car x) 10)
                    (/= (car x) 11)
                  )
                )
              )
              enx
            )
          )
        )
      )
    )

    (defun selfintlst ( obj / lst rtn )
      (setq lst
        (vlax-invoke
          (if (= (type obj) (quote ename))
            (vlax-ename->vla-object obj)
            obj
          )
          (quote intersectwith)
          (if (= (type obj) (quote ename))
            (vlax-ename->vla-object obj)
            obj
          )
          acextendnone
        )
      )
      (repeat (/ (length lst) 3)
        (setq rtn
          (cons
            (trans (list (car lst) (cadr lst) (caddr lst))
              0
              (if (= (type obj) (quote vla-object))
                (vlax-vla-object->ename obj)
                obj
              )
            )
            rtn
          )
        )
        (setq lst (cdddr lst))
      )
      (reverse rtn)
    )

    (if
      (not
        (vl-catch-all-error-p
          (vl-catch-all-apply
            (function vlax-curve-getstartpoint)
            (list obj)
          )
        )
      )
      (mapcar
        (function
          (lambda ( p )
            (trans p
              (if (= (type obj) (quote vla-object))
                (vlax-vla-object->ename obj)
                obj
              )
              0
            )
          )
        )
        (vl-remove-if
          (function
            (lambda ( x )
              (vl-some
                (function
                  (lambda ( y )
                    (equal (list (car x) (cadr x)) (list (car y) (cadr y)) 1e-6)
                  )
                )
                (vertlst obj)
              )
            )
          )
          (selfintlst obj)
        )
      )
      (progn
        (prompt "\nInvalid entity pick... Picked entity must be AcDbCurve... Better luck next time...")
        (exit)
      )
    )
  )

  (if (setq ent (car (entsel "\nPick curve entity to get its self-intersecting-overlapping points...")))
    (setq lst (self-inters-overls ent))
    (prompt "\nMissed... Better luck next time...")
  )
  (*error* nil)
)

 

HTH.

Regards, M.R.

Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 58 of 124

marko_ribar
Advisor
Advisor

Just slightly different, but still it can't find self-intersecting point on example shown in the picture...

self-inters-overls.png

Here is my latest attempt and I think that is better than my previous IMHO...

(defun c:self-inters-overls ( / *error* removeonce self-inters-overls ent lst )

  (or
    (not
      (vl-catch-all-error-p
        (vl-catch-all-apply
          (function vlax-get-acad-object) nil
        )
      )
    )
    (vl-load-com)
  )

  (defun *error* ( m )
    (if (and m (wcmatch (strcase m) "*EXIT*"))
      (princ)
      (if m
        (progn
          (prompt m)
          (princ)
        )
        (princ)
      )
    )
    (if lst
      (progn
        (prompt "\n")
        (read (vl-princ-to-string lst))
      )
    )
  )

  (defun removeonce ( a l fuzz / n c d )
    (setq n
      (vl-some
        (function
          (lambda ( x )
            (setq c (if (not c) 0 (1+ c)))
            (if (equal x a fuzz) c)
          )
        )
        l
      )
    )
    (vl-remove nil
      (mapcar
        (function
          (lambda ( x )
            (setq d (if (not d) 0 (1+ d)))
            (if (= d n) nil x)
          )
        )
        l
      )
    )
  )

  (defun self-inters-overls ( obj / vertlst selfintlst vl sl )

    (defun vertlst ( obj / e ent enx lst )
      (if (= (type obj) (quote vla-object))
        (setq ent (vlax-vla-object->ename obj))
        (setq ent obj)
      )
      (setq e ent)
      (cond
        ( (= (cdr (assoc 0 (setq enx (entget ent)))) "LWPOLYLINE")
          (mapcar
            (function
              (lambda ( p )
                (trans
                  (append
                    (mapcar (function +) (list 0.0 0.0) p)
                    (list (cdr (assoc 38 enx)))
                  )
                  e
                  0
                )
              )
            )
            (mapcar (function cdr)
              (vl-remove-if
                (function
                  (lambda ( x )
                    (/= (car x) 10)
                  )
                )
                enx
              )
            )
          )
        )
        ( (and (= (cdr (assoc 0 enx)) "POLYLINE") (or (= 8 (cdr (assoc 70 enx))) (= 9 (cdr (assoc 70 enx)))))
          (while (setq ent (entnext ent))
            (if (= (cdr (assoc 0 (setq enx (entget ent)))) "VERTEX")
              (setq lst
                (cons
                  (cdr (assoc 10 enx))
                  lst
                )
              )
            )
          )
          (reverse lst)
        )
        ( (= (cdr (assoc 0 enx)) "POLYLINE")
          (while (setq ent (entnext ent))
            (if (= (cdr (assoc 0 (setq enx (entget ent)))) "VERTEX")
              (setq lst
                (cons
                  (cdr (assoc 10 enx))
                  lst
                )
              )
            )
          )
          (mapcar
            (function
              (lambda ( p )
                (trans p e 0)
              )
            )
            (reverse lst)
          )
        )
        ( (= (cdr (assoc 0 enx)) "SPLINE")
          (mapcar (function cdr)
            (vl-remove-if
              (function
                (lambda ( x )
                  (or
                    (/= (car x) 10)
                    (/= (car x) 11)
                  )
                )
              )
              enx
            )
          )
        )
      )
    )

    (defun selfintlst ( obj / lst rtn )
      (setq lst
        (vlax-invoke
          (if (= (type obj) (quote ename))
            (vlax-ename->vla-object obj)
            obj
          )
          (quote intersectwith)
          (if (= (type obj) (quote ename))
            (vlax-ename->vla-object obj)
            obj
          )
          acextendnone
        )
      )
      (repeat (/ (length lst) 3)
        (setq rtn
          (cons
            (list (car lst) (cadr lst) (caddr lst))
            rtn
          )
        )
        (setq lst (cdddr lst))
      )
      (reverse rtn)
    )

    (if
      (not
        (vl-catch-all-error-p
          (vl-catch-all-apply
            (function vlax-curve-getstartpoint)
            (list obj)
          )
        )
      )
      (progn
        (setq vl (vertlst obj))
        (setq sl (selfintlst obj))
        (foreach x vl
          (setq sl (removeonce x sl 1e-6))
        )
        sl
      )
      (progn
        (prompt "\nInvalid entity pick... Picked entity must be AcDbCurve... Better luck next time...")
        (exit)
      )
    )
  )

  (if (setq ent (car (entsel "\nPick curve entity to get its self-intersecting-overlapping points...")))
    (setq lst (self-inters-overls ent))
    (prompt "\nMissed... Better luck next time...")
  )
  (*error* nil)
)

 

HTH.

Regards, M.R.

Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 59 of 124

АлексЮстасу
Advisor
Advisor

@marko_ribar,

The latest versions of self-inters-overls work slowly - many tens of seconds on objects with thousands of vertices. And they produce false results at coordinates in millions.
This is probably because you have switched to the already tried ‘intersectwith’ and so on.
Self-inters-overls only look for self-intersections, and do not find self-overlaps.

 

‘Programme’ in #24 is so far the only one I know of that finds all self-intersections and self overlaps, and does not give false answers. It has the right overall logic. But it is very slow.
We are not actually programmers, and can only do primitive things. We don't know what we can replace ‘while’ and so on with to make it work faster.
How can speed it up?


-- Alexander, private person, pacifist, english only with translator 🙂 --

Object-modeling _ odclass-odedit.com _ Help

0 Likes
Message 60 of 124

marko_ribar
Advisor
Advisor

@АлексЮстасу 

I also am not a programmer, but I know that ObjectARX is far more faster than LISP... From above posted link for message #24, you could contact @daniel_cadext who knows to write *.arx and *.brx files... His name is Daniel and if I am to be asked I prefer more *.brx for BricsCAD V25... Actually I recently uninstalled AutoCAD 2025 as it failed to load any of my *.lsp files - there is a bug - unknown function definition : ACET-AUTOLOAD2 and as a solution from Autodesk they replied with downgrading AutoCAD from 2025 version to 2024... This is what I did and there they are - my *.lsp files normally loaded at start-up... So, if you ask Daniel, I'd suggest for making *.arx for AutoCAD 2024 and *.brx for BricsCAD V25... Still, if you are stick to Autodesk AutoCAD, I suggest that you install BricsCAD as it's far more superior with speed of execution of *.lsp files and it also has pretty good debugging environment called BLADE - you can invoke it by both VLIDE or BLADE command... There is also DESencoder which compiles *.lsp files to *.des similarilly to *.VLX or *.fas from AutoCAD... So I suppose that @daniel_cadext may jump in to try to answer to our needs if he is available... For me, I barely have needs for finding self intersections and overlaps on curves, but what I coded was my attempt from LISP perspective and I don't work in units so far from origin base of WCS... Have you tried scailing DWG from 0,0 by factor 1e-8 to make DWG more appropriate for intersectwith method and when points are founded multiply each coordinate with 1e+8?

Marko Ribar, d.i.a. (graduated engineer of architecture)