Author Topic: Erase segments from polyline  (Read 15339 times)

0 Members and 1 Guest are viewing this topic.

cadplayer

  • Bull Frog
  • Posts: 390
  • Autocad Civil3d, OpenDCL.Runtime, LISP, .NET (C#)
Erase segments from polyline
« on: October 01, 2012, 10:23:30 AM »
Hi!

I´ve done here a simple routines which can erase segments in a polyline. My problem is, sometimes works break command not rigtht. Know anybody a better way to can do program it.
I only want erase a picked segment in a polyline but not explode line because I need them som Polyline.

Code: [Select]
(vl-load-com)
  (while
    (setq obj (entsel "\nselect Breakobject! ")
  en (car obj)
  pt (car (cdr obj))
  )
    (if
      (or
(equal (cdr (assoc 0 (entget en))) "POLYLINE")
(equal (cdr (assoc 0 (entget en))) "LWPOLYLINE")
)
      (progn
(setq i  (fix (vlax-curve-getParamAtPoint en
(vlax-curve-getClosestPointTo en pt)
)
      )
      p1 (vlax-curve-getPointAtParam en i)
      p2 (vlax-curve-getPointAtParam en (1+ i))
      )
(list p1 p2)
)
      )
    (command "_BREAK" obj "_F" p1 p2)
    (princ)
    )

pBe

  • Bull Frog
  • Posts: 402
Re: Erase segments from polyline
« Reply #1 on: October 01, 2012, 10:41:49 AM »
Hi!
My problem is, sometimes works break command not rigtht...

What constitute a "not right" break?

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Erase segments from polyline
« Reply #2 on: October 01, 2012, 10:51:20 AM »
The 'cheats' way:

Code - Auto/Visual Lisp: [Select]
  1. (defun c:delseg ( / e )
  2.     (if (and (setq e (entsel "\nSelect LWPolyline: "))
  3.              (= "LWPOLYLINE" (cdr (assoc 0 (entget (car e)))))
  4.         )
  5.         (command "_.trim" e "" e "")
  6.     )
  7.     (princ)
  8. )

pBe

  • Bull Frog
  • Posts: 402
Re: Erase segments from polyline
« Reply #3 on: October 01, 2012, 11:01:53 AM »
The 'cheats' way:

Code - Auto/Visual Lisp: [Select]
  1. (defun c:delseg ( / e )
  2.     (if (and (setq e (entsel "\nSelect LWPolyline: "))
  3.              (= "LWPOLYLINE" (cdr (assoc 0 (entget (car e)))))
  4.         )
  5.         (command "_.trim" e "" e "")
  6.     )
  7.     (princ)
  8. )

 :lol:   i was about to suggest that. trying to understand what is the "not right" break? I was hoping there's more to it that just that?


Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Erase segments from polyline
« Reply #4 on: October 01, 2012, 11:44:05 AM »
Or perhaps:

Code - Auto/Visual Lisp: [Select]
  1. ;; Delete LWPolyline Segment  -  Lee Mac
  2. (defun c:delseg ( / e h l p )
  3.     (if
  4.         (and
  5.             (setq l (entsel "\nSelect LWPolyline: "))
  6.             (= "LWPOLYLINE" (cdr (assoc 0 (entget (setq e (car l))))))
  7.         )
  8.         (progn
  9.             (setq p (trans (cadr l) 1 0)
  10.                   p (trans
  11.                         (vlax-curve-getpointatparam e
  12.                             (1+ (fix (vlax-curve-getparamatpoint e (vlax-curve-getclosestpointto e p))))
  13.                         )
  14.                         0 e
  15.                     )
  16.                   p (list 10 (car p) (cadr p))
  17.                   e (entget e)
  18.                   h (reverse (cons (assoc 210 e)  (member (assoc 39 e) (reverse e))))
  19.                   e (vl-remove (assoc 210 e) (cdr (member (assoc 39 e) e)))
  20.             )
  21.             (if (= 1 (logand 1 (cdr (assoc 70 h))))
  22.                 (entmod
  23.                     (append
  24.                         (subst (cons 70 (boole 4 1 (cdr (assoc 70 h)))) (assoc 70 h) h)
  25.                         (member p e)
  26.                         (reverse (cdr (member p (reverse e))))
  27.                     )
  28.                 )
  29.                 (progn
  30.                     (entmake (append h (member p e)))
  31.                     (entmake (append h (reverse (cdr (member p (reverse e))))))
  32.                     (entdel (car l))
  33.                 )
  34.             )
  35.         )
  36.     )
  37.     (princ)
  38. )

chlh_jd

  • Guest
Re: Erase segments from polyline
« Reply #5 on: October 01, 2012, 04:39:48 PM »
Hi!
I´ve done here a simple routines which can erase segments in a polyline. My problem is, sometimes works break command not rigtht. Know anybody a better way to can do program it.
I only want erase a picked segment in a polyline but not explode line because I need them som Polyline.
change
Code: [Select]
...(command "_BREAK" obj "_F" p1 p2)...
into
Code: [Select]
...(command "_BREAK" en  p1 p2)...
or
Code: [Select]
...(command "_BREAK"  p1 p2)...

cadplayer

  • Bull Frog
  • Posts: 390
  • Autocad Civil3d, OpenDCL.Runtime, LISP, .NET (C#)
Re: Erase segments from polyline
« Reply #6 on: October 02, 2012, 07:21:19 AM »
Thanks at all. Very nice help from all ... it goes better now... 8-)

cadplayer

  • Bull Frog
  • Posts: 390
  • Autocad Civil3d, OpenDCL.Runtime, LISP, .NET (C#)
Re: Erase segments from polyline
« Reply #7 on: October 17, 2012, 10:38:50 AM »
Lee your routines for delete segments in LwPolylines is very good.
I ´m wondering how could I do this with 3dPolylines. I find a sugestion in this code. Is it possible to can erase segment  from point segA to segE or there is another way.

Code: [Select]
(defun c:test ( /
               )
  (setvar "OSMODE" 0)
  (if
      (= (cdr
           (assoc 0
                  (entget
                    (setq en (car
                               (setq pt (entsel "\nSelect Polyline "))
                               )
                          )
                    )
                  )
               )
         "POLYLINE")
    (progn
      (setq segN (abs (fix (vlax-curve-getendparam en)))) ; number of segments
      (setq vl-en (vlax-ename->vla-object en))
      (setq pt (vlax-curve-getClosestPointTo vl-en (cadr pt)))
      (setq segP (vlax-curve-getparamAtPoint vl-en pt))
      (setq segA (vlax-curve-getpointatparam vl-en (fix segP)))
      (setq segE (vlax-curve-getpointatparam vl-en (1+ (fix segP))))
      )
    )
  )

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Erase segments from polyline
« Reply #8 on: October 17, 2012, 02:49:31 PM »
Lee your routines for delete segments in LwPolylines is very good.

Thank you  :-)

I'm wondering how could I do this with 3dPolylines.

A program could certainly be constructed to retrieve the set of VERTEX entities of a selected POLYLINE entity and proceed to manipulate the vertices based on the picked segment (as per my LWPOLYLINE program posted above), however, I cannot justify devoting voluntary time to such a project.

If this is intended as a shortcut for use in everyday drafting work, have you considered simply using the TRIM command as per my initial post?

cadplayer

  • Bull Frog
  • Posts: 390
  • Autocad Civil3d, OpenDCL.Runtime, LISP, .NET (C#)
Re: Erase segments from polyline
« Reply #9 on: October 18, 2012, 02:25:32 AM »
Trim works good but bad if crossing a Polyline themselves, I think it´s better to do with break.
In this code I have problem only with 3d-Polylines sometimes I click on a segment but get wrong segment in routines. Have somebody a idea to program that better

Code: [Select]
(defun c:test ( /
               en
               vl-en
               pt
               segN
               segP
               segA
               segE
               )
  (setvar "OSMODE" 0)
  (setq en (car (setq pt (entsel "\nSelect Polyline "))))
  (if (wcmatch (strcase (cdr (assoc 0 (entget en)))) "*POLYLINE")
    (progn
      (setq segN (abs (fix (vlax-curve-getendparam en)))) ; number of segments
      (setq vl-en (vlax-ename->vla-object en))
      (setq pt (vlax-curve-getClosestPointTo vl-en (cadr pt)))
      (setq segP (vlax-curve-getparamAtPoint vl-en pt))
      (setq segA (vlax-curve-getpointatparam vl-en (fix segP)))
      (setq segE (vlax-curve-getpointatparam vl-en (1+ (fix segP))))
      (command "_break" en segA segE)
      )
    (princ "\nObject was not a Polyline")
    )
  (princ)
  )


vlax-curve-getEndParam give not right segmentnumber !?

Here is a example file you can test it.


« Last Edit: October 18, 2012, 02:51:09 AM by cadplayer »

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Erase segments from polyline
« Reply #10 on: October 18, 2012, 06:57:12 AM »
Here is an example using the break command:

Code - Auto/Visual Lisp: [Select]
  1. (defun c:delsegbreak ( / l p )
  2.     (if
  3.         (and
  4.             (setq l (entsel "\nSelect Polyline: "))
  5.             (wcmatch (cdr (assoc 0 (entget (car l)))) "*POLYLINE")
  6.         )
  7.         (progn
  8.             (setq p
  9.                 (fix
  10.                     (vlax-curve-getparamatpoint (car l)
  11.                          (vlax-curve-getclosestpointto (car l) (trans (cadr l) 1 0))
  12.                     )
  13.                 )
  14.             )
  15.             (command "_.break" l "_F"
  16.                 "_non" (trans (vlax-curve-getpointatparam (car l)     p ) 0 1)
  17.                 "_non" (trans (vlax-curve-getpointatparam (car l) (1+ p)) 0 1)
  18.             )
  19.         )
  20.     )
  21.     (princ)
  22. )

cadplayer

  • Bull Frog
  • Posts: 390
  • Autocad Civil3d, OpenDCL.Runtime, LISP, .NET (C#)
Re: Erase segments from polyline
« Reply #11 on: October 18, 2012, 07:34:40 AM »
Lee very good idea to transform points... but sorry I have the same scenario, I have to more think about it.
Is it a bug i vl-function that I don´t get right segment

Code: [Select]
(setq p
                   (fix
                       (vlax-curve-getparamatpoint (car l)
                            (vlax-curve-getclosestpointto (car l) (trans (cadr l) 1 0))
                       )
                   )
               )

For example I click on the short segment in polyline and get p=0 but it´s 2

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Erase segments from polyline
« Reply #12 on: October 18, 2012, 08:18:11 AM »
Is it a bug i vl-function that I don´t get right segment

Its not a bug with the vlax-curve-* functions, try the following instead:

Code - Auto/Visual Lisp: [Select]
  1. (defun c:delsegbreak ( / l p )
  2.     (if
  3.         (and
  4.             (setq l (entsel "\nSelect Polyline: "))
  5.             (wcmatch (cdr (assoc 0 (entget (car l)))) "*POLYLINE")
  6.         )
  7.         (progn
  8.             (setq p
  9.                 (fix
  10.                     (vlax-curve-getparamatpoint (car l)
  11.                         (vlax-curve-getclosestpointtoprojection
  12.                             (car l)
  13.                             (trans (cadr l) 1 0)
  14.                            '(0.0 0.0 1.0)
  15.                         )
  16.                     )
  17.                 )
  18.             )
  19.             (command "_.break" l "_F"
  20.                 "_non" (trans (vlax-curve-getpointatparam (car l)     p ) 0 1)
  21.                 "_non" (trans (vlax-curve-getpointatparam (car l) (1+ p)) 0 1)
  22.             )
  23.         )
  24.     )
  25.     (princ)
  26. )

cadplayer

  • Bull Frog
  • Posts: 390
  • Autocad Civil3d, OpenDCL.Runtime, LISP, .NET (C#)
Re: Erase segments from polyline
« Reply #13 on: October 18, 2012, 08:33:31 AM »
It goes... thank you so much Lee, you have done it perfect. It was maybe precision that vlax-curve-getClosestPointToProjection is in this case better.


Certanly I´m not realy understand so much with VisualLisp but I believe that explanation in "theswamp" is much better as from Autodesk.
Construction for beginners I´m missing :wink:

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Erase segments from polyline
« Reply #14 on: October 18, 2012, 09:12:45 AM »
It goes... thank you so much Lee, you have done it perfect.

You're welcome  :-)

It was maybe precision that vlax-curve-getClosestPointToProjection is in this case better.

It was not a precision problem, but rather the difference in how vlax-curve-getclosestpointo and vlax-curve-getclosestpointtoprojection calculate the returned closest point.

vlax-curve-getclosestpointo will return the point given by the shortest 3D vector to the supplied curve; whereas  vlax-curve-getclosestpointtoprojection will project the curve to the plane with the supplied normal vector, before returning the point given by the shortest 2D vector to the projection of the curve in the plane.

Hopefully the following diagram is somewhat comprehensible:


cadplayer

  • Bull Frog
  • Posts: 390
  • Autocad Civil3d, OpenDCL.Runtime, LISP, .NET (C#)
Re: Erase segments from polyline
« Reply #15 on: October 18, 2012, 09:42:32 AM »
Great thanks for your time and explantion - it´s clear now "why"

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Erase segments from polyline
« Reply #16 on: October 18, 2012, 09:46:29 AM »
Great thanks for your time and explantion - it´s clear now "why"

Excellent, you're welcome.  :-)

cadplayer

  • Bull Frog
  • Posts: 390
  • Autocad Civil3d, OpenDCL.Runtime, LISP, .NET (C#)
Re: Erase segments from polyline
« Reply #17 on: November 02, 2012, 01:39:30 PM »
Completly another trick to erase segments in a Polyline is to press CTRL and than click on the segment

Regards Dirk

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Erase segments from polyline
« Reply #18 on: November 02, 2012, 04:00:28 PM »
Completly another trick to erase segments in a Polyline is to press CTRL and than click on the segment

This doesn't appear to work in 2010  :?

ronjonp

  • Needs a day job
  • Posts: 7529
Re: Erase segments from polyline
« Reply #19 on: November 02, 2012, 05:37:03 PM »
Works in 2013  8-)  Pretty cool.

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Roger W

  • Guest
Re: Erase segments from polyline
« Reply #20 on: October 16, 2013, 08:00:01 AM »
Thanks a million this works perfectly for all types of polylines.

Is it a bug i vl-function that I don´t get right segment

Its not a bug with the vlax-curve-* functions, try the following instead:

Code - Auto/Visual Lisp: [Select]
  1. (defun c:delsegbreak ( / l p )
  2.     (if
  3.         (and
  4.             (setq l (entsel "\nSelect Polyline: "))
  5.             (wcmatch (cdr (assoc 0 (entget (car l)))) "*POLYLINE")
  6.         )
  7.         (progn
  8.             (setq p
  9.                 (fix
  10.                     (vlax-curve-getparamatpoint (car l)
  11.                         (vlax-curve-getclosestpointtoprojection
  12.                             (car l)
  13.                             (trans (cadr l) 1 0)
  14.                            '(0.0 0.0 1.0)
  15.                         )
  16.                     )
  17.                 )
  18.             )
  19.             (command "_.break" l "_F"
  20.                 "_non" (trans (vlax-curve-getpointatparam (car l)     p ) 0 1)
  21.                 "_non" (trans (vlax-curve-getpointatparam (car l) (1+ p)) 0 1)
  22.             )
  23.         )
  24.     )
  25.     (princ)
  26. )

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Erase segments from polyline
« Reply #21 on: October 16, 2013, 08:22:25 AM »
Thanks a million this works perfectly for all types of polylines.

You're most welcome Roger!  :-)

Bhull1985

  • Guest
Re: Erase segments from polyline
« Reply #22 on: October 21, 2013, 07:50:42 AM »
A few months ago I attempted to tackle some of this type of code, through no small assistance of the others in this forum namely hmsilva lee mac and a few others over at the autodesk forums. After much testing and deliberation this is the portion of code we've decided on and have used successfully since then:

Code: [Select]
(if (setq insertpt1 (getpoint "\nPick Insertion Point: "))
(progn
  (if (and (setq ntsel (nentselp insertpt1))
   (= (length ntsel) 2)
   (setq name (car ntsel))
   (wcmatch (cdr (assoc 0 (entget name)))"LINE,LWPOLYLINE")
   );; and

Additionally, and this may or may not be useful for the OP but I want to show how the (vlax-curve-getpointatparam) function was used in addition to the break command. I am not sure if this has already been looked at , or would not work- just wanted to share in case it may be found to be useful.

Code: [Select]
(if (eq (vla-get-ObjectName obj) "AcDbPolyline")
     (setq p3 insertpt1
   p2 (angle insertpt1  (vlax-curve-getpointatparam obj  (fix (vlax-curve-getparamatpoint obj insertpt1)))))
     (setq p3 insertpt1
      p2 (angle (vlax-curve-getStartpoint obj) (vlax-curve-getEndPoint obj)))
)
(command "break" name (polar p3 p2 a2) (polar p3 p2 a3))



The reasons that the portions of code are the way they are is because of the conditions in which we require the program to work properly. If one user wishes to insert their fittings onto blank space before connecting them together in-line, they can. At the same time if another user wishes to draw a routing line and place all of their fittings onto that line, then the prog will do so. It will then trim out any lines that remain under the fittings. Speaking of lines, most of the time we use lwpolylines but wanted to ensure this code would work for any typical condition that we may use: lwpolylines, lines, blank space.
Hope that helps a little if you were still looking for a method....as I did not see the functions being used here explained by Lee i'm wondering where they'd fit in with his get-closest-point-to diagram..... :)

skkkk

  • Guest
Re: Erase segments from polyline
« Reply #23 on: August 21, 2014, 09:42:06 AM »
This is another variant (based on Lee Mac's code). I've added: cycle with cancelling by Enter, handling misses, undo by step, prompts.
Code: [Select]
(defun c:DELSEGS ( / *error* en flag p)
(vl-load-com)
(defun *error* (msg)   
(if oldCMDECHO (setvar "CMDECHO" oldCMDECHO))
(princ msg)
(princ)
) ;defun *error*
(setq en T flag 0 oldCMDECHO (getvar "CMDECHO"))
(setvar "CMDECHO" 0)
(while en
(initget "u")
(setq en (entsel "\nSelect segment <complete>: "))
(cond
  ( (= en "u")
(if (> flag 0)
(progn
(vl-cmdf "_u")
(princ "1 segment were recovered")
(setq flag (1- flag) en T)
)
(princ "All removed segments was recovered.")
)
  )
  ( (and (null en) (= (getvar "ERRNO") 7))
(setq en T)
  )
  ( (null en)
(princ (strcat "\nFunction is completed. "
(if (> flag 0) (strcat "Segments removed: " (vl-princ-to-string flag)) "")
)
)
  )
  ( (not (wcmatch (cdr (assoc 0 (entget (car en)))) "*POLYLINE"))
(princ "\nIt's not a polyline.")
(setq en T)
  )
  ( t
(setq p
(fix
(vlax-curve-getParamAtPoint (car en)
(vlax-curve-getClosestPointToProjection
(car en)
(trans (cadr en) 1 0)
'(0.0 0.0 1.0)
)
)
)
)
(command "_.break" en "_F"
"_non" (trans (vlax-curve-getPointAtParam (car en)     p ) 0 1)
"_non" (trans (vlax-curve-getPointAtParam (car en) (1+ p)) 0 1)
)
(setq flag (1+ flag))
  )
)
)
(setvar "CMDECHO" oldCMDECHO)
(princ)
)
« Last Edit: August 21, 2014, 04:39:29 PM by skkkk »