Changing variables of a function in ofApp::update()

Hey!

I am kind of new to programming and I was wondering, how I can solve the following problem:

I would like to animate a mesh without calling the entire function again, that creates the mesh.

I created a class (based on an example in the oF book) where I create an object in the setup() function as well as calling the class function calculation(). Later on I draw the mesh that got created in the calculation() function to the screen in the draw() function.

I was wondering, how I can manage to alter variables (via OSC) in the update() function without calling the entire function “calculation()” again since it makes the application really slow because it iterates through the whole image.

Here is the code of the function that creates the mesh and gets called once in setup().
I would like to alter for example the variables “negative” and “positive” in the update() function.

Any tips or work arounds are highly appreciated!
Thank you!

void BrightnessTreshold::detection(){
    
    mesh.setMode(OF_PRIMITIVE_POINTS);
    ofBackground(0);
    
    mesh.enableColors();

    int w = image.getWidth();
    int h = image.getHeight();
    
    for (int x=0; x<w; ++x) {
        for (int y=0; y<h; ++y) {
            ofColor c = image.getColor(x, y);
            float intensity = c.getLightness();
            if (intensity >= intensityThreshold) {
                saturation = c.getSaturation();
                
                //here I would like to alter the variables "negative" and "positive"
                z = ofMap(saturation, 0, 255, negative, positive);
                ofVec3f pos(x, y, z);
                mesh.addVertex(pos);
                mesh.addColor(c);      
            }
        }
    }
}

i’m not certain that I fully understand you but…

once you have made the mesh you can manipulate the vertices of the mesh individually or on mass, changing their position and color as you like. You do not need to re-create the mesh from scratch.

int index= 0;
for (int x=0; x<w; ++x) {
        for (int y=0; y<h; ++y) {
            ofColor c = image.getColor(x, y);
            float intensity = c.getLightness();
            if (intensity >= intensityThreshold) {
                saturation = c.getSaturation();
                
                //here I would like to alter the variables "negative" and "positive"
                z = ofMap(saturation, 0, 255, negative, positive);
                ofVec3f pos(x, y, z);
                mesh.setVertex(index, pos);
                // mesh.setColor(index, c); // set color also if you need to
            }
         index++;
        }
    }

this may be the kind of thing you want, using index integer to count through the sum of all vertices so you can address individual ones as you need…

Hey danb!

thank you for your response. I tried it out but I could not really get it to what I want.
This Code (below) does the ideal effect, except that the application itself runs not very fluent. I was hoping to get the code somehow more efficient. I am actually not sure if I can get it more efficient thou. I thought there might be a way to access some variables via pointers (?) or something alike.
I will keep trying out different things! Thank you!

//--------------------------------------------------------------
void ofApp::setup(){
    
    image.load("2.JPG");
    image.resize(1024, 768);

    receiver.setup(30000);
}

//--------------------------------------------------------------
void ofApp::update(){
    
    while(receiver.hasWaitingMessages()){
        ofxOscMessage m;
        receiver.getNextMessage(m);
        
        if(m.getAddress() == "/positive/x"){
            
            positive = m.getArgAsFloat(0);
            mesh.clear();
        }
    }
}

//--------------------------------------------------------------
void ofApp::draw(){
    
    mesh.setMode(OF_PRIMITIVE_LINES);
    ofBackground(0);
    
    mesh.enableColors();
    
    int w = image.getWidth();
    int h = image.getHeight();
    
    for (int x=0; x<w; ++x) {
        for (int y=0; y<h; ++y) {
            
            ofColor c = image.getColor(x, y);
            float intensity = c.getLightness();
            
            if (intensity >= intensityThreshold) {
                saturation = c.getSaturation();
                
                //here I would like to alter the variables "negative" and "positive"
                float z = ofMap(saturation, 0, 255, negative, positive);
                
                ofVec3f pos(x, y, z);
                
                mesh.addVertex(pos);
                
                mesh.addColor(c);
            }
        }
    }

    easyCam.begin();
        ofPushMatrix();
            ofTranslate(-ofGetWidth()/2, -ofGetHeight()/2);
            mesh.draw();
        ofPopMatrix();
    easyCam.end();
}

Hey!

So what you’re doing right now is essentially in update() clearing the mesh and then adding new vertices to the mesh through a for loop in the draw function.

Your approach, instead, should be modifying the existing vertices of the mesh (without clearing it).

For example, if I have an mesh, and I want to displace the vertices in the z direction randomly, I’d go about it like this,

for(int i = 0; i<mesh.getVertices.size(); i++){
auto vertex = mesh.getVertex(i);
vertex.z += ofRandom(10);
mesh.setVertex(i, vertex); //not sure if this is necessary, can't remember if getVertex() is returning a reference or a copy, writing this from memory so it might not be 100% correct.
}

if you are having challenges, simple things like reducing calls and calculations per frame can help.
eg: create app-scope variables for image.width and image.height in your header file and set them in setup, only updating if you load another image,
create float intensity outside your for loops so it isnt being constantly created and destroyed
the same with ofVec3f pos
the same for ofbackground and mesh.setmode(), mesh.enablecolors() move these into setup{} so they are not called every frame