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:
Diffstat (limited to 'object_fracture_crack/crack_it.py')
-rw-r--r--object_fracture_crack/crack_it.py240
1 files changed, 156 insertions, 84 deletions
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