#!BPY

"""
Name: 'Hang Curve'
Blender: 248
Group: 'Add'
Tooltip: 'Hang curve between 2 objects or empties'
"""
__author__ = ["Elephants Dream Team"]
__url__ = ("http://wiki.blender.org/index.php/Extensions:Py/Scripts/Manual/Add/Hang_Curve")
__version__ = "248 - 2008-10"

__bpydoc__ = """\
Hang a curve between two objects or empties,
Parameters can be edited in the text editor.
.\n\
"""

# --------------------------------------------------------------------------
# ***** BEGIN GPL LICENSE BLOCK *****
#
# Copyright ((C) Elephants Dream Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
# ***** END GPL LICENCE BLOCK *****
# --------------------------------------------------------------------------

import Blender

from Blender import Scene, Object, Mesh #reading
from Blender import Curve, BezTriple #creating
from Blender.Mathutils import Vector, MidpointVecs
from add_hang_curve_module import global_loc

W = 0.040
BEVRESOL = 10
RESOLU = 24
MIDLEN = 1
G = 3.5 #'gravity' i.e. how much midpoint is lowered
#RESOLV =

scene = Scene.GetCurrent()

try:
	a, b = Blender.Object.GetSelected()
except ValueError:
	raise RuntimeError, "Please select exactly two objects to connect with a hanging tube."
else:
	print "Got:", a, b
		
ob = Object.New('Curve', 'Hangtube')
cob = Curve.New('HangtubeData')

aloc = global_loc(a)
bloc = global_loc(b)
print aloc, bloc

avec = Vector(aloc)
bvec = Vector(bloc)
mvec = MidpointVecs(avec, bvec)
print mvec
mvec.z -= G

#assuming the selected object has a single face:
#data = Mesh.Get(a.getData(name_only=True))
#no = data.faces[0].no
#print no

def sort(p1, p2, tvec, which):
	if which == 'a':
		if (tvec - Vector(p1)).length < (tvec - Vector(p2)).length:
			print 'a'
			return p2, p1
		else:
			return p1, p2
	elif which == 'b': #yet another ugliest hack ever!
		if (tvec - Vector(p1)).length > (tvec - Vector(p2)).length:
			print 'b'
			return p2, p1
		else:
			return p1, p2
		
def attach(target, mvec, which):
	no = target.matrix[2][:3] #object z-axis in worldspace
	x, y, z = global_loc(target)
	h1 = x-no[0], y-no[1], z-no[2]
	h2 = x+no[0], y+no[1], z+no[2]
	h1, h2 = sort(h1, h2, mvec, which)
	btri = BezTriple.New((h1[0], h1[1], h1[2],
						  x, y, z,
						  h2[0], h2[1], h2[2]))
	return btri

btri_a = attach(a, mvec, 'a')
btri_b = attach(b, mvec, 'b')

#middle
x, y, z = mvec[0], mvec[1], mvec[2]
m1 = x-MIDLEN, y, z
m2 = x+MIDLEN, y, z
m1, m2 = sort(m1, m2, bvec, 'a') #go figure
btri_m = BezTriple.New((m1[0], m1[1], m1[2],
					    x, y, z,
					    m2[0], m2[1], m2[2]))

bez = cob.appendNurb(btri_a)
bez.append(btri_m)
bez.append(btri_b)

cob.ext2 = W	
cob.bevresol = BEVRESOL
cob.resolu = RESOLU 
cob.update()

ob.link(cob)
scene.link(ob)

Blender.Redraw()