I've been fighting with this problem for a few days now and have had zero luck getting it resolved or finding any support on the web. Basically, I am trying to create a VisualBrush with a canvas as the visual element. I want to be able to draw several lines on this canvas and will eventually be mapping it to a 3D surface (2 parallel triangles forming a rectangle). I've set up the texture coordinates and can confirm everything works by simply using an ImageBrush or something of that nature. The problem I am having is that the canvas refuses to maintain its size and is constantly scaled based on the content that is inside it. So for example, if the canvas is 100x100 and I have a single line inside it from (0, 0) to (50, 50), the canvas would be scaled such that only the 50x50 portion with content inside is mapped to the texture coordinates and onto the 3D surface. I have tried many combinations of Viewport/Viewbox/StretchMode/Alignment/etc and can't find anything that stops this from happening. I am setting the Width and Height properties of the canvas so I can't see why it would perform differently in the VisualBrush versus if I simply added it into a grid or some other layout container.
Here's some code to help illustrate the problem.
// create the canvas for the VisualBrush
Canvas drawCanvas = new Canvas();
drawCanvas.Background = Brushes.Transparent; // transparent canvas background so only content is rendered
drawCanvas.Width = 100;
drawCanvas.Height = 100;
// add a line to the canvas
Line l = new Line();
l.X1 = 0;
l.Y1 = 0;
l.X2 = 50;
l.Y2 = 50;
l.Stroke = Brushes.Red;
l.StrokeThickness = 2;
drawCanvas.Children.Add(l);
// create rectangular surface mesh
MeshGeometry3D TableMesh = new MeshGeometry3D();
CreateRectangleModel(
new Point3D(0, 0, 0),
new Point3D(0, 0, 100),
new Point3D(100, 0, 100),
TableMesh);
// need to include texture coordinates for our table mesh to map canvas to 3D model
TableMesh.TextureCoordinates = new PointCollection {
new Point(0, 0), new Point(0, 1), new Point(1, 1),
new Point(1, 1), new Point(0, 1), new Point(0, 0),
new Point(1, 1), new Point(1, 0), new Point(0, 0),
new Point(0, 0), new Point(1, 0), new Point(1, 1)
};
// finally make our visual brush with the canvas we have created
VisualBrush vb = new VisualBrush();
vb.Visual = drawCanvas;
Material TableMaterial = new DiffuseMaterial(vb);
// add our new model to the scene
GeometryModel3D geometry = new GeometryModel3D(TableMesh, TableMaterial);
Model3DGroup group = new Model3DGroup();
group.Children.Add(geometry);
ModelVisual3D previewTable = new ModelVisual3D();
previewTable.Content = group;
MainViewport.Children.Add(previewTable);
And the one function I referenced is
private void CreateRectangleModel(Point3D pStart, Point3D pCorner1, Point3D pEnd, MeshGeometry3D mesh)
{
// pCorner -> O--O <- pEnd
// | /|
// |/ |
// pStart -> O--O <- pCorner2
// find the remaining point for our rectangle
Point3D pCorner2 = new Point3D(
pStart.X + (pEnd.X - pCorner1.X),
pStart.Y + (pEnd.Y - pCorner1.Y),
pStart.Z + (pEnd.Z - pCorner1.Z));
// add necessary triangles to our group (we create 2 facing up, 2 facing down)
CreateTriangleModel(pStart, pCorner1, pEnd, mesh);
CreateTriangleModel(pEnd, pCorner1, pStart, mesh);
CreateTriangleModel(pEnd, pCorner2, pStart, mesh);
CreateTriangleModel(pStart, pCorner2, pEnd, mesh);
}
I can't get the canvas to maintain its set size of 100x100 unless the children content goes all the way to these extremes. For my purposes, the line coordinates could be anywhere within the canvas and I need to have it maintain its desired shape regardless of the content.
Any advice would be greatly appreciated!