using System.Windows.Media.Media3D;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows;
namespace HelixToolkit
{
// http://www.ericsink.com/wpf3d/4_Text.html
public static class TextCreator
{
///
/// Creates a ModelVisual3D containing a text label.
///
/// The string
/// The color of the text.
/// Visible from both sides?
/// Height of the characters
/// The center of the label
/// Horizontal direction of the label
/// Vertical direction of the label
/// Suitable for adding to your Viewport3D
public static ModelVisual3D CreateTextLabel3D(
string text,
Brush textColor,
bool bDoubleSided,
double height,
Point3D center,
Vector3D over,
Vector3D up)
{
var mv3D = new ModelVisual3D
{
Content = CreateTextLabelModel3D(text, textColor, bDoubleSided, height, center, over, up)
};
return mv3D;
}
public static GeometryModel3D CreateTextLabelModel3D(
string text,
Brush textColor,
bool bDoubleSided,
double height,
Point3D center,
Vector3D over,
Vector3D up)
{
// First we need a textblock containing the text of our label
var tb = new TextBlock(new Run(text)) { Foreground = textColor, FontFamily = new FontFamily("Arial") };
// Now use that TextBlock as the brush for a material
var mat = new DiffuseMaterial { Brush = new VisualBrush(tb) };
// We just assume the characters are square
double width = text.Length * height;
// tb.Measure(new Size(text.Length * height * 2, height * 2));
// width=tb.DesiredSize.Width;
// Since the parameter coming in was the center of the label,
// we need to find the four corners
// p0 is the lower left corner
// p1 is the upper left
// p2 is the lower right
// p3 is the upper right
Point3D p0 = center - width / 2 * over - height / 2 * up;
Point3D p1 = p0 + up * 1 * height;
Point3D p2 = p0 + over * width;
Point3D p3 = p0 + up * 1 * height + over * width;
// Now build the geometry for the sign. It's just a
// rectangle made of two triangles, on each side.
var mg = new MeshGeometry3D();
mg.Positions = new Point3DCollection();
mg.Positions.Add(p0); // 0
mg.Positions.Add(p1); // 1
mg.Positions.Add(p2); // 2
mg.Positions.Add(p3); // 3
if (bDoubleSided)
{
mg.Positions.Add(p0); // 4
mg.Positions.Add(p1); // 5
mg.Positions.Add(p2); // 6
mg.Positions.Add(p3); // 7
}
mg.TriangleIndices.Add(0);
mg.TriangleIndices.Add(3);
mg.TriangleIndices.Add(1);
mg.TriangleIndices.Add(0);
mg.TriangleIndices.Add(2);
mg.TriangleIndices.Add(3);
if (bDoubleSided)
{
mg.TriangleIndices.Add(4);
mg.TriangleIndices.Add(5);
mg.TriangleIndices.Add(7);
mg.TriangleIndices.Add(4);
mg.TriangleIndices.Add(7);
mg.TriangleIndices.Add(6);
}
// These texture coordinates basically stretch the
// TextBox brush to cover the full side of the label.
mg.TextureCoordinates.Add(new Point(0, 1));
mg.TextureCoordinates.Add(new Point(0, 0));
mg.TextureCoordinates.Add(new Point(1, 1));
mg.TextureCoordinates.Add(new Point(1, 0));
if (bDoubleSided)
{
mg.TextureCoordinates.Add(new Point(1, 1));
mg.TextureCoordinates.Add(new Point(1, 0));
mg.TextureCoordinates.Add(new Point(0, 1));
mg.TextureCoordinates.Add(new Point(0, 0));
}
// And that's all. Return the result.
return new GeometryModel3D(mg, mat); ;
}
}
}