1
# ##### BEGIN GPL LICENSE BLOCK #####
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.
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.
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.
17
# ##### END GPL LICENSE BLOCK #####
21
"name": "Torus Knots",
22
"author": "testscreenings",
25
"location": "View3D > Add > Curve",
26
"description": "Adds many types of (torus) knots",
28
"wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
29
"Scripts/Curve/Torus_Knot",
30
"tracker_url": "https://projects.blender.org/tracker/index.php?"\
31
"func=detail&aid=22403",
32
"category": "Add Curve"}
35
##------------------------------------------------------------
38
from bpy.props import *
39
from math import sin, cos, pi
40
from bpy_extras.object_utils import AddObjectHelper, object_data_add
43
########################################################################
44
####################### Knot Definitions ###############################
45
########################################################################
54
rounds = self.torus_rounds
62
for i in range(res-1):
65
x = (2 * scale + cos((q*t)/p*v)) * cos(t * u)
66
y = (2 * scale + cos((q*t)/p*v)) * sin(t * u)
67
z = sin(q*t/p) * height
69
newPoints.extend([x,y,z,1])
74
##------------------------------------------------------------
76
def create_torus_knot(self, context):
77
verts = Torus_Knot(self)
79
curve_data = bpy.data.curves.new(name='Torus Knot', type='CURVE')
80
spline = curve_data.splines.new(type='NURBS')
81
spline.points.add(int(len(verts)*0.25 - 1))
82
spline.points.foreach_set('co', verts)
83
spline.use_endpoint_u = True
84
spline.use_cyclic_u = True
86
curve_data.dimensions = '3D'
89
curve_data.bevel_depth = self.geo_bDepth
90
curve_data.bevel_resolution = self.geo_bRes
91
curve_data.fill_mode = 'FULL'
92
curve_data.extrude = self.geo_extrude
93
#curve_data.offset = self.geo_width # removed, somehow screws things up all of a sudden
94
curve_data.resolution_u = self.geo_res
96
new_obj = object_data_add(context, curve_data, operator=self)
99
class torus_knot_plus(bpy.types.Operator, AddObjectHelper):
101
bl_idname = "curve.torus_knot_plus"
102
bl_label = "Torus Knot +"
103
bl_options = {'REGISTER', 'UNDO'}
104
bl_description = "adds many types of knots"
107
options_plus = BoolProperty(name="plus options",
109
description="Show more options (the plus part)")
112
geo_surf = BoolProperty(name="Surface",
114
geo_bDepth = FloatProperty(name="bevel",
117
geo_bRes = IntProperty(name="bevel res",
121
geo_extrude = FloatProperty(name="extrude",
124
geo_res = IntProperty(name="resolution",
130
torus_res = IntProperty(name="Resoulution",
133
description='Resolution, Number of controlverticies')
134
torus_p = IntProperty(name="p",
139
torus_q = IntProperty(name="q",
144
torus_w = FloatProperty(name="Height",
148
description="Height in Z")
149
torus_h = FloatProperty(name="Scale",
153
description="Scale, in XY")
154
torus_u = IntProperty(name="u",
159
torus_v = IntProperty(name="v",
164
torus_rounds = IntProperty(name="Rounds",
168
description="Rounds")
171
def draw(self, context):
175
layout.label(text="Torus Knot Parameters:")
179
box.prop(self, 'torus_res')
180
box.prop(self, 'torus_w')
181
box.prop(self, 'torus_h')
182
box.prop(self, 'torus_p')
183
box.prop(self, 'torus_q')
184
box.prop(self, 'options_plus')
185
if self.options_plus:
186
box.prop(self, 'torus_u')
187
box.prop(self, 'torus_v')
188
box.prop(self, 'torus_rounds')
191
col = layout.column()
192
col.label(text="Geometry Options:")
194
box.prop(self, 'geo_surf')
196
box.prop(self, 'geo_bDepth')
197
box.prop(self, 'geo_bRes')
198
box.prop(self, 'geo_extrude')
199
box.prop(self, 'geo_res')
201
col = layout.column()
202
col.prop(self, 'location')
203
col.prop(self, 'rotation')
207
def poll(cls, context):
208
return context.scene != None
211
def execute(self, context):
213
undo = bpy.context.user_preferences.edit.use_global_undo
214
bpy.context.user_preferences.edit.use_global_undo = False
216
if not self.options_plus:
217
self.torus_rounds = self.torus_p
219
#recoded for add_utils
220
create_torus_knot(self, context)
222
# restore pre operator undo state
223
bpy.context.user_preferences.edit.use_global_undo = undo
227
################################################################################
230
def torus_knot_plus_button(self, context):
231
self.layout.operator(torus_knot_plus.bl_idname, text="Torus Knot +", icon="PLUGIN")
235
bpy.utils.register_module(__name__)
237
bpy.types.INFO_MT_curve_add.append(torus_knot_plus_button)
240
bpy.utils.unregister_module(__name__)
242
bpy.types.INFO_MT_curve_add.remove(torus_knot_plus_button)
244
if __name__ == "__main__":