Skip to content

Commit 40a7db3

Browse files
committed
fix ply reader
1 parent 029aae4 commit 40a7db3

File tree

2 files changed

+74
-57
lines changed

2 files changed

+74
-57
lines changed

MainWindow.xaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ namespace PointCloudConverter
3030
{
3131
public partial class MainWindow : Window
3232
{
33-
static readonly string version = "08.04.2025";
33+
static readonly string version = "04.05.2025";
3434
static readonly string appname = "PointCloud Converter - " + version;
3535
static readonly string rootFolder = AppDomain.CurrentDomain.BaseDirectory;
3636

Readers/PLY.cs

Lines changed: 73 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
using System.Linq;
77
using Color = PointCloudConverter.Structs.Color;
88
using System.Diagnostics;
9+
using static Ply.Net.PlyParser;
10+
using System.Collections.Immutable;
911

1012
namespace PointCloudConverter.Readers
1113
{
@@ -15,8 +17,13 @@ public class PLY : IReader, IDisposable
1517
private int pointIndex;
1618
private int pointCount;
1719

18-
private PlyParser.PropertyData px, py, pz;
19-
private PlyParser.PropertyData pr, pg, pb;
20+
private List<ElementData> vertexChunks;
21+
private int currentChunkIndex;
22+
private int currentPointInChunk;
23+
24+
private PropertyData px, py, pz;
25+
private PropertyData pr, pg, pb;
26+
2027
//private PlyParser.PropertyData pintensity, pclass, ptime;
2128

2229
private Float3 currentPoint;
@@ -29,39 +36,26 @@ public class PLY : IReader, IDisposable
2936
public bool InitReader(ImportSettings importSettings, int fileIndex)
3037
{
3138
var file = importSettings.inputFiles[fileIndex];
32-
using var stream = File.OpenRead(file);
33-
dataset = PlyParser.Parse(stream, 1024);
34-
35-
//var info = PlyParser.ParseHeader(file);
36-
//var infoVertices = info.Elements.FirstOrDefault(x => x.Type == PlyParser.ElementType.Vertex);
37-
//Trace.WriteLine($"PLY: {file} has {infoVertices?.Count} vertices");
38-
39-
var vertexElement = dataset.Data.FirstOrDefault(d => d.Element.Type == PlyParser.ElementType.Vertex);
40-
if (vertexElement == null) return false;
41-
42-
pointCount = vertexElement.Data[0].Data.Length;
4339

44-
px = vertexElement["x"] ?? throw new Exception("Missing 'x' property in PLY file");
45-
py = vertexElement["y"] ?? throw new Exception("Missing 'y' property in PLY file");
46-
pz = vertexElement["z"] ?? throw new Exception("Missing 'z' property in PLY file");
40+
using var stream = File.OpenRead(file);
41+
dataset = PlyParser.Parse(stream, 4096);
4742

48-
pr = vertexElement["red"];
49-
pg = vertexElement["green"];
50-
pb = vertexElement["blue"];
43+
vertexChunks = dataset.Data
44+
.Where(d => d.Element.Type == ElementType.Vertex)
45+
.ToList();
5146

52-
Debug.WriteLine($"PLY: {file} has {pointCount} points");
53-
Debug.WriteLine($"PLY: {file} has {pr.Data.Length} pr values");
47+
if (vertexChunks.Count == 0) return false;
5448

49+
pointCount = vertexChunks.Sum(chunk => ((Array)chunk.Data[0].Data).Length);
50+
currentChunkIndex = 0;
51+
currentPointInChunk = 0;
5552

56-
//pa = vertexElement["alpha"];
57-
// pintensity = vertexElement["intensity"] ?? vertexElement["scalar_intensity"];
58-
// pclass = vertexElement["classification"] ?? vertexElement["scalar_classification"];
59-
// ptime = vertexElement["time"];
53+
SetCurrentChunkProperties(); // helper method to cache px, py, pz, etc.
6054

6155
CalculateBounds();
62-
pointIndex = 0;
6356

6457
return true;
58+
6559
}
6660

6761
public int GetPointCount() => pointCount;
@@ -70,36 +64,40 @@ public bool InitReader(ImportSettings importSettings, int fileIndex)
7064

7165
public Float3 GetXYZ()
7266
{
73-
if (pointIndex >= pointCount)
67+
if (currentChunkIndex >= vertexChunks.Count)
7468
return new Float3 { hasError = true };
7569

70+
int chunkSize = ((Array)px.Data).Length;
71+
if (currentPointInChunk >= chunkSize)
72+
{
73+
currentChunkIndex++;
74+
if (currentChunkIndex >= vertexChunks.Count)
75+
return new Float3 { hasError = true };
76+
77+
currentPointInChunk = 0;
78+
SetCurrentChunkProperties();
79+
}
80+
7681
currentPoint = new Float3
7782
{
78-
x = Convert.ToSingle(px.Data.GetValue(pointIndex)),
79-
y = Convert.ToSingle(py.Data.GetValue(pointIndex)),
80-
z = Convert.ToSingle(pz.Data.GetValue(pointIndex)),
83+
x = Convert.ToSingle(px.Data.GetValue(currentPointInChunk)),
84+
y = Convert.ToSingle(py.Data.GetValue(currentPointInChunk)),
85+
z = Convert.ToSingle(pz.Data.GetValue(currentPointInChunk)),
8186
hasError = false
8287
};
8388

84-
//Trace.WriteLine($"PLY: {pointIndex} {pr.Data.GetValue(pointIndex)} {pg.Data.GetValue(pointIndex)} {pb.Data.GetValue(pointIndex)}");
8589
currentColor = new Color
8690
{
87-
r = pr != null ? Convert.ToSingle(Convert.ToByte(pr.Data.GetValue(pointIndex))) / 255f : 1f,
88-
g = pg != null ? Convert.ToSingle(Convert.ToByte(pg.Data.GetValue(pointIndex))) / 255f : 1f,
89-
b = pb != null ? Convert.ToSingle(Convert.ToByte(pb.Data.GetValue(pointIndex))) / 255f : 1f
91+
r = Convert.ToSingle(Convert.ToByte(pr.Data.GetValue(currentPointInChunk))) / 255f,
92+
g = Convert.ToSingle(Convert.ToByte(pg.Data.GetValue(currentPointInChunk))) / 255f,
93+
b = Convert.ToSingle(Convert.ToByte(pb.Data.GetValue(currentPointInChunk))) / 255f
9094
};
9195

92-
93-
//Trace.WriteLine($"PLY: {pointIndex} {currentColor.r} {currentColor.g} {currentColor.b}");
94-
95-
// currentIntensity = pintensity != null ? Convert.ToByte(pintensity.Data.GetValue(pointIndex)) : (byte)0;
96-
// currentClassification = pclass != null ? Convert.ToByte(pclass.Data.GetValue(pointIndex)) : (byte)0;
97-
// currentTime = ptime != null ? Convert.ToDouble(ptime.Data.GetValue(pointIndex)) : 0.0;
98-
99-
pointIndex++;
96+
currentPointInChunk++;
10097
return currentPoint;
10198
}
10299

100+
103101
public Color GetRGB()
104102
{
105103
//currentColor = new Color();
@@ -149,9 +147,6 @@ public void Close()
149147

150148
private void CalculateBounds()
151149
{
152-
// NOTE doesnt support BINARY ply
153-
154-
// need to calculate manually
155150
bounds = new Bounds
156151
{
157152
minX = float.MaxValue,
@@ -162,24 +157,46 @@ private void CalculateBounds()
162157
maxZ = float.MinValue
163158
};
164159

165-
for (int i = 0; i < pointCount; i++)
160+
foreach (var chunk in vertexChunks)
166161
{
167-
float x = Convert.ToSingle(px.Data.GetValue(i));
168-
float y = Convert.ToSingle(py.Data.GetValue(i));
169-
float z = Convert.ToSingle(pz.Data.GetValue(i));
170-
171-
bounds.minX = Math.Min(bounds.minX, x);
172-
bounds.maxX = Math.Max(bounds.maxX, x);
173-
bounds.minY = Math.Min(bounds.minY, y);
174-
bounds.maxY = Math.Max(bounds.maxY, y);
175-
bounds.minZ = Math.Min(bounds.minZ, z);
176-
bounds.maxZ = Math.Max(bounds.maxZ, z);
162+
var cx = chunk["x"]!;
163+
var cy = chunk["y"]!;
164+
var cz = chunk["z"]!;
165+
int count = ((Array)cx.Data).Length;
166+
167+
for (int i = 0; i < count; i++)
168+
{
169+
float x = Convert.ToSingle(cx.Data.GetValue(i));
170+
float y = Convert.ToSingle(cy.Data.GetValue(i));
171+
float z = Convert.ToSingle(cz.Data.GetValue(i));
172+
173+
bounds.minX = Math.Min(bounds.minX, x);
174+
bounds.maxX = Math.Max(bounds.maxX, x);
175+
bounds.minY = Math.Min(bounds.minY, y);
176+
bounds.maxY = Math.Max(bounds.maxY, y);
177+
bounds.minZ = Math.Min(bounds.minZ, z);
178+
bounds.maxZ = Math.Max(bounds.maxZ, z);
179+
}
177180
}
178181
}
179182

183+
180184
ushort IReader.GetIntensity()
181185
{
182186
return GetIntensity();
183187
}
188+
189+
private void SetCurrentChunkProperties()
190+
{
191+
var chunk = vertexChunks[currentChunkIndex];
192+
px = chunk["x"] ?? throw new Exception("Missing 'x' property");
193+
py = chunk["y"] ?? throw new Exception("Missing 'y' property");
194+
pz = chunk["z"] ?? throw new Exception("Missing 'z' property");
195+
pr = chunk["red"] ?? throw new Exception("Missing 'red' property");
196+
pg = chunk["green"] ?? throw new Exception("Missing 'green' property");
197+
pb = chunk["blue"] ?? throw new Exception("Missing 'blue' property");
198+
}
199+
200+
184201
}
185202
}

0 commit comments

Comments
 (0)