VisuaBrush与Canvas错误地缩放为Visual元素

时间:2012-08-19 00:54:28

标签: c# wpf canvas visualbrush

我几天来一直在与这个问题作斗争,并且没有运气来解决它或在网络上找到任何支持。基本上,我正在尝试使用canvas作为可视元素创建一个VisualBrush。我希望能够在这个画布上绘制几条线,并最终将它映射到3D表面(2个平行的三角形形成一个矩形)。我已经设置了纹理坐标,并且可以通过简单地使用ImageBrush或其他类似的东西来确认一切正常。我遇到的问题是画布拒绝保持其大小,并根据其中的内容不断缩放。因此,例如,如果画布是100x100并且我在其中有一条从(0,0)到(50,50)的单行,则画布将被缩放,使得仅具有内部内容的50x50部分被映射到纹理坐标并进入3D表面。我已经尝试过Viewport / Viewbox / StretchMode / Alignment / etc的许多组合,并且无法找到阻止这种情况发生的任何事情。我正在设置画布的宽度和高度属性,所以我不明白为什么它会在VisualBrush中执行不同,如果我只是将它添加到网格或其他布局容器中。

以下是一些有助于说明问题的代码。

        // 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);

我引用的一个函数是

    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);
    }

我不能让画布保持其设置大小为100x100,除非儿童内容一直到这些极端。就我的目的而言,线坐标可以在画布内的任何位置,我需要让它保持其所需的形状,而不管内容如何。

非常感谢任何建议!

1 个答案:

答案 0 :(得分:0)

有些事情要尝试:

  • 手动创建一个100x100像素的图像文件,然后将其放入ImageBrush中,并在DiffuseMaterial中使用该画笔。这是为了确认您的纹理坐标等正确设置。

  • 不要在“画布”上使用“透明背景”颜色,请尝试使用“绿色”(这是为了查看是否根据透明像素裁剪纹理)

  • 如果正在对纹理进行裁剪(由于透明度)...然后尝试在画布上放置一个矩形,你想要纹理的尺寸......也许会改变一些东西。

  • 或者尝试使用RenderTargetBitmap从Canvas visual中创建图像...然后在ImageBrush中使用该图像。 (然后您可以确认图像的预期区域为100x100)。

  • 最后,不要使用Canvas + VisualBrush来创建纹理,而是尝试使用DrawingBrush + DrawingGroup + GeometryDrawing创建画笔