TriangleMesh doJoinBoundaries(int boundary[][], int boundaryVert[][], double offset, boolean reverse)
{
int maxsteps = (boundary[0].length > boundary[1].length ? boundary[0].length : boundary[1].length);
double step0 = boundary[0].length/((double) maxsteps);
double step1 = (reverse ? -1.0 : 1.0)*boundary[1].length/((double) maxsteps);
TriangleMesh theMesh = (TriangleMesh) objInfo.getObject();
Vertex vt[] = (Vertex []) theMesh.getVertices();
Edge ed[] = theMesh.getEdges();
Face fc[] = theMesh.getFaces();
Vec3 newvert[] = new Vec3 [vt.length];
int newface[][] = new int [fc.length+boundary[0].length+boundary[1].length][];
// First copy over the old vertices and faces.
for (int i = 0; i < vt.length; i++)
newvert[i] = vt[i].r;
for (int i = 0; i < fc.length; i++)
newface[i] = new int [] {fc[i].v1, fc[i].v2, fc[i].v3};
int count = fc.length;
// Go around the boundaries and add new faces.
if (isBoundaryClosed(boundary[0]))
{
// We are connecting two closed boundaries.
double p0 = 0.0, p1 = offset;
int i0prev = 0, i1prev = ((int) Math.round(p1)+boundary[1].length) % boundary[1].length;
for (int i = 1; i <= maxsteps; i++)
{
p0 += step0;
p1 += step1;
while (p1 < 0.0)
p1 += boundary[1].length;
int i0 = ((int) Math.round(p0)) % boundary[0].length;
int i1 = ((int) Math.round(p1)) % boundary[1].length;
if (i0 != i0prev)
{
Edge e = ed[boundary[0][step0 > 0.0 ? i0prev : i0]];
Face f = fc[e.f1];
int v1 = boundaryVert[0][i0prev], v2 = boundaryVert[0][i0];
if ((f.v1 == v1 && f.v2 == v2) || (f.v2 == v1 && f.v3 == v2) || (f.v3 == v1 && f.v1 == v2))
newface[count++] = new int [] {v2, v1, boundaryVert[1][i1prev]};
else
newface[count++] = new int [] {v1, v2, boundaryVert[1][i1prev]};
}
if (i1 != i1prev)
{
Edge e = ed[boundary[1][step1 > 0.0 ? i1prev : i1]];
Face f = fc[e.f1];
int v1 = boundaryVert[1][i1prev], v2 = boundaryVert[1][i1];
if ((f.v1 == v1 && f.v2 == v2) || (f.v2 == v1 && f.v3 == v2) || (f.v3 == v1 && f.v1 == v2))
newface[count++] = new int [] {v2, v1, boundaryVert[0][i0]};
else
newface[count++] = new int [] {v1, v2, boundaryVert[0][i0]};
}
i0prev = i0;
i1prev = i1;
}
}
else
{
// We are connecting two open boundaries.
double p0 = 0.0, p1 = (reverse ? boundary[1].length : 0.0);
int i0prev = 0, i1prev = (int) Math.round(p1);
while (count < newface.length)
{
p0 += step0;
p1 += step1;
int i0 = (int) Math.round(p0);
int i1 = (int) Math.round(p1);
if (i0 < 0)
i0 = 0;
if (i1 < 0)
i1 = 0;
if (i0 > boundary[0].length)
i0 = boundary[0].length;
if (i1 > boundary[1].length)
i1 = boundary[1].length;
if (i0 != i0prev)
{
Edge e = ed[boundary[0][i0prev < i0 ? i0prev : i0]];
Face f = fc[e.f1];
int v1 = boundaryVert[0][i0prev], v2 = boundaryVert[0][i0];
if ((f.v1 == v1 && f.v2 == v2) || (f.v2 == v1 && f.v3 == v2) || (f.v3 == v1 && f.v1 == v2))
newface[count++] = new int [] {v2, v1, boundaryVert[1][i1prev]};
else
newface[count++] = new int [] {v1, v2, boundaryVert[1][i1prev]};
}
if (i1 != i1prev)
{
Edge e = ed[boundary[1][i1prev < i1 ? i1prev : i1]];
Face f = fc[e.f1];
int v1 = boundaryVert[1][i1prev], v2 = boundaryVert[1][i1];
if ((f.v1 == v1 && f.v2 == v2) || (f.v2 == v1 && f.v3 == v2) || (f.v3 == v1 && f.v1 == v2))
newface[count++] = new int [] {v2, v1, boundaryVert[0][i0]};
else
newface[count++] = new int [] {v1, v2, boundaryVert[0][i0]};
}
i0prev = i0;
i1prev = i1;
}
}
// Create the new mesh.
TriangleMesh newmesh = new TriangleMesh(newvert, newface);
Vertex newvt[] = (Vertex []) newmesh.getVertices();
Edge newed[] = newmesh.getEdges();
newmesh.copyTextureAndMaterial(theMesh);
newmesh.setSmoothingMethod(theMesh.getSmoothingMethod());
// Update the texture parameters.
TextureParameter param[] = theMesh.getParameters();
ParameterValue oldParamVal[] = theMesh.getParameterValues();
ParameterValue newParamVal[] = new ParameterValue [oldParamVal.length];
for (int i = 0; i < oldParamVal.length; i++)
{
if (oldParamVal[i] instanceof FaceParameterValue)
{
double oldval[] = ((FaceParameterValue) oldParamVal[i]).getValue();
double newval[] = new double [newface.length];
for (int j = 0; j < oldval.length; j++)
newval[j] = oldval[j];
if (param[i] == getFaceIndexParameter()) // The parameter added by the editor window to record face indices
for (int j = oldval.length; j < newval.length; j++)
newval[j] = j;
else
for (int j = oldval.length; j < newval.length; j++)
newval[j] = param[i].defaultVal;
newParamVal[i] = new FaceParameterValue(newval);
}
else if (oldParamVal[i] instanceof FaceVertexParameterValue)
{
FaceVertexParameterValue fvpv = (FaceVertexParameterValue) oldParamVal[i];
double newval[][] = new double [newface.length][3];
for (int j = 0; j < 3; j++)
{
for (int k = 0; k < fvpv.getFaceCount(); k++)
newval[k][j] = fvpv.getValue(k, j);
for (int k = fvpv.getFaceCount(); k < newface.length; k++)
newval[k][j] = param[i].defaultVal;
}
newParamVal[i] = new FaceVertexParameterValue(newval);
}
else
newParamVal[i] = oldParamVal[i].duplicate();
}
newmesh.setParameterValues(newParamVal);
// Copy over the smoothness values.
for (int i = 0; i < vt.length; i++)
newvt[i].smoothness = vt[i].smoothness;