Jump to content

Failing to "Select by Polygon".


Almonan

Recommended Posts

Hello,

 

The other day I wrote here in the forum and the help given was really good, I was able to move forward with code and the script I'm doing. Now I'm having anohter issue wit the code:

 

;---------------------------------------------------------------
; Creates an array of objects based on max and min x y Coordinates from a poligon.
;---------------------------------------------------------------
(vl-load-com)
(defun c:Si3_TRACKER (/ *error* poly minExt maxExt blname)

	
	;; This example creates a line in model space. It then finds the
	;; bounding box for the line and displays the corners of the box.
	(setq acadObj (vlax-get-acad-object))
	(setq doc (vla-get-ActiveDocument acadObj))
	(setq modelSpace (vla-get-ModelSpace doc))
	
	;; Select the polyline
	(setq poly (car (entsel)))
	(setq polyObj (vlax-ename->vla-object poly))
	(vla-ZoomExtents acadObj)
	
	;; Return the bounding box for the line and return the minimum
    ;; and maximum extents of the box in the minExt and maxExt variables.
    (vla-GetBoundingBox polyObj 'minExt 'maxExt)
    (setq minExt (vlax-safearray->list minExt)
	      maxExt (vlax-safearray->list maxExt))
	
	;; Selects the block you want to insert and then it inserts the block
    ;; in the bottom left corner of the polyline bounding box.
	(setq BlockObj (vlax-ename->vla-object (car (entsel))))
	(setq BlockName (LM:effectivename BlockObj))
	(setq ip (vlax-3d-point minExt))
	(setq BlockInsrt (vla-InsertBlock modelSpace ip BlockName 1.0 1.0 1.0 0.0))
	
	;; Creates an array of the block that it has been inserted with a similar 
	;; extent as the bounding box.
	(setq NumbRows (LM:round (/(- (car (cdr maxExt)) (car (cdr minExt))) 64.656)))
	(setq NumbColms (LM:round (/(- (car maxExt) (car minExt)) 7.995)))
	(setq DistRows (+ 64.656 1.0))
	(setq DistColms (* 5.71 2.0))
	
	(setq PVplant (vla-ArrayRectangular BlockInsrt NumbRows NumbColms 1 DistRows DistColms 0.0))
	
	;; Select the Blocks that are inside the polygon and earase those that  
	;; are outside or touchig the polygon.
	
	; Here you create a selection set to put all the objects selected.
	
	(setq ssetObj (vla-Add (vla-get-SelectionSets doc) "TRACKERS_9"))
	
	; Here creates the selection of the PVplant.
	(setq polyPoints (LM:ent->pts poly 50.0))
	(setq polyPoints (c:list->array polyPoints vlax-vbDouble))
	(setq mode acSelectionSetWindowPolygon)
	(vla-SelectByPolygon ssetObj mode polyPoints)
	
	(setq ctr 0)
	
	(alert (itoa (vla-get-count ssetObj)))
	
	(repeat (vla-get-count ssetObj)
		(setq item (vla-item newsset ctr))
		(setq check (vlax-property-available-p item "Layer" T))
		(if check
			(vlax-put-property item 'Layer "00_seguidor")
			(vlax-put-property item 'Color 252)
		)
		(setq ctr (1+ ctr))
	)
	(vla-delete (vla-item doc "TRACKERS_9"))
)
;---------------------------------------------------------------

 

I'm able to get the points that define de polygon and construct an array so I can pass that to the function "vla-SelectByPolygon" with the variable "polyPoints", but when the program reach the "alert" part, the count of selected object is 0. I debugged the code on VLAlisp tool that AutoCAD has, and there is no error when the programs goes through that part of the code. ¿What I'm doing wrong?

 

Furthermore, I'm having issues with the last sentence 

(vla-delete (vla-item doc "TRACKERS_9"))

 

Every time the programs reaches this part of the code it troughs an error:

 

error: ActiveX Server returned the error: unknown name: Item

 

I checked on internet and the AutoCAD help and I don't know what I'm doing wrong here either. It's very annoying to change the name of the selection set every time I want to try the code.

 

If you need the entire file I'll be glad to share it if that helps.

 

Thanks in advanced.

 

See you.

 

 

Link to comment
Share on other sites

1 hour ago, Almonan said:

Every time the programs reaches this part of the code it troughs an error:

 

error: ActiveX Server returned the error: unknown name: Item

 

I checked on internet and the AutoCAD help and I don't know what I'm doing wrong here either. It's very annoying to change the name of the selection set every time I want to try the code.

Lee Mac's Error Message Troubleshooter says: "The program is attempting to access a ActiveX Property or Method with the name as noted in the error message which is not available for the supplied VLA-Object." http://www.lee-mac.com/errormessages.html

Handy reference.

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

I am not seeing where TRACKERS_9 selection set is created. When the alert comes up is their something other then 0?

 

Its good to define what you want selected. entsel can display a custom message. rather then the default Select entity.

(setq poly (car (entsel "\nSelect Polyline:")))
(setq BlockObj (car (entsel "\nSelect Block to Array:")))

 

Not 100% but I think.

(vla-delete (vla-item doc "TRACKERS_9"))
your trying to delete the selection set?
(vl-cmdf "_.Erase" "TRACKERS_9")

 

  • Thanks 1
Link to comment
Share on other sites

16 hours ago, tombu said:

Lee Mac's Error Message Troubleshooter says: "The program is attempting to access a ActiveX Property or Method with the name as noted in the error message which is not available for the supplied VLA-Object." http://www.lee-mac.com/errormessages.html

Handy reference.

 

16 hours ago, mhupp said:

I am not seeing where TRACKERS_9 selection set is created. When the alert comes up is their something other then 0?

 

Thanks for the help! Yes, the problem was that I created the object which gets the selected objects but the selection set was not assigned to a variable that I could call later. This is solved now and the programs runs without sending an error.

16 hours ago, mhupp said:

Its good to define what you want selected. entsel can display a custom message. rather then the default Select entity.


(setq poly (car (entsel "\nSelect Polyline:")))
(setq BlockObj (car (entsel "\nSelect Block to Array:")))

 

Not 100% but I think.


(vla-delete (vla-item doc "TRACKERS_9"))
your trying to delete the selection set?
(vl-cmdf "_.Erase" "TRACKERS_9")

 

 

Thanks for the tips mhupp, now the selection part is more clear 😁 And yes I was trying to delete the selection set, but in a wrong way. What I saw now at the end of the program in AutoCAD is this line :

 _.erase 1836 found

 

So, basically I'm doing the same but instead of using the name of the selection set im using his object id, Am I right?

 

Finally I was able to understand why my script wont select any object inside the polygon. I have separated into two functions the array creation and the selection part, so the array is first created and then manually the users calls the selectionObject function so it can select the polygon and then select the objects already created that are inside of it.

 

My first idea was to do it all in the same function but it seems that it can't be done. I'll work to do it another way so the user interaction is lesser than with two functions.

 

Thanks again for the help! 😁

 

See you.

Link to comment
Share on other sites

2 hours ago, Almonan said:

 so it can select the polygon and then select the objects already created that are inside of it.

this will allow you to select inside your polyline then delete stuff thats still within the min max of the polyline  not completely inside.

 

;;----------------------------------------------------------------------------;;
;; ssget "WP" doesn't work well with arc this fixes it
(defun SELECTINSIDE (ent acc / i j l)
  (setq i (/ (vlax-curve-getdistatparam ent (vlax-curve-getendparam ent)) acc)
        j (- i)
  )
  (repeat (fix acc)
    (setq l (cons (trans (vlax-curve-getpointatdist ent (setq j (+ j i))) 0 1) l))
  )
  (setq SS1 (ssget "_WP" l))
)

(SELECTINSIDE poly 100)
(setq SS (ssget "_W" minExt maxExt))
(ssdel poly ss)
(foreach e (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss1)))
  (ssdel e SS)
)
(foreach e (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))
  (entdel e)
)

 

image.thumb.png.4ab5206f3b0a596edb14eeebc614f735.png

Edited by mhupp
Added a picture
  • Thanks 1
Link to comment
Share on other sites

Hi,

 

Thanks again for the help mhupp!

 

I read your reply and it give me an idea of what to do. The only thing is that i didn't quit understand some parts of your code because of lack of knowledge. 

 

(foreach e (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss1)))
  (ssdel e SS)
)
(foreach e (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))
  (entdel e)
)

 

Here I understand this 

  • in the first iteration you delete from the selection you have made all the objects that are inside, and the second iteration deletes all the objects that are in the selection. Is this correct?
  • With "mapcar" I undesrtand that you are applying the function "cadr" on every single element of each ssnamex element, which returns a point of the object. The next function "listp" I dont know what it mens or does. 

As I could understand the code, or at least what you were trying to tell me, I did the next:

 

(defun c:Si3_SelectObjects (/ *error* )
    
	;; This example creates a line in model space. It then finds the
	;; bounding box for the line and displays the corners of the box.
	(setq acadObj (vlax-get-acad-object))
	(setq doc (vla-get-ActiveDocument acadObj))
	(setq modelSpace (vla-get-ModelSpace doc))
	(setq ssets (vla-get-selectionsets doc))
	
	(setq flag nil)
	(vlax-for item ssets
		(if (= (vla-get-name item) "Sel")
			(setq flag T)
		);if
	)
	(if flag
		(vla-delete (vla-item ssets "Sel"))
	)

	(vlax-for item ssets
		(if (= (vla-get-name item) "Sel1")
			(setq flag T)
		);if
	)
	(if flag
		(vla-delete (vla-item ssets "Sel1"))
	)
	
	;; Select the polyline
	(setq poly (car (entsel "\nSelect Polyline: ")))
	(setq polyObj (vlax-ename->vla-object poly))
	
	;; Return the bounding box for the line and return the minimum
    ;; and maximum extents of the box in the minExt and maxExt variables.
    (vla-GetBoundingBox polyObj 'minExt 'maxExt)
    (setq minExt (vlax-safearray->list minExt)
	      maxExt (vlax-safearray->list maxExt))
	(vla-ZoomWindow acadObj (vlax-3d-point minExt)(vlax-3d-point maxExt))
	
	;; Here you create a selection set to put all the objects thar are inside
	;; the polygon.
	(setq ssetInside (vla-Add ssets "Sel"))
	
	;; Here you add the strucutures that are inside the polygon.
	(setq polyPoints (LM:ent->pts poly 100.0))
	(setq polyArray (c:list->array polyPoints vlax-vbDouble))
	(setq mode acSelectionSetWindowPolygon)
	(vla-SelectByPolygon ssetInside mode polyArray)
	
	(setq ctr 0)
	
	(alert (strcat "The number of Trackers is: " "\n - " (itoa (vla-get-count ssetInside))))
	
	(repeat (vla-get-count ssetInside)
		(setq item (vla-item ssetInside ctr))
		(setq check (vlax-property-available-p item "Layer" T))
		(if check
			(vlax-put-property item 'Layer "00_Estructura 6.85_GCR_2.65")
		)
		(setq ctr (1+ ctr))
	)
	
	;; Here you create a selection set to put all the objects thar are
	;; touching or outside the polygon.
	(setq ssetOutside (vla-Add ssets "Sel1"))
	
	;; Delete the structures thar are not inside the polygon
	(setq filter_code (vlax-make-safearray vlax-vbInteger '(0 . 1)))
	(setq filter_value (vlax-make-safearray vlax-vbVariant '(0 . 1)))
	(vlax-safearray-fill filter_code '(8 2))
	(vlax-safearray-fill filter_value '("0" "Bifila_6.90m_540W"))
	
	(setq mode acSelectionSetCrossing)
	(vla-Select ssetOutside mode (vlax-3d-point minExt) (vlax-3d-point maxExt) filter_code filter_value)
	
	(alert (strcat "The number of Trackers to delete is: " "\n - " (itoa (vla-get-count ssetOutside))))
		
	(setq ctr 0)
	(repeat (vla-get-count ssetOutside)
		(setq item (vla-item ssetOutside ctr))
		(vla-Delete item)
		(setq ctr (1+ ctr))
	)
	
	(vla-ZoomPrevious acadObj)
	
)

 

I used the Layer information to select those objects that are outside the polygon. Is more messy than yours because I needed a lot more of code to do the same thing, but in this way I understand what I'm doing. But I would like to understand yours so I can improve my Lisp knowledge 😁.

 

Thanks again for the help mhupp.

 

See you!

Link to comment
Share on other sites

That syntax :

(vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))

is general approach of retrieving enames from sel. set obtained by using any (ssget) method...

It is often used when you don't want to iterate through sel. set and form entity list by using (ssname) function... (ssname) approach is better, because it's faster than (ssnamex), but anyway those differences are measured in few milliseconds ranges... Common thing is that you use (ssnamex) when you want to make code concise and quickly get resulting ename list...

First part (vl-remove-if 'lisp ... ) is used just in situations where beside enames in list (mapcar 'cadr (ssnamex ss)) there are other elements that are actually lists - (mapcar 'cadr (ssnamex ss)) = (ename1 ename2 (list1) (list2) ... )... (vl-remove-if 'listp ... ) ensures that resulting output of complete syntax is list of only enames... Now I forgot an example, so I may be wrong, but (setq ss (ssget "_X")) and then (mapcar 'cadr (ssnamex ss)) will produce list that beside enames has also other not relevant lists as elements... So in any situation (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))) is more reliable approach than just (mapcar 'cadr (ssnamex ss)), but some users still are using shorter (mapcar 'cadr (ssnamex ss)) as they are sure that (ssnamex ss) don't give side lists within output resulting list - i.e. (setq ss (ssget "_X")) wasn't used for storing ss variable for later usage in (ssnamex ss)...

 

[EDIT]

Just checked : (setq ss (ssget "_X")) (setq elst (mapcar 'cadr (ssnamex ss))) [elst contains only enames]

Then : (setq ss (ssget)) ;selected couple of lines, lwpolylines... (setq elst (mapcar 'cadr (ssnamex ss))) [elst contains enames + one list at the end]

Conclustion : (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))) should be used if (setq ss (ssget "_X")) wasn't used - i.e. for other methods...

So I did forget, but anyway main story stands : (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))) is choice with which you'll get enames list in any situation...

[/EDIT]

Edited by marko_ribar
  • Agree 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...