Welcome to mirror list, hosted at ThFree Co, Russian Federation.

remove_doubles.py « curve_tools - git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: c63d82be08bf2ea1638ac2a5aedddb019d7a36ec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# SPDX-License-Identifier: GPL-2.0-or-later

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 command "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:
                            ii = i - 1

                        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"
            else:
                if len(spline.points) > 1:
                    for i in range(0, len(spline.points)):

                        if i == 0:
                            ii = len(spline.points) - 1
                        else:
                            ii = i - 1

                        dot = spline.points[i];
                        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')

    return bezier_count + count



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):
        return util.Selected1OrMoreCurves()

    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]