Gabungkan dan duplikat jerat sebelum mengekspornya?

Sep 05 2019

Saya sedang menulis add-on yang mengekspor objek ke format file FBX.

Salah satu fiturnya adalah kemampuan untuk menggabungkan objek lain untuk diekspor. Jadi pengguna memilih objek A, klik tombol "pilih objek gabungan", lalu klik objek B. Selama ekspor, objek digabungkan sesuai operasi tipe Ctrl+ J, diekspor sebagai objek tunggal, lalu semuanya dikembalikan ke normal (kembali ke 2 objek).

Ini ide saya:

  1. Gandakan kedua objek - langkah yang tersisa berurusan dengan salinan
  2. Tetapkan Bsebagai dipilih dan Aaktif
  3. Menggunakan bpy.ops.object.join()
  4. Ekspor A( active_object)
  5. Menghapus A

Saya punya beberapa pertanyaan tentang ini jika ada yang tahu sesuatu tentang itu ..

X . Apakah ada alternatif untuk menghindari kebutuhan membuat temporer dan menghapusnya sesudahnya? Objek bisa berupa kerumitan apa pun yang bisa dibayangkan, jadi cara apa pun untuk menggunakan input sebagai hanya-baca akan lebih baik. Beberapa merger alternatif? A+B=Cbukannya A+=delete(B)?

Sunting: Saya kemudian menemukan bahwa Anda dapat menduplikasi objek sebagai tautan (yang tidak menyalin data mesh), kemudian menggunakan duplikat tertaut itu sebagai objek input untuk join (). Ini sangat mirip dengan tidak perlu membuat temporaries karena data mesh tidak pernah diduplikasi.

Y. Dalam skenario penggunaan di atas join(), apakah salinan sementara Bakan dihapus secara otomatis? Tidak yakin bagaimana cara join()kerjanya di bawah tenda. Dan sedikit khawatir tentang mengotak-atik referensi objek yang dihapus dalam kode.

Edit: Ya, semua objek input kecuali yang aktif dihapus oleh join ().

Saya sangat menghargai saran apapun. Saya sangat baru dalam pengembangan python dan add-on, jadi detailnya juga dihargai.

Jawaban

2 brockmann Sep 06 2019 at 08:58

Kedengarannya seperti pekerjaan untuk teman lama kita yang baik: Urungkan . Anda dapat membuatnya rumit pasti , tetapi karena operasinya ada dalam memori, itu akan membuatnya cukup cepat.

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')

Operator didasarkan pada Templates> Python> Operator File Export


Pendekatan lain yang cukup membosankan adalah menyimpan file sebelum mengekspor ke fbx dan kemudian memuat ulang campurannya:

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'} 

Mungkin menyenangkan melakukan beberapa tes untuk mengukur waktu eksekusi keduanya ... dalam memori.

GabrielRohweder Sep 05 2019 at 21:09

Saya tidak melihat kebutuhan untuk menggabungkan objek sama sekali di dalam Blender. Sejak Anda? menulis kode ekspor fbx, cukup gabungkan data segitiga / tekstur / animasi untuk kedua mesh tersebut dan tuliskan ke format fbx sebagai objek tunggal.