1 '''# +---------------------------------------------------------+
2 # | Copyright (c) 2005-2010 Anthony D'Agostino |
3 # | http://home.comcast.net/~chronosphere |
4 # | scorpius@netzero.com |
5 # | February 12, 2005 |
6 # | Torus Knot Generator |
7 # | Adds the famous missing primitive to Blender |
8 # +---------------------------------------------------------+
10 # ***** BEGIN GPL LICENSE BLOCK *****
12 # This program is free software; you can redistribute it and/or
13 # modify it under the terms of the GNU General Public License
14 # as published by the Free Software Foundation; either version 2
15 # of the License, or (at your option) any later version.
17 # This program is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # GNU General Public License for more details.
22 # You should have received a copy of the GNU General Public License
23 # along with this program; if not, write to the Free Software Foundation,
24 # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 # ***** END GPL LICENCE BLOCK *****
30 "author": "Anthony D'Agostino",
32 "blender": (2, 57, 0),
33 "location": "View3D > Add > Mesh ",
34 "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"
35 "Scripts/Add_TorusKnot",
36 "category": "Add Mesh",
39 import bpy
, mathutils
, math
41 def create_mesh_object(context
, verts
, edges
, faces
, name
):
43 mesh
= bpy
.data
.meshes
.new(name
)
44 # Make a mesh from a list of verts/edges/faces.
45 mesh
.from_pydata(verts
, edges
, faces
)
46 # Update mesh geometry after adding stuff.
48 from bpy_extras
import object_utils
49 return object_utils
.object_data_add(context
, mesh
, operator
=None)
51 # ========================
52 # === Torus Knot Block ===
53 # ========================
55 x
= math
.cos(t
) - 2*math
.cos(2*t
)
56 y
= math
.sin(t
) + 2*math
.sin(2*t
)
58 return mathutils
.Vector([x
,y
,z
])
61 x
= 10 * (math
.cos(t
) + math
.cos(3*t
)) + math
.cos(2*t
) + math
.cos(4*t
)
62 y
= 6 * math
.sin(t
) + 10 * math
.sin(3*t
)
63 z
= 4 * math
.sin(3*t
) * math
.sin(5*t
/2) + 4*math
.sin(4*t
) - 2*math
.sin(6*t
)
64 return mathutils
.Vector([x
,y
,z
]) * 0.2
67 x
= 2.5*math
.cos(t
+math
.pi
)/3 + 2*math
.cos(3*t
)
68 y
= 2.5*math
.sin(t
)/3 + 2*math
.sin(3*t
)
69 z
= 1.5*math
.sin(4*t
) + math
.sin(2*t
)/3
70 return mathutils
.Vector([x
,y
,z
])
72 def make_verts(ures
, vres
, r2
, knotfunc
):
75 t1
= (i
+0) * 2*math
.pi
/ures
76 t2
= (i
+1) * 2*math
.pi
/ures
77 a
= knotfunc(t1
) # curr point
78 b
= knotfunc(t2
) # next point
79 a
,b
= map(mathutils
.Vector
, (a
,b
))
87 k
= j
* 2*math
.pi
/vres
88 l
= (math
.cos(k
),0.0,math
.sin(k
))
89 l
= mathutils
.Vector(l
)
99 def make_faces(ures
, vres
):
101 for u
in range(0, ures
):
102 for v
in range(0, vres
):
104 p2
= v
+ ((u
+1)%ures)*vres
105 p4
= (v
+1)%vres
+ u
*vres
106 p3
= (v
+1)%vres
+ ((u
+1)%ures)*vres
107 faces
.append([p4
, p3
, p2
, p1
])
110 def make_knot(knotidx
, ures
):
112 knotfunc
= knots
[knotidx
-1]
115 verts
= make_verts(ures
, vres
, r2
, knotfunc
)
116 faces
= make_faces(ures
, vres
)
117 return (verts
, faces
)
119 class AddTorusKnot(bpy
.types
.Operator
):
120 """Add a torus-knot mesh"""
121 bl_idname
= "mesh.primitive_torusknot_add"
122 bl_label
= "Add Torus Knot"
123 bl_options
= {"REGISTER", "UNDO"}
125 resolution
= bpy
.props
.IntProperty(name
="Resolution",
126 description
="Resolution of the Torus Knot",
127 default
=80, min=30, max=256)
129 objecttype
= bpy
.props
.IntProperty(name
="Knot Type",
130 description
="Type of Knot",
131 default
=1, min=1, max=3)
133 def execute(self
, context
):
134 verts
, faces
= make_knot(self
.objecttype
,
136 obj
= create_mesh_object(context
, verts
, [], faces
, "Torus Knot")
139 def menu_func(self, context):
140 self.layout.operator(AddTorusKnot.bl_idname, text="Torus Knot", icon="MESH_CUBE")
143 bpy.utils.register_module(__name__)
144 bpy.types.INFO_MT_mesh_add.append(menu_func)
147 bpy.utils.unregister_module(__name__)
148 bpy.types.INFO_MT_mesh_add.remove(menu_func)
150 if __name__ == "__main__":