[Bf-extensions-cvs] [d3443dc5] master: Bool Tool: Auto Slice handle multiple objects and improve UX

Mikhail Rachinskiy noreply at git.blender.org
Tue Sep 17 11:54:01 CEST 2019


Commit: d3443dc5fc9896bc0d04c2cc4a57a38e23cc08e7
Author: Mikhail Rachinskiy
Date:   Tue Sep 17 13:53:46 2019 +0400
Branches: master
https://developer.blender.org/rBAd3443dc5fc9896bc0d04c2cc4a57a38e23cc08e7

Bool Tool: Auto Slice handle multiple objects and improve UX

Simplify UI layout and replace greyout UI with execute warnings, which tell user what exactly went wrong.

===================================================================

M	object_boolean_tools.py

===================================================================

diff --git a/object_boolean_tools.py b/object_boolean_tools.py
index dc0012f0..30bd89cb 100644
--- a/object_boolean_tools.py
+++ b/object_boolean_tools.py
@@ -303,7 +303,7 @@ def ApplyAll(context, list):
 
     bpy.ops.object.select_all(action="DESELECT")
     for obj in objDeleteList:
-        obj.select_set(state=True)
+        obj.select_set(True)
     bpy.ops.object.delete()
 
 
@@ -324,7 +324,7 @@ def ApplyThisBrush(context, brush):
                     bpy.ops.object.select_all(action="DESELECT")
 
     # Garbage Collector
-    brush.select_set(state=True)
+    brush.select_set(True)
     # bpy.ops.object.delete()
 
 
@@ -361,7 +361,7 @@ def ApplyThisBrush(context, brush):
 #         self.count += 1
 #         actObj = bpy.context.active_object
 #         if self.count == 1:
-#             actObj.select_set(state=True)
+#             actObj.select_set(True)
 #             bpy.ops.gpencil.draw("INVOKE_DEFAULT", mode="DRAW_POLY")
 
 #         if event.type == "RIGHTMOUSE":
@@ -378,7 +378,7 @@ def ApplyThisBrush(context, brush):
 #                     obj.name = "PolyDraw"
 #                     bpy.context.view_layer.objects.active = obj
 #                     bpy.ops.object.select_all(action="DESELECT")
-#                     obj.select_set(state=True)
+#                     obj.select_set(True)
 #                     bpy.ops.object.convert(target="MESH")
 #                     bpy.ops.object.mode_set(mode="EDIT")
 #                     bpy.ops.mesh.select_all(action="SELECT")
@@ -397,8 +397,8 @@ def ApplyThisBrush(context, brush):
 #                     bpy.ops.object.select_all(action="DESELECT")
 #                     bpy.context.view_layer.objects.active = actObj
 #                     bpy.context.view_layer.update()
-#                     actObj.select_set(state=True)
-#                     obj.select_set(state=True)
+#                     actObj.select_set(True)
+#                     obj.select_set(True)
 
 #                     bpy.context.view_layer.grease_pencil.clear()
 #                     bpy.ops.gpencil.data_unlink()
@@ -479,70 +479,59 @@ class BTool_FastTransform(Operator):
 
 # -------------------  Bool Tool OPERATOR CLASSES --------------------------------------------------------
 
-# Brush Operators --------------------------------------------
 
-# Boolean Union Operator
-class BTool_Union(Operator):
+# Brush operators
+# --------------------------------------------------------------------------------------
+
+
+class BToolSetup():
+
+    def execute(self, context):
+        Operation(context, self.mode)
+        return {"FINISHED"}
+
+    def invoke(self, context, event):
+        if len(context.selected_objects) < 2:
+            self.report({"ERROR"}, "At least two objects must be selected")
+            return {"CANCELLED"}
+
+        return self.execute(context)
+
+
+class BTool_Union(Operator, BToolSetup):
     bl_idname = "btool.boolean_union"
     bl_label = "Brush Union"
     bl_description = "This operator add a union brush to a canvas"
     bl_options = {"REGISTER", "UNDO"}
 
-    @classmethod
-    def poll(cls, context):
-        return context.active_object is not None
-
-    def execute(self, context):
-        Operation(context, "UNION")
-        return {"FINISHED"}
+    mode = "UNION"
 
 
-# Boolean Intersection Operator
-class BTool_Inters(Operator):
+class BTool_Inters(Operator, BToolSetup):
     bl_idname = "btool.boolean_inters"
     bl_label = "Brush Intersection"
     bl_description = "This operator add a intersect brush to a canvas"
     bl_options = {"REGISTER", "UNDO"}
 
-    @classmethod
-    def poll(cls, context):
-        return context.active_object is not None
-
-    def execute(self, context):
-        Operation(context, "INTERSECT")
-        return {"FINISHED"}
+    mode = "INTERSECT"
 
 
-# Boolean Difference Operator
-class BTool_Diff(Operator):
+class BTool_Diff(Operator, BToolSetup):
     bl_idname = "btool.boolean_diff"
     bl_label = "Brush Difference"
     bl_description = "This operator add a difference brush to a canvas"
     bl_options = {"REGISTER", "UNDO"}
 
-    @classmethod
-    def poll(cls, context):
-        return context.active_object is not None
-
-    def execute(self, context):
-        Operation(context, "DIFFERENCE")
-        return {"FINISHED"}
+    mode = "DIFFERENCE"
 
 
-# Boolean Slices Operator
-class BTool_Slice(Operator):
+class BTool_Slice(Operator, BToolSetup):
     bl_idname = "btool.boolean_slice"
     bl_label = "Brush Slice"
     bl_description = "This operator add a intersect brush to a canvas"
     bl_options = {"REGISTER", "UNDO"}
 
-    @classmethod
-    def poll(cls, context):
-        return context.active_object is not None
-
-    def execute(self, context):
-        Operation(context, "SLICE")
-        return {"FINISHED"}
+    mode = "SLICE"
 
 
 # Auto Boolean operators
@@ -550,10 +539,11 @@ class BTool_Slice(Operator):
 
 
 class Auto_Boolean:
+
     def objects_prepare(self):
         for ob in bpy.context.selected_objects:
             if ob.type != "MESH":
-                ob.select_set(state=False)
+                ob.select_set(False)
         bpy.ops.object.make_single_user(object=True, obdata=True)
         bpy.ops.object.convert(target="MESH")
 
@@ -571,14 +561,16 @@ class Auto_Boolean:
 
     def boolean_operation(self):
         obj = bpy.context.active_object
-        obj.select_set(state=False)
+        obj.select_set(False)
         obs = bpy.context.selected_objects
 
         self.mesh_selection(obj, "DESELECT")
+
         for ob in obs:
             self.mesh_selection(ob, "SELECT")
             self.boolean_mod(obj, ob, self.mode)
-        obj.select_set(state=True)
+
+        obj.select_set(True)
 
     def boolean_mod(self, obj, ob, mode, ob_delete=True):
         md = obj.modifiers.new("Auto Boolean", "BOOLEAN")
@@ -586,10 +578,23 @@ class Auto_Boolean:
         md.operation = mode
         md.object = ob
 
-        bpy.ops.object.modifier_apply(modifier="Auto Boolean")
-        if not ob_delete:
-            return
-        bpy.data.objects.remove(ob)
+        override = {"object": obj}
+        bpy.ops.object.modifier_apply(override, modifier=md.name)
+
+        if ob_delete:
+            bpy.data.objects.remove(ob)
+
+    def execute(self, context):
+        self.objects_prepare()
+        self.boolean_operation()
+        return {"FINISHED"}
+
+    def invoke(self, context, event):
+        if len(context.selected_objects) < 2:
+            self.report({"ERROR"}, "At least two objects must be selected")
+            return {"CANCELLED"}
+
+        return self.execute(context)
 
 
 class OBJECT_OT_BoolTool_Auto_Union(Operator, Auto_Boolean):
@@ -600,11 +605,6 @@ class OBJECT_OT_BoolTool_Auto_Union(Operator, Auto_Boolean):
 
     mode = "UNION"
 
-    def execute(self, context):
-        self.objects_prepare()
-        self.boolean_operation()
-        return {"FINISHED"}
-
 
 class OBJECT_OT_BoolTool_Auto_Difference(Operator, Auto_Boolean):
     bl_idname = "object.booltool_auto_difference"
@@ -614,11 +614,6 @@ class OBJECT_OT_BoolTool_Auto_Difference(Operator, Auto_Boolean):
 
     mode = "DIFFERENCE"
 
-    def execute(self, context):
-        self.objects_prepare()
-        self.boolean_operation()
-        return {"FINISHED"}
-
 
 class OBJECT_OT_BoolTool_Auto_Intersect(Operator, Auto_Boolean):
     bl_idname = "object.booltool_auto_intersect"
@@ -628,42 +623,40 @@ class OBJECT_OT_BoolTool_Auto_Intersect(Operator, Auto_Boolean):
 
     mode = "INTERSECT"
 
-    def execute(self, context):
-        self.objects_prepare()
-        self.boolean_operation()
-        return {"FINISHED"}
-
 
 class OBJECT_OT_BoolTool_Auto_Slice(Operator, Auto_Boolean):
     bl_idname = "object.booltool_auto_slice"
     bl_label = "Bool Tool Slice"
-    bl_description = "Slice active object along the selected object"
+    bl_description = "Slice active object along the selected objects"
     bl_options = {"REGISTER", "UNDO"}
 
     def execute(self, context):
+        space_data = context.space_data
+        is_local_view = bool(space_data.local_view)
         self.objects_prepare()
 
-        obj = context.active_object
-        obj.select_set(state=False)
-        ob = context.selected_objects[0]
+        ob1 = context.active_object
+        ob1.select_set(False)
+        self.mesh_selection(ob1, "DESELECT")
 
-        self.mesh_selection(obj, "DESELECT")
-        self.mesh_selection(ob, "SELECT")
+        for ob2 in context.selected_objects:
 
-        obj_copy = obj.copy()
-        obj_copy.data = obj.data.copy()
-        context.collection.objects.link(obj_copy)
+            self.mesh_selection(ob2, "SELECT")
 
-        space_data = context.space_data
-        is_local_view = bool(space_data.local_view)
+            ob1_copy = ob1.copy()
+            ob1_copy.data = ob1.data.copy()
+
+            for coll in ob1.users_collection:
+                coll.objects.link(ob1_copy)
 
-        if is_local_view:
-            obj_copy.local_view_set(space_data, True)
+            if is_local_view:
+                ob1_copy.local_view_set(space_data, True)
 
-        self.boolean_mod(obj, ob, "DIFFERENCE", ob_delete=False)
-        context.view_layer.objects.active = obj_copy
-        self.boolean_mod(obj_copy, ob, "INTERSECT")
-        obj_copy.select_set(state=True)
+            self.boolean_mod(ob1, ob2, "DIFFERENCE", ob_delete=False)
+            self.boolean_mod(ob1_copy, ob2, "INTERSECT")
+            ob1_copy.select_set(True)
+
+        context.view_layer.objects.active = ob1_copy
 
         return {"FINISHED"}
 
@@ -827,7 +820,7 @@ class BTool_BrushToMesh(Operator):
 
 # 3Dview Header Menu
 class VIEW3D_MT_booltool_menu(Menu):
-    bl_label = "BoolTool Operators"
+    bl_label = "Bool Tool"
     bl_idname = "VIEW3D_MT_booltool_menu"
 
     def draw(self, context):
@@ -887,28 +880,16 @@ class VIEW3D_PT_booltool_tools(Panel):
     def draw(self, context):
         layout = self.layout
         obj = context.active_object
-        obs_len = len(context.selected_objects)
 
-        main = layout.column(align=True)
-        main.enabled = obj.type == "MESH" and obs_len > 0
-
-        col = main.column(align=True)
-        col.enabled = obs_l

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list