1
$\begingroup$

As the title says, I want to be able to check a location for the existence of an object. I'm randomly filling a space with objects and want to make sure I'm not placing an object somewhere that is already occupied. Current code is:

for x in range(1000):
    loc = np.random.randint(-100, 100, 3)
    bpy.ops.mesh.primitive_cube_add(size=2, view_align=False, enter_editmode=False, location=(loc[0],loc[1],loc[2]))
    bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1)

I'd like to add something like,

if NOT location(loc[0],loc[1],loc[2]):
    add object...

Existing questions seem to be about getting location of known objects. I need the reverse of that - getting an object (or not) at a known location.

$\endgroup$
  • $\begingroup$ Related Fills a box with randomly generated spheres. $\endgroup$ – batFINGER Jan 4 at 6:35
  • $\begingroup$ Actually the reverse of what I'm after. It queries position of known spheres where as I want to query known position for an object. $\endgroup$ – d8sconz Jan 4 at 6:55
  • 1
    $\begingroup$ Huh? in the script I'm randomly filling a space with objects and want to make sure I'm not placing an object somewhere that is already occupied Each new sphere has to be positioned using its own "known position" against the "known position" of others. Yes the objects are known to be spheroids with origin at geometry, and positioned globally. The others could be scene.objects ie all other objects in scene. The test could involve the overlapping of bounding box etc. $\endgroup$ – batFINGER Jan 4 at 7:17
  • $\begingroup$ As a work around I'm appending each cubes location to a list of tuples as they get added to the scene. Each new random location is then tested against that list. My question is, do I have to make my own list like this. I can query scene.objects, but I have to turn the locations into a new list on each iteration. Or do I. $\endgroup$ – d8sconz Jan 4 at 10:21
  • $\begingroup$ As in example shown would iIMO be far better off using vectors. The location is already a vector. If the length of the difference of two vectors is less than some tolerance it is considered same. Whereas is (0.999999,) == (1,) It places a new sphere in a location that is available. There is a "tweak" to edge them away from the other if slightly overlapping. All this is simplest with spheres. The beauty of scripts is you can run them to see how they work. I've updated the code to also work in 2.8 if you are using that version, which I would suggest you do if you are just starting. $\endgroup$ – batFINGER Jan 4 at 10:40
1
$\begingroup$

If purely creating the random objects...

Here is a test script that places 100 cubes in scene with integer location components x, y, z selected randomly from range [-10, 10]

Each random location could be added to a list or set when assigned and its contents checked x in [0, 1, 2] Instead I've chosen to use defaultdict(list), which behaves like a dictionary that returns an empty list() if there is no value for that key. An empty list is Boolean False ie there is no object in that location..

>>> dd = defaultdict(list)
>>> dd["missing"]
[]

The tuple (x, y, z) is used as a key. If the key is taken, choose another random number combo, otherwise append to the list of that key marking as taken, until all cubes placed.

import bpy
import numpy as np
from collections import defaultdict

ncubes = 100
locations = defaultdict(list)
i = 0
while i < ncubes:
    loc = tuple(np.random.randint(-10, 10, 3))
    if locations[loc]:
        continue

    locations[loc].append(i)
    bpy.ops.mesh.primitive_cube_add(location=loc)
    i += 1

Without checking against already existing objects in a scene this is pretty much purely a python problem. A good place to find answers to python questions is https://stackoverflow.com

$\endgroup$

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.