Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrendon Murphy <meta.androcto1@gmail.com>2015-04-18 08:56:40 +0300
committerBrendon Murphy <meta.androcto1@gmail.com>2015-05-04 03:46:41 +0300
commit93b9836e0ba6c634a4531622eba86fd501a83ba5 (patch)
treeb557c74c6ab03e61ca9f7e1a273d723a7ed379f1
parent8cf173ddbe041e9a4b0ac22f83e7290e53936a9d (diff)
fix
-rw-r--r--add_curve_extra_objects/__init__.py82
-rw-r--r--add_curve_extra_objects/add_curve_aceous_galore.py1122
-rw-r--r--add_curve_extra_objects/add_curve_spirals.py248
-rw-r--r--add_curve_extra_objects/add_curve_torus_knots.py223
4 files changed, 1675 insertions, 0 deletions
diff --git a/add_curve_extra_objects/__init__.py b/add_curve_extra_objects/__init__.py
new file mode 100644
index 00000000..434b7191
--- /dev/null
+++ b/add_curve_extra_objects/__init__.py
@@ -0,0 +1,82 @@
+# ##### 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 #####
+# Contributed to by
+# testscreenings, Alejandro Omar Chocano Vasquez, Jimmy Hazevoet, meta-androcto #
+
+bl_info = {
+ "name": "Extra Objects",
+ "author": "Multiple Authors",
+ "version": (0, 1),
+ "blender": (2, 63, 0),
+ "location": "View3D > Add > Curve > Extra Objects",
+ "description": "Add extra curve object types",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
+ "Scripts/Curve/Curve_Objects",
+ "category": "Add Curve"}
+
+if "bpy" in locals():
+ import imp
+ imp.reload(add_curve_aceous_galore)
+ imp.reload(add_curve_spirals)
+ imp.reload(add_curve_torus_knots)
+
+else:
+ from . import add_curve_aceous_galore
+ from . import add_curve_spirals
+ from . import add_curve_torus_knots
+
+import bpy
+
+class INFO_MT_curve_extras_add(bpy.types.Menu):
+ # Define the "Extras" menu
+ bl_idname = "curve_extra_objects_add"
+ bl_label = "Extra Objects"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'INVOKE_REGION_WIN'
+ layout.operator("mesh.curveaceous_galore",
+ text="Curves Galore!")
+ layout.operator("curve.spirals",
+ text="Spirals")
+ layout.operator("curve.torus_knot_plus",
+ text="Torus Knot Plus")
+# Define "Extras" menu
+def menu_func(self, context):
+ self.layout.operator("mesh.curveaceous_galore",
+ text="Curves Galore!")
+ self.layout.operator("curve.torus_knot_plus",
+ text="Torus Knot Plus")
+ self.layout.operator("curve.spirals",
+ text="Spirals")
+
+def register():
+ bpy.utils.register_module(__name__)
+
+ # Add "Extras" menu to the "Add Curve" menu
+ bpy.types.INFO_MT_curve_add.append(menu_func)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+ # Remove "Extras" menu from the "Add Curve" menu.
+ bpy.types.INFO_MT_curve_add.remove(menu_func)
+
+if __name__ == "__main__":
+ register()
diff --git a/add_curve_extra_objects/add_curve_aceous_galore.py b/add_curve_extra_objects/add_curve_aceous_galore.py
new file mode 100644
index 00000000..0eae5e80
--- /dev/null
+++ b/add_curve_extra_objects/add_curve_aceous_galore.py
@@ -0,0 +1,1122 @@
+# ##### 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": "Curveaceous Galore!",
+ "author": "Jimmy Hazevoet, testscreenings",
+ "version": (0, 2),
+ "blender": (2, 59, 0),
+ "location": "View3D > Add > Curve",
+ "description": "Adds many different types of Curves",
+ "warning": "", # used for warning icon and text in addons panel
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
+ "Scripts/Curve/Curves_Galore",
+ "category": "Add Curve",
+}
+'''
+
+
+##------------------------------------------------------------
+#### import modules
+import bpy
+from bpy.props import *
+from mathutils import *
+from math import *
+import mathutils.noise as Noise
+###------------------------------------------------------------
+#### Some functions to use with others:
+###------------------------------------------------------------
+
+#------------------------------------------------------------
+# Generate random number:
+def randnum(low=0.0, high=1.0, seed=0):
+ """
+ randnum( low=0.0, high=1.0, seed=0 )
+
+ Create random number
+
+ Parameters:
+ low - lower range
+ (type=float)
+ high - higher range
+ (type=float)
+ seed - the random seed number, if seed is 0, the current time will be used instead
+ (type=int)
+ Returns:
+ a random number
+ (type=float)
+ """
+
+ Noise.seed_set(seed)
+ rnum = Noise.random()
+ rnum = rnum*(high-low)
+ rnum = rnum+low
+ return rnum
+
+
+#------------------------------------------------------------
+# Make some noise:
+def vTurbNoise(x,y,z, iScale=0.25, Size=1.0, Depth=6, Hard=0, Basis=0, Seed=0):
+ """
+ vTurbNoise((x,y,z), iScale=0.25, Size=1.0, Depth=6, Hard=0, Basis=0, Seed=0 )
+
+ Create randomised vTurbulence noise
+
+ Parameters:
+ xyz - (x,y,z) float values.
+ (type=3-float tuple)
+ iScale - noise intensity scale
+ (type=float)
+ Size - noise size
+ (type=float)
+ Depth - number of noise values added.
+ (type=int)
+ Hard - noise hardness: 0 - soft noise; 1 - hard noise
+ (type=int)
+ basis - type of noise used for turbulence
+ (type=int)
+ Seed - the random seed number, if seed is 0, the current time will be used instead
+ (type=int)
+ Returns:
+ the generated turbulence vector.
+ (type=3-float list)
+ """
+ rand = randnum(-100,100,Seed)
+ if Basis == 9: Basis = 14
+ vTurb = Noise.turbulence_vector((x/Size+rand, y/Size+rand, z/Size+rand), Depth, Hard, Basis)
+ tx = vTurb[0]*iScale
+ ty = vTurb[1]*iScale
+ tz = vTurb[2]*iScale
+ return tx,ty,tz
+
+
+#------------------------------------------------------------
+# Axis: ( used in 3DCurve Turbulence )
+def AxisFlip(x,y,z, x_axis=1, y_axis=1, z_axis=1, flip=0 ):
+ if flip != 0:
+ flip *= -1
+ else: flip = 1
+ x *= x_axis*flip
+ y *= y_axis*flip
+ z *= z_axis*flip
+ return x,y,z
+
+
+###-------------------------------------------------------------------
+#### 2D Curve shape functions:
+###-------------------------------------------------------------------
+
+##------------------------------------------------------------
+# 2DCurve: Profile: L, H, T, U, Z
+def ProfileCurve(type=0, a=0.25, b=0.25):
+ """
+ ProfileCurve( type=0, a=0.25, b=0.25 )
+
+ Create profile curve
+
+ Parameters:
+ type - select profile type, L, H, T, U, Z
+ (type=int)
+ a - a scaling parameter
+ (type=float)
+ b - b scaling parameter
+ (type=float)
+ Returns:
+ a list with lists of x,y,z coordinates for curve points, [[x,y,z],[x,y,z],...n]
+ (type=list)
+ """
+
+ newpoints = []
+ if type ==1:
+ ## H:
+ a*=0.5
+ b*=0.5
+ newpoints = [ [ -1.0, 1.0, 0.0 ], [ -1.0+a, 1.0, 0.0 ],
+ [ -1.0+a, b, 0.0 ], [ 1.0-a, b, 0.0 ], [ 1.0-a, 1.0, 0.0 ],
+ [ 1.0, 1.0, 0.0 ], [ 1.0, -1.0, 0.0 ], [ 1.0-a, -1.0, 0.0 ],
+ [ 1.0-a, -b, 0.0 ], [ -1.0+a, -b, 0.0 ], [ -1.0+a, -1.0, 0.0 ],
+ [ -1.0, -1.0, 0.0 ] ]
+ elif type ==2:
+ ## T:
+ a*=0.5
+ newpoints = [ [ -1.0, 1.0, 0.0 ], [ 1.0, 1.0, 0.0 ],
+ [ 1.0, 1.0-b, 0.0 ], [ a, 1.0-b, 0.0 ], [ a, -1.0, 0.0 ],
+ [ -a, -1.0, 0.0 ], [ -a, 1.0-b, 0.0 ], [ -1.0, 1.0-b, 0.0 ] ]
+ elif type ==3:
+ ## U:
+ a*=0.5
+ newpoints = [ [ -1.0, 1.0, 0.0 ], [ -1.0+a, 1.0, 0.0 ],
+ [ -1.0+a, -1.0+b, 0.0 ], [ 1.0-a, -1.0+b, 0.0 ], [ 1.0-a, 1.0, 0.0 ],
+ [ 1.0, 1.0, 0.0 ], [ 1.0, -1.0, 0.0 ], [ -1.0, -1.0, 0.0 ] ]
+ elif type ==4:
+ ## Z:
+ a*=0.5
+ newpoints = [ [ -0.5, 1.0, 0.0 ], [ a, 1.0, 0.0 ],
+ [ a, -1.0+b, 0.0 ], [ 1.0, -1.0+b, 0.0 ], [ 1.0, -1.0, 0.0 ],
+ [ -a, -1.0, 0.0 ], [ -a, 1.0-b, 0.0 ], [ -1.0, 1.0-b, 0.0 ],
+ [ -1.0, 1.0, 0.0 ] ]
+ else:
+ ## L:
+ newpoints = [ [ -1.0, 1.0, 0.0 ], [ -1.0+a, 1.0, 0.0 ],
+ [ -1.0+a, -1.0+b, 0.0 ], [ 1.0, -1.0+b, 0.0 ],
+ [ 1.0, -1.0, 0.0 ], [ -1.0, -1.0, 0.0 ] ]
+ return newpoints
+
+##------------------------------------------------------------
+# 2DCurve: Miscellaneous.: Diamond, Arrow1, Arrow2, Square, ....
+def MiscCurve(type=1, a=1.0, b=0.5, c=1.0):
+ """
+ MiscCurve( type=1, a=1.0, b=0.5, c=1.0 )
+
+ Create miscellaneous curves
+
+ Parameters:
+ type - select type, Diamond, Arrow1, Arrow2, Square
+ (type=int)
+ a - a scaling parameter
+ (type=float)
+ b - b scaling parameter
+ (type=float)
+ c - c scaling parameter
+ (type=float)
+ doesn't seem to do anything
+ Returns:
+ a list with lists of x,y,z coordinates for curve points, [[x,y,z],[x,y,z],...n]
+ (type=list)
+ """
+
+ newpoints = []
+ a*=0.5
+ b*=0.5
+ if type == 1:
+ ## diamond:
+ newpoints = [ [ 0.0, b, 0.0 ], [ a, 0.0, 0.0 ], [ 0.0, -b, 0.0 ], [ -a, 0.0, 0.0 ] ]
+ elif type == 2:
+ ## Arrow1:
+ newpoints = [ [ -a, b, 0.0 ], [ a, 0.0, 0.0 ], [ -a, -b, 0.0 ], [ 0.0, 0.0, 0.0 ] ]
+ elif type == 3:
+ ## Arrow2:
+ newpoints = [ [ -1.0, b, 0.0 ], [ -1.0+a, b, 0.0 ],
+ [ -1.0+a, 1.0, 0.0 ], [ 1.0, 0.0, 0.0 ],
+ [ -1.0+a, -1.0, 0.0 ], [ -1.0+a, -b, 0.0 ],
+ [ -1.0, -b, 0.0 ] ]
+ elif type == 4:
+ ## Rounded square:
+ newpoints = [ [ -a, b-b*0.2, 0.0 ], [ -a+a*0.05, b-b*0.05, 0.0 ], [ -a+a*0.2, b, 0.0 ],
+ [ a-a*0.2, b, 0.0 ], [ a-a*0.05, b-b*0.05, 0.0 ], [ a, b-b*0.2, 0.0 ],
+ [ a, -b+b*0.2, 0.0 ], [ a-a*0.05, -b+b*0.05, 0.0 ], [ a-a*0.2, -b, 0.0 ],
+ [ -a+a*0.2, -b, 0.0 ], [ -a+a*0.05, -b+b*0.05, 0.0 ], [ -a, -b+b*0.2, 0.0 ] ]
+ elif type == 5:
+ ## Rounded Rectangle II:
+ newpoints = []
+ x = a / 2
+ y = b / 2
+ r = c / 2
+
+ if r > x:
+ r = x - 0.0001
+ if r > y:
+ r = y - 0.0001
+
+ if r>0:
+ newpoints.append([-x+r,y,0])
+ newpoints.append([x-r,y,0])
+ newpoints.append([x,y-r,0])
+ newpoints.append([x,-y+r,0])
+ newpoints.append([x-r,-y,0])
+ newpoints.append([-x+r,-y,0])
+ newpoints.append([-x,-y+r,0])
+ newpoints.append([-x,y-r,0])
+ else:
+ newpoints.append([-x,y,0])
+ newpoints.append([x,y,0])
+ newpoints.append([x,-y,0])
+ newpoints.append([-x,-y,0])
+
+ else:
+ ## Square:
+ newpoints = [ [ -a, b, 0.0 ], [ a, b, 0.0 ], [ a, -b, 0.0 ], [ -a, -b, 0.0 ] ]
+ return newpoints
+
+##------------------------------------------------------------
+# 2DCurve: Star:
+def StarCurve(starpoints=8, innerradius=0.5, outerradius=1.0, twist=0.0):
+ """
+ StarCurve( starpoints=8, innerradius=0.5, outerradius=1.0, twist=0.0 )
+
+ Create star shaped curve
+
+ Parameters:
+ starpoints - the number of points
+ (type=int)
+ innerradius - innerradius
+ (type=float)
+ outerradius - outerradius
+ (type=float)
+ twist - twist amount
+ (type=float)
+ Returns:
+ a list with lists of x,y,z coordinates for curve points, [[x,y,z],[x,y,z],...n]
+ (type=list)
+ """
+
+ newpoints = []
+ step = (2.0/(starpoints))
+ i = 0
+ while i < starpoints:
+ t = (i*step)
+ x1 = cos(t*pi)*outerradius
+ y1 = sin(t*pi)*outerradius
+ newpoints.append([x1,y1,0])
+ x2 = cos(t*pi+(pi/starpoints+twist))*innerradius
+ y2 = sin(t*pi+(pi/starpoints+twist))*innerradius
+ newpoints.append([x2,y2,0])
+ i+=1
+ return newpoints
+
+##------------------------------------------------------------
+# 2DCurve: Flower:
+def FlowerCurve(petals=8, innerradius=0.5, outerradius=1.0, petalwidth=2.0):
+ """
+ FlowerCurve( petals=8, innerradius=0.5, outerradius=1.0, petalwidth=2.0 )
+
+ Create flower shaped curve
+
+ Parameters:
+ petals - the number of petals
+ (type=int)
+ innerradius - innerradius
+ (type=float)
+ outerradius - outerradius
+ (type=float)
+ petalwidth - width of petals
+ (type=float)
+ Returns:
+ a list with lists of x,y,z coordinates for curve points, [[x,y,z],[x,y,z],...n]
+ (type=list)
+ """
+
+ newpoints = []
+ step = (2.0/(petals))
+ pet = (step/pi*2)*petalwidth
+ i = 0
+ while i < petals:
+ t = (i*step)
+ x1 = cos(t*pi-(pi/petals))*innerradius
+ y1 = sin(t*pi-(pi/petals))*innerradius
+ newpoints.append([x1,y1,0])
+ x2 = cos(t*pi-pet)*outerradius
+ y2 = sin(t*pi-pet)*outerradius
+ newpoints.append([x2,y2,0])
+ x3 = cos(t*pi+pet)*outerradius
+ y3 = sin(t*pi+pet)*outerradius
+ newpoints.append([x3,y3,0])
+ i+=1
+ return newpoints
+
+##------------------------------------------------------------
+# 2DCurve: Arc,Sector,Segment,Ring:
+def ArcCurve(sides=6, startangle=0.0, endangle=90.0, innerradius=0.5, outerradius=1.0, type=3):
+ """
+ ArcCurve( sides=6, startangle=0.0, endangle=90.0, innerradius=0.5, outerradius=1.0, type=3 )
+
+ Create arc shaped curve
+
+ Parameters:
+ sides - number of sides
+ (type=int)
+ startangle - startangle
+ (type=float)
+ endangle - endangle
+ (type=float)
+ innerradius - innerradius
+ (type=float)
+ outerradius - outerradius
+ (type=float)
+ type - select type Arc,Sector,Segment,Ring
+ (type=int)
+ Returns:
+ a list with lists of x,y,z coordinates for curve points, [[x,y,z],[x,y,z],...n]
+ (type=list)
+ """
+
+ newpoints = []
+ sides += 1
+ angle = (2.0*(1.0/360.0))
+ endangle-=startangle
+ step = ((angle*endangle)/(sides-1))
+ i = 0
+ while i < sides:
+ t = (i*step) + angle*startangle
+ x1 = sin(t*pi)*outerradius
+ y1 = cos(t*pi)*outerradius
+ newpoints.append([x1,y1,0])
+ i+=1
+
+ #if type ==0:
+ # Arc: turn cyclic curve flag off!
+
+ # Segment:
+ if type ==2:
+ newpoints.append([0,0,0])
+ # Ring:
+ elif type ==3:
+ j=sides-1
+ while j > -1:
+ t = (j*step) + angle*startangle
+ x2 = sin(t*pi)*innerradius
+ y2 = cos(t*pi)*innerradius
+ newpoints.append([x2,y2,0])
+ j-=1
+ return newpoints
+
+##------------------------------------------------------------
+# 2DCurve: Cog wheel:
+def CogCurve(theeth=8, innerradius=0.8, middleradius=0.95, outerradius=1.0, bevel=0.5):
+ """
+ CogCurve( theeth=8, innerradius=0.8, middleradius=0.95, outerradius=1.0, bevel=0.5 )
+
+ Create cog wheel shaped curve
+
+ Parameters:
+ theeth - number of theeth
+ (type=int)
+ innerradius - innerradius
+ (type=float)
+ middleradius - middleradius
+ (type=float)
+ outerradius - outerradius
+ (type=float)
+ bevel - bevel amount
+ (type=float)
+ Returns:
+ a list with lists of x,y,z coordinates for curve points, [[x,y,z],[x,y,z],...n]
+ (type=list)
+ """
+
+ newpoints = []
+ step = (2.0/(theeth))
+ pet = (step/pi*2)
+ bevel = 1.0-bevel
+ i = 0
+ while i < theeth:
+ t = (i*step)
+ x1 = cos(t*pi-(pi/theeth)-pet)*innerradius
+ y1 = sin(t*pi-(pi/theeth)-pet)*innerradius
+ newpoints.append([x1,y1,0])
+ x2 = cos(t*pi-(pi/theeth)+pet)*innerradius
+ y2 = sin(t*pi-(pi/theeth)+pet)*innerradius
+ newpoints.append([x2,y2,0])
+ x3 = cos(t*pi-pet)*middleradius
+ y3 = sin(t*pi-pet)*middleradius
+ newpoints.append([x3,y3,0])
+ x4 = cos(t*pi-(pet*bevel))*outerradius
+ y4 = sin(t*pi-(pet*bevel))*outerradius
+ newpoints.append([x4,y4,0])
+ x5 = cos(t*pi+(pet*bevel))*outerradius
+ y5 = sin(t*pi+(pet*bevel))*outerradius
+ newpoints.append([x5,y5,0])
+ x6 = cos(t*pi+pet)*middleradius
+ y6 = sin(t*pi+pet)*middleradius
+ newpoints.append([x6,y6,0])
+ i+=1
+ return newpoints
+
+##------------------------------------------------------------
+# 2DCurve: nSide:
+def nSideCurve(sides=6, radius=1.0):
+ """
+ nSideCurve( sides=6, radius=1.0 )
+
+ Create n-sided curve
+
+ Parameters:
+ sides - number of sides
+ (type=int)
+ radius - radius
+ (type=float)
+ Returns:
+ a list with lists of x,y,z coordinates for curve points, [[x,y,z],[x,y,z],...n]
+ (type=list)
+ """
+
+ newpoints = []
+ step = (2.0/(sides))
+ i = 0
+ while i < sides:
+ t = (i*step)
+ x = sin(t*pi)*radius
+ y = cos(t*pi)*radius
+ newpoints.append([x,y,0])
+ i+=1
+ return newpoints
+
+
+##------------------------------------------------------------
+# 2DCurve: Splat:
+def SplatCurve(sides=24, scale=1.0, seed=0, basis=0, radius=1.0):
+ """
+ SplatCurve( sides=24, scale=1.0, seed=0, basis=0, radius=1.0 )
+
+ Create splat curve
+
+ Parameters:
+ sides - number of sides
+ (type=int)
+ scale - noise size
+ (type=float)
+ seed - noise random seed
+ (type=int)
+ basis - noise basis
+ (type=int)
+ radius - radius
+ (type=float)
+ Returns:
+ a list with lists of x,y,z coordinates for curve points, [[x,y,z],[x,y,z],...n]
+ (type=list)
+ """
+
+ newpoints = []
+ step = (2.0/(sides))
+ i = 0
+ while i < sides:
+ t = (i*step)
+ turb = vTurbNoise(t,t,t, 1.0, scale, 6, 0, basis, seed )
+ turb = turb[2] * 0.5 + 0.5
+ x = sin(t*pi)*radius * turb
+ y = cos(t*pi)*radius * turb
+ newpoints.append([x,y,0])
+ i+=1
+ return newpoints
+
+###-----------------------------------------------------------
+#### 3D curve shape functions:
+###-----------------------------------------------------------
+
+###------------------------------------------------------------
+# 3DCurve: Helix:
+def HelixCurve( number=100, height=2.0, startangle=0.0, endangle=360.0, width=1.0, a=0.0, b=0.0 ):
+ """
+ HelixCurve( number=100, height=2.0, startangle=0.0, endangle=360.0, width=1.0, a=0.0, b=0.0 )
+
+ Create helix curve
+
+ Parameters:
+ number - the number of points
+ (type=int)
+ height - height
+ (type=float)
+ startangle - startangle
+ (type=float)
+ endangle - endangle
+ (type=float)
+ width - width
+ (type=float)
+ a - a
+ (type=float)
+ b - b
+ (type=float)
+ Returns:
+ a list with lists of x,y,z coordinates for curve points, [[x,y,z],[x,y,z],...n]
+ (type=list)
+ """
+
+ newpoints = []
+ angle = (2.0/360.0)*(endangle-startangle)
+ step = angle/(number-1)
+ h = height/angle
+ start = (startangle*2.0/360.0)
+ a/=angle
+ i = 0
+ while i < number:
+ t = ( i*step+start )
+ x = sin( (t*pi) ) * ( 1.0 + cos( t * pi * a - ( b * pi ) ) ) * ( 0.25 * width )
+ y = cos( (t*pi) ) * ( 1.0 + cos( t * pi * a - ( b * pi ) ) ) * ( 0.25 * width )
+ z = ( t * h ) -h*start
+ newpoints.append([x,y,z])
+ i+=1
+ return newpoints
+
+###------------------------------------------------------------ ?
+# 3DCurve: Cycloid: Cycloid, Epicycloid, Hypocycloid
+def CycloidCurve( number=24, length=2.0, type=0, a=1.0, b=1.0, startangle=0.0, endangle=360.0 ):
+ """
+ CycloidCurve( number=24, length=2.0, type=0, a=1.0, b=1.0, startangle=0.0, endangle=360.0 )
+
+ Create a Cycloid, Epicycloid or Hypocycloid curve
+
+ Parameters:
+ number - the number of points
+ (type=int)
+ length - length of curve
+ (type=float)
+ type - types: Cycloid, Epicycloid, Hypocycloid
+ (type=int)
+ Returns:
+ a list with lists of x,y,z coordinates for curve points, [[x,y,z],[x,y,z],...n]
+ (type=list)
+ """
+
+ newpoints = []
+ angle = (2.0/360.0)*(endangle-startangle)
+ step = angle/(number-1)
+ #h = height/angle
+ d = length
+ start = (startangle*2.0/360.0)
+ a/=angle
+ i = 0
+ if type == 0: # Epitrochoid
+ while i < number:
+ t = ( i*step+start )
+ x = ((a + b) * cos(t*pi)) - (d * cos(((a+b)/b)*t*pi))
+ y = ((a + b) * sin(t*pi)) - (d * sin(((a+b)/b)*t*pi))
+ z = 0 # ( t * h ) -h*start
+ newpoints.append([x,y,z])
+ i+=1
+
+ else:
+ newpoints = [[-1,-1,0], [-1,1,0], [1,1,0], [1,-1,0]]
+ return newpoints
+
+##------------------------------------------------------------
+# calculates the matrix for the new object
+# depending on user pref
+def align_matrix(context):
+ loc = Matrix.Translation(context.scene.cursor_location)
+ obj_align = context.user_preferences.edit.object_align
+ if (context.space_data.type == 'VIEW_3D'
+ and obj_align == 'VIEW'):
+ rot = context.space_data.region_3d.view_matrix.to_3x3().inverted().to_4x4()
+ else:
+ rot = Matrix()
+ align_matrix = loc * rot
+ return align_matrix
+
+##------------------------------------------------------------
+#### Curve creation functions
+# sets bezierhandles to auto
+def setBezierHandles(obj, mode = 'AUTOMATIC'):
+ scene = bpy.context.scene
+ if obj.type != 'CURVE':
+ return
+ scene.objects.active = obj
+ bpy.ops.object.mode_set(mode='EDIT', toggle=True)
+ bpy.ops.curve.select_all(action='SELECT')
+ bpy.ops.curve.handle_type_set(type=mode)
+ bpy.ops.object.mode_set(mode='OBJECT', toggle=True)
+
+# get array of vertcoordinates acording to splinetype
+def vertsToPoints(Verts, splineType):
+ # main vars
+ vertArray = []
+
+ # array for BEZIER spline output (V3)
+ if splineType == 'BEZIER':
+ for v in Verts:
+ vertArray += v
+
+ # array for nonBEZIER output (V4)
+ else:
+ for v in Verts:
+ vertArray += v
+ if splineType == 'NURBS':
+ vertArray.append(1) #for nurbs w=1
+ else: #for poly w=0
+ vertArray.append(0)
+ return vertArray
+
+# create new CurveObject from vertarray and splineType
+def createCurve(vertArray, self, align_matrix):
+ # options to vars
+ splineType = self.outputType # output splineType 'POLY' 'NURBS' 'BEZIER'
+ name = self.GalloreType # GalloreType as name
+
+ # create curve
+ scene = bpy.context.scene
+ newCurve = bpy.data.curves.new(name, type = 'CURVE') # curvedatablock
+ newSpline = newCurve.splines.new(type = splineType) # spline
+
+ # create spline from vertarray
+ if splineType == 'BEZIER':
+ newSpline.bezier_points.add(int(len(vertArray)*0.33))
+ newSpline.bezier_points.foreach_set('co', vertArray)
+ else:
+ newSpline.points.add(int(len(vertArray)*0.25 - 1))
+ newSpline.points.foreach_set('co', vertArray)
+ newSpline.use_endpoint_u = True
+
+ # set curveOptions
+ newCurve.dimensions = self.shape
+ newSpline.use_cyclic_u = self.use_cyclic_u
+ newSpline.use_endpoint_u = self.endp_u
+ newSpline.order_u = self.order_u
+
+ # create object with newCurve
+ new_obj = bpy.data.objects.new(name, newCurve) # object
+ scene.objects.link(new_obj) # place in active scene
+ new_obj.select = True # set as selected
+ scene.objects.active = new_obj # set as active
+ new_obj.matrix_world = align_matrix # apply matrix
+
+ # set bezierhandles
+ if splineType == 'BEZIER':
+ setBezierHandles(new_obj, self.handleType)
+
+ return
+
+##------------------------------------------------------------
+# Main Function
+def main(context, self, align_matrix):
+ # deselect all objects
+ bpy.ops.object.select_all(action='DESELECT')
+
+ # options
+ galType = self.GalloreType
+ splineType = self.outputType
+ innerRadius = self.innerRadius
+ middleRadius = self.middleRadius
+ outerRadius = self.outerRadius
+
+ # get verts
+ if galType == 'Profile':
+ verts = ProfileCurve(self.ProfileCurveType,
+ self.ProfileCurvevar1,
+ self.ProfileCurvevar2)
+ if galType == 'Miscellaneous':
+ verts = MiscCurve(self.MiscCurveType,
+ self.MiscCurvevar1,
+ self.MiscCurvevar2,
+ self.MiscCurvevar3)
+ if galType == 'Flower':
+ verts = FlowerCurve(self.petals,
+ innerRadius,
+ outerRadius,
+ self.petalWidth)
+ if galType == 'Star':
+ verts = StarCurve(self.starPoints,
+ innerRadius,
+ outerRadius,
+ self.starTwist)
+ if galType == 'Arc':
+ verts = ArcCurve(self.arcSides,
+ self.startAngle,
+ self.endAngle,
+ innerRadius,
+ outerRadius,
+ self.arcType)
+ if galType == 'Cogwheel':
+ verts = CogCurve(self.teeth,
+ innerRadius,
+ middleRadius,
+ outerRadius,
+ self.bevel)
+ if galType == 'Nsided':
+ verts = nSideCurve(self.Nsides,
+ outerRadius)
+
+ if galType == 'Splat':
+ verts = SplatCurve(self.splatSides,
+ self.splatScale,
+ self.seed,
+ self.basis,
+ outerRadius)
+
+ if galType == 'Helix':
+ verts = HelixCurve(self.helixPoints,
+ self.helixHeight,
+ self.helixStart,
+ self.helixEnd,
+ self.helixWidth,
+ self.helix_a,
+ self.helix_b)
+ if galType == 'Cycloid':
+ verts = CycloidCurve(self.cycloPoints,
+ self.cyclo_d,
+ self.cycloType,
+ self.cyclo_a,
+ self.cyclo_b,
+ self.cycloStart,
+ self.cycloEnd)
+
+ # turn verts into array
+ vertArray = vertsToPoints(verts, splineType)
+
+ # create object
+ createCurve(vertArray, self, align_matrix)
+
+ return
+
+class Curveaceous_galore(bpy.types.Operator):
+ """Add many types of curves"""
+ bl_idname = "mesh.curveaceous_galore"
+ bl_label = "Curveaceous galore"
+ bl_options = {'REGISTER', 'UNDO', 'PRESET'}
+
+ # align_matrix for the invoke
+ align_matrix = Matrix()
+
+ #### general properties
+ GalloreTypes = [
+ ('Profile', 'Profile', 'Profile'),
+ ('Miscellaneous', 'Miscellaneous', 'Miscellaneous'),
+ ('Flower', 'Flower', 'Flower'),
+ ('Star', 'Star', 'Star'),
+ ('Arc', 'Arc', 'Arc'),
+ ('Cogwheel', 'Cogwheel', 'Cogwheel'),
+ ('Nsided', 'Nsided', 'Nsided'),
+ ('Splat', 'Splat', 'Splat'),
+ ('Cycloid', 'Cycloid', 'Cycloid'),
+ ('Helix', 'Helix (3D)', 'Helix')]
+ GalloreType = EnumProperty(name="Type",
+ description="Form of Curve to create",
+ items=GalloreTypes)
+ SplineTypes = [
+ ('POLY', 'Poly', 'POLY'),
+ ('NURBS', 'Nurbs', 'NURBS'),
+ ('BEZIER', 'Bezier', 'BEZIER')]
+ outputType = EnumProperty(name="Output splines",
+ description="Type of splines to output",
+ items=SplineTypes)
+
+ #### Curve Options
+ shapeItems = [
+ ('2D', '2D', '2D'),
+ ('3D', '3D', '3D')]
+ shape = EnumProperty(name="2D / 3D",
+ items=shapeItems,
+ description="2D or 3D Curve")
+ use_cyclic_u = BoolProperty(name="Cyclic",
+ default=True,
+ description="make curve closed")
+ endp_u = BoolProperty(name="use_endpoint_u",
+ default=True,
+ description="stretch to endpoints")
+ order_u = IntProperty(name="order_u",
+ default=4,
+ min=2, soft_min=2,
+ max=6, soft_max=6,
+ description="Order of nurbs spline")
+ bezHandles = [
+ ('VECTOR', 'Vector', 'VECTOR'),
+ ('AUTOMATIC', 'Auto', 'AUTOMATIC')]
+ handleType = EnumProperty(name="Handle type",
+ description="bezier handles type",
+ items=bezHandles)
+
+ #### ProfileCurve properties
+ ProfileCurveType = IntProperty(name="Type",
+ min=1, soft_min=1,
+ max=5, soft_max=5,
+ default=1,
+ description="Type of ProfileCurve")
+ ProfileCurvevar1 = FloatProperty(name="var_1",
+ default=0.25,
+ description="var1 of ProfileCurve")
+ ProfileCurvevar2 = FloatProperty(name="var_2",
+ default=0.25,
+ description="var2 of ProfileCurve")
+
+ #### MiscCurve properties
+ MiscCurveType = IntProperty(name="Type",
+ min=1, soft_min=1,
+ max=6, soft_max=6,
+ default=1,
+ description="Type of MiscCurve")
+ MiscCurvevar1 = FloatProperty(name="var_1",
+ default=1.0,
+ description="var1 of MiscCurve")
+ MiscCurvevar2 = FloatProperty(name="var_2",
+ default=0.5,
+ description="var2 of MiscCurve")
+ MiscCurvevar3 = FloatProperty(name="var_3",
+ default=0.1,
+ min=0, soft_min=0,
+ description="var3 of MiscCurve")
+
+ #### Common properties
+ innerRadius = FloatProperty(name="Inner radius",
+ default=0.5,
+ min=0, soft_min=0,
+ description="Inner radius")
+ middleRadius = FloatProperty(name="Middle radius",
+ default=0.95,
+ min=0, soft_min=0,
+ description="Middle radius")
+ outerRadius = FloatProperty(name="Outer radius",
+ default=1.0,
+ min=0, soft_min=0,
+ description="Outer radius")
+
+ #### Flower properties
+ petals = IntProperty(name="Petals",
+ default=8,
+ min=2, soft_min=2,
+ description="Number of petals")
+ petalWidth = FloatProperty(name="Petal width",
+ default=2.0,
+ min=0.01, soft_min=0.01,
+ description="Petal width")
+
+ #### Star properties
+ starPoints = IntProperty(name="Star points",
+ default=8,
+ min=2, soft_min=2,
+ description="Number of star points")
+ starTwist = FloatProperty(name="Twist",
+ default=0.0,
+ description="Twist")
+
+ #### Arc properties
+ arcSides = IntProperty(name="Arc sides",
+ default=6,
+ min=1, soft_min=1,
+ description="Sides of arc")
+ startAngle = FloatProperty(name="Start angle",
+ default=0.0,
+ description="Start angle")
+ endAngle = FloatProperty(name="End angle",
+ default=90.0,
+ description="End angle")
+ arcType = IntProperty(name="Arc type",
+ default=3,
+ min=1, soft_min=1,
+ max=3, soft_max=3,
+ description="Sides of arc")
+
+ #### Cogwheel properties
+ teeth = IntProperty(name="Teeth",
+ default=8,
+ min=2, soft_min=2,
+ description="number of teeth")
+ bevel = FloatProperty(name="Bevel",
+ default=0.5,
+ min=0, soft_min=0,
+ max=1, soft_max=1,
+ description="Bevel")
+
+ #### Nsided property
+ Nsides = IntProperty(name="Sides",
+ default=8,
+ min=3, soft_min=3,
+ description="Number of sides")
+
+ #### Splat properties
+ splatSides = IntProperty(name="Splat sides",
+ default=24,
+ min=3, soft_min=3,
+ description="Splat sides")
+ splatScale = FloatProperty(name="Splat scale",
+ default=1.0,
+ min=0.0001, soft_min=0.0001,
+ description="Splat scale")
+ seed = IntProperty(name="Seed",
+ default=0,
+ min=0, soft_min=0,
+ description="Seed")
+ basis = IntProperty(name="Basis",
+ default=0,
+ min=0, soft_min=0,
+ max=14, soft_max=14,
+ description="Basis")
+
+ #### Helix properties
+ helixPoints = IntProperty(name="resolution",
+ default=100,
+ min=3, soft_min=3,
+ description="resolution")
+ helixHeight = FloatProperty(name="Height",
+ default=2.0,
+ min=0, soft_min=0,
+ description="Helix height")
+ helixStart = FloatProperty(name="Start angle",
+ default=0.0,
+ description="Helix start angle")
+ helixEnd = FloatProperty(name="Endangle",
+ default=360.0,
+ description="Helix end angle")
+ helixWidth = FloatProperty(name="Width",
+ default=1.0,
+ description="Helix width")
+ helix_a = FloatProperty(name="var_1",
+ default=0.0,
+ description="Helix var1")
+ helix_b = FloatProperty(name="var_2",
+ default=0.0,
+ description="Helix var2")
+
+ #### Cycloid properties
+ cycloPoints = IntProperty(name="Resolution",
+ default=100,
+ min=3, soft_min=3,
+ description="Resolution")
+ cyclo_d = FloatProperty(name="var_3",
+ default=1.5,
+ description="Cycloid var3")
+ cycloType = IntProperty(name="Type",
+ default=0,
+ min=0, soft_min=0,
+ max=0, soft_max=0,
+ description="resolution")
+ cyclo_a = FloatProperty(name="var_1",
+ default=5.0,
+ min=0.01, soft_min=0.01,
+ description="Cycloid var1")
+ cyclo_b = FloatProperty(name="var_2",
+ default=0.5,
+ min=0.01, soft_min=0.01,
+ description="Cycloid var2")
+ cycloStart = FloatProperty(name="Start angle",
+ default=0.0,
+ description="Cycloid start angle")
+ cycloEnd = FloatProperty(name="End angle",
+ default=360.0,
+ description="Cycloid end angle")
+
+ ##### DRAW #####
+ def draw(self, context):
+ layout = self.layout
+
+ # general options
+ col = layout.column()
+ col.prop(self, 'GalloreType')
+ col.label(text=self.GalloreType + " Options:")
+
+ # options per GalloreType
+ box = layout.box()
+ if self.GalloreType == 'Profile':
+ box.prop(self, 'ProfileCurveType')
+ box.prop(self, 'ProfileCurvevar1')
+ box.prop(self, 'ProfileCurvevar2')
+ elif self.GalloreType == 'Miscellaneous':
+ box.prop(self, 'MiscCurveType')
+ box.prop(self, 'MiscCurvevar1', text='Width')
+ box.prop(self, 'MiscCurvevar2', text='Height')
+ if self.MiscCurveType == 5:
+ box.prop(self, 'MiscCurvevar3', text='Rounded')
+ elif self.GalloreType == 'Flower':
+ box.prop(self, 'petals')
+ box.prop(self, 'petalWidth')
+ box.prop(self, 'innerRadius')
+ box.prop(self, 'outerRadius')
+ elif self.GalloreType == 'Star':
+ box.prop(self, 'starPoints')
+ box.prop(self, 'starTwist')
+ box.prop(self, 'innerRadius')
+ box.prop(self, 'outerRadius')
+ elif self.GalloreType == 'Arc':
+ box.prop(self, 'arcSides')
+ box.prop(self, 'arcType') # has only one Type?
+ box.prop(self, 'startAngle')
+ box.prop(self, 'endAngle')
+ box.prop(self, 'innerRadius') # doesn't seem to do anything
+ box.prop(self, 'outerRadius')
+ elif self.GalloreType == 'Cogwheel':
+ box.prop(self, 'teeth')
+ box.prop(self, 'bevel')
+ box.prop(self, 'innerRadius')
+ box.prop(self, 'middleRadius')
+ box.prop(self, 'outerRadius')
+ elif self.GalloreType == 'Nsided':
+ box.prop(self, 'Nsides')
+ box.prop(self, 'outerRadius', text='Radius')
+
+ elif self.GalloreType == 'Splat':
+ box.prop(self, 'splatSides')
+ box.prop(self, 'outerRadius')
+ box.prop(self, 'splatScale')
+ box.prop(self, 'seed')
+ box.prop(self, 'basis')
+
+ elif self.GalloreType == 'Helix':
+ box.prop(self, 'helixPoints')
+ box.prop(self, 'helixHeight')
+ box.prop(self, 'helixWidth')
+ box.prop(self, 'helixStart')
+ box.prop(self, 'helixEnd')
+ box.prop(self, 'helix_a')
+ box.prop(self, 'helix_b')
+ elif self.GalloreType == 'Cycloid':
+ box.prop(self, 'cycloPoints')
+ #box.prop(self, 'cycloType') # needs the other types first
+ box.prop(self, 'cycloStart')
+ box.prop(self, 'cycloEnd')
+ box.prop(self, 'cyclo_a')
+ box.prop(self, 'cyclo_b')
+ box.prop(self, 'cyclo_d')
+
+ col = layout.column()
+ col.label(text="Output Curve Type:")
+ col.row().prop(self, 'outputType', expand=True)
+ col.label(text="Curve Options:")
+
+ # output options
+ box = layout.box()
+ if self.outputType == 'NURBS':
+ box.row().prop(self, 'shape', expand=True)
+ #box.prop(self, 'use_cyclic_u')
+ #box.prop(self, 'endp_u')
+ box.prop(self, 'order_u')
+
+ elif self.outputType == 'POLY':
+ box.row().prop(self, 'shape', expand=True)
+ #box.prop(self, 'use_cyclic_u')
+
+ elif self.outputType == 'BEZIER':
+ box.row().prop(self, 'shape', expand=True)
+ box.row().prop(self, 'handleType', expand=True)
+ #box.prop(self, 'use_cyclic_u')
+
+
+ ##### POLL #####
+ @classmethod
+ def poll(cls, context):
+ return context.scene != None
+
+ ##### EXECUTE #####
+ def execute(self, context):
+ # turn off undo
+ undo = bpy.context.user_preferences.edit.use_global_undo
+ bpy.context.user_preferences.edit.use_global_undo = False
+
+ # deal with 2D - 3D curve differences
+ if self.GalloreType in ['Helix', 'Cycloid']:
+ self.shape = '3D'
+ #else:
+ #self.shape = '2D' # someone decide if we want this
+
+ if self.GalloreType in ['Helix']:
+ self.use_cyclic_u = False
+ else:
+ self.use_cyclic_u = True
+
+
+ # main function
+ main(context, self, self.align_matrix)
+
+ # restore pre operator undo state
+ bpy.context.user_preferences.edit.use_global_undo = undo
+
+ return {'FINISHED'}
+
+ ##### INVOKE #####
+ def invoke(self, context, event):
+ # store creation_matrix
+ self.align_matrix = align_matrix(context)
+ self.execute(context)
+
+ return {'FINISHED'}
diff --git a/add_curve_extra_objects/add_curve_spirals.py b/add_curve_extra_objects/add_curve_spirals.py
new file mode 100644
index 00000000..11d86eb7
--- /dev/null
+++ b/add_curve_extra_objects/add_curve_spirals.py
@@ -0,0 +1,248 @@
+'''bl_info = {
+ "name": "Spirals",
+ "description": "Make spirals",
+ "author": "Alejandro Omar Chocano Vasquez",
+ "version": (1, 2),
+ "blender": (2, 62, 0),
+ "location": "View3D > Add > Curve",
+ "warning": "", # used for warning icon and text in addons panel
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.4/Py/"
+ "Scripts/Object/Spirals",
+ "tracker_url": "http://alexvaqp.googlepages.com?"
+ "func=detail&aid=<number>",
+ "category": "Add Curve",
+}
+'''
+import bpy, time
+from bpy.props import *
+from math import sin, cos, pi, exp
+from bpy_extras.object_utils import AddObjectHelper, object_data_add
+
+#make normal spiral
+#-----------------------------------------------------------------------------
+def make_spiral(props, context): #archemedian and logarithmic can be plottet in zylindrical coordinates
+ #if props.spiral_type != 1 and props.spiral_type != 2:
+ # return None
+
+ #INPUT: turns->degree->max_phi, steps, direction
+ #Initialise Polar Coordinate Enviroment
+ #-------------------------------
+ props.degree = 360*props.turns #If you want to make the slider for degree
+ steps = props.steps * props.turns #props.steps[per turn] -> steps[for the whole spiral]
+ props.z_scale = props.dif_z * props.turns
+
+ max_phi = pi*props.degree/180 #max angle in radian
+ step_phi = max_phi/steps #angle in radians between two vertices
+ if props.spiral_direction == 1:
+ step_phi *= -1 #flip direction
+ max_phi *= -1
+ step_z = props.z_scale/(steps-1) #z increase in one step
+
+ verts = []
+ verts.extend([props.radius,0,0,1])
+
+ cur_phi = 0
+ cur_z = 0
+ #-------------------------------
+
+ #Archemedean: dif_radius, radius
+ cur_rad = props.radius
+ step_rad = props.dif_radius/(steps * 360/props.degree) #radius increase per angle for archemedean spiral| (steps * 360/props.degree)...Steps needed for 360 deg
+ #Logarithmic: radius, B_force, ang_div, dif_z
+
+ #print("max_phi:",max_phi,"step_phi:",step_phi,"step_rad:",step_rad,"step_z:",step_z)
+ while abs(cur_phi) <= abs(max_phi):
+ cur_phi += step_phi
+ cur_z += step_z
+
+ #-------------------------------
+ if props.spiral_type == 1:
+ cur_rad += step_rad
+ if props.spiral_type == 2:
+ #r = a*e^{|theta| * b}
+ cur_rad = props.radius * pow(props.B_force, abs(cur_phi))
+ #-------------------------------
+
+ px = cur_rad * cos(cur_phi)
+ py = cur_rad * sin(cur_phi)
+ verts.extend( [px,py,cur_z,1] )
+
+ return verts
+
+
+#make Spheric spiral
+#-----------------------------------------------------------------------------
+def make_spiral_spheric(props, context):
+ #INPUT: turns, steps[per turn], radius
+ #use spherical Coordinates
+ step_phi = (2*pi) / props.steps #Step of angle in radians for one turn
+ steps = props.steps * props.turns #props.steps[per turn] -> steps[for the whole spiral]
+
+ max_phi = 2*pi*props.turns #max angle in radian
+ step_phi = max_phi/steps #angle in radians between two vertices
+ if props.spiral_direction == 1: #flip direction
+ step_phi *= -1
+ max_phi *= -1
+ step_theta = pi / (steps-1) #theta increase in one step (pi == 180 deg)
+
+ verts = []
+ verts.extend([0,0,-props.radius,1]) #First vertex at south pole
+
+ #cur_rad = props.radius = CONST
+
+ cur_phi = 0
+ cur_theta = -pi/2 #Beginning at south pole
+
+ while abs(cur_phi) <= abs(max_phi):
+ #Coordinate Transformation sphere->rect
+ px = props.radius * cos(cur_theta) * cos(cur_phi)
+ py = props.radius * cos(cur_theta) * sin(cur_phi)
+ pz = props.radius * sin(cur_theta)
+
+ verts.extend([px,py,pz,1])
+ cur_theta += step_theta
+ cur_phi += step_phi
+
+ return verts
+
+#make torus spiral
+#-----------------------------------------------------------------------------
+
+def make_spiral_torus(props, context):
+ #INPUT: turns, steps, inner_radius, curves_number, mul_height, dif_inner_radius, cycles
+ max_phi = 2*pi*props.turns * props.cycles #max angle in radian
+ step_phi = 2*pi/props.steps #Step of angle in radians between two vertices
+ if props.spiral_direction == 1: #flip direction
+ step_phi *= -1
+ max_phi *= -1
+ step_theta = (2*pi / props.turns) / props.steps
+ step_rad = props.dif_radius / (props.steps * props.turns)
+ step_inner_rad = props.dif_inner_radius / props.steps
+ step_z = props.dif_z / (props.steps * props.turns)
+
+ verts = []
+
+ cur_phi = 0 #Inner Ring Radius Angle
+ cur_theta = 0 #Ring Radius Angle
+ cur_rad = props.radius
+ cur_inner_rad = props.inner_radius
+ cur_z = 0
+ n_cycle = 0
+
+ while abs(cur_phi) <= abs(max_phi):
+ #Torus Coordinates -> Rect
+ px = ( cur_rad + cur_inner_rad * cos(cur_phi) ) * cos(props.curves_number * cur_theta)
+ py = ( cur_rad + cur_inner_rad * cos(cur_phi) ) * sin(props.curves_number * cur_theta)
+ pz = cur_inner_rad * sin(cur_phi) + cur_z
+
+ verts.extend([px,py,pz,1])
+
+ if props.touch == True and cur_phi >= n_cycle * 2*pi:
+ step_z = ( (n_cycle+1) * props.dif_inner_radius + props.inner_radius ) * 2 / (props.steps * props.turns)
+ n_cycle += 1
+
+ cur_theta += step_theta
+ cur_phi += step_phi
+ cur_rad += step_rad
+ cur_inner_rad += step_inner_rad
+ cur_z += step_z
+
+ return verts
+#-----------------------------------------------------------------------------
+
+def draw_curve(props, context):
+ if props.spiral_type == 1:
+ verts = make_spiral(props, context)
+ if props.spiral_type == 2:
+ verts = make_spiral(props, context)
+ if props.spiral_type == 3:
+ verts = make_spiral_spheric(props, context)
+ if props.spiral_type == 4:
+ verts = make_spiral_torus(props, context)
+
+ curve_data = bpy.data.curves.new(name='Spiral', type='CURVE')
+ curve_data.dimensions = '3D'
+
+ if props.curve_type == 0:
+ spline = curve_data.splines.new(type='POLY')
+ elif props.curve_type == 1:
+ spline = curve_data.splines.new(type='NURBS')
+
+ spline.points.add( len(verts)*0.25-1 ) #Add only one quarter of points as elements in verts, because verts looks like: "x,y,z,?,x,y,z,?,x,..."
+ spline.points.foreach_set('co', verts)
+# new_obj = object_data_add(bpy.context, curve_data)
+ new_obj = object_data_add(context, curve_data)
+
+class spirals(bpy.types.Operator):
+ bl_idname = "curve.spirals"
+ bl_label = "Spirals"
+ bl_options = {'REGISTER','UNDO', 'PRESET'} #UNDO needed for operator redo and therefore also to let the addobjecthelp appear!!!
+ bl_description = "adds different types of spirals"
+
+ spiral_type = IntProperty(default=1, min=1, max=4, description="1:archemedian, 2:logarithmic, 3:spheric, 4:torus")
+ curve_type = IntProperty(default=0, min=0, max=1, description="0:Poly, 1:Nurb")
+ spiral_direction = IntProperty(default=0, min=0, max=1, description="0:counter-clockwise, 1:clockwise")
+
+ turns = IntProperty(default=1, min=1, max=1000, description="Length of Spiral in 360 deg")
+ steps = IntProperty(default=24, min=2, max=1000, description="Number of Vertices per turn")
+
+
+ radius = FloatProperty(default=1.00, min=0.00, max=100.00, description="radius for first turn")
+ dif_z = FloatProperty(default=0, min=-10.00, max=100.00, description="increase in z axis per turn") #needed for 1 and 2 spiral_type
+ #ARCHMEDEAN variables
+ dif_radius = FloatProperty(default=0.00, min=-50.00, max=50.00, description="radius increment in each turn") #step between turns(one turn equals 360 deg)
+ #LOG variables
+ B_force = FloatProperty(default=1.00, min=0.00, max=30.00, description="factor of exponent")
+ #TORUS variables
+ inner_radius = FloatProperty(default=0.20, min=0.00, max=100, description="Inner Radius of Torus")
+ dif_inner_radius = FloatProperty(default=0, min=-10, max=100, description="Increase of inner Radius per Cycle")
+ dif_radius = FloatProperty(default=0, min=-10, max=100, description="Increase of Torus Radius per Cycle")
+ cycles = FloatProperty(default=1, min=0.00, max=1000, description="Number of Cycles")
+ curves_number = IntProperty(default=1, min=1, max=400, description="Number of curves of spiral")
+ touch = BoolProperty(default=False, description="No empty spaces between cycles")
+
+ def draw(self, context): #Function used by Blender to draw the menu
+ layout = self.layout
+ layout.prop(self, 'spiral_type', text="Spiral Type")
+ layout.prop(self, 'curve_type', text="Curve Type")
+ layout.prop(self, 'spiral_direction', text="Spiral Direction")
+
+ layout.label(text="Spiral Parameters:")
+ layout.prop(self, 'turns', text = "Turns")
+ layout.prop(self, 'steps', text = "Steps")
+
+ box = layout.box()
+ if self.spiral_type == 1:
+ box.prop(self, 'dif_radius', text = "Radius Growth")
+ box.prop(self, 'radius', text = "Radius")
+ box.prop(self, 'dif_z', text = "Height")
+ if self.spiral_type == 2:
+ box.prop(self, 'radius', text = "Radius")
+ box.prop(self, 'B_force', text = "Expansion Force")
+ box.prop(self, 'dif_z', text = "Height")
+ if self.spiral_type == 3:
+ box.prop(self, 'radius', text = "Radius")
+ if self.spiral_type == 4:
+ box.prop(self, 'cycles', text = "Number of Cycles")
+ if self.dif_inner_radius == 0 and self.dif_z == 0:
+ self.cycles = 1
+ box.prop(self, 'radius', text = "Radius")
+ if self.dif_z == 0:
+ box.prop(self, 'dif_z', text = "Height per Cycle")
+ else:
+ box2 = box.box()
+ box2.prop(self, 'dif_z', text = "Height per Cycle")
+ box2.prop(self, 'touch', text = "Make Snail")
+ box.prop(self, 'inner_radius', text = "Inner Radius")
+ box.prop(self, 'curves_number', text = "Curves Number")
+ box.prop(self, 'dif_radius', text = "Increase of Torus Radius")
+ box.prop(self, 'dif_inner_radius', text = "Increase of Inner Radius")
+
+ @classmethod
+ def poll(cls, context): #method called by blender to check if the operator can be run
+ return context.scene != None
+ def execute(self, context):
+ time_start = time.time()
+ draw_curve(self, context)
+ print("Drawing Spiral Finished: %.4f sec", time.time() - time_start)
+ return {'FINISHED'}
diff --git a/add_curve_extra_objects/add_curve_torus_knots.py b/add_curve_extra_objects/add_curve_torus_knots.py
new file mode 100644
index 00000000..22fe48fe
--- /dev/null
+++ b/add_curve_extra_objects/add_curve_torus_knots.py
@@ -0,0 +1,223 @@
+# ##### 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": "Torus Knots",
+ "author": "testscreenings",
+ "version": (0, 1),
+ "blender": (2, 59, 0),
+ "location": "View3D > Add > Curve",
+ "description": "Adds many types of (torus) knots",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
+ "Scripts/Curve/Torus_Knot",
+ "category": "Add Curve"}
+'''
+
+##------------------------------------------------------------
+#### import modules
+import bpy
+from bpy.props import *
+from math import sin, cos, pi
+from bpy_extras.object_utils import AddObjectHelper, object_data_add
+
+
+########################################################################
+####################### Knot Definitions ###############################
+########################################################################
+def Torus_Knot(self):
+ p = self.torus_p
+ q = self.torus_q
+ w = self.torus_w
+ res = self.torus_res
+ h = self.torus_h
+ u = self.torus_u
+ v = self.torus_v
+ rounds = self.torus_rounds
+
+ newPoints = []
+ angle = 2*rounds
+ step = angle/(res-1)
+ scale = h
+ height = w
+
+ for i in range(res-1):
+ t = ( i*step*pi)
+
+ x = (2 * scale + cos((q*t)/p*v)) * cos(t * u)
+ y = (2 * scale + cos((q*t)/p*v)) * sin(t * u)
+ z = sin(q*t/p) * height
+
+ newPoints.extend([x,y,z,1])
+
+ return newPoints
+
+
+##------------------------------------------------------------
+# Main Function
+def create_torus_knot(self, context):
+ verts = Torus_Knot(self)
+
+ curve_data = bpy.data.curves.new(name='Torus Knot', type='CURVE')
+ spline = curve_data.splines.new(type='NURBS')
+ spline.points.add(int(len(verts)*0.25 - 1))
+ spline.points.foreach_set('co', verts)
+ spline.use_endpoint_u = True
+ spline.use_cyclic_u = True
+ spline.order_u = 4
+ curve_data.dimensions = '3D'
+
+ if self.geo_surf:
+ curve_data.bevel_depth = self.geo_bDepth
+ curve_data.bevel_resolution = self.geo_bRes
+ curve_data.fill_mode = 'FULL'
+ curve_data.extrude = self.geo_extrude
+ #curve_data.offset = self.geo_width # removed, somehow screws things up all of a sudden
+ curve_data.resolution_u = self.geo_res
+
+ new_obj = object_data_add(context, curve_data, operator=self)
+
+
+class torus_knot_plus(bpy.types.Operator, AddObjectHelper):
+ """"""
+ bl_idname = "curve.torus_knot_plus"
+ bl_label = "Torus Knot +"
+ bl_options = {'REGISTER', 'UNDO', 'PRESET'}
+ bl_description = "adds many types of knots"
+
+ #### general options
+ options_plus = BoolProperty(name="plus options",
+ default=False,
+ description="Show more options (the plus part)")
+
+ #### GEO Options
+ geo_surf = BoolProperty(name="Surface",
+ default=True)
+ geo_bDepth = FloatProperty(name="bevel",
+ default=0.08,
+ min=0, soft_min=0)
+ geo_bRes = IntProperty(name="bevel res",
+ default=2,
+ min=0, soft_min=0,
+ max=4, soft_max=4)
+ geo_extrude = FloatProperty(name="extrude",
+ default=0.0,
+ min=0, soft_min=0)
+ geo_res = IntProperty(name="resolution",
+ default=12,
+ min=1, soft_min=1)
+
+
+ #### Parameters
+ torus_res = IntProperty(name="Resoulution",
+ default=100,
+ min=3, soft_min=3,
+ description='Resolution, Number of controlverticies')
+ torus_p = IntProperty(name="p",
+ default=2,
+ min=1, soft_min=1,
+ #max=1, soft_max=1,
+ description="p")
+ torus_q = IntProperty(name="q",
+ default=3,
+ min=1, soft_min=1,
+ #max=1, soft_max=1,
+ description="q")
+ torus_w = FloatProperty(name="Height",
+ default=1,
+ #min=0, soft_min=0,
+ #max=1, soft_max=1,
+ description="Height in Z")
+ torus_h = FloatProperty(name="Scale",
+ default=1,
+ #min=0, soft_min=0,
+ #max=1, soft_max=1,
+ description="Scale, in XY")
+ torus_u = IntProperty(name="u",
+ default=1,
+ min=1, soft_min=1,
+ #max=1, soft_max=1,
+ description="u")
+ torus_v = IntProperty(name="v",
+ default=1,
+ min=1, soft_min=1,
+ #max=1, soft_max=1,
+ description="v")
+ torus_rounds = IntProperty(name="Rounds",
+ default=2,
+ min=1, soft_min=1,
+ #max=1, soft_max=1,
+ description="Rounds")
+
+ ##### DRAW #####
+ def draw(self, context):
+ layout = self.layout
+
+ # general options
+ layout.label(text="Torus Knot Parameters:")
+
+ # Parameters
+ box = layout.box()
+ box.prop(self, 'torus_res')
+ box.prop(self, 'torus_w')
+ box.prop(self, 'torus_h')
+ box.prop(self, 'torus_p')
+ box.prop(self, 'torus_q')
+ box.prop(self, 'options_plus')
+ if self.options_plus:
+ box.prop(self, 'torus_u')
+ box.prop(self, 'torus_v')
+ box.prop(self, 'torus_rounds')
+
+ # surface Options
+ col = layout.column()
+ col.label(text="Geometry Options:")
+ box = layout.box()
+ box.prop(self, 'geo_surf')
+ if self.geo_surf:
+ box.prop(self, 'geo_bDepth')
+ box.prop(self, 'geo_bRes')
+ box.prop(self, 'geo_extrude')
+ box.prop(self, 'geo_res')
+
+ col = layout.column()
+ col.prop(self, 'location')
+ col.prop(self, 'rotation')
+
+ ##### POLL #####
+ @classmethod
+ def poll(cls, context):
+ return context.scene != None
+
+ ##### EXECUTE #####
+ def execute(self, context):
+ # turn off undo
+ undo = bpy.context.user_preferences.edit.use_global_undo
+ bpy.context.user_preferences.edit.use_global_undo = False
+
+ if not self.options_plus:
+ self.torus_rounds = self.torus_p
+
+ #recoded for add_utils
+ create_torus_knot(self, context)
+
+ # restore pre operator undo state
+ bpy.context.user_preferences.edit.use_global_undo = undo
+
+ return {'FINISHED'}