Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# gpl author: Antonis Karvelas
# -*- coding: utf-8 -*-
bl_info = {
"name": "Circle Array",
"author": "Antonis Karvelas",
"version": (1, 0),
"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": "",
"tracker_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 & Surface")
@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):
try:
allowed_obj = ['MESH', 'CURVE', 'SURFACE', 'FONT']
if context.active_object.type not in allowed_obj:
self.report(
{"WARNING"},
"Operation Cancelled. The active object is not of "
"Mesh, Curve, Surface or Font type"
)
return {'CANCELLED'}
default_name = self.check_empty_name(context) or "EMPTY_C_Array"
bpy.ops.object.modifier_add(type='ARRAY')
if len(bpy.context.selected_objects) == 2:
list = bpy.context.selected_objects
active = list[0]
active.modifiers[0].use_object_offset = True
active.modifiers[0].use_relative_offset = False
active.select = False
bpy.context.scene.objects.active = list[0]
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 circle_array_menu(self, context):
self.layout.operator(Circle_Array.bl_idname, text="Circle_Array")
def register():
bpy.utils.register_class(Circle_Array)
bpy.types.VIEW3D_MT_object.append(circle_array_menu)
def unregister():
bpy.utils.unregister_class(Circle_Array)
bpy.types.VIEW3D_MT_object.remove(circle_array_menu)
if __name__ == "__main__":
register()