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
|
# GPL # Author, Anthony D'Agostino
import bpy
from mathutils import Vector
from math import sin, cos, pi
from bpy.props import IntProperty
def create_mesh_object(context, verts, edges, faces, name):
# Create new mesh
mesh = bpy.data.meshes.new(name)
# Make a mesh from a list of verts/edges/faces.
mesh.from_pydata(verts, edges, faces)
# Update mesh geometry after adding stuff.
mesh.update()
from bpy_extras import object_utils
return object_utils.object_data_add(context, mesh, operator=None)
# ========================
# === Torus Knot Block ===
# ========================
def k1(t):
x = cos(t) - 2 * cos(2 * t)
y = sin(t) + 2 * sin(2 * t)
z = sin(3 * t)
return Vector([x, y, z])
def k2(t):
x = 10 * (cos(t) + cos(3 * t)) + cos(2 * t) + cos(4 * t)
y = 6 * sin(t) + 10 * sin(3 * t)
z = 4 * sin(3 * t) * sin(5 * t / 2) + 4 * sin(4 * t) - 2 * sin(6 * t)
return Vector([x, y, z]) * 0.2
def k3(t):
x = 2.5 * cos(t + pi) / 3 + 2 * cos(3 * t)
y = 2.5 * sin(t) / 3 + 2 * sin(3 * t)
z = 1.5 * sin(4 * t) + sin(2 * t) / 3
return Vector([x, y, z])
def make_verts(ures, vres, r2, knotfunc):
verts = []
for i in range(ures):
t1 = (i + 0) * 2 * pi / ures
t2 = (i + 1) * 2 * pi / ures
a = knotfunc(t1) # curr point
b = knotfunc(t2) # next point
a, b = map(Vector, (a, b))
e = a - b
f = a + b
g = e.cross(f)
h = e.cross(g)
g.normalize()
h.normalize()
for j in range(vres):
k = j * 2 * pi / vres
l = (cos(k), 0.0, sin(k))
l = Vector(l)
m = l * r2
x, y, z = m
n = h * x
o = g * z
p = n + o
q = a + p
verts.append(q)
return verts
def make_faces(ures, vres):
faces = []
for u in range(0, ures):
for v in range(0, vres):
p1 = v + u * vres
p2 = v + ((u + 1) % ures) * vres
p4 = (v + 1) % vres + u * vres
p3 = (v + 1) % vres + ((u + 1) % ures) * vres
faces.append([p4, p3, p2, p1])
return faces
def make_knot(knotidx, ures):
knots = [k1, k2, k3]
knotfunc = knots[knotidx - 1]
vres = ures // 10
r2 = 0.5
verts = make_verts(ures, vres, r2, knotfunc)
faces = make_faces(ures, vres)
return (verts, faces)
class AddTorusKnot(bpy.types.Operator):
bl_idname = "mesh.primitive_torusknot_add"
bl_label = "Add Torus Knot"
bl_description = "Construct a torus knot mesh"
bl_options = {"REGISTER", "UNDO"}
resolution: IntProperty(
name="Resolution",
description="Resolution of the Torus Knot",
default=80,
min=30, max=256
)
objecttype: IntProperty(
name="Knot Type",
description="Type of Knot",
default=1,
min=1, max=3
)
def execute(self, context):
verts, faces = make_knot(self.objecttype, self.resolution)
obj = create_mesh_object(context, verts, [], faces, "Torus Knot")
return {'FINISHED'}
|