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:
authormeta-androcto <meta.androcto1@gmail.com>2017-03-17 06:46:03 +0300
committermeta-androcto <meta.androcto1@gmail.com>2017-03-17 06:46:03 +0300
commitfcf5f2842a836006aa5fb4a0fe037a3ff49fff97 (patch)
tree336dfe59ca9304b3ab109602562fc246706d6f82 /add_curve_extra_objects
parentf14b4f40c13285bede9fa3b07f79e45fa4952910 (diff)
Update add curve extra objects Re: T50943
Diffstat (limited to 'add_curve_extra_objects')
-rw-r--r--add_curve_extra_objects/__init__.py51
-rw-r--r--add_curve_extra_objects/add_curve_aceous_galore.py347
-rw-r--r--add_curve_extra_objects/add_curve_braid.py88
-rw-r--r--add_curve_extra_objects/add_curve_celtic_links.py249
-rw-r--r--add_curve_extra_objects/add_curve_curly.py386
-rw-r--r--add_curve_extra_objects/add_curve_simple.py1612
-rw-r--r--add_curve_extra_objects/beveltaper_curve.py259
-rw-r--r--add_curve_extra_objects/bpybraid.py84
-rw-r--r--add_curve_extra_objects/braid.py60
9 files changed, 3012 insertions, 124 deletions
diff --git a/add_curve_extra_objects/__init__.py b/add_curve_extra_objects/__init__.py
index 65a3a411..ffa04938 100644
--- a/add_curve_extra_objects/__init__.py
+++ b/add_curve_extra_objects/__init__.py
@@ -17,6 +17,7 @@
# ##### END GPL LICENSE BLOCK #####
# Contributed to by
# testscreenings, Alejandro Omar Chocano Vasquez, Jimmy Hazevoet, meta-androcto #
+# Cmomoney, Jared Forsyth, Adam Newgas, Spivak Vladimir
bl_info = {
"name": "Extra Objects",
@@ -37,12 +38,22 @@ if "bpy" in locals():
importlib.reload(add_curve_spirals)
importlib.reload(add_curve_torus_knots)
importlib.reload(add_surface_plane_cone)
+ importlib.reload(add_curve_curly)
+ importlib.reload(beveltaper_curve)
+ importlib.reload(add_curve_celtic_links)
+ importlib.reload(add_curve_braid)
+ importlib.reload(add_curve_simple)
else:
from . import add_curve_aceous_galore
from . import add_curve_spirals
from . import add_curve_torus_knots
from . import add_surface_plane_cone
+ from . import add_curve_curly
+ from . import beveltaper_curve
+ from . import add_curve_celtic_links
+ from . import add_curve_braid
+ from . import add_curve_simple
import bpy
from bpy.types import Menu, AddonPreferences
@@ -131,24 +142,22 @@ class CurveExtraObjectsAddonPreferences(AddonPreferences):
else:
layout.prop(self, "update_spiral_presets")
-
-# TODO check if this is even used.
-class INFO_MT_curve_extras_add(Menu):
+class INFO_MT_curve_knots_add1(bpy.types.Menu):
# Define the "Extras" menu
- bl_idname = "curve_extra_objects_add"
- bl_label = "Extra Objects"
+ bl_idname = "curve_knots_add"
+ bl_label = "Plants"
def draw(self, context):
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
- layout.operator_menu_enum("mesh.curveaceous_galore",
- "ProfileType",
- )
- layout.operator_menu_enum("curve.spirals",
- "spiral_type",
- icon='FORCE_VORTEX')
layout.operator("curve.torus_knot_plus",
- text="Torus Knot Plus")
+ text="Torus Knot Plus")
+ layout.operator("curve.celtic_links",
+ text="Celtic Links")
+ layout.operator("mesh.add_braid",
+ text="Braid Knot")
+
+
# Define "Extras" menus
def menu_func(self, context):
@@ -156,14 +165,19 @@ def menu_func(self, context):
# fix in D2142 will allow to work in EDIT_CURVE
return None
layout = self.layout
- layout.separator()
+
layout.operator_menu_enum("mesh.curveaceous_galore",
"ProfileType",
- )
+ icon='CURVE_DATA')
layout.operator_menu_enum("curve.spirals",
"spiral_type",
- icon='FORCE_VORTEX')
- layout.operator("curve.torus_knot_plus", text="Torus Knot Plus")
+ icon='CURVE_DATA')
+ layout.separator()
+ layout.menu("curve_knots_add", text="Knots", icon='CURVE_DATA')
+ layout.separator()
+ layout.operator("curve.curlycurve", text="Curly Curve", icon='CURVE_DATA')
+ layout.menu("OBJECT_MT_bevel_taper_curve_menu", text="Bevel/Taper", icon='CURVE_DATA')
+
def menu_surface(self, context):
layout = self.layout
@@ -177,6 +191,7 @@ def menu_surface(self, context):
self.layout.operator("object.add_surface_plane", text="Plane", icon="MOD_CURVE")
def register():
+ add_curve_simple.register()
bpy.utils.register_module(__name__)
# Add "Extras" menu to the "Add Curve" menu
@@ -185,12 +200,14 @@ def register():
bpy.types.INFO_MT_surface_add.append(menu_surface)
def unregister():
- bpy.utils.unregister_module(__name__)
+ add_curve_simple.unregister()
# Remove "Extras" menu from the "Add Curve" menu.
bpy.types.INFO_MT_curve_add.remove(menu_func)
# Remove "Extras" menu from the "Add Surface" menu.
bpy.types.INFO_MT_surface_add.remove(menu_surface)
+ bpy.utils.unregister_module(__name__)
+
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
index 259660fb..6a7ac654 100644
--- a/add_curve_extra_objects/add_curve_aceous_galore.py
+++ b/add_curve_extra_objects/add_curve_aceous_galore.py
@@ -20,7 +20,7 @@ bl_info = {
"name": "Curveaceous Galore!",
"author": "Jimmy Hazevoet, testscreenings",
"version": (0, 2),
- "blender": (2, 59, 0),
+ "blender": (2, 59),
"location": "View3D > Add > Curve",
"description": "Adds many different types of Curves",
"warning": "", # used for warning icon and text in addons panel
@@ -193,61 +193,81 @@ def ProfileCurve(type=0, a=0.25, b=0.25):
return newpoints
# ------------------------------------------------------------
-# 2DCurve: Miscellaneous.: Diamond, Arrow1, Arrow2, Square, ....
-def MiscCurve(type=1, a=1.0, b=0.5, c=1.0):
+# 2DCurve: Arrows
+def ArrowCurve(type=1, a=1.0, b=0.5):
"""
- MiscCurve( type=1, a=1.0, b=0.5, c=1.0 )
+ ArrowCurve( type=1, a=1.0, b=0.5, c=1.0 )
- Create miscellaneous curves
+ Create arrow curves
Parameters:
- type - select type, Diamond, Arrow1, Arrow2, Square
+ type - select type, Arrow1, Arrow2
(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:
+ if type == 0:
# 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:
+ a *= 0.5
+ b *= 0.5
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:
+ elif type == 1:
+ # Arrow2:
+ newpoints = [[-a, b, 0.0], [a, 0.0, 0.0], [-a, -b, 0.0], [0.0, 0.0, 0.0]]
+ else:
+ # diamond:
+ newpoints = [[0.0, b, 0.0], [a, 0.0, 0.0], [0.0, -b, 0.0], [-a, 0.0, 0.0]]
+ return newpoints
+
+# ------------------------------------------------------------
+# 2DCurve: Square / Rectangle
+def RectCurve(type=1, a=1.0, b=0.5, c=1.0):
+ """
+ RectCurve( type=1, a=1.0, b=0.5, c=1.0 )
+
+ Create square / rectangle curves
+
+ Parameters:
+ type - select type, Square, Rounded square 1, Rounded square 2
+ (type=int)
+ a - a scaling parameter
+ (type=float)
+ b - b scaling parameter
+ (type=float)
+ c - c 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:
+ # Rounded Rectangle:
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:
+ elif type == 2:
# Rounded Rectangle II:
newpoints = []
- x = a / 2
- y = b / 2
- r = c / 2
-
+ x = a
+ y = b
+ r = c
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])
@@ -262,9 +282,8 @@ def MiscCurve(type=1, a=1.0, b=0.5, c=1.0):
newpoints.append([x, y, 0])
newpoints.append([x, -y, 0])
newpoints.append([-x, -y, 0])
-
else:
- # Square:
+ # Rectangle:
newpoints = [[-a, b, 0.0], [a, b, 0.0], [a, -b, 0.0], [-a, -b, 0.0]]
return newpoints
@@ -567,47 +586,116 @@ def HelixCurve(number=100, height=2.0, startangle=0.0, endangle=360.0, width=1.0
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):
+#------------------------------------------------------------
+# Cycloid curve
+
+def CycloidCurve(number=100, type=0, R=4.0, r=1.0, d=1.0):
"""
- CycloidCurve( number=24, length=2.0, type=0, a=1.0, b=1.0, startangle=0.0, endangle=360.0 )
+ CycloidCurve( number=100, type=0, a=4.0, b=1.0 )
- Create a Cycloid, Epicycloid or Hypocycloid curve
+ Create a Cycloid, Hypotrochoid / Hypocycloid or Epitrochoid / Epycycloid type of curve
Parameters:
number - the number of points
(type=int)
- length - length of curve
- (type=float)
- type - types: Cycloid, Epicycloid, Hypocycloid
+ type - types: Cycloid, Hypocycloid, Epicycloid
(type=int)
+ R = Radius a scaling parameter
+ (type=float)
+ r = Radius b scaling parameter
+ (type=float)
+ d = Distance 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)
"""
+ a = R
+ b = r
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
+ step = (2.0/(number-1))
i = 0
- if type == 0: # Epitrochoid
+ if type == 1:
+ # Hypotrochoid / Hypocycloid
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
+ t = i*step
+ 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
+ newpoints.append([x,y,z])
+ i+=1
+ elif type == 2:
+ # Epitrochoid / Epycycloid
+ while i < number:
+ t = i*step
+ 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
+ newpoints.append([x,y,z])
+ i+=1
+ else:
+ # Cycloid
+ while i < number:
+ t = (i*step*pi)*a
+ x = (t-sin(t)*b)
+ y = (1-cos(t)*b)
+ z = 0
+ newpoints.append([x,y,z])
+ i+=1
+ return newpoints
+
+#------------------------------------------------------------
+# 3D Noise curve
+def NoiseCurve(number=100, length=2.0, scale=1.0, octaves=6, basis=1, seed=0, type=0):
+ """
+ NoiseCurve( number=100, length=2.0, scale=1.0, octaves=2, basis=1, seed=0, type=1 )
+ Create noise curve
+
+ Parameters:
+ number - number of points
+ (type=int)
+ length - curve length
+ (type=float)
+ scale - noise scale
+ (type=float)
+ basis - noise basis
+ (type=int)
+ seed - noise random seed
+ (type=int)
+ type - noise curve type
+ (type=int)
+ Returns:
+ a list with lists of x,y,z coordinates for curve points, [[x,y,z],[x,y,z],...n]
+ (type=list)
+ """
+
+ rand = randnum(-100,100,seed)
+ newpoints = []
+ step = (length/number)
+ i = 0
+ if type == 1:
+ # noise knot
+ while i < number:
+ t = ((i*step)+rand)
+ v = vTurbNoise(t,t,t, scale, 1.0, octaves, 0, basis, seed)
+ newpoints.append([v[0], v[1], v[2]])
+ i+=1
else:
- newpoints = [[-1, -1, 0], [-1, 1, 0], [1, 1, 0], [1, -1, 0]]
+ # noise linear
+ while i < number:
+ t = i*step
+ tt = t+rand
+ v = vTurbNoise(t,t,t, scale, 1.0, octaves, 0, basis, seed)
+ x = t
+ y = v[1]
+ z = v[2]
+ newpoints.append([x,y,z])
+ i+=1
return newpoints
+
# ------------------------------------------------------------
# calculates the matrix for the new object
# depending on user pref
@@ -712,8 +800,12 @@ def main(context, self, align_matrix):
verts = ProfileCurve(self.ProfileCurveType,
self.ProfileCurvevar1,
self.ProfileCurvevar2)
- if proType == 'Miscellaneous':
- verts = MiscCurve(self.MiscCurveType,
+ if proType == 'Arrow':
+ verts = ArrowCurve(self.MiscCurveType,
+ self.MiscCurvevar1,
+ self.MiscCurvevar2)
+ if proType == 'Rectangle':
+ verts = RectCurve(self.MiscCurveType,
self.MiscCurvevar1,
self.MiscCurvevar2,
self.MiscCurvevar3)
@@ -759,12 +851,18 @@ def main(context, self, align_matrix):
self.helix_b)
if proType == 'Cycloid':
verts = CycloidCurve(self.cycloPoints,
- self.cyclo_d,
self.cycloType,
self.cyclo_a,
self.cyclo_b,
- self.cycloStart,
- self.cycloEnd)
+ self.cyclo_d)
+ if proType == 'Noise':
+ verts = NoiseCurve(self.noisePoints,
+ self.noiseLength,
+ self.noiseScale,
+ self.noiseOctaves,
+ self.noiseBasis,
+ self.noiseSeed,
+ self.noiseType)
# turn verts into array
vertArray = vertsToPoints(verts, splineType)
@@ -777,7 +875,7 @@ def main(context, self, align_matrix):
class Curveaceous_galore(Operator):
"""Add many types of curves"""
bl_idname = "mesh.curveaceous_galore"
- bl_label = "Curve Profiles"
+ bl_label = "2D Profiles"
bl_options = {'REGISTER', 'UNDO', 'PRESET'}
# align_matrix for the invoke
@@ -786,7 +884,8 @@ class Curveaceous_galore(Operator):
# general properties
ProfileTypes = [
('Profile', 'Profile', 'Profile'),
- ('Miscellaneous', 'Miscellaneous', 'Miscellaneous'),
+ ('Arrow', 'Arrow', 'Arrow'),
+ ('Rectangle', 'Rectangle', 'Rectangle'),
('Flower', 'Flower', 'Flower'),
('Star', 'Star', 'Star'),
('Arc', 'Arc', 'Arc'),
@@ -794,7 +893,8 @@ class Curveaceous_galore(Operator):
('Nsided', 'Nsided', 'Nsided'),
('Splat', 'Splat', 'Splat'),
('Cycloid', 'Cycloid', 'Cycloid'),
- ('Helix', 'Helix (3D)', 'Helix')]
+ ('Helix', 'Helix (3D)', 'Helix'),
+ ('Noise', 'Noise (3D)', 'Noise')]
ProfileType = EnumProperty(name="Type",
description="Form of Curve to create",
items=ProfileTypes)
@@ -844,22 +944,22 @@ class Curveaceous_galore(Operator):
default=0.25,
description="var2 of ProfileCurve")
- # MiscCurve properties
+ # Arrow, Rectangle, MiscCurve properties
MiscCurveType = IntProperty(name="Type",
- min=1, soft_min=1,
- max=6, soft_max=6,
- default=1,
- description="Type of MiscCurve")
+ min=0, soft_min=0,
+ max=3, soft_max=3,
+ default=0,
+ description="Type of Curve")
MiscCurvevar1 = FloatProperty(name="var_1",
default=1.0,
- description="var1 of MiscCurve")
+ description="var1 of Curve")
MiscCurvevar2 = FloatProperty(name="var_2",
default=0.5,
- description="var2 of MiscCurve")
+ description="var2 of Curve")
MiscCurvevar3 = FloatProperty(name="var_3",
default=0.1,
min=0, soft_min=0,
- description="var3 of MiscCurve")
+ description="var3 of Curve")
# Common properties
innerRadius = FloatProperty(name="Inner radius",
@@ -977,28 +1077,55 @@ class Curveaceous_galore(Operator):
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,
+ max=2, soft_max=2,
+ description="Type: Cycloid , Hypocycloid / Hypotrochoid , Epicycloid / Epitrochoid")
+ cyclo_a = FloatProperty(name="R",
+ default=4.0,
min=0.01, soft_min=0.01,
- description="Cycloid var1")
- cyclo_b = FloatProperty(name="var_2",
- default=0.5,
+ description="Cycloid: R radius a")
+ cyclo_b = FloatProperty(name="r",
+ default=1.0,
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")
+ description="Cycloid: r radius b")
+ cyclo_d = FloatProperty(name="d",
+ default=1.0,
+ description="Cycloid: d distance")
+
+ # Noise properties
+ noisePoints = IntProperty(name="Resolution",
+ default=100,
+ min=3, soft_min=3,
+ description="Resolution")
+ noiseLength = FloatProperty(name="Length",
+ default=2.0,
+ min=0.01, soft_min=0.01,
+ description="Curve Length")
+ noiseScale = FloatProperty(name="Noise scale",
+ default=1.0,
+ min=0.0001, soft_min=0.0001,
+ description="Noise scale")
+ noiseOctaves = IntProperty(name="Octaves",
+ default=2,
+ min=0, soft_min=0,
+ max=16, soft_max=16,
+ description="Basis")
+ noiseBasis = IntProperty(name="Basis",
+ default=0,
+ min=0, soft_min=0,
+ max=14, soft_max=14,
+ description="Basis")
+ noiseSeed = IntProperty(name="Seed",
+ default=1,
+ min=0, soft_min=0,
+ description="Random Seed")
+ noiseType = IntProperty(name="Type",
+ default=0,
+ min=0, soft_min=0,
+ max=1, soft_max=1,
+ description="Noise curve type: Linear or Knot")
##### DRAW #####
def draw(self, context):
@@ -1016,12 +1143,17 @@ class Curveaceous_galore(Operator):
box.prop(self, 'ProfileCurvevar1')
box.prop(self, 'ProfileCurvevar2')
- elif self.ProfileType == 'Miscellaneous':
+ elif self.ProfileType == 'Arrow':
+ box.prop(self, 'MiscCurveType')
+ box.prop(self, 'MiscCurvevar1', text='Height')
+ box.prop(self, 'MiscCurvevar2', text='Width')
+
+ elif self.ProfileType == 'Rectangle':
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')
+ if self.MiscCurveType == 2:
+ box.prop(self, 'MiscCurvevar3', text='Corners')
elif self.ProfileType == 'Flower':
box.prop(self, 'petals')
@@ -1037,10 +1169,10 @@ class Curveaceous_galore(Operator):
elif self.ProfileType == 'Arc':
box.prop(self, 'arcSides')
- box.prop(self, 'arcType') # has only one Type?
+ box.prop(self, 'arcType')
box.prop(self, 'startAngle')
box.prop(self, 'endAngle')
- box.prop(self, 'innerRadius') # doesn't seem to do anything
+ box.prop(self, 'innerRadius')
box.prop(self, 'outerRadius')
elif self.ProfileType == 'Cogwheel':
@@ -1052,7 +1184,7 @@ class Curveaceous_galore(Operator):
elif self.ProfileType == 'Nsided':
box.prop(self, 'Nsides')
- box.prop(self, 'outerRadius', text='Radius')
+ box.prop(self, 'outerRadius')
elif self.ProfileType == 'Splat':
box.prop(self, 'splatSides')
@@ -1072,34 +1204,30 @@ class Curveaceous_galore(Operator):
elif self.ProfileType == '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, 'cycloType')
box.prop(self, 'cyclo_a')
box.prop(self, 'cyclo_b')
box.prop(self, 'cyclo_d')
+ elif self.ProfileType == 'Noise':
+ box.prop(self, 'noisePoints')
+ box.prop(self, 'noiseType')
+ box.prop(self, 'noiseLength')
+ box.prop(self, 'noiseScale')
+ box.prop(self, 'noiseOctaves')
+ box.prop(self, 'noiseBasis')
+ box.prop(self, 'noiseSeed')
+
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
@@ -1113,13 +1241,18 @@ class Curveaceous_galore(Operator):
context.user_preferences.edit.use_global_undo = False
# deal with 2D - 3D curve differences
- if self.ProfileType in ['Helix', 'Cycloid']:
+ if self.ProfileType in ['Helix', 'Cycloid', 'Noise']:
self.shape = '3D'
- # else:
- # self.shape = '2D' # someone decide if we want this
+ else:
+ self.shape = '2D'
- if self.ProfileType in ['Helix']:
+ if self.ProfileType in ['Helix','Noise', 'Cycloid']:
self.use_cyclic_u = False
+ if self.ProfileType in ['Cycloid']:
+ if self.cycloType == 0:
+ self.use_cyclic_u = False
+ else:
+ self.use_cyclic_u = True
else:
self.use_cyclic_u = True
diff --git a/add_curve_extra_objects/add_curve_braid.py b/add_curve_extra_objects/add_curve_braid.py
new file mode 100644
index 00000000..e31033a2
--- /dev/null
+++ b/add_curve_extra_objects/add_curve_braid.py
@@ -0,0 +1,88 @@
+
+import bpy
+from bpy.props import (FloatProperty,
+ FloatVectorProperty,
+ IntProperty,
+ BoolProperty,
+ StringProperty)
+
+from .bpybraid import awesome_braid, defaultCircle
+'''
+bl_info = {
+ "name": "New Braid",
+ "author": "Jared Forsyth <github.com/jaredly>",
+ "version": (1, 0),
+ "blender": (2, 6, 0),
+ "location": "View3D > Add > Mesh > New Braid",
+ "description": "Adds a new Braid",
+ "warning": "",
+ "wiki_url": "",
+ "tracker_url": "",
+ "category": "Add Mesh"}
+'''
+from bpy.types import Operator
+
+
+class Braid(Operator):
+ '''Add a Braid'''
+ bl_idname = 'mesh.add_braid'
+ bl_label = 'New Braid'
+ bl_description = 'Create a new braid'
+ bl_options = {'REGISTER', 'UNDO', 'PRESET'}
+
+ strands = IntProperty(name='strands', min=2, max=100, default=3)
+ sides = IntProperty(name='sides', min=2, max=100, default=5)
+ radius = FloatProperty(name='radius', default=1)
+ thickness = FloatProperty(name='thickness', default=.3)
+ strandsize = FloatProperty(name='strandsize', default=.3, min=.01, max=10)
+ width = FloatProperty(name='width', default=.2)
+ resolution = IntProperty(name='resolution', min=1, default=2, max=100)
+ pointy = BoolProperty(name='pointy', default=False)
+
+ def execute(self, context):
+ circle = defaultCircle(self.strandsize)
+ context.scene.objects.link(circle)
+ braid = awesome_braid(self.strands, self.sides,
+ bevel=circle.name,
+ pointy=self.pointy,
+ radius=self.radius,
+ mr=self.thickness,
+ mz=self.width,
+ resolution=self.resolution)
+ base = context.scene.objects.link(braid)
+
+ for ob in context.scene.objects:
+ ob.select = False
+ base.select = True
+ context.scene.objects.active = braid
+ return {'FINISHED'}
+
+ def draw(self, context):
+ layout = self.layout
+
+ box = layout.box()
+ box.prop(self, 'strands')
+ box.prop(self, 'sides')
+ box.prop(self, 'radius')
+ box.prop(self, 'thickness')
+ box.prop(self, 'strandsize')
+ box.prop(self, 'width')
+ box.prop(self, 'resolution')
+ box.prop(self, 'pointy')
+
+
+def add_object_button(self, context):
+ self.layout.operator(Braid.bl_idname, text="Add Braid", icon='PLUGIN')
+
+
+def register():
+ bpy.utils.register_class(Braid)
+ bpy.types.INFO_MT_mesh_add.append(add_object_button)
+
+
+def unregister():
+ bpy.utils.unregister_class(Braid)
+ bpy.types.INFO_MT_mesh_add.remove(add_object_button)
+
+if __name__ == "__main__":
+ register()
diff --git a/add_curve_extra_objects/add_curve_celtic_links.py b/add_curve_extra_objects/add_curve_celtic_links.py
new file mode 100644
index 00000000..b1171e92
--- /dev/null
+++ b/add_curve_extra_objects/add_curve_celtic_links.py
@@ -0,0 +1,249 @@
+# Blender plugin for generating celtic knot curves from 3d meshes
+# See README for more information
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2013 Adam Newgas
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+bl_info = {
+ "name": "Celtic Knot",
+ "description": "",
+ "author": "Adam Newgas",
+ "version": (0, 1, 1),
+ "blender": (2, 74, 0),
+ "location": "View3D > Add > Curve",
+ "warning": "",
+ "wiki_url": "https://github.com/BorisTheBrave/celtic-knot/wiki",
+ "category": "Add Curve"}
+
+import bpy
+import bmesh
+from collections import defaultdict
+from mathutils import Vector
+from math import pi, sin, cos
+
+
+class CelticKnotOperator(bpy.types.Operator):
+ bl_idname = "curve.celtic_links"
+ bl_label = "Celtic Links"
+ bl_description = 'Select low poly Mesh Object to cover with Knitted Links'
+ bl_options = {'REGISTER', 'UNDO', 'PRESET'}
+
+ weave_up = bpy.props.FloatProperty(name="Weave Up",
+ description="Distance to shift curve upwards over knots",
+ subtype="DISTANCE",
+ unit="LENGTH")
+ weave_down = bpy.props.FloatProperty(name="Weave Down",
+ description="Distance to shift curve downward under knots",
+ subtype="DISTANCE",
+ unit="LENGTH")
+ handle_types = [("ALIGNED", "Aligned", "Points at a fixed crossing angle"),
+ ("AUTO", "Auto", "Automatic control points")]
+ handle_type = bpy.props.EnumProperty(items=handle_types,
+ name="Handle Type",
+ description="Controls what type the bezier control points use",
+ default="AUTO")
+ crossing_angle = bpy.props.FloatProperty(name="Crossing Angle",
+ description="Aligned only: the angle between curves in a knot",
+ default=pi / 4,
+ min=0, max=pi / 2,
+ subtype="ANGLE",
+ unit="ROTATION")
+ crossing_strength = bpy.props.FloatProperty(name="Crossing Strength",
+ description="Aligned only: strenth of bezier control points",
+ soft_min=0,
+ subtype="DISTANCE",
+ unit="LENGTH")
+
+ handle_type_map = {"AUTO": "AUTOMATIC", "ALIGNED": "ALIGNED"}
+ geo_bDepth = bpy.props.FloatProperty(
+ name="Bevel Depth",
+ default=0.04,
+ min=0, soft_min=0,
+ description="Bevel Depth",
+ )
+
+ @classmethod
+ def poll(cls, context):
+ ob = context.active_object
+ # return True
+ return ((ob is not None) and
+ (ob.mode == "OBJECT") and
+ (ob.type == "MESH") and
+ (context.mode == "OBJECT"))
+
+ def execute(self, context):
+ # Cache some values
+ s = sin(self.crossing_angle) * self.crossing_strength
+ c = cos(self.crossing_angle) * self.crossing_strength
+ handle_type = self.handle_type
+ weave_up = self.weave_up
+ weave_down = self.weave_down
+ # Create the new object
+ orig_obj = obj = context.active_object
+ curve = bpy.data.curves.new("Celtic", "CURVE")
+ curve.dimensions = "3D"
+ curve.twist_mode = "MINIMUM"
+ curve.fill_mode = "FULL"
+ curve.bevel_depth = 0.015
+ curve.extrude = 0.003
+ curve.bevel_resolution = 4
+ obj = obj.data
+ midpoints = []
+ # Compute all the midpoints of each edge
+ for e in obj.edges.values():
+ v1 = obj.vertices[e.vertices[0]]
+ v2 = obj.vertices[e.vertices[1]]
+ m = (v1.co + v2.co) / 2.0
+ midpoints.append(m)
+
+ bm = bmesh.new()
+ bm.from_mesh(obj)
+ # Stores which loops the curve has already passed through
+ loops_entered = defaultdict(lambda: False)
+ loops_exited = defaultdict(lambda: False)
+ # Loops on the boundary of a surface
+
+ def ignorable_loop(loop):
+ return len(loop.link_loops) == 0
+ # Starting at loop, build a curve one vertex at a time
+ # until we start where we came from
+ # Forward means that for any two edges the loop crosses
+ # sharing a face, it is passing through in clockwise order
+ # else anticlockwise
+
+ def make_loop(loop, forward):
+ current_spline = curve.splines.new("BEZIER")
+ current_spline.use_cyclic_u = True
+ first = True
+ # Data for the spline
+ # It's faster to store in an array and load into blender
+ # at once
+ cos = []
+ handle_lefts = []
+ handle_rights = []
+ while True:
+ if forward:
+ if loops_exited[loop]:
+ break
+ loops_exited[loop] = True
+ # Follow the face around, ignoring boundary edges
+ while True:
+ loop = loop.link_loop_next
+ if not ignorable_loop(loop):
+ break
+ assert loops_entered[loop] == False
+ loops_entered[loop] = True
+ v = loop.vert.index
+ prev_loop = loop
+ # Find next radial loop
+ assert loop.link_loops[0] != loop
+ loop = loop.link_loops[0]
+ forward = loop.vert.index == v
+ else:
+ if loops_entered[loop]:
+ break
+ loops_entered[loop] = True
+ # Follow the face around, ignoring boundary edges
+ while True:
+ v = loop.vert.index
+ loop = loop.link_loop_prev
+ if not ignorable_loop(loop):
+ break
+ assert loops_exited[loop] == False
+ loops_exited[loop] = True
+ prev_loop = loop
+ # Find next radial loop
+ assert loop.link_loops[-1] != loop
+ loop = loop.link_loops[-1]
+ forward = loop.vert.index == v
+ if not first:
+ current_spline.bezier_points.add()
+ first = False
+ midpoint = midpoints[loop.edge.index]
+ normal = loop.calc_normal() + prev_loop.calc_normal()
+ normal.normalize()
+ offset = weave_up if forward else weave_down
+ midpoint = midpoint + offset * normal
+ cos.extend(midpoint)
+ if handle_type != "AUTO":
+ tangent = loop.link_loop_next.vert.co - loop.vert.co
+ tangent.normalize()
+ binormal = normal.cross(tangent).normalized()
+ if not forward:
+ tangent *= -1
+ s_binormal = s * binormal
+ c_tangent = c * tangent
+ handle_left = midpoint - s_binormal - c_tangent
+ handle_right = midpoint + s_binormal + c_tangent
+ handle_lefts.extend(handle_left)
+ handle_rights.extend(handle_right)
+ points = current_spline.bezier_points
+ points.foreach_set("co", cos)
+ if handle_type != "AUTO":
+ points.foreach_set("handle_left", handle_lefts)
+ points.foreach_set("handle_right", handle_rights)
+
+ # Attempt to start a loop at each untouched loop in the entire mesh
+ for face in bm.faces:
+ for loop in face.loops:
+ if ignorable_loop(loop):
+ continue
+ if not loops_exited[loop]:
+ make_loop(loop, True)
+ if not loops_entered[loop]:
+ make_loop(loop, False)
+ # Create an object from the curve
+ from bpy_extras import object_utils
+ object_utils.object_data_add(context, curve, operator=None)
+ # Set the handle type (this is faster than setting it pointwise)
+ bpy.ops.object.editmode_toggle()
+ bpy.ops.curve.select_all(action="SELECT")
+ bpy.ops.curve.handle_type_set(type=self.handle_type_map[handle_type])
+ # Some blender versions lack the default
+ bpy.ops.curve.radius_set(radius=1.0)
+ bpy.ops.object.editmode_toggle()
+ # Restore active selection
+ curve_obj = context.active_object
+ context.scene.objects.active = orig_obj
+
+ # If thick, then give it a bevel_object and convert to mesh
+
+ return {'FINISHED'}
+
+
+def menu_func(self, context):
+ self.layout.operator(CelticKnotOperator.bl_idname,
+ text="Celtic Knot From Mesh",
+ icon='PLUGIN')
+
+
+def register():
+ bpy.utils.register_module(__name__)
+ bpy.types.INFO_MT_curve_add.append(menu_func)
+
+
+def unregister():
+ bpy.types.INFO_MT_curve_add.remove(menu_func)
+ bpy.utils.unregister_module(__name__)
+
+if __name__ == "__main__":
+ register()
diff --git a/add_curve_extra_objects/add_curve_curly.py b/add_curve_extra_objects/add_curve_curly.py
new file mode 100644
index 00000000..5201bf62
--- /dev/null
+++ b/add_curve_extra_objects/add_curve_curly.py
@@ -0,0 +1,386 @@
+bl_info = {
+ "name": "Curly Curves",
+ "author": "Cmomoney",
+ "version": (1, 17),
+ "blender": (2, 69, 0),
+ "location": "View3D > Add > Curve > Curly Curve",
+ "description": "Adds a new Curly Curve",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Curve/Curly_Curves",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?func=detail&aid=37299&group_id=153&atid=467",
+ "category": "Add Curve"}
+
+import bpy
+from bpy.types import Operator
+from bpy.props import *
+from bpy_extras.object_utils import AddObjectHelper, object_data_add
+from mathutils import Vector
+
+
+def add_type6(self, context):
+
+ scale_x = self.scale_x
+ scale_y = self.scale_y
+ verts = [[0.047131 * scale_x, 0.065832 * scale_y,
+ 0.0, 0.010396 * scale_x, -0.186771 * scale_y,
+ 0.0, 0.076107 * scale_x, 0.19414 * scale_y,
+ 0.0, 0.0 * scale_x, -1.0 * scale_y, 0.0],
+ [0.451396 * scale_x, -0.48376 * scale_y,
+ 0.0, 0.433623 * scale_x, -0.587557 * scale_y,
+ 0.0, 0.525837 * scale_x, -0.423363 * scale_y,
+ 0.0, 0.15115 * scale_x, -0.704345 * scale_y, 0.0]]
+ lhandles = [[(-0.067558 * scale_x, 0.078418 * scale_y, 0.0),
+ (0.168759 * scale_x, -0.154334 * scale_y, 0.0),
+ (-0.236823 * scale_x, 0.262436 * scale_y, 0.0),
+ (0.233116 * scale_x, -0.596115 * scale_y, 0.0)],
+ [(0.498001 * scale_x, -0.493434 * scale_y, 0.0),
+ (0.375618 * scale_x, -0.55465 * scale_y, 0.0),
+ (0.634373 * scale_x, -0.49873 * scale_y, 0.0),
+ (0.225277 * scale_x, -0.526814 * scale_y, 0.0)]]
+ rhandles = [[(0.161825 * scale_x, 0.053245 * scale_y, 0.0),
+ (-0.262003 * scale_x, -0.242566 * scale_y, 0.0),
+ (0.519691 * scale_x, 0.097329 * scale_y, 0.0),
+ (-0.233116 * scale_x, -1.403885 * scale_y, 0.0)],
+ [(0.404788 * scale_x, -0.474085 * scale_y, 0.0),
+ (0.533397 * scale_x, -0.644158 * scale_y, 0.0),
+ (0.371983 * scale_x, -0.316529 * scale_y, 0.0),
+ (0.077022 * scale_x, -0.881876 * scale_y, 0.0)]]
+ make_curve(self, context, verts, lhandles, rhandles)
+
+
+def add_type5(self, context):
+
+ scale_x = self.scale_x
+ scale_y = self.scale_y
+ verts = [[0.047131 * scale_x, 0.065832 * scale_y, 0.0, 0.010396 * scale_x, -0.186771 * scale_y,
+ 0.0, 0.076107 * scale_x, 0.19414 * scale_y, 0.0, 0.0 * scale_x, -1.0 * scale_y, 0.0],
+ [0.086336 * scale_x, -0.377611 * scale_y, 0.0, 0.022417 * scale_x, -0.461301 * scale_y, 0.0,
+ 0.079885 * scale_x, -0.281968 * scale_y, 0.0, 0.129212 * scale_x, -0.747702 * scale_y, 0.0]]
+ lhandles = [[(-0.067558 * scale_x, 0.078419 * scale_y, 0.0),
+ (0.168759 * scale_x, -0.154335 * scale_y, 0.0),
+ (-0.236823 * scale_x, 0.262436 * scale_y, 0.0),
+ (0.233116 * scale_x, -0.596115 * scale_y, 0.0)],
+ [(0.047518 * scale_x, -0.350065 * scale_y, 0.0),
+ (0.086012 * scale_x, -0.481379 * scale_y, 0.0),
+ (-0.049213 * scale_x, -0.253793 * scale_y, 0.0),
+ (0.208763 * scale_x, -0.572534 * scale_y, 0.0)]]
+ rhandles = [[(0.161825 * scale_x, 0.053245 * scale_y, 0.0),
+ (-0.262003 * scale_x, -0.242566 * scale_y, 0.0),
+ (0.519691 * scale_x, 0.097329 * scale_y, 0.0),
+ (-0.233116 * scale_x, -1.403885 * scale_y, 0.0)],
+ [(0.125156 * scale_x, -0.405159 * scale_y, 0.0),
+ (-0.086972 * scale_x, -0.426766 * scale_y, 0.0),
+ (0.262886 * scale_x, -0.321908 * scale_y, 0.0),
+ (0.049661 * scale_x, -0.92287 * scale_y, 0.0)]]
+ make_curve(self, context, verts, lhandles, rhandles)
+
+
+def add_type8(self, context):
+
+ scale_x = self.scale_x
+ scale_y = self.scale_y
+ verts = [[-0.850431 * scale_x, -0.009091 * scale_y,
+ 0.0, -0.818807 * scale_x, -0.130518 * scale_y,
+ 0.0, -0.944931 * scale_x, 0.055065 * scale_y,
+ 0.0, -0.393355 * scale_x, -0.035521 * scale_y,
+ 0.0, 0.0 * scale_x, 0.348298 * scale_y,
+ 0.0, 0.393355 * scale_x, -0.035521 * scale_y,
+ 0.0, 0.978373 * scale_x, 0.185638 * scale_y,
+ 0.0, 0.771617 * scale_x, 0.272819 * scale_y,
+ 0.0, 0.864179 * scale_x, 0.188103 * scale_y, 0.0]]
+ lhandles = [[(-0.90478 * scale_x, -0.025302 * scale_y, 0.0),
+ (-0.753279 * scale_x, -0.085571 * scale_y, 0.0),
+ (-1.06406 * scale_x, -0.047879 * scale_y, 0.0),
+ (-0.622217 * scale_x, -0.022501 * scale_y, 0.0),
+ (0.181 * scale_x, 0.34879 * scale_y, 0.0),
+ (-0.101464 * scale_x, -0.063669 * scale_y, 0.0),
+ (0.933064 * scale_x, 0.03001 * scale_y, 0.0),
+ (0.82418 * scale_x, 0.39899 * scale_y, 0.0),
+ (0.827377 * scale_x, 0.144945 * scale_y, 0.0)]]
+ rhandles = [[(-0.796079 * scale_x, 0.007121 * scale_y, 0.0),
+ (-0.931521 * scale_x, -0.207832 * scale_y, 0.0),
+ (-0.822288 * scale_x, 0.161045 * scale_y, 0.0),
+ (0.101464 * scale_x, -0.063671 * scale_y, 0.0),
+ (-0.181193 * scale_x, 0.347805 * scale_y, 0.0),
+ (0.622217 * scale_x, -0.022502 * scale_y, 0.0),
+ (1.022383 * scale_x, 0.336808 * scale_y, 0.0),
+ (0.741059 * scale_x, 0.199468 * scale_y, 0.0),
+ (0.900979 * scale_x, 0.231258 * scale_y, 0.0)]]
+ make_curve(self, context, verts, lhandles, rhandles)
+
+
+def add_type3(self, context):
+
+ scale_x = self.scale_x
+ scale_y = self.scale_y
+ verts = [[-0.78652 * scale_x, -0.070157 * scale_y,
+ 0.0, -0.697972 * scale_x, -0.247246 * scale_y,
+ 0.0, -0.953385 * scale_x, -0.002048 * scale_y,
+ 0.0, 0.0 * scale_x, 0.0 * scale_y,
+ 0.0, 0.917448 * scale_x, 0.065788 * scale_y,
+ 0.0, 0.448535 * scale_x, 0.515947 * scale_y,
+ 0.0, 0.6111 * scale_x, 0.190831 * scale_y, 0.0]]
+ lhandles = [[(-0.86511 * scale_x, -0.112965 * scale_y, 0.0),
+ (-0.61153 * scale_x, -0.156423 * scale_y, 0.0),
+ (-1.103589 * scale_x, -0.199934 * scale_y, 0.0),
+ (-0.446315 * scale_x, 0.135163 * scale_y, 0.0),
+ (0.669383 * scale_x, -0.254463 * scale_y, 0.0),
+ (0.721512 * scale_x, 0.802759 * scale_y, 0.0),
+ (0.466815 * scale_x, 0.112232 * scale_y, 0.0)]]
+ rhandles = [[(-0.707927 * scale_x, -0.027348 * scale_y, 0.0),
+ (-0.846662 * scale_x, -0.40347 * scale_y, 0.0),
+ (-0.79875 * scale_x, 0.201677 * scale_y, 0.0),
+ (0.446315 * scale_x, -0.135163 * scale_y, 0.0),
+ (1.196752 * scale_x, 0.42637 * scale_y, 0.0),
+ (0.289834 * scale_x, 0.349204 * scale_y, 0.0),
+ (0.755381 * scale_x, 0.269428 * scale_y, 0.0)]]
+ make_curve(self, context, verts, lhandles, rhandles)
+
+
+def add_type2(self, context):
+
+ scale_x = self.scale_x
+ scale_y = self.scale_y
+ verts = [[-0.719632 * scale_x, -0.08781 * scale_y,
+ 0.0, -0.605138 * scale_x, -0.31612 * scale_y,
+ 0.0, -0.935392 * scale_x, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.935392 * scale_x, 0.0, 0.0, 0.605138 * scale_x,
+ -0.316119 * scale_y, 0.0, 0.719632 * scale_x, -0.08781 * scale_y, 0.0]]
+ lhandles = [[(-0.82125 * scale_x, -0.142999 * scale_y, 0.0),
+ (-0.493366 * scale_x, -0.199027 * scale_y, 0.0),
+ (-1.129601 * scale_x, -0.25513 * scale_y, 0.0),
+ (-0.467584 * scale_x, 0.00044 * scale_y, 0.0),
+ (0.735439 * scale_x, 0.262646 * scale_y, 0.0),
+ (0.797395 * scale_x, -0.517531 * scale_y, 0.0),
+ (0.618012 * scale_x, -0.032614 * scale_y, 0.0)]]
+ rhandles = [[(-0.618009 * scale_x, -0.032618 * scale_y, 0.0),
+ (-0.797396 * scale_x, -0.517532 * scale_y, 0.0),
+ (-0.735445 * scale_x, 0.262669 * scale_y, 0.0),
+ (0.468041 * scale_x, -0.00044 * scale_y, 0.0),
+ (1.129616 * scale_x, -0.255119 * scale_y, 0.0),
+ (0.493365 * scale_x, -0.199025 * scale_y, 0.0),
+ (0.821249 * scale_x, -0.143004 * scale_y, 0.0)]]
+ make_curve(self, context, verts, lhandles, rhandles)
+
+
+def add_type10(self, context):
+
+ scale_x = self.scale_x
+ scale_y = self.scale_y
+ verts = [[-0.999637 * scale_x, 0.000348 * scale_y,
+ 0.0, 0.259532 * scale_x, -0.017841 * scale_y,
+ 0.0, 0.482303 * scale_x, 0.780429 * scale_y,
+ 0.0, 0.573183 * scale_x, 0.506898 * scale_y, 0.0],
+ [0.259532 * scale_x, -0.017841 * scale_y,
+ 0.0, 0.554919 * scale_x, -0.140918 * scale_y,
+ 0.0, 0.752264 * scale_x, -0.819275 * scale_y,
+ 0.0, 0.824152 * scale_x, -0.514881 * scale_y, 0.0]]
+ lhandles = [[(-1.258333 * scale_x, -0.258348 * scale_y, 0.0),
+ (-0.240006 * scale_x, -0.15259 * scale_y, 0.0),
+ (0.79037 * scale_x, 0.857575 * scale_y, 0.0),
+ (0.376782 * scale_x, 0.430157 * scale_y, 0.0)],
+ [(0.224917 * scale_x, -0.010936 * scale_y, 0.0),
+ (0.514858 * scale_x, -0.122809 * scale_y, 0.0),
+ (1.057957 * scale_x, -0.886925 * scale_y, 0.0),
+ (0.61945 * scale_x, -0.464285 * scale_y, 0.0)]]
+ rhandles = [[(-0.74094 * scale_x, 0.259045 * scale_y, 0.0),
+ (0.768844 * scale_x, 0.119545 * scale_y, 0.0),
+ (0.279083 * scale_x, 0.729538 * scale_y, 0.0),
+ (0.643716 * scale_x, 0.534458 * scale_y, 0.0)],
+ [(0.294147 * scale_x, -0.024746 * scale_y, 0.0),
+ (1.03646 * scale_x, -0.358598 * scale_y, 0.0),
+ (0.547718 * scale_x, -0.774008 * scale_y, 0.0),
+ (0.897665 * scale_x, -0.533051 * scale_y, 0.0)]]
+ make_curve(self, context, verts, lhandles, rhandles)
+
+
+def add_type9(self, context):
+
+ scale_x = self.scale_x
+ scale_y = self.scale_y
+ verts = [[0.260968 * scale_x, -0.668118 * scale_y,
+ 0.0, 0.108848 * scale_x, -0.381587 * scale_y,
+ 0.0, 0.537002 * scale_x, -0.77303 * scale_y,
+ 0.0, -0.600421 * scale_x, -0.583106 * scale_y,
+ 0.0, -0.600412 * scale_x, 0.583103 * scale_y,
+ 0.0, 0.537002 * scale_x, 0.773025 * scale_y,
+ 0.0, 0.108854 * scale_x, 0.381603 * scale_y,
+ 0.0, 0.260966 * scale_x, 0.668129 * scale_y, 0.0]]
+ lhandles = [[(0.387973 * scale_x, -0.594856 * scale_y, 0.0),
+ (-0.027835 * scale_x, -0.532386 * scale_y, 0.0),
+ (0.775133 * scale_x, -0.442883 * scale_y, 0.0),
+ (-0.291333 * scale_x, -1.064385 * scale_y, 0.0),
+ (-0.833382 * scale_x, 0.220321 * scale_y, 0.0),
+ (0.291856 * scale_x, 1.112891 * scale_y, 0.0),
+ (0.346161 * scale_x, 0.119777 * scale_y, 0.0),
+ (0.133943 * scale_x, 0.741389 * scale_y, 0.0)]]
+ rhandles = [[(0.133951 * scale_x, -0.741386 * scale_y, 0.0),
+ (0.346154 * scale_x, -0.119772 * scale_y, 0.0),
+ (0.291863 * scale_x, -1.112896 * scale_y, 0.0),
+ (-0.833407 * scale_x, -0.220324 * scale_y, 0.0),
+ (-0.29134 * scale_x, 1.064389 * scale_y, 0.0),
+ (0.775125 * scale_x, 0.442895 * scale_y, 0.0),
+ (-0.029107 * scale_x, 0.533819 * scale_y, 0.0),
+ (0.387981 * scale_x, 0.594873 * scale_y, 0.0)]]
+ make_curve(self, context, verts, lhandles, rhandles)
+
+
+def add_type7(self, context):
+
+ scale_x = self.scale_x
+ scale_y = self.scale_y
+ verts = [[-0.850431 * scale_x, -0.009091 * scale_y,
+ 0.0, -0.818807 * scale_x, -0.130518 * scale_y,
+ 0.0, -0.944931 * scale_x, 0.055065 * scale_y, 0.0,
+ -0.393355 * scale_x, -0.035521 * scale_y,
+ 0.0, 0.0 * scale_x, 0.348298 * scale_y,
+ 0.0, 0.393355 * scale_x, -0.035521 * scale_y,
+ 0.0, 0.944931 * scale_x, 0.055065 * scale_y,
+ 0.0, 0.818807 * scale_x, -0.130518 * scale_y,
+ 0.0, 0.850431 * scale_x, -0.009091 * scale_y,0.0]]
+ lhandles = [[(-0.90478 * scale_x, -0.025302 * scale_y, 0.0),
+ (-0.753279 * scale_x, -0.085571 * scale_y, 0.0),
+ (-1.06406 * scale_x, -0.047879 * scale_y, 0.0),
+ (-0.622217 * scale_x, -0.022502 * scale_y, 0.0),
+ (0.181 * scale_x, 0.348791 * scale_y, 0.0),
+ (-0.101464 * scale_x, -0.063671 * scale_y, 0.0),
+ (0.822288 * scale_x, 0.161045 * scale_y, 0.0),
+ (0.931521 * scale_x, -0.207832 * scale_y, 0.0),
+ (0.796079 * scale_x, 0.007121 * scale_y, 0.0)]]
+ rhandles = [[(-0.796079 * scale_x, 0.007121 * scale_y, 0.0),
+ (-0.931521 * scale_x, -0.207832 * scale_y, 0.0),
+ (-0.822288 * scale_x, 0.161045 * scale_y, 0.0),
+ (0.101464 * scale_x, -0.063671 * scale_y, 0.0),
+ (-0.181193 * scale_x, 0.347805 * scale_y, 0.0),
+ (0.622217 * scale_x, -0.022502 * scale_y, 0.0),
+ (1.06406 * scale_x, -0.047879 * scale_y, 0.0),
+ (0.753279 * scale_x, -0.085571 * scale_y, 0.0),
+ (0.90478 * scale_x, -0.025302 * scale_y, 0.0)]]
+ make_curve(self, context, verts, lhandles, rhandles)
+
+
+def add_type4(self, context):
+
+ scale_x = self.scale_x
+ scale_y = self.scale_y
+ verts = [[0.072838 * scale_x, -0.071461 * scale_y,
+ 0.0, -0.175451 * scale_x, -0.130711 * scale_y,
+ 0.0, 0.207269 * scale_x, 0.118064 * scale_y,
+ 0.0, 0 * scale_x, -1.0 * scale_y, 0.0]]
+ lhandles = [[(0.042135 * scale_x, 0.039756 * scale_y, 0),
+ (-0.086769 * scale_x, -0.265864 * scale_y, 0),
+ (0.002865 * scale_x, 0.364657 * scale_y, 0),
+ (0.233116 * scale_x, -0.596115 * scale_y, 0)]]
+ rhandles = [[(0.103542 * scale_x, -0.182683 * scale_y, 0),
+ (-0.327993 * scale_x, 0.101765 * scale_y, 0),
+ (0.417702 * scale_x, -0.135803 * scale_y, 0),
+ (-0.233116 * scale_x, -1.403885 * scale_y, 0)]]
+ make_curve(self, context, verts, lhandles, rhandles)
+
+
+def add_type1(self, context):
+
+ scale_x = self.scale_x
+ scale_y = self.scale_y
+ verts = [[-0.71753 * scale_x, -0.08781 * scale_y,
+ 0, -0.60337 * scale_x, -0.31612 * scale_y, 0,
+ -0.93266 * scale_x, 0, 0, 0, 0, 0, 0.93266 * scale_x,
+ 0, 0, 0.60337 * scale_x, 0.31612 * scale_y,
+ 0, 0.71753 * scale_x, 0.08781 * scale_y, 0]]
+ lhandles = [[(-0.81885 * scale_x, -0.143002 * scale_y, 0),
+ (-0.491926 * scale_x, -0.199026 * scale_y, 0),
+ (-1.126316 * scale_x, -0.255119 * scale_y, 0),
+ (-0.446315 * scale_x, 0.135164 * scale_y, 0),
+ (0.733297 * scale_x, -0.26265 * scale_y, 0),
+ (0.795065 * scale_x, 0.517532 * scale_y, 0),
+ (0.616204 * scale_x, 0.03262 * scale_y, 0)]]
+ rhandles = [[(-0.616204 * scale_x, -0.032618 * scale_y, 0),
+ (-0.795067 * scale_x, -0.517532 * scale_y, 0),
+ (-0.733297 * scale_x, 0.262651 * scale_y, 0),
+ (0.446315 * scale_x, -0.135163 * scale_y, 0),
+ (1.126316 * scale_x, 0.255119 * scale_y, 0),
+ (0.491924 * scale_x, 0.199026 * scale_y, 0),
+ (0.81885 * scale_x, 0.143004 * scale_y, 0)]]
+ make_curve(self, context, verts, lhandles, rhandles)
+
+
+def make_curve(self, context, verts, lh, rh):
+
+ scale_x = self.scale_x
+ scale_y = self.scale_y
+ type = self.type
+ curve_data = bpy.data.curves.new(name='CurlyCurve', type='CURVE')
+ curve_data.dimensions = '3D'
+ for p in range(len(verts)):
+ c = 0
+ spline = curve_data.splines.new(type='BEZIER')
+ spline.bezier_points.add(len(verts[p]) / 3 - 1)
+ spline.bezier_points.foreach_set('co', verts[p])
+ for bp in spline.bezier_points:
+ bp.handle_left_type = 'ALIGNED'
+ bp.handle_right_type = 'ALIGNED'
+ bp.handle_left.xyz = lh[p][c]
+ bp.handle_right.xyz = rh[p][c]
+ c += 1
+ # something weird with this one
+ if type == 1 or type == 2 or type == 3:
+ spline.bezier_points[3].handle_left.xyz = lh[p][3]
+ object_data_add(context, curve_data, operator=self)
+
+
+class add_curlycurve(Operator, AddObjectHelper):
+ """Create a Curly Curve"""
+ bl_idname = "curve.curlycurve"
+ bl_label = "Add Curly Curve"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ type = IntProperty(name='Type', description='Type of curly curve', default=1, min=1, max=10)
+ scale_x = FloatProperty(name="scale x", description="scale on x axis", default=1.0)
+ scale_y = FloatProperty(name="scale y", description="scale on y axis", default=1.0)
+
+ def execute(self, context):
+ if self.type == 1:
+ add_type1(self, context)
+ if self.type == 2:
+ add_type2(self, context)
+ if self.type == 3:
+ add_type3(self, context)
+ if self.type == 4:
+ add_type4(self, context)
+ if self.type == 5:
+ add_type5(self, context)
+ if self.type == 6:
+ add_type6(self, context)
+ if self.type == 7:
+ add_type7(self, context)
+ if self.type == 8:
+ add_type8(self, context)
+ if self.type == 9:
+ add_type9(self, context)
+ if self.type == 10:
+ add_type10(self, context)
+ return {'FINISHED'}
+
+# Registration
+
+
+def add_curlycurve_button(self, context):
+ self.layout.operator(
+ add_curlycurve.bl_idname,
+ text="Add Curly Curve",
+ icon='PLUGIN')
+
+
+def register():
+ bpy.utils.register_class(add_curlycurve)
+ # bpy.utils.register_manual_map(add_object_manual_map)
+ bpy.types.INFO_MT_curve_add.append(add_curlycurve_button)
+
+
+def unregister():
+ bpy.utils.unregister_class(add_curlycurve)
+ # bpy.utils.unregister_manual_map(add_object_manual_map)
+ bpy.types.INFO_MT_curve_add.remove(add_curlycurve_button)
+
+if __name__ == "__main__":
+ register()
diff --git a/add_curve_extra_objects/add_curve_simple.py b/add_curve_extra_objects/add_curve_simple.py
new file mode 100644
index 00000000..111d8c08
--- /dev/null
+++ b/add_curve_extra_objects/add_curve_simple.py
@@ -0,0 +1,1612 @@
+# ##### 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': 'Simple Curve',
+ 'author': 'Spivak Vladimir (http://cwolf3d.korostyshev.net)',
+ 'version': (1, 5, 2),
+ 'blender': (2, 6, 9),
+ 'location': 'View3D > Add > Curve',
+ 'description': 'Adds Simple Curve',
+ 'warning': '', # used for warning icon and text in addons panel
+ 'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Curve/Simple_curves',
+ "tracker_url": "https://developer.blender.org/maniphest/task/edit/form/2/",
+ 'category': 'Add Curve'}
+
+
+# ------------------------------------------------------------
+#### import modules
+import bpy
+from bpy.props import *
+from mathutils import *
+from math import *
+from bpy_extras.object_utils import *
+from random import *
+
+# ------------------------------------------------------------
+# Point:
+
+
+def SimplePoint():
+ newpoints = []
+
+ newpoints.append([0.0, 0.0, 0.0])
+
+ return newpoints
+
+# ------------------------------------------------------------
+# Line:
+
+
+def SimpleLine(c1=[0.0, 0.0, 0.0], c2=[2.0, 2.0, 2.0]):
+ newpoints = []
+
+ c3 = Vector(c2) - Vector(c1)
+ newpoints.append([0.0, 0.0, 0.0])
+ newpoints.append([c3[0], c3[1], c3[2]])
+
+ return newpoints
+
+# ------------------------------------------------------------
+# Angle:
+
+
+def SimpleAngle(length=1.0, angle=45.0):
+ newpoints = []
+
+ angle = radians(angle)
+ newpoints.append([length, 0.0, 0.0])
+ newpoints.append([0.0, 0.0, 0.0])
+ newpoints.append([length * cos(angle), length * sin(angle), 0.0])
+
+ return newpoints
+
+# ------------------------------------------------------------
+# Distance:
+
+
+def SimpleDistance(length=1.0, center=True):
+ newpoints = []
+
+ if center:
+ newpoints.append([-length / 2, 0.0, 0.0])
+ newpoints.append([length / 2, 0.0, 0.0])
+ else:
+ newpoints.append([0.0, 0.0, 0.0])
+ newpoints.append([length, 0.0, 0.0])
+
+ return newpoints
+
+# ------------------------------------------------------------
+# Circle:
+
+
+def SimpleCircle(sides=4, radius=1.0):
+ newpoints = []
+
+ angle = radians(360) / sides
+ newpoints.append([radius, 0, 0])
+ j = 1
+ while j < sides:
+ t = angle * j
+ x = cos(t) * radius
+ y = sin(t) * radius
+ newpoints.append([x, y, 0])
+ j += 1
+
+ return newpoints
+
+# ------------------------------------------------------------
+# Ellipse:
+
+
+def SimpleEllipse(a=2.0, b=1.0):
+ newpoints = []
+
+ newpoints.append([a, 0.0, 0.0])
+ newpoints.append([0.0, b, 0.0])
+ newpoints.append([-a, 0.0, 0.0])
+ newpoints.append([0.0, -b, 0.0])
+
+ return newpoints
+
+# ------------------------------------------------------------
+# Arc:
+
+
+def SimpleArc(sides=0, radius=1.0, startangle=0.0, endangle=45.0):
+ newpoints = []
+
+ startangle = radians(startangle)
+ endangle = radians(endangle)
+ sides += 1
+
+ angle = (endangle - startangle) / sides
+ x = cos(startangle) * radius
+ y = sin(startangle) * radius
+ newpoints.append([x, y, 0])
+ j = 1
+ while j < sides:
+ t = angle * j
+ x = cos(t + startangle) * radius
+ y = sin(t + startangle) * radius
+ newpoints.append([x, y, 0])
+ j += 1
+ x = cos(endangle) * radius
+ y = sin(endangle) * radius
+ newpoints.append([x, y, 0])
+
+ return newpoints
+
+# ------------------------------------------------------------
+# Sector:
+
+
+def SimpleSector(sides=0, radius=1.0, startangle=0.0, endangle=45.0):
+ newpoints = []
+
+ startangle = radians(startangle)
+ endangle = radians(endangle)
+ sides += 1
+
+ newpoints.append([0, 0, 0])
+ angle = (endangle - startangle) / sides
+ x = cos(startangle) * radius
+ y = sin(startangle) * radius
+ newpoints.append([x, y, 0])
+ j = 1
+ while j < sides:
+ t = angle * j
+ x = cos(t + startangle) * radius
+ y = sin(t + startangle) * radius
+ newpoints.append([x, y, 0])
+ j += 1
+ x = cos(endangle) * radius
+ y = sin(endangle) * radius
+ newpoints.append([x, y, 0])
+
+ return newpoints
+
+# ------------------------------------------------------------
+# Segment:
+
+
+def SimpleSegment(sides=0, a=2.0, b=1.0, startangle=0.0, endangle=45.0):
+ newpoints = []
+
+ startangle = radians(startangle)
+ endangle = radians(endangle)
+ sides += 1
+
+ angle = (endangle - startangle) / sides
+ x = cos(startangle) * a
+ y = sin(startangle) * a
+ newpoints.append([x, y, 0])
+ j = 1
+ while j < sides:
+ t = angle * j
+ x = cos(t + startangle) * a
+ y = sin(t + startangle) * a
+ newpoints.append([x, y, 0])
+ j += 1
+ x = cos(endangle) * a
+ y = sin(endangle) * a
+ newpoints.append([x, y, 0])
+
+ x = cos(endangle) * b
+ y = sin(endangle) * b
+ newpoints.append([x, y, 0])
+ j = sides
+ while j > 0:
+ t = angle * j
+ x = cos(t + startangle) * b
+ y = sin(t + startangle) * b
+ newpoints.append([x, y, 0])
+ j -= 1
+ x = cos(startangle) * b
+ y = sin(startangle) * b
+ newpoints.append([x, y, 0])
+
+ return newpoints
+
+# ------------------------------------------------------------
+# Rectangle:
+
+
+def SimpleRectangle(width=2.0, length=2.0, rounded=0.0, center=True):
+ newpoints = []
+
+ r = rounded / 2
+
+ if center:
+ x = width / 2
+ y = length / 2
+ if rounded != 0.0:
+ newpoints.append([-x + r, y, 0.0])
+ newpoints.append([x - r, y, 0.0])
+ newpoints.append([x, y - r, 0.0])
+ newpoints.append([x, -y + r, 0.0])
+ newpoints.append([x - r, -y, 0.0])
+ newpoints.append([-x + r, -y, 0.0])
+ newpoints.append([-x, -y + r, 0.0])
+ newpoints.append([-x, y - r, 0.0])
+ else:
+ newpoints.append([-x, y, 0.0])
+ newpoints.append([x, y, 0.0])
+ newpoints.append([x, -y, 0.0])
+ newpoints.append([-x, -y, 0.0])
+
+ else:
+ x = width
+ y = length
+ if rounded != 0.0:
+ newpoints.append([r, y, 0.0])
+ newpoints.append([x - r, y, 0.0])
+ newpoints.append([x, y - r, 0.0])
+ newpoints.append([x, r, 0.0])
+ newpoints.append([x - r, 0.0, 0.0])
+ newpoints.append([r, 0.0, 0.0])
+ newpoints.append([0.0, r, 0.0])
+ newpoints.append([0.0, y - r, 0.0])
+ else:
+ newpoints.append([0.0, 0.0, 0.0])
+ newpoints.append([0.0, y, 0.0])
+ newpoints.append([x, y, 0.0])
+ newpoints.append([x, 0.0, 0.0])
+
+ return newpoints
+
+# ------------------------------------------------------------
+# Rhomb:
+
+
+def SimpleRhomb(width=2.0, length=2.0, center=True):
+ newpoints = []
+ x = width / 2
+ y = length / 2
+
+ if center:
+ newpoints.append([-x, 0.0, 0.0])
+ newpoints.append([0.0, y, 0.0])
+ newpoints.append([x, 0.0, 0.0])
+ newpoints.append([0.0, -y, 0.0])
+ else:
+ newpoints.append([x, 0.0, 0.0])
+ newpoints.append([0.0, y, 0.0])
+ newpoints.append([x, length, 0.0])
+ newpoints.append([width, y, 0.0])
+
+ return newpoints
+
+# ------------------------------------------------------------
+# Polygon:
+
+
+def SimplePolygon(sides=3, radius=1.0):
+ newpoints = []
+ angle = radians(360.0) / sides
+ j = 0
+
+ while j < sides:
+ t = angle * j
+ x = sin(t) * radius
+ y = cos(t) * radius
+ newpoints.append([x, y, 0.0])
+ j += 1
+
+ return newpoints
+
+# ------------------------------------------------------------
+# Polygon_ab:
+
+
+def SimplePolygon_ab(sides=3, a=2.0, b=1.0):
+ newpoints = []
+ angle = radians(360.0) / sides
+ j = 0
+
+ while j < sides:
+ t = angle * j
+ x = sin(t) * a
+ y = cos(t) * b
+ newpoints.append([x, y, 0.0])
+ j += 1
+
+ return newpoints
+
+# ------------------------------------------------------------
+# Trapezoid:
+
+
+def SimpleTrapezoid(a=2.0, b=1.0, h=1.0, center=True):
+ newpoints = []
+ x = a / 2
+ y = b / 2
+ r = h / 2
+
+ if center:
+ newpoints.append([-x, -r, 0.0])
+ newpoints.append([-y, r, 0.0])
+ newpoints.append([y, r, 0.0])
+ newpoints.append([x, -r, 0.0])
+
+ else:
+ newpoints.append([0.0, 0.0, 0.0])
+ newpoints.append([x - y, h, 0.0])
+ newpoints.append([x + y, h, 0.0])
+ newpoints.append([a, 0.0, 0.0])
+
+ return newpoints
+
+# ------------------------------------------------------------
+# calculates the matrix for the new object
+# depending on user pref
+
+
+def align_matrix(context, location):
+ loc = Matrix.Translation(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
+
+# ------------------------------------------------------------
+# Main Function
+
+
+def main(context, self, align_matrix):
+ # deselect all objects
+ bpy.ops.object.select_all(action='DESELECT')
+
+ # create object
+ name = self.Simple_Type # Type as name
+
+ # create curve
+ scene = bpy.context.scene
+ newCurve = bpy.data.curves.new(name, type='CURVE') # curvedatablock
+ newSpline = newCurve.splines.new('BEZIER') # spline
+
+ # set curveOptions
+ newCurve.dimensions = self.shape
+ newSpline.use_endpoint_u = True
+
+ sides = abs(int((self.Simple_endangle - self.Simple_startangle) / 90))
+
+ # get verts
+ if self.Simple_Type == 'Point':
+ verts = SimplePoint()
+ newSpline.use_cyclic_u = False
+
+ if self.Simple_Type == 'Line':
+ verts = SimpleLine(self.Simple_startlocation, self.Simple_endlocation)
+ newSpline.use_cyclic_u = False
+ newCurve.dimensions = '3D'
+
+ if self.Simple_Type == 'Distance':
+ verts = SimpleDistance(self.Simple_length, self.Simple_center)
+ newSpline.use_cyclic_u = False
+
+ if self.Simple_Type == 'Angle':
+ verts = SimpleAngle(self.Simple_length, self.Simple_angle)
+ newSpline.use_cyclic_u = False
+
+ if self.Simple_Type == 'Circle':
+ if self.Simple_sides < 4:
+ self.Simple_sides = 4
+ verts = SimpleCircle(self.Simple_sides, self.Simple_radius)
+ newSpline.use_cyclic_u = True
+
+ if self.Simple_Type == 'Ellipse':
+ verts = SimpleEllipse(self.Simple_a, self.Simple_b)
+ newSpline.use_cyclic_u = True
+
+ if self.Simple_Type == 'Arc':
+ if self.Simple_sides < sides:
+ self.Simple_sides = sides
+ if self.Simple_radius == 0:
+ return {'FINISHED'}
+ verts = SimpleArc(self.Simple_sides, self.Simple_radius, self.Simple_startangle, self.Simple_endangle)
+ newSpline.use_cyclic_u = False
+
+ if self.Simple_Type == 'Sector':
+ if self.Simple_sides < sides:
+ self.Simple_sides = sides
+ if self.Simple_radius == 0:
+ return {'FINISHED'}
+ verts = SimpleSector(self.Simple_sides, self.Simple_radius, self.Simple_startangle, self.Simple_endangle)
+ newSpline.use_cyclic_u = True
+
+ if self.Simple_Type == 'Segment':
+ if self.Simple_sides < sides:
+ self.Simple_sides = sides
+ if self.Simple_a == 0 or self.Simple_b == 0:
+ return {'FINISHED'}
+ verts = SimpleSegment(self.Simple_sides, self.Simple_a, self.Simple_b, self.Simple_startangle, self.Simple_endangle)
+ newSpline.use_cyclic_u = True
+
+ if self.Simple_Type == 'Rectangle':
+ verts = SimpleRectangle(self.Simple_width, self.Simple_length, self.Simple_rounded, self.Simple_center)
+ newSpline.use_cyclic_u = True
+
+ if self.Simple_Type == 'Rhomb':
+ verts = SimpleRhomb(self.Simple_width, self.Simple_length, self.Simple_center)
+ newSpline.use_cyclic_u = True
+
+ if self.Simple_Type == 'Polygon':
+ if self.Simple_sides < 3:
+ self.Simple_sides = 3
+ verts = SimplePolygon(self.Simple_sides, self.Simple_radius)
+ newSpline.use_cyclic_u = True
+
+ if self.Simple_Type == 'Polygon_ab':
+ if self.Simple_sides < 3:
+ self.Simple_sides = 3
+ verts = SimplePolygon_ab(self.Simple_sides, self.Simple_a, self.Simple_b)
+ newSpline.use_cyclic_u = True
+
+ if self.Simple_Type == 'Trapezoid':
+ verts = SimpleTrapezoid(self.Simple_a, self.Simple_b, self.Simple_h, self.Simple_center)
+ newSpline.use_cyclic_u = True
+
+ vertArray = []
+ for v in verts:
+ vertArray += v
+
+ newSpline.bezier_points.add(int(len(vertArray) * 0.333333333))
+ newSpline.bezier_points.foreach_set('co', vertArray)
+
+ # create object with newCurve
+ SimpleCurve = bpy.data.objects.new(name, newCurve) # object
+ scene.objects.link(SimpleCurve) # place in active scene
+ SimpleCurve.select = True # set as selected
+ scene.objects.active = SimpleCurve # set as active
+ SimpleCurve.matrix_world = align_matrix # apply matrix
+ SimpleCurve.rotation_euler = self.Simple_rotation_euler
+
+ all_points = [p for p in newSpline.bezier_points]
+ d = 2 * 0.27606262
+ n = 0
+ for p in all_points:
+ p.handle_right_type = 'VECTOR'
+ p.handle_left_type = 'VECTOR'
+ n += 1
+
+ if self.Simple_Type == 'Circle' or self.Simple_Type == 'Arc' or self.Simple_Type == 'Sector' or self.Simple_Type == 'Segment' or self.Simple_Type == 'Ellipse':
+ for p in all_points:
+ p.handle_right_type = 'FREE'
+ p.handle_left_type = 'FREE'
+
+ if self.Simple_Type == 'Circle':
+ i = 0
+ for p1 in all_points:
+ if i != n - 1:
+ p2 = all_points[i + 1]
+ u1 = asin(p1.co.y / self.Simple_radius)
+ u2 = asin(p2.co.y / self.Simple_radius)
+ if p1.co.x > 0 and p2.co.x < 0:
+ u1 = acos(p1.co.x / self.Simple_radius)
+ u2 = acos(p2.co.x / self.Simple_radius)
+ elif p1.co.x < 0 and p2.co.x > 0:
+ u1 = acos(p1.co.x / self.Simple_radius)
+ u2 = acos(p2.co.x / self.Simple_radius)
+ u = u2 - u1
+ if u < 0:
+ u = -u
+ l = 4 / 3 * tan(1 / 4 * u) * self.Simple_radius
+ v1 = Vector((-p1.co.y, p1.co.x, 0))
+ v1.normalize()
+ v2 = Vector((-p2.co.y, p2.co.x, 0))
+ v2.normalize()
+ vh1 = v1 * l
+ vh2 = v2 * l
+ v1 = Vector((p1.co.x, p1.co.y, 0)) + vh1
+ v2 = Vector((p2.co.x, p2.co.y, 0)) - vh2
+ p1.handle_right = v1
+ p2.handle_left = v2
+ if i == n - 1:
+ p2 = all_points[0]
+ u1 = asin(p1.co.y / self.Simple_radius)
+ u2 = asin(p2.co.y / self.Simple_radius)
+ if p1.co.x > 0 and p2.co.x < 0:
+ u1 = acos(p1.co.x / self.Simple_radius)
+ u2 = acos(p2.co.x / self.Simple_radius)
+ elif p1.co.x < 0 and p2.co.x > 0:
+ u1 = acos(p1.co.x / self.Simple_radius)
+ u2 = acos(p2.co.x / self.Simple_radius)
+ u = u2 - u1
+ if u < 0:
+ u = -u
+ l = 4 / 3 * tan(1 / 4 * u) * self.Simple_radius
+ v1 = Vector((-p1.co.y, p1.co.x, 0))
+ v1.normalize()
+ v2 = Vector((-p2.co.y, p2.co.x, 0))
+ v2.normalize()
+ vh1 = v1 * l
+ vh2 = v2 * l
+ v1 = Vector((p1.co.x, p1.co.y, 0)) + vh1
+ v2 = Vector((p2.co.x, p2.co.y, 0)) - vh2
+ p1.handle_right = v1
+ p2.handle_left = v2
+ i += 1
+
+ if self.Simple_Type == 'Ellipse':
+ all_points[0].handle_right = Vector((self.Simple_a, self.Simple_b * d, 0))
+ all_points[0].handle_left = Vector((self.Simple_a, -self.Simple_b * d, 0))
+ all_points[1].handle_right = Vector((-self.Simple_a * d, self.Simple_b, 0))
+ all_points[1].handle_left = Vector((self.Simple_a * d, self.Simple_b, 0))
+ all_points[2].handle_right = Vector((-self.Simple_a, -self.Simple_b * d, 0))
+ all_points[2].handle_left = Vector((-self.Simple_a, self.Simple_b * d, 0))
+ all_points[3].handle_right = Vector((self.Simple_a * d, -self.Simple_b, 0))
+ all_points[3].handle_left = Vector((-self.Simple_a * d, -self.Simple_b, 0))
+
+ if self.Simple_Type == 'Arc':
+ i = 0
+ for p1 in all_points:
+ if i != n - 1:
+ p2 = all_points[i + 1]
+ u1 = asin(p1.co.y / self.Simple_radius)
+ u2 = asin(p2.co.y / self.Simple_radius)
+ if p1.co.x > 0 and p2.co.x < 0:
+ u1 = acos(p1.co.x / self.Simple_radius)
+ u2 = acos(p2.co.x / self.Simple_radius)
+ elif p1.co.x < 0 and p2.co.x > 0:
+ u1 = acos(p1.co.x / self.Simple_radius)
+ u2 = acos(p2.co.x / self.Simple_radius)
+ u = u2 - u1
+ if u < 0:
+ u = -u
+ l = 4 / 3 * tan(1 / 4 * u) * self.Simple_radius
+ v1 = Vector((-p1.co.y, p1.co.x, 0))
+ v1.normalize()
+ v2 = Vector((-p2.co.y, p2.co.x, 0))
+ v2.normalize()
+ vh1 = v1 * l
+ vh2 = v2 * l
+ if self.Simple_startangle < self.Simple_endangle:
+ v1 = Vector((p1.co.x, p1.co.y, 0)) + vh1
+ v2 = Vector((p2.co.x, p2.co.y, 0)) - vh2
+ p1.handle_right = v1
+ p2.handle_left = v2
+ else:
+ v1 = Vector((p1.co.x, p1.co.y, 0)) - vh1
+ v2 = Vector((p2.co.x, p2.co.y, 0)) + vh2
+ p1.handle_right = v1
+ p2.handle_left = v2
+ i += 1
+
+ if self.Simple_Type == 'Sector':
+ i = 0
+ for p1 in all_points:
+ if i == 0:
+ p1.handle_right_type = 'VECTOR'
+ p1.handle_left_type = 'VECTOR'
+ elif i != n - 1:
+ p2 = all_points[i + 1]
+ u1 = asin(p1.co.y / self.Simple_radius)
+ u2 = asin(p2.co.y / self.Simple_radius)
+ if p1.co.x > 0 and p2.co.x < 0:
+ u1 = acos(p1.co.x / self.Simple_radius)
+ u2 = acos(p2.co.x / self.Simple_radius)
+ elif p1.co.x < 0 and p2.co.x > 0:
+ u1 = acos(p1.co.x / self.Simple_radius)
+ u2 = acos(p2.co.x / self.Simple_radius)
+ u = u2 - u1
+ if u < 0:
+ u = -u
+ l = 4 / 3 * tan(1 / 4 * u) * self.Simple_radius
+ v1 = Vector((-p1.co.y, p1.co.x, 0))
+ v1.normalize()
+ v2 = Vector((-p2.co.y, p2.co.x, 0))
+ v2.normalize()
+ vh1 = v1 * l
+ vh2 = v2 * l
+ if self.Simple_startangle < self.Simple_endangle:
+ v1 = Vector((p1.co.x, p1.co.y, 0)) + vh1
+ v2 = Vector((p2.co.x, p2.co.y, 0)) - vh2
+ p1.handle_right = v1
+ p2.handle_left = v2
+ else:
+ v1 = Vector((p1.co.x, p1.co.y, 0)) - vh1
+ v2 = Vector((p2.co.x, p2.co.y, 0)) + vh2
+ p1.handle_right = v1
+ p2.handle_left = v2
+ i += 1
+
+ if self.Simple_Type == 'Segment':
+ i = 0
+ for p1 in all_points:
+ if i < n / 2 - 1:
+ p2 = all_points[i + 1]
+ u1 = asin(p1.co.y / self.Simple_a)
+ u2 = asin(p2.co.y / self.Simple_a)
+ if p1.co.x > 0 and p2.co.x < 0:
+ u1 = acos(p1.co.x / self.Simple_a)
+ u2 = acos(p2.co.x / self.Simple_a)
+ elif p1.co.x < 0 and p2.co.x > 0:
+ u1 = acos(p1.co.x / self.Simple_a)
+ u2 = acos(p2.co.x / self.Simple_a)
+ u = u2 - u1
+ if u < 0:
+ u = -u
+ l = 4 / 3 * tan(1 / 4 * u) * self.Simple_a
+ v1 = Vector((-p1.co.y, p1.co.x, 0))
+ v1.normalize()
+ v2 = Vector((-p2.co.y, p2.co.x, 0))
+ v2.normalize()
+ vh1 = v1 * l
+ vh2 = v2 * l
+ if self.Simple_startangle < self.Simple_endangle:
+ v1 = Vector((p1.co.x, p1.co.y, 0)) + vh1
+ v2 = Vector((p2.co.x, p2.co.y, 0)) - vh2
+ p1.handle_right = v1
+ p2.handle_left = v2
+ else:
+ v1 = Vector((p1.co.x, p1.co.y, 0)) - vh1
+ v2 = Vector((p2.co.x, p2.co.y, 0)) + vh2
+ p1.handle_right = v1
+ p2.handle_left = v2
+ elif i != n / 2 - 1 and i != n - 1:
+ p2 = all_points[i + 1]
+ u1 = asin(p1.co.y / self.Simple_b)
+ u2 = asin(p2.co.y / self.Simple_b)
+ if p1.co.x > 0 and p2.co.x < 0:
+ u1 = acos(p1.co.x / self.Simple_b)
+ u2 = acos(p2.co.x / self.Simple_b)
+ elif p1.co.x < 0 and p2.co.x > 0:
+ u1 = acos(p1.co.x / self.Simple_b)
+ u2 = acos(p2.co.x / self.Simple_b)
+ u = u2 - u1
+ if u < 0:
+ u = -u
+ l = 4 / 3 * tan(1 / 4 * u) * self.Simple_b
+ v1 = Vector((-p1.co.y, p1.co.x, 0))
+ v1.normalize()
+ v2 = Vector((-p2.co.y, p2.co.x, 0))
+ v2.normalize()
+ vh1 = v1 * l
+ vh2 = v2 * l
+ if self.Simple_startangle < self.Simple_endangle:
+ v1 = Vector((p1.co.x, p1.co.y, 0)) - vh1
+ v2 = Vector((p2.co.x, p2.co.y, 0)) + vh2
+ p1.handle_right = v1
+ p2.handle_left = v2
+ else:
+ v1 = Vector((p1.co.x, p1.co.y, 0)) + vh1
+ v2 = Vector((p2.co.x, p2.co.y, 0)) - vh2
+ p1.handle_right = v1
+ p2.handle_left = v2
+
+ i += 1
+ all_points[0].handle_left_type = 'VECTOR'
+ all_points[n - 1].handle_right_type = 'VECTOR'
+ all_points[int(n / 2) - 1].handle_right_type = 'VECTOR'
+ all_points[int(n / 2)].handle_left_type = 'VECTOR'
+
+ SimpleCurve.Simple = True
+ SimpleCurve.Simple_Change = False
+ SimpleCurve.Simple_Type = self.Simple_Type
+ SimpleCurve.Simple_startlocation = self.Simple_startlocation
+ SimpleCurve.Simple_endlocation = self.Simple_endlocation
+ SimpleCurve.Simple_a = self.Simple_a
+ SimpleCurve.Simple_b = self.Simple_b
+ SimpleCurve.Simple_h = self.Simple_h
+ SimpleCurve.Simple_angle = self.Simple_angle
+ SimpleCurve.Simple_startangle = self.Simple_startangle
+ SimpleCurve.Simple_endangle = self.Simple_endangle
+ SimpleCurve.Simple_rotation_euler = self.Simple_rotation_euler
+ SimpleCurve.Simple_sides = self.Simple_sides
+ SimpleCurve.Simple_radius = self.Simple_radius
+ SimpleCurve.Simple_center = self.Simple_center
+ SimpleCurve.Simple_width = self.Simple_width
+ SimpleCurve.Simple_length = self.Simple_length
+ SimpleCurve.Simple_rounded = self.Simple_rounded
+
+ bpy.ops.object.mode_set(mode='EDIT', toggle=True)
+ bpy.ops.curve.select_all(action='SELECT')
+ bpy.ops.object.mode_set(mode='OBJECT', toggle=True)
+
+ return
+
+# ------------------------------------------------------------
+# Delete simple curve
+
+
+def SimpleDelete(name):
+ if bpy.ops.object.mode_set.poll():
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ bpy.context.scene.objects.active = bpy.data.objects[name]
+ bpy.ops.object.delete()
+
+ return
+
+# ------------------------------------------------------------
+# Simple operator
+
+
+class Simple(bpy.types.Operator):
+ ''''''
+ bl_idname = "curve.simple"
+ bl_label = "Simple curve"
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = "adds simple curve"
+
+ # align_matrix for the invoke
+ align_matrix = Matrix()
+
+ # change properties
+ Simple = BoolProperty(name="Simple",
+ default=True,
+ description="simple curve")
+
+ Simple_Change = BoolProperty(name="Change",
+ default=False,
+ description="change simple curve")
+
+ Simple_Delete = StringProperty(name="Delete",
+ description="Delete simple curve")
+
+ # general properties
+ Types = [('Point', 'Point', 'Point'),
+ ('Line', 'Line', 'Line'),
+ ('Distance', 'Distance', 'Distance'),
+ ('Angle', 'Angle', 'Angle'),
+ ('Circle', 'Circle', 'Circle'),
+ ('Ellipse', 'Ellipse', 'Ellipse'),
+ ('Arc', 'Arc', 'Arc'),
+ ('Sector', 'Sector', 'Sector'),
+ ('Segment', 'Segment', 'Segment'),
+ ('Rectangle', 'Rectangle', 'Rectangle'),
+ ('Rhomb', 'Rhomb', 'Rhomb'),
+ ('Polygon', 'Polygon', 'Polygon'),
+ ('Polygon_ab', 'Polygon_ab', 'Polygon_ab'),
+ ('Trapezoid', 'Trapezoid', 'Trapezoid')]
+ Simple_Type = EnumProperty(name="Type",
+ description="Form of Curve to create",
+ items=Types)
+
+ # Line properties
+ Simple_startlocation = FloatVectorProperty(name="",
+ description="Start location",
+ default=(0.0, 0.0, 0.0),
+ subtype='TRANSLATION')
+ Simple_endlocation = FloatVectorProperty(name="",
+ description="End location",
+ default=(2.0, 2.0, 2.0),
+ subtype='TRANSLATION')
+ Simple_rotation_euler = FloatVectorProperty(name="",
+ description="Rotation",
+ default=(0.0, 0.0, 0.0),
+ subtype='EULER')
+
+ # Trapezoid properties
+ Simple_a = FloatProperty(name="a",
+ default=2.0,
+ min=0.0, soft_min=0.0,
+ unit='LENGTH',
+ description="a")
+ Simple_b = FloatProperty(name="b",
+ default=1.0,
+ min=0.0, soft_min=0.0,
+ unit='LENGTH',
+ description="b")
+ Simple_h = FloatProperty(name="h",
+ default=1.0,
+ unit='LENGTH',
+ description="h")
+
+ Simple_angle = FloatProperty(name="Angle",
+ default=45.0,
+ description="Angle")
+ Simple_startangle = FloatProperty(name="Start angle",
+ default=0.0,
+ min=-360.0, soft_min=-360.0,
+ max=360.0, soft_max=360.0,
+ description="Start angle")
+ Simple_endangle = FloatProperty(name="End angle",
+ default=45.0,
+ min=-360.0, soft_min=-360.0,
+ max=360.0, soft_max=360.0,
+ description="End angle")
+
+ Simple_sides = IntProperty(name="sides",
+ default=3,
+ min=0, soft_min=0,
+ description="sides")
+
+ Simple_radius = FloatProperty(name="radius",
+ default=1.0,
+ min=0.0, soft_min=0.0,
+ unit='LENGTH',
+ description="radius")
+
+ Simple_center = BoolProperty(name="Length center",
+ default=True,
+ description="Length center")
+
+ Angle_types = [('Degrees', 'Degrees', 'Degrees'),
+ ('Radians', 'Radians', 'Radians')]
+ Simple_degrees_or_radians = EnumProperty(name="Degrees or radians",
+ description="Degrees or radians",
+ items=Angle_types)
+
+ # Rectangle properties
+ Simple_width = FloatProperty(name="Width",
+ default=2.0,
+ min=0.0, soft_min=0,
+ unit='LENGTH',
+ description="Width")
+ Simple_length = FloatProperty(name="Length",
+ default=2.0,
+ min=0.0, soft_min=0.0,
+ unit='LENGTH',
+ description="Length")
+ Simple_rounded = FloatProperty(name="Rounded",
+ default=0.0,
+ min=0.0, soft_min=0.0,
+ unit='LENGTH',
+ description="Rounded")
+
+ # Curve Options
+ shapeItems = [
+ ('2D', '2D', '2D'),
+ ('3D', '3D', '3D')]
+ shape = EnumProperty(name="2D / 3D",
+ items=shapeItems,
+ description="2D or 3D Curve")
+
+ ##### DRAW #####
+ def draw(self, context):
+ layout = self.layout
+
+ # general options
+ col = layout.column()
+ col.prop(self, 'Simple_Type')
+
+ l = 0
+ s = 0
+
+ if self.Simple_Type == 'Line':
+ col.label(text=self.Simple_Type + " Options")
+ box = layout.box()
+ box.prop(self, 'Simple_endlocation')
+ v = Vector(self.Simple_endlocation) - Vector(self.Simple_startlocation)
+ l = v.length
+
+ if self.Simple_Type == 'Distance':
+ col.label(text=self.Simple_Type + " Options")
+ box = layout.box()
+ box.prop(self, 'Simple_length')
+ box.prop(self, 'Simple_center')
+ l = self.Simple_length
+
+ if self.Simple_Type == 'Angle':
+ col.label(text=self.Simple_Type + " Options")
+ box = layout.box()
+ box.prop(self, 'Simple_length')
+ box.prop(self, 'Simple_angle')
+ row = layout.row()
+ row.prop(self, 'Simple_degrees_or_radians', expand=True)
+
+ if self.Simple_Type == 'Circle':
+ col.label(text=self.Simple_Type + " Options")
+ box = layout.box()
+ box.prop(self, 'Simple_sides')
+ box.prop(self, 'Simple_radius')
+ l = 2 * pi * abs(self.Simple_radius)
+ s = pi * self.Simple_radius * self.Simple_radius
+
+ if self.Simple_Type == 'Ellipse':
+ col.label(text=self.Simple_Type + " Options")
+ box = layout.box()
+ box.prop(self, 'Simple_a')
+ box.prop(self, 'Simple_b')
+ l = pi * (3 * (self.Simple_a + self.Simple_b) - sqrt((3 * self.Simple_a + self.Simple_b) * (self.Simple_a + 3 * self.Simple_b)))
+ s = pi * abs(self.Simple_b) * abs(self.Simple_a)
+
+ if self.Simple_Type == 'Arc':
+ col.label(text=self.Simple_Type + " Options")
+ box = layout.box()
+ box.prop(self, 'Simple_sides')
+ box.prop(self, 'Simple_radius')
+ box.prop(self, 'Simple_startangle')
+ box.prop(self, 'Simple_endangle')
+ row = layout.row()
+ row.prop(self, 'Simple_degrees_or_radians', expand=True)
+ l = abs(pi * self.Simple_radius * (self.Simple_endangle - self.Simple_startangle) / 180)
+
+ if self.Simple_Type == 'Sector':
+ col.label(text=self.Simple_Type + " Options")
+ box = layout.box()
+ box.prop(self, 'Simple_sides')
+ box.prop(self, 'Simple_radius')
+ box.prop(self, 'Simple_startangle')
+ box.prop(self, 'Simple_endangle')
+ row = layout.row()
+ row.prop(self, 'Simple_degrees_or_radians', expand=True)
+ l = abs(pi * self.Simple_radius * (self.Simple_endangle - self.Simple_startangle) / 180) + self.Simple_radius * 2
+ s = pi * self.Simple_radius * self.Simple_radius * abs(self.Simple_endangle - self.Simple_startangle) / 360
+
+ if self.Simple_Type == 'Segment':
+ col.label(text=self.Simple_Type + " Options")
+ box = layout.box()
+ box.prop(self, 'Simple_sides')
+ box.prop(self, 'Simple_a')
+ box.prop(self, 'Simple_b')
+ box.prop(self, 'Simple_startangle')
+ box.prop(self, 'Simple_endangle')
+ row = layout.row()
+ row.prop(self, 'Simple_degrees_or_radians', expand=True)
+ la = abs(pi * self.Simple_a * (self.Simple_endangle - self.Simple_startangle) / 180)
+ lb = abs(pi * self.Simple_b * (self.Simple_endangle - self.Simple_startangle) / 180)
+ l = abs(self.Simple_a - self.Simple_b) * 2 + la + lb
+ sa = pi * self.Simple_a * self.Simple_a * abs(self.Simple_endangle - self.Simple_startangle) / 360
+ sb = pi * self.Simple_b * self.Simple_b * abs(self.Simple_endangle - self.Simple_startangle) / 360
+ s = abs(sa - sb)
+
+ if self.Simple_Type == 'Rectangle':
+ col.label(text=self.Simple_Type + " Options")
+ box = layout.box()
+ box.prop(self, 'Simple_width')
+ box.prop(self, 'Simple_length')
+ box.prop(self, 'Simple_rounded')
+ box.prop(self, 'Simple_center')
+ l = 2 * abs(self.Simple_width) + 2 * abs(self.Simple_length)
+ s = abs(self.Simple_width) * abs(self.Simple_length)
+
+ if self.Simple_Type == 'Rhomb':
+ col.label(text=self.Simple_Type + " Options")
+ box = layout.box()
+ box.prop(self, 'Simple_width')
+ box.prop(self, 'Simple_length')
+ box.prop(self, 'Simple_center')
+ g = hypot(self.Simple_width / 2, self.Simple_length / 2)
+ l = 4 * g
+ s = self.Simple_width * self.Simple_length / 2
+
+ if self.Simple_Type == 'Polygon':
+ col.label(text=self.Simple_Type + " Options")
+ box = layout.box()
+ box.prop(self, 'Simple_sides')
+ box.prop(self, 'Simple_radius')
+
+ if self.Simple_Type == 'Polygon_ab':
+ col.label(text=self.Simple_Type + " Options")
+ box = layout.box()
+ box.prop(self, 'Simple_sides')
+ box.prop(self, 'Simple_a')
+ box.prop(self, 'Simple_b')
+
+ if self.Simple_Type == 'Trapezoid':
+ col.label(text=self.Simple_Type + " Options")
+ box = layout.box()
+ box.prop(self, 'Simple_a')
+ box.prop(self, 'Simple_b')
+ box.prop(self, 'Simple_h')
+ box.prop(self, 'Simple_center')
+ g = hypot(self.Simple_h, (self.Simple_a - self.Simple_b) / 2)
+ l = self.Simple_a + self.Simple_b + g * 2
+ s = (abs(self.Simple_a) + abs(self.Simple_b)) / 2 * self.Simple_h
+
+ row = layout.row()
+ row.prop(self, 'shape', expand=True)
+ box = layout.box()
+ box.label("Location:")
+ box.prop(self, 'Simple_startlocation')
+ box = layout.box()
+ box.label("Rotation:")
+ box.prop(self, 'Simple_rotation_euler')
+ if l != 0:
+ l_str = str(round(l, 4))
+ row = layout.row()
+ row.label("Length: " + l_str)
+ if s != 0:
+ s_str = str(round(s, 4))
+ row = layout.row()
+ row.label("Area: " + s_str)
+
+ ##### POLL #####
+ @classmethod
+ def poll(cls, context):
+ return context.scene != None
+
+ ##### EXECUTE #####
+ def execute(self, context):
+ if self.Simple_Change:
+ SimpleDelete(self.Simple_Delete)
+
+ # go to object mode
+ if bpy.ops.object.mode_set.poll():
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ # turn off undo
+ undo = bpy.context.user_preferences.edit.use_global_undo
+ bpy.context.user_preferences.edit.use_global_undo = False
+
+ # main function
+ self.align_matrix = align_matrix(context, self.Simple_startlocation)
+ 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
+ if self.Simple_Change:
+ bpy.context.scene.cursor_location = self.Simple_startlocation
+ else:
+ self.Simple_startlocation = bpy.context.scene.cursor_location
+
+ self.align_matrix = align_matrix(context, self.Simple_startlocation)
+ self.execute(context)
+
+ return {'FINISHED'}
+
+# ------------------------------------------------------------
+# Fillet
+
+
+class BezierPointsFillet(bpy.types.Operator):
+ ''''''
+ bl_idname = "curve.bezier_points_fillet"
+ bl_label = "Bezier points fillet"
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = "bezier points fillet"
+
+ Fillet_radius = FloatProperty(name="Radius",
+ default=0.25,
+ unit='LENGTH',
+ description="radius")
+
+ Types = [('Round', 'Round', 'Round'),
+ ('Chamfer', 'Chamfer', 'Chamfer')]
+ Fillet_Type = EnumProperty(name="Type",
+ description="Fillet type",
+ items=Types)
+
+ ##### DRAW #####
+ def draw(self, context):
+ layout = self.layout
+
+ # general options
+ col = layout.column()
+ col.prop(self, 'Fillet_radius')
+ col.prop(self, 'Fillet_Type', expand=True)
+
+ ##### POLL #####
+ @classmethod
+ def poll(cls, context):
+ return context.scene != None
+
+ ##### EXECUTE #####
+ def execute(self, context):
+ # go to object mode
+ if bpy.ops.object.mode_set.poll():
+ bpy.ops.object.mode_set(mode='OBJECT')
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ # turn off undo
+ undo = bpy.context.user_preferences.edit.use_global_undo
+ bpy.context.user_preferences.edit.use_global_undo = False
+
+ # main function
+ spline = bpy.context.object.data.splines.active
+ selected = [p for p in spline.bezier_points if p.select_control_point]
+
+ bpy.ops.curve.handle_type_set(type='VECTOR')
+ n = 0
+ ii = []
+ for p in spline.bezier_points:
+ if p.select_control_point:
+ ii.append(n)
+ n += 1
+ else:
+ n += 1
+
+ if n > 2:
+
+ jn = 0
+
+ for j in ii:
+
+ j += jn
+
+ selected_all = [p for p in spline.bezier_points]
+
+ bpy.ops.curve.select_all(action='DESELECT')
+
+ if j != 0 and j != n - 1:
+ selected_all[j].select_control_point = True
+ selected_all[j + 1].select_control_point = True
+ bpy.ops.curve.subdivide()
+ selected_all = [p for p in spline.bezier_points]
+ selected4 = [selected_all[j - 1], selected_all[j], selected_all[j + 1], selected_all[j + 2]]
+ jn += 1
+ n += 1
+
+ elif j == 0:
+ selected_all[j].select_control_point = True
+ selected_all[j + 1].select_control_point = True
+ bpy.ops.curve.subdivide()
+ selected_all = [p for p in spline.bezier_points]
+ selected4 = [selected_all[n], selected_all[0], selected_all[1], selected_all[2]]
+ jn += 1
+ n += 1
+
+ elif j == n - 1:
+ selected_all[j].select_control_point = True
+ selected_all[j - 1].select_control_point = True
+ bpy.ops.curve.subdivide()
+ selected_all = [p for p in spline.bezier_points]
+ selected4 = [selected_all[0], selected_all[n], selected_all[n - 1], selected_all[n - 2]]
+
+ selected4[2].co = selected4[1].co
+ s1 = Vector(selected4[0].co) - Vector(selected4[1].co)
+ s2 = Vector(selected4[3].co) - Vector(selected4[2].co)
+ s1.normalize()
+ s11 = Vector(selected4[1].co) + s1 * self.Fillet_radius
+ selected4[1].co = s11
+ s2.normalize()
+ s22 = Vector(selected4[2].co) + s2 * self.Fillet_radius
+ selected4[2].co = s22
+
+ if self.Fillet_Type == 'Round':
+ if j != n - 1:
+ selected4[2].handle_right_type = 'VECTOR'
+ selected4[1].handle_left_type = 'VECTOR'
+ selected4[1].handle_right_type = 'ALIGNED'
+ selected4[2].handle_left_type = 'ALIGNED'
+ else:
+ selected4[1].handle_right_type = 'VECTOR'
+ selected4[2].handle_left_type = 'VECTOR'
+ selected4[2].handle_right_type = 'ALIGNED'
+ selected4[1].handle_left_type = 'ALIGNED'
+ if self.Fillet_Type == 'Chamfer':
+ selected4[2].handle_right_type = 'VECTOR'
+ selected4[1].handle_left_type = 'VECTOR'
+ selected4[1].handle_right_type = 'VECTOR'
+ selected4[2].handle_left_type = 'VECTOR'
+
+ bpy.ops.curve.select_all(action='SELECT')
+ bpy.ops.curve.spline_type_set(type='BEZIER')
+
+ # restore pre operator undo state
+ bpy.context.user_preferences.edit.use_global_undo = undo
+
+ return {'FINISHED'}
+
+ ##### INVOKE #####
+ def invoke(self, context, event):
+ self.execute(context)
+
+ return {'FINISHED'}
+
+
+def subdivide_cubic_bezier(p1, p2, p3, p4, t):
+ p12 = (p2 - p1) * t + p1
+ p23 = (p3 - p2) * t + p2
+ p34 = (p4 - p3) * t + p3
+ p123 = (p23 - p12) * t + p12
+ p234 = (p34 - p23) * t + p23
+ p1234 = (p234 - p123) * t + p123
+ return [p12, p123, p1234, p234, p34]
+
+# ------------------------------------------------------------
+# BezierDivide Operator
+
+
+class BezierDivide(bpy.types.Operator):
+ ''''''
+ bl_idname = "curve.bezier_spline_divide"
+ bl_label = "Bezier Divide (enters edit mode) for Fillet Curves"
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = "bezier spline divide"
+
+ # align_matrix for the invoke
+ align_matrix = Matrix()
+
+ Bezier_t = FloatProperty(name="t (0% - 100%)",
+ default=50.0,
+ min=0.0, soft_min=0.0,
+ max=100.0, soft_max=100.0,
+ description="t (0% - 100%)")
+
+ ##### POLL #####
+ @classmethod
+ def poll(cls, context):
+ return context.scene != None
+
+ ##### EXECUTE #####
+ def execute(self, context):
+ # go to object mode
+ if bpy.ops.object.mode_set.poll():
+ bpy.ops.object.mode_set(mode='OBJECT')
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ # turn off undo
+ undo = bpy.context.user_preferences.edit.use_global_undo
+ bpy.context.user_preferences.edit.use_global_undo = False
+
+ # main function
+ spline = bpy.context.object.data.splines.active
+ vertex = []
+ selected_all = [p for p in spline.bezier_points if p.select_control_point]
+ h = subdivide_cubic_bezier(selected_all[0].co, selected_all[0].handle_right, selected_all[1].handle_left, selected_all[1].co, self.Bezier_t / 100)
+
+ selected_all[0].handle_right_type = 'FREE'
+ selected_all[0].handle_left_type = 'FREE'
+ selected_all[1].handle_right_type = 'FREE'
+ selected_all[1].handle_left_type = 'FREE'
+ bpy.ops.curve.subdivide(1)
+ selected_all = [p for p in spline.bezier_points if p.select_control_point]
+
+ selected_all[0].handle_right = h[0]
+ selected_all[1].co = h[2]
+ selected_all[1].handle_left = h[1]
+ selected_all[1].handle_right = h[3]
+ selected_all[2].handle_left = h[4]
+
+ # restore pre operator undo state
+ bpy.context.user_preferences.edit.use_global_undo = undo
+
+ return {'FINISHED'}
+
+ ##### INVOKE #####
+ def invoke(self, context, event):
+ self.execute(context)
+
+ return {'FINISHED'}
+
+# ------------------------------------------------------------
+# Simple change panel
+
+
+class SimplePanel(bpy.types.Panel):
+
+ bl_label = "Simple change"
+ bl_space_type = "VIEW_3D"
+ bl_region_type = "TOOLS"
+ bl_options = {'DEFAULT_CLOSED'}
+ bl_category = "Tools"
+
+ ##### POLL #####
+ @classmethod
+ def poll(cls, context):
+ if not context.active_object:
+ pass
+ elif context.object.Simple == True:
+ return (context.object)
+
+ ##### DRAW #####
+ def draw(self, context):
+ if context.object.Simple == True:
+
+ layout = self.layout
+
+ obj = context.object
+ row = layout.row()
+ simple_change = row.operator("curve.simple", text='Change')
+ simple_change.Simple_Change = True
+ simple_change.Simple_Delete = obj.name
+ simple_change.Simple_Type = obj.Simple_Type
+ simple_change.Simple_startlocation = obj.location
+ simple_change.Simple_endlocation = obj.Simple_endlocation
+ simple_change.Simple_a = obj.Simple_a
+ simple_change.Simple_b = obj.Simple_b
+ simple_change.Simple_h = obj.Simple_h
+ simple_change.Simple_angle = obj.Simple_angle
+ simple_change.Simple_startangle = obj.Simple_startangle
+ simple_change.Simple_endangle = obj.Simple_endangle
+ simple_change.Simple_rotation_euler = obj.rotation_euler
+ simple_change.Simple_sides = obj.Simple_sides
+ simple_change.Simple_radius = obj.Simple_radius
+ simple_change.Simple_center = obj.Simple_center
+ simple_change.Simple_width = obj.Simple_width
+ simple_change.Simple_length = obj.Simple_length
+ simple_change.Simple_rounded = obj.Simple_rounded
+
+# ------------------------------------------------------------
+# Fillet tools panel
+
+
+class SimpleEdit(bpy.types.Operator):
+
+ """Curve Simple"""
+ bl_idname = "object._simple_edit"
+ bl_label = "Create Curves"
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = "Subdivide & Fillet Curves"
+
+ ##### POLL #####
+ @classmethod
+ def poll(cls, context):
+ vertex = []
+ nselected = []
+ n = 0
+ obj = context.active_object
+ if obj != None:
+ if obj.type == 'CURVE':
+ for i in obj.data.splines:
+ for j in i.bezier_points:
+ n += 1
+ if j.select_control_point:
+ nselected.append(n)
+ vertex.append(obj.matrix_world * j.co)
+
+ if len(vertex) > 0 and n > 2:
+ return (context.active_object)
+ if len(vertex) == 2 and abs(nselected[0] - nselected[1]) == 1:
+ return (context.active_object)
+
+ selected = 0
+ for obj in context.selected_objects:
+ if obj.type == 'CURVE':
+ selected += 1
+
+ if selected >= 2:
+ return (context.selected_objects)
+
+ ##### DRAW #####
+ def draw(self, context):
+ vertex = []
+ selected = []
+ n = 0
+ obj = context.active_object
+ if obj != None:
+ if obj.type == 'CURVE':
+ for i in obj.data.splines:
+ for j in i.bezier_points:
+ n += 1
+ if j.select_control_point:
+ selected.append(n)
+ vertex.append(obj.matrix_world * j.co)
+
+ if len(vertex) > 0 and n > 2:
+ layout = self.layout
+ row = layout.row()
+ simple_edit = row.operator("curve.bezier_points_fillet", text='Fillet')
+ if len(vertex) == 2 and abs(selected[0] - selected[1]) == 1:
+ layout = self.layout
+ row = layout.row()
+ simple_divide = row.operator("curve.bezier_spline_divide", text='Divide')
+
+# ------------------------------------------------------------
+# location update
+
+
+def StartLocationUpdate(self, context):
+
+ bpy.context.scene.cursor_location = self.Simple_startlocation
+
+ return
+
+# ------------------------------------------------------------
+# Add properties to objects
+
+
+def SimpleVariables():
+
+ bpy.types.Object.Simple = bpy.props.BoolProperty()
+ bpy.types.Object.Simple_Change = bpy.props.BoolProperty()
+ # general properties
+ Types = [('Point', 'Point', 'Point'),
+ ('Line', 'Line', 'Line'),
+ ('Distance', 'Distance', 'Distance'),
+ ('Angle', 'Angle', 'Angle'),
+ ('Circle', 'Circle', 'Circle'),
+ ('Ellipse', 'Ellipse', 'Ellipse'),
+ ('Arc', 'Arc', 'Arc'),
+ ('Sector', 'Sector', 'Sector'),
+ ('Segment', 'Segment', 'Segment'),
+ ('Rectangle', 'Rectangle', 'Rectangle'),
+ ('Rhomb', 'Rhomb', 'Rhomb'),
+ ('Polygon', 'Polygon', 'Polygon'),
+ ('Polygon_ab', 'Polygon_ab', 'Polygon_ab'),
+ ('Trapezoid', 'Trapezoid', 'Trapezoid')]
+ bpy.types.Object.Simple_Type = bpy.props.EnumProperty(name="Type",
+ description="Form of Curve to create",
+ items=Types)
+
+ # Line properties
+ bpy.types.Object.Simple_startlocation = bpy.props.FloatVectorProperty(name="Start location",
+ description="Start location",
+ default=(0.0, 0.0, 0.0),
+ subtype='TRANSLATION',
+ update=StartLocationUpdate)
+ bpy.types.Object.Simple_endlocation = bpy.props.FloatVectorProperty(name="End location",
+ description="End location",
+ default=(2.0, 2.0, 2.0),
+ subtype='TRANSLATION')
+ bpy.types.Object.Simple_rotation_euler = bpy.props.FloatVectorProperty(name="Rotation",
+ description="Rotation",
+ default=(0.0, 0.0, 0.0),
+ subtype='EULER')
+
+ # Trapezoid properties
+ bpy.types.Object.Simple_a = bpy.props.FloatProperty(name="a",
+ default=2.0,
+ min=0.0, soft_min=0.0,
+ unit='LENGTH',
+ description="a")
+ bpy.types.Object.Simple_b = bpy.props.FloatProperty(name="b",
+ default=1.0,
+ min=0.0, soft_min=0.0,
+ unit='LENGTH',
+ description="b")
+ bpy.types.Object.Simple_h = bpy.props.FloatProperty(name="h",
+ default=1.0,
+ unit='LENGTH',
+ description="h")
+
+ bpy.types.Object.Simple_angle = bpy.props.FloatProperty(name="Angle",
+ default=45.0,
+ description="Angle")
+ bpy.types.Object.Simple_startangle = bpy.props.FloatProperty(name="Start angle",
+ default=0.0,
+ min=-360.0, soft_min=-360.0,
+ max=360.0, soft_max=360.0,
+ description="Start angle")
+ bpy.types.Object.Simple_endangle = bpy.props.FloatProperty(name="End angle",
+ default=45.0,
+ min=-360.0, soft_min=-360.0,
+ max=360.0, soft_max=360.0,
+ description="End angle")
+
+ bpy.types.Object.Simple_sides = bpy.props.IntProperty(name="sides",
+ default=3,
+ min=3, soft_min=3,
+ description="sides")
+
+ bpy.types.Object.Simple_radius = bpy.props.FloatProperty(name="radius",
+ default=1.0,
+ min=0.0, soft_min=0.0,
+ unit='LENGTH',
+ description="radius")
+
+ bpy.types.Object.Simple_center = bpy.props.BoolProperty(name="Length center",
+ default=True,
+ description="Length center")
+
+ # Rectangle properties
+ bpy.types.Object.Simple_width = bpy.props.FloatProperty(name="Width",
+ default=2.0,
+ min=0.0, soft_min=0.0,
+ unit='LENGTH',
+ description="Width")
+ bpy.types.Object.Simple_length = bpy.props.FloatProperty(name="Length",
+ default=2.0,
+ min=0.0, soft_min=0.0,
+ unit='LENGTH',
+ description="Length")
+ bpy.types.Object.Simple_rounded = bpy.props.FloatProperty(name="Rounded",
+ default=0.0,
+ unit='LENGTH',
+ description="Rounded")
+
+################################################################################
+##### REGISTER #####
+
+
+class INFO_MT_simple_menu(bpy.types.Menu):
+ # Define the "Extras" menu
+ bl_idname = "INFO_MT_simple_menu"
+ bl_label = "2D Objects"
+
+ def draw(self, context):
+ self.layout.operator_context = 'INVOKE_REGION_WIN'
+
+ oper2 = self.layout.operator(Simple.bl_idname, text="Point", icon="MOD_CURVE")
+ oper2.Simple_Change = False
+ oper2.Simple_Type = "Point"
+
+ oper3 = self.layout.operator(Simple.bl_idname, text="Line", icon="MOD_CURVE")
+ oper3.Simple_Change = False
+ oper3.Simple_Type = "Line"
+
+ oper4 = self.layout.operator(Simple.bl_idname, text="Distance", icon="MOD_CURVE")
+ oper4.Simple_Change = False
+ oper4.Simple_Type = "Distance"
+
+ oper5 = self.layout.operator(Simple.bl_idname, text="Angle", icon="MOD_CURVE")
+ oper5.Simple_Change = False
+ oper5.Simple_Type = "Angle"
+
+ oper6 = self.layout.operator(Simple.bl_idname, text="Circle", icon="MOD_CURVE")
+ oper6.Simple_Change = False
+ oper6.Simple_Type = "Circle"
+
+ oper7 = self.layout.operator(Simple.bl_idname, text="Ellipse", icon="MOD_CURVE")
+ oper7.Simple_Change = False
+ oper7.Simple_Type = "Ellipse"
+
+ oper8 = self.layout.operator(Simple.bl_idname, text="Arc", icon="MOD_CURVE")
+ oper8.Simple_Change = False
+ oper8.Simple_Type = "Arc"
+
+ oper9 = self.layout.operator(Simple.bl_idname, text="Sector", icon="MOD_CURVE")
+ oper9.Simple_Change = False
+ oper9.Simple_Type = "Sector"
+
+ oper10 = self.layout.operator(Simple.bl_idname, text="Segment", icon="MOD_CURVE")
+ oper10.Simple_Change = False
+ oper10.Simple_Type = "Segment"
+
+ oper11 = self.layout.operator(Simple.bl_idname, text="Rectangle", icon="MOD_CURVE")
+ oper11.Simple_Change = False
+ oper11.Simple_Type = "Rectangle"
+
+ oper12 = self.layout.operator(Simple.bl_idname, text="Rhomb", icon="MOD_CURVE")
+ oper12.Simple_Change = False
+ oper12.Simple_Type = "Rhomb"
+
+ oper13 = self.layout.operator(Simple.bl_idname, text="Polygon", icon="MOD_CURVE")
+ oper13.Simple_Change = False
+ oper13.Simple_Type = "Polygon"
+
+ oper14 = self.layout.operator(Simple.bl_idname, text="Polygon_ab", icon="MOD_CURVE")
+ oper14.Simple_Change = False
+ oper14.Simple_Type = "Polygon_ab"
+
+ oper15 = self.layout.operator(Simple.bl_idname, text="Trapezoid", icon="MOD_CURVE")
+ oper15.Simple_Change = False
+ oper15.Simple_Type = "Trapezoid"
+
+
+def Simple_button(self, context):
+ layout = self.layout
+ layout.separator()
+ oper11 = self.layout.operator(Simple.bl_idname, text="Rectangle", icon="MOD_CURVE")
+ oper11.Simple_Change = False
+ oper11.Simple_Type = "Rectangle"
+
+ self.layout.menu("INFO_MT_simple_menu", icon="MOD_CURVE")
+
+
+def register():
+ bpy.utils.register_class(Simple)
+ bpy.utils.register_class(BezierPointsFillet)
+ bpy.utils.register_class(BezierDivide)
+ bpy.utils.register_class(SimplePanel)
+ bpy.utils.register_class(SimpleEdit)
+ bpy.utils.register_class(INFO_MT_simple_menu)
+
+ bpy.types.INFO_MT_curve_add.append(Simple_button)
+
+ SimpleVariables()
+
+
+def unregister():
+ bpy.utils.unregister_class(Simple)
+ bpy.utils.unregister_class(BezierPointsFillet)
+ bpy.utils.unregister_class(BezierDivide)
+ bpy.utils.unregister_class(SimplePanel)
+ bpy.utils.unregister_class(SimpleEdit)
+ bpy.utils.unregister_class(INFO_MT_simple_menu)
+
+ bpy.types.INFO_MT_curve_add.remove(Simple_button)
+
+if __name__ == "__main__":
+ register()
diff --git a/add_curve_extra_objects/beveltaper_curve.py b/add_curve_extra_objects/beveltaper_curve.py
new file mode 100644
index 00000000..70e910fb
--- /dev/null
+++ b/add_curve_extra_objects/beveltaper_curve.py
@@ -0,0 +1,259 @@
+bl_info = {
+ "name": "Bevel/Taper Curve",
+ "author": "Cmomoney",
+ "version": (1, 1),
+ "blender": (2, 69, 0),
+ "location": "View3D > Object > Bevel/Taper",
+ "description": "Adds bevel and/or taper curve to active curve",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Curve/Bevel_-Taper_Curve",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?func=detail&aid=37377&group_id=153&atid=467",
+ "category": "Curve"}
+
+ # ***** 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 3 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, see <http://www.gnu.org/licenses/>.
+ #
+ # ***** END GPL LICENSE BLOCK *****
+
+import bpy
+from bpy.types import Operator
+from bpy.props import *
+from bpy_extras.object_utils import AddObjectHelper, object_data_add
+from mathutils import Vector
+
+def add_taper(self, context):
+
+ scale_ends1 = self.scale_ends1
+ scale_ends2 = self.scale_ends2
+ scale_mid = self.scale_mid
+ verts = [(-2.0, 1.0 * scale_ends1, 0.0, 1.0),
+ (-1.0, 0.75 * scale_mid, 0.0, 1.0),
+ (0.0, 1.5 * scale_mid, 0.0, 1.0),
+ (1.0, 0.75 * scale_mid, 0.0, 1.0),
+ (2.0, 1.0 * scale_ends2, 0.0, 1.0)]
+ make_path(self, context, verts)
+
+def add_type5(self, context):
+
+ scale_x = self.scale_x
+ scale_y = self.scale_y
+ verts = [[0.0 * scale_x, 0.049549 * scale_y,
+ 0.0, 0.031603 * scale_x, 0.047013 * scale_y,
+ 0.0, 0.05 * scale_x, 0.0 * scale_y, 0.0,
+ 0.031603 * scale_x, -0.047013 * scale_y,
+ 0.0, 0.0 * scale_x, -0.049549 * scale_y,
+ 0.0, -0.031603 * scale_x, -0.047013 * scale_y,
+ 0.0, -0.05 * scale_x, -0.0 * scale_y, 0.0,
+ -0.031603 * scale_x, 0.047013 * scale_y, 0.0]]
+ lhandles = [[(-0.008804 * scale_x, 0.049549 * scale_y, 0.0),
+ (0.021304 * scale_x, 0.02119 * scale_y, 0.0),
+ (0.05 * scale_x, 0.051228 * scale_y, 0.0),
+ (0.036552 * scale_x, -0.059423 * scale_y, 0.0),
+ (0.008804 * scale_x, -0.049549 * scale_y, 0.0),
+ (-0.021304 * scale_x, -0.02119 * scale_y, 0.0),
+ (-0.05 * scale_x, -0.051228 * scale_y, 0.0),
+ (-0.036552 * scale_x, 0.059423 * scale_y, 0.0)]]
+ rhandles = [[(0.008803 * scale_x, 0.049549 * scale_y, 0.0),
+ (0.036552 * scale_x, 0.059423 * scale_y, 0.0),
+ (0.05 * scale_x, -0.051228 * scale_y, 0.0),
+ (0.021304 * scale_x, -0.02119 * scale_y, 0.0),
+ (-0.008803 * scale_x, -0.049549 * scale_y, 0.0),
+ (-0.036552 * scale_x, -0.059423 * scale_y, 0.0),
+ (-0.05 * scale_x, 0.051228 * scale_y, 0.0),
+ (-0.021304 * scale_x, 0.02119 * scale_y, 0.0)]]
+ make_curve(self, context, verts, lhandles, rhandles)
+
+def add_type4(self, context):
+
+ scale_x = self.scale_x
+ scale_y = self.scale_y
+ verts = [[-0.0 * scale_x, 0.017183 * scale_y,
+ 0.0, 0.05 * scale_x, 0.0 * scale_y,
+ 0.0, 0.0 * scale_x, -0.017183 * scale_y,
+ 0.0, -0.05 * scale_x, -0.0 * scale_y, 0.0]]
+ lhandles = [[(-0.017607 * scale_x, 0.017183 * scale_y, 0.0),
+ (0.05 * scale_x, 0.102456 * scale_y, 0.0),
+ (0.017607 * scale_x, -0.017183 * scale_y, 0.0),
+ (-0.05 * scale_x, -0.102456 * scale_y, 0.0)]]
+ rhandles = [[(0.017607 * scale_x, 0.017183 * scale_y, 0.0),
+ (0.05 * scale_x, -0.102456 * scale_y, 0.0),
+ (-0.017607 * scale_x, -0.017183 * scale_y, 0.0),
+ (-0.05 * scale_x, 0.102456 * scale_y, 0.0)]]
+ make_curve(self, context, verts, lhandles, rhandles)
+
+def add_type3(self, context):
+
+ scale_x = self.scale_x
+ scale_y = self.scale_y
+ verts = [[-0.017183 * scale_x, 0.0 * scale_y,
+ 0.0, 0.0 * scale_x, 0.05 * scale_y,
+ 0.0, 0.017183 * scale_x, 0.0 * scale_y,
+ 0.0, 0.0 * scale_x, -0.05 * scale_y, 0.0]]
+ lhandles = [[(-0.017183 * scale_x, -0.017607 * scale_y, 0.0),
+ (-0.102456 * scale_x, 0.05 * scale_y, 0.0),
+ (0.017183 * scale_x, 0.017607 * scale_y, 0.0),
+ (0.102456 * scale_x, -0.05 * scale_y, 0.0)]]
+ rhandles = [[(-0.017183 * scale_x, 0.017607 * scale_y, 0.0),
+ (0.102456 * scale_x, 0.05 * scale_y, 0.0),
+ (0.017183 * scale_x, -0.017607 * scale_y, 0.0),
+ (-0.102456 * scale_x, -0.05 * scale_y, 0.0)]]
+ make_curve(self, context, verts, lhandles, rhandles)
+
+def add_type2(self, context):
+
+ scale_x = self.scale_x
+ scale_y = self.scale_y
+ verts = [[-0.05 * scale_x, 0.0 * scale_y,
+ 0.0, 0.0 * scale_x, 0.05 * scale_y,
+ 0.0, 0.05 * scale_x, 0.0 * scale_y,
+ 0.0, 0.0 * scale_x, -0.05 * scale_y, 0.0]]
+ lhandles = [[(-0.05 * scale_x, -0.047606 * scale_y, 0.0),
+ (-0.047606 * scale_x, 0.05 * scale_y, 0.0),
+ (0.05 * scale_x, 0.047607 * scale_y, 0.0),
+ (0.047606 * scale_x, -0.05 * scale_y, 0.0)]]
+ rhandles = [[(-0.05 * scale_x, 0.047607 * scale_y, 0.0),
+ (0.047607 * scale_x, 0.05 * scale_y, 0.0),
+ (0.05 * scale_x, -0.047607 * scale_y, 0.0),
+ (-0.047607 * scale_x, -0.05 * scale_y, 0.0)]]
+ make_curve(self, context, verts, lhandles, rhandles)
+
+def add_type1(self, context):
+
+ scale_x = self.scale_x
+ scale_y = self.scale_y
+ verts = [[-0.05 * scale_x, 0.0 * scale_y,
+ 0.0, 0.0 * scale_x, 0.05 * scale_y,
+ 0.0, 0.05 * scale_x, 0.0 * scale_y,
+ 0.0, 0.0 * scale_x, -0.05 * scale_y, 0.0]]
+ lhandles = [[(-0.05 * scale_x, -0.027606 * scale_y, 0.0),
+ (-0.027606 * scale_x, 0.05 * scale_y, 0.0),
+ (0.05 * scale_x, 0.027606 * scale_y, 0.0),
+ (0.027606 * scale_x, -0.05 * scale_y, 0.0)]]
+ rhandles = [[(-0.05 * scale_x, 0.027607 * scale_y, 0.0),
+ (0.027607 * scale_x, 0.05 * scale_y, 0.0),
+ (0.05 * scale_x, -0.027607 * scale_y, 0.0),
+ (-0.027607 * scale_x, -0.05 * scale_y, 0.0)]]
+ make_curve(self, context, verts, lhandles, rhandles)
+
+def make_path(self, context, verts):
+
+ target = bpy.context.scene.objects.active
+ bpy.ops.curve.primitive_nurbs_path_add(view_align=False, enter_editmode=False, location=(0, 0, 0))
+ target.data.taper_object = bpy.context.scene.objects.active
+ taper = bpy.context.scene.objects.active
+ taper.name = target.name + '_Taper'
+ bpy.context.scene.objects.active = target
+ points = taper.data.splines[0].points
+ for i in range(len(verts)):
+ points[i].co = verts[i]
+
+def make_curve(self, context, verts, lh, rh):
+
+ scale_x = self.scale_x
+ scale_y = self.scale_y
+ type = self.type
+ target = bpy.context.scene.objects.active
+ curve_data = bpy.data.curves.new(name=target.name +'_Bevel', type='CURVE')
+ curve_data.dimensions = '3D'
+ for p in range(len(verts)):
+ c = 0
+ spline = curve_data.splines.new(type='BEZIER')
+ spline.use_cyclic_u = True
+ spline.bezier_points.add( len(verts[p])/3-1 )
+ spline.bezier_points.foreach_set('co', verts[p])
+ for bp in spline.bezier_points:
+ bp.handle_left_type = 'ALIGNED'
+ bp.handle_right_type = 'ALIGNED'
+ bp.handle_left.xyz = lh[p][c]
+ bp.handle_right.xyz = rh[p][c]
+ c += 1
+ object_data_add(context, curve_data, operator=self)
+ target.data.bevel_object = bpy.context.scene.objects.active
+ bpy.context.scene.objects.active = target
+
+class add_tapercurve(Operator, AddObjectHelper):
+ """Add taper curve to active curve"""
+ bl_idname = "curve.tapercurve"
+ bl_label = "Add Curve as Taper"
+ bl_options = {'REGISTER', 'UNDO'}
+
+
+ scale_ends1 = FloatProperty(name="End Width Left", description="Adjust left end taper", default=0.0, min=0.0)
+ scale_ends2 = FloatProperty(name="End Width Right", description="Adjust right end taper", default=0.0, min=0.0)
+ scale_mid = FloatProperty(name="Center Width", description="Adjust taper at center", default=1.0, min=0.0)
+ link1 = BoolProperty(name='link ends', default=True)
+ link2 = BoolProperty(name='link ends/center', default=False)
+ if link2:
+ diff = FloatProperty(name='Difference', default=1, description='Difference between ends and center while linked')
+
+ def execute(self, context):
+ if self.link1:
+ self.scale_ends2 = self.scale_ends1
+ if self.link2:
+ self.scale_ends2 = self.scale_ends1 = self.scale_mid-self.diff
+ add_taper(self, context)
+ return {'FINISHED'}
+
+class add_bevelcurve(Operator, AddObjectHelper):
+ """Add bevel curve to active curve"""
+ bl_idname = "curve.bevelcurve"
+ bl_label = "Add Curve as Bevel"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ type = IntProperty(name='Type', description='Type of bevel curve', default=1, min=1, max=5)
+ scale_x = FloatProperty(name="scale x", description="scale on x axis", default=1.0)
+ scale_y = FloatProperty(name="scale y", description="scale on y axis", default=1.0)
+ link = BoolProperty(name='link xy', default=True)
+
+ def execute(self, context):
+ if self.link:
+ self.scale_y = self.scale_x
+ if self.type == 1:
+ add_type1(self, context)
+ if self.type == 2:
+ add_type2(self, context)
+ if self.type == 3:
+ add_type3(self, context)
+ if self.type == 4:
+ add_type4(self, context)
+ if self.type == 5:
+ add_type5(self, context)
+
+ return {'FINISHED'}
+
+class Bevel_Taper_Curve_Menu(bpy.types.Menu):
+ bl_label = "Bevel/Taper"
+ bl_idname = "OBJECT_MT_bevel_taper_curve_menu"
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.operator("curve.bevelcurve")
+ layout.operator("curve.tapercurve")
+
+def menu_funcs(self, context):
+ if bpy.context.scene.objects.active.type == "CURVE":
+ self.layout.menu("OBJECT_MT_bevel_taper_curve_menu")
+
+def register():
+ bpy.utils.register_module(__name__)
+ bpy.types.VIEW3D_MT_object.append(menu_funcs)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+ bpy.types.VIEW3D_MT_object.remove(menu_funcs)
+
+if __name__ == "__main__":
+ register()
diff --git a/add_curve_extra_objects/bpybraid.py b/add_curve_extra_objects/bpybraid.py
new file mode 100644
index 00000000..1046843c
--- /dev/null
+++ b/add_curve_extra_objects/bpybraid.py
@@ -0,0 +1,84 @@
+
+from math import sin, cos, pi
+
+from . import braid
+from .braid import angle_point
+
+import bpy
+
+
+def poly_line(curve, points, join=True, type='NURBS'):
+ polyline = curve.splines.new(type)
+ polyline.points.add(len(points) - 1)
+ for num in range(len(points)):
+ polyline.points[num].co = (points[num]) + (1,)
+
+ polyline.order_u = len(polyline.points) - 1
+ if join:
+ polyline.use_cyclic_u = True
+
+
+def poly_lines(objname, curvename, lines, bevel=None, joins=False, ctype='NURBS'):
+ curve = bpy.data.curves.new(name=curvename, type='CURVE')
+ curve.dimensions = '3D'
+
+ obj = bpy.data.objects.new(objname, curve)
+ obj.location = (0, 0, 0) # object origin
+ # ctx.scene.objects.link(obj)
+
+ for i, line in enumerate(lines):
+ poly_line(curve, line, joins if type(joins) == bool else joins[i], type=ctype)
+
+ if bevel:
+ curve.bevel_object = bpy.data.objects[bevel]
+ return obj
+
+
+def nurbs_circle(name, w, h):
+ pts = [(-w / 2, 0, 0), (0, -h / 2, 0), (w / 2, 0, 0), (0, h / 2, 0)]
+ return poly_lines(name, name + '_curve', [pts], joins=True)
+
+
+def star_pts(r=1, ir=None, points=5, center=(0, 0)):
+ '''Create points for a star. They are 2d - z is always zero
+
+ r: the outer radius
+ ir: the inner radius
+ '''
+ if not ir:
+ ir = r / 5
+ pts = []
+ dt = pi * 2 / points
+ for i in range(points):
+ t = i * dt
+ ti = (i + .5) * dt
+ pts.append(angle_point(center, t, r) + (0,))
+ pts.append(angle_point(center, ti, ir) + (0,))
+ return pts
+
+
+def clear():
+ for obj in bpy.data.objects:
+ if obj.type not in ('CAMERA', 'LAMP'):
+ obj.select = True
+ else:
+ obj.select = False
+ bpy.ops.object.delete()
+
+
+def defaultCircle(w=.6):
+ circle = nurbs_circle('braid_circle', w, w)
+ circle.hide = True
+ return circle
+
+
+def defaultStar():
+ star = poly_lines('star', 'staz', [tuple(star_pts(points=5, r=.5, ir=.05))], type='NURBS')
+ star.hide = True
+ return star
+
+
+def awesome_braid(strands=3, sides=5, bevel='braid_circle', pointy=False, **kwds):
+ lines = braid.strands(strands, sides, **kwds)
+ type = {True: 'POLY', False: 'NURBS'}[pointy]
+ return poly_lines('Braid', 'Braid_c', lines, bevel=bevel, joins=True, ctype=type)
diff --git a/add_curve_extra_objects/braid.py b/add_curve_extra_objects/braid.py
new file mode 100644
index 00000000..cebfee17
--- /dev/null
+++ b/add_curve_extra_objects/braid.py
@@ -0,0 +1,60 @@
+
+import math
+from math import sin, cos, pi
+
+
+def angle_point(center, angle, distance):
+ cx, cy = center
+ x = cos(angle) * distance
+ y = sin(angle) * distance
+ return x + cx, y + cy
+
+
+def flat_hump(strands, mx=1, my=1, mz=1, resolution=2):
+ num = 4 * resolution
+ dy = 2 * pi / num
+ dz = 2 * pi * (strands - 1) / num
+ for i in range(num):
+ x = i * mx
+ y = cos(i * dy) * my
+ z = sin(i * dz) * mz
+ # print(i, x, y, z)
+ yield x, y, z
+
+
+def circle_hump(pos, strands, humps, radius=1, mr=1, mz=.2, resolution=2):
+ num = 5 * resolution
+ dt = 2 * pi / humps * strands / num
+ dr = 2 * pi * (strands - 1) / num
+ dz = 2 * pi / num
+ t0 = 2 * pi / humps * pos
+ # print('ds', dt, dr, dz)
+ for i in range(num):
+ # i += pos
+ rdi = sin(i * dr) * mr
+ # print('rdi', rdi, radius, i*dt, i*dz, cos(i*dz) * mz)
+ x, y = angle_point((0, 0), i * dt + t0, radius + sin(i * dr) * mr)
+ z = cos(i * dz) * mz
+ yield x, y, z
+
+
+def strands(strands, humps, radius=1, mr=1, mz=.2, resolution=2):
+ positions = [0 for x in range(humps)]
+ made = 0
+ last = None
+ lines = []
+ at = 0
+ while 0 in positions:
+ if positions[at]:
+ at = positions.index(0)
+ last = None
+ hump = list(circle_hump(at, strands, humps, radius, mr, mz, resolution))
+ if last is None:
+ last = hump
+ lines.append(last)
+ else:
+ last.extend(hump)
+ positions[at] = 1
+ at += strands
+ at %= humps
+ return lines