• fullscreen
  • control.pde
  • controlPanel.pde
  • createFloor.pde
  • scanContainer.pde
  • scanViewer.pde
  • /*
     * Scene controls
     */
    
    void mouseDragged(){
      noCursor();
      rotX -= map(mouseY-pmouseY,-height,height,-TWO_PI,TWO_PI);
      rotY -= map(mouseX-pmouseX,-width,width,-TWO_PI,TWO_PI);
    }
    
    void mouseReleased(){
      cursor();
    }
    
    void keyPressed(){
      switch(keyCode){
        case UP:
          zoom *= 1.02;
          break;
        case DOWN:
          zoom /= 1.02;
          break;
        case LEFT:
          resolution++;
          if(resolution > 10){
            resolution = 10;
          }
          else{
            scan = new ScanContainer(scans[currentScan]);
            scan = scan.reduceResolution(resolution);
            backSide = scan.offsetScan(offsetDist);
          }
          break;
        case RIGHT:
          resolution--;
          if(resolution < 1){
            resolution = 1;
          }
          else{
            scan = new ScanContainer(scans[currentScan]);
            scan = scan.reduceResolution(resolution);
            backSide = scan.offsetScan(offsetDist);
          }
          break;
      }
      if(key == ' '){
        psychedelic = !psychedelic;
      }
      if(key == 'l'){
        asLines = !asLines;
        asPixels = false;
      }
      if(key == 'p'){
        asPixels = !asPixels;
        asLines = false;
      }
      if(key == '+'){
        pixelSize++;
        if(pixelSize > 3) pixelSize = 3;
      }
      if(key == '-'){
        pixelSize--;
        if(pixelSize < 1) pixelSize = 1;
      } 
    }
    
    
    /*
     * ControlP5 selection panel
     */
    
    void controlPanel(){
      cp5 = new ControlP5(this);
      cp5.addButton("scan0",0, 40,40,20,20).setCaptionLabel("");
      cp5.addButton("scan1",0, 70,40,20,20).setCaptionLabel("");
      cp5.addButton("scan2",0,100,40,20,20).setCaptionLabel("");
      cp5.addButton("scan3",0,130,40,20,20).setCaptionLabel("");
      cp5.addButton("scan4",0,160,40,20,20).setCaptionLabel("");
      cp5.addButton("scan5",0,190,40,20,20).setCaptionLabel("");
      cp5.setAutoDraw(false);
    }
    
    void controlEvent(ControlEvent event){
      if(event.isFrom("scan0")){
        currentScan = 0;
        scan = new ScanContainer(scans[currentScan]);
        backSide = scan.offsetScan(offsetDist);
        resolution = 1;
      }
      if(event.isFrom("scan1")){
        currentScan = 1;
        scan = new ScanContainer(scans[currentScan]);
        backSide = scan.offsetScan(offsetDist);
        resolution = 1;
      }
      if(event.isFrom("scan2")){
        currentScan = 2;
        scan = new ScanContainer(scans[currentScan]);
        backSide = scan.offsetScan(offsetDist);
        resolution = 1;
      }
      if(event.isFrom("scan3")){
        currentScan = 3;
        scan = new ScanContainer(scans[currentScan]);
        backSide = scan.offsetScan(offsetDist);
        resolution = 1;
      }
      if(event.isFrom("scan4")){
        currentScan = 4;
        scan = new ScanContainer(scans[currentScan]);
        backSide = scan.offsetScan(-offsetDist);
        resolution = 1;
      }
      if(event.isFrom("scan5")){
        currentScan = 5;
        scan = new ScanContainer(scans[currentScan]);
        backSide = scan.offsetScan(offsetDist);
        resolution = 1;
      }
    }
    
    
    /*
     * Creates an image with a color gradient in the direction of the y-axis
     */
    
    PImage createFloor(color backgroundColor){
      PImage img = createImage(width,height,RGB);
    
      img.loadPixels();
      for (int y = 0; y < height; y++){
        for (int x = 0; x < width; x++){
          int loc = x + y*width;
          float gradientR = map(y,0,height,red(backgroundColor),40);
          float gradientG = map(y,0,height,green(backgroundColor),40);
          float gradientB = map(y,0,height,blue(backgroundColor),40);
          img.pixels[loc] = color(gradientR-15*y/height,gradientG-15*y/height,gradientB);
        }
      }
      img.updatePixels();
      
      return img;
    }
    
    
    /*
     * ScanContainer class.
     */
    
    class ScanContainer{
      int xSize;          // Hozizontal dimension
      int ySize;          // Vertical dimension
      int nPoints;        // Number of points
      PVector[] map3D;    // 3D points
      PImage rgbImg;      // Point colors 
      boolean[] consImg;  // Valid points 
      int[] ini;          // Start of the valid points (in the line)
      int[] end;          // End of the valid points (in the line)
      boolean[] empty;    // No valid points in the line
      
      
      //
      // Constructor
      //
    
      ScanContainer(String tempFile){
        String[] pointsAndColors = loadStrings(tempFile);
        String[] header = split(pointsAndColors[0]," ");
    
        xSize = int(header[0]);
        ySize = int(header[1]);
        nPoints = xSize*ySize;
        map3D = new PVector[nPoints];
        rgbImg = createImage(xSize,ySize,RGB); 
        consImg = new boolean[nPoints]; 
        ini = new int[ySize];
        end = new int[ySize];
        empty = new boolean[ySize];
      
        // Populate the arrays
        rgbImg.loadPixels();
        for(int i = 0; i < nPoints; i++){
          String[] row = split(pointsAndColors[i+1]," ");
          map3D[i] = new PVector(float(row[0]),float(row[1]),float(row[2]));
          if(float(row[3]) < 0){
            rgbImg.pixels[i] = color(0);
            consImg[i] = false;
          }
          else{
            rgbImg.pixels[i] = color(float(row[3]),float(row[4]),float(row[5]));
            consImg[i] = true;
          }
        }
        rgbImg.updatePixels();
    
        // Find the extremes
        for(int y = 0; y < ySize; y++){
          ini[y] = -1;
          end[y] = -1;
          empty[y] = true;
          for(int x = 0; x < xSize; x++){
            int index = x + y*xSize;
            if(consImg[index]){
              if(ini[y] < 0){
                ini[y] = x;
              }
              end[y] = x;
              empty[y] = false;
            }
          }
        }
      }
      
      
      ScanContainer(PVector[] tempMap3D, PImage tempRGBimg, boolean[] tempConsImg){
        xSize = tempRGBimg.width;
        ySize = tempRGBimg.height;
        nPoints = xSize*ySize;
        map3D = new PVector[nPoints];
        rgbImg = createImage(xSize,ySize,RGB); 
        consImg = new boolean[nPoints]; 
        ini = new int[ySize];
        end = new int[ySize];
        empty = new boolean[ySize];
      
        // Populate the arrays
        rgbImg.loadPixels();
        tempRGBimg.loadPixels();
        for(int i = 0; i < nPoints; i++){
          map3D[i] = tempMap3D[i].get();
          rgbImg.pixels[i] = tempRGBimg.pixels[i];
          consImg[i] = tempConsImg[i];
        }
        rgbImg.updatePixels();
    
        // Find the extremes
        for(int y = 0; y < ySize; y++){
          ini[y] = -1;
          end[y] = -1;
          empty[y] = true;
          for(int x = 0; x < xSize; x++){
            int index = x + y*xSize;
            if(consImg[index]){
              if(ini[y] < 0){
                ini[y] = x;
              }
              end[y] = x;
              empty[y] = false;
            }
          }
        }
      }  
      
    
      ScanContainer(ScanContainer tempScan){
        this(tempScan.map3D,tempScan.rgbImg,tempScan.consImg);
      }
      
      
      //
      // Class Methods 
      //
    
      // fillHoles
      void fillHoles(){
        rgbImg.loadPixels();
        for(int y = 0; y < ySize; y++){
          if(!empty[y]){
            int start = 0;
            int finish = 0;
            for(int x = ini[y]+1; x < end[y]; x++){
              int index = x + y*xSize;
              if(!consImg[index]){
                // Calculate the limits of the hole
                if(index > finish){
                  start = index-1;
                  for(int i = x+1; i <= end[y]; i++){
                    int iterIndex = i + y*xSize;
                    if(consImg[iterIndex]){
                      finish = iterIndex;
                      break;
                    }
                  }
                }
                // Fill the hole if the gap is not too big
                if(finish-start < 4){ 
                  PVector deltaPos = PVector.sub(map3D[finish],map3D[start]);
                  float deltaR = (red(rgbImg.pixels[finish])-red(rgbImg.pixels[start]));
                  float deltaG = (green(rgbImg.pixels[finish])-green(rgbImg.pixels[start]));
                  float deltaB = (blue(rgbImg.pixels[finish])-blue(rgbImg.pixels[start]));
    
                  float step = float(index-start)/float(finish-start);
                  deltaPos.mult(step);
                  deltaR = deltaR*step;
                  deltaG = deltaG*step;
                  deltaB = deltaB*step;
                  
                  map3D[index] = PVector.add(map3D[start],deltaPos);
                  rgbImg.pixels[index] = color(red(rgbImg.pixels[start])+deltaR,green(rgbImg.pixels[start])+deltaG,blue(rgbImg.pixels[start])+deltaB);
                  consImg[index] = true;
                }
              } 
            }    
          }
        }
        rgbImg.updatePixels();
      }
    
    
      // gaussianSmooth
      ScanContainer gaussianSmooth(int n){
        if(n > 0){
          // Create the gaussian mask
          float[][] m = new float[2*n+1][2*n+1];
          for(int i = -n; i <= n; i++){
            for(int j = -n; j <= n; j++){
              float distSq = sq(i)+sq(j);
              if(distSq <= sq(n)){
                m[i+n][j+n] = pow(2.718,-distSq/(2*sq(n/2)));
              }
              else{
                m[i+n][j+n] = 0;
              }
            }
          }
    
          // Create the array for the smoothed 3Dpoints
          PVector[] smMap3D = new PVector[nPoints];
    
          // Populate the array
          for(int y = 0; y < ySize; y++){
            for(int x = 0; x < xSize; x++){
              int index = x + y*xSize;
              if(consImg[index]){
                // Average between nearby pixels
                PVector p = new PVector(0,0,0);
                float multCounter = 0;
                for(int i = -n; i <= n; i++){
                  for(int j = -n; j <= n; j++){
                    int xNearby = x+i;
                    int yNearby = y+j;
                    if(xNearby >=0 && xNearby < xSize && yNearby >= 0 && yNearby < ySize){
                      int indexNearby = xNearby + yNearby*xSize;
                      if(consImg[indexNearby]){
                        p.add(PVector.mult(map3D[indexNearby],m[i+n][j+n]));
                        multCounter += m[i+n][j+n];
                      }
                    }
                  }
                }
                if(multCounter > 0){
                  p.div(multCounter);
                  smMap3D[index] = p.get();
                }
                else{
                  smMap3D[index] = map3D[index].get();
                }
              }
              else{
                smMap3D[index] = map3D[index].get();
              }
            }
          }
          return new ScanContainer(smMap3D,rgbImg,consImg);
        }
        else{
          return this;
        }
      }
    
    
      // reduceResolution
      ScanContainer reduceResolution(int n){
        if(n > 1){
          // Dimensions of the reduced scan
          int xSizeRed = xSize/n;
          int ySizeRed = ySize/n;
          int nPointsRed = xSizeRed*ySizeRed;
          PVector[] redMap3D = new PVector[nPointsRed];
          PImage redRGBimg = createImage(xSizeRed,ySizeRed,RGB);
          boolean[] redConsImg = new boolean[nPointsRed]; 
    
          // Populate the arrays
          redRGBimg.loadPixels();
          rgbImg.loadPixels();
          for(int y = 0; y < ySizeRed; y++){
            for(int x = 0; x < xSizeRed; x++){
              int index = x*n + y*n*xSize;
              int indexRed = x + y*xSizeRed;
              
              // Average between nearby pixels
              PVector p = new PVector(0,0,0);
              float r = 0;
              float g = 0;
              float b = 0;
              float pointsCounter = 0;
              for(int i = -n/2; i <= n/2; i++){
                for(int j = -n/2; j <= n/2; j++){
                  int xNearby = (x*n)+i;
                  int yNearby = (y*n)+j;
                  if(xNearby >=0 && xNearby < xSize && yNearby >= 0 && yNearby < ySize){
                    int indexNearby = xNearby + yNearby*xSize;
                    if(consImg[indexNearby]){
                      p.add(map3D[indexNearby]);
                      r += red(rgbImg.pixels[indexNearby]);
                      g += green(rgbImg.pixels[indexNearby]);
                      b += blue(rgbImg.pixels[indexNearby]);
                      pointsCounter++;
                    }
                  }
                }
              }
              if(pointsCounter > 0){
                p.div(pointsCounter);
                r = r/pointsCounter;
                g = g/pointsCounter;
                b = b/pointsCounter;
    
                redMap3D[indexRed] = p.get();
                redRGBimg.pixels[indexRed] = color(r,g,b);
                redConsImg[indexRed] = true;
              }
              else{
                redMap3D[indexRed] = map3D[index].get();
                redRGBimg.pixels[indexRed] = rgbImg.pixels[index];
                redConsImg[indexRed] = consImg[index];
              }
            }
          }
          redRGBimg.updatePixels();
        
          return new ScanContainer(redMap3D,redRGBimg,redConsImg);
        }
        else{
          return this;
        }
      }
    
      
      // offsetScan
      ScanContainer offsetScan(float offset){
        // Create the arrays for the offset scan
        PVector[] offMap3D = new PVector[nPoints];
        PImage offRGBimg = createImage(xSize,ySize,RGB);
        boolean[] offConsImg = new boolean[nPoints];
    
        // Populate the arrays
        offRGBimg.loadPixels();
        for(int y = 0; y < ySize; y++){
          for(int x = 0; x < xSize; x++){
            int index = x + y*xSize;
            if(x-1 >= 0 && y-1 >= 0 && x+1 < xSize && y+1 < ySize && 
               consImg[index] && consImg[index+1] && consImg[index-1] && consImg[index+xSize] && consImg[index-xSize]){
              PVector v1 = PVector.sub(map3D[index+1],map3D[index]);
              PVector v2 = PVector.sub(map3D[index+xSize],map3D[index]);
              PVector v3 = PVector.sub(map3D[index-1],map3D[index]);
              PVector v4 = PVector.sub(map3D[index-xSize],map3D[index]);
              PVector perp1 = v2.cross(v1);
              PVector perp2 = v3.cross(v2);
              PVector perp3 = v4.cross(v3);
              PVector perp4 = v1.cross(v4);
              perp1.normalize();
              perp2.normalize();
              perp3.normalize();
              perp4.normalize();
              PVector perp = PVector.add(perp1,perp2);
              perp.add(perp3);
              perp.add(perp4);
              perp.mult(offset/4);
              offMap3D[index] = PVector.add(map3D[index],perp);
              offRGBimg.pixels[index] = 255;
              offConsImg[index] = true;
            }
            else{
              offMap3D[index] = map3D[index].get();
              offRGBimg.pixels[index] = 255;
              offConsImg[index] = consImg[index];
            }
          }
        }
        offRGBimg.updatePixels();
        
        return new ScanContainer(offMap3D,offRGBimg,offConsImg);
      }
    
    
      // drawAsPixels
      void drawAsPixels(int pSize){
        strokeWeight(pSize);
        rgbImg.loadPixels();
        for(int y = 0; y < ySize; y++){
          if(!empty[y]){
            for(int x = ini[y]; x <= end[y]; x++){
              int index = x + y*xSize;
              if(consImg[index]){
                stroke(rgbImg.pixels[index]);
                point(map3D[index].x,map3D[index].y,map3D[index].z);
              }
            }
          }  
        }
        noStroke();
      }
      
      
      // drawAsTriangles
      void drawAsTriangles(){
        float maxSep = 90;  // Maximum separation allowed between two consecutive points
    
        noStroke();
        rgbImg.loadPixels();
        for(int y = 0; y < ySize-1; y++){
          if(!empty[y] && !empty[y+1]){
            int xStart = min(ini[y],ini[y+1]);
            int xEnd = max(end[y],end[y+1]);
            for(int x = xStart; x < xEnd; x++){
              int index = x + y*xSize;
              // First triangle
              if(consImg[index] && consImg[index+1] && consImg[index+xSize]){
                PVector p1 = map3D[index].get();
                PVector p2 = map3D[index+1].get();
                PVector p3 = map3D[index+xSize].get();
                float dist1 = p1.dist(p2);
                float dist2 = p1.dist(p3);
                float dist3 = p2.dist(p3);
                boolean cond = (dist1 < maxSep) && (dist2 < maxSep) && (dist3 < maxSep) &&
                               (dist1 != 0) && (dist2 != 0) && (dist3 != 0);
                if(cond){
                  beginShape(TRIANGLES);
                    fill(rgbImg.pixels[index]);
                    vertex(p1.x,p1.y,p1.z);
                    fill(rgbImg.pixels[index+1]);
                    vertex(p2.x,p2.y,p2.z);
                    fill(rgbImg.pixels[index+xSize]);
                    vertex(p3.x,p3.y,p3.z);
                  endShape(); 
                }
              }
              else if(consImg[index] && consImg[index+1+xSize] && consImg[index+xSize]){
                PVector p1 = map3D[index].get();
                PVector p2 = map3D[index+1+xSize].get();
                PVector p3 = map3D[index+xSize].get();
                float dist1 = p1.dist(p2);
                float dist2 = p1.dist(p3);
                float dist3 = p2.dist(p3);
                boolean cond = (dist1 < maxSep) && (dist2 < maxSep) && (dist3 < maxSep) &&
                               (dist1 != 0) && (dist2 != 0) && (dist3 != 0);
                if(cond){
                  beginShape(TRIANGLES);
                    fill(rgbImg.pixels[index]);
                    vertex(p1.x,p1.y,p1.z);
                    fill(rgbImg.pixels[index+1+xSize]);
                    vertex(p2.x,p2.y,p2.z);
                    fill(rgbImg.pixels[index+xSize]);
                    vertex(p3.x,p3.y,p3.z);
                  endShape(); 
                }
              }
              // Second triangle
              if(consImg[index+1] && consImg[index+1+xSize] && consImg[index+xSize]){
                PVector p1 = map3D[index+1].get();
                PVector p2 = map3D[index+1+xSize].get();
                PVector p3 = map3D[index+xSize].get();
                float dist1 = p1.dist(p2);
                float dist2 = p1.dist(p3);
                float dist3 = p2.dist(p3);
                boolean cond = (dist1 < maxSep) && (dist2 < maxSep) && (dist3 < maxSep) &&
                               (dist1 != 0) && (dist2 != 0) && (dist3 != 0);
                if(cond){
                  beginShape(TRIANGLES);
                    fill(rgbImg.pixels[index+1]);
                    vertex(p1.x,p1.y,p1.z);
                    fill(rgbImg.pixels[index+1+xSize]);
                    vertex(p2.x,p2.y,p2.z);
                    fill(rgbImg.pixels[index+xSize]);
                    vertex(p3.x,p3.y,p3.z);
                  endShape();
                } 
              }
              else if(consImg[index] && consImg[index+1] && consImg[index+1+xSize]){
                PVector p1 = map3D[index].get();
                PVector p2 = map3D[index+1].get();
                PVector p3 = map3D[index+1+xSize].get();
                float dist1 = p1.dist(p2);
                float dist2 = p1.dist(p3);
                float dist3 = p2.dist(p3);
                boolean cond = (dist1 < maxSep) && (dist2 < maxSep) && (dist3 < maxSep) &&
                               (dist1 != 0) && (dist2 != 0) && (dist3 != 0);
                if(cond){
                  beginShape(TRIANGLES);
                    fill(rgbImg.pixels[index]);
                    vertex(p1.x,p1.y,p1.z);
                    fill(rgbImg.pixels[index+1]);
                    vertex(p2.x,p2.y,p2.z);
                    fill(rgbImg.pixels[index+1+xSize]);
                    vertex(p3.x,p3.y,p3.z);
                  endShape();
                } 
              }
            }
          }
        }
      }
    
    
      // drawAsPsyTriangles
      void drawAsPsyTriangles(){
        float maxSep = 90;  // Maximum separation allowed between two consecutive points
    
        noStroke();
        rgbImg.loadPixels();
        for(int y = 0; y < ySize-1; y++){
          if(!empty[y] && !empty[y+1]){
            int xStart = min(ini[y],ini[y+1]);
            int xEnd = max(end[y],end[y+1]);
            for(int x = xStart; x < xEnd; x++){
              int index = x + y*xSize;
              // First triangle
              if(consImg[index] && consImg[index+1] && consImg[index+xSize]){
                PVector p1 = map3D[index].get();
                PVector p2 = map3D[index+1].get();
                PVector p3 = map3D[index+xSize].get();
                float dist1 = p1.dist(p2);
                float dist2 = p1.dist(p3);
                float dist3 = p2.dist(p3);
                boolean cond = (dist1 < maxSep) && (dist2 < maxSep) && (dist3 < maxSep) &&
                               (dist1 != 0) && (dist2 != 0) && (dist3 != 0);
                if(cond){
                  beginShape(TRIANGLES);
                    fill(blendColor(rgbImg.pixels[index],color(random(-150,150),random(-150,150),0),ADD));
                    vertex(p1.x,p1.y,p1.z);
                    vertex(p2.x,p2.y,p2.z);
                    vertex(p3.x,p3.y,p3.z);
                  endShape(); 
                }
              }
              else if(consImg[index] && consImg[index+1+xSize] && consImg[index+xSize]){
                PVector p1 = map3D[index].get();
                PVector p2 = map3D[index+1+xSize].get();
                PVector p3 = map3D[index+xSize].get();
                float dist1 = p1.dist(p2);
                float dist2 = p1.dist(p3);
                float dist3 = p2.dist(p3);
                boolean cond = (dist1 < maxSep) && (dist2 < maxSep) && (dist3 < maxSep) &&
                               (dist1 != 0) && (dist2 != 0) && (dist3 != 0);
                if(cond){
                  beginShape(TRIANGLES);
                    fill(blendColor(rgbImg.pixels[index],color(random(-150,150),random(-150,150),0),ADD));
                    vertex(p1.x,p1.y,p1.z);
                    vertex(p2.x,p2.y,p2.z);
                    vertex(p3.x,p3.y,p3.z);
                  endShape(); 
                }
              }
              // Second triangle
              if(consImg[index+1] && consImg[index+1+xSize] && consImg[index+xSize]){
                PVector p1 = map3D[index+1].get();
                PVector p2 = map3D[index+1+xSize].get();
                PVector p3 = map3D[index+xSize].get();
                float dist1 = p1.dist(p2);
                float dist2 = p1.dist(p3);
                float dist3 = p2.dist(p3);
                boolean cond = (dist1 < maxSep) && (dist2 < maxSep) && (dist3 < maxSep) &&
                               (dist1 != 0) && (dist2 != 0) && (dist3 != 0);
                if(cond){
                  beginShape(TRIANGLES);
                    fill(blendColor(rgbImg.pixels[index+1],color(random(-150,150),random(-150,150),0),ADD));
                    vertex(p1.x,p1.y,p1.z);
                    vertex(p2.x,p2.y,p2.z);
                    vertex(p3.x,p3.y,p3.z);
                  endShape(); 
                }
              }
              else if(consImg[index] && consImg[index+1] && consImg[index+1+xSize]){
                PVector p1 = map3D[index].get();
                PVector p2 = map3D[index+1].get();
                PVector p3 = map3D[index+1+xSize].get();
                float dist1 = p1.dist(p2);
                float dist2 = p1.dist(p3);
                float dist3 = p2.dist(p3);
                boolean cond = (dist1 < maxSep) && (dist2 < maxSep) && (dist3 < maxSep) &&
                               (dist1 != 0) && (dist2 != 0) && (dist3 != 0);
                if(cond){
                  beginShape(TRIANGLES);
                    fill(blendColor(rgbImg.pixels[index+1],color(random(-150,150),random(-150,150),0),ADD));
                    vertex(p1.x,p1.y,p1.z);
                    vertex(p2.x,p2.y,p2.z);
                    vertex(p3.x,p3.y,p3.z);
                  endShape();
                } 
              }
            }
          }
        }
      }
      
      
      // drawAsLines
      void drawAsLines(){
        float maxSep = 90;  // Maximum separation allowed between two consecutive points
    
        rgbImg.loadPixels();
        for(int y = 0; y < ySize; y++){
          if(!empty[y]){
            for(int x = ini[y]; x <= end[y]; x++){
              int index = x + y*xSize;
              if(x+1 < xSize && consImg[index] && consImg[index+1] && map3D[index].dist(map3D[index+1]) < maxSep){
                stroke(rgbImg.pixels[index]);
                line(map3D[index].x,map3D[index].y,map3D[index].z,map3D[index+1].x,map3D[index+1].y,map3D[index+1].z);
              }
              if(y+1 < ySize && consImg[index] && consImg[index+xSize] && map3D[index].dist(map3D[index+xSize]) < maxSep){
                stroke(rgbImg.pixels[index]);
                line(map3D[index].x,map3D[index].y,map3D[index].z,map3D[index+xSize].x,map3D[index+xSize].y,map3D[index+xSize].z);
              }
              if(x+1 < xSize && y+1 < ySize && consImg[index] && consImg[index+1+xSize] && map3D[index].dist(map3D[index+1+xSize]) < maxSep){
                stroke(rgbImg.pixels[index]);
                line(map3D[index].x,map3D[index].y,map3D[index].z,map3D[index+1+xSize].x,map3D[index+1+xSize].y,map3D[index+1+xSize].z);
              }
            }
          }
        }
        noStroke();
      }
    
    }
    
    /* 
     * Scan viewer (JGC, version 3).
     *
     * Description: Reads and draws scans obtained with the Kinect 3D scanner.
     *   http://www.openprocessing.org/sketch/78606
     * 
     * Controls:
     *   - Use the mouse to rotate the scan
     *   - Use "Up" and "Down" arrows to zoom
     *   - Use "Left" and "Right" arrows to decrease/increase the scan resolution
     *   - 'p' switchs between the mesh view and the pixels view
     *   - 'l' switchs between the mesh view and the lines view
     *   - "+" and "-" increase/decrease the pixel size (only in pixel view)
     *   - 'Space' creates some psychedelic effects (only in mesh view) 
     */
    
    import controlP5.*;
    
    String[] files = {"scan1.points","scan2.points","scan3.points","scan4.points","scan-slit1.points","scan-slit2.points"};
    ScanContainer[] scans = new ScanContainer[files.length];
    ScanContainer scan, backSide;
    int currentScan = 0;
    int resolution = 1;
    int pixelSize = 1;
    float offsetDist = 0.1; 
    boolean asPixels = false;
    boolean asLines = false;
    boolean psychedelic = false;
    
    ControlP5 cp5;
    PImage fakeFloor;
    
    float zoom = 1;
    float rotX = PI;
    float rotY = 0;
    
    void setup(){
      size(700,550,P3D);
      
      // Read the scans
      for(int i = 0; i < scans.length; i++){
        ScanContainer s = new ScanContainer(files[i]);
        s = s.reduceResolution(resolution);
        s.fillHoles();
        s = s.gaussianSmooth(5);
        scans[i] = s;
      }
     
      // Start with the first scan as default 
      currentScan = 0;
      scan = new ScanContainer(scans[currentScan]);
      backSide = scan.offsetScan(offsetDist);
      
      // Create an image to represent the floor
      fakeFloor = createFloor(color(200));
    
      // Initialize ControlP5
      controlPanel();
    }
    
    void draw(){
      background(200);
      
      // Draw the floor image in an inclined plane
      noStroke();
      beginShape();
        texture(fakeFloor);
        vertex(-width,0.75*height,-300,0,0);
        vertex(2*width,0.75*height,-300,width,0);
        vertex(width,height,0,width,height);
        vertex(0,height,0,0,height);
      endShape();
    
      // Draw the control panel
      cp5.draw();
    
      // Position the scene
      translate(width/2,height/2,0);
      rotateX(rotX);
      rotateY(rotY);
      scale(zoom);
      
      // Draw the scan
      if(asPixels){
        scan.drawAsPixels(pixelSize);
      }
      else if(asLines){
        scan.drawAsLines();
      }
      else if(psychedelic){
        scan.drawAsPsyTriangles();
        lights();
        backSide.drawAsTriangles();
      }
      else{
        scan.drawAsTriangles();
        lights();
        backSide.drawAsTriangles();
      }
    }
    
    

    code

    tweaks (0)

    about this sketch

    This sketch is running as Java applet, exported from Processing.

    license

    advertisement

    Javier Graciá Carpio

    Scan Viewer 2.0

    Add to Faves Me Likey@! 5
    You must login/register to add this sketch to your favorites.

    Reads and draws various scans obtained with the Kinect 3D scanner:
    http://www.openprocessing.org/sketch/78606

    This video shows more examples:
    https://vimeo.com/54903115

    Controls:
    - Use the mouse to rotate the scan
    - Use "Up" and "Down" arrows to zoom
    - Use "Left" and "Right" arrows to decrease/increase the scan resolution
    - 'p' switchs between the mesh view and the pixels view
    - 'l' switchs between the mesh view and the lines view
    - "+" and "-" increase/decrease the pixel size (only in pixel view)
    - 'Space' creates some psychedelic effects (only in mesh view)

    You need to login/register to comment.