[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