c# - WPF ModelVisual3D 的可见 2D 内容边界

标签 c# wpf 3d

在 WPF 中,我们可以轻松地使用 VisualTreeHelper.GetDescendantBounds(Viewport3D) 来获取 ModelVisual3D 的可见二维内容边界,而无需进行转换。但是,当转换 ModelVisual3D 时,GetDescendantBounds 返回比可见内容更大的边界。如何获取可见内容的准确边界?

代码-xaml:

<Grid Background="LightGray">
    <Viewport3D x:Name="MyViewport">
        <Viewport3D.Camera>
            <OrthographicCamera Position="3 3 5" LookDirection="-3 -3 -5" Width="3"/>
        </Viewport3D.Camera>
        <Viewport3D.Children>
            <ModelVisual3D>
                <ModelVisual3D.Content>
                    <DirectionalLight Color="White" Direction="-1 -1 -1"/>
                </ModelVisual3D.Content>
            </ModelVisual3D>
            <ModelVisual3D x:Name="MyVisual">
                <ModelVisual3D.Content>
                    <GeometryModel3D>
                        <GeometryModel3D.Geometry>
                            <MeshGeometry3D Positions="0,0,0 1,0,0 0,1,0 1,1,0 0,0,1 1,0,1 0,1,1 1,1,1"
                                            TriangleIndices="0,2,1 1,2,3 0,4,2 2,4,6 0,1,4 1,5,4 1,7,5 1,3,7 4,5,6 7,6,5 2,6,3 3,6,7"/>
                        </GeometryModel3D.Geometry>
                        <GeometryModel3D.Material>
                            <DiffuseMaterial Brush="Red"/>
                        </GeometryModel3D.Material>
                        <!--<GeometryModel3D.Transform>
                            <RotateTransform3D>
                                <RotateTransform3D.Rotation>
                                    <AxisAngleRotation3D Axis="1 1 0" Angle="5"/>
                                </RotateTransform3D.Rotation>
                            </RotateTransform3D>
                        </GeometryModel3D.Transform>-->
                    </GeometryModel3D>
                </ModelVisual3D.Content>
            </ModelVisual3D>
        </Viewport3D.Children>
    </Viewport3D>
    <Rectangle x:Name="MyRegion" Stroke="Blue" StrokeThickness="1" VerticalAlignment="Top" HorizontalAlignment="Left"/>
</Grid>

代码隐藏:

var bounds = VisualTreeHelper.GetDescendantBounds(MyViewport);

MyRegion.Width = bounds.Width;
MyRegion.Height = bounds.Height;

MyRegion.Margin = new Thickness(bounds.Left, bounds.Top, 0, 0);

最佳答案

如果您可以在网格几何体中轻松找到所有三角形点而不会出现性能问题,您可以尝试下面的方法。我所做的是将所有 Point3D 转换为二维坐标并获取所有二维点的边界。

GeneralTransform3DTo2D transform = MyVisual.TransformToAncestor(MyViewport);
MeshGeometry3D geometry = (MeshGeometry3D) ((GeometryModel3D) MyVisual.Content).Geometry;
Rect wholeBounds = Rect.Empty;
if (transform != null)
{
    for (int i = 0; i < geometry.TriangleIndices.Count;)
    {
        Polygon p = new Polygon
        {
            Stroke = Brushes.Blue,
            StrokeThickness = 0.25
        };
        var tr = ((GeometryModel3D) MyVisual.Content).Transform;
        p.Points.Add(transform.Transform(tr.Transform(geometry.Positions[geometry.TriangleIndices[i++]])));
        p.Points.Add(transform.Transform(tr.Transform(geometry.Positions[geometry.TriangleIndices[i++]])));
        p.Points.Add(transform.Transform(tr.Transform(geometry.Positions[geometry.TriangleIndices[i++]])));
        foreach (Point point in p.Points)
        {
            wholeBounds.Union(point);
        }
    }
    MyRegion.Width = wholeBounds.Width;
    MyRegion.Height = wholeBounds.Height;

    MyRegion.Margin = new Thickness(wholeBounds.Left, wholeBounds.Top, 0, 0);
}

enter image description here

关于c# - WPF ModelVisual3D 的可见 2D 内容边界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46740152/

相关文章:

c# - 如何在面板中并排设置控件

c# - ConfigurationManager.GetSection 给出错误 "Could not load type....from assembly..."

c# - 如何防止在 WPF DataGrid 中取消选择?

c++ - 具有部分颜色写入的 OpenGL 全深度

CSS3 第二个 3D 视角

android - 适用于 android 的 native c++ 3d 数学/几何库?

c# - Visual Studio 2010 编辑器停止工作

c# - 将 IRandomAccessStreamWithContentType 转换为字节 []

wpf - 当 wpf 数据网格的单元格中的值使用 MVVM 更改时,如何引发事件?

c# - 在 Surface 上的 ScatterView 中使用 LibraryStacks