# PYMEL V 1.0.0 REQUIRED - get it at http://code.google.com/p/pymel/ # ASSUMES use of PyMel v 1.0.0 or greater. WILL NOT WORK WITH PREVIOUS VERSIONS import pymel.all as pm import math """ by Geordie Martinez """ def generatePhyllotaxisGroup(numOfItems, dupObj, spread=0.25,grpName=None): """ creates a phyllotaxis placement of a series of duplicated items. good for creating globs of cells or interesting patterns for geometry or particles USAGE: select an object: phyllotaxis.generatePhyllotaxisGroup(100, pm.selected()[0], spread=0.25,grpName="blah") or declare an object: phyllotaxis.generatePhyllotaxisGroup(100, "ball", spread=0.25,grpName="blah") or pymel sphere to begin with: phyllotaxis.generatePhyllotaxisGroup(100, pm.sphere()[0], spread=0.25,grpName="blah") """ grp = None if grpName: # SEE IF GROUP ALREADY EXISTS try: grp = pm.PyNode(grpName) except: pass if grpName and not grp : grp = group(em=True, n=grpName) dupObj = dupObj or pm.selected()[0] # 137.5 degrees ... one of the phyllotaxin rotation values degreesToRadians = 2.399827 rotateAxis = pm.datatypes.Vector([0,1,0]) # IF NOT A PyNode OBJECT PASSED IN make the object a PyNode if not hasattr(dupObj,"exists"): dupObj = pm.PyNode(dupObj) dupStartPos = dupObj.getTranslation(ws=True) bbox = dupObj.getBoundingBox() width = abs(bbox[0][0] - bbox[1][0]) height = abs(bbox[0][1] - bbox[1][1]) depth = abs(bbox[0][2] - bbox[1][2]) spacer = width if width >= depth else depth sweepStart = pm.datatypes.Vector([spacer,0,0]) + dupStartPos prev = None for phy in range(numOfItems): print prev dup = duplicate(dupObj,n="%s_%s" % (dupObj,phy))[0] if not prev: prev = sweepStart dup.translate.set(prev) if grp: dup.setParent(grp) continue radiusThisPass = math.sqrt(phy) * spread sweepStart = prev newRot = pm.datatypes.Vector.rotateBy( sweepStart,rotateAxis,degreesToRadians ) newPos = (spacer * radiusThisPass) * pm.datatypes.VectorN.unit(newRot) prev = newPos dup.translate.set((newPos+dupStartPos)) if grp: dup.setParent(grp)