Skip to content

Commit 622e181

Browse files
committed
add initial E57 support
1 parent b88d408 commit 622e181

File tree

7 files changed

+209
-3
lines changed

7 files changed

+209
-3
lines changed

MainWindow.xaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ namespace PointCloudConverter
2929
{
3030
public partial class MainWindow : Window
3131
{
32-
static readonly string version = "03.04.2025";
32+
static readonly string version = "17.05.2025";
3333
static readonly string appname = "PointCloud Converter - " + version;
3434
static readonly string rootFolder = AppDomain.CurrentDomain.BaseDirectory;
3535

PointCloudConverter.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
</ItemGroup>
3535

3636
<ItemGroup>
37+
<PackageReference Include="Aardvark.Base" Version="5.3.12" />
38+
<PackageReference Include="Aardvark.Data.E57" Version="5.5.6" />
3739
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" />
3840
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
3941
<PackageReference Include="Ply.Net" Version="5.5.5" />

Readers/E57.cs

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
using System;
2+
using System.IO;
3+
using System.Collections.Generic;
4+
using Aardvark.Base;
5+
using Aardvark.Data.Points.Import;
6+
using PointCloudConverter.Structs;
7+
using static Aardvark.Data.Points.Import.E57;
8+
using Aardvark.Data.Points;
9+
using System.Text.Json;
10+
using Aardvark.Data.E57;
11+
12+
namespace PointCloudConverter.Readers
13+
{
14+
public class E57 : IReader, IDisposable
15+
{
16+
private IEnumerator<E57Chunk> chunkEnumerator;
17+
private E57Chunk currentChunk;
18+
private int currentPointIndex = 0;
19+
20+
private ASTM_E57.E57FileHeader header;
21+
private E57MetaData metaData;
22+
23+
private Float3 lastXYZ;
24+
25+
public struct E57MetaData
26+
{
27+
public string Name { get; set; }
28+
public double X { get; set; }
29+
public double Y { get; set; }
30+
public double Z { get; set; }
31+
public double RX { get; set; }
32+
public double RY { get; set; }
33+
public double RZ { get; set; }
34+
public double RW { get; set; }
35+
}
36+
37+
public bool InitReader(ImportSettings importSettings, int fileIndex)
38+
{
39+
try
40+
{
41+
var filePath = importSettings.inputFiles[fileIndex];
42+
43+
// Read header metadata
44+
using var stream = File.OpenRead(filePath);
45+
header = ASTM_E57.E57FileHeader.Parse(stream, new FileInfo(filePath).Length, false);
46+
stream.Close();
47+
48+
var pose = header.E57Root.Data3D[0].Pose;
49+
50+
metaData = new E57MetaData
51+
{
52+
Name = header.E57Root.Data3D[0].Name,
53+
X = pose.Translation.X,
54+
Y = importSettings.swapYZ ? pose.Translation.Z : pose.Translation.Y,
55+
Z = importSettings.swapYZ ? pose.Translation.Y : pose.Translation.Z,
56+
RX = pose.Rotation.X,
57+
RY = importSettings.swapYZ ? pose.Rotation.Z : pose.Rotation.Y,
58+
RZ = importSettings.swapYZ ? pose.Rotation.Y : pose.Rotation.Z,
59+
RW = pose.Rotation.W
60+
};
61+
62+
var chunks = ChunksFull(filePath, ParseConfig.Default);
63+
chunkEnumerator = chunks.GetEnumerator();
64+
65+
if (!chunkEnumerator.MoveNext())
66+
return false;
67+
68+
currentChunk = chunkEnumerator.Current;
69+
currentPointIndex = 0;
70+
71+
return true;
72+
}
73+
catch (Exception ex)
74+
{
75+
Console.WriteLine("E57 InitReader error: " + ex.Message);
76+
return false;
77+
}
78+
}
79+
80+
public LasHeader GetMetaData(ImportSettings importSettings, int fileIndex)
81+
{
82+
return new LasHeader
83+
{
84+
FileName = importSettings.inputFiles[fileIndex],
85+
NumberOfPointRecords = (uint)(header?.E57Root?.Data3D?[0]?.Points?.RecordCount ?? 0)
86+
};
87+
}
88+
89+
public Bounds GetBounds()
90+
{
91+
var bounds = header.E57Root.Data3D[0].CartesianBounds.Bounds;
92+
93+
return new Bounds
94+
{
95+
minX = (float)bounds.X.Min,
96+
maxX = (float)bounds.X.Max,
97+
minY = (float)bounds.Y.Min,
98+
maxY = (float)bounds.Y.Max,
99+
minZ = (float)bounds.Z.Min,
100+
maxZ = (float)bounds.Z.Max
101+
};
102+
}
103+
104+
public int GetPointCount()
105+
{
106+
return (int)(header?.E57Root?.Data3D?[0]?.Points?.RecordCount ?? 0);
107+
}
108+
109+
public Float3 GetXYZ()
110+
{
111+
if (currentChunk == null || currentPointIndex >= currentChunk.Count)
112+
{
113+
if (!chunkEnumerator.MoveNext())
114+
return new Float3 { hasError = true };
115+
116+
currentChunk = chunkEnumerator.Current;
117+
currentPointIndex = 0;
118+
}
119+
120+
var p = currentChunk.Positions[currentPointIndex];
121+
lastXYZ.x = p.X;
122+
lastXYZ.y = p.Y;
123+
lastXYZ.z = p.Z;
124+
lastXYZ.hasError = false;
125+
126+
currentPointIndex++;
127+
return lastXYZ;
128+
}
129+
130+
private C3b[] cachedColors = null;
131+
132+
public Color GetRGB()
133+
{
134+
if (cachedColors == null && currentChunk?.Colors != null)
135+
cachedColors = currentChunk.Colors;
136+
137+
int i = currentPointIndex - 1;
138+
if (cachedColors != null && i >= 0 && i < cachedColors.Length)
139+
{
140+
var c = cachedColors[i];
141+
return new Color
142+
{
143+
r = c.R / 255f,
144+
g = c.G / 255f,
145+
b = c.B / 255f
146+
};
147+
}
148+
149+
return default;
150+
}
151+
152+
public byte GetIntensity()
153+
{
154+
var i = currentPointIndex - 1;
155+
if (currentChunk?.Intensities != null && i >= 0 && i < currentChunk.Intensities.Length)
156+
{
157+
return (byte)currentChunk.Intensities[i];
158+
}
159+
return 0;
160+
}
161+
162+
public byte GetClassification() => 0;
163+
164+
public double GetTime()
165+
{
166+
// Not implemented for now
167+
return 0;
168+
}
169+
170+
public void Close() { }
171+
172+
public void Dispose()
173+
{
174+
Close();
175+
GC.SuppressFinalize(this);
176+
}
177+
178+
~E57()
179+
{
180+
Dispose();
181+
}
182+
183+
public string GetMetaDataJSON()
184+
{
185+
return JsonSerializer.Serialize(metaData);
186+
}
187+
}
188+
}

Readers/PLY.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ public class PLY : IReader, IDisposable
2626
// private byte currentClassification;
2727
private Bounds bounds;
2828

29+
30+
//int? taskID;
31+
//// add constructor
32+
//public PLY(int? _taskID)
33+
//{
34+
// taskID = _taskID;
35+
//}
36+
2937
public bool InitReader(ImportSettings importSettings, int fileIndex)
3038
{
3139
var file = importSettings.inputFiles[fileIndex];

Structs/ImportFormat.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ public enum ImportFormat
44
{
55
Unknown,
66
LAS, // and LAZ
7-
PLY
7+
PLY,
8+
E57
89
}
910
}

Structs/ImportSettings.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ public IReader GetOrCreateReader(int? taskId)
6262
case ImportFormat.PLY:
6363
readerInstance = new PLY(); // no taskId needed here
6464
break;
65+
case ImportFormat.E57:
66+
readerInstance = new E57();
67+
break;
6568
default:
6669
Log.Write($"Unsupported import format: {importFormat}", LogEvent.Error);
6770
throw new NotSupportedException($"Unsupported import format: {importFormat}");

Tools/ArgParser.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ public static ImportSettings Parse(string[] args, string rootFolder, ILogger log
153153
string importFormatParsed = param.ToUpper();
154154

155155
if (string.IsNullOrEmpty(importFormatParsed) ||
156-
(importFormatParsed != "LAS" && importFormatParsed != "LAZ" && importFormatParsed != "PLY"))
156+
(importFormatParsed != "LAS" && importFormatParsed != "LAZ" && importFormatParsed != "PLY") && importFormatParsed != "E57")
157157
{
158158
importSettings.errors.Add("Unsupported import format: " + param);
159159
importSettings.importFormat = ImportFormat.Unknown;
@@ -171,6 +171,10 @@ public static ImportSettings Parse(string[] args, string rootFolder, ILogger log
171171
importSettings.importFormat = ImportFormat.PLY;
172172
importSettings.reader = new PLY();
173173
break;
174+
case "E57":
175+
importSettings.importFormat = ImportFormat.E57;
176+
importSettings.reader = new E57();
177+
break;
174178
}
175179
}
176180
break;

0 commit comments

Comments
 (0)