TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: cadplayer on October 01, 2012, 10:23:30 AM

Title: Erase segments from polyline
Post by: cadplayer 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)
    )
Title: Re: Erase segments from polyline
Post by: pBe on October 01, 2012, 10:41:49 AM
Hi!
My problem is, sometimes works break command not rigtht...

What constitute a "not right" break?
Title: Re: Erase segments from polyline
Post by: Lee Mac 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. )
Title: Re: Erase segments from polyline
Post by: pBe 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?

Title: Re: Erase segments from polyline
Post by: Lee Mac 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. )
Title: Re: Erase segments from polyline
Post by: chlh_jd 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)...
Title: Re: Erase segments from polyline
Post by: cadplayer on October 02, 2012, 07:21:19 AM
Thanks at all. Very nice help from all ... it goes better now... 8-)
Title: Re: Erase segments from polyline
Post by: cadplayer 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))))
      )
    )
  )
Title: Re: Erase segments from polyline
Post by: Lee Mac 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?
Title: Re: Erase segments from polyline
Post by: cadplayer 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.


Title: Re: Erase segments from polyline
Post by: Lee Mac 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. )
Title: Re: Erase segments from polyline
Post by: cadplayer 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
Title: Re: Erase segments from polyline
Post by: Lee Mac 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. )
Title: Re: Erase segments from polyline
Post by: cadplayer 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:
Title: Re: Erase segments from polyline
Post by: Lee Mac 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:

(http://www.theswamp.org/lilly_pond/leemac/closestpointtoprojection.png)
Title: Re: Erase segments from polyline
Post by: cadplayer on October 18, 2012, 09:42:32 AM
Great thanks for your time and explantion - itīs clear now "why"
Title: Re: Erase segments from polyline
Post by: Lee Mac on October 18, 2012, 09:46:29 AM
Great thanks for your time and explantion - itīs clear now "why"

Excellent, you're welcome.  :-)
Title: Re: Erase segments from polyline
Post by: cadplayer 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
Title: Re: Erase segments from polyline
Post by: Lee Mac 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  :?
Title: Re: Erase segments from polyline
Post by: ronjonp on November 02, 2012, 05:37:03 PM
Works in 2013  8-)  Pretty cool.
Title: Re: Erase segments from polyline
Post by: Roger W 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. )
Title: Re: Erase segments from polyline
Post by: Lee Mac on October 16, 2013, 08:22:25 AM
Thanks a million this works perfectly for all types of polylines.

You're most welcome Roger!  :-)
Title: Re: Erase segments from polyline
Post by: Bhull1985 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..... :)
Title: Re: Erase segments from polyline
Post by: skkkk 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)
)