Newer
Older
if isPolyBrush(actObj):
row = layout.row(align=False)
row.label(text="POLY BRUSH", icon="LINE_DATA")
mod = actObj.modifiers["BTool_PolyBrush"]
row.prop(mod, "thickness", text="Size")
layout.separator()
if isBrush(actObj):
row.operator(BTool_BrushToMesh.bl_idname, icon="MOD_LATTICE", text="Apply Brush")
Rem = row.operator(BTool_Remove.bl_idname, icon="X", text="Remove Brush")
Rem.thisObj = ""
Rem.Prop = "BRUSH"
layout.separator()
# ---------- Toolshelf: Brush Viewer -------------------------------------------------------
class VIEW3D_PT_booltool_bviewer(Panel):
bl_label = "Brush Viewer"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_context = "objectmode"
bl_parent_id = "VIEW3D_PT_booltool_tools"
@classmethod
def poll(cls, context):
actObj = bpy.context.active_object
if isCanvas(actObj):
return True
else:
return False
def draw(self, context):
actObj = bpy.context.active_object
icon = ""
if isCanvas(actObj):
for mod in actObj.modifiers:
container = self.layout.box()
if "BTool_" in mod.name:
if mod.operation == "DIFFERENCE":
icon = "SELECT_SUBTRACT"
elif mod.operation == "UNION":
icon = "SELECT_EXTEND"
elif mod.operation == "INTERSECT":
icon = "SELECT_INTERSECT"
elif mod.operation == "SLICE":
icon = "SELECT_DIFFERENCE"
objSelect = row.operator("btool.find_brush", text=mod.object.name, icon=icon, emboss=False)
objSelect.obj = mod.object.name
EnableIcon = "RESTRICT_VIEW_ON"
EnableIcon = "RESTRICT_VIEW_OFF"
Enable = row.operator(BTool_EnableBrush.bl_idname, icon=EnableIcon, emboss=False)
Enable.thisObj = mod.object.name
Remove = row.operator("btool.remove", icon="X", emboss=False)
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
Remove.thisObj = mod.object.name
Remove.Prop = "THIS"
# Stack Changer
Up = row.operator("btool.move_stack", icon="TRIA_UP", emboss=False)
Up.modif = mod.name
Up.direction = "UP"
Dw = row.operator("btool.move_stack", icon="TRIA_DOWN", emboss=False)
Dw.modif = mod.name
Dw.direction = "DOWN"
else:
row.label(mod.name)
# Stack Changer
Up = row.operator("btool.move_stack", icon="TRIA_UP", emboss=False)
Up.modif = mod.name
Up.direction = "UP"
Dw = row.operator("btool.move_stack", icon="TRIA_DOWN", emboss=False)
Dw.modif = mod.name
Dw.direction = "DOWN"
# ------------------ BOOL TOOL Help ----------------------------
class WM_OT_BoolTool_Help(Operator):
bl_idname = "wm.booltool_help"
bl_label = "Bool Tool Help"
bl_description = "Help - click to read basic information"
def draw(self, context):
layout = self.layout
layout.label(text="To use:")
layout.label(text="Select two or more objects,")
layout.label(text="choose one option from the panel")
layout.label(text="or from the Ctrl + Shift + B menu")
layout.separator()
layout.label(text="Auto Boolean:")
layout.label(text="Apply Boolean operation directly to mesh.")
layout.separator()
layout.label(text="Brush Boolean:")
layout.label(text="Create a Boolean brush modifier setup.")
def execute(self, context):
def invoke(self, context, event):
return context.window_manager.invoke_popup(self, width=220)
# ------------------ BOOL TOOL ADD-ON PREFERENCES ----------------------------
def UpdateBoolTool_Pref(self, context):
if self.fast_transform:
RegisterFastT()
else:
UnRegisterFastT()
# Add-ons Preferences Update Panel
# Define Panel classes for updating
panels = (
VIEW3D_PT_booltool_tools,
VIEW3D_PT_booltool_config,
VIEW3D_PT_booltool_bviewer,
def update_panels(self, context):
for panel in panels:
if "bl_rna" in panel.__dict__:
bpy.utils.unregister_class(panel)
for panel in panels:
panel.bl_category = context.preferences.addons[
__name__
].preferences.category
bpy.utils.register_class(panel)
except Exception as e:
message = "Bool Tool: Updating Panel locations has failed"
print("\n[{}]\n{}\n\nError:\n{}".format(__name__, message, e))
class PREFS_BoolTool_Props(AddonPreferences):
bl_idname = __name__
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
fast_transform: BoolProperty(
name="Fast Transformations",
default=False,
update=UpdateBoolTool_Pref,
description="Replace the Transform HotKeys (G,R,S)\n"
"for a custom version that can optimize the visualization of Brushes",
)
make_vertex_groups: BoolProperty(
name="Make Vertex Groups",
default=False,
description="When Applying a Brush to the Object it will create\n"
"a new vertex group for the new faces",
)
make_boundary: BoolProperty(
name="Make Boundary",
default=False,
description="When Apply a Brush to the Object it will create a\n"
"new vertex group of the boundary boolean area",
)
use_wire: BoolProperty(
name="Use Bmesh",
default=False,
description="Use The Wireframe Instead of Bounding Box for visualization",
)
category: StringProperty(
name="Tab Category",
description="Choose a name for the category of the panel",
default="Edit",
update=update_panels,
)
Enable_Tab_01: BoolProperty(default=False)
def draw(self, context):
layout = self.layout
split = layout.split(factor=split_percent)
col = split.column()
col = split.column()
col.prop(self, "category", text="")
split = layout.split(factor=split_percent)
col.prop(self, "fast_transform")
col.prop(self, "use_wire", text="Use Wire Instead Of Bbox")
layout.prop(self, "Enable_Tab_01", text="Hot Keys", icon="KEYINGSET")
if self.Enable_Tab_01:
row = layout.row()
col = row.column()
col.label(text="Hotkey List:")
col.label(text="Menu: Ctrl Shift B")
row = layout.row()
col = row.column()
col.label(text="Brush Operators:")
col.label(text="Union: Ctrl Num +")
col.label(text="Diff: Ctrl Num -")
col.label(text="Intersect: Ctrl Num *")
col.label(text="Slice: Ctrl Num /")
row = layout.row()
col = row.column()
col.label(text="Auto Operators:")
col.label(text="Difference: Ctrl Shift Num -")
col.label(text="Union: Ctrl Shift Num +")
col.label(text="Intersect: Ctrl Shift Num *")
col.label(text="Slice: Ctrl Shift Num /")
col.label(text="BTool Brush To Mesh: Ctrl Num Enter")
col.label(text="BTool All Brush To Mesh: Ctrl Shift Num Enter")
# ------------------- Class List ------------------------------------------------
PREFS_BoolTool_Props,
VIEW3D_MT_booltool_menu,
VIEW3D_PT_booltool_tools,
VIEW3D_PT_booltool_config,
VIEW3D_PT_booltool_bviewer,
OBJECT_OT_BoolTool_Auto_Union,
OBJECT_OT_BoolTool_Auto_Difference,
OBJECT_OT_BoolTool_Auto_Intersect,
OBJECT_OT_BoolTool_Auto_Slice,
BTool_Union,
BTool_Diff,
BTool_Inters,
BTool_Slice,
BTool_Remove,
BTool_AllBrushToMesh,
BTool_BrushToMesh,
BTool_FindBrush,
BTool_MoveStack,
BTool_EnableBrush,
BTool_EnableThisBrush,
BTool_EnableFTransform,
BTool_FastTransform,
# ------------------- REGISTER ------------------------------------------------
addon_keymaps = []
addon_keymapsFastT = []
# Fast Transform HotKeys Register
def RegisterFastT():
wm = bpy.context.window_manager
km = wm.keyconfigs.addon.keymaps.new(name="Object Mode", space_type="EMPTY")
kmi = km.keymap_items.new(BTool_FastTransform.bl_idname, "G", "PRESS")
kmi.properties.operator = "Translate"
addon_keymapsFastT.append((km, kmi))
kmi = km.keymap_items.new(BTool_FastTransform.bl_idname, "R", "PRESS")
kmi.properties.operator = "Rotate"
addon_keymapsFastT.append((km, kmi))
kmi = km.keymap_items.new(BTool_FastTransform.bl_idname, "S", "PRESS")
kmi.properties.operator = "Scale"
addon_keymapsFastT.append((km, kmi))
# Fast Transform HotKeys UnRegister
def UnRegisterFastT():
wm = bpy.context.window_manager
kc = wm.keyconfigs.addon
if kc:
for km, kmi in addon_keymapsFastT:
km.keymap_items.remove(kmi)
addon_keymapsFastT.clear()
def register():
for cls in classes:
bpy.utils.register_class(cls)
update_panels(None, bpy.context)
bpy.types.Scene.BoolHide = BoolProperty(
default=False,
description="Hide boolean objects",
update=update_BoolHide,
)
bpy.types.VIEW3D_MT_object.append(VIEW3D_BoolTool_Menu)
try:
bpy.types.VIEW3D_MT_Object.prepend(VIEW3D_BoolTool_Menu)
except:
pass
kc = wm.keyconfigs.addon
# create the boolean menu hotkey
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
if kc is not None:
km = kc.keymaps.new(name="Object Mode")
kmi = km.keymap_items.new("wm.call_menu", "B", "PRESS", ctrl=True, shift=True)
kmi.properties.name = "VIEW3D_MT_booltool_menu"
addon_keymaps.append((km, kmi))
# Brush Operators
kmi = km.keymap_items.new(BTool_Union.bl_idname, "NUMPAD_PLUS", "PRESS", ctrl=True)
addon_keymaps.append((km, kmi))
kmi = km.keymap_items.new(BTool_Diff.bl_idname, "NUMPAD_MINUS", "PRESS", ctrl=True)
addon_keymaps.append((km, kmi))
kmi = km.keymap_items.new(BTool_Inters.bl_idname, "NUMPAD_ASTERIX", "PRESS", ctrl=True)
addon_keymaps.append((km, kmi))
kmi = km.keymap_items.new(BTool_Slice.bl_idname, "NUMPAD_SLASH", "PRESS", ctrl=True)
addon_keymaps.append((km, kmi))
kmi = km.keymap_items.new(BTool_BrushToMesh.bl_idname, "NUMPAD_ENTER", "PRESS", ctrl=True)
addon_keymaps.append((km, kmi))
kmi = km.keymap_items.new(
BTool_AllBrushToMesh.bl_idname,
"NUMPAD_ENTER",
"PRESS",
ctrl=True,
shift=True,
)
addon_keymaps.append((km, kmi))
# Auto Operators
kmi = km.keymap_items.new(
OBJECT_OT_BoolTool_Auto_Union.bl_idname,
"NUMPAD_PLUS",
"PRESS",
ctrl=True,
shift=True,
)
addon_keymaps.append((km, kmi))
kmi = km.keymap_items.new(
OBJECT_OT_BoolTool_Auto_Difference.bl_idname,
"NUMPAD_MINUS",
"PRESS",
ctrl=True,
shift=True,
)
addon_keymaps.append((km, kmi))
kmi = km.keymap_items.new(
OBJECT_OT_BoolTool_Auto_Intersect.bl_idname,
"NUMPAD_ASTERIX",
"PRESS",
ctrl=True,
shift=True,
)
addon_keymaps.append((km, kmi))
kmi = km.keymap_items.new(
OBJECT_OT_BoolTool_Auto_Slice.bl_idname,
"NUMPAD_SLASH",
"PRESS",
ctrl=True,
shift=True,
)
addon_keymaps.append((km, kmi))
def unregister():
# Keymapping
# remove keymaps when add-on is deactivated
wm = bpy.context.window_manager
kc = wm.keyconfigs.addon
for km, kmi in addon_keymaps:
km.keymap_items.remove(kmi)
addon_keymaps.clear()
UnRegisterFastT()
bpy.types.VIEW3D_MT_object.remove(VIEW3D_BoolTool_Menu)
try:
bpy.types.VIEW3D_MT_Object.remove(VIEW3D_BoolTool_Menu)
except:
pass
del bpy.types.Scene.BoolHide
for cls in classes:
bpy.utils.unregister_class(cls)
if __name__ == "__main__":