1 # gpl author: Antonis Karvelas
3 # -*- coding: utf-8 -*-
6 "name": "Circle Array",
7 "author": "Antonis Karvelas",
10 "location": "View3D > Object > Circle_Array",
11 "description": "Uses an existing array and creates an empty, "
12 "rotates it properly and makes a Circle Array",
20 from bpy
.types
import Operator
21 from math
import radians
24 class Circle_Array(Operator
):
25 bl_label
= "Circle Array"
26 bl_idname
= "objects.circle_array_operator"
27 bl_description
= ("Creates an Array Modifier with offset empty object\n"
28 "Works with Mesh, Curve, Text and Surface\n"
29 "Use an object with an existing Array modifier\n"
30 "or rotate the newly created Empty with the name pattern\n"
31 "EMPTY_C_Array_ if the Array doesn't exist (angle: 360/Count)")
34 def poll(cls
, context
):
35 return context
.active_object
is not None
37 def check_empty_name(self
, context
):
38 new_name
, def_name
= "", "EMPTY_C_Array"
41 # first slap a simple linear count + 1 for numeric suffix, if it fails
42 # harvest for the rightmost numbers and append the max value
44 obj_all
= context
.scene
.objects
45 list_obj
= [obj
.name
for obj
in obj_all
if obj
.name
.startswith(def_name
)]
46 new_name
= "{}_{}".format(def_name
, len(list_obj
) + 1)
48 if new_name
in list_obj
:
49 from re
import findall
50 test_num
= [findall("\d+", words
) for words
in list_obj
]
51 suffix
+= max([int(l
[-1]) for l
in test_num
])
52 new_name
= "{}_{}".format(def_name
, suffix
)
57 def execute(self
, context
):
60 allowed_obj
= ['MESH', 'CURVE', 'SURFACE', 'FONT']
61 for obj
in context
.selected_objects
:
62 if obj
.type not in allowed_obj
:
69 "The Active/Selected objects are not of "
70 "Mesh, Curve, Surface or Font type. Operation Cancelled"
74 default_name
= self
.check_empty_name(context
) or "EMPTY_C_Array"
75 bpy
.ops
.object.modifier_add(type='ARRAY')
77 if len(context
.selected_objects
) == 2:
78 selected
= context
.selected_objects
79 lists
= [obj
for obj
in selected
if obj
!= context
.active_object
]
81 # check if the list object has a modifier
83 for mod
in active
.modifiers
[:]:
84 if mod
.type == "ARRAY":
89 check_mod
.use_object_offset
= True
90 check_mod
.use_relative_offset
= False
93 bpy
.context
.scene
.objects
.active
= active
94 bpy
.ops
.object.modifier_add(type='ARRAY')
95 active
.modifiers
[0].use_object_offset
= True
96 active
.modifiers
[0].use_relative_offset
= False
98 active
.modifiers
[0].use_object_offset
= True
99 active
.modifiers
[0].use_relative_offset
= False
100 active
.select
= False
101 bpy
.context
.scene
.objects
.active
= context
.active_object
102 bpy
.ops
.view3d
.snap_cursor_to_selected()
104 if active
.modifiers
[0].offset_object
is None:
105 bpy
.ops
.object.add(type='EMPTY')
106 empty_name
= bpy
.context
.active_object
107 empty_name
.name
= default_name
108 active
.modifiers
[0].offset_object
= empty_name
110 empty_name
= active
.modifiers
[0].offset_object
112 bpy
.context
.scene
.objects
.active
= active
113 num
= active
.modifiers
["Array"].count
114 rotate_num
= 360 / num
116 bpy
.ops
.object.transform_apply(location
=False, rotation
=True, scale
=True)
117 empty_name
.rotation_euler
= (0, 0, radians(rotate_num
))
118 empty_name
.select
= False
120 bpy
.ops
.object.origin_set(type="ORIGIN_CURSOR")
124 active
= context
.active_object
125 active
.modifiers
[0].use_object_offset
= True
126 active
.modifiers
[0].use_relative_offset
= False
127 bpy
.ops
.view3d
.snap_cursor_to_selected()
129 if active
.modifiers
[0].offset_object
is None:
130 bpy
.ops
.object.add(type='EMPTY')
131 empty_name
= bpy
.context
.active_object
132 empty_name
.name
= default_name
133 active
.modifiers
[0].offset_object
= empty_name
135 empty_name
= active
.modifiers
[0].offset_object
137 bpy
.context
.scene
.objects
.active
= active
138 num
= active
.modifiers
["Array"].count
139 rotate_num
= 360 / num
141 bpy
.ops
.object.transform_apply(location
=False, rotation
=True, scale
=True)
142 empty_name
.rotation_euler
= (0, 0, radians(rotate_num
))
143 empty_name
.select
= False
148 except Exception as e
:
149 self
.report({'WARNING'},
150 "Circle Array operator could not be executed (See the console for more info)")
151 print("\n[objects.circle_array_operator]\nError: {}\n".format(e
))
158 bpy
.utils
.register_class(Circle_Array
)
162 bpy
.utils
.unregister_class(Circle_Array
)
165 if __name__
== "__main__":