Skip to content

Commit fa50c2e

Browse files
committed
require importformat before input folder for Batch, add missing ply reader, default importformat is unknown now
1 parent 52b3e82 commit fa50c2e

File tree

4 files changed

+202
-10
lines changed

4 files changed

+202
-10
lines changed

MainWindow.xaml.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,12 +1100,13 @@ void StartProcess(bool doProcess = true)
11001100
if (inputFile.Contains(" ")) inputFile = "\"" + inputFile + "\"";
11011101
if (outputFile.Contains(" ")) outputFile = "\"" + outputFile + "\"";
11021102

1103-
args.Add("-input=" + inputFile);
1104-
11051103
if (cmbImportFormat.SelectedItem != null)
11061104
{
11071105
args.Add("-importformat=" + cmbImportFormat.SelectedItem.ToString());
11081106
}
1107+
1108+
args.Add("-input=" + inputFile);
1109+
11091110
if (cmbExportFormat.SelectedItem != null)
11101111
{
11111112
args.Add("-exportformat=" + cmbExportFormat.SelectedItem.ToString());

Readers/PLY.cs

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
using PointCloudConverter.Structs;
2+
using Ply.Net;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.IO;
6+
using System.Linq;
7+
using Color = PointCloudConverter.Structs.Color;
8+
using System.Diagnostics;
9+
10+
namespace PointCloudConverter.Readers
11+
{
12+
public class PLY : IReader, IDisposable
13+
{
14+
private PlyParser.Dataset dataset;
15+
private int pointIndex;
16+
private int pointCount;
17+
18+
private PlyParser.PropertyData px, py, pz;
19+
private PlyParser.PropertyData pr, pg, pb;
20+
//private PlyParser.PropertyData pintensity, pclass, ptime;
21+
22+
private Float3 currentPoint;
23+
private Color currentColor;
24+
// private double currentTime;
25+
// private byte currentIntensity;
26+
// private byte currentClassification;
27+
private Bounds bounds;
28+
29+
public bool InitReader(ImportSettings importSettings, int fileIndex)
30+
{
31+
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+
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");
47+
48+
pr = vertexElement["red"];
49+
pg = vertexElement["green"];
50+
pb = vertexElement["blue"];
51+
52+
Debug.WriteLine($"PLY: {file} has {pointCount} points");
53+
Debug.WriteLine($"PLY: {file} has {pr.Data.Length} pr values");
54+
55+
56+
//pa = vertexElement["alpha"];
57+
// pintensity = vertexElement["intensity"] ?? vertexElement["scalar_intensity"];
58+
// pclass = vertexElement["classification"] ?? vertexElement["scalar_classification"];
59+
// ptime = vertexElement["time"];
60+
61+
CalculateBounds();
62+
pointIndex = 0;
63+
64+
return true;
65+
}
66+
67+
public int GetPointCount() => pointCount;
68+
69+
public Bounds GetBounds() => bounds;
70+
71+
public Float3 GetXYZ()
72+
{
73+
if (pointIndex >= pointCount)
74+
return new Float3 { hasError = true };
75+
76+
currentPoint = new Float3
77+
{
78+
x = Convert.ToSingle(px.Data.GetValue(pointIndex)),
79+
y = Convert.ToSingle(py.Data.GetValue(pointIndex)),
80+
z = Convert.ToSingle(pz.Data.GetValue(pointIndex)),
81+
hasError = false
82+
};
83+
84+
//Trace.WriteLine($"PLY: {pointIndex} {pr.Data.GetValue(pointIndex)} {pg.Data.GetValue(pointIndex)} {pb.Data.GetValue(pointIndex)}");
85+
currentColor = new Color
86+
{
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
90+
};
91+
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++;
100+
return currentPoint;
101+
}
102+
103+
public Color GetRGB()
104+
{
105+
//currentColor = new Color();
106+
//currentColor.r = 255;
107+
//currentColor.g = 0;
108+
//currentColor.b = 0;
109+
return currentColor;
110+
}
111+
112+
public double GetTime()
113+
{
114+
return 0.0;
115+
}
116+
117+
public byte GetIntensity()
118+
{
119+
return 0;
120+
}
121+
122+
public byte GetClassification()
123+
{
124+
return 0;
125+
}
126+
127+
// TODO return ply data
128+
public LasHeader GetMetaData(ImportSettings importSettings, int fileIndex)
129+
{
130+
return new LasHeader
131+
{
132+
FileName = importSettings.inputFiles[fileIndex],
133+
NumberOfPointRecords = (uint)pointCount,
134+
MinX = bounds.minX,
135+
MaxX = bounds.maxX,
136+
MinY = bounds.minY,
137+
MaxY = bounds.maxY,
138+
MinZ = bounds.minZ,
139+
MaxZ = bounds.maxZ
140+
};
141+
}
142+
143+
public void Close()
144+
{
145+
dataset = null;
146+
}
147+
148+
public void Dispose() => Close();
149+
150+
private void CalculateBounds()
151+
{
152+
// NOTE doesnt support BINARY ply
153+
154+
// need to calculate manually
155+
bounds = new Bounds
156+
{
157+
minX = float.MaxValue,
158+
maxX = float.MinValue,
159+
minY = float.MaxValue,
160+
maxY = float.MinValue,
161+
minZ = float.MaxValue,
162+
maxZ = float.MinValue
163+
};
164+
165+
for (int i = 0; i < pointCount; i++)
166+
{
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);
177+
}
178+
}
179+
}
180+
}

Structs/ImportSettings.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ public void ReleaseReader(int? taskId)
178178
public float scale { get; set; } = 1f;
179179

180180
[JsonConverter(typeof(JsonStringEnumConverter))]
181-
public ImportFormat importFormat { get; set; } = ImportFormat.LAS; //default to las for now
181+
public ImportFormat importFormat { get; set; } = ImportFormat.Unknown; //default to las for now
182182
[JsonConverter(typeof(JsonStringEnumConverter))]
183183
public ExportFormat exportFormat { get; set; }
184184

Tools/ArgParser.cs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -245,18 +245,29 @@ public static ImportSettings Parse(string[] args, string rootFolder, ILogger log
245245

246246
// TODO get file extension from commandline param? but then need to set -format before input.. for now only LAS/LAZ
247247
// TODO parse/sort args in required order, not in given order
248-
var filePaths = Directory.GetFiles(param).Where(file => Regex.IsMatch(file, @"^.+\.(las|laz|ply)$", RegexOptions.IgnoreCase)).ToArray();
249248

250-
251-
for (int j = 0; j < filePaths.Length; j++)
249+
if (importSettings.importFormat == ImportFormat.Unknown)
252250
{
253-
Console.ForegroundColor = ConsoleColor.Gray;
254-
Log.Write("Found file: " + filePaths[j]);
255-
Console.ForegroundColor = ConsoleColor.White;
256-
importSettings.inputFiles.Add(filePaths[j]);
251+
importSettings.errors.Add("Import format not defined before -input folder for batch (use -importformat" + argValueSeparator + "LAS or PLY)");
257252
}
253+
else
254+
{
255+
string importExtensions = "";
256+
if (importSettings.importFormat == ImportFormat.LAS) importExtensions = "las|laz";
257+
if (importSettings.importFormat == ImportFormat.PLY) importExtensions = "ply";
258+
var filePaths = Directory.GetFiles(param).Where(file => Regex.IsMatch(file, @"^.+\.(" + importExtensions + ")$", RegexOptions.IgnoreCase)).ToArray();
259+
260+
for (int j = 0; j < filePaths.Length; j++)
261+
{
262+
Console.ForegroundColor = ConsoleColor.Gray;
263+
Log.Write("Found file: " + filePaths[j]);
264+
Console.ForegroundColor = ConsoleColor.White;
265+
importSettings.inputFiles.Add(filePaths[j]);
266+
}
258267

268+
}
259269
importSettings.batch = true;
270+
260271
}
261272
else // single file
262273
{

0 commit comments

Comments
 (0)