Ejemplo n.º 1
0
def send_data_creations(proxies: CreationChangeset):
    if share_data.use_vrtist_protocol():
        return

    codec = Codec()

    for datablock_proxy in proxies:
        logger.info("%s %s", "send_data_create", datablock_proxy)
        send_media_creations(datablock_proxy)
        try:
            encoded_proxy = codec.encode(datablock_proxy)
        except EncodeError as e:
            logger.error(
                f"send_data_create: encode exception for {datablock_proxy}")
            logger.error(f"... {e!r}")
            return
        except Exception:
            logger.error(
                f"send_data_create: encode exception for {datablock_proxy}")
            for line in traceback.format_exc().splitlines():
                logger.error(line)
            return

        buffer = BlenderDataMessage.encode(datablock_proxy, encoded_proxy)
        command = Command(MessageType.BLENDER_DATA_CREATE, buffer, 0)
        share_data.client.add_command(command)
Ejemplo n.º 2
0
    def test_world(self):
        world = bpy.data.worlds[0]
        world.use_nodes = True
        self.assertGreaterEqual(len(world.node_tree.nodes), 2)

        self.diff.diff(self.bpy_data_proxy, safe_context)
        sent_ids = {}
        sent_ids.update({("worlds", world.name): world})

        changeset = self.bpy_data_proxy.update(self.diff, safe_context)
        updates = changeset.creations
        # avoid clash on restore
        world.name = world.name + "_bak"

        codec = Codec()
        for update in updates:
            key = (update.collection_name, update.data("name"))
            sent_id = sent_ids.get(key)
            if sent_id is None:
                continue

            encoded = codec.encode(update)
            # sender side
            #######################
            # receiver side
            decoded = codec.decode(encoded)
            created = self.bpy_data_proxy.update_datablock(decoded)
            self.assertEqual(created, sent_id)
Ejemplo n.º 3
0
def build_data_create(buffer):
    if share_data.use_vrtist_protocol():
        return

    share_data.set_dirty()
    rename_changeset = None
    codec = Codec()
    try:
        message = BlenderDataMessage()
        message.decode(buffer)
        datablock_proxy = codec.decode(message.proxy_string)
        logger.info("%s %s", "build_data_create", datablock_proxy)
        datablock_proxy.arrays = message.arrays
        _, rename_changeset = share_data.bpy_data_proxy.create_datablock(
            datablock_proxy)
        _build_soas(datablock_proxy.mixer_uuid, message.soas)
    except DecodeError as e:
        logger.error(f"Decode error for {str(e.args[1])[:100]} ...")
        logger.error("... possible version mismatch")
        return
    except Exception:
        logger.error("Exception during build_data_create")
        for line in traceback.format_exc().splitlines():
            logger.error(line)
        logger.error(buffer[0:200])
        logger.error("...")
        logger.error(buffer[-200:0])
        logger.error("ignored")
        return

    if rename_changeset:
        send_data_renames(rename_changeset)
Ejemplo n.º 4
0
def build_data_create(buffer):
    if not share_data.use_experimental_sync():
        return

    proxy_string, index = decode_string(buffer, 0)
    codec = Codec()
    rename_changeset = None

    try:
        datablock_proxy: DatablockProxy = codec.decode(proxy_string)
        logger.info("%s: %s", "build_data_create", datablock_proxy)

        # TODO temporary until VRtist protocol uses Blenddata instead of blender_objects & co
        share_data.set_dirty()

        _, rename_changeset = share_data.bpy_data_proxy.create_datablock(
            datablock_proxy)
        _decode_and_build_soas(datablock_proxy.mixer_uuid(), buffer, index)
    except Exception:
        logger.error("Exception during build_data_create")
        for line in traceback.format_exc().splitlines():
            logger.error(line)
        logger.error(buffer[0:200])
        logger.error("...")
        logger.error(buffer[-200:0])
        logger.error("ignored")

    if rename_changeset:
        send_data_renames(rename_changeset)
Ejemplo n.º 5
0
def build_data_update(buffer: bytes):
    if not share_data.use_experimental_sync():
        return

    proxy_string, index = decode_string(buffer, 0)
    codec = Codec()

    try:
        delta: DeltaUpdate = codec.decode(proxy_string)
        logger.info("%s: %s", "build_data_update", delta)
        # TODO temporary until VRtist protocol uses Blenddata instead of blender_objects & co
        share_data.set_dirty()
        share_data.bpy_data_proxy.update_datablock(delta)
        datablock_proxy = delta.value
        if datablock_proxy is not None:
            _decode_and_build_soas(datablock_proxy.mixer_uuid(), buffer, index)
    except Exception:
        logger.error("Exception during build_data_update")
        for line in traceback.format_exc().splitlines():
            logger.error(line)
        logger.error(f"During processing of buffer for {delta}")
        logger.error(buffer[0:200])
        logger.error("...")
        logger.error(buffer[-200:0])
        logger.error("ignored")
Ejemplo n.º 6
0
    def test_world(self):
        # test_end_to_end.TestWorld.test_world
        world = bpy.data.worlds[0]
        world.use_nodes = True
        self.assertGreaterEqual(len(world.node_tree.nodes), 2)

        self.diff.diff(self.bpy_data_proxy, safe_properties)
        sent_ids = {}
        sent_ids.update({("worlds", world.name): world})

        changeset = self.bpy_data_proxy.update(self.diff, {}, False,
                                               safe_properties)
        updates = changeset.creations
        # avoid clash on restore
        world.name = world.name + "_bak"

        codec = Codec()
        for update in updates:
            key = (update.collection_name, update.data("name"))
            sent_id = sent_ids.get(key)
            if sent_id is None:
                continue

            # pretend it is a new one
            update._datablock_uuid += "_new"

            encoded = codec.encode(update)
            # sender side
            #######################
            # receiver side
            decoded = codec.decode(encoded)
            created, _ = self.bpy_data_proxy.create_datablock(decoded)
            self.assertEqual(created, sent_id)
Ejemplo n.º 7
0
def build_data_update(buffer: bytes):
    if share_data.use_vrtist_protocol():
        return

    share_data.set_dirty()
    codec = Codec()
    try:
        message = BlenderDataMessage()
        message.decode(buffer)
        delta: Delta = codec.decode(message.proxy_string)
        logger.debug("%s: %s", "build_data_update", delta)
        delta.value.arrays = message.arrays
        share_data.bpy_data_proxy.update_datablock(delta)

        datablock_proxy = delta.value
        if datablock_proxy is not None:
            _build_soas(datablock_proxy.mixer_uuid, message.soas)

    except DecodeError as e:
        logger.error(
            f"Decode error for {str(e.args[1])[:100]} . Possible causes...")
        logger.error("... user error: version mismatch")
        logger.error(
            "... internal error: Proxy class not registered. Import it in blender_data.__init__.py"
        )
    except Exception:
        logger.error("Exception during build_data_update")
        for line in traceback.format_exc().splitlines():
            logger.error(line)
        logger.error(f"During processing of buffer for {delta}")
        logger.error(buffer[0:200])
        logger.error("...")
        logger.error(buffer[-200:0])
        logger.error("ignored")
Ejemplo n.º 8
0
    def test_non_existing(self):
        world = bpy.data.worlds[0]

        self.diff.diff(self.bpy_data_proxy, safe_context)
        sent_ids = {}
        sent_ids.update({("worlds", world.name): world})

        changeset = self.bpy_data_proxy.update(self.diff, safe_context)
        creations = changeset.creations
        # avoid clash on restore
        world.name = world.name + "_bak"

        codec = Codec()
        for update in creations:
            key = (update.collection_name, update.data("name"))
            sent_id = sent_ids.get(key)
            if sent_id is None:
                continue

            # create a property on the send proxy and test that is does not fail on the receiver
            # property on ID
            update._data["does_not_exist_property"] = ""
            update._data["does_not_exist_struct"] = BpyStructProxy()
            update._data["does_not_exist_ID"] = BpyIDProxy()

            encoded = codec.encode(update)
            # sender side
            #######################
            # receiver side
            decoded = codec.decode(encoded)
            created = self.bpy_data_proxy.update_datablock(decoded)
            self.assertEqual(created, sent_id)
Ejemplo n.º 9
0
def build_data_update(buffer):
    if not share_data.use_experimental_sync():
        return

    buffer, _ = common.decode_string(buffer, 0)
    codec = Codec()
    try:
        id_proxy = codec.decode(buffer)
        try:
            collection_name, key = blenddata_path(id_proxy)
        except InvalidPath:
            logger.error("... update ignored")
            return

        uuid = id_proxy.mixer_uuid()
        logger.info("build_data_update: %s[%s] %s", collection_name, key, uuid)
        share_data.proxy.update_one(id_proxy)
        # TODO temporary until VRtist protocol uses Blenddata instead of blender_objects & co
        share_data.set_dirty()
    except Exception:
        logger.error("Exception during build_data_update")
        log_traceback(logger.error)
        logger.error(
            f"During processing of buffer with blenddata_path {id_proxy._blenddata_path}"
        )
        logger.error(buffer[0:200])
        logger.error("...")
        logger.error(buffer[-200:0])
        logger.error(
            f"Creation or update of bpy.data.{collection_name}[{key}] was ignored"
        )
Ejemplo n.º 10
0
def send_data_updates(updates: List[BpyIDProxy]):
    if not share_data.use_experimental_sync():
        return
    if not updates:
        return
    codec = Codec()
    for proxy in updates:
        # We send an ID, so we need to make sure that it includes a bp.data collection name
        # and the associated key
        try:
            collection_name, key = blenddata_path(proxy)
        except InvalidPath:
            logger.error("... update ignored")
            continue

        logger.info("send_data_update %s[%s]", collection_name, key)

        try:
            encoded_proxy = codec.encode(proxy)
        except InvalidPath:
            logger.error("send_update: Exception :")
            log_traceback(logger.error)
            logger.error(
                f"while processing bpy.data.{collection_name}[{key}]:")

        # For BpyIdProxy, the target is encoded in the proxy._blenddata_path
        buffer = common.encode_string(encoded_proxy)
        command = common.Command(common.MessageType.BLENDER_DATA_UPDATE,
                                 buffer, 0)
        share_data.client.add_command(command)
Ejemplo n.º 11
0
def _build_data_update_or_create(buffer, display_name: str,
                                 func: Callable[[BpyBlendProxy], BpyIDProxy]):
    """
    Process a datablock update request
    """
    def log_exception(when: str):
        logger.error(f"Exception during {display_name}, decode")
        for line in traceback.format_exc().splitlines():
            logger.error(line)
        logger.error(f"During {when}")
        logger.error(buffer[0:200])
        logger.error("...")
        logger.error(buffer[-200:0])
        logger.error("ignored")

    if not share_data.use_experimental_sync():
        return

    buffer, _ = common.decode_string(buffer, 0)
    codec = Codec()

    try:
        id_proxy = codec.decode(buffer)
    except Exception:
        log_exception("decode")

    logger.info("%s: %s", display_name, id_proxy)
    try:
        # TODO temporary until VRtist protocol uses Blenddata instead of blender_objects & co
        share_data.set_dirty()
        return func(share_data.bpy_data_proxy, id_proxy)
    except Exception:
        log_exception(f"processing of buffer for {id_proxy}")
Ejemplo n.º 12
0
def send_data_updates(updates: UpdateChangeset):
    if share_data.use_vrtist_protocol():
        return

    codec = Codec()
    for update in updates:
        logger.debug("%s %s", "send_data_update", update)

        try:
            encoded_update = codec.encode(update)
        except Exception:
            logger.error(f"send_data_update: encode exception for {update}")
            for line in traceback.format_exc().splitlines():
                logger.error(line)
            continue

        buffer = BlenderDataMessage.encode(update.value, encoded_update)
        command = Command(MessageType.BLENDER_DATA_UPDATE, buffer, 0)
        share_data.client.add_command(command)
Ejemplo n.º 13
0
    def test_camera(self):
        # test_codec.TestCodec.test_camera

        # prepare camera
        transmit_name = "transmit_camera"
        cam_sent = D.cameras["Camera_0"]

        cam_sent.dof.focus_object = D.objects["Cube"]

        # load into proxy
        self.proxy.load(test_context)

        # patch the name so that it does not get mixed up as we restore later in the same scene
        cam_proxy_sent = self.proxy.data("cameras").data("Camera_0")
        cam_proxy_sent._data["name"] = transmit_name
        self.assertIsInstance(cam_proxy_sent, BpyIDProxy)

        # encode
        codec = Codec()
        message = codec.encode(cam_proxy_sent)

        #
        # transmit
        #

        # create
        cam_received = D.cameras.new(transmit_name)

        # decode into proxy
        cam_proxy_received = codec.decode(message)

        focus_object_proxy = cam_proxy_received.data("dof").data(
            "focus_object")
        self.assertIsInstance(focus_object_proxy, BpyIDRefProxy)
        self.assertEqual(focus_object_proxy._datablock_uuid,
                         cam_sent.dof.focus_object.mixer_uuid)

        # save into blender
        cam_proxy_received.save(D.cameras, transmit_name,
                                self.proxy.visit_state())
        self.assertEqual(cam_sent, cam_received)
        pass
Ejemplo n.º 14
0
    def test_camera(self):
        # test_codec.TestCodec.test_camera

        # prepare camera
        transmit_name = "transmit_camera"
        cam_sent = D.cameras["Camera_0"]

        cam_sent.dof.focus_object = D.objects["Cube"]

        # load into proxy
        self.proxy.load(test_properties)

        # patch the name so that it does not get mixed up as we restore later in the same scene
        cam_proxy_sent = self.proxy.data("cameras").search_one("Camera_0")
        cam_proxy_sent._data["name"] = transmit_name
        self.assertIsInstance(cam_proxy_sent, DatablockProxy)

        # encode
        codec = Codec()
        message = codec.encode(cam_proxy_sent)

        #
        # transmit
        #

        # decode into proxy
        cam_proxy_received = codec.decode(message)

        focus_object_proxy = cam_proxy_received.data("dof").data(
            "focus_object")
        self.assertIsInstance(focus_object_proxy, DatablockRefProxy)
        self.assertEqual(focus_object_proxy._datablock_uuid,
                         cam_sent.dof.focus_object.mixer_uuid)

        # save into blender
        cam_proxy_received._datablock_uuid = "__" + cam_proxy_received._datablock_uuid
        cam_received, _ = cam_proxy_received.create_standalone_datablock(
            self.proxy.context())

        self.assertEqual(cam_sent, cam_received)
        pass
Ejemplo n.º 15
0
def send_data_updates(updates: UpdateChangeset):
    if not share_data.use_experimental_sync():
        return

    codec = Codec()
    for update in updates:
        logger.info("%s %s", "send_data_update", update)

        try:
            encoded_update = codec.encode(update)
        except Exception:
            logger.error(f"send_data_update: encode exception for {update}")
            for line in traceback.format_exc().splitlines():
                logger.error(line)
            continue

        items: List[bytes] = []
        items.append(encode_string(encoded_update))
        items.extend(soa_buffers(update.value))
        command = Command(MessageType.BLENDER_DATA_UPDATE, b"".join(items), 0)
        share_data.client.add_command(command)
Ejemplo n.º 16
0
def _send_data_create_or_update(proxies: Union[CreationChangeset,
                                               UpdateChangeset],
                                display_name: str,
                                message: common.MessageType):
    if not share_data.use_experimental_sync():
        return

    codec = Codec()
    for proxy in proxies:
        logger.info("%s %s", display_name, proxy)

        try:
            encoded_proxy = codec.encode(proxy)
        except Exception:
            logger.error(f"{display_name}: encode exception for {proxy}")
            for line in traceback.format_exc().splitlines():
                logger.error(line)
            continue

        buffer = common.encode_string(encoded_proxy)
        command = common.Command(message, buffer, 0)
        share_data.client.add_command(command)
Ejemplo n.º 17
0
def send_data_creations(proxies: CreationChangeset):
    if not share_data.use_experimental_sync():
        return

    codec = Codec()
    for datablock_proxy in proxies:
        logger.info("%s %s", "send_data_create", datablock_proxy)

        try:
            encoded_proxy = codec.encode(datablock_proxy)
        except Exception:
            logger.error(
                f"send_data_create: encode exception for {datablock_proxy}")
            for line in traceback.format_exc().splitlines():
                logger.error(line)
            continue

        send_media_creations(datablock_proxy)
        # creation so that it is available at bpy_data_ctor() time
        items: List[bytes] = []
        items.append(encode_string(encoded_proxy))
        items.extend(soa_buffers(datablock_proxy))
        command = Command(MessageType.BLENDER_DATA_CREATE, b"".join(items), 0)
        share_data.client.add_command(command)