Jump to content
relume

Find 2D Objects by point with radius or overlapping circle

Recommended Posts

Hello

I am still struggling with this very basic geometric search problem. I am looking for an approach to select 2D objects by a 2D point (preferably with a "pick radius") that lays within the objects to be searched/selected or are overlapped by the pick radius. The issues with the vs functions are still the same as reported some years ago: FindObjAtPt_Create any working example?

 

basic but sever issues with the vs.FindObjAtPt_Create functions are:

  •     works only on the active layer and not over all layers or a selection of layers (e.g. visible ones)
  •     works only if the document origin does not have been moved - that is a very sever issue
  •     does not work correctly on arcs and other object types

 

So my question is, are there any alternative approaches now with python to achieve this?

 

 

Many thanks for any hint and best regards.

 

Share this post


Link to post

Have you looked at a combination of GetPoint and ForEachObjectAtPoint?

 

I don't know if they have the same issues as FindObjAtPt or note.

Share this post


Link to post

Hello Pat

 

Thank you for considering my question. vs.ForEachObjectAtPoint has similiar issues - works only on the active layer and does not enter in grouped objects.

 

 

Share this post


Link to post

Do find objects on multiple layers, look through all the document layers, check if it is visible, and run the FindObj routine

 

I haven't recently experienced issues with the origin shift, but if you do, you can retrieve the origin offset and shift the pick point.

 

Not sure about the arc issue, though the developer notes indicate that it should work for arcs.  Are you explicitly dining arcs?  If so, you can always loop through all the arc objects and see if the distance from a given point is less than or equal to a given radius.

Share this post


Link to post

Hello

 

Thank you very much. Yes this is the approach I am considering - although I hopped for a more convenient way. 9_9

  • I have addressed the issue with the origin shift already some years ago (see my post (3rd entry) : FindObjAtPt_Create any working example?
  • I have documented  the issue with the circle/arc object in the same post (see 4th entry).

best regards

 

 

Share this post


Link to post

Hello

 

So my approach is, also by condoning the issues with the FindObjAtPt_Create (e.g. the function does not search on the objects precise shape but on its bounding box), it the following script (may be it may help others and save time):

 

def object_atPt_list(vPoint_ToSearch, vPoint_ToSearch_Tolerance = 0, vLayers_ToSearch = None, vSelection_Criteria = ''):
	
	import vest.base.vw._ 

	vLayer_Active_handle = vs.ActLayer()
	vLayer_Active_name = vs.GetLName(vLayer_Active_handle)
	
	vXorg, vYorg = vs.GetOrigin()
	vPoint_ToSearch_new_X = vXorg+vPoint_ToSearch[0]
	vPoint_ToSearch_new_Y = vYorg+vPoint_ToSearch[1]
	# vs.AlrtDialog('X/Y Org : ' + str(vXorg) + '/' + str(vYorg) + '\n' + 'PointToSearch new X/Y : ' + str(vPoint_ToSearch_new_X) + '/' + str(vPoint_ToSearch_new_Y))

	
	if vLayers_ToSearch is None:
		vLayers_ToSearch = layers_info_list('visible')
	
	vObjects_ToSearch = 0
	if vSelection_Criteria != '':
		vs.DSelectAll()
		vs.SelectObj(vSearch_Selection_Criteria)
		vObjects_ToSearch = 2
	
	vObject_Handle_list = list()
	
	for vLayers_ToSearch_item in vLayers_ToSearch:
		vs.Layer(vLayers_ToSearch_item["name"])
		
		vSearch_Container_start = vs.Handle()
		vSearch_list = vs.FindObjAtPt_Create(vSearch_Container_start, vObjects_ToSearch, 0, vPoint_ToSearch_new_X, vPoint_ToSearch_new_Y, vPoint_ToSearch_Tolerance) # 2 = selected only; 0 = shalow
		vSearch_list_size = vs.FindObjAtPt_GetCount(vSearch_list)
		
		for i in range(vSearch_list_size):
			vObject_handle = vs.FindObjAtPt_GetObj( vSearch_list, i )
			vObject_Handle_list.append(vObject_handle)
			# vs.AlrtDialog( 'Index: ' + str(i) + '\n' + 'Obj Type: ' + str(vs.GetTypeN(vObject_handle)))
		
		vs.FindObjAtPt_Delete( vSearch_list )
	
	if vSelection_Criteria != '': vs.DSelectAll()
	vs.Layer(vLayer_Active_name)
	
	
	# vs.AlrtDialog ("vest.base.vw.objects.object_atPt_list : vObject_Handle_list : " + str(vObject_Handle_list))
	
	return(vObject_Handle_list)

and the called script snippet "layers_info_list" to get a layers list to search in, if the layers list is not provided in the function parameters:

 

def layers_info_list(vVisibility="all"):
	vLayer_list = list()
	vLayer_handle = vs.FLayer()
	vLayer_id = 1
	while vLayer_handle != None:
		vLayer_attributes = {}
		vLayer_attributes["id"] = vLayer_id
		vLayer_attributes["handle"] = vLayer_handle
		vLayer_attributes["name"] = vs.GetLName(vLayer_handle)
		vLayer_visibility = vs.GetLVis(vLayer_handle)
		vLayer_attributes["visibility"] = vLayer_visibility
		vLayer_attributes["scale"] = vs.GetLScale(vLayer_handle)
		vLayer_attributes["options"] = vs.GetLayerOptions()
		vLayer_attributes["mode"] = vs.GetLayerRenderMode(vLayer_handle)
		vLayer_id += 1
		
		if vVisibility == "visible" and vLayer_visibility == 0: # normal
			vLayer_list.append(vLayer_attributes)

		elif vVisibility == "visible_all" and (vLayer_visibility == 0 or vLayer_visibility == 2): # normal or grayed
			vLayer_list.append(vLayer_attributes)

		elif vVisibility == "grayed" and vLayer_visibility == 2: # grayed
			vLayer_list.append(vLayer_attributes)
			
		elif vVisibility == "invisible" and vLayer_visibility == 1: # invisible
			vLayer_list.append(vLayer_attributes)
			
		elif vVisibility == "all":
			vLayer_list.append(vLayer_attributes)

		vLayer_handle = vs.NextLayer(vLayer_handle)
		
	return (vLayer_list)

best regards

 

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×