package org.reprap.geometry.polygons; import java.util.*; import org.reprap.Attributes; import org.reprap.Extruder; /** * It's convenient to have lists of CSG polygons (even though they * can be multiple polygons themselves) so that you each entry * can be one collection of polygons per material (attribute). * * @author Adrian * */ public class RrCSGPolygonList { /** * The list of polygons */ List<RrCSGPolygon> csgPolygons = null; /** * Flag to prevent cyclic graphs going round forever */ private boolean beingDestroyed = false; /** * Destroy me and all that I point to */ public void destroy() { if(beingDestroyed) // Prevent infinite loop return; beingDestroyed = true; if(csgPolygons != null) { for(int i = 0; i < csgPolygons.size(); i++) { csgPolygons.get(i).destroy(); csgPolygons.set(i, null); } } csgPolygons = null; beingDestroyed = false; } /** * Destroy just me */ protected void finalize() throws Throwable { csgPolygons = null; super.finalize(); } /** * */ public RrCSGPolygonList() { csgPolygons = new ArrayList<RrCSGPolygon>(); } /** * Add polygon c * @param c */ public void add(RrCSGPolygon c) { csgPolygons.add(c); } /** * Get the ith polygon in the list * @param i * @return */ public RrCSGPolygon get(int i) { return csgPolygons.get(i); } /** * How many polygons? * @return */ public int size() { return csgPolygons.size(); } /** * The minimum enclosing rectangle * @return */ public RrBox box() { RrBox result = new RrBox(); for(int i = 0; i < size(); i++) result.expand(get(i).box()); return result; } /** * Offset the lot by appropriate extruder widths * @param es * @param outline * @return */ public RrCSGPolygonList offset(Extruder[] es, boolean outline) { RrCSGPolygonList result = new RrCSGPolygonList(); for(int i = 0; i < size(); i++) { Attributes att = get(i).getAttributes(); if(att == null) System.err.println("offset(): null attribute!"); else { Extruder e = att.getExtruder(es); int shells = e.getShells(); if(outline) { for(int shell = 0; shell < shells; shell++) result.add(get(i).offset(-((double)shell + 0.5)*e.getExtrusionSize())); } else { // Must be a hatch. Only do it if the gap is +ve if (e.getExtrusionInfillWidth(0, 1) > 0) // Z valuesn't mattere here result.add(get(i).offset(-((double)shells + 0.5)*e.getExtrusionSize() + e.getInfillOverlap())); } } } return result; } /** * Recursively divide the lot * @param res_2 * @param swell */ public void divide(double res_2, double swell) { for(int i = 0; i < size(); i++) get(i).divide(res_2, swell); } /** * Generate boundary lists for the lot * @return */ public RrPolygonList megList() { RrPolygonList result = new RrPolygonList(); for(int i = 0; i < size(); i++) result.add(get(i).megList()); return result; } /** * Cross hatch the lot * @param hp * @param es * @return */ public RrPolygonList hatch(RrHalfPlane hp, Extruder[] es, double z, double zMax) { RrPolygonList result = new RrPolygonList(); for(int i = 0; i < size(); i++) { Attributes att = get(i).getAttributes(); result.add(get(i).hatch(hp, att.getExtruder(es).getExtrusionInfillWidth(z, zMax))); } return result; } }