# How best to create random surface variations (BI) in script-generated objects?

This lineup of marble-ish cubes with copper-ish letters affixed is the product of my very first Python script. I have never written or even read Python prior to a couple of weeks ago, so... many thanks to all those whose code-snippets were shamelessly copied to get this working! My next challenge is to make the marble-ish cube surface treatment a little more random, less obviously cloned. I am applying pre-fabricated Material and Texture (Blender Internal) as follows

    #assign materials to cube and letter mesh

marble_mat = bpy.data.materials.get("Marble")
copper_mat = bpy.data.materials.get("Copper")

if letter.data.materials:
#assign to 1st material slot
letter.data.materials[0] = copper_mat
else:
# no slots
letter.data.materials.append(copper_mat)

if cube.data.materials:
cube.data.materials[0] = marble_mat
else:
cube.data.materials.append(marble_mat)


and now I am wondering what would be the smartest way to introduce small variations in the Material/Texture of the cubes. I'd like slight colour and pattern variations, but have no idea how to go about it; do I have to create N Materials and/or Textures for N cubes? Or could I decorate each cube as I create it, by subtly and randomly altering the standard Material and Texture and then baking it?

• Cycles or Blender Internal? – batFINGER Jan 6 '17 at 6:17
• Apologies, I have just edited to indicate I am using BI. Still can't get cosy with Cycles, it seems so slow; maybe I need more expensive hardware :-) – Tazling Jan 7 '17 at 1:55
• this vimeo.com/40389198 might be what I am looking for... will report back when I have time to check it out. – Tazling Jan 7 '17 at 19:46

DRIVERS

Here is a quick manual proof-of-concept using Drivers, as in the tutorial ref'd below and in Comments on the original Question, which I heartily recommend. My text explanation here will not be nearly so clear and user-friendly as the video, so I suggest anyone who is interested should watch it!

These cubes are copies of one cube (manually created, not scripted) which has random-number drivers (manually created and tweaked via the UI) attached to various properties -- Scale (xyz), Diffuse Colour, Diffuse Intensity, and the geometry of the Marble generated texture. The result is fairly pleasing, though I would like to know whether/how I can overcome the signature diagonal grain of the generated texture. In a game landscape these cubes would probably pass OK as "different" from one another, despite the grain issue.

Method:

1) expose some kind of python random function(s) to driver context, as shown in this vimeo tutorial: https://vimeo.com/40389198
(sample rand function code is provided by the author via a link on this vimeo page, and this is what I used:).

import bpy
import random

def randf(lo, hi):
return random.uniform(lo, hi)

def randi(lo, hi):
return random.randint(lo, hi)

def gauss(mean, stdev):
return random.gauss(mean, stdev)

bpy.app.driver_namespace["randf"] = randf
bpy.app.driver_namespace["randi"] = randi
bpy.app.driver_namespace["gauss"] = gauss


2) With object selected: in a property editing pane, select an object property such as Scale, RGB value in Material, etc. Other-click on it (whichever one you don't use for regular selection of objects, focus placement, etc). When menu comes up, choose "Add Driver" and then select either the whole group or just one property, to be "set manually later". The slider should turn purple to indicate that it's being driven.

3) Open a Graph Editor and reveal its property editing panel (N). Choose the Driver tab. Now you can select your driver (at left) and edit/tweak it in the pane. I for example would choose Scripted Expression for my randomising drivers, and for the expression enter my randf function which takes 2 args, min and max. For some properties (material and texture props, so far) you have to set a driver variable. For others (pos/rot/scale I believe) you can skip it... I don't know why there is a difference. If you've done it all correctly, then when you press Update Dependencies, your object should randomly change its shape, position, rotation, colour, whatever the driver is randomising -- in my case, within the bounds set by the 2 args to the rand function. Anything that causes a Scene Update should trigger this regeneration of the random values, but you can "turn off" the drivers using the "mute buttons" next to their entries in the GE left hand pane, freezing the object's appearance.

4) When you Duplicate this "driven" object, the drivers go with it and the cloned object also has the randomised property. However, aspects of the original object are by default shared with its dupes. So for example, material seems to be shared with dupes; you can spawn a new cube by duplication but it will have the same (random) colour as the original; they will both change to the identical new value when Update Dependencies is invoked. To fix this, I selected all the objects (dupes and original), hit U, and picked Materials/Texture. This apparently prevents sharing. Each cube now has its own independent material/texture settings and finds its own random colour/texture when the update happens. You can dupe the dupes and the inheritance continues; the original object can even be deleted without losing any of your hard work. But whenever you dupe, you have to turn off material sharing if you want randomised material properties.

Conclusion: Drivers are insanely powerful; also -- potentially -- insanely fun. It actually boggles the mind, thinking of all the strange and wonderful ways that properties could be driven by, say, other objects' properties, frame count, external data files, higher math functions... But my immediate practical need was to make random small variations in mass produced objects, and Drivers seem to be the solution of choice. My next challenge is to create drivers under Python control. If I succeed, there will be one more photo in this series :-)

Another interesting write-up on Drivers may be found here

http://blendersushi.blogspot.ca/2013/06/python-driving-arrays-like-boss.html

some of it is a bit beyond me right now, but I hope to understand it better in a day or so.

• A moderator deleted my original Answer because it didn't meet SE standards (yep, it was a bit lazy), so I rewrote and expanded it, editing everything in sight. I was unable then to undelete it so I posted this new Answer instead. If someone wants to delete the old one permanently, that would be grand. Thanks. – Tazling Jan 8 '17 at 5:47