Gabungkan dan duplikat jerat sebelum mengekspornya?
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:
- Gandakan kedua objek - langkah yang tersisa berurusan dengan salinan
- Tetapkan
B
sebagai dipilih danA
aktif - Menggunakan
bpy.ops.object.join()
- Ekspor
A
(active_object
) - 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=C
bukannya 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 B
akan 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
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.
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.