首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >WPF中的动态运行时三维点

WPF中的动态运行时三维点
EN

Stack Overflow用户
提问于 2021-07-04 12:14:06
回答 2查看 214关注 0票数 0

我试图使用WPF创建三维点的动态视图,我可以绘制第一组点,但是它会崩溃,因为Mesh3DGeometry被冻结了。是否需要解冻Mesh3DGeomerty并清除网格,以便绘制下一组?

代码语言:javascript
运行
复制
    var rand = new Random();
while (true)
{
    points.Clear();
    for (int i = 0; i < 100; i++)
    {
        points.Add(new Point3D(rand.NextDouble(), rand.NextDouble(), rand.NextDouble()));
    }
    for (int i = 0; i < points.Count; i++)
    {
        AddCubeToMesh(pointCloudMesh, points[i], 0.01);
    }
    pointCloudMesh.Freeze();
}

还有XAML在这里

代码语言:javascript
运行
复制
<Grid Grid.Row="1" Grid.Column="1"  Margin="0 20 0 -20" Background="LightGray" Name="MyCanvas" >
                <Viewport3D>
                    <Viewport3D.Camera>
                        <PerspectiveCamera x:Name="camMain" Position="0 0 5" LookDirection="0 0 -5"/>
                    </Viewport3D.Camera>

                    <ModelVisual3D>
                        <ModelVisual3D.Content>
                            <Model3DGroup>
                                <Model3DGroup.Children>
                                    <AmbientLight Color="#AAAAAA" />
                                </Model3DGroup.Children>
                            </Model3DGroup>
                        </ModelVisual3D.Content>
                    </ModelVisual3D>

                    <ModelVisual3D>
                        <ModelVisual3D.Content>
                            <GeometryModel3D>
                                <GeometryModel3D.Geometry>
                                    <MeshGeometry3D x:Name="pointCloudMesh" />
                                </GeometryModel3D.Geometry>
                                <GeometryModel3D.Material>
                                    <DiffuseMaterial Brush="Red"/>
                                </GeometryModel3D.Material>
                            </GeometryModel3D>
                        </ModelVisual3D.Content>
                    </ModelVisual3D>
                </Viewport3D>
            </Grid>

AddCubeToMesh代码

代码语言:javascript
运行
复制
private void AddCubeToMesh(MeshGeometry3D mesh, Point3D center, double size)
    {
        if (mesh != null)
        {
            int offset = mesh.Positions.Count;

            mesh.Positions.Add(new Point3D(center.X - size, center.Y + size, center.Z - size));
            mesh.Positions.Add(new Point3D(center.X + size, center.Y + size, center.Z - size));
            mesh.Positions.Add(new Point3D(center.X + size, center.Y + size, center.Z + size));
            mesh.Positions.Add(new Point3D(center.X - size, center.Y + size, center.Z + size));
            mesh.Positions.Add(new Point3D(center.X - size, center.Y - size, center.Z - size));
            mesh.Positions.Add(new Point3D(center.X + size, center.Y - size, center.Z - size));
            mesh.Positions.Add(new Point3D(center.X + size, center.Y - size, center.Z + size));
            mesh.Positions.Add(new Point3D(center.X - size, center.Y - size, center.Z + size));

            mesh.TriangleIndices.Add(offset + 3);
            mesh.TriangleIndices.Add(offset + 2);
            mesh.TriangleIndices.Add(offset + 6);

            mesh.TriangleIndices.Add(offset + 3);
            mesh.TriangleIndices.Add(offset + 6);
            mesh.TriangleIndices.Add(offset + 7);

            mesh.TriangleIndices.Add(offset + 2);
            mesh.TriangleIndices.Add(offset + 1);
            mesh.TriangleIndices.Add(offset + 5);

            mesh.TriangleIndices.Add(offset + 2);
            mesh.TriangleIndices.Add(offset + 5);
            mesh.TriangleIndices.Add(offset + 6);

            mesh.TriangleIndices.Add(offset + 1);
            mesh.TriangleIndices.Add(offset + 0);
            mesh.TriangleIndices.Add(offset + 4);

            mesh.TriangleIndices.Add(offset + 1);
            mesh.TriangleIndices.Add(offset + 4);
            mesh.TriangleIndices.Add(offset + 5);

            mesh.TriangleIndices.Add(offset + 0);
            mesh.TriangleIndices.Add(offset + 3);
            mesh.TriangleIndices.Add(offset + 7);

            mesh.TriangleIndices.Add(offset + 0);
            mesh.TriangleIndices.Add(offset + 7);
            mesh.TriangleIndices.Add(offset + 4);

            mesh.TriangleIndices.Add(offset + 7);
            mesh.TriangleIndices.Add(offset + 6);
            mesh.TriangleIndices.Add(offset + 5);

            mesh.TriangleIndices.Add(offset + 7);
            mesh.TriangleIndices.Add(offset + 5);
            mesh.TriangleIndices.Add(offset + 4);

            mesh.TriangleIndices.Add(offset + 2);
            mesh.TriangleIndices.Add(offset + 3);
            mesh.TriangleIndices.Add(offset + 0);

            mesh.TriangleIndices.Add(offset + 2);
            mesh.TriangleIndices.Add(offset + 0);
            mesh.TriangleIndices.Add(offset + 1);
        }
    }

我的解决方案是将所有这些添加到一个分离的UserControl中,并在每次新数据到达时调用它。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-07-12 14:43:34

我想出的解决方案是将Point Cloud视图与另一个用户控件分开,每当我想显示一组新的数据时,我就销毁旧的用户控件并重新构建它。这是一种咄咄逼人的方法,但效果很好

用于新用户控件的XAML

代码语言:javascript
运行
复制
<UserControl x:Class="LPDTool.View3D"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:LPDTool"
         mc:Ignorable="d" 
         d:DesignHeight="500" d:DesignWidth="500"
         KeyDown="Window_KeyDown">
<GroupBox x:Name="GBox" Margin="0 20 0 -20" Foreground="#AAAAAA" FontSize="18" FontWeight="Medium" Background="#DDDBDA" BorderBrush="#7B7704" BorderThickness="2" FontFamily="Abadi MT">
    <Viewport3D>
        <Viewport3D.Camera>
            <PerspectiveCamera x:Name="camMain"/>
        </Viewport3D.Camera>
        <ModelVisual3D>
            <ModelVisual3D.Content>
                <Model3DGroup>
                    <Model3DGroup.Children>
                        <AmbientLight Color="#AAAAAA" />
                    </Model3DGroup.Children>
                </Model3DGroup>
            </ModelVisual3D.Content>
        </ModelVisual3D>
        <ModelVisual3D>
            <ModelVisual3D.Content>
                <GeometryModel3D>
                    <GeometryModel3D.Geometry>
                        <MeshGeometry3D x:Name="pointCloudMesh" />
                    </GeometryModel3D.Geometry>
                    <GeometryModel3D.Material>
                        <DiffuseMaterial Brush="Red"/>
                    </GeometryModel3D.Material>
                </GeometryModel3D>
            </ModelVisual3D.Content>
        </ModelVisual3D>
    </Viewport3D>
</GroupBox>

初始化构造器

代码语言:javascript
运行
复制
public View3D()
    {

        InitializeComponent();
        PositionCamera();

        for (int i = 0; i < LPDTest.points.Count; i++)
        {
            AddCubeToMesh(pointCloudMesh, points[i], 0.02);
        }
    }

包含部分的XAML

代码语言:javascript
运行
复制
<Grid x:Name="My3dview">

</Grid>

下面是生成代码部分(使用矮胖数据)

代码语言:javascript
运行
复制
var rand = new Random();
while (true)
{
    My3dview.Children.Clear();
    points.Clear();
    for (int i = 0; i < 100; i++)
    {
        points.Add(new Point3D(rand.NextDouble(), rand.NextDouble(), rand.NextDouble()));
    }
    My3dview.Children.Add(new View3D());
}
票数 0
EN

Stack Overflow用户

发布于 2021-07-06 15:31:41

首先:一个不给UI线程时间而生成UI部件的没完没了的循环是行不通的。在独立线程上生成数据,并将数据传递给UI线程以创建模型并显示它。

那么,解冻冷冻是不可能的:

“解冻”一个可冻结的克隆一旦冻结,就永远不能被修改或解冻;但是,您可以使用clone或CloneCurrentValue方法创建一个未冻结的克隆。

来源

所以,如果你认为它真的需要冻结/解冻,你可以通过克隆来完成。我不认为这里需要它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68244615

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档