NEW: Crinkle Script

Here’s a new script I just finished. It’s my second Python script. It’s called Crinkle, and it does just that to any mesh you hand it :smiley: It’s adjustable and allows you to crinkle along either the X, Y, or Z axis of an object (or all the axes). With this you can introduce randomized minor or major disturbances/bumps/variations in an otherwise plain symmetrical mesh.

Here’s an image of primitives deformed after several iterations with varying crinkle values:

Interested? [>] Download .zip file

Contents (3 files): README.txt,, crinkle.blend

Read the README.txt file first to get an idea how this works and for some ideas on how to get the most out of this script.

I hope someone finds this useful.


It would be particularly nice if it could work on the normals of the faces too.


Theeth, how about this?

I created a second script that may or may not do it. If it doesn’t do it let me know and I’ll see what I can do. Thanks! :slight_smile:


Theeth, I just updated this variant script again in case you downloaded it in my last post.

I added another loop to cycle through face vertices. Still not sure if this is what you’d like, but the results are interesting :smiley:


It doesn’t seem to make a reference to the face normals anywhere.

Also, when you loop on the vertice of the face, using xrange(3) isn’t really safe IMHO, since you can have tris, not just quads.


Hi Theeth. I’ve been referring to the new Python documentation over at The only place I only see face normals mentioned in the NMFace class. I’m using in the script to reference face normal vectors. Is there another way? I deeply appreciate your time and insight.

BTW, I fixed the xrange: xrange(len(f.v)). I decimated some test meshes and tried it on both meshes with tris and quads and had no problems:

Here’s a test render using the second script. This was a UVsphere:

Several smoothings were applied and it was subsurfed.


Just to show I’m not crazy. Here’s the code from the script your download link point to:

# by RobertT 
# Version: 1.0
# Author E-mail: [email protected]
# Script Release Date: December 11, 2003
# Based on my original Crinkle script at

import Blender
from Blender import NMesh, Material
from Blender.Draw import *
from Blender.BGL import *

from Blender import Window
from whrandom import random

print "Now Running: Crinkle Script (FACE VERSION) V1.0 by RobertT ([email protected])"

def crinkle(whichAxis):
	check = Blender.Object.GetSelected()
	oldCrinkleValue = crinkleIntensity.val
	print "OldCrinkle: " , oldCrinkleValue
	if (len(check)>0):
		for o in Blender.Object.GetSelected():
			objName = o.getName()
			print "Crinkling " , objName , "by amount of" , crinkleIntensity.val
			meshData = NMesh.GetRaw(objName)
			s = random()*3
			if (s>1 and s<3):
				s = -1
			for f in meshData.faces:
				for i in xrange(3):
					if (whichAxis == 1):
						f.v[i][0] += s*(random() * crinkleIntensity.val)
					if (whichAxis == 2):
						f.v[i][1] += s*(random() * crinkleIntensity.val)
					if (whichAxis == 3):
			 		  	f.v[i][2] += s*(random() * crinkleIntensity.val)
					if (whichAxis == 4):
			 		  	f.v[i][0] += s*(random() * crinkleIntensity.val)
			 	 	 	f.v[i][1] += s*(random() * crinkleIntensity.val)
			 	  		f.v[i][2] += s*(random() * crinkleIntensity.val)
			print "crinkleIntensity: " , crinkleIntensity
			crinkleIntensity.val = oldCrinkleValue
		print "No object selected."

def draw():
	global crinkleIntensity, xButton, yButton, zButton, xyzButton
	crinkleIntensity = Create (.05)
	glClearColor(.7, .7, 1, 0.0)
	Text("Crinkle Script")
	Text("by RobertT ([email protected])", "small")
	crinkleIntensity = Slider("Crinkle amount: ", 1, 20, 350, 365, 30, crinkleIntensity.val, .05 , 2.0, False)#, True, "Amount to crinkle vertices of selected mesh(es) by");
	b = Button("Crinkle along X axis",   2, 20, 320,  180, 25)
	b = Button("Crinkle along Y axis",   3, 205, 320,  180, 25)
	b = Button("Crinkle along Z axis",   4, 20, 290,  180, 25)
	b = Button("Crinkle all XYZ axes",   5, 205, 290,  180, 25)
	Text("Tips: Experiment 1st on a COPY of an object: actions cannot be undone!", "small")
	Text("For more tips and important info read the README.TXT file.", "small")
	Button("Exit",          6, 205, 220,  180, 25)

def event(evt, val):
	if (evt == XKEY or evt == QKEY):
		print "Script exited by user."

def bevent(evt):
	if evt == 11:
	if evt == 2:
	if evt == 3:
	if evt == 4:
	if evt == 5:
	if evt == 6:
		print "Script exited by user."

Register (draw, event, bevent)

It still uses xrange(3) and there’s no reference to the normal.



Theeth, that’s the first version of the second script. I had updated my website (the sixth post) but my ISP announced late last night through this morning they were experiencing problems. I just uploaded the script again under a different filename:

I’ve been searching Elysiun and’s forums for info on face normals, but there isn’t much there. From what little I’ve seen so far there might need to be further calculations to determine the true normals. What I really should have asked was if you could have elaborated on “if it could work on the normals of the faces too” – do you mean to directly alter face normals and not the vertices? I’m sort of confused.

I also wanted to ask you two other questions unrelated to this script about Blender/Python: is it possible under the current API to change material types (e.g. Phong to Blinn)? Also, is it possible to select an object directly through Python?

I truly appreciate your help. I realize how busy you are, and I am totally thankful for any guidance you can provide. I’m working on some more scripts, so every little piece of knowledge is greatly appreciated.


Woo an updated version :slight_smile:

Regarding the use of xrange, you could also have done it this way:

for v in f.v:
	if (whichAxis == 1):
		v[0] +=[0] * s * (random() * crinkleIntensity.val)
	if (whichAxis == 2):
		v[1] +=[1] * s * (random() * crinkleIntensity.val)
	if (whichAxis == 3):
		v[2] +=[2] * s * (random() * crinkleIntensity.val)
	if (whichAxis == 4):
		v[0] +=[0] * s * (random() * crinkleIntensity.val)
		v[1] +=[1] * s * (random() * crinkleIntensity.val)
		v[2] +=[2] * s * (random() * crinkleIntensity.val)

and iterate directly on the vertex objects.

Regarding your two questions. I don’t think there’s a way to select an object (but I could be wrong, the API changes fast and I don’t look at all the updates). For the material shaders, I’ve looked at the material object a bit, and it doesn’t seem to have access to that.

Seem like a feature request to the python coders mailing list is in order :wink: