3

I am trying to visualize a point cloud of ~170000 points using WPF's Viewport3D control. After generating the 3D point coordinates I create a triangle with a certain size at each point and add it to a Model3DGroup object which I append to my Viewport aftwerwards.

My problem is that the code below responsible for this takes 3 seconds alone to run. After the Model3DGroup has been added to the Viewport the UI is frozen for another 3-5 seconds more.

How can I make this work faster? Also if Viewport3D can't handle models of this number can anyone recommend an alternative way of visualizing a 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);
András Kovács
  • 847
  • 1
  • 10
  • 29
  • Even after your optimization efforts, I don't believe you will see the results you are searching for. You may be better served with a pure native solution and D3D. Looks like a fun project. Good luck. – Jeff Jul 06 '15 at 13:57

1 Answers1

2

Per This Page:

Create different models only when they require different Materials or Transforms. Otherwise, try to coalesce many GeometryModel3D instances with the same Materials and Transforms into a few larger GeometryModel3D and MeshGeometry3D instances.

Instead of creating multiple MeshGeometry3D create just one and add it to a single GeometryModel3D. Add that single GeometeryModel3D to your ModelVisual3D. This should significantly improve the performance of your model (I've experienced this myself).

For additional speed improvements you may be able to 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 haven't tested this code. There may be some additional work required to get it to work in parallel. Be sure to create the points in triplets, otherwise you'll get points in a very weird order which will create some crazy triangles.

You can skip the specifying of TriangleIndices as they are inferred if not specified. Although I doubt that will buy you much processing time and I'm unsure if it has performance impacts later.

MikeH
  • 4,242
  • 1
  • 17
  • 32
  • hmm...I didn't notice until after I posted this that the question is 2 months old! Oh, well...For posterity! – MikeH Sep 04 '15 at 22:09