Package ShapePacking

Source Code of ShapePacking.spPage

/*******************************************************************************
* This is part of SketchChair, an open-source tool for designing your own furniture.
*     www.sketchchair.cc
*    
*     Copyright (C) 2012, Diatom Studio ltd.  Contact: hello@diatom.cc
*
*     This program is free software: you can redistribute it and/or modify
*     it under the terms of the GNU General Public License as published by
*     the Free Software Foundation, either version 3 of the License, or
*     (at your option) any later version.
*
*     This program is distributed in the hope that it will be useful,
*     but WITHOUT ANY WARRANTY; without even the implied warranty of
*     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*     GNU General Public License for more details.
*
*     You should have received a copy of the GNU General Public License
*     along with this program.  If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package ShapePacking;

import nu.xom.Attribute;
import nu.xom.Element;
import cc.sketchchair.core.LOGGER;
import ToolPathWriter.CraftRoboWriter;
import ToolPathWriter.DXFWriter;
import ToolPathWriter.HPGLWriter;
import processing.core.PGraphics;

/**
* Represents a single page in a multipage cutting file. Holds spOutlines.
* @author gregsaul
*
*/
public class spPage {
  spShapePack shapePack;
  spShapes shapes = new spShapes();
  float yPos  = 0;
  float xPos  = 0;
  float lastHeight  = 0;
  int tilePackCount = 0;
 
  public void packSmart(spShapes packingShapes) {
    LOGGER.info("packSmart");

    float lineWidth = 0;
    float lineHeight = 0;
    float tallestOnLine = 0;
    float gap = shapePack.shapeGap;
    float xPos = gap;
    float yPos = gap;
    float pageBorder = 10;
    float step = 5*shapePack.scale;
    boolean  ignorePageBounds = false;
   
    //Lets smart pack everything
    //we could start by ordering parts from large to small but it shouldn't be necessary
   
    for (int i = 0; i < packingShapes.l.size(); i++) {
      spShape shape = (spShape) packingShapes.l.get(i);
      spShape shapeCopy = shape.clone();
      shape.translate(-shape.outlines.getMinX(), -shape.outlines.getMinY());
   
      ignorePageBounds = false;
      if(shapeCopy.width >= (this.shapePack.materialWidth-(pageBorder*2)) && shapeCopy.height >= this.shapePack.materialHeight-(pageBorder*2)){
        ignorePageBounds = true;
      LOGGER.info("IGNORE BOUNDS");
      }
     
      boolean placeFound = false;
      //try each position and rotation on the material
      placingLoop :  for(float yOffsetTry = 0 ; yOffsetTry < this.shapePack.materialWidth ; yOffsetTry+=step){
        for(float xOffsetTry = 0 ; xOffsetTry < this.shapePack.materialHeight ; xOffsetTry+=step){
          for(float rotateTry = 0 ; rotateTry < (Math.PI*2) ; rotateTry+= (Math.PI/2)){
           
            shapeCopy = shape.clone();
            shapeCopy.translate(xOffsetTry, yOffsetTry);

           
            shapeCopy.rotate(rotateTry);
            //LOGGER.info("looking");
            boolean inBounds = shapeCopy.inBoundss(pageBorder,pageBorder,this.shapePack.materialWidth-(pageBorder*2),this.shapePack.materialHeight-(pageBorder*2));
          //  float shapesArea = (this.shapes.getWidth()*this.shapes.getHeight());
           
           
            if( !placeFound && (inBounds || ignorePageBounds)){
              boolean hasCollision =  this.shapes.hasCollisions(shapeCopy);
              if(!hasCollision ){
            this.shapes.add(shapeCopy);
            placeFound = true;
           
            packingShapes.l.remove(i);
            i--;
            break placingLoop;
            }
          }

       
       
       
       
          }
        }
      }
     
     
     
     
     
     

   
     
    }

  }
 
  public void packTile(spShapes packingShapes) {
    LOGGER.info("packTile Page");

    float lineWidth = 0;
    float lineHeight = 0;
    float tallestOnLine = 0;
    float gap = shapePack.shapeGap;
     xPos = gap;
     yPos = gap;

    for (int i = 0; i < packingShapes.l.size(); i++) {
      spShape shape = (spShape) packingShapes.l.get(i);

      if (shape.getWidth() + xPos + gap > this.shapePack.materialWidth) {
        xPos = gap;
        yPos += tallestOnLine + gap;
        lastHeight = tallestOnLine+ gap;
        tallestOnLine = 0;
      }

      if (yPos + shape.getHeight() + gap > this.shapePack.materialHeight) {
        i = packingShapes.l.size() + 1;

        return;
      }

      if (shape.getHeight() > tallestOnLine){
        tallestOnLine = shape.getHeight();
        lastHeight = shape.getHeight()+gap;
      }
      //shape.offsetX = xPos;
      //shape.offsetY = yPos;

     
      shape.translate(xPos,yPos);
      xPos += shape.getWidth() + gap;

      shape.packed = true;

      this.shapes.add(shape);
      packingShapes.l.remove(i);
      i--;
    }

  }
 
 
 
  public void packTileSmart(spShapes packingShapes) {
   
LOGGER.debug("packTileSmart Page");

    float lineWidth = 0;
    float lineHeight = 0;
   
    float tallestOnLine = 0;
    float shortestOnLine = -1;

    float gap = 2.0f*shapePack.scale;//shapePack.shapeGap;
    float xPos = gap;
    float yPos = gap;
    float pageBorder = 10;
    float startX =0;
    float startY = 0;
   
    float step = 5*shapePack.scale;
   
    //Lets smart pack everything
    //we could start by ordering parts from large to small but it shouldn't be necessary
   
    boolean firstPlace = true;
    boolean ignorePageBounds = false;
   
    for (int i = 0; i < packingShapes.l.size(); i++) {
      spShape shape = (spShape) packingShapes.l.get(i);
      spShape shapeCopy = shape.clone();
      shape.translate(-shape.outlines.getMinX(), -shape.outlines.getMinY());
     
      float shapeWidth = shapeCopy.width;
     
      if(shapeCopy.width == 0)
        break;
     
      boolean placeFound = false;
      firstPlace = true;

      ignorePageBounds = false;
     
     
      if(shapeCopy.width >= (this.shapePack.materialWidth-(pageBorder*2)) || shapeCopy.height >= this.shapePack.materialHeight-(pageBorder*2)){
        ignorePageBounds = true;
        LOGGER.debug("ignorePageBounds");
      }else{
        LOGGER.debug(" dont ignorePageBounds");

      }
      //try each position and rotation on the material
      placingLoop : 
        for(float yOffsetTry = pageBorder ; yOffsetTry < this.shapePack.materialHeight ; yOffsetTry+=step){ 
        boolean collisionFoundOnRow = false;
       
          for(float xOffsetTry = pageBorder ; xOffsetTry < this.shapePack.materialWidth ; xOffsetTry+=step){
           
         
          if(yOffsetTry > this.shapePack.materialHeight)
            break placingLoop;

          //LOGGER.info("checking  x" + xOffsetTry + " y" + yOffsetTry + " of " +  this.shapePack.materialHeight);

         
          if(firstPlace){
            yOffsetTry = startY;
            xOffsetTry = startX;
          }
         
         
          shapeCopy = shape.clone();
           
         
         
            // if we can't fit on the page at least alight to the left
            if(ignorePageBounds){
              shapeCopy.translate(pageBorder, yOffsetTry);
              xOffsetTry = this.shapePack.materialWidth;

            }else{
            shapeCopy.translate(xOffsetTry, yOffsetTry);
            }
           
   
           
            //LOGGER.info("looking at " + xOffsetTry + " " + yOffsetTry);
            boolean inBounds = shapeCopy.inBounds(pageBorder,pageBorder,this.shapePack.materialWidth-(pageBorder*2),this.shapePack.materialHeight-(pageBorder*2));
          //  float shapesArea = (this.shapes.getWidth()*this.shapes.getHeight());
           
           

           
            if(!firstPlace && !collisionFoundOnRow && !ignorePageBounds && xOffsetTry + shapeCopy.width + gap > this.shapePack.materialWidth-pageBorder){
              xOffsetTry = pageBorder;
              yOffsetTry += shortestOnLine+(gap*2);
              shortestOnLine = -1;
            }
            firstPlace = false;

             
            if( !placeFound && (inBounds || ignorePageBounds)){
              boolean hasCollision = this.shapes.hasCollisionsBounds(shapeCopy, gap);
           
            if(!hasCollision ){
            this.shapes.add(shapeCopy);
            placeFound = true;
           
            startX = xOffsetTry + shapeCopy.width + (gap);
            startY = yOffsetTry;
           
            if(ignorePageBounds){
              startY += shapeCopy.height + (gap*2);
            }

           
            if(shortestOnLine == -1 || shapeCopy.height < shortestOnLine)
              shortestOnLine = shapeCopy.height;
           
           
            packingShapes.l.remove(i);
            i--;
            break placingLoop;
            }else{
              collisionFoundOnRow = true;
            }

          }
        }
      }
     
     
     
     
     
     

   
     
    }

  }
 
 

  public void render(PGraphics g) {
    g.stroke(0);
    g.fill(250);
    g.rect(0, 0, this.shapePack.materialWidth, this.shapePack.materialHeight);
    shapes.renderPage(g);
  }
 
  public void renderPickBuffer(PGraphics pickBuffer) {
    pickBuffer.stroke(0);
    pickBuffer.fill(250);
    pickBuffer.rect(0, 0, this.shapePack.materialWidth, this.shapePack.materialHeight);
    shapes.renderPickBufferPage(pickBuffer);   
  }
 

  public void renderList(PGraphics g) {
    shapes.renderPage(g);   
  }
 
 
  public void renderPickBufferList(PGraphics pickBuffer) {
    shapes.renderPickBufferPage(pickBuffer);   

  }
 
 
 
  public void renderDXF(DXFWriter dxf, float offsetX, float offsetY) {
    //g.stroke(0);
    //g.fill(255);
    //g.rect(0,0,this.shapePack.pageWidth,this.shapePack.pageHeight);
    shapes.renderPageDXF(dxf, offsetX, offsetY);
  }

  public void renderToPlotter(HPGLWriter craftRoboWriter) {
    this.shapes.renderToPlotter(craftRoboWriter);

  }

  public float getHeight() {
    return yPos+lastHeight;
  }

  public Element toXML() {

      Element element = new Element("g","http://www.w3.org/2000/svg");
      element.addAttribute(new Attribute("id","page"));
      element.appendChild(this.shapes.toXML());
     
      return element;

  }



 



}
TOP

Related Classes of ShapePacking.spPage

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.