space filling

Hi Forum.

Often I take code from this great forum.

But today I wanted to share this approach to filling a space with non overlapping images.

It loads in x amount of images and tries to place as many as possible in to the boundaries of a white space.

It is inspired by Scattered Letters by Algirdas Rascius: http://www.openprocessing.org/visuals/?visualID=1811

let me know what you think.

Stephan.

testApp.h

  
#ifndef _TEST_APP  
#define _TEST_APP  
  
  
#include "ofMain.h"  
#include "ofxFBOTexture.h"  
#include "ofxDirList.h"  
  
#define maxObj 6  
  
typedef struct {  
	  
	float 	x;  
	float 	y;  
	bool 	bBeingDragged;  
	bool 	bOver;  
	float 	radius;  
	  
}	draggableVertex;  
  
class testApp : public ofBaseApp{  
	  
	public:  
		  
		void setup();  
		void update();  
		void draw();  
	void arrangeStraightTail(float x, float y, float w, float h);  
  
	  
		void keyPressed  (int key);  
		  
	void placeImages();  
	  
	ofImage pastImageList[100];  
	ofPoint pastPickedPosList[100];  
	ofImage pastPickedImgList[100];  
  
	  
	ofxFBOTexture myFBO;  
	unsigned char * fboPixels;  
	unsigned char * secondImgPixels;  
  
	int fboHeight,fboWidth;  
	  
	int 		nImages;  
	ofxDirList   DIR;  
	int placeCnt,pickCnt;  
	  
};  
  
#endif	  
  
  

testApp.cpp

  
/*  
this space filling approche was inspired by   
   
 Scattered Letters by Algirdas Rascius.  
   
 [http://www.openprocessing.org/visuals/?visualID=1811](http://www.openprocessing.org/visuals/?visualID=1811)  
  
 */  
  
#include "testApp.h"  
  
  
  
//--------------------------------------------------------------  
void testApp::setup(){	   
	  
	//load past images  
	DIR.setVerbose(false);  
    nImages = DIR.listDir("images/");  
	ofImage tempImg;  
	for(int i=0;i<100; i++){  
		int randomFileIndex = int(ofRandom(0, nImages));  
		pastImageList[i].loadImage(DIR.getPath(randomFileIndex));  
		pastImageList[i].setImageType(OF_IMAGE_COLOR_ALPHA);  
	  
	}  
	cout<<"loaded "<<nImages<<" past images"<<endl;  
  
	myFBO.allocate(ofGetWidth(), ofGetHeight(),GL_RGB);// GL_RGBA);  
	  
	fboWidth = ofGetWidth(); //tailWidth+50;  
	fboHeight = ofGetHeight();// tailHeight;  
	  
	  
	pickCnt = 0;  
	placeCnt = 0;  
  
		  
	myFBO.begin();  
	ofSetColor(255,255,255);  
	ofFill();  
	ofRect(int(ofRandom(0, ofGetWidth()/2)), int(ofRandom(0, ofGetHeight()/2)), int(ofRandom(400, ofGetWidth()/2)),  int(ofRandom(400, ofGetHeight()/2)));		  
	myFBO.end();  
  
	  
}  
  
  
//--------------------------------------------------------------  
void testApp::update(){  
	  
		  
}  
void testApp::placeImages(){  
  
	int wROI = pastImageList[placeCnt].width;  
	int hROI = pastImageList[placeCnt].height;  
	  
	secondImgPixels = pastImageList[placeCnt].getPixels();  
	  
	fboPixels = (unsigned char*) myFBO.getPixels();  
	  
	ofSetColor(0, 255, 0);  
	bool fits = true;  
	for (int tries=20; tries>0; tries--) {  
		  
		int xROI = (int)ofRandom(0, myFBO.getWidth() - wROI);  
		int yROI = (int)ofRandom(0, myFBO.getWidth() - hROI);  
		  
		fits = true;  
		for (int x = 0; x < wROI; x++){   
			for (int y = 0; y < hROI; y++){   
				  
				int n = ((myFBO.getHeight()-y-yROI) * myFBO.getWidth() + (x+xROI)); //flip fbo pixels because opengl origion is at bottom left  
				  
				int imgPos = (y * wROI + x);   
				  
				if(secondImgPixels[imgPos*4+3]!=0){  
					if(fboPixels[n*3] == 0){  
						  
						fits = false;  
						break;  
					}  
				}  
			}   
		}  
		  
		if(fits){  
			myFBO.begin();  
			ofSetColor(0, 0, 0);  
			ofEnableAlphaBlending();  
			pastImageList[placeCnt].draw(xROI,yROI);  
			ofDisableAlphaBlending();  
			myFBO.end();  
			pastPickedPosList[pickCnt].x = xROI;  
			pastPickedPosList[pickCnt].y = yROI;  
			pastPickedImgList[pickCnt] = pastImageList[placeCnt];  
			pickCnt++;  
			cout<<"found fit "<<placeCnt<<"xROI "<<xROI<<" yROI "<<yROI<<endl;  
			placeCnt++;  
			break;  
		}  
	}  
	if(fits == false){  
		cout<<"this one did not fit "<<placeCnt<<endl;  
		placeCnt++;  
		  
	}  
}  
  
//--------------------------------------------------------------  
void testApp::draw(){	  
	ofBackground(0,0,0);  
	  
	ofSetColor(255,255,255);  
	myFBO.draw(0,0);  
	  
	/*  
	ofEnableAlphaBlending();  
	for(int i=0; i<pickCnt; i++){  
		pastPickedImgList[i].draw(pastPickedPosList[i].x,pastPickedPosList[i].y);  
	}  
	ofDisableAlphaBlending();  
	 */  
	ofDrawBitmapString("press [a] to fill white space \npress [n] to start again", mouseX, mouseY);  
	  
}  
  
//--------------------------------------------------------------  
void testApp::keyPressed  (int key){   
	  
	if(key == 'p') placeImages();  
	if(key == 'a'){  
		for(int i=0; i<50;i++){  
			placeImages();	  
		}  
	}  
	if(key == 'n'){  
		pickCnt = 0;  
		placeCnt = 0;  
		  
		  
		myFBO.begin();//off screen buffer of blob image  
		ofFill();  
		ofSetColor(0,0,0);  
		ofRect(0, 0, ofGetWidth(), ofGetHeight());  
		  
		ofSetColor(255,255,255);  
		ofRect(int(ofRandom(0, ofGetWidth()/2)), int(ofRandom(0, ofGetHeight()/2)), int(ofRandom(400, ofGetWidth()/2)),  int(ofRandom(400, ofGetHeight()/2)));		  
		myFBO.end();  
		  
	}  
	  
}  
  
  

hi

probably you changed teh FBO class , because i have an error :
myFBO.getPixels();

error C2039: ‘getPixels’ : is not memeber of ‘ofxFBOTexture’

Hi.

I don’t think i did.
I just checked my ofxfbo.cpp and.h file and getPixels is a public function.
So i don’t see why it would not be a member ?

Which OF version are you using on what system ?
Stephan.

I didn’t have the getPixels() problem but it crashes once I hit 100 images . It looks like placeCnt just needs a check

Cool stuff - thanks for sharing!