def run(self): self.start() self.communicate(TDWUtils.create_empty_room(20, 20)) self.communicate(TDWUtils.create_avatar(position={"x": 0, "y": 3, "z": -6}, look_at=TDWUtils.VECTOR3_ZERO)) model_name = "rh10" z = -3 x = -1.5 print("With the add_object command (complex syntax but you have maximum control):") record = ModelLibrarian().get_record(model_name) self.communicate({"$type": "add_object", "name": model_name, "url": record.get_url(), "scale_factor": record.scale_factor, "position": {"x": x, "y": 0, "z": z}, "rotation": TDWUtils.VECTOR3_ZERO, "category": record.wcategory, "id": self.get_unique_id()}) x = 0 print("With the wrapper function Controller.add_object() " "(easy to use, but you can't add additional commands to this frame):") self.add_object(model_name=model_name, position={"x": x, "y": 0, "z": z}, rotation=TDWUtils.VECTOR3_ZERO, library="models_core.json") x = 1.5 print("With the wrapper function Controller.get_add_object() " "(harder to use, but you can add commands to this frame):") self.communicate(self.get_add_object(model_name=model_name, object_id=self.get_unique_id(), position={"x": x, "y": 0, "z": 0}, rotation=TDWUtils.VECTOR3_ZERO, library="models_core.json")) print("With the add_object command, minus all optional parameters (the model won't scale properly!):") self.communicate({"$type": "add_object", "name": model_name, "url": record.get_url(), "id": self.get_unique_id()}) print("With the wrapper function Controller.add_object(), minus all optional parameters:") self.add_object(model_name) print("With the wrapper function Controller.get_add_object(), minus all optional parameters:") self.communicate(self.get_add_object(model_name=model_name, object_id=self.get_unique_id()))
def run(self): """ Generate room using COCO_TDW dataset """ objects_in_scene = 15 object_ids = [] # Get Category-Object mapping TDW_COCO_models = TDW_relationships.get_COCO_TDW_mapping() # print("TDWCOCO:", TDW_COCO_models) # print("KEYS:", TDW_COCO_models.keys()) # Gets COCO categories co-occurring in a scene # +5 is for dealing with failed object insertion attempts COCO_configurations = msCOCO_matrix.get_max_co_occurrence(5, int(objects_in_scene + 5)) configuration_1 = COCO_configurations[0] print("Config 1:", configuration_1) # TDW models/objects objects = [] for COCO_object in configuration_1: print(COCO_object) print(COCO_object.split()) if len(COCO_object.split()) > 1: COCO_object = COCO_object.split()[-1] print(COCO_object) # Check if COCO category is a key in the COCO-TDW mapping if COCO_object in TDW_COCO_models.keys(): # Gets random TDW model (from COCO-to-TDW map) based on COCO category key print(TDW_COCO_models[COCO_object]) model = TDW_COCO_models[COCO_object][random.randint(0, len(TDW_COCO_models[COCO_object]) - 1)] objects.append(model) print("COCO to TDW objects:", objects) # print(len(objects)) # Stores object categories that other objects can be placed upon (e.g. table, chair, couch, bed) surface_properties_list = TDW_COCO_models['table'] + TDW_COCO_models['chair'] + \ TDW_COCO_models['bed'] + TDW_COCO_models['couch'] + \ TDW_COCO_models['bench'] + TDW_COCO_models['refrigerator'] surface_categories = [] for surface_properties in surface_properties_list: surface_categories.append(surface_properties[0]) print("Surface Categories:", surface_categories) # Stores the actual surface object instances/ids alongside number of objects on the surface surface_object_ids = {} self.start() positions_list = [] # Stores current model locations and radii scene_dimensions = [] # Store scene/environment dimensions init_setup_commands = [{"$type": "set_screen_size", "width": 640, "height": 481}, {"$type": "set_render_quality", "render_quality": 1}] self.communicate(init_setup_commands) scene_lib = SceneLibrarian() # Disable physics when adding in new objects (objects float) self.communicate({"$type": "simulate_physics", "value": False}) for scene in scenes[1:]: # Load in scene # print("Scene", scene[0]) if scene[3] == "interior" and scene[0] == "box_room_2018": self.start() scene_record = scene_lib.get_record(scene[0]) self.communicate({"$type": "add_scene", "name": scene_record.name, "url": scene_record.get_url()}) # Gets dimensions of environments (e.g. inside, outside) in the scene # This command returns environment data in the form of a list of serialized byte arrays scene_bytes = self.communicate({"$type": "send_environments", "frequency": "once"}) # Iterating through data and parsing byte array # Ignoring the last element (the frame count) for b in scene_bytes[:-1]: e = Environments(b) for i in range(e.get_num()): center = e.get_center(i) bounds = e.get_bounds(i) env_id = e.get_id(i) scene_dimensions = [center, bounds, env_id] # Center, bounds are tuples # Must come before set_pass_masks avatar_position = TDWUtils.array_to_vector3([0.9 * scene_dimensions[1][0] / 2, scene_dimensions[1][1] / 2, 0]) # print("Avatar Position:", avatar_position) self.communicate(TDWUtils.create_avatar(avatar_id="avatar", position=avatar_position, look_at={"x": 0, "y": scene_dimensions[0][1] / 2, "z": 0})) # Set collision mode self.communicate({"$type": "set_avatar_collision_detection_mode", "mode": "continuous_speculative", "avatar_id": "avatar"}) # Alter FOV self.communicate({"$type": "set_field_of_view", "field_of_view": 80, "avatar_id": "avatar"}) # # Gets rid of header (Model: Category) # objects = TDW_COCO_models[1:] # random.shuffle(objects) obj_count = 0 obj_overlaps = 0 # Number of failed attempts to place object due to over-dense objects area while obj_count < objects_in_scene and obj_overlaps < 5: # Handles if object has been added to a flat surface added_to_surface = False print("Object COUNT:", obj_count) # Need to have random position for Bounds Data to return meaningful info valid_obj_pos = {"x": random.uniform(-1 * scene_dimensions[1][0] / 2, 0.5 * scene_dimensions[1][0] / 2), "y": scene_dimensions[1][1] / 4, "z": random.uniform(-0.9 * scene_dimensions[1][2] / 2, 0.9 * scene_dimensions[1][2] / 2)} print("First random position") # Add in the object at random position # Object will later be removed or updated accordingly after performing collision calculations record = ModelLibrarian(library="models_full.json").get_record(objects[obj_count][0]) print("Record gotten") print(objects[obj_count][0]) o_id = self.communicate({"$type": "add_object", "name": objects[obj_count][0], "url": record.get_url(), "scale_factor": record.scale_factor, "position": valid_obj_pos, "rotation": TDWUtils.VECTOR3_ZERO, "category": record.wcategory, "id": obj_count}) print("Random first add") # Returns bound data for added object bounds_data = self.communicate({"$type": "send_bounds", "frequency": "once"}) print("Bounds returned") # Appends object, with information on position and obj_radius, to positions_list # Length of buffer array should be 1 # print("Bounds Data:", bounds_data) for b in bounds_data[:-1]: # print("Buffer Loop:", b) b_id = OutputData.get_data_type_id(b) if b_id == "boun": # print("BOUNDS") o = Bounds(b) # print("# of Objects:", o.get_num()) # print("# of Failed Attempts:", obj_overlaps) # print("Buffer Array:", b) # print("Bounds Object:", o) for i in range(o.get_num()): print("Object ID:", o.get_id(i)) print("obj_count:", obj_count) print("Object:", objects[obj_count][0], "Category:", objects[obj_count][1]) # print("Object Center:", o.get_center(i)) # Only want to compute valid_position for object we are about to add # Skip any computation if this is not the case if o.get_id(i) != obj_count: continue # Useful for detecting if object fits in environment # print("Calculating if object fits in environment") width = distance.euclidean(o.get_left(i), o.get_right(i)) depth = distance.euclidean(o.get_front(i), o.get_back(i)) height = distance.euclidean(o.get_top(i), o.get_bottom(i)) # print("Width:", width) # print("Depth:", depth) # ("Height:", height) # Useful for avoiding object overlap # print("Calculating Object Bounds") center_to_top = distance.euclidean(o.get_center(i), o.get_top(i)) center_to_bottom = distance.euclidean(o.get_center(i), o.get_bottom(i)) center_to_left = distance.euclidean(o.get_center(i), o.get_left(i)) center_to_right = distance.euclidean(o.get_center(i), o.get_right(i)) center_to_front = distance.euclidean(o.get_center(i), o.get_front(i)) center_to_back = distance.euclidean(o.get_center(i), o.get_back(i)) # Max object radius (center to diagonal of bounding box) obj_radius = \ max(math.sqrt(center_to_top ** 2 + center_to_left ** 2 + center_to_front ** 2), math.sqrt(center_to_top ** 2 + center_to_right ** 2 + center_to_front ** 2), math.sqrt(center_to_top ** 2 + center_to_left ** 2 + center_to_back ** 2), math.sqrt(center_to_top ** 2 + center_to_right ** 2 + center_to_back ** 2), math.sqrt(center_to_bottom ** 2 + center_to_left ** 2 + center_to_front ** 2), math.sqrt(center_to_bottom ** 2 + center_to_right ** 2 + center_to_front ** 2), math.sqrt(center_to_bottom ** 2 + center_to_left ** 2 + center_to_back ** 2), math.sqrt(center_to_bottom ** 2 + center_to_right ** 2 + center_to_back ** 2)) # print("Obj_Radius:", obj_radius) # Set sweeping radius, based on scene plane dimensions l_radius = random.uniform(0, min(0.5 * scene_dimensions[1][0] / 2, 0.5 * scene_dimensions[1][2] / 2)) # Checking that object fits in scene viewing if (width > min(0.7 * scene_dimensions[1][0], 0.7 * scene_dimensions[1][2]) or depth > min(0.7 * scene_dimensions[1][0], 0.7 * scene_dimensions[1][2]) or height > 0.7 * scene_dimensions[1][1]): print("Object does not fit in scene") self.communicate([{"$type": "send_images", "frequency": "never"}, {"$type": "destroy_object", "id": obj_count}]) # Ensures next attempt to load in item is not the same item as before random.shuffle(objects) break # Not possible to find valid object position -- too many overlapping objects elif (not self._get_object_position(scene_dimensions=scene_dimensions, object_positions=positions_list, object_to_add_radius=obj_radius, max_tries=20, location_radius=l_radius)[0]): print("Could not calculate valid object location") self.communicate([{"$type": "send_images", "frequency": "never"}, {"$type": "destroy_object", "id": obj_count}]) obj_overlaps += 1 # Ensures next attempt to load in item is not the same item as before random.shuffle(objects) break # Find appropriate, non-overlapping object position # Reset object position to the valid position else: print("Object fits in scene") # Check if object fits on table, chair, couch, etc. # Add object if it fits, place it somewhere on top of the surface for surface_id in surface_object_ids.keys(): print("Surface ID:", surface_id) # Skip placement feasibility if the object is already a surface-type object # Ex. no chair on top of a table if objects[obj_count][0] in surface_categories: print("Object: %s is already a surface object" % objects[obj_count][0]) break # Check how many objects are on surface if surface_object_ids[surface_id] >= 3: print("Too many objects on surface") print("From surface objects dict:", surface_object_ids[surface_id]) continue surface_bounds = self.get_bounds_data(surface_id) surface_area = distance.euclidean(surface_bounds.get_left(0), surface_bounds.get_right(0)) * \ distance.euclidean(surface_bounds.get_front(0), surface_bounds.get_back(0)) obj_area = width * height if obj_area < surface_area: s_center_to_top = distance.euclidean(surface_bounds.get_center(0), surface_bounds.get_top(0)) s_center_to_bottom = distance.euclidean(surface_bounds.get_center(0), surface_bounds.get_bottom(0)) s_center_to_left = distance.euclidean(surface_bounds.get_center(0), surface_bounds.get_left(0)) s_center_to_right = distance.euclidean(surface_bounds.get_center(0), surface_bounds.get_right(0)) s_center_to_front = distance.euclidean(surface_bounds.get_center(0), surface_bounds.get_front(0)) s_center_to_back = distance.euclidean(surface_bounds.get_center(0), surface_bounds.get_back(0)) surface_radius = \ max(math.sqrt( s_center_to_top ** 2 + s_center_to_left ** 2 + s_center_to_front ** 2), math.sqrt( s_center_to_top ** 2 + s_center_to_right ** 2 + s_center_to_front ** 2), math.sqrt( s_center_to_top ** 2 + s_center_to_left ** 2 + s_center_to_back ** 2), math.sqrt( s_center_to_top ** 2 + s_center_to_right ** 2 + s_center_to_back ** 2), math.sqrt( s_center_to_bottom ** 2 + s_center_to_left ** 2 + s_center_to_front ** 2), math.sqrt( s_center_to_bottom ** 2 + s_center_to_right ** 2 + s_center_to_front ** 2), math.sqrt( s_center_to_bottom ** 2 + s_center_to_left ** 2 + s_center_to_back ** 2), math.sqrt( s_center_to_bottom ** 2 + s_center_to_right ** 2 + s_center_to_back ** 2)) print("Surface-type object") self.communicate({"$type": "destroy_object", "id": obj_count}) # Adding the object to the top of the surface on_pos = surface_bounds.get_top(0) on_y = on_pos[1] on_pos = TDWUtils.get_random_point_in_circle(np.array(on_pos), 0.7 * surface_radius) on_pos[1] = on_y on_pos = TDWUtils.array_to_vector3(on_pos) on_rot = {"x": 0, "y": random.uniform(-45, 45), "z": 0} # Add the object. print("Model Name on Surface:", objects[obj_count][0]) record = ModelLibrarian(library="models_full.json").get_record( objects[obj_count][0]) on_id = self.communicate({"$type": "add_object", "name": objects[obj_count][0], "url": record.get_url(), "scale_factor": record.scale_factor, "position": on_pos, "rotation": on_rot, "category": record.wcategory, "id": obj_count}) obj_count += 1 surface_object_ids[surface_id] += 1 object_ids.append(obj_count) print("Object added on top of surface") added_to_surface = True # Breaking out of surface objects loop break if added_to_surface: print("Breaking out of object loop") # Breaking out of object loop break print("Post-surface") valid_obj_pos = self._get_object_position(scene_dimensions=scene_dimensions, object_positions=positions_list, object_to_add_radius=obj_radius, max_tries=20, location_radius=l_radius)[1] print("Position calculated") positions_list.append(ObjectPosition(valid_obj_pos, obj_radius)) self.communicate([{"$type": "send_images", "frequency": "never"}, {"$type": "destroy_object", "id": obj_count}]) added_object_id = self.communicate({"$type": "add_object", "name": objects[obj_count][0], "url": record.get_url(), "scale_factor": record.scale_factor, "position": valid_obj_pos, "rotation": {"x": 0, "y": 0, "z": 0}, "category": record.wcategory, "id": obj_count}) # print("Object ID:", added_object_id) print("Regular object add") object_ids.append(added_object_id) # If TDW model belongs to surface categories, store id_information if objects[obj_count][0] in surface_categories: surface_object_ids[obj_count] = 0 # Rotate the object randomly print("Rotating object") self.communicate({"$type": "rotate_object_by", "angle": random.uniform(-45, 45), "axis": "yaw", "id": obj_count, "is_world": True}) # Minimal rotating for position differences # Don't rotate the object if doing so will result in overlap into scene if not (o.get_bottom(i)[1] < 0 or o.get_top(i)[1] > 0.9 * scene_dimensions[1][1]): pitch_angle = random.uniform(-45, 45) self.communicate({"$type": "rotate_object_by", "angle": pitch_angle, "axis": "pitch", "id": obj_count, "is_world": True}) roll_angle = random.uniform(-45, 45) self.communicate({"$type": "rotate_object_by", "angle": roll_angle, "axis": "roll", "id": obj_count, "is_world": True}) # Don't need this for just changing positions # Setting random materials/textures # Looping through sub-objects and materials sub_count = 0 for sub_object in record.substructure: # Loop through materials in sub-objects for j in range(len(sub_object)): # Get random material and load in material = random.choice(materials[1:]) self.load_material(material) print("Material loaded") # Set random material on material of sub-object self.communicate({"$type": "set_visual_material", "material_index": j, "material_name": material[0], "object_name": sub_object['name'], "id": obj_count}) print("Material set") sub_count += 1 if sub_count > 10: break break print("Updating count") obj_count += 1 print("Breaking out of object_id loop") break # Break out of buffer loop print("Breaking out of buffer loop") break # Move onto next iteration of while loop (next object to load in) print("Object added - next while loop iteration") continue # for i in range(200): # self.communicate({"$type": "simulate_physics", # "value": False}) # Enable image capture self.communicate({"$type": "set_pass_masks", "avatar_id": "avatar", "pass_masks": ["_img", "_id"]}) self.communicate({"$type": "send_images", "frequency": "always"}) # Capture scene # NOTE: THESE SCENES GET REPLACED IN THE TARGET DIRECTORY scene_data = self.communicate({"$type": "look_at_position", "avatar_id": "avatar", "position": {"x": 0, "y": scene_dimensions[0][1] / 2, "z": 0}}) images = Images(scene_data[0]) TDWUtils.save_images(images, TDWUtils.zero_padding(i), output_directory=path) print("Object ids:", object_ids)
def run(self): self.start() init_setup_commands = [{"$type": "set_screen_size", "width": 640, "height": 480}, {"$type": "set_render_quality", "render_quality": 5}] self.communicate(init_setup_commands) self.communicate({"$type": "create_empty_environment", "center": {"x": 0, "y": 0, "z": 0}, "bounds": {"x": 15, "y": 15, "z": 15}}) # Disable physics. self.communicate({"$type": "set_gravity", "value": False}) # Add the avatar. self.communicate(TDWUtils.create_avatar(position={"x": -1.5, "y": 1.4, "z": 0.6}, look_at=TDWUtils.array_to_vector3([3, 0.5, 0.5]), avatar_id="avatar")) self.communicate(self.get_add_hdri_skybox("table_mountain_1_4k")) self.communicate({"$type": "set_field_of_view", "field_of_view": 68.0, "avatar_id": "avatar"}) cube_record = ModelLibrarian("models_special.json").get_record("prim_cube") self.communicate({"$type": "add_object", "name": "prim_cube", "url": cube_record.get_url(), "scale_factor": cube_record.scale_factor, "position": {"x": 0, "y": 0, "z": 0}, "rotation": {"x": 0, "y": 0, "z": 0}, "category": cube_record.wcategory, "id": 1}) self.communicate({"$type": "scale_object", "scale_factor": {"x": 30, "y": 0.0001, "z": 30}, "id": 1}) grass_record = MaterialLibrarian("materials_high.json").get_record("grass_countryside") self.communicate({"$type": "add_material", "name": "grass_countryside", "url": grass_record.get_url()}) self.communicate(TDWUtils.set_visual_material(c=self, substructure=cube_record.substructure, object_id=1, material="grass_countryside")) self.add_object(model_name="b03_horse", position={"x": 3, "y": 0.0001, "z": 0.5}, rotation={"x": 0, "y": 0, "z": 0}, library="models_full.json") bird = self.add_object(model_name="polysurface63", position={"x": 1.2, "y": 0.0001, "z": 1}, rotation={"x": 0, "y": 0, "z": 0}, library="models_full.json") self.communicate({"$type": "scale_object", "scale_factor": {"x": 2, "y": 2, "z": 2}, "id": bird}) bird = self.add_object(model_name="b03_realistic_pigeon_max", position={"x": 1.8, "y": 0.0001, "z": 0.45}, rotation={"x": 0, "y": -95, "z": 0}, library="models_full.json") self.communicate({"$type": "scale_object", "scale_factor": {"x": 2, "y": 2, "z": 2}, "id": bird}) bird = self.add_object(model_name="rockdove_polysurface77", position={"x": 1, "y": 0.0001, "z": 0.7}, rotation={"x": 0, "y": -80, "z": 0}, library="models_full.json") self.communicate({"$type": "scale_object", "scale_factor": {"x": 2, "y": 2, "z": 2}, "id": bird}) # Enable image capture self.communicate({"$type": "set_pass_masks", "avatar_id": "avatar", "pass_masks": ["_img", "_id"]}) self.communicate({"$type": "send_images", "frequency": "always"}) scene_data = self.communicate({"$type": "look_at_position", "avatar_id": "avatar", "position": TDWUtils.array_to_vector3([3, 0.5, 0])}) images = Images(scene_data[0]) TDWUtils.save_images(images, "bird2", output_directory="/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/exterior")
def run(self): self.start() init_setup_commands = [{ "$type": "set_screen_size", "width": 600, "height": 480 }, { "$type": "set_render_quality", "render_quality": 5 }] self.communicate(init_setup_commands) # Create an empty room. self.communicate({ "$type": "create_empty_environment", "center": { "x": 0, "y": 0, "z": 0 }, "bounds": { "x": 8, "y": 8, "z": 8 } }) self.communicate({"$type": "set_gravity", "value": False}) cube_record = ModelLibrarian("models_special.json").get_record( "prim_cube") self.communicate({ "$type": "add_object", "name": "prim_cube", "url": cube_record.get_url(), "scale_factor": cube_record.scale_factor, "position": { "x": 0, "y": 0, "z": 0 }, "rotation": { "x": 0, "y": 0, "z": 0 }, "category": cube_record.wcategory, "id": 1 }) self.communicate({ "$type": "scale_object", "scale_factor": { "x": 30, "y": 0.0001, "z": 30 }, "id": 1 }) # Add the avatar. self.communicate( TDWUtils.create_avatar(position={ "x": 0, "y": 0.6, "z": 0 }, look_at=TDWUtils.array_to_vector3( [0.5, 0.5, 0]), avatar_id="avatar")) self.communicate(self.get_add_hdri_skybox("table_mountain_1_4k")) self.communicate({"$type": "rotate_hdri_skybox_by", "angle": 90}) lib = MaterialLibrarian(library="materials_med.json") record = lib.get_record("bricks_chatham_gray_used") self.communicate({ "$type": "add_material", "name": "bricks_chatham_gray_used", "url": record.get_url() }) self.communicate( TDWUtils.set_visual_material(c=self, substructure=cube_record.substructure, object_id=1, material="bricks_chatham_gray_used")) # self.communicate({"$type": "set_field_of_view", # "field_of_view": 68.0, # "avatar_id": "avatar"}) bench = self.add_object(model_name="b04_wood_metal_park_bench", position={ "x": 2, "y": 0, "z": 0.5 }, rotation={ "x": 0, "y": -90, "z": 0 }, library="models_full.json") self.add_object(model_name="b04_wood_metal_park_bench", position={ "x": 5, "y": 0, "z": 0.5 }, rotation={ "x": 0, "y": -90, "z": 0 }, library="models_full.json") bench_bounds = self.get_bounds_data(bench) top = bench_bounds.get_top(0) self.add_object(model_name="cgaxis_models_65_06_vray", position={ "x": 1.8, "y": top[1] - 0.42, "z": 0.35 }, rotation={ "x": 0, "y": 0, "z": 0 }, library="models_full.json") # Enable image capture self.communicate({ "$type": "set_pass_masks", "avatar_id": "avatar", "pass_masks": ["_img", "_id"] }) self.communicate({"$type": "send_images", "frequency": "always"}) scene_data = self.communicate({ "$type": "look_at_position", "avatar_id": "avatar", "position": TDWUtils.array_to_vector3([0.5, 0.5, 0]) }) images = Images(scene_data[0]) TDWUtils.save_images( images, "bench_book", output_directory= "/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/exterior" )
def run(self): self.start() init_setup_commands = [{ "$type": "set_screen_size", "width": 600, "height": 480 }, { "$type": "set_render_quality", "render_quality": 5 }] self.communicate(init_setup_commands) # Create an empty scene (no walls) self.communicate({ "$type": "create_empty_environment", "center": { "x": 0, "y": 0, "z": 0 }, "bounds": { "x": 20, "y": 20, "z": 20 } }) self.communicate(self.get_add_hdri_skybox("kiara_5_noon_4k")) self.communicate({"$type": "rotate_hdri_skybox_by", "angle": 90}) cube_record = ModelLibrarian("models_special.json").get_record( "prim_cube") self.communicate({ "$type": "add_object", "name": "prim_cube", "url": cube_record.get_url(), "scale_factor": cube_record.scale_factor, "position": { "x": 0, "y": 0, "z": 0 }, "rotation": { "x": 0, "y": 0, "z": 0 }, "category": cube_record.wcategory, "id": 1 }) self.communicate({ "$type": "scale_object", "scale_factor": { "x": 30, "y": 0.0001, "z": 30 }, "id": 1 }) grass_record = MaterialLibrarian("materials_high.json").get_record( "limestone_white") self.communicate({ "$type": "add_material", "name": "limestone_white", "url": grass_record.get_url() }) self.communicate( TDWUtils.set_visual_material(c=self, substructure=cube_record.substructure, object_id=1, material="limestone_white")) # Disable physics. self.communicate({"$type": "set_gravity", "value": False}) # Add the avatar. self.communicate( TDWUtils.create_avatar(position={ "x": -5, "y": 1.5, "z": 0 }, look_at=TDWUtils.array_to_vector3( [0, 1.5, 0]), avatar_id="avatar")) self.communicate({ "$type": "set_field_of_view", "field_of_view": 68.0, "avatar_id": "avatar" }) self.add_object(model_name="b03_topkicktruck", position={ "x": 4, "y": 0, "z": 0.4 }, rotation={ "x": 0, "y": -30, "z": 0 }, library="models_full.json") self.add_object(model_name="b05_iz-49_3", position={ "x": -1, "y": 0, "z": -1.7 }, rotation={ "x": 0, "y": 90, "z": 0 }, library="models_full.json") self.add_object(model_name="3dscan_man_002", position={ "x": -1.6, "y": 0, "z": -2 }, rotation={ "x": 0, "y": 90, "z": 0 }, library="models_full.json") # Enable image capture self.communicate({ "$type": "set_pass_masks", "avatar_id": "avatar", "pass_masks": ["_img", "_id"] }) self.communicate({"$type": "send_images", "frequency": "always"}) scene_data = self.communicate({ "$type": "look_at_position", "avatar_id": "avatar", "position": TDWUtils.array_to_vector3([0, 1.5, 0]) }) images = Images(scene_data[0]) TDWUtils.save_images( images, "truck_moto", output_directory= "/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/exterior" )
def run(self): self.start() positions_list = [] # Stores current model locations and radii scene_dimensions = [] # Store scene/environment dimensions init_setup_commands = [{ "$type": "set_screen_size", "width": 1280, "height": 962 }, { "$type": "set_render_quality", "render_quality": 5 }] self.communicate(init_setup_commands) scene_lib = SceneLibrarian() # Disable physics when adding in new objects (objects float) self.communicate({"$type": "simulate_physics", "value": False}) for scene in scenes[1:]: # Load in scene print("Scene", scene[0]) if scene[3] == "interior" and scene[0] == "box_room_2018": self.start() scene_record = scene_lib.get_record(scene[0]) self.communicate({ "$type": "add_scene", "name": scene_record.name, "url": scene_record.get_url() }) # Gets dimensions of environments (e.g. inside, outside) in the scene # This command returns environment data in the form of a list of serialized byte arrays scene_bytes = self.communicate({ "$type": "send_environments", "frequency": "once" }) # Iterating through data and parsing byte array # Ignoring the last element (the frame count) for b in scene_bytes[:-1]: e = Environments(b) for i in range(e.get_num()): center = e.get_center(i) bounds = e.get_bounds(i) env_id = e.get_id(i) scene_dimensions = [center, bounds, env_id] # Center, bounds are tuples # Must come before set_pass_masks avatar_position = TDWUtils.array_to_vector3([ 0.9 * scene_dimensions[1][0] / 2, scene_dimensions[1][1] / 2, 0 ]) print("Avatar Position:", avatar_position) self.communicate( TDWUtils.create_avatar(avatar_id="avatar", position=avatar_position, look_at={ "x": 0, "y": scene_dimensions[0][1] / 2, "z": 0 })) # Set collision mode self.communicate({ "$type": "set_avatar_collision_detection_mode", "mode": "continuous_speculative", "avatar_id": "avatar" }) # Alter FOV self.communicate({ "$type": "set_field_of_view", "field_of_view": 80, "avatar_id": "avatar" }) # Gets rid of header (Model: Category) objects = models[1:] random.shuffle(objects) obj_count = 0 obj_overlaps = 0 # Number of failed attempts to place object due to over-dense objects area while obj_count < 30 and obj_overlaps < 5: # Need to have random position for Bounds Data to return meaningful info valid_obj_pos = { "x": random.uniform(-1 * scene_dimensions[1][0] / 2, 0.5 * scene_dimensions[1][0] / 2), "y": scene_dimensions[1][1] / 4, "z": random.uniform(-0.9 * scene_dimensions[1][2] / 2, 0.9 * scene_dimensions[1][2] / 2) } # Add in the object at random position # Object will later be removed or updated accordingly after performing collision calculations record = ModelLibrarian( library="models_full.json").get_record( objects[obj_count][0]) self.communicate({ "$type": "add_object", "name": objects[obj_count][0], "url": record.get_url(), "scale_factor": record.scale_factor, "position": valid_obj_pos, "rotation": { "x": 0, "y": 0, "z": 0 }, "category": record.wcategory, "id": obj_count }) # Returns bound data for added object bounds_data = self.communicate({ "$type": "send_bounds", "frequency": "once" }) # Appends object, with information on position and obj_radius, to positions_list # Length of buffer array should be 1 print("Bounds Data:", bounds_data) for b in bounds_data[:-1]: print("Buffer Loop:", b) b_id = OutputData.get_data_type_id(b) if b_id == "boun": print("BOUNDS") o = Bounds(b) print("# of Objects:", o.get_num()) print("# of Failed Attempts:", obj_overlaps) print("Buffer Array:", b) print("Bounds Object:", o) for i in range(o.get_num()): print("Object ID:", o.get_id(i)) print("obj_count:", obj_count) print("Object:", objects[obj_count][0], "Category:", objects[obj_count][1]) print("Object Center:", o.get_center(i)) # Only want to compute valid_position for object we are about to add # Skip any computation if this is not the case if o.get_id(i) != obj_count: continue # Useful for detecting if object fits in environment print( "Calculating if object fits in environment" ) width = distance.euclidean( o.get_left(i), o.get_right(i)) depth = distance.euclidean( o.get_front(i), o.get_back(i)) height = distance.euclidean( o.get_top(i), o.get_bottom(i)) print("Width:", width) print("Depth:", depth) print("Height:", height) # Useful for avoiding object overlap print("Calculating Object Bounds") center_to_top = distance.euclidean( o.get_center(i), o.get_top(i)) center_to_bottom = distance.euclidean( o.get_center(i), o.get_bottom(i)) center_to_left = distance.euclidean( o.get_center(i), o.get_left(i)) center_to_right = distance.euclidean( o.get_center(i), o.get_right(i)) center_to_front = distance.euclidean( o.get_center(i), o.get_front(i)) center_to_back = distance.euclidean( o.get_center(i), o.get_back(i)) # Max object radius (center to diagonal of bounding box) obj_radius = \ max(math.sqrt(center_to_top ** 2 + center_to_left ** 2 + center_to_front ** 2), math.sqrt(center_to_top ** 2 + center_to_right ** 2 + center_to_front ** 2), math.sqrt(center_to_top ** 2 + center_to_left ** 2 + center_to_back ** 2), math.sqrt(center_to_top ** 2 + center_to_right ** 2 + center_to_back ** 2), math.sqrt(center_to_bottom ** 2 + center_to_left ** 2 + center_to_front ** 2), math.sqrt(center_to_bottom ** 2 + center_to_right ** 2 + center_to_front ** 2), math.sqrt(center_to_bottom ** 2 + center_to_left ** 2 + center_to_back ** 2), math.sqrt(center_to_bottom ** 2 + center_to_right ** 2 + center_to_back ** 2)) print("Obj_Radius:", obj_radius) # Set sweeping radius, based on scene plane dimensions l_radius = random.uniform( 0, min(0.9 * scene_dimensions[1][0] / 2, 0.9 * scene_dimensions[1][2] / 2)) # Checking that object fits in scene viewing if (width > min(0.7 * scene_dimensions[1][0], 0.7 * scene_dimensions[1][2]) or depth > min( 0.7 * scene_dimensions[1][0], 0.7 * scene_dimensions[1][2]) or height > 0.7 * scene_dimensions[1][1]): print("Object does not fit in scene") self.communicate([{ "$type": "send_images", "frequency": "never" }, { "$type": "destroy_object", "id": obj_count }]) # Ensures next attempt to load in item is not the same item as before random.shuffle(objects) break # Not possible to find valid object position -- too many overlapping objects elif (not self._get_object_position( scene_dimensions=scene_dimensions, object_positions=positions_list, object_to_add_radius=obj_radius, max_tries=20, location_radius=l_radius)[0]): print( "Could not calculate valid object location" ) self.communicate([{ "$type": "send_images", "frequency": "never" }, { "$type": "destroy_object", "id": obj_count }]) obj_overlaps += 1 # Ensures next attempt to load in item is not the same item as before random.shuffle(objects) break # Find appropriate, non-overlapping object position # Reset object position to the valid position else: print("Object fits in scene") valid_obj_pos = self._get_object_position( scene_dimensions=scene_dimensions, object_positions=positions_list, object_to_add_radius=obj_radius, max_tries=20, location_radius=l_radius)[1] print("Position calculated") positions_list.append( ObjectPosition(valid_obj_pos, obj_radius)) self.communicate([{ "$type": "send_images", "frequency": "never" }, { "$type": "destroy_object", "id": obj_count }]) print("Object ready to reset") self.communicate([{ "$type": "send_images", "frequency": "never" }, { "$type": "add_object", "name": objects[obj_count][0], "url": record.get_url(), "scale_factor": record.scale_factor, "position": valid_obj_pos, "rotation": { "x": 0, "y": 0, "z": 0 }, "category": record.wcategory, "id": obj_count }]) print("Object reset") # Rotate the object randomly print("Rotating object") self.communicate({ "$type": "rotate_object_by", "angle": random.uniform(-45, 45), "axis": "yaw", "id": obj_count, "is_world": True }) # Don't rotate the object if doing so will result in overlap into scene if not (o.get_bottom(i)[1] < 0 or o.get_top(i)[1] > 0.9 * scene_dimensions[1][1]): pitch_angle = random.uniform(-45, 45) self.communicate({ "$type": "rotate_object_by", "angle": pitch_angle, "axis": "pitch", "id": obj_count, "is_world": True }) roll_angle = random.uniform(-45, 45) self.communicate({ "$type": "rotate_object_by", "angle": roll_angle, "axis": "roll", "id": obj_count, "is_world": True }) # Setting random materials/textures # Looping through sub-objects and materials sub_count = 0 for sub_object in record.substructure: # Loop through materials in sub-objects for j in range(len(sub_object)): # Get random material and load in material = random.choice( materials[1:]) self.load_material(material) print("Material loaded") # Set random material on material of sub-object self.communicate({ "$type": "set_visual_material", "material_index": j, "material_name": material[0], "object_name": sub_object['name'], "id": obj_count }) print("Material set") sub_count += 1 if sub_count > 10: break break print("Updating count") obj_count += 1 print("Breaking out of object_id loop") break # Break out of buffer loop print("Breaking out of buffer loop") break # Move onto next iteration of while loop (next object to load in) print("Object added - next while loop iteration") continue # Enable image capture self.communicate({ "$type": "set_pass_masks", "avatar_id": "avatar", "pass_masks": ["_img", "_id"] }) self.communicate({ "$type": "send_images", "frequency": "always" }) # Capture scene scene_data = self.communicate({ "$type": "look_at_position", "avatar_id": "avatar", "position": { "x": 0, "y": scene_dimensions[0][1] / 2, "z": 0 } }) images = Images(scene_data[0]) TDWUtils.save_images(images, TDWUtils.zero_padding(i), output_directory=path)
def run(self): self.start() init_setup_commands = [{ "$type": "set_screen_size", "width": 640, "height": 480 }, { "$type": "set_render_quality", "render_quality": 5 }] self.communicate(init_setup_commands) self.communicate({ "$type": "create_empty_environment", "center": { "x": 0, "y": 0, "z": 0 }, "bounds": { "x": 15, "y": 15, "z": 15 } }) # Disable physics. self.communicate({"$type": "set_gravity", "value": False}) # Add the avatar. self.communicate( TDWUtils.create_avatar(position={ "x": 5, "y": 1.4, "z": 0.6 }, look_at=TDWUtils.array_to_vector3( [0, 0.5, 0.5]), avatar_id="avatar")) self.communicate(self.get_add_hdri_skybox("sky_white")) self.communicate({ "$type": "set_field_of_view", "field_of_view": 68.0, "avatar_id": "avatar" }) cube_record = ModelLibrarian("models_special.json").get_record( "prim_cube") self.communicate({ "$type": "add_object", "name": "prim_cube", "url": cube_record.get_url(), "scale_factor": cube_record.scale_factor, "position": { "x": 0, "y": 0, "z": 0 }, "rotation": { "x": 0, "y": 0, "z": 0 }, "category": cube_record.wcategory, "id": 1 }) self.communicate({ "$type": "scale_object", "scale_factor": { "x": 30, "y": 0.0001, "z": 30 }, "id": 1 }) grass_record = MaterialLibrarian("materials_high.json").get_record( "iceland_mossy_meadow") self.communicate({ "$type": "add_material", "name": "iceland_mossy_meadow", "url": grass_record.get_url() }) self.communicate( TDWUtils.set_visual_material(c=self, substructure=cube_record.substructure, object_id=1, material="iceland_mossy_meadow")) bench = self.add_object(model_name="b04_wood_metal_park_bench", position={ "x": 3, "y": 0, "z": 0.5 }, rotation={ "x": 0, "y": 0, "z": 0 }, library="models_full.json") bench_bounds = self.get_bounds_data(bench) top = bench_bounds.get_top(0) self.add_object(model_name="3dscan_man_004", position={ "x": 2.5, "y": 0, "z": 0 }, rotation={ "x": 0, "y": 90, "z": 0 }, library="models_full.json") hummingbird = self.add_object(model_name="b04_pigeon", position={ "x": 3, "y": top[1] - 0.05, "z": 0.75 }, rotation={ "x": 0, "y": 0, "z": 0 }, library="models_full.json") self.add_object(model_name="b03_realistic_pigeon_max", position={ "x": 3, "y": top[1] - 0.05, "z": 0.35 }, rotation={ "x": 0, "y": 90, "z": 0 }, library="models_full.json") # Enable image capture self.communicate({ "$type": "set_pass_masks", "avatar_id": "avatar", "pass_masks": ["_img", "_id"] }) self.communicate({"$type": "send_images", "frequency": "always"}) scene_data = self.communicate({ "$type": "look_at_position", "avatar_id": "avatar", "position": TDWUtils.array_to_vector3([0, 0.5, 0.5]) }) images = Images(scene_data[0]) TDWUtils.save_images( images, "bird1", output_directory= "/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/exterior" )
def run(self): self.start() init_setup_commands = [{ "$type": "set_screen_size", "width": 640, "height": 480 }, { "$type": "set_render_quality", "render_quality": 5 }] self.communicate(init_setup_commands) self.communicate(TDWUtils.create_empty_room(8, 8)) # Disable physics. self.communicate({"$type": "set_gravity", "value": False}) # Add the avatar. self.communicate( TDWUtils.create_avatar(position={ "x": 0, "y": 1.4, "z": 3 }, look_at=TDWUtils.array_to_vector3( [0, 0.5, 0]), avatar_id="avatar")) self.communicate({ "$type": "set_field_of_view", "field_of_view": 68.0, "avatar_id": "avatar" }) table_record = ModelLibrarian(library="models_full.json").get_record( "restoration_hardware_salvaged_tables") table = self.add_object( model_name="restoration_hardware_salvaged_tables", position={ "x": 0, "y": 0, "z": 0 }, rotation={ "x": 0, "y": -90, "z": 0 }, library="models_full.json") table_bounds = self.get_bounds_data(table) left = table_bounds.get_left(0) self.add_object(model_name="3dscan_man_002", position={ "x": 1.6, "y": 0, "z": left[2] }, rotation={ "x": 0, "y": 124, "z": 0 }, library="models_full.json") top = table_bounds.get_top(0) cup_record = ModelLibrarian( library="models_full.json").get_record("cup") self.communicate({ "$type": "add_object", "name": "cup", "url": cup_record.get_url(), "scale_factor": cup_record.scale_factor, "position": { "x": 0, "y": top[1], "z": -0.07 }, "rotation": { "x": 0, "y": -90, "z": 0 }, "category": cup_record.wcategory, "id": 1 }) # record = MaterialLibrarian(library='materials_high.json').get_record("polystyrene_foam") self.communicate({ "$type": "add_material", "name": "polystyrene_foam", "url": "http://s3.amazonaws.com/tdw_test_dev/materials/osx/high/polystyrene_foam" }) for sub_object in cup_record.substructure: for j in range(len(sub_object)): self.communicate({ "$type": "set_visual_material", "material_index": j, "material_name": "polystyrene_foam", "object_name": sub_object["name"], "id": 1 }) self.communicate({ "$type": "add_object", "name": "cup", "url": cup_record.get_url(), "scale_factor": cup_record.scale_factor, "position": { "x": -0.3, "y": top[1], "z": 0.1 }, "rotation": { "x": 0, "y": -90, "z": 0 }, "category": cup_record.wcategory, "id": 2 }) for sub_object in cup_record.substructure: for j in range(len(sub_object)): self.communicate({ "$type": "set_visual_material", "material_index": j, "material_name": "polystyrene_foam", "object_name": sub_object["name"], "id": 2 }) self.add_object(model_name='neopolitan_pizza', position={ "x": 0.7, "y": top[1], "z": 0 }, rotation={ "x": 0, "y": -22, "z": 0 }, library="models_full.json") self.add_object(model_name='stua_onda_stool_max2012', position={ "x": -1.4, "y": 0, "z": 0 }, rotation={ "x": 0, "y": 90, "z": 0 }, library="models_full.json") # Enable image capture self.communicate({ "$type": "set_pass_masks", "avatar_id": "avatar", "pass_masks": ["_img", "_id"] }) self.communicate({"$type": "send_images", "frequency": "always"}) scene_data = self.communicate({ "$type": "look_at_position", "avatar_id": "avatar", "position": TDWUtils.array_to_vector3([0, 0.5, 0]) }) images = Images(scene_data[0]) TDWUtils.save_images( images, "pizza2", output_directory= "/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/interior" )
def run(self): self.start() init_setup_commands = [{"$type": "set_screen_size", "width": 1280, "height": 962}, {"$type": "set_render_quality", "render_quality": 5}] self.communicate(init_setup_commands) # Create an empty room. self.load_streamed_scene(scene="tdw_room_2018") # Disable physics. self.communicate({"$type": "set_gravity", "value": False}) # Add the avatar. self.communicate(TDWUtils.create_avatar(position={"x": 2, "y": 1.5, "z": 0}, look_at=TDWUtils.array_to_vector3([2, 0.8, -4]), avatar_id="avatar")) self.communicate({"$type": "set_field_of_view", "field_of_view": 68.0, "avatar_id": "avatar"}) self.add_object(model_name="kenmore_refr_74049", position={"x": 3, "y": 0, "z": -4}, rotation={"x": 0, "y": 90, "z": 0}, library="models_full.json") record = ModelLibrarian(library='models_full.json').get_record("b03_bosch_cbg675bs1b_2013__vray_composite") self.communicate({"$type": "add_object", "name": "b03_bosch_cbg675bs1b_2013__vray_composite", "url": record.get_url(), "scale_factor": 1.5, "position": {"x": 2, "y": 0, "z": -4}, "category": record.wcategory, "id": self.get_unique_id()}) table_id = self.add_object(model_name="b03_restoration_hardware_pedestal_salvaged_round_tables", position={"x": 1, "y": 0, "z": -4}, library="models_full.json") table_bounds = self.get_bounds_data(table_id) top = table_bounds.get_top(0) self.add_object(model_name="cgaxis_models_65_06_vray", position={"x": 1.2, "y": top[1], "z": -4.2}, library="models_full.json") self.add_object(model_name="b04_heineken_beer_vray", position={"x": 0.77, "y": top[1], "z": -3.9}, library="models_full.json") self.add_object(model_name="b03_backpack", position={"x": 1.3, "y": 0, "z": -3.7}, rotation={"x": 0, "y": 20, "z": 0}, library="models_full.json") # Enable image capture self.communicate({"$type": "set_pass_masks", "avatar_id": "avatar", "pass_masks": ["_img", "_id"]}) self.communicate({"$type": "send_images", "frequency": "always"}) scene_data = self.communicate({"$type": "look_at_position", "avatar_id": "avatar", "position": TDWUtils.array_to_vector3([2, 0.8, -4])}) images = Images(scene_data[0]) TDWUtils.save_images(images, "fridge", output_directory="replicated_images")
def run(self): self.start() init_setup_commands = [{ "$type": "set_screen_size", "width": 1280, "height": 962 }, { "$type": "set_render_quality", "render_quality": 5 }] self.communicate(init_setup_commands) # Create an empty room. self.load_streamed_scene(scene="tdw_room_2018") # Disable physics. self.communicate({"$type": "simulate_physics", "value": False}) # Add the avatar. self.communicate( TDWUtils.create_avatar(position={ "x": 0, "y": 1.5, "z": -2 }, look_at=TDWUtils.array_to_vector3( [0, 0.8, 4]), avatar_id="avatar")) self.communicate({ "$type": "set_field_of_view", "field_of_view": 68.0, "avatar_id": "avatar" }) # Enable image capture scene_data = self.communicate({ "$type": "set_pass_masks", "avatar_id": "avatar", "pass_masks": ["_id"] }) self.communicate({"$type": "send_images", "frequency": "always"}) chair_id = self.add_object(model_name="ligne_roset_armchair", position={ "x": -1.5, "y": 0, "z": 4 }, library="models_full.json") self.communicate({ "$type": "rotate_object_by", "angle": 180, "axis": "yaw", "id": chair_id, "is_world": True }) scene_data = self.communicate({ "$type": "look_at_position", "avatar_id": "avatar", "position": TDWUtils.array_to_vector3([0, 0.8, 4]) }) images = Images(scene_data[0]) TDWUtils.save_images(images, "armchair_1", output_directory="replicated_images") record = ModelLibrarian( library='models_full.json').get_record("b05_tv1970") self.communicate({ "$type": "add_object", "name": "b05_tv1970", "url": record.get_url(), "scale_factor": 30, "position": { "x": 0, "y": 0, "z": 3.5 }, "category": record.wcategory, "id": self.get_unique_id() }) scene_data = self.communicate({ "$type": "look_at_position", "avatar_id": "avatar", "position": TDWUtils.array_to_vector3([0, 0.8, 4]) }) images = Images(scene_data[0]) TDWUtils.save_images(images, "armchair_2", output_directory="replicated_images") self.add_object(model_name="side_table_wood", position={ "x": -2.5, "y": 0, "z": 4 }, library="models_full.json") scene_data = self.communicate({ "$type": "look_at_position", "avatar_id": "avatar", "position": TDWUtils.array_to_vector3([0, 0.8, 4]) }) images = Images(scene_data[0]) TDWUtils.save_images(images, "armchair_3", output_directory="replicated_images") side_table = self.add_object(model_name="side_table_wood", position={ "x": 1.5, "y": 0, "z": 4 }, library="models_full.json") side_table_bounds = self.get_bounds_data(side_table) top = side_table_bounds.get_top(0) scene_data = self.communicate({ "$type": "look_at_position", "avatar_id": "avatar", "position": TDWUtils.array_to_vector3([0, 0.8, 4]) }) images = Images(scene_data[0]) TDWUtils.save_images(images, "armchair_4", output_directory="replicated_images") self.add_object(model_name="acacia_table_lamp_jamie_young", position={ "x": 1.5, "y": top[1], "z": 4 }, library="models_full.json") scene_data = self.communicate({ "$type": "look_at_position", "avatar_id": "avatar", "position": TDWUtils.array_to_vector3([0, 0.8, 4]) }) images = Images(scene_data[0]) TDWUtils.save_images(images, "armchair_5", output_directory="replicated_images") # Enable image capture self.communicate({ "$type": "set_pass_masks", "avatar_id": "avatar", "pass_masks": ["_img"] }) scene_data = self.communicate({ "$type": "look_at_position", "avatar_id": "avatar", "position": TDWUtils.array_to_vector3([0, 0.8, 4]) }) images = Images(scene_data[0]) TDWUtils.save_images( images, "armchair", output_directory="../replicated_images/segmentation")
def run(self): self.start() init_setup_commands = [{ "$type": "set_screen_size", "width": 640, "height": 480 }, { "$type": "set_render_quality", "render_quality": 5 }] self.communicate(init_setup_commands) self.communicate(TDWUtils.create_empty_room(8, 8)) # Disable physics. self.communicate({"$type": "set_gravity", "value": False}) # Add the avatar. self.communicate( TDWUtils.create_avatar(position={ "x": 0.75, "y": 1, "z": 0 }, look_at=TDWUtils.array_to_vector3( [3, 0.7, 0]), avatar_id="avatar")) # self.communicate({"$type": "set_field_of_view", # "field_of_view": 68.0, # "avatar_id": "avatar"}) self.add_object(model_name="12_01_001", position={ "x": 3, "y": 0, "z": -0.35 }, rotation={ "x": 0, "y": 90, "z": 0 }, library="models_full.json") sink = self.add_object(model_name="cgaxis_models_22_33_vray", position={ "x": 3, "y": 0, "z": 0.35 }, rotation={ "x": 0, "y": -90, "z": 0 }, library="models_full.json") record = ModelLibrarian(library='models_full.json').get_record( "b03_simpsons_london_-_round_hudson_mirror") self.communicate({ "$type": "add_object", "name": "b05_tv1970", "url": record.get_url(), "scale_factor": 0.5, "position": { "x": 3, "y": 0.6, "z": 0.35 }, "rotation": { "x": 0, "y": -90, "z": 0 }, "category": record.wcategory, "id": self.get_unique_id() }) sink_bounds = self.get_bounds_data(sink) top = sink_bounds.get_top(0) self.add_object(model_name="808409_toothbrush", position={ "x": 3, "y": top[1] - 0.217, "z": 0.7 }, rotation={ "x": -20, "y": -40, "z": 90 }, library="models_full.json") # Enable image capture self.communicate({ "$type": "set_pass_masks", "avatar_id": "avatar", "pass_masks": ["_img", "_id"] }) self.communicate({"$type": "send_images", "frequency": "always"}) scene_data = self.communicate({ "$type": "look_at_position", "avatar_id": "avatar", "position": TDWUtils.array_to_vector3([3, 0.7, 0]) }) images = Images(scene_data[0]) TDWUtils.save_images(images, "bathroom1", output_directory="replicated_images")