66using System . Linq ;
77using Color = PointCloudConverter . Structs . Color ;
88using System . Diagnostics ;
9+ using static Ply . Net . PlyParser ;
10+ using System . Collections . Immutable ;
911
1012namespace 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