import java.awt.Rectangle; import java.util.Enumeration; import java.util.Vector; class CSG extends Object3D // Composite implements java.io.Serializable { static final long serialVersionUID = 3639231904991892506L; // 6738468315356680055L; CSG() { csgType = 1; genType = 0; userType = 1; // No strip normals = true; cellSize = 2; cellSize2 = 2; tolerance = 0; //.1; name = "CSG"; link2master = true; // display the mesh, not the primitives CreateMaterial(); } Object3D deepCopy() { CSG csg = new CSG(); deepCopySelf(csg); return csg; } protected void deepCopyNode(Object3D other) { super.deepCopyNode(other); CSG c = (CSG) other; c.csgType = csgType; c.genType = genType; c.userType = userType; c.normals = normals; c.cellSize = cellSize; c.cellSize2 = cellSize2; c.tolerance = tolerance; } void generatePOV(StringBuffer buffer) { generateNameComment(buffer); generateIndent(buffer); switch (csgType) { case 1: // '\001' buffer.append("union"); break; case 2: // '\002' buffer.append("merge"); break; case 3: // '\003' buffer.append("intersection"); break; case 4: // '\004' buffer.append("difference"); break; } buffer.append(" {\n"); Object3D.povDepth += 4; Object3D child; for (Enumeration e = Children().elements(); e.hasMoreElements(); child.generatePOV(buffer)) { child = (Object3D) e.nextElement(); } Object3D.povDepth -= 4; generateTransform(buffer); generateIndent(buffer); buffer.append("}\n"); } void createEditWindow(GroupEditor callee, boolean newWindow) { System.out.println("csg.tolerance2 = " + tolerance); //editWindow = new CSGEditor(this, deepCopy(), callee); if (newWindow) { objectUI = new CSGEditor(this, deepCopy(), callee); } else { objectUI = new CSGEditor(this, callee); } editWindow = objectUI.GetEditor(); } boolean doSelection(ClickInfo info, Rectangle r, int level) { if (csgType == UNION) // || csgType == MERGE) { return super.doSelection(info, r, level); } if ((info.flags & 0x1) == 0 && level == 0) // ?? { return super.doSelection(info, r, level); } if (Children().size() < 1) // 2) { return super.doSelection(info, r, level); } else { return doSelectionSelf(info, r, level); } } void draw(ClickInfo info, int level, boolean select) { if (csgType == UNION) // || csgType == MERGE) { super.draw(info, level, select); } else if ((info.flags & 0x1) == 0 && level == 0) // ?? { super.draw(info, level, select); } else if (Children().size() < 1) // 2) { super.draw(info, level, select); } else { drawSelf(info, level, select); } } /**/ void draw(iCameraPane display, Object3D /*Composite*/ root, boolean selected, boolean blocked) { if (csgType == UNION || !link2master) // || csgType == MERGE) { BoundaryRep keep = bRep; bRep = null; super.draw(display, root, selected, blocked); bRep = keep; } else //if ((info.flags & 0x1) == 0 && level == 0) // ?? // super.draw(gl); //else if (Children().size() < 1) // 2) { super.draw(display, root, selected, blocked); } else { //super.draw(display, root, selected); // Reset touched flag Draw(display, root, selected, blocked); } } /**/ void PreprocessOcclusion(iCameraPane cp) { if (csgType == UNION) // || csgType == MERGE) { super.PreprocessOcclusion(cp); return; } if (count <= 1) { return; } System.out.println("processing " + this + ": " + (bRep.getRawVertices().length / 3) + " vertices..."); bRep.PreprocessOcclusion(cp, GlobalTransformInv()); Touch(); } void Touch() { super.Touch(); /* for(Object3D c : children) { if( c.touched ) { retile0(true); //new Exception().printStackTrace(); return; } } */ //csgType = UNION; } void retile() { retile(true); } void retile(boolean forced) { //new Exception().printStackTrace(); ClearList(); retile0(forced); } void retile0(boolean forced) { if (csgType == UNION) // || csgType == 2) { bRep = null; // new BoundaryRep(); return; } if (Children().size() < 1) // 2) { bRep = null; // new BoundaryRep(); return; } else { if (forced || aNormals != normals || aStripify != userType || aGenType != genType || aCellSize != cellSize || aCellSize2 != cellSize2 || aTolerance != tolerance) { System.out.println("RETILE " + userType); bRep = (new ImplicitTiler(this, genType, normals, userType != 2, userType == 0, cellSize, cellSize + cellSize2, tolerance, true)).bRep; } aNormals = normals; aStripify = userType; aGenType = genType; aCellSize = cellSize; aCellSize2 = cellSize2; aTolerance = tolerance; return; } } void getBounds(cVector minima, cVector maxima, boolean xform) { if (Children().size() == 0) { minima.x = minima.y = minima.z = Double.MAX_VALUE; maxima.x = maxima.y = maxima.z = -Double.MAX_VALUE; return; } Object3D child = (Object3D) Children().get/*reserve*/(0); child.getBounds(minima, maxima, true); // xform); //children.release(0); if (csgType != DIFFERENCE) { cVector min = new cVector(); cVector max = new cVector(); for (int i = Children().size() - 1; i >= 1; i--) { child = (Object3D) Children().get(i); // reserve(i); if (child == null) return; child.getBounds(min, max, true); // xform); //children.release(i); for (int xyz = 0; xyz < 3; xyz++) { if (csgType == MERGE || csgType == UNION) { if (min.get(xyz) < minima.get(xyz)) { minima.set(xyz, min.get(xyz)); } if (max.get(xyz) > maxima.get(xyz)) { maxima.set(xyz, max.get(xyz)); } } else { // INTERSECTION if (min.get(xyz) > minima.get(xyz)) { minima.set(xyz, min.get(xyz)); } if (max.get(xyz) < maxima.get(i)) { maxima.set(xyz, max.get(xyz)); } } } } } if (xform) { transformBounds(minima, maxima); } } boolean inside(double x, double y, double z, boolean xform) { //if (x == 0 && y == 0 && z == 0) //System.out.println("TEST INSIDE = " + this); if (xform && fromParent != null) { untransform(x, y, z, cStatic.point1); x = cStatic.point1.x; y = cStatic.point1.y; z = cStatic.point1.z; } //else // LA.setVector(cStatic.point1, x, y, z); boolean inside = false; if (csgType == MERGE || csgType == UNION) { /* //Enumeration e = children.elements(); for (int i=children.size()-1; i>=0; i--) // (e.hasMoreElements()) { Object3D child = (Object3D) children.reserve(i); // e.nextElement(); if (child.inside(x, y, z, xform)) { inside = true; //break; } children.release(i); if (inside) break; } */ BoundaryRep keep = bRep; bRep = null; // for merge inside = super.inside(x, y, z, false); // xform); bRep = keep; } else { //if (children.size() > 0) { //Enumeration e = children.elements(); Object3D child = (Object3D) Children().get(0); // e.nextElement(); if (child.inside(x, y, z, true)) // xform)) { inside = true; if (csgType == DIFFERENCE) { for (int i = Children().size() - 1; i > 0; i--) // (e.hasMoreElements()) { child = (Object3D) Children().get(i); // e.nextElement(); if (child.inside(x, y, z, true)) // xform)) { inside = false; break; } } } else { // INTERSECTION for (int i = Children().size() - 1; i > 0; i--) // (e.hasMoreElements()) { child = (Object3D) Children().get(i); // e.nextElement(); if (!child.inside(x, y, z, true)) // xform)) { inside = false; break; } } } } } } //if (x == 0 && y == 0 && z == 0) //System.out.println("result = " + inside); return inside; } public static final int UNION = 1; public static final int MERGE = 2; public static final int INTERSECTION = 3; public static final int DIFFERENCE = 4; public static final int DIFFERENCEBA = 5; int userType; // 0 == stripify, 1 == trimmed, 2 == no trim int csgType; int genType; boolean normals; //boolean stripify; transient int aGenType; transient boolean aNormals; transient int aStripify; transient int aCellSize; transient int aCellSize2; transient double aTolerance; int cellSize; int cellSize2; double tolerance; }