diff options
author | meta-androcto <meta.androcto1@gmail.com> | 2017-06-15 15:06:00 +0300 |
---|---|---|
committer | meta-androcto <meta.androcto1@gmail.com> | 2017-06-15 15:06:00 +0300 |
commit | c6676127556e5756e4c94f39784d27149f2eb86d (patch) | |
tree | a97b100b59224a3c3b8954b891968c4afa9bea79 /add_advanced_objects_menu/circle_array.py | |
parent | 17d293687324e86b2e94e6ca3574e294f3da3667 (diff) |
add advanced objects: split to 2 folders menu and panel
Diffstat (limited to 'add_advanced_objects_menu/circle_array.py')
-rw-r--r-- | add_advanced_objects_menu/circle_array.py | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/add_advanced_objects_menu/circle_array.py b/add_advanced_objects_menu/circle_array.py new file mode 100644 index 00000000..af5a6a0a --- /dev/null +++ b/add_advanced_objects_menu/circle_array.py @@ -0,0 +1,166 @@ +# gpl author: Antonis Karvelas + +# -*- coding: utf-8 -*- + +bl_info = { + "name": "Circle Array", + "author": "Antonis Karvelas", + "version": (1, 0, 1), + "blender": (2, 6, 7), + "location": "View3D > Object > Circle_Array", + "description": "Uses an existing array and creates an empty, " + "rotates it properly and makes a Circle Array", + "warning": "", + "wiki_url": "", + "category": "Mesh" + } + + +import bpy +from bpy.types import Operator +from math import radians + + +class Circle_Array(Operator): + bl_label = "Circle Array" + bl_idname = "objects.circle_array_operator" + bl_description = ("Creates an Array Modifier with offset empty object\n" + "Works with Mesh, Curve, Text and Surface\n" + "Use an object with an existing Array modifier\n" + "or rotate the newly created Empty with the name pattern\n" + "EMPTY_C_Array_ if the Array doesn't exist (angle: 360/Count)") + + @classmethod + def poll(cls, context): + return context.active_object is not None + + def check_empty_name(self, context): + new_name, def_name = "", "EMPTY_C_Array" + suffix = 1 + try: + # first slap a simple linear count + 1 for numeric suffix, if it fails + # harvest for the rightmost numbers and append the max value + list_obj = [] + obj_all = context.scene.objects + list_obj = [obj.name for obj in obj_all if obj.name.startswith(def_name)] + new_name = "{}_{}".format(def_name, len(list_obj) + 1) + + if new_name in list_obj: + from re import findall + test_num = [findall("\d+", words) for words in list_obj] + suffix += max([int(l[-1]) for l in test_num]) + new_name = "{}_{}".format(def_name, suffix) + return new_name + except: + return None + + def execute(self, context): + is_allowed = True + try: + allowed_obj = ['MESH', 'CURVE', 'SURFACE', 'FONT'] + for obj in context.selected_objects: + if obj.type not in allowed_obj: + is_allowed = False + break + + if not is_allowed: + self.report( + {"WARNING"}, + "The Active/Selected objects are not of " + "Mesh, Curve, Surface or Font type. Operation Cancelled" + ) + return {'CANCELLED'} + + default_name = self.check_empty_name(context) or "EMPTY_C_Array" + bpy.ops.object.modifier_add(type='ARRAY') + + if len(context.selected_objects) == 2: + selected = context.selected_objects + lists = [obj for obj in selected if obj != context.active_object] + active = lists[0] + # check if the list object has a modifier + check_mod = None + for mod in active.modifiers[:]: + if mod.type == "ARRAY": + check_mod = mod + break + + if check_mod: + check_mod.use_object_offset = True + check_mod.use_relative_offset = False + else: + # fallback + bpy.context.scene.objects.active = active + bpy.ops.object.modifier_add(type='ARRAY') + active.modifiers[0].use_object_offset = True + active.modifiers[0].use_relative_offset = False + + active.modifiers[0].use_object_offset = True + active.modifiers[0].use_relative_offset = False + active.select = False + bpy.context.scene.objects.active = context.active_object + bpy.ops.view3d.snap_cursor_to_selected() + + if active.modifiers[0].offset_object is None: + bpy.ops.object.add(type='EMPTY') + empty_name = bpy.context.active_object + empty_name.name = default_name + active.modifiers[0].offset_object = empty_name + else: + empty_name = active.modifiers[0].offset_object + + bpy.context.scene.objects.active = active + num = active.modifiers["Array"].count + rotate_num = 360 / num + active.select = True + bpy.ops.object.transform_apply(location=False, rotation=True, scale=True) + empty_name.rotation_euler = (0, 0, radians(rotate_num)) + empty_name.select = False + active.select = True + bpy.ops.object.origin_set(type="ORIGIN_CURSOR") + + return {'FINISHED'} + else: + active = context.active_object + active.modifiers[0].use_object_offset = True + active.modifiers[0].use_relative_offset = False + bpy.ops.view3d.snap_cursor_to_selected() + + if active.modifiers[0].offset_object is None: + bpy.ops.object.add(type='EMPTY') + empty_name = bpy.context.active_object + empty_name.name = default_name + active.modifiers[0].offset_object = empty_name + else: + empty_name = active.modifiers[0].offset_object + + bpy.context.scene.objects.active = active + num = active.modifiers["Array"].count + rotate_num = 360 / num + active.select = True + bpy.ops.object.transform_apply(location=False, rotation=True, scale=True) + empty_name.rotation_euler = (0, 0, radians(rotate_num)) + empty_name.select = False + active.select = True + + return {'FINISHED'} + + except Exception as e: + self.report({'WARNING'}, + "Circle Array operator could not be executed (See the console for more info)") + print("\n[objects.circle_array_operator]\nError: {}\n".format(e)) + + return {'CANCELLED'} + + +# Register +def register(): + bpy.utils.register_class(Circle_Array) + + +def unregister(): + bpy.utils.unregister_class(Circle_Array) + + +if __name__ == "__main__": + register() |