diff options
author | meta-androcto <meta.androcto1@gmail.com> | 2019-07-06 12:36:15 +0300 |
---|---|---|
committer | meta-androcto <meta.androcto1@gmail.com> | 2019-07-06 12:36:15 +0300 |
commit | 64d89567923df223f50eeeaa2f79f93f23da74f6 (patch) | |
tree | 5ff138a6a2264359bbf8b9047cd010727be9d0dc /object_fracture_cell | |
parent | 686f1f149ef0c0cd66480ff52b8db8f72772d12d (diff) |
object_fracture_cell: fix for bool method, tidy ui, clean white space: T61901
Diffstat (limited to 'object_fracture_cell')
-rw-r--r-- | object_fracture_cell/__init__.py | 58 | ||||
-rw-r--r-- | object_fracture_cell/operator.py | 121 | ||||
-rw-r--r-- | object_fracture_cell/process/cell_calc.py | 36 | ||||
-rw-r--r-- | object_fracture_cell/process/cell_functions.py | 136 | ||||
-rw-r--r-- | object_fracture_cell/process/cell_main.py | 56 | ||||
-rw-r--r-- | object_fracture_cell/process/crack_functions.py | 10 | ||||
-rw-r--r-- | object_fracture_cell/process/material_functions.py | 2 | ||||
-rw-r--r-- | object_fracture_cell/utilities.py | 8 |
8 files changed, 223 insertions, 204 deletions
diff --git a/object_fracture_cell/__init__.py b/object_fracture_cell/__init__.py index d7adc80f..794c2fe1 100644 --- a/object_fracture_cell/__init__.py +++ b/object_fracture_cell/__init__.py @@ -19,7 +19,7 @@ bl_info = { "name": "Cell Fracture", "author": "ideasman42, phymec, Sergey Sharybin, Nobuyuki Hirakata", - "version": (1, 0, 1), + "version": (1, 0, 2), "blender": (2, 80, 0), "location": "View3D > Sidebar > Transform tab", "description": "Fractured Object, or Cracked Surface", @@ -51,7 +51,7 @@ from bpy.props import ( from bpy.types import ( Panel, PropertyGroup, - ) + ) class FRACTURE_PT_Menu(Panel): @@ -59,19 +59,19 @@ class FRACTURE_PT_Menu(Panel): bl_label = "Fracture Cell" bl_space_type = "VIEW_3D" bl_region_type = "UI" - bl_category = "Transform" + bl_category = "Create" bl_context = 'objectmode' bl_options = {"DEFAULT_CLOSED"} - + def draw(self, context): # Show pop-upped menu when the button is hit. layout = self.layout #layout.label(text="Cell Fracture:") layout.operator(operator.FRACTURE_OT_Cell.bl_idname, - text="1. Cell Fracture") + text="1. Cell Fracture") layout.operator(operator.FRACTURE_OT_Crack.bl_idname, text="2. Cell to Crack") - + material_props = context.window_manager.fracture_material_props layout.separator() box = layout.box() @@ -88,10 +88,10 @@ class FRACTURE_PT_Menu(Panel): row = box.row() row.operator(operator.FRACTURE_OT_Material.bl_idname, icon="MATERIAL_DATA", - text="Append Material") + text="Append Material") -class FractureCellProperties(PropertyGroup): +class FractureCellProperties(PropertyGroup): # ------------------------------------------------------------------------- # Source Options source_vert_own: IntProperty( @@ -130,16 +130,16 @@ class FractureCellProperties(PropertyGroup): min=0, max=2000, default=0, ) - ''' + ''' source_limit: IntProperty( name="Source Limit", description="Limit the number of input points, 0 for unlimited", min=0, max=5000, default=100, ) - ''' + ''' # ------------------------------------------------------------------------- - # Transform + # Transform source_noise: FloatProperty( name="Noise", description="Randomize point distribution", @@ -187,7 +187,7 @@ class FractureCellProperties(PropertyGroup): recursion_source_limit: IntProperty( name="Fracture Each", description="Limit the number of input points, 0 for unlimited (applies to recursion only)", - min=2, max=2000, # Oviously, dividing in more than two objects is needed, to avoid no fracture object. + min=2, max=2000, # Oviously, dividing in more than two objects is needed, to avoid no fracture object. default=8, ) recursion_clamp: IntProperty( @@ -197,7 +197,7 @@ class FractureCellProperties(PropertyGroup): default=250, ) recursion_chance: FloatProperty( - name="Recursion Chance", + name="Rec Chance", description="Likelihood of recursion", min=0.0, max=1.0, default=1.00, @@ -245,17 +245,17 @@ class FractureCellProperties(PropertyGroup): default=False, ) # ------------------------------------------------------------------------- - # Scene Options + # Scene Options use_collection: BoolProperty( name="Use Collection", description="Use collection to organize fracture objects", default=True, - ) + ) new_collection: BoolProperty( - name="New Collection", + name="Use New", description="Make new collection for fracture objects", default=True, - ) + ) collection_name: StringProperty( name="Name", description="Collection name.", @@ -272,12 +272,12 @@ class FractureCellProperties(PropertyGroup): default=False, ) # ------------------------------------------------------------------------- - # Custom Property Options + # Custom Property Options use_mass: BoolProperty( name="Mass", description="Append mass data on custom properties of cell objects.", default=False, - ) + ) mass_name: StringProperty( name="Property Name", description="Name for custome properties.", @@ -316,7 +316,7 @@ class FractureCellProperties(PropertyGroup): default=False, ) - + class FractureCrackProperties(PropertyGroup): modifier_decimate : FloatProperty( name="Reduce Faces", @@ -357,10 +357,10 @@ class FractureCrackProperties(PropertyGroup): name="Wireframe Modifier", description="Wireframe Modifier", default=False - ) + ) -class FractureMaterialProperties(PropertyGroup): +class FractureMaterialProperties(PropertyGroup): # Note: you can choose the original name in the library blend # or the prop name material_preset : EnumProperty( @@ -384,7 +384,7 @@ class FractureMaterialProperties(PropertyGroup): "instead of the one defined in the Preset", default=True ) - + classes = ( FractureCellProperties, FractureCrackProperties, @@ -408,13 +408,17 @@ def register(): ) bpy.types.WindowManager.fracture_material_props = PointerProperty( type=FractureMaterialProperties - ) - + ) + def unregister(): del bpy.types.WindowManager.fracture_material_props del bpy.types.WindowManager.fracture_crack_props del bpy.types.WindowManager.fracture_cell_props - + from bpy.utils import unregister_class for cls in reversed(classes): - unregister_class(cls)
\ No newline at end of file + unregister_class(cls) + +if __name__ == "__main__": + register() + diff --git a/object_fracture_cell/operator.py b/object_fracture_cell/operator.py index cd8dca00..7bc35a46 100644 --- a/object_fracture_cell/operator.py +++ b/object_fracture_cell/operator.py @@ -24,27 +24,32 @@ class FRACTURE_OT_Cell(Operator): bl_description = "Make fractured cells from selected object." bl_options = {'REGISTER', 'UNDO'} - def execute(self, context): + @classmethod + def poll(cls, context): + obj = context.active_object + return obj and obj.type == "MESH" + + def execute(self, context): #keywords = self.as_keywords() # ignore=("blah",) - + fracture_cell_props = context.window_manager.fracture_cell_props cell_keywords = utilities._cell_props_to_dict(fracture_cell_props) - - originals = context.selected_editable_objects + + originals = context.selected_editable_objects for original in originals: cell_main.main(context, original, **cell_keywords) - + return {'FINISHED'} def invoke(self, context, event): wm = context.window_manager - return wm.invoke_props_dialog(self, width=600) - - def draw(self, context): + return wm.invoke_props_dialog(self, width=350) + + def draw(self, context): cell_props = context.window_manager.fracture_cell_props - + layout = self.layout - + box = layout.box() col = box.column() col.label(text="Fracture From") @@ -52,23 +57,24 @@ class FRACTURE_OT_Cell(Operator): #row.prop(cell_props, "source") row.prop(cell_props, "source_vert_own") row.prop(cell_props, "source_particle_own") - row.prop(cell_props, "source_random") row = col.row() + row.prop(cell_props, "source_random") row.prop(cell_props, "source_vert_child") + row = col.row() row.prop(cell_props, "source_particle_child") row.prop(cell_props, "source_pencil") - + box = layout.box() col = box.column() col.label(text="Transform") row = col.row() row.prop(cell_props, "pre_simplify") row.prop(cell_props, "source_noise") + row = col.row(align=True) row.prop(cell_props, "margin") + row.prop(cell_props, "use_recenter") row = col.row(align=True) - row.prop(cell_props, "cell_scale") - row.prop(cell_props, "use_recenter") # could be own section, control how we subdiv #row.prop(cell_props, "use_island_split") @@ -76,38 +82,37 @@ class FRACTURE_OT_Cell(Operator): col = box.column() col.label(text="Recursive Shatter") row = col.row(align=True) - row.alignment = 'LEFT' row.prop(cell_props, "recursion") + row.prop(cell_props, "recursion_chance") row = col.row(align=True) - row.alignment = 'LEFT' if cell_props.recursion > 0: row.enabled = True else: row.enabled = False row.prop(cell_props, "recursion_source_limit") row.prop(cell_props, "recursion_clamp") - row.prop(cell_props, "recursion_chance") + row = col.row() row.prop(cell_props, "recursion_chance_select")#, expand=True) box = layout.box() col = box.column() col.label(text="Interior Meshes") row = col.row(align=True) - row.alignment = 'LEFT' - row.prop(cell_props, "use_data_match") + row.prop(cell_props, "use_data_match") row.prop(cell_props, "use_interior_vgroup") - row.prop(cell_props, "use_smooth_faces") + row = col.row(align=True) + row.prop(cell_props, "use_smooth_faces") row.prop(cell_props, "use_sharp_edges") if cell_props.use_sharp_edges == True: row.prop(cell_props, "use_sharp_edges_apply") - + row = col.row() if cell_props.use_data_match == True: row.enabled = True else: row.enabled = False row.alignment = 'LEFT' - # on same row for even layout but infact are not all that related + # on same row for even layout but infact are not all that related row.prop(cell_props, "material_index") box = layout.box() @@ -121,28 +126,31 @@ class FRACTURE_OT_Cell(Operator): row = col.row(align=True) row.prop(cell_props, "mass_mode") row.prop(cell_props, "mass") - + box = layout.box() col = box.column() - col.label(text="Scene Management") + col.label(text="Object Management") row = col.row(align=True) - row.alignment = 'LEFT' row.prop(cell_props, "original_hide") row.prop(cell_props, "cell_relocate") + + box = layout.box() + col = box.column() + col.label(text="Collections:") row = col.row(align=True) row.prop(cell_props, "use_collection") if cell_props.use_collection: row.prop(cell_props, "new_collection") row.prop(cell_props, "collection_name") - + box = layout.box() col = box.column() col.label(text="Debug") row = col.row(align=True) - row.prop(cell_props, "use_debug_redraw") row.prop(cell_props, "use_debug_points") row.prop(cell_props, "use_debug_bool") - + row = col.row(align=True) + row.prop(cell_props, "use_debug_redraw") class FRACTURE_OT_Crack(Operator): bl_idname = "object.add_fracture_crack" @@ -150,36 +158,41 @@ class FRACTURE_OT_Crack(Operator): bl_description = "Make a cracked object from cell objects" bl_options = {'REGISTER', 'UNDO'} + @classmethod + def poll(cls, context): + obj = context.active_object + return obj and obj.type == "MESH" + def invoke(self, context, event): wm = context.window_manager - return wm.invoke_props_dialog(self, width=600) - - def execute(self, context): + return wm.invoke_props_dialog(self, width=350) + + def execute(self, context): crack_props = context.window_manager.fracture_crack_props - + cells = context.selected_editable_objects object = None - - if cells: + + if cells: # clear sharp edges for correct crack surface. bpy.context.view_layer.objects.active = cells[0] bpy.ops.object.mode_set(mode='EDIT') bpy.ops.mesh.reveal() - + bpy.ops.mesh.mark_sharp(clear=True, use_verts=True) - bpy.ops.object.mode_set(mode='OBJECT') - + bpy.ops.object.mode_set(mode='OBJECT') + for cell in cells: bpy.context.view_layer.objects.active = cell bpy.ops.object.modifier_remove(modifier="EDGE_SPLIT_cell") bpy.context.object.vertex_groups.clear() - + bpy.context.view_layer.objects.active = cells[0] object = crack_functions.make_join(cells) - + if object: bpy.context.view_layer.objects.active = object - + crack_functions.add_modifiers() bpy.context.object.modifiers['DECIMATE_crackit'].ratio = crack_props.modifier_decimate bpy.context.object.modifiers['SMOOTH_crackit'].factor = crack_props.modifier_smooth @@ -193,19 +206,19 @@ class FRACTURE_OT_Crack(Operator): ) bpy.ops.object.modifier_apply(apply_as='DATA', modifier='DECIMATE_crackit') bpy.ops.object.shade_smooth() - + if crack_props.modifier_wireframe == True: bpy.ops.object.modifier_add(type='WIREFRAME') wireframe = bpy.context.object.modifiers[-1] wireframe.name = 'WIREFRAME_crackit' wireframe.use_even_offset = False - wireframe.thickness = 0.01 + wireframe.thickness = 0.01 else: assert("Joining into One object had been failed. Mesh object can only be joined.") - + return {'FINISHED'} - def draw(self, context): + def draw(self, context): cell_props = context.window_manager.fracture_cell_props crack_props = context.window_manager.fracture_crack_props layout = self.layout @@ -213,7 +226,7 @@ class FRACTURE_OT_Crack(Operator): box = layout.box() col = box.column() col.label(text='* Execute After "1. Cell Fracture"') - + box = layout.box() col = box.column() col.label(text="Surface:") @@ -221,20 +234,20 @@ class FRACTURE_OT_Crack(Operator): row.alignment = 'LEFT' row.prop(crack_props, "modifier_decimate") row.prop(crack_props, "modifier_smooth") - + col = box.column() - col.label(text="Extrude:") - row = col.row(align=True) + col.label(text="Extrude:") + row = col.row(align=True) row.prop(crack_props, "extrude_scale") row.prop(crack_props, "extrude_var") row.prop(crack_props, "extrude_num") - - col = box.column() + + col = box.column() col.label(text="Post Processing") row = col.row(align=True) row.prop(crack_props, "modifier_wireframe") - - + + class FRACTURE_OT_Material(Operator): bl_idname = "object.add_fracture_material" bl_label = "Material Preset" @@ -248,9 +261,9 @@ class FRACTURE_OT_Material(Operator): included = ['MESH', 'CURVE', 'SURFACE', 'FONT', 'META'] return (obj is not None and obj.type in included) - def execute(self, context): + def execute(self, context): material_props = context.window_manager.fracture_material_props - + mat_name = material_props.material_preset mat_lib_name = material_props.material_lib_name mat_ui_name = material_props.get_ui_mat_name(mat_name) if not mat_lib_name else mat_name diff --git a/object_fracture_cell/process/cell_calc.py b/object_fracture_cell/process/cell_calc.py index 272ebff1..9541e5f5 100644 --- a/object_fracture_cell/process/cell_calc.py +++ b/object_fracture_cell/process/cell_calc.py @@ -46,14 +46,14 @@ def points_to_verts(original_xyz_minmax, xmin, xmax = original_xyz_minmax["x"] ymin, ymax = original_xyz_minmax["y"] zmin, zmax = original_xyz_minmax["z"] - + xmin -= margin_bounds xmax += margin_bounds ymin -= margin_bounds ymax += margin_bounds zmin -= margin_bounds zmax += margin_bounds - + # (x,y,z,scaler) for plane. xyz is normaliized direction. scaler is scale for plane. # Plane will be made at the perpendicular direction of the normal vector. convexPlanes = [ @@ -64,33 +64,33 @@ def points_to_verts(original_xyz_minmax, Vector((0.0, 0.0, +1.0, -zmax)), Vector((0.0, 0.0, -1.0, +zmin)), ] - + if len(points) > 1: points_dist_sorted = [(Vector(p[0]), p[1]) for p in points] - + for i, point_current in enumerate(points): planes = [None] * len(convexPlanes) for j in range(len(convexPlanes)): - planes[j] = convexPlanes[j].copy() + planes[j] = convexPlanes[j].copy() # e.g. Dot product point's (xyz) with convex's (+1.0,0.0,0.0) detects x value of the point. # e.g. Then, x scaler += point's x value. planes[j][3] += planes[j].xyz.dot(point_current[0]) - + distance_max = 10000000000.0 # a big value! - + points_dist_sorted_current = points_dist_sorted.copy() # Closer points to the current point are earlier order. Of course, current point is the first. points_dist_sorted_current.sort(key=lambda p: (p[0] - point_current[0]).length_squared) - + # The point itself is removed. - points_dist_sorted_current.pop(0) - + points_dist_sorted_current.pop(0) + # Compare the current point with other points. for j in range(len(points_dist_sorted_current)): point_target = points_dist_sorted_current[j] - normal = 0 - normal = point_target[0] - point_current[0] + normal = 0 + normal = point_target[0] - point_current[0] nlength = normal.length # is sqrt(X^2+y^2+z^2). if points_scale is not None: @@ -115,7 +115,7 @@ def points_to_verts(original_xyz_minmax, plane.resize_4d() plane[3] = (-nlength / 2.0) + margin_cell planes.append(plane) - + # Make vertex points of cell, by crossing point of planes. vertices[:], plane_indices[:] = mathutils.geometry.points_in_planes(planes) #if len(vertices) == 0: @@ -125,7 +125,7 @@ def points_to_verts(original_xyz_minmax, planes[:] = [planes[k] for k in plane_indices] # for comparisons use length_squared and delay - # converting to a real length until the end. + # converting to a real length until the end. distance_max = 10000000000.0 # a big value! for v in vertices: distance = v.length_squared @@ -136,14 +136,14 @@ def points_to_verts(original_xyz_minmax, if len(vertices) == 0: continue - + cells.append((point_current[0], vertices[:])) - del vertices[:] - + del vertices[:] + else: vertices[:], plane_indices[:] = mathutils.geometry.points_in_planes(convexPlanes) #convex_center = Vector(((xmin-xmax)/2, (ymin-ymax)/2, (zmin-zmax)/2)) convex_center = Vector((0,0,0)) cells.append((convex_center, vertices[:])) - + return cells
\ No newline at end of file diff --git a/object_fracture_cell/process/cell_functions.py b/object_fracture_cell/process/cell_functions.py index 80f77870..026bdc53 100644 --- a/object_fracture_cell/process/cell_functions.py +++ b/object_fracture_cell/process/cell_functions.py @@ -45,14 +45,14 @@ def points_from_object(original, original_xyz_minmax, source_particle_child=0, source_pencil=0, source_random=0): - + points = [] - + # This is not used by anywhere def edge_center(mesh, edge): v1, v2 = edge.vertices return (mesh.vertices[v1].co + mesh.vertices[v2].co) / 2.0 - + # This is not used by anywhere def poly_center(mesh, poly): from mathutils import Vector @@ -62,13 +62,13 @@ def points_from_object(original, original_xyz_minmax, co += mesh.vertices[mesh.loops[i].vertex_index].co tot += 1 return co / tot - + def points_from_verts(original): """Takes points from _any_ object with geometry""" if original.type == 'MESH': mesh = original.data - matrix = original.matrix_world.copy() - p = [(matrix @ v.co, 'VERTS') for v in mesh.vertices] + matrix = original.matrix_world.copy() + p = [(matrix @ v.co, 'VERTS') for v in mesh.vertices] return p else: depsgraph = bpy.context.evaluated_depsgraph_get() @@ -78,21 +78,21 @@ def points_from_object(original, original_xyz_minmax, except: mesh = None - if mesh is not None: + if mesh is not None: matrix = original.matrix_world.copy() - p = [(matrix @ v.co, 'VERTS') for v in mesh.vertices] + p = [(matrix @ v.co, 'VERTS') for v in mesh.vertices] ob_eval.to_mesh_clear() return p def points_from_particles(original): depsgraph = bpy.context.evaluated_depsgraph_get() obj_eval = original.evaluated_get(depsgraph) - + p = [(particle.location.copy(), 'PARTICLE') for psys in obj_eval.particle_systems for particle in psys.particles] return p - + def points_from_random(original, original_xyz_minmax): xmin, xmax = original_xyz_minmax["x"] ymin, ymax = original_xyz_minmax["y"] @@ -100,19 +100,19 @@ def points_from_object(original, original_xyz_minmax, from random import uniform from mathutils import Vector - + p = [] for i in range(source_random): new_pos = Vector( (uniform(xmin, xmax), uniform(ymin, ymax), uniform(zmin, zmax)) ) - p.append((new_pos, 'RANDOM')) - return p - + p.append((new_pos, 'RANDOM')) + return p + # geom own if source_vert_own > 0: new_points = points_from_verts(original) new_points = _limit_source(new_points, source_vert_own) points.extend(new_points) - + # random if source_random > 0: new_points = points_from_random(original, original_xyz_minmax) @@ -125,7 +125,7 @@ def points_from_object(original, original_xyz_minmax, new_points = points_from_verts(original_child) new_points = _limit_source(new_points, source_vert_child) points.extend(new_points) - + # geom particles if source_particle_own > 0: new_points = points_from_particles(original) @@ -151,13 +151,13 @@ def points_from_object(original, original_xyz_minmax, gpl.frames.new(current) gpl.active_frame = current fr = gpl.active_frame - - return [get_points(stroke) for stroke in fr.strokes] + + return [get_points(stroke) for stroke in fr.strokes] else: return [] - if source_pencil > 0: - gp = bpy.context.scene.grease_pencil + if source_pencil > 0: + gp = bpy.context.scene.grease_pencil if gp: line_points = [] line_points = [(p, 'PENCIL') for spline in get_splines(gp) @@ -168,17 +168,17 @@ def points_from_object(original, original_xyz_minmax, # Make New point between the line point and the closest point. if not points: points.extend(line_points) - + else: for lp in line_points: # Make vector between the line point and its closest point. points.sort(key=lambda p: (p[0] - lp[0]).length_squared) - closest_point = points[0] + closest_point = points[0] normal = lp[0].xyz - closest_point[0].xyz - + new_point = (lp[0], lp[1]) new_point[0].xyz += normal / 2 - + points.append(new_point) #print("Found %d points" % len(points)) return points @@ -186,7 +186,7 @@ def points_from_object(original, original_xyz_minmax, def points_to_cells(context, original, original_xyz_minmax, points, source_limit=0, - source_noise=0.0, + source_noise=0.0, use_smooth_faces=False, use_data_match=False, use_debug_points=False, @@ -199,16 +199,16 @@ def points_to_cells(context, original, original_xyz_minmax, points, from . import cell_calc collection = context.collection view_layer = context.view_layer - + # apply optional clamp if source_limit != 0 and source_limit < len(points): points = _limit_source(points, source_limit) - + # saddly we cant be sure there are no doubles from mathutils import Vector to_tuple = Vector.to_tuple - - # To remove doubles, round the values. + + # To remove doubles, round the values. points = [(Vector(to_tuple(p[0], 4)),p[1]) for p in points] del to_tuple del Vector @@ -234,11 +234,11 @@ def points_to_cells(context, original, original_xyz_minmax, points, obj_tmp = bpy.data.objects.new(name=mesh_tmp.name, object_data=mesh_tmp) collection.objects.link(obj_tmp) del obj_tmp, mesh_tmp - + cells_verts = cell_calc.points_to_verts(original_xyz_minmax, points, cell_scale, - margin_cell=margin) + margin_cell=margin) # some hacks here :S cell_name = original.name + "_cell" cells = [] @@ -247,13 +247,13 @@ def points_to_cells(context, original, original_xyz_minmax, points, # BMESH # create the convex hulls bm = bmesh.new() - + # WORKAROUND FOR CONVEX HULL BUG/LIMIT # XXX small noise import random def R(): return (random.random() - 0.5) * 0.001 - + for i, co in enumerate(cell_verts): co.x += R() co.y += R() @@ -328,7 +328,7 @@ def points_to_cells(context, original, original_xyz_minmax, points, view_layer.update() # move this elsewhere... # Blender 2.8: BGE integration was disabled, -- - # -- because BGE was deleted in Blender 2.8. + # -- because BGE was deleted in Blender 2.8. ''' for cell in cells: game = cell.game @@ -353,51 +353,54 @@ def cell_boolean(context, original, cells, collection = context.collection scene = context.scene view_layer = context.view_layer - + if use_interior_hide and level == 0: # only set for level 0 - original.data.polygons.foreach_set("hide", [False] * len(original.data.polygons)) - + original.data.polygons.foreach_set("hide", [False] * len(original.data.polygons)) + # The first object can't be applied by bool, so it is used as a no-effect first straw-man. bpy.ops.mesh.primitive_cube_add(enter_editmode=False, location=(original.location.x+10000000000.0, 0, 0)) temp_cell = bpy.context.active_object cells.insert(0, temp_cell) - - bpy.ops.object.select_all(action='DESELECT') + + bpy.ops.object.select_all(action='DESELECT') for i, cell in enumerate(cells): + mod = cell.modifiers.new(name="Boolean", type='BOOLEAN') + mod.object = original + mod.operation = 'INTERSECT' + if not use_debug_bool: if use_interior_hide: cell.data.polygons.foreach_set("hide", [True] * len(cell.data.polygons)) - + # mesh_old should be made before appling boolean modifier. mesh_old = cell.data - + original.select_set(True) cell.select_set(True) bpy.context.view_layer.objects.active = cell - bpy.ops.btool.boolean_inters() - bpy.ops.object.modifier_apply(apply_as='DATA', modifier="BTool_" + original.name) - + bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Boolean") + if i == 0: bpy.data.objects.remove(cell, do_unlink=True) continue - + cell = bpy.context.active_object cell.select_set(False) - + # depsgraph sould be gotten after applied boolean modifier, for new_mesh. depsgraph = context.evaluated_depsgraph_get() cell_eval = cell.evaluated_get(depsgraph) - - mesh_new = bpy.data.meshes.new_from_object(cell_eval) + + mesh_new = bpy.data.meshes.new_from_object(cell_eval) cell.data = mesh_new - + ''' check_hide = [11] * len(cell.data.polygons) cell.data.polygons.foreach_get("hide", check_hide) - print(check_hide) + print(check_hide) ''' - + # remove if not valid if not mesh_old.users: bpy.data.meshes.remove(mesh_old) @@ -443,23 +446,22 @@ def cell_boolean(context, original, cells, if use_debug_redraw: _redraw_yasiamevil() - + bpy.context.view_layer.objects.active = original - bpy.ops.btool.remove(thisObj=original.name, Prop="THIS") - + if (not use_debug_bool) and use_island_split: # this is ugly and Im not proud of this - campbell for ob in view_layer.objects: ob.select_set(False) for cell in cells_boolean: - cell.select_set(True) + cell.select_set(True) # If new separated meshes are made, selected objects is increased. if cells_boolean: bpy.ops.mesh.separate(type='LOOSE') cells_boolean[:] = [cell for cell in scene.objects if cell.select_get()] - - context.view_layer.update() + + context.view_layer.update() return cells_boolean @@ -496,7 +498,7 @@ def interior_handle(cells, if use_sharp_edges: bpy.context.space_data.overlay.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 @@ -515,7 +517,7 @@ def interior_handle(cells, bm.normal_update() bmesh.ops.split_edges(bm, edges=edges) ''' - + for bm_face in bm.faces: bm_face.hide = False @@ -531,30 +533,30 @@ def post_process(cells, mass=1.0, mass_mode='VOLUME', mass_name='mass', ): - + """Run after Interiro handle""" #-------------- - # Collection Options + # Collection Options if use_collection: - colle = None + colle = None if not new_collection: colle = bpy.data.collections.get(collection_name) if colle is None: colle = bpy.data.collections.new(collection_name) - + # THe collection should be children of master collection to show in outliner. child_names = [m.name for m in bpy.context.scene.collection.children] if colle.name not in child_names: bpy.context.scene.collection.children.link(colle) - + # Cell objects are only link to the collection. - bpy.ops.collection.objects_remove_all() # For all selected object. - for colle_obj in cells: + bpy.ops.collection.objects_remove_all() # For all selected object. + for colle_obj in cells: colle.objects.link(colle_obj) #-------------- - # Mass Options + # Mass Options if use_mass: # Blender 2.8: Mass for BGE was no more available.-- # -- Instead, Mass values is used for custom properies on cell objects. diff --git a/object_fracture_cell/process/cell_main.py b/object_fracture_cell/process/cell_main.py index 8283b5a2..eefa18c9 100644 --- a/object_fracture_cell/process/cell_main.py +++ b/object_fracture_cell/process/cell_main.py @@ -19,7 +19,7 @@ def main_object(context, original, level, **kw): source_particle_child = kw_copy.pop("source_particle_child") source_pencil = kw_copy.pop("source_pencil") source_random = kw_copy.pop("source_random") - + use_recenter = kw_copy.pop("use_recenter") recursion = kw_copy.pop("recursion") recursion_source_limit = kw_copy.pop("recursion_source_limit") @@ -48,12 +48,12 @@ def main_object(context, original, level, **kw): if kw_copy["use_debug_redraw"]: original_display_type_prev = original.display_type original.display_type = 'WIRE' - + original_mesh = original.data original_matrix = original.matrix_world.copy() - original_verts = [original_matrix @ v.co for v in original_mesh.vertices] + original_verts = [original_matrix @ v.co for v in original_mesh.vertices] original_xyz_minmax = cell_functions.original_minmax(original_verts) - + cells = [] points = cell_functions.points_from_object(original, original_xyz_minmax, source_vert_own=source_vert_own, @@ -61,9 +61,9 @@ def main_object(context, original, level, **kw): source_particle_own=source_particle_own, source_particle_child=source_particle_child, source_pencil=source_pencil, - source_random=source_random) + source_random=source_random) - cells = cell_functions.points_to_cells(context, original, original_xyz_minmax, points, **kw_copy) + cells = cell_functions.points_to_cells(context, original, original_xyz_minmax, points, **kw_copy) cells = cell_functions.cell_boolean(context, original, cells, use_island_split=use_island_split, use_interior_hide=(use_interior_vgroup or use_sharp_edges), @@ -76,7 +76,7 @@ def main_object(context, original, level, **kw): if use_recenter: bpy.ops.object.origin_set({"selected_editable_objects": cells}, type='ORIGIN_GEOMETRY', center='MEDIAN') - + #-------------- # Recursion. if level == 0: @@ -99,10 +99,10 @@ def main_object(context, original, level, **kw): (ob_pair[1].location - c).length_squared) if recursion_chance_select == 'CURSOR_MAX': objects_recurse_input.reverse() - + objects_recurse_input[int(recursion_chance * len(objects_recurse_input)):] = [] objects_recurse_input.sort() - + # reverse index values so we can remove from original list. objects_recurse_input.reverse() @@ -120,7 +120,7 @@ def main_object(context, original, level, **kw): if recursion_clamp and len(cells) > recursion_clamp: break - + #-------------- # Level Options if level == 0: @@ -131,25 +131,25 @@ def main_object(context, original, level, **kw): use_sharp_edges=use_sharp_edges, use_sharp_edges_apply=use_sharp_edges_apply, ) - + if cell_relocate: for cell in cells: cell.location.x += (original_xyz_minmax["x"][1] - original_xyz_minmax["x"][0]) + 1 - + if kw_copy["use_debug_redraw"]: original.display_type = original_display_type_prev - + return cells - + def main(context, original, **kw): ''' import time t = time.time() - ''' + ''' kw_copy = kw.copy() - + # Pre_Simplify pre_simplify = kw_copy.pop("pre_simplify") # collection @@ -157,31 +157,31 @@ def main(context, original, **kw): new_collection = kw_copy.pop("new_collection") collection_name = kw_copy.pop("collection_name") # object visibility - original_hide = kw_copy.pop("original_hide") + original_hide = kw_copy.pop("original_hide") # mass use_mass = kw_copy.pop("use_mass") mass_name = kw_copy.pop("mass_name") mass_mode = kw_copy.pop("mass_mode") mass = kw_copy.pop("mass") - + cells = [] - + if original.type == 'MESH': if pre_simplify > 0.0: cell_functions.simplify_original(original=original, pre_simplify=pre_simplify) - + cells += main_object(context, original, 0, **kw_copy) - + if pre_simplify > 0.0: cell_functions.desimplify_original(original=original) else: assert obj.type == 'MESH', "No MESH object selected." bpy.ops.object.select_all(action='DESELECT') - + for cell in cells: cell.select_set(True) - + cell_functions.post_process(cells, use_collection=use_collection, new_collection=new_collection, @@ -190,19 +190,19 @@ def main(context, original, **kw): mass=mass, mass_mode=mass_mode, mass_name=mass_name, - ) + ) # To avoid select both original object and cells in EDIT mode. bpy.context.view_layer.objects.active = cells[0] - + # de-hide all objects and meshes. bpy.ops.object.mode_set(mode='EDIT') - bpy.ops.mesh.reveal() + bpy.ops.mesh.reveal() bpy.ops.object.mode_set(mode='OBJECT') - + if original_hide: original.hide_set(True) #print("Done! %d objects in %.4f sec" % (len(cells), time.time() - t)) - #print("Done!") + #print("Done!") return (original, cells)
\ No newline at end of file diff --git a/object_fracture_cell/process/crack_functions.py b/object_fracture_cell/process/crack_functions.py index ff7e93a3..ffc513b6 100644 --- a/object_fracture_cell/process/crack_functions.py +++ b/object_fracture_cell/process/crack_functions.py @@ -13,20 +13,20 @@ from mathutils import Euler # Join fractures into an object def make_join(cells): - + # Execute join bpy.context.view_layer.objects.active = cells[0] cells[0].select_set(state=True) bpy.ops.object.join() bpy.ops.object.origin_set(type='GEOMETRY_ORIGIN') - + joined = bpy.context.active_object - + suffix_index = joined.name.rfind("_cell") if suffix_index != -1: joined.name = joined.name[:suffix_index] + "_crack" - + return bpy.context.active_object @@ -45,7 +45,7 @@ def add_modifiers(decimate_val=0.4, smooth_val=0.5): smooth = bpy.context.object.modifiers[-1] smooth.name = 'SMOOTH_crackit' smooth.factor = smooth_val - + # -------------- multi extrude -------------------- # var1=random offset, var2=random rotation, var3=random scale diff --git a/object_fracture_cell/process/material_functions.py b/object_fracture_cell/process/material_functions.py index 938474d4..a2b2d803 100644 --- a/object_fracture_cell/process/material_functions.py +++ b/object_fracture_cell/process/material_functions.py @@ -56,7 +56,7 @@ def appendMaterial(mat_lib_name, mat_name, mat_ui_names="Nameless Material"): bpy.context.object.data.materials.append(mat) return True - + return False diff --git a/object_fracture_cell/utilities.py b/object_fracture_cell/utilities.py index 705d3452..0e87a967 100644 --- a/object_fracture_cell/utilities.py +++ b/object_fracture_cell/utilities.py @@ -1,6 +1,6 @@ def _cell_props_to_dict(fracture_cell_props): - cell_keywords = { + cell_keywords = { 'source_vert_own': fracture_cell_props.source_vert_own, 'source_vert_child': fracture_cell_props.source_vert_child, 'source_particle_own': fracture_cell_props.source_particle_own, @@ -24,7 +24,7 @@ def _cell_props_to_dict(fracture_cell_props): 'use_data_match': fracture_cell_props.use_data_match, 'material_index': fracture_cell_props.material_index, 'use_interior_vgroup': fracture_cell_props.use_interior_vgroup, - + 'use_collection': fracture_cell_props.use_collection, 'new_collection': fracture_cell_props.new_collection, 'collection_name': fracture_cell_props.collection_name, @@ -34,9 +34,9 @@ def _cell_props_to_dict(fracture_cell_props): 'mass_name': fracture_cell_props.mass_name, 'mass_mode': fracture_cell_props.mass_mode, 'mass': fracture_cell_props.mass, - + 'use_debug_points': fracture_cell_props.use_debug_points, 'use_debug_redraw': fracture_cell_props.use_debug_redraw, - 'use_debug_bool': fracture_cell_props.use_debug_bool + 'use_debug_bool': fracture_cell_props.use_debug_bool } return cell_keywords |