Skip to content
Snippets Groups Projects
mesh_ktools.py 99.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • 
                    for x in range(iterate):
                            bpy.ops.object.modifier_add(type='SHRINKWRAP')
                            mod_id = (len(bpy.context.object.modifiers)-1)
                            shrink_name = bpy.context.object.modifiers[mod_id].name
    
                            bpy.context.object.modifiers[shrink_name].target = bpy.data.objects[shrink_ob]
                            bpy.context.object.modifiers[shrink_name].vertex_group = sel
    
                            bpy.context.object.modifiers[shrink_name].wrap_method = 'PROJECT'
                            bpy.context.object.modifiers[shrink_name].use_negative_direction = True
                            bpy.context.object.modifiers[shrink_name].subsurf_levels = self.subsurf
    
    
                            bpy.ops.mesh.vertices_smooth(factor=1, repeat=1)
    
    
                            bpy.ops.object.mode_set(mode = 'OBJECT', toggle = False)
                            bpy.ops.object.convert(target='MESH')
                            bpy.ops.object.mode_set(mode = 'EDIT', toggle = False)
    
    
                    bpy.ops.object.mode_set(mode = 'OBJECT', toggle = False)
    
                    bpy.ops.object.vertex_group_remove(all = False)
                    bpy.ops.object.modifier_remove(modifier=shrink_name)
    
                    bpy.ops.object.select_all(action='DESELECT')
                    bpy.ops.object.select_pattern(pattern=shrink_ob)
    
                    bpy.context.view_layer.objects.active = bpy.data.objects[shrink_ob]
    
    
                    #Delete all geo inside Shrink_Object
                    bpy.ops.object.mode_set(mode = 'EDIT', toggle = False)
                    bpy.ops.mesh.select_all(action='SELECT')
                    bpy.ops.mesh.delete(type='VERT')
                    bpy.ops.object.mode_set(mode = 'OBJECT', toggle = False)
    
                    bpy.ops.object.delete(use_global=True)
    
                    bpy.ops.object.select_pattern(pattern=tmp_ob)
    
                    bpy.context.view_layer.objects.active = bpy.data.objects[tmp_ob]
    
    
    
                    bpy.ops.object.mode_set(mode = 'EDIT', toggle = False)
    
                    if pin == True:
                            bpy.ops.mesh.select_all(action='DESELECT')
                            bpy.ops.object.vertex_group_select(org_id)
    
                    bpy.ops.object.mode_set(mode = 'OBJECT', toggle = False)
    
                    bpy.ops.object.delete(use_global=False)
    
    
                    bpy.ops.object.select_pattern(pattern=org_ob)
    
                    bpy.context.view_layer.objects.active = bpy.data.objects[org_ob]
    
    
                    bpy.ops.object.mode_set(mode = 'EDIT', toggle = False)
    
                    # Fix for Blender remembering the previous selection
                    bpy.ops.object.vertex_group_assign_new()
                    bpy.ops.object.vertex_group_remove(all = False)
    
    #Adds buildCorner to the Addon
    
    
    class buildCorner(bpy.types.Operator):
            """Builds corner topology. Good for converting ngons"""
            bl_idname = "mesh.build_corner"
            bl_label = "Build Corner"
    
            bl_options = {'REGISTER', 'UNDO'}
    
            offset: IntProperty()
    
            def modal(self, context, event):
    
                    if event.type == 'MOUSEMOVE':
    
                            delta = self.offset - event.mouse_x
    
                            if delta >= 0:
                                    offset = 1
                            else:
                                    offset = 0
    
                            bpy.ops.mesh.edge_face_add()
    
                            bpy.ops.mesh.poke()
                            bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
                            bpy.ops.object.vertex_group_assign_new()
                            sel_id = bpy.context.object.vertex_groups.active_index
    
                            bpy.ops.mesh.region_to_loop()
                            bpy.ops.object.vertex_group_remove_from()
    
                            bpy.ops.mesh.select_nth(nth=2, skip=1, offset=offset)
    
                            bpy.ops.object.vertex_group_select(sel_id)
    
                            bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
                            bpy.ops.mesh.dissolve_mode(use_verts=False)
    
                            bpy.ops.mesh.select_all(action='DESELECT')
                            bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
                            bpy.ops.object.vertex_group_select()
                            bpy.ops.mesh.select_more()
    
                            bpy.ops.object.vertex_group_remove(all = False)
                            bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='FACE')
    
    
                    elif event.type == 'LEFTMOUSE':
                            return {'FINISHED'}
    
                    elif event.type in {'RIGHTMOUSE', 'ESC'}:
                        bpy.ops.ed.undo()
                        return {'CANCELLED'}
    
                    return {'RUNNING_MODAL'}
    
            def invoke(self, context, event):
                    if context.object:
    
                            # Check selection
    
                            bpy.ops.mesh.edge_face_add()
                            bpy.ops.mesh.region_to_loop()
    
                            bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
    
                            me = bpy.context.object.data
                            bm = bmesh.new()     # create an empty BMesh
                            bm.from_mesh(me)     # fill it in from a Mesh
    
                            face_sel = []
                            edge_sel = []
    
    
                            for v in bm.faces:
                                    if v.select:
                                            face_sel.append(v.index)
                            for v in bm.edges:
                                    if v.select:
                                            edge_sel.append(v.index)
    
    
                            bm.to_mesh(me)
                            bpy.ops.object.mode_set(mode='EDIT', toggle=False)
                            bpy.ops.mesh.loop_to_region()
    
    
                            ###################################
    
                            edge_sel = len(edge_sel)
    
                            if edge_sel == 4:
                                    return {'FINISHED'}
    
                            elif edge_sel%2 == 0:
                                    self.offset = event.mouse_x
                                    context.window_manager.modal_handler_add(self)
                                    return {'RUNNING_MODAL'}
    
                            #elif edge_sel == 5:
                            #    bpy.ops.mesh.quads_convert_to_tris(quad_method='BEAUTY', ngon_method='BEAUTY')
                            #    bpy.ops.mesh.tris_convert_to_quads(face_threshold=3.14159, shape_threshold=3.14159)
                            #    return {'FINISHED'}
    
                            else:
                                    bpy.ops.mesh.poke()
                                    bpy.ops.mesh.quads_convert_to_tris(quad_method='BEAUTY', ngon_method='BEAUTY')
                                    bpy.ops.mesh.tris_convert_to_quads(face_threshold=3.14159, shape_threshold=3.14159)
                                    return {'FINISHED'}
    
                    else:
                            self.report({'WARNING'}, "No active object, could not finish")
                            return {'CANCELLED'}
    
    
    class drawPoly(bpy.types.Operator):
        """Draw a polygon"""
        bl_idname = "mesh.draw_poly"
        bl_label = "Draw Poly"
    
        cursor_co: FloatVectorProperty()
    
        vert_count = 0
    
        manip: BoolProperty()
        vgrp: IntProperty()
    
        sel_mode = BoolVectorProperty()
    
        cursor_depth: BoolProperty()
        snap: BoolProperty()
    
        def modal(self, context, event):
    
            # set header gui
            context.area.tag_redraw()
            context.area.header_text_set("LMB = Create New Point, SHIFT = Flip Normals, RMB / ENTER = Accept NGon, MMB = Accept QuadFill")
    
    
            mesh = bpy.context.active_object.data
    
            if event.type == 'LEFTMOUSE':
                if event.value == 'PRESS':
    
                    bpy.ops.view3d.cursor3d('INVOKE_DEFAULT')
    
                    obj = bpy.context.active_object
                    vert_co = bpy.context.scene.cursor_location
                    world = obj.matrix_world.inverted_safe()
    
                    bpy.ops.mesh.select_all(action='DESELECT')
                    bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
    
                    me = bpy.context.object.data
                    bm = bmesh.new()
                    bm.from_mesh(me)
    
                    # Add new vert
                    new_vert = bm.verts.new(vert_co)
                    new_vert.co = world*new_vert.co
                    new_vert_id = new_vert.index
                    self.vert_count += 1
    
                    if self.vert_count >= 2:
                        bm.verts.ensure_lookup_table()
                        set_of_verts = set(bm.verts[i] for i in range(-2,0))
                        bm.edges.new(set_of_verts)
    
                    # Get index of first and last vertex
                    first_index = len(bm.verts)-self.vert_count
                    second_index = first_index+1
                    third_index = first_index+2
                    second_to_last_index = len(bm.verts)-2
    
                    bm.to_mesh(me)
                    bm.free()
    
                    mesh.vertices[new_vert_id].select = True
                    bpy.ops.object.mode_set(mode='EDIT', toggle=False)
                    bpy.context.scene.cursor_location = self.cursor_co
    
                    if self.vert_count >= 4:
                        bpy.ops.object.vertex_group_assign()
    
                    if self.vert_count == 3:
                        # remove second vertex from group
                        bpy.ops.mesh.select_all(action='DESELECT')
                        bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
                        mesh.vertices[first_index].select = True
                        mesh.vertices[third_index].select = True
                        bpy.ops.object.mode_set(mode='EDIT', toggle=False)
                        bpy.ops.object.vertex_group_assign()
                        bpy.ops.mesh.select_more()
    
                    if self.vert_count == 2:
                        bpy.ops.mesh.select_more()
    
                    if self.vert_count >= 4:
                        # make core poly
                        bpy.ops.mesh.select_all(action='DESELECT')
                        bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
                        mesh.vertices[first_index].select = True
                        mesh.vertices[second_index].select = True
                        mesh.vertices[third_index].select = True
                        bpy.ops.object.mode_set(mode='EDIT', toggle=False)
                        bpy.ops.mesh.edge_face_add()
    
                    if self.vert_count == 4:
                        bpy.ops.mesh.select_all(action='DESELECT')
                        bpy.ops.object.vertex_group_select(self.vgrp)
                        bpy.ops.mesh.edge_face_add()
    
                        # Remove remaining core edge
                        bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
                        mesh.vertices[second_index].select = True
                        bpy.ops.object.mode_set(mode='EDIT', toggle=False)
                        bpy.ops.mesh.edge_face_add()
    
                    if self.vert_count >= 5:
                        #bpy.ops.object.vertex_group_assign()
                        bpy.ops.mesh.select_all(action='DESELECT')
    
                        # Remove Last Edge
                        bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
                        mesh.vertices[first_index].select = True
                        mesh.vertices[second_to_last_index].select = True
                        bpy.ops.object.mode_set(mode='EDIT', toggle=False)
                        bpy.ops.mesh.delete(type='EDGE')
    
                        # Fill in rest of face
                        bpy.ops.object.vertex_group_select(self.vgrp)
                        bpy.ops.mesh.edge_face_add()
    
                        # Remove remaining core edge
                        bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
                        mesh.vertices[second_index].select = True
                        bpy.ops.object.mode_set(mode='EDIT', toggle=False)
                        bpy.ops.mesh.edge_face_add()
                        bpy.ops.mesh.flip_normals()
    
                #return {'FINISHED'}
            elif event.type == 'MIDDLEMOUSE':
    
                # reset header gui
                context.area.tag_redraw()
    
                context.area.header_text_set(None)
    
                # Convert to Quads
                bpy.ops.mesh.quads_convert_to_tris(quad_method='BEAUTY', ngon_method='BEAUTY')
                bpy.ops.mesh.tris_convert_to_quads()
                bpy.ops.mesh.tris_convert_to_quads(face_threshold=3.14159, shape_threshold=3.14159)
    
    
                # restore selection mode and manipulator
                bpy.context.tool_settings.mesh_select_mode = self.sel_mode
                bpy.context.space_data.show_manipulator = self.manip
    
                bpy.context.preferences.input.use_mouse_depth_cursor = self.cursor_depth
    
                bpy.context.scene.tool_settings.use_snap = self.snap
    
                # Remove and make sure vertex group data is gone
                bpy.ops.object.vertex_group_remove_from(use_all_verts=True)
                bpy.ops.object.vertex_group_remove()
                bpy.ops.object.vertex_group_assign_new()
                bpy.context.object.vertex_groups.active.name = "drawPoly_temp"
                bpy.ops.object.vertex_group_remove()
    
    
                return {'CANCELLED'}
    
            elif event.type in {'RIGHTMOUSE', 'ESC', 'SPACE'}:
    
                # reset header gui
                context.area.tag_redraw()
    
                context.area.header_text_set(None)
    
                # restore selection mode and manipulator
                bpy.context.tool_settings.mesh_select_mode = self.sel_mode
                bpy.context.space_data.show_manipulator = self.manip
    
                bpy.context.preferences.input.use_mouse_depth_cursor = self.cursor_depth
    
                bpy.context.scene.tool_settings.use_snap = self.snap
    
                # Remove and make sure vertex group data is gone
                bpy.ops.object.vertex_group_remove_from(use_all_verts=True)
                bpy.ops.object.vertex_group_remove()
                bpy.ops.object.vertex_group_assign_new()
                bpy.context.object.vertex_groups.active.name = "drawPoly_temp"
                bpy.ops.object.vertex_group_remove()
    
    
                return {'CANCELLED'}
    
            elif event.type == 'LEFT_SHIFT' or event.type == 'RIGHT_SHIFT':
                bpy.ops.mesh.flip_normals()
    
                return {'PASS_THROUGH'}
    
            elif event.type == 'LEFT_CTRL' or event.type == 'RIGHT_CTRL' :
    
                if bpy.context.preferences.input.use_mouse_depth_cursor == True:
                    bpy.context.preferences.input.use_mouse_depth_cursor = False
    
                    bpy.context.scene.tool_settings.use_snap = False
                else:
    
                    bpy.context.preferences.input.use_mouse_depth_cursor = True
    
                    bpy.context.scene.tool_settings.use_snap = True
                return {'PASS_THROUGH'}
    
            return {'RUNNING_MODAL'}
    
        def invoke(self, context, event):
    
            sel_ob = len(bpy.context.selected_objects)
    
            if sel_ob >= 1:
                sel_type = bpy.context.object.type
    
                if sel_type == 'MESH':
                    bpy.ops.object.mode_set(mode='EDIT', toggle=False)
    
                else:
                    self.report({'WARNING'}, "Active object is not a mesh.")
                    return {'CANCELLED'}
    
            elif sel_ob == 0:
                bpy.ops.mesh.primitive_plane_add()
                bpy.context.selected_objects[0].name = "polyDraw"
                bpy.context.selected_objects[0].data.name = "polyDraw"
                bpy.ops.object.mode_set(mode='EDIT', toggle=False)
                bpy.ops.mesh.select_all(action='SELECT')
                bpy.ops.mesh.delete(type='VERT')
    
            # Store selection mode, snap and manipulator settings
            self.sel_mode = bpy.context.tool_settings.mesh_select_mode[:]
            bpy.context.tool_settings.mesh_select_mode = True, False, False
            self.manip = bpy.context.space_data.show_manipulator
            bpy.context.space_data.show_manipulator = False
    
            self.cursor_depth = bpy.context.preferences.input.use_mouse_depth_cursor
            bpy.context.preferences.input.use_mouse_depth_cursor = False
    
            self.snap = bpy.context.scene.tool_settings.use_snap
            bpy.context.scene.tool_settings.use_snap = False
    
            bpy.ops.object.mode_set(mode='EDIT', toggle=False)
    
            bpy.ops.mesh.select_all(action='DESELECT')
            bpy.ops.object.vertex_group_assign_new()
            self.vgrp = bpy.context.object.vertex_groups.active_index
            bpy.context.object.vertex_groups.active.name = "drawPoly_temp"
    
            self.cursor_co = bpy.context.scene.cursor_location
    
    
            context.window_manager.modal_handler_add(self)
            return {'RUNNING_MODAL'}
    
    class toggleSilhouette(bpy.types.Operator):
        """Turns everything black so that you can evaluate the overall shape. Useful when designing"""
        bl_idname = "object.toggle_silhouette"
        bl_label = "Toggle Silhouette"
    
    
        diff_col: FloatVectorProperty(default = (0.226, 0.179, 0.141))
        disp_mode: StringProperty(default = 'SOLID')
        matcap: BoolProperty(default = False)
        only_render: BoolProperty(default = False)
    
        def execute(self, context):
    
            light_check = bpy.context.preferences.system.solid_lights[0].use
    
    
            if light_check == True:
                # Set Lights to Off
    
                bpy.context.preferences.system.solid_lights[0].use = False
                bpy.context.preferences.system.solid_lights[1].use = False
    
                # Store variables
    
                self.diff_col = bpy.context.preferences.system.solid_lights[2].diffuse_color
    
                self.disp_mode = bpy.context.space_data.viewport_shade
                self.matcap = bpy.context.space_data.use_matcap
                self.only_render = bpy.context.space_data.show_only_render
    
                bpy.context.preferences.system.solid_lights[2].diffuse_color = 0,0,0
    
                bpy.context.space_data.viewport_shade = 'SOLID'
                bpy.context.space_data.use_matcap = False
                bpy.context.space_data.show_only_render = True
    
                bpy.context.preferences.system.solid_lights[0].use = True
                bpy.context.preferences.system.solid_lights[1].use = True
                bpy.context.preferences.system.solid_lights[2].diffuse_color = self.diff_col
    
                bpy.context.space_data.viewport_shade = self.disp_mode
                bpy.context.space_data.use_matcap = self.matcap
                bpy.context.space_data.show_only_render = self.only_render
    
    
    #Adds growLoop to the Addon
    
    
    class growLoop(bpy.types.Operator):
    
            """Grows the selected edges in both directions """
            bl_idname = "mesh.grow_loop"
            bl_label = "Grow Loop"
            bl_options = {'REGISTER', 'UNDO'}
    
            grow: IntProperty(name="Grow Selection", description="How much to grow selection", default= 1, min=1, soft_max=10)
    
            def execute(self, context):
    
                    grow = self.grow
                    sel_mode = bpy.context.tool_settings.mesh_select_mode[:]
    
                    for x in range(grow):
                            if sel_mode[2] == True:
    
                                    edge_sel = []
                                    border = []
                                    interior = []
                                    face_org = []
                                    face_loop = []
                                    face_grow = []
                                    face_sel = []
                                    mesh_edges = bpy.context.active_object.data.edges
                                    mesh_faces = bpy.context.active_object.data.polygons
    
    
                                    bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='FACE')
    
    
                                    me = bpy.context.object.data
                                    bm = bmesh.from_edit_mesh(me)
    
                                    for e in bm.edges:
                                            if e.select:
                                                    edge_sel.append(e.index)
    
                                    for f in bm.faces:
                                            if f.select:
                                                    face_org.append(f.index)
    
                                    bpy.ops.mesh.region_to_loop()
    
                                    for e in bm.edges:
                                            if e.select:
                                                    border.append(e.index)
    
    
    
                                    for e in edge_sel:
                                            if e not in border:
                                                    interior.append(e)
    
                                    bmesh.update_edit_mesh(me, True, False)
    
    
                                    bpy.ops.mesh.select_all(action='DESELECT')
    
                                    #Select the interior edges
                                    bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
    
    
                                    for e in interior:
                                            mesh_edges[e].select = True
    
                                    bpy.ops.object.mode_set(mode='EDIT', toggle=False)
                                    bpy.ops.mesh.loop_multi_select(ring=True)
                                    bpy.ops.mesh.select_mode(use_extend=False, use_expand=True, type='FACE')
    
                                    me = bpy.context.object.data
                                    bm = bmesh.from_edit_mesh(me)
    
                                    for f in bm.faces:
                                            if f.select:
                                                    face_loop.append(f.index)
    
                                    bmesh.update_edit_mesh(me, True, False)
    
                                    bpy.ops.mesh.select_all(action='DESELECT')
    
    
                                    # Select original faces
                                    bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
                                    for x in face_org:
                                            mesh_faces[x].select = True
                                    bpy.ops.object.mode_set(mode='EDIT', toggle=False)
    
    
                                    bpy.ops.mesh.select_more(use_face_step=False)
    
                                    me = bpy.context.object.data
                                    bm = bmesh.from_edit_mesh(me)
    
                                    for f in bm.faces:
                                            if f.select:
                                                    face_grow.append(f.index)
    
                                    for f in face_grow:
                                            if f in face_loop:
                                                    face_sel.append(f)
    
                                    for f in face_org:
                                            face_sel.append(f)
    
                                    bmesh.update_edit_mesh(me, True, False)
    
                                    bpy.ops.mesh.select_all(action='DESELECT')
    
                                    bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
    
                                    for f in face_sel:
                                            mesh_faces[f].select = True
    
                                    bpy.ops.object.mode_set(mode='EDIT', toggle=False)
    
                            else:
                                    mesh = bpy.context.active_object.data.edges
    
                                    me = bpy.context.object.data
                                    bm = bmesh.from_edit_mesh(me)
                                    org_sel = []
                                    grow_sel = []
                                    loop_sel = []
                                    sel = []
    
                                    bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
    
                                    for e in bm.edges:
                                            if e.select:
                                                    org_sel.append(e.index)
    
                                    bpy.ops.mesh.select_more(use_face_step=False)
    
                                    for e in bm.edges:
                                            if e.select:
                                                    grow_sel.append(e.index)
    
                                    bpy.ops.mesh.select_all(action='DESELECT')
    
                                    bmesh.update_edit_mesh(me, True, False)
    
                                    # Select the original edges
                                    bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
                                    for e in org_sel:
    
                                            mesh[e].select = True
    
                                    bpy.ops.object.mode_set(mode='EDIT', toggle=False)
    
    
                                    me = bpy.context.object.data
                                    bm = bmesh.from_edit_mesh(me)
                                    bpy.ops.mesh.loop_multi_select(ring=False)
    
                                    for e in bm.edges:
                                            if e.select:
                                                    loop_sel.append(e.index)
    
                                    bmesh.update_edit_mesh(me, True, False)
    
                                    bpy.ops.mesh.select_all(action='DESELECT')
    
                                    for x in loop_sel:
                                            if x in grow_sel:
                                                    sel.append(x)
    
                                    bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
                                    for e in sel:
    
                                            mesh[e].select = True
                                    bpy.ops.object.mode_set(mode='EDIT', toggle=False)
    
    
                            bpy.context.tool_settings.mesh_select_mode = sel_mode
    
                    return {'FINISHED'}
    
    
    #Adds extendLoop to the Addon
    
    
    class extendLoop(bpy.types.Operator):
    
            """Uses the active face or edge to extends the selection in one direction"""
            bl_idname = "mesh.extend_loop"
            bl_label = "Extend Loop"
            bl_options = {'REGISTER', 'UNDO'}
    
            extend: IntProperty(name="Extend Selection", description="How much to extend selection", default= 1, min=1, soft_max=10)
    
            def execute(self, context):
    
                    sel_mode = bpy.context.tool_settings.mesh_select_mode[:]
                    extend = self.extend
    
                    for x in range(extend):
                        if sel_mode[2] == True:
    
                            bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
                            active_face = bpy.context.object.data.polygons.active # find active face
                            bpy.ops.object.mode_set(mode='EDIT', toggle=False)
    
                            edge_sel = []
                            interior = []
                            face_org = []
                            face_loop = []
                            face_grow = []
                            face_sel = []
                            active_edges = []
    
                            # Get face selection
                            me = bpy.context.object.data
                            bm = bmesh.from_edit_mesh(me)
    
                            for f in bm.faces:
                                    if f.select:
                                            face_org.append(f.index)
    
                            face_org.remove(active_face)
    
    
                            bmesh.update_edit_mesh(me, True, False)
    
                            bpy.ops.mesh.select_all(action='DESELECT')
                            mesh = bpy.context.active_object.data.polygons
    
                            bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
                            for x in face_org:
                                    mesh[x].select = True
                            bpy.ops.object.mode_set(mode='EDIT', toggle=False)
    
    
    
                            # Get edge selection
                            me = bpy.context.object.data
                            bm = bmesh.from_edit_mesh(me)
    
                            for e in bm.edges:
                                    if e.select:
                                            edge_sel.append(e.index)
    
    
                            bmesh.update_edit_mesh(me, True, False)
    
    
                            # Select Active Face
                            bpy.ops.mesh.select_all(action='DESELECT')
                            mesh = bpy.context.active_object.data.polygons
    
                            bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
                            mesh[active_face].select = True
                            bpy.ops.object.mode_set(mode='EDIT', toggle=False)
                            bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
    
                            me = bpy.context.object.data
                            bm = bmesh.from_edit_mesh(me)
    
    
                            # Store the interior edge
    
                            for e in bm.edges:
                                    if e.select:
                                            active_edges.append(e.index)
    
    
                            for e in active_edges:
                                    if e in edge_sel:
                                            interior.append(e)
    
                            bmesh.update_edit_mesh(me, True, False)
    
    
                            bpy.ops.mesh.select_all(action='DESELECT')
    
                            #Select the interior edges
                            bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
    
                            mesh = bpy.context.active_object.data.edges
    
                            for e in interior:
                                    mesh[e].select = True
    
                            bpy.ops.object.mode_set(mode='EDIT', toggle=False)
    
    
                            bpy.ops.mesh.loop_multi_select(ring=True)
                            bpy.ops.mesh.select_mode(use_extend=False, use_expand=True, type='FACE')
    
    
                            me = bpy.context.object.data
                            bm = bmesh.from_edit_mesh(me)
    
                            for f in bm.faces:
                                    if f.select:
                                            face_loop.append(f.index)
    
    
                            bmesh.update_edit_mesh(me, True, False)
    
                            bpy.ops.mesh.select_all(action='DESELECT')
    
                            # Select active face
                            mesh = bpy.context.active_object.data.polygons
    
                            bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
                            mesh[active_face].select = True
                            bpy.ops.object.mode_set(mode='EDIT', toggle=False)
                            bpy.ops.mesh.select_more(use_face_step=False)
    
    
                            face_org.append(active_face)
    
                            me = bpy.context.object.data
                            bm = bmesh.from_edit_mesh(me)
    
                            for f in bm.faces:
                                    if f.select:
                                            face_grow.append(f.index)
    
                            for f in face_grow:
                                    if f in face_loop:
                                            face_sel.append(f)
    
                            for f in face_sel:
                                    if f not in face_org:
                                            active_face = f
    
                            for f in face_org:
                                    face_sel.append(f)
    
                            bmesh.update_edit_mesh(me, True, False)
    
                            bpy.ops.mesh.select_all(action='DESELECT')
    
                            bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
    
                            for f in face_sel:
                                    mesh[f].select = True
                            bpy.context.object.data.polygons.active = active_face
    
                            bpy.ops.object.mode_set(mode='EDIT', toggle=False)
    
                        elif sel_mode[1] == True:
    
                            mesh = bpy.context.active_object.data
                            org_sel = []
                            grow_sel = []
                            loop_sel = []
                            sel = []
                            org_verts = []
                            active_verts = []
    
                            # Get active edge
                            me = bpy.context.object.data
                            bm = bmesh.from_edit_mesh(me)
    
                            for x in reversed(bm.select_history):
                                    if isinstance(x, bmesh.types.BMEdge):
                                            active_edge = x.index
                                            break
    
                            # Store the originally selected edges
                            for e in bm.edges:
                                    if e.select:
                                            org_sel.append(e.index)
    
    
                            bmesh.update_edit_mesh(me, True, False)
    
                            # Select active edge
                            bpy.ops.mesh.select_all(action='DESELECT')
                            bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
                            mesh.edges[active_edge].select = True
                            bpy.ops.object.mode_set(mode='EDIT', toggle=False)
    
                            # Get verts of active edge
                            bm = bmesh.from_edit_mesh(me)
    
                            for v in bm.verts:
                                    if v.select:
                                            active_verts.append(v.index)
    
                            bmesh.update_edit_mesh(me, True, False)
    
                            # Select original selection minus active edge
                            bpy.ops.mesh.select_all(action='DESELECT')
                            bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
                            for x in org_sel:
                                mesh.edges[x].select = True
                            mesh.edges[active_edge].select = False
                            bpy.ops.object.mode_set(mode='EDIT', toggle=False)
    
                            bm = bmesh.from_edit_mesh(me)
    
                            # Store the original vertices minus active edge
                            for v in bm.verts:
                                if v.select:
                                    org_verts.append(v.index)
    
                            # Compare verts
                            for x in active_verts:
                                if x in org_verts:
                                    active_verts.remove(x)
    
                            bmesh.update_edit_mesh(me, True, False)
    
                            # Select end vertex
                            bpy.ops.mesh.select_all(action='DESELECT')
                            bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
                            bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
                            mesh.vertices[active_verts[0]].select = True
                            bpy.ops.object.mode_set(mode='EDIT', toggle=False)
    
                            # Grow the end vertex and store the edges
                            bpy.ops.mesh.select_more(use_face_step=False)
                            bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
                            bm = bmesh.from_edit_mesh(me)
    
                            for e in bm.edges:
                                    if e.select:
                                            grow_sel.append(e.index)
    
                            bmesh.update_edit_mesh(me, True, False)
                            bpy.ops.mesh.select_all(action='DESELECT')
    
                            # Run loop of the active edges and store it
                            bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
    
                            mesh.edges[active_edge].select = True
    
                            bpy.ops.object.mode_set(mode='EDIT', toggle=False)
                            bpy.ops.mesh.loop_multi_select(ring=False)
    
                            me = bpy.context.object.data
                            bm = bmesh.from_edit_mesh(me)
    
                            for e in bm.edges:
                                    if e.select:
                                            loop_sel.append(e.index)
    
                            bmesh.update_edit_mesh(me, True, False)
                            bpy.ops.mesh.select_all(action='DESELECT')
    
                            # Compare loop_sel vs grow_sel
                            for x in loop_sel:
                                    if x in grow_sel:
                                            sel.append(x)
    
    
                            # Add original selection to new selection
    
                            for x in org_sel:
                                if x not in sel:
                                    sel.append(x)
    
    
                            # Compare org_sel with sel to get the active edge
                            for x in sel:
                                if x not in org_sel:
                                    active_edge = x
    
                            # Select the resulting edges
                            bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
                            for e in sel:
    
                                    mesh.edges[e].select = True
    
                            bpy.ops.object.mode_set(mode='EDIT', toggle=False)
    
                            # Set the new active edge
                            bm = bmesh.from_edit_mesh(me)
    
                            bm.edges.ensure_lookup_table()
                            bm.select_history.add(bm.edges[active_edge])
                            bmesh.update_edit_mesh(me, True, False)
    
    #Adds extendLoop to the Addon
    
    
    class shrinkLoop(bpy.types.Operator):
    
            """Shrink the selected loop"""
            bl_idname = "mesh.shrink_loop"
            bl_label = "Shrink Loop"
            bl_options = {'REGISTER', 'UNDO'}
    
            shrink: IntProperty(name="Shrink Selection", description="How much to shrink selection", default= 1, min=1, soft_max=15)
    
            def execute(self, context):
    
                    sel_mode = bpy.context.tool_settings.mesh_select_mode[:]
                    shrink = self.shrink
    
                    for x in range(shrink):
                        if sel_mode[2] == True:
                            me = bpy.context.object.data
                            bm = bmesh.from_edit_mesh(me)
                            mesh = bpy.context.active_object.data
    
                            sel = []
                            edge_dic = {}
                            vert_list = []
                            end_verts = []
                            org_faces = []
                            cur_faces = []
                            new_faces = []
    
                            # Store edges and verts
                            for e in bm.edges:
                                if e.select:
                                    sel.append(e.index)
    
                                    # Populate vert_list
                                    vert_list.append(e.verts[0].index)
                                    vert_list.append(e.verts[1].index)
    
                                    # Store dictionary
                                    edge_dic[e.index] = [e.verts[0].index, e.verts[1].index]
    
                            # Store original faces
                            for f in bm.faces:
                                if f.select:
                                    org_faces.append(f.index)
    
                            # Store end verts
                            for v in vert_list:
                                if vert_list.count(v) == 2:
                                    end_verts.append(v)
    
                            # Check verts in dictionary