コード例 #1
0
ファイル: collection.py プロジェクト: UPBGE/blender-addons
def build_collection_to_collection(data):
    parent_name, index = common.decode_string(data, 0)
    child_name, _ = common.decode_string(data, index)

    # This message is not emitted by VRtist, only by Blender, so it is used only for Blender/Blender sync.
    # In generic mode, it conflicts with generic messages, so drop it
    if not share_data.use_vrtist_protocol():
        logger.warning(
            "build_collection_to_collection %s <- %s, ignore in generic mode",
            parent_name, child_name)
        return

    logger.info("build_collection_to_collection %s <- %s", parent_name,
                child_name)
    parent = share_data.blender_collections[parent_name]

    child = share_data.blender_collections[child_name]

    try:
        parent.children.link(child)
    except RuntimeError as e:
        if not share_data.use_vrtist_protocol():
            # Added by the Blender Protocol
            logger.info(
                f"build_collection_to_collection(): parent {parent_name}, child {child_name}..."
            )
            logger.info("... Exception during parent.children.link() ...")
            logger.info("... Safe in generic mode ...")
            logger.info(f"... {e!r}")
        else:
            logger.warning(
                f"build_collection_to_collection(): parent {parent_name}, child {child_name}..."
            )
            logger.warning("... Exception during parent.children.link() ...")
            logger.warning(f"... {e!r}")
コード例 #2
0
ファイル: data.py プロジェクト: nondejus/mixer
def build_data_create(buffer):
    if share_data.use_vrtist_protocol():
        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 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)
コード例 #3
0
ファイル: data.py プロジェクト: pypingyi/mixer
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")
コード例 #4
0
ファイル: data.py プロジェクト: pypingyi/mixer
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)
コード例 #5
0
ファイル: data.py プロジェクト: nondejus/mixer
def build_data_update(buffer: bytes):
    if share_data.use_vrtist_protocol():
        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 DecodeError as e:
        logger.error(f"Decode error for {str(e.args[1])[:100]} ...")
        logger.error("... possible version mismatch")
    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")
コード例 #6
0
ファイル: collection.py プロジェクト: UPBGE/blender-addons
def build_collection(data):
    name_full, index = common.decode_string(data, 0)

    # This message is not emitted by VRtist, only by Blender, so it is used only for Blender/Blender sync.
    # In generic mode, it conflicts with generic messages, so drop it
    if not share_data.use_vrtist_protocol():
        logger.warning("build_collection %s, ignored in generic mode",
                       name_full)
        return

    # Blender/Blender in VRtist (non generic) mode
    visible, index = common.decode_bool(data, index)
    hide_viewport = not visible
    offset, index = common.decode_vector3(data, index)
    temporary_visibility, index = common.decode_bool(data, index)

    logger.info("build_collection %s", name_full)
    collection = share_data.blender_collections.get(name_full)
    if collection is None:
        collection = bpy.data.collections.new(name_full)
        share_data.blender_collections[name_full] = collection

    collection.hide_viewport = hide_viewport
    collection.instance_offset = offset

    layer_collection = share_data.blender_layer_collections.get(name_full)
    if layer_collection:
        layer_collection.hide_viewport = not temporary_visibility
    else:
        # if the layer collection does not exists, store its state for later
        share_data.blender_collection_temporary_visibility[
            name_full] = temporary_visibility
コード例 #7
0
ファイル: collection.py プロジェクト: UPBGE/blender-addons
def build_remove_object_from_collection(data):
    collection_name, index = common.decode_string(data, 0)
    object_name, _ = common.decode_string(data, index)

    # This message is not emitted by VRtist, only by Blender, so it is used only for Blender/Blender sync.
    # In generic mode, it conflicts with generic messages, so drop it
    if not share_data.use_vrtist_protocol():
        logger.warning(
            "build_remove_object_from_collection %s <- %s, ignore in generic mode",
            collection_name, object_name)
        return

    logger.info("build_remove_object_from_collection %s <- %s",
                collection_name, object_name)

    collection = share_data.blender_collections[collection_name]
    object_ = share_data.blender_objects.get(object_name)
    if object_:
        # otherwise already removed by Blender protocol
        try:
            collection.objects.unlink(object_)
        except Exception as e:
            logger.info(
                "build_remove_object_from_collection: exception during unlink... "
            )
            logger.info(f"... {e!r} ")
コード例 #8
0
ファイル: handlers.py プロジェクト: pypingyi/mixer
def handler_send_scene_data_to_server(scene, dummy):
    global processing_depsgraph_handler
    if processing_depsgraph_handler:
        logger.error("Depsgraph handler recursion attempt")
        return

    processing_depsgraph_handler = True
    try:
        logger.debug("handler_send_scene_data_to_server")

        # Ensure we will rebuild accessors when a depsgraph update happens
        # todo investigate why we need this...
        share_data.set_dirty()

        if share_data.client.block_signals:
            logger.debug(
                "handler_send_scene_data_to_server canceled (block_signals = True)"
            )
            return

        if share_data.use_vrtist_protocol():
            send_scene_data_to_server(scene, dummy)
        else:
            generic.send_scene_data_to_server(scene, dummy)
    finally:
        processing_depsgraph_handler = False
コード例 #9
0
ファイル: data.py プロジェクト: pypingyi/mixer
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)
コード例 #10
0
ファイル: data.py プロジェクト: nondejus/mixer
def send_data_removals(removals: RemovalChangeset):
    if share_data.use_vrtist_protocol():
        return

    for uuid, _, debug_info in removals:
        logger.info("send_removal: %s (%s)", uuid, debug_info)
        buffer = encode_string(uuid) + encode_string(debug_info)
        command = Command(MessageType.BLENDER_DATA_REMOVE, buffer, 0)
        share_data.client.add_command(command)
コード例 #11
0
ファイル: scene.py プロジェクト: UPBGE/blender-addons
def build_collection_to_scene(data):
    scene_name, index = common.decode_string(data, 0)
    collection_name, _ = common.decode_string(data, index)

    # This message is not emitted by VRtist, only by Blender, so it is used only for Blender/Blender sync.
    # In generic mode, it conflicts with generic messages, so drop it
    if not share_data.use_vrtist_protocol():
        logger.warning("build_collection_to_scene %s <- %s", scene_name,
                       collection_name)
        return

    logger.info("build_collection_to_scene %s <- %s", scene_name,
                collection_name)

    try:
        scene = share_data.blender_scenes[scene_name]
    except KeyError:
        if not share_data.use_vrtist_protocol():
            # Removed by the Blender Protocol
            logger.info(
                f"build_collection_to_scene(): scene not found {scene_name}. Safe in generic mode ..."
            )
            return
        else:
            raise

    collection = share_data.blender_collections[collection_name]
    try:
        scene.collection.children.link(collection)
    except RuntimeError as e:
        if not share_data.use_vrtist_protocol():
            # Added by the Blender Protocol
            logger.info(
                f"build_collection_to_scene(): scene {scene_name}, collection {collection_name}..."
            )
            logger.info(
                "... Exception during scene.collection.children.link() ...")
            logger.info("... Safe in generic mode ...")
            logger.info(f"... {e!r}")
        else:
            raise
    share_data.update_collection_temporary_visibility(collection_name)
コード例 #12
0
ファイル: data.py プロジェクト: pypingyi/mixer
def build_data_remove(buffer):
    if share_data.use_vrtist_protocol():
        return

    message = BlenderRemoveMessage()
    message.decode(buffer)
    logger.info("build_data_remove: %s (%s)", message.uuid, message.debug_info)
    share_data.bpy_data_proxy.remove_datablock(message.uuid)

    # TODO temporary until VRtist protocol uses Blenddata instead of blender_objects & co
    share_data.set_dirty()
コード例 #13
0
ファイル: data.py プロジェクト: nondejus/mixer
def build_data_remove(buffer):
    if share_data.use_vrtist_protocol():
        return

    uuid, index = decode_string(buffer, 0)
    debug_info, index = decode_string(buffer, index)
    logger.info("build_data_remove: %s (%s)", uuid, debug_info)
    share_data.bpy_data_proxy.remove_datablock(uuid)

    # TODO temporary until VRtist protocol uses Blenddata instead of blender_objects & co
    share_data.set_dirty()
コード例 #14
0
ファイル: data.py プロジェクト: nondejus/mixer
def send_data_renames(renames: RenameChangeset):
    if not renames:
        return
    if share_data.use_vrtist_protocol():
        return

    items = []
    for uuid, old_name, new_name, debug_info in renames:
        logger.info("send_rename: %s (%s) into %s", uuid, debug_info, new_name)
        items.extend([uuid, old_name, new_name])

    buffer = encode_string_array(items)
    command = Command(MessageType.BLENDER_DATA_RENAME, buffer, 0)
    share_data.client.add_command(command)
コード例 #15
0
def build_scene_renamed(data):
    # TODO check if obsolete

    old_name, index = common.decode_string(data, 0)
    new_name, _ = common.decode_string(data, index)

    # This message is not emitted by VRtist, only by Blender, so it is used only for Blender/Blender sync.
    # In generic mode, it conflicts with generic messages, so drop it
    if not share_data.use_vrtist_protocol():
        logger.warning("build_scene_renamed  %s to %s", old_name, new_name)
        return

    logger.info("build_scene_renamed %s to %s", old_name, new_name)
    scene = share_data.blender_scenes.get(old_name)
    scene.name = new_name
    share_data.blender_scenes_dirty = True
コード例 #16
0
ファイル: collection.py プロジェクト: UPBGE/blender-addons
def build_remove_collection_from_collection(data):
    parent_name, index = common.decode_string(data, 0)
    child_name, _ = common.decode_string(data, index)

    # This message is not emitted by VRtist, only by Blender, so it is used only for Blender/Blender sync.
    # In generic mode, it conflicts with generic messages, so drop it
    if not share_data.use_vrtist_protocol():
        logger.warning(
            "build_remove_collection_from_collection %s <- %s, ignore in generic mode",
            parent_name, child_name)
        return

    logger.info("build_remove_collection_from_collection %s <- %s",
                parent_name, child_name)

    parent = share_data.blender_collections[parent_name]
    child = share_data.blender_collections[child_name]
    parent.children.unlink(child)
コード例 #17
0
ファイル: data.py プロジェクト: pypingyi/mixer
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)
コード例 #18
0
ファイル: data.py プロジェクト: nondejus/mixer
def send_data_updates(updates: UpdateChangeset):
    if share_data.use_vrtist_protocol():
        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)
コード例 #19
0
ファイル: collection.py プロジェクト: UPBGE/blender-addons
def build_add_object_to_collection(data):
    collection_name, index = common.decode_string(data, 0)
    object_name, _ = common.decode_string(data, index)

    # This message is not emitted by VRtist, only by Blender, so it is used only for Blender/Blender sync.
    # In generic mode, it conflicts with generic messages, so drop it
    if not share_data.use_vrtist_protocol():
        logger.warning(
            "build_add_object_to_collection %s <- %s, ignore in generic mode",
            collection_name, object_name)
        return
    logger.info("build_add_object_to_collection %s <- %s", collection_name,
                object_name)

    collection = share_data.blender_collections[collection_name]

    # We may have received an object creation message before this collection link message
    # and object creation will have created and linked the collection if needed
    if collection.objects.get(object_name) is None:
        object_ = share_data.blender_objects[object_name]
        collection.objects.link(object_)
コード例 #20
0
ファイル: scene.py プロジェクト: UPBGE/blender-addons
def build_add_object_to_scene(data):
    scene_name, index = common.decode_string(data, 0)
    object_name, _ = common.decode_string(data, index)
    logger.info("build_add_object_to_scene %s <- %s", scene_name, object_name)

    try:
        scene = share_data.blender_scenes[scene_name]
    except KeyError:
        if not share_data.use_vrtist_protocol():
            # Removed by the Blender Protocol
            logger.info(
                f"build_collection_to_scene(): scene not found {scene_name}. Safe in generic mode ..."
            )
            return
        else:
            raise

    # We may have received an object creation message before this collection link message
    # and object creation will have created and linked the collecetion if needed
    if scene.collection.objects.get(object_name) is None:
        object_ = share_data.blender_objects[object_name]
        scene.collection.objects.link(object_)
コード例 #21
0
ファイル: data.py プロジェクト: nondejus/mixer
def build_data_rename(buffer):
    if share_data.use_vrtist_protocol():
        return

    strings, _ = decode_string_array(buffer, 0)

    # (uuid1, old1, new1, uuid2, old2, new2, ...) to ((uuid1, old1, new1), (uuid2, old2, new2), ...)
    args = [iter(strings)] * 3
    # do not consume the iterator on the log loop !
    items = list(itertools.zip_longest(*args))

    for uuid, old_name, new_name in items:
        logger.info("build_data_rename: %s (%s) into %s", uuid, old_name,
                    new_name)

    rename_changeset = share_data.bpy_data_proxy.rename_datablocks(items)

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

    if rename_changeset:
        send_data_renames(rename_changeset)
コード例 #22
0
ファイル: collection.py プロジェクト: UPBGE/blender-addons
def build_collection_instance(data):
    instance_name, index = common.decode_string(data, 0)
    instantiated_name, _ = common.decode_string(data, index)

    # This message is not emitted by VRtist, only by Blender, so it is used only for Blender/Blender sync.
    # In generic mode, it conflicts with generic messages, so drop it
    if not share_data.use_vrtist_protocol():
        logger.warning(
            "build_collection_instance %s <- %s, ignore in generic mode",
            instantiated_name, instance_name)
        return

    logger.info("build_collection_instance %s from %s", instantiated_name,
                instance_name)

    instantiated = share_data.blender_collections[instantiated_name]

    instance = bpy.data.objects.new(name=instance_name, object_data=None)
    instance.instance_collection = instantiated
    instance.instance_type = "COLLECTION"

    share_data.blender_objects[instance_name] = instance
コード例 #23
0
ファイル: collection.py プロジェクト: UPBGE/blender-addons
def build_collection_removed(data):
    name_full, index = common.decode_string(data, 0)

    # This message is not emitted by VRtist, only by Blender, so it is used only for Blender/Blender sync.
    # In generic mode, it conflicts with generic messages, so drop it
    if not share_data.use_vrtist_protocol():
        logger.warning("build_collection_remove %s, ignore in generic mode",
                       name_full)
        return

    # Blender/Blender in VRtist (non generic) mode
    logger.info("build_collectionRemove %s", name_full)
    collection = share_data.blender_collections.get(name_full)
    if collection:
        # otherwise already removed by Blender protocol
        try:
            del share_data.blender_collections[name_full]
            bpy.data.collections.remove(collection)
        except Exception as e:
            logger.info(
                "build_remove_collection_from_scene: exception during unlink... "
            )
            logger.info(f"... {e!r} ")
コード例 #24
0
ファイル: scene.py プロジェクト: UPBGE/blender-addons
def build_remove_collection_from_scene(data):
    scene_name, index = common.decode_string(data, 0)
    collection_name, _ = common.decode_string(data, index)

    # This message is not emitted by VRtist, only by Blender, so it is used only for Blender/Blender sync.
    # In generic mode, it conflicts with generic messages, so drop it
    if not share_data.use_vrtist_protocol():
        logger.warning("build_remove_collection_from_scene  %s <- %s",
                       scene_name, collection_name)
        return

    logger.info("build_remove_collection_from_scene %s <- %s", scene_name,
                collection_name)
    scene = share_data.blender_scenes[scene_name]
    collection = share_data.blender_collections.get(collection_name)
    if collection:
        # otherwise already removed by Blender protocol
        try:
            scene.collection.children.unlink(collection)
        except Exception as e:
            logger.info(
                "build_remove_collection_from_scene: exception during unlink... "
            )
            logger.info(f"... {e!r} ")
コード例 #25
0
ファイル: data.py プロジェクト: nondejus/mixer
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)

        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)
コード例 #26
0
ファイル: handlers.py プロジェクト: pypingyi/mixer
def handler_on_undo_redo_post(scene, dummy):
    logger.error(f"Undo/redo post on {scene}")
    share_data.client.send_error(
        f"Undo/redo post from {get_mixer_prefs().user}")

    if not share_data.use_vrtist_protocol():
        # Generic sync: reload all datablocks
        undone = share_data.bpy_data_proxy.snapshot_undo_post()
        logger.warning(f"undone uuids : {undone}")
        share_data.bpy_data_proxy.reload_datablocks()
    else:
        share_data.set_dirty()
        share_data.clear_lists()
        # apply only in object mode
        if not is_in_object_mode():
            return

        old_objects_name = dict([
            (k, None) for k in share_data.old_objects.keys()
        ])  # value not needed
        remap_objects_info()
        for k, v in share_data.old_objects.items():
            if k in old_objects_name:
                old_objects_name[k] = v

        update_object_state(old_objects_name, share_data.old_objects)

        update_collections_state()
        update_scenes_state()

        remove_objects_from_scenes()
        remove_objects_from_collections()
        remove_collections_from_scenes()
        remove_collections_from_collections()

        remove_collections()
        add_scenes()
        add_objects()
        add_collections()

        add_collections_to_scenes()
        add_collections_to_collections()

        add_objects_to_collections()
        add_objects_to_scenes()

        update_collections_parameters()
        create_vrtist_objects()
        delete_scene_objects()
        rename_objects()
        update_objects_visibility()
        update_objects_constraints()
        update_objects_transforms()
        reparent_objects()

        # send selection content (including data)
        materials = set()
        for obj in bpy.context.selected_objects:
            update_transform(obj)
            if hasattr(obj, "data"):
                update_params(obj)
            if hasattr(obj, "material_slots"):
                for slot in obj.material_slots[:]:
                    materials.add(slot.material)

        for material in materials:
            share_data.client.send_material(material)

        share_data.update_current_data()
コード例 #27
0
ファイル: handlers.py プロジェクト: pypingyi/mixer
def handler_on_undo_redo_pre(scene):
    if share_data.use_vrtist_protocol():
        send_scene_data_to_server(scene, None)
    else:
        share_data.bpy_data_proxy.snapshot_undo_pre()