[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [2137] branches/ivygen/truman_ivy/ ivy_gen_truman.py: - Added precalculation of the ivy length.

Andrew Hale TrumanBlending at gmail.com
Tue Jul 19 10:11:58 CEST 2011


Revision: 2137
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=2137
Author:   trumanblending
Date:     2011-07-19 08:11:58 +0000 (Tue, 19 Jul 2011)
Log Message:
-----------
- Added precalculation of the ivy length.
- Added the restriction on the growth of the ivy which limits its length by adding a new property to Ivy class.
- Added better poll function to check if the selected object is a mesh and whether the 3D cursor is close enough to it.
- Added a check on the ivy growth to catch the case that all ivy may die before the target length is reached.
- The target maximum length of the ivy is given as a multiple of the bounding sphere radius.

Modified Paths:
--------------
    branches/ivygen/truman_ivy/ivy_gen_truman.py

Modified: branches/ivygen/truman_ivy/ivy_gen_truman.py
===================================================================
--- branches/ivygen/truman_ivy/ivy_gen_truman.py	2011-07-19 07:15:08 UTC (rev 2136)
+++ branches/ivygen/truman_ivy/ivy_gen_truman.py	2011-07-19 08:11:58 UTC (rev 2137)
@@ -60,17 +60,17 @@
     # Loop over all roots
     for root in IVY.ivyRoots:
         # Get the last node in the root
-        prevIvy = root.ivyNodes[-1]
+        prevIvyLength = 1 / root.ivyNodes[-1].length
         # Loop over all node ten times
         for i in range(10):
             for node in root.ivyNodes:
                 # Find the weight and normalise the smooth adhesion vector
-                weight = pow(node.length / prevIvy.length, 0.7)
+                weight = pow(node.length * prevIvyLength, 0.7)
                 normalAd = node.smoothAdhesionVector.normalized()
 
                 # Calculate the ground ivy and the new weight
                 groundIvy = max(0.0, -normalAd.dot(Vector((0, 0, 1))))
-                weight += groundIvy * pow(1 - node.length / prevIvy.length, 2)
+                weight += groundIvy * pow(1 - node.length * prevIvyLength, 2)
 
                 # Generate the probability
                 probability = rand_val()
@@ -236,7 +236,7 @@
     __slots__ = ('ivyRoots', 'primaryWeight', 'randomWeight',
                  'gravityWeight', 'adhesionWeight', 'branchingProbability',
                  'leafProbability', 'ivySize', 'ivyLeafSize', 'ivyBranchSize',
-                 'maxFloatLength', 'maxAdhesionDistance')
+                 'maxFloatLength', 'maxAdhesionDistance', 'maxLength')
 
     def __init__(self):
         self.ivyRoots = deque()
@@ -251,6 +251,7 @@
         self.ivyBranchSize = 0.15
         self.maxFloatLength = 0.1
         self.maxAdhesionDistance = 0.1
+        self.maxLength = 0.0
 
         # Normalise all the weights only on intialisation
         sum = self.primaryWeight + self.randomWeight + self.adhesionWeight
@@ -326,6 +327,9 @@
             tmpNode.primaryDir.normalize()
             tmpNode.adhesionVector = adhesionVector
             tmpNode.length = prevIvy.length + (newPos - prevIvy.pos).length
+            
+            if tmpNode.length > self.maxLength:
+                self.maxLength = tmpNode.length
 
             # If the node isn't climbing, update it's floating length
             # Otherwise set it to 0
@@ -407,25 +411,22 @@
 
     @classmethod
     def poll(self, context):
-        # Check if there's an object
-        if context.active_object is None:
-            return False
-        else:
+        # Check if there's an object and whether it's a mesh
+        ob = context.active_object
+        if (ob is not None) and (ob.type == 'MESH'):
+            # Check that the cursor is close enough
             curPos = context.scene.cursor_location
-            nearPos = context.active_object.closest_point_on_mesh(curPos)
-            # Check if the cursor is close enough
-            if (curPos - nearPos[0]).length > 0.1:
-                return False
-            else:
+            nearPos = ob.closest_point_on_mesh(curPos)
+            if (curPos - nearPos[0]).length < 0.1:
                 return True
+        return False
 
     def execute(self, context):
         # Get the selected object
         ob = context.active_object
 
-        # If it's a mesh, compute bounding sphere radius
-        if ob.type == 'MESH':
-            radius = computeBoundingSphere(ob)
+        # Compute bounding sphere radius
+        radius = computeBoundingSphere(ob)
 
         # Get the seeding point
         seedPoint = context.scene.cursor_location
@@ -436,11 +437,16 @@
         # Generate first root and node
         IVY.seed(seedPoint)
 
+        # Set the maximum length as a multiple of the radius
+        maxIvyLength = 0.5
+        checkAlive = True
+
         # Grow until 200 roots is reached or backup counter exceeds limit
-        i = 0
-        while len(IVY.ivyRoots) < 200 and i < 100000:
+        while IVY.maxLength < (radius*maxIvyLength) and checkAlive:
             IVY.grow(radius, ob)
-            i += 1
+            checkAliveIter = (r.alive for r in IVY.ivyRoots)
+            if True in checkAliveIter:
+                checkAlive = True
 
         # Create the curve and leaf geometry
         curveOb = createIvyCurves(IVY, radius)



More information about the Bf-extensions-cvs mailing list