[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [2156] branches/ivygen/pkhg_ivy/ testditNew.py: littlebit differen approach.

Peter K.H. Gragert pkhgragert at gmail.com
Thu Jul 21 12:26:51 CEST 2011


Revision: 2156
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=2156
Author:   pkhg
Date:     2011-07-21 10:26:50 +0000 (Thu, 21 Jul 2011)
Log Message:
-----------
littlebit differen approach.
A Panel in the toolsshelf
Timelimits to set to prevent to long execution.

Added Paths:
-----------
    branches/ivygen/pkhg_ivy/testditNew.py

Added: branches/ivygen/pkhg_ivy/testditNew.py
===================================================================
--- branches/ivygen/pkhg_ivy/testditNew.py	                        (rev 0)
+++ branches/ivygen/pkhg_ivy/testditNew.py	2011-07-21 10:26:50 UTC (rev 2156)
@@ -0,0 +1,696 @@
+# ##### 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 compliant>
+
+bl_info = {
+    "name": "IvyGen",
+    "author": "testscreenings, PKHG, TrumanBlending",
+    "version": (0, 0, 2),
+    "blender": (2, 5, 8),
+    "api": 38479,
+    "location": "toolspanel! (View3D T if needed)",
+    "description": "Adds generated ivy to an object.",
+    "warning": "Script in Beta",
+    "wiki_url": "",
+    "tracker_url": "",
+    "category": "Add Curve"}
+
+
+import bpy
+from bpy.props import FloatProperty, IntProperty
+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
+from time import time
+
+def createIvyLeaves(IVY, radius):
+    # Create the ivy leaves
+    # Order location of the vertices
+    signList = [(-1, 1), (1, 1), (1, -1), (-1, -1)]
+
+    # Get the local size
+    local_ivyLeafSize = radius * IVY.ivySize * IVY.ivyLeafSize
+
+    # Initialise the vertex and face lists
+    vertList = deque()
+    faceList = deque()
+
+    # Store the methods for faster calling
+    addV = vertList.append
+    addF = faceList.append
+    rotMat = Matrix.Rotation
+
+    # Loop over all roots
+    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 node in root.ivyNodes:
+                # Find the weight and normalise the smooth adhesion vector
+                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 * prevIvyLength, 2)
+
+                # Generate the probability
+                probability = rand_val()
+
+                # If we need to grow a leaf, do so
+                if ((probability * weight) > IVY.leafProbability and
+                                      node.smoothAdhesionVector.length != 0.0):
+                    # Find the alignment weight
+                    alignmentWeight = node.smoothAdhesionVector.length
+
+                    # Calculate the needed angles
+                    phi = atan2(node.smoothAdhesionVector.y,
+                                          node.smoothAdhesionVector.x) - pi / 2
+                    theta = (0.5 *
+                           node.smoothAdhesionVector.angle(Vector((0, 0, -1))))
+
+                    # 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 + local_ivyLeafSize * randomVector
+
+                    # 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 = local_ivyLeafSize * sizeWeight
+                    currentVert = len(vertList)
+
+                    faceList.append((currentVert, currentVert + 1,
+                                             currentVert + 2, currentVert + 3))
+
+                    # For each of the verts in the list rotate/scale and append
+                    for k1, k2 in signList:
+                        randomVector = Vector((rand_val() - 0.5,
+                                           rand_val() - 0.5, rand_val() - 0.5))
+                        tmpPos = Vector((k1 * leafSize, k2 * leafSize, 0.0))
+                        horiRot = rotMat(theta, 3, 'X')
+                        tmpPos.rotate(horiRot)
+                        vertRot = rotMat(phi, 3, 'Z')
+                        tmpPos.rotate(vertRot)
+                        tmpPos += (randomVector * local_ivyLeafSize *
+                                                     sizeWeight * 0.5 + center)
+                        addV(tmpPos)
+
+    # 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)
+
+    tex = me.uv_textures.new("Leaves")
+
+    # Set the uv texture coords
+    for d in tex.data:
+        uv1, uv2, uv3, uv4 = signList
+
+    return ob
+
+
+def createIvyCurves(IVY, radius):
+    '''Create the curve geometry for IVY'''
+    # Compute the local size and the gauss weight filter
+    local_ivyBranchSize = radius * IVY.ivySize * IVY.ivyBranchSize
+    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
+    bpy.ops.object.select_all(action='DESELECT')
+    curve = bpy.data.curves.new("IVY", type='CURVE')
+    curve.dimensions = '3D'
+    curve.bevel_depth = 1
+    curve.use_fill_front = curve.use_fill_back = False
+    scene = bpy.context.scene
+    print("\n======= start Ivy Curves")
+    startTime = time()
+    # 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:
+            timeNow = time()
+            if timeNow - startTime > scene.maxTimeCreateIvyCurves:
+                break
+            # Calculate the local radius
+            local_ivyBranchRadius = 1 / (root.parents + 1) + 1
+            splineVerts = deque()
+            splineRadii = deque()
+            extendV = splineVerts.extend
+            appendR = splineRadii.append
+            # Loop over all nodes in the root
+            for i, n in enumerate(root.ivyNodes):
+                # Calculate the weighting for the node
+                weight = n.length / root.ivyNodes[-1].length
+                ivyRad = (local_ivyBranchRadius *
+                                         local_ivyBranchSize * (1.3 - weight))
+                tmpPos = n.pos.copy()
+                tmpPos.resize_4d()
+                extendV(tmpPos.to_tuple())
+                appendR(ivyRad)
+                # Generate the smoothed adhesion vector
+                for k in range(len(gaussWeight)):
+                    idx = max(0, min(i + k - 5, len(root.ivyNodes) - 1))
+                    n.smoothAdhesionVector += (gaussWeight[k] *
+                                             root.ivyNodes[idx].adhesionVector)
+                n.smoothAdhesionVector /= 56.0
+            # 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)
+
+    # Add the object and link to scene
+    newCurve = bpy.data.objects.new("IVY_Curve", curve)
+    bpy.context.scene.objects.link(newCurve)
+    newCurve.select = True
+    bpy.context.scene.objects.active = newCurve
+
+    return newCurve
+
+
+def computeBoundingSphere(ob):
+    # Get the mesh data
+    me = ob.data
+    # Intialise the center
+    center = Vector((0, 0, 0))
+    # Add all vertex coords
+    for v in me.vertices:
+        center += v.co
+    # Average over all verts
+    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',
+                 '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.95,
+                 leafProbability=0.7,
+                 ivySize=0.005,
+                 ivyLeafSize=1.5,
+                 ivyBranchSize=0.15,
+                 maxFloatLength=0.1,
+                 maxAdhesionDistance=0.1):
+
+        self.ivyRoots = deque()
+        scene = bpy.context.scene

@@ Diff output truncated at 10240 characters. @@


More information about the Bf-extensions-cvs mailing list