Cleanup: remove unnecessary use of addon_utils to access the FBX version
[blender-addons.git] / curve_tools / splines_sequence.py
blob2d0f21d0a4ae8dfa302f25cc839cd2d9a44f2d87
1 # SPDX-FileCopyrightText: 2019-2023 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
6 import bpy
8 import blf
9 import gpu
10 from gpu_extras.batch import batch_for_shader
12 import math
13 import mathutils
14 from mathutils import Vector
16 from bpy.props import (
17 EnumProperty,
20 # ------------------------------------------------------------
21 # ShowSplinesSequence
23 def draw_number(n, co, font_height):
25 point_list = []
27 numeral = [
28 [Vector((0, 0, 0)), Vector((0, 2, 0)), Vector((0, 2, 0)), Vector((1, 2, 0)), Vector((1, 2, 0)), Vector((1, 0, 0)), Vector((1, 0, 0)), Vector((0, 0, 0))],
29 [Vector((0, 1, 0)), Vector((1, 2, 0)), Vector((1, 2, 0)), Vector((1, 0, 0))],
30 [Vector((0, 2, 0)), Vector((1, 2, 0)), Vector((1, 2, 0)), Vector((1, 1, 0)), Vector((1, 1, 0)), Vector((0, 0, 0)), Vector((0, 0, 0)), Vector((1, 0, 0))],
31 [Vector((0, 2, 0)), Vector((1, 2, 0)), Vector((1, 2, 0)), Vector((0, 1, 0)), Vector((0, 1, 0)), Vector((1, 1, 0)), Vector((1, 1, 0)), Vector((0, 0, 0))],
32 [Vector((0, 2, 0)), Vector((0, 1, 0)), Vector((0, 1, 0)), Vector((1, 1, 0)), Vector((1, 1, 0)), Vector((1, 2, 0)), Vector((1, 2, 0)), Vector((1, 0, 0))],
33 [Vector((1, 2, 0)), Vector((0, 2, 0)), Vector((0, 2, 0)), Vector((0, 1, 0)), Vector((0, 1, 0)), Vector((1, 1, 0)), Vector((1, 1, 0)), Vector((1, 0, 0)), Vector((1, 0, 0)), Vector((0, 0, 0))],
34 [Vector((1, 2, 0)), Vector((0, 1, 0)), Vector((0, 1, 0)), Vector((0, 0, 0)), Vector((0, 0, 0)), Vector((1, 0, 0)), Vector((1, 0, 0)), Vector((1, 1, 0)), Vector((1, 1, 0)), Vector((0, 1, 0))],
35 [Vector((0, 2, 0)), Vector((1, 2, 0)), Vector((1, 2, 0)), Vector((0, 1, 0)), Vector((0, 1, 0)), Vector((0, 0, 0))],
36 [Vector((0, 1, 0)), Vector((0, 2, 0)), Vector((0, 2, 0)), Vector((1, 2, 0)), Vector((1, 2, 0)), Vector((1, 0, 0)), Vector((1, 0, 0)), Vector((0, 0, 0)), Vector((0, 0, 0)), Vector((0, 1, 0)), Vector((0, 1, 0)), Vector((1, 1, 0))],
37 [Vector((0, 0, 0)), Vector((1, 1, 0)), Vector((1, 1, 0)), Vector((1, 2, 0)), Vector((1, 2, 0)), Vector((0, 2, 0)), Vector((0, 2, 0)), Vector((0, 1, 0)), Vector((0, 1, 0)), Vector((1, 1, 0))],
40 for num in numeral[n]:
41 point_list.extend([num * font_height + co])
43 return point_list
46 def draw(self, context, splines, sequence_color, font_thickness, font_size, matrix_world):
48 splines_len = len(splines)
49 for n in range(0, splines_len):
51 res = [int(x) for x in str(n)]
53 i = 0
54 for r in res:
55 # draw some text
56 if splines[n].type == 'BEZIER':
57 first_point_co = matrix_world @ splines[n].bezier_points[0].co
58 else:
59 first_point = matrix_world @ splines[n].points[0].co
60 first_point_co = Vector((first_point.x, first_point.y, first_point.z))
62 first_point_co = Vector((i, 0, 0)) + first_point_co
63 points = draw_number(r, first_point_co, font_size)
65 shader = gpu.shader.from_builtin('UNIFORM_COLOR')
67 batch = batch_for_shader(shader, 'LINES', {"pos": points})
69 shader.bind()
70 gpu.state.line_width_set(font_thickness)
71 shader.uniform_float("color", sequence_color)
72 batch.draw(shader)
73 i += font_size + font_size * 0.5
75 class ShowSplinesSequence(bpy.types.Operator):
76 bl_idname = "curvetools.show_splines_sequence"
77 bl_label = "Show Splines Sequence"
78 bl_description = "Show Splines Sequence / [ESC] - remove"
80 handlers = []
82 def modal(self, context, event):
83 context.area.tag_redraw()
85 if event.type in {'ESC'}:
86 for handler in self.handlers:
87 try:
88 bpy.types.SpaceView3D.draw_handler_remove(handler, 'WINDOW')
89 except:
90 pass
91 for handler in self.handlers:
92 self.handlers.remove(handler)
93 return {'CANCELLED'}
95 return {'PASS_THROUGH'}
98 def invoke(self, context, event):
100 if context.area.type == 'VIEW_3D':
102 # color change in the panel
103 sequence_color = bpy.context.scene.curvetools.sequence_color
104 font_thickness = bpy.context.scene.curvetools.font_thickness
105 font_size = bpy.context.scene.curvetools.font_size
107 splines = context.active_object.data.splines
108 matrix_world = context.active_object.matrix_world
110 # the arguments we pass the the callback
111 args = (self, context, splines, sequence_color, font_thickness, font_size, matrix_world)
113 # Add the region OpenGL drawing callback
114 # draw in view space with 'POST_VIEW' and 'PRE_VIEW'
115 self.handlers.append(bpy.types.SpaceView3D.draw_handler_add(draw, args, 'WINDOW', 'POST_VIEW'))
117 context.window_manager.modal_handler_add(self)
118 return {'RUNNING_MODAL'}
119 else:
120 self.report({'WARNING'},
121 "View3D not found, cannot run operator")
122 return {'CANCELLED'}
124 @classmethod
125 def poll(cls, context):
126 return (context.object is not None and
127 context.object.type == 'CURVE')
129 # ------------------------------------------------------------
130 # RearrangeSpline
132 def rearrangesplines(dataCurve, select_spline1, select_spline2):
134 spline1 = dataCurve.splines[select_spline1]
135 spline2 = dataCurve.splines[select_spline2]
137 bpy.ops.curve.select_all(action='SELECT')
138 bpy.ops.curve.spline_type_set(type='BEZIER')
139 bpy.ops.curve.select_all(action='DESELECT')
141 type1 = spline1.type
142 type2 = spline2.type
144 len_spline1 = len(spline1.bezier_points)
145 len_spline2 = len(spline2.bezier_points)
147 newSpline = dataCurve.splines.new(type=type1)
148 newSpline.bezier_points.add(len_spline1 - 1)
149 newSpline.use_cyclic_u = spline1.use_cyclic_u
150 for n in range(0, len_spline1):
151 newSpline.bezier_points[n].co = spline1.bezier_points[n].co
152 newSpline.bezier_points[n].handle_left_type = spline1.bezier_points[n].handle_left_type
153 newSpline.bezier_points[n].handle_left = spline1.bezier_points[n].handle_left
154 newSpline.bezier_points[n].handle_right_type = spline1.bezier_points[n].handle_right_type
155 newSpline.bezier_points[n].handle_right = spline1.bezier_points[n].handle_right
156 spline1.bezier_points[n].select_control_point = True
158 spline1.bezier_points[0].select_control_point = False
159 spline1.bezier_points[0].select_left_handle = False
160 spline1.bezier_points[0].select_right_handle = False
161 bpy.ops.curve.delete(type='VERT')
163 spline1.bezier_points[0].select_control_point = True
164 bpy.ops.curve.spline_type_set(type=type2)
166 bpy.ops.curve.select_all(action='DESELECT')
168 spline1.bezier_points.add(len_spline2 - 1)
169 spline1.use_cyclic_u = spline2.use_cyclic_u
170 for n in range(0, len_spline2):
171 spline1.bezier_points[n].co = spline2.bezier_points[n].co
172 spline1.bezier_points[n].handle_left_type = spline2.bezier_points[n].handle_left_type
173 spline1.bezier_points[n].handle_left = spline2.bezier_points[n].handle_left
174 spline1.bezier_points[n].handle_right_type = spline2.bezier_points[n].handle_right_type
175 spline1.bezier_points[n].handle_right = spline2.bezier_points[n].handle_right
176 spline1.bezier_points[n].select_control_point = False
177 spline1.bezier_points[n].select_left_handle = False
178 spline1.bezier_points[n].select_right_handle = False
179 spline2.bezier_points[n].select_control_point = True
181 spline2.bezier_points[0].select_control_point = False
182 spline2.bezier_points[0].select_left_handle = False
183 spline2.bezier_points[0].select_right_handle = False
184 bpy.ops.curve.delete(type='VERT')
186 spline2.bezier_points[0].select_control_point = True
187 bpy.ops.curve.spline_type_set(type=type1)
189 spline2.bezier_points.add(len_spline1 - 1)
190 spline2.use_cyclic_u = newSpline.use_cyclic_u
191 for m in range(0, len_spline1):
192 spline2.bezier_points[m].co = newSpline.bezier_points[m].co
193 spline2.bezier_points[m].handle_left_type = newSpline.bezier_points[m].handle_left_type
194 spline2.bezier_points[m].handle_left = newSpline.bezier_points[m].handle_left
195 spline2.bezier_points[m].handle_right_type = newSpline.bezier_points[m].handle_right_type
196 spline2.bezier_points[m].handle_right = newSpline.bezier_points[m].handle_right
198 bpy.ops.curve.select_all(action='DESELECT')
199 for point in newSpline.bezier_points:
200 point.select_control_point = True
201 bpy.ops.curve.delete(type='VERT')
203 spline2.bezier_points[0].select_control_point = True
205 def rearrange(dataCurve, select_spline, command):
206 len_splines = len(dataCurve.splines)
207 if command == 'NEXT':
208 if select_spline < len_splines - 1:
209 rearrangesplines(dataCurve, select_spline + 1, select_spline)
211 if command == 'PREV':
212 if select_spline > 0:
213 rearrangesplines(dataCurve, select_spline, select_spline - 1)
215 class RearrangeSpline(bpy.types.Operator):
216 bl_idname = "curvetools.rearrange_spline"
217 bl_label = "Rearrange Spline"
218 bl_description = "Rearrange Spline"
219 bl_options = {'UNDO'}
221 Types = [('NEXT', "Next", "next"),
222 ('PREV', "Prev", "prev")]
223 command : EnumProperty(
224 name="command",
225 description="Command (prev or next)",
226 items=Types
229 def execute(self, context):
230 bpy.ops.object.mode_set(mode = 'EDIT')
231 bpy.context.view_layer.update()
233 dataCurve = context.active_object.data
235 splines = context.active_object.data.splines
237 select_spline = 0
239 sn = 0
240 for spline in splines:
241 for bezier_points in spline.bezier_points:
242 if bezier_points.select_control_point:
243 select_spline = sn
244 sn += 1
246 sn = 0
247 for spline in splines:
248 for point in spline.points:
249 if point.select:
250 select_spline = sn
251 sn += 1
253 rearrange(dataCurve, select_spline, self.command)
255 return {'FINISHED'}
257 @classmethod
258 def poll(cls, context):
259 return (context.object is not None and
260 context.object.type == 'CURVE')
262 def register():
263 for cls in classes:
264 bpy.utils.register_class(operators)
266 def unregister():
267 for cls in classes:
268 bpy.utils.unregister_class(operators)
270 if __name__ == "__main__":
271 register()
273 operators = [ShowSplinesSequence, RearrangeSpline]