Skip to content

Instantly share code, notes, and snippets.

@zeffii
Forked from anonymous/add_coil_spring3.py
Last active August 20, 2019 07:07
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save zeffii/5488993 to your computer and use it in GitHub Desktop.
Save zeffii/5488993 to your computer and use it in GitHub Desktop.
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
bl_info = {
"name": "Spring Coil",
"author": "Dealga McArdle",
"version": (0, 1, 0),
"blender": (2, 6, 7),
"location": "View3D > Add > Mesh > Add Spring",
"description": "Add a coil/spring",
"warning": "",
"wiki_url": "",
"tracker_url": "",
"category": "Add Mesh"
}
import bpy
from bpy.props import *
from math import sin, cos, pi, atan2
from mathutils import Vector, Euler
def make_coil(self):
# variables and shortnames
amp = self.profile_radius
n_verts = self.num_verts
n_turns = self.num_turns
th = self.height / n_turns
ipt = self.iterations_per_turn
radius = self.coil_radius
diameter = radius * 2
two_pi = 2.0 * pi
section_angle = two_pi / n_verts
rad_slice = two_pi / ipt
total_segments = (ipt * n_turns) + 1
z_jump = self.height / total_segments
x_rotation = atan2(th / 2, diameter)
n = n_verts
Verts = []
for segment in range(total_segments):
rad_angle = rad_slice * segment
for i in range(n):
# create the vector
this_angle = section_angle * i
x_float = amp * sin(this_angle) + radius
z_float = amp * cos(this_angle)
v1 = Vector((x_float, 0.0, z_float))
# rotate it
xz_euler = Euler((-x_rotation, 0.0, -rad_angle), 'XYZ')
v1.rotate(xz_euler)
# add extra z height per segment
v1 += Vector((0, 0, (segment * z_jump)))
# append it
Verts.append(v1)
Faces = []
# skin it, normals facing outwards
for t in range(total_segments-1):
for i in range(n-1):
p0 = i + (n*t)
p1 = i + (n*t) + 1
p2 = i + (n*t + n) + 1
p3 = i + (n*t + n)
Faces.append([p3,p2,p1,p0])
p0 = n*t
p1 = n*t + n
p2 = n*t + (2 * n) - 1
p3 = n*t + n-1
Faces.append([p3,p2,p1,p0])
return Verts, Faces
def create_mesh_object(context, verts, edges, faces, name):
mesh = bpy.data.meshes.new(name)
mesh.from_pydata(verts, edges, faces)
mesh.update()
from bpy_extras import object_utils
return object_utils.object_data_add(context, mesh, operator=None)
class AddSpringObject(bpy.types.Operator):
bl_idname = "mesh.spring_add"
bl_label = "Add Spring"
bl_options = {'REGISTER', 'UNDO', 'PRESET'}
num_verts = IntProperty(name="num profile verts",
description="how many verts in profile shape",
default=12, min=3, max=30)
profile_radius = FloatProperty(name="profile radius",
description="Radius of profile shape",
default=1.0, min=0.001, max=20.0)
coil_radius = FloatProperty(name="coil radius",
description="Coil radius measured from center of profile shape",
default=4.0, min=0.001, max=20.0)
iterations_per_turn = IntProperty(name="num segments per turn",
description="how many profile segments per turn",
default=20, min=4, max=30)
num_turns = IntProperty(name="total turns in coil",
description="how many turns in coil",
default=4, min=1, max=30)
height = FloatProperty(name="coil height",
description="Coil height measured from first to last profile centers.",
default=8.0, min=2.0, max=20.0)
def execute(self, context):
verts, faces = make_coil(self)
base = create_mesh_object(context, verts, [], faces, "Spring")
return {'FINISHED'}
def menu_func(self, context):
self.layout.operator("mesh.spring_add", icon="PLUGIN")
def register():
bpy.utils.register_module(__name__)
bpy.types.INFO_MT_mesh_add.append(menu_func)
def unregister():
bpy.utils.unregister_module(__name__)
bpy.types.INFO_MT_mesh_add.remove(menu_func)
if __name__ == "__main__":
register()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment