Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikhail Rachinskiy <mikhail.rachinskiy@gmail.com>2016-08-01 13:03:01 +0300
committerMikhail Rachinskiy <mikhail.rachinskiy@gmail.com>2016-08-01 13:03:01 +0300
commitb7f883ed69a3ff7cb0678f26c445caca8c778a3e (patch)
tree681647dab8bbcf163e67555f80e3c050b48c2393 /object_boolean_tools.py
parent4744a96bea1afd11b70b2f1932ca2072a0f17dc9 (diff)
BoolTools: Add preference to choose boolean solver
Add preference to choose boolean solver. Also refactor preferences UI so humans could actually read it.
Diffstat (limited to 'object_boolean_tools.py')
-rw-r--r--object_boolean_tools.py274
1 files changed, 166 insertions, 108 deletions
diff --git a/object_boolean_tools.py b/object_boolean_tools.py
index 6e857ce3..c92ce53b 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("Experimental Features:")
- layout.prop(self, "fast_transform")
- layout.prop(self, "use_wire", text="Use Wire Instead Of Bbox")
+ split_percent = 0.15
+
+ split = layout.split(percentage=split_percent)
+ col_1 = split.column()
+ col_2 = split.column()
+ col_1.label(text="Category:")
+ col_2.prop(self, "category", text="")
+
+ split = layout.split(percentage=split_percent)
+ col_1 = split.column()
+ col_2 = split.column()
+ col_1.label('Boolean Solver:')
+ col_2.prop(self, 'solver', text='')
+
+ split = layout.split(percentage=split_percent)
+ col_1 = split.column()
+ col_2 = split.column()
+ col_1.label("Experimental Features:")
+ col_2.prop(self, "fast_transform")
+ col_2.prop(self, "use_wire", text="Use Wire Instead Of Bbox")
"""
# EXPERIMENTAL
- layout.prop(self, "make_vertex_groups")
- layout.prop(self, "make_boundary")
+ col_2.prop(self, "make_vertex_groups")
+ col_2.prop(self, "make_boundary")
"""
- layout = self.layout
- layout.separator()
- layout.label("Hotkey List:")
- layout.separator()
- layout.label("Menu: 'B', 'PRESS', ctrl=True, shift=True")
- layout.label("Brush Operators:")
- layout.label("Union: 'NUMPAD_PLUS', 'PRESS', ctrl=True")
- layout.label("Diff: 'NUMPAD_MINUS', 'PRESS', ctrl=True")
- layout.label("Intersect: 'NUMPAD_ASTERIX', 'PRESS', ctrl=True")
- layout.label("Slice: 'NUMPAD_SLASH', 'PRESS', ctrl=True")
- layout.label("Direct Operators:")
- layout.label("Direct_Union: 'NUMPAD_PLUS', 'PRESS', ctrl=True, shift=True")
- layout.label("Direct_Difference: 'NUMPAD_MINUS', 'PRESS', ctrl=True, shift=True")
- layout.label("Direct_Intersect: 'NUMPAD_ASTERIX', 'PRESS', ctrl=True, shift=True")
- layout.label("Direct_Slice: 'NUMPAD_SLASH', 'PRESS', ctrl=True, shift=True")
- layout.label("BTool_BrushToMesh: 'NUMPAD_ENTER', 'PRESS', ctrl=True")
- layout.label("BTool_AllBrushToMesh: 'NUMPAD_ENTER', 'PRESS', ctrl=True, shift=True")
+
+ split = layout.split(percentage=split_percent)
+ col_1 = split.column()
+ col_2 = split.column()
+ col_1.label("Hotkey List:")
+ col_2.label("Menu: Ctrl Shift B")
+
+ split = layout.split(percentage=split_percent)
+ col_1 = split.column()
+ col_2 = split.column()
+ col_1.label("Brush Operators:")
+ col_2.label("Union: Ctrl Num +")
+ col_2.label("Diff: Ctrl Num -")
+ col_2.label("Intersect: Ctrl Num *")
+ col_2.label("Slice: Ctrl Num /")
+
+ split = layout.split(percentage=split_percent)
+ col_1 = split.column()
+ col_2 = split.column()
+ col_1.label("Direct Operators:")
+ col_2.label("Direct Union: Ctrl Shift Num +")
+ col_2.label("Direct Difference: Ctrl Shift Num -")
+ col_2.label("Direct Intersect: Ctrl Shift Num *")
+ col_2.label("Direct Slice: Ctrl Shift Num /")
+ col_2.label("BTool Brush To Mesh: Ctrl Num Enter")
+ col_2.label("BTool All Brush To Mesh: Ctrl Shift Num Enter")
+
# ------------------- Class List ------------------------------------------------
+
classes = (
+ BoolTool_Pref,
# Booltron
Direct_Union,
Direct_Difference,
@@ -1277,8 +1336,7 @@ classes = (
BoolTool_Config,
BoolTool_BViwer,
BTool_FastTransform,
- BoolTool_Pref,
- )
+)
# ------------------- REGISTER ------------------------------------------------
addon_keymaps = []