c651e7edca8d1e43ed9d2e04e709134d87a63e6e
[blender.git] / release / scripts / io / add_mesh_torus.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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 import bpy, Mathutils
20 from math import cos, sin, pi, radians
21
22
23 def add_torus(PREF_MAJOR_RAD, PREF_MINOR_RAD, PREF_MAJOR_SEG, PREF_MINOR_SEG):
24         Vector = Mathutils.Vector
25         Quaternion = Mathutils.Quaternion
26         
27         PI_2= pi*2
28         Z_AXIS = 0,0,1
29         
30         verts = []
31         faces = []
32         i1 = 0
33         tot_verts = PREF_MAJOR_SEG * PREF_MINOR_SEG
34         for major_index in range(PREF_MAJOR_SEG):
35                 verts_tmp = []
36                 quat = Quaternion( Z_AXIS, (major_index/PREF_MAJOR_SEG)*PI_2)
37
38                 for minor_index in range(PREF_MINOR_SEG):
39                         angle = 2*pi*minor_index/PREF_MINOR_SEG
40                         
41                         vec = Vector(PREF_MAJOR_RAD+(cos(angle)*PREF_MINOR_RAD), 0, (sin(angle)*PREF_MINOR_RAD)) * quat
42                         verts.extend([vec.x, vec.y, vec.z])
43                         
44                         if minor_index+1==PREF_MINOR_SEG:
45                                 i2 = (major_index)*PREF_MINOR_SEG
46                                 i3 = i1 + PREF_MINOR_SEG
47                                 i4 = i2 + PREF_MINOR_SEG
48                                 
49                         else:
50                                 i2 = i1 + 1
51                                 i3 = i1 + PREF_MINOR_SEG
52                                 i4 = i3 + 1
53                         
54                         if i2>=tot_verts:       i2 = i2-tot_verts
55                         if i3>=tot_verts:       i3 = i3-tot_verts
56                         if i4>=tot_verts:       i4 = i4-tot_verts
57                         
58                         # stupid eekadoodle
59                         if i2:  faces.extend( [i1,i3,i4,i2] )
60                         else:   faces.extend( [i2,i1,i3,i4] )
61                                 
62                         i1+=1
63         
64         return verts, faces
65
66 from bpy.props import *
67
68 class MESH_OT_primitive_torus_add(bpy.types.Operator):
69         '''Add a torus mesh.'''
70         bl_idname = "mesh.primitive_torus_add"
71         bl_label = "Add Torus"
72         bl_register = True
73         bl_undo = True
74         
75         major_radius = FloatProperty(name="Major Radius", description="Number of segments for the main ring of the torus", default= 1.0, min= 0.01, max= 100.0)
76         minor_radius = FloatProperty(name="Minor Radius", description="Number of segments for the minor ring of the torus", default= 0.25, min= 0.01, max= 100.0)
77         major_segments = IntProperty(name="Major Segments", description="Number of segments for the main ring of the torus", default= 48, min= 3, max= 256)
78         minor_segments = IntProperty(name="Minor Segments", description="Number of segments for the minor ring of the torus", default= 16, min= 3, max= 256)
79         
80         def execute(self, context):
81                 verts_loc, faces = add_torus(self.major_radius, self.minor_radius, self.major_segments, self.minor_segments)
82                 
83                 me= bpy.data.add_mesh("Torus")
84                 
85                 me.add_geometry(int(len(verts_loc)/3), 0, int(len(faces)/4))
86                 me.verts.foreach_set("co", verts_loc)
87                 me.faces.foreach_set("verts_raw", faces)
88                 
89                 sce = context.scene
90                 
91                 # ugh
92                 for ob in sce.objects:
93                         ob.selected = False
94                 
95                 me.update()
96                 ob= bpy.data.add_object('MESH', "Torus")
97                 ob.data= me
98                 context.scene.add_object(ob)
99                 context.scene.active_object = ob
100                 ob.selected = True
101                 
102                 ob.location = tuple(context.scene.cursor_location)
103                 
104                 return ('FINISHED',)
105
106 # Register the operator
107 bpy.ops.add(MESH_OT_primitive_torus_add)
108
109 # Add to a menu
110 import dynamic_menu
111 import space_info
112 menu_item = dynamic_menu.add(bpy.types.INFO_MT_mesh_add, (lambda self, context: self.layout.itemO("mesh.primitive_torus_add", text="Torus", icon='ICON_MESH_DONUT')) )
113
114 if __name__ == "__main__":
115         bpy.ops.mesh.primitive_torus_add()