Rendering point clouds in WPF Viewport3D is extremely slow
I am trying to render a ~ 170,000 point cloud using WPF Viewport3D. After creating the coordinates of the 3D points, I create a triangle with a specific size at each point and add it to the Model3DGroup object, which I add to my Viewport aftwerwards.
My problem is that the code below only takes 3 seconds to run. After the Model3DGroup is added to the Viewport, the UI will freeze for another 3-5 seconds.
How can I make this work faster? Also, if the Viewport3D cannot handle the models of that number, can anyone recommend an alternative way to render the point cloud in a WPF control?
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);
source to share
Per This page :
Only create different models when they require different Materials or Transforms. If not, try combining many GeometryModel3D instances with the same Materials and Transforms into a somewhat larger GeometryModel3D and MeshGeometry3D.
Instead of creating multiple, MeshGeometry3D
create just one and add it to one GeometryModel3D
. Add this one GeometeryModel3D
to yours ModelVisual3D
. This should significantly improve the performance of your model (I've experienced this myself).
For additional speed improvements, you can create your positions in parallel ( Parallel.ForEach Example )
List<Point3D> points = new List<Point3D>();
Parallel.ForEach(workspace.PointCloud, point =>
{
//Do Work
}
);
Point3DCollection p3d = new Point3DCollection(points);
mymesh.Positions = p3d;
I have not tested this code. More work might be needed to get it to run in parallel. Don't forget to create points in triplets, otherwise you will get points in a very strange order that will create crazy triangles.
You can skip this TriangleIndices
as they are displayed if not specified. Though I doubt you will buy you a lot of processing time and I'm not sure if this will affect performance later.
source to share