[solved] Vector filled in update() gets empty in draw()

Hi there,
I have got following problem that ist most likely due to my limited knowledge of proper c++ constructor usage and reference handling.

However, here it is:
I have a class Artefact in whose objects I store a few strings
and also a vector<ofRectangle> foundObjects.
My ofApp stores a few of those artefact objects in a vector.

In update(), I pushBack() new ofRectangles into the foundObjects vector of each artefact.
If I check it with a simple cout << artefact.foundObjects.size() it gets incremented as expected.

void ofApp::update() {
    cam.update();
    if(cam.isFrameNew()) {
        for(Artefact a : artefacts){
            finder.setup(a.cascadepath);
            finder.update(cam);
            for(int i = 0; i < finder.size(); i++){
                ofRectangle r;
                cout << "found objects: " << finder.size() << " in " << a.name << endl;
                r = ofRectangle(finder.getObjectSmoothed(i));
                cout << " size of foundobjects before: " << a.foundObjects.size() << endl;
                a.foundObjects.push_back(r);
                cout << " size of foundobjects after: " << a.foundObjects.size() << endl;
            }
        }
    }
}

But: When I want to draw those rects, the vector foundObjects is suddenly empty again.
On the other hand, all the strings I saved in the artefact are still accessible, but the vector of Rectangles is empty.

void ofApp::draw() {
    ofSetColor(255);
    cam.draw(0, 0);
    for(Artefact a : artefacts){
        for(int i = 0; i < a.foundObjects.size(); i++) {
 
            
            cout << "this is not being executed as foundObjects.size() is now 0. why?" << endl;
            
            
            cout << a.foundObjects.size() << endl;
            ofRectangle object = a.foundObjects[i];
            ofNoFill();
            ofSetColor(0, 30, 200);
            ofRect(object.getPosition(), object.width, object.height);
        }
    }
}

What am I doing wrong?

I am not sure whether I fully understand your code or what you are trying to accomplish - but I don’t think you can use ofRectangle like that.

I would create a separate rectangle class, that contains variables for position, width, height, color etc. and then call ofRectangle and feeding it the parameters from your rectangle objects when you want to draw them; something like:

ofRect(rectangles[i].Position, rectangles[i].width, rectangles[i].height);

Yay! Solved it myself, thanks to a friendly person in the oF irc, this tutorial and this stackoverflow question.

The problem (I think) is that my own class Artefact, doesnt have a copy constructor, so I can’t reliably use it with vectors of that type.

So, as a solution instead of using a vector of objects:

 vector<Artefact> artefacts;

I now use a vector of pointers to objects:

vector<*Artefact> artefacts;

The modifed code is now:

void ofApp::update() {
    cam.update();
    if(cam.isFrameNew()) {
        for(Artefact * a : artefacts){
            finder.setup(a->cascadepath);
            finder.update(cam);
            
            // remove all old ofRectangles
            a->foundObjects.clear();
            for(int i = 0; i < finder.size(); i++){
                a->foundObjects.push_back(ofRectangle(finder.getObjectSmoothed(i)));
            }
        }
    }
}

void ofApp::draw() {
    ofSetColor(255);
    cam.draw(0, 0);
    for(Artefact * a : artefacts){
        for(int i = 0; i < a->foundObjects.size(); i++) {
            ofRectangle object = a->foundObjects[i];
            ofNoFill();
            ofSetColor(0, 30, 200);
            ofRect(object.getPosition(), object.width, object.height);
        }
    }
}
1 Like