TheSwamp
Code Red => AutoLISP (Vanilla / Visual) => Topic started 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.
-
Look into nentselp.
Example:
(command ".point" "_non" '(0 0 0))
(setq ename (car (nentselp '(0 0 0))))
-
I assume you want an end point, center point, mid point. Try polar and cdr assoc 10, 11 and 50.
-
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.
-
[...]
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:
(setq point (getpoint))
(ssget point)
Of course you must have a list of points in advance, if you don't want to zoom. ;)
-
If you want to select ALLentities at ONE point you can use this:
(ssget ":S:E")
-
How to supply point to this with out giving point manually
(ssget ":S:E")
-
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:
(setq pt (getpoint))
(ssget (list (list (car pt)(cadr pt))))
This is untested as I am currently away from the office.
-
Sub, what point do you want? It's better if you want a specific point along an object of each item.
-
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.
:?:
-
Good strategy Amsterdammed: what's the description of the problem at a higher level?
-
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.
-
How many drawings do you have to do suddup. ?
-
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 ??
-
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).
(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)
)
-
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
(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.
-
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.
-
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.
(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)
)