'Displaying .ply Point Cloud in C# using Helix-Toolkit

I'm trying to create a Point Cloud from a .ply File which holds vertices (v x y z r g b) and their color recorded from a Kinect v2. What I've tried so far:

At first I used MeshLab to check whether my .ply File is correct. It is. So I tried to export the .ply file as .obj to use Helix-Toolkits

HelixToolkit.Wpf.ModelImporter

However, this gives me a blank screen, both when using my own code and the ModelViewer in the Helix-Toolkit Examples. This is probably due to the fact that the ply file holds no information about the faces.

1. Is there a simple way to create an obj file from ply, adding faces in the process?

2. Is there another - possibly better way - to create Points from the ply file and displaying them on screen using Helix?



Solution 1:[1]

I'll tackle your second question, as I have no knowledge with regards to your first question.

Assuming you can read in the vertex data, Read the cloud data into a collection structure like a Point3D list.

Point3DCollection dataList = new Point3DCollection();

//read from ply file and append the positions to the dataList. i.e. dataList.Add(new Point3D(x,y,x));
PointsVisual3D cloudPoints = new PointsVisual3D { Color = Colors.Red, Size = 5 };

cloudPoints.Points = dataList;

In your XAML give the helix viewport a name so it can be refenced in C#

<h:HelixViewport3D x:Name="HViewPort">
<h:DefaultLights/>

</h:HelixViewport3D>

In c#

HViewPort.Children.Add(cloudPoints);

NB: This will display all the points with the same colour that was specified on initialisation. So it maybe worth retaining the rgb values of your data in a seperate list.

To date I have no idea of how to assign the colour to individual PointVisual3D. If you figure it out please share.

An alternative would be to create individual 3D spheres centered around the dataPoints and then assign them the recorded rgb vals. I would be mindfull of this approach as its performance heavy and dependent on the data size.

Good luck :)

Solution 2:[2]

Just to build upon the other answer, you can set the Points property of PointsVisual3D in XAML via binding, MVVM-style:

<helix:HelixViewport3D>
    <helix:DefaultLights/>
    <helix:PointsVisual3D Color="Black" Size="2" Points="{Binding dataList}"/>
</helix:HelixViewport3D>

Solution 3:[3]

It is necessary to create an instance of the importer class, and in the XAML file the compiler asks you to place the model declaration before the camera is declared.

cpp file:

ModelImporter importer = new ModelImporter();
Model3DGroup model=importer.Load("model_file.ply");
MyModel.Content = model;

XAML:

<helix:HelixViewport3D x:Name="viewPort3d">
    <ModelVisual3D x:Name="MyModel"/>
    <helix:HelixViewport3D.Camera>
        <PerspectiveCamera UpDirection="-0.00794080933244957, 0.909926622339627, 0.414693242656239"
                           LookDirection="49.636719684, -2387.8047, -29918.6652549283"
                           Position="-48.6367196, 5688.80470553634, 29917.665254"/>

    </helix:HelixViewport3D.Camera>
</helix:HelixViewport3D>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 heltonbiker
Solution 3 Kate_Relate