Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Lisp to join multiple lines together ?

14 REPLIES 14
Reply
Message 1 of 15
shehab10
11761 Views, 14 Replies

Lisp to join multiple lines together ?

Hello,

I want to join multiple lines together like join command
but with multi selection.

 

14 REPLIES 14
Message 2 of 15
Lee_Mac
in reply to: shehab10

The following program is only a quick draft but should join all collinear lines found in a selection, whilst retaining all properties of the original lines:

 

;; Join Lines  -  Lee Mac
;; Joins collinear lines in a selection, retaining all original properties.

(defun c:joinlines ( / process e i l s x )

    (defun process ( l / x r )
        (if (setq x (car l))
            (progn
                (foreach y (cdr l)
                    (if (vl-every '(lambda ( a ) (apply 'LM:collinear-p (cons a (cdr x)))) (cdr y))
                        (setq x (cons (car x) (LM:furthestapart (append (cdr x) (cdr y)))))
                        (setq r (cons y r))
                    )
                )
                (entmake (append (car x) (mapcar 'cons '(10 11) (cdr x))))
                (process r)
            )
        )
    )
    (if (setq s (ssget "_:L" '((0 . "LINE"))))
        (process
            (repeat (setq i (sslength s))
                (setq e (ssname s (setq i (1- i)))
                      x (entget e)
                      e (entdel e)
                      l (cons (list x (cdr (assoc 10 x)) (cdr (assoc 11 x))) l)
                )
            )
        )
    )
    (princ)
)

;; Furthest Apart  -  Lee Mac
;; Returns the two points furthest apart in a given list

(defun LM:furthestapart ( lst / di1 di2 pt1 rtn )
    (setq di1 0.0)
    (while (setq pt1 (car lst))
        (foreach pt2 (setq lst (cdr lst))
            (if (< di1 (setq di2 (distance pt1 pt2)))
                (setq di1 di2
                      rtn (list pt1 pt2)
                )
            )
        )
    )
    rtn
)

;; Collinear-p  -  Lee Mac
;; Returns T if p1,p2,p3 are collinear

(defun LM:Collinear-p ( p1 p2 p3 )
    (
        (lambda ( a b c )
            (or
                (equal (+ a b) c 1e-8)
                (equal (+ b c) a 1e-8)
                (equal (+ c a) b 1e-8)
            )
        )
        (distance p1 p2) (distance p2 p3) (distance p1 p3)
    )
)

(princ)

 

If two or more collinear lines hold differing properties, the resulting joined line will inherit the properties of an arbitrary line from the set of collinear lines.

 

The program should perform successfully in all UCS & views and with 3D collinear lines.

Tags (3)
Message 3 of 15
3wood
in reply to: Lee_Mac

It looks like he wants to join Mlines, not Lines.

Message 4 of 15
Lee_Mac
in reply to: 3wood


@3wood wrote:

It looks like he wants to join Mlines, not Lines.


Let's hope not! Smiley Sad

Message 5 of 15
shehab10
in reply to: Lee_Mac

Right now i am satisified with this codeMan Happy

i just want something extra looks like similar but different which is making lisp draw line between two lines when making window selection

 i put here in this post  

http://forums.autodesk.com/t5/Visual-LISP-AutoLISP-and-General/Construct-lines-between-Lines-ending-...

Message 6 of 15
jsuryakanth
in reply to: Lee_Mac

         Hi,

 

 

            Can any one please help me this Q:I want to combine multiple grids each other in this case i want to join all boundary lines,polyline,3D polylines with the same layer. Is there any lisp tool is available please let me know. 

            

         

              Thanks in advance.

 

 

Regards

Suryakanth J

Message 7 of 15
Kent1Cooper
in reply to: jsuryakanth


@jsuryakanth wrote:

....I want to combine multiple grids each other in this case i want to join all boundary lines,polyline,3D polylines with the same layer. Is there any lisp tool is available please let me know. 

....


Try this.

[EDIT:  I haven't downloaded it and tried it, so I don't know whether it will do 3DPolylines.  If it works with PEDIT and the Join option, in my version here that won't work with 3DPolylines, but something else could be done to connect them.]

Kent Cooper, AIA
Message 8 of 15
Tom2023
in reply to: Lee_Mac

Awesome codes Lee as always. Is it possible to delete all Blocks in the Selection Window too?

 

I've tried

 

(set s2 (ssget ":L" ' ((0 . "INSERT"))))

(command "erase" s2 " ")

 

But I have to do the Selection Window twice. Is there a way to just do it once? Thank you.

Message 9 of 15
Kent1Cooper
in reply to: Tom2023


@Tom2023 wrote:

...

(set s2 (ssget ":L" ' ((0 . "INSERT"))))

(command "erase" s2 " ")

....


Does it work if you remove the extraneous spaces?  I see two that should not be there, in the upper line between the apostrophe and the left parenthesis, and in the lower line between the double-quotes at the end.

Kent Cooper, AIA
Message 10 of 15
Tom2023
in reply to: Kent1Cooper

Thank you for the reply Kent1Cooper. Unfortunately, I still have to do the Selection Window twice.

 


;;;;;;;;;; MODIFIED

;; Join Lines - Lee Mac
;; Joins collinear lines in a selection, retaining all original properties.


;; Join Lines - Lee Mac
;; Joins collinear lines in a selection, retaining all original properties.

(defun c:fx ( / process e i l s x )

(defun process ( l / x r )
(if (setq x (car l))
(progn
(foreach y (cdr l)
(if (vl-every '(lambda ( a ) (apply 'LM:collinear-p (cons a (cdr x)))) (cdr y))
(setq x (cons (car x) (LM:furthestapart (append (cdr x) (cdr y)))))
(setq r (cons y r))
)
)
(entmake (append (car x) (mapcar 'cons '(10 11) (cdr x))))
(process r)
)
)
)

;;;;;;;;;;;;;;; MODIFIED
(if (setq s2 (ssget ":L"'((0 . "INSERT"))))
(command "erase" s2 ""))
;;;;;;;;;;;;;;;

(if (setq s (ssget "_:L" '((0 . "LINE"))))
(process
(repeat (setq i (sslength s))
(setq e (ssname s (setq i (1- i)))
x (entget e)
e (entdel e)
l (cons (list x (cdr (assoc 10 x)) (cdr (assoc 11 x))) l)
)
)
)

)

(princ)
)

Message 11 of 15
Kent1Cooper
in reply to: Tom2023


@Tom2023 wrote:

Thank you for the reply Kent1Cooper. Unfortunately, I still have to do the Selection Window twice.

....

(if (setq s2 (ssget ":L"'((0 . "INSERT"))))
....

(if (setq s (ssget "_:L" '((0 . "LINE"))))
....


Well, now that you show the whole thing, of course you need two selections if you have two (ssget) functions that don't include one of the modes that applies itself without User selection.

 

Try this approach that selects both kinds of things together, then goes through and eliminates any Blocks before processing the Lines [untested].  Leave everything before your ;;;;; MODIFIED line, and everything after the  (process  line, and replace what's between with this:

(if (setq s (ssget ":L" '((0 . "LINE,INSERT"))))
  (repeat (setq n (sslength s)); then
    (setq ent (ssname s (setq n (1- n))))
    (if (member '(0 . "INSERT") (entget ent))
      (progn ; then
        (ssdel ent s); remove from selection set
        (entdel ent); and from drawing
      ); progn
    ); if
  ); repeat
); if

(if s ; anything left? [will be LINEs]
  (process
    .....

 

Kent Cooper, AIA
Message 12 of 15
Tom2023
in reply to: Kent1Cooper

Thank you Kent. It's beautiful! Exactly like you say.

Message 13 of 15
Peter_MElad
in reply to: Lee_Mac

@Lee_Mac  it is like a charm is there a lisp for trim/join/trim...Thanks in Advance

mina.PNG

lines

Message 14 of 15
marko_ribar
in reply to: Peter_MElad

Have you tried PEDIT command with Multiple and Join options and with large fuzz factor for joining... I suppose that it should work, but for collinear cases, it'll make extra vertex where joining occur... For that situation, try this code :

 

(defun c:lwsdvts ( / *error* ftoa groupbynum assocon tang prelst suflst foo process osm cmd ss ti i pl obj len )

  (defun *error* ( m )
    (if (= 8 (logand 8 (getvar (quote undoctl))))
      (if command-s
        (command-s "_.UNDO" "_E")
        (vl-cmdf "_.UNDO" "_E")
      )
    )
    (if cmd
      (setvar (quote cmdecho) cmd)
    )
    (if osm
      (setvar (quote osmode) osm)
    )
    (if m
      (prompt m)
    )
    (princ)
  )

  (defun ftoa ( n / m a s b )
    (if (numberp n)
      (progn
        (setq m (fix ((if (< n 0) - +) n 1e-8)))
        (setq a (abs (- n m)))
        (setq m (itoa m))
        (setq s "")
        (while (and (not (equal a 0.0 1e-6)) (setq b (fix (* a 10.0))))
          (setq s (strcat s (itoa b)))
          (setq a (- (* a 10.0) b))
        )
        (if (= (type n) (quote int))
          m
          (if (= s "")
            m
            (if (and (= m "0") (< n 0))
              (strcat "-" m "." s)
              (strcat m "." s)
            )
          )
        )
      )
    )
  )

  (defun groupbynum ( lst n / sub lll )

    (defun sub ( m n / ll q )
      (cond
        ( (and m (< (length m) n))
          (repeat (- n (length m))
            (setq m (append m (list nil)))
          )
          (setq ll (vl-remove-if-not (function (lambda ( x ) (setq q (if (not q) 0 (1+ q))) (< q n))) m))
          (setq lll (cons ll lll))
          (setq q nil)
          (sub (vl-remove-if (function (lambda ( x ) (setq q (if (not q) 0 (1+ q))) (< q n))) m) n)
        )
        ( m
          (setq ll (vl-remove-if-not (function (lambda ( x ) (setq q (if (not q) 0 (1+ q))) (< q n))) m))
          (setq lll (cons ll lll))
          (setq q nil)
          (sub (vl-remove-if (function (lambda ( x ) (setq q (if (not q) 0 (1+ q))) (< q n))) m) n)
        )
        ( t
          (reverse lll)
        )
      )
    )

    (sub lst n)
  )

  (defun assocon ( searchterm lst func fuzz )
    (car
      (vl-member-if
        (function (lambda ( pair )
          (equal searchterm (func pair) fuzz)
        ))
        lst
      )
    )
  )

  (defun tang ( a )
    (if (not (equal (cos a) 0.0 1e-8))
      (/ (sin a) (cos a))
      (if (minusp (cos a))
        -1e+308
        1e+308
      )
    )
  )

  (defun prelst ( lst el index / f n )
    (vl-remove-if
      (function (lambda ( a )
        (setq n (if (not n) 0 (1+ n)))
        (cond
          ( el
            (if (equal a el 1e-6)
              (not (setq f t))
              f
            )
          )
          ( index
            (if (= index n)
              (not (setq f t))
              f
            )
          )
        )
      ))
      lst
    )
  )

  (defun suflst ( lst el index / f n )
    (setq f t)
    (vl-remove-if
      (function (lambda ( a )
        (setq n (if (not n) 0 (1+ n)))
        (cond
          ( el
            (if (equal a el 1e-6)
              (setq f nil)
            )
          )
          ( index
            (if (= index n)
              (setq f nil)
            )
          )
        )
        f
      ))
      lst
    )
  )

  (defun foo ( pl pt par / plx bul parp ptp bulp a1 r1 c1 parn ptn a2 r2 c2 bulpn pll pllp plls plll )
    (gc)
    (if
      (and
        pl (not (vlax-erased-p pl)) (= (type pl) (quote ename)) (= "LWPOLYLINE" (cdr (assoc 0 (setq plx (entget pl)))))
        pt (= (type pt) (quote list)) (vl-every (function numberp) pt)
        par (= (type par) (quote real))
        (> (length (vl-remove-if (function (lambda ( x ) (/= (car x) 10))) plx)) 2)
      )
      (progn
        (setq pt (trans pt 0 pl))
        (setq pt (mapcar (function +) (list 0.0 0.0) pt))
        (setq bul (cdr (assoc 42 (vl-member-if (function (lambda ( x ) (equal x (assocon pt plx cdr 1e-6) 1e-6))) plx))))
        (setq parp (1- par))
        (setq ptp (vlax-curve-getpointatparam pl parp))
        (setq ptp (trans ptp 0 pl))
        (setq ptp (mapcar (function +) (list 0.0 0.0) ptp))
        (setq bulp (cdr (assoc 42 (vl-member-if (function (lambda ( x ) (equal x (assocon ptp plx cdr 1e-6) 1e-6))) plx))))
        (if (/= bulp 0.0)
          (progn
            (setq a1 (* 4.0 (atan bulp)))
            (setq r1 (/ (distance ptp pt) (* 2 (sin (* 2 (atan bulp))))))
            (setq c1 (polar ptp (+ (angle ptp pt) (- (/ pi 2.0) (* 2 (atan bulp)))) r1))
            (if (/= bul 0.0)
              (progn
                (setq parn (+ par 1.0))
                (setq ptn (vlax-curve-getpointatparam pl parn))
                (setq ptn (trans ptn 0 pl))
                (setq ptn (mapcar (function +) (list 0.0 0.0) ptn))
                (setq a2 (* 4.0 (atan bul)))
                (setq r2 (/ (distance pt ptn) (* 2 (sin (* 2 (atan bul))))))
                (setq c2 (polar pt (+ (angle pt ptn) (- (/ pi 2.0) (* 2 (atan bul)))) r2))
                (if (and (equal r1 r2 1e-6) (equal c1 c2 1e-6))
                  (setq bulpn (tang (/ (+ a1 a2) 4.0)))
                )
              )
              (setq bulpn 0.0)
            )
          )
          (setq bulpn 0.0)
        )
        (setq pll plx)
        (setq pll (append (reverse (cdr (reverse (prelst pll (assocon pt pll cdr 1e-6) nil)))) (cdr ((if (assoc 91 pll) cddddr cdddr) (suflst pll (assocon pt pll cdr 1e-6) nil)))))
        (setq pllp (reverse (cdr (reverse (prelst pll (assocon ptp pll cdr 1e-6) nil)))))
        (setq plls (cdr (suflst pll (assocon ptp pll cdr 1e-6) nil)))
        (setq plls (subst (cons 42 (if bulpn bulpn 0.0)) (assoc 42 plls) plls))
        (setq plll (append pllp (list (assocon ptp pll cdr 1e-6)) plls))
        (if (not (equal plx plll 1e-6))
          (setq plll (subst (cons 90 (1- (cdr (assoc 90 plll)))) (assoc 90 plll) plll))
        )
        (entupd (cdr (assoc -1 (entmod plll))))
      )
    )
  )

  (defun process ( pl obj len / loop coords coordsn par pts f )
    (gc)
    (setq loop t)
    (while loop
      (setq coords (safearray-value (variant-value (vla-get-coordinates obj))))
      (setq pts (groupbynum coords 2))
      (setq pts (cdr (reverse (cdr (reverse pts)))))
      (foreach pt pts
        (if command-s
          (command-s "_.UNDO" "_G")
          (vl-cmdf "_.UNDO" "_G")
        )
        (vl-catch-all-apply
          (function foo)
          (list
            pl
            (trans pt pl 0)
            (setq par (float (fix (+ 1e-6 (vlax-curve-getparamatpoint pl (vlax-curve-getclosestpointto pl (trans pt pl 0)))))))
          )
        )
        (if (not (equal len (vla-get-length obj) 1e-3))
          (if command-s
            (command-s "_.UNDO" 1)
            (vl-cmdf "_.UNDO" 1)
          )
        )
      )
      (vla-update obj)
      (setq coordsn (safearray-value (variant-value (vla-get-coordinates obj))))
      (cond
        ( (/= (length coords) (length coordsn)) )
        ( (and (not f) (= (length coords) (length coordsn)))
          (setq f t)
        )
        ( t
          (setq loop nil)
        )
      )
    )
  )

  (or cad (progn (vl-load-com) (setq cad (vlax-get-acad-object))))
  (or doc (setq doc (vla-get-activedocument cad)))
  (or spc (setq spc (vla-get-block (setq alo (vla-get-activelayout doc)))))
  (setq osm (getvar (quote osmode)))
  (setvar (quote osmode) 0)
  (setq cmd (getvar (quote cmdecho)))
  (setvar (quote cmdecho) 0)
  (if (= 8 (logand 8 (getvar (quote undoctl))))
    (if command-s
      (command-s "_.UNDO" "_E")
      (vl-cmdf "_.UNDO" "_E")
    )
  )
  (if command-s
    (command-s "_.UNDO" "_M")
    (vl-cmdf "_.UNDO" "_M")
  )
  (prompt "\nSelect LWPOLYLINE(S) on unlocked layer(s)...")
  (if (setq ss (ssget "_:L" (list (cons 0 "LWPOLYLINE"))))
    (progn
      (setq ti (car (_vl-times)))
      (repeat (setq i (sslength ss))
        (gc)
        (setq pl (ssname ss (setq i (1- i))))
        (setq obj (vlax-ename->vla-object pl))
        (setq len (vla-get-length obj))
        (process pl obj len)
      )
      (prompt "\nElapsed time : ") (princ (ftoa (- (car (_vl-times)) ti))) (prompt " milliseconds...")
      (prompt "\nFor UNDO - type \"UNDO\" - \"Back\" option...")
    )
  )
  (*error* nil)
)

 

HTH.

M.R.

Marko Ribar, d.i.a. (graduated engineer of architecture)
Message 15 of 15
Peter_MElad
in reply to: marko_ribar

 @marko_ribar Nothing occurred after using lisp... Thanks in Advance

Animation.gif

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost