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

select lines/plines that intersect a given pline..

12 REPLIES 12
SOLVED
Reply
Message 1 of 13
sean.keohane
4321 Views, 12 Replies

select lines/plines that intersect a given pline..

Hi,

I need to change the color of all lines/plines that intersect a given pline. How would I go about making the selection set of all lines that intersect that given pline.

Thanks for any help

regards

Sean

12 REPLIES 12
Message 2 of 13
_Tharwat
in reply to: sean.keohane

Here it goes ...

 

(defun c:Test (/ s prm i lst ss)
  (if (setq s (ssget "_+.:S" '((0 . "*POLYLINE"))))
    (progn
      (setq prm (fix (vlax-curve-getendparam (ssname s 0))))
      (setq i 0)
      (repeat (1+ prm)
        (setq
          lst (cons (vlax-curve-getpointatparam (ssname s 0) i) lst)
        )
        (setq i (1+ i))
      )
      (if (setq ss (ssget "_F" lst '((0 . "LINE,*POLYLINE"))))
        (sssetfirst nil ss)
      )
    )
    (princ)
  )
)

 Tharwat

Message 3 of 13
Kent1Cooper
in reply to: sean.keohane


@sean.keohane wrote:

.... I need to change the color of all lines/plines that intersect a given pline. How would I go about making the selection set of all lines that intersect that given pline.

....


I find that _Tharwat's suggestion can, if the Polyline has any arc segments, miss some Lines that do intersect the Polyline, and/or "find" some that don't intersect, because the Fence line through the vertices will go straight across the chords of the arcs, rather than follow their curvature.
 

If that is a possibilty that you need to account for, you probably need to collect a selection set of all Lines in the drawing [or in a selected area, or something], and do a series of (vla-intersectwith) tests, pairing each of them with the Polyline, and if that doesn't find any intersection, remove that Line from the selection set.  In simplest terms, without the usual controls, etc., something like this [minimally tested]:

 

(defun C:LIP (/ pobj lss lint inc lent); = LinesIntersectingPolyline
  (setq
    pobj (vlax-ename->vla-object (car (entsel "\nSelect Polyline: "))); = Polyline OBJect
    lss (ssget "_X" '((0 . "LINE"))); = Line Selection Set
    lint (ssadd); = Lines that INTersect -- start empty
    inc -1
  ); setq
  (repeat (sslength lss)
    (setq lent (ssname lss (setq inc (1+ inc)))); = Line ENTity
    (if
      (vlax-invoke
        pobj
        'IntersectWith
        (vlax-ename->vla-object lent)
        acExtendNone
      ); vlax-invoke
      (ssadd lent lint)
    ); if
  ); repeat
); defun

 

Or, if the drawing may have a very large number of Lines in it [as most of ours do], that might be a tedious effort.  You could get closer to overcoming the arc-segment problem by making the selection Fence in _Tharwat's suggestion with a series of more closely-spaced points along the Polyline, using multiples of some comparatively short distance, rather than using the vertices.  If you're really tricky, you could probably use just the vertices for all line segments, and only along arc segments, add points close enough together to approximate the curve to whatever degree of accuracy you need.

Kent Cooper, AIA
Message 4 of 13
Kent1Cooper
in reply to: Kent1Cooper


@Kent1Cooper wrote:
....
lss (ssget "_X" '((0 . "LINE"))); = Line Selection Set
....

Oops -- I paid attention to the one sentence in the original post that mentioned Lines but not Polylines.  Try this instead:

(defun C:LPIP (/ pobj ss int inc ent); = LinesPolylinesIntersectingPolyline
  (setq
    pobj (vlax-ename->vla-object (car (entsel "\nSelect Polyline: "))); = Polyline OBJect
    ss (ssget "_X" '((0 . "LINE,*POLYLINE"))); = line/polyline Selection Set
    int (ssadd); = things that INTersect -- start empty
    inc -1
  ); setq
  (repeat (sslength ss)
    (setq ent (ssname ss (setq inc (1+ inc)))); = line/polyline ENTity
    (if
      (vlax-invoke
        pobj
        'IntersectWith
        (vlax-ename->vla-object ent)
        acExtendNone
      ); vlax-invoke
      (ssadd ent int)
    ); if
  ); repeat
); defun

Kent Cooper, AIA
Message 5 of 13
sean.keohane
in reply to: Kent1Cooper

Kent/Tharwat,

Thank you for your replies. I've tried your codes and I played around with it but I can't get it to give me a selection set of lines that intersect. I keep getting  - Select Polyline: ; error: An error has occurred inside the *error*
functionAutoCAD variable setting rejected: "osmode" nil

I'd appreciate it if you could take another look at it if you have time.

thanks

Sean

Message 6 of 13
Kent1Cooper
in reply to: sean.keohane


@sean.keohane wrote:

.... I played around with it but I can't get it to give me a selection set of lines that intersect. I keep getting  - Select Polyline: ; error: An error has occurred inside the *error*
functionAutoCAD variable setting rejected: "osmode" nil

....


There must be something else going on.  _Tharwat's routine worked for me when I tried it earlier [except for the arc-segment question], and mine works once I remove the 'int' variable name from the localized variables list at the top [rather silly of me to include it there], so you can actually use what's stored in it afterwards.  [It still "works" if you don't fix that, but you can't use the selection set it built.]

 

Neither includes anything about Osmode, and neither contains an *error* function, so there's probably something related to another routine sticking around.  Are you sure nothing else is active when you try it?  Have you tried opening a new drawing, drawing some of those things, and trying it, without having run any other routines yet?  Are you getting the same error with both routines?

Kent Cooper, AIA
Message 7 of 13
sean.keohane
in reply to: Kent1Cooper

Hi Kent,

I tried again this morning and both your code and Tharwat's code return a selection.(don't know what happened last night) Your code however returns all lines in the dwg in the selection and not just the lines that intersect my selected pline. Tharwat's code returns the selection sought. I like the added intention for arc segment in your code and I'll continue to work on it.

Thanking you and Tharwat again for sharing your expertise.

Regards

Sean

 

Message 8 of 13
Kent1Cooper
in reply to: sean.keohane


@sean.keohane wrote:

.... Your code however returns all lines in the dwg in the selection and not just the lines that intersect my selected pline. .... 


Odd again....  Afer removing that one variable name from the localized list in each, both the LIP [Lines only] and LPIP [Lines & Polylines] are working for me, without including all Lines [or all Lines & Polylines] in the final set.

Kent Cooper, AIA
Message 9 of 13
sean.keohane
in reply to: Kent1Cooper

Hi Kent,

Thanks again for helping me out. I unloaded a menu (for contour generating from a points file) I use it once in a blue moon. Restarted Autocad and your lisp is working. It was the only non standard feature permanently loaded, so perhaps some feature of that program was interfering with your lisp. Anyhow, its working at my end now.

Have a good weekend,

 

no -  have a great weekend!

Regards

Sean Keohane

Message 10 of 13
nqcong365
in reply to: _Tharwat

Hi everyone, I have 2 problems with this code.

- All line/polyline intersect with latest point of select line not choose.

- 2 line intersect with 1 point choose one only.

If I choose green line, blue line will be chose, but red line won't. šŸ˜ž

I want to choose all of them please.

(defun c:Test (/ s prm i lst ss)
  (if (setq s (ssget "_+.:S" '((0 . "*LINE"))))
    (progn
      (setq prm (fix (vlax-curve-getendparam (ssname s 0))))
      (setq i 0)
      (repeat (1+ prm)
        (setq
          lst (cons (vlax-curve-getpointatparam (ssname s 0) i) lst)
        )
        (setq i (1+ i))
      )
      (if (setq ss (ssget "_F" lst '((0 . "*LINE"))))
        (sssetfirst nil ss)
      )
    )
    (princ)
  )
)

Capture.JPG

Please help me!

Message 11 of 13
Kent1Cooper
in reply to: nqcong365


@nqcong365 wrote:

... I have 2 problems with this code.

- All line/polyline intersect with latest point of select line not choose.

- 2 line intersect with 1 point choose one only.

If I choose green line, blue line will be chose, but red line won't. šŸ˜ž

I want to choose all of them please.

(defun c:Test (/ s prm i lst ss)
  (if (setq s (ssget "_+.:S" '((0 . "*LINE"))))
    (progn
      (setq prm (fix (vlax-curve-getendparam (ssname s 0))))
      (setq i 0)
      (repeat (1+ prm)
        (setq
          lst (cons (vlax-curve-getpointatparam (ssname s 0) i) lst)
        )
        (setq i (1+ i))
      )
      (if (setq ss (ssget "_F" lst '((0 . "*LINE"))))
        (sssetfirst nil ss)
      )
    )
    (princ)
  )
)

....


The first "*LINE" in your altered code is invalid in relation to how the rest of the code works.  You can't just blithely change "*POLYLINE" to "*LINE" in the path selection part, and expect it to work in the same way.

 

Here's why:

 

In (vlax-curve-...) functions that use parameters, what the point at a given parameter represents varies with the object type.  For a Polyline, each vertex is at an integer-value parameter, starting at 0, and points in between are decimal values proportionally in between the integers [e.g. the midpoint of the first segment is at parameter 0.5].  Its end parameter will also be an integer value.  For an Arc or a Circle, it's completely different -- parameter values represent the angle [in radians] from the center to the point on the curve, which means [for example] its start parameter [most of the time] is not 0 as it is for many other object types.  For an Xline, since it extends in both directions, parameter values are positive in one direction from its origin point [parameter 0], but negative in the other [I don't think any other object type can have negative parameter values].  Etc.

 

For a Line, parameter values are the distance in drawing units along the Line, starting at 0 as for a Polyline, but not necessarily ending at an integer value as a Polyline does.  If a Line is 3.66345 drawing units long, its end parameter will be 3.66345.

 

That means that since the (repeat) function above needs an integer, for such a Line, the part I made magenta above rounds down the end parameter to 3.  It will make a list [the lst variable] of points at the start of the Line, and at 1 drawing along it, and 2 and 3, and stop there.  So the Fence for selection that uses the lst points list will not reach the end of the Line.

 

If you use PEDIT to turn the green Line into a one-segment Polyline, does it work?

 

And of course, you need to be sure that the red and blue things actually intersect the green one.  If they miss by even a very tiny amount, they will not be selected.  We can't judge that without a .DWG file, but you should be able to determine that.

Kent Cooper, AIA
Message 12 of 13
nqcong365
in reply to: Kent1Cooper

cable route.JPG

Thank you so much.

I understood your explaining about line, polyline, arc.

Parameters work with polyline, but line not.

I think your lisp is nice  for both line and polyline. But it do not work with my CAD 2016, the result is "Select Polyline: nil" only. šŸ˜ž

If you have time, would you please help me more, Sir? I have a trouble, I want to choose the first and end line/polyline (green), it will automatic select shortest route connected line/polyline (red). It's so hard, is it possible, Sir?

Best regards!

Message 13 of 13
Kent1Cooper
in reply to: nqcong365


@nqcong365 wrote:

....

Parameters work with polyline, but line not.

.... your lisp ... do not work with my CAD 2016, the result is "Select Polyline: nil" only.

.... I want to choose the first and end line/polyline (green), it will automatic select shortest route connected line/polyline (red). ....


Parameters do work with Lines, just not in the same way as with Polylines.  You could do it with Line parameters, but the approach would be different.

 

If by "your lisp" you mean Message 4, that nil return would happen if you simply missed in picking a Polyline.  Is there any other message?

 

I don't understand your new request.  If the red and blue paths are already drawn, it looks like there's nothing to choose between, because the blue path doesn't connect the green ones. If the red path is not already drawn, and you want the routine to find the shortest route between the green parts, isn't the shortest route just a straight line?  [And if finding a shortest path is the intent, it's a different enough situation that it should be a new Topic.]  Can you describe in more detail?

Kent Cooper, AIA

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

Post to forums  

Autodesk Design & Make Report

ā€Boost