3ab102a803b110b456eb57a199dc381fd8f70666
[blender-staging.git] / release / scripts / ui / properties_data_modifier.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
3 #  This program is free software; you can redistribute it and/or
4 #  modify it under the terms of the GNU General Public License
5 #  as published by the Free Software Foundation; either version 2
6 #  of the License, or (at your option) any later version.
7 #
8 #  This program is distributed in the hope that it will be useful,
9 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #  GNU General Public License for more details.
12 #
13 #  You should have received a copy of the GNU General Public License
14 #  along with this program; if not, write to the Free Software Foundation,
15 #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8 compliant>
20 import bpy
21
22 narrowui = 180
23 narrowmod = 260
24
25
26 class DataButtonsPanel(bpy.types.Panel):
27     bl_space_type = 'PROPERTIES'
28     bl_region_type = 'WINDOW'
29     bl_context = "modifier"
30
31
32 class DATA_PT_modifiers(DataButtonsPanel):
33     bl_label = "Modifiers"
34
35     def draw(self, context):
36         layout = self.layout
37
38         ob = context.object
39         wide_ui = context.region.width > narrowui
40         compact_mod = context.region.width < narrowmod
41
42         layout.operator_menu_enum("object.modifier_add", "type")
43
44         for md in ob.modifiers:
45             box = layout.template_modifier(md, compact=compact_mod)
46             if box:
47                 # match enum type to our functions, avoids a lookup table.
48                 getattr(self, md.type)(box, ob, md, wide_ui)
49
50     # the mt.type enum is (ab)used for a lookup on function names
51     # ...to avoid lengthy if statements
52     # so each type must have a function here.
53
54     def ARMATURE(self, layout, ob, md, wide_ui):
55         split = layout.split()
56
57         col = split.column()
58         col.label(text="Object:")
59         col.prop(md, "object", text="")
60
61         if wide_ui:
62             col = split.column()
63         col.label(text="Vertex Group::")
64         col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
65         sub = col.column()
66         sub.active = bool(md.vertex_group)
67         sub.prop(md, "invert")
68
69         split = layout.split()
70
71         col = split.column()
72         col.label(text="Bind To:")
73         col.prop(md, "use_vertex_groups", text="Vertex Groups")
74         col.prop(md, "use_bone_envelopes", text="Bone Envelopes")
75
76         if wide_ui:
77             col = split.column()
78         col.label(text="Deformation:")
79         col.prop(md, "quaternion")
80         col.prop(md, "multi_modifier")
81
82     def ARRAY(self, layout, ob, md, wide_ui):
83         if wide_ui:
84             layout.prop(md, "fit_type")
85         else:
86             layout.prop(md, "fit_type", text="")
87
88
89         if md.fit_type == 'FIXED_COUNT':
90             layout.prop(md, "count")
91         elif md.fit_type == 'FIT_LENGTH':
92             layout.prop(md, "length")
93         elif md.fit_type == 'FIT_CURVE':
94             layout.prop(md, "curve")
95
96         layout.separator()
97
98         split = layout.split()
99
100         col = split.column()
101         col.prop(md, "constant_offset")
102         sub = col.column()
103         sub.active = md.constant_offset
104         sub.prop(md, "constant_offset_displacement", text="")
105
106         col.separator()
107
108         col.prop(md, "merge_adjacent_vertices", text="Merge")
109         sub = col.column()
110         sub.active = md.merge_adjacent_vertices
111         sub.prop(md, "merge_end_vertices", text="First Last")
112         sub.prop(md, "merge_distance", text="Distance")
113
114         if wide_ui:
115             col = split.column()
116         col.prop(md, "relative_offset")
117         sub = col.column()
118         sub.active = md.relative_offset
119         sub.prop(md, "relative_offset_displacement", text="")
120
121         col.separator()
122
123         col.prop(md, "add_offset_object")
124         sub = col.column()
125         sub.active = md.add_offset_object
126         sub.prop(md, "offset_object", text="")
127
128         layout.separator()
129
130         col = layout.column()
131         col.prop(md, "start_cap")
132         col.prop(md, "end_cap")
133
134     def BEVEL(self, layout, ob, md, wide_ui):
135         split = layout.split()
136
137         col = split.column()
138         col.prop(md, "width")
139
140         if wide_ui:
141             col = split.column()
142         col.prop(md, "only_vertices")
143
144         layout.label(text="Limit Method:")
145         layout.row().prop(md, "limit_method", expand=True)
146         if md.limit_method == 'ANGLE':
147             layout.prop(md, "angle")
148         elif md.limit_method == 'WEIGHT':
149             layout.row().prop(md, "edge_weight_method", expand=True)
150
151     def BOOLEAN(self, layout, ob, md, wide_ui):
152         split = layout.split()
153
154         col = split.column()
155         col.label(text="Operation:")
156         col.prop(md, "operation", text="")
157
158         if wide_ui:
159             col = split.column()
160         col.label(text="Object:")
161         col.prop(md, "object", text="")
162
163     def BUILD(self, layout, ob, md, wide_ui):
164         split = layout.split()
165
166         col = split.column()
167         col.prop(md, "start")
168         col.prop(md, "length")
169
170         if wide_ui:
171             col = split.column()
172         col.prop(md, "randomize")
173         sub = col.column()
174         sub.active = md.randomize
175         sub.prop(md, "seed")
176
177     def CAST(self, layout, ob, md, wide_ui):
178         split = layout.split(percentage=0.25)
179
180         if wide_ui:
181             split.label(text="Cast Type:")
182             split.prop(md, "cast_type", text="")
183         else:
184             layout.prop(md, "cast_type", text="")
185
186         split = layout.split(percentage=0.25)
187
188         col = split.column()
189         col.prop(md, "x")
190         col.prop(md, "y")
191         col.prop(md, "z")
192
193         col = split.column()
194         col.prop(md, "factor")
195         col.prop(md, "radius")
196         col.prop(md, "size")
197         col.prop(md, "from_radius")
198
199         split = layout.split()
200
201         col = split.column()
202         col.label(text="Vertex Group:")
203         col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
204         if wide_ui:
205             col = split.column()
206         col.label(text="Control Object:")
207         col.prop(md, "object", text="")
208         if md.object:
209             col.prop(md, "use_transform")
210
211     def CLOTH(self, layout, ob, md, wide_ui):
212         layout.label(text="See Cloth panel.")
213
214     def COLLISION(self, layout, ob, md, wide_ui):
215         layout.label(text="See Collision panel.")
216
217     def CURVE(self, layout, ob, md, wide_ui):
218         split = layout.split()
219
220         col = split.column()
221         col.label(text="Object:")
222         col.prop(md, "object", text="")
223         if wide_ui:
224             col = split.column()
225         col.label(text="Vertex Group:")
226         col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
227         layout.label(text="Deformation Axis:")
228         layout.row().prop(md, "deform_axis", expand=True)
229
230     def DECIMATE(self, layout, ob, md, wide_ui):
231         layout.prop(md, "ratio")
232         layout.prop(md, "face_count")
233
234     def DISPLACE(self, layout, ob, md, wide_ui):
235         split = layout.split()
236
237         col = split.column()
238         col.label(text="Texture:")
239         col.prop(md, "texture", text="")
240         col.label(text="Vertex Group:")
241         col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
242
243         if wide_ui:
244             col = split.column()
245         col.label(text="Direction:")
246         col.prop(md, "direction", text="")
247         col.label(text="Texture Coordinates:")
248         col.prop(md, "texture_coordinates", text="")
249         if md.texture_coordinates == 'OBJECT':
250             layout.prop(md, "texture_coordinate_object", text="Object")
251         elif md.texture_coordinates == 'UV' and ob.type == 'MESH':
252             layout.prop_object(md, "uv_layer", ob.data, "uv_textures")
253
254         layout.separator()
255
256         split = layout.split()
257
258         col = split.column()
259         col.prop(md, "midlevel")
260
261         if wide_ui:
262             col = split.column()
263         col.prop(md, "strength")
264
265     def EDGE_SPLIT(self, layout, ob, md, wide_ui):
266         split = layout.split()
267
268         col = split.column()
269         col.prop(md, "use_edge_angle", text="Edge Angle")
270         sub = col.column()
271         sub.active = md.use_edge_angle
272         sub.prop(md, "split_angle")
273
274         if wide_ui:
275             col = split.column()
276         col.prop(md, "use_sharp", text="Sharp Edges")
277
278     def EXPLODE(self, layout, ob, md, wide_ui):
279         split = layout.split()
280
281         col = split.column()
282         col.label(text="Vertex group:")
283         col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
284         sub = col.column()
285         sub.active = bool(md.vertex_group)
286         sub.prop(md, "protect")
287
288         if wide_ui:
289             col = split.column()
290         col.prop(md, "split_edges")
291         col.prop(md, "unborn")
292         col.prop(md, "alive")
293         col.prop(md, "dead")
294
295         layout.operator("object.explode_refresh", text="Refresh")
296
297     def FLUID_SIMULATION(self, layout, ob, md, wide_ui):
298         layout.label(text="See Fluid panel.")
299
300     def HOOK(self, layout, ob, md, wide_ui):
301         split = layout.split()
302
303         col = split.column()
304         col.label(text="Object:")
305         col.prop(md, "object", text="")
306         if md.object and md.object.type == 'ARMATURE':
307             col.label(text="Bone:")
308             col.prop_object(md, "subtarget", md.object.data, "bones", text="")
309         if wide_ui:
310             col = split.column()
311         col.label(text="Vertex Group:")
312         col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
313
314         layout.separator()
315
316         split = layout.split()
317
318         col = split.column()
319         col.prop(md, "falloff")
320         col.prop(md, "force", slider=True)
321         if wide_ui:
322             col = split.column()
323         else:
324             col.separator()
325         col.operator("object.hook_reset", text="Reset")
326         col.operator("object.hook_recenter", text="Recenter")
327
328         if ob.mode == 'EDIT':
329             layout.separator()
330             row = layout.row()
331             row.operator("object.hook_select", text="Select")
332             row.operator("object.hook_assign", text="Assign")
333
334     def LATTICE(self, layout, ob, md, wide_ui):
335         split = layout.split()
336
337         col = split.column()
338         col.label(text="Object:")
339         col.prop(md, "object", text="")
340
341         if wide_ui:
342             col = split.column()
343         col.label(text="Vertex Group:")
344         col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
345
346     def MASK(self, layout, ob, md, wide_ui):
347         split = layout.split()
348
349         col = split.column()
350         col.label(text="Mode:")
351         col.prop(md, "mode", text="")
352         if wide_ui:
353             col = split.column()
354         if md.mode == 'ARMATURE':
355             col.label(text="Armature:")
356             col.prop(md, "armature", text="")
357         elif md.mode == 'VERTEX_GROUP':
358             col.label(text="Vertex Group:")
359             col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
360
361         sub = col.column()
362         sub.active = bool(md.vertex_group)
363         sub.prop(md, "invert")
364
365     def MESH_DEFORM(self, layout, ob, md, wide_ui):
366         split = layout.split()
367         col = split.column()
368         sub = col.column()
369         sub.label(text="Object:")
370         sub.prop(md, "object", text="")
371         sub.prop(md, "mode", text="")
372         sub.active = not md.is_bound
373         if wide_ui:
374             col = split.column()
375         col.label(text="Vertex Group:")
376         col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
377
378         sub = col.column()
379         sub.active = bool(md.vertex_group)
380         sub.prop(md, "invert")
381
382         layout.separator()
383
384         if md.is_bound:
385             layout.operator("object.meshdeform_bind", text="Unbind")
386         else:
387             layout.operator("object.meshdeform_bind", text="Bind")
388
389             if md.mode == 'VOLUME':
390                 split = layout.split()
391
392                 col = split.column()
393                 col.prop(md, "precision")
394
395                 if wide_ui:
396                     col = split.column()
397                 col.prop(md, "dynamic")
398
399     def MIRROR(self, layout, ob, md, wide_ui):
400         layout.prop(md, "merge_limit")
401         if wide_ui:
402             split = layout.split(percentage=0.25)
403         else:
404             split = layout.split(percentage=0.4)
405
406         col = split.column()
407         col.label(text="Axis:")
408         col.prop(md, "x")
409         col.prop(md, "y")
410         col.prop(md, "z")
411
412         if wide_ui:
413             col = split.column()
414         else:
415             subsplit = layout.split()
416             col = subsplit.column()
417         col.label(text="Options:")
418         col.prop(md, "clip", text="Clipping")
419         col.prop(md, "mirror_vertex_groups", text="Vertex Groups")
420
421         col = split.column()
422         col.label(text="Textures:")
423         col.prop(md, "mirror_u", text="U")
424         col.prop(md, "mirror_v", text="V")
425
426         col = layout.column()
427         col.label(text="Mirror Object:")
428         col.prop(md, "mirror_object", text="")
429
430     def MULTIRES(self, layout, ob, md, wide_ui):
431         if wide_ui:
432             layout.row().prop(md, "subdivision_type", expand=True)
433         else:
434             layout.row().prop(md, "subdivision_type", text="")
435
436         split = layout.split()
437         col = split.column()
438         col.prop(md, "levels", text="Preview")
439         col.prop(md, "sculpt_levels", text="Sculpt")
440         col.prop(md, "render_levels", text="Render")
441
442         if wide_ui:
443             col = split.column()
444
445         col.enabled = ob.mode != 'EDIT'
446         col.operator("object.multires_subdivide", text="Subdivide")
447         col.operator("object.multires_higher_levels_delete", text="Delete Higher")
448         col.operator("object.multires_reshape", text="Reshape")
449         col.prop(md, "optimal_display")
450
451         layout.separator()
452
453         col = layout.column()
454         row = col.row()
455         if md.external:
456             row.operator("object.multires_pack_external", text="Pack External")
457             row.label()
458             row = col.row()
459             row.prop(md, "filename", text="")
460         else:
461             row.operator("object.multires_save_external", text="Save External...")
462             row.label()
463
464     def PARTICLE_INSTANCE(self, layout, ob, md, wide_ui):
465         layout.prop(md, "object")
466         layout.prop(md, "particle_system_number", text="Particle System")
467
468         split = layout.split()
469         col = split.column()
470         col.label(text="Create From:")
471         col.prop(md, "normal")
472         col.prop(md, "children")
473         col.prop(md, "size")
474
475         if wide_ui:
476             col = split.column()
477         col.label(text="Show Particles When:")
478         col.prop(md, "alive")
479         col.prop(md, "unborn")
480         col.prop(md, "dead")
481
482         layout.separator()
483
484         layout.prop(md, "path", text="Create Along Paths")
485
486         split = layout.split()
487         split.active = md.path
488         col = split.column()
489         col.row().prop(md, "axis", expand=True)
490         col.prop(md, "keep_shape")
491
492         if wide_ui:
493             col = split.column()
494         col.prop(md, "position", slider=True)
495         col.prop(md, "random_position", text="Random", slider=True)
496
497     def PARTICLE_SYSTEM(self, layout, ob, md, wide_ui):
498         layout.label(text="See Particle panel.")
499
500     def SCREW(self, layout, ob, md, wide_ui):
501         split = layout.split()
502         
503         col = split.column()
504         col.prop(md, "axis")
505         col.prop(md, "object", text="AxisOb")
506         col.prop(md, "angle")
507         col.prop(md, "steps")
508         col.prop(md, "render_steps")
509         
510         if wide_ui:
511             col = split.column()
512         row = col.row()
513         row.active = (md.object is None or md.use_object_screw_offset == False)
514         row.prop(md, "screw_offset")
515         row = col.row()
516         row.active = (md.object is not None)
517         row.prop(md, "use_object_screw_offset")
518         col.prop(md, "use_normal_calculate")
519         col.prop(md, "use_normal_flip")
520         col.prop(md, "iterations")
521         
522
523     def SHRINKWRAP(self, layout, ob, md, wide_ui):
524         split = layout.split()
525         col = split.column()
526         col.label(text="Target:")
527         col.prop(md, "target", text="")
528         if wide_ui:
529             col = split.column()
530         col.label(text="Vertex Group:")
531         col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
532
533         split = layout.split()
534
535         col = split.column()
536         col.prop(md, "offset")
537         col.prop(md, "subsurf_levels")
538
539         if wide_ui:
540             col = split.column()
541             col.label(text="Mode:")
542         col.prop(md, "mode", text="")
543
544         if wide_ui:
545             split = layout.split(percentage=0.25)
546         else:
547             split = layout.split(percentage=0.35)
548         col = split.column()
549
550         if md.mode == 'PROJECT':
551             col.label(text="Axis:")
552             col.prop(md, "x")
553             col.prop(md, "y")
554             col.prop(md, "z")
555
556             col = split.column()
557             col.label(text="Direction:")
558             col.prop(md, "negative")
559             col.prop(md, "positive")
560
561             if wide_ui:
562                 col = split.column()
563             else:
564                 subsplit = layout.split()
565                 col = subsplit.column()
566             col.label(text="Cull Faces:")
567             col.prop(md, "cull_front_faces", text="Front")
568             col.prop(md, "cull_back_faces", text="Back")
569
570             layout.label(text="Auxiliary Target:")
571             layout.prop(md, "auxiliary_target", text="")
572
573         elif md.mode == 'NEAREST_SURFACEPOINT':
574             layout.prop(md, "keep_above_surface")
575
576     def SIMPLE_DEFORM(self, layout, ob, md, wide_ui):
577         split = layout.split()
578
579         col = split.column()
580         col.label(text="Mode:")
581         col.prop(md, "mode", text="")
582
583         if wide_ui:
584             col = split.column()
585         col.label(text="Vertex Group:")
586         col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
587
588         split = layout.split()
589
590         col = split.column()
591         col.label(text="Origin:")
592         col.prop(md, "origin", text="")
593         sub = col.column()
594         sub.active = (md.origin != "")
595         sub.prop(md, "relative")
596
597         if wide_ui:
598             col = split.column()
599         col.label(text="Deform:")
600         col.prop(md, "factor")
601         col.prop(md, "limits", slider=True)
602         if md.mode in ('TAPER', 'STRETCH'):
603             col.prop(md, "lock_x_axis")
604             col.prop(md, "lock_y_axis")
605
606     def SMOKE(self, layout, ob, md, wide_ui):
607         layout.label(text="See Smoke panel.")
608
609     def SMOOTH(self, layout, ob, md, wide_ui):
610         split = layout.split(percentage=0.25)
611
612         col = split.column()
613         col.label(text="Axis:")
614         col.prop(md, "x")
615         col.prop(md, "y")
616         col.prop(md, "z")
617
618         col = split.column()
619         col.prop(md, "factor")
620         col.prop(md, "repeat")
621         col.label(text="Vertex Group:")
622         col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
623
624     def SOFT_BODY(self, layout, ob, md, wide_ui):
625         layout.label(text="See Soft Body panel.")
626
627     def SOLIDIFY(self, layout, ob, md, wide_ui):
628
629         split = layout.split()
630
631         col = split.column()
632         col.prop(md, "thickness")
633         col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
634
635         col.label(text="Crease:")
636         col.prop(md, "edge_crease_inner", text="Inner")
637         col.prop(md, "edge_crease_outer", text="Outer")
638         col.prop(md, "edge_crease_rim", text="Rim")
639
640         if wide_ui:
641             col = split.column()
642
643         col.prop(md, "offset")
644         colsub = col.column()
645         colsub.active = (md.vertex_group is not "")
646         colsub.prop(md, "invert", text="Invert")
647
648         if wide_ui:
649             col.label(text="")
650
651         col.prop(md, "use_rim")
652         col.prop(md, "use_even_offset")
653         col.prop(md, "use_quality_normals")
654
655         # col = layout.column()
656         # col.label(text="Vertex Group:")
657         # col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
658
659     def SUBSURF(self, layout, ob, md, wide_ui):
660         if wide_ui:
661             layout.row().prop(md, "subdivision_type", expand=True)
662         else:
663             layout.row().prop(md, "subdivision_type", text="")
664
665         split = layout.split()
666         col = split.column()
667         col.label(text="Subdivisions:")
668         col.prop(md, "levels", text="View")
669         col.prop(md, "render_levels", text="Render")
670
671         if wide_ui:
672             col = split.column()
673         col.label(text="Options:")
674         col.prop(md, "optimal_display")
675
676     def SURFACE(self, layout, ob, md, wide_ui):
677         layout.label(text="See Fields panel.")
678
679     def UV_PROJECT(self, layout, ob, md, wide_ui):
680         if ob.type == 'MESH':
681             split = layout.split()
682
683             col = split.column()
684             col.label(text="Image:")
685             col.prop(md, "image", text="")
686
687             if wide_ui:
688                 col = split.column()
689             col.label(text="UV Layer:")
690             col.prop_object(md, "uv_layer", ob.data, "uv_textures", text="")
691
692             split = layout.split()
693             col = split.column()
694             col.prop(md, "override_image")
695             col.prop(md, "num_projectors", text="Projectors")
696             for proj in md.projectors:
697                 col.prop(proj, "object", text="")
698
699             if wide_ui:
700                 col = split.column()
701             sub = col.column(align=True)
702             sub.prop(md, "aspect_x", text="Aspect X")
703             sub.prop(md, "aspect_y", text="Aspect Y")
704
705             sub = col.column(align=True)
706             sub.prop(md, "scale_x", text="Scale X")
707             sub.prop(md, "scale_y", text="Scale Y")
708
709     def WAVE(self, layout, ob, md, wide_ui):
710         split = layout.split()
711
712         col = split.column()
713         col.label(text="Motion:")
714         col.prop(md, "x")
715         col.prop(md, "y")
716         col.prop(md, "cyclic")
717
718         if wide_ui:
719             col = split.column()
720         col.prop(md, "normals")
721         sub = col.column()
722         sub.active = md.normals
723         sub.prop(md, "x_normal", text="X")
724         sub.prop(md, "y_normal", text="Y")
725         sub.prop(md, "z_normal", text="Z")
726
727         split = layout.split()
728
729         col = split.column()
730         col.label(text="Time:")
731         sub = col.column(align=True)
732         sub.prop(md, "time_offset", text="Offset")
733         sub.prop(md, "lifetime", text="Life")
734         col.prop(md, "damping_time", text="Damping")
735
736         if wide_ui:
737             col = split.column()
738         col.label(text="Position:")
739         sub = col.column(align=True)
740         sub.prop(md, "start_position_x", text="X")
741         sub.prop(md, "start_position_y", text="Y")
742         col.prop(md, "falloff_radius", text="Falloff")
743
744         layout.separator()
745
746         layout.prop(md, "start_position_object")
747         layout.prop_object(md, "vertex_group", ob, "vertex_groups")
748         layout.prop(md, "texture")
749         layout.prop(md, "texture_coordinates")
750         if md.texture_coordinates == 'MAP_UV' and ob.type == 'MESH':
751             layout.prop_object(md, "uv_layer", ob.data, "uv_textures")
752         elif md.texture_coordinates == 'OBJECT':
753             layout.prop(md, "texture_coordinates_object")
754
755         layout.separator()
756
757         split = layout.split()
758
759         col = split.column()
760         col.prop(md, "speed", slider=True)
761         col.prop(md, "height", slider=True)
762
763         if wide_ui:
764             col = split.column()
765         col.prop(md, "width", slider=True)
766         col.prop(md, "narrowness", slider=True)
767
768
769 classes = [
770     DATA_PT_modifiers]
771
772
773 def register():
774     register = bpy.types.register
775     for cls in classes:
776         register(cls)
777
778
779 def unregister():
780     unregister = bpy.types.unregister
781     for cls in classes:
782         unregister(cls)
783
784 if __name__ == "__main__":
785     register()