Help automating (randomizing) texture mapping position

This is my first post, so pardon any ignorance’s-

I’m using Rhino5, with Maxwell for Rhino Plugin (rendering). I’ve got a lot of experience writing LISP for AutoCAD, but am quite new to Rhino’s scripting options. I’ve done some searching but honestly, given my desired task, I can’t even determine whether I should be looking at Grasshopper, RhinoScript, RhinoPython or even RhinoCommon…

What I want to do is:

  • Select a number of objects
  • Run a command (preferably) that would:
    -Randomize the texture mapping X, Y, and Z position numbers for all selected objects, say between 1 and 999

Seems simple enough, but like I said, I’m having trouble even getting my foot in the door. Any help wound be greatly appreciated!


1 Like

Hi Jon - I’m not sure that I follow, here… default mapping is in surface UV - do you have custom mapping (Planar etc) on these objects and you want to jiggle the mapping widget locations, or do you want to jiggle the UV coordinates… or?


Thanks for the reply- short answer is yes, I have custom mapping (Box, mostly) and yes I want to jiggle the mapping within that.

The use for this lies in having a large wall, for example, broken into many panels, both horizontally and vertically. I have one over-sized material, which, by changing the position of the map for each object, it gives the effect of each panel having a unique material (the seams of the panels don’t line up vertically and horizontally that way).

I’ve been doing this manually for quite some time, but am trying to create a better workflow…

*Edit- If adjusting the surface UV in a random manner is simpler, that would achieve that same effect, so that would also be more than helpful…


Hi Jon - here is a very quick Python - for now it assumes you have turned on the mapping widgets for all of the objects and selected the widgets before starting -

import Rhino
import rhinoscriptsyntax as rs
import random

def randVec():
    x = random.random()
    vec = Rhino.Geometry.Vector3d(random.random(), random.random(), random.random())
    if x > .5: vec.Reverse()
    return vec

def test():
    ids = rs.SelectedObjects()
    for id in ids:
        rs.MoveObject(id, randVec()*random.uniform(0, 100))

Change the numbers in random.uniform() to modify the move range…
Something like that?


Again, thanks for your help-

Your script actually moves all of the selected objects, both physically and the texture map position. Is there a way to only change the position of the texture mapping through Python? This is where I got stuck trying to look into this myself- I couldn’t find the correct operator (rs.MoveObject) for only adjusting the XYZ position under the texture mapping tab…

Hi Jon - if the mapping widgets are on, showing, and you select them, not the objects they are mapping, then just the widgets should move… any luck? We can make it fancier as far as selection and so on goes, UI, but for now I just want to know if it does the right thing to the widgets…

@Jon_Weber - here’s a little friendlier version, if I’ve done it right… you get to select the objects, the widgets can be off. (2.1 KB)



AH! Sorry, I misunderstood your first instructions. Selecting the widgets worked perfectly. Oh that’s so awesome! I understand that this was a quick script for you, but I really appreciate it.


Hi Pascal,

Thank you for the script. Would like to ask if this works on Surface Mapping as well?

Thank you!

Hi Yu-Heng - no, this is for mapping that uses widgets only - it moves the mapping widgets - crude but effective… UV is a different bag altogether, I’d need to know more about what you want to accomplish.


Hi Pascal,

So basically I have these pipes that are mapped with a bamboo texture.
In order to create a more natural outlook, each pipe would have a random UVW repeat settings.

As shown in the picture, the portion circled in blue is natural vs the repetitive look which is in red.

Thanks and hope to hear your reply!

Thank you, again, so much for this script. It works wonders. A bit confusing that you select the objects after you put the max Distance, so when selected before launching script you have no distance option (defaults to 1), but nevertheless, it works 100% ok.

if i knew how to code in python i would make it maxDistanceX, maxDistanceY and Scale, so full control over the outcome.

I guess replacing randVec() with x, y vectors and same maxdist input will do the job, have no idea how to do it, just commenting your excellent work. Pitty Grasshopper have no option to replicate this on nurbs and not meshes.

just make your bamboo texture random, brick like and tileable in photoshop and re-apply it. simple.

@flatform - I don’t know if this is any better - the code is a bit ratty still but it might be workable - you get to preview the jiggle and change the number if you do not like it. (4.9 KB)


yes, it is more interactive now, thank you. you can even re-type same number and just have a different seed of jiggling, and if you type 0 it returns to unaltered (what you do with reverse vector i guess, and comment in the code?), so you can compare results, great! code almost doubled. it is fine as it was and as it is so all ok :wink:

@pascal I like the idea of the script and I would like to use the randomizer for my current project. But I get an error. Do you have an idea?


I had this same issue, you need to apply a type of mapping first, not just the material. click you objects > properties > texture mapping then apply the relevant mapping type, scale as needed then run the script

1 Like

Hi Pascal,

It’s very helpful to see your scripts here. I’m stucked in automating the UVEditor commands since I need to click the “Apply” button by hand after all the changes. I’m trying to modify objects’ texture scale automatically. Do you have any idea about how to deal with this problem, either in python or grasshopper?



Is there anyway you could modify this so that it could randomly rotated textures somewhere within a domain of 0-360 degrees?



1 Like

Hi Arkadius - what would be the plane of rotation? As is the script does not know anything about the mapping type - it just grabs the mapping widget and moves it. To rotate, I would need to know and pay attention to the mapping type in order to rotate in a sensible way relative to the mapping - that will take some investigation. If rotating in the current CPlane is OK, then that is much more straightforward, but it is hard to see how that would be useful very often.


It could be from the same cplane, that would work for basic usage, that way we would just need to set the cplane to the objects / surface



  • this would be useful in the case I am working on now!
1 Like