diff options
author | lijenstina <lijenstina@gmail.com> | 2017-06-05 15:53:42 +0300 |
---|---|---|
committer | lijenstina <lijenstina@gmail.com> | 2017-06-05 15:53:42 +0300 |
commit | be1ffdc175be417a0f9eabc95e6c7c6f243dab01 (patch) | |
tree | 728a3c73d32c84aece48de779e0cbf96f4bff3ed /object_fracture_crack | |
parent | 6feeb4de6d939c17d931f2763043ea9224154949 (diff) |
Cell Fracture Crack It: Fixes, clean up
Bumped verison to 0.1.1
Pep8 cleanup
Replace deprecated imp calls with importlib
Small UI changes
Make the Panel by default closed
Move scene properties to a PropertyGroup
they can be accessed with context.scene.crackit
Fixed some polling issues related to using Fracture
(as the operator will ignore objects that are not processed)
causing the operation to fail further on
Added an option for using the original names or the Enum ones
for the materials shipped in the Blend file
More robust error handling
Add a button for the wm.addon_userpref_show to open the
Cell Fracture add-on if it is not enabled
Diffstat (limited to 'object_fracture_crack')
-rw-r--r-- | object_fracture_crack/__init__.py | 208 | ||||
-rw-r--r-- | object_fracture_crack/crack_it.py | 240 | ||||
-rw-r--r-- | object_fracture_crack/operator.py | 229 |
3 files changed, 411 insertions, 266 deletions
diff --git a/object_fracture_crack/__init__.py b/object_fracture_crack/__init__.py index f2aa7593..dc43fbe3 100644 --- a/object_fracture_crack/__init__.py +++ b/object_fracture_crack/__init__.py @@ -1,4 +1,4 @@ -#====================== BEGIN GPL LICENSE BLOCK ====================== +# ##### BEGIN GPL LICENSE BLOCK ##### # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -14,115 +14,135 @@ # along with this program; if not, write to the Free Software Foundation, # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # -#======================= END GPL LICENSE BLOCK ======================== +# ##### END GPL LICENSE BLOCK ##### +bl_info = { + "name": "Cell Fracture Crack It", + "author": "Nobuyuki Hirakata", + "version": (0, 1, 1), + "blender": (2, 78, 5), + "location": "View3D > Toolshelf > Crack it! Tab", + "description": "Displaced Cell Fracture Addon", + "warning": "Make sure to enable 'Object: Cell Fracture' Addon", + "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/" + "Py/Scripts/Object/CrackIt", + "category": "Object" +} if 'bpy' in locals(): - import imp - imp.reload(operator) + import importlib + importlib.reload(operator) else: from . import operator import bpy +from bpy.types import PropertyGroup +from bpy.props import ( + BoolProperty, + EnumProperty, + FloatProperty, + IntProperty, + PointerProperty, + ) import os -bl_info = { - "name": "Cell Fracture Crack It", - "author": "Nobuyuki Hirakata", - "version": (0, 1, 0), - "blender": (2, 77, 0), - "location": "View3D > Toolshelf > Creat Tab", - "description": "Displaced Cell Fracture Addon", - "warning": "Make sure to enable 'Object: Cell Fracture' Addon", - "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Object/CrackIt", - "category": "Object" -} + +class CrackItProperties(PropertyGroup): + # Input on toolshelf before execution + # In Panel subclass, In bpy.types.Operator subclass, + # reference them by context.scene.crackit + + fracture_childverts = BoolProperty( + name="From Child Verts", + description="Use child object's vertices and position for origin of crack", + default=False + ) + fracture_scalex = FloatProperty( + name="Scale X", + description="Scale X", + default=1.00, + min=0.00, + max=1.00 + ) + fracture_scaley = FloatProperty( + name="Scale Y", + description="Scale Y", + default=1.00, + min=0.00, + max=1.00 + ) + fracture_scalez = FloatProperty( + name="Scale Z", + description="Scale Z", + default=1.00, + min=0.00, + max=1.00 + ) + fracture_div = IntProperty( + name="Max Crack", + description="Max Crack", + default=100, + min=0, + max=10000 + ) + fracture_margin = FloatProperty( + name="Margin Size", + description="Margin Size", + default=0.001, + min=0.000, + max=1.000 + ) + extrude_offset = FloatProperty( + name="Offset", + description="Extrude Offset", + default=0.10, + min=0.00, + max=2.00 + ) + extrude_random = FloatProperty( + name="Random", + description="Extrude Random", + default=0.30, + min=-1.00, + max=1.00 + ) + # Path of the addon + material_addonpath = os.path.dirname(__file__) + # Selection of material preset + # Note: you can choose the original name in the library blend + # or the prop name + material_preset = EnumProperty( + name="Preset", + description="Material Preset", + items=[ + ('crackit_organic_mud', "Organic Mud", "Mud material"), + ('crackit_mud1', "Mud", "Mud material"), + ('crackit_tree1_moss1', "Tree Moss", "Tree Material"), + ('crackit_tree2_dry1', "Tree Dry", "Tree Material"), + ('crackit_tree3_red1', "Tree Red", "Tree Material"), + ('crackit_rock1', "Rock", "Rock Material") + ] + ) + material_lib_name = BoolProperty( + name="Library Name", + description="Use the original Material name from the .blend library\n" + "instead of the one defined in the Preset", + default=True + ) + def register(): bpy.utils.register_module(__name__) - - # Input on toolshelf before execution -------------------------- - # In Panel subclass, In bpy.types.Operator subclass, reference them by context.scene.~. - - bpy.types.Scene.crackit_fracture_childverts = bpy.props.BoolProperty( - name = 'From Child Verts', - description = "Use child object's vertices and position for origin of crack.", - default = False - ) - bpy.types.Scene.crackit_fracture_scalex = bpy.props.FloatProperty( - name = 'Scale X', - description = "Scale X", - default = 1.00, - min = 0.00, - max = 1.00 - ) - bpy.types.Scene.crackit_fracture_scaley = bpy.props.FloatProperty( - name = 'Scale Y', - description = "Scale Y", - default = 1.00, - min = 0.00, - max = 1.00 - ) - bpy.types.Scene.crackit_fracture_scalez = bpy.props.FloatProperty( - name = 'Scale Z', - description = "Scale Z", - default = 1.00, - min = 0.00, - max = 1.00 - ) - bpy.types.Scene.crackit_fracture_div = bpy.props.IntProperty( - name = 'Max Crack', - description = "Max Crack", - default = 100, - min = 0, - max = 10000 - ) - bpy.types.Scene.crackit_fracture_margin = bpy.props.FloatProperty( - name = 'Margin Size', - description = "Margin Size", - default = 0.001, - min = 0.000, - max = 1.000 - ) - bpy.types.Scene.crackit_extrude_offset = bpy.props.FloatProperty( - name = 'Extrude', - description = "Extrude Offset", - default = 0.10, - min = 0.00, - max = 2.00 - ) - bpy.types.Scene.crackit_extrude_random = bpy.props.FloatProperty( - name = 'Random', - description = "Extrude Random", - default = 0.30, - min = -1.00, - max = 1.00 - ) - # Path of the addon. - bpy.types.Scene.crackit_material_addonpath = os.path.dirname(__file__) - # Selection of material preset. - bpy.types.Scene.crackit_material_preset = bpy.props.EnumProperty( - name = 'Preset', - description = "Material Preset", - items = [('crackit_organic_mud', 'Organic Mud', "Mud material"), - ('crackit_mud1', 'Mud', "Mud material"), - ('crackit_tree1_moss1', 'Tree1_moss', "Tree Material"), - ('crackit_tree2_dry1', 'Tree2_dry', "Tree Material"), - ('crackit_tree3_red1', 'Tree3_red', "Tree Material"), - ('crackit_rock1', 'Rock', "Rock Material")] - ) + bpy.types.Scene.crackit = PointerProperty( + type=CrackItProperties + ) + def unregister(): - # Delete bpy.types.Scene.~. - del bpy.types.Scene.crackit_fracture_scalex - del bpy.types.Scene.crackit_fracture_scaley - del bpy.types.Scene.crackit_fracture_scalez - del bpy.types.Scene.crackit_fracture_div - del bpy.types.Scene.crackit_fracture_margin - del bpy.types.Scene.crackit_extrude_offset - + del bpy.types.Scene.crackit bpy.utils.unregister_module(__name__) + if __name__ == "__main__": register() diff --git a/object_fracture_crack/crack_it.py b/object_fracture_crack/crack_it.py index 6d0cd571..489d2c87 100644 --- a/object_fracture_crack/crack_it.py +++ b/object_fracture_crack/crack_it.py @@ -1,77 +1,124 @@ +# gpl: author Nobuyuki Hirakata + import bpy -import bmesh, mathutils, random -from random import gauss +import bmesh +from random import ( + gauss, + seed, + ) from math import radians -from mathutils import Euler, Vector +from mathutils import Euler + + +# Allow changing the original material names from the .blend file +# by replacing them with the UI Names from the EnumProperty +def get_ui_mat_name(mat_name): + mat_ui_name = "CrackIt Material" + try: + # access the Scene type directly to get the name from the enum + mat_items = bpy.types.Scene.crackit[1]["type"].bl_rna.material_preset[1]["items"] + for mat_id, mat_list in enumerate(mat_items): + if mat_name in mat_list: + mat_ui_name = mat_items[mat_id][1] + break + del mat_items + except Exception as e: + error_handlers( + False, "get_ui_mat_name", e, + "Retrieving the EnumProperty key UI Name could not be completed", True + ) + pass + + return mat_ui_name + -import addon_utils +def error_handlers(self, op_name, error, reports="ERROR", func=False): + if self and reports: + self.report({'WARNING'}, reports + " (See Console for more info)") -# ---------------------Crack------------------- + is_func = "Function" if func else "Operator" + print("\n[Cell Fracture Crack It]\n{}: {}\nError: " + "{}\nReport: {}\n".format(is_func, op_name, error, reports)) + + +# -------------------- Crack ------------------- # Cell fracture and post-process: -def makeFracture(child_verts=False, division=100, noise=0.00, scaleX=1.00, scaleY=1.00, scaleZ=1.00, recursion=0, margin=0.001): - # Get active object name and active layer. +def makeFracture(child_verts=False, division=100, noise=0.00, + scaleX=1.00, scaleY=1.00, scaleZ=1.00, recursion=0, margin=0.001): + + # Get active object name and active layer active_name = bpy.context.scene.objects.active.name active_layer = bpy.context.scene.active_layer - - # source method of whether use child verts. - if child_verts == True: - crack_source = 'VERT_CHILD' + + # source method of whether use child verts + if child_verts is True: + crack_source = 'VERT_CHILD' else: - crack_source = 'PARTICLE_OWN' - - bpy.ops.object.add_fracture_cell_objects(source={crack_source}, source_limit=division, source_noise=noise, - cell_scale=(scaleX, scaleY, scaleZ), recursion=recursion, recursion_source_limit=8, recursion_clamp=250, recursion_chance=0.25, recursion_chance_select='SIZE_MIN', - use_smooth_faces=False, use_sharp_edges=False, use_sharp_edges_apply=True, use_data_match=True, use_island_split=True, - margin=margin, material_index=0, use_interior_vgroup=False, mass_mode='VOLUME', mass=1, use_recenter=True, use_remove_original=True, use_layer_index=0, use_layer_next=False, - group_name="", use_debug_points=False, use_debug_redraw=True, use_debug_bool=False) + crack_source = 'PARTICLE_OWN' + + bpy.ops.object.add_fracture_cell_objects( + source={crack_source}, source_limit=division, source_noise=noise, + cell_scale=(scaleX, scaleY, scaleZ), recursion=recursion, + recursion_source_limit=8, recursion_clamp=250, recursion_chance=0.25, + recursion_chance_select='SIZE_MIN', use_smooth_faces=False, + use_sharp_edges=False, use_sharp_edges_apply=True, use_data_match=True, + use_island_split=True, margin=margin, material_index=0, + use_interior_vgroup=False, mass_mode='VOLUME', mass=1, use_recenter=True, + use_remove_original=True, use_layer_index=0, use_layer_next=False, + group_name="", use_debug_points=False, use_debug_redraw=True, use_debug_bool=False + ) _makeJoin(active_name, active_layer) -# Join fractures into an object. + +# Join fractures into an object def _makeJoin(active_name, active_layer): - # Get object by name. - #bpy.context.scene.layers[active_layer+1] = True + # Get object by name bpy.ops.object.select_all(action='DESELECT') bpy.ops.object.select_pattern(pattern=active_name + '_cell*') fractures = bpy.context.selected_objects - - # Execute join. - bpy.context.scene.objects.active = fractures[0] - fractures[0].select = True - bpy.ops.object.join() - - # Change name. + + if fractures: + # Execute join + bpy.context.scene.objects.active = fractures[0] + fractures[0].select = True + bpy.ops.object.join() + else: + error_handlers( + False, "_makeJoin", "if fractures condition has not passed", + "Warning: No objects could be joined", True + ) + + # Change name bpy.context.scene.objects.active.name = active_name + '_crack' - - # Change origin. + + # Change origin bpy.ops.object.origin_set(type='GEOMETRY_ORIGIN') - - # Turn off the layer where original object is. - #bpy.context.scene.layers[active_layer] = False -# Add modifier and setting. + +# Add modifier and setting def addModifiers(): bpy.ops.object.modifier_add(type='DECIMATE') decimate = bpy.context.object.modifiers[-1] decimate.name = 'DECIMATE_crackit' decimate.ratio = 0.4 - + bpy.ops.object.modifier_add(type='SUBSURF') subsurf = bpy.context.object.modifiers[-1] subsurf.name = 'SUBSURF_crackit' - + bpy.ops.object.modifier_add(type='SMOOTH') smooth = bpy.context.object.modifiers[-1] smooth.name = 'SMOOTH_crackit' +# -------------- multi extrude -------------------- +# var1=random offset, var2=random rotation, var3=random scale +def multiExtrude(off=0.1, rotx=0, roty=0, rotz=0, sca=1.0, + var1=0.01, var2=0.3, var3=0.3, num=1, ran=0): -# --------------multi extrude-------------------- -# var1=random offset, var2=random rotation, var3=random scale. -def multiExtrude(off=0.1, rotx=0, roty=0, rotz=0, sca=1.0, var1=0.01, var2=0.3, var3=0.3, num=1, ran=0): obj = bpy.context.object - data, om = obj.data, obj.mode bpy.context.tool_settings.mesh_select_mode = [False, False, True] # bmesh operations @@ -92,7 +139,7 @@ def multiExtrude(off=0.1, rotx=0, roty=0, rotz=0, sca=1.0, var1=0.01, var2=0.3, nf.normal_update() no = nf.normal.copy() ce = nf.calc_center_bounds() - s = _vsca(r=i+r, ran=ran, var3=var3, sca=sca) + s = _vsca(r=i + r, ran=ran, var3=var3, sca=sca) for v in nf.verts: v.co -= ce @@ -102,82 +149,107 @@ def multiExtrude(off=0.1, rotx=0, roty=0, rotz=0, sca=1.0, var1=0.01, var2=0.3, # extrude code from TrumanBlending for a, b in zip(of.loops, nf.loops): - sf = bm.faces.new((a.vert, a.link_loop_next.vert, \ - b.link_loop_next.vert, b.vert)) + sf = bm.faces.new((a.vert, a.link_loop_next.vert, + b.link_loop_next.vert, b.vert)) sf.normal_update() bm.faces.remove(of) of = nf - for v in bm.verts: v.select = False - for e in bm.edges: e.select = False + for v in bm.verts: + v.select = False + + for e in bm.edges: + e.select = False + bm.to_mesh(obj.data) obj.data.update() - if not len(sel): - self.report({'INFO'}, "Select one or more faces...") - return{'FINISHED'} def _vloc(r, ran, off, var1): - random.seed(ran + r) - return off * (1 + random.gauss(0, var1 / 3)) + seed(ran + r) + return off * (1 + gauss(0, var1 / 3)) + def _vrot(r, ran, rotx, var2, roty, rotz): - random.seed(ran + r) - return Euler((radians(rotx) + random.gauss(0, var2 / 3), \ - radians(roty) + random.gauss(0, var2 / 3), \ - radians(rotz) + random.gauss(0, var2 / 3)), 'XYZ') + seed(ran + r) + return Euler((radians(rotx) + gauss(0, var2 / 3), + radians(roty) + gauss(0, var2 / 3), + radians(rotz) + gauss(0, var2 / 3)), 'XYZ') + def _vsca(r, ran, sca, var3): - random.seed(ran + r) - return sca * (1 + random.gauss(0, var3 / 3)) + seed(ran + r) + return sca * (1 + gauss(0, var3 / 3)) + -# centroide de una seleccion de vertices +# Centroid of a selection of vertices def _centro(ver): vvv = [v for v in ver if v.select] - if not vvv or len(vvv) == len(ver): return ('error') - x = sum([round(v.co[0],4) for v in vvv]) / len(vvv) - y = sum([round(v.co[1],4) for v in vvv]) / len(vvv) - z = sum([round(v.co[2],4) for v in vvv]) / len(vvv) - return (x,y,z) + if not vvv or len(vvv) == len(ver): + return ('error') + + x = sum([round(v.co[0], 4) for v in vvv]) / len(vvv) + y = sum([round(v.co[1], 4) for v in vvv]) / len(vvv) + z = sum([round(v.co[2], 4) for v in vvv]) / len(vvv) + + return (x, y, z) + -# recuperar el estado original del objeto +# Retrieve the original state of the object def _volver(obj, copia, om, msm, msv): - for i in copia: obj.data.vertices[i].select = True + for i in copia: + obj.data.vertices[i].select = True bpy.context.tool_settings.mesh_select_mode = msm + for i in range(len(msv)): obj.modifiers[i].show_viewport = msv[i] - -# --------------Material preset-------------------------- -def appendMaterial(addon_path, material_name): - # Load material from the addon directory. +# -------------- Material preset -------------------------- +def appendMaterial(addon_path, material_name, mat_ui_names="Nameless Material"): + # Load material from the addon directory file_path = _makeFilePath(addon_path=addon_path) bpy.ops.wm.append(filename=material_name, directory=file_path) - - # If material is loaded some times, select the last-loaded material. + + # If material is loaded some times, select the last-loaded material last_material = _getAppendedMaterial(material_name) - mat = bpy.data.materials[last_material] - - # Apply Only one material in the material slot. - for m in bpy.context.object.data.materials: - bpy.ops.object.material_slot_remove() - bpy.context.object.data.materials.append(mat) - -# Make file path of addon. + + if last_material: + mat = bpy.data.materials[last_material] + # skip renaming if the prop is True + if not bpy.context.scene.crackit.material_lib_name: + mat.name = mat_ui_names + + # Apply Only one material in the material slot + for m in bpy.context.object.data.materials: + bpy.ops.object.material_slot_remove() + + bpy.context.object.data.materials.append(mat) + + return True + + return False + + +# Make file path of addon def _makeFilePath(addon_path): material_folder = "/materials" blend_file = "/materials1.blend" category = "\\Material\\" - + file_path = addon_path + material_folder + blend_file + category return file_path -# Get last-loaded material, such as ~.002. + +# Get last-loaded material, such as ~.002 def _getAppendedMaterial(material_name): - # Get material name list. + # Get material name list material_names = [m.name for m in bpy.data.materials if material_name in m.name] - # Return last material in the sorted order. - material_names.sort() - return material_names[-1] + if material_names: + # Return last material in the sorted order + material_names.sort() + + return material_names[-1] + + return None diff --git a/object_fracture_crack/operator.py b/object_fracture_crack/operator.py index 5f1b51e7..d6b2da7b 100644 --- a/object_fracture_crack/operator.py +++ b/object_fracture_crack/operator.py @@ -1,111 +1,164 @@ +# gpl: author Nobuyuki Hirakata + import bpy +from bpy.types import ( + Operator, + Panel, + ) from . import crack_it -# Class for input and execution settings. -class FractureOperation(bpy.types.Operator): - bl_idname = 'mesh.crackit_fracture' # Access by bpy.ops.mesh.crackit_fracture. - bl_label = "Crack It!" # Label of button on menu. - bl_description = "Make crack by cell fracture addon." +def check_object_cell_fracture(): + if "object_fracture_cell" in bpy.context.user_preferences.addons.keys(): + return True + return False + + +# Access by bpy.ops.mesh.crackit_fracture +class FractureOperation(Operator): + bl_idname = "mesh.crackit_fracture" + bl_label = "Crack it!" + bl_description = ("Make cracks using the cell fracture add-on\n" + "Needs only one Selected Mesh Object") bl_options = {'REGISTER', 'UNDO'} - # Input after execution------------------------ - # Reference by self.~ in execute(). - - # ----------------------------------------- - - ''' @classmethod def poll(cls, context): - return (context.object is not None) - - ''' + obj = context.active_object + sel_obj = len(context.selected_objects) == 1 + + return (obj is not None and obj.type == "MESH" and sel_obj) def execute(self, context): - sce = context.scene - - crack_it.makeFracture(child_verts=sce.crackit_fracture_childverts, division=sce.crackit_fracture_div, - scaleX=sce.crackit_fracture_scalex, scaleY=sce.crackit_fracture_scaley, scaleZ=sce.crackit_fracture_scalez, - margin=sce.crackit_fracture_margin) - crack_it.addModifiers() - crack_it.multiExtrude(off=sce.crackit_extrude_offset, - var2=sce.crackit_extrude_random, var3=sce.crackit_extrude_random) - bpy.ops.object.shade_smooth() + if check_object_cell_fracture(): + crackit = context.scene.crackit + try: + crack_it.makeFracture( + child_verts=crackit.fracture_childverts, + division=crackit.fracture_div, scaleX=crackit.fracture_scalex, + scaleY=crackit.fracture_scaley, scaleZ=crackit.fracture_scalez, + margin=crackit.fracture_margin + ) + crack_it.addModifiers() + crack_it.multiExtrude( + off=crackit.extrude_offset, + var2=crackit.extrude_random, var3=crackit.extrude_random + ) + bpy.ops.object.shade_smooth() + + except Exception as e: + crack_it.error_handlers( + self, "mesh.crackit_fracture", e, "Crack It! could not be completed." + ) + return {"CANCELLED"} + else: + self.report({'WARNING'}, + "Depends on Object: Cell Fracture addon. Please enable it first. " + "Operation Cancelled" + ) + return {"CANCELLED"} + return {'FINISHED'} -# Apply material preset. -class MaterialOperation(bpy.types.Operator): - bl_idname = 'mesh.crackit_material' # Access by bpy.ops.mesh.crackit_material. - bl_label = "Apply Material" # Label of button on menu. - bl_description = "Apply a preset material" +# Apply material preset +# Access by bpy.ops.mesh.crackit_material +class MaterialOperation(Operator): + bl_idname = "mesh.crackit_material" + bl_label = "Apply Material" + bl_description = ("Apply a preset material\n" + "The Material will be applied to the Active Object\n" + "from the type of Mesh, Curve, Surface, Font, Meta") bl_options = {'REGISTER', 'UNDO'} - # Input after execution------------------------ - # Reference by self.~ in execute(). - - # ----------------------------------------- - - ''' @classmethod def poll(cls, context): - return (context.object is not None) - - ''' + obj = context.active_object + # included - type that can have materials + included = ['MESH', 'CURVE', 'SURFACE', 'FONT', 'META'] + return (obj is not None and obj.type in included) def execute(self, context): - sce = context.scene + crackit = context.scene.crackit + mat_name = crackit.material_preset + mat_lib_name = crackit.material_lib_name + mat_ui_name = crack_it.get_ui_mat_name(mat_name) if not mat_lib_name else mat_name + + try: + crack_it.appendMaterial( + addon_path=crackit.material_addonpath, + material_name=mat_name, + mat_ui_names=mat_ui_name + ) + except Exception as e: + crack_it.error_handlers( + self, "mesh.crackit_material", e, + "The active Object could not have the Material {} applied".format(mat_ui_name) + ) + return {"CANCELLED"} - crack_it.appendMaterial(addon_path=sce.crackit_material_addonpath, material_name=sce.crackit_material_preset) return {'FINISHED'} -# Menu settings. -class crackitPanel(bpy.types.Panel): - bl_label = "Crack it!" # title. - bl_idname = 'crack_it' # id to reference. - bl_space_type = 'VIEW_3D' # 3Dview. - bl_region_type = 'TOOLS' # make menu on tool shelf. - bl_category = 'Create' # Tab name on tool shelf. - bl_context = (('objectmode')) # Mode to show the menu. - - # Menu. + +# Menu settings +class crackitPanel(Panel): + bl_label = "Crack it!" + bl_idname = 'crack_it' + bl_space_type = "VIEW_3D" + bl_region_type = "TOOLS" + bl_category = "Create" + bl_context = 'objectmode' + bl_options = {"DEFAULT_CLOSED"} + def draw(self, context): - obj = context.object - sce = context.scene - layout = self.layout - - # Crack input - box = layout.box() - row = box.row() - row.label("Crack") - # Warning if fracture cell addon is not enabled. - if 'object_fracture_cell' not in bpy.context.user_preferences.addons.keys(): - row = box.row() - row.label("Note: Please enable 'Object: Cell Fracture' addon!") - row = box.row() - row.prop(sce, 'crackit_fracture_childverts') - row = box.row() - row.prop(sce, 'crackit_fracture_scalex') # bpy.types.Scene.crackit_fracture_scalex. - row = box.row() - row.prop(sce, 'crackit_fracture_scaley') - row = box.row() - row.prop(sce, 'crackit_fracture_scalez') - row = box.row() - row.prop(sce, 'crackit_fracture_div') - row = box.row() - row.prop(sce, 'crackit_fracture_margin') - row = box.row() - row.prop(sce, 'crackit_extrude_offset') - row = box.row() - row.prop(sce, 'crackit_extrude_random') - row = box.row() - row.operator(FractureOperation.bl_idname) # Execute button. - - # material Preset: - box = layout.box() - row = box.row() - row.label("Material Preset") - row = box.row() - row.prop(sce, 'crackit_material_preset') - row = box.row() - row.operator(MaterialOperation.bl_idname) # Execute button.
\ No newline at end of file + crackit = context.scene.crackit + layout = self.layout + + # Crack input + box = layout.box() + row = box.row() + + # Warning if the fracture cell addon is not enabled + if not check_object_cell_fracture(): + col = box.column() + col.label(text="Please enable Object: Cell Fracture addon", icon="INFO") + col.separator() + col.operator("wm.addon_userpref_show", + text="Go to Cell Fracture addon", + icon="PREFERENCES").module = "object_fracture_cell" + + layout.separator() + return + else: + row.operator(FractureOperation.bl_idname, icon="SPLITSCREEN") + + row = box.row() + row.prop(crackit, "fracture_childverts") + + col = box.column(align=True) + col.prop(crackit, "fracture_scalex") + col.prop(crackit, "fracture_scaley") + col.prop(crackit, "fracture_scalez") + + col = box.column(align=True) + col.label("Settings:") + col.prop(crackit, "fracture_div") + col.prop(crackit, "fracture_margin") + + col = box.column(align=True) + col.label("Extrude:") + col.prop(crackit, "extrude_offset") + col.prop(crackit, "extrude_random") + + # material Preset: + box = layout.box() + row = box.row() + row.label("Material Preset:") + row_sub = row.row() + row_sub.prop(crackit, "material_lib_name", text="", + toggle=True, icon="LONGDISPLAY") + row = box.row() + row.prop(crackit, "material_preset") + + row = box.row() + row.operator(MaterialOperation.bl_idname) |