//***************************************************************************** // Polyloop editor + Js refinement, Jarek Rossignac, Feb 2007 //***************************************************************************** //import processing.opengl.*; // comment out if not using OpenGL color red = color(255,0,0), yellow= color(255,255,0), green= color(0,255,0), cyan= color(0,255,255), blue= color(0,0,255), magenta= color(255,0,255), dred = color(125,0,0), dyellow= color(125,125,0), dgreen= color(0,125,0), dcyan= color(0,125,125), dblue= color(0,0,125), dmagenta= color(125,0,125), grey =color(200,200,200), black=color(0,0,0); Polyloop C = new Polyloop(), R = new Polyloop(), U = new Polyloop(), S = new Polyloop(); // control, retrofit, and subdivided polyloops Polyloop [] CC = new Polyloop[10]; pt pmouse = new pt(0,0); // remembers where mouse was pressed for translations pt closest = new pt(0,0); // tracks closest point on control polyloop boolean showHelpText=true, showMenu=true, showVertexIds=false, showVertices=true, showAll=false, showJspline=false, fillCurve=false, openLoop=false, showControl=true, showResampled=true, animating=false; String [] fn= {"C0.pts","C1.pts","C2.pts","C3.pts","C4.pts","C5.pts","C6.pts","C7.pts"}; // names of files with control loops int fni=0; // pointer to the next file to load String lastRead=fn[fni]; float Carea=0, Clength=0, Sarea=0, Slength=0; float nrv=150; // number of vertices on resampled curve U boolean debug=false; boolean ctrl=false; // CONTROL is pressed boolean showCorrections=true; int predict = 1; void setup() { size(1100, 800, P3D); PFont font = loadFont("Courier-14.vlw"); textFont(font, 12); for(int i=0; i<10; i++) { CC[i] = new Polyloop(); CC[i].reset(6); CC[i].barycenter(); CC[i].scaleByG(0.2); CC[i].translateBy(new vec(height*0.4*cos(TWO_PI*i/10+PI),height*0.4*sin(TWO_PI*i/10+PI))); }; C.reset(20); // makes control loop of 6 vertices in a circle loadButtons(); loadToggles(); this.addMouseWheelListener(new CMouseWheelEvent()); initTP(); // declares points for capturing sphereDetail(6); } void draw() { background(255); strokeWeight(2); noFill(); if (showHelpText) { showHelp(); showColors(); return; }; // if (showTerrain) { pushMatrix(); showTerrain(); translate(0,0,10); noFill(); stroke(red); C.drawCurve(); popMatrix(); return; }; if (capturing) {if(mousePressed&&mouseIsInWindow()) addTP(); stroke(dgreen); drawTP();} else { if ((mousePressed)&&(mouse().isInWindow())&&(keyPressed)) { if (key=='t') C.translateBy(new vec(mouseX-pmouseX,mouseY-pmouseY )); if ((key=='e')||(keyCode==CONTROL)) {C.barycenter(); C.move(new pt(pmouseX,pmouseY), new vec(mouseX-pmouseX,mouseY-pmouseY));}; if (key=='z') C.scaleBy( C.P[C.p].disTo(mouse()) / C.P[C.p].disTo(pmouse()) ); if (key=='Z') C.scaleByG( C.P[C.p].disTo(mouse()) / C.P[C.p].disTo(pmouse()) ); if (key=='r') C.rotateBy( angle( C.P[C.p].makeVecTo(mouse()) , C.P[C.p].makeVecTo(pmouse()) ) ); if (key=='R') C.rotateByG( angle( C.G.makeVecTo(mouse()) , C.G.makeVecTo(pmouse()) ) ); if (key=='a') C.dragVertex(pmouse().makeVecTo(mouse())); if (key=='q') {C.dragVertex(pmouse().makeVecTo(mouse())); for(int i=0; i<10; i++) {C.computeL2(); C.applyLaround(150);};}; } else { if ((mousePressed)&&(mouse().isInWindow())&&(!keyPressed)) {C.dragVertex(pmouse().makeVecTo(mouse()));} else if ((!mousePressed)&&(mouse().isInWindow())&&(keyPressed)) { if (key=='S') {C.pickClosestVertex(mouse()); C.computeL(); C.applyLhere(150);}; if (key=='s') {C.pickClosestVertex(mouse()); C.computeL2(); C.applyLhere(150);}; }; }; if(showAll) { for (int i=0; i<10; i++) {S.setTo(CC[i]); stroke(dyellow,70); S.drawCurve(); S.loadRing(); S.deriveRings(); S.showRefined(); }; }; if(showControl) { stroke(dblue); strokeWeight(3); C.drawCurve(); strokeWeight(1); if( showVertices) C.drawVertices(); // C.barycenter().showCross(5); fill(red); C.P[C.p].show(4); noFill(); noStroke(); closest=C.project(mouse()); fill(green); closest.show(2); noFill(); if (showVertexIds) {fill(dblue); C.drawVertexIDs(); noFill();}; if (C.contains(mouse())) fill(dyellow); else fill(cyan); mouse().show(5); noFill(); }; if (showCorrections) { float m; pushMatrix(); fill(black); float e = C.averageEdgeLength(); for (int i=1; i<10; i++) { m=C.computeCorrections(i); translate(0,20); text("P"+i+": error = "+Format(m*100/e,1,4)+" %",20,0); }; translate(0,20); text("Displaying P"+predict,20,0); popMatrix(); noFill(); m=C.computeCorrections(predict); stroke(dred); C.showLarrow(); }; if(showMenu) { Buttons.show(); Toggles.show(); pushMatrix(); translate(width-290,Buttons.depth()); text("Demo of predictors",0,0); translate(0,20); text("built in Processing by Jarek Rossignac",0,0); translate(0,20); text("last file read: "+lastRead,0,0); translate(0,20); if (!openLoop) { text("Area:"+Format(abs(Carea/height/height),1,3),0,0); translate(0,20);}; text("Length:"+Format(Clength/height,1,3),0,0); translate(0,20); popMatrix(); } } } void loadButtons() { Buttons.add(new button("s",-2,_gs,2,0.01,0.125)); Buttons.add(new button("resample pts",0,nrv,500,1,10)); Buttons.add(new button("predictor",1,predict,9,1,9)); } void loadToggles() { Toggles.add(new toggle(" show vertrex IDs",showVertexIds)); Toggles.add(new toggle(" show vertrices",showVertices)); Toggles.add(new toggle(" fill curve",fillCurve)); Toggles.add(new toggle(" open loop",openLoop)); Toggles.add(new toggle(" reset to 4 points",false)); Toggles.add(new toggle(" load a new curve",false)); Toggles.add(new toggle(" align with axes",false)); Toggles.add(new toggle(" fit to window",false)); Toggles.add(new toggle(" shift labels",false)); Toggles.add(new toggle(" coarsen",false)); Toggles.add(new toggle(" dual",false)); Toggles.add(new toggle(" smooth curve",false)); Toggles.add(new toggle(" split all edges",false)); Toggles.add(new toggle(" subdivide(s)",false)); Toggles.add(new toggle(" resample",false)); Toggles.add(new toggle(" corrections",showCorrections)); } void mousePressed() { int k= Buttons.click(); int m=-1; if(k==++m) _gs=Buttons.v(m); if(k==++m) nrv=Buttons.v(m); if(k==++m) predict=int(Buttons.v(m)); k= Toggles.click(); m=-1; if(k==++m) showVertexIds=Toggles.v(m); if(k==++m) showVertices=Toggles.v(m); if(k==++m) fillCurve =Toggles.v(m); if(k==++m) {openLoop =Toggles.v(m); if(openLoop) C.openLoop(); else C.closeLoop(); }; if(k==++m) {Toggles.B[m].V=false; C.reset(4); if(openLoop) C.openLoop(); }; if(k==++m) {Toggles.B[m].V=false; {C.closeLoop(); lastRead=fn[fni]; C.loadPts(fn[fni++]); if(fni==fn.length) fni=0;}; openLoop=false; Toggles.B[6].V=openLoop; }; if(k==++m) {Toggles.B[m].V=false; C.align(); }; if(k==++m) {Toggles.B[m].V=false; C.frame();}; if(k==++m) {Toggles.B[m].V=false; C.shiftIDs();}; if(k==++m) {Toggles.B[m].V=false; C.coarsen();}; if(k==++m) {Toggles.B[m].V=false; C.dual();}; if(k==++m) {Toggles.B[m].V=false; C.computeL(); C.applyL();}; if(k==++m) {Toggles.B[m].V=false; C.refine();}; if(k==++m) {Toggles.B[m].V=false; C.refine(_gs);}; if(k==++m) {Toggles.B[m].V=false; S.setAsRefined(C); C.setAsResampled(S,int(nrv)); }; if(k==++m) showCorrections=Toggles.v(m); pmouse=mouse(); if (mouse().isInWindow()) { if (!keyPressed) C.pickClosestVertex(mouse()); else { if (key=='q') C.pickClosestVertex(mouse()); if (key=='a') C.grabInsert(mouse()); if (key=='d') { C.pickClosestVertex(mouse()); C.delete();} } } if(openLoop) C.adjustOpenEnds(); } void mouseReleased() {if (capturing) {copyTP(); capturing=false;};} void keyReleased() {ctrl=false; }; void keyPressed() { if (key=='1') C.setTo(CC[1]); if (key=='2') C.setTo(CC[2]); if (key=='3') C.setTo(CC[3]); if (key=='4') C.setTo(CC[4]); if (key=='5') C.setTo(CC[5]); if (key=='6') C.setTo(CC[6]); if (key=='7') C.setTo(CC[7]); if (key=='8') C.setTo(CC[8]); if (key=='9') C.setTo(CC[9]); if (key=='0') C.setTo(CC[0]); if (key=='!') CC[1].setTo(C); if (key=='@') CC[2].setTo(C); if (key=='#') CC[3].setTo(C); if (key=='$') CC[4].setTo(C); if (key=='%') CC[5].setTo(C); if (key=='^') CC[6].setTo(C); if (key=='&') CC[7].setTo(C); if (key=='*') CC[8].setTo(C); if (key=='*') CC[9].setTo(C); if (key==')') CC[0].setTo(C); if (key==' ') showHelpText=!showHelpText ; if (key=='M') showMenu=!showMenu; if (key=='W') {C.savePts(); fni=0;} if (key=='G') {C.loadPts(); fni=0;} if (key=='X') {String S=" "+"-####.tif"; saveFrame(S);}; ; if (key=='f') C.frame(); if (key=='+') C.align(); if (key=='c') {resetTP(); capturing=true; }; };