[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [2190] branches/ivygen/truman_ivy/ add_curve_ivygen.py: Version 0.0.6

Andrew Hale TrumanBlending at gmail.com
Thu Jul 28 10:27:17 CEST 2011


Revision: 2190
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=2190
Author:   trumanblending
Date:     2011-07-28 08:27:16 +0000 (Thu, 28 Jul 2011)
Log Message:
-----------
Version 0.0.6
- Consolidated geometry generation to increase speed
- Various speed increases

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

Modified: branches/ivygen/truman_ivy/add_curve_ivygen.py
===================================================================
--- branches/ivygen/truman_ivy/add_curve_ivygen.py	2011-07-28 07:10:02 UTC (rev 2189)
+++ branches/ivygen/truman_ivy/add_curve_ivygen.py	2011-07-28 08:27:16 UTC (rev 2190)
@@ -21,7 +21,7 @@
 bl_info = {
     "name": "IvyGen",
     "author": "testscreenings, PKHG, TrumanBlending",
-    "version": (0, 0, 5),
+    "version": (0, 0, 6),
     "blender": (2, 5, 8),
     "api": 38479,
     "location": "View3D > Add > Curve",
@@ -41,48 +41,81 @@
 import time
 
 
-def createIvyLeaves(IVY):
-    # Create the ivy leaves
-    # Order location of the vertices
-    signList = [(-1, 1), (1, 1), (1, -1), (-1, -1)]
+def createIvyGeometry(IVY, growLeaves):
+    '''Create the curve geometry for IVY'''
+    # Compute the local size and the gauss weight filter
+    local_ivyBranchSize = IVY.ivyBranchSize  # * radius * IVY.ivySize
+    gaussWeight = [1.0, 2.0, 4.0, 7.0, 9.0, 10.0, 9.0, 7.0, 4.0, 2.0, 1.0]
 
-    # Get the local size
-    local_ivyLeafSize = IVY.ivyLeafSize  # * radius * IVY.ivySize
+    # Create a new curve and intialise it
+    curve = bpy.data.curves.new("IVY", type='CURVE')
+    curve.dimensions = '3D'
+    curve.bevel_depth = 1
+    curve.use_fill_front = curve.use_fill_back = False
 
-    # Initialise the vertex and face lists
-    vertList = deque()
-    faceList = deque()
+    if growLeaves:
+        # Create the ivy leaves
+        # Order location of the vertices
+        signList = [(-1, 1), (1, 1), (1, -1), (-1, -1)]
 
-    # Store the methods for faster calling
-    addV = vertList.append
-    addF = faceList.append
-    rotMat = Matrix.Rotation
+        # Get the local size
+        local_ivyLeafSize = IVY.ivyLeafSize  # * radius * IVY.ivySize
 
-    # Loop over all roots
+        # Initialise the vertex and face lists
+        vertList = deque()
+        faceList = deque()
+
+        # Store the methods for faster calling
+        addV = vertList.extend
+        addF = faceList.extend
+        rotMat = Matrix.Rotation
+
+    # Loop over all roots to generate its nodes
     for root in IVY.ivyRoots:
-        # Get the last node in the root
-        prevIvyLength = 1 / root.ivyNodes[-1].length
-        # Loop over all node ten times
-        for i in range(10):
-            for j in range(len(root.ivyNodes) - 1):
-                node = root.ivyNodes[j]
-                nodeNext = root.ivyNodes[j + 1]
+        # Only grow if more than one node
+        numNodes = len(root.ivyNodes)
+        if numNodes > 1:
+            # Calculate the local radius
+            local_ivyBranchRadius = 1 / (root.parents + 1) + 1
+            splineVerts = deque()
+            splineRadii = deque()
+            prevIvyLength = 1 / root.ivyNodes[-1].length
+            splineVerts.extend([n.pos.to_4d()[i] for n in
+                                              root.ivyNodes for i in range(4)])
+            splineRadii.extend([(local_ivyBranchRadius * local_ivyBranchSize *
+                     (1.3 - n.length * prevIvyLength)) for n in root.ivyNodes])
 
-                # Find the weight and normalise the smooth adhesion vector
-                weight = pow(node.length * prevIvyLength, 0.7)
-                normalAd = node.smoothAdhesionVector.normalized()
+            # Add the poly curve and set coords and radii
+            newSpline = curve.splines.new(type='POLY')
+            newSpline.points.add(len(splineVerts) // 4 - 1)
+            newSpline.points.foreach_set('co', splineVerts)
+            newSpline.points.foreach_set('radius', splineRadii)
 
-                # Calculate the ground ivy and the new weight
-                groundIvy = max(0.0, -normalAd.z)
-                weight += groundIvy * pow(1 - node.length * prevIvyLength, 2)
+            # Loop over all nodes in the root
+            for i, n in enumerate(root.ivyNodes):
+                for k in range(len(gaussWeight)):
+                    idx = max(0, min(i + k - 5, numNodes - 1))
+                    n.smoothAdhesionVector += (gaussWeight[k] *
+                                             root.ivyNodes[idx].adhesionVector)
+                n.smoothAdhesionVector /= 56.0
+                n.adhesionLength = n.smoothAdhesionVector.length
+                n.smoothAdhesionVector.normalize()
 
-                # Generate the probability
-                probability = rand_val()
+                if growLeaves and (i < numNodes - 1):
+                    count = 0
+                    node = root.ivyNodes[i]
+                    nodeNext = root.ivyNodes[i + 1]
 
-                # If we need to grow a leaf, do so
-                if (probability * weight) > IVY.leafProbability:
+                    # Find the weight and normalise the smooth adhesion vector
+                    weight = pow(node.length * prevIvyLength, 0.7)
+
+                    # Calculate the ground ivy and the new weight
+                    groundIvy = max(0.0, -node.smoothAdhesionVector.z)
+                    weight += groundIvy * pow(1 - node.length *
+                                                              prevIvyLength, 2)
+
                     # Find the alignment weight
-                    alignmentWeight = node.smoothAdhesionVector.length
+                    alignmentWeight = node.adhesionLength
 
                     # Calculate the needed angles
                     phi = atan2(node.smoothAdhesionVector.y,
@@ -91,14 +124,6 @@
                     theta = (0.5 *
                         node.smoothAdhesionVector.angle(Vector((0, 0, -1)), 0))
 
-                    # Generate the random vector
-                    randomVector = Vector((rand_val() - 0.5, rand_val() - 0.5,
-                                   rand_val() - 0.5))
-
-                    # Find the leaf center
-                    center = node.pos.lerp(nodeNext.pos, i / 10) +\
-                                               local_ivyLeafSize * randomVector
-
                     # Find the size weight
                     sizeWeight = 1.5 - (cos(2 * pi * weight) * 0.5 + 0.5)
 
@@ -108,103 +133,68 @@
 
                     # Calculate the leaf size an append the face to the list
                     leafSize = local_ivyLeafSize * sizeWeight
-                    currentVert = len(vertList)
 
-                    addF((currentVert, currentVert + 1,
-                                             currentVert + 2, currentVert + 3))
+                    for j in range(10):
+                        # Generate the probability
+                        probability = rand_val()
 
-                    # For each of the verts in the list rotate/scale and append
-                    basisVecX = Vector((1, 0, 0))
-                    basisVecY = Vector((0, 1, 0))
+                        # If we need to grow a leaf, do so
+                        if (probability * weight) > IVY.leafProbability:
 
-                    horiRot = rotMat(theta, 3, 'X')
-                    vertRot = rotMat(phi, 3, 'Z')
+                            count += 1
 
-                    basisVecX.rotate(horiRot)
-                    basisVecY.rotate(horiRot)
-
-                    basisVecX.rotate(vertRot)
-                    basisVecY.rotate(vertRot)
-
-                    basisVecX *= leafSize
-                    basisVecY *= leafSize
-
-                    randomVector = Vector((rand_val() - 0.5,
+                            # Generate the random vector
+                            randomVector = Vector((rand_val() - 0.5,
                                            rand_val() - 0.5, rand_val() - 0.5))
 
-                    for k1, k2 in signList:
-                        tmpPos = k1 * basisVecX + k2 * basisVecY
-                        tmpPos += (randomVector * local_ivyLeafSize *
-                                                     sizeWeight * 0.5 + center)
-                        addV(tmpPos)
+                            # Find the leaf center
+                            center = node.pos.lerp(nodeNext.pos, j / 10) +\
+                                               local_ivyLeafSize * randomVector
 
-    # Generate the new leaf mesh and link
-    me = bpy.data.meshes.new('IvyLeaf')
-    me.from_pydata(vertList, [], faceList)
-    me.validate()
-    ob = bpy.data.objects.new('IvyLeaf', me)
-    bpy.context.scene.objects.link(ob)
+                            # For each of the verts, rotate/scale and append
+                            basisVecX = Vector((1, 0, 0))
+                            basisVecY = Vector((0, 1, 0))
 
-    tex = me.uv_textures.new("Leaves")
+                            horiRot = rotMat(theta, 3, 'X')
+                            vertRot = rotMat(phi, 3, 'Z')
 
-    # Set the uv texture coords
-    for d in tex.data:
-        uv1, uv2, uv3, uv4 = signList
+                            basisVecX.rotate(horiRot)
+                            basisVecY.rotate(horiRot)
 
-    return ob
+                            basisVecX.rotate(vertRot)
+                            basisVecY.rotate(vertRot)
 
+                            basisVecX *= leafSize
+                            basisVecY *= leafSize
 
-def createIvyCurves(IVY):
-    '''Create the curve geometry for IVY'''
-    # Compute the local size and the gauss weight filter
-    local_ivyBranchSize = IVY.ivyBranchSize  # * radius * IVY.ivySize
-    gaussWeight = [1.0, 2.0, 4.0, 7.0, 9.0, 10.0, 9.0, 7.0, 4.0, 2.0, 1.0]
+                            addV([k1 * basisVecX + k2 * basisVecY + center for
+                                                           k1, k2 in signList])
 
-    # Create a new curve and intialise it
-    curve = bpy.data.curves.new("IVY", type='CURVE')
-    curve.dimensions = '3D'
-    curve.bevel_depth = 1
-    curve.use_fill_front = curve.use_fill_back = False
+                    currentVert = len(faceList)
+                    addF([[4 * k + l for l in range(4)] for k in
+                                      range(currentVert, currentVert + count)])
 
-    # Loop over all roots to generate its nodes
-    for root in IVY.ivyRoots:
-        # Only grow if more than one node
-        if len(root.ivyNodes) > 1:
-            # Calculate the local radius
-            local_ivyBranchRadius = 1 / (root.parents + 1) + 1
-            splineVerts = deque()
-            splineRadii = deque()
-            extendV = splineVerts.extend
-            appendR = splineRadii.append

@@ Diff output truncated at 10240 characters. @@


More information about the Bf-extensions-cvs mailing list