object_fracture_cell: Update add-on for 2.8x
Note, there is a remaining TODO: We should be able to initialize rigit-body data so the mass can be set.
This commit is contained in:
parent
3f68f8442a
commit
f1176bd276
Notes:
blender-bot
2023-02-14 19:19:54 +01:00
Referenced by issue #61901, Update Crackit addon for Blender 2.8
|
@ -19,14 +19,15 @@
|
|||
bl_info = {
|
||||
"name": "Cell Fracture",
|
||||
"author": "ideasman42, phymec, Sergey Sharybin",
|
||||
"version": (0, 1),
|
||||
"blender": (2, 70, 0),
|
||||
"location": "Edit panel of Tools tab, in Object mode, 3D View tools",
|
||||
"version": (0, 2),
|
||||
"blender": (2, 80, 0),
|
||||
"location": "Viewport Object Menu -> Quick Effects",
|
||||
"description": "Fractured Object, Bomb, Projectile, Recorder",
|
||||
"warning": "",
|
||||
"wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
|
||||
"Scripts/Object/CellFracture",
|
||||
"category": "Object"}
|
||||
"category": "Object",
|
||||
}
|
||||
|
||||
|
||||
#if "bpy" in locals():
|
||||
|
@ -57,9 +58,7 @@ def main_object(context, obj, level, **kw):
|
|||
recursion_clamp = kw_copy.pop("recursion_clamp")
|
||||
recursion_chance = kw_copy.pop("recursion_chance")
|
||||
recursion_chance_select = kw_copy.pop("recursion_chance_select")
|
||||
use_layer_next = kw_copy.pop("use_layer_next")
|
||||
use_layer_index = kw_copy.pop("use_layer_index")
|
||||
group_name = kw_copy.pop("group_name")
|
||||
collection_name = kw_copy.pop("collection_name")
|
||||
use_island_split = kw_copy.pop("use_island_split")
|
||||
use_debug_bool = kw_copy.pop("use_debug_bool")
|
||||
use_interior_vgroup = kw_copy.pop("use_interior_vgroup")
|
||||
|
@ -150,24 +149,11 @@ def main_object(context, obj, level, **kw):
|
|||
#--------------
|
||||
# Scene Options
|
||||
|
||||
# layer
|
||||
layers_new = None
|
||||
if use_layer_index != 0:
|
||||
layers_new = [False] * 20
|
||||
layers_new[use_layer_index - 1] = True
|
||||
elif use_layer_next:
|
||||
layers_new = [False] * 20
|
||||
layers_new[(obj.layers[:].index(True) + 1) % 20] = True
|
||||
|
||||
if layers_new is not None:
|
||||
for obj_cell in objects:
|
||||
obj_cell.layers = layers_new
|
||||
|
||||
# group
|
||||
if group_name:
|
||||
group = bpy.data.collections.get(group_name)
|
||||
if collection_name:
|
||||
group = bpy.data.collections.get(collection_name)
|
||||
if group is None:
|
||||
group = bpy.data.collections.new(group_name)
|
||||
group = bpy.data.collections.new(collection_name)
|
||||
group_objects = group.objects[:]
|
||||
for obj_cell in objects:
|
||||
if obj_cell not in group_objects:
|
||||
|
@ -201,9 +187,12 @@ def main(context, **kw):
|
|||
for obj_cell in objects:
|
||||
obj_cell.select_set(True)
|
||||
|
||||
# FIXME(campbell): we should be able to initialize rigid-body data.
|
||||
if mass_mode == 'UNIFORM':
|
||||
for obj_cell in objects:
|
||||
obj_cell.game.mass = mass
|
||||
rb = obj_cell.rigid_body
|
||||
if rb is not None:
|
||||
rb.mass = mass
|
||||
elif mass_mode == 'VOLUME':
|
||||
from mathutils import Vector
|
||||
def _get_volume(obj_cell):
|
||||
|
@ -237,7 +226,9 @@ def main(context, **kw):
|
|||
if obj_volume_tot > 0.0:
|
||||
mass_fac = mass / obj_volume_tot
|
||||
for i, obj_cell in enumerate(objects):
|
||||
obj_cell.game.mass = obj_volume_ls[i] * mass_fac
|
||||
rb = obj_cell.rigid_body
|
||||
if rb is not None:
|
||||
rb.mass = obj_volume_ls[i] * mass_fac
|
||||
else:
|
||||
assert(0)
|
||||
|
||||
|
@ -259,7 +250,7 @@ class FractureCell(Operator):
|
|||
"source object")),
|
||||
('PARTICLE_CHILD', "Child Particles", ("All particle systems of the "
|
||||
"child objects")),
|
||||
('PENCIL', "Grease Pencil", "This object's grease pencil"),
|
||||
('PENCIL', "Annotations", "Use points from visible annotation"),
|
||||
),
|
||||
options={'ENUM_FLAG'},
|
||||
default={'PARTICLE_OWN'},
|
||||
|
@ -420,22 +411,9 @@ class FractureCell(Operator):
|
|||
# .. different from object options in that this controls how the objects
|
||||
# are setup in the scene.
|
||||
|
||||
use_layer_index: IntProperty(
|
||||
name="Layer Index",
|
||||
description="Layer to add the objects into or 0 for existing",
|
||||
default=0,
|
||||
min=0, max=20,
|
||||
)
|
||||
|
||||
use_layer_next: BoolProperty(
|
||||
name="Next Layer",
|
||||
description="At the object into the next layer (layer index overrides)",
|
||||
default=True,
|
||||
)
|
||||
|
||||
group_name: StringProperty(
|
||||
name="Group",
|
||||
description="Create objects int a group "
|
||||
collection_name: StringProperty(
|
||||
name="Collection",
|
||||
description="Create objects in a collection "
|
||||
"(use existing or create new)",
|
||||
)
|
||||
|
||||
|
@ -534,9 +512,7 @@ class FractureCell(Operator):
|
|||
col = box.column()
|
||||
col.label(text="Scene")
|
||||
rowsub = col.row(align=True)
|
||||
rowsub.prop(self, "use_layer_index")
|
||||
rowsub.prop(self, "use_layer_next")
|
||||
rowsub.prop(self, "group_name")
|
||||
rowsub.prop(self, "collection_name")
|
||||
|
||||
box = layout.box()
|
||||
col = box.column()
|
||||
|
@ -549,19 +525,18 @@ class FractureCell(Operator):
|
|||
|
||||
def menu_func(self, context):
|
||||
layout = self.layout
|
||||
layout.label(text="Cell Fracture:")
|
||||
layout.operator("object.add_fracture_cell_objects",
|
||||
text="Cell Fracture")
|
||||
layout.separator()
|
||||
layout.operator("object.add_fracture_cell_objects", text="Cell Fracture")
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(FractureCell)
|
||||
bpy.types.VIEW3D_PT_tools_object.append(menu_func)
|
||||
bpy.types.VIEW3D_MT_object_quick_effects.append(menu_func)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(FractureCell)
|
||||
bpy.types.VIEW3D_PT_tools_object.remove(menu_func)
|
||||
bpy.types.VIEW3D_MT_object_quick_effects.remove(menu_func)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -30,7 +30,7 @@ _redraw_yasiamevil.opr = bpy.ops.wm.redraw_timer
|
|||
_redraw_yasiamevil.arg = dict(type='DRAW_WIN_SWAP', iterations=1)
|
||||
|
||||
|
||||
def _points_from_object(obj, source):
|
||||
def _points_from_object(scene, obj, source):
|
||||
|
||||
_source_all = {
|
||||
'PARTICLE_OWN', 'PARTICLE_CHILD',
|
||||
|
@ -63,7 +63,7 @@ def _points_from_object(obj, source):
|
|||
if obj.type == 'MESH':
|
||||
mesh = obj.data
|
||||
matrix = obj.matrix_world.copy()
|
||||
points.extend([matrix * v.co for v in mesh.vertices])
|
||||
points.extend([matrix @ v.co for v in mesh.vertices])
|
||||
else:
|
||||
depsgraph = bpy.context.evaluated_depsgraph_get()
|
||||
ob_eval = ob.evaluated_get(depsgraph)
|
||||
|
@ -74,7 +74,7 @@ def _points_from_object(obj, source):
|
|||
|
||||
if mesh is not None:
|
||||
matrix = obj.matrix_world.copy()
|
||||
points.extend([matrix * v.co for v in mesh.vertices])
|
||||
points.extend([matrix @ v.co for v in mesh.vertices])
|
||||
ob_eval.to_mesh_clear()
|
||||
|
||||
def points_from_particles(obj):
|
||||
|
@ -111,7 +111,8 @@ def _points_from_object(obj, source):
|
|||
return []
|
||||
|
||||
if 'PENCIL' in source:
|
||||
gp = obj.grease_pencil
|
||||
# Used to be from object in 2.7x, now from scene.
|
||||
gp = scene.grease_pencil
|
||||
if gp:
|
||||
points.extend([p for spline in get_splines(gp)
|
||||
for p in spline])
|
||||
|
@ -137,17 +138,18 @@ def cell_fracture_objects(context, obj,
|
|||
):
|
||||
|
||||
from . import fracture_cell_calc
|
||||
scene = context.scene
|
||||
collection = context.collection
|
||||
view_layer = context.view_layer
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# GET POINTS
|
||||
|
||||
points = _points_from_object(obj, source)
|
||||
points = _points_from_object(scene, obj, source)
|
||||
|
||||
if not points:
|
||||
# print using fallback
|
||||
points = _points_from_object(obj, {'VERT_OWN'})
|
||||
points = _points_from_object(scene, obj, {'VERT_OWN'})
|
||||
|
||||
if not points:
|
||||
print("no points found")
|
||||
|
@ -174,7 +176,7 @@ def cell_fracture_objects(context, obj,
|
|||
# boundbox approx of overall scale
|
||||
from mathutils import Vector
|
||||
matrix = obj.matrix_world.copy()
|
||||
bb_world = [matrix * Vector(v) for v in obj.bound_box]
|
||||
bb_world = [matrix @ Vector(v) for v in obj.bound_box]
|
||||
scalar = source_noise * ((bb_world[0] - bb_world[6]).length / 2.0)
|
||||
|
||||
from mathutils.noise import random_unit_vector
|
||||
|
@ -194,7 +196,7 @@ def cell_fracture_objects(context, obj,
|
|||
|
||||
mesh = obj.data
|
||||
matrix = obj.matrix_world.copy()
|
||||
verts = [matrix * v.co for v in mesh.vertices]
|
||||
verts = [matrix @ v.co for v in mesh.vertices]
|
||||
|
||||
cells = fracture_cell_calc.points_as_bmesh_cells(verts,
|
||||
points,
|
||||
|
@ -270,7 +272,7 @@ def cell_fracture_objects(context, obj,
|
|||
mesh_src = obj.data
|
||||
for mat in mesh_src.materials:
|
||||
mesh_dst.materials.append(mat)
|
||||
for lay_attr in ("vertex_colors", "uv_textures"):
|
||||
for lay_attr in ("vertex_colors", "uv_layers"):
|
||||
lay_src = getattr(mesh_src, lay_attr)
|
||||
lay_dst = getattr(mesh_dst, lay_attr)
|
||||
for key in lay_src.keys():
|
||||
|
@ -301,13 +303,6 @@ def cell_fracture_objects(context, obj,
|
|||
|
||||
view_layer.update()
|
||||
|
||||
# move this elsewhere...
|
||||
for obj_cell in objects:
|
||||
game = obj_cell.game
|
||||
game.physics_type = 'RIGID_BODY'
|
||||
game.use_collision_bounds = True
|
||||
game.collision_bounds_type = 'CONVEX_HULL'
|
||||
|
||||
return objects
|
||||
|
||||
|
||||
|
@ -400,9 +395,13 @@ def cell_fracture_boolean(context, obj, objects,
|
|||
for obj_cell in objects_boolean:
|
||||
obj_cell.select_set(True)
|
||||
|
||||
objects_before = set(scene.objects)
|
||||
|
||||
bpy.ops.mesh.separate(type='LOOSE')
|
||||
|
||||
objects_boolean[:] = [obj_cell for obj_cell in scene.objects if obj_cell.select]
|
||||
objects_boolean[:] = [obj_cell for obj_cell in scene.objects if obj_cell not in objects_before]
|
||||
|
||||
del objects_before
|
||||
|
||||
context.view_layer.update()
|
||||
|
||||
|
@ -441,7 +440,6 @@ def cell_fracture_interior_handle(objects,
|
|||
obj_cell.vertex_groups.new(name="Interior")
|
||||
|
||||
if use_sharp_edges:
|
||||
mesh.show_edge_sharp = True
|
||||
for bm_edge in bm.edges:
|
||||
if len({bm_face.hide for bm_face in bm_edge.link_faces}) == 2:
|
||||
bm_edge.smooth = False
|
||||
|
|
Loading…
Reference in New Issue