private line intersection(face a, face b)
{
line L;
L.point=intersectionpoint(a.normal,a.point,b.normal,b.point);
L.dir=unit(cross(a.normal,b.normal));
return L;
}
struct half {
pair[] left,right;
// Sort the points in the pair array z according to whether they lie on the
// left or right side of the line L in the direction dir passing through P.
// Points exactly on L are considered to be on the right side.
// Also push any points of intersection of L with the path operator --(... z)
// onto each of the arrays left and right.
void operator init(pair dir, pair P ... pair[] z) {
pair lastz;
pair invdir=dir != 0 ? 1/dir : 0;
bool left,last;
for(int i=0; i < z.length; ++i) {
left=(invdir*z[i]).y > (invdir*P).y;
if(i > 0 && last != left) {
pair w=extension(P,P+dir,lastz,z[i]);
this.left.push(w);
this.right.push(w);
}
if(left) this.left.push(z[i]);
else this.right.push(z[i]);
last=left;
lastz=z[i];
}
}
}
struct splitface {
face back,front;
}
// Return the pieces obtained by splitting face a by face cut.
splitface split(face a, face cut, projection P)
{
splitface S;
// Draw from back to front.
void add(frame f) {
if(back != null) back.add(f);
add(f,node.fit,group=true);
if(labels(node.fit)) layer(f); // Draw over any existing TeX layers.
if(front != null) front.add(f);
}
}
void add(picture pic=currentpicture, face[] faces,
projection P=currentprojection)
{
int n=faces.length;
face[] Faces=new face[n];
for(int i=0; i < n; ++i)
Faces[i]=faces[i].copy();
pic.add(new void (frame f, transform t, transform T,
pair m, pair M) {
// Fit all of the pictures so we know their exact sizes.
face[] faces=new face[n];
for(int i=0; i < n; ++i) {
faces[i]=Faces[i].copy();
face F=faces[i];
F.t=t*T*F.pic.T;
F.fit=F.pic.fit(t,T*F.pic.T,m,M);
}
for(int i=0; i < n; ++i) {
picture F=Faces[i].pic;
pic.userBox3(F.userMin3(), F.userMax3());
pic.bounds.append(F.T, F.bounds);
// The above 2 lines should be replaced with a routine in picture which
// copies only sizing data from another picture.
}
}