in image_generation/render_images.py [0:0]
def add_random_objects(scene_struct, num_objects, args, camera):
"""
Add random objects to the current blender scene
"""
# Load the property file
with open(args.properties_json, 'r') as f:
properties = json.load(f)
color_name_to_rgba = {}
for name, rgb in properties['colors'].items():
rgba = [float(c) / 255.0 for c in rgb] + [1.0]
color_name_to_rgba[name] = rgba
material_mapping = [(v, k) for k, v in properties['materials'].items()]
object_mapping = [(v, k) for k, v in properties['shapes'].items()]
size_mapping = list(properties['sizes'].items())
shape_color_combos = None
if args.shape_color_combos_json is not None:
with open(args.shape_color_combos_json, 'r') as f:
shape_color_combos = list(json.load(f).items())
positions = []
objects = []
blender_objects = []
for i in range(num_objects):
# Choose a random size
size_name, r = random.choice(size_mapping)
# Try to place the object, ensuring that we don't intersect any existing
# objects and that we are more than the desired margin away from all existing
# objects along all cardinal directions.
num_tries = 0
while True:
# If we try and fail to place an object too many times, then delete all
# the objects in the scene and start over.
num_tries += 1
if num_tries > args.max_retries:
for obj in blender_objects:
utils.delete_object(obj)
return add_random_objects(scene_struct, num_objects, args, camera)
x = random.uniform(-3, 3)
y = random.uniform(-3, 3)
# Check to make sure the new object is further than min_dist from all
# other objects, and further than margin along the four cardinal directions
dists_good = True
margins_good = True
for (xx, yy, rr) in positions:
dx, dy = x - xx, y - yy
dist = math.sqrt(dx * dx + dy * dy)
if dist - r - rr < args.min_dist:
dists_good = False
break
for direction_name in ['left', 'right', 'front', 'behind']:
direction_vec = scene_struct['directions'][direction_name]
assert direction_vec[2] == 0
margin = dx * direction_vec[0] + dy * direction_vec[1]
if 0 < margin < args.margin:
print(margin, args.margin, direction_name)
print('BROKEN MARGIN!')
margins_good = False
break
if not margins_good:
break
if dists_good and margins_good:
break
# Choose random color and shape
if shape_color_combos is None:
obj_name, obj_name_out = random.choice(object_mapping)
color_name, rgba = random.choice(list(color_name_to_rgba.items()))
else:
obj_name_out, color_choices = random.choice(shape_color_combos)
color_name = random.choice(color_choices)
obj_name = [k for k, v in object_mapping if v == obj_name_out][0]
rgba = color_name_to_rgba[color_name]
# For cube, adjust the size a bit
if obj_name == 'Cube':
r /= math.sqrt(2)
# Choose random orientation for the object.
theta = 360.0 * random.random()
# Actually add the object to the scene
utils.add_object(args.shape_dir, obj_name, r, (x, y), theta=theta)
obj = bpy.context.object
blender_objects.append(obj)
positions.append((x, y, r))
# Attach a random material
mat_name, mat_name_out = random.choice(material_mapping)
utils.add_material(mat_name, Color=rgba)
# Record data about the object in the scene data structure
pixel_coords = utils.get_camera_coords(camera, obj.location)
objects.append({
'shape': obj_name_out,
'size': size_name,
'material': mat_name_out,
'3d_coords': tuple(obj.location),
'rotation': theta,
'pixel_coords': pixel_coords,
'color': color_name,
})
# Check that all objects are at least partially visible in the rendered image
all_visible = check_visibility(blender_objects, args.min_pixels_per_object)
if not all_visible:
# If any of the objects are fully occluded then start over; delete all
# objects from the scene and place them all again.
print('Some objects are occluded; replacing objects')
for obj in blender_objects:
utils.delete_object(obj)
return add_random_objects(scene_struct, num_objects, args, camera)
return objects, blender_objects