WPF Viewport3D中的点云可视化非常缓慢。

3
我正在尝试使用WPF的Viewport3D控件可视化一个约170000个点的点云。在生成3D点坐标后,我在每个点上创建一个特定大小的三角形,并将其添加到一个Model3DGroup对象中,然后将其附加到我的Viewport之后。
我的问题是,下面的代码负责这个过程需要独自运行3秒钟。在Model3DGroup已经添加到Viewport后,UI仍会再次冻结3-5秒钟。
如何使它更快?如果Viewport3D无法处理此数量的模型,是否有人可以推荐一种替代方法来在WPF控件中显示点云?
        viewport.Children.Clear();

        Model3DGroup triangles = new Model3DGroup();
        foreach (Point3D point in workspace.PointCloud)
        {
            double x = point.X;
            double y = point.Y;
            double z = point.Z;

            Point3D p1 = new Point3D(x + 0.005, y, z);
            Point3D p2 = new Point3D(x, y + 0.005, z);

            MeshGeometry3D mymesh = new MeshGeometry3D();
            mymesh.Positions.Add(point);
            mymesh.Positions.Add(p1);
            mymesh.Positions.Add(p2);
            mymesh.TriangleIndices.Add(0);
            mymesh.TriangleIndices.Add(1);
            mymesh.TriangleIndices.Add(2);

            Vector3D Normal = GeometryHelper.CalculateTraingleNormal(p0, p1, p2);
            mymesh.Normals.Add(Normal);
            mymesh.Normals.Add(Normal);
            mymesh.Normals.Add(Normal);

            Material Material = new DiffuseMaterial(
                new SolidColorBrush(Colors.Red) { Opacity = 0.5 });
            GeometryModel3D model = new GeometryModel3D(
                mymesh, Material);

            triangles.Children.Add(model);
        }

        ModelVisual3D modelVisual = new ModelVisual3D();
        modelVisual.Content = triangles;
        viewport.Children.Add(modelVisual);

即使您进行了优化,我仍然不相信您会看到您正在寻找的结果。您可能会更好地使用纯本地解决方案和D3D。看起来像是一个有趣的项目。祝你好运。 - Jeff
1个回答

2
根据此页面,只有当需要不同的材料或变换时才创建不同的模型。否则,尝试将具有相同材料和变换的多个GeometryModel3D实例合并为几个较大的GeometryModel3D和MeshGeometry3D实例。
不要创建多个MeshGeometry3D,只需创建一个并将其添加到单个GeometryModel3D中。然后将该单个GeometeryModel3D添加到您的ModelVisual3D中。这应显着提高模型的性能(我自己也经历过)。
为了获得更快的性能改进,您可以尝试使用并行方式创建位置(例如:Parallel.ForEach示例)。
      List<Point3D> points = new List<Point3D>();
      Parallel.ForEach(workspace.PointCloud, point =>
      {
        //Do Work
      }
      );
      Point3DCollection p3d = new Point3DCollection(points);
      mymesh.Positions = p3d;

我没有测试过这段代码。为了让它在并行环境下正常工作,可能需要做一些额外的工作。请确保以三元组的形式创建点,否则你将得到一些非常奇怪的顺序,从而创建一些疯狂的三角形。

你可以跳过指定TriangleIndices,因为如果未指定,则会被推断出来。虽然我怀疑这不会节省太多处理时间,而且我不确定它是否会对后面的性能产生影响。


嗯...我发完帖子后才注意到这个问题已经两个月了!哦,好吧...为了后人! - MikeH

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接