diff --git a/object_fracture_cell/__init__.py b/object_fracture_cell/__init__.py index b6b0c8c4715b531df3e825478ae5a90759c15b11..6bd20a8c314eb6599043648ba9f32a4fc09b67cd 100644 --- a/object_fracture_cell/__init__.py +++ b/object_fracture_cell/__init__.py @@ -60,6 +60,8 @@ def main_object(scene, obj, level, **kw): 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") + use_smooth_edges = kw_copy.pop("use_smooth_edges") + use_smooth_edges_apply = kw_copy.pop("use_smooth_edges_apply") if level != 0: kw_copy["source_limit"] = recursion_source_limit @@ -78,7 +80,10 @@ def main_object(scene, obj, level, **kw): use_island_split=use_island_split, use_interior_vgroup=use_interior_vgroup, use_debug_bool=use_debug_bool, - use_debug_redraw=kw_copy["use_debug_redraw"]) + use_debug_redraw=kw_copy["use_debug_redraw"], + use_smooth_edges=use_smooth_edges, + use_smooth_edges_apply=use_smooth_edges_apply, + ) # todo, split islands. @@ -243,14 +248,14 @@ class FractureCell(Operator): ('PENCIL', "Grease Pencil", "This objects grease pencil"), ), options={'ENUM_FLAG'}, - default={'PARTICLE_OWN', 'VERT_OWN'}, + default={'PARTICLE_OWN'}, ) source_limit = IntProperty( name="Source Limit", description="Limit the number of input points, 0 for unlimited", min=0, max=5000, - default=1000, + default=100, ) source_noise = FloatProperty( @@ -289,7 +294,7 @@ class FractureCell(Operator): name="Random Factor", description="Likelyhood of recursion", min=0.0, max=1.0, - default=1.0, + default=0.5, ) recursion_chance_select = EnumProperty( @@ -313,10 +318,16 @@ class FractureCell(Operator): use_smooth_edges = BoolProperty( name="Smooth Edges", - description="Set sharp edges whem disabled", + description="Set sharp edges when disabled", default=True, ) + use_smooth_edges_apply = BoolProperty( + name="Apply Split Edge", + description="Split sharp hard edges", + default=False, + ) + use_data_match = BoolProperty( name="Match Data", description="Match original mesh materials and data layers", @@ -469,11 +480,15 @@ class FractureCell(Operator): rowsub = col.row() rowsub.prop(self, "use_smooth_faces") rowsub.prop(self, "use_smooth_edges") + rowsub.prop(self, "use_smooth_edges_apply") rowsub.prop(self, "use_data_match") - rowsub.prop(self, "use_interior_vgroup") - rowsub.prop(self, "material_index") rowsub = col.row() - # could be own section, control how we subdiv + + # on same row for even layout but infact are not all that related + rowsub.prop(self, "material_index") + rowsub.prop(self, "use_interior_vgroup") + + # could be own section, control how we subdiv rowsub.prop(self, "margin") rowsub.prop(self, "use_island_split") diff --git a/object_fracture_cell/fracture_cell_setup.py b/object_fracture_cell/fracture_cell_setup.py index 889f9135ffdce402d4d450444068d562ddbbbd32..c5d60d8e25d2f650d11639cf2b8fa8b7c1e2ebbd 100644 --- a/object_fracture_cell/fracture_cell_setup.py +++ b/object_fracture_cell/fracture_cell_setup.py @@ -232,7 +232,6 @@ def cell_fracture_objects(scene, obj, # XXX small noise bm_vert = bm.verts.new(co) - bm_vert.tag = True import mathutils bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=0.005) @@ -243,10 +242,6 @@ def cell_fracture_objects(scene, obj, traceback.print_exc() if clean: - for bm_vert in bm.verts: - bm_vert.tag = True - for bm_edge in bm.edges: - bm_edge.tag = True bm.normal_update() try: bmesh.ops.dissolve_limit(bm, verts=bm.verts, angle_limit=0.001) @@ -258,9 +253,7 @@ def cell_fracture_objects(scene, obj, for bm_face in bm.faces: bm_face.smooth = True - if use_smooth_edges: - for bm_edge in bm.edges: - bm_edge.smooth = True + # use_smooth_edges is handled after boolean if material_index != 0: for bm_face in bm.faces: @@ -321,13 +314,17 @@ def cell_fracture_boolean(scene, obj, objects, use_island_split=False, use_interior_vgroup=False, use_debug_redraw=False, + use_smooth_edges=True, + use_smooth_edges_apply=True, ): objects_boolean = [] - if use_interior_vgroup: + do_hide_hack = use_interior_vgroup or (use_smooth_edges is False) + + if do_hide_hack: obj.data.polygons.foreach_set("hide", [False] * len(obj.data.polygons)) - + for obj_cell in objects: mod = obj_cell.modifiers.new(name="Boolean", type='BOOLEAN') mod.object = obj @@ -335,7 +332,7 @@ def cell_fracture_boolean(scene, obj, objects, if not use_debug_bool: - if use_interior_vgroup: + if do_hide_hack: obj_cell.data.polygons.foreach_set("hide", [True] * len(obj_cell.data.polygons)) mesh_new = obj_cell.to_mesh(scene, @@ -357,43 +354,58 @@ def cell_fracture_boolean(scene, obj, objects, bpy.data.meshes.remove(mesh_new) mesh_new = None - if clean and mesh_new is not None: - bm = bmesh.new() - bm.from_mesh(mesh_new) - for bm_vert in bm.verts: - bm_vert.tag = True - for bm_edge in bm.edges: - bm_edge.tag = True + # avoid unneeded bmesh re-conversion + bm = None + + if clean and mesh_new: + if bm is None: # ok this will always be true for now... + bm = bmesh.new() + bm.from_mesh(mesh_new) bm.normal_update() try: bmesh.ops.dissolve_limit(bm, verts=bm.verts, edges=bm.edges, angle_limit=0.001) except RuntimeError: import traceback traceback.print_exc() - bm.to_mesh(mesh_new) - bm.free() - if use_interior_vgroup and mesh_new: - bm = bmesh.new() - bm.from_mesh(mesh_new) - for bm_vert in bm.verts: - bm_vert.tag = True - for bm_face in bm.faces: - if not bm_face.hide: - for bm_vert in bm_face.verts: - bm_vert.tag = False - # now add all vgroups - defvert_lay = bm.verts.layers.deform.verify() - for bm_vert in bm.verts: - if bm_vert.tag: - bm_vert[defvert_lay][0] = 1.0 + if do_hide_hack and mesh_new: + # use_interior_vgroup or (use_smooth_edges == False) + if bm is None: + bm = bmesh.new() + bm.from_mesh(mesh_new) + + if use_interior_vgroup: + for bm_vert in bm.verts: + bm_vert.tag = True + for bm_face in bm.faces: + if not bm_face.hide: + for bm_vert in bm_face.verts: + bm_vert.tag = False + + # now add all vgroups + defvert_lay = bm.verts.layers.deform.verify() + for bm_vert in bm.verts: + if bm_vert.tag: + bm_vert[defvert_lay][0] = 1.0 + + if use_smooth_edges is False: + mesh_new.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 + for bm_face in bm.faces: bm_face.hide = False + + if bm is not None: bm.to_mesh(mesh_new) bm.free() + if use_interior_vgroup: # add a vgroup obj_cell.vertex_groups.new(name="Interior") + del mesh_new + del mesh_old if obj_cell is not None: objects_boolean.append(obj_cell) @@ -424,6 +436,20 @@ def cell_fracture_boolean(scene, obj, objects, objects_boolean = objects_islands + # _must_ be done after split islands + if use_smooth_edges is False and use_smooth_edges_apply is True: + for obj_cell in objects_boolean: + mesh = obj_cell.data + bm = bmesh.new() + bm.from_mesh(mesh) + bm.normal_update() + bmesh.ops.split_edges(bm, + edges=[edge for edge in bm.edges + if not edge.smooth] + ) + bm.to_mesh(mesh) + bm.free() + scene.update() return objects_boolean