def add_random_objects(scene_struct, args, camera, idx): """ 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()) objects = [] blender_objects = [] cob = clevr_scene[idx]['objects'] num_objects = len(cob) for i in range(num_objects): sf = cob[i] theta = sf['rotation'] obj_name_out = sf['shape'] obj_name = restore_util.get_obj_name(obj_name_out) size_name = sf['size'] r = restore_util.get_by_size(size_name) if obj_name == 'Cube': r /= math.sqrt(2) x, y = sf['3d_coords'][:2] mat_name_out = sf['material'] mat_name = restore_util.get_by_mat_name_out(mat_name_out) color_name = sf['color'] rgb = restore_util.get_by_colorname(color_name) rgba = [float(c) / 255.0 for c in rgb] + [1.0] # 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) # Attach a random material utils.add_material(mat_name, Color=rgba) # Record data about the object in the scene data structure pixel_coords, _wh = utils.get_camera_coords(camera, obj.location) #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, }) return objects, blender_objects
def post(object_type=None): result = utils.add_object(object_type, request, MONGO_COLLECTION["ripe-" + object_type]) print(result) print "object_id={} successfully added".format(result.keys()[0]) return result, httplib.CREATED
def post(self): error_message = None blob_name = request.args.get("blob_name") if blob_name is None: error_message = "blob_name must be provided as request arguments" return error_message, httplib.BAD_REQUEST # save blob to /tmp/<blob_name> blob = request.files["blob"] blob_path = os.path.join("/tmp/", blob_name) blob.save(blob_path) # fetch attributes from media blob blob_attributes = utils.fetch_attributes(blob_path) # upload blob to ripe-staging bucket try: s3_client = boto3.client("s3", aws_access_key_id=AWS_ACCESS_KEY_ID, aws_secret_access_key=AWS_SECRET_ACCESS_KEY) print("posting blob to s3...") s3_client.upload_file(blob_path, S3_BUCKET, utils.get_filename(blob_path)) print("done posting blob to s3") except Exception as e: error_message = str(e) return error_message, httplib.INTERNAL_SERVER_ERROR # remove file so we don't waste local space os.remove(blob_path) # generate a download link download_url = s3_client.generate_presigned_url( ClientMethod="get_object", Params={ "Bucket": S3_BUCKET, "Key": blob_name, }, ExpiresIn=constants.BLOB_EXPIRATION ) blob_location = "https://{}.s3.amazonaws.com/{}".format(S3_BUCKET, blob_name) blob_attributes["url_download"] = download_url blob_attributes["url_location"] = blob_location object_attributes = utils.object_from_blob(blob_attributes) # post the attributes object_attributes = utils.add_object("media", object_attributes, MONGO_COLLECTION["ripe-media"]) result = { "blob_attributes": blob_attributes, "object_attributes": object_attributes, } print(result) return result, httplib.CREATED
def add_objects(scene_struct, camera, objects): """ Add objects to the current blender scene """ blender_objects = [] for obj in objects: # Actually add the object to the scene utils.add_object(args.shape_dir, obj["shape"], obj["size"], obj["location"], theta=obj["rotation"]) bobj = bpy.context.object blender_objects.append(bobj) utils.add_material(obj["material"], Color=obj["color"]) obj["pixel_coords"] = utils.get_camera_coords(camera, bobj.location) import numpy as np loc = np.array(bobj.location) dim = np.array(bobj.dimensions) half = dim / 2 corners = [] corners.append(loc + half * [1, 1, 1]) corners.append(loc + half * [1, 1, -1]) corners.append(loc + half * [1, -1, 1]) corners.append(loc + half * [1, -1, -1]) corners.append(loc + half * [-1, 1, 1]) corners.append(loc + half * [-1, 1, -1]) corners.append(loc + half * [-1, -1, 1]) corners.append(loc + half * [-1, -1, -1]) import mathutils corners_camera_coords = np.array([ utils.get_camera_coords(camera, mathutils.Vector(tuple(corner))) for corner in corners ]) xmax = np.amax(corners_camera_coords[:, 0]) ymax = np.amax(corners_camera_coords[:, 1]) xmin = np.amin(corners_camera_coords[:, 0]) ymin = np.amin(corners_camera_coords[:, 1]) obj["bbox"] = (float(xmin), float(ymin), float(xmax), float(ymax)) return blender_objects
def render_object(obj): obj_name_out = obj['shape'] obj_name = [k for k, v in object_mapping if v == obj_name_out][0] color_name = obj['color'] rgba = color_name_to_rgba[color_name] size_name = obj['size'] r = [v for k, v in size_mapping if k == size_name][0] if obj_name == 'Cube': r /= math.sqrt(2) theta = obj['rotation'] mat_name_out = obj['material'] mat_name = [k for k, v in material_mapping if v == mat_name_out][0] x, y, z = obj['3d_coords'] position = (x, y, r) utils.add_object(args.shape_dir, obj_name, r, (x, y), theta=theta) new_blend_obj = bpy.context.object utils.add_material(mat_name, Color=rgba) new_pixel_coords = utils.get_camera_coords(camera, new_blend_obj.location) return new_blend_obj, position, new_pixel_coords
def __init__(self, **kwargs): # the factory what did the making self._factory = kwargs['factory'] # set up the properties self.material = kwargs['material'] self.color = kwargs['color'] self.size = kwargs['size'] self.shape = kwargs['shape'] self.position = kwargs['position'] self.rotation = kwargs['rotation'] # make the blender object representation utils.add_object(self._factory.shape_directory, self._factory.convert_shape(self.shape), self.radius, self.position, theta=self.rotation) utils.add_material(self._factory.convert_material(self.material), Color=self._factory.convert_color(self.color)) self._blender_object = bpy.context.object
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 = [] if balanced_num_shapes_flag: chosen_objects = [ object_mapping[j] for j in range(NUM_SHAPES) for _ in range(num_objects[j]) ] range_num = sum(num_objects) else: range_num = num_objects for i in range(range_num): # 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: # Need to change this line to just choose one of the pre-chosen shapes. # obj_name, obj_name_out = random.choice(object_mapping) # Here, obj_name_out is "cube", "sphere", or "cylinder" if balanced_num_shapes_flag: obj_name, obj_name_out = chosen_objects[i] else: 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] # Get a random material mat_name, mat_name_out = random.choice(material_mapping) # Here, check if any of the chosen properties are disallowed. # If so, then keep randomly selecting again until no pair is disallowed. # Unfortunately, this will remove any guarantees about the distribution of labels. while obj_has_conflict(size_name, obj_name_out, mat_name_out, color_name): size_name, r = random.choice(size_mapping) obj_name, obj_name_out = random.choice(object_mapping) mat_name, mat_name_out = random.choice(material_mapping) color_name, rgba = random.choice(list(color_name_to_rgba.items())) # 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 the chosen material and color. 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
def add_random_objects_closure(scene_struct, args, camera): # 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 = [] # We first randomly determine how many groups we want to have num_groups = random.randint(2, 3) generated_pos = pg.pos_by_closure(num_groups) # pg.position_visualizer(generated_pos) for group_index in range(num_groups): group = generated_pos[group_index] for position in group: x = position[0] y = position[1] # Choose a random size size_name, r = random.choice(size_mapping) # choose random color and object 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) theta = 360.0 * random.random() # Actually add the object to the scene print(args.shape_dir) print(obj_name) 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)) 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, 'group': group }) # -------------end pos one obj #all_visible = check_visibility(blender_objects, 1) all_visible= True 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_closure(scene_struct, args, camera) return objects, blender_objects
def add_random_objects(scene_struct, num_objects, args, camera, init_positions, sizes=[], inout=False): """ Add random objects to the current blender scene """ # Load the property file print(init_positions) color_name_to_rgba = {} with open(args.properties_json, 'r') as f: properties = json.load(f) 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): if len(sizes) == 1 and i != 0: # Choose a random size size_name, r = random.choice(size_mapping) else: size_name, r = sizes[i] x, y, z = init_positions[i] # 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())) if inout and i == 0: obj_name, obj_name_out = ('Tray', 'tray') color_name, rgba = ('gray', [0.5, 0.5, 0.5, 1]) # elif i == 0: # obj_name, obj_name_out = ('SmoothCube_v2', 'cube') # color_name, rgba = ('red', [0.67, 0.13, 0.13, 1]) # elif i == 1: # obj_name, obj_name_out = ('SmoothCube_v2', 'cube') # color_name, rgba = ('blue', color_name_to_rgba['blue']) # elif i == 2: # obj_name, obj_name_out = ('SmoothCylinder', 'cylinder') # color_name, rgba = ('green', color_name_to_rgba['green']) 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) theta = 0 # Actually add the object to the scene utils.add_object(args.shape_dir, obj_name, r, (x, y, z), theta=theta) obj = bpy.context.object blender_objects.append(obj) positions.append((x, y, z, r)) # Attach a random material mat_name, mat_name_out = random.choice(material_mapping) if i == 0 or i == 1: mat_name = "Rubber" elif i == 2: mat_name = "MyMetal" 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), 'r' : r, '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, 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, init_positions + np.random.uniform(low=-0.05, high=0.05, size=(np.array(init_positions).shape)), sizes=sizes, inout=inout) return objects, blender_objects
def add_random_objects(scene_struct, num_objects, args, camera, init_positions): """ 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) # size_name, r = size_mapping[0] # x = random.choice(np.linspace(-2, 2, 3, endpoint=True)) # y = random.choice(np.linspace(-2, 2, 3, endpoint=True)) # z = random.choice(np.linspace(0, 2, 3, endpoint=True)) # z = 0 x, y, z = init_positions[i] # 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())) # obj_name, obj_name_out = object_mapping[i] # color_name, rgba = list(color_name_to_rgba.items())[i] 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() theta = 0 # Actually add the object to the scene utils.add_object(args.shape_dir, obj_name, r, (x, y, z), theta=theta) obj = bpy.context.object blender_objects.append(obj) positions.append((x, y, z, 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), 'r': r, '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, init_positions + np.random.uniform(low=-0.1, high=0.1, size=3)) return objects, blender_objects
def add_random_objects_groups(scene_struct, num_groups, args, camera,num_objects): # If we have just one group, it's the "normal" case so just call the normal function if num_groups == 1: return add_random_objects(scene_struct,num_objects,args,camera) #We read the properties and do smth======================================= 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 = [] group_center_positions=get_center_positions_spatial_grouping(num_groups) for i in range(num_groups): #Choose a random size of the group. A group contains between 1-5 elements num_elements=random.randint(1,5) for element in range(num_elements): r=0 while r<0.3: # 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 print("Try to place object.") if num_tries > args.max_retries: print("Too many tries. Delete All and Start over.") for obj in blender_objects: utils.delete_object(obj) return add_random_objects_groups(scene_struct, num_groups, args, camera,num_objects) x=group_center_positions[i][0]+random.uniform(args.within_group_distance_min+r,args.within_group_distance_max+r) y=group_center_positions[i][1]+random.uniform(args.within_group_distance_min+r,args.within_group_distance_max+r) # 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.within_group_distance_min: 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] print(margin) print("Args margin: "+str(args.margin)) 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 print(args.shape_dir) print(obj_name) 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, 'group':i, }) print("Check visibility") # Check that all objects are at least partially visible in the rendered image all_visible = check_visibility(blender_objects, 1) 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_groups(scene_struct, num_groups, args, camera,num_objects) return objects, blender_objects
def add_objects(scene_struct, blender_objects, camera, args): num_objects = 1 # 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()) objects = scene_struct['objects'] positions = [obj.location for obj in 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: print("*" * 20, " Num tries reached!!") #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) bbox = camera_view_bounds_2d( bpy.context.scene, camera, obj ) #bpy_extras.object_utils.world_to_camera_view(scene, obj, coord) #print("*"* 10, b2, pixel_coords) #break objects.append({ 'shape': obj_name_out, 'size': size_name, 'material': mat_name_out, '3d_coords': tuple(obj.location), 'rotation': theta, 'pixel_coords': pixel_coords, 'bbox': bbox.to_tuple(), 'color': color_name, }) scene_struct['objects'] = objects return blender_objects, scene_struct
def add_random_objects(scene_struct, num_objects, args, camera, gen_list): """ 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 = [] assert num_objects == 1, "Only Generate Single" gen_config = gen_list.split('.') gen_config = [k.split('_') for k in gen_config] 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, gen_list) # if i == 0: # x = random.uniform(-2.5, -0.3) # else: # x = random.uniform(0.3, 2.5) x = random.uniform(-1.5, 1.5) # x = random.uniform(-3, 3) y = x #random.uniform(-0.2, 0.2)#random.uniform(-3, 3) rn = random.uniform(0.5 * (np.abs(x) - 0.3) - 2.1, 0.1) y += rn x -= rn # 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] # print (obj_name, obj_name_out, color_name, rgba) # abc color_name = gen_config[i][0] obj_name = properties['shapes'][gen_config[i][1]] obj_name_out = gen_config[i][1] rgba = color_name_to_rgba[color_name] print(color_name, obj_name) # abc # For cube, adjust the size a bit if obj_name == 'cube': assert False r /= math.sqrt(2) # Choose random orientation for the object. theta = 45. #360.0 * random.random() if obj_name == 'Trunk': theta = 134. # 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, gen_list) return objects, blender_objects
def add_random_objects(scene_struct, num_objects, args, camera, attempts=0): """ Add random objects to the current blender scene """ if attempts > 10: print ("Tried 10 times to place {} objects and failed. Giving up hope and moving on.".format(num_objects)) return None, None # 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()) num_objects = [["duck",args.num_ducks],["sphere",args.num_balls]] objects_to_place = [] for obj_name, num in num_objects: for i in range(num): objects_to_place.append(obj_name) 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 = [] x_range = [-2.5,2.5] y_range = [-2.5,2.5] corners = [[x_range[0], y_range[0]], [x_range[0], y_range[1]], [x_range[1], y_range[0]], [x_range[1], y_range[1]],] i=-1 while len(objects_to_place) > 0: i+=1 #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, attempts=attempts+1) #x = corners[i][0] #y = corners[i][1] #print (x, y, "POSITION") x = random.uniform(*x_range) y = random.uniform(*y_range) # 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_out = objects_to_place.pop() #obj_name = object_mapping[obj_name_out] obj_name = properties["shapes"][obj_name_out] #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] r *= args.width / 256. / 1.2 zshift=0.0 # For cube, adjust the size a bit if obj_name == 'Cube': r /= math.sqrt(2) if obj_name=="Sphere": zshift = -0.25*r if obj_name == 'Rubber Duck': r /= math.sqrt(2) zshift=-1.15 # 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, zshift=zshift) obj = bpy.context.object blender_objects.append(obj) positions.append((x, y, r)) # Attach a random material if obj_name != 'Rubber Duck': 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*(args.width/256)**2) 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, attempts=attempts+1) return objects, blender_objects
def replace_random_object(scene_struct, blender_objects, camera, args): num_objs = len(blender_objects) n_rand = int(random.uniform(0, 1) * num_objs) obj = blender_objects[n_rand] x, y, r = obj.location size_name = scene_struct['objects'][n_rand]['size'] old_shape = scene_struct['objects'][n_rand]['shape'] old_color = scene_struct['objects'][n_rand]['color'] utils.delete_object(obj) scene_struct['objects'].pop(n_rand) blender_objects.pop(n_rand) objects = scene_struct['objects'] positions = [obj.location for obj in blender_objects] # 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()) # Choose random color and shape if shape_color_combos is None: obj_name_out = old_shape color_name = old_color while obj_name_out == old_shape: obj_name, obj_name_out = random.choice(object_mapping) while color_name == old_color: color_name, rgba = random.choice(list(color_name_to_rgba.items())) else: obj_name_out = old_shape color_name = old_color while obj_name_out == old_shape: obj_name_out, color_choices = random.choice(shape_color_combos) while color_name == old_color: 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.active_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) bbox = camera_view_bounds_2d(bpy.context.scene, camera, obj) objects.append({ 'shape': obj_name_out, 'size': size_name, 'material': mat_name_out, '3d_coords': tuple(obj.location), 'rotation': theta, 'pixel_coords': pixel_coords, 'bbox': bbox.to_tuple(), 'color': color_name, }) scene_struct['objects'] = objects return blender_objects, scene_struct
def add_random_objects(view_struct, num_objects, args, cams): """ 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 = {cam.name: [] for cam in cams} blender_objects = [] texts = [] blender_texts = [] all_chars = [] for i in range(num_objects): # Choose a random size size_name, r = ('large', 0.7) #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) for text in blender_texts: utils.delete_object(text) return add_random_objects(view_struct, num_objects, args, cams) x = uniform(-3, 3) y = 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 = view_struct['cc']['directions'][ direction_name] assert direction_vec[2] == 0 margin = dx * direction_vec[0] + dy * direction_vec[1] if 0 < margin < args.margin: __builtin__.print(margin, args.margin, direction_name) __builtin__.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 = choice(object_mapping) color_name, rgba = choice(list(color_name_to_rgba.items())) else: obj_name_out, color_choices = choice(shape_color_combos) color_name = 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() # 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)) __builtin__.print("added random object " + str(i)) # Attach a random material mat_name, mat_name_out = choice(material_mapping) utils.add_material(mat_name, Color=rgba) # Record data about the object in the scene data structure for cam in cams: pixel_coords = utils.get_camera_coords(cam, obj.location) objects[cam.name].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, }) # Generate Text num_chars = 1 # random.choice(range(1, 7)) chars = choice( string.ascii_lowercase ) # "".join([random.choice(string.printable[:36]) for _ in range(num_chars)]) # Add text to Blender if args.text: try: word_bboxes, char_bboxes, chars = utils.add_text( chars, args.random_text_rotation, cams) all_chars.extend(chars) except Exception as e: return purge(blender_objects, blender_texts, view_struct, num_objects, args, cams) # Select material and color for text text = bpy.context.scene.objects.active temp_dict = color_name_to_rgba.copy() del temp_dict[color_name] mat_name, mat_name_out = choice(material_mapping) color_name, rgba = choice(list(temp_dict.items())) utils.add_material(mat_name, Color=rgba) for char in chars: bpy.context.scene.objects.active = char utils.add_material(mat_name, Color=rgba) blender_texts.append(text) __builtin__.print("added text to object " + str(i)) # Check that all objects are at least partially visible in the rendered image for cam in cams: bpy.context.scene.camera = cam all_objects_visible, visible_chars = check_visibility( blender_objects + all_chars, args.min_pixels_per_object, cams) for textid, visible_pixels in visible_chars.items(): for char_bbox in char_bboxes[cam.name]: if char_bbox['id'] == textid: char_bbox['visible_pixels'] = visible_pixels all_chars_visible = [ c['visible_pixels'] > args.min_char_pixels for c in char_bboxes['cc'] ] if args.all_chars_visible and not all(all_chars_visible): __builtin__.print( "not all characters were visible, purging and retrying...") return purge(blender_objects, blender_texts, view_struct, num_objects, args, cams) for cam in cams: x, y, _ = utils.get_camera_coords(cam, text.location) objects[cam.name][-1]['text'] = { "font": text.data.font.name, "body": text.data.body, "3d_coords": tuple(text.location), "pixel_coords": (x / bpy.context.scene.render.resolution_x, y / bpy.context.scene.render.resolution_y), "color": color_name, "char_bboxes": char_bboxes, "word_bboxes": word_bboxes } else: all_objects_visible, visible_chars = check_visibility( blender_objects + all_chars, args.min_pixels_per_object, cams) if args.enforce_obj_visibility and not all_objects_visible: __builtin__.print( "not all objects were visible, purging and retrying...") return purge(blender_objects, blender_texts, view_struct, num_objects, args, cams) return texts, blender_texts, objects, blender_objects
def add_random_objects(scene_struct, num_objects, args, camera, scene_idx=0): """ 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 = [] last_obj_params = [] for i in range(num_objects): # Choose random color and shape obj_name, obj_name_out = random.choice(object_mapping) while i != 0 and obj_name_out == "tray": obj_name, obj_name_out = random.choice(object_mapping) if i == 0: if np.random.rand() > 0.5: obj_name, obj_name_out = ("Tray", "tray") if obj_name_out == "tray": color_name, rgba = "gray", [0.66, 0.66, 0.66, 1] else: color_name, rgba = random.choice(list(color_name_to_rgba.items())) # Choose a random size if obj_name_out == "tray": size_name, r = "large", 0.6 else: size_name, r = random.choice(size_mapping) # Attach a random material mat_name, mat_name_out = random.choice(material_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) if np.random.rand() > 0.5 and \ last_obj_params != [] and \ ("Cube" in last_obj_params[4] or "Cylinder" in last_obj_params[4]) and \ last_obj_params[2] < 1: x = last_obj_params[0] + random.uniform(-0.3, 0.3) y = last_obj_params[1] + random.uniform(-0.3, 0.3) z = last_obj_params[2] + (2 * last_obj_params[3]) min_dist = 0 directions_to_check = [] elif np.random.rand() > 0 and \ last_obj_params != [] and \ ("Tray" in last_obj_params[4]): x = last_obj_params[0] + random.uniform(-0.3, 0.3) y = last_obj_params[1] + random.uniform(-0.3, 0.3) z = last_obj_params[2] min_dist = -10 directions_to_check = [] else: x = random.choice(np.linspace(-2, 2, 25, endpoint=True)) y = random.choice(np.linspace(-2, 2, 25, endpoint=True)) z = random.choice(np.linspace(0, 2, 25, endpoint=True)) if obj_name_out == "tray": z = random.choice(np.linspace(0, 1, 25, endpoint=True)) # x = 0 # y = 0 # z = 0 min_dist = args.min_dist directions_to_check = [ x for x in scene_struct['directions'].keys() ] # 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, zz, rr) in positions: dx, dy, dz = x - xx, y - yy, z - zz dist = math.sqrt(dx * dx + dy * dy + dz * dz) if dist - r - rr < min_dist: # print('BROKEN DISTANCE!', dist - r - rr, min_dist) dists_good = False break for direction_name in directions_to_check: direction_vec = scene_struct['directions'][direction_name] margin = dx * direction_vec[0] + dy * direction_vec[ 1] + dz * direction_vec[2] 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 # 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() theta = 0 # Actually add the object to the scene utils.add_object(args.shape_dir, obj_name, r, (x, y, z), theta=theta) last_obj_params = [x, y, z, r, obj_name] utils.add_material(mat_name, Color=rgba) obj = bpy.context.object blender_objects.append(obj) # if obj_name_out != "tray": positions.append((x, y, z, r)) # 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, 'r': r, 'material': mat_name_out, '3d_coords': tuple(obj.location), 'rotation': theta, 'pixel_coords': pixel_coords, 'color': color_name, }) if obj_name_out == "tray": objects[-1]["mask_color"] = [0.66, 0.66, 0.66] # Check that all objects are at least partially visible in the rendered image all_visible = check_visibility(blender_objects, 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 or too small; 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
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()] # Choose between disks.blend and leaf.obj leaf_disk = False leaf_properties = properties['shapes'].copy() leaf_properties.pop('sphere') leaf_obj_mapping = [(v, k) for k, v in leaf_properties.items()] size_mapping = list(properties['sizes'].items()) print("size mapping: ", size_mapping) 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 = [] init_rot = 0 size_name, r = random.choice(size_mapping) color_name, rgba = random.choice(list(color_name_to_rgba.items())) ''' WORKFLOW: First select nb of rows - 1 being bottom-most For each row, select nb of leaves - each row has a tilt angle that's a function of the row For each leaf, select angular position of leaf around z-axis. ensure leaves don't fully overlap ''' nb_rows = random.randint(1, 3) # TEST CASE: # nb_rows = 4 size_map_sorted = sorted(size_mapping, key=lambda x: x[1]) size_map_sorted.reverse() # Position of leaves x = 0.0 y = 0.0 for row in range(nb_rows): # For each row pick nb of leaves nb_leaves_per_row = random.randint(3, 7) # TEST CASE: #nb_leaves_per_row = 4 # nb_leaves + 1 (coz sphere) --> change for i in range(nb_leaves_per_row): theta = math.pi * (random.choice( list(np.arange(row * 20, (row + 1) * 20, 0.5)))) / 180 # lower leaves are less tilted # Pick largest leaves for lowest rows, and decrease leaf size as rows increase (may need to be modified for more randomness) #size_name, r = size_map_sorted[row] size_name, r = random.choice(size_mapping) color_name, rgba = random.choice(list(color_name_to_rgba.items())) if not positions: z = r obj_name_out = str('sphere') obj_name = properties['shapes']['sphere'] else: z = 0.0 if leaf_disk == True: obj_name, obj_name_out = random.choice(leaf_obj_mapping) else: obj_name_out = str('leaf') obj_name = str('leaf') # Actually add the object to the scene utils.add_object(args.shape_dir, obj_name, r, (x, y, z), theta=theta) obj = bpy.context.object blender_objects.append(obj) positions.append((x, y, r)) # TEST CASE: CHECK ORIENTATION print("theta: ", theta, " for obj: ", obj) # Attach a random material mat_name, mat_name_out = random.choice(material_mapping) utils.add_material(mat_name, Color=rgba) # 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, }) # Rotate objects on axis of central sphere before placing next object # Create a parent and add children parent_object = blender_objects[0] bpy.context.object.rotation_mode = 'XYZ' if (len(positions) > 1 and obj.type == "MESH"): obj.select = True parent_object.select = True obj.parent = parent_object obj.matrix_parent_inverse = parent_object.matrix_world.inverted( ) rot_angle_deg = 360.0 / (float(nb_leaves_per_row - 1) ) # to have some overlap between objects rot_angle = (3.14159 * rot_angle_deg / 180) # print("Rotated by: ", rot_angle - init_rot, " & rotation angle was: ", rot_angle) init_rot = rot_angle # Info note: The axis of interest is indexed by bpy.data.objects['ObjName'].rotation_euler[2] bpy.context.scene.objects.active = bpy.data.objects[ parent_object.name] bpy.context.object.rotation_euler[ 2] = bpy.context.object.rotation_euler[2] + rot_angle parent_object.select = False obj.select = False bpy.ops.object.select_all(action='DESELECT') # Check that all objects are at least partially visible in the rendered image all_visible = check_visibility(blender_objects, args.min_pixels_per_object) return objects, blender_objects
def add_random_objects(scene_struct, num_objects, args, camera, output_mask="mask.png"): """ 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, output_mask=output_mask) 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, "mask_color": tuple(), }) # Check that all objects are at least partially visible in the rendered image all_visible = check_visibility(blender_objects, objects, args.min_pixels_per_object, output_mask=output_mask) 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, output_mask=output_mask) return objects, blender_objects
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(-2.5, 2.5) y = random.uniform(-2.5, 2.5) # 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 <= 0.5 and random.random() <= 0.5: x = xx y = yy dx, dy = x - xx, y - yy dist = math.sqrt(dx * dx + dy * dy) if dist >= 0.1 and dist - r - rr < args.min_dist: dists_good = False break for direction_name in [ 'left', 'right', 'front', 'behind', 'above', 'below' ]: direction_vec = scene_struct['directions'][direction_name] # assert direction_vec[2] == 0 margin = dx * direction_vec[0] + dy * direction_vec[1] if dist >= 0.1 and 0 < margin < args.margin: print(dist, margin, args.margin, direction_name) print('BROKEN MARGIN!') margins_good = False break if not margins_good: break num, z = height(objects, (x, y)) if dists_good and margins_good and num <= 2: 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, z + r), theta=theta) obj = bpy.context.object blender_objects.append(obj) positions.append((x, y, z + 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) import numpy as np bobj = bpy.context.object loc = np.array(bobj.location) dim = np.array(bobj.dimensions) half = dim / 2 corners = [] corners.append(loc + half * [1, 1, 1]) corners.append(loc + half * [1, 1, -1]) corners.append(loc + half * [1, -1, 1]) corners.append(loc + half * [1, -1, -1]) corners.append(loc + half * [-1, 1, 1]) corners.append(loc + half * [-1, 1, -1]) corners.append(loc + half * [-1, -1, 1]) corners.append(loc + half * [-1, -1, -1]) import mathutils corners_camera_coords = np.array([ utils.get_camera_coords(camera, mathutils.Vector(tuple(corner))) for corner in corners ]) xmax = np.amax(corners_camera_coords[:, 0]) ymax = np.amax(corners_camera_coords[:, 1]) xmin = np.amin(corners_camera_coords[:, 0]) ymin = np.amin(corners_camera_coords[:, 1]) objects.append({ 'shape': obj_name_out, 'r': r, 'size': size_name, 'material': mat_name_out, '3d_coords': tuple(obj.location), 'rotation': theta, 'pixel_coords': pixel_coords, 'color': color_name, 'xmin': xmin, 'ymin': ymin, 'xmax': xmax, 'ymax': ymax }) # 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) for obj in objects: print(obj['shape'], obj['color']) return objects, blender_objects
def add_random_objects(scene_struct, parameters, args, camera): """ Add random objects to the current blender scene """ #TODO: changed sigature, num_objects changed to parameters # 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(len(parameters)): # # 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) objct = parameters[i] size_name = objct["size_name"] x, y, r = objct["position"] obj_name = objct["obj_name"] obj_name_out = objct["obj_name_out"] color_name = objct["color_name"] rgba = objct["rgba"] mat_name = objct["mat_name"] mat_name_out = objct["mat_name_out"] theta = objct["theta"] # obj = {"size_name": size_name, "position": [x, y, y], "obj_name": obj_name, "obj_name_out": obj_name_out, # "color_name": color_name, "rgba": rgba, "mat_name": mat_name, "mat_name_out": mat_name_out} # 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) print("not all visible") return [], [], False return objects, blender_objects, True
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): if i == 0: # first element is the small shiny gold "snitch"! size_name, r = "small", 0.3 # slightly larger than small obj_name, obj_name_out = 'Spl', 'spl' color_name = "gold" rgba = [1.0, 0.843, 0.0, 1.0] mat_name, mat_name_out = "MyMetal", "metal" elif i == 1: # second element is a medium cone size_name, r = "medium", 0.5 obj_name, obj_name_out = 'Cone', 'cone' color_name, rgba = random.choice(list(color_name_to_rgba.items())) mat_name, mat_name_out = random.choice(material_mapping) elif i == 2: # third element is a large cone size_name, r = "large", 0.75 obj_name, obj_name_out = 'Cone', 'cone' color_name, rgba = random.choice(list(color_name_to_rgba.items())) mat_name, mat_name_out = random.choice(material_mapping) else: # Choose a random size size_name, r = random.choice(size_mapping) # 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] # Choose a random material mat_name, mat_name_out = random.choice(material_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: logging.debug('{} {} {}'.format( margin, args.margin, direction_name)) logging.debug('BROKEN MARGIN!') margins_good = False break if not margins_good: break if dists_good and margins_good: break # 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() theta = 2 * np.pi * 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)) # Actually add material utils.add_material(mat_name, Color=rgba) # get bbox corners in world coord bbox_corners_world = np.array([ obj.matrix_world * Vector(corner) for corner in obj.bound_box ]) # 8 x 3 array T = np.average(bbox_corners_world, axis=0) # len-3, xyz coord in world system # try to create lrt l = [obj.dimensions.x, obj.dimensions.y, obj.dimensions.z] # R = eul2rot((0, 0, theta), degrees=True) # lx, ly, lz = l # xs = np.array([-lx/2., -lx/2., -lx/2., -lx/2., lx/2., lx/2., lx/2., lx/2.])[None, :] # 1 x 8 # ys = np.array([-ly/2., -ly/2., ly/2., ly/2., -ly/2., -ly/2., ly/2., ly/2.])[None, :] # zs = np.array([-lz/2., lz/2., -lz/2., lz/2., -lz/2., lz/2., -lz/2., lz/2.])[None, :] # xyzs_obj = np.concatenate([xs, ys, zs], axis=0) # 3 x 8 # xyzs_world = np.dot(R, xyzs) + T[:, None] # 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, 'sized': r, 'material': mat_name_out, '3d_coords': tuple(obj.location), '3d_bbox': bbox_corners_world.tolist(), '3d_size': l, '3d_bbox_center': T.tolist(), 'rotation': theta, 'pixel_coords': pixel_coords, 'color': color_name, 'instance': obj.name, }) return objects, blender_objects
def add_random_objects(scene_struct, num_objects, args, inp, img_config, 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 user_obj = img_config.objects[i] size_name = user_obj['size'] assert size_name in properties[ 'sizes'], "Size not defined in properties.json" r = properties['sizes'][size_name] # 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) print("Failed to place objects") print(dists_good, margins_good) sys.exit( "Failed to place objects. Check `user_config.py` for image {image_index}, object {i}" .format(image_index=image_index, i=i)) dy = lambda: random.uniform(-0.45, 0.45) clamp = lambda x: min(2.95, max(-2.95, x)) x = clamp(user_obj['x']) y = clamp(user_obj['y']) z = user_obj['z'] # 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())) obj_name_out = user_obj['shape'] color_name = user_obj['color'] assert obj_name_out in properties[ 'shapes'], "Shape not defined in properties.json" assert color_name in color_name_to_rgba, "Color not defined in properties.json" obj_name = properties['shapes'][obj_name_out] rgba = color_name_to_rgba[color_name] 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 = user_obj[ 'orientation'] if 'orientation' in user_obj else 360.0 * random.random( ) # Actually add the object to the scene utils.add_object(args.shape_dir, obj_name, r, (x, y, z), 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) mat_name_out = user_obj['material'] assert mat_name_out in properties[ 'materials'], "Material not defined in properties.json" mat_name = properties['materials'][mat_name_out] 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, inp, img_config, camera) return objects, blender_objects
def relchange_random(scene_struct, blender_objects, camera, args): num_objs = len(blender_objects) n_rand = int(random.uniform(0, 1) * num_objs) obj = blender_objects[n_rand] loc = obj.location r = loc[2] size_name = scene_struct['objects'][n_rand]['size'] shape = scene_struct['objects'][n_rand]['shape'] color = scene_struct['objects'][n_rand]['color'] mat_name = scene_struct['objects'][n_rand]['material'] theta = scene_struct['objects'][n_rand]['rotation'] utils.delete_object(obj) scene_struct['objects'].pop(n_rand) blender_objects.pop(n_rand) objects = scene_struct['objects'] positions = [obj.location for obj in blender_objects] num_tries = 0 while True: num_tries += 1 dists_good = True margins_good = True x = random.uniform(-3, 3) y = random.uniform(-3, 3) dx_s, dy_s = x - loc[0], y - loc[1] dist = math.sqrt(dx_s * dx_s + dy_s * dy_s) if dist < 4: dists_good = False continue 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: #print(dist - r - rr) 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: margins_good = False break if num_tries > 10 and not (dists_good and margins_good): n_rand = int(random.uniform(0, num_objs - 1)) obj = blender_objects[n_rand] loc = obj.location r = loc[2] num_tries = 0 if dists_good and margins_good: break # 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()) shape_name = properties['shapes'][shape] rgba = color_name_to_rgba[color] # Actually add the object to the scene utils.add_object(args.shape_dir, shape_name, r, (x, y), theta=theta) obj = bpy.context.active_object blender_objects.append(obj) positions.append((x, y, r)) utils.add_material(properties['materials'][mat_name], Color=rgba) # Record data about the object in the scene data structure pixel_coords = utils.get_camera_coords(camera, obj.location) bbox = camera_view_bounds_2d(bpy.context.scene, camera, obj) objects.append({ 'shape': shape, #obj_name_out 'size': size_name, 'material': mat_name, #_out '3d_coords': tuple(obj.location), 'rotation': theta, 'pixel_coords': pixel_coords, 'bbox': bbox.to_tuple(), 'color': color, #_name }) scene_struct['objects'] = objects return blender_objects, scene_struct
def add_specific_objects(scene_struct, object_dict, num_objects, args, camera): """ Add specific 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): specific_object = object_dict[str(i)] size_idx = specific_object["size"] colour_idx = specific_object["colour"] material_idx = specific_object["material"] object_type_idx = specific_object["object_type"] orientation_spec = specific_object["orientation"] x_spec = specific_object["x"] y_spec = specific_object["y"] size_name, r = size_idx # 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) return None, None x = x_spec y = y_spec # 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 = object_type_idx color_name, rgba = colour_idx else: fdhkfhddfh # TODO: fail gracefully # 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 * orientation_spec # 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 = material_idx 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 None, None return objects, blender_objects
def add_random_objects(scene_struct, num_objects, args, camera, frame): """ Add random objects to the current blender scene """ flag = 0 # 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) # yuji_size # size_name = "small" # r = 0.35 size_name = "big" r = args.Objsize # 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) # shana_position # x = random.uniform(-3, 3) # y = random.uniform(-3, 3) x = pos[frame][0] y = pos[frame][1] # print("(x,y) = ("+str(x)+","+str(y)+")") # 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: # yuji # print("shana") obj_name, obj_name_out = random.choice(object_mapping) obj_name = "SmoothCube_v2" obj_name = args.Objname obj_name_out = "cube" # obj_name = "Sphere" # obj_name_out = "sphere" # print(obj_name) # print(obj_name_out) color_name, rgba = random.choice(list(color_name_to_rgba.items())) # color_name = "red" # color_name = "yellow" col = (args.Objco).split(",") rgba = [] for sh in range(0, 4): rgba.append(float(col[sh])) # if args.Objco == 0: #Red # rgba = [0.6784313725490196, 0.13725490196078433, 0.13725490196078433, 1.0] # elif args.Objco == 1: #Gray # rgba = [0.341176, 0.341176, 0.341176, 1.0] # elif args.Objco == 2: #Blue # rgba = [0.164705, 0.294117, 0.84313, 1.0] # elif args.Objco == # else:#Yellow # rgba = [1.0,0.933333,0.2,1.0] # print(color_name) # print(rgba) 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() theta = 348.20058907697677 # print(theta) # 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) mat_name = "Rubber" mat_name_out = "rubber" # print(mat_name) # print(mat_name_out) 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: # flag = 1 # # # 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 , flag
def add_cups(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 = [] # Choose a random size, same for all cups size_name, r = size_mapping[0] first_cup_x = 0 first_cup_y = 0 # obj_name, obj_name_out = random.choice(object_mapping) obj_name, obj_name_out = [ el for el in object_mapping if el[1] == 'cylinder' ][0] color_name, rgba = random.choice(list(color_name_to_rgba.items())) # If using combos # 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] # Attach a random material mat_name, mat_name_out = random.choice(material_mapping) # 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() theta = 0.0 for i in range(num_objects): x = first_cup_x + i * 1.5 y = first_cup_y # 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)) 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, }) return objects, blender_objects
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) # Info Comment: For first loop, (x,y) as position and r as radius initialized above are placed in positions list. The for loop # below exists to ensure min dist between objects. # Maybe add code to limit spacing if nb of objects is low? (so if fewer objs and/or smaller size(?), closer together) # For first object, have anchor position. if not positions: x = 0.0 y = 0.0 # Check to make sure the new object is further than min_dist and closer than max distance (2(r+rr)) from all # other objects, and further than margin along the four cardinal directions dists_good = True margins_good = True # print('positions: ',positions) for (xx, yy, rr) in positions: # print("r, rr: ", r, " , ", rr) dx, dy = x - xx, y - yy dist = math.sqrt(dx * dx + dy * dy) max_dist = 2 * (r + rr) # print("x_dist, min_dist, max_dist: ", dist - r -rr, " , ", args.min_dist, " , ", max_dist) if (dist - r - rr < args.min_dist) or (dist - r - rr > (2 * (r + rr))): 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) # obj_name_out is the key and obj_name is val 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
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({ 'name': obj.name, '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, args.height, args.width, # args.crop_up, args.crop_down, args.crop_left, args.crop_right) # 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) indices = [ n[0] for n in sorted(enumerate(objects), key=lambda x: x[1]['pixel_coords'][2], reverse=True) ] objects = [objects[idx] for idx in indices] blender_objects = [blender_objects[idx] for idx in indices] return objects, blender_objects
def add_random_objects_group_by_similarity(scene_struct, args, camera): #TODO Implemetn 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()) not_fixed = random.randint(0,3) #0=color #1=size #2=material #3=shape fixed_size_name, fixed_size = random.choice(size_mapping) fixed_color_name, fixed_rgba = random.choice(list(color_name_to_rgba.items())) fixed_mat_name, fixed_mat_name_out = random.choice(material_mapping) fixed_obj_name, fixed_obj_name_out = random.choice(object_mapping) num_objects=random.randint(4,10) postitions=get_positions(num_objects,-7,7,-7,7) groups = {} objects = [] blender_objects = [] for num_object_actual in range(num_objects): position=postitions[num_object_actual] print("Iteration: ",num_object_actual) print("Position: ",position) if not_fixed == 0: fixed_color_name, fixed_rgba = random.choice(list(color_name_to_rgba.items())) if len(groups) > 0: if fixed_color_name not in groups.keys(): index = max(groups.values()) groups[fixed_color_name]=index+1 group=index+1 else: group=groups[fixed_color_name] else: groups[fixed_color_name] = 0 group=0 if not_fixed == 1: fixed_size_name, fixed_size = random.choice(size_mapping) if len(groups) > 0: if fixed_size_name not in groups.keys(): index = max(groups.values()) groups[fixed_size_name] = index + 1 group = index + 1 else: group = groups[fixed_size_name] else: groups[fixed_size_name] = 0 group = 0 if not_fixed == 2: fixed_mat_name, fixed_mat_name_out = random.choice(material_mapping) if len(groups) > 0: if fixed_mat_name not in groups.keys(): index = max(groups.values()) groups[fixed_mat_name] = index + 1 group = index + 1 else: group = groups[fixed_mat_name] else: groups[fixed_mat_name] = 0 group = 0 if not_fixed == 3: fixed_obj_name, fixed_obj_name_out = random.choice(object_mapping) if len(groups) > 0: if fixed_obj_name not in groups.keys(): index = max(groups.values()) groups[fixed_obj_name] = index + 1 group = index + 1 else: group = groups[fixed_obj_name] else: groups[fixed_obj_name] = 0 group = 0 print("---------Group ", group) if fixed_obj_name == 'Cube': fixed_size /= math.sqrt(2) theta = 360.0 * random.random() # Actually add the object to the scene utils.add_object(args.shape_dir, fixed_obj_name, fixed_size, position, theta=theta) object = bpy.context.object blender_objects.append(object) utils.add_material(fixed_mat_name, Color=fixed_rgba) # Record data about the object in the scene data structure pixel_coords = utils.get_camera_coords(camera, object.location) objects.append({ 'shape': fixed_obj_name_out, 'size': fixed_size_name, 'material': fixed_mat_name_out, '3d_coords': tuple(object.location), 'rotation': theta, 'pixel_coords': pixel_coords, 'color': fixed_color_name, 'group': group }) # 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 thing in blender_objects: utils.delete_object(thing) return add_random_objects_group_by_similarity(scene_struct, args, camera) return objects, blender_objects