Reverse Break - Osnap Problem

Reverse Break - Osnap Problem

Anonymous
Not applicable
1,059 Views
6 Replies
Message 1 of 7

Reverse Break - Osnap Problem

Anonymous
Not applicable

Need something that will let me select two points on a polyline and keep the segments in between.   This works except if osnap is used when selecting pt1 and pt2...why is that?

 

(defun traceBetween (/ ensel Pt1 ep1 Pt2 ep2)
  (while (setq ensel (entsel "\nSelect line of Polyline <quit>: "))
    (if (wcmatch (cdr (assoc 0 (entget (car ensel)))) "LINE,LWPOLYLINE,ARC")
      (progn
        (setq pt1 (getpoint "\nSelect first point: "))
        (setq pt2 (getpoint "\nSelect second point: "))
        (if(< (vlax-curve-getdistatpoint (car ensel) pt1) (vlax-curve-getdistatpoint (car ensel) pt2))
          (progn
            (command "_break" (car ensel) pt1 (vlax-curve-getendpoint (car ensel)))
            (command "_break" (car ensel) pt2 (vlax-curve-getstartpoint (car ensel))))
         (progn
           (command "_break" (car ensel) pt2 (vlax-curve-getendpoint (car ensel)))
           (command "_break" (car ensel) pt1 (vlax-curve-getstartpoint (car ensel))))
         )
      )
    )
  )
 (princ)

)

0 Likes
Accepted solutions (1)
1,060 Views
6 Replies
Replies (6)
Message 2 of 7

zph
Collaborator
Collaborator

jfl2010,

 

I am a little confused. 

 

Do you want to have the segment (defined by the two selection points) be a new entity without altering the initial selection?

 

If this is the case, this is a simple problem.

 

/r

~Z

0 Likes
Message 3 of 7

Anonymous
Not applicable

Yes, this is the ultimate goal.  But was confused why when using the "near" osnap, it always selects an endpoint.

0 Likes
Message 4 of 7

ВeekeeCZ
Consultant
Consultant

Well, if the OSNAPs are the only issue, you can always specify appropriate osmode.

 

     (command "_break" (car ensel) "_none" pt1 "_end" (trans (vlax-curve-getendpoint (car ensel)) 0 1))

 You also may to add the (trans) function to correct function under UCS.

0 Likes
Message 5 of 7

Kent1Cooper
Consultant
Consultant
Accepted solution

@Anonymous wrote:

....
        (if(< (vlax-curve-getdistatpoint (car ensel) pt1) (vlax-curve-getdistatpoint (car ensel) pt2))
          (progn
            (command "_break" (car ensel) pt1 (vlax-curve-getendpoint (car ensel)))
            (command "_break" (car ensel) pt2 (vlax-curve-getstartpoint (car ensel))))
....


I think you have your 'then' and 'else' arguments reversed.  It checks whether pt1 is closer  to the beginning than pt2, and if it is, it Breaks from pt1 to the end, rather than to the start, as your description would suggest, and the reverse breaking from pt2 to the start, rather than the end.  So the Break ranges overlap.

 

But even reversing those, it goes wrong sometimes, because (vlax-curve) functions finding things based on points along the object require the points to be truly on  the object.  When they're not, the distance returned will be nil.  With the 'then'/'else' reversal, and Osnap used to pick the points so they are  truly on it, it finds the distance in each case, and the crossover of Break ranges wipes the whole thing out.  When Osnap isn't  on, if you don't pick at points that are truly on the object, it gets nil  for the distance check, so whether it works right depends on whether you picked pt1 closer to the start than pt2.

 

In addition to switching the 'then'/'else' (progn) functions [or alternatively, changing the  <  to  > ], try changing that blue line above to:

 

(if(< (vlax-curve-getdistatpoint (car ensel) (osnap pt1 "_nea")) (vlax-curve-getdistatpoint (car ensel) (osnap pt2 "_nea")))

 

Those changes made it work reliably for me, in limited testing.

Kent Cooper, AIA
0 Likes
Message 6 of 7

Anonymous
Not applicable

Nice catch. That an annoying mistake to have made.

 

I could not get it to work (all of the time) by adding osnap where you indicated. However, I think the following should work:

 

(defun traceBetween (/ ent ensel pt1 pt2)
  (setq oom (getvar "osmode"))
  (setvar "ERRNO" 0)
  ;repeat request for polyline/line/arc until
  ;user picks a polyline or exits without picking
  (while (and (not ensel) (/= (getvar "ERRNO") 52))
    (if (and (setq ensel (entsel "\nSelect line or polyline <quit>: "))
                  (not (wcmatch (cdr (assoc 0 (entget (car ensel)))) "LINE,LWPOLYLINE,ARC"))
                  )
      (setq ensel nil)
      (setq ent (car ensel))
      )
    )
  (if (/= ent nil)
    (progn
      ;repeat request for pt1 until user selects point on line
      (while (not pt1)
          (setq pt1 (osnap (getpoint "\nSelect first point on line: ") "NEA,END,INT")))
      ;repeat request for pt2 until user selects point on line
      (while (not pt2)
          (setq pt2 (osnap (getpoint "\nSelect second point on line: ") "NEA,END,INT")))
      (if(< (vlax-curve-getdistatpoint ent pt1) (vlax-curve-getdistatpoint ent pt2))
          (progn
             (command "_break" ent pt2 (vlax-curve-getendpoint ent))
             (command "_break" ent pt1 (vlax-curve-getstartpoint ent)))
          (progn
             (command "_break" ent pt1 (vlax-curve-getendpoint ent))
             (command "_break" ent pt2 (vlax-curve-getstartpoint ent)))
           )
        )
    )
  (setvar "osmode" oom)
  (princ)
  )



 

0 Likes
Message 7 of 7

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

.... I could not get it to work (all of the time) by adding osnap where you indicated. .... I think the following should work:

....
          (setq pt1 (osnap (getpoint "\nSelect first point on line: ") "NEA,END,INT")))
....


On the not-always-working, it does depend on your picked pt1 and pt2 locations being within Osnap Aperture target range of the object.  Could you have been farther away than that?  A little more description of the details would be helpful.

 

I would caution you about that set of Osnap modes.  "NEA" is always  going to "win out" over END and INT, because the NEArest point on the object to the cursor location, if that is not actually on  an end or intersection, will always  be closer to the pick point than the closest ENDpoint or INTersection is -- that's what "nearest" means.  So the ,END,INT part really contributes nothing.

 

I suspect it's better to use END or INT Osnap, if that's what you're aiming for, from outside rather than built into the routine [whether as running modes or called on for each point], and apply NEA in an (osnap) function to cover the times when you pick without  Osnap at some along-the-way location on a segment.  That won't change the picked result when you used Osnap in picking, but it will "fix" the result when you didn't, i.e. put it truly on the object so the distance test will function properly.

Kent Cooper, AIA
0 Likes