#include "ofApp.h" #include "glew.h" vector cmdnames={"moveTo","lineTo","curveTo","bezierTo","quadBezierTo","arc","arcNegative","close"}; float simplify_factor=0.2f; //-------------------------------------------------------------- void ofApp::setup(){ ofxSVG svg; svg.load("circles.svg"); imagepaths= svg.getPaths(); std::stringstream strm; for (auto& path:imagepaths){ path.setPolyWindingMode(OF_POLY_WINDING_ODD); vector outlines= path.getOutline(); for (auto& outline:outlines){ strm << outline.size() << "->"; outline.simplify(simplify_factor); strm << outline.size() << " "; segmenters.push_back(lineSegmenter(outline)); } strm << " , "; } cout << "Drawing: found " << imagepaths.size() << " paths with " << segmenters.size() << " shapes [ " << strm.str() << " ]" < outlines= path.getOutline(); for (auto& outline:outlines){ outline.simplify(simplify_factor); mask.push_back(outline); masksegmenters.push_back(lineSegmenter(outline)); } /* vector cmds=paths[i].getCommands(); std::stringstream strm; strm << "Mask: found " << cmds.size() << " commands ("; for (auto& cmd:cmds){ strm << cmdnames[cmd.type] <<","; } strm << ")" << std::endl; cout << strm.str(); */ } cout << "Mask: found " << maskpaths.size() << " paths with " << mask.size() << " shapes" < fabs(input[iMax * n + j])) { iMax = k; } } if (input[iMax * n + j] != 0) { if (i != iMax) { for (auto k = 0; k < n; ++k) { auto ikIn = input[i * n + k]; input[i * n + k] = input[iMax * n + k]; input[iMax * n + k] = ikIn; } } float ijIn = input[i * n + j]; for (auto k = 0; k < n; ++k) { input[i * n + k] /= ijIn; } for (auto u = i + 1; u < m; ++u) { auto ujIn = input[u * n + j]; for (auto k = 0; k < n; ++k) { input[u * n + k] -= ujIn * input[i * n + k]; } } ++i; } ++j; } for (auto i = m - 2; i >= 0; --i) { for (auto j = i + 1; j < n - 1; ++j) { input[i * n + m] -= input[i * n + j] * input[j * n + m]; } } } glm::mat4 ofApp::getPerspectiveTransformMatrix(const glm::vec2 src[4], const glm::vec2 dst[4]) { float p[8][9] = { { -src[0][0], -src[0][1], -1, 0, 0, 0, src[0][0] * dst[0][0], src[0][1] * dst[0][0], -dst[0][0] }, // h11 { 0, 0, 0, -src[0][0], -src[0][1], -1, src[0][0] * dst[0][1], src[0][1] * dst[0][1], -dst[0][1] }, // h12 { -src[1][0], -src[1][1], -1, 0, 0, 0, src[1][0] * dst[1][0], src[1][1] * dst[1][0], -dst[1][0] }, // h13 { 0, 0, 0, -src[1][0], -src[1][1], -1, src[1][0] * dst[1][1], src[1][1] * dst[1][1], -dst[1][1] }, // h21 { -src[2][0], -src[2][1], -1, 0, 0, 0, src[2][0] * dst[2][0], src[2][1] * dst[2][0], -dst[2][0] }, // h22 { 0, 0, 0, -src[2][0], -src[2][1], -1, src[2][0] * dst[2][1], src[2][1] * dst[2][1], -dst[2][1] }, // h23 { -src[3][0], -src[3][1], -1, 0, 0, 0, src[3][0] * dst[3][0], src[3][1] * dst[3][0], -dst[3][0] }, // h31 { 0, 0, 0, -src[3][0], -src[3][1], -1, src[3][0] * dst[3][1], src[3][1] * dst[3][1], -dst[3][1] }, // h32 }; gaussianElimination(&p[0][0], 9); return glm::mat4(p[0][8], p[3][8], 0, p[6][8], p[1][8], p[4][8], 0, p[7][8], 0, 0, 1, 0, p[2][8], p[5][8], 0, 1); } ofPolyline ofApp::polyLineTransform(const ofPolyline& poly, ofMatrix4x4 xform){ ofPolyline tempPoly; for (auto& p:poly){ tempPoly.addVertex(ofVec3f(p)*xform); } return tempPoly; } ofPolyline ofApp::makePolygon(int num,float diam){ ofPolyline poly; float step=PI*2/num; for (int i=0;i<=num;i++){ poly.addVertex(cos(step*i)*diam,sin(step*i)*diam); } return poly; } void ofApp::drawPoly(ofPolyline poly,float x,float y){ glPushMatrix(); ofTranslate(x,y); poly.draw(); for (int i=0;i lasershapes; switch (mode){ case 0:{ //just draw the mask for (auto shape=masksegmenters.begin();shape!=masksegmenters.end();shape++){ lasershapes.push_back(shape->getPoly()); } break; } case 1:{ //just draw 1 mask shape int s=((int)(ofGetElapsedTimef()*10))%masksegmenters.size(); lasershapes.push_back(masksegmenters[s].getPoly()); break; } case 2:{ for (auto shape=segmenters.begin();shape!=segmenters.end();shape++){ auto segments=shape->getSegments(numsegments,coverage,phase); for (auto segment=segments.begin();segment!=segments.end();segment++){ lasershapes.push_back(colourPolyline(*segment)); } } break; } case 3:{ //clip the shape with the mask (intersction) vector shapes; for (auto shape=segmenters.begin();shape!=segmenters.end();shape++){ auto segments=shape->getSegments(numsegments,coverage,phase); for (auto segment=segments.begin();segment!=segments.end();segment++){ shapes.push_back(*segment); } } clipper.addPolylines(shapes,ClipperLib::ptSubject); vector clipped = clipper.getClippedLines(ClipperLib::ctIntersection); for (auto& clip: clipped) { lasershapes.push_back(colourPolyline(clip)); } break; } case 4:{ //clip the shape with the mask (difference) vector shapes; for (auto shape=segmenters.begin();shape!=segmenters.end();shape++){ auto segments=shape->getSegments(numsegments,coverage,phase); for (auto segment=segments.begin();segment!=segments.end();segment++){ shapes.push_back(*segment); } } clipper.addPolylines(shapes,ClipperLib::ptSubject); vector clipped = clipper.getClippedLines(ClipperLib::ctDifference); for (auto& clip: clipped) { clip.simplify(simplify_factor); lasershapes.push_back(colourPolyline(clip)); } break; } case 5:{ //translate it vector shapes; ofMatrix4x4 rm = ofMatrix4x4::newIdentityMatrix(); rm.translate(-600,-450,0); rm.rotateRad(ofGetElapsedTimef(),0,0,1); rm.translate(600,450,0); for (auto& segment:segmenters){ shapes.push_back(polyLineTransform(segment.getPoly(),rm)); } clipper.addPolylines(shapes,ClipperLib::ptSubject); vector clipped = clipper.getClippedLines(ClipperLib::ctIntersection); for (auto& clip: clipped) { clip.simplify(simplify_factor); lasershapes.push_back(colourPolyline(clip)); } break; } case 6:{ vector clipped = clipper.getOffsets(maskpaths,((sin(ofGetElapsedTimef())+1)*5)+1,true); for (auto& clip: clipped) { lasershapes.push_back(colourPolyline(clip)); } break; } case 7:{ //the N only fucks up when the other shapes are drawn! vector clipped; for (auto & maskpath:maskpaths){ auto clips=clipper.getOffsets(maskpath,-((phase*20)+1),true); clipped.insert(clipped.end(),clips.begin(),clips.end()); } vector simplified = clipper.simplifyPolylines(clipped); ofSetColor(255*(1.0f-phase),255*(1.0f-phase),255*(1.0f-phase)); for (auto& clip: simplified) { clip.simplify(simplify_factor); lasershapes.push_back(colourPolyline(clip)); } /* float phase1=fmod(phase+0.5f,1.0f); clipped.clear(); clipped = clipper.getOffsets(maskpaths,-((phase*20)+1),true); simplified.clear(); simplified = clipper.simplifyPolylines(clipped); ofSetColor(255*(1.0f-phase1),255*(1.0f-phase1),255*(1.0f-phase1)); for (auto& clip: simplified) { clip.draw(); segmentsdrawn++; pointsdrawn+=clip.size(); } */ break; } case 8:{ vector shapes; for (auto& shape: mask) { shape.close(); shapes.push_back(shape); } vector clipped = clipper.getOffsets(shapes,((sin(ofGetElapsedTimef())+1)*5)+1); vector simplified = clipper.simplifyPolylines(clipped); for (auto& clip: simplified) { clip.simplify(simplify_factor); lasershapes.push_back(colourPolyline(clip)); } break; } case 9: { ofPoint scale; if(dir.isValidIndex(dirIdx)){ //client.update(); /* scale=ofPoint(ofGetWidth()/client.getWidth(),ofGetHeight()/client.getHeight()); ofPixels pixels; ofTexture texture=client.getTexture(); texture.bind(); texture.readToPixels(pixels); texture.unbind(); colorImg.setFromPixels(pixels); grayImage = colorImg; grayImage.threshold(threshold); contourFinder.findContours(grayImage, 20, (340*240)/3, 10, true); */ scale=ofPoint(ofGetWidth()/syphonFbo.getWidth(),ofGetHeight()/syphonFbo.getHeight()); syphonFbo.begin(); client.draw(0, 0, syphonFbo.getWidth(),syphonFbo.getHeight()); syphonFbo.end(); //syphonFbo.draw(0,0,ofGetWidth(),ofGetHeight()); //works //printf("got fbo: %ix%i format %i\n",syphonFbo.getWidth(),syphonFbo.getHeight(),syphonFbo.getTexture().getPixelFormat()); //syphonFbo.updateTexture(0); ofTexture texture= syphonFbo.getTexture(); //texture.draw(0,0,ofGetWidth(),ofGetHeight()); //works //printf("got texture: %ix%i format %i\n",texture.getWidth(),texture.getHeight(),texture.getTextureData().glInternalFormat); ofPixels pixels; texture.readToPixels(pixels); //printf("got texture: %ix%i format %i\n",pixels.getWidth(),pixels.getHeight(),pixels.getPixelFormat()); //pixels are in RGBA format allegedly, but maybe this is the problem colorImg.setFromPixels(pixels); colorImg.draw(0,0,ofGetWidth(),ofGetHeight()); //mangled grayImage = colorImg; grayImage.threshold(threshold); contourFinder.findContours(grayImage, 20, (340*240)/3, 10, true); } else { movie.update(); scale=ofPoint(ofGetWidth()/movie.getWidth(),ofGetHeight()/movie.getHeight()); if (movie.isFrameNew()){ colorImg.setFromPixels(movie.getPixels()); grayImage = colorImg; grayImage.threshold(threshold); contourFinder.findContours(grayImage, 20, (340*240)/3, 10, true); } } vector shapes; for (int i = 0; i < contourFinder.nBlobs; i++){ colourPolyline shape; for (auto& point:contourFinder.blobs[i].pts){ ofVec3f p=point*scale; ofColor c=colorImg.getPixels().getColor(point.x,point.y); shape.addVertex(p,c); } shape.simplify(simplify_factor); lasershapes.push_back(shape); } break; } case 10:{ int w=ofRandom(1000); lasershapes.push_back(colourPolyline(masksegmenters[w%masksegmenters.size()].getPoly(),ofColor(ofRandom(255),ofRandom(255),ofRandom(255)))); break; } } /* ofxSVG svg; svg.load("lorenzos.svg"); vector paths= svg.getPaths(); for (auto& l:paths) l.draw(); */ glm::vec2 src[]={ glm::vec2(0,0), glm::vec2(ofGetWidth(),0), glm::vec2(ofGetWidth(),ofGetHeight()), glm::vec2(0,ofGetHeight()) }; glm::vec2 mp=glm::vec2(ofGetWidth()/2,ofGetHeight()/2); glm::vec2 scaled_dest[]={ ((warpframe[0]-mp)*mapping_scale)+mp, ((warpframe[1]-mp)*mapping_scale)+mp, ((warpframe[2]-mp)*mapping_scale)+mp, ((warpframe[3]-mp)*mapping_scale)+mp }; ofMatrix4x4 warp =getPerspectiveTransformMatrix(src,scaled_dest); vector warpedshapes; for (auto s:lasershapes){ warpedshapes.push_back(polyLineTransform(s,warp)); } int num = laser.draw(warpedshapes,ofColor(125,0,255)); for (auto& shape:lasershapes){ shape.draw(); } if (bDrawFrame) drawWarpFrame(); if (num>0){ ofSetWindowTitle(ofToString(ofGetFrameRate(), 2)+" fps laser points: "+ofToString(num)); } else { ofSetWindowTitle(ofToString(ofGetFrameRate(), 2)+" fps laser error "); } mainOutputSyphonServer.publishScreen(); } //-------------------------------------------------------------- void ofApp::exit() { } //-------------------------------------------------------------- void ofApp::keyPressed(ofKeyEventArgs &args){ } //-------------------------------------------------------------- void ofApp::keyReleased(int key){ switch(key){ case '[':{ numsegments=max(0,numsegments-1); break; } case ']':{ numsegments++; break; } case '{':{ coverage=coverage*0.9f; break; } case '}':{ coverage=min(coverage/0.9f,1.0f); break; } case 'p':{ mode=(mode+1)%11; break; } case 'q':{ mode=(mode-1); if (mode<0) mode=10; break; } case '-':{ threshold=max(threshold-1,0); break; } case '=':{ threshold=min(threshold+1,255); break; } case ' ':{ if (dir.size() > 0) { dirIdx++; if(dirIdx > dir.size() - 1) dirIdx = 0; client.set(dir.getDescription(dirIdx)); string serverName = client.getServerName(); string appName = client.getApplicationName(); if(serverName == ""){ serverName = "null"; } if(appName == ""){ appName = "null"; } ofSetWindowTitle(serverName + ":" + appName); } else { ofSetWindowTitle("No Server"); } } case 'w':{ bDrawFrame=!bDrawFrame; break; } } } //-------------------------------------------------------------- void ofApp::mouseMoved(int x, int y ){ } //-------------------------------------------------------------- void ofApp::mouseDragged(int x, int y, int button){ if (select_warpframe>-1){ warpframe[select_warpframe]=glm::vec2(x,y); } } //-------------------------------------------------------------- void ofApp::mousePressed(int x, int y, int button){ for (int i=0;i<4;i++){ if (ofPoint(x,y).distance(warpframe[i])<25){ select_warpframe=i; } } } //-------------------------------------------------------------- void ofApp::mouseReleased(int x, int y, int button){ select_warpframe=-1; } //-------------------------------------------------------------- void ofApp::mouseEntered(int x, int y){ } //-------------------------------------------------------------- void ofApp::mouseExited(int x, int y){ } //-------------------------------------------------------------- void ofApp::windowResized(int w, int h){ } void ofApp::outputWindowResized(ofResizeEventArgs &resizeargs){ } //-------------------------------------------------------------- void ofApp::gotMessage(ofMessage msg){ } //-------------------------------------------------------------- void ofApp::dragEvent(ofDragInfo dragInfo){ }