|
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 || !Link2Support()) // || 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;
|
}
|