/*
* LoopUnfold attempts to add as many FlatFaces to a FlatBody as it can. If interference checking is off, it will add all of the
* faces of the body. (Actually, the shell, as we do not handle voids). We expect for the seed face of the FlatBody to already
* be created, so we have some FlatFins from which to propogate.
*
* If interference checking is on, multiple flat bodies are required to avoid collisions. Therefore
* we return the list of FlatFins on the completed FlatBody that need to start as the seeds for additional FlatBodies. By returning
* the FlatFins on the base, rather than just the faces, we can easily transfrom the adjacent FlatFace to line up with that FlatFin
* by making it the seed face for the next FlatBody.
*/
// TBD add tab code would go here, created extra flatfaces, but we need to consider the tabs as part of the collision detection???
private List <FlatFin> LoopUnfold(FlatBody flatBody)
{
Debug.Assert(flatBody.FlatFaces.Count > 0); // should only be one, but more is harmless if we optimize with seeds of several flatfaces
List <FlatFin> remainingFins = new List <FlatFin>();
while (flatBody.OpenFins.Count > 0)
{
if (AddInHelper.IsEscDown)
{
break;
}
FlatFace testFace = null;
List <FlatFin> interferingFins = new List <FlatFin>();
foreach (FlatFin baseFin in flatBody.OpenFins) // OpenFins sorts itself to present the most desirable edge (the longest)
{
testFace = new FlatFace(baseFin.FlatFace.SourceFace.GetAdjacentFace(baseFin.SourceFin.Edge), flatBody);
baseFin.AdjacentFin = baseFin.OtherFlatFin(testFace); // make symmetric? Careful: FlatFace.Render() relies on the assumption it is not
testFace.Transform = Matrix.CreateMapping(AddInHelper.CreateFrame(baseFin.Start, (baseFin.End - baseFin.Start).Direction, -Direction.DirZ)) *
Matrix.CreateMapping(AddInHelper.CreateFrame(baseFin.AdjacentFin.SourceEnd, (baseFin.AdjacentFin.SourceStart - baseFin.AdjacentFin.SourceEnd).Direction, baseFin.AdjacentFin.FlatFace.SourcePlane.Frame.DirZ)).Inverse;
if (isDetectingCollisions && flatBody.FaceInterferes(testFace)) // FaceInterferes only gets called if isDetectingCollisions == True
{
interferingFins.Add(baseFin);
}
else
{
flatBody.AddFace(testFace);
baseFin.IsInternal = true;
baseFin.AdjacentFin.IsInternal = true;
break;
}
}
foreach (FlatFin baseFin in interferingFins)
{
flatBody.OpenFins.Remove(baseFin);
remainingFins.Add(baseFin);
}
}
return(remainingFins);
}