diff --git a/◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/R_ARRAY-MASTER/__INIT__.PY b/◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/R_ARRAY-MASTER/__INIT__.PY deleted file mode 100644 index 0b4143ba..00000000 --- a/◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/R_ARRAY-MASTER/__INIT__.PY +++ /dev/null @@ -1,666 +0,0 @@ - -import bpy,math,mathutils,blf,rna_keymap_ui - -from .RA_draw_ui import * -from mathutils import Matrix -from bpy.types import ( - PropertyGroup, - Menu - ) -from bpy.props import ( - IntProperty, - FloatProperty, - BoolProperty - ) -#// join objects option in modal operator -#// Reset array option in modal operator -#// Modal operator Ui -#// add Radial Array hotkey -#// preferences add hotkey in addon preferences menu -#// addon menu ui -#// add modal selectable toggle -#// add modal apply option -#// add modal ui tooltips -#// add make unique -#// add create collection toggle - - -bl_info = { - "name" : "R.Array", - "author" : "Syler", - "version": (0, 0, 1, 2), - "description": "Adds Radial Array Operator", - "blender" : (2, 80, 0), - "category" : "Object" -} -#+ handle the keymap -addon_keymaps = [] - -def add_hotkey(): - #* Ctrl Q call R_Array - wm = bpy.context.window_manager - km = wm.keyconfigs.addon.keymaps.new(name='Object Mode', space_type='EMPTY') - kmi = km.keymap_items.new(R_Array.bl_idname, 'Q', 'PRESS', ctrl=True) - addon_keymaps.append(km) - -def remove_hotkey(): - wm = bpy.context.window_manager - for km in addon_keymaps: - wm.keyconfigs.addon.keymaps.remove(km) - # clear the list - del addon_keymaps[:] -#--------------------------------------------------------------------------------------# -def RA_Update_Sel_Status(self, context): - if self.RA_Sel_Status == True: - for ob in self.RA_Parent.children: - ob.hide_select = False - if self.RA_Sel_Status == False: - for ob in self.RA_Parent.children: - ob.hide_select = True - -def RA_Update_ObjNum(self, context): - - if self.RA_Status == True: - - if len(self.RA_Parent.children) == self.RA_ObjNum: - pass - - #+ Add Objects - if len(self.RA_Parent.children) < self.RA_ObjNum: - object_list = [] - object_to_copy = self.RA_Parent.children[0] - # append already existing objects to object list - for c in self.RA_Parent.children: - object_list.append(c) - - - for i in range (len(self.RA_Parent.children), self.RA_ObjNum): - object_list.append(object_to_copy.copy()) - - - - # Add Objects To Collection - for index, ob in enumerate(object_list): - - # Reset Matrix - ob.matrix_basis = mathutils.Matrix() - - # set object location to RA_Parent + RA_Offset - ob.location[1] = self.RA_Parent.location[1] + self.RA_Parent.RA_Offset - # create angle variable - angle = math.radians(360/self.RA_Parent.RA_ObjNum) - - # rotate object - R = mathutils.Matrix.Rotation(angle * (index), 4, 'Z') - T = mathutils.Matrix.Translation([0, 0, 0]) - M = T @ R @ T.inverted() - ob.location = M @ ob.location - ob.rotation_euler.rotate(M) - - - # Parent Object - ob.parent = self.RA_Parent - self.RA_Parent.matrix_parent_inverse = ob.matrix_world.inverted() - ob.RA_Parent = self.RA_Parent - - # make objects selectable/unselectable - if self.RA_Sel_Status == True: - ob.hide_select = False - if self.RA_Sel_Status == False: - ob.hide_select = True - - # Change Object Name - ob.name = "RA - " + self.RA_Name + " - " + str(index) - # set RA Status - ob.RA_Status = True - # Link object - try: - self.RA_Parent.users_collection[0].objects.link(ob) - #print ("For LINK") - except: - #print ("PASS Linking object to collection failed") - pass - - #+ Remove Objects - if len(self.RA_Parent.children) > self.RA_ObjNum: - - # deselect all objects - for d in bpy.context.view_layer.objects: - d.select_set(False) - bpy.context.view_layer.objects.active = None - - # Make selectable and Select all objects that will be deleted - for i in range (self.RA_ObjNum, len(self.RA_Parent.children)): - self.RA_Parent.children[i].hide_select = False - self.RA_Parent.children[i].select_set(True) - # Delete Objects - bpy.ops.object.delete() - # select control Object - bpy.context.view_layer.objects.active = self.RA_Parent - self.RA_Parent.select_set(True) - for index, ob in enumerate(self.RA_Parent.children): - # Reset Matrix - ob.matrix_basis = mathutils.Matrix() - - # set object location to RA_Parent + RA_Offset - ob.location[1] = self.RA_Parent.location[1] + self.RA_Parent.RA_Offset - # create angle variable - angle = math.radians(360/self.RA_Parent.RA_ObjNum) - - # rotate object - R = mathutils.Matrix.Rotation(angle * (index), 4, 'Z') - T = mathutils.Matrix.Translation([0, 0, 0]) - M = T @ R @ T.inverted() - ob.location = M @ ob.location - ob.rotation_euler.rotate(M) - -def RA_Update_Offset(self, context): - - if self.RA_Status == True: - for ob in self.RA_Parent.children: - # define variables - loc = mathutils.Vector((0.0, self.RA_Offset, 0.0)) - rot = ob.rotation_euler - # rotate location - loc.rotate(rot) - # apply rotation - ob.location = loc - else: - pass -#--------------------------------------------------------------------------------------# -class R_Array(bpy.types.Operator): - bl_idname = 'sop.r_array' - bl_label = 'Radial Array' - bl_description = 'Radial Array S.Operator' - bl_options = {'REGISTER', 'UNDO'} - - - - - #?Useless !? - @classmethod - def poll(cls, context): - return True - - def execute(self, context): - - #Create Bpy.context Variable - C = bpy.context - active_object = C.active_object - - - # call modal if RA_Status = True - try: - if active_object.RA_Status == True: - bpy.ops.sop.ra_modal('INVOKE_DEFAULT') - return {'FINISHED'} - except: - pass - # Check Selected Cancel if NOT Mesh - if C.selected_objects == [] or C.active_object.type != 'MESH': - self.report({'INFO'}, "No Mesh Selected") - return {'CANCELLED'} - - - # Create Variables - L_Objects = [] # object list - ob = active_object # active object reference - ob_collections = ob.users_collection # active Object collections - f_name = ob.name # Object Name - point = ob.location.copy() # Middle point - is_col_new = True - - - # Create New Collection - if bpy.context.preferences.addons[__name__].preferences.col_toggle == True: - for q in bpy.data.collections: - if q.name == "RA -" + f_name: - collection = q - is_col_new = False - try: - for col in ob_collections: - col.objects.unlink(ob) - collection.objects.link(ob) - except: - pass - - - if is_col_new == True: - # create and link new collection - collection = bpy.data.collections.new(name="RA -" + f_name) - bpy.context.scene.collection.children.link(collection) - print ("NEW") - # Move Object to collection - for col in ob_collections: - col.objects.unlink(ob) - collection.objects.link(ob) - else: - collection = ob_collections[0] - - # Create/Location/Name/Status/set RA_Parent/Link Empty and other memery - empty = bpy.data.objects.new( "empty", None ) - empty.location = point - empty.name = ".RA - " + ob.name + " - Control Empty" - empty.RA_Status = True - empty.RA_Parent = empty - empty.RA_Name = f_name - empty.RA_Sel_Status = bpy.context.preferences.addons[__name__].preferences.selectable - collection.objects.link(empty) - - # Move object - ob.location[1] = ob.location[1] + ob.RA_Offset - - # Deselect Active Object and select Control Object - ob.select_set(False) - empty.select_set(True) - - # set empty as active object - bpy.context.view_layer.objects.active = empty - - # create duplicate objects - for o in range(0, empty.RA_ObjNum): - - if o == 0: - L_Objects.append(ob) - if o != 0: - L_Objects.append(ob.copy()) - # Add Objects To Collection - for index, ob in enumerate(L_Objects): - # create angle variable - angle = math.radians(360/empty.RA_ObjNum) - - - # rotate object - R = mathutils.Matrix.Rotation(angle * (index), 4, 'Z') - T = mathutils.Matrix.Translation([0, 0, 0]) - M = T @ R @ T.inverted() - ob.location = M @ ob.location - ob.rotation_euler.rotate(M) - - # Parent Object - ob.parent = empty - empty.matrix_parent_inverse = ob.matrix_world.inverted() - ob.RA_Parent = empty - - # make objects selectable/unselectable - if empty.RA_Sel_Status == True: - ob.hide_select = False - if empty.RA_Sel_Status == False: - ob.hide_select = True - - # Change Object Name - ob.name = "RA - " + str(f_name) + " - " + str(index) - # Set RA Status - ob.RA_Status = True - - # Link object - try: - collection.objects.link(ob) - #print ("For LINK") - except: - #print ("PASS Linking object to collection failed") - pass - bpy.ops.sop.ra_modal('INVOKE_DEFAULT') - - return {'FINISHED'} -#--------------------------------------------------------------------------------------# -class RA_Modal(bpy.types.Operator): - # Change Radial Array - bl_idname = "sop.ra_modal" - bl_label = "Radial Array Modal" - bl_options = {"REGISTER", "UNDO", "BLOCKING", "GRAB_CURSOR", "INTERNAL"} #- add later!? - - first_mouse_x: IntProperty() - I_RA_Offset: FloatProperty() - I_RA_ObjNum: IntProperty() - unq_mode: BoolProperty() - - - def modal(self, context, event): - - # context shortcut - C = context - OB = C.object - context.area.tag_redraw() #? - prefs = bpy.context.preferences.addons[__name__].preferences - # -------------------------------------------------------------# - #+ change offset - if event.type == 'MOUSEMOVE' : - delta = self.first_mouse_x - event.mouse_x - if event.shift: - C.object.RA_Offset = round((self.I_RA_Offset + delta * 0.01)) - else: - C.object.RA_Offset = self.I_RA_Offset + delta * 0.01 - # -------------------------------------------------------------# - #+ add/remove Objects - if event.type == 'WHEELUPMOUSE' and OB.RA_Unq_mode == False: - OB.RA_ObjNum = OB.RA_ObjNum + 1 - - if event.type == 'WHEELDOWNMOUSE' and OB.RA_Unq_mode == False: - OB.RA_ObjNum = OB.RA_ObjNum - 1 - # -------------------------------------------------------------# - #+ call the tarnslation operator - if event.type == 'G' and event.value == "PRESS": - - C.tool_settings.use_snap = True - C.tool_settings.snap_elements = {'FACE'} - C.tool_settings.use_snap_align_rotation = True - - bpy.ops.transform.translate('INVOKE_DEFAULT') - bpy.types.SpaceView3D.draw_handler_remove(self.ra_draw_b, 'WINDOW') - bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW') - return {'FINISHED'} - # -------------------------------------------------------------# - - #+ join objects - if event.type == 'J' and event.value == "PRESS": - objects = OB.RA_Parent.children - location = OB.RA_Parent.location - cursor_location = bpy.context.scene.cursor.location.copy() - - # deselect objects and select control object - for o in C.selected_objects: - o.select_set(False) - C.object.RA_Parent.hide_select = False - bpy.context.view_layer.objects.active = C.object.RA_Parent - C.object.RA_Parent.select_set(True) - - # Delete control object - bpy.ops.object.delete() - - for ob in objects: - ob.hide_select = False - ob.select_set(True) - bpy.context.view_layer.objects.active = objects[0] - - - bpy.context.scene.cursor.location = location - bpy.ops.view3d.snap_selected_to_cursor(use_offset=True) - bpy.ops.object.parent_clear(type='CLEAR_KEEP_TRANSFORM') - bpy.ops.object.join() - bpy.ops.object.origin_set(type='ORIGIN_CURSOR') - bpy.context.scene.cursor.location = cursor_location - bpy.types.SpaceView3D.draw_handler_remove(self.ra_draw_b, 'WINDOW') - bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW') - return {'FINISHED'} - # -------------------------------------------------------------# - - #+ Reset - if event.type == 'R' and event.value == "PRESS": - - objects = OB.RA_Parent.children - name = OB.RA_Parent.RA_Name - # deslect all objects - for o in C.selected_objects: - o.select_set(False) - # select objects - for ob in objects: - if ob != objects[0]: - ob.hide_select = False - ob.select_set(True) - # delete objects - bpy.ops.object.delete() - - # select object and clear parent and other memery - objects[0].location = objects[0].RA_Parent.location - objects[0].RA_Parent.select_set(True) - bpy.ops.object.delete() - objects[0].hide_select = False - bpy.context.view_layer.objects.active = objects[0] - objects[0].select_set(True) - objects[0].parent = None - objects[0].name = name - try: - del objects[0]["RA_Parent"] - del objects[0]["RA_Status"] - except: - pass - - bpy.types.SpaceView3D.draw_handler_remove(self.ra_draw_b, 'WINDOW') - bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW') - return {'FINISHED'} - #+ Apply - if event.type == 'A' and event.value == "PRESS": - - objects = OB.RA_Parent.children - # deslect all objects - for o in C.selected_objects: - o.select_set(False) - # select and delete control object - objects[0].RA_Parent.select_set(True) - bpy.ops.object.delete() - # select objects - for ob in objects: - - ob.hide_select = False - ob.select_set(True) - ob.RA_Status = False - ob.parent = None - - bpy.context.view_layer.objects.active = objects[0] - bpy.types.SpaceView3D.draw_handler_remove(self.ra_draw_b, 'WINDOW') - bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW') - return {'FINISHED'} - #+ Make Unique Mode toggle - if event.type == 'Q' and event.value == "PRESS": - objects = OB.RA_Parent.children - if OB.RA_Unq_mode == True: - for ob in objects: - ob.data = objects[0].data - OB.RA_Unq_mode = False - else: - #* make unique data - for ob in objects: - ob.data = ob.data.copy() - OB.RA_Unq_mode = True - #+ Selectable toggle - if event.type == 'S' and event.value == "PRESS": - if OB.RA_Sel_Status == True: - OB.RA_Sel_Status = False - else: - OB.RA_Sel_Status = True - #+ Help Mode toggle - if event.type == 'H' and event.value == "PRESS": - if prefs.modal_help == True: - prefs.modal_help = False - else: - prefs.modal_help = True - # -------------------------------------------------------------# - #+ Finish/Cancel Modal - elif event.type == 'LEFTMOUSE': - bpy.types.SpaceView3D.draw_handler_remove(self.ra_draw_b, 'WINDOW') - bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW') - return {'FINISHED'} - - elif event.type in {'RIGHTMOUSE', 'ESC'}: - C.object.RA_Offset = self.I_RA_Offset - C.object.RA_ObjNum = self.I_RA_ObjNum - bpy.types.SpaceView3D.draw_handler_remove(self.ra_draw_b, 'WINDOW') - bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW') - return {'CANCELLED'} - - return {'RUNNING_MODAL'} - - def invoke(self, context, event): - # context shortcut - C = context - if C.object.RA_Status == True: - for o in C.selected_objects: - o.select_set(False) - bpy.context.view_layer.objects.active = C.object.RA_Parent - C.object.RA_Parent.select_set(True) - - - - if C.object: - # set initial Variable values - self.first_mouse_x = event.mouse_x - self.I_RA_Offset = C.object.RA_Offset - self.I_RA_ObjNum = C.object.RA_ObjNum - self.unq_mode = C.object.RA_Unq_mode - self.prefs = bpy.context.preferences.addons[__name__].preferences - ###-------------------------------------------### - args = (self, context, self.prefs) - - - self.ra_draw_b = bpy.types.SpaceView3D.draw_handler_add(RA_draw_B, args, 'WINDOW', 'POST_PIXEL') - self._handle = bpy.types.SpaceView3D.draw_handler_add(RA_modal_Draw, args, 'WINDOW', 'POST_PIXEL') - - self.mouse_path = [] - - context.window_manager.modal_handler_add(self) - return {'RUNNING_MODAL'} - else: - self.report({'WARNING'}, "No active object, could not finish") - return {'CANCELLED'} -#--------------------------------------------------------------------------------------# -class RA_Prefs(bpy.types.AddonPreferences): - bl_idname = __name__ - # here you define the addons customizable props - offset: bpy.props.FloatProperty(default=5) - objnum: bpy.props.IntProperty(default=6) - selectable: bpy.props.BoolProperty(default= True, description="False = Only Control Object is selectable") - modal_help: bpy.props.BoolProperty(default= False, description="True = Display Help text in modal") - col_toggle: bpy.props.BoolProperty(default= False, description="True = Create New Collection") - # here you specify how they are drawn - def draw(self, context): - layout = self.layout - box = layout.box() - split = box.split() - col = split.column() - # Layout ---------------------------------------------------------------- # - col.label(text="Default Values:") - col.prop(self, "offset",text="Default Offset") - col.prop(self, "objnum",text="Default Count") - col.prop(self, "selectable",text="Selectable") - col.prop(self, "modal_help",text="Modal Help") - col.label(text ="Options:") - col.prop(self, "col_toggle",text="Create New Collection") - col.label(text="Keymap:") - - - wm = bpy.context.window_manager - kc = wm.keyconfigs.user - km = kc.keymaps['Object Mode'] - #kmi = km.keymap_items[0] - kmi = get_hotkey_entry_item(km, 'sop.r_array', 'sop.r_array') - - if addon_keymaps: - km = addon_keymaps[0].active() - col.context_pointer_set("keymap", km) - rna_keymap_ui.draw_kmi([], kc, km, kmi, col, 0) - - - -def get_addon_preferences(): - ''' quick wrapper for referencing addon preferences ''' - addon_preferences = bpy.context.user_preferences.addons[__name__].preferences - return addon_preferences -def get_hotkey_entry_item(km, kmi_name, kmi_value): - ''' - returns hotkey of specific type, with specific properties.name (keymap is not a dict, so referencing by keys is not enough - if there are multiple hotkeys!) - ''' - for i, km_item in enumerate(km.keymap_items): - if km.keymap_items.keys()[i] == kmi_name: - if km.keymap_items[i].idname == kmi_value: - return km_item - return None - -classes = ( - RA_Prefs, - R_Array, - RA_Modal, -) - - -def register(): - print ("----------------------------------") - print ("S.Ops Init") - print ("----------------------------------") - - #+ add hotkey - add_hotkey() - - from bpy.utils import register_class - for cls in classes: - register_class(cls) - # Init Props - - bpy.types.Object.RA_Parent = bpy.props.PointerProperty( - name="RA Parent", - description="RA Parent Object Reference", - type=bpy.types.Object - ) - - bpy.types.Object.RA_ObjNum = bpy.props.IntProperty( - name="RA ObjNum", - description="RA Object Number", - default = bpy.context.preferences.addons[__name__].preferences.objnum, - min = 1, - update = RA_Update_ObjNum - ) - - bpy.types.Object.RA_Offset = bpy.props.FloatProperty( - name="Offset", - description="Radial Array Offset", - default = bpy.context.preferences.addons[__name__].preferences.offset, - update = RA_Update_Offset - ) - - bpy.types.Object.RA_Status = bpy.props.BoolProperty( - name="Status", - description="Radial Array Status", - default = False - ) - - bpy.types.Object.RA_Sel_Status = bpy.props.BoolProperty( - name="Selectable", - description="False = Only Control Object is selectable", - default = bpy.context.preferences.addons[__name__].preferences.selectable, - update = RA_Update_Sel_Status - ) - - bpy.types.Object.RA_Unq_mode = bpy.props.BoolProperty( - name="Unique Mode", - description="True = all objects have a unique data block(Disables Count in Modal)", - default = False - ) - bpy.types.Object.RA_Name = bpy.props.StringProperty( - name="Name", - description="Radial Array Name", - default = "Nameing Error" - ) - - - print ("----------------------------------") - print ("S.Ops Register End") - print ("----------------------------------") - - -def unregister(): - print ("----------------------------------") - print ("S.Ops unRegister Start") - print ("----------------------------------") - #+ remove hotkey - remove_hotkey() - - from bpy.utils import unregister_class - for cls in classes: - unregister_class(cls) - - - - - - print ("----------------------------------") - print ("S.Ops unRegister End") - print ("----------------------------------") - -if __name__ == "__main__": - register() - - - - -