__INIT__.PY 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  1. import bpy,math,mathutils,blf,rna_keymap_ui
  2. from .RA_draw_ui import *
  3. from mathutils import Matrix
  4. from bpy.types import (
  5. PropertyGroup,
  6. Menu
  7. )
  8. from bpy.props import (
  9. IntProperty,
  10. FloatProperty,
  11. BoolProperty
  12. )
  13. #// join objects option in modal operator
  14. #// Reset array option in modal operator
  15. #// Modal operator Ui
  16. #// add Radial Array hotkey
  17. #// preferences add hotkey in addon preferences menu
  18. #// addon menu ui
  19. #// add modal selectable toggle
  20. #// add modal apply option
  21. #// add modal ui tooltips
  22. #// add make unique
  23. #// add create collection toggle
  24. bl_info = {
  25. "name" : "R.Array",
  26. "author" : "Syler",
  27. "version": (0, 0, 1, 2),
  28. "description": "Adds Radial Array Operator",
  29. "blender" : (2, 80, 0),
  30. "category" : "Object"
  31. }
  32. #+ handle the keymap
  33. addon_keymaps = []
  34. def add_hotkey():
  35. #* Ctrl Q call R_Array
  36. wm = bpy.context.window_manager
  37. km = wm.keyconfigs.addon.keymaps.new(name='Object Mode', space_type='EMPTY')
  38. kmi = km.keymap_items.new(R_Array.bl_idname, 'Q', 'PRESS', ctrl=True)
  39. addon_keymaps.append(km)
  40. def remove_hotkey():
  41. wm = bpy.context.window_manager
  42. for km in addon_keymaps:
  43. wm.keyconfigs.addon.keymaps.remove(km)
  44. # clear the list
  45. del addon_keymaps[:]
  46. #--------------------------------------------------------------------------------------#
  47. def RA_Update_Sel_Status(self, context):
  48. if self.RA_Sel_Status == True:
  49. for ob in self.RA_Parent.children:
  50. ob.hide_select = False
  51. if self.RA_Sel_Status == False:
  52. for ob in self.RA_Parent.children:
  53. ob.hide_select = True
  54. def RA_Update_ObjNum(self, context):
  55. if self.RA_Status == True:
  56. if len(self.RA_Parent.children) == self.RA_ObjNum:
  57. pass
  58. #+ Add Objects
  59. if len(self.RA_Parent.children) < self.RA_ObjNum:
  60. object_list = []
  61. object_to_copy = self.RA_Parent.children[0]
  62. # append already existing objects to object list
  63. for c in self.RA_Parent.children:
  64. object_list.append(c)
  65. for i in range (len(self.RA_Parent.children), self.RA_ObjNum):
  66. object_list.append(object_to_copy.copy())
  67. # Add Objects To Collection
  68. for index, ob in enumerate(object_list):
  69. # Reset Matrix
  70. ob.matrix_basis = mathutils.Matrix()
  71. # set object location to RA_Parent + RA_Offset
  72. ob.location[1] = self.RA_Parent.location[1] + self.RA_Parent.RA_Offset
  73. # create angle variable
  74. angle = math.radians(360/self.RA_Parent.RA_ObjNum)
  75. # rotate object
  76. R = mathutils.Matrix.Rotation(angle * (index), 4, 'Z')
  77. T = mathutils.Matrix.Translation([0, 0, 0])
  78. M = T @ R @ T.inverted()
  79. ob.location = M @ ob.location
  80. ob.rotation_euler.rotate(M)
  81. # Parent Object
  82. ob.parent = self.RA_Parent
  83. self.RA_Parent.matrix_parent_inverse = ob.matrix_world.inverted()
  84. ob.RA_Parent = self.RA_Parent
  85. # make objects selectable/unselectable
  86. if self.RA_Sel_Status == True:
  87. ob.hide_select = False
  88. if self.RA_Sel_Status == False:
  89. ob.hide_select = True
  90. # Change Object Name
  91. ob.name = "RA - " + self.RA_Name + " - " + str(index)
  92. # set RA Status
  93. ob.RA_Status = True
  94. # Link object
  95. try:
  96. self.RA_Parent.users_collection[0].objects.link(ob)
  97. #print ("For LINK")
  98. except:
  99. #print ("PASS Linking object to collection failed")
  100. pass
  101. #+ Remove Objects
  102. if len(self.RA_Parent.children) > self.RA_ObjNum:
  103. # deselect all objects
  104. for d in bpy.context.view_layer.objects:
  105. d.select_set(False)
  106. bpy.context.view_layer.objects.active = None
  107. # Make selectable and Select all objects that will be deleted
  108. for i in range (self.RA_ObjNum, len(self.RA_Parent.children)):
  109. self.RA_Parent.children[i].hide_select = False
  110. self.RA_Parent.children[i].select_set(True)
  111. # Delete Objects
  112. bpy.ops.object.delete()
  113. # select control Object
  114. bpy.context.view_layer.objects.active = self.RA_Parent
  115. self.RA_Parent.select_set(True)
  116. for index, ob in enumerate(self.RA_Parent.children):
  117. # Reset Matrix
  118. ob.matrix_basis = mathutils.Matrix()
  119. # set object location to RA_Parent + RA_Offset
  120. ob.location[1] = self.RA_Parent.location[1] + self.RA_Parent.RA_Offset
  121. # create angle variable
  122. angle = math.radians(360/self.RA_Parent.RA_ObjNum)
  123. # rotate object
  124. R = mathutils.Matrix.Rotation(angle * (index), 4, 'Z')
  125. T = mathutils.Matrix.Translation([0, 0, 0])
  126. M = T @ R @ T.inverted()
  127. ob.location = M @ ob.location
  128. ob.rotation_euler.rotate(M)
  129. def RA_Update_Offset(self, context):
  130. if self.RA_Status == True:
  131. for ob in self.RA_Parent.children:
  132. # define variables
  133. loc = mathutils.Vector((0.0, self.RA_Offset, 0.0))
  134. rot = ob.rotation_euler
  135. # rotate location
  136. loc.rotate(rot)
  137. # apply rotation
  138. ob.location = loc
  139. else:
  140. pass
  141. #--------------------------------------------------------------------------------------#
  142. class R_Array(bpy.types.Operator):
  143. bl_idname = 'sop.r_array'
  144. bl_label = 'Radial Array'
  145. bl_description = 'Radial Array S.Operator'
  146. bl_options = {'REGISTER', 'UNDO'}
  147. #?Useless !?
  148. @classmethod
  149. def poll(cls, context):
  150. return True
  151. def execute(self, context):
  152. #Create Bpy.context Variable
  153. C = bpy.context
  154. active_object = C.active_object
  155. # call modal if RA_Status = True
  156. try:
  157. if active_object.RA_Status == True:
  158. bpy.ops.sop.ra_modal('INVOKE_DEFAULT')
  159. return {'FINISHED'}
  160. except:
  161. pass
  162. # Check Selected Cancel if NOT Mesh
  163. if C.selected_objects == [] or C.active_object.type != 'MESH':
  164. self.report({'INFO'}, "No Mesh Selected")
  165. return {'CANCELLED'}
  166. # Create Variables
  167. L_Objects = [] # object list
  168. ob = active_object # active object reference
  169. ob_collections = ob.users_collection # active Object collections
  170. f_name = ob.name # Object Name
  171. point = ob.location.copy() # Middle point
  172. is_col_new = True
  173. # Create New Collection
  174. if bpy.context.preferences.addons[__name__].preferences.col_toggle == True:
  175. for q in bpy.data.collections:
  176. if q.name == "RA -" + f_name:
  177. collection = q
  178. is_col_new = False
  179. try:
  180. for col in ob_collections:
  181. col.objects.unlink(ob)
  182. collection.objects.link(ob)
  183. except:
  184. pass
  185. if is_col_new == True:
  186. # create and link new collection
  187. collection = bpy.data.collections.new(name="RA -" + f_name)
  188. bpy.context.scene.collection.children.link(collection)
  189. print ("NEW")
  190. # Move Object to collection
  191. for col in ob_collections:
  192. col.objects.unlink(ob)
  193. collection.objects.link(ob)
  194. else:
  195. collection = ob_collections[0]
  196. # Create/Location/Name/Status/set RA_Parent/Link Empty and other memery
  197. empty = bpy.data.objects.new( "empty", None )
  198. empty.location = point
  199. empty.name = ".RA - " + ob.name + " - Control Empty"
  200. empty.RA_Status = True
  201. empty.RA_Parent = empty
  202. empty.RA_Name = f_name
  203. empty.RA_Sel_Status = bpy.context.preferences.addons[__name__].preferences.selectable
  204. collection.objects.link(empty)
  205. # Move object
  206. ob.location[1] = ob.location[1] + ob.RA_Offset
  207. # Deselect Active Object and select Control Object
  208. ob.select_set(False)
  209. empty.select_set(True)
  210. # set empty as active object
  211. bpy.context.view_layer.objects.active = empty
  212. # create duplicate objects
  213. for o in range(0, empty.RA_ObjNum):
  214. if o == 0:
  215. L_Objects.append(ob)
  216. if o != 0:
  217. L_Objects.append(ob.copy())
  218. # Add Objects To Collection
  219. for index, ob in enumerate(L_Objects):
  220. # create angle variable
  221. angle = math.radians(360/empty.RA_ObjNum)
  222. # rotate object
  223. R = mathutils.Matrix.Rotation(angle * (index), 4, 'Z')
  224. T = mathutils.Matrix.Translation([0, 0, 0])
  225. M = T @ R @ T.inverted()
  226. ob.location = M @ ob.location
  227. ob.rotation_euler.rotate(M)
  228. # Parent Object
  229. ob.parent = empty
  230. empty.matrix_parent_inverse = ob.matrix_world.inverted()
  231. ob.RA_Parent = empty
  232. # make objects selectable/unselectable
  233. if empty.RA_Sel_Status == True:
  234. ob.hide_select = False
  235. if empty.RA_Sel_Status == False:
  236. ob.hide_select = True
  237. # Change Object Name
  238. ob.name = "RA - " + str(f_name) + " - " + str(index)
  239. # Set RA Status
  240. ob.RA_Status = True
  241. # Link object
  242. try:
  243. collection.objects.link(ob)
  244. #print ("For LINK")
  245. except:
  246. #print ("PASS Linking object to collection failed")
  247. pass
  248. bpy.ops.sop.ra_modal('INVOKE_DEFAULT')
  249. return {'FINISHED'}
  250. #--------------------------------------------------------------------------------------#
  251. class RA_Modal(bpy.types.Operator):
  252. # Change Radial Array
  253. bl_idname = "sop.ra_modal"
  254. bl_label = "Radial Array Modal"
  255. bl_options = {"REGISTER", "UNDO", "BLOCKING", "GRAB_CURSOR", "INTERNAL"} #- add later!?
  256. first_mouse_x: IntProperty()
  257. I_RA_Offset: FloatProperty()
  258. I_RA_ObjNum: IntProperty()
  259. unq_mode: BoolProperty()
  260. def modal(self, context, event):
  261. # context shortcut
  262. C = context
  263. OB = C.object
  264. context.area.tag_redraw() #?
  265. prefs = bpy.context.preferences.addons[__name__].preferences
  266. # -------------------------------------------------------------#
  267. #+ change offset
  268. if event.type == 'MOUSEMOVE' :
  269. delta = self.first_mouse_x - event.mouse_x
  270. if event.shift:
  271. C.object.RA_Offset = round((self.I_RA_Offset + delta * 0.01))
  272. else:
  273. C.object.RA_Offset = self.I_RA_Offset + delta * 0.01
  274. # -------------------------------------------------------------#
  275. #+ add/remove Objects
  276. if event.type == 'WHEELUPMOUSE' and OB.RA_Unq_mode == False:
  277. OB.RA_ObjNum = OB.RA_ObjNum + 1
  278. if event.type == 'WHEELDOWNMOUSE' and OB.RA_Unq_mode == False:
  279. OB.RA_ObjNum = OB.RA_ObjNum - 1
  280. # -------------------------------------------------------------#
  281. #+ call the tarnslation operator
  282. if event.type == 'G' and event.value == "PRESS":
  283. C.tool_settings.use_snap = True
  284. C.tool_settings.snap_elements = {'FACE'}
  285. C.tool_settings.use_snap_align_rotation = True
  286. bpy.ops.transform.translate('INVOKE_DEFAULT')
  287. bpy.types.SpaceView3D.draw_handler_remove(self.ra_draw_b, 'WINDOW')
  288. bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
  289. return {'FINISHED'}
  290. # -------------------------------------------------------------#
  291. #+ join objects
  292. if event.type == 'J' and event.value == "PRESS":
  293. objects = OB.RA_Parent.children
  294. location = OB.RA_Parent.location
  295. cursor_location = bpy.context.scene.cursor.location.copy()
  296. # deselect objects and select control object
  297. for o in C.selected_objects:
  298. o.select_set(False)
  299. C.object.RA_Parent.hide_select = False
  300. bpy.context.view_layer.objects.active = C.object.RA_Parent
  301. C.object.RA_Parent.select_set(True)
  302. # Delete control object
  303. bpy.ops.object.delete()
  304. for ob in objects:
  305. ob.hide_select = False
  306. ob.select_set(True)
  307. bpy.context.view_layer.objects.active = objects[0]
  308. bpy.context.scene.cursor.location = location
  309. bpy.ops.view3d.snap_selected_to_cursor(use_offset=True)
  310. bpy.ops.object.parent_clear(type='CLEAR_KEEP_TRANSFORM')
  311. bpy.ops.object.join()
  312. bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
  313. bpy.context.scene.cursor.location = cursor_location
  314. bpy.types.SpaceView3D.draw_handler_remove(self.ra_draw_b, 'WINDOW')
  315. bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
  316. return {'FINISHED'}
  317. # -------------------------------------------------------------#
  318. #+ Reset
  319. if event.type == 'R' and event.value == "PRESS":
  320. objects = OB.RA_Parent.children
  321. name = OB.RA_Parent.RA_Name
  322. # deslect all objects
  323. for o in C.selected_objects:
  324. o.select_set(False)
  325. # select objects
  326. for ob in objects:
  327. if ob != objects[0]:
  328. ob.hide_select = False
  329. ob.select_set(True)
  330. # delete objects
  331. bpy.ops.object.delete()
  332. # select object and clear parent and other memery
  333. objects[0].location = objects[0].RA_Parent.location
  334. objects[0].RA_Parent.select_set(True)
  335. bpy.ops.object.delete()
  336. objects[0].hide_select = False
  337. bpy.context.view_layer.objects.active = objects[0]
  338. objects[0].select_set(True)
  339. objects[0].parent = None
  340. objects[0].name = name
  341. try:
  342. del objects[0]["RA_Parent"]
  343. del objects[0]["RA_Status"]
  344. except:
  345. pass
  346. bpy.types.SpaceView3D.draw_handler_remove(self.ra_draw_b, 'WINDOW')
  347. bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
  348. return {'FINISHED'}
  349. #+ Apply
  350. if event.type == 'A' and event.value == "PRESS":
  351. objects = OB.RA_Parent.children
  352. # deslect all objects
  353. for o in C.selected_objects:
  354. o.select_set(False)
  355. # select and delete control object
  356. objects[0].RA_Parent.select_set(True)
  357. bpy.ops.object.delete()
  358. # select objects
  359. for ob in objects:
  360. ob.hide_select = False
  361. ob.select_set(True)
  362. ob.RA_Status = False
  363. ob.parent = None
  364. bpy.context.view_layer.objects.active = objects[0]
  365. bpy.types.SpaceView3D.draw_handler_remove(self.ra_draw_b, 'WINDOW')
  366. bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
  367. return {'FINISHED'}
  368. #+ Make Unique Mode toggle
  369. if event.type == 'Q' and event.value == "PRESS":
  370. objects = OB.RA_Parent.children
  371. if OB.RA_Unq_mode == True:
  372. for ob in objects:
  373. ob.data = objects[0].data
  374. OB.RA_Unq_mode = False
  375. else:
  376. #* make unique data
  377. for ob in objects:
  378. ob.data = ob.data.copy()
  379. OB.RA_Unq_mode = True
  380. #+ Selectable toggle
  381. if event.type == 'S' and event.value == "PRESS":
  382. if OB.RA_Sel_Status == True:
  383. OB.RA_Sel_Status = False
  384. else:
  385. OB.RA_Sel_Status = True
  386. #+ Help Mode toggle
  387. if event.type == 'H' and event.value == "PRESS":
  388. if prefs.modal_help == True:
  389. prefs.modal_help = False
  390. else:
  391. prefs.modal_help = True
  392. # -------------------------------------------------------------#
  393. #+ Finish/Cancel Modal
  394. elif event.type == 'LEFTMOUSE':
  395. bpy.types.SpaceView3D.draw_handler_remove(self.ra_draw_b, 'WINDOW')
  396. bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
  397. return {'FINISHED'}
  398. elif event.type in {'RIGHTMOUSE', 'ESC'}:
  399. C.object.RA_Offset = self.I_RA_Offset
  400. C.object.RA_ObjNum = self.I_RA_ObjNum
  401. bpy.types.SpaceView3D.draw_handler_remove(self.ra_draw_b, 'WINDOW')
  402. bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
  403. return {'CANCELLED'}
  404. return {'RUNNING_MODAL'}
  405. def invoke(self, context, event):
  406. # context shortcut
  407. C = context
  408. if C.object.RA_Status == True:
  409. for o in C.selected_objects:
  410. o.select_set(False)
  411. bpy.context.view_layer.objects.active = C.object.RA_Parent
  412. C.object.RA_Parent.select_set(True)
  413. if C.object:
  414. # set initial Variable values
  415. self.first_mouse_x = event.mouse_x
  416. self.I_RA_Offset = C.object.RA_Offset
  417. self.I_RA_ObjNum = C.object.RA_ObjNum
  418. self.unq_mode = C.object.RA_Unq_mode
  419. self.prefs = bpy.context.preferences.addons[__name__].preferences
  420. ###-------------------------------------------###
  421. args = (self, context, self.prefs)
  422. self.ra_draw_b = bpy.types.SpaceView3D.draw_handler_add(RA_draw_B, args, 'WINDOW', 'POST_PIXEL')
  423. self._handle = bpy.types.SpaceView3D.draw_handler_add(RA_modal_Draw, args, 'WINDOW', 'POST_PIXEL')
  424. self.mouse_path = []
  425. context.window_manager.modal_handler_add(self)
  426. return {'RUNNING_MODAL'}
  427. else:
  428. self.report({'WARNING'}, "No active object, could not finish")
  429. return {'CANCELLED'}
  430. #--------------------------------------------------------------------------------------#
  431. class RA_Prefs(bpy.types.AddonPreferences):
  432. bl_idname = __name__
  433. # here you define the addons customizable props
  434. offset: bpy.props.FloatProperty(default=5)
  435. objnum: bpy.props.IntProperty(default=6)
  436. selectable: bpy.props.BoolProperty(default= True, description="False = Only Control Object is selectable")
  437. modal_help: bpy.props.BoolProperty(default= False, description="True = Display Help text in modal")
  438. col_toggle: bpy.props.BoolProperty(default= False, description="True = Create New Collection")
  439. # here you specify how they are drawn
  440. def draw(self, context):
  441. layout = self.layout
  442. box = layout.box()
  443. split = box.split()
  444. col = split.column()
  445. # Layout ---------------------------------------------------------------- #
  446. col.label(text="Default Values:")
  447. col.prop(self, "offset",text="Default Offset")
  448. col.prop(self, "objnum",text="Default Count")
  449. col.prop(self, "selectable",text="Selectable")
  450. col.prop(self, "modal_help",text="Modal Help")
  451. col.label(text ="Options:")
  452. col.prop(self, "col_toggle",text="Create New Collection")
  453. col.label(text="Keymap:")
  454. wm = bpy.context.window_manager
  455. kc = wm.keyconfigs.user
  456. km = kc.keymaps['Object Mode']
  457. #kmi = km.keymap_items[0]
  458. kmi = get_hotkey_entry_item(km, 'sop.r_array', 'sop.r_array')
  459. if addon_keymaps:
  460. km = addon_keymaps[0].active()
  461. col.context_pointer_set("keymap", km)
  462. rna_keymap_ui.draw_kmi([], kc, km, kmi, col, 0)
  463. def get_addon_preferences():
  464. ''' quick wrapper for referencing addon preferences '''
  465. addon_preferences = bpy.context.user_preferences.addons[__name__].preferences
  466. return addon_preferences
  467. def get_hotkey_entry_item(km, kmi_name, kmi_value):
  468. '''
  469. returns hotkey of specific type, with specific properties.name (keymap is not a dict, so referencing by keys is not enough
  470. if there are multiple hotkeys!)
  471. '''
  472. for i, km_item in enumerate(km.keymap_items):
  473. if km.keymap_items.keys()[i] == kmi_name:
  474. if km.keymap_items[i].idname == kmi_value:
  475. return km_item
  476. return None
  477. classes = (
  478. RA_Prefs,
  479. R_Array,
  480. RA_Modal,
  481. )
  482. def register():
  483. print ("----------------------------------")
  484. print ("S.Ops Init")
  485. print ("----------------------------------")
  486. #+ add hotkey
  487. add_hotkey()
  488. from bpy.utils import register_class
  489. for cls in classes:
  490. register_class(cls)
  491. # Init Props
  492. bpy.types.Object.RA_Parent = bpy.props.PointerProperty(
  493. name="RA Parent",
  494. description="RA Parent Object Reference",
  495. type=bpy.types.Object
  496. )
  497. bpy.types.Object.RA_ObjNum = bpy.props.IntProperty(
  498. name="RA ObjNum",
  499. description="RA Object Number",
  500. default = bpy.context.preferences.addons[__name__].preferences.objnum,
  501. min = 1,
  502. update = RA_Update_ObjNum
  503. )
  504. bpy.types.Object.RA_Offset = bpy.props.FloatProperty(
  505. name="Offset",
  506. description="Radial Array Offset",
  507. default = bpy.context.preferences.addons[__name__].preferences.offset,
  508. update = RA_Update_Offset
  509. )
  510. bpy.types.Object.RA_Status = bpy.props.BoolProperty(
  511. name="Status",
  512. description="Radial Array Status",
  513. default = False
  514. )
  515. bpy.types.Object.RA_Sel_Status = bpy.props.BoolProperty(
  516. name="Selectable",
  517. description="False = Only Control Object is selectable",
  518. default = bpy.context.preferences.addons[__name__].preferences.selectable,
  519. update = RA_Update_Sel_Status
  520. )
  521. bpy.types.Object.RA_Unq_mode = bpy.props.BoolProperty(
  522. name="Unique Mode",
  523. description="True = all objects have a unique data block(Disables Count in Modal)",
  524. default = False
  525. )
  526. bpy.types.Object.RA_Name = bpy.props.StringProperty(
  527. name="Name",
  528. description="Radial Array Name",
  529. default = "Nameing Error"
  530. )
  531. print ("----------------------------------")
  532. print ("S.Ops Register End")
  533. print ("----------------------------------")
  534. def unregister():
  535. print ("----------------------------------")
  536. print ("S.Ops unRegister Start")
  537. print ("----------------------------------")
  538. #+ remove hotkey
  539. remove_hotkey()
  540. from bpy.utils import unregister_class
  541. for cls in classes:
  542. unregister_class(cls)
  543. print ("----------------------------------")
  544. print ("S.Ops unRegister End")
  545. print ("----------------------------------")
  546. if __name__ == "__main__":
  547. register()