How can I do something like,
bpy.ops.object.select(object at location x,y,z)
bpy.ops.object.delete()
In the event you want to include some objects whose origin points are close but not exactly the location given. Please note this does not specify object type so any object (camera, armature, light, etc) within range will be deleted.
import bpy
from mathutils import Vector
target_loc = (1.0,1.0,1.0)
target_deviation = .1
objs = [obj for obj in bpy.data.objects if (
(obj.location[0]-target_loc[0])**2 +
(obj.location[1]-target_loc[1])**2 +
(obj.location[2]-target_loc[2])**2 <= target_deviation**2)]
bpy.ops.object.select_all(action = 'DESELECT')
for obj in objs:
obj.select = True
bpy.ops.object.delete()
length, magnitude or length_squared
property of the vector result of subtracting one location from another. Would only involve v = Vector(target_loc)
to convert tuple to vector in code above.
$\endgroup$
Commented
Jan 5, 2019 at 15:08
Vector maths
Blender uses vectors. The object's location is a point in 3D space designated by a mathutils.Vector
.
Its local location relative to it's parent
lloc = ob.location
Its global location, relative to the global origin (0, 0, 0)
gloc = ob.matrix_world.to_translation()
If we have a point in space (global) P
then the distance from the point to the object is the length of the vector gloc - P
.
d = (gloc - P).length
If this distance is within some radius d
, then we select. Setting this to a very small value, 1e-7
is around blender's error margin, and for most applications can be considered the same location.
Relying on equality of vectors v1 == v2
is IMO not reliable.
>>> Vector((0.9999999, 1, 1)) == Vector((1, 1, 1))
False
>>> Vector((1.0000001 , 1, 1)) == Vector((1, 1, 1))
True
>>> Vector((1.0000002 , 1, 1)) == Vector((1, 1, 1))
False
Test script, selects any object within d of scene cursor.
import bpy
context = bpy.context
d = 0.0001
loc = context.scene.cursor_location
for o in context.scene.objects:
gloc = o.matrix_world.to_translation()
# o.select = (gloc - loc).length < d # pre 2.80
o.select_set((gloc - loc).length < d)
Since there is a chance the active object is not selected we'll set it to None
before calling the delete op
# context.scene.objects.active # for pre 2.80
context.view_layer.objects.active = None
bpy.ops.object.delete()
You will have to loop trough all the objects in the scene and check its location. Then you can delete that obtained object if one is found.
import bpy
from mathutils import Vector
x = 0
y = 0
z = 0
objects = [ o for o in bpy.data.objects if o.location == Vector((x,y,z))]
if len(objects) > 0:
for o in objects:
bpy.ops.object.select_all(action='DESELECT')
bpy.data.objects[o.name].select = True
bpy.ops.object.delete()
Extension for multiple objects and multiple possible locations
import bpy
from mathutils import Vector
locations = [Vector((0,0,0)), Vector((4,0,0))]
objects = [ o for o in bpy.data.objects if o.location in locations]
if len(objects) > 0:
for o in objects:
bpy.ops.object.select_all(action='DESELECT')
bpy.data.objects[o.name].select = True
bpy.ops.object.delete()
I think one loop is enough for this:
import bpy
from mathutils import Vector
location = Vector((0,0,0)) # this should be some location
for o in bpy.context.scene.objects:
if o.location == location:
bpy.data.objects.remove(o)
Obviously all kinds of conditions related to the location could be checked, but those should be another questions.
I think keeping in mind that floating point binary conversion errors do exist is a good idea in this context as well.