[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [2132] branches/ivygen: Added own directory with working copy of the script.
Andrew Hale
TrumanBlending at gmail.com
Mon Jul 18 09:12:17 CEST 2011
Revision: 2132
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=2132
Author: trumanblending
Date: 2011-07-18 07:12:16 +0000 (Mon, 18 Jul 2011)
Log Message:
-----------
Added own directory with working copy of the script.
Added Paths:
-----------
branches/ivygen/truman_ivy/
branches/ivygen/truman_ivy/ivy_gen_truman.py
Added: branches/ivygen/truman_ivy/ivy_gen_truman.py
===================================================================
--- branches/ivygen/truman_ivy/ivy_gen_truman.py (rev 0)
+++ branches/ivygen/truman_ivy/ivy_gen_truman.py 2011-07-18 07:12:16 UTC (rev 2132)
@@ -0,0 +1,462 @@
+# ##### 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": "Ivy Gen",
+ "author": "testscreenings, PKHG, TrumanBlending",
+ "version": (0, 2),
+ "blender": (2, 5, 8),
+ "api": 38470,
+ "location": "View3D > Add > Curve",
+ "description": "Adds generated ivy to an object.",
+ "warning": "Experimental",
+ "wiki_url": "",
+ "tracker_url": "",
+ "category": "Add Curve"}
+
+import bpy
+from bpy.props import *
+from mathutils import Vector, Matrix, geometry
+from collections import deque
+from math import pow, cos, pi, atan2
+from random import random as rand_val
+import random
+
+
+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
+ prevIvy = root.ivyNodes[-1]
+ # 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)
+ 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)
+
+ # 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
+
+ # 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
+ # 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')
+
+ def __init__(self):
+ self.ivyRoots = deque()
+ self.primaryWeight = 0.5
+ self.randomWeight = 0.2
+ self.gravityWeight = 1.0
+ self.adhesionWeight = 0.1
+ self.branchingProbability = 0.95
+ self.leafProbability = 0.7
+ self.ivySize = 0.005
+ self.ivyLeafSize = 1.5
+ self.ivyBranchSize = 0.15
+ self.maxFloatLength = 0.1
+ self.maxAdhesionDistance = 0.1
+
+ # Normalise all the weights only on intialisation
+ sum = self.primaryWeight + self.randomWeight + self.adhesionWeight
+ self.primaryWeight /= sum
+ self.randomWeight /= sum
+ self.adhesionWeight /= sum
+
+ def seed(self, seedPos):
+ # Seed the Ivy by making a new root and first node
+ tmpRoot = IvyRoot()
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-extensions-cvs
mailing list