[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [2198] branches/ivygen/pkhg_ivy/ 2197_pkhg.py: Version 2197 from Truman used but a lot of change!

Peter K.H. Gragert pkhgragert at gmail.com
Sat Jul 30 08:09:14 CEST 2011


Revision: 2198
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=2198
Author:   pkhg
Date:     2011-07-30 06:09:13 +0000 (Sat, 30 Jul 2011)
Log Message:
-----------
Version 2197 from Truman used but a lot of change!
A Panel, much nicer!
Deletion of latest Ivy in place of update (not understood yet)
 only done if a checkbox is clicked.
Leaves get an strange but good visible green colour
Reversion to default values available
If a blend file is saved, the scene values were saved too, so the parameters are the latest used ones,
good if gooing on later and no paperwork needed.

Added Paths:
-----------
    branches/ivygen/pkhg_ivy/2197_pkhg.py

Added: branches/ivygen/pkhg_ivy/2197_pkhg.py
===================================================================
--- branches/ivygen/pkhg_ivy/2197_pkhg.py	                        (rev 0)
+++ branches/ivygen/pkhg_ivy/2197_pkhg.py	2011-07-30 06:09:13 UTC (rev 2198)
@@ -0,0 +1,781 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8-80 compliant>
+
+bl_info = {
+    "name": "IvyGenPanel",
+    "author": "testscreenings, PKHG, TrumanBlending",
+    "version": (0, 0, 8),
+    "blender": (2, 5, 8),
+    "api": 38479,
+    "location": "View3D (toolshelf, toggle is T)",
+    "description": "Adds generated ivy to a mesh object starting at the 3D"\
+                   " cursor.",
+    "warning": "beta",
+    "wiki_url": "",
+    "tracker_url": "",
+    "category": "Add Curve"}
+
+
+import bpy
+from bpy.props import FloatProperty, IntProperty, BoolProperty
+from mathutils import Vector, Matrix
+from collections import deque
+from math import pow, cos, pi, atan2
+from random import random as rand_val, seed as rand_seed
+import time
+
+def makeMaterial(name = "White", diffuse = [1,1,1], specular = [0.,.5,.5], alpha = 1):
+    mat = bpy.data.materials.new(name)
+    mat.diffuse_color = diffuse
+    mat.diffuse_shader = 'LAMBERT' 
+    mat.diffuse_intensity = 1.0 
+    mat.specular_color = specular
+    mat.specular_shader = 'COOKTORR'
+    mat.specular_intensity = 0.5
+    mat.alpha = alpha
+    mat.ambient = 1
+    return mat
+
+def setMaterial(ob, mat):
+    me = ob.data
+    me.materials.append(mat)
+pureLightingGreen = makeMaterial(name="pureLightingGreen", diffuse = [0.0, 10.0, 0.0])
+
+
+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]
+
+    # Create a new curve and intialise it
+    curve = bpy.data.curves.new("IVY.000", type='CURVE')
+    curve.dimensions = '3D'
+    curve.bevel_depth = 1
+    curve.use_fill_front = curve.use_fill_back = False
+
+    if growLeaves:
+        # Create the ivy leaves
+        # Order location of the vertices
+        signList = [(-1, 1), (1, 1), (1, -1), (-1, -1)]
+
+        # Get the local size
+        #local_ivyLeafSize = IVY.ivyLeafSize  # * radius * IVY.ivySize
+
+        # Initialise the vertex and face lists
+        vertList = deque()
+
+        # Store the methods for faster calling
+        addV = vertList.extend
+        rotMat = Matrix.Rotation
+
+    # Loop over all roots to generate its nodes
+    for root in IVY.ivyRoots:
+        # 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
+            prevIvyLength = 1 / root.ivyNodes[-1].length
+            splineVerts = [ax for n in root.ivyNodes for ax in n.pos.to_4d()]
+
+            radiusConstant = local_ivyBranchRadius * IVY.ivyBranchSize
+            splineRadii = [radiusConstant * (1.3 - n.length * prevIvyLength)
+                                                        for n in root.ivyNodes]
+
+            # 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)
+
+            # 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()
+
+                if growLeaves and (i < numNodes - 1):
+                    node = root.ivyNodes[i]
+                    nodeNext = root.ivyNodes[i + 1]
+
+                    # 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.adhesionLength
+
+                    # Calculate the needed angles
+                    phi = atan2(node.smoothAdhesionVector.y,
+                                          node.smoothAdhesionVector.x) - pi / 2
+
+                    theta = (0.5 *
+                        node.smoothAdhesionVector.angle(Vector((0, 0, -1)), 0))
+
+                    # Find the size weight
+                    sizeWeight = 1.5 - (cos(2 * pi * weight) * 0.5 + 0.5)
+
+                    # Randomise the angles
+                    phi += (rand_val() - 0.5) * (1.3 - alignmentWeight)
+                    theta += (rand_val() - 0.5) * (1.1 - alignmentWeight)
+
+                    # Calculate the leaf size an append the face to the list
+                    leafSize = IVY.ivyLeafSize * sizeWeight
+
+                    for j in range(10):
+                        # Generate the probability
+                        probability = rand_val()
+
+                        # If we need to grow a leaf, do so
+                        if (probability * weight) > IVY.leafProbability:
+
+                            # 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, j / 10) +\
+                                               IVY.ivyLeafSize * randomVector
+
+                            # For each of the verts, rotate/scale and append
+                            basisVecX = Vector((1, 0, 0))
+                            basisVecY = Vector((0, 1, 0))
+
+                            horiRot = rotMat(theta, 3, 'X')
+                            vertRot = rotMat(phi, 3, 'Z')
+
+                            basisVecX.rotate(horiRot)
+                            basisVecY.rotate(horiRot)
+
+                            basisVecX.rotate(vertRot)
+                            basisVecY.rotate(vertRot)
+
+                            basisVecX *= leafSize
+                            basisVecY *= leafSize
+
+                            addV([k1 * basisVecX + k2 * basisVecY + center for
+                                                           k1, k2 in signList])
+
+    # Add the object and link to scene
+    newCurve = bpy.data.objects.new("IVY_Curve.000", curve)
+    bpy.context.scene.objects.link(newCurve)
+
+    if growLeaves:
+        faceList = [[4 * i + l for l in range(4)] for i in
+                                                     range(len(vertList) // 4)]
+
+        # Generate the new leaf mesh and link
+        me = bpy.data.meshes.new('IvyLeaf.000')
+        me.from_pydata(vertList, [], faceList)
+        me.update(calc_edges=True)
+        ob = bpy.data.objects.new('IvyLeaf.000', me)
+        bpy.context.scene.objects.link(ob)
+        setMaterial(ob, pureLightingGreen) #nice or not? PKHG
+        tex = me.uv_textures.new("Leaves.000")
+
+        # Set the uv texture coords
+        for d in tex.data:
+            uv1, uv2, uv3, uv4 = signList
+
+        ob.parent = newCurve
+
+
+def computeBoundingSphere(ob):
+    me = ob.data
+    center = Vector((0, 0, 0))
+    for v in me.vertices:
+        center += v.co
+    center /= len(me.vertices)
+    # Create the iterator and find its max
+    length_iter = ((center - v.co).length for v in me.vertices)
+    radius = max(length_iter)
+    return radius
+
+
+class IvyNode:
+    """ The basic class used for each point on the ivy which is grown."""
+    __slots__ = ('pos', 'primaryDir', 'adhesionVector', 'adhesionLength',
+                 'smoothAdhesionVector', 'length', 'floatingLength', 'climb')
+
+    def __init__(self):
+        self.pos = Vector((0, 0, 0))
+        self.primaryDir = Vector((0, 0, 1))
+        self.adhesionVector = Vector((0, 0, 0))
+        self.smoothAdhesionVector = Vector((0, 0, 0))
+        self.length = 0.0001
+        self.floatingLength = 0.0
+        self.climb = True
+
+
+class IvyRoot:
+    """ The class used to hold all ivy nodes growing from this root point."""
+    __slots__ = ('ivyNodes', 'alive', 'parents')
+
+    def __init__(self):
+        self.ivyNodes = deque()
+        self.alive = True
+        self.parents = 0
+
+
+class Ivy:
+    """ The class holding all parameters and ivy roots."""
+    __slots__ = ('ivyRoots', 'primaryWeight', 'randomWeight',
+                 'gravityWeight', 'adhesionWeight', 'branchingProbability',
+                 'leafProbability', 'ivySize', 'ivyLeafSize', 'ivyBranchSize',
+                 'maxFloatLength', 'maxAdhesionDistance', 'maxLength')
+
+    def __init__(self,
+                 primaryWeight=0.5,
+                 randomWeight=0.2,
+                 gravityWeight=1.0,
+                 adhesionWeight=0.1,
+                 branchingProbability=0.05,
+                 leafProbability=0.35,
+                 ivySize=0.02,
+                 ivyLeafSize=0.02,

@@ Diff output truncated at 10240 characters. @@


More information about the Bf-extensions-cvs mailing list