メッシュをエクスポートする前に結合して複製しますか?

Sep 05 2019

オブジェクトをFBXファイル形式にエクスポートするアドオンを作成しています。

その機能の1つは、エクスポートのために別のオブジェクトをマージする機能です。したがって、ユーザーはオブジェクトをA選択し、[オブジェクトのマージを選択]ボタンをクリックしてから、オブジェクトをクリックしますB。エクスポート中、オブジェクトはCtrl+Jタイプの操作に従って結合され、単一のオブジェクトとしてエクスポートされ、その後すべてが通常に復元されます(2つのオブジェクトに戻ります)。

これは私の考えです:

  1. 両方のオブジェクトを複製します-残りの手順はコピーを処理します
  2. B選択済みおよびAアクティブとして設定
  3. 使用する bpy.ops.object.join()
  4. エクスポートAactive_object
  5. 削除 A

誰かがそれについて何か知っているかもしれないなら、私はこれに関していくつか質問があります。

X。一時的なものを作成して後で削除する必要性を回避するための代替手段はありますか?オブジェクトは考えられるあらゆる複雑さである可能性があるため、入力を読み取り専用として使用する方法が適しています。いくつかの代替合併??のA+B=C代わりにA+=delete(B)

編集:後で、オブジェクトをリンク(メッシュデータをコピーしない)として複製し、そのリンクされた複製をjoin()の入力オブジェクトとして使用できることを発見しました。これは、メッシュデータが複製されないため、一時的なデータを作成する必要がないことと非常によく似ています。

Y.を使用した上記のシナリオjoin()では、の一時コピーはB自動的に削除されますか?内部でどのようにjoin()機能するかわからない。そして、コード内の削除されたオブジェクト参照をいじり回すことについて少し心配しました。

編集:はい、アクティブなものを除くすべての入力オブジェクトは、join()によって削除されます。

アドバイスをいただければ幸いです。私はPythonとアドオンの開発に非常に慣れていないので、詳細も高く評価されています。

回答

2 brockmann Sep 06 2019 at 08:58

古き良き友人の仕事のように聞こえます:元に戻す。確かに複雑にすることもできますが、とにかく操作はメモリ内にあるので、かなり高速になるはずです。

import bpy

from bpy.props import (BoolProperty, FloatProperty, StringProperty)
from bpy.types import (Operator)
from bpy_extras.io_utils import ExportHelper

# ExportHelper is a helper class, defines filename and
# invoke() function which calls the file selector.
class EXPORT_OT_customFBX(Operator, ExportHelper):
    """Export the scene to FBX"""
    bl_idname = "export_scene.custom_fbx"
    bl_label = "Export FBX"

    # ExportHelper mixin class uses this
    filename_ext = ".fbx"

    filter_glob: StringProperty(
        default="*.fbx",
        options={'HIDDEN'},
        maxlen=255,  # Max internal buffer length, longer would be clamped.
    )

    # List of operator properties, the attributes will be assigned
    # to the class instance from the operator settings before calling.
    global_scale: FloatProperty(
        name="Scale",
        description="Scale",
        default=1.0,
    )

    use_subsurf: BoolProperty(
        name="Use Subsurf",
        description="Use Subsurf",
        default=False,
    )

    apply_unit_scale: BoolProperty(
        name="Apply Unit Scale",
        description="Use Subsurf",
        default=True,
    )

    def execute(self, context):

        viewport_selection = [o for o in context.selected_objects if o.type == 'MESH']

        if len(viewport_selection) == 2:
            if context.active_object in viewport_selection:
                # Join! 
                # https://blender.stackexchange.com/q/13986
                # https://blender.stackexchange.com/q/50160
                bpy.ops.object.join()
            else:
                print ("Can not call join operator")
        else:
            print ("Nothing to join.")

        # Export
        bpy.ops.export_scene.fbx(
                filepath=self.filepath,
                global_scale=self.global_scale, 
                apply_unit_scale=self.apply_unit_scale, 
                use_subsurf=self.use_subsurf,
                use_metadata=True, 
                axis_forward='-Z', 
                axis_up='Y'
            )

        # Undo!
        bpy.ops.ed.undo()
        return {'FINISHED'} 

# Only needed if you want to add into a dynamic menu
def draw_export_fbx(self, context):
    self.layout.operator(EXPORT_OT_customFBX.bl_idname, text="Custom FBX (.fbx)", icon="MESH_MONKEY")


# Registration
classes = (
    EXPORT_OT_customFBX,
)

def register():
    from bpy.utils import register_class
    for cls in classes:
        register_class(cls)

    bpy.types.TOPBAR_MT_file_export.prepend(draw_export_fbx)


def unregister():
    from bpy.utils import unregister_class
    for cls in reversed(classes):
        unregister_class(cls)

    bpy.types.TOPBAR_MT_file_export.remove(draw_export_fbx)


if __name__ == "__main__":
    register()

    # test call
    bpy.ops.export_scene.custom_fbx('INVOKE_DEFAULT')

演算子はテンプレート> Python>演算子ファイルのエクスポートに基づいています


もう1つの非常に退屈なアプローチは、fbxにエクスポートする前にファイルを保存してから、ブレンドをリロードすることです。

def execute(self, context):

    # Save!
    if bpy.data.is_dirty:
        bpy.ops.wm.save_as_mainfile(filepath=bpy.data.filepath)

    viewport_selection = [o for o in context.selected_objects if o.type == 'MESH']

    if len(viewport_selection) == 2:
        if context.active_object in viewport_selection:
            # Join! # https://blender.stackexchange.com/q/13986
            bpy.ops.object.join()
        else:
            print ("Can not call join operator")
    else:
        print ("Nothing to join.")

    # Export
    bpy.ops.export_scene.fbx(
            filepath=self.filepath,
            global_scale=self.global_scale, 
            apply_unit_scale=self.apply_unit_scale, 
            use_subsurf=self.use_subsurf,
            use_metadata=True, 
            axis_forward='-Z', 
            axis_up='Y'
        )

    # Reload
    bpy.ops.wm.open_mainfile(filepath=bpy.data.filepath)
    return {'FINISHED'} 

メモリ内の両方の実行時間を測定するためにいくつかのテストを行うのは良いことかもしれません。

GabrielRohweder Sep 05 2019 at 21:09

Blender内でオブジェクトを結合する必要はまったくないと思います。あなたがいるので?fbxエクスポートコードを作成するには、2つのメッシュの三角形/テクスチャ/アニメーションデータを自分でマージし、単一のオブジェクトとしてfbx形式で書き出します。