Author Topic: Joining Polylines with Gaps  (Read 3308 times)

0 Members and 1 Guest are viewing this topic.

cmwade77

  • Swamp Rat
  • Posts: 1443
Joining Polylines with Gaps
« on: May 09, 2018, 03:30:13 PM »
I am working on updating my join all routine to include joining co-planar polylines with gaps. Now I haven't gotten very far yet, but here is essentially what I need to do to make it work:

I am thinking that I need to keep track of the width of each polyline, explode them, then turn them back into polylines and reset the widths as appropriate, but perhaps there is another way, as I am unsure how I would track the widths of the polylines.


Code: [Select]
;Written by: Chris Wade
;Permission to use/modify/distribute is granted as long as this notice remains and all changes are documented.

;Version 2.0 - 05/??/2018 - Chris Wade
;   - Added support for joining polyLines
(DEFUN C:ja ( / *error* uFlag doc StopLoop SelSet SelLen LoopCT ent Type PlStWidth PlEdWidth)
(defun ja-work (SelSet)
(if (/= SelSet nil)
(progn
(vla-StartUndoMark doc)
(setq uFlag t)
(setq SelLen (sslength SelSet))
(setq LoopCT 0)
(while (< LoopCT SelLen)
    (setq ent (ssname SelSet LoopCT)
          Type (cdr (assoc 0 Ent))
    )
    (if (or (= Type "LWPOLYLINE") (= Type "POLYLINE")
        (progn
            (setq PlStWidth (cdr (assoc 40 Ent))
                  PlEdWidth (cdr (assoc 41 Ent))
            )
           
            (vl-cmdf "._join" ent SelSet "")
        )
        (progn
            (vl-cmdf "._join" ent SelSet "")
        )
    )
(setq LoopCT (+ LoopCT 1))
)
(vla-EndUndoMark doc)
(setq uFlag nil)
)
)
)
(vl-load-com)
(setq doc   (vla-get-ActiveDocument
                (vlax-get-acad-object)))
(defun *error* (msg)
(if (and uflag doc) (vla-EndUndoMark doc))
(or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")
(princ (strcat "\n** Error: " msg " **")))
(princ)
)
(while (= StopLoop nil)
(princ  "\nPlease select the objects that you would like to join:  ")
(setq SelSet (ssget))
(cond
((/= SelSet nil)
(ja-work SelSet)
)
(T
(setq StopLoop T)
)
)

    )
(princ)
);defun c:ja

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Joining Polylines with Gaps
« Reply #1 on: May 14, 2018, 07:02:53 PM »
Bumping this back up to see if anyone has any more ideas.

ronjonp

  • Needs a day job
  • Posts: 7527
Re: Joining Polylines with Gaps
« Reply #2 on: May 14, 2018, 07:58:41 PM »
Mpedit with fuzz ?

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Joining Polylines with Gaps
« Reply #3 on: May 16, 2018, 01:38:06 PM »
Unfortunately, that didn't work, perhaps I am not explaining clearly, I have attached a screenshot to help explain. Now the trick is sometimes the polylines may have various widths and I would want to reassign the widths after exploding the polylines.

ronjonp

  • Needs a day job
  • Posts: 7527
Re: Joining Polylines with Gaps
« Reply #4 on: May 16, 2018, 02:09:15 PM »
Why are you exploding them?

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Joining Polylines with Gaps
« Reply #5 on: May 16, 2018, 02:13:47 PM »
That seems to be the only way to make them work with the join command. Ultimately, I want the polyline to join completely and be one single segment where possible, see attached screenshot for example.

ChrisCarlson

  • Guest
Re: Joining Polylines with Gaps
« Reply #6 on: May 16, 2018, 04:20:39 PM »
That seems to be the only way to make them work with the join command. Ultimately, I want the polyline to join completely and be one single segment where possible, see attached screenshot for example.

Once it's joined, perform an overkill on the resulting entity.

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Joining Polylines with Gaps
« Reply #7 on: May 16, 2018, 05:46:05 PM »
Ok, getting closer, but now I have an error that creates an extra line closing to two ends. My code is below, this relies on some express tools with some modifications, the modified portions are in my routine below. I have attached an animated screenshot that shows what is going on.

Code: [Select]
;Written by: Chris Wade
;Permission to use/modify/distribute is granted as long as this notice remains and all changes are documented.

;Version 2.0 - 05/??/2018 - Chris Wade
;   - Added support for joining polyLines
(DEFUN C:ja ( / *error* uFlag doc StopLoop SelSet SelLen LoopCT ent PlStWidth PlEdWidth flt)
;;;
;;;    MPEDIT.LSP
;;;    Copyright © 1999 by Autodesk, Inc.
;;;
;;;    Your use of this software is governed by the terms and conditions of the
;;;    License Agreement you accepted prior to installation of this software.
;;;    Please note that pursuant to the License Agreement for this software,
;;;    "[c]opying of this computer program or its documentation except as
;;;    permitted by this License is copyright infringement under the laws of
;;;    your country.  If you copy this computer program without permission of
;;;    Autodesk, you are violating the law."
;;;
;;;    AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
;;;    AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
;;;    MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE.  AUTODESK, INC.
;;;    DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
;;;    UNINTERRUPTED OR ERROR FREE.
;;;
;;;    Use, duplication, or disclosure by the U.S. Government is subject to
;;;    restrictions set forth in FAR 52.227-19 (Commercial Computer
;;;    Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
;;;    (Rights in Technical Data and Computer Software), as applicable.
;;;
;;;  ----------------------------------------------------------------
 
;;;    Multiple objects can be selected for the equivalent of the pedit operation
;;;    on polylines.  Objects that are not polylines will be filtered out of the
;;;    selection set.
;;;
(defun ja-mpedit (plines / ss ss2 )

 

 (if plines
     (setq plines (acet-ss-filter-current-ucs plines T))
 );if
 (if plines
     (setq plines (car (acet-ss-filter (list plines '(("CURRENTUCS")) T))))
 );if
 (princ "\n")
 (if plines
     (setq ss (ja-convert plines));setq
 );if
 (if (and ss
          (> (sslength ss) 0)
          plines
     );and
     (ja-mpedit2 ss "Join") ;after conversion, plines sset is duplicated in ss
     (progn
      (if (not plines)
          (princ "\nNothing selected.")
          (princ "\nNo valid objects selected.")
      );if
     );progn else
 );if
 ss
 
);defun c:mpedit

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; mpedit functionality and switch cases based on kword input operation
 
(defun ja-mpedit2 (plines opt / newWidth ss flt fuz st na ss2 )
 
 ; (while (/= opt "eXit")
  ;(initget 0 "Open Close Join Ltype Decurve Fit Spline Width eXit _Open Close Join Ltype Decurve Fit Spline Width eXit")
  ; (setq opt (getkword "\nEnter an option [Open/Close/Join/Width/Fit/Spline/Decurve/Ltype gen/eXit] <eXit>: "))
   ;Changed code below to a cond structure to improve readability R.K.
 
   (if (and opt
            (not (equal opt "eXit"))
       );and
       (acet-undo-begin)
       (acet-undo-end)
   );if
 
   (cond
    ((not opt) (setq opt "eXit"))
    ((= opt "Open") (chgplopen plines)) ;open
    ((= opt "Close") (chgplclose plines));close
    ((= opt "Ltype") (chgltgen plines)) ;ltgen
    ((= opt "Decurve") (chgdecurve plines));decurve
    ((= opt "Fit") (chgfit plines))
    ((= opt "Spline") (chgspline plines))
    ((= opt "Width")
     (initget 69)
     (setq newWidth (getdist "\nEnter new width for all segments: "))
     (chgplwidths plines newWidth)
    );width option
    ((= opt "Join")
     (setq flt '((-4 . "<OR")
                  (0 . "LINE")
                  (0 . "ARC")
                  (-4 . "<AND")
                   (0 . "*POLYLINE")
                   (-4 . "<NOT") (-4 . "&") (70 . 89)  (-4 . "NOT>") ;1 8 16 64
                  (-4 . "AND>")
                 (-4 . "OR>")
                )
           flt (list flt
                     "\n1 object is invalid for join."
                     "\n%1 objects are invalid for join."
               );list
           flt (list flt
                     (list "LAYERUNLOCKED")
                     (list "CURRENTUCS")
               );list
            ss (car (acet-ss-filter (list plines flt T)))
     );setq
 
     ;(acet-autoload (list "pljoin.lsp" "(acet-pljoin-get-fuzz-and-mode)"))
     (acet-autoload (list "pljoin.lsp" "(acet-pljoin ss st fuz)"))
 
     (if ss
         (progn
          (setvar "highlight" 0)
          (setq fuz (ja-acet-pljoin-get-fuzz-and-mode2)
                 st (cadr fuz)
                fuz (car fuz)
                 na (entlast)
          );setq
          (acet-pljoin2 ss st fuz)
          (setq ss2 (acet-ss-new na))
          (setq plines (acet-ss-union (list plines ss2)))
         );progn then
         (princ "\nNo valid objects to join.")
     );if
    );cond Join option
   );cond close
  ;);while
);defun mpedit

;;;
;;;    PLJOINSUP.LSP
;;;    Copyright © 1999 by Autodesk, Inc.
;;;
;;;    Your use of this software is governed by the terms and conditions of the
;;;    License Agreement you accepted prior to installation of this software.
;;;    Please note that pursuant to the License Agreement for this software,
;;;    "[c]opying of this computer program or its documentation except as
;;;    permitted by this License is copyright infringement under the laws of
;;;    your country.  If you copy this computer program without permission of
;;;    Autodesk, you are violating the law."
;;;
;;;    AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
;;;    AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
;;;    MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE.  AUTODESK, INC.
;;;    DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
;;;    UNINTERRUPTED OR ERROR FREE.
;;;
;;;    Use, duplication, or disclosure by the U.S. Government is subject to
;;;    restrictions set forth in FAR 52.227-19 (Commercial Computer
;;;    Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
;;;    (Rights in Technical Data and Computer Software), as applicable.
;;;
;;;  ----------------------------------------------------------------

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;prompt for fuzz distance and/or pljoinmode setting.
;return list... (fuzz pljoinmode)
;
(defun ja-acet-pljoin-get-fuzz-and-mode2 ( / st fuzz )
  (setq st (acet-pljoin-init-mode2))
  (princ (acet-str-format "\n Join Type = %1" st))
  (if (equal "Both" st)
      (princ " (Fillet and Add) ")
  );if
  (if (not #acet-pljoin-fuzz)
      (setq #acet-pljoin-fuzz 0.0)
  );if
  (if (assoc "OSMODE" (car acet:sysvar-list))
      (setvar "OSMODE" (cadr (assoc "OSMODE" (car acet:sysvar-list))))
  );if
  (setq fuzz "")
  (while (equal (type fuzz) 'STR)
   (initget "Jointype _Jointype" 4)
   (setq fuzz 500.0
             ;(getdist
              ;  (acet-str-format "\nEnter fuzz distance or [Jointype] <%1>: " (rtos #acet-pljoin-fuzz))
              ;);getdist
   );setq
   (cond
    ((not fuzz)
     (setq fuzz #acet-pljoin-fuzz)
    );cond #1
    ((equal "Jointype" fuzz)
     (acet-pljoinmode2)
    );cond #2
    ((equal (type fuzz) 'REAL)
     (setq #acet-pljoin-fuzz fuzz)
    );cond #3
   );cond close
  );while
  (setvar "osmode" 0)
 
  (list #acet-pljoin-fuzz #acet-pljoinmode)
);defun acet-pljoin-get-fuzz-and-mode


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Convert arcs and lines to polylines
;;; ss is retained as a duplicate of the plines selection set because
;;; after conversion, new handles are assigned to what were arcs and lines
(defun ja-convert ( plines / ss count opt )
 ;(if (> (sslength plines) 0)
  ;   (progn
   ;   (initget 0 "Yes No _Yes No")
    ;  (setq opt (getkword "Convert Lines and Arcs to polylines? [Yes/No] <Yes>: "))
     ;);progn then
 ;);if
 (if (not opt)
     (setq opt "Yes")
 )
 (if (and (= opt "Yes")
          (> (sslength plines) 0)
     );and
     (progn ;if yes -- convert lines and arcs to polylines
      (acet-undo-begin)
      (setq ss (ssadd))
      (setq count 0)
      (while (< count (sslength plines))
       (if (or (equal (assoc 0 (entget (ssname plines count))) '(0 . "ARC"))
               (equal (assoc 0 (entget (ssname plines count))) '(0 . "LINE"))
           );or
           (progn
            (command "_.pedit" (ssname plines count) "_yes" "_exit")
            (ssadd (entlast) ss)
           );progn true
           (ssadd (ssname plines count) ss)
       );if
       (setq count (1+ count))
      );while
      (acet-undo-end)
     );progn yes
     (progn ;if no -- do not convert
      (setq ss plines)
      (setq count 0)
      (while (< count (sslength ss))
       (if (or (equal (assoc 0 (entget (ssname ss count))) '(0 . "ARC"))
               (equal (assoc 0 (entget (ssname ss count))) '(0 . "LINE"))
           );or
           (progn
            (ssdel (ssname ss count) ss)
            (setq count (1- count))
           );progn true
       );if
       (setq count (1+ count))
      );while
     );progn no
 );if
 (if (and ss
          (equal (type ss) 'PICKSET)
          (equal 0 (sslength ss))
     );and
     (setq ss nil)
 );if
ss
)

(defun ja-work (SelSet)
(if (/= SelSet nil)
(progn
(vla-StartUndoMark doc)
(setq uFlag t)
(setq SelLen (sslength SelSet))
(setq LoopCT 0)
(while (< LoopCT SelLen)
            (vl-cmdf "._join" ent SelSet "")
    (setq LoopCT (+ LoopCT 1))
)
(vla-EndUndoMark doc)
(setq uFlag nil)

)
)
)
(vl-load-com)
(setq doc   (vla-get-ActiveDocument
                (vlax-get-acad-object)))
(defun *error* (msg)
(if (and uflag doc) (vla-EndUndoMark doc))
(or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")
(princ (strcat "\n** Error: " msg " **")))
(princ)
)
(while (= StopLoop nil)
(princ  "\nPlease select the objects that you would like to join:  ")
(setq SelSet (ssget ":l" '(
        (-4 . "<OR")
         (0 . "ARC")
         (0 . "LINE")
         (-4 . "<AND")
          (0 . "*POLYLINE")
          (-4 . "<NOT") (-4 . "&") (70 . 88) (-4 . "NOT>") ;8 16 64 not a 3dpoly or 3d/pface mesh
         (-4 . "AND>")
         (0 . "LWPOLYLINE")
        (-4 . "OR>")
                  )
              ))
(cond
((/= SelSet nil)
    (setq SelSet (ja-mpedit SelSet))
    (command "-overkill" SelSet "" "p" "" "")
    (ja-work SelSet)
)
(T
(setq StopLoop T)
)
)

    )
(princ)
);defun c:ja

trogg

  • Bull Frog
  • Posts: 255
Re: Joining Polylines with Gaps
« Reply #8 on: May 18, 2018, 06:37:23 PM »
Chris,

There might be something helpful is this "Heal" routine posted by PBE at http://www.cadtutor.net/forum/showthread.php?73328-Joining-2-commands

After the routine deletes the block, it joins the 2 colinear lines or polylines. Maybe there is something helpful in there.

~Greg

Code: [Select]
; by PBE
; http://www.cadtutor.net/forum/showthread.php?73328-Joining-2-commands
; erase a block and join the lines that the block broke
(defun c:hint ()
   (if (setq ss (ssget '((0 . "INSERT"))))
    (repeat (setq i (sslength ss))
  (setq pt  (cdr
(assoc  10
   (entget
     (setq e (ssname ss (setq i (1- i))))
   ))))
  (command "_rotate" e "" "_non" pt "180")
  )
     )(princ)
   )

(defun c:HEAL (/ pea $blk block i ll ur objs p1 p2)
  (vl-load-com)
  (setq pea (getvar 'Peditaccept))
  (setvar 'PeditAccept 1)
  (if (setq $blk (ssget '((0 . "insert"))))
  (repeat (setq i (sslength $blk))
    (setq e (ssname  $blk (setq i (1- i))))
  (vla-getboundingbox (vlax-ename->vla-object e) 'll 'ur)
    (entdel e)
  (setq objs (ssget "C"
      (setq p1 (vlax-safearray->list ll))
      (setq p2 (vlax-safearray->list ur))
      )
  )
(if (eq (cdr (assoc 0 (entget (ssname objs 0)))) "LWPOLYLINE")
  (command "_.pedit"  "_m"  objs
   ""  "_join" "_Joint"
   "_Both" (distance p1 p2)
   "" )
  (command "_.join" (ssname objs 0) (ssname objs 1) "")
)
    )
    (princ "\nNo Blocks Selected")
    )
  (setvar 'PeditAccept pea)
  (princ)
)

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Joining Polylines with Gaps
« Reply #9 on: May 22, 2018, 07:56:55 PM »
Ok, I have made some changes and this was working, but all of the sudden it stopped working, can someone please help me figure out where the errors are?

Code: [Select]
;Written by: Chris Wade
;Permission to use/modify/distribute is granted as long as this notice remains and all changes are documented.

;Version 2.0 - by Chris Wade - 05/??/2018
;Made the routine work better with polylines

(DEFUN C:ja ( / *error* uFlag doc StopLoop SelSet SelLen LoopCT OldPeditAccept ScaleFactor)
;Collinear test adapted from code at: https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/colinear-lines/m-p/836033/highlight/true#M61691
(defun ja-collinear (e1 e2 / p1 p2 p3 p4 Obj1 Obj2 Results)
    (vl-load-com)
    (if (/= e1 nil)
        (setq obj1 (vlax-ename->vla-object e1))
    )
    (if (/= e2 nil)
        (setq obj2 (vlax-ename->vla-object e2))
    )
    (if (and (/= obj1 nil) (/= Obj2 nil))
        (progn
            (setq p1 (vlax-curve-getStartPoint Obj1)
                  p2 (vlax-curve-getEndPoint Obj1)
                  p3 (vlax-curve-getStartPoint Obj2)
                  p4 (vlax-curve-getEndPoint Obj2)
            )
        )
    )
    (if (and (/= p1 nil) (/= p2 nil) (/= p3 nil) (/= p4 nil))
        (setq Results
            (and
                (null (inters p1 p2 p3 p4 nil))
           
                (null (inters p1 p2 p1 p4 nil))
            )
        )
    )
    Results
)

(defun ja-work (SelSet / ent LoopCt2 SS2 ent2 type2 type1 e1 e2 pLine2)
(if (/= SelSet nil)
(progn
(vla-StartUndoMark doc)
(setq uFlag t)
(setq SelLen (sslength SelSet))
(setq LoopCT 0)

(while (< LoopCT SelLen)
    (setq e1 (ssname SelSet LoopCT)
          ent (entget (ssname SelSet LoopCT))
          type1 (cdr (assoc 0 Ent)) 
    )
   
   
            (setq LoopCt2 0
                  SS2 nil
                  SS2 (ssadd)
                  pLine2 nil
            )
            (ssadd e1 SS2)
            (while (< LoopCT2 SelLen)
                (setq e2 (ssname SelSet LoopCT2)
                      ent2 (entget (ssname SelSet LoopCT2))
                      type2 (cdr (assoc 0 ent2))
                )
                (if (or (= Type2 "LWPOLYLINE") (= Type2 "POLYLINE") (= Type2 "LINE") (= Type2 "ARC"))
                    (progn
                        (if (ja-collinear e1 e2)
                            (ssadd e2 SS2)
                            (if (or (= Type2 "LWPOLYLINE") (= Type2 "POLYLINE"))
                                (setq pLine2 T)
                            )
                        )
                    )
                )
                (setq LoopCT2 (+ LoopCT2 1))
            )
            (if (or (= Type1 "LWPOLYLINE") (= Type1 "POLYLINE") (/= Pline2 nil))
                (progn
                    (if (/= SS2 nil)
                        (progn
                            (setq OldPeditAccept (getvar "peditaccept"))
                            (setvar "peditaccept" 1)
                            (setq ScaleFactor (* (getvar "dimscale") 0.25))
                            (command "._pedit" "_m" SS2 "" "_Join" "_Joint" "_both" ScaleFactor "")
                            (ssadd (entlast) SS2)
                            (setvar "peditaccept" OldPeditAccept)
                            (command "._-overkill" SS2 "" "_Ignore" "_None" "_tOlerance" ScaleFactor "_P" "_B" "_Y" "_Y" "_T" "_Y" "_E" "_Y" "_A" "_Y" "_Done")
                        )
                    )
                )
                (progn
                    (if (/= SS2 nil)
                        (command "._join" e1 SS2 "")
                    )
                )
            )
   
    (setq LoopCT (+ LoopCT 1))
)
;
(vla-EndUndoMark doc)
(setq uFlag nil)
)
)
)
(vl-load-com)
(setq doc   (vla-get-ActiveDocument
                (vlax-get-acad-object)))
(defun *error* (msg)
(if (and uflag doc) (vla-EndUndoMark doc))
(or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")
(princ (strcat "\n** Error: " msg " **")))
(princ)
)
(while (= StopLoop nil)
(princ  "\nPlease select the objects that you would like to join:  ")
(setq flt '((-4 . "<OR")
                  (0 . "LINE")
                  (0 . "ARC")
                  (-4 . "<AND")
                   (0 . "*POLYLINE")
                   (-4 . "<NOT") (-4 . "&") (70 . 89)  (-4 . "NOT>") ;1 8 16 64
                  (-4 . "AND>")
                 (-4 . "OR>")
                )
                )
(setq SelSet (ssget flt))
(cond
((/= SelSet nil)
(ja-work SelSet)
)
(T
(setq StopLoop T)
)
)

    )
(princ)
);defun c:ja

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Joining Polylines with Gaps
« Reply #10 on: May 24, 2018, 07:17:52 PM »
Just a heads up, after restarting AutoCAD, the code in my previous post works again, perhaps someone can help me figure out why it stops working at times?