Skip to content
Snippets Groups Projects
remove_doubles.py 4.56 KiB
Newer Older
  • Learn to ignore specific revisions
  • import bpy, mathutils
    from . import util
    
    bl_info = {
        'name': 'Curve Remove Doubles',
        'author': 'Michael Soluyanov',
        'version': (1, 1),
        'blender': (2, 80, 0),
        'location': 'View3D > Context menu (W/RMB) > Remove Doubles',
        'description': 'Adds comand "Remove Doubles" for curves',
        'category': 'Add Curve'
    }
    
    def main(context, distance = 0.01):
    
        selected_Curves = util.GetSelectedCurves()
        if bpy.ops.object.mode_set.poll():
            bpy.ops.object.mode_set(mode='EDIT')
    
        for curve in selected_Curves:
            bezier_dellist = []
            dellist = []
    
    
            for spline in curve.data.splines:
    
                if spline.type == 'BEZIER':
                    if len(spline.bezier_points) > 1:
    
                        for i in range(0, len(spline.bezier_points)):
    
    
                            if i == 0:
                                ii = len(spline.bezier_points) - 1
    
                            else:
    
                            dot = spline.bezier_points[i];
    
                            dot1 = spline.bezier_points[ii];
    
    
                            while dot1 in bezier_dellist and i != ii:
                                ii -= 1
    
                                if ii < 0:
    
                                    ii = len(spline.bezier_points)-1
                                dot1 = spline.bezier_points[ii]
    
    
                            if dot.select_control_point and dot1.select_control_point and (i!=0 or spline.use_cyclic_u):
    
    
                                if (dot.co-dot1.co).length < distance:
                                    # remove points and recreate hangles
                                    dot1.handle_right_type = "FREE"
                                    dot1.handle_right = dot.handle_right
                                    dot1.co = (dot.co + dot1.co) / 2
                                    bezier_dellist.append(dot)
    
                                else:
                                    # Handles that are on main point position converts to vector,
                                    # if next handle are also vector
                                    if dot.handle_left_type == 'VECTOR' and (dot1.handle_right - dot1.co).length < distance:
                                        dot1.handle_right_type = "VECTOR"
                                    if dot1.handle_right_type == 'VECTOR' and (dot.handle_left - dot.co).length < distance:
    
                                        dot.handle_left_type = "VECTOR"
    
                        for i in range(0, len(spline.points)):
    
    
                            if i == 0:
                                ii = len(spline.points) - 1
    
                            else:
    
                            dot1 = spline.points[ii];
    
    
                            while dot1 in dellist and i != ii:
                                ii -= 1
    
                                if ii < 0:
    
                                    ii = len(spline.points)-1
                                dot1 = spline.points[ii]
    
    
                            if dot.select and dot1.select and (i!=0 or spline.use_cyclic_u):
    
    
                                if (dot.co-dot1.co).length < distance:
                                    dot1.co = (dot.co + dot1.co) / 2
                                    dellist.append(dot)
    
        bpy.ops.curve.select_all(action = 'DESELECT')
    
        for dot in bezier_dellist:
            dot.select_control_point = True
    
        for dot in dellist:
            dot.select = True
    
        bezier_count = len(bezier_dellist)
        count = len(dellist)
    
        bpy.ops.curve.delete(type = 'VERT')
    
        bpy.ops.curve.select_all(action = 'DESELECT')
    
    
    
    class CurveRemvDbs(bpy.types.Operator):
        """Merge consecutive points that are near to each other"""
        bl_idname = 'curvetools.remove_doubles'
        bl_label = 'Remove Doubles'
        bl_options = {'REGISTER', 'UNDO'}
    
        distance: bpy.props.FloatProperty(name = 'Distance', default = 0.01)
    
        @classmethod
        def poll(cls, context):
    
    
        def execute(self, context):
            removed=main(context, self.distance)
            self.report({'INFO'}, "Removed %d bezier points" % removed)
            return {'FINISHED'}
    
    
    
    def menu_func(self, context):
        self.layout.operator(CurveRemvDbs.bl_idname, text='Remove Doubles')
    
    def register():
        bpy.utils.register_class(CurveRemvDbs)
        bpy.types.VIEW3D_MT_edit_curve_context_menu.append(menu_func)
    
    def unregister():
        bpy.utils.unregister_class(CurveRemvDbs)
        bpy.types.VIEW3D_MT_edit_curve_context_menu.remove(menu_func)
    
    if __name__ == "__main__":
        register()
    
    operators = [CurveRemvDbs]