0

几天来,我一直在与这个问题作斗争,并且在解决它或在网络上找到任何支持的运气为零。基本上,我正在尝试创建一个以画布作为视觉元素的 VisualBrush。我希望能够在此画布上绘制几条线,并最终将其映射到 3D 表面(形成一个矩形的 2 个平行三角形)。我已经设置了纹理坐标,并且可以通过简单地使用 ImageBrush 或类似的东西来确认一切正常。我遇到的问题是画布拒绝保持其大小,并且根据其中的内容不断缩放。例如,如果画布是 100x100 并且我在其中有一条从 (0, 0) 到 (50, 50) 的线,画布将被缩放,使得只有内部内容的 50x50 部分被映射到纹理坐标和 3D 表面。我已经尝试了许多 Viewport/Viewbox/StretchMode/Alignment/etc 的组合,但找不到任何可以阻止这种情况发生的东西。我正在设置画布的 Width 和 Height 属性,所以我看不出为什么它在 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 大小,除非子内容一直到这些极端。出于我的目的,线坐标可以在画布中的任何位置,无论内容如何,​​我都需要让它保持其所需的形状。

任何建议将不胜感激!

4

1 回答 1

0

一些事情要尝试:

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

  • 不要在画布上使用透明背景颜色,而是尝试绿色(这是为了查看纹理是否基于透明像素进行裁剪)

  • 如果正在对您的纹理进行裁剪(由于透明度)......然后尝试在 Canvas 上以您希望纹理的尺寸放置一个矩形......也许这会改变一些东西。

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

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

于 2012-08-19T01:37:16.753 回答