To merge / add two polylines by removing intersecting part using (entmod ...) or (vlax-put ...)

To merge / add two polylines by removing intersecting part using (entmod ...) or (vlax-put ...)

mmkkmmv
Contributor Contributor
3,090 Views
21 Replies
Message 1 of 22

To merge / add two polylines by removing intersecting part using (entmod ...) or (vlax-put ...)

mmkkmmv
Contributor
Contributor

Hi,

 

To merge 2 polylines by removing intersecting part using (entmod ...) or (vlax-put ...) see snapshot below :

 

mmkkmmv_1-1605105909981.png

 

Is below code is correct method to follow, to join 2 lwpoly using "vlax-put ..." ?

I tried below code, but it is not working if lwpoly is closed or open with its start, end points at same location, any suggestions?

 

 

 

;;; e1 to join with e2 lwpoly
(defun c:test(/ e1 e2 )
(vl-load-com)
  (setq e1(car(entsel))
        e2(car(entsel))
	obj1 (vlax-ename->vla-object e1)
  	obj2 (vlax-ename->vla-object e2)        
  	;pts1(vlax-get obj1 'Coordinates)
  	;pts2(vlax-get obj2 'Coordinates)
  ) ; end setq

  (if (= (cdr(assoc 0 (entget e1))) "LWPOLYLINE") (PROGN
    (setq e1_pts (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget e1))))
  )) ; end if
  
  (if (= (cdr(assoc 0 (entget e2))) "LWPOLYLINE")(PROGN
    (setq e2_pts (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget e2))))
  )) ; end if
  
  (setq st_pt(car e2_pts)
        end_pt (last e2_pts)
   	idx1(vlax-curve-getparamatpoint e1 st_pt)
        idx2(vlax-curve-getparamatpoint e1 end_pt)
  	idx1_fix(fix(vlax-curve-getparamatpoint e1 st_pt))
        idx2_fix(fix(vlax-curve-getparamatpoint e1 end_pt))
        reverse1 nil
  ) ; setq 
  
  (if (<= idx1_fix idx2_fix) (progn
  (if (< idx1_fix idx2_fix) (progn
  (setq c1 0
   	list1 '()
  	list2 '()) ; setq
  
  (if (= (zerop (- idx1_fix idx1)) nil) (progn
  (repeat (+ idx1_fix 1)    
  	(setq list1(append list1 (list (nth c1 e1_pts))))
  	(setq c1(1+ c1))
  ) ; repeat
  )) ; if & progn
  (setq c2 (1+ idx2_fix))  
  (repeat (- (- (length e1_pts) 1) idx2_fix)
  (setq list2(append list2 (list (nth c2 e1_pts) ) ))
    (setq c2(1+ c2))
    ) ; repeat  
  )
 (progn ; if both index equal
  ;  if required
   ) ; progn
    ) ; if
  )) ; if & progn
  
 (if (> idx1_fix idx2_fix) (progn
  (setq reverse1 T  
  	c1 (1- (length e1_pts))
  	list1 '()
  	list2 '()) ;setq
  (if (= (zerop (- idx1_fix idx1)) nil) (progn
  (repeat (- (1- (length e1_pts)) idx1_fix)    
  	(setq list1(append list1 (list (nth c1 e1_pts))))
  	(setq c1(1- c1))
  ) ; repeat
  )) ; if & progn
  
  (setq list1(reverse list1)) ; to check
  (setq c2 0)  
  (repeat (+ idx2_fix 1)
  	(setq list2(append list2 (list (nth c2 e1_pts) ) ))
    	(setq c2(1+ c2))
  ) ; repeat 
  )) ;if & progn
  
  (setq new_coords '())
  (if (= reverse1 nil)(progn
  (setq new_coords(append list1 e2_pts list2))
  )
    (progn
      (setq new_coords(append list2 (reverse e2_pts) list1))
      )
    ) ; if

  (setq obj_coords '())  
  (foreach item new_coords
    (setq obj_coords (append obj_coords (list (car item) (cadr item)) )   )
	)
  (vlax-put obj1 'Coordinates obj_coords )
  (command ".erase" e2 "")
  (vlax-release-object obj1)
  (vlax-release-object obj2)
  (princ) 
  
  ) ; end defun

 

 

suggestions will be helpful

 

Thanks & Regards,

(mmkkmmv)

0 Likes
3,091 Views
21 Replies
Replies (21)
Message 2 of 22

devitg
Advisor
Advisor

@mmkkmmv For better understanding, and maybe get further help, please upload such sample.dwg

 

0 Likes
Message 3 of 22

mmkkmmv
Contributor
Contributor

Hi,

 

@devitgplease refer above snapshot, its like breaking intersecting part of two lwpoly & joining, but using vlax-put or entmod because in some of the cases break or trim may not work

 

Thanks & Regards,

(mmkkmmv)

0 Likes
Message 4 of 22

devitg
Advisor
Advisor

@mmkkmmv  As far as I know, ACAD only can edit DWG.

0 Likes
Message 5 of 22

ronjonp
Mentor
Mentor

Why not a simple trim then join?

0 Likes
Message 6 of 22

mmkkmmv
Contributor
Contributor

@devitgsample.dwg attached for your reference, below is snapshot :

 

mmkkmmv_0-1605109499291.png

 

Thanks,

(mmkkmmv)

0 Likes
Message 7 of 22

Kent1Cooper
Consultant
Consultant

[In the case of the right-side before-&-after with the closed white one, whether it's truly "closed" or "open" with its start and end points in the same place, if the yellow one touches (or crosses) the white one at both ends, you can just use BOUNDARY or BPOLY.]

Kent Cooper, AIA
0 Likes
Message 8 of 22

Kent1Cooper
Consultant
Consultant

@mmkkmmv wrote:

.... in some of the cases break or trim may not work ....


Does that mean that the yellow one may not always actually touch the white one?  I haven't studied how it figures the new set of coordinates to use, but does it depend on the end vertices of the yellow one coinciding with vertices in the white one?

Kent Cooper, AIA
0 Likes
Message 9 of 22

mmkkmmv
Contributor
Contributor

@Kent1Cooper  yellow color lwpoly will always snap to white one, and at right side white color poly (in snapshot) is closed  and it can be open with start, end point at same location, any suggestions in above code given?

0 Likes
Message 10 of 22

Kent1Cooper
Consultant
Consultant

I can't take the time right now to study the code and understand how it makes its new coordinates list -- maybe later.  The syntax of the (vlax-put...) looks correct to me, and you can certainly change the shape of a Polyline by giving it a new Coordinates list like that, if you don't need to deal with the complications of arc segments.  It's just a question of how that list is built.  The best way to do that may be affected by whether the start/end of a closed [or apparently-closed] white one is within the to-be-removed range -- would that ever happen?

Kent Cooper, AIA
0 Likes
Message 11 of 22

mmkkmmv
Contributor
Contributor

@Kent1Cooper  the major issue is from closed (or apparently closed) lwpoly, i have got two entities to process in code (white, yellow ones) i have tried trim, break in code but its not working in all cases (especially with closed ones), I have checked "-Boundary" command (its a nice suggestion) but how to get inside point (there are many other lwpoly surrounding them), actually these are contours lines, user will modify these contours(lwpolylines) if it is bumpy  to somewhat straighten them or vice versa, there are many contours going round and round adjacent to each other, to get "internal point" is difficult for me, any suggestions?

 

Thanks,

(mmkkmmv)

0 Likes
Message 12 of 22

Kent1Cooper
Consultant
Consultant

@mmkkmmv wrote:

.... these are contours lines, user will modify these contours(lwpolylines) if it is bumpy  to somewhat straighten them or vice versa, there are many contours going round and round adjacent to each other, to get "internal point" is difficult for me, any suggestions?

....


That makes BOUNDARY/BPOLY less likely to be useful, because there would be two  resulting objects, one along the inner and one the outer edge of the space the internal point is in.  But if you could count on always  wanting the same one [e.g. the outer one], that could be determined by comparing areas.

Kent Cooper, AIA
0 Likes
Message 13 of 22

ВeekeeCZ
Consultant
Consultant

@mmkkmmv wrote:

...

Is below code is correct method to follow, to join 2 lwpoly using "vlax-put ..." ?

I tried below code, but it is not working if lwpoly is closed or open with its start, end points at same location, any suggestions?

...


 

The is really no magic function that will solve the issue for you. All the hard work is up to you.

And honestly, with this approach of yours, you are doomed to failure.

 

The question of 'how to do' is really the minor issue here.

The real question is 'what to do'. And the first step has to be to elaborate on the issue in detail. Not for us, for yourself. I've done this (partially) for you... you to see how much COMPLEX the issue is. Then you can start to build your program. Good luck, honestly! Be systematic, or you will fail.

 

Z9E3zK5E_0-1605174849151.png

 

Message 14 of 22

john.uhden
Mentor
Mentor

Thinking conceptually only (because my own laptop is temporarily not available), it seems that...

0.  You probably have to check that both are at the same elevation

1.  You need to find out if the two polylines intersect (probably using extendboth or maybe just the lesser one).

2.  Trim or break the greater one at the points of intersection.  BUT, if its start and end are within the area to be trimmed then you will probably have to trim twice.  If it's  closed within that area then maybe one trim will do but I can't test right now to see if that's true.

3.  Perhaps trim the lesser one if it overlaps the greater

4.  At this point you may be able to join the greater (both parts) with the lesser and you're done, though I have had plenty of experiences where AutoCAD just won't join them.  I had to write my own PJOIN command to be sure it worked every time.  But my code is not accessible right now to tell you what that entails.

4 (alternate).  You would have to sort all the vertices to be headed in the right direction, remove any duplicates where they were trimmed, get all their bulges in the same order and vlax-put the coordinates and bulges while at the same time considering if the greater was closed, because if you are as **** as I you don't want to create an unecessary vertex.

 

Oh, BTW, you have probably noticed that the coordinate list is what is called a flat list.  I don't have it with me, but my @group function is handy for converting (x1 y1 x2 y2 xn yn) to ((x1 y1)(x2 y2)(xn yn)).  You might be able to find it searching the forum, or I'll try to remember to post it on Monday 'cause I left my flash drive at work.

Then, to put the list of points back to flat, all you have to do is (apply 'append 2dlist).

Gotta go as my mind is drifting toward the prime strip steak I bought for dinner and I want my cocktails first.

John F. Uhden

Message 15 of 22

john.uhden
Mentor
Mentor

@mmkkmmv :

It was there.  I just found it for you...

(defun @group (old n / item new)
  (while old
    (while (< (length item) n)
      (setq item (cons (car old) item) old (cdr old))
    )
    (setq new (cons (reverse item) new) item nil)
  )
  (reverse new)
)

which can be used as follows:

 

Command: (setq coords '(1 2 3 4 5 6 7 8 9)
Command: (@group coords 3)
((1 2 3) (4 5 6) (7 8 9))

or

Command: (setq coords '(1 2 3 4 5 6 7 8)
Command: (@group coords 2)
((1 2)(3 4)(5 6)(7 8))

John F. Uhden

0 Likes
Message 16 of 22

devitg
Advisor
Advisor

@john.uhden Hi , it is what I use, from the unforgettable Fatty TOH and also known as Fixo at Augi   , who helped to all us. Sad to say he had passed away about 5 years ago. 

 

fixo avatar augi.png

;;;GROUP
;;;LIST
;;;BY
;;;NUMBER
 ; written by Fatty T.O.H
(DEFUN GROUP-BY-NUM/lst-num  (LST
                      NUM
                      /
                      LS
 ;ret
                      )
  (IF (= (REM (LENGTH LST) NUM) 0)
    (PROGN
      (SETQ LS NIL)
      (REPEAT (/ (LENGTH LST) NUM)
        (REPEAT NUM
          (SETQ LS
                    (CONS (CAR LST) LS)
                LST (CDR LST)))
        (SETQ RET (APPEND RET (LIST (REVERSE LS)))
              LS  NIL)))
    )
  RET
  )

God bless him . 

0 Likes
Message 17 of 22

john.uhden
Mentor
Mentor

Well, I was outta here for about 10 years, so I don't remember Fatty or Fixo, but I like mine better.

Anyway, I haven't time tested, but (vl-remove-if-not-dxf10) <that's not a real function but a nickname for the process> might be faster than @grouping a flat list.  I dunno.  I guess the correct answer is whatever works for you.  When you are removing ravaiolis from a pot, does it matter whether the holes in your big spoon are round or oval?

John F. Uhden

0 Likes
Message 18 of 22

devitg
Advisor
Advisor

@john.uhden , did not say which is better , the Fatty defun controls if the list length is multiple of the group to do . 

Of course that flat list from variants are always 2 or 3 multiple, but group could be any other number . 

About Fatty , he participate at the .net forum  at ADSK, and very often at AUGI. I get references from others lispers , taht Fatty was a good helper. 

About raviolis, I hope hole are smaller than raviolis.

0 Likes
Message 19 of 22

mmkkmmv
Contributor
Contributor

@ВeekeeCZwrote :

 

...
I've done this (partially) for you...

 

@Z9E3zK5E thanks for your effort

 

Regards,

(mmkkmmv)

0 Likes
Message 20 of 22

mmkkmmv
Contributor
Contributor

@john.uhdenwrote

It was there. I just found it for you...

 

@john.uhdenthanks for your effort to get the code, i appreciate that, it might useful to convert vla-.. 'coordinates in pairs or any other use as required, its just a suggestion for everyone, need to put some condition before 'while' to avoid 'reset break loop' if n is 0 or less in said function [@group (old n /)]

 

Thanks again for effort and reply

 

Regards,

(mmkkmmv)

0 Likes