Message 1 of 14
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Required autocad lsp to select all object outside of a boundary by selecting the boundary
Solved! Go to Solution.
Required autocad lsp to select all object outside of a boundary by selecting the boundary
Solved! Go to Solution.
Select ALL and then remove all objects within boundary... It would be helpful if you code for selecting objects inside boundary...
We don't know how your boundary looks like - is it rectangle, or something more complex...
@sdhara.hit Untested: start here and scroll down
This is not exact I want. I get a lsp WCS. but its select all object within the boundary, But I want to select outside of boundary. lsp reference attached. if you can modify then I will be happy.
(defun c:SWC (/ _pac add ss i temp i2)
;; Select Within Curve
;; Alan J. Thompson, 03.31.11
(vl-load-com)
(defun _pac (e / l v d lst)
(setq d (- (setq v (/ (setq l (vlax-curve-getDistAtParam e (vlax-curve-getEndParam e))) 100.))))
(while (< (setq d (+ d v)) l)
(setq lst (cons (vlax-curve-getPointAtDist e d) lst))
)
)
(princ "\nSelect closed curves to select object(s) within: ")
(if (setq add (ssadd)
ss (ssget '((-4 . "<OR")
(0 . "CIRCLE,ELLIPSE")
(-4 . "<AND")
(0 . "*POLYLINE")
(-4 . "&=")
(70 . 1)
(-4 . "AND>")
(-4 . "OR>")
)
)
)
(progn (repeat (setq i (sslength ss))
(if (setq temp (ssget "_WP" (_pac (ssname ss (setq i (1- i))))))
(repeat (setq i2 (sslength temp)) (ssadd (ssname temp (setq i2 (1- i2))) add))
)
)
(sssetfirst nil add)
(ssget "_I")
)
)
(princ)
)
;Polyline/circle select - www.cadstudio.cz - www.cadforum.cz
;(use the WPS command or 'WPS inside an object selection prompt)
(defun C:SIB ( / i elist at cmde cen rad p1 impl)
(setq cmde (getvar "cmdecho"))
(setvar "cmdecho" 0)
(setq i 0 elist (entget (car (entsel "\nPick a bounding circle or polyline: "))))
(setvar "OSMODE" (boole 7 (getvar "OSMODE") 16384))
(if (zerop (getvar "CMDACTIVE")) (progn (setq impl T)(command "_select")))
(command "_wp") ; or _CP
(if (= (cdr(assoc 0 elist)) "CIRCLE")
(progn
(setq cen (cdr (assoc 10 elist))
rad (cdr (assoc 40 elist))
)
(repeat 90 ; 360/4 0.06981317=4*pi/180
(setq p1 (polar cen (* i 0.06981317) rad) i (1+ i))
; (command "_POINT" (trans p1 0 1))
(command (trans p1 0 1))
)); else
(repeat (length elist)
(setq at (nth i elist) i (1+ i))
; (if (= (car at) 10) (command (cdr at)))
(if (= (car at) 10) (command (trans (cdr at) 0 1)))
)
);if CIRCLE
(command "")
(setvar "OSMODE" (boole 2 (getvar "OSMODE") 16384))
(setvar "cmdecho" cmde)
(if impl (progn (command "")(sssetfirst nil (ssget "_P"))))
(princ)
)
its polygon boundary
I have attach a lsp. its select within the boundary. But I want Outside of boundary by selecting the boundary. boundary will be polygon
if you change the lisp you sent to get the objects as a selectionset this should work.
Its kinda like what marko_ribar described.
(defun c:test123 (/ ents ss)
(setq ents (LM:ListDifference
(LM:ss->ent (ssget "_all"))
(LM:ss->ent (c:swc))
)
)
(setq ss (ssadd))
(sssetfirst nil (foreach e ents (ssadd e ss)))
)
and here the Lee Mac subfunctions:
;;--------------=={ SelectionSet -> Entities }==--------------;;
;; ;;
;; Converts a SelectionSet to a list of Entities ;;
;;------------------------------------------------------------;;
;; Author: Lee Mac, Copyright © 2011 - www.lee-mac.com ;;
;;------------------------------------------------------------;;
;; Arguments: ;;
;; ss - Valid SelectionSet (Pickset) ;;
;;------------------------------------------------------------;;
;; Returns: List of Entity names, else nil ;;
;;------------------------------------------------------------;;
(defun LM:ss->ent ( ss / i l )
(if ss
(repeat (setq i (sslength ss))
(setq l (cons (ssname ss (setq i (1- i))) l))
)
)
)
;;-------------------=={ List Difference }==------------------;;
;; ;;
;; Returns items appearing exclusively in one list but not ;;
;; another, i.e. the relative complement: l1 \ l2 ;;
;;------------------------------------------------------------;;
;; Author: Lee Mac, Copyright © 2011 - www.lee-mac.com ;;
;;------------------------------------------------------------;;
;; Arguments: ;;
;; l1,l2 - lists for which to return the difference ;;
;;------------------------------------------------------------;;
;; Returns: List of items appearing exclusively in list l1 ;;
;;------------------------------------------------------------;;
(defun LM:ListDifference ( l1 l2 )
(vl-remove-if '(lambda ( x ) (member x l2)) l1)
)
Regards @sdhara.hit
Try this code...
Select all objects that are completely outside the boundary
(defun c:sb (/ sp sa lp sop objn)
(princ "\nSelect a Boundary...:")
(setq lp (mapcar
'cdr
(vl-remove-if-not
'(Lambda (j) (= (car j) 10))
(entget
(ssname (ssget "_+.:E:S" '((0 . "lwpolyline") (-4 . "&") (70 . 1)))
0
)
)
)
)
sa (ssget "_x")
sop (ssget "cp" lp '((0 . "*")))
)
(repeat (setq i (sslength sop))
(setq objn (ssname sop (setq i (1- i))))
(ssdel objn sa)
)
(sssetfirst nil sa)
)
Carlos Calderon G
>Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
@calderg1000 wrote:
Try this code... Select all objects that are completely outside the boundary ....
... provided the boundary Polyline contains only line segments. Maybe that will always the case, if in Message 5 the word "polygon" means [as I would expect, but you never know...] something with only straight edges. Any arc segments can throw off the selection [or in this case de-selection], because a crossing-polygon selection area defined by only the point list of vertices does not account for the possibility of arcs, but acts as though all segments between vertices are lines.
Thanks you so much. it is exactly what I want
Some time earlier this year I think I posted a function to create a point list by approximating bulged polyline segments with tiny chords. It's not exact but only like 0.02 units off at worst. You could reduce the "error" by using smaller chords, but it would increase processing times.
Anyway, his use of the word "polygon" does strike me as having all straight segments in accordance with the AutoCAD POLYGON command.
John F. Uhden
Hi, @sdhara.hit
Maybe the attached lisp will be useful. The boundary can be all polylines types, splines, circles, arcs and ellipses.
Hi, @john.uhden
Can you provide a link to this solution of yours?
I have now discovered that the accuracy of the _SELECT command, lisp functions ssget and vla-selectbypolygon to select relative to polygons is only 0.001-0.0007. And probably all the tools for selecting relative to polygons are built on these functions.
It seems to me that we should look for an alternative to them. Or are there already solutions?
Here are the parts to take an LWpolyline and produce a list of points including ones for tiny chords around bulged segments. You can use the point list for the ssget options of "F" "CP" and "WP." NOTE that if using either "CP" or "WP" the polyline must be closed.
(defun @2d (p)(mapcar '* p '(1 1)))
(defun @acos (x) (atan (sqrt (- 1 (* x x))) x))
(defun @remdupes (old / new)
(foreach item old
(if (not (vl-position item new))(setq new (cons item new)))
)
(reverse new)
)
;;--------------------------------------------------------------
;; This function adds fence points along bulged segments, if any.
(defun @fencepts (fence M / start end param bulge d1 d2 incs d dd p plist R L)
;; where:
;; fence is the polyline fence vla-object or ename
;; M is the mid-ordinate for calculating additional points along an arced segment. Try 0.02 for around 40,000 units of area.
(or (= (type fence) 'vla-object)(setq fence (vlax-ename->vla-object fence)))
(setq start (vlax-curve-getstartparam fence))
(setq end (vlax-curve-getendparam fence))
(setq param start)
(while (< param end)
(setq plist (cons (@2d (vlax-curve-getpointatparam fence param)) plist))
(and
(not (zerop (setq bulge (vla-getbulge fence param))))
(setq delta (* 4 (atan (abs bulge))))
(setq chord (distance (vlax-curve-getpointatparam fence param)(vlax-curve-getpointatparam fence (1+ param))))
(setq R (/ chord (sin (/ delta 2))))
(setq x (- 1 (/ M R)))
(setq L (* 2 R (@acos x)))
(setq d1 (vlax-curve-getdistatparam fence param)
d d1
d2 (vlax-curve-getdistatparam fence (1+ param))
incs (max 5 (fix (/ (- d2 d1) L)))
dd (/ (- d2 d1) incs)
)
(while (< (setq d (+ d dd)) d2)
(setq p (@2d (vlax-curve-getpointatdist fence d)))
(setq plist (cons p plist))
)
)
(setq param (1+ param))
)
(@remdupes (reverse (cons (@2d (vlax-curve-getpointatparam fence end)) plist)))
)
John F. Uhden
I have attached the approximation functions we took from Vladimir Azarko (VVA). Perhaps, not all functions were written by him or only by him.
Maybe your @fencepts is faster - we need to test on a large number of contours. So far we have seen that it performs its task well.
In general, however, I am concerned about the low sensitivity of selection by lisp functions: ssget and vla-selectbypolygon.
After all, even on line segments these functions are too inaccurate - up to 0.001. As a consequence, in _F mode only 50-70% of the lines lying on the selection lines are selected. In _WP and _CP modes, probably 99% of objects adjacent to the selection lines are not selected.
Either need to use other functions - ??? Or need to analyse the objects close to the selection lines additionally, also by other means.
But how?
... While vertical applications (Map, Civil) have means for precise and fast selection relative to selection lines. Moreover, for the most common AutoCAD primitives. 😞