Fix error in rigify property generation
[blender-addons.git] / add_mesh_extra_objects / add_mesh_torusknot.py
blob39e985c307de53c63603ebffda188b46ed9a1c54
1 # GPL # Author, Anthony D'Agostino
3 import bpy
4 from mathutils import Vector
5 from math import sin, cos, pi
6 from bpy.props import (
7 BoolProperty,
8 IntProperty,
9 StringProperty,
11 from bpy_extras import object_utils
14 def create_mesh_object(context, verts, edges, faces, name):
15 # Create new mesh
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.
20 mesh.update()
21 from bpy_extras import object_utils
22 return object_utils.object_data_add(context, mesh, operator=None)
25 # ========================
26 # === Torus Knot Block ===
27 # ========================
29 def k1(t):
30 x = cos(t) - 2 * cos(2 * t)
31 y = sin(t) + 2 * sin(2 * t)
32 z = sin(3 * t)
33 return Vector([x, y, z])
36 def k2(t):
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
43 def k3(t):
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):
51 verts = []
52 for i in range(ures):
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))
58 e = a - b
59 f = a + b
60 g = e.cross(f)
61 h = e.cross(g)
62 g.normalize()
63 h.normalize()
64 for j in range(vres):
65 k = j * 2 * pi / vres
66 l = (cos(k), 0.0, sin(k))
67 l = Vector(l)
68 m = l * r2
69 x, y, z = m
70 n = h * x
71 o = g * z
72 p = n + o
73 q = a + p
74 verts.append(q)
75 return verts
78 def make_faces(ures, vres):
79 faces = []
80 for u in range(0, ures):
81 for v in range(0, vres):
82 p1 = v + u * 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])
87 return faces
90 def make_knot(knotidx, ures):
91 knots = [k1, k2, k3]
92 knotfunc = knots[knotidx - 1]
93 vres = ures // 10
94 r2 = 0.5
95 verts = make_verts(ures, vres, r2, knotfunc)
96 faces = make_faces(ures, vres)
97 return (verts, faces)
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",
107 default = True,
108 description = "TorusKnot")
109 change : BoolProperty(name = "Change",
110 default = False,
111 description = "change TorusKnot")
113 resolution: IntProperty(
114 name="Resolution",
115 description="Resolution of the Torus Knot",
116 default=80,
117 min=30, max=256
119 objecttype: IntProperty(
120 name="Knot Type",
121 description="Type of Knot",
122 default=1,
123 min=1, max=3
126 def draw(self, context):
127 layout = self.layout
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 # turn off 'Enter Edit Mode'
142 use_enter_edit_mode = bpy.context.preferences.edit.use_enter_edit_mode
143 bpy.context.preferences.edit.use_enter_edit_mode = False
145 if bpy.context.mode == "OBJECT":
146 if context.selected_objects != [] and context.active_object and \
147 (context.active_object.data is not None) and ('TorusKnot' in context.active_object.data.keys()) and \
148 (self.change == True):
149 obj = context.active_object
150 oldmesh = obj.data
151 oldmeshname = obj.data.name
152 verts, faces = make_knot(self.objecttype, self.resolution)
153 mesh = bpy.data.meshes.new('TorusKnot')
154 mesh.from_pydata(verts, [], faces)
155 obj.data = mesh
156 for material in oldmesh.materials:
157 obj.data.materials.append(material)
158 bpy.data.meshes.remove(oldmesh)
159 obj.data.name = oldmeshname
160 else:
161 verts, faces = make_knot(self.objecttype, self.resolution)
162 mesh = bpy.data.meshes.new('TorusKnot')
163 mesh.from_pydata(verts, [], faces)
164 obj = object_utils.object_data_add(context, mesh, operator=self)
166 obj.data["TorusKnot"] = True
167 obj.data["change"] = False
168 for prm in TorusKnotParameters():
169 obj.data[prm] = getattr(self, prm)
171 if bpy.context.mode == "EDIT_MESH":
172 active_object = context.active_object
173 name_active_object = active_object.name
174 bpy.ops.object.mode_set(mode='OBJECT')
175 verts, faces = make_knot(self.objecttype, self.resolution)
176 mesh = bpy.data.meshes.new('TorusKnot')
177 mesh.from_pydata(verts, [], faces)
178 obj = object_utils.object_data_add(context, mesh, operator=self)
179 obj.select_set(True)
180 active_object.select_set(True)
181 bpy.context.view_layer.objects.active = active_object
182 bpy.ops.object.join()
183 context.active_object.name = name_active_object
184 bpy.ops.object.mode_set(mode='EDIT')
186 if use_enter_edit_mode:
187 bpy.ops.object.mode_set(mode = 'EDIT')
189 # restore pre operator state
190 bpy.context.preferences.edit.use_enter_edit_mode = use_enter_edit_mode
192 return {'FINISHED'}
194 def TorusKnotParameters():
195 TorusKnotParameters = [
196 "resolution",
197 "objecttype",
199 return TorusKnotParameters