[Bf-extensions-cvs] [b7f883e] master: BoolTools: Add preference to choose boolean solver

Mikhail Rachinskiy noreply at git.blender.org
Mon Aug 1 12:04:50 CEST 2016


Commit: b7f883ed69a3ff7cb0678f26c445caca8c778a3e
Author: Mikhail Rachinskiy
Date:   Mon Aug 1 14:03:01 2016 +0400
Branches: master
https://developer.blender.org/rBAb7f883ed69a3ff7cb0678f26c445caca8c778a3e

BoolTools: Add preference to choose boolean solver

Add preference to choose boolean solver.
Also refactor preferences UI so humans could actually read it.

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

M	object_boolean_tools.py

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

diff --git a/object_boolean_tools.py b/object_boolean_tools.py
index 6e857ce..c92ce53 100644
--- a/object_boolean_tools.py
+++ b/object_boolean_tools.py
@@ -21,21 +21,20 @@
 bl_info = {
     "name": "Bool Tool",
     "author": "Vitor Balbio, Mikhail Rachinskiy, TynkaTopi, Meta-Androcto",
-    "version": (0, 3, 3),
-    "blender": (2, 77, 0),
+    "version": (0, 3, 4),
+    "blender": (2, 78, 0),
     "location": "View3D > Toolshelf > BoolTool",
     "description": "Bool Tools Hotkey: Ctrl Shift B",
     "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Object/BoolTool",
     "tracker_url": "https://developer.blender.org/maniphest/task/edit/form/2/",
-    "category": "Object",
-    }
+    "category": "Object"}
 
 import bpy
 from bpy.app.handlers import persistent
 from bpy.types import (
-        Operator,
-        Panel,
-        )
+    Operator,
+    Panel,
+)
 
 
 # -------------------  Bool Tool FUNCTIONS------------------------------
@@ -614,8 +613,13 @@ class BTool_Slice(Operator):
         Operation(context, "SLICE")
         return {'FINISHED'}
 
-# Booltron Direct FUNCTIONS ---------------------------------------------------
 
+# Booltron operators for direct booleans ---------------------------------------------------
+
+
+def prepare_objects():
+    bpy.ops.object.make_single_user(object=True, obdata=True)
+    bpy.ops.object.convert(target='MESH')
 
 def mesh_selection(ob, select_action):
     context = bpy.context
@@ -624,44 +628,27 @@ def mesh_selection(ob, select_action):
     ops_me = bpy.ops.mesh
     ops_ob = bpy.ops.object
 
-    scene.objects.active = ob
-    ops_ob.mode_set(mode="EDIT")
-    ops_me.select_all(action=select_action)
-    ops_ob.mode_set(mode="OBJECT")
-    scene.objects.active = obj
-
+    def mesh_cleanup():
+        ops_me.select_all(action='SELECT')
+        ops_me.delete_loose()
+        ops_me.select_all(action='SELECT')
+        ops_me.remove_doubles(threshold=0.0001)
+        ops_me.fill_holes(sides=0)
+        ops_me.normals_make_consistent()
 
-def modifier_boolean(obj, ob, mode, delete_not=False):
-    md = obj.modifiers.new("BoolTool Direct", 'BOOLEAN')
-    md.show_viewport = False
-    md.show_render = False
-    md.operation = mode
-    md.object = ob
+    scene.objects.active = ob
+    ops_ob.mode_set(mode='EDIT')
 
-    bpy.ops.object.modifier_apply(modifier="BoolTool Direct")
-    if delete_not is True:
-        return
-    bpy.context.scene.objects.unlink(ob)
-    bpy.data.objects.remove(ob)
+    mesh_cleanup()
+    ops_me.select_all(action=select_action)
 
+    ops_ob.mode_set(mode='OBJECT')
+    scene.objects.active = obj
 
-def boolean_each(mode):
-    context = bpy.context
+def get_objects(context):
     obj = context.active_object
 
-    obj.select = False
-    obs = context.selected_objects
-
-    mesh_selection(obj, 'DESELECT')
-    for ob in obs:
-        mesh_selection(ob, 'SELECT')
-        modifier_boolean(obj, ob, mode)
-    obj.select = True
-
-
-def objects_get():
-    context = bpy.context
-    obj = context.active_object
+    prepare_objects()
 
     obj.select = False
     ob = context.selected_objects[0]
@@ -671,47 +658,90 @@ def objects_get():
 
     return obj, ob
 
-# Booltron Direct Operators ---------------------------------------------------
 
+class DirectBooleans:
+    bl_options = {'REGISTER', 'UNDO'}
+
+    solver = bpy.props.EnumProperty(
+        name='Boolean Solver',
+        items=(
+            ('DEFAULT', 'Default', ''),
+            ('BMESH',   'BMesh',   ''),
+            ('CARVE',   'Carve',   ''),
+        ),
+        default='DEFAULT',
+        description='Specify solver for boolean operations',
+        options={'SKIP_SAVE'})
+
+    def boolean_each(self, mode):
+        context = bpy.context
+        obj = context.active_object
+
+        prepare_objects()
+
+        obj.select = False
+        obs = context.selected_objects
+
+        mesh_selection(obj, 'DESELECT')
+        for ob in obs:
+            mesh_selection(ob, 'SELECT')
+            self.modifier_boolean(obj, ob, mode)
+        obj.select = True
+
+    def modifier_boolean(self, obj, ob, mode, terminate=True):
+        if self.solver == 'DEFAULT':
+            solver = bpy.context.user_preferences.addons[__name__].preferences.solver
+        else:
+            solver = self.solver
+
+        md = obj.modifiers.new('Immediate apply', 'BOOLEAN')
+        md.show_viewport = False
+        md.show_render = False
+        md.operation = mode
+        md.solver = solver
+        md.object = ob
 
-class Direct_Union(Operator):
+        bpy.ops.object.modifier_apply(modifier='Immediate apply')
+        if not terminate:
+            return
+        bpy.context.scene.objects.unlink(ob)
+        bpy.data.objects.remove(ob)
+
+
+class Direct_Union(DirectBooleans, Operator):
     """Combine selected objects"""
     bl_idname = "btool.direct_union"
     bl_label = "Union"
-    bl_options = {'REGISTER', 'UNDO'}
 
     def execute(self, context):
-        boolean_each('UNION')
+        self.boolean_each('UNION')
         return {'FINISHED'}
 
 
-class Direct_Difference(Operator):
+class Direct_Difference(DirectBooleans, Operator):
     """Subtract selected objects from active object"""
     bl_idname = "btool.direct_difference"
     bl_label = "Difference"
-    bl_options = {'REGISTER', 'UNDO'}
 
     def execute(self, context):
-        boolean_each('DIFFERENCE')
+        self.boolean_each('DIFFERENCE')
         return {'FINISHED'}
 
 
-class Direct_Intersect(Operator):
+class Direct_Intersect(DirectBooleans, Operator):
     """Keep only intersecting geometry"""
     bl_idname = "btool.direct_intersect"
     bl_label = "Intersect"
-    bl_options = {'REGISTER', 'UNDO'}
 
     def execute(self, context):
-        boolean_each('INTERSECT')
+        self.boolean_each('INTERSECT')
         return {'FINISHED'}
 
 
-class Direct_Slice(Operator):
+class Direct_Slice(DirectBooleans, Operator):
     """Slice active object along the selected object (can handle only two objects at a time)"""
     bl_idname = "btool.direct_slice"
     bl_label = "Slice"
-    bl_options = {'REGISTER', 'UNDO'}
 
     @classmethod
     def poll(cls, context):
@@ -719,7 +749,7 @@ class Direct_Slice(Operator):
 
     def execute(self, context):
         scene = context.scene
-        obj, ob = objects_get()
+        obj, ob = get_objects(context)
 
         def object_duplicate(ob):
             ops_ob = bpy.ops.object
@@ -730,28 +760,28 @@ class Direct_Slice(Operator):
             return context.selected_objects[0]
 
         obj_copy = object_duplicate(obj)
-        modifier_boolean(obj, ob, 'DIFFERENCE', delete_not=True)
+        self.modifier_boolean(obj, ob, 'DIFFERENCE', terminate=False)
         scene.objects.active = obj_copy
-        modifier_boolean(obj_copy, ob, 'INTERSECT')
+        self.modifier_boolean(obj_copy, ob, 'INTERSECT')
         return {'FINISHED'}
 
 
-class Direct_Subtract(Operator):
+class Direct_Subtract(DirectBooleans, Operator):
     """Subtract selected object from active object, """ \
     """subtracted object not removed (can handle only two objects at a time))"""
     bl_idname = "btool.direct_subtract"
     bl_label = "Subtract"
-    bl_options = {'REGISTER', 'UNDO'}
 
     @classmethod
     def poll(cls, context):
         return len(context.selected_objects) == 2
 
     def execute(self, context):
-        obj, ob = objects_get()
-        modifier_boolean(obj, ob, 'DIFFERENCE', delete_not=True)
+        obj, ob = get_objects(context)
+        self.modifier_boolean(obj, ob, 'DIFFERENCE', terminate=False)
         return {'FINISHED'}
 
+
 # Utils Class ---------------------------------------------------------------
 
 # Find the Brush Selected in Three View
@@ -1190,68 +1220,97 @@ class BoolTool_Pref(bpy.types.AddonPreferences):
             default=False,
             update=UpdateBoolTool_Pref,
             description=("Replace the Transform HotKeys (G,R,S) "
-                        "for a custom version that can optimize the visualization of Brushes")
-            )
+                         "for a custom version that can optimize the visualization of Brushes"))
 
     make_vertex_groups = bpy.props.BoolProperty(
-            name="Make Vertex Groups",
-            default=False,
-            description="When Apply a Brush to de Object it will create a new vertex group of the new faces"
-            )
+        name="Make Vertex Groups",
+        default=False,
+        description="When Apply a Brush to de Object it will create a new vertex group of the new faces")
+
     make_boundary = bpy.props.BoolProperty(
-            name="Make Boundary",
-            default=False,
-            description="When Apply a Brush to de Object it will create a new vertex group of the bondary boolean area"
-            )
+        name="Make Boundary",
+        default=False,
+        description="When Apply a Brush to de Object it will create a new vertex group of the bondary boolean area")
+ 
     use_wire = bpy.props.BoolProperty(
-            name="Use Bmesh",
-            default=False,
-            description="Use The Wireframe Instead Of Boolean"
-            )
+        name="Use Bmesh",
+        default=False,
+        description="Use The Wireframe Instead Of Boolean")
 
     category = bpy.props.StringProperty(
-            name="Tab Category",
-            description="Choose a name for the category of the panel",
-            default="Bool Tools",
-            update=update_panel)
+        name="Tab Category",
+        description="Choose a name for the category of the panel",
+        default="Bool Tools",
+        update=update_panel)
+
+    solver = bpy.props.EnumProperty(
+        name='Boolean Solver',
+        items=(
+            ('BMESH', 'BMesh', ''),
+            ('CARVE', 'Carve', ''),
+        ),
+        default='BMESH',
+        description='Specify solver for boolean operations')
 
     def draw(self, context):
-
-        layout = self.layout
-        row = layout.row()
-        col = row.column()
-        col.label(text="Category:")
-        col.prop(self, "category", text="")
-        layout.separator()
         layout = self.layout
-        layout.label("Ex

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list