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

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormeta-androcto <meta.androcto1@gmail.com>2017-05-07 12:51:22 +0300
committermeta-androcto <meta.androcto1@gmail.com>2017-05-07 12:51:22 +0300
commit5911df5ca356dc09a15aed29642f05296df09c84 (patch)
treef6433966fb01f64e7f4b4e128b6c3f0527a15ed7 /add_curve_extra_objects/add_curve_spirofit_bouncespline.py
parent65741d7430102d5f2745ce30997c9549567c7e25 (diff)
Curve Extra Objects: update bounce splines by Jimmy Haze
Diffstat (limited to 'add_curve_extra_objects/add_curve_spirofit_bouncespline.py')
-rw-r--r--add_curve_extra_objects/add_curve_spirofit_bouncespline.py1197
1 files changed, 604 insertions, 593 deletions
diff --git a/add_curve_extra_objects/add_curve_spirofit_bouncespline.py b/add_curve_extra_objects/add_curve_spirofit_bouncespline.py
index f40c7680..ad6c5485 100644
--- a/add_curve_extra_objects/add_curve_spirofit_bouncespline.py
+++ b/add_curve_extra_objects/add_curve_spirofit_bouncespline.py
@@ -23,99 +23,108 @@ bl_info = {
"version": (0, 2, 0),
"blender": (2, 78, 0),
"location": "Toolshelf > Create Tab",
- "description": "SpiroFit and BounceSpline adds splines to selected mesh",
+ "description": "SpiroFit, BounceSpline and Catenary adds splines to selected mesh or objects",
"warning": "",
"wiki_url": "",
"category": "Object",
-}
-
+ }
import bpy
from bpy.props import (
- BoolProperty,
- EnumProperty,
- FloatProperty,
- IntProperty,
- )
+ BoolProperty,
+ EnumProperty,
+ FloatProperty,
+ IntProperty,
+ )
from bpy.types import Operator
from mathutils import (
- Matrix,
- Vector,
- )
+ Matrix,
+ Vector,
+ )
from math import (
- sin,
- cos,
- pi,
- sqrt,
- pow
- )
+ sin,
+ cos,
+ pi,
+ sqrt,
+ pow,
+ radians
+ )
import random as r
-# ------------------------------------------------------------
-
-def use_random_seed(seed):
- r.seed(seed)
- return
# ------------------------------------------------------------
-# Generate new curve object from given points
+# Generate curve object from given points
# ------------------------------------------------------------
def add_curve_object(
- verts,
- matrix,
- spline_name="Spline",
- x_ray=False,
- spline_type='BEZIER',
- spline_resolution=12,
- bevel=0.0,
- bevel_resolution=0,
- extrude=0.0,
- spline_random_radius=0.0,
- twist_mode='MINIMUM',
- twist_smooth=0.0,
- tilt=0.0
- ):
-
- curve = bpy.data.curves.new(spline_name,'CURVE')
+ verts,
+ matrix,
+ spline_name="Spline",
+ spline_type='BEZIER',
+ resolution_u=12,
+ bevel=0.0,
+ bevel_resolution=0,
+ extrude=0.0,
+ spline_radius=0.0,
+ twist_mode='MINIMUM',
+ twist_smooth=0.0,
+ tilt=0.0,
+ x_ray=False
+ ):
+
+ curve = bpy.data.curves.new(spline_name, 'CURVE')
curve.dimensions = '3D'
spline = curve.splines.new(spline_type)
- cur = bpy.data.objects.new(spline_name,curve)
+ cur = bpy.data.objects.new(spline_name, curve)
+
+ spline.radius_interpolation = 'BSPLINE'
+ spline.tilt_interpolation = 'BSPLINE'
if spline_type == 'BEZIER':
- spline.bezier_points.add(int(len(verts)-1))
+ spline.bezier_points.add(int(len(verts) - 1))
for i in range(len(verts)):
spline.bezier_points[i].co = verts[i]
spline.bezier_points[i].handle_right_type = 'AUTO'
spline.bezier_points[i].handle_left_type = 'AUTO'
- spline.bezier_points[i].radius += r.random() * spline_random_radius
- spline.bezier_points[i].tilt = tilt
+ spline.bezier_points[i].radius += spline_radius * r.random()
+ spline.bezier_points[i].tilt = radians(tilt)
else:
- spline.points.add(int(len(verts)-1))
+ spline.points.add(int(len(verts) - 1))
for i in range(len(verts)):
spline.points[i].co = verts[i][0], verts[i][1], verts[i][2], 1
bpy.context.scene.objects.link(cur)
cur.data.use_uv_as_generated = True
- cur.data.resolution_u = spline_resolution
+ cur.data.resolution_u = resolution_u
cur.data.fill_mode = 'FULL'
cur.data.bevel_depth = bevel
cur.data.bevel_resolution = bevel_resolution
cur.data.extrude = extrude
cur.data.twist_mode = twist_mode
cur.data.twist_smooth = twist_smooth
- if matrix is None:
- cur.select = True
- bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS')
- cur.select = False
- else:
- cur.matrix_world = matrix
+ cur.matrix_world = matrix
+ bpy.context.scene.objects.active = cur
+ cur.select = True
if x_ray is True:
cur.show_x_ray = x_ray
return
-#------------------------------------------------------------
-def draw_spline_settings(self, context):
+
+def move_origin_to_start():
+ active = bpy.context.active_object
+ spline = active.data.splines[0]
+ if spline.type == 'BEZIER':
+ start = active.matrix_world * spline.bezier_points[0].co
+ else:
+ start = active.matrix_world * spline.points[0].co
+ start = start[:-1]
+ cursor = bpy.context.scene.cursor_location.copy()
+ bpy.context.scene.cursor_location = start
+ bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
+ bpy.context.scene.cursor_location = cursor
+
+
+def draw_spline_settings(self):
layout = self.layout
col = layout.column(align=True)
col.prop(self, 'spline_type')
@@ -131,15 +140,15 @@ def draw_spline_settings(self, context):
col.separator()
if self.twist_mode == 'TANGENT':
col.prop(self, 'twist_smooth')
- col.prop(self, 'tilt')
+ if self.spline_type == 'BEZIER':
+ col.prop(self, 'tilt')
# ------------------------------------------------------------
+# "Build a spiral that fit the active object"
# Spirofit, original blender 2.45 script by: Antonio Osprite
# http://www.kino3d.com/forum/viewtopic.php?t=5374
# ------------------------------------------------------------
-# Build a spiral that fit the active object
-
def distance(v1, v2):
d = (Vector(v1) - Vector(v2)).length
return d
@@ -156,7 +165,6 @@ def object_mapping_ray_cast(obj, vert, center, offset):
ray = Vector(vert)
orig = Vector(center)
direction = ray - orig
- poly = obj.data.polygons
foo, hit, nor, index = obj.ray_cast(orig, direction)
mapped = hit + offset * nor
return [mapped[0], mapped[1], mapped[2]]
@@ -169,28 +177,28 @@ def object_mapping_closest_point(obj, vert, offset):
def spirofit_spline(obj,
- spire_resolution=4,
- spires=4,
- offset=0.0,
- waves=0,
- wave_height=0.0,
- rndm_spire=0.0,
- direction=False,
- map_method='RAYCAST'):
+ spire_resolution=4,
+ spires=4,
+ offset=0.0,
+ waves=0,
+ wave_height=0.0,
+ rndm_spire=0.0,
+ direction=False,
+ map_method='RAYCAST'
+ ):
bb = obj.bound_box
- bb_xmin = min([ v[0] for v in bb ])
- bb_ymin = min([ v[1] for v in bb ])
- bb_zmin = min([ v[2] for v in bb ])
- bb_xmax = max([ v[0] for v in bb ])
- bb_ymax = max([ v[1] for v in bb ])
- bb_zmax = max([ v[2] for v in bb ])
+ bb_xmin = min([v[0] for v in bb])
+ bb_ymin = min([v[1] for v in bb])
+ bb_zmin = min([v[2] for v in bb])
+ bb_xmax = max([v[0] for v in bb])
+ bb_ymax = max([v[1] for v in bb])
+ bb_zmax = max([v[2] for v in bb])
radius = distance([bb_xmax, bb_ymax, bb_zmin], [bb_xmin, bb_ymin, bb_zmin]) / 2.0
height = bb_zmax - bb_zmin
cx = (bb_xmax + bb_xmin) / 2.0
cy = (bb_ymax + bb_ymin) / 2.0
- center = [cx, cy, bb_zmin]
points = []
steps = spires * spire_resolution
@@ -209,164 +217,201 @@ def spirofit_spline(obj,
points.append(cp)
return points
-# ------------------------------------------------------------
class SpiroFitSpline(bpy.types.Operator):
bl_idname = "object.add_spirofit_spline"
bl_label = "SpiroFit"
- bl_description="Wrap selected mesh in a spiral"
+ bl_description = "Wrap selected mesh in a spiral"
bl_options = {'REGISTER', 'UNDO', 'PRESET'}
map_method = bpy.props.EnumProperty(
- name="Mapping Method",
- default='RAYCAST',
- description="Mapping method",
- items=[('RAYCAST', 'Ray cast', 'Ray casting'),
- ('CLOSESTPOINT', 'Closest point', 'Closest point on mesh')]
- )
+ name="Mapping Method",
+ default='RAYCAST',
+ description="Mapping method",
+ items=[('RAYCAST', 'Ray cast', 'Ray casting'),
+ ('CLOSESTPOINT', 'Closest point', 'Closest point on mesh')]
+ )
direction = bpy.props.BoolProperty(
- name="Direction",
- description="Spire direction",
- default=False
- )
+ name="Direction",
+ description="Spire direction",
+ default=False
+ )
spire_resolution = bpy.props.IntProperty(
- name="Spire Resolution",
- default=8,
- min=3,
- max=256,
- soft_max=128,
- description="Number of steps for one turn"
- )
+ name="Spire Resolution",
+ default=8,
+ min=3,
+ max=256,
+ soft_max=128,
+ description="Number of steps for one turn"
+ )
spires = bpy.props.IntProperty(
- name="Spires",
- default=4,
- min=1,
- max=512,
- soft_max=256,
- description="Number of turns"
- )
+ name="Spires",
+ default=4,
+ min=1,
+ max=512,
+ soft_max=256,
+ description="Number of turns"
+ )
offset = bpy.props.FloatProperty(
- name="Offset",
- default=0.0,
- precision=3,
- description="Use normal direction to offset spline"
- )
+ name="Offset",
+ default=0.0,
+ precision=3,
+ description="Use normal direction to offset spline"
+ )
waves = bpy.props.IntProperty(
- name="Waves",
- default=0,
- min=0,
- description="Waves amount"
- )
+ name="Waves",
+ default=0,
+ min=0,
+ description="Waves amount"
+ )
wave_height = bpy.props.FloatProperty(
- name="Wave Intensity",
- default=0.25,
- min=0.0,
- precision=3,
- description="Wave intensity scale"
- )
+ name="Wave Intensity",
+ default=0.0,
+ min=0.0,
+ precision=3,
+ description="Wave intensity scale"
+ )
rndm_spire = bpy.props.FloatProperty(
- name="Randomise",
- default=0.0,
- min=0.0,
- precision=3,
- description="Randomise spire"
- )
+ name="Randomise",
+ default=0.0,
+ min=0.0,
+ precision=3,
+ description="Randomise spire"
+ )
spline_name = bpy.props.StringProperty(
- name="Name",
- default="SpiroFit"
- )
+ name="Name",
+ default="SpiroFit"
+ )
spline_type = bpy.props.EnumProperty(
- name="Spline Type",
- default='BEZIER',
- description="Spline type",
- items=[('POLY', 'Poly', 'Poly spline'),
- ('BEZIER', 'Bezier', 'Bezier spline')]
- )
+ name="Spline Type",
+ default='BEZIER',
+ description="Spline type",
+ items=[('POLY', 'Poly', 'Poly spline'),
+ ('BEZIER', 'Bezier', 'Bezier spline')]
+ )
resolution_u = bpy.props.IntProperty(
- name="Resolution U",
- default=12,
- min=0,
- max=64,
- description="Curve resolution u"
- )
+ name="Resolution U",
+ default=12,
+ min=0,
+ max=64,
+ description="Curve resolution u"
+ )
bevel = bpy.props.FloatProperty(
- name="Bevel Radius",
- default=0.0,
- min=0.0,
- precision=3,
- description="Bevel depth"
- )
+ name="Bevel Radius",
+ default=0.0,
+ min=0.0,
+ precision=3,
+ description="Bevel depth"
+ )
bevel_res = bpy.props.IntProperty(
- name="Bevel Resolution",
- default=0,
- min=0,
- max=32,
- description="Bevel resolution"
- )
+ name="Bevel Resolution",
+ default=0,
+ min=0,
+ max=32,
+ description="Bevel resolution"
+ )
random_radius = bpy.props.FloatProperty(
- name="Randomise Radius",
- default=0.0,
- min=0.0,
- precision=3,
- description="Random radius amount"
- )
+ name="Randomise Radius",
+ default=0.0,
+ min=0.0,
+ precision=3,
+ description="Random radius amount"
+ )
extrude = bpy.props.FloatProperty(
- name="Extrude",
- default=0.0,
- min=0.0,
- precision=3,
- description="Extrude amount"
- )
+ name="Extrude",
+ default=0.0,
+ min=0.0,
+ precision=3,
+ description="Extrude amount"
+ )
twist_mode = bpy.props.EnumProperty(
- name="Twisting",
- default='MINIMUM',
- description="Twist method, type of tilt calculation",
- items=[('Z_UP', "Z-Up", 'Z Up'),
- ('MINIMUM', "Minimum", 'Minimum'),
- ('TANGENT', "Tangent", 'Tangent')]
- )
+ name="Twisting",
+ default='MINIMUM',
+ description="Twist method, type of tilt calculation",
+ items=[('Z_UP', "Z-Up", 'Z Up'),
+ ('MINIMUM', "Minimum", 'Minimum'),
+ ('TANGENT', "Tangent", 'Tangent')]
+ )
twist_smooth = bpy.props.FloatProperty(
- name="Smooth",
- default=0.0,
- min=0.0,
- precision=3,
- description="Twist smoothing amount for tangents"
- )
+ name="Smooth",
+ default=0.0,
+ min=0.0,
+ precision=3,
+ description="Twist smoothing amount for tangents"
+ )
tilt = bpy.props.FloatProperty(
- name="Tilt",
- default=0.0,
- precision=3,
- description="Spline handle tilt"
- )
+ name="Tilt",
+ default=0.0,
+ precision=3,
+ description="Spline handle tilt"
+ )
x_ray = bpy.props.BoolProperty(
- name="X-Ray",
- default=True,
- description = "Make the object draw in front of others"
- )
+ name="X-Ray",
+ default=True,
+ description="Make the object draw in front of others"
+ )
random_seed = bpy.props.IntProperty(
- name="Random Seed",
- default=1,
- min=0,
- description="Random seed number"
- )
+ name="Random Seed",
+ default=1,
+ min=0,
+ description="Random seed number"
+ )
+ origin_to_start = bpy.props.BoolProperty(
+ name="Origin at Start",
+ description="Set origin at first point of spline",
+ default=False
+ )
refresh = bpy.props.BoolProperty(
- name="Refresh",
- description="Refresh spline",
- default=False
- )
+ name="Refresh",
+ description="Refresh spline",
+ default=False
+ )
auto_refresh = bpy.props.BoolProperty(
- name="Auto",
- description="Auto refresh spline",
- default=True
- )
+ name="Auto",
+ description="Auto refresh spline",
+ default=True
+ )
+
+ def draw(self, context):
+ layout = self.layout
+ col = layout.column(align=True)
+ row = col.row(align=True)
+ row.prop(self, 'x_ray', toggle=True)
+ row.separator()
+ if self.auto_refresh is False:
+ self.refresh = False
+ elif self.auto_refresh is True:
+ self.refresh = True
+ row.prop(self, 'auto_refresh', toggle=True, icon='AUTO', text="")
+ row.prop(self, 'refresh', toggle=True, icon='FILE_REFRESH', text="")
+ row.separator()
+ row.prop(self, 'origin_to_start', toggle=True, icon='MANIPUL', text="")
+ row.separator()
+ row.operator('object.add_spirofit_spline', text="Add New")
+
+ col = layout.column(align=True)
+ col.prop(self, 'spline_name')
+ col.separator()
+ col.prop(self, 'map_method')
+ col.separator()
+ col.prop(self, 'spire_resolution')
+ row = col.row(align=True).split(0.9, align=True)
+ row.prop(self, 'spires')
+ row.prop(self, 'direction', toggle=True, text="", icon='ARROW_LEFTRIGHT')
+ col.prop(self, 'offset')
+ col.prop(self, 'waves')
+ col.prop(self, 'wave_height')
+ col.prop(self, 'rndm_spire')
+ col.prop(self, 'random_seed')
+
+ draw_spline_settings(self)
@classmethod
def poll(self, context):
ob = context.active_object
return ((ob is not None) and
- (ob.type == 'MESH') and
(context.mode == 'OBJECT'))
@@ -379,45 +424,47 @@ class SpiroFitSpline(bpy.types.Operator):
if not self.refresh:
return {'PASS_THROUGH'}
+ obj = context.active_object
+ if obj.type != 'MESH':
+ return {'CANCELLED'}
+
undo = context.user_preferences.edit.use_global_undo
context.user_preferences.edit.use_global_undo = False
- bpy.ops.object.mode_set(mode='EDIT', toggle=False)
- bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
-
- obj = context.active_object
- matrix = obj.matrix_world
+ bpy.ops.object.select_all(action='DESELECT')
- if self.random_seed:
- use_random_seed(self.random_seed)
+ r.seed(self.random_seed)
points = spirofit_spline(
- obj,
- self.spire_resolution,
- self.spires,
- self.offset,
- self.waves,
- self.wave_height,
- self.rndm_spire,
- self.direction,
- self.map_method
- )
+ obj,
+ self.spire_resolution,
+ self.spires,
+ self.offset,
+ self.waves,
+ self.wave_height,
+ self.rndm_spire,
+ self.direction,
+ self.map_method
+ )
add_curve_object(
- points,
- matrix,
- self.spline_name,
- self.x_ray,
- self.spline_type,
- self.resolution_u,
- self.bevel,
- self.bevel_res,
- self.extrude,
- self.random_radius,
- self.twist_mode,
- self.twist_smooth,
- self.tilt
- )
+ points,
+ obj.matrix_world,
+ self.spline_name,
+ self.spline_type,
+ self.resolution_u,
+ self.bevel,
+ self.bevel_res,
+ self.extrude,
+ self.random_radius,
+ self.twist_mode,
+ self.twist_smooth,
+ self.tilt,
+ self.x_ray
+ )
+
+ if self.origin_to_start is True:
+ move_origin_to_start()
if self.auto_refresh is False:
self.refresh = False
@@ -426,57 +473,24 @@ class SpiroFitSpline(bpy.types.Operator):
return {'FINISHED'}
- def draw(self, context):
- layout = self.layout
- col = layout.column(align=True)
- row = col.row(align=True)
- row.prop(self, 'x_ray', toggle=True)
- row.separator()
- if self.auto_refresh is False:
- self.refresh = False
- elif self.auto_refresh is True:
- self.refresh = True
- row.prop(self, 'auto_refresh', toggle=True, icon='AUTO', text="")
- row.prop(self, 'refresh', toggle=True, icon='FILE_REFRESH', text="")
- row.separator()
- row.operator('object.add_spirofit_spline', text="Add New")
-
- col = layout.column(align=True)
- col.prop(self, 'spline_name')
- col.separator()
- col.prop(self, 'map_method')
- col.separator()
- col.prop(self, 'spire_resolution')
- row = col.row(align=True).split(0.9,align=True)
- row.prop(self, 'spires')
- row.prop(self, 'direction', toggle=True, text="", icon='ARROW_LEFTRIGHT')
- col.prop(self, 'offset')
- col.prop(self, 'waves')
- col.prop(self, 'wave_height')
- col.prop(self, 'rndm_spire')
- col.prop(self, 'random_seed')
-
- draw_spline_settings(self, context)
-
-
# ------------------------------------------------------------
# Bounce spline / Fiber mesh
# Original script by Liero and Atom
# https://blenderartists.org/forum/showthread.php?331750-Fiber-Mesh-Emulation
# ------------------------------------------------------------
-
def noise(var=1):
- rand = Vector((r.gauss(0,1), r.gauss(0,1), r.gauss(0,1)))
+ rand = Vector((r.gauss(0, 1), r.gauss(0, 1), r.gauss(0, 1)))
vec = rand.normalized() * var
return vec
def bounce_spline(obj,
- number=1000,
- ang_noise=0.25,
- offset=0.0,
- extra=50,
- active_face=False):
+ number=1000,
+ ang_noise=0.25,
+ offset=0.0,
+ extra=50,
+ active_face=False
+ ):
dist, points = 1000, []
poly = obj.data.polygons
@@ -488,7 +502,7 @@ def bounce_spline(obj,
print("No active face selected")
pass
else:
- n = r.randint(0, len(poly)-1)
+ n = r.randint(0, len(poly) - 1)
end = poly[n].normal.copy() * -1
start = poly[n].center
@@ -510,145 +524,179 @@ def bounce_spline(obj,
return points
return points
-# ------------------------------------------------------------
class BounceSpline(bpy.types.Operator):
bl_idname = "object.add_bounce_spline"
bl_label = "BounceSpline"
- bl_description="Fill selected mesh with a bounce spline"
+ bl_description = "Fill selected mesh with a spline"
bl_options = {'REGISTER', 'UNDO', 'PRESET'}
bounce_number = bpy.props.IntProperty(
- name="Bounces",
- default=500,
- min=1,
- max=99999,
- soft_max=9999,
- description="Number of bounces"
- )
+ name="Bounces",
+ default=500,
+ min=1,
+ max=99999,
+ soft_max=9999,
+ description="Number of bounces"
+ )
ang_noise = bpy.props.FloatProperty(
- name="Angular Noise",
- default=0.25,
- min=0.0,
- precision=3,
- description="Add some noise to ray direction"
- )
+ name="Angular Noise",
+ default=0.25,
+ min=0.0,
+ precision=3,
+ description="Add some noise to ray direction"
+ )
offset = bpy.props.FloatProperty(
- name="Offset",
- default=0.0,
- precision=3,
- description="Use normal direction to offset spline"
- )
+ name="Offset",
+ default=0.0,
+ precision=3,
+ description="Use normal direction to offset spline"
+ )
extra = bpy.props.IntProperty(
- name="Extra",
- default=50,
- min=0,
- max=1000,
- soft_min=0,
- soft_max=500,
- description="Number of extra tries if it fails to hit mesh"
- )
+ name="Extra",
+ default=50,
+ min=0,
+ max=1000,
+ soft_min=0,
+ soft_max=500,
+ description="Number of extra tries if it fails to hit mesh"
+ )
active_face = bpy.props.BoolProperty(
- name="Active Face",
- default=False,
- description = "Starts from active face or a random one"
- )
+ name="Active Face",
+ default=False,
+ description="Starts from active face or a random one"
+ )
spline_name = bpy.props.StringProperty(
- name="Name",
- default="BounceSpline"
- )
+ name="Name",
+ default="BounceSpline"
+ )
spline_type = bpy.props.EnumProperty(
- name="Spline Type",
- default='BEZIER',
- description="Spline type",
- items=[('POLY', 'Poly', 'Poly spline'),
- ('BEZIER', 'Bezier', 'Bezier spline')]
- )
+ name="Spline Type",
+ default='BEZIER',
+ description="Spline type",
+ items=[('POLY', 'Poly', 'Poly spline'),
+ ('BEZIER', 'Bezier', 'Bezier spline')]
+ )
resolution_u = bpy.props.IntProperty(
- name="Resolution U",
- default=12,
- min=0,
- max=64,
- description="Curve resolution u"
- )
+ name="Resolution U",
+ default=12,
+ min=0,
+ max=64,
+ description="Curve resolution u"
+ )
bevel = bpy.props.FloatProperty(
- name="Bevel Radius",
- default=0.0,
- min=0.0,
- precision=3,
- description="Bevel depth"
- )
+ name="Bevel Radius",
+ default=0.0,
+ min=0.0,
+ precision=3,
+ description="Bevel depth"
+ )
bevel_res = bpy.props.IntProperty(
- name="Bevel Resolution",
- default=0,
- min=0,
- max=32,
- description="Bevel resolution"
- )
+ name="Bevel Resolution",
+ default=0,
+ min=0,
+ max=32,
+ description="Bevel resolution"
+ )
random_radius = bpy.props.FloatProperty(
- name="Randomise Radius",
- default=0.0,
- min=0.0,
- precision=3,
- description="Random radius amount"
- )
+ name="Randomise Radius",
+ default=0.0,
+ min=0.0,
+ precision=3,
+ description="Random radius amount"
+ )
extrude = bpy.props.FloatProperty(
- name="Extrude",
- default=0.0,
- min=0.0,
- precision=3,
- description="Extrude amount"
- )
+ name="Extrude",
+ default=0.0,
+ min=0.0,
+ precision=3,
+ description="Extrude amount"
+ )
twist_mode = bpy.props.EnumProperty(
- name="Twisting",
- default='MINIMUM',
- description="Twist method, type of tilt calculation",
- items=[('Z_UP', "Z-Up", 'Z Up'),
- ('MINIMUM', "Minimum", 'Minimum'),
- ('TANGENT', "Tangent", 'Tangent')]
- )
+ name="Twisting",
+ default='MINIMUM',
+ description="Twist method, type of tilt calculation",
+ items=[('Z_UP', "Z-Up", 'Z Up'),
+ ('MINIMUM', "Minimum", 'Minimum'),
+ ('TANGENT', "Tangent", 'Tangent')]
+ )
twist_smooth = bpy.props.FloatProperty(
- name="Smooth",
- default=0.0,
- min=0.0,
- precision=3,
- description="Twist smoothing amount for tangents"
- )
+ name="Smooth",
+ default=0.0,
+ min=0.0,
+ precision=3,
+ description="Twist smoothing amount for tangents"
+ )
tilt = bpy.props.FloatProperty(
- name="Tilt",
- default=0.0,
- precision=3,
- description="Spline handle tilt"
- )
+ name="Tilt",
+ default=0.0,
+ precision=3,
+ description="Spline handle tilt"
+ )
x_ray = bpy.props.BoolProperty(
- name="X-Ray",
- default=True,
- description = "Make the object draw in front of others"
- )
+ name="X-Ray",
+ default=True,
+ description="Make the object draw in front of others"
+ )
random_seed = bpy.props.IntProperty(
- name="Random Seed",
- default=1,
- min=0,
- description="Random seed number"
- )
+ name="Random Seed",
+ default=1,
+ min=0,
+ description="Random seed number"
+ )
+ origin_to_start = bpy.props.BoolProperty(
+ name="Origin at Start",
+ description="Set origin at first point of spline",
+ default=False
+ )
refresh = bpy.props.BoolProperty(
- name="Refresh",
- description="Refresh spline",
- default=False
- )
+ name="Refresh",
+ description="Refresh spline",
+ default=False
+ )
auto_refresh = bpy.props.BoolProperty(
- name="Auto",
- description="Auto refresh spline",
- default=True
- )
+ name="Auto",
+ description="Auto refresh spline",
+ default=True
+ )
+
+
+ def draw(self, context):
+ layout = self.layout
+ col = layout.column(align=True)
+ row = col.row(align=True)
+ row.prop(self, 'x_ray', toggle=True)
+ row.separator()
+ if self.auto_refresh is False:
+ self.refresh = False
+ elif self.auto_refresh is True:
+ self.refresh = True
+ row.prop(self, 'auto_refresh', toggle=True, icon='AUTO', text="")
+ row.prop(self, 'refresh', toggle=True, icon='FILE_REFRESH', text="")
+ row.separator()
+ row.prop(self, 'origin_to_start', toggle=True, icon='MANIPUL', text="")
+ row.separator()
+ row.operator('object.add_bounce_spline', text="Add New")
+
+ col = layout.column(align=True)
+ col.prop(self, 'spline_name')
+ col.separator()
+ col.prop(self, 'bounce_number')
+ row = col.row(align=True).split(0.9, align=True)
+ row.prop(self, 'ang_noise')
+ row.prop(self, 'active_face', toggle=True, text="", icon='FACESEL')
+ col.prop(self, 'offset')
+ col.prop(self, 'extra')
+ col.prop(self, 'random_seed')
+
+ draw_spline_settings(self)
@classmethod
def poll(self, context):
ob = context.active_object
return ((ob is not None) and
- (ob.type == 'MESH') and
(context.mode == 'OBJECT'))
@@ -661,41 +709,44 @@ class BounceSpline(bpy.types.Operator):
if not self.refresh:
return {'PASS_THROUGH'}
+ obj = context.active_object
+ if obj.type != 'MESH':
+ return {'CANCELLED'}
+
undo = context.user_preferences.edit.use_global_undo
context.user_preferences.edit.use_global_undo = False
- bpy.ops.object.mode_set(mode='EDIT', toggle=False)
- bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
+ bpy.ops.object.select_all(action='DESELECT')
- obj = context.active_object
-
- if self.random_seed:
- use_random_seed(self.random_seed)
+ r.seed(self.random_seed)
points = bounce_spline(
- obj,
- self.bounce_number,
- self.ang_noise,
- self.offset,
- self.extra,
- self.active_face
- )
+ obj,
+ self.bounce_number,
+ self.ang_noise,
+ self.offset,
+ self.extra,
+ self.active_face
+ )
add_curve_object(
- points,
- obj.matrix_world,
- self.spline_name,
- self.x_ray,
- self.spline_type,
- self.resolution_u,
- self.bevel,
- self.bevel_res,
- self.extrude,
- self.random_radius,
- self.twist_mode,
- self.twist_smooth,
- self.tilt
- )
+ points,
+ obj.matrix_world,
+ self.spline_name,
+ self.spline_type,
+ self.resolution_u,
+ self.bevel,
+ self.bevel_res,
+ self.extrude,
+ self.random_radius,
+ self.twist_mode,
+ self.twist_smooth,
+ self.tilt,
+ self.x_ray
+ )
+
+ if self.origin_to_start is True:
+ move_origin_to_start()
if self.auto_refresh is False:
self.refresh = False
@@ -704,39 +755,9 @@ class BounceSpline(bpy.types.Operator):
return {'FINISHED'}
- def draw(self, context):
- layout = self.layout
- col = layout.column(align=True)
- row = col.row(align=True)
- row.prop(self, 'x_ray', toggle=True)
- row.separator()
- if self.auto_refresh is False:
- self.refresh = False
- elif self.auto_refresh is True:
- self.refresh = True
- row.prop(self, 'auto_refresh', toggle=True, icon='AUTO', text="")
- row.prop(self, 'refresh', toggle=True, icon='FILE_REFRESH', text="")
- row.separator()
- row.operator('object.add_bounce_spline', text="Add New")
-
- col = layout.column(align=True)
- col.prop(self, 'spline_name')
- col.separator()
- col.prop(self, 'bounce_number')
- row = col.row(align=True).split(0.9, align=True)
- row.prop(self, 'ang_noise')
- row.prop(self, 'active_face', toggle=True, text="", icon='FACESEL')
- col.prop(self, 'offset')
- col.prop(self, 'extra')
- col.prop(self, 'random_seed')
-
- draw_spline_settings(self, context)
-
-
-#------------------------------------------------------------
+# ------------------------------------------------------------
# Hang Catenary curve between two selected objects
-#------------------------------------------------------------
-
+# ------------------------------------------------------------
def catenary_curve(
start=[-2, 0, 2],
end=[2, 0, 2],
@@ -744,7 +765,7 @@ def catenary_curve(
a=2.0
):
- points=[]
+ points = []
lx = end[0] - start[0]
ly = end[1] - start[1]
lr = sqrt(pow(lx, 2) + pow(ly, 2))
@@ -757,135 +778,131 @@ def catenary_curve(
while i <= steps:
x = start[0] + i * slx
y = start[1] + i * sly
- z = zv+pow((i * slr) - lv, 2) / (2 * a)
+ z = zv + pow((i * slr) - lv, 2) / (2 * a)
points.append([x, y, z])
i += 1
return points
-#------------------------------------------------------------
+
class CatenaryCurve(bpy.types.Operator):
bl_idname = "object.add_catenary_curve"
bl_label = "Catenary"
- bl_description="Hang a catenary curve between two selected objects"
+ bl_description = "Hang a curve between two selected objects"
bl_options = {'REGISTER', 'UNDO', 'PRESET'}
- start_location = bpy.props.StringProperty(
- name="Start",
- default="",
- description="Catenary start location",
- )
- end_location = bpy.props.StringProperty(
- name="End",
- default="",
- description="Catenary end location",
- )
steps = bpy.props.IntProperty(
- name="Steps",
- description="Resolution of the curve",
- default=24,
- min=2,
- max=256,
- )
+ name="Steps",
+ description="Resolution of the curve",
+ default=24,
+ min=2,
+ max=256,
+ )
var_a = bpy.props.FloatProperty(
- name="a",
- description="Catenary variable a",
- precision=3,
- default=2.0,
- min=0.0, soft_min=0.01,
- max=100.0, soft_max=10.0
- )
+ name="a",
+ description="Catenary variable a",
+ precision=3,
+ default=2.0,
+ min=0.0,
+ soft_min=0.01,
+ max=100.0
+ )
spline_name = bpy.props.StringProperty(
- name="Name",
- default="Catenary"
- )
+ name="Name",
+ default="Catenary"
+ )
spline_type = bpy.props.EnumProperty(
- name="Spline Type",
- default='BEZIER',
- description="Spline type",
- items=[('POLY', 'Poly', 'Poly spline'),
- ('BEZIER', 'Bezier', 'Bezier spline')]
- )
+ name="Spline Type",
+ default='BEZIER',
+ description="Spline type",
+ items=[('POLY', 'Poly', 'Poly spline'),
+ ('BEZIER', 'Bezier', 'Bezier spline')]
+ )
resolution_u = bpy.props.IntProperty(
- name="Resolution U",
- default=12,
- min=0,
- max=64,
- description="Curve resolution u"
- )
+ name="Resolution U",
+ default=12,
+ min=0,
+ max=64,
+ description="Curve resolution u"
+ )
bevel = bpy.props.FloatProperty(
- name="Bevel Radius",
- default=0.0,
- min=0.0,
- precision=3,
- description="Bevel depth"
- )
+ name="Bevel Radius",
+ default=0.0,
+ min=0.0,
+ precision=3,
+ description="Bevel depth"
+ )
bevel_res = bpy.props.IntProperty(
- name="Bevel Resolution",
- default=0,
- min=0,
- max=32,
- description="Bevel resolution"
- )
+ name="Bevel Resolution",
+ default=0,
+ min=0,
+ max=32,
+ description="Bevel resolution"
+ )
random_radius = bpy.props.FloatProperty(
- name="Randomise Radius",
- default=0.0,
- min=0.0,
- precision=3,
- description="Random radius amount"
- )
+ name="Randomise Radius",
+ default=0.0,
+ min=0.0,
+ precision=3,
+ description="Random radius amount"
+ )
extrude = bpy.props.FloatProperty(
- name="Extrude",
- default=0.0,
- min=0.0,
- precision=3,
- description="Extrude amount"
- )
+ name="Extrude",
+ default=0.0,
+ min=0.0,
+ precision=3,
+ description="Extrude amount"
+ )
twist_mode = bpy.props.EnumProperty(
- name="Twisting",
- default='MINIMUM',
- description="Twist method, type of tilt calculation",
- items=[('Z_UP', "Z-Up", 'Z Up'),
- ('MINIMUM', "Minimum", 'Minimum'),
- ('TANGENT', "Tangent", 'Tangent')]
- )
+ name="Twisting",
+ default='MINIMUM',
+ description="Twist method, type of tilt calculation",
+ items=[('Z_UP', "Z-Up", 'Z Up'),
+ ('MINIMUM', "Minimum", 'Minimum'),
+ ('TANGENT', "Tangent", 'Tangent')]
+ )
twist_smooth = bpy.props.FloatProperty(
- name="Smooth",
- default=0.0,
- min=0.0,
- precision=3,
- description="Twist smoothing amount for tangents"
- )
+ name="Smooth",
+ default=0.0,
+ min=0.0,
+ precision=3,
+ description="Twist smoothing amount for tangents"
+ )
tilt = bpy.props.FloatProperty(
- name="Tilt",
- default=0.0,
- precision=3,
- description="Spline handle tilt"
- )
+ name="Tilt",
+ default=0.0,
+ precision=3,
+ description="Spline handle tilt"
+ )
x_ray = bpy.props.BoolProperty(
- name="X-Ray",
- default=False,
- description = "Make the object draw in front of others"
- )
+ name="X-Ray",
+ default=False,
+ description="Make the object draw in front of others"
+ )
random_seed = bpy.props.IntProperty(
- name="Random Seed",
- default=1,
- min=0,
- description="Random seed number"
- )
+ name="Random Seed",
+ default=1,
+ min=0,
+ description="Random seed number"
+ )
+ origin_to_start = bpy.props.BoolProperty(
+ name="Origin at Start",
+ description="Set origin at first point of spline",
+ default=False
+ )
refresh = bpy.props.BoolProperty(
- name="Refresh",
- description="Refresh spline",
- default=False
- )
+ name="Refresh",
+ description="Refresh spline",
+ default=False
+ )
auto_refresh = bpy.props.BoolProperty(
- name="Auto",
- description="Auto refresh spline",
- default=True
- )
+ name="Auto",
+ description="Auto refresh spline",
+ default=True
+ )
+
def draw(self, context):
- scene = bpy.context.scene
layout = self.layout
col = layout.column(align=True)
row = col.row(align=True)
@@ -898,19 +915,17 @@ class CatenaryCurve(bpy.types.Operator):
row.prop(self, 'auto_refresh', toggle=True, icon='AUTO', text="")
row.prop(self, 'refresh', toggle=True, icon='FILE_REFRESH', text="")
row.separator()
+ row.prop(self, 'origin_to_start', toggle=True, icon='MANIPUL', text="")
+ row.separator()
row.operator('object.add_catenary_curve', text="Add New")
col = layout.column(align=True)
col.prop(self, 'spline_name')
col.separator()
- col.prop_search(self, "start_location", scene, "objects")
- col.prop_search(self, "end_location", scene, "objects")
- col.separator()
col.prop(self, 'steps')
col.prop(self, 'var_a')
- draw_spline_settings(self, context)
-
+ draw_spline_settings(self)
col = layout.column(align=True)
col.prop(self, 'random_seed')
@@ -918,7 +933,7 @@ class CatenaryCurve(bpy.types.Operator):
@classmethod
def poll(self, context):
ob = context.active_object
- return (ob is not None)
+ return ob is not None
def invoke(self, context, event):
@@ -930,53 +945,51 @@ class CatenaryCurve(bpy.types.Operator):
if not self.refresh:
return {'PASS_THROUGH'}
- undo = context.user_preferences.edit.use_global_undo
- context.user_preferences.edit.use_global_undo = False
-
- if self.random_seed:
- use_random_seed(self.random_seed)
-
- matrix = None
-
try:
- ob1 = bpy.data.objects[self.start_location]
- ob2 = bpy.data.objects[self.end_location]
+ ob1 = bpy.context.active_object
+ ob1.select = False
+ ob2 = bpy.context.selected_objects[0]
start = ob1.location
end = ob2.location
- if end == start:
- start = [-2, 0, 2]
- end= [2, 0, 2]
- sel = bpy.context.selected_objects
- for o in sel:
- o.select = False
- ob1.select = True
- ob2.select = True
+ if start[0] == end[0] and start[1] == end[1]:
+ return {'CANCELLED'}
except:
- start = [-2, 0, 2]
- end= [2, 0, 2]
+ return {'CANCELLED'}
+
+ bpy.ops.object.select_all(action='DESELECT')
+
+ undo = context.user_preferences.edit.use_global_undo
+ context.user_preferences.edit.use_global_undo = False
+
+ r.seed(self.random_seed)
points = catenary_curve(
- start,
- end,
- self.steps,
- self.var_a
- )
+ start,
+ end,
+ self.steps,
+ self.var_a
+ )
add_curve_object(
- points,
- matrix,
- self.spline_name,
- self.x_ray,
- self.spline_type,
- self.resolution_u,
- self.bevel,
- self.bevel_res,
- self.extrude,
- self.random_radius,
- self.twist_mode,
- self.twist_smooth,
- self.tilt
- )
+ points,
+ Matrix(),
+ self.spline_name,
+ self.spline_type,
+ self.resolution_u,
+ self.bevel,
+ self.bevel_res,
+ self.extrude,
+ self.random_radius,
+ self.twist_mode,
+ self.twist_smooth,
+ self.tilt,
+ self.x_ray
+ )
+
+ if self.origin_to_start is True:
+ move_origin_to_start()
+ else:
+ bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS')
if self.auto_refresh is False:
self.refresh = False
@@ -984,22 +997,20 @@ class CatenaryCurve(bpy.types.Operator):
context.user_preferences.edit.use_global_undo = undo
return {'FINISHED'}
+
# ------------------------------------------------------------
-# Tools Panel > Misc
+# Tools Panel > Create
# ------------------------------------------------------------
-
-class SplinePanel( bpy.types.Panel ):
+class SplinePanel(bpy.types.Panel):
bl_space_type = "VIEW_3D"
bl_context = "objectmode"
bl_region_type = "TOOLS"
- bl_label = "Add Spline to Mesh"
+ bl_label = "Spline:"
bl_category = "Create"
bl_options = {'DEFAULT_CLOSED'}
- def draw( self, context ):
- scn = context.scene
- layout = self.layout
- col = self.layout.column()
+ def draw(self, context):
+ col = self.layout.column(align=True)
col.operator(SpiroFitSpline.bl_idname, icon="FORCE_MAGNETIC")
col.operator(BounceSpline.bl_idname, icon="FORCE_HARMONIC")
col.operator(CatenaryCurve.bl_idname, icon="FORCE_CURVE")
@@ -1007,7 +1018,6 @@ class SplinePanel( bpy.types.Panel ):
# ------------------------------------------------------------
# Menu: Add > Curve >
# ------------------------------------------------------------
-
'''
def menu_func(self, context):
self.layout.operator(SpiroFitSpline.bl_idname, icon="PLUGIN")
@@ -1018,20 +1028,21 @@ def menu_func(self, context):
# ------------------------------------------------------------
# Register
# ------------------------------------------------------------
-
def register():
bpy.utils.register_class(SplinePanel)
bpy.utils.register_class(SpiroFitSpline)
bpy.utils.register_class(BounceSpline)
bpy.utils.register_class(CatenaryCurve)
- #bpy.types.INFO_MT_curve_add.append(menu_func)
+ # bpy.types.INFO_MT_curve_add.append(menu_func)
+
def unregister():
bpy.utils.unregister_class(SplinePanel)
bpy.utils.unregister_class(SpiroFitSpline)
bpy.utils.unregister_class(BounceSpline)
bpy.utils.unregister_class(CatenaryCurve)
- #bpy.types.INFO_MT_curve_add.remove(menu_func)
+ # bpy.types.INFO_MT_curve_add.remove(menu_func)
+
if __name__ == "__main__":
- register()
+ register() \ No newline at end of file