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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2007-11-10 23:00:15 +0300
committerCampbell Barton <ideasman42@gmail.com>2007-11-10 23:00:15 +0300
commitb7d3a8786a3e7d16da892612ea75ae3db56d67dc (patch)
tree922d4df2ca36dc1a892b71dde200b3e3c7a4305d /release/scripts/wizard_curve2tree.py
parent2abb50d1ea4679f9e3a22ec0e8df65945da0358e (diff)
Rewrote the part that converted blenders curves into branches,
Was converting into a mesh and then doing location checks, to figure out what the radius should be and then interpolating. this was the slowest part of the script and it made a mesh every time. Now use blenders bezier interpolation function and calculate points like blender does. fixed a driver syntax error for the Z axis (typo)
Diffstat (limited to 'release/scripts/wizard_curve2tree.py')
-rw-r--r--release/scripts/wizard_curve2tree.py208
1 files changed, 97 insertions, 111 deletions
diff --git a/release/scripts/wizard_curve2tree.py b/release/scripts/wizard_curve2tree.py
index 4c20a869e00..9e34b4f82c9 100644
--- a/release/scripts/wizard_curve2tree.py
+++ b/release/scripts/wizard_curve2tree.py
@@ -19,6 +19,36 @@ import Blender
from Blender.Mathutils import Vector, CrossVecs, AngleBetweenVecs, LineIntersect, TranslationMatrix, ScaleMatrix
from Blender.Geometry import ClosestPointOnLine
+# Copied from blender, we could wrap this! - BKE_curve.c
+# But probably not toooo bad in python
+def forward_diff_bezier(q0, q1, q2, q3, pointlist, steps, axis):
+ f= float(steps)
+ rt0= q0
+ rt1= 3.0*(q1-q0)/f
+ f*= f
+ rt2= 3.0*(q0-2.0*q1+q2)/f
+ f*= steps
+ rt3= (q3-q0+3.0*(q1-q2))/f
+
+ q0= rt0
+ q1= rt1+rt2+rt3
+ q2= 2*rt2+6*rt3
+ q3= 6*rt3
+ if axis == None:
+ for a in xrange(steps+1):
+ pointlist[a] = q0
+ q0+= q1
+ q1+= q2
+ q2+= q3;
+
+ else:
+ for a in xrange(steps+1):
+ pointlist[a][axis] = q0
+ q0+= q1
+ q1+= q2
+ q2+= q3;
+
+
def debug_pt(co):
Blender.Window.SetCursorPos(tuple(co))
Blender.Window.RedrawAll()
@@ -28,6 +58,8 @@ def closestVecIndex(vec, vecls):
best= -1
best_dist = 100000000
for i, vec_test in enumerate(vecls):
+ # Dont use yet, we may want to tho
+ #if vec_test: # Seems odd, but use this so we can disable some verts in the list.
dist = (vec-vec_test).length
if dist < best_dist:
best = i
@@ -60,8 +92,10 @@ class tree:
def fromCurve(self, object):
+ # Now calculate the normals
self.object = object
curve = object.data
+ steps = curve.resolu # curve resolution
# Set the curve object scale
if curve.bevob:
@@ -69,118 +103,46 @@ class tree:
bb = curve.bevob.boundingBox
# self.limbScale = (bb[0] - bb[7]).length / 2.825 # THIS IS GOOD WHEN NON SUBSURRFED
self.limbScale = (bb[0] - bb[7]).length / 1.8
- # end
- # Get the curve points as bpoints
+ # forward_diff_bezier will fill in the blanks
+ pointlist = [[None, None, None] for i in xrange(steps+1)]
+ radlist = [ [None] for i in xrange(steps+1) ]
+
+
for spline in curve:
brch = branch()
self.branches_all.append(brch)
- brch.bpoints = [ bpoint(brch, Vector(bez.vec[1]), Vector(), bez.radius * self.limbScale) for bez in spline ]
-
- # Get the curve as a mesh. - for inbetween points
- tmpme = bpy.data.meshes.new()
-
- # remove/backup bevel ob
- bev_back = curve.bevob
- if bev_back: curve.bevob = None
-
- # get the curve mesh data
- tmpob = bpy.data.scenes.active.objects.new( curve )
- tmpme.getFromObject(object)
- bpy.data.scenes.active.objects.unlink(tmpob)
-
- # restore bevel ob
- if bev_back:
- curve.bevob = bev_back
-
- # Guess the size of the curve object if you have one. This is not perfect but good enough
- bb = bev_back.boundingBox
- self.limbScale = (bb[0] - bb[7]).length / 2.825
-
-
- # TEMP FOR TESTING
- # bpy.data.scenes.active.objects.new(tmpme)
-
- vecs = [ tuple(v.co) for v in tmpme.verts ]
- del tmpme
-
- # for branch
- #used_points = set()
- for brch in self.branches_all:
- offset = 0
- for i in xrange(1, len(brch.bpoints)):
- # find the start/end points
- start_pt = brch.bpoints[offset+i-1]
- end_pt = brch.bpoints[offset+i]
+ bez_list = list(spline)
+ for i in xrange(1, len(bez_list)):
+ bez1 = bez_list[i-1]
+ bez2 = bez_list[i]
+ bez1_vec = bez1.vec
+ bez2_vec = bez2.vec
- start = end = None
- for j, co in enumerate(vecs):
- if start == None:
- if abs(co[0]-start_pt.co[0]) < eul and abs(co[1]-start_pt.co[1]) < eul and abs(co[2]-start_pt.co[2]) < eul:
- start = j
- if end == None:
- if abs(co[0]-end_pt.co[0]) < eul and abs(co[1]-end_pt.co[1]) < eul and abs(co[2]-end_pt.co[2]) < eul:
- end = j
- if start != None and end != None:
- break
+ roll1 = bez1.radius
+ roll2 = bez2.radius
- # for now we assuem the start is always a lower index.
- #if start > end:
- # raise "error index is not one we like"
+ # x,y,z,axis
+ for ii in (0,1,2):
+ forward_diff_bezier(bez1_vec[1][ii], bez1_vec[2][ii], bez2_vec[0][ii], bez2_vec[1][ii], pointlist, steps, ii)
- #used_points.add(start)
- #used_points.add(end)
- radius = start_pt.radius
+ # radius - no axis
+ forward_diff_bezier(roll1, roll1 + 0.390464*(roll2-roll1), roll2 - 0.390464*(roll2-roll1), roll2, radlist, steps, None)
- #print 'coords', start_co, end_co
- #### print "starting", start, end
- if start > end:
- j = start-1
- raise "some bug!"
- else:
- j = start+1
+ bpoints = [ bpoint(brch, Vector(pointlist[ii]), Vector(), radlist[ii] * self.limbScale) for ii in xrange(len(pointlist)) ]
- step = 1
- step_tot = abs(start-end)
- while j!=end:
- #radius = (start_pt.radius*(step_tot-step) - end_pt.radius*step ) / step_tot
- w1 = step_tot-step
- w2 = step
-
- radius = ((start_pt.radius*w1) + (end_pt.radius*w2)) / step_tot
-
- #### print i,j, radius
- pt = bpoint(brch, Vector(vecs[j]), Vector(), radius)
- brch.bpoints.insert(offset+i, pt)
- offset+=1
-
- if start > end:
- j-=1
- else:
- j+=1
-
- step +=1
+ # remove endpoint for all but the last
+ if i != len(bez_list)-1:
+ bpoints.pop()
+
+ brch.bpoints.extend(bpoints)
- # Now calculate the normals
- for brch in self.branches_all:
- for i in xrange(1, len(brch.bpoints)-1):
- brch.bpoints[i].next = brch.bpoints[i+1]
- brch.bpoints[i].prev = brch.bpoints[i-1]
-
- brch.bpoints[0].next = brch.bpoints[1]
- brch.bpoints[-1].prev = brch.bpoints[-2]
-
-
- for pt in brch.bpoints:
- pt.calcNormal()
- pt.calcNextMidCo()
- # remove segments
- # We may want to remove segments for 2 reasons
- # 1) - too high resolution
- # 2) - too close together (makes yucky geometry)
+ for brch in self.branches_all:
+ brch.calcPointLinkedList()
+ brch.calcPointExtras()
def resetTags(self, value):
for brch in self.branches_all:
@@ -203,24 +165,26 @@ class tree:
brch_j = self.branches_all[j]
- best_j, dist = brch_j.findClosest(brch_i.bpoints[0].co)
+ pt_best_j, dist = brch_j.findClosest(brch_i.bpoints[0].co)
- # Check its in range, allow for a bit out - hense the 1.5
- if dist < best_j.radius * sloppy:
+ # Check its in range, allow for a bit out - hense the sloppy
+ if dist < pt_best_j.radius * sloppy:
- # if 1) dont remove the whole branch, maybe an option but later
- # if 2) we are alredy a parent, cant remove me now.... darn :/ not nice... could do this properly but it would be slower and its a corner case.
- # if 3) this point is within the branch, remove it.
+ # if 1) dont remove the whole branch, maybe an option but later
+ # if 2) we are alredy a parent, cant remove me now.... darn :/ not nice...
+ # could do this properly but it would be slower and its a corner case.
+ #
+ # if 3) this point is within the branch, remove it.
while len(brch_i.bpoints)>2 and\
brch_i.bpoints[0].isParent == False and\
- (brch_i.bpoints[0].co - best_j.nextMidCo).length < best_j.radius * base_trim:
+ (brch_i.bpoints[0].co - pt_best_j.nextMidCo).length < pt_best_j.radius * base_trim:
# brch_i.bpoints[0].next = 101 # testing.
del brch_i.bpoints[0]
brch_i.bpoints[0].prev = None
- brch_i.parent_pt = best_j
- best_j.isParent = True # dont remove me
+ brch_i.parent_pt = pt_best_j
+ pt_best_j.isParent = True # dont remove me
# addas a member of best_j.children later when we have the geometry info available.
@@ -260,6 +224,7 @@ class tree:
# Assign this to a spesific side of the parents point
# we know this is a child but not which side it should be attached to.
if brch.parent_pt:
+
child_locs = [\
brch.parent_pt.childPoint(0),\
brch.parent_pt.childPoint(1),\
@@ -267,8 +232,17 @@ class tree:
brch.parent_pt.childPoint(3)]
best_idx = closestVecIndex(brch.bpoints[0].co, child_locs)
- brch.parent_pt.children[best_idx] = brch
- # DONE
+
+ # Crap! we alredy have a branch here, this is hard to solve nicely :/
+ # Probably the best thing to do here is attach this branch to the base of the one thats alredy there
+ # For even
+
+ if brch.parent_pt.children[best_idx]:
+ # Todo - some fun trick! to get the join working.
+ pass
+ else:
+ brch.parent_pt.children[best_idx] = brch
+ #~ # DONE
done_nothing = False
@@ -713,7 +687,7 @@ class tree:
try: cu.delBezier(0)
except: pass
cu.driver = 2 # Python expression
- cu.driverExpression = '%.3f*(%s.evaluate(%.3f,%.3f,(b.Get("curframe")*%.3f)+%.3f).w-0.5)' % (anim_magnitude, tex_str, anim_offset.x, anim_offset.y, anim_speed_final, anim_offset.z)
+ cu.driverExpression = '%.3f*(%s.evaluate((%.3f,%.3f,(b.Get("curframe")*%.3f)+%.3f)).w-0.5)' % (anim_magnitude, tex_str, anim_offset.x, anim_offset.y, anim_speed_final, anim_offset.z)
#(%s.evaluate((b.Get("curframe")*%.3f,0,0)).w-0.5)*%.3f
@@ -1093,8 +1067,19 @@ class branch:
s += '\tbpoints:', len(self.bpoints)
for pt in brch.bpoints:
s += str(self.pt)
+
+ def calcPointLinkedList(self):
+ for i in xrange(1, len(self.bpoints)-1):
+ self.bpoints[i].next = self.bpoints[i+1]
+ self.bpoints[i].prev = self.bpoints[i-1]
+ self.bpoints[0].next = self.bpoints[1]
+ self.bpoints[-1].prev = self.bpoints[-2]
+ def calcPointExtras(self):
+ for pt in self.bpoints:
+ pt.calcNormal()
+ pt.calcNextMidCo()
def getParentQuadAngle(self):
'''
@@ -1472,6 +1457,7 @@ def buildTree(ob, single=False):
joint_smooth = PREFS['seg_joint_smooth'].val\
)
+
ob_mesh = getCurveChild('Mesh')
if not ob_mesh:
# New object