SetItem

 
 
 
Posted by:hotknife
Data created:14 May 2014

How do I set a single value or multiple values in an array of Vertices (Using Nodes) ?

For example I have an object with 100000 verts - I want to set the value of vert indices [1],[5],[10000] to [30,30,30] or a variable vector number.

I could create an array with the the vert indices that I want changing i.e [1,5,10000] and loop through the entire mesh verts checking for verts 1,5,10000....but I should be able to individually set their valuse with SetItem[1] = [30,30,30] etc. which I can do but....

What is confusing me is the VoidOutput of the SetItem- and the fact that the mesh only updates when I force it to by turning on and off a modifer below the LabModfier.

So in short how do i quickly set a single item in an array.

Sorry if this is a rudimentry question im having a brain failure.

 

 

 

 

Just to illustrate the point a video. Am I using SetItem incorrectly ?

https://www.youtube.com/watch?v=oBel5m0xnDA&feature=youtu.be


Attached Files:

>SetItem.mp4 (528305 bytes),

Hi Andrew,

I am trying to this about this scenario and the best solution I can come up with at the moment is creating a sub-graph which would use copy input directly to output and use an if node inside to copy a different value for specific indices like you listed, then using this graph as a dynamic array to iterate over all incoming vertices.

But this solution doesn't seem ideal nor efficient. The problem with setting vertices is that it mutates the vertex array, and instead the whole vertex array must be copied while changing a couple of vertices along the way. For example, consider a situation where the vertex array is used by two different nodes as input. If you mutate it by changing a few vertices for one input then the other input will also get the same result.

Perhaps you can create a script node for now which would take the array, do the necessary modifications to it, then return it as a result?

We will consult about the best solution to this. Seems like a dedicated node would be best to have.

Marsel Khadiyev (Software Developer, EPHERE Inc.)

Hi Marsel - thanks for the reply.

I've tried a script and again the update doesn't work interactively while altering a single value without turning on/off a modifier below the Lab. It does work if you alter all values ??

 

C# isn't my strongest (which is why I bought Lab :)) so I may be doing something wrong. See below.

// Ephere.Geometry.dll
using System;
using Ephere.Modeling.Attributes;
using  Ephere.Geometry;

[assembly: Pluggable]

namespace MyScript
{
    public static class MyScript
    {
        public static Vector3[] Function( Vector3[] myVec , Vector3 singleVec)
            
        {
            myVec[0]=singleVec;
            return myVec;
        }
    }
}

However the below does work - not sure why the above doesn't work ? Thanks for the feedback though I find the forum really responsive.

Edit : I may have asked this before - but what is the SetItem for if not to alter a value ? And why VoidOuput ?

     public static Vector3 Function( Vector3 myVec , Vector3 singleVec)
            
        {
            myVec+=singleVec;
            return myVec;
        }

Sorry for the late reply. The SetItem method is automatically exposed from a list. It doesn't have an output so it isn't very useful at this point. One of the goals is to potentially use void methods as events in the GUI (having a button to invoke them). We are in the middle of a discussion of how to handle mutating classes and this is a good example of why :) Me or Ivan will get back to you with a workaround.

Marsel Khadiyev (Software Developer, EPHERE Inc.)

Indeed, mutating methods (that change the incoming object) do not behave well. I was able to achieve the result you want with the following script:

 

// Ephere.Geometry
using System;
using System.Linq;
using System.Collections.Generic;
using Ephere.Geometry;
using Ephere.Modeling.Attributes;

[assembly: Pluggable]

namespace MyScript
{
    public static class MyScript
    {
        public static IList<Vector3> Function( IList<Vector3> points, int index, Vector3 newValue )
        {
            var result = points.ToArray();
            result[index] = newValue;
            return result;
        }
    }
}

The key is to make a copy of the incoming object and only then modify it, and then return the new object. I'll attach the scene.  


Attached Files:

>SetArrayItems01.max (233472 bytes),

Ivan Kolev (Software Developer, EPHERE Inc.)

E-mail: ivan.kolev at ephere dot com

Discord: ikolev