Lisp for breakinig polylines doesn't work, need to convert to lwpolyline

Lisp for breakinig polylines doesn't work, need to convert to lwpolyline

Anonymous
Not applicable
1,021 Views
8 Replies
Message 1 of 9

Lisp for breakinig polylines doesn't work, need to convert to lwpolyline

Anonymous
Not applicable

Hello All, 

 

I'm the AutoCAD administrator of a drawing office, and we work with an application to draw P&ID's. This application is developed by a third party and contains pieces of code from the ealy 90's (when i was still a kid). 

There is a problem, and although I am the CAD Administrator, i can't write lisp.

I can read it, edit it, and paste it, but not write it. A true script kiddie.

 

Problem

One of the buttons of the application breaks two crossing polylines, using a lisp routine. 

 

However, since 2k11 the lisp routine doesn't work anymore, we need to convert the polylines (2D polylines) into LWpolylines first. 

I've tried a couple of things, including changing the variable LWPOLYLINE to POLYLINE, AcadPolyLine, AcDbPolyline, AcDb2dPolyline etc. 

 

What does work is breaking 2 normal lines. 

But, when i draw two crossing polylines, it doesn't do anything

 

Here's the code. 

 

(prompt "\n  breakver.lsp")
;
(defun BreakVer (brkdst / brkdst bdir osn insp x y ss len index found ent e1 ang
                          flg p1 pd1 e1 p2 d0 d1 d2)
  (initerr)
  (if (or (= brkdst Nil)(= brkdst 0))(setq brkdst 2.0))
  (setq bdir "V")
  (setq osn(getvar "osmode"))
  (setvar "osmode" 32)
  (initget (+ 1 2))
  (setq insp(getpoint "\nCrossing point: \n"))
  (setq x(car insp))
  (setq y(cadr insp))
  (setq ss(ssget "c" (list (- x 1)(- y 1))(list (+ x 1)(+ y 1))))
  (if (/= ss nil)
    (setq len(sslength ss))
  )
  (if(> len 1)
    (progn
      (setq index 0)
      (setq found 0)
      (while (and (< index len)(= found 0))
        (setq ent(ssname ss index))
        (setq index(1+ index))
        (setq e1(entget ent))
        (if(= (cdr(assoc 0 e1)) "LINE")
          (progn
            (setq ang(rng(angle(cdr(assoc 10 e1))(cdr(assoc 11 e1)))))
            (setq ang (if (> ang 315)(- ang 360) ang))
            (if (= bdir "V")
              (progn ; vert. lijn onderbreken
                (if(or(and(< ang 135)(> ang 45))(and(> ang 225.0)(< ang 315.0)))
	          (progn
                    (setvar "osmode" 0)
	            (command "break" ent (list x (- y brkdst))(list x (+ y brkdst)))
	            (setq found 1)
	          )))))) ;endprogn
          (if(= (cdr(assoc 0 e1)) "LWPOLYLINE")
          (progn
            (setq flg 1)
            (while (and (= flg 1) (assoc 10 e1))
              (setq p1 (cdr (setq pd1(assoc 10 e1))))
              (setq e1 (cdr (member pd1 e1)))
              (setq p2 (cdr (assoc 10 e1)))
              (setq d0 (distance p1 p2))
              (setq d1 (distance p1 insp))
              (setq d2 (distance p2 insp))
              (if (< (Abs(-(+ D1 D2) D0)) 0.001)
                (progn
                  (setq flg 0)
                  (setq ang(rng(angle p1 p2)))
                  (setq ang (if (> ang 315)(- ang 360) ang))
                  (if (= bdir "V")
                    (progn ; vert. lijn onderbreken
                      (if(or(and(< ang 135)(> ang 45))(and(> ang 225.0)(< ang 315.0)))
	                (progn
                          (setvar "osmode" 0)
	                  (command "break" ent (list x (- y brkdst))(list x (+ y brkdst)))
	                  (setq found 1)
	                )))))))))))) ;endprogn
            (setvar "osmode" osn)
  (reset nil)
)

(defun rng(ho)
  (* ho(/ 180.0 pi))
)
(prompt "...............Loaded.")
(princ)

The weird thing is that when we insert a valve into a polyline (also via a lisp routine) this does break the polyline, without converting. 

Part of that code: 

 

    (setq pt1 (polar pt (+ ang1 hk1) dist1))
      (setq pt2 (polar pt (+ ang2 hk1) dist2))
      (setq s  (ssget "c" pt1 pt2))
      (if s
        (progn
          (setq l 0 n(sslength s))
          (while (< l n)
            (setq e(ssname s l))
            (if (or (= "LINE" (cdr(assoc 0(entget e))))(= "POLYLINE" (cdr(assoc 0(entget e)))))
              (command "break" e pt1 pt2)
            )
            (setq l(1+ l))
          )
        )

Could anyone help me or point me in the right direction? I'm a bit clueless.

 

Thanks in advance!

 

Regards, 

 

Chris

0 Likes
Accepted solutions (1)
1,022 Views
8 Replies
Replies (8)
Message 2 of 9

marko_ribar
Advisor
Advisor

One thing to point :

 

This isn't the same :

 

(or(and(< ang 135)(> ang 45))(and(> ang 225.0)(< ang 315.0)))
(or (< 45.0 ang 135.0) (< 225.0 ang 315.0))

 And you probably thought ab second syntax...

 

M.R.

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

Anonymous
Not applicable

Marko,

 

Are you saying that there is a fault in the code?

 

 

I haven't written this code..Could you elaborate?

 

Edit: i see what you mean now, change the second into the first.

0 Likes
Message 4 of 9

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

.... since 2k11 the lisp routine doesn't work anymore, we need to convert the polylines (2D polylines) into LWpolylines first. 

.... when i draw two crossing polylines, it doesn't do anything

....

The weird thing is that when we insert a valve into a polyline (also via a lisp routine) this does break the polyline, without converting. 

....


I would be surprised if this problem didn't also exist prior to 2011 -- the difference between LWPOLYLINEs and POLYLINEs goes way back earlier than that, long before releases/versions were named for years.

 

The first routine doesn't contain anything to do if the entity type is "POLYLINE", but only for "LINE" and "LWPOLYLINE" objects.  Unfortunately, just changing the check for "LWPOLYLINE" into "POLYLINE" won't work, because the LWPOLYLINE approach uses the (assoc 10) entries in entity data, which are where a LWPOLYLINE keeps its vertices, but a POLYLINE stores that information in an entirely different way.  It would probably be simpler to include a check on the entity type, and apply the CONVERTPOLY command when needed, than to construct what it would need to do to work with POLYLINE objects.

 

And the second one would have a problem if you use it with a LWPOLYLINE, since it doesn't have any accounting for that possibility.

 

But there are various inefficiencies in that code, which suggest that the whole thing could be done much more simply, and I believe in a way that wouldn't care what kind of entity type was involved, and could even work with additional entity types [Arc, Circle, Spline, Ellipse, Ray, Xline].

 

But before diving into that idea, you may be able to work with other routines designed to do the same.  I expect there are several on these Forums that you could find with a Search, and I know of a simple one elsewhere, which despite talking in terms of lines would work on other object types, too.

Kent Cooper, AIA
0 Likes
Message 5 of 9

Anonymous
Not applicable

Kent, 

 

Thanks for that answer. I suspected as much. 

 

I'm not a lisp programmer, but as a script kiddie even I can see that the code is very inefficient.

 

As for the problem itself, i had to ask some collegues about when this originated. They couldn't give me a exact answer. 
Nevertheless i'll try and find a solution to this problem on this forum and the elsewhere option you suggested. 

 

Thanks for taking the time to read this problem. 

 

0 Likes
Message 6 of 9

marko_ribar
Advisor
Advisor

Further more to connect with my previous point :

This line is buggus...

 

(setq ang (if (> ang 315)(- ang 360) ang))

Consider ang=330, then ang will become -30, and that angle may satisfy your (look in the first (and)) :

 

(or(and(< ang 135)(> ang 45))(and(> ang 225.0)(< ang 315.0)))

And actually you probably didn't wanted to account for that angle - ang=330, which is refused if first syntax is omitted...

 

Instead I'd suggest :

 

(setq ang (if (> ang 360)(- ang 360) ang))

Or even better :

 

(setq ang (rem ang 360.0))

 

M.R.

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

Anonymous
Not applicable

Well,

 

Yesterday i made it work, however me and my stupid head deleted the wrong backup (the new working original). 

Luckily i am able to restore backup files of folders and i've recovered part of my working lisp. 

 

However i'm stuck. 

 

Thusfar i've got the following code, but it doesnt even show the promts. 

It just stucks on:

Enter command name to repeat: BreakVer

and when i click somewhere it cancels. 

Enter command name to repeat: BreakVer*Cancel*

This is the code

 

I've added the test prompts to check where the code would fail.. however.. no prompts at all..

;*****************************************************************************
; File         : BreakVer.lsp
; Author       : Chris D1
; Date	       : 23-03-2016
; Description  : Breaks vertical polylines
;*****************************************************************************
; Revision 1    : C.D1 23 maart 2016
;				: Updated Lisp
;*****************************************************************************
;            
(prompt "\n  breakver.lsp")
;
(defun BreakVer(n)
  (setq osn(getvar "osmode"))
  ;(setvar "osmode" 32)
  (setq insp(getpoint "\n Select crossing \n"))
  (setq x(car insp))  
  (setq y(cadr insp))
  (setq ss(ssget "c" (list (- x 2)(- y 2)(list (+ x 2)(+ y 2)))))
  (if (/= ss nil)(setq len(sslength ss)))
   (if (> len 1)
	(progn
		(prompt "test4")
			(setq index 0)
			(setq found 0)
			(while (< index len)(= found 0)
				(setq ent(ssname ss index))
				(setq index(1+ index))
				(setq e1(entget ent))
				(prompt "test5")
				(setvar "osmode" 0)
				(prompt "test6")
				(command "break" ent (list x(- y 2))(list x (+ y 2)))
				(prompt "test7")
				(setq found 1)
			)
	 )
	)
	;(setvar "osmode" osn)
)
(prompt ".....................Loaded.")
(princ)

Something isn't making the lisp run. but i cant figure out what anymore. 

 

Any advice would be greatly appreciated

 

Regards, 

 

Chris

0 Likes
Message 8 of 9

Kent1Cooper
Consultant
Consultant
Accepted solution

@Anonymous wrote:

...

  (setq ss(ssget "c" (list (- x 2)(- y 2)(list (+ x 2)(+ y 2)))))

....

Something isn't making the lisp run. but i cant figure out what anymore. 

 

....
The list for the first crossing-window corner point it not completed [a right parenthesis in the wrong place].  Try making that quoted line:
(setq ss (ssget "c" (list (- x 2) (- y 2)(list (+ x 2) (+ y 2))))

 

Kent Cooper, AIA
0 Likes
Message 9 of 9

Anonymous
Not applicable

Kent,

again my hero. (2nd time this week).

 

Now i just feel stupid for missing the bracket.. Smiley Embarassed I've looked over it a dozen times.. 

 

But i am glad, my lisp works. It's not the most elegant piece of code but it's something.

 

 

Thanks

 

Regards 

 

Chris

0 Likes