0

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!

H.B.
  • 166,899
  • 29
  • 327
  • 400

1 Answers1

0

Some things to try:

  • Create an image file of 100x100 pixels by hand and then put it into an ImageBrush, and use that brush in your DiffuseMaterial. This is to confirm that your texture coords, etc are being set up properly.

  • Instead of using a Transparent Background colour on your Canvas, try Green (this is to see if the texture is being cropped based on transparent pixels)

  • If the cropping is being done of your texture (due to transparency)...then try putting a rectangle on the Canvas at the dimensions you want the texture to be...maybe that will change something.

  • Or try using RenderTargetBitmap to create an image from your Canvas visual...then use that image within an ImageBrush. (you can then confirm that the image is of your expected area of 100x100).

  • Finally, instead of using a Canvas+VisualBrush to create your texture try creating the Brush by using a DrawingBrush+DrawingGroup+GeometryDrawing

Colin Smith
  • 12,375
  • 4
  • 39
  • 47