From 19be92e0aff674b95bdae72fe7a2e409fd1bf77a Mon Sep 17 00:00:00 2001 From: Tim Redfern Date: Mon, 17 Apr 2023 19:44:00 +0100 Subject: add to archive --- FESgui/src/ofApp.cpp | 1064 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1064 insertions(+) create mode 100644 FESgui/src/ofApp.cpp (limited to 'FESgui/src/ofApp.cpp') diff --git a/FESgui/src/ofApp.cpp b/FESgui/src/ofApp.cpp new file mode 100644 index 0000000..a1c49be --- /dev/null +++ b/FESgui/src/ofApp.cpp @@ -0,0 +1,1064 @@ +#include "ofApp.h" + + + +//====================== settings + +void ofApp::default_settings(){ + warpframe[0]=glm::vec3(0,0,0); + warpframe[1]=glm::vec3(outputWindowSize.x,0,0); + warpframe[2]=glm::vec3(outputWindowSize.x,outputWindowSize.y,0); + warpframe[3]=glm::vec3(0,outputWindowSize.y,0); + outputPosition=ofPoint(0,0,0); + outputScale=1.0f; +} + +void ofApp::save_settings(){ + XML.setValue("WARP:p0:X", warpframe[0].x); + XML.setValue("WARP:p0:Y", warpframe[0].y); + XML.setValue("WARP:p1:X", warpframe[1].x); + XML.setValue("WARP:p1:Y", warpframe[1].y); + XML.setValue("WARP:p2:X", warpframe[2].x); + XML.setValue("WARP:p2:Y", warpframe[2].y); + XML.setValue("WARP:p3:X", warpframe[3].x); + XML.setValue("WARP:p3:Y", warpframe[3].y); + + XML.setValue("SAFETY:p0:X", safety_frame[0].x); + XML.setValue("SAFETY:p0:Y", safety_frame[0].y); + XML.setValue("SAFETY:p1:X", safety_frame[1].x); + XML.setValue("SAFETY:p1:Y", safety_frame[1].y); + XML.setValue("SAFETY:p2:X", safety_frame[2].x); + XML.setValue("SAFETY:p2:Y", safety_frame[2].y); + XML.setValue("SAFETY:p3:X", safety_frame[3].x); + XML.setValue("SAFETY:p3:Y", safety_frame[3].y); + + XML.setValue("POSITION:X", outputPosition.x); + XML.setValue("POSITION:Y", outputPosition.y); + + XML.setValue("SCALE", outputScale); + + if (XML.saveFile("settings.xml")){ + cout << "settings.xml saved!" < deviceList = kinect.getDeviceList(); + if (deviceList.size()){ + useKinect=kinect.open(deviceList[0].serial); + } + else useKinect=false; + } + + if (!useKinect) { + _video.initGrabber(1280, 720); + } + + contourgui.setup("video contours","",550,550); + contourgui.add(video_outlines.set("enable",false)); + contourgui.add(contour_adaptive.set("adaptive",false)); + contourgui.add(contour_threshold.set("threshold", 140, 0, 255)); + contourgui.add(contour_adaptive_window.set("window", 0.5, 0, 1.0)); + contourgui.add(contour_simplify.set("simplify", 0.8, 0.0, 10.0)); + //contourgui.add(contour_useColour.set("use colour",false)); //TODO + + vectorTransforms.setup("vector transform","",550,750); + vectorTransforms.add(use_rotate.set("rotation",false)); + vectorTransforms.add(xf_rotate.set("rotate speed", 0.0, -1.0, 1.0)); + vectorTransforms.add(use_scale.set("scaling",false)); + vectorTransforms.add(xf_scale_speed.set("scale speed", 1.0, 0.0, 10.0)); + vectorTransforms.add(xf_scale_min.set("scale min", 1.0, 0.0, 3.0)); + vectorTransforms.add(xf_scale_max.set("scale maz", 1.0, 0.0, 3.0)); + + perlin = new PerlinPhasingFilter( + outputWindowSize.x, + outputWindowSize.y, + 8.f + ); + + perlinpanel.setup("PerlinPhasingFilter","",760,500); + perlinpanel.add(perlinEnable.set("enable",false)); + perlinpanel.add(perlinScale.set("scale",0.0,-1.0,1.0)); + perlinpanel.add(perlinSpeed.set("speed",0.0,-1.0,1.0)); + perlinpanel.add(perlinPixelWidth.set("pixel width",0.0,0.0,1.0)); + perlinpanel.add(perlinPixelWidthSpeed.set("pixel speed",1.0,0.0,10.0)); + + preview.allocate(outputWindowSize.x,outputWindowSize.y); + + gist.setUseForOnsetDetection(GIST_PEAK_ENERGY); + gist.setThreshold(GIST_PEAK_ENERGY, .05);// + + ofAddListener(GistEvent::ON,this,&ofApp::onNoteOn); + ofAddListener(GistEvent::OFF,this,&ofApp::onNoteOff); + + onset_frame=0; +} + +//-------------------------------------------------------------- +void ofApp::updateOutput(ofEventArgs & args){ + _player.setSpeed(video_speed); +} + +void ofApp::update(){ + laser.update(); + text.update(onset_frame); + + if (_player.isLoaded()){ + _player.update(); + } + + if (captPreview||captEnable){ + if (useKinect){ + kinect.update(); + if (kinect.isFrameNew()){ + texRGB.setFromPixels(kinect.getPixels()); + } + } + else { + _video.update(); + texRGB.setFromPixels(_video.getPixels()); + } + int tw=texRGB.getHeight()*1.333f; + int sl=(texRGB.getWidth()-tw)/2; + texRGB.crop(sl, 0, tw, texRGB.getHeight()); + } + + float interval=ofGetElapsedTimef()-prev_time; + rotate_amt+=interval*xf_rotate*5; + + phase=fmod(phase+(interval*segmenter_speed),1); //for segmenter + prev_time=ofGetElapsedTimef(); + + while (phase<0.0f) { + phase+=1.0f; + } + + scale_phase+=(interval*xf_scale_speed); + + scale_amt=(((sin(scale_phase)*0.5)+0.5)*(xf_scale_max-xf_scale_min))+xf_scale_min; + + gist.setThreshold(GIST_PEAK_ENERGY,onset_threshold); + + onset_frame++; +} + +//-------------------------------------------------------------- GUI +void ofApp::draw(){ + //draw the workspace window. + // 5 - 240 - panels + // 250 - 570 - sources (320x240) + // 580 - 1220 - preview (640x480) + + + + ofBackground(0); + + ofSetColor(255); + + + if (bShowPositionInterface){ + + glPushMatrix(); + + ofNoFill(); + + glTranslatef(20,20,0); + + ofDrawRectangle(0,0,560,560); + + glTranslatef(outputOffset.x,outputOffset.y,0); + + glScalef(guiScale,guiScale,guiScale ); + + glTranslatef(2048.0f+outputPosition.x,2048.0f+outputPosition.y,0); + + if (bOutputSelected) { + if (commandPressed) { + ofSetColor(0,255,0); + } + else { + ofSetColor(255,0,0); + } + } + + ofDrawRectangle( + (-outputWindowSize.x/2)*outputScale*outputOffsetScale, + (-outputWindowSize.y/2)*outputScale*outputOffsetScale, + outputWindowSize.x*outputScale*outputOffsetScale, + outputWindowSize.y*outputScale*outputOffsetScale); + + ofFill(); + + glPopMatrix(); + } + else { + //draw gui, sources and preview + + videoSourcePanel.draw(); + vectorSourcePanel.draw(); + audiopanel.draw(); + drawingpanel.draw(); + perlinpanel.draw(); + contourgui.draw(); + vectorTransforms.draw(); + svggui.draw(); + laser.drawgui(); + text.drawgui(); + + float sourcescale=sourceframesize.x/outputWindowSize.x; + + for (int i=0;i<4;i++){ + glPushMatrix(); + glTranslatef(210,249*i,0); + ofNoFill(); + ofDrawRectangle(5,5,sourceframesize.x+4,sourceframesize.y+4); + ofFill(); + + glTranslatef(7,7,0); + + //draw video sources within case statement + switch(i){ + case 0:{ + if (captPreview){ + if (useKinect){ + if (texRGB.isAllocated()){ + texRGB.draw(0,0,sourceframesize.x,sourceframesize.y); + } + } + else { + texRGB.draw(0,0,sourceframesize.x,sourceframesize.y); + } + } + break; + } + case 1:{ + if (_player.isLoaded()){ + if (ofGetElapsedTimef()-videostart<2.54f){ + int amt=(ofGetElapsedTimef()-videostart)*100; + ofSetColor(amt); + } + _player.draw(0,0,sourceframesize.x,sourceframesize.y); + ofSetColor(255); + } + break; + } + case 2:{ + glPushMatrix(); + glScalef(sourcescale,sourcescale,sourcescale); + for (auto shape=segmenters.begin();shape!=segmenters.end();shape++){ + shape->getPoly().draw(); + } + glPopMatrix(); + ofSetColor(255); + break; + } + } + + + + //draw vectors within case statement + + glPopMatrix(); + } + + glPushMatrix(); + glTranslatef(550,5,0); + ofNoFill(); + ofDrawRectangle(0,0,previewframesize.x+4,previewframesize.y+4); + ofFill(); + + if (perlinEnable) perlin->begin(); + preview.draw(2,2,previewframesize.x,previewframesize.y); + if (perlinEnable) perlin->end(); + + glPopMatrix(); + + } + + ofSetWindowTitle(ofToString(phase, 3)+" "+ofToString(ofGetFrameRate(), 2)+" fps laser points: "+ofToString(laser.get_numpts())); +} + +static float phase=0.0f; +static float lastframetime=0.0f; +static float scale=10.0f; +static float pixelWidth=0.05f; + +static int num=0; + +void ofApp::drawOutput(ofEventArgs & args){ +/* + if (perlinScale!=ps){ + perlin->updateParameter("scale", perlinScale); + ps=perlinScale; + //ofLog()<<"set perlin scale to "<updateParameter("phase", phase); + perlin->updateParameter("scale", scale); + perlin->updateParameter("fractionalWidthOfPixel",0.05f+(sin(ofGetElapsedTimef()*perlinPixelWidthSpeed)*perlinPixelWidth)); + + //prepare vectors + + float vpos=ofGetHeight()/2; + + float scale=ofGetHeight()*vScale; + + ofPolyline osc; + + osc.addVertex(0,vpos+(buffer[0]*scale)); + + float i=0.0f; + float step=ofGetWidth()/(hScale*48); + + while (i<(ofGetWidth()+step)){ + i+=max(1.0f,(float)step); + osc.lineTo(i,vpos+(buffer[(int)i]*scale)); + } + + //render output to fbo and output + + preview.begin(); + + ofBackground(0); + ofSetColor(255,255,255); + + + ofClear(0,0,0,0); + + vector contouroutput; + + if (captEnable||(_player.isLoaded()&&playerEnable)){ + if (video_outlines){ + //use capture or player to generate outlines + if (captEnable){ + colorImg.setFromPixels(texRGB.getPixels()); + } + else if (_player.isLoaded()&&playerEnable){ + colorImg.setFromPixels(_player.getPixels()); + } + ofPoint scale=ofPoint(outputWindowSize.x/colorImg.getWidth(),outputWindowSize.y/colorImg.getHeight()); + if (grayImage.getWidth()!=colorImg.getWidth()||grayImage.getHeight()!=colorImg.getHeight()){ + grayImage.clear(); + } + grayImage=colorImg; + if(contour_adaptive){ + grayImage.adaptiveThreshold(grayImage.getWidth()*contour_adaptive_window, contour_threshold,false,true); + } + else { + grayImage.threshold(contour_threshold); + } + contourFinder.findContours(grayImage, 20, (grayImage.getWidth()*grayImage.getHeight())/3, 10, true); + 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); //contour_useColour?c:ofColor(laser_R,laser_G,laser_B)); + } + shape.simplify(contour_simplify); + contouroutput.push_back(shape); + } + } + } + + vector svgoutput; + + if (SVGLaserDraw||SVGVideoDraw){ + if (!use_onset||onset_framegetSegments(segmenter_number,segmenter_length,phase); + for (auto segment=segments.begin();segment!=segments.end();segment++){ + //polyOutput.push_back(colourPolyline(*segment,ofColor(laser_R,laser_G,laser_B))); + svgoutput.push_back(*segment); + } + } + else { + //polyOutput.push_back(colourPolyline(shape->getPoly(),ofColor(laser_R,laser_G,laser_B))); + svgoutput.push_back(shape->getPoly()); + } + } + } + if (contour_useColour){ + vector newPolys; + for (auto p: svgoutput){ + newPolys.push_back(colourPolyline((ofPolyline)p,ofColor(255,255,255))); //laser_R,laser_G,laser_B))) ; + } + svgoutput=newPolys; + } + } + } + + vector textoutput; + + if (textVideoDraw||textLaserDraw){ + textoutput = text.getOutlines(ofGetWidth()/2,ofGetHeight()/2); + /* + if (textoutput.size()!=num) { + ofLog()<begin(); + //shader.begin(); + preview.draw(0,0); + //shader.end(); + if (perlinEnable) perlin->end(); + + vector output; + + if (vectorOscEnable) output.push_back(osc); + else if (contoursLaserDraw) output=contouroutput; + else if (SVGLaserDraw) output=svgoutput; + else if (textLaserDraw) output=textoutput; + + //laser transformation comes here + + vector transformedOutput; + + if (use_rotate||use_scale){ + ofMatrix4x4 rm = ofMatrix4x4::newIdentityMatrix(); + rm.translate(-outputWindowSize.x/2,-outputWindowSize.y/2,0); + if (use_rotate){ + rm.rotateRad(rotate_amt,0,0,1); + } + if (use_scale){ + rm.scale(scale_amt,scale_amt,scale_amt); + } + rm.translate(outputWindowSize.x/2,outputWindowSize.y/2,0); + for (auto& shape:output){ + transformedOutput.push_back(lineTransformer::polyLineTransform(rm,shape)); + } + } + else { + transformedOutput=output; + } + + //laser warping comes here + + glm::vec2 src[]={ + glm::vec2(0,0), + glm::vec2(ofGetWidth(),0), + glm::vec2(ofGetWidth(),ofGetHeight()), + glm::vec2(0,ofGetHeight()) + }; + + glm::vec2 mp=glm::vec2(outputWindowSize.x/2,outputWindowSize.y/2); + + glm::vec2 scaled_dest[]={ + ((warpframe[0]-mp)*outputScale*outputOffsetScale)+mp, + ((warpframe[1]-mp)*outputScale*outputOffsetScale)+mp, + ((warpframe[2]-mp)*outputScale*outputOffsetScale)+mp, + ((warpframe[3]-mp)*outputScale*outputOffsetScale)+mp + }; + + ofMatrix4x4 scaled_warp =lineTransformer::getPerspectiveTransformMatrix(src,scaled_dest); + ofMatrix4x4 warp =lineTransformer::getPerspectiveTransformMatrix(src,warpframe); + + vector warpedOutput; + vector scaledWarpedOutput; + + for (auto s:transformedOutput){ + warpedOutput.push_back(lineTransformer::polyLineTransform(warp,s)); + scaledWarpedOutput.push_back(lineTransformer::polyLineTransform(scaled_warp,s)); + } + + ofPolyline safety; + safety.addVertex(safety_frame[0]); + safety.addVertex(safety_frame[1]); + safety.addVertex(safety_frame[2]); + safety.addVertex(safety_frame[3]); + //safety.close(); //addVertex(safety_frame[0]); + + ofPolyline warpedScaledSafety=lineTransformer::polyLineTransform(scaled_warp,safety); + + warpedScaledSafety.close(); + + vector clippedOutput; + + if (use_safety){ + vector masks; + masks.push_back(warpedScaledSafety); //create polyline + + for (auto& poly: scaledWarpedOutput) + { + clipper.Clear(); + clipper.addPolylines(masks, ClipperLib::ptClip); + vector shapes; //TODO make clipper clip colourpolylines + shapes.push_back(poly); + clipper.addPolylines(shapes,ClipperLib::ptSubject); + vector clipped; + //if (invert_mask){ + // clipped = clipper.getClippedLines(ClipperLib::ctDifference); + //}else { + clipped = clipper.getClippedLines(ClipperLib::ctIntersection); + //} + for (auto& clip: clipped) + { + clip.simplify(contour_simplify); + clippedOutput.push_back(colourPolyline(clip,poly.getColourAt(0))); + } + } + } + else { + clippedOutput=scaledWarpedOutput; + } + + //laser sorting comes here + + if (edit_safety){ + lineTransformer::drawWarpFrame(safety_frame); + laser.draw(warpedScaledSafety); + } + else if (clippedOutput.size()) { + laser.draw(clippedOutput); + } + else { + colourPolyline blank; + for (int i=0;i<100;i++){ + blank.addVertex(ofGetWidth()/2,ofGetHeight()/2,0,0,0); + } + laser.draw(blank); + } + + if (bDrawFrame){ + lineTransformer::drawWarpFrame(warpframe); + } +} + +void ofApp::onNoteOn(GistEvent &e){ + //ofLog() << "<>"; + onset_frame=0; + onset_number++; + //noteOnRadius = 100; +}; + + +void ofApp::onNoteOff(GistEvent &e){ + //ofLog() << "<>"; + //turn off? + //noteOnRadius = 0; +}; + +void ofApp::audioIn(float * input, int blockSize, int nChannels){ + buffer.add(input,blockSize); + + vectorbuf; + buf.assign(&input[0],&input[blockSize-1]); + gist.processAudio(buf, blockSize, nChannels,SAMPLERATE); +} + + +void ofApp::select_random_shapes(float duration,bool generate){ + float timedelta=ofGetElapsedTimef()-last_frame_time; + last_frame_time=ofGetElapsedTimef(); + //track how long each shape has been selected + for (int i=0;i0.0f){ + shape_selection_durations[i]=shape_selection_durations[i]-timedelta; + } + } + + shape_selection.clear(); + + for (int i=0;i0.0f){ + shape_selection.insert(i); + } + } + std::stringstream strom; + for (auto& s:shape_selection){ + strom << s <<":"<-1){ + warpframe[select_warpframe]=glm::vec2(args.x,args.y); + } + if (select_safetyframe>-1){ + safety_frame[select_safetyframe]=glm::vec3(args.x,args.y,0); + } + +} + +void ofApp::mouseDragged(int x, int y, int button){ + if (bOutputSelected){ + if (commandPressed){ + float startDistance=((outputPosition*guiScale)+ofPoint(300,300)).distance(outputSelectionPoint); + float currentDistance=((outputPosition*guiScale)+ofPoint(300,300)).distance(ofPoint(x,y)); + outputOffsetScale=currentDistance/startDistance; + } + else { + outputOffset=ofPoint(x,y)-outputSelectionPoint; + laser.set_centre(ofPoint( + outputPosition.x+(outputOffset.x/guiScale), + outputPosition.y+(outputOffset.y/guiScale) + )); + } + } +} + +//-------------------------------------------------------------- +void ofApp::outputMousePressed(ofMouseEventArgs & args){ + for (int i=0;i<4;i++){ + if (ofPoint(args.x,args.y).distance(warpframe[i])<25){ + select_warpframe=i; + } + } + if (edit_safety){ + for (int i=0;i<4;i++){ + if (ofPoint(args.x,args.y).distance(safety_frame[i])<25){ + select_safetyframe=i; + } + } + } +} + +void ofApp::mousePressed(int x, int y, int button){ + if (bShowPositionInterface){ + if (x>(300+((outputPosition.x-((outputWindowSize.x/2)*outputScale))*guiScale))&& + x<(300+((outputPosition.x+((outputWindowSize.x/2)*outputScale))*guiScale))&& + y>(300+((outputPosition.y-((outputWindowSize.y/2)*outputScale))*guiScale))&& + y<(300+((outputPosition.y+((outputWindowSize.y/2)*outputScale))*guiScale)) + ){ + outputSelectionPoint=ofPoint(x,y); + bOutputSelected=true; + } + } + +} + +//-------------------------------------------------------------- +void ofApp::outputMouseReleased(ofMouseEventArgs & args){ + select_warpframe=-1; + select_safetyframe=-1; +} + +void ofApp::mouseReleased(int x, int y, int button){ + if (bOutputSelected){ + if (commandPressed){ + outputScale*=outputOffsetScale; + } + else { + outputPosition+=outputOffset/guiScale; + } + bOutputSelected=false; + outputOffset=ofPoint(0,0); + outputOffsetScale=1.0f; + } + +} + +//-------------------------------------------------------------- +void ofApp::mouseEntered(int x, int y){ + +} + +//-------------------------------------------------------------- +void ofApp::mouseExited(int x, int y){ + +} + +//-------------------------------------------------------------- +void ofApp::outputWindowResized(ofResizeEventArgs &resizeargs){ + +} + +void ofApp::windowResized(int w, int h){ + +} + + + +//-------------------------------------------------------------- +void ofApp::dragEvent(ofDragInfo dragInfo){ + std::string filename=dragInfo.files[0]; + for (int i=0;i<4;i++){ + if (dragInfo.position.x>215&&dragInfo.position.x<540 + &&dragInfo.position.y>249*i+5&&dragInfo.position.y<249*i+249){ + ofLog()<<"slot "< imagepaths= svg.getPaths(); + + std::stringstream strm; + + if (imagepaths.size()){ + segmenters.clear(); + shape_selection_durations.clear(); + for (auto& path:imagepaths){ + path.setPolyWindingMode(OF_POLY_WINDING_ODD); + + vector outlines= path.getOutline(); + for (auto& outline:outlines){ + strm << outline.size() << "->"; + outline.simplify(contour_simplify); + strm << outline.size() << " "; + segmenters.push_back(colourLineSegmenter(outline,path.getStrokeColor())); + shape_selection_durations.push_back(0.0f); + } + + strm << " , "; + } + + std::stringstream strom; + + shape_selection.clear(); + while (shape_selection.size()<(segmenters.size()*shapes_amount)){ + int selection=(int)ofRandom(0,segmenters.size()); + shape_selection.insert(selection); + } + for (auto s:shape_selection){ + float spawn=(ofRandom(0,(float)shapes_duration)); + shape_selection_durations[s]=spawn; + strom << s << ":"<