6
6
using System . Linq ;
7
7
using Color = PointCloudConverter . Structs . Color ;
8
8
using System . Diagnostics ;
9
+ using static Ply . Net . PlyParser ;
10
+ using System . Collections . Immutable ;
9
11
10
12
namespace PointCloudConverter . Readers
11
13
{
@@ -15,8 +17,13 @@ public class PLY : IReader, IDisposable
15
17
private int pointIndex ;
16
18
private int pointCount ;
17
19
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
+
20
27
//private PlyParser.PropertyData pintensity, pclass, ptime;
21
28
22
29
private Float3 currentPoint ;
@@ -29,39 +36,26 @@ public class PLY : IReader, IDisposable
29
36
public bool InitReader ( ImportSettings importSettings , int fileIndex )
30
37
{
31
38
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 ;
43
39
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 ) ;
47
42
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 ( ) ;
51
46
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 ;
54
48
49
+ pointCount = vertexChunks . Sum ( chunk => ( ( Array ) chunk . Data [ 0 ] . Data ) . Length ) ;
50
+ currentChunkIndex = 0 ;
51
+ currentPointInChunk = 0 ;
55
52
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.
60
54
61
55
CalculateBounds ( ) ;
62
- pointIndex = 0 ;
63
56
64
57
return true ;
58
+
65
59
}
66
60
67
61
public int GetPointCount ( ) => pointCount ;
@@ -70,36 +64,40 @@ public bool InitReader(ImportSettings importSettings, int fileIndex)
70
64
71
65
public Float3 GetXYZ ( )
72
66
{
73
- if ( pointIndex >= pointCount )
67
+ if ( currentChunkIndex >= vertexChunks . Count )
74
68
return new Float3 { hasError = true } ;
75
69
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
+
76
81
currentPoint = new Float3
77
82
{
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 ) ) ,
81
86
hasError = false
82
87
} ;
83
88
84
- //Trace.WriteLine($"PLY: {pointIndex} {pr.Data.GetValue(pointIndex)} {pg.Data.GetValue(pointIndex)} {pb.Data.GetValue(pointIndex)}");
85
89
currentColor = new Color
86
90
{
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
90
94
} ;
91
95
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 ++ ;
100
97
return currentPoint ;
101
98
}
102
99
100
+
103
101
public Color GetRGB ( )
104
102
{
105
103
//currentColor = new Color();
@@ -149,9 +147,6 @@ public void Close()
149
147
150
148
private void CalculateBounds ( )
151
149
{
152
- // NOTE doesnt support BINARY ply
153
-
154
- // need to calculate manually
155
150
bounds = new Bounds
156
151
{
157
152
minX = float . MaxValue ,
@@ -162,24 +157,46 @@ private void CalculateBounds()
162
157
maxZ = float . MinValue
163
158
} ;
164
159
165
- for ( int i = 0 ; i < pointCount ; i ++ )
160
+ foreach ( var chunk in vertexChunks )
166
161
{
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
+ }
177
180
}
178
181
}
179
182
183
+
180
184
ushort IReader . GetIntensity ( )
181
185
{
182
186
return GetIntensity ( ) ;
183
187
}
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
+
184
201
}
185
202
}
0 commit comments