/// <summary>
/// Do the tessellation and return the <see cref="MeshGeometry3D"/> .
/// </summary>
/// <returns>
/// A triangular mesh geometry.
/// </returns>
protected override MeshGeometry3D Tessellate()
{
if (this.Path == null || this.Path.Count < 2)
{
return null;
}
// See also "The GLE Tubing and Extrusion Library":
// http://linas.org/gle/
// http://sharpmap.codeplex.com/Thread/View.aspx?ThreadId=18864
var builder = new MeshBuilder(false, this.TextureCoordinates != null);
var sectionXAxis = this.SectionXAxis;
if (sectionXAxis.Length < 1e-6)
{
sectionXAxis = new Vector3D(1, 0, 0);
}
var forward = this.Path[1] - this.Path[0];
var up = Vector3D.CrossProduct(forward, sectionXAxis);
if (up.LengthSquared < 1e-6)
{
sectionXAxis = forward.FindAnyPerpendicular();
}
builder.AddTube(
this.Path,
this.Angles,
this.TextureCoordinates,
this.Diameters,
this.Section,
sectionXAxis,
this.IsPathClosed,
this.IsSectionClosed);
// Add Caps if wanted and needed
if (this.AddCaps && !this.IsPathClosed && builder.Positions.Count >= Section.Count)
{
var sCount = Section.Count;
var normals = new Vector3D[sCount];
var vertices = new Point3D[sCount];
var pCount = Path.Count;
//Add back cap
var circleBack = builder.Positions.Skip(builder.Positions.Count - sCount).Take(sCount).ToArray();
var normal = Path[pCount - 1] - Path[pCount - 2];
normal.Normalize();
for (int i = 0; i < normals.Length; ++i)
{
normals[i] = normal;
}
builder.AddTriangleFan(circleBack, normals);
//Add front cap
var circleFront = builder.Positions.Take(sCount).ToArray();
normal = Path[0] - Path[1];
normal.Normalize();
for (int i = 0; i < normals.Length; ++i)
{
normals[i] = normal;
}
builder.AddTriangleFan(circleFront, normals);
}
return builder.ToMesh();
}