Blender 3D: Blending Into Python/OrphanScripts
Tools
General
Sister projects
In other projects
Hi, post unmaintained scripts here.
Be wary of malicious code, especially the OS module, check in the history every so often for edits to see nobody's doing bad stuff.
Currently there are two scripts here in need of nice mothers or fathers.
This script is a simple L system that allows you to use pre-defined meshes. It DOES work in 2.43and could possibly be a building generator (with some work).
## =====================# README# =====================## this is a simple L-system that uses pre-made mesh elemental blocks## source blocks are in a different layer - press tilde (`) in 3d view# to see them all## a new mesh is created every time; edge creases are carried over from# source meshes to allow subsurf work## this system uses the turtle concept with pushable/poppable state,# just like most other L-systems# however, the "drawing" operation here is to place a pre-made mesh# instead the usual plant-oriented stuff# as a result, this should be pretty well suitable for Discombobulator# style work such as generating lots of small detail## turtle instructions and any other tokens are XML-like tags# instead of single characters; they can also contain an arbitrary# argument string# rewriting rules are actually defined as functions to allow# procedural flexibility## things left to do really depend on what the actual use is# some ideas include using lists instead of strings for arbitrary# argument data (may help with speed); supplying environment# info to the rule function (for queries, like in some advanced# L-systems out there) as well as the current model info# for true Discombobulator-style detail generation there has# to be a mode to populate the axiom (initial state) with# existing model faces## of course, more code cleanup is in order#importsysimportreimportBlenderfromBlenderimportMathutilsfromBlenderimportNMeshsubstrate='<LimbArray>'#'<twist:90><turn:90><LimbArray>'# custom characters and their translationscustom=[ \('<Stem>','<add:Stem><offset:0.5,0,0>'), \('<Joint2>','<add:Joint2Start><offset:0.2,0,0><pitch:-30_0><add:Joint2Middle><turn:-20_20><add:Joint2End><offset:0.2,0,0>') \]print"growing..."# force recompile of rulesetif'ruleset'insys.modules:delsys.modules['ruleset']importrulesetrules=[(re.compile('<'+name+'(?::([^>]+))?>'),getattr(ruleset,name))fornameindir(ruleset)]# do the matchingforstageinrange(20):curPos=0whileTrue:newPos,newEnd=None,NonenewStr=Noneforregex,funcinrules:match=regex.search(substrate,curPos)ifmatch!=None:ifnewPos==NoneornewPos>match.start():newPos=match.start()newEnd=match.end()newStr=func(match.group(1))ifnewPos==None:breaksubstrate=substrate[:newPos]+newStr+substrate[newEnd:]curPos+=len(newStr)# translate custom charsforchar,replincustom:substrate=re.sub(char,repl,substrate)print"interpreting..."# interpret the resultclassStackFrame:# prev is the parent framedef__init__(self,prev=None):self.prev=previfprev!=None:self.matrix=prev.matrixelse:self.matrix=Mathutils.Matrix()self.matrix.identity()self.matrix.resize4x4()# modificationsdefrotate(self,axis,angle):rot=Mathutils.RotationMatrix(angle,4,axis)self.matrix=rot*self.matrixdefoffset(self,xyz):tra=Mathutils.TranslationMatrix(Mathutils.Vector(xyz))self.matrix=tra*self.matrixdefscale(self,ratio):sca=Mathutils.Matrix( \[ratio,0,0,0], \[0,ratio,0,0], \[0,0,ratio,0], \[0,0,0,1])self.matrix=sca*self.matrix# raises exception if no parentdefgetPrev(self):ifself.prev==None:raiseException,"no parent frames"returnself.prev# appends current mesh to given one# does NOT change positiondefaddMesh(self,meshObj,dest):mesh=meshObj.getData()vertBase=len(dest.verts)forvinmesh.verts:vec=Mathutils.Vector(v.co[0],v.co[1],v.co[2],1)vec=vec*self.matrixcv=NMesh.Vert(vec.x,vec.y,vec.z)dest.verts.append(cv)forfinmesh.faces:cf=NMesh.Face([dest.verts[v.index+vertBase]forvinf.v])dest.addFace(cf)ifmesh.edges!=None:foreinmesh.edges:v1,v2=e.v1,e.v2nv1,nv2=dest.verts[v1.index+vertBase],dest.verts[v2.index+vertBase]ne=dest.addEdge(nv1,nv2)ne.crease=e.crease#dest.update()# create result meshmesh=NMesh.New()#mesh.addEdgesData() # for things like creases# do the dewframe=StackFrame()# parses and interprets a string of type# X:Y_Z (randomly choose either X or something between Y and Z)defnumber(str):importrandomchoices=str.split(':')choice=random.choice(choices)limits=choice.split('_',2)iflen(limits)==2:returnrandom.uniform(float(limits[0]),float(limits[1]))returnfloat(limits[0])instrMatch=re.compile(r"""<(?P<instr1>\w+)(?::(?P<arg>[^>]+))?>|(?P<instr2>[\[\]])""",re.VERBOSE)curPos=0whileTrue:match=instrMatch.search(substrate,curPos)ifmatch==None:breakcurPos=match.end()# collect instructioninstr=match.group('instr1')ifinstr==None:instr=match.group('instr2')arg=match.group('arg')# do the dewifinstr=="[":frame=StackFrame(frame)elifinstr=="]":frame=frame.getPrev()elifinstr=="offset":frame.offset([number(a)forainarg.split(',',3)])elifinstr=="turn":frame.rotate("z",number(arg))elifinstr=="pitch":frame.rotate("y",number(arg))elifinstr=="twist":frame.rotate("x",number(arg))elifinstr=="scale":frame.scale(number(arg))elifinstr=="add":frame.addMesh(Blender.Object.Get(arg),mesh)NMesh.PutRaw(mesh,"Result",1,1)
This script apparently WONT work in blender 2.43, updates welcome.
# Jamesk's Walk-o-matic version 0.49.9 (MODIFIED)# for Blender 2.25 and a fully installed Python 2.0 [required]# CHANGES FOR BLENDER 2.36 GENERALLY MARKED '#MDR:' ...# Badly coded changes for Blender 2.43 by TwinStripe :) ! Appears to perform more passes but produces the same results!?!# SET/CHECK THE PARAMETERS BELOW BEFORE EXECUTING THE SCRIPT.# Make sure to select your proxy object, then run the script with ALT+P.# Please consult the documentation for a full description of the parameters.# ...Aaaaand check the console window for any messages.# GENERAL SETTINGS:FF=FIRST_FRAME=1# begin evaluating at this frameLF=LAST_FRAME=850# stop evaluating after this frameHS=HEEL_SEPARATION=3.0# desired distance between heel targets (in Blender Units)MT=MOVE_TIME=8.0# number of frames/cycle a foot is movingMSD=MOVE_STOP_DELAY=0# any value above zero will prolong the time a foot stays in the air.HEEL_TO_FLAT_DISTANCE=1# desired distance between a heel target and its associated foot look-at-targetFLAT_TO_TLAT_DISTANCE=0.5# desired distance between a foot look-at-target and its associated toe look-at-targetAL=ALWAYS_LIFT=0# set to zero to prevent feet moving up/down when proxy has speed 0CTD=C_TARG_DISTANCE=2.0# how far above proxy to place center targetLA=LIFT_AXIS='local'# lift feet along global Z or local proxy Z?CTDLA=CTD_LIFT_AXIS='global'# raise center target along global Z or local proxy Z?# NAMES FOR THE EMPTIES:HEEL_LEFT,HEEL_RIGHT='heel.ikt.left','heel.ikt.right'FLAT_LEFT,FLAT_RIGHT='foot.lat.left','foot.lat.right'TLAT_LEFT,TLAT_RIGHT='toe.lat.left','toe.lat.right'TARGET_CENTRE='target.centre'# LIFT ENVELOPE SETTINGS:LP=LIFT_PEAK=0.5# how far to lift above proxy initiallyFLATLP=FLAT_LIFT_PEAK=0.2# how far to lift foot look-at-target above proxy initiallyTLATLP=TLAT_LIFT_PEAK=0.2# how far to lift toe look-at-target above proxy initiallyLPT=LIFT_PEAK_TIME=0.2# time to reach lift-peak. (relative to movetime)MP=MID_PEAK=0.4# how far from proxy after lift-peakFLATMP=FLAT_MID_PEAK=0.4# how far to lift foot look-at-targetTLATMP=TLAT_MID_PEAK=0.4# how far to lift toe look-at-targetMPT=MID_PEAK_TIME=0.5# time to reach mid-peak (relative to movetime)FP=FINAL_PEAK=0.5# how far from proxy before setting down againFLATFP=FLAT_FINAL_PEAK=0.7# how far to lift foot look-at-targetTLATFP=TLAT_FINAL_PEAK=0.9# how far to lift toe look-at-targetFPT=FINAL_PEAK_TIME=0.8# time to reach final_peak (relative to - you guessed it - movetime)## Concept and coding by James Kaufeldt a.k.a. Jamesk# Made in Sweden, november 2002# Contact: james.k@home.se## Special thanx to# - [d0pamine] and [theeth] for some hints regarding vector math.# - Martin [Strubi] Strubel from whom I borrowed the "normalize" function,# len3(x), dist3(x,y) and sub3(x,y) funcs found in his "vect.py" utility module.# - [eeshlo] for pointing out how simple it was to give names to the empties.## ---------------------------------------------------------------------------------------# EDITABLE SECTION ENDS HERE!## NO USER DEFINABLE VALUES BEYOND THIS POINT!# ---------------------------------------------------------------------------------------####LT=MTCT=MT+LTfromBlenderimportObject,Scene,Window,IpofromBlender.SceneimportRenderfromBlender.WindowimportTypesimportsys,mathproxy=Object.GetSelected()status='UNDEFINED ERROR'Layer=0printprint'----------------------------------'print'W A L K - O - M A T I C V 0.49.9'print'----------------------------------'print# make sure that there's an actual walker proxy to use:ifproxy==[]:print'No proxy indicated, terminating...'status='NO PROXY OBJECT SELECTED'ifproxy!=[]:proxy=proxy[0]print'Proxy in use:\t',proxyLayer=proxy.Layerprint' in Layer',Layerstatus='OK'sys.stdout.flush()scene=Scene.GetCurrent()# make sure there's a scene to use (should always be one, but wth...)ifscene==[]:print'No scene available, terminating...'status='NO CURRENT SCENE AVAILABLE'ifscene!=[]:print'Target scene:\t',scenesys.stdout.flush()# some generally useful functions below:defnormalize(v):r=math.sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2])return(v[0]/r,v[1]/r,v[2]/r)deflen3(x):returnmath.sqrt(x[0]*x[0]+x[1]*x[1]+x[2]*x[2])defsub3(x,y):return((x[0]-y[0]),(x[1]-y[1]),(x[2]-y[2]))defdist3(x,y):returnlen3(sub3(x,y))defmoveAlong(origpos,distance,vector):newpos=[0,0,0]newpos[0]=origpos[0]+distance*vector[0]newpos[1]=origpos[1]+distance*vector[1]newpos[2]=origpos[2]+distance*vector[2]returnnewposdefinvertVector(v):return(-v[0],-v[1],-v[2])#MDR:defselectFrame(f):f=int(f)ifscene.getRenderingContext().currentFrame()!=f:scene.getRenderingContext().currentFrame(f)Window.Redraw(Window.Types.VIEW3D)# MDR:# Conversion routine: try to get an object, return None if it's not there.# Just like Blender used to do. The easiest way to accomplish this is to# allow the exception to occur, and catch it.defTryGetObject(v):try:returnObject.Get(v)except:returnNonedefgetOffset(origin,frame,xdir,xdist,forward):# origin: the point to offset frame: framenumber# xdir: 1 = positive offset along X, -1 = negative offset# xdist: how much to offsetselectFrame(frame)loc=origin.getMatrix()[3]loc=moveAlong(loc,forward,normalize(origin.getMatrix()[1]))direction=normalize(origin.getMatrix()[0])ifxdir==-1:direction=invertVector(direction)returnmoveAlong(loc,xdist,direction)defgetLiftAxisOffset(origin,frame,liftaxis,liftdist):# origin: the point to offset frame: framenumber# liftaxis: 'global' or 'local' lifting liftdist: the amount of liftselectFrame(frame)loc=origin.getMatrix()[3]direction=normalize(origin.getMatrix()[2])ifliftaxis=='global':direction=[0,0,1.0]returnmoveAlong(loc,liftdist,direction)defgetElevation(origin,frame,axis,zdist,xdir,xdist,forward):# origin: the point to offset frame: framenumber# axis: 'local' or 'global' zdist: how much to elevate# xdir: the X offset xdist: the distance to offset along Xloc=getOffset(origin,frame,xdir,xdist,forward)ifaxis=='local':direction=normalize(origin.getMatrix()[2])returnmoveAlong(loc,zdist,direction)ifaxis=='global':direction=[0,0,1.0]returnmoveAlong(loc,zdist,direction)defwriteCurvePoint(ipo,frame,point):# ipo: the IPOblock to use frame: at what frame# point: the 3D coordinate to writexc=ipo.getCurve('LocX')yc=ipo.getCurve('LocY')zc=ipo.getCurve('LocZ')foridx,cinenumerate([xc,yc,zc]):c.addBezier((frame,point[idx]))c.update()defmakeIPO(name,ipol,expol):# name: desired name for this IPOblock ipol: type of interpolation# expol: type of extrapolationipo=Ipo.New('Object',name)xc=ipo.addCurve('LocX')yc=ipo.addCurve('LocY')zc=ipo.addCurve('LocZ')forcurvein[xc,yc,zc]:curve.setInterpolation(ipol)curve.setExtrapolation(expol)returnipodefmove(ipo,origin,destination,startframe,framespan,proxob,xdir,xdist,forward):# ipo - what ipo to write points to origin - the location (3Dpoint) to start at# destination - the location to end up at startframe - frame to set the first curvepoint at# framespan - total number of frames for the move proxob - the proxy/reference object# xdir - pos or neg offset along proxy X-axis xdist - how much to offset along proxy X-axiswriteCurvePoint(ipo,startframe,origin)ifAL==1ororigin!=destination:# Write curvepoints for LiftPeak and LiftPeakTime:# Pretty hackish formulae for proxyTime here... But they do work, so wtf...lpProxyTime=startframe+(LPT*framespan*2)-framespan*0.25lpRealTime=startframe+(framespan+MSD)*LPTlpLocation=getElevation(proxob,lpProxyTime,LA,LP,xdir,xdist,forward)writeCurvePoint(ipo,lpRealTime,lpLocation)# Write curvepoints for MidPeak and MidPeakTime:mpProxyTime=startframe+(MPT*framespan*2)-framespan*0.25mpRealTime=startframe+(framespan+MSD)*MPTmpLocation=getElevation(proxob,mpProxyTime,LA,MP,xdir,xdist,forward)writeCurvePoint(ipo,mpRealTime,mpLocation)# Write curvepoints for FinalPeak and FinalPeakTime:fpProxyTime=startframe+(FPT*framespan*2)-framespan*0.25fpRealTime=startframe+(framespan+MSD)*FPTfpLocation=getElevation(proxob,fpProxyTime,LA,FP,xdir,xdist,forward)writeCurvePoint(ipo,fpRealTime,fpLocation)writeCurvePoint(ipo,startframe+framespan+MSD,destination)return(startframe+framespan,destination)defhold(ipo,location,startframe,framespan):# ipo - what ipo to write points to # location - the position (3Dpoint) to hold at# startframe - the first frame in the hold sequence # framespan - total number of frames to holdwriteCurvePoint(ipo,startframe+MSD,location)writeCurvePoint(ipo,startframe+framespan,location)return(startframe+framespan,location)defrecalculator(assignedTargets,targ1,targ2,basetarg):# rewrites some globals based on the current arrangement of the empties:loc1=targ1.getLocation()loc2=targ2.getLocation()loc3=basetarg.getLocation()# HEEL_SEPARATION:ifassignedTargets=='heels':print'Default heel empties found. Recalculating:'globalHSHS=dist3(loc1,loc2)print'HEEL_SEPARATION set to',HSifassignedTargets=='flats':print'Default foot look-at targets found. Reusing.'globalHEEL_TO_FLAT_DISTANCEHEEL_TO_FLAT_DISTANCE=dist3(loc2,loc3)print'HEEL_TO_FLAT_DISTANCE set to',HEEL_TO_FLAT_DISTANCEifassignedTargets=='tlats':print'Default toe look-at targets found. Reusing.'globalFLAT_TO_TLAT_DISTANCEFLAT_TO_TLAT_DISTANCE=dist3(loc2,loc3)print'FLAT_TO_TLAT_DISTANCE set to',FLAT_TO_TLAT_DISTANCEdefdoIt(forwardOffset,addCenter,whatsUp,firstName,secondName):printprint'Currently processing:',whatsUp# Start building the IPO for the right foot:ffootipo=makeIPO('rfoot','Linear','Constant')cpf=currentProxyFrame=FF# make first step (only half as far as the others):ffootloc=getOffset(proxy,cpf,1,HS/2,forwardOffset)ffootframe=cpftargetloc=getOffset(proxy,cpf+MT,1,HS/2,forwardOffset)ffootframe,ffootloc=move(ffootipo,ffootloc,targetloc,ffootframe,MT/2,proxy,1,HS/2,forwardOffset)ffootframe,ffootloc=hold(ffootipo,ffootloc,ffootframe,LT)# now make the rest of the steps (full length):whileTrue:cpf+=CTtargetloc=getOffset(proxy,cpf+MT,1,HS/2,forwardOffset)ffootframe,ffootloc=move(ffootipo,ffootloc,targetloc,ffootframe,MT,proxy,1,HS/2,forwardOffset)ffootframe,ffootloc=hold(ffootipo,ffootloc,ffootframe,LT)ifcpf>LF:break# Then we'll build the IPO for the left foot:sfootipo=makeIPO('lfoot','Linear','Constant')cpf=currentProxyFrame=FF# this one starts in hold-mode (waits for right foot to finish)sfootloc=getOffset(proxy,cpf,-1,HS/2,forwardOffset)sfootframe=cpfsfootframe,sfootloc=hold(sfootipo,sfootloc,cpf,MT/2)whileTrue:cpf+=CTtargetloc=getOffset(proxy,cpf,-1,HS/2,forwardOffset)sfootframe,sfootloc=move(sfootipo,sfootloc,targetloc,sfootframe,MT,proxy,-1,HS/2,forwardOffset)sfootframe,sfootloc=hold(sfootipo,sfootloc,sfootframe,LT)ifcpf>LF:breakifaddCenter:# And to finish it off, let's put something in the middle of this:# This will simply add a third target floating above the proxy.# It will respect the specified lift axis, hence useful as parent for an armaturectargetipo=makeIPO('center','Linear','Constant')forcframeinrange(FF,LF):targetloc=getLiftAxisOffset(proxy,cframe,CTDLA,CTD)writeCurvePoint(ctargetipo,cframe,targetloc)# Finished. Add or reuse empties and link them to their respective IPOblocks.leftikt=TryGetObject(firstName)leftnew=Falseifleftikt==None:leftikt=Object.New('Empty')leftnew=Truerightikt=TryGetObject(secondName)rightnew=Falseifrightikt==None:rightikt=Object.New('Empty')rightnew=Trueleftikt.name=firstNamerightikt.name=secondNameprint'Targets',leftikt,rightiktifaddCenter:centertarget=TryGetObject(TARGET_CENTRE)centernew=Falseifcentertarget==None:centertarget=Object.New('Empty')centernew=Truecentertarget.name=TARGET_CENTREprint'Centertarget',centertargetcentertarget.Layer=Layerifcenternew:scene.link(centertarget)#MDR: 'SetIPO' was 'link'...centertarget.setIpo(ctargetipo)leftikt.Layer=Layerrightikt.Layer=Layerifleftnew:scene.link(leftikt)ifrightnew:scene.link(rightikt)#MDR: Ditto... 'setIpo' was 'link'...leftikt.setIpo(sfootipo)rightikt.setIpo(ffootipo)printwhatsUp,'IPO:s',sfootipo,ffootipoprint'---------------------------------------------------------'sys.stdout.flush()########################################## if everything's OK, let's get to work ##########################################ifstatus=='OK':currentUserFrame=scene.getRenderingContext().currentFrame()# grab any walkomat empties left in the scene:oldleftheel=TryGetObject(HEEL_LEFT)oldrightheel=TryGetObject(HEEL_RIGHT)oldleftflat=TryGetObject(FLAT_LEFT)oldrightflat=TryGetObject(FLAT_RIGHT)oldlefttlat=TryGetObject(TLAT_LEFT)oldrighttlat=TryGetObject(TLAT_RIGHT)emptyipo=makeIPO('emptydummy','Linear','Constant')# recalculate if there were any such empties:ifoldleftheel!=Noneandoldrightheel!=None:# assign an empty IPO first to clear any anim:# why isn't there some 'unlink' function somewhere???## MDR: These 'setIpo' calls were 'link' ....#oldleftheel.setIpo(emptyipo)oldrightheel.setIpo(emptyipo)recalculator('heels',oldleftheel,oldrightheel,oldrightheel)ifoldleftflat!=Noneandoldrightflat!=None:oldleftflat.setIpo(emptyipo)oldrightflat.setIpo(emptyipo)recalculator('flats',oldleftflat,oldrightflat,oldrightheel)ifoldlefttlat!=Noneandoldrighttlat!=None:oldlefttlat.setIpo(emptyipo)oldrighttlat.setIpo(emptyipo)recalculator('tlats',oldlefttlat,oldrighttlat,oldrightflat)# first pass, heel targets:doIt(0,1,'Heel targets',HEEL_LEFT,HEEL_RIGHT)#second pass, foot look-at targets:LP=FLATLPMP=FLATMPFP=FLATFPdoIt(HEEL_TO_FLAT_DISTANCE,0,'Foot look-at targets',FLAT_LEFT,FLAT_RIGHT)#third pass, toe look-at targets:LP=TLATLPMP=TLATMPFP=TLATFPdoIt(HEEL_TO_FLAT_DISTANCE+FLAT_TO_TLAT_DISTANCE,0,'Toe look-at targets',TLAT_LEFT,TLAT_RIGHT)# At last, as a friendly gesture, restore the frame to whatever the user# was looking at before running the script, and refresh the screens:scene.getRenderingContext().currentFrame(currentUserFrame)Window.RedrawAll()print'Processing completed.'print'Thank you for using Walk-O-Matic :D'sys.stdout.flush()#################################################### if things are not right, print some dying words:####################################################ifstatus!='OK':print''print'Walk-o-matic is sadly forced to report that'print'it could not go to work properly.'print'Cause of termination: ',statusprint'Please consult the documentation regarding proper use.'sys.stdout.flush()