diff options
-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) |