Skip to content

Instantly share code, notes, and snippets.

@batFINGER
Created January 23, 2020 10:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save batFINGER/a6831a816e008f1ddf0958f0f8ea99bd to your computer and use it in GitHub Desktop.
Save batFINGER/a6831a816e008f1ddf0958f0f8ea99bd to your computer and use it in GitHub Desktop.
Add Mesh Spiral Thingy
bl_info = {
"name": "Spiral Mesh",
"author": "batFINGER",
"version": (1, 0),
"blender": (2, 80, 0),
"location": "View3D > Add > Mesh > Spiral Mesh",
"description": "Adds a Spiral Thingy",
"warning": "",
"wiki_url": "",
"category": "Add Mesh",
}
import bmesh
from math import sin, cos, radians
from mathutils import Vector, Matrix
from bpy_extras.object_utils import AddObjectHelper, object_data_add
from bpy.props import FloatProperty, IntProperty, EnumProperty
from bpy.types import Operator
import bpy
def spiral_thingy_mesh(radius,
c,
segments,
growth_angle,
thickness,
thickness_type):
me = bpy.data.meshes.new("Spiral Thingy")
z_axis = Vector((0, 0, 1))
def spherical_to_xyz(theta):
x = sin(theta) * cos(c * theta)
y = sin(theta) * sin(c * theta)
z = cos(theta)
return radius * Vector((x, y, z))
bm = bmesh.new()
edges = []
seg_angle = radians(180 / segments)
for i in range(segments + 1):
theta = i * seg_angle
co = spherical_to_xyz(theta)
axis = z_axis.cross(co)
v = bm.verts.new(co)
M = Matrix.Rotation(growth_angle, 4, co)
R = Matrix.Rotation(sin(theta) * growth_angle, 4, axis)
x = bm.verts.new(R @ M @ co)
R = Matrix.Rotation(sin(theta) * -growth_angle, 4, axis)
y = bm.verts.new(R @ M @ co)
et = bm.edges.new((x, v))
eb = bm.edges.new((v, y))
if edges:
bmesh.ops.bridge_loops(bm,
edges=edges + [et, eb])
edges = [eb, et]
if thickness_type != 'NONE':
geom = bmesh.ops.extrude_face_region(
bm,
geom=bm.faces[:] + bm.edges[:] + bm.verts[:],
)["geom"]
verts = [e for e in geom if isinstance(e, bmesh.types.BMVert)]
if thickness_type == 'CONSTANT':
s = (radius - thickness) / radius
bmesh.ops.scale(bm,
verts=verts,
vec=(s,) * 3)
elif thickness_type == 'TAPER':
for v in verts:
s = sin(v.co.angle(z_axis)) * thickness
v.co -= s * thickness * v.co.normalized()
bm.to_mesh(me)
return me
class MESH_OT_add_spiral_thingy(Operator, AddObjectHelper):
"""Add a Spiral Thingy"""
bl_idname = "mesh.add_spiral_thingy"
bl_label = "Add Spiral Thingy"
bl_options = {'REGISTER', 'UNDO'}
radius: FloatProperty(
name="Radius",
default=1.0,
subtype='DISTANCE',
description="Sphere Radius",
)
turns: IntProperty(
name="Turns",
default=5,
min=2,
)
segments: IntProperty(
name="Segments",
default=64,
min=2,
)
growth_angle: FloatProperty(
name="Width Angle",
subtype='ANGLE',
default=radians(10),
)
# use_thickness enum
thickness: FloatProperty(
name="Thickness",
subtype='DISTANCE',
default=0.1,
)
thickness_type: EnumProperty(
items=[('NONE', "None", "No Thickness"),
('TAPER', "Taper", "Taper Thickness"),
('CONSTANT', "Constant", "Constant Thickness"),
],
default = 'NONE',
)
def draw(self, context):
layout = self.layout
col = layout.column()
col.prop(self, "radius")
col.prop(self, "turns")
col.prop(self, "segments")
col.prop(self, "growth_angle")
col.prop(self, "thickness_type")
if self.thickness_type != 'NONE':
col.prop(self, "thickness")
# annotated on AddObjectHelper
for prop in AddObjectHelper.__annotations__.keys():
col.prop(self, prop)
def execute(self, context):
object_data_add(context,
spiral_thingy_mesh(
self.radius,
self.turns,
self.segments,
self.growth_angle,
self.thickness,
self.thickness_type),
operator=self)
return {'FINISHED'}
# Registration
def add_spiral_thingy_button(self, context):
self.layout.operator(
MESH_OT_add_spiral_thingy.bl_idname,
icon='FORCE_VORTEX')
classes = (MESH_OT_add_spiral_thingy,)
def register():
for cls in classes:
bpy.utils.register_class(cls)
bpy.types.VIEW3D_MT_mesh_add.append(add_spiral_thingy_button)
def unregister():
for cls in reversed(classes):
bpy.utils.unregister_class(cls)
bpy.types.VIEW3D_MT_mesh_add.remove(add_spiral_thingy_button)
if __name__ == "__main__":
register()
@batFINGER
Copy link
Author

Peek 2020-01-23 21-45

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment