Jump to content

Recommended Posts

Posted

hello everyone,

 

i am wondering if someone have lisp for this, i have a lot of blocks, each block consists of some lines, i want the lines inside each block to be one line or polyline and i don't want the block, you can say that i want the lines in each block to be one line or one polyline.

 

Thank you

 

image.thumb.png.285e7b128eb09c7286870ba10513422f.png

image.thumb.png.4925d799fa8e76350c024f09016f3617.png

new block.dwg

Posted

When you connect lines using the Pedit command, Join option, they become a single polyline.  You can't have separate lines, even if they meet end to end, be a single line.

Posted
32 minutes ago, ReMark said:

When you connect lines using the Pedit command, Join option, they become a single polyline.  You can't have separate lines, even if they meet end to end, be a single line.

no worries for polyline i am ok with it i am just giving options

Posted

This should do what you want.

Exploded Selected blocks

Add entity's into a selection set

Join them (if they are connecting will become a polyline)

 

(defun c:foo (/ SSblk SS LastEnt en)
  (setq SSblk (ssadd))
  (if (setq SS (ssget "_:L" '((0 . "INSERT"))))
    (foreach blk (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))
      (setq LastEnt (entlast))
      (vl-cmdf "_.Explode" blk)
      (if (setq en (entnext LastEnt))
        (while en
          (ssadd en SSblk)
          (setq en (entnext en))
        )
      )
    )
    (prompt "\nNothing selected")
  )
  (if SSblk
    (vl-cmdf "_.join" SSblk)
  )
  (princ)
)

 

 

Posted
1 hour ago, mhupp said:

This should do what you want.

Exploded Selected blocks

Add entity's into a selection set

Join them (if they are connecting will become a polyline)

 

(defun c:foo (/ SSblk SS LastEnt en)
  (setq SSblk (ssadd))
  (if (setq SS (ssget "_:L" '((0 . "INSERT"))))
    (foreach blk (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))
      (setq LastEnt (entlast))
      (vl-cmdf "_.Explode" blk)
      (if (setq en (entnext LastEnt))
        (while en
          (ssadd en SSblk)
          (setq en (entnext en))
        )
      )
    )
    (prompt "\nNothing selected")
  )
  (if SSblk
    (vl-cmdf "_.join" SSblk)
  )
  (princ)
)

 

 

This is so good thank you so much.

But i now have to select each block, then it will be exploded, then to select all the exploded line that were in the block and then the lines changes to one line. Isn't there a way that i select all the blocks at once and the blocks changes to lines or polylines (as the attached screenshot the 5 blocks changed to 5 polylines or 5 lines) ?

Posted

I thought you where using a dashed line instead of multiple little lines. have to think about what to do.

  • Like 1
Posted (edited)

The problem @BIGAL is that one block is 10-20 small lines that don't touch making them look like one long dashed line.

That code you posted is basically what I posted but cleaner.

 

If all block's are to representing a line. I guess you could explode one at a time. add all those little lines into a selection set.

then get all the start and end points of each line add them into a list.

process the list to find the longest distance (kinda know how to do this part but not really)

and use those two end points to generate a long line add that to a third selection set.

Delete all the little lines.

repeat

join all long lines that where created.

 

--Edit

Just had to write out the steps.

*This will only work if blocks are like example

(defun c:foo (/ SSblk SS LastEnt SSline)
  (setq SSline (ssadd))
  (if (setq SS (ssget "_:L" '((0 . "INSERT"))))
    (foreach blk (vl-remove-if 'listp (mapcar 'cadr (ssnamex SS)))
      (setq SSblk (ssadd))
      (setq LastEnt (entlast))
      (vl-cmdf "_.Explode" blk)
      (while (setq LastEnt (entnext LastEnt))
        (ssadd LastEnt SSblk)
      )
      (foreach ent (vl-remove-if 'listp (mapcar 'cadr (ssnamex SSblk))) 
        (setq ptlst (cons (cdr (assoc 10 (setq line (entget ent)))) ptlst))
        (setq ptlst (cons (cdr (assoc 11 line)) ptlst))
        (entdel ent)
      )
      (vl-sort ptlst '(lambda (a b) ;probably need a better sort like chekcing distance but this works
          (if (equal (car a) (car b) 1e-6)
            (< (car a) (car b))
            (< (cadr a) (cadr b))
          )
        )
      )
      ;after sort first and last point should be the greast distance
      (entmake (list '(0 . "LINE") (cons 10 (car ptlst)) (cons 11 (last ptlst)) '(62 . 1)))
      (ssadd (entlast) SSline)
      (setq ptlst nil
            ssBlk nil
      )
    )
    (prompt "\nNothing selected")
  )
  (if SSline
    (vl-cmdf "_.join" SSline "")
  )
  (princ)
)

 

Edited by mhupp
  • Thanks 1
Posted
9 hours ago, mhupp said:

The problem @BIGAL is that one block is 10-20 small lines that don't touch making them look like one long dashed line.

That code you posted is basically what I posted but cleaner.

 

If all block's are to representing a line. I guess you could explode one at a time. add all those little lines into a selection set.

then get all the start and end points of each line add them into a list.

process the list to find the longest distance (kinda know how to do this part but not really)

and use those two end points to generate a long line add that to a third selection set.

Delete all the little lines.

repeat

join all long lines that where created.

 

--Edit

Just had to write out the steps.

*This will only work if blocks are like example

(defun c:foo (/ SSblk SS LastEnt SSline)
  (setq SSline (ssadd))
  (if (setq SS (ssget "_:L" '((0 . "INSERT"))))
    (foreach blk (vl-remove-if 'listp (mapcar 'cadr (ssnamex SS)))
      (setq SSblk (ssadd))
      (setq LastEnt (entlast))
      (vl-cmdf "_.Explode" blk)
      (while (setq LastEnt (entnext LastEnt))
        (ssadd LastEnt SSblk)
      )
      (foreach ent (vl-remove-if 'listp (mapcar 'cadr (ssnamex SSblk))) 
        (setq ptlst (cons (cdr (assoc 10 (setq line (entget ent)))) ptlst))
        (setq ptlst (cons (cdr (assoc 11 line)) ptlst))
        (entdel ent)
      )
      (vl-sort ptlst '(lambda (a b) ;probably need a better sort like chekcing distance but this works
          (if (equal (car a) (car b) 1e-6)
            (< (car a) (car b))
            (< (cadr a) (cadr b))
          )
        )
      )
      ;after sort first and last point should be the greast distance
      (entmake (list '(0 . "LINE") (cons 10 (car ptlst)) (cons 11 (last ptlst)) '(62 . 1)))
      (ssadd (entlast) SSline)
      (setq ptlst nil
            ssBlk nil
      )
    )
    (prompt "\nNothing selected")
  )
  (if SSline
    (vl-cmdf "_.join" SSline "")
  )
  (princ)
)

 

This works so good, i will try more but i guess it will be perfect. Thank you so much for your efforts

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...