Beispiel #1
0
    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(TDWUtils.create_empty_room(10, 10))
        # Disable physics.
        self.communicate({"$type": "set_gravity",
                          "value": False})
        self.communicate(self.get_add_hdri_skybox("autumn_hockey_4k"))

        # Add the avatar.
        self.communicate(TDWUtils.create_avatar(position={"x": 3, "y": 1.3, "z": 0},
                                                look_at=TDWUtils.array_to_vector3([0, 0.5, 0]),
                                                avatar_id="avatar"))

        lib = MaterialLibrarian(library="materials_med.json")
        record = lib.get_record("grass_countryside")
        print(record)
        self.communicate({"$type": "add_material", "name": "grass_countryside", "url": record.get_url()})
        self.communicate({"$type": "set_proc_gen_floor_material", "name": "grass_countryside"})

        # self.communicate({"$type": "set_field_of_view",
        #                   "field_of_view": 68.0,
        #                   "avatar_id": "avatar"})

        self.add_object(model_name="b05_clochild4",
                        position={"x": 0, "y": 0, "z": 0},
                        rotation={"x": 0, "y": 30, "z": 0},
                        library="models_full.json")

        self.add_object(model_name="baseballbat",
                        position={"x": 0.5, "y": 0, "z": 0.3},
                        rotation={"x": 0, "y": 30, "z": 0},
                        library="models_full.json")

        self.add_object(model_name="base-ball",
                        position={"x": 0.4, "y": 0, "z": 0.22},
                        rotation={"x": 0, "y": 30, "z": 10},
                        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, "kid_baseball", output_directory="/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/exterior")
Beispiel #2
0
    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(TDWUtils.create_empty_room(32, 32))
        # Disable physics.
        self.communicate({"$type": "set_gravity",
                          "value": False})

        # Add the avatar.
        self.communicate(TDWUtils.create_avatar(position={"x": -1.5, "y": 1.5, "z": -15},
                                                look_at=TDWUtils.array_to_vector3([-1.7, 0.7, -2.3]),
                                                avatar_id="avatar"))

        lib = MaterialLibrarian(library="materials_med.json")
        record = lib.get_record("concrete_chipped_cracked")
        self.communicate({"$type": "add_material", "name": "concrete_chipped_cracked", "url": record.get_url()})
        self.communicate({"$type": "set_proc_gen_floor_material", "name": "concrete_chipped_cracked"})
        # self.communicate({"$type": "set_proc_gen_walls_material", "name": "concrete"})

        self.communicate({"$type": "set_field_of_view",
                          "field_of_view": 68.0,
                          "avatar_id": "avatar"})

        bus = self.add_object(model_name="b06_bus_new",
                              position={"x": -2, "y": 0, "z": 0},
                              rotation={"x": 0, "y": -70, "z": 0},
                              library="models_full.json")

        bus_bounds = self.get_bounds_data(bus)
        bus_front = bus_bounds.get_front(0)
        print(bus_front)

        self.add_object(model_name="3dscan_man_004",
                        position={"x": -3.7, "y": 0, "z": -7.3},
                        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([-1.7, 0.7, -2.3])})

        images = Images(scene_data[0])
        TDWUtils.save_images(images, "bus",
                             output_directory="/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/exterior")
Beispiel #3
0
    def run(self):
        self.create_scene()

        print("Using Controller.get_add_material wrapper function:")

        self.communicate([self.get_add_material("parquet_long_horizontal_clean"),
                          {"$type": "set_proc_gen_floor_material",
                           "name": "parquet_long_horizontal_clean"}])

        sleep(5)

        self.create_scene()

        print("Using the add_material command without any wrappers:")
        lib = MaterialLibrarian()
        record = lib.get_record("parquet_long_horizontal_clean")
        self.communicate([{"$type": "add_material",
                           "name": record.name,
                           "url": record.get_url()},
                          {"$type": "set_proc_gen_floor_material",
                           "name": "parquet_long_horizontal_clean"}])
Beispiel #4
0
    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(TDWUtils.create_empty_room(8, 8))

        # Disable physics.
        self.communicate({"$type": "set_gravity", "value": False})

        lib = MaterialLibrarian(library="materials_med.json")
        record = lib.get_record("parquet_wood_mahogany")
        self.communicate({
            "$type": "add_material",
            "name": "parquet_wood_mahogany",
            "url": record.get_url()
        })
        self.communicate({
            "$type": "set_proc_gen_floor_material",
            "name": "parquet_wood_mahogany"
        })

        # Add the avatar.
        self.communicate(
            TDWUtils.create_avatar(position={
                "x": -1,
                "y": 1.4,
                "z": -1
            },
                                   look_at=TDWUtils.array_to_vector3(
                                       [-0.1, 0.7, -0.1]),
                                   avatar_id="avatar"))

        self.communicate({
            "$type": "set_field_of_view",
            "field_of_view": 68.0,
            "avatar_id": "avatar"
        })

        table_id = self.add_object(
            model_name=
            "b03_restoration_hardware_pedestal_salvaged_round_tables",
            position={
                "x": 0,
                "y": 0,
                "z": 0
            },
            library="models_full.json")

        table_bounds = self.get_bounds_data(table_id)
        top = table_bounds.get_top(0)

        self.add_object(model_name="club_sandwich",
                        position={
                            "x": 0.45,
                            "y": top[1],
                            "z": 0.25
                        },
                        rotation={
                            "x": 0,
                            "y": 30,
                            "z": 0
                        },
                        library="models_full.json")

        self.add_object(model_name="coffeemug",
                        position={
                            "x": 0.03,
                            "y": top[1],
                            "z": 0.03
                        },
                        library="models_full.json")

        self.add_object(model_name="knife3",
                        position={
                            "x": -0.17,
                            "y": top[1],
                            "z": 0.15
                        },
                        rotation={
                            "x": 0,
                            "y": 24,
                            "z": 90
                        },
                        library="models_full.json")

        self.add_object(model_name="notes_02",
                        position={
                            "x": 0.17,
                            "y": top[1],
                            "z": -0.12
                        },
                        rotation={
                            "x": 0,
                            "y": 24,
                            "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, 0.7, -0.1])
        })

        images = Images(scene_data[0])
        TDWUtils.save_images(
            images,
            "sadnwich2",
            output_directory=
            "/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/interior"
        )
Beispiel #5
0
    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})

        lib = MaterialLibrarian(library="materials_med.json")
        record = lib.get_record("laser_cut_white_norway_spruce")
        self.communicate({
            "$type": "add_material",
            "name": "laser_cut_white_norway_spruce",
            "url": record.get_url()
        })
        self.communicate({
            "$type": "set_proc_gen_floor_material",
            "name": "laser_cut_white_norway_spruce"
        })

        # Add the avatar.
        self.communicate(
            TDWUtils.create_avatar(position={
                "x": 1.5,
                "y": 1.6,
                "z": 0
            },
                                   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 = self.add_object(
            model_name="boconcept_lugo_dining_table_vray1.5",
            position={
                "x": 0,
                "y": 0,
                "z": 0.0
            },
            rotation={
                "x": 0,
                "y": -90,
                "z": 0
            },
            library="models_full.json")

        table_bounds = self.get_bounds_data(table)

        top = table_bounds.get_top(0)
        self.add_object(model_name='macbook_001',
                        position={
                            "x": 0,
                            "y": top[1],
                            "z": 0.1
                        },
                        rotation={
                            "x": 0,
                            "y": 90,
                            "z": 0
                        },
                        library="models_full.json")

        self.add_object(model_name='spunlight_designermesh_lamp',
                        position={
                            "x": -0.19,
                            "y": top[1],
                            "z": -0.4
                        },
                        rotation={
                            "x": 0,
                            "y": 0,
                            "z": 0
                        },
                        library="models_full.json")

        self.add_object(model_name="apple_magic_mouse_2_(2015)_vray",
                        position={
                            "x": 0,
                            "y": top[1],
                            "z": 0.32
                        },
                        rotation={
                            "x": 0,
                            "y": 86,
                            "z": 0
                        },
                        library="models_full.json")

        self.add_object(model_name="f10_apple_iphone_4",
                        position={
                            "x": 0.14,
                            "y": top[1],
                            "z": -0.3
                        },
                        rotation={
                            "x": 0,
                            "y": 12,
                            "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,
            "phone",
            output_directory=
            "/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/interior"
        )
Beispiel #6
0
    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(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": 2.5,
                "y": 1.5,
                "z": 0.3
            },
                                   look_at=TDWUtils.array_to_vector3(
                                       [3, 0.5, 0.5]),
                                   avatar_id="avatar"))

        lib = MaterialLibrarian(library="materials_med.json")
        record = lib.get_record("gravel_white")
        self.communicate({
            "$type": "add_material",
            "name": "gravel_white",
            "url": record.get_url()
        })
        self.communicate({
            "$type": "set_proc_gen_floor_material",
            "name": "gravel_white"
        })
        # self.communicate({"$type": "set_proc_gen_walls_material", "name": "concrete"})

        # 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": 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="b05_baseball_bat_01",
                        position={
                            "x": 2.8,
                            "y": top[1] - 0.35,
                            "z": 0
                        },
                        rotation={
                            "x": 0,
                            "y": 90,
                            "z": 90
                        },
                        library="models_full.json")

        self.add_object(model_name="b05_baseballnew_v03_12",
                        position={
                            "x": 2.9,
                            "y": top[1] - 0.35,
                            "z": 0.4
                        },
                        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([3, 0.5, 0.5])
        })

        images = Images(scene_data[0])
        TDWUtils.save_images(
            images,
            "bench_ball",
            output_directory=
            "/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/exterior"
        )
Beispiel #7
0
class Controller(object):
    """
    Base class for all controllers.

    Usage:

    ```python
    from tdw.controller import Controller
    c = Controller()
    c.start()
    ```
    """
    def __init__(self,
                 port: int = 1071,
                 check_version: bool = True,
                 launch_build: bool = True):
        """
        Create the network socket and bind the socket to the port.

        :param port: The port number.
        :param check_version: If true, the controller will check the version of the build and print the result.
        :param launch_build: If True, automatically launch the build. If one doesn't exist, download and extract the correct version. Set this to False to use your own build, or (if you are a backend developer) to use Unity Editor.
        """

        # Compare the installed version of the tdw Python module to the latest on PyPi.
        # If there is a difference, recommend an upgrade.
        if check_version:
            self._check_pypi_version()

        # Launch the build.
        if launch_build:
            Controller.launch_build()

        context = zmq.Context()

        self.socket = context.socket(zmq.REP)
        self.socket.bind('tcp://*:' + str(port))

        self.socket.recv()

        self.model_librarian: Optional[ModelLibrarian] = None
        self.scene_librarian: Optional[SceneLibrarian] = None
        self.material_librarian: Optional[MaterialLibrarian] = None
        self.hdri_skybox_librarian: Optional[HDRISkyboxLibrarian] = None
        self.humanoid_librarian: Optional[HumanoidLibrarian] = None
        self.humanoid_animation_librarian: Optional[
            HumanoidAnimationLibrarian] = None

        # Compare the version of the tdw module to the build version.
        if check_version and launch_build:
            self._check_build_version()

    def communicate(self, commands: Union[dict, List[dict]]) -> list:
        """
        Send commands and receive output data in response.

        :param commands: A list of JSON commands.

        :return The output data from the build.
        """

        if not isinstance(commands, list):
            commands = [commands]

        self.socket.send_multipart([json.dumps(commands).encode('utf-8')])

        return self.socket.recv_multipart()

    def start(self, scene="ProcGenScene") -> None:
        """
        Init TDW.

        :param scene: The scene to load.
        """

        self.communicate([{"$type": "load_scene", "scene_name": scene}])

    def get_add_object(self,
                       model_name: str,
                       object_id: int,
                       position={
                           "x": 0,
                           "y": 0,
                           "z": 0
                       },
                       rotation={
                           "x": 0,
                           "y": 0,
                           "z": 0
                       },
                       library: str = "") -> dict:
        """
        Returns a valid add_object command.

        :param model_name: The name of the model.
        :param position: The position of the model.
        :param rotation: The starting rotation of the model, in Euler angles.
        :param library: The path to the records file. If left empty, the default library will be selected. See `ModelLibrarian.get_library_filenames()` and `ModelLibrarian.get_default_library()`.
        :param object_id: The ID of the new object.

        :return An add_object command that the controller can then send.
        """

        if self.model_librarian is None or (
                library != "" and self.model_librarian.library != library):
            self.model_librarian = ModelLibrarian(library=library)

        record = self.model_librarian.get_record(model_name)

        return {
            "$type": "add_object",
            "name": model_name,
            "url": record.get_url(),
            "scale_factor": record.scale_factor,
            "position": position,
            "rotation": rotation,
            "category": record.wcategory,
            "id": object_id
        }

    def get_add_material(self, material_name: str, library: str = "") -> dict:
        """
        Returns a valid add_material command.

        :param material_name: The name of the material.
        :param library: The path to the records file. If left empty, the default library will be selected. See `MaterialLibrarian.get_library_filenames()` and `MaterialLibrarian.get_default_library()`.

        :return An add_material command that the controller can then send.
        """

        if self.material_librarian is None:
            self.material_librarian = MaterialLibrarian(library=library)

        record = self.material_librarian.get_record(material_name)
        return {
            "$type": "add_material",
            "name": material_name,
            "url": record.get_url()
        }

    def get_add_scene(self, scene_name: str, library: str = "") -> dict:
        """
        Returns a valid add_scene command.

        :param scene_name: The name of the scene.
        :param library: The path to the records file. If left empty, the default library will be selected. See `SceneLibrarian.get_library_filenames()` and `SceneLibrarian.get_default_library()`.

        :return An add_scene command that the controller can then send.
        """

        if self.scene_librarian is None:
            self.scene_librarian = SceneLibrarian(library=library)

        record = self.scene_librarian.get_record(scene_name)
        return {
            "$type": "add_scene",
            "name": scene_name,
            "url": record.get_url()
        }

    def get_add_hdri_skybox(self, skybox_name: str, library: str = "") -> dict:
        """
        Returns a valid add_hdri_skybox command.

        :param skybox_name: The name of the skybox.
        :param library: The path to the records file. If left empty, the default library will be selected. See `HDRISkyboxLibrarian.get_library_filenames()` and `HDRISkyboxLibrarian.get_default_library()`.

        :return An add_hdri_skybox command that the controller can then send.
        """

        if self.hdri_skybox_librarian is None:
            self.hdri_skybox_librarian = HDRISkyboxLibrarian(library=library)

        record = self.hdri_skybox_librarian.get_record(skybox_name)
        return {
            "$type": "add_hdri_skybox",
            "name": skybox_name,
            "url": record.get_url(),
            "exposure": record.exposure,
            "initial_skybox_rotation": record.initial_skybox_rotation,
            "sun_elevation": record.sun_elevation,
            "sun_initial_angle": record.sun_initial_angle,
            "sun_intensity": record.sun_intensity
        }

    def get_add_humanoid(self,
                         humanoid_name: str,
                         object_id: int,
                         position={
                             "x": 0,
                             "y": 0,
                             "z": 0
                         },
                         rotation={
                             "x": 0,
                             "y": 0,
                             "z": 0
                         },
                         library: str = "") -> dict:
        """
        Returns a valid add_humanoid command.

        :param humanoid_name: The name of the humanoid.
        :param position: The position of the humanoid.
        :param rotation: The starting rotation of the humanoid, in Euler angles.
        :param library: The path to the records file. If left empty, the default library will be selected. See `HumanoidLibrarian.get_library_filenames()` and `HumanoidLibrarian.get_default_library()`.
        :param object_id: The ID of the new object.

        :return An add_humanoid command that the controller can then send.
        """

        if self.humanoid_librarian is None or (
                library != "" and self.humanoid_librarian.library != library):
            self.humanoid_librarian = HumanoidLibrarian(library=library)

        record = self.humanoid_librarian.get_record(humanoid_name)

        return {
            "$type": "add_humanoid",
            "name": humanoid_name,
            "url": record.get_url(),
            "position": position,
            "rotation": rotation,
            "id": object_id
        }

    def get_add_humanoid_animation(
            self,
            humanoid_animation_name: str,
            library="") -> (dict, HumanoidAnimationRecord):
        """
        Returns a valid add_humanoid_animation command and the record (which you will need to play an animation).

        :param humanoid_animation_name: The name of the animation.
        :param library: The path to the records file. If left empty, the default library will be selected. See `HumanoidAnimationLibrarian.get_library_filenames()` and `HumanoidAnimationLibrarian.get_default_library()`.

        return An add_humanoid_animation command that the controller can then send.
        """

        if self.humanoid_animation_librarian is None:
            self.humanoid_animation_librarian = HumanoidAnimationLibrarian(
                library=library)

        record = self.humanoid_animation_librarian.get_record(
            humanoid_animation_name)
        return {
            "$type": "add_humanoid_animation",
            "name": humanoid_animation_name,
            "url": record.get_url()
        }, record

    def load_streamed_scene(self, scene="tdw_room_2018") -> None:
        """
        Load a streamed scene. This is equivalent to: `c.communicate(c.get_add_scene(scene))`

        :param scene: The name of the streamed scene.
        """

        self.communicate(self.get_add_scene(scene))

    def add_object(self,
                   model_name: str,
                   position={
                       "x": 0,
                       "y": 0,
                       "z": 0
                   },
                   rotation={
                       "x": 0,
                       "y": 0,
                       "z": 0
                   },
                   library: str = "") -> int:
        """
        Add a model to the scene. This is equivalent to: `c.communicate(c.get_add_object())`

        :param model_name: The name of the model.
        :param position: The position of the model.
        :param rotation: The starting rotation of the model, in Euler angles.
        :param library: The path to the records file. If left empty, the default library will be selected. See `ModelLibrarian.get_library_filenames()` and `ModelLibrarian.get_default_library()`.

        :return The ID of the new object.
        """

        object_id = Controller.get_unique_id()
        self.communicate(
            self.get_add_object(model_name, object_id, position, rotation,
                                library))

        return object_id

    def get_version(self) -> Tuple[str, str]:
        """
        Send a send_version command to the build.

        :return The TDW version and the Unity Engine version.
        """

        resp = self.communicate({"$type": "send_version"})
        for r in resp[:-1]:
            if Version.get_data_type_id(r) == "vers":
                v = Version(r)
                return v.get_tdw_version(), v.get_unity_version()
        if len(resp) == 1:
            raise Exception(
                "Tried receiving version output data but didn't receive anything!"
            )
        raise Exception(f"Expected output data with ID vers but got: " +
                        Version.get_data_type_id(resp[0]))

    @staticmethod
    def get_unique_id() -> int:
        """
        Generate a unique integer. Useful when creating objects.

        :return The new unique ID.
        """

        return int.from_bytes(os.urandom(3), byteorder='big')

    @staticmethod
    def get_frame(frame: bytes) -> int:
        """
        Converts the frame byte array to an integer.

        :param frame: The frame as bytes.

        :return The frame as an integer.
        """

        return int.from_bytes(frame, byteorder='big')

    @staticmethod
    def launch_build() -> None:
        """
        Launch the build. If a build doesn't exist at the expected location, download one to that location.
        """

        # Download the build.
        if not Build.BUILD_PATH.exists():
            print(
                f"Couldn't find build at {Build.BUILD_PATH}\nDownloading now..."
            )
            success = Build.download()
            if not success:
                print("You need to launch your own build.")
        else:
            success = True
        # Launch the build.
        if success:
            Popen(str(Build.BUILD_PATH.resolve()))

    def _check_build_version(self,
                             version: str = __version__,
                             build_version: str = None) -> None:
        """
        Check the version of the build. If there is no build, download it.
        If the build is of the wrong version, recommend an upgrade.


        :param version: The version of TDW. You can set this to an arbitrary version for testing purposes.
        :param build_version: If not None, this overrides the expected build version. Only override for debugging.
        """

        v = PyPi.strip_post_release(version)
        tdw_version, unity_version = self.get_version()
        # Override the build version for testing.
        if build_version is not None:
            tdw_version = build_version
        pypi_version = PyPi.get_latest_minor_release(tdw_version)
        print(
            f"Build version {tdw_version}\nUnity Engine {unity_version}\nPython tdw module version {version}"
        )
        if v < tdw_version:
            print(
                "WARNING! Your TDW build is newer than your tdw Python module. They might not be compatible."
            )
            print(
                f"To download the correct build:\n\nfrom tdw.release.build import Build\nBuild.download(version={v})"
            )
            print(
                f"\nTo upgrade your Python module (usually recommended):\n\npip3 install tdw=={pypi_version}"
            )
        elif v > tdw_version:
            print(
                "WARNING! Your TDW build is older than your tdw Python module. Downloading the correct build..."
            )
            Build.download(v)

    @staticmethod
    def _check_pypi_version(v_installed_override: str = None,
                            v_pypi_override: str = None) -> None:
        """
        Compare the version of the tdw Python module to the latest on PyPi.
        If there is a mismatch, offer an upgrade recommendation.

        :param v_installed_override: Override for the installed version. Change this to debug.
        :param v_pypi_override: Override for the PyPi version. Change this to debug.
        """

        # Get the version of the installed tdw module.
        installed_tdw_version = PyPi.get_installed_tdw_version()
        # Get the latest version of the tdw module on PyPi.
        pypi_version = PyPi.get_pypi_version()

        # Apply overrides
        if v_installed_override is not None:
            installed_tdw_version = v_installed_override
        if v_pypi_override is not None:
            pypi_version = v_pypi_override

        # If there is a mismatch, recommend an upgrade.
        if installed_tdw_version != pypi_version:
            # Strip the installed version of the post-release suffix (e.g. 1.6.3.4 to 1.6.3).
            stripped_installed_version = PyPi.strip_post_release(
                installed_tdw_version)
            # This message is here only for debugging.
            if stripped_installed_version != __version__:
                print(
                    f"Your installed version: {stripped_installed_version} "
                    f"doesn't match tdw.version.__version__: {__version__} "
                    f"(this may be because you're using code from the tdw repo that is ahead of PyPi)."
                )
            # Strip the latest PyPi version of the post-release suffix.
            stripped_pypi_version = PyPi.strip_post_release(pypi_version)
            print(
                f"You are using TDW {installed_tdw_version} but version {pypi_version} is available."
            )

            # If user is behind by a post release, recommend an upgrade to the latest.
            # (Example: installed version is 1.6.3.4 and PyPi version is 1.6.3.5)
            if stripped_installed_version == stripped_pypi_version:
                print(
                    f"Upgrade to the latest version of TDW:\npip3 install tdw -U"
                )

            # Using a version behind the latest (e.g. latest is 1.6.3 and installed is 1.6.2)
            # If the user is behind by a major or minor release, recommend either upgrading to a minor release
            # or to a major release.
            # (Example: installed version is 1.6.3.4 and PyPi version is 1.7.0.0)
            else:
                installed_major = PyPi.get_major_release(
                    stripped_installed_version)
                pypi_minor = PyPi.get_latest_minor_release(
                    stripped_installed_version)
                # Minor release mis-match.
                if PyPi.strip_post_release(
                        pypi_minor) != stripped_installed_version:
                    print(
                        f"To upgrade to the last version of 1.{installed_major}:\n"
                        f"pip3 install tdw=={pypi_minor}")
                pypi_major = PyPi.get_major_release(stripped_pypi_version)
                # Major release mis-match.
                if installed_major != pypi_major:
                    # Offer to upgrade to a major release.
                    print(
                        f"Consider upgrading to the latest version of TDW ({stripped_pypi_version}):"
                        f"\npip3 install tdw -U")
        else:
            print("Your installed tdw Python module is up to date with PyPi.")
Beispiel #8
0
    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"
        )
Beispiel #9
0
    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)

        self.communicate(self.get_add_hdri_skybox("industrial_sunset_4k"))

        # Create an empty room.
        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": 1,
                "y": 1.5,
                "z": 0.3
            },
                                   look_at=TDWUtils.array_to_vector3(
                                       [2.5, 0.5, 0.5]),
                                   avatar_id="avatar"))

        lib = MaterialLibrarian(library="materials_med.json")
        record = lib.get_record("concrete_049")
        self.communicate({
            "$type": "add_material",
            "name": "concrete_049",
            "url": record.get_url()
        })
        self.communicate({
            "$type": "set_proc_gen_floor_material",
            "name": "concrete_049"
        })
        # self.communicate({"$type": "set_proc_gen_walls_material", "name": "concrete"})

        # self.communicate({"$type": "set_field_of_view",
        #                   "field_of_view": 68.0,
        #                   "avatar_id": "avatar"})

        bench = self.add_object(model_name="cgaxis_models_51_19_01",
                                position={
                                    "x": 2.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="b05_cat_model_3dmax2012",
                        position={
                            "x": 2.5,
                            "y": top[1],
                            "z": 0.2
                        },
                        rotation={
                            "x": 0,
                            "y": 0,
                            "z": 0
                        },
                        library="models_full.json")

        self.add_object(model_name="azor",
                        position={
                            "x": 3,
                            "y": 0,
                            "z": 0.5
                        },
                        rotation={
                            "x": 0,
                            "y": 90,
                            "z": 0
                        },
                        library="models_full.json")
        """ Post-scene construction """

        # Enable image capture
        self.communicate({
            "$type": "set_pass_masks",
            "avatar_id": "avatar",
            "pass_masks": ["_id"]
        })

        scene_data = self.communicate({
            "$type":
            "look_at_position",
            "avatar_id":
            "avatar",
            "position":
            TDWUtils.array_to_vector3([3, 0.5, 0.5])
        })

        # images = Images(scene_data[0])
        im = cv2.imread(
            "/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/"
            "compare_COCO_TDW/replicated_images/exterior/id_bench_bike.png")
        im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)

        # WRITE THIS TO JSON!
        segmentation_data = []
        COCO_to_TDW = pd.read_csv(
            '/Users/leonard/Desktop/coco/COCO_to_TDW.csv',
            header=None,
            index_col=0,
            squeeze=True).to_dict()

        segmentation_colors = self.communicate({
            "$type": "send_segmentation_colors",
            "frequency": "once"
        })
        for r in segmentation_colors[:-1]:
            r_id = OutputData.get_data_type_id(r)
            if r_id == "segm":
                s = SegmentationColors(r)
                for i in range(s.get_num()):
                    name = s.get_object_name(i)
                    category = get_COCO(name, COCO_to_TDW)

                    color = s.get_object_color(i)
                    indices = np.where(im != 0)  # Segmentation pixels
                    print(color)
                    print(indices)
                    print(im[indices[0][0]]
                          )  # some random RGB val -- MUSt match one of the 3
                    segmentation_data.append([indices, category])

        # TDWUtils.save_images(images, "bench_bike",
        #                      output_directory="/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/exterior")

        # Consider using zip() to clean up coordinates

        return segmentation_data
    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(TDWUtils.create_empty_room(16, 16))
        # Disable physics.
        self.communicate({"$type": "set_gravity", "value": False})

        # Add the avatar.
        self.communicate(
            TDWUtils.create_avatar(position={
                "x": -7.5,
                "y": 1.5,
                "z": 0
            },
                                   look_at=TDWUtils.array_to_vector3(
                                       [0, 0.7, 0]),
                                   avatar_id="avatar"))

        self.communicate(self.get_add_hdri_skybox("industrial_sunset_4k"))

        lib = MaterialLibrarian(library="materials_med.json")
        record = lib.get_record("concrete_asphalt_rolled")
        self.communicate({
            "$type": "add_material",
            "name": "concrete_asphalt_rolled",
            "url": record.get_url()
        })
        self.communicate({
            "$type": "set_proc_gen_floor_material",
            "name": "concrete_asphalt_rolled"
        })
        # self.communicate({"$type": "set_proc_gen_walls_material", "name": "concrete"})

        self.communicate({
            "$type": "set_field_of_view",
            "field_of_view": 68.0,
            "avatar_id": "avatar"
        })

        self.add_object(model_name="b05_model_sell",
                        position={
                            "x": 2.5,
                            "y": 0,
                            "z": 4
                        },
                        rotation={
                            "x": 0,
                            "y": 90,
                            "z": 0
                        },
                        library="models_full.json")

        self.add_object(model_name="b03_fire_hydrant",
                        position={
                            "x": 2,
                            "y": 0,
                            "z": -1
                        },
                        rotation={
                            "x": 0,
                            "y": 0,
                            "z": 0
                        },
                        library="models_full.json")

        # record = ModelLibrarian(library='models_full.json').get_record("bigben_clock")
        # self.communicate({"$type": "add_object",
        #                   "name": "bigben_clock",
        #                   "url": record.get_url(),
        #                   "scale_factor": record.scale_factor * 10,
        #                   "position": {"x": 1.7, "y": 0, "z": -3},
        #                   "rotation": TDWUtils.VECTOR3_ZERO,
        #                   "category": record.wcategory,
        #                   "id": self.get_unique_id()})

        self.add_object(model_name="bench",
                        position={
                            "x": 1.7,
                            "y": 0,
                            "z": -3
                        },
                        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.7, 0])
        })

        images = Images(scene_data[0])
        TDWUtils.save_images(
            images,
            "hydrant_clock",
            output_directory=
            "/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/exterior"
        )
Beispiel #11
0
    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": 30,
                "y": 30,
                "z": 30
            }
        })

        self.communicate(self.get_add_hdri_skybox("pink_sunrise_4k"))

        cube = self.communicate({
            "$type": "load_primitive_from_resources",
            "primitive_type": "Cube",
            "id": 1,
            "position": {
                "x": 0,
                "y": 0,
                "z": 0
            },
            "orientation": {
                "x": 0,
                "y": 0,
                "z": 0
            }
        })
        self.communicate({
            "$type": "scale_object",
            "scale_factor": {
                "x": 30,
                "y": 0.0001,
                "z": 30
            },
            "id": 1
        })
        lib = MaterialLibrarian(library="materials_med.json")
        record = lib.get_record("concrete_chipped_cracked")
        self.communicate({
            "$type": "add_material",
            "name": "concrete_chipped_cracked",
            "url": record.get_url()
        })

        # self.communicate({"$type": "set_visual_material",
        #                   "material_index": 1,
        #                   "material_name": "concrete_chipped_cracked",
        #                   "object_name": "cube",
        #                   "id": 1})
        # Disable physics.
        self.communicate({"$type": "set_gravity", "value": False})

        # Add the avatar.
        self.communicate(
            TDWUtils.create_avatar(position={
                "x": -13,
                "y": 1.5,
                "z": 0
            },
                                   look_at=TDWUtils.array_to_vector3(
                                       [5, 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="spitfire_2012",
                        position={
                            "x": 0,
                            "y": 0,
                            "z": 2
                        },
                        rotation={
                            "x": 0,
                            "y": 90,
                            "z": 0
                        },
                        library="models_full.json")

        self.add_object(model_name="b03_topkicktruck",
                        position={
                            "x": -7,
                            "y": 0,
                            "z": -5
                        },
                        rotation={
                            "x": 0,
                            "y": 0,
                            "z": 0
                        },
                        library="models_full.json")

        self.add_object(model_name="3dscan_man_012",
                        position={
                            "x": -4,
                            "y": 0,
                            "z": 3
                        },
                        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([5, 1.5, 0])
        })

        images = Images(scene_data[0])
        TDWUtils.save_images(
            images,
            "airplane",
            output_directory=
            "/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/exterior"
        )
Beispiel #12
0
    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(TDWUtils.create_empty_room(16, 16))
        # Disable physics.
        self.communicate({"$type": "set_gravity", "value": False})

        # Add the avatar.
        self.communicate(
            TDWUtils.create_avatar(position={
                "x": -7.5,
                "y": 1.5,
                "z": 0
            },
                                   look_at=TDWUtils.array_to_vector3(
                                       [0, 0.7, 0]),
                                   avatar_id="avatar"))

        lib = MaterialLibrarian(library="materials_med.json")
        record = lib.get_record("concrete_asphalt_rolled")
        self.communicate({
            "$type": "add_material",
            "name": "concrete_asphalt_rolled",
            "url": record.get_url()
        })
        self.communicate({
            "$type": "set_proc_gen_floor_material",
            "name": "concrete_asphalt_rolled"
        })
        # self.communicate({"$type": "set_proc_gen_walls_material", "name": "concrete"})

        self.communicate({
            "$type": "set_field_of_view",
            "field_of_view": 68.0,
            "avatar_id": "avatar"
        })

        self.add_object(model_name="b05_2018_chevy_tahoe_rst",
                        position={
                            "x": 3,
                            "y": 0,
                            "z": 0.5
                        },
                        rotation={
                            "x": 0,
                            "y": 90,
                            "z": 0
                        },
                        library="models_full.json")

        self.add_object(model_name="b05_chevrolet_camaro_3ds_max_2010_v-ray",
                        position={
                            "x": -2,
                            "y": 0,
                            "z": -3
                        },
                        rotation={
                            "x": 0,
                            "y": 0,
                            "z": 0
                        },
                        library="models_full.json")

        self.add_object(model_name="b04_harley_davidson_3dsmax2014",
                        position={
                            "x": -4.2,
                            "y": 0,
                            "z": 2
                        },
                        rotation={
                            "x": 0,
                            "y": 0,
                            "z": 0
                        },
                        library="models_full.json")

        self.add_object(model_name="audia7_2018_vray",
                        position={
                            "x": -6.5,
                            "y": 0,
                            "z": -3
                        },
                        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, 0.7, 0])
        })

        images = Images(scene_data[0])
        TDWUtils.save_images(
            images,
            "cars_bikes",
            output_directory=
            "/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/exterior"
        )
Beispiel #13
0
    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(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,
                "z": 0
            },
                                   look_at=TDWUtils.array_to_vector3(
                                       [4, 0.3, -0.3]),
                                   avatar_id="avatar"))

        lib = MaterialLibrarian(library="materials_med.json")
        record = lib.get_record("concrete")
        self.communicate({
            "$type": "add_material",
            "name": "concrete",
            "url": record.get_url()
        })
        self.communicate({
            "$type": "set_proc_gen_floor_material",
            "name": "concrete"
        })
        self.communicate({
            "$type": "set_proc_gen_wall_material",
            "name": "concrete"
        })

        # self.communicate({"$type": "set_field_of_view",
        #                   "field_of_view": 68.0,
        #                   "avatar_id": "avatar"})

        self.add_object(model_name="b05_skateboard",
                        position={
                            "x": 3.2,
                            "y": 0.3,
                            "z": -0.5
                        },
                        rotation={
                            "x": 0,
                            "y": 0,
                            "z": 80
                        },
                        library="models_full.json")

        self.add_object(model_name="skateboard_3",
                        position={
                            "x": 3,
                            "y": 0,
                            "z": 0.6
                        },
                        rotation={
                            "x": 0,
                            "y": 30,
                            "z": 0
                        },
                        library="models_full.json")

        self.add_object(model_name="b03_3wheels",
                        position={
                            "x": 1.8,
                            "y": 0,
                            "z": 0.2
                        },
                        rotation={
                            "x": 0,
                            "y": 30,
                            "z": 0
                        },
                        library="models_full.json")

        self.add_object(model_name="bicycle_001",
                        position={
                            "x": 2.7,
                            "y": 0,
                            "z": -1.1
                        },
                        rotation={
                            "x": 0,
                            "y": 34,
                            "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([4, 0.3, -0.3])
        })

        images = Images(scene_data[0])
        TDWUtils.save_images(
            images,
            "skateboard",
            output_directory=
            "/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/interior"
        )
Beispiel #14
0
class Controller(object):
    """
    Base class for all controllers.

    Usage:

    ```python
    from tdw.controller import Controller
    c = Controller()
    c.start()
    ```
    """
    def __init__(self, port: int = 1071, check_version: bool = True):
        """
        Create the network socket and bind the socket to the port.

        :param port: The port number.
        :param check_version: If true, the controller will check the version of the build and print the result.
        """

        context = zmq.Context()

        self.socket = context.socket(zmq.REP)
        self.socket.bind('tcp://*:' + str(port))

        self.socket.recv()

        self.model_librarian: Optional[ModelLibrarian] = None
        self.scene_librarian: Optional[SceneLibrarian] = None
        self.material_librarian: Optional[MaterialLibrarian] = None
        self.hdri_skybox_librarian: Optional[HDRISkyboxLibrarian] = None
        self.humanoid_librarian: Optional[HumanoidLibrarian] = None
        self.humanoid_animation_librarian: Optional[
            HumanoidAnimationLibrarian] = None

        # Compare the version of the tdw module to the build version.
        if check_version:
            tdw_version, unity_version = self.get_version()
            print(
                f"Build version {tdw_version}\nUnity Engine {unity_version}\nPython tdw module version {__version__}"
            )
            if __version__ != tdw_version:
                print(
                    "WARNING! Your Python code is not the same version as the build. They might not be compatible."
                )
                print(
                    "Either use the latest prerelease build, or use the last stable release via:\n"
                )
                print("git checkout v" + last_stable_release)

    def communicate(self, commands: Union[dict, List[dict]]) -> list:
        """
        Send commands and receive output data in response.

        :param commands: A list of JSON commands.

        :return The output data from the build.
        """

        if not isinstance(commands, list):
            commands = [commands]

        self.socket.send_multipart([json.dumps(commands).encode('utf-8')])

        return self.socket.recv_multipart()

    def start(self, scene="ProcGenScene") -> None:
        """
        Init TDW.

        :param scene: The scene to load.
        """

        self.communicate([{"$type": "load_scene", "scene_name": scene}])

    def get_add_object(self,
                       model_name: str,
                       object_id: int,
                       position={
                           "x": 0,
                           "y": 0,
                           "z": 0
                       },
                       rotation={
                           "x": 0,
                           "y": 0,
                           "z": 0
                       },
                       library: str = "") -> dict:
        """
        Returns a valid add_object command.

        :param model_name: The name of the model.
        :param position: The position of the model.
        :param rotation: The starting rotation of the model, in Euler angles.
        :param library: The path to the records file. If left empty, the default library will be selected. See `ModelLibrarian.get_library_filenames()` and `ModelLibrarian.get_default_library()`.
        :param object_id: The ID of the new object.

        :return An add_object command that the controller can then send.
        """

        if self.model_librarian is None or (
                library != "" and self.model_librarian.library != library):
            self.model_librarian = ModelLibrarian(library=library)

        record = self.model_librarian.get_record(model_name)

        return {
            "$type": "add_object",
            "name": model_name,
            "url": record.get_url(),
            "scale_factor": record.scale_factor,
            "position": position,
            "rotation": rotation,
            "category": record.wcategory,
            "id": object_id
        }

    def get_add_material(self, material_name: str, library: str = "") -> dict:
        """
        Returns a valid add_material command.

        :param material_name: The name of the material.
        :param library: The path to the records file. If left empty, the default library will be selected. See `MaterialLibrarian.get_library_filenames()` and `MaterialLibrarian.get_default_library()`.

        :return An add_material command that the controller can then send.
        """

        if self.material_librarian is None:
            self.material_librarian = MaterialLibrarian(library=library)

        record = self.material_librarian.get_record(material_name)
        return {
            "$type": "add_material",
            "name": material_name,
            "url": record.get_url()
        }

    def get_add_scene(self, scene_name: str, library: str = "") -> dict:
        """
        Returns a valid add_scene command.

        :param scene_name: The name of the scene.
        :param library: The path to the records file. If left empty, the default library will be selected. See `SceneLibrarian.get_library_filenames()` and `SceneLibrarian.get_default_library()`.

        :return An add_scene command that the controller can then send.
        """

        if self.scene_librarian is None:
            self.scene_librarian = SceneLibrarian(library=library)

        record = self.scene_librarian.get_record(scene_name)
        return {
            "$type": "add_scene",
            "name": scene_name,
            "url": record.get_url()
        }

    def get_add_hdri_skybox(self, skybox_name: str, library: str = "") -> dict:
        """
        Returns a valid add_hdri_skybox command.

        :param skybox_name: The name of the skybox.
        :param library: The path to the records file. If left empty, the default library will be selected. See `HDRISkyboxLibrarian.get_library_filenames()` and `HDRISkyboxLibrarian.get_default_library()`.

        :return An add_hdri_skybox command that the controller can then send.
        """

        if self.hdri_skybox_librarian is None:
            self.hdri_skybox_librarian = HDRISkyboxLibrarian(library=library)

        record = self.hdri_skybox_librarian.get_record(skybox_name)
        return {
            "$type": "add_hdri_skybox",
            "name": skybox_name,
            "url": record.get_url(),
            "exposure": record.exposure,
            "initial_skybox_rotation": record.initial_skybox_rotation,
            "sun_elevation": record.sun_elevation,
            "sun_initial_angle": record.sun_initial_angle,
            "sun_intensity": record.sun_intensity
        }

    def get_add_humanoid(self,
                         humanoid_name: str,
                         object_id: int,
                         position={
                             "x": 0,
                             "y": 0,
                             "z": 0
                         },
                         rotation={
                             "x": 0,
                             "y": 0,
                             "z": 0
                         },
                         library: str = "") -> dict:
        """
        Returns a valid add_humanoid command.

        :param humanoid_name: The name of the humanoid.
        :param position: The position of the humanoid.
        :param rotation: The starting rotation of the humanoid, in Euler angles.
        :param library: The path to the records file. If left empty, the default library will be selected. See `HumanoidLibrarian.get_library_filenames()` and `HumanoidLibrarian.get_default_library()`.
        :param object_id: The ID of the new object.

        :return An add_humanoid command that the controller can then send.
        """

        if self.humanoid_librarian is None or (
                library != "" and self.humanoid_librarian.library != library):
            self.humanoid_librarian = HumanoidLibrarian(library=library)

        record = self.humanoid_librarian.get_record(humanoid_name)

        return {
            "$type": "add_humanoid",
            "name": humanoid_name,
            "url": record.get_url(),
            "position": position,
            "rotation": rotation,
            "id": object_id
        }

    def get_add_humanoid_animation(
            self,
            humanoid_animation_name: str,
            library="") -> (dict, HumanoidAnimationRecord):
        """
        Returns a valid add_humanoid_animation command and the record (which you will need to play an animation).

        :param humanoid_animation_name: The name of the animation.
        :param library: The path to the records file. If left empty, the default library will be selected. See `HumanoidAnimationLibrarian.get_library_filenames()` and `HumanoidAnimationLibrarian.get_default_library()`.

        return An add_humanoid_animation command that the controller can then send.
        """

        if self.humanoid_animation_librarian is None:
            self.humanoid_animation_librarian = HumanoidAnimationLibrarian(
                library=library)

        record = self.humanoid_animation_librarian.get_record(
            humanoid_animation_name)
        return {
            "$type": "add_humanoid_animation",
            "name": humanoid_animation_name,
            "url": record.get_url()
        }, record

    def load_streamed_scene(self, scene="tdw_room_2018") -> None:
        """
        Load a streamed scene. This is equivalent to: `c.communicate(c.get_add_scene(scene))`

        :param scene: The name of the streamed scene.
        """

        self.communicate(self.get_add_scene(scene))

    def add_object(self,
                   model_name: str,
                   position={
                       "x": 0,
                       "y": 0,
                       "z": 0
                   },
                   rotation={
                       "x": 0,
                       "y": 0,
                       "z": 0
                   },
                   library: str = "") -> int:
        """
        Add a model to the scene. This is equivalent to: `c.communicate(c.get_add_object())`

        :param model_name: The name of the model.
        :param position: The position of the model.
        :param rotation: The starting rotation of the model, in Euler angles.
        :param library: The path to the records file. If left empty, the default library will be selected. See `ModelLibrarian.get_library_filenames()` and `ModelLibrarian.get_default_library()`.

        :return The ID of the new object.
        """

        object_id = Controller.get_unique_id()
        self.communicate(
            self.get_add_object(model_name, object_id, position, rotation,
                                library))

        return object_id

    def get_version(self) -> Tuple[str, str]:
        """
        Send a send_version command to the build.

        :return The TDW version and the Unity Engine version.
        """

        resp = self.communicate({"$type": "send_version"})
        for r in resp[:-1]:
            if Version.get_data_type_id(r) == "vers":
                v = Version(r)
                return v.get_tdw_version(), v.get_unity_version()
        if len(resp) == 1:
            raise Exception(
                "Tried receiving version output data but didn't receive anything!"
            )
        raise Exception(f"Expected output data with ID vers but got: " +
                        Version.get_data_type_id(resp[0]))

    @staticmethod
    def get_unique_id() -> int:
        """
        Generate a unique integer. Useful when creating objects.

        :return The new unique ID.
        """

        return int.from_bytes(os.urandom(3), byteorder='big')

    @staticmethod
    def get_frame(frame: bytes) -> int:
        """
        Converts the frame byte array to an integer.

        :param frame: The frame as bytes.

        :return The frame as an integer.
        """

        return int.from_bytes(frame, byteorder='big')