TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: subbup on May 27, 2005, 12:07:19 AM

Title: How to select objects at a particular point
Post by: subbup on May 27, 2005, 12:07:19 AM
Hello all,

Thanks in advance
I want to select the features at a particular point.
I can do this in this way.
Zoom to that point.
select the objects with SSGET with cross option.
If I want to repeat the same thing about 10000 times means 10000 places I want to zoom and collect objects and If it is dense drawing,
It' s taking lot of time.
Is there any other way to get objects at particualr point without zooming.
Title: How to select objects at a particular point
Post by: MP on May 27, 2005, 12:12:52 AM
Look into nentselp.

Example:

(command ".point" "_non" '(0 0 0))

(setq ename (car (nentselp '(0 0 0))))
Title: How to select objects at a particular point
Post by: daron on May 27, 2005, 09:30:00 AM
I assume you want an end point, center point, mid point. Try polar and cdr assoc 10, 11 and 50.
Title: How to select objects at a particular point
Post by: DParcon on May 29, 2005, 03:07:14 PM
Try zoom center option with magnification or height.
The center point is the centroid of object's bounding
box and the magnification/height is the diameter of
the circle circumscribing the bounding box.
Title: Re: How to select objects at a particular point
Post by: Crank on May 29, 2005, 03:31:47 PM
Quote from: subbup
[...]
Zoom to that point.
select the objects with SSGET with cross option.
[...]
Is there any other way to get objects at particualr point without zooming.

Just use the point in SSGET to select:
Code: [Select]

(setq point (getpoint))
(ssget point)

Of course you must have a list of points in advance, if you don't want to zoom. ;)
Title: How to select objects at a particular point
Post by: whdjr on May 29, 2005, 05:06:46 PM
If you want to select ALLentities at ONE point you can use this:
Code: [Select]
(ssget ":S:E")
Title: How to select objects at a particular point
Post by: subbup on May 30, 2005, 06:00:03 AM
How to supply point to this with out giving point manually
(ssget ":S:E")
Title: How to select objects at a particular point
Post by: whdjr on May 30, 2005, 10:08:21 AM
Upon further research I realized that the :S gives you everything within your pickbox, not at a specified point.  So that being said try this:

Code: [Select]
(setq pt (getpoint))
(ssget (list (list (car pt)(cadr pt))))


This is untested as I am currently away from the office.
Title: How to select objects at a particular point
Post by: daron on May 31, 2005, 07:24:08 AM
Sub, what point do you want? It's better if you want a specific point along an object of each item.
Title: Re: How to select objects at a particular point
Post by: Amsterdammed on May 31, 2005, 08:17:03 AM
Quote from: subbup


I want to select the features at a particular point.


To me the real question is: Why do you need to select the objects on this particular point.

 To my experience the ssget with a point argument only works ok with
 zoom “c” and something like 200, depending how tense the drawing is. I always try to add a filter argument to make sure the entity I want is selected.

    Can’t you filter with the block name to get your ss and than calculate from the cdr 10 value for each object?

I guess if you tell us more what you want to do with the objects it will be easier to give useful advice.


 :?:
Title: How to select objects at a particular point
Post by: MP on May 31, 2005, 09:16:58 AM
Good strategy Amsterdammed: what's the description of the problem at a higher level?
Title: How to select objects at a particular point
Post by: subbup on June 01, 2005, 02:39:48 AM
I have a situation like this.
I have lwpolylines in one layer and lines in other layer.
The line end points are snapped to polylines, but there is no vertex and no break.
I want to check whether all lines are snapped to any of the polylines are not.

For this what I am doing is zoom to each and every line endpoint
ssget with "c" option I am checking is there any polyline is there or not.
My drawing has almost 10000 lines. If I do the same thing it's taking nearly 10 to 15 minutes.
I think you understand what my problem.
Title: How to select objects at a particular point
Post by: Kerry on June 01, 2005, 03:00:09 AM
How many drawings do you have to do suddup. ?
Title: How to select objects at a particular point
Post by: Kerry on June 01, 2005, 03:05:50 AM
Quote
The line end points are snapped to polylines, but there is no vertex and no break.
I want to check whether all lines are snapped to any of the polylines are not.


Sorry, I do not understand this ??

What do you want to check ??

What do you want to do ??
Title: How to select objects at a particular point
Post by: SMadsen on June 01, 2005, 06:39:17 AM
Subbup, would the following stuff do what you want? It selects (or should select) all lines that have one or both points in common with any lwpolyline in the drawing. It's based on a fuzz factor of 1E-6, which means that points should be equal down to the 6th decimal. This can be adjusted in the CHECKPOINTS routine.

It's rather basic in perfomance (sequential stuff) so I'm not sure the speed is reasonable if the drawing is heavy on lines and/or plines but tests would show that. When issuing the LINESONPLINES command (feel free to rename), it asks if you want to check against all vertices or just the "end" vertices of all plines (for closed plines that also includes the vertex that starts the closing segment).

Code: [Select]
(defun getPlinePoints (all / plsts plst ss ent entl)
  (setq i -1)
  (cond ((setq ss (ssget "X" '((0 . "LWPOLYLINE"))))
         (repeat (sslength ss)
           (setq ent  (ssname ss (setq i (1+ i)))
                 entl (entget ent)
           )
           (cond (all
                  (foreach pt entl
                    (if (= (car pt) 10)
                      (setq plst (cons (cdr pt) plst))
                    )
                  )
                 )
                 ((setq plst (append (list (cdr (assoc 10 entl))
                                           (cdr (assoc 10 (reverse entl)))
                                     )
                                     plst
                             )
                  )
                 )
           )
           (setq plsts (append plst plsts)
                 plst  nil
           )
         )
        )
  )
  plsts
)

(defun checkPoints (ppts lpts)
  (apply 'or
         (apply
           'append
           (mapcar
             (function
               (lambda (pt)
                 (mapcar (function (lambda (n) (equal pt n 1e-6))) ppts)
               )
             )
             lpts
           )
         )
  )
)

(defun divideAndConquer (all div /      cdrd   dwgDim ent    entl
                         i      osm    plinePts      ss     x
                         xIncr  xZoom  y      yIncr  yZoom  newSS
                        )
  (defun cdrd (lst)
    (reverse (cdr (reverse (cdr lst))))
  )
  (vl-cmdf "_ZOOM" "_Extents")
  (setq dwgDim (mapcar '- (getvar "EXTMAX") (getvar "EXTMIN"))
        xIncr  (/ (car dwgDim) div)
        yIncr  (/ (cadr dwgDim) div)
        x      (car (getvar "EXTMIN"))
        y      (cadr (getvar "EXTMIN"))
        osm    (getvar "OSMODE")
        newSS  (ssadd)
  )
  (setvar "OSMODE" 0)
  (setq plinePts (getPlinePoints all))
  (while (< y (cadr dwgDim))
    (setq xZoom (+ x xIncr)
          yZoom (+ y yIncr)
    )
    (cond ((setq
             ss (ssget "C"
                       (list x y)
                       (list xZoom yZoom)
                       '((0 . "LINE"))
                )
           )
           (setq i -1)
           (repeat (sslength ss)
             (setq ent  (ssname ss (setq i (1+ i)))
                   entl (entget ent)
             )
             (cond
               ((checkPoints
                  plinePts
                  (list (cdrd (assoc 10 entl)) (cdrd (assoc 11 entl)))
                )
                (ssadd ent newSS)
               )
             )
           )
          )
    )
    (cond ((>= xZoom (car dwgDim))
           (setq x (car (getvar "EXTMIN"))
                 y (+ y yIncr)
           )
          )
          ((setq x xZoom))
    )
  )
  (vl-cmdf "_ZOOM" "_Previous")
  (setvar "OSMODE" osm)
  newSS
)

(defun C:LINESONPLINES (/ sset)
  (initget "All Endpoints")
  (cond ((setq
           sset
            (divideAndConquer
              (= "All"
                 (getkword
                   "\nCheck for all or end vertices? [All/Ends] <Ends>: "
                 )
              )
              5.0
            )
         )
         (mapcar 'princ (list "\n" (sslength sset) " objects found"))
         (sssetfirst nil sset)
        )
  )
  (princ)
)
Title: How to select objects at a particular point
Post by: Amsterdammed on June 01, 2005, 07:50:32 AM
Quote
The line end points are snapped to polylines, but there is no vertex and no break.


I’m afraid this code is not what will solve the Problem. Because it is the wrong approach, from the polylines. But we want to know if every line is attached to a polyline on at least one Endpoint.

So maybe collecting all the lines in a ss and than foreach checking the Endpoints. But with what? We can’ t do it with equal because there is no point to compare, it is somewhere on the polyline.

So ether we let zoom in again on the points and try with ssget point and filter set to Polyline (to me the easiest but not the most reliable way).

Or you make a ssget with a little window and filter set to Polyline on each checked Endpoint.
Than you can check with the found Polyline or polylines if the drawing is tense if there is a intersection point between the vertex’s and the line we are checking. Doing so with the inters function or
Code: [Select]

 (setq ar
    (vlax-invoke-method
      (vlax-ename->vla-object ent1)
     'IntersectWith
      (vlax-ename->vla-object ent2)
      acExtendNone
    )
  )


This code I found somewhere else but I only used it once and so did not test  a lot.

But the question remains: why doing all this, you said the lines where drawn with snap to the polylines.
Title: How to select objects at a particular point
Post by: SMadsen on June 01, 2005, 08:13:46 AM
Oh, you need to check if lines touch  polyline segments in arbitrary places? Shouldn't be hard to do. Collect polylines as well as line endpoints and play a bit with VLAX-CURVE-GETCLOSESTPOINTTO.

Kinda like (equal 0.0 (distance line_pt (vlax-curve-getClosestPointTo pline_obj line_pt nil)) fuzz) .. but only in pseudo-form as the curve thingie can return nil.
Title: How to select objects at a particular point
Post by: Jeff_M on June 01, 2005, 01:21:32 PM
I think that this will accomplish the task. If any lines are found that do not touch any pline, they are placed into a named selection set and highlighted. Command is ALLTOUCH.....the named selection set will be "NoTouch" and can be accessed by either VBA or Vlisp.
Code: [Select]

(defun c:alltouch (/    close2ept      close2spt
  ept    idx     int?     lines    no_int
  pline    plines   spt
 )
  (vl-load-com)
  (defun active_ss (flist name / code val ss doc)
    (setq doc (vla-get-activedocument (vlax-get-acad-object)))
    (vl-catch-all-apply
      'vla-add
      (list (vla-get-selectionsets doc) name)
    )
    (setq ss (vla-item (vla-get-selectionsets doc) name))
    (vla-clear ss)
    (if flist
      (progn
(mapcar '(lambda (a)
  (setq code (cons (car a) code))
  (setq val (cons (cdr a) val))
)
flist
)
(setq code (vlax-safearray-fill
    (vlax-make-safearray
      vlax-vbinteger
      (cons 0 (- (length code) 1))
    )
    code
  )
     val  (vlax-safearray-fill
    (vlax-make-safearray
      vlax-vbvariant
      (cons 0 (- (length val) 1))
    )
    val
  )
)
(vlax-invoke-method
 ss 'select acSelectionSetAll nil nil code val)
      )
      (vla-select ss acSelectionSetAll)
    )
    (vla-highlight ss :vlax-true)
    (if (> (vla-get-count ss) 0)
      ss
      nil
    )
  )
  (if
    (and (setq lines (active_ss '((0 . "LINE") (67 . 0)) "LineSS"))
(setq plines (active_ss '((0 . "LWPOLYLINE") (67 . 0)) "PLineSS"))
    )
     (progn
       (setq no_int nil)
       (vlax-for line lines
(setq idx  0
      int? nil
      sPt  (vlax-get line 'startpoint)
      ePt  (vlax-get line 'endpoint)
)
(while (and (not int?)
    (< idx (vla-get-count plines))
)
  (setq pline   (vla-item plines idx)
close2sPt (vlax-curve-getclosestpointto pline sPt)
close2ePt (vlax-curve-getclosestpointto pline ePt)
  )
  (if (or (equal (distance sPt close2sPt) 0.0 1e-6)
  (equal (distance ePt close2ePt) 0.0 1e-6)
      )
    (setq int? t)
    (setq idx (1+ idx))
  )
)
(if (not int?)
  (setq no_int (cons line no_int))
)
       )
       (vla-highlight lines :vlax-false)
       (vla-highlight plines :vlax-false)
     )
  )
  (if no_int
    (progn
      (princ
(strcat "\n There are a total of "
(itoa (length no_int))
" lines that do not touch a Polyline."
"\nThese lines are saved in the ActiveX SS \"NoTouch\""
)
      )
      (vl-catch-all-apply
'vla-add
(list (vla-get-selectionsets *doc*) "NoTouch")
      )
      (setq ss (vla-item (vla-get-selectionsets *doc*) "NoTouch"))
      (vla-clear ss)
      (vlax-invoke ss 'additems no_int)
      (vla-highlight ss :vlax-true)
    )
    (princ "\nCongratulations! No untouching lines found!")
  )
  (princ)
)