Export_3ds: Added distance cue chunk export
[blender-addons.git] / curve_tools / remove_doubles.py
blobc95370800fe30756675e4c8eb550c89e4a352605
1 # SPDX-FileCopyrightText: 2019-2022 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
5 import bpy, mathutils
6 from . import util
8 bl_info = {
9 'name': 'Curve Remove Doubles',
10 'author': 'Michael Soluyanov',
11 'version': (1, 1),
12 'blender': (2, 80, 0),
13 'location': 'View3D > Context menu (W/RMB) > Remove Doubles',
14 'description': 'Adds command "Remove Doubles" for curves',
15 'category': 'Add Curve'
18 def main(context, distance = 0.01):
20 selected_Curves = util.GetSelectedCurves()
21 if bpy.ops.object.mode_set.poll():
22 bpy.ops.object.mode_set(mode='EDIT')
24 for curve in selected_Curves:
25 bezier_dellist = []
26 dellist = []
28 for spline in curve.data.splines:
29 if spline.type == 'BEZIER':
30 if len(spline.bezier_points) > 1:
31 for i in range(0, len(spline.bezier_points)):
33 if i == 0:
34 ii = len(spline.bezier_points) - 1
35 else:
36 ii = i - 1
38 dot = spline.bezier_points[i];
39 dot1 = spline.bezier_points[ii];
41 while dot1 in bezier_dellist and i != ii:
42 ii -= 1
43 if ii < 0:
44 ii = len(spline.bezier_points)-1
45 dot1 = spline.bezier_points[ii]
47 if dot.select_control_point and dot1.select_control_point and (i!=0 or spline.use_cyclic_u):
49 if (dot.co-dot1.co).length < distance:
50 # remove points and recreate hangles
51 dot1.handle_right_type = "FREE"
52 dot1.handle_right = dot.handle_right
53 dot1.co = (dot.co + dot1.co) / 2
54 bezier_dellist.append(dot)
56 else:
57 # Handles that are on main point position converts to vector,
58 # if next handle are also vector
59 if dot.handle_left_type == 'VECTOR' and (dot1.handle_right - dot1.co).length < distance:
60 dot1.handle_right_type = "VECTOR"
61 if dot1.handle_right_type == 'VECTOR' and (dot.handle_left - dot.co).length < distance:
62 dot.handle_left_type = "VECTOR"
63 else:
64 if len(spline.points) > 1:
65 for i in range(0, len(spline.points)):
67 if i == 0:
68 ii = len(spline.points) - 1
69 else:
70 ii = i - 1
72 dot = spline.points[i];
73 dot1 = spline.points[ii];
75 while dot1 in dellist and i != ii:
76 ii -= 1
77 if ii < 0:
78 ii = len(spline.points)-1
79 dot1 = spline.points[ii]
81 if dot.select and dot1.select and (i!=0 or spline.use_cyclic_u):
83 if (dot.co-dot1.co).length < distance:
84 dot1.co = (dot.co + dot1.co) / 2
85 dellist.append(dot)
87 bpy.ops.curve.select_all(action = 'DESELECT')
89 for dot in bezier_dellist:
90 dot.select_control_point = True
92 for dot in dellist:
93 dot.select = True
95 bezier_count = len(bezier_dellist)
96 count = len(dellist)
98 bpy.ops.curve.delete(type = 'VERT')
100 bpy.ops.curve.select_all(action = 'DESELECT')
102 return bezier_count + count
106 class CurveRemvDbs(bpy.types.Operator):
107 """Merge consecutive points that are near to each other"""
108 bl_idname = 'curvetools.remove_doubles'
109 bl_label = 'Remove Doubles'
110 bl_options = {'REGISTER', 'UNDO'}
112 distance: bpy.props.FloatProperty(name = 'Distance', default = 0.01)
114 @classmethod
115 def poll(cls, context):
116 return util.Selected1OrMoreCurves()
118 def execute(self, context):
119 removed=main(context, self.distance)
120 self.report({'INFO'}, "Removed %d bezier points" % removed)
121 return {'FINISHED'}
125 def menu_func(self, context):
126 self.layout.operator(CurveRemvDbs.bl_idname, text='Remove Doubles')
128 def register():
129 bpy.utils.register_class(CurveRemvDbs)
130 bpy.types.VIEW3D_MT_edit_curve_context_menu.append(menu_func)
132 def unregister():
133 bpy.utils.unregister_class(CurveRemvDbs)
134 bpy.types.VIEW3D_MT_edit_curve_context_menu.remove(menu_func)
136 if __name__ == "__main__":
137 register()
139 operators = [CurveRemvDbs]