SetTextureMapping() synchronization issue

Hello everyone!

I’m trying to create a Rhino command to randomly shift multiple objects’ texture mapping, but bumped into a bug, which I suspect to be an issue related to synchronization in the backend API.

Here’s the code I’m using:
It allows the user to select multiple objects, loop through all the objects and their texture channels, and apply a random translation on each of the texture mapping’s UvwTransform.

// Get Input
GetObject go = new GetObject();
go.SetCommandPrompt("Select objects");
go.EnablePreSelect(true, true);
go.GetMultiple(1, 0);
if (go.CommandResult() != Result.Success)
    return go.CommandResult();

objects = go.Objects().ToList();

double strength = 1.0f;

// loop through all the object
for (int i = 0; i < objects.Count; i++)
{
    var obj = objects[i].Object();
    var textureChannels = obj.GetTextureChannels();
    foreach(int channel in textureChannels)
    {
        var objTextureMapping = obj.GetTextureMapping(channel);
        objTextureMapping.LockId();

        var transform = new Rhino.Geometry.Transform(1);

        var random = new Random();

        transform.M03 = random.NextDouble() * strength;
        transform.M13 = random.NextDouble() * strength;
        transform.M23 = random.NextDouble() * strength;

        objTextureMapping.UvwTransform = objTextureMapping.UvwTransform * transform;
    }

    // With Sleep() it works!
    // System.Threading.Thread.Sleep(100);

}

The code would produce an incorrect result that all the objects get the same translation. After debugging for a while, I found a workaround for this issue by adding the line System.Threading.Thread.Sleep(100) in the loop. I would like to know if there’s a better way to do this.

I noticed that there’s LockId(), LockIndex(), and LockName() for TextureMapping class. Are they some kind of mutex lock? If it is, how do I use them? The document is not so clear for them :melting_face:

Thanks in advance :smiley:

1 Like