[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12577] trunk/blender/release/scripts/ wizard_curve2tree.py: - new UV scaling option works better for big/ small branches.

Campbell Barton ideasman42 at gmail.com
Tue Nov 13 17:50:44 CET 2007


Revision: 12577
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12577
Author:   campbellbarton
Date:     2007-11-13 17:50:43 +0100 (Tue, 13 Nov 2007)

Log Message:
-----------
- new UV scaling option works better for big/small branches.
- Can constrain twigs to only grow in a bounding mesh. And an option to prune twigs that grow out.

Modified Paths:
--------------
    trunk/blender/release/scripts/wizard_curve2tree.py

Modified: trunk/blender/release/scripts/wizard_curve2tree.py
===================================================================
--- trunk/blender/release/scripts/wizard_curve2tree.py	2007-11-13 15:32:27 UTC (rev 12576)
+++ trunk/blender/release/scripts/wizard_curve2tree.py	2007-11-13 16:50:43 UTC (rev 12577)
@@ -101,7 +101,10 @@
 		self.branches_twigs =	[]
 		self.mesh = None
 		self.armature = None
-		self.object = None
+		self.objectCurve = None
+		self.objectTwigBounds = None # use for twigs only at the moment.
+		self.objectTwigBoundsIMat = None
+		self.objectTwigBoundsMesh = None
 		self.limbScale = 1.0
 		
 		self.debug_objects = []
@@ -110,16 +113,16 @@
 		s = ''
 		s += '[Tree]'
 		s += '  limbScale: %.6f' % self.limbScale
-		s += '  object: %s' % self.object
+		s += '  object: %s' % self.objectCurve
 		
 		for brch in self.branches_root:
 			s += str(brch)
 		return s
 	
-	def fromCurve(self, object):
+	def fromCurve(self, objectCurve):
 		# Now calculate the normals
-		self.object = object
-		curve = object.data
+		self.objectCurve = objectCurve
+		curve = objectCurve.data
 		steps = curve.resolu # curve resolution
 		
 		# Set the curve object scale
@@ -163,7 +166,7 @@
 				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)
 				
-				# radius - no axis
+				# radius - no axis, Copied from blenders BBone roll interpolation.
 				forward_diff_bezier(radius1, radius1 + 0.390464*(radius2-radius1), radius2 - 0.390464*(radius2-radius1),	radius2,	radlist, steps, None)
 				
 				bpoints = [ bpoint(brch, Vector(pointlist[ii]), Vector(), radlist[ii] * self.limbScale) for ii in xrange(len(pointlist)) ]
@@ -180,13 +183,33 @@
 		# Sort from big to small, so big branches get priority
 		self.branches_all.sort( key = lambda brch: -brch.bpoints[0].radius )
 		
+	def setTwigBounds(self, objectMesh):
+		self.objectTwigBounds = objectMesh
+		self.objectTwigBoundsMesh = objectMesh.getData(mesh=1)
+		self.objectTwigBoundsIMat = objectMesh.matrixWorld.copy().invert()
 		
-		
+		for brch in self.branches_all:
+			brch.calcTwigBounds(self)
+	
+	def isPointInTwigBounds(self, co):
+		return self.objectTwigBoundsMesh.pointInside(co ) #* self.objectTwigBoundsIMat)
+	
 	def resetTags(self, value):
 		for brch in self.branches_all:
 			brch.tag = value
 	
-	def buildConnections(self, sloppy=1.0, base_trim = 1.0, do_twigs = False, twig_ratio=2.0, twig_scale=0.8, twig_random_orientation= 0.5, twig_recursive=True):
+	def buildConnections(	self,\
+							sloppy = 1.0,\
+							base_trim = 1.0,\
+							do_twigs = False,\
+							twig_ratio = 2.0,\
+							twig_scale = 0.8,\
+							twig_random_orientation = 180,\
+							twig_recursive=True,\
+							twig_ob_bounds=None,\
+							twig_ob_bounds_prune=True,\
+							twig_ob_bounds_prune_taper=True,\
+						):
 		'''
 		build tree data - fromCurve must run first
 		
@@ -252,6 +275,11 @@
 		# Important we so this with existing parent/child but before connecting and calculating verts.
 		
 		if do_twigs:
+			irational_num = 22.0/7.0 # use to make the random number more odd
+			
+			if twig_ob_bounds: # Only spawn twigs inside this mesh
+				self.setTwigBounds(twig_ob_bounds)
+			
 			self.buildTwigs(twig_ratio)
 			
 			branches_twig_attached = []
@@ -266,11 +294,10 @@
 				brch_twig_index_LAST = brch_twig_index
 				
 				# new twigs have been added, recalculate
-				branches_twig_sort = [(brch.bestTwigSegment(), brch) for brch in self.branches_all]
+				branches_twig_sort = [brch.bestTwigSegment() for brch in self.branches_all]
 				branches_twig_sort.sort() # this will sort the branches with best braches for adding twigs to at the start of the list
 				
-				for twig_data, brch_parent in branches_twig_sort:
-					twig_pt_index = twig_data[1]
+				for tmp_sortval, twig_pt_index, brch_parent in branches_twig_sort: # tmp_sortval is not used.
 					
 					if twig_pt_index != -1:
 						
@@ -279,22 +306,20 @@
 						if brch_twig_index >= len(self.branches_twigs):
 							break
 						
-						#print "twig"
-						
 						brch_twig = self.branches_twigs[brch_twig_index]
 						
+						parent_pt = brch_parent.bpoints[twig_pt_index]
 						
-						parent_pt = brch_parent.bpoints[twig_pt_index]
+						#if parent_pt.inTwigBounds == False:
+						#	raise "Error"
+						
 						brch_twig.parent_pt = parent_pt
 						parent_pt.childCount += 1
 						
-						#angle = brch_parent.getParentAngle()
-						
 						# Align this with the existing branch
 						angle = AngleBetweenVecs(zup, parent_pt.no)
 						cross = CrossVecs(zup, parent_pt.no)
 						mat_align = RotationMatrix(angle, 3, 'r', cross)
-						# brch_twig.transform(mat)
 						
 						# Use the bend on the point to work out which way to make the branch point!
 						if parent_pt.prev:	cross = CrossVecs(parent_pt.no, parent_pt.prev.no - parent_pt.no)
@@ -316,23 +341,48 @@
 						mat_scale = Matrix([scale,0,0],[0,scale,0],[0,0,scale])
 						
 						# Random orientation
+						# THIS IS NOT RANDOM - Dont be real random so we can always get re-produceale results.
+						# Number b
+						rnd = (((irational_num * scale * 10000000) % 360) - 180) * twig_random_orientation
 						
-						rnd = Rand(0, twig_random_orientation)
+						mat_orientation = RotationMatrix(rnd, 3, 'r', parent_pt.no)
 						
-						mat_orientation = RotationMatrix(rnd*180, 3, 'r', parent_pt.no)
-						
 						brch_twig.transform(mat_scale * mat_branch_angle * mat_align * mat_orientation, parent_pt.co)
 						
+						
+						
+						# When using a bounding mesh, clip and calculate points in bounds.
 						#print "Attempting to trim base"
 						brch_twig.baseTrim(base_trim)
 						
+						if twig_ob_bounds and (twig_ob_bounds_prune or twig_recursive):
+							brch_twig.calcTwigBounds(self)
+						
+							# we would not have been but here if the bounds were outside
+							if twig_ob_bounds_prune:
+								brch_twig.boundsTrim()
+								
+								if twig_ob_bounds_prune_taper:
+									# taper to a point.
+									brch_twig.taper()
+									
+									
+									
+								
+						
+						
+						
 						# Make sure this dosnt mess up anything else
 						
 						brch_twig_index += 1
 						
 						# Add to the branches
 						#self.branches_all.append(brch_twig)
-						branches_twig_attached.append(brch_twig)
+						if len(brch_twig.bpoints) > 4:
+							branches_twig_attached.append(brch_twig)
+						else:
+							# Dont add the branch
+							parent_pt.childCount -= 1
 				
 				# Watch This! - move 1 tab down for no recursive twigs
 				if twig_recursive:
@@ -467,11 +517,11 @@
 		
 		
 	
-	def toMesh(self, mesh=None, do_uv=True, do_uv_scalewidth=True, uv_image = None, uv_x_scale=1.0, uv_y_scale=4.0, do_cap_ends=False):
+	def toMesh(self, mesh=None, do_uv=True, do_uv_keep_vproportion=True, do_uv_uscale=False, uv_image = None, uv_x_scale=1.0, uv_y_scale=4.0, do_cap_ends=False):
 		# Simple points
 		'''
 		self.mesh = bpy.data.meshes.new()
-		self.object = bpy.data.scenes.active.objects.new(self.mesh)
+		self.objectCurve = bpy.data.scenes.active.objects.new(self.mesh)
 		self.mesh.verts.extend([ pt.co for brch in self.branches_all for pt in brch.bpoints ])
 		'''
 		if mesh:
@@ -644,13 +694,23 @@
 			
 			for brch in self.branches_all:
 				
+				uv_x_scale_branch = 1.0
+				if do_uv_uscale:
+					uv_x_scale_branch = 0.0
+					for pt in brch.bpoints:
+						uv_x_scale_branch += pt.radius
+					
+					uv_x_scale_branch = uv_x_scale_branch / len(brch.bpoints)
+					# uv_x_scale_branch = brch.bpoints[0].radius
+					
+				
 				y_val = 0.0
 				for pt in brch.bpoints:
 					if pt.next:
 						y_size = (pt.co-pt.next.co).length
 						
-						# scale the uvs by the radiusm, avoids stritching.
-						if do_uv_scalewidth:
+						# scale the uvs by the radius, avoids stritching.
+						if do_uv_keep_vproportion:
 							y_size = y_size / pt.radius * uv_y_scale
 						
 						for i in (0,1,2,3):
@@ -658,10 +718,11 @@
 								if uv_image:
 									pt.faces[i].image = uv_image
 								
-								x1 = i*0.25 * uv_x_scale							
-								x2 = (i+1)*0.25 * uv_x_scale
+								uvs = pt.faces[i].uv
 								
-								uvs = pt.faces[i].uv
+								x1 = i*0.25 * uv_x_scale * uv_x_scale_branch	
+								x2 = (i+1)*0.25 * uv_x_scale * uv_x_scale_branch
+								
 								uvs[3].x = x1;
 								uvs[3].y = y_val+y_size
 								
@@ -673,9 +734,7 @@
 								
 								uvs[2].x = x2
 								uvs[2].y = y_val+y_size
-								
 						
-						do_uv_scalewidth
 						if pt.next:	
 							y_val += y_size
 		else:
@@ -818,7 +877,7 @@
 		# When we have the same trees next to eachother, they will animate the same way unless we give each its own texture or offset settings.
 		# We can use the object's location as a factor - this also will have the advantage? of seeing the animation move across the tree's
 		# allow a scale so the difference between tree textures can be adjusted.
-		anim_offset = self.object.matrixWorld.translationPart() * anim_offset_scale
+		anim_offset = self.objectCurve.matrixWorld.translationPart() * anim_offset_scale
 		
 		anim_speed_final = anim_speed
 		# Assign drivers to them all
@@ -867,7 +926,7 @@
 class bpoint(object):
 	''' The point in the middle of the branch, not the mesh points
 	'''
-	__slots__ = 'branch', 'co', 'no', 'radius', 'vecs', 'verts', 'children', 'faces', 'next', 'prev', 'childCount', 'bpbone', 'roll_angle', 'nextMidCo', 'childrenMidCo', 'childrenMidRadius', 'targetCos'
+	__slots__ = 'branch', 'co', 'no', 'radius', 'vecs', 'verts', 'children', 'faces', 'next', 'prev', 'childCount', 'bpbone', 'roll_angle', 'nextMidCo', 'childrenMidCo', 'childrenMidRadius', 'targetCos', 'inTwigBounds'
 	def __init__(self, brch, co, no, radius):
 		self.branch = brch
 		self.co = co
@@ -902,6 +961,9 @@
 		# Target locations are used when you want to move the point to a new location but there are
 		# more then 1 influence, build up a list and then apply
 		self.targetCos = []
+		
+		# When we use twig bounding mesh, store if this point is in the bounding mesh. Assume true unless we set to false and do the test
+		self.inTwigBounds = True 
 	
 	def __repr__(self):
 		s = ''
@@ -911,7 +973,10 @@
 		s += '\t\tchildren:', [(child != False) for child in self.children]
 		return s
 		
-		
+	def makeLast(self):
+		self.next = None
+		self.nextMidCo = None
+		self.childrenMidCo = None
 	
 	def setCo(self, co):
 		self.co[:] = co
@@ -1289,10 +1354,23 @@
 		self.bpoints[-1].prev = self.bpoints[-2]
 		

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list