1 # GPL # Author, Anthony D'Agostino
4 from mathutils
import Vector
5 from math
import sin
, cos
, pi
6 from bpy
.props
import (
11 from bpy_extras
import object_utils
14 def create_mesh_object(context
, verts
, edges
, faces
, name
):
16 mesh
= bpy
.data
.meshes
.new(name
)
17 # Make a mesh from a list of verts/edges/faces.
18 mesh
.from_pydata(verts
, edges
, faces
)
19 # Update mesh geometry after adding stuff.
21 from bpy_extras
import object_utils
22 return object_utils
.object_data_add(context
, mesh
, operator
=None)
25 # ========================
26 # === Torus Knot Block ===
27 # ========================
30 x
= cos(t
) - 2 * cos(2 * t
)
31 y
= sin(t
) + 2 * sin(2 * t
)
33 return Vector([x
, y
, z
])
37 x
= 10 * (cos(t
) + cos(3 * t
)) + cos(2 * t
) + cos(4 * t
)
38 y
= 6 * sin(t
) + 10 * sin(3 * t
)
39 z
= 4 * sin(3 * t
) * sin(5 * t
/ 2) + 4 * sin(4 * t
) - 2 * sin(6 * t
)
40 return Vector([x
, y
, z
]) * 0.2
44 x
= 2.5 * cos(t
+ pi
) / 3 + 2 * cos(3 * t
)
45 y
= 2.5 * sin(t
) / 3 + 2 * sin(3 * t
)
46 z
= 1.5 * sin(4 * t
) + sin(2 * t
) / 3
47 return Vector([x
, y
, z
])
50 def make_verts(ures
, vres
, r2
, knotfunc
):
53 t1
= (i
+ 0) * 2 * pi
/ ures
54 t2
= (i
+ 1) * 2 * pi
/ ures
55 a
= knotfunc(t1
) # curr point
56 b
= knotfunc(t2
) # next point
57 a
, b
= map(Vector
, (a
, b
))
66 l
= (cos(k
), 0.0, sin(k
))
78 def make_faces(ures
, vres
):
80 for u
in range(0, ures
):
81 for v
in range(0, vres
):
83 p2
= v
+ ((u
+ 1) % ures
) * vres
84 p4
= (v
+ 1) % vres
+ u
* vres
85 p3
= (v
+ 1) % vres
+ ((u
+ 1) % ures
) * vres
86 faces
.append([p4
, p3
, p2
, p1
])
90 def make_knot(knotidx
, ures
):
92 knotfunc
= knots
[knotidx
- 1]
95 verts
= make_verts(ures
, vres
, r2
, knotfunc
)
96 faces
= make_faces(ures
, vres
)
100 class AddTorusKnot(bpy
.types
.Operator
, object_utils
.AddObjectHelper
):
101 bl_idname
= "mesh.primitive_torusknot_add"
102 bl_label
= "Add Torus Knot"
103 bl_description
= "Construct a torus knot mesh"
104 bl_options
= {"REGISTER", "UNDO"}
106 TorusKnot
: BoolProperty(name
= "TorusKnot",
108 description
= "TorusKnot")
109 change
: BoolProperty(name
= "Change",
111 description
= "change TorusKnot")
113 resolution
: IntProperty(
115 description
="Resolution of the Torus Knot",
119 objecttype
: IntProperty(
121 description
="Type of Knot",
126 def draw(self
, context
):
129 layout
.prop(self
, 'resolution', expand
=True)
130 layout
.prop(self
, 'objecttype', expand
=True)
132 if self
.change
== False:
133 col
= layout
.column(align
=True)
134 col
.prop(self
, 'align', expand
=True)
135 col
= layout
.column(align
=True)
136 col
.prop(self
, 'location', expand
=True)
137 col
= layout
.column(align
=True)
138 col
.prop(self
, 'rotation', expand
=True)
140 def execute(self
, context
):
141 if bpy
.context
.mode
== "OBJECT":
142 if context
.selected_objects
!= [] and context
.active_object
and \
143 ('TorusKnot' in context
.active_object
.data
.keys()) and (self
.change
== True):
144 obj
= context
.active_object
146 oldmeshname
= obj
.data
.name
147 verts
, faces
= make_knot(self
.objecttype
, self
.resolution
)
148 mesh
= bpy
.data
.meshes
.new('TorusKnot')
149 mesh
.from_pydata(verts
, [], faces
)
151 for material
in oldmesh
.materials
:
152 obj
.data
.materials
.append(material
)
153 bpy
.data
.meshes
.remove(oldmesh
)
154 obj
.data
.name
= oldmeshname
156 verts
, faces
= make_knot(self
.objecttype
, self
.resolution
)
157 mesh
= bpy
.data
.meshes
.new('TorusKnot')
158 mesh
.from_pydata(verts
, [], faces
)
159 obj
= object_utils
.object_data_add(context
, mesh
, operator
=self
)
161 obj
.data
["TorusKnot"] = True
162 obj
.data
["change"] = False
163 for prm
in TorusKnotParameters():
164 obj
.data
[prm
] = getattr(self
, prm
)
166 if bpy
.context
.mode
== "EDIT_MESH":
167 active_object
= context
.active_object
168 name_active_object
= active_object
.name
169 bpy
.ops
.object.mode_set(mode
='OBJECT')
170 verts
, faces
= make_knot(self
.objecttype
, self
.resolution
)
171 mesh
= bpy
.data
.meshes
.new('TorusKnot')
172 mesh
.from_pydata(verts
, [], faces
)
173 obj
= object_utils
.object_data_add(context
, mesh
, operator
=self
)
175 active_object
.select_set(True)
176 bpy
.ops
.object.join()
177 context
.active_object
.name
= name_active_object
178 bpy
.ops
.object.mode_set(mode
='EDIT')
182 def TorusKnotParameters():
183 TorusKnotParameters
= [
187 return TorusKnotParameters