f02a12536e8e1f2072ba44a4728604f1f658a140
[blender-addons-contrib.git] / add_advanced_objects_menu / object_add_chain.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
3 #  This program is free software; you can redistribute it and/or
4 #  modify it under the terms of the GNU General Public License
5 #  as published by the Free Software Foundation; either version 2
6 #  of the License, or (at your option) any later version.
7 #
8 #  This program is distributed in the hope that it will be useful,
9 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #  GNU General Public License for more details.
12 #
13 #  You should have received a copy of the GNU General Public License
14 #  along with this program; if not, write to the Free Software Foundation,
15 #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 bl_info = {
20     "name": "Add Chain",
21     "author": "Brian Hinton (Nichod)",
22     "version": (0, 1, 2),
23     "blender": (2, 71, 0),
24     "location": "Toolshelf > Create Tab",
25     "description": "Adds Chain with curve guide for easy creation",
26     "warning": "",
27     "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/"
28                 "Scripts/Object/Add_Chain",
29     "category": "Object",
30 }
31
32 import bpy
33 from bpy.types import Operator
34
35
36 def Add_Chain():
37     # Adds Empty to scene
38     bpy.ops.object.add(
39             type='EMPTY',
40             align='WORLD',
41             enter_editmode=False,
42             location=(0, 0, 0),
43             rotation=(0, 0, 0),
44             )
45
46     # Changes name of Empty to rot_link adds variable emp
47     emp = bpy.context.object
48     emp.name = "rot_link"
49
50     # Rotate emp ~ 90 degrees
51     emp.rotation_euler = [1.570796, 0, 0]
52
53     # Adds Curve Path to scene
54     bpy.ops.curve.primitive_nurbs_path_add(
55             align='WORLD',
56             enter_editmode=False,
57             location=(0, 0, 0),
58             rotation=(0, 0, 0),
59             )
60
61     # Change Curve name to deform adds variable curv
62     curv = bpy.context.object
63     curv.name = "deform"
64
65     # Inserts Torus primitive
66     bpy.ops.mesh.primitive_torus_add(
67             major_radius=1,
68             minor_radius=0.25,
69             major_segments=12,
70             minor_segments=4,
71             abso_major_rad=1,
72             abso_minor_rad=0.5,
73             )
74
75     # Positions Torus primitive to center of scene
76     bpy.context.active_object.location = 0.0, 0.0, 0.0
77
78     # Resetting Torus rotation in case of 'Align to view' option enabled
79     bpy.context.active_object.rotation_euler = 0.0, 0.0, 0.0
80
81     # Changes Torus name to chain adds variable tor
82     tor = bpy.context.object
83     tor.name = "chain"
84
85     # Adds Array Modifier to tor
86     bpy.ops.object.modifier_add(type='ARRAY')
87
88     # Adds subsurf modifier tor
89     bpy.ops.object.modifier_add(type='SUBSURF')
90
91     # Smooths tor
92     bpy.ops.object.shade_smooth()
93
94     # Select curv
95     sce = bpy.context.scene
96     sce.objects.active = curv
97
98     # Toggle into editmode
99     bpy.ops.object.editmode_toggle()
100
101     # TODO, may be better to move objects directly
102     # Translate curve object
103     bpy.ops.transform.translate(
104             value=(2, 0, 0),
105             constraint_axis=(True, False, False),
106             orient_type='GLOBAL',
107             mirror=False,
108             proportional='DISABLED',
109             proportional_edit_falloff='SMOOTH',
110             proportional_size=1,
111             snap=False,
112             snap_target='CLOSEST',
113             snap_point=(0, 0, 0),
114             snap_align=False,
115             snap_normal=(0, 0, 0),
116             release_confirm=False,
117             )
118
119     # Toggle into objectmode
120     bpy.ops.object.editmode_toggle()
121
122     # Select tor or chain
123     sce.objects.active = tor
124
125     # Selects Array Modifier for editing
126     array = tor.modifiers['Array']
127
128     # Change Array Modifier Parameters
129     array.fit_type = 'FIT_CURVE'
130     array.curve = curv
131     array.offset_object = emp
132     array.use_object_offset = True
133     array.relative_offset_displace = 0.549, 0.0, 0.0
134
135     # Add curve modifier
136     bpy.ops.object.modifier_add(type='CURVE')
137
138     # Selects Curve Modifier for editing
139     cur = tor.modifiers['Curve']
140
141     # Change Curve Modifier Parameters
142     cur.object = curv
143
144
145 class AddChain(Operator):
146     bl_idname = "mesh.primitive_chain_add"
147     bl_label = "Add Chain"
148     bl_description = ("Create a Chain segment with helper objects controlling modifiers:\n"
149                       "1) A Curve Modifier Object (deform) for the length and shape,\n"
150                       "Edit the Path to extend Chain Length\n"
151                       "2) An Empty (rot_link) as an Array Offset for rotation")
152     bl_options = {'REGISTER', 'UNDO'}
153
154     def execute(self, context):
155         try:
156             Add_Chain()
157
158         except Exception as e:
159             self.report({'WARNING'},
160                         "Some operations could not be performed (See Console for more info)")
161
162             print("\n[Add Advanced  Objects]\nOperator: "
163                   "mesh.primitive_chain_add\nError: {}".format(e))
164
165             return {'CANCELLED'}
166
167         return {'FINISHED'}
168
169
170 def register():
171     bpy.utils.register_class(AddChain)
172
173
174 def unregister():
175     bpy.utils.unregister_class(AddChain)
176
177
178 if __name__ == "__main__":
179     register()