4

Relatively new to python so apologies for any terrible coding.

I'm using blender to create random stimuli sets using the sapling add on to create something likeenter image description here

I also want to define a random camera position and angle in a hemisphere above the plane which I do by producing two random numbers (u and v in my example below).

However, calling the py.ops.curve.tree_add function (which generates the tree) sets some kind of seed which means that the random numbers I produce are always the same.

E.g. in the example code it creates a range of different trees depending on the randint() generated for basesize/ basesplit.

However, for each unique tree these generate, the random numbers u and v are always the same. This means for every random tree I generate, the camera angle is specific for that tree (and not completely random)

I assume this occurs via some seed, so I was wondering if there is a way to tell python to generate a random number and ignore any seeds?

Best,

Example code: (import bpy is the python api module for blender)

### libraries
import bpy
from random import random, randint

u = random()
v = random()
obj = bpy.ops.curve.tree_add(bevel = True,
                                prune = True,
                                showLeaves = True,
                                baseSize = randint(1,10)/10,
                                baseSplits = randint(0,4))
print(u)
print(v)

in case it helps, my function to generate a sphere to place the camera and then point it towards the object is (I haven't included the libraries/ rest of the script etc. here for brevity- it creates a point around a defined centre which is a radius r away and works apart from the above issue):

#generate the position of the new camera
def randomSpherePoint(sphere_centre, r, u, v):
    theta = 2 * pi * u
    phi = acos(2 * v - 1)
    x = centre[0] + (r * sin(phi) * cos(theta))
    y = centre[1] + (r * sin(phi) * sin(theta))
    z = fabs(centre[2] + (r * cos(phi)))
    return(x,y,z)

hemisphere_point = randomSpherePoint(centre, radius, u, v)
print(hemisphere_point)
#add a camera at this randomly generated hemispheric location
bpy.ops.object.camera_add(location = hemisphere_point)
the_camera = bpy.data.objects["Camera"]
#rotate the camera to the centre of the plane
camera_direction = centre - camera_location
camera_rotation = camera_direction.to_track_quat('-Z', 'Y')
the_camera.rotation_euler = camera_rotation.to_euler()
Robert Hickman
  • 869
  • 1
  • 6
  • 22
  • There is an issue with the code: you import certain functions from `random`, but then access `random.uniform`. Either use `import random` taking the namespace `random`, or import the `uniform` function from it and don't prefix with `random`. – trincot Apr 04 '17 at 08:30
  • ahh sorry! its from some tinkering with the code this morning. I've generally just been using random(). Edited the code in the example to reflect this – Robert Hickman Apr 04 '17 at 08:33
  • Do you have the completed Tree Sapling that is callable via Python instead of using the menu and preset? Thanks! – user2153553 Aug 22 '18 at 12:33

2 Answers2

5

You can make a instance of random using the class random.Random. An example would be:

randomgen = random.Random()
randomgen.uniform(0,1)

This reason is:

The functions supplied by this module are actually bound methods of a hidden instance of the random.Random class. You can instantiate your own instances of Random to get generators that don’t share state

(from https://docs.python.org/3/library/random.html)

Lasse VB
  • 129
  • 2
  • thanks! this seems to be working :) if I want to create multiple random numbers can I reuse the same randomgen or will they be correlated? e.g. If I want to create a random integer for one parameter, a random gauss for another etc. etc. would they all be similarly high/low numbers? – Robert Hickman Apr 04 '17 at 10:29
  • 1
    You can use the same randomgen, it will give you a new random number. randomgen will do the same as random, except it uses a different seed. – Lasse VB Apr 05 '17 at 11:29
0

Python's random module provides the seed() method for you to set the seed.

import random
random.seed(12)
random.randint(0,100)

Another option to get variations in your trees is to provide a different seed for the sapling addon to work with. You can find it in the operator adjustment panel above the tree scale, the python API also accepts a seed paramater.

bpy.ops.curve.tree_add(seed=myseed)
sambler
  • 6,917
  • 1
  • 16
  • 23