mirror of
https://github.com/blender/blender-addons.git
synced 2025-07-25 16:05:20 +00:00
1500 lines
44 KiB
Python
1500 lines
44 KiB
Python
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
"""
|
|
bl_info = {
|
|
"name": "Curveaceous Galore!",
|
|
"author": "Jimmy Hazevoet, testscreenings",
|
|
"version": (0, 2, 3),
|
|
"blender": (2, 80),
|
|
"location": "View3D > Add > Curve",
|
|
"description": "Adds many different types of Curves",
|
|
"warning": "",
|
|
"doc_url": "{BLENDER_MANUAL_URL}/addons/add_curve/extra_objects.html",
|
|
"category": "Add Curve",
|
|
}
|
|
"""
|
|
|
|
import bpy
|
|
from bpy_extras import object_utils
|
|
from bpy.props import (
|
|
BoolProperty,
|
|
EnumProperty,
|
|
FloatProperty,
|
|
IntProperty,
|
|
FloatVectorProperty
|
|
)
|
|
from mathutils import Matrix, Vector
|
|
from bpy.types import Operator
|
|
from math import (
|
|
sin, cos, pi
|
|
)
|
|
import mathutils.noise as Noise
|
|
|
|
|
|
# ------------------------------------------------------------
|
|
# Some functions to use with others:
|
|
# ------------------------------------------------------------
|
|
|
|
# ------------------------------------------------------------
|
|
# Generate random number:
|
|
def randnum(low=0.0, high=1.0, seed=0):
|
|
"""
|
|
randnum( low=0.0, high=1.0, seed=0 )
|
|
|
|
Create random number
|
|
Parameters:
|
|
low - lower range
|
|
(type=float)
|
|
high - higher range
|
|
(type=float)
|
|
seed - the random seed number, if seed == 0, the current time will be used instead
|
|
(type=int)
|
|
Returns:
|
|
a random number
|
|
(type=float)
|
|
"""
|
|
|
|
Noise.seed_set(seed)
|
|
rnum = Noise.random()
|
|
rnum = rnum * (high - low)
|
|
rnum = rnum + low
|
|
return rnum
|
|
|
|
|
|
# ------------------------------------------------------------
|
|
# Make some noise:
|
|
def vTurbNoise(x, y, z, iScale=0.25, Size=1.0, Depth=6, Hard=False, Basis=0, Seed=0):
|
|
"""
|
|
vTurbNoise((x,y,z), iScale=0.25, Size=1.0, Depth=6, Hard=0, Basis=0, Seed=0 )
|
|
|
|
Create randomised vTurbulence noise
|
|
|
|
Parameters:
|
|
xyz - (x,y,z) float values.
|
|
(type=3-float tuple)
|
|
iScale - noise intensity scale
|
|
(type=float)
|
|
Size - noise size
|
|
(type=float)
|
|
Depth - number of noise values added.
|
|
(type=int)
|
|
Hard - noise hardness: True - soft noise; False - hard noise
|
|
(type=int)
|
|
basis - type of noise used for turbulence
|
|
(type=int)
|
|
Seed - the random seed number, if seed == 0, the current time will be used instead
|
|
(type=int)
|
|
Returns:
|
|
the generated turbulence vector.
|
|
(type=3-float list)
|
|
"""
|
|
rand = randnum(-100, 100, Seed)
|
|
if Basis == 9:
|
|
Basis = 14
|
|
vec = Vector((x / Size + rand, y / Size + rand, z / Size + rand))
|
|
vTurb = Noise.turbulence_vector(vec, Depth, Hard)
|
|
#mathutils.noise.turbulence_vector(position, octaves, hard, noise_basis='PERLIN_ORIGINAL', amplitude_scale=0.5, frequency_scale=2.0)
|
|
tx = vTurb[0] * iScale
|
|
ty = vTurb[1] * iScale
|
|
tz = vTurb[2] * iScale
|
|
return tx, ty, tz
|
|
|
|
|
|
# -------------------------------------------------------------------
|
|
# 2D Curve shape functions:
|
|
# -------------------------------------------------------------------
|
|
|
|
# ------------------------------------------------------------
|
|
# 2DCurve: Profile: L, H, T, U, Z
|
|
def ProfileCurve(type=0, a=0.25, b=0.25):
|
|
"""
|
|
ProfileCurve( type=0, a=0.25, b=0.25 )
|
|
|
|
Create profile curve
|
|
|
|
Parameters:
|
|
type - select profile type, L, H, T, U, Z
|
|
(type=int)
|
|
a - a scaling parameter
|
|
(type=float)
|
|
b - b scaling parameter
|
|
(type=float)
|
|
Returns:
|
|
a list with lists of x,y,z coordinates for curve points, [[x,y,z],[x,y,z],...n]
|
|
(type=list)
|
|
"""
|
|
|
|
newpoints = []
|
|
if type == 1:
|
|
# H:
|
|
a *= 0.5
|
|
b *= 0.5
|
|
newpoints = [
|
|
[-1.0, 1.0, 0.0], [-1.0 + a, 1.0, 0.0],
|
|
[-1.0 + a, b, 0.0], [1.0 - a, b, 0.0], [1.0 - a, 1.0, 0.0],
|
|
[1.0, 1.0, 0.0], [1.0, -1.0, 0.0], [1.0 - a, -1.0, 0.0],
|
|
[1.0 - a, -b, 0.0], [-1.0 + a, -b, 0.0], [-1.0 + a, -1.0, 0.0],
|
|
[-1.0, -1.0, 0.0]
|
|
]
|
|
elif type == 2:
|
|
# T:
|
|
a *= 0.5
|
|
newpoints = [
|
|
[-1.0, 1.0, 0.0], [1.0, 1.0, 0.0],
|
|
[1.0, 1.0 - b, 0.0], [a, 1.0 - b, 0.0], [a, -1.0, 0.0],
|
|
[-a, -1.0, 0.0], [-a, 1.0 - b, 0.0], [-1.0, 1.0 - b, 0.0]
|
|
]
|
|
elif type == 3:
|
|
# U:
|
|
a *= 0.5
|
|
newpoints = [
|
|
[-1.0, 1.0, 0.0], [-1.0 + a, 1.0, 0.0],
|
|
[-1.0 + a, -1.0 + b, 0.0], [1.0 - a, -1.0 + b, 0.0], [1.0 - a, 1.0, 0.0],
|
|
[1.0, 1.0, 0.0], [1.0, -1.0, 0.0], [-1.0, -1.0, 0.0]
|
|
]
|
|
elif type == 4:
|
|
# Z:
|
|
a *= 0.5
|
|
newpoints = [
|
|
[-0.5, 1.0, 0.0], [a, 1.0, 0.0],
|
|
[a, -1.0 + b, 0.0], [1.0, -1.0 + b, 0.0], [1.0, -1.0, 0.0],
|
|
[-a, -1.0, 0.0], [-a, 1.0 - b, 0.0], [-1.0, 1.0 - b, 0.0],
|
|
[-1.0, 1.0, 0.0]
|
|
]
|
|
else:
|
|
# L:
|
|
newpoints = [
|
|
[-1.0, 1.0, 0.0], [-1.0 + a, 1.0, 0.0],
|
|
[-1.0 + a, -1.0 + b, 0.0], [1.0, -1.0 + b, 0.0],
|
|
[1.0, -1.0, 0.0], [-1.0, -1.0, 0.0]
|
|
]
|
|
return newpoints
|
|
|
|
|
|
# ------------------------------------------------------------
|
|
# 2DCurve: Arrow
|
|
def ArrowCurve(type=1, a=1.0, b=0.5):
|
|
"""
|
|
ArrowCurve( type=1, a=1.0, b=0.5, c=1.0 )
|
|
|
|
Create arrow curve
|
|
|
|
Parameters:
|
|
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 curve
|
|
|
|
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 == 2:
|
|
# Rounded Rectangle II:
|
|
newpoints = []
|
|
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])
|
|
newpoints.append([x, y - r, 0])
|
|
newpoints.append([x, -y + r, 0])
|
|
newpoints.append([x - r, -y, 0])
|
|
newpoints.append([-x + r, -y, 0])
|
|
newpoints.append([-x, -y + r, 0])
|
|
newpoints.append([-x, y - r, 0])
|
|
else:
|
|
newpoints.append([-x, y, 0])
|
|
newpoints.append([x, y, 0])
|
|
newpoints.append([x, -y, 0])
|
|
newpoints.append([-x, -y, 0])
|
|
else:
|
|
# Rectangle:
|
|
newpoints = [[-a, b, 0.0], [a, b, 0.0], [a, -b, 0.0], [-a, -b, 0.0]]
|
|
return newpoints
|
|
|
|
|
|
# ------------------------------------------------------------
|
|
# 2DCurve: Star:
|
|
def StarCurve(starpoints=8, innerradius=0.5, outerradius=1.0, twist=0.0):
|
|
"""
|
|
StarCurve( starpoints=8, innerradius=0.5, outerradius=1.0, twist=0.0 )
|
|
|
|
Create star shaped curve
|
|
|
|
Parameters:
|
|
starpoints - the number of points
|
|
(type=int)
|
|
innerradius - innerradius
|
|
(type=float)
|
|
outerradius - outerradius
|
|
(type=float)
|
|
twist - twist amount
|
|
(type=float)
|
|
Returns:
|
|
a list with lists of x,y,z coordinates for curve points, [[x,y,z],[x,y,z],...n]
|
|
(type=list)
|
|
"""
|
|
|
|
newpoints = []
|
|
step = 2.0 / starpoints
|
|
i = 0
|
|
while i < starpoints:
|
|
t = i * step
|
|
x1 = cos(t * pi) * outerradius
|
|
y1 = sin(t * pi) * outerradius
|
|
newpoints.append([x1, y1, 0])
|
|
x2 = cos(t * pi + (pi / starpoints + twist)) * innerradius
|
|
y2 = sin(t * pi + (pi / starpoints + twist)) * innerradius
|
|
newpoints.append([x2, y2, 0])
|
|
i += 1
|
|
return newpoints
|
|
|
|
|
|
# ------------------------------------------------------------
|
|
# 2DCurve: Flower:
|
|
def FlowerCurve(petals=8, innerradius=0.5, outerradius=1.0, petalwidth=2.0):
|
|
"""
|
|
FlowerCurve( petals=8, innerradius=0.5, outerradius=1.0, petalwidth=2.0 )
|
|
|
|
Create flower shaped curve
|
|
|
|
Parameters:
|
|
petals - the number of petals
|
|
(type=int)
|
|
innerradius - innerradius
|
|
(type=float)
|
|
outerradius - outerradius
|
|
(type=float)
|
|
petalwidth - width of petals
|
|
(type=float)
|
|
Returns:
|
|
a list with lists of x,y,z coordinates for curve points, [[x,y,z],[x,y,z],...n]
|
|
(type=list)
|
|
"""
|
|
|
|
newpoints = []
|
|
step = 2.0 / petals
|
|
pet = (step / pi * 2) * petalwidth
|
|
i = 0
|
|
while i < petals:
|
|
t = i * step
|
|
x1 = cos(t * pi - (pi / petals)) * innerradius
|
|
y1 = sin(t * pi - (pi / petals)) * innerradius
|
|
newpoints.append([x1, y1, 0])
|
|
x2 = cos(t * pi - pet) * outerradius
|
|
y2 = sin(t * pi - pet) * outerradius
|
|
newpoints.append([x2, y2, 0])
|
|
x3 = cos(t * pi + pet) * outerradius
|
|
y3 = sin(t * pi + pet) * outerradius
|
|
newpoints.append([x3, y3, 0])
|
|
i += 1
|
|
return newpoints
|
|
|
|
|
|
# ------------------------------------------------------------
|
|
# 2DCurve: Arc,Sector,Segment,Ring:
|
|
def ArcCurve(sides=6, startangle=0.0, endangle=90.0, innerradius=0.5, outerradius=1.0, type=3):
|
|
"""
|
|
ArcCurve( sides=6, startangle=0.0, endangle=90.0, innerradius=0.5, outerradius=1.0, type=3 )
|
|
|
|
Create arc shaped curve
|
|
|
|
Parameters:
|
|
sides - number of sides
|
|
(type=int)
|
|
startangle - startangle
|
|
(type=float)
|
|
endangle - endangle
|
|
(type=float)
|
|
innerradius - innerradius
|
|
(type=float)
|
|
outerradius - outerradius
|
|
(type=float)
|
|
type - select type Arc,Sector,Segment,Ring
|
|
(type=int)
|
|
Returns:
|
|
a list with lists of x,y,z coordinates for curve points, [[x,y,z],[x,y,z],...n]
|
|
(type=list)
|
|
"""
|
|
|
|
newpoints = []
|
|
sides += 1
|
|
angle = 2.0 * (1.0 / 360.0)
|
|
endangle -= startangle
|
|
step = (angle * endangle) / (sides - 1)
|
|
i = 0
|
|
while i < sides:
|
|
t = (i * step) + angle * startangle
|
|
x1 = sin(t * pi) * outerradius
|
|
y1 = cos(t * pi) * outerradius
|
|
newpoints.append([x1, y1, 0])
|
|
i += 1
|
|
|
|
# if type == 1:
|
|
# Arc: turn cyclic curve flag off!
|
|
|
|
# Segment:
|
|
if type == 2:
|
|
newpoints.append([0, 0, 0])
|
|
# Ring:
|
|
elif type == 3:
|
|
j = sides - 1
|
|
while j > -1:
|
|
t = (j * step) + angle * startangle
|
|
x2 = sin(t * pi) * innerradius
|
|
y2 = cos(t * pi) * innerradius
|
|
newpoints.append([x2, y2, 0])
|
|
j -= 1
|
|
return newpoints
|
|
|
|
|
|
# ------------------------------------------------------------
|
|
# 2DCurve: Cog wheel:
|
|
def CogCurve(theeth=8, innerradius=0.8, middleradius=0.95, outerradius=1.0, bevel=0.5):
|
|
"""
|
|
CogCurve( theeth=8, innerradius=0.8, middleradius=0.95, outerradius=1.0, bevel=0.5 )
|
|
|
|
Create cog wheel shaped curve
|
|
|
|
Parameters:
|
|
theeth - number of theeth
|
|
(type=int)
|
|
innerradius - innerradius
|
|
(type=float)
|
|
middleradius - middleradius
|
|
(type=float)
|
|
outerradius - outerradius
|
|
(type=float)
|
|
bevel - bevel amount
|
|
(type=float)
|
|
Returns:
|
|
a list with lists of x,y,z coordinates for curve points, [[x,y,z],[x,y,z],...n]
|
|
(type=list)
|
|
"""
|
|
|
|
newpoints = []
|
|
step = 2.0 / theeth
|
|
pet = step / pi * 2
|
|
bevel = 1.0 - bevel
|
|
i = 0
|
|
while i < theeth:
|
|
t = i * step
|
|
x1 = cos(t * pi - (pi / theeth) - pet) * innerradius
|
|
y1 = sin(t * pi - (pi / theeth) - pet) * innerradius
|
|
newpoints.append([x1, y1, 0])
|
|
x2 = cos(t * pi - (pi / theeth) + pet) * innerradius
|
|
y2 = sin(t * pi - (pi / theeth) + pet) * innerradius
|
|
newpoints.append([x2, y2, 0])
|
|
x3 = cos(t * pi - pet) * middleradius
|
|
y3 = sin(t * pi - pet) * middleradius
|
|
newpoints.append([x3, y3, 0])
|
|
x4 = cos(t * pi - (pet * bevel)) * outerradius
|
|
y4 = sin(t * pi - (pet * bevel)) * outerradius
|
|
newpoints.append([x4, y4, 0])
|
|
x5 = cos(t * pi + (pet * bevel)) * outerradius
|
|
y5 = sin(t * pi + (pet * bevel)) * outerradius
|
|
newpoints.append([x5, y5, 0])
|
|
x6 = cos(t * pi + pet) * middleradius
|
|
y6 = sin(t * pi + pet) * middleradius
|
|
newpoints.append([x6, y6, 0])
|
|
i += 1
|
|
return newpoints
|
|
|
|
|
|
# ------------------------------------------------------------
|
|
# 2DCurve: nSide:
|
|
def nSideCurve(sides=6, radius=1.0):
|
|
"""
|
|
nSideCurve( sides=6, radius=1.0 )
|
|
|
|
Create n-sided curve
|
|
|
|
Parameters:
|
|
sides - number of sides
|
|
(type=int)
|
|
radius - radius
|
|
(type=float)
|
|
Returns:
|
|
a list with lists of x,y,z coordinates for curve points, [[x,y,z],[x,y,z],...n]
|
|
(type=list)
|
|
"""
|
|
|
|
newpoints = []
|
|
step = 2.0 / sides
|
|
i = 0
|
|
while i < sides:
|
|
t = i * step
|
|
x = sin(t * pi) * radius
|
|
y = cos(t * pi) * radius
|
|
newpoints.append([x, y, 0])
|
|
i += 1
|
|
return newpoints
|
|
|
|
|
|
# ------------------------------------------------------------
|
|
# 2DCurve: Splat:
|
|
def SplatCurve(sides=24, scale=1.0, seed=0, basis=0, radius=1.0):
|
|
"""
|
|
SplatCurve( sides=24, scale=1.0, seed=0, basis=0, radius=1.0 )
|
|
|
|
Create splat curve
|
|
|
|
Parameters:
|
|
sides - number of sides
|
|
(type=int)
|
|
scale - noise size
|
|
(type=float)
|
|
seed - noise random seed
|
|
(type=int)
|
|
basis - noise basis
|
|
(type=int)
|
|
radius - radius
|
|
(type=float)
|
|
Returns:
|
|
a list with lists of x,y,z coordinates for curve points, [[x,y,z],[x,y,z],...n]
|
|
(type=list)
|
|
"""
|
|
|
|
newpoints = []
|
|
step = 2.0 / sides
|
|
i = 0
|
|
while i < sides:
|
|
t = i * step
|
|
turb = vTurbNoise(t, t, t, 1.0, scale, 6, False, basis, seed)
|
|
turb = turb[2] * 0.5 + 0.5
|
|
x = sin(t * pi) * radius * turb
|
|
y = cos(t * pi) * radius * turb
|
|
newpoints.append([x, y, 0])
|
|
i += 1
|
|
return newpoints
|
|
|
|
|
|
# -----------------------------------------------------------
|
|
# Cycloid 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)
|
|
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 = []
|
|
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)
|
|
x = (t - sin(t) * b) * a / pi
|
|
y = (1 - cos(t) * b) * a / pi
|
|
z = 0
|
|
newpoints.append([x, y, z])
|
|
i += 1
|
|
return newpoints
|
|
|
|
|
|
# -----------------------------------------------------------
|
|
# 3D curve shape functions:
|
|
# -----------------------------------------------------------
|
|
|
|
# ------------------------------------------------------------
|
|
# 3DCurve: Helix:
|
|
def HelixCurve(number=100, height=2.0, startangle=0.0, endangle=360.0, width=1.0, a=0.0, b=0.0):
|
|
"""
|
|
HelixCurve( number=100, height=2.0, startangle=0.0, endangle=360.0, width=1.0, a=0.0, b=0.0 )
|
|
|
|
Create helix curve
|
|
|
|
Parameters:
|
|
number - the number of points
|
|
(type=int)
|
|
height - height
|
|
(type=float)
|
|
startangle - startangle
|
|
(type=float)
|
|
endangle - endangle
|
|
(type=float)
|
|
width - width
|
|
(type=float)
|
|
a - a
|
|
(type=float)
|
|
b - b
|
|
(type=float)
|
|
Returns:
|
|
a list with lists of x,y,z coordinates for curve points, [[x,y,z],[x,y,z],...n]
|
|
(type=list)
|
|
"""
|
|
|
|
newpoints = []
|
|
angle = (2.0 / 360.0) * (endangle - startangle)
|
|
step = angle / (number - 1)
|
|
h = height / angle
|
|
start = startangle * 2.0 / 360.0
|
|
a /= angle
|
|
i = 0
|
|
while i < number:
|
|
t = (i * step + start)
|
|
x = sin((t * pi)) * (1.0 + cos(t * pi * a - (b * pi))) * (0.25 * width)
|
|
y = cos((t * pi)) * (1.0 + cos(t * pi * a - (b * pi))) * (0.25 * width)
|
|
z = (t * h) - h * start
|
|
newpoints.append([x, y, z])
|
|
i += 1
|
|
return newpoints
|
|
|
|
|
|
# -----------------------------------------------------------
|
|
# 3D Noise curve
|
|
def NoiseCurve(type=0, number=100, length=2.0, size=0.5,
|
|
scale=[0.5, 0.5, 0.5], octaves=2, basis=0, seed=0):
|
|
"""
|
|
Create noise curve
|
|
|
|
Parameters:
|
|
number - number of points
|
|
(type=int)
|
|
length - curve length
|
|
(type=float)
|
|
size - noise size
|
|
(type=float)
|
|
scale - noise intensity scale x,y,z
|
|
(type=list)
|
|
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)
|
|
"""
|
|
|
|
newpoints = []
|
|
step = (length / number)
|
|
i = 0
|
|
if type == 1:
|
|
# noise circle
|
|
while i < number:
|
|
t = i * step
|
|
v = vTurbNoise(t, t, t, 1.0, size, octaves, False, basis, seed)
|
|
x = sin(t * pi) + (v[0] * scale[0])
|
|
y = cos(t * pi) + (v[1] * scale[1])
|
|
z = v[2] * scale[2]
|
|
newpoints.append([x, y, z])
|
|
i += 1
|
|
elif type == 2:
|
|
# noise knot / ball
|
|
while i < number:
|
|
t = i * step
|
|
v = vTurbNoise(t, t, t, 1.0, 1.0, octaves, False, basis, seed)
|
|
x = v[0] * scale[0] * size
|
|
y = v[1] * scale[1] * size
|
|
z = v[2] * scale[2] * size
|
|
newpoints.append([x, y, z])
|
|
i += 1
|
|
else:
|
|
# noise linear
|
|
while i < number:
|
|
t = i * step
|
|
v = vTurbNoise(t, t, t, 1.0, size, octaves, False, basis, seed)
|
|
x = t + v[0] * scale[0]
|
|
y = v[1] * scale[1]
|
|
z = v[2] * scale[2]
|
|
newpoints.append([x, y, z])
|
|
i += 1
|
|
return newpoints
|
|
|
|
|
|
# get array of vertcoordinates according to splinetype
|
|
def vertsToPoints(Verts, splineType):
|
|
|
|
# main vars
|
|
vertArray = []
|
|
|
|
# array for BEZIER spline output (V3)
|
|
if splineType == 'BEZIER':
|
|
for v in Verts:
|
|
vertArray += v
|
|
|
|
# array for nonBEZIER output (V4)
|
|
else:
|
|
for v in Verts:
|
|
vertArray += v
|
|
if splineType == 'NURBS':
|
|
# for nurbs w=1
|
|
vertArray.append(1)
|
|
else:
|
|
# for poly w=0
|
|
vertArray.append(0)
|
|
return vertArray
|
|
|
|
|
|
# create new CurveObject from vertarray and splineType
|
|
def createCurve(context, vertArray, self):
|
|
# output splineType 'POLY' 'NURBS' 'BEZIER'
|
|
splineType = self.outputType
|
|
|
|
# GalloreType as name
|
|
name = self.ProfileType
|
|
|
|
# create object
|
|
if bpy.context.mode == 'EDIT_CURVE':
|
|
Curve = context.active_object
|
|
newSpline = Curve.data.splines.new(type=splineType) # spline
|
|
else:
|
|
# create curve
|
|
dataCurve = bpy.data.curves.new(name, type='CURVE') # curve data block
|
|
newSpline = dataCurve.splines.new(type=splineType) # spline
|
|
|
|
# create object with newCurve
|
|
Curve = object_utils.object_data_add(context, dataCurve, operator=self) # place in active scene
|
|
|
|
# set newSpline Options
|
|
newSpline.use_cyclic_u = self.use_cyclic_u
|
|
newSpline.use_endpoint_u = self.endp_u
|
|
newSpline.order_u = self.order_u
|
|
|
|
# set curve Options
|
|
Curve.data.dimensions = self.shape
|
|
Curve.data.use_path = True
|
|
if self.shape == '3D':
|
|
Curve.data.fill_mode = 'FULL'
|
|
else:
|
|
Curve.data.fill_mode = 'BOTH'
|
|
|
|
for spline in Curve.data.splines:
|
|
if spline.type == 'BEZIER':
|
|
for point in spline.bezier_points:
|
|
point.select_control_point = False
|
|
point.select_left_handle = False
|
|
point.select_right_handle = False
|
|
else:
|
|
for point in spline.points:
|
|
point.select = False
|
|
|
|
# create spline from vertarray
|
|
if splineType == 'BEZIER':
|
|
newSpline.bezier_points.add(int(len(vertArray) * 0.33))
|
|
newSpline.bezier_points.foreach_set('co', vertArray)
|
|
for point in newSpline.bezier_points:
|
|
point.handle_right_type = self.handleType
|
|
point.handle_left_type = self.handleType
|
|
point.select_control_point = True
|
|
point.select_left_handle = True
|
|
point.select_right_handle = True
|
|
else:
|
|
newSpline.points.add(int(len(vertArray) * 0.25 - 1))
|
|
newSpline.points.foreach_set('co', vertArray)
|
|
newSpline.use_endpoint_u = True
|
|
for point in newSpline.points:
|
|
point.select = True
|
|
|
|
# move and rotate spline in edit mode
|
|
if bpy.context.mode == 'EDIT_CURVE':
|
|
if self.align == "WORLD":
|
|
location = self.location - context.active_object.location
|
|
bpy.ops.transform.translate(value = location, orient_type='GLOBAL')
|
|
bpy.ops.transform.rotate(value = self.rotation[0], orient_axis = 'X', orient_type='GLOBAL')
|
|
bpy.ops.transform.rotate(value = self.rotation[1], orient_axis = 'Y', orient_type='GLOBAL')
|
|
bpy.ops.transform.rotate(value = self.rotation[2], orient_axis = 'Z', orient_type='GLOBAL')
|
|
|
|
elif self.align == "VIEW":
|
|
bpy.ops.transform.translate(value = self.location)
|
|
bpy.ops.transform.rotate(value = self.rotation[0], orient_axis = 'X')
|
|
bpy.ops.transform.rotate(value = self.rotation[1], orient_axis = 'Y')
|
|
bpy.ops.transform.rotate(value = self.rotation[2], orient_axis = 'Z')
|
|
|
|
elif self.align == "CURSOR":
|
|
location = context.active_object.location
|
|
self.location = bpy.context.scene.cursor.location - location
|
|
self.rotation = bpy.context.scene.cursor.rotation_euler
|
|
|
|
bpy.ops.transform.translate(value = self.location)
|
|
bpy.ops.transform.rotate(value = self.rotation[0], orient_axis = 'X')
|
|
bpy.ops.transform.rotate(value = self.rotation[1], orient_axis = 'Y')
|
|
bpy.ops.transform.rotate(value = self.rotation[2], orient_axis = 'Z')
|
|
|
|
return
|
|
|
|
|
|
# ------------------------------------------------------------
|
|
# Main Function
|
|
def main(context, self):
|
|
# options
|
|
proType = self.ProfileType
|
|
splineType = self.outputType
|
|
innerRadius = self.innerRadius
|
|
middleRadius = self.middleRadius
|
|
outerRadius = self.outerRadius
|
|
|
|
# get verts
|
|
if proType == 'Profile':
|
|
verts = ProfileCurve(
|
|
self.ProfileCurveType,
|
|
self.ProfileCurvevar1,
|
|
self.ProfileCurvevar2
|
|
)
|
|
if proType == 'Arrow':
|
|
verts = ArrowCurve(
|
|
self.MiscCurveType,
|
|
self.MiscCurvevar1,
|
|
self.MiscCurvevar2
|
|
)
|
|
if proType == 'Rectangle':
|
|
verts = RectCurve(
|
|
self.MiscCurveType,
|
|
self.MiscCurvevar1,
|
|
self.MiscCurvevar2,
|
|
self.MiscCurvevar3
|
|
)
|
|
if proType == 'Flower':
|
|
verts = FlowerCurve(
|
|
self.petals,
|
|
innerRadius,
|
|
outerRadius,
|
|
self.petalWidth
|
|
)
|
|
if proType == 'Star':
|
|
verts = StarCurve(
|
|
self.starPoints,
|
|
innerRadius,
|
|
outerRadius,
|
|
self.starTwist
|
|
)
|
|
if proType == 'Arc':
|
|
verts = ArcCurve(
|
|
self.arcSides,
|
|
self.startAngle,
|
|
self.endAngle,
|
|
innerRadius,
|
|
outerRadius,
|
|
self.arcType
|
|
)
|
|
if proType == 'Cogwheel':
|
|
verts = CogCurve(
|
|
self.teeth,
|
|
innerRadius,
|
|
middleRadius,
|
|
outerRadius,
|
|
self.bevel
|
|
)
|
|
if proType == 'Nsided':
|
|
verts = nSideCurve(
|
|
self.Nsides,
|
|
outerRadius
|
|
)
|
|
if proType == 'Splat':
|
|
verts = SplatCurve(
|
|
self.splatSides,
|
|
self.splatScale,
|
|
self.seed,
|
|
self.basis,
|
|
outerRadius
|
|
)
|
|
if proType == 'Cycloid':
|
|
verts = CycloidCurve(
|
|
self.cycloPoints,
|
|
self.cycloType,
|
|
self.cyclo_a,
|
|
self.cyclo_b,
|
|
self.cyclo_d
|
|
)
|
|
if proType == 'Helix':
|
|
verts = HelixCurve(
|
|
self.helixPoints,
|
|
self.helixHeight,
|
|
self.helixStart,
|
|
self.helixEnd,
|
|
self.helixWidth,
|
|
self.helix_a,
|
|
self.helix_b
|
|
)
|
|
if proType == 'Noise':
|
|
verts = NoiseCurve(
|
|
self.noiseType,
|
|
self.noisePoints,
|
|
self.noiseLength,
|
|
self.noiseSize,
|
|
[self.noiseScaleX, self.noiseScaleY, self.noiseScaleZ],
|
|
self.noiseOctaves,
|
|
self.noiseBasis,
|
|
self.noiseSeed
|
|
)
|
|
|
|
# turn verts into array
|
|
vertArray = vertsToPoints(verts, splineType)
|
|
|
|
# create object
|
|
createCurve(context, vertArray, self)
|
|
|
|
return
|
|
|
|
|
|
class Curveaceous_galore(Operator, object_utils.AddObjectHelper):
|
|
bl_idname = "curve.curveaceous_galore"
|
|
bl_label = "Curve Profiles"
|
|
bl_description = "Construct many types of curves"
|
|
bl_options = {'REGISTER', 'UNDO', 'PRESET'}
|
|
|
|
# general properties
|
|
ProfileType : EnumProperty(
|
|
name="Type",
|
|
description="Form of Curve to create",
|
|
items=[
|
|
('Arc', "Arc", "Arc"),
|
|
('Arrow', "Arrow", "Arrow"),
|
|
('Cogwheel', "Cogwheel", "Cogwheel"),
|
|
('Cycloid', "Cycloid", "Cycloid"),
|
|
('Flower', "Flower", "Flower"),
|
|
('Helix', "Helix (3D)", "Helix"),
|
|
('Noise', "Noise (3D)", "Noise"),
|
|
('Nsided', "Nsided", "Nsided"),
|
|
('Profile', "Profile", "Profile"),
|
|
('Rectangle', "Rectangle", "Rectangle"),
|
|
('Splat', "Splat", "Splat"),
|
|
('Star', "Star", "Star")]
|
|
)
|
|
outputType : EnumProperty(
|
|
name="Output splines",
|
|
description="Type of splines to output",
|
|
items=[
|
|
('POLY', "Poly", "Poly Spline type"),
|
|
('NURBS', "Nurbs", "Nurbs Spline type"),
|
|
('BEZIER', "Bezier", "Bezier Spline type")]
|
|
)
|
|
# Curve Options
|
|
shape : EnumProperty(
|
|
name="2D / 3D",
|
|
description="2D or 3D Curve",
|
|
items=[
|
|
('2D', "2D", "2D"),
|
|
('3D', "3D", "3D")
|
|
]
|
|
)
|
|
use_cyclic_u : BoolProperty(
|
|
name="Cyclic",
|
|
default=True,
|
|
description="make curve closed"
|
|
)
|
|
endp_u : BoolProperty(
|
|
name="Use endpoint u",
|
|
default=True,
|
|
description="stretch to endpoints"
|
|
)
|
|
order_u : IntProperty(
|
|
name="Order u",
|
|
default=4,
|
|
min=2, soft_min=2,
|
|
max=6, soft_max=6,
|
|
description="Order of nurbs spline"
|
|
)
|
|
handleType : EnumProperty(
|
|
name="Handle type",
|
|
default='AUTO',
|
|
description="Bezier handles type",
|
|
items=[
|
|
('VECTOR', "Vector", "Vector type Bezier handles"),
|
|
('AUTO', "Auto", "Automatic type Bezier handles")]
|
|
)
|
|
# ProfileCurve properties
|
|
ProfileCurveType : IntProperty(
|
|
name="Type",
|
|
min=1,
|
|
max=5,
|
|
default=1,
|
|
description="Type of Curve's Profile"
|
|
)
|
|
ProfileCurvevar1 : FloatProperty(
|
|
name="Variable 1",
|
|
default=0.25,
|
|
description="Variable 1 of Curve's Profile"
|
|
)
|
|
ProfileCurvevar2 : FloatProperty(
|
|
name="Variable 2",
|
|
default=0.25,
|
|
description="Variable 2 of Curve's Profile"
|
|
)
|
|
# Arrow, Rectangle, MiscCurve properties
|
|
MiscCurveType : IntProperty(
|
|
name="Type",
|
|
min=0,
|
|
max=3,
|
|
default=0,
|
|
description="Type of Curve"
|
|
)
|
|
MiscCurvevar1 : FloatProperty(
|
|
name="Variable 1",
|
|
default=1.0,
|
|
description="Variable 1 of Curve"
|
|
)
|
|
MiscCurvevar2 : FloatProperty(
|
|
name="Variable 2",
|
|
default=0.5,
|
|
description="Variable 2 of Curve"
|
|
)
|
|
MiscCurvevar3 : FloatProperty(
|
|
name="Variable 3",
|
|
default=0.1,
|
|
min=0,
|
|
description="Variable 3 of Curve"
|
|
)
|
|
# Common properties
|
|
innerRadius : FloatProperty(
|
|
name="Inner radius",
|
|
default=0.5,
|
|
min=0,
|
|
description="Inner radius"
|
|
)
|
|
middleRadius : FloatProperty(
|
|
name="Middle radius",
|
|
default=0.95,
|
|
min=0,
|
|
description="Middle radius"
|
|
)
|
|
outerRadius : FloatProperty(
|
|
name="Outer radius",
|
|
default=1.0,
|
|
min=0,
|
|
description="Outer radius"
|
|
)
|
|
# Flower properties
|
|
petals : IntProperty(
|
|
name="Petals",
|
|
default=8,
|
|
min=2,
|
|
description="Number of petals"
|
|
)
|
|
petalWidth : FloatProperty(
|
|
name="Petal width",
|
|
default=2.0,
|
|
min=0.01,
|
|
description="Petal width"
|
|
)
|
|
# Star properties
|
|
starPoints : IntProperty(
|
|
name="Star points",
|
|
default=8,
|
|
min=2,
|
|
description="Number of star points"
|
|
)
|
|
starTwist : FloatProperty(
|
|
name="Twist",
|
|
default=0.0,
|
|
description="Twist"
|
|
)
|
|
# Arc properties
|
|
arcSides : IntProperty(
|
|
name="Arc sides",
|
|
default=6,
|
|
min=1,
|
|
description="Sides of arc"
|
|
)
|
|
startAngle : FloatProperty(
|
|
name="Start angle",
|
|
default=0.0,
|
|
description="Start angle"
|
|
)
|
|
endAngle : FloatProperty(
|
|
name="End angle",
|
|
default=90.0,
|
|
description="End angle"
|
|
)
|
|
arcType : IntProperty(
|
|
name="Arc type",
|
|
default=3,
|
|
min=1,
|
|
max=3,
|
|
description="Sides of arc"
|
|
)
|
|
# Cogwheel properties
|
|
teeth : IntProperty(
|
|
name="Teeth",
|
|
default=8,
|
|
min=2,
|
|
description="number of teeth"
|
|
)
|
|
bevel : FloatProperty(
|
|
name="Bevel",
|
|
default=0.5,
|
|
min=0,
|
|
max=1,
|
|
description="Bevel"
|
|
)
|
|
# Nsided property
|
|
Nsides : IntProperty(
|
|
name="Sides",
|
|
default=8,
|
|
min=3,
|
|
description="Number of sides"
|
|
)
|
|
# Splat properties
|
|
splatSides : IntProperty(
|
|
name="Splat sides",
|
|
default=24,
|
|
min=3,
|
|
description="Splat sides"
|
|
)
|
|
splatScale : FloatProperty(
|
|
name="Splat scale",
|
|
default=1.0,
|
|
min=0.0001,
|
|
description="Splat scale"
|
|
)
|
|
seed : IntProperty(
|
|
name="Seed",
|
|
default=0,
|
|
min=0,
|
|
description="Seed"
|
|
)
|
|
basis : IntProperty(
|
|
name="Basis",
|
|
default=0,
|
|
min=0,
|
|
max=14,
|
|
description="Basis"
|
|
)
|
|
# Helix properties
|
|
helixPoints : IntProperty(
|
|
name="Resolution",
|
|
default=100,
|
|
min=3,
|
|
description="Resolution"
|
|
)
|
|
helixHeight : FloatProperty(
|
|
name="Height",
|
|
default=2.0,
|
|
min=0,
|
|
description="Helix height"
|
|
)
|
|
helixStart : FloatProperty(
|
|
name="Start angle",
|
|
default=0.0,
|
|
description="Helix start angle"
|
|
)
|
|
helixEnd : FloatProperty(
|
|
name="Endangle",
|
|
default=360.0,
|
|
description="Helix end angle"
|
|
)
|
|
helixWidth : FloatProperty(
|
|
name="Width",
|
|
default=1.0,
|
|
description="Helix width"
|
|
)
|
|
helix_a : FloatProperty(
|
|
name="Variable 1",
|
|
default=0.0,
|
|
description="Helix Variable 1"
|
|
)
|
|
helix_b : FloatProperty(
|
|
name="Variable 2",
|
|
default=0.0,
|
|
description="Helix Variable 2"
|
|
)
|
|
# Cycloid properties
|
|
cycloPoints : IntProperty(
|
|
name="Resolution",
|
|
default=100,
|
|
min=3,
|
|
soft_min=3,
|
|
description="Resolution"
|
|
)
|
|
cycloType : IntProperty(
|
|
name="Type",
|
|
default=1,
|
|
min=0,
|
|
max=2,
|
|
description="Type: Cycloid , Hypocycloid / Hypotrochoid , Epicycloid / Epitrochoid"
|
|
)
|
|
cyclo_a : FloatProperty(
|
|
name="R",
|
|
default=1.0,
|
|
min=0.01,
|
|
description="Cycloid: R radius a"
|
|
)
|
|
cyclo_b : FloatProperty(
|
|
name="r",
|
|
default=0.25,
|
|
min=0.01,
|
|
description="Cycloid: r radius b"
|
|
)
|
|
cyclo_d : FloatProperty(
|
|
name="d",
|
|
default=0.25,
|
|
description="Cycloid: d distance"
|
|
)
|
|
# Noise properties
|
|
noiseType : IntProperty(
|
|
name="Type",
|
|
default=0,
|
|
min=0,
|
|
max=2,
|
|
description="Noise curve type: Linear, Circular or Knot"
|
|
)
|
|
noisePoints : IntProperty(
|
|
name="Resolution",
|
|
default=100,
|
|
min=3,
|
|
description="Resolution"
|
|
)
|
|
noiseLength : FloatProperty(
|
|
name="Length",
|
|
default=2.0,
|
|
min=0.01,
|
|
description="Curve Length"
|
|
)
|
|
noiseSize : FloatProperty(
|
|
name="Noise size",
|
|
default=1.0,
|
|
min=0.0001,
|
|
description="Noise size"
|
|
)
|
|
noiseScaleX : FloatProperty(
|
|
name="Noise x",
|
|
default=1.0,
|
|
min=0.0001,
|
|
description="Noise x"
|
|
)
|
|
noiseScaleY : FloatProperty(
|
|
name="Noise y",
|
|
default=1.0,
|
|
min=0.0001,
|
|
description="Noise y"
|
|
)
|
|
noiseScaleZ : FloatProperty(
|
|
name="Noise z",
|
|
default=1.0,
|
|
min=0.0001,
|
|
description="Noise z"
|
|
)
|
|
noiseOctaves : IntProperty(
|
|
name="Octaves",
|
|
default=2,
|
|
min=1,
|
|
max=16,
|
|
description="Basis"
|
|
)
|
|
noiseBasis : IntProperty(
|
|
name="Basis",
|
|
default=0,
|
|
min=0,
|
|
max=9,
|
|
description="Basis"
|
|
)
|
|
noiseSeed : IntProperty(
|
|
name="Seed",
|
|
default=1,
|
|
min=0,
|
|
description="Random Seed"
|
|
)
|
|
|
|
edit_mode : BoolProperty(
|
|
name="Show in edit mode",
|
|
default=True,
|
|
description="Show in edit mode"
|
|
)
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
# general options
|
|
col = layout.column()
|
|
col.prop(self, 'ProfileType')
|
|
col.label(text=self.ProfileType + " Options:")
|
|
|
|
# options per ProfileType
|
|
box = layout.box()
|
|
col = box.column(align=True)
|
|
|
|
if self.ProfileType == 'Profile':
|
|
col.prop(self, "ProfileCurveType")
|
|
col.prop(self, "ProfileCurvevar1")
|
|
col.prop(self, "ProfileCurvevar2")
|
|
|
|
elif self.ProfileType == 'Arrow':
|
|
col.prop(self, "MiscCurveType")
|
|
col.prop(self, "MiscCurvevar1", text="Height")
|
|
col.prop(self, "MiscCurvevar2", text="Width")
|
|
|
|
elif self.ProfileType == 'Rectangle':
|
|
col.prop(self, "MiscCurveType")
|
|
col.prop(self, "MiscCurvevar1", text="Width")
|
|
col.prop(self, "MiscCurvevar2", text="Height")
|
|
if self.MiscCurveType == 2:
|
|
col.prop(self, "MiscCurvevar3", text="Corners")
|
|
|
|
elif self.ProfileType == 'Flower':
|
|
col.prop(self, "petals")
|
|
col.prop(self, "petalWidth")
|
|
|
|
col = box.column(align=True)
|
|
col.prop(self, "innerRadius")
|
|
col.prop(self, "outerRadius")
|
|
|
|
elif self.ProfileType == 'Star':
|
|
col.prop(self, "starPoints")
|
|
col.prop(self, "starTwist")
|
|
|
|
col = box.column(align=True)
|
|
col.prop(self, "innerRadius")
|
|
col.prop(self, "outerRadius")
|
|
|
|
elif self.ProfileType == 'Arc':
|
|
col.prop(self, "arcType")
|
|
col.prop(self, "arcSides")
|
|
|
|
col = box.column(align=True)
|
|
col.prop(self, "startAngle")
|
|
col.prop(self, "endAngle")
|
|
|
|
col = box.column(align=True)
|
|
col.prop(self, "innerRadius")
|
|
col.prop(self, "outerRadius")
|
|
|
|
elif self.ProfileType == 'Cogwheel':
|
|
col.prop(self, "teeth")
|
|
col.prop(self, "bevel")
|
|
|
|
col = box.column(align=True)
|
|
col.prop(self, "innerRadius")
|
|
col.prop(self, "middleRadius")
|
|
col.prop(self, "outerRadius")
|
|
|
|
elif self.ProfileType == 'Nsided':
|
|
col.prop(self, "Nsides")
|
|
col.prop(self, "outerRadius")
|
|
|
|
elif self.ProfileType == 'Splat':
|
|
col.prop(self, "splatSides")
|
|
col.prop(self, "outerRadius")
|
|
|
|
col = box.column(align=True)
|
|
col.prop(self, "splatScale")
|
|
col.prop(self, "seed")
|
|
col.prop(self, "basis")
|
|
|
|
elif self.ProfileType == 'Cycloid':
|
|
col.prop(self, "cycloType")
|
|
col.prop(self, "cycloPoints")
|
|
|
|
col = box.column(align=True)
|
|
col.prop(self, "cyclo_a")
|
|
col.prop(self, "cyclo_b")
|
|
if self.cycloType != 0:
|
|
col.prop(self, "cyclo_d")
|
|
|
|
elif self.ProfileType == 'Helix':
|
|
col.prop(self, "helixPoints")
|
|
col.prop(self, "helixHeight")
|
|
col.prop(self, "helixWidth")
|
|
|
|
col = box.column(align=True)
|
|
col.prop(self, "helixStart")
|
|
col.prop(self, "helixEnd")
|
|
|
|
col = box.column(align=True)
|
|
col.prop(self, "helix_a")
|
|
col.prop(self, "helix_b")
|
|
|
|
elif self.ProfileType == 'Noise':
|
|
col.prop(self, "noiseType")
|
|
col.prop(self, "noisePoints")
|
|
col.prop(self, "noiseLength")
|
|
|
|
col = box.column(align=True)
|
|
col.prop(self, "noiseSize")
|
|
col.prop(self, "noiseScaleX")
|
|
col.prop(self, "noiseScaleY")
|
|
col.prop(self, "noiseScaleZ")
|
|
|
|
col = box.column(align=True)
|
|
col.prop(self, "noiseOctaves")
|
|
col.prop(self, "noiseBasis")
|
|
col.prop(self, "noiseSeed")
|
|
|
|
row = layout.row()
|
|
row.prop(self, "shape", expand=True)
|
|
|
|
# output options
|
|
col = layout.column()
|
|
col.label(text="Output Curve Type:")
|
|
col.row().prop(self, "outputType", expand=True)
|
|
|
|
if self.outputType == 'NURBS':
|
|
col.prop(self, 'order_u')
|
|
elif self.outputType == 'BEZIER':
|
|
col.row().prop(self, 'handleType', expand=True)
|
|
|
|
col = layout.column()
|
|
col.row().prop(self, "use_cyclic_u", expand=True)
|
|
|
|
col = layout.column()
|
|
col.row().prop(self, "edit_mode", expand=True)
|
|
|
|
col = layout.column()
|
|
# AddObjectHelper props
|
|
col.prop(self, "align")
|
|
col.prop(self, "location")
|
|
col.prop(self, "rotation")
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
return context.scene is not None
|
|
|
|
def execute(self, context):
|
|
# turn off 'Enter Edit Mode'
|
|
use_enter_edit_mode = bpy.context.preferences.edit.use_enter_edit_mode
|
|
bpy.context.preferences.edit.use_enter_edit_mode = False
|
|
|
|
# main function
|
|
main(context, self)
|
|
|
|
if use_enter_edit_mode:
|
|
bpy.ops.object.mode_set(mode = 'EDIT')
|
|
|
|
# restore pre operator state
|
|
bpy.context.preferences.edit.use_enter_edit_mode = use_enter_edit_mode
|
|
|
|
if self.edit_mode:
|
|
bpy.ops.object.mode_set(mode = 'EDIT')
|
|
else:
|
|
bpy.ops.object.mode_set(mode = 'OBJECT')
|
|
|
|
return {'FINISHED'}
|
|
|
|
def invoke(self, context, event):
|
|
# deal with 2D - 3D curve differences
|
|
if self.ProfileType in ['Helix', 'Cycloid', 'Noise']:
|
|
self.shape = '3D'
|
|
else:
|
|
self.shape = '2D'
|
|
|
|
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:
|
|
if self.ProfileType == 'Arc' and self.arcType == 1:
|
|
self.use_cyclic_u = False
|
|
else:
|
|
self.use_cyclic_u = True
|
|
|
|
self.execute(context)
|
|
|
|
return {'FINISHED'}
|
|
|
|
# Register
|
|
classes = [
|
|
Curveaceous_galore
|
|
]
|
|
|
|
def register():
|
|
from bpy.utils import register_class
|
|
for cls in classes:
|
|
register_class(cls)
|
|
|
|
def unregister():
|
|
from bpy.utils import unregister_class
|
|
for cls in reversed(classes):
|
|
unregister_class(cls)
|
|
|
|
if __name__ == "__main__":
|
|
register()
|