รหัสสำหรับ“ แยกและเลือกในโหมดวัตถุ”

Aug 18 2020

ดังนั้นฉันกำลังสร้างมาโครโดยไม่ต้องแยกการเลือกในโหมดตัวแก้ไขจากนั้นเลือกตาข่ายที่แยกจากกันในโหมดวัตถุ ... ฉันมีความรู้น้อยมากเกี่ยวกับสิ่งที่ฉันกำลังทำ แต่ฉันทำมันไม่เคยน้อยลง ..

ดังนั้นฉันต้องการความช่วยเหลือ รหัสจะใช้ในการเลือกตาข่ายที่คั่นสุดท้ายหลังจากออกจากโหมดวัตถุคืออะไร? ขออภัยหากสิ่งนี้ไม่สมเหตุสมผล ฉันหวังว่าเครื่องปั่นจะเลือกตาข่ายที่แยกในโหมดวัตถุทันทีหลังจากที่คุณแยกมัน ฉันไม่รู้ว่าจะหาตาข่ายที่แยกออกมาได้อย่างไร

ฉันจะทำอย่างไรจึงจะใช้ได้ทุกครั้งกับวัตถุใด ๆ ขอบคุณ

คำตอบ

2 HikariTW Aug 18 2020 at 15:07

วิธีแก้ปัญหาคือเก็บชื่อออบเจ็กต์ที่คุณเลือกไว้ก่อนจากนั้นจึงยกเลิกการเลือกหลังจากที่คุณแยกเมช

สิ่งนี้:

org_obj_list = {obj.name for obj in context.selected_objects}
# This is a Set comprehension in Python,
# which create a set of name from the context.selected_objects
# context.selected_objects will be a Iterable collection of some object

bpy.ops.mesh.separate(type = 'SELECTED')
# This will call the separate operator in your code directly
# the type can be a enum string in ['SELECTED', 'LOOSE', 'MATERIAL']

bpy.ops.object.editmode_toggle()
# Switch back to object mode from edit mode

# Those separated object will also be selected now
# We then check if selected object is the one we saved before, then deselect it.
for obj in context.selected_objects:
    if obj and obj.name in org_obj_list:
        # Deselect selected object
        obj.select_set(False)
    else:
        # Set the new created object to active
        context.view_layer.objects.active = obj

ไม่แน่ใจว่านี่เป็นแนวทางปฏิบัติที่ดีที่สุด แต่ได้ผล


ตัวดำเนินการที่กำหนดเอง:

import bpy

class SeparateSelectionActive(bpy.types.Operator):
    """Separate object by selection and set it as active object."""
    bl_idname = "mesh.select_separate_active"
    bl_label = "Separate Selection Active"
    
    # An enum for prompt dialog
    separate_method: bpy.props.EnumProperty(
        items = {
            ('SELECTED', 'Selected', "Selected mesh"),
            ('MATERIAL', 'Material', "Based on material"),
            ('LOOSE', 'Loose', "Based on loose part")
        },
        name = "Separate Method",
        description = "Choose a method to separate mesh",
        default = 'SELECTED'
    )
    
    @classmethod
    def poll(cls, context):
        return context.object is not None and context.mode == 'EDIT_MESH'
    
    def invoke(self, context, event):
        # Prompt to ask a method to separate
        return context.window_manager.invoke_props_dialog(self)

    def execute(self, context):
        org_obj_list = {o.name for o in context.selected_objects}
        
        # Separate using selected method
        bpy.ops.mesh.separate(type = self.separate_method)
        bpy.ops.object.editmode_toggle()
        for obj in context.selected_objects:
            if obj and obj.name in org_obj_list:
                # Deselect everything selected before
                obj.select_set(False)
            else:
                # Set the new created object to active
                context.view_layer.objects.active = obj
                self.report({'INFO'},f"Set active object to: {obj.name}")
        return {'FINISHED'}

# A menu inject into View3D > Edit > Mesh tab
def _menu_func(self, context):
    self.layout.operator(SeparateSelectionActive.bl_idname)

def register():
    bpy.utils.register_class(SeparateSelectionActive)
    bpy.types.VIEW3D_MT_edit_mesh.append(_menu_func)

def unregister():
    bpy.utils.unregister_class(SeparateSelectionActive)
    bpy.types.VIEW3D_MT_edit_mesh.remove(_menu_func)

if __name__ == "__main__":
    register()

    # test call
    bpy.ops.mesh.select_separate_active()

หลังจากลงทะเบียนเป็นตัวดำเนินการคุณสามารถค้นหาและเรียกใช้ตัวดำเนินการนี้ในโหมดแก้ไขภายในช่องว่าง 3 มิติ:

หรือในView3d> โหมดแก้ไข> mesh> Separate Selection Activeหลังจากผนวกฟังก์ชันเมนูใหม่เพื่อให้สามารถค้นหาได้ใน Blender 2.90

คุณควรเห็นข้อความแจ้งถามวิธีการแยก:

ตัวเลือกเหล่านี้เหมือนกันทุกประการกับตัวดำเนินการแยกต่างหาก

และตัวดำเนินการนี้จะแยกมันยกเลิกการเลือกตาข่ายเดิมทำให้ตาข่ายที่สร้างขึ้นใหม่ใช้งานได้:

หมายเหตุ: หากกระบวนการแยกต่างหากทำให้กระบวนการที่คุณต้องการใช้งานไม่เปลี่ยนแปลงตัวดำเนินการนี้จะใช้งานเมชที่ไม่ถูกต้องเนื่องจากยังคงเป็นเมชเดิมที่มีชื่อเดียวกัน