WPF 3D图形循环时间过长

amrnrhlw  于 2023-01-27  发布在  其他
关注(0)|答案(1)|浏览(131)

我试图创建goldbergs多面体,但代码,应该画它在我的屏幕上工作太慢(约22秒,以绘制第6级的detalization)

Stopwatch sw = new Stopwatch();

        var hexes = sphere.hexes.ToArray();

        sw.Start();

        for (int j = 0; j < hexes.Length; j++)
        {
            MeshGeometry3D myMeshGeometry3D = new MeshGeometry3D();

            Vector3DCollection myNormalCollection = new Vector3DCollection();

            foreach (var verts in hexes[j].Normals)
            {
                myNormalCollection.Add(verts);
            }

            myMeshGeometry3D.Normals = myNormalCollection;

            Point3DCollection myPositionCollection = new Point3DCollection();

            foreach (var verts in hexes[j].Normals)
            {
                myPositionCollection.Add(new Point3D(verts.X, verts.Y, verts.Z));
            }

            myMeshGeometry3D.Positions = myPositionCollection;

            Int32Collection myTriangleIndicesCollection = new Int32Collection();

            foreach (var triangle in hexes[j].Tris)
            {
                myTriangleIndicesCollection.Add(triangle);
            }

            myMeshGeometry3D.TriangleIndices = myTriangleIndicesCollection;                

            Material material = new DiffuseMaterial(
                            new SolidColorBrush(Colors.Black)); ;

            if (switcher)
            {
                material = new DiffuseMaterial(
                            new SolidColorBrush(Colors.BlueViolet)); 
            }

            switcher = !switcher;

            GeometryModel3D model = new GeometryModel3D(
                myMeshGeometry3D, material);

            myGeometryModel.Geometry = myMeshGeometry3D;

            myModel3DGroup.Children.Add(model);

            myModel3DGroup.Children.Add(myGeometryModel);                
        }

        sw.Stop();

我试着让循环并行,但是myGeometryModelmyModel3DGroup在主线程中,所以我不能修改它们。

wd2eg0qa

wd2eg0qa1#

我认为所有重要的东西都是可冷冻的。
.Freeze()是一个freezable,可以提高性能,但也可以将它从一个线程传递到另一个线程。
您可以在多个并行后台线程上完成大部分工作。
例如,每个十六进制可以建立在一组并行的工作线程上。每个线程建立自己的myMeshGeometry3D,并将其冻结并返回给调用线程。
简单地说,你有一个任务DoMeshGeom3D(int j),它返回你的一个三维几何体。
您可以使用plinq或task.whenall或parallel.foreach
大致

var taskList = new List<Task<MeshGeometry3D>>();

 for (int j = 0; j < hexes.Length; j++)
 {
    taskList.Add(DoMeshGeom3D(j));
 }

 var result = await Task.WhenAll(taskList.ToList());

抓取您的众多MeshGeometry3D列表并将它们组装在一起。
您可能正在另一个任务的后台线程上等待。
你也可以尝试使用在单独线程中构造的这些东西的列表或ienumerable来构造你的3dgroup,而不是一次添加一个。
https://briancaos.wordpress.com/2020/09/11/run-tasks-in-parallel-using-net-core-c-and-async-coding/
https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.whenall?view=netcore-3.1

相关问题