Update add curve extra objects Re: T50943
This commit is contained in:
parent
f14b4f40c1
commit
fcf5f2842a
Notes:
blender-bot
2023-02-14 20:14:15 +01:00
Referenced by issue #50943, Update: Add Curve Extra Objects Referenced by issue #37377, This addon adds a bevel and/or taper curve to the currently active curve. Referenced by issue #37299, Adds curled curves for use in scrollwork or flourish designs Referenced by issue #36460, Add a Braided Torus
|
@ -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()
|
||||
|
|
|
@ -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,15 +193,52 @@ 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)
|
||||
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 == 0:
|
||||
# Arrow1:
|
||||
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 == 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)
|
||||
|
@ -209,45 +246,28 @@ def MiscCurve(type=1, a=1.0, b=0.5, c=1.0):
|
|||
(type=float)
|
||||
c - c scaling parameter
|
||||
(type=float)
|
||||
doesn't seem to do anything
|
||||
Returns:
|
||||
a list with lists of x,y,z coordinates for curve points, [[x,y,z],[x,y,z],...n]
|
||||
(type=list)
|
||||
"""
|
||||
|
||||
newpoints = []
|
||||
a *= 0.5
|
||||
b *= 0.5
|
||||
if type == 1:
|
||||
# diamond:
|
||||
newpoints = [[0.0, b, 0.0], [a, 0.0, 0.0], [0.0, -b, 0.0], [-a, 0.0, 0.0]]
|
||||
elif type == 2:
|
||||
# Arrow1:
|
||||
newpoints = [[-a, b, 0.0], [a, 0.0, 0.0], [-a, -b, 0.0], [0.0, 0.0, 0.0]]
|
||||
elif type == 3:
|
||||
# Arrow2:
|
||||
newpoints = [[-1.0, b, 0.0], [-1.0+a, b, 0.0],
|
||||
[-1.0+a, 1.0, 0.0], [1.0, 0.0, 0.0],
|
||||
[-1.0+a, -1.0, 0.0], [-1.0+a, -b, 0.0],
|
||||
[-1.0, -b, 0.0]]
|
||||
elif type == 4:
|
||||
# Rounded square:
|
||||
# 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):
|
||||
"""
|
||||
CycloidCurve( number=24, length=2.0, type=0, a=1.0, b=1.0, startangle=0.0, endangle=360.0 )
|
||||
#------------------------------------------------------------
|
||||
# Cycloid curve
|
||||
|
||||
Create a Cycloid, Epicycloid or Hypocycloid curve
|
||||
def CycloidCurve(number=100, type=0, R=4.0, r=1.0, d=1.0):
|
||||
"""
|
||||
CycloidCurve( number=100, type=0, a=4.0, b=1.0 )
|
||||
|
||||
Create a Cycloid, Hypotrochoid / Hypocycloid or Epitrochoid / Epycycloid type of curve
|
||||
|
||||
Parameters:
|
||||
number - the number of points
|
||||
(type=int)
|
||||
length - length of curve
|
||||
type - types: Cycloid, Hypocycloid, Epicycloid
|
||||
(type=int)
|
||||
R = Radius a scaling parameter
|
||||
(type=float)
|
||||
type - types: Cycloid, Epicycloid, Hypocycloid
|
||||
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 = []
|
||||
step = (2.0/(number-1))
|
||||
i = 0
|
||||
if type == 1:
|
||||
# Hypotrochoid / Hypocycloid
|
||||
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
|
||||
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 = []
|
||||
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 = (length/number)
|
||||
i = 0
|
||||
if type == 0: # Epitrochoid
|
||||
if type == 1:
|
||||
# noise knot
|
||||
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)+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
|
||||
|
||||
|
|
|
@ -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()
|
|
@ -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()
|
|
@ -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()
|
File diff suppressed because it is too large
Load Diff
|
@ -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()
|
|
@ -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)
|
|
@ -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
|
Loading…
Reference in New Issue