Skip to content

Commit 42d12db

Browse files
committed
test c# 7.3, use hash instead of string for dictionary,
1 parent 0002b29 commit 42d12db

File tree

4 files changed

+115
-57
lines changed

4 files changed

+115
-57
lines changed

MainWindow.xaml.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -427,9 +427,15 @@ static bool ParseFile(ImportSettings importSettings, int fileIndex)
427427
point.z -= importSettings.offsetZ;
428428

429429
// scale if enabled
430-
point.x = importSettings.useScale ? point.x * importSettings.scale : point.x;
431-
point.y = importSettings.useScale ? point.y * importSettings.scale : point.y;
432-
point.z = importSettings.useScale ? point.z * importSettings.scale : point.z;
430+
//point.x = importSettings.useScale ? point.x * importSettings.scale : point.x;
431+
//point.y = importSettings.useScale ? point.y * importSettings.scale : point.y;
432+
//point.z = importSettings.useScale ? point.z * importSettings.scale : point.z;
433+
if (importSettings.useScale == true)
434+
{
435+
point.x *= importSettings.scale;
436+
point.y *= importSettings.scale;
437+
point.z *= importSettings.scale;
438+
}
433439

434440
// flip if enabled
435441
if (importSettings.swapYZ == true)

PointCloudConverter.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<RootNamespace>PointCloudConverter</RootNamespace>
1010
<AssemblyName>PointCloudConverter</AssemblyName>
1111
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
12+
<LangVersion>7.3</LangVersion>
1213
<FileAlignment>512</FileAlignment>
1314
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
1415
<WarningLevel>4</WarningLevel>

Tools/Tools.cs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -249,43 +249,49 @@ public static void Shuffle<T>(Random rng, ref List<T> array1, ref List<T> array2
249249
}
250250
}
251251

252+
252253
public static void Shuffle<T>(Random rng, ref List<T> array1, ref List<T> array2, ref List<T> array3, ref List<T> arrayR, ref List<T> arrayG, ref List<T> arrayB, ref List<double> arrayTime)
253254
{
254255
int index = array1.Count;
256+
T temp, temp2, temp3, tempR, tempG, tempB;
257+
double tempT;
258+
255259
while (index > 1)
256260
{
257261
int rnd = rng.Next(index--);
258262

259-
T temp = array1[index];
263+
temp = array1[index];
260264
array1[index] = array1[rnd];
261265
array1[rnd] = temp;
262266

263-
T temp2 = array2[index];
267+
temp2 = array2[index];
264268
array2[index] = array2[rnd];
265269
array2[rnd] = temp2;
266270

267-
T temp3 = array3[index];
271+
temp3 = array3[index];
268272
array3[index] = array3[rnd];
269273
array3[rnd] = temp3;
270274

271-
T tempR = arrayR[index];
275+
tempR = arrayR[index];
272276
arrayR[index] = arrayR[rnd];
273277
arrayR[rnd] = tempR;
274278

275-
T tempG = arrayG[index];
279+
tempG = arrayG[index];
276280
arrayG[index] = arrayG[rnd];
277281
arrayG[rnd] = tempG;
278282

279-
T tempB = arrayB[index];
283+
tempB = arrayB[index];
280284
arrayB[index] = arrayB[rnd];
281285
arrayB[rnd] = tempB;
282286

283-
double tempT = arrayTime[index];
287+
tempT = arrayTime[index];
284288
arrayTime[index] = arrayTime[rnd];
285289
arrayTime[rnd] = tempT;
286290
}
287291
}
288292

293+
294+
289295
// https://stackoverflow.com/a/110570/5452781
290296
public static void ShuffleXYZ<T>(Random rng, ref T[] array1)
291297
{

Writers/PCROOT.cs

Lines changed: 92 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,19 @@ public class PCROOT : IWriter
1717
BufferedStream bsPoints = null;
1818
BinaryWriter writerPoints = null;
1919

20-
static List<PointCloudTile> nodeBounds = new List<PointCloudTile>();
20+
static List<PointCloudTile> nodeBounds = new List<PointCloudTile>(); // for all tiles
2121

2222
// our nodes (=tiles, =grid cells), string is tileID and float are X,Y,Z,R,G,B values
23-
Dictionary<string, List<float>> nodeX = new Dictionary<string, List<float>>();
24-
Dictionary<string, List<float>> nodeY = new Dictionary<string, List<float>>();
25-
Dictionary<string, List<float>> nodeZ = new Dictionary<string, List<float>>();
23+
Dictionary<int, List<float>> nodeX = new Dictionary<int, List<float>>();
24+
Dictionary<int, List<float>> nodeY = new Dictionary<int, List<float>>();
25+
Dictionary<int, List<float>> nodeZ = new Dictionary<int, List<float>>();
2626

27-
Dictionary<string, List<float>> nodeR = new Dictionary<string, List<float>>();
28-
Dictionary<string, List<float>> nodeG = new Dictionary<string, List<float>>();
29-
Dictionary<string, List<float>> nodeB = new Dictionary<string, List<float>>();
30-
31-
Dictionary<string, List<float>> nodeIntensity = new Dictionary<string, List<float>>();
32-
Dictionary<string, List<double>> nodeTime = new Dictionary<string, List<double>>();
27+
Dictionary<int, List<float>> nodeR = new Dictionary<int, List<float>>();
28+
Dictionary<int, List<float>> nodeG = new Dictionary<int, List<float>>();
29+
Dictionary<int, List<float>> nodeB = new Dictionary<int, List<float>>();
3330

31+
Dictionary<int, List<float>> nodeIntensity = new Dictionary<int, List<float>>();
32+
Dictionary<int, List<double>> nodeTime = new Dictionary<int, List<double>>();
3433

3534
static float cloudMinX = float.PositiveInfinity;
3635
static float cloudMinY = float.PositiveInfinity;
@@ -90,24 +89,69 @@ void IWriter.Randomize()
9089

9190
}
9291

92+
int Hash(int x, int y, int z)
93+
{
94+
unchecked
95+
{
96+
// Apply offset to ensure all values are positive
97+
x += OFFSET;
98+
y += OFFSET;
99+
z += OFFSET;
100+
101+
// Combine the values into a single hash using a method that can handle larger ranges
102+
long combined = ((long)x << 40) | ((long)y << 20) | (long)z;
103+
return combined.GetHashCode();
104+
}
105+
}
106+
107+
const int OFFSET = 12345678;
108+
109+
(int x, int y, int z) Unhash(int hash)
110+
{
111+
// Restore the original x, y, z values
112+
long combined = hash;
113+
114+
int z = (int)(combined & ((1L << 20) - 1));
115+
combined >>= 20;
116+
int y = (int)(combined & ((1L << 20) - 1));
117+
combined >>= 20;
118+
int x = (int)combined;
119+
120+
// Remove the offset to get original values
121+
x -= OFFSET;
122+
y -= OFFSET;
123+
z -= OFFSET;
124+
125+
return (x, y, z);
126+
}
127+
93128
void IWriter.AddPoint(int index, float x, float y, float z, float r, float g, float b, bool hasIntensity, float i, bool hasTime, double time)
94129
{
95130
// get global all clouds bounds
96-
if (x < cloudMinX) cloudMinX = x;
97-
if (x > cloudMaxX) cloudMaxX = x;
98-
if (y < cloudMinY) cloudMinY = y;
99-
if (y > cloudMaxY) cloudMaxY = y;
100-
if (z < cloudMinZ) cloudMinZ = z;
101-
if (z > cloudMaxZ) cloudMaxZ = z;
131+
//if (x < cloudMinX) cloudMinX = x;
132+
//if (x > cloudMaxX) cloudMaxX = x;
133+
//if (y < cloudMinY) cloudMinY = y;
134+
//if (y > cloudMaxY) cloudMaxY = y;
135+
//if (z < cloudMinZ) cloudMinZ = z;
136+
//if (z > cloudMaxZ) cloudMaxZ = z;
137+
cloudMinX = Math.Min(cloudMinX, x);
138+
cloudMaxX = Math.Max(cloudMaxX, x);
139+
cloudMinY = Math.Min(cloudMinY, y);
140+
cloudMaxY = Math.Max(cloudMaxY, y);
141+
cloudMinZ = Math.Min(cloudMinZ, z);
142+
cloudMaxZ = Math.Max(cloudMaxZ, z);
143+
144+
float gridSize = importSettings.gridSize;
102145

103146
// add to correct cell, MOVE to writer
104147
// TODO handle bytepacked gridsize here
105-
int cellX = (int)(x / importSettings.gridSize);
106-
int cellY = (int)(y / importSettings.gridSize);
107-
int cellZ = (int)(z / importSettings.gridSize);
148+
int cellX = (int)(x / gridSize);
149+
int cellY = (int)(y / gridSize);
150+
int cellZ = (int)(z / gridSize);
108151

109-
// collect point to its cell node
110-
string key = cellX + "_" + cellY + "_" + cellZ;
152+
// collect point to its cell node, TODO optimize this is ~23% of total time?
153+
//string key = cellX + "_" + cellY + "_" + cellZ;
154+
int key = Hash(cellX, cellY, cellZ);
111155

112156
if (nodeX.ContainsKey(key))
113157
{
@@ -125,29 +169,21 @@ void IWriter.AddPoint(int index, float x, float y, float z, float r, float g, fl
125169
else // create new list for this key
126170
{
127171
// NOTE if memory error here, use smaller gridsize (single array maxsize is ~2gb)
128-
nodeX[key] = new List<float>();
129-
nodeX[key].Add(x);
130-
nodeY[key] = new List<float>();
131-
nodeY[key].Add(y);
132-
nodeZ[key] = new List<float>();
133-
nodeZ[key].Add(z);
134-
nodeR[key] = new List<float>();
135-
nodeR[key].Add(r);
136-
nodeG[key] = new List<float>();
137-
nodeG[key].Add(g);
138-
nodeB[key] = new List<float>();
139-
nodeB[key].Add(b);
172+
nodeX[key] = new List<float> { x };
173+
nodeY[key] = new List<float> { y };
174+
nodeZ[key] = new List<float> { z };
175+
nodeR[key] = new List<float> { r };
176+
nodeG[key] = new List<float> { g };
177+
nodeB[key] = new List<float> { b };
140178

141179
if (hasIntensity == true)
142180
{
143-
nodeIntensity[key] = new List<float>();
144-
nodeIntensity[key].Add(i);
181+
nodeIntensity[key] = new List<float> { i };
145182
}
146183

147184
if (hasTime == true)
148185
{
149-
nodeTime[key] = new List<double>();
150-
nodeTime[key].Add(time);
186+
nodeTime[key] = new List<double> { time };
151187
}
152188
}
153189
}
@@ -196,7 +232,7 @@ void IWriter.Save(int fileIndex)
196232
List<double> nodeTempTime = null;
197233

198234
// process all tiles
199-
foreach (KeyValuePair<string, List<float>> nodeData in nodeX)
235+
foreach (KeyValuePair<int, List<float>> nodeData in nodeX)
200236
{
201237
if (nodeData.Value.Count < importSettings.minimumPointCount)
202238
{
@@ -206,7 +242,8 @@ void IWriter.Save(int fileIndex)
206242

207243
nodeTempX = nodeData.Value;
208244

209-
string key = nodeData.Key;
245+
//string key = nodeData.Key;
246+
int key = nodeData.Key;
210247

211248
nodeTempY = nodeY[key];
212249
nodeTempZ = nodeZ[key];
@@ -323,12 +360,16 @@ void IWriter.Save(int fileIndex)
323360
if (importSettings.packColors == true)
324361
{
325362
// get local coords within tile
326-
var keys = nodeData.Key.Split('_');
363+
//var keys = nodeData.Key.Split('_');
364+
(int restoredX, int restoredY, int restoredZ) = Unhash(nodeData.Key);
365+
cellX = restoredX;
366+
cellY = restoredY;
367+
cellZ = restoredZ;
327368

328369
// TODO no need to parse, we should know these values?
329-
cellX = int.Parse(keys[0]);
330-
cellY = int.Parse(keys[1]);
331-
cellZ = int.Parse(keys[2]);
370+
//cellX = int.Parse(keys[0]);
371+
//cellY = int.Parse(keys[1]);
372+
//cellZ = int.Parse(keys[2]);
332373
// offset to local coords (within tile)
333374
px -= (cellX * importSettings.gridSize);
334375
py -= (cellY * importSettings.gridSize);
@@ -370,13 +411,17 @@ void IWriter.Save(int fileIndex)
370411
else if (useLossyFiltering == true) // test lossy, not regular packed
371412
{
372413
// get local coords within tile
373-
var keys = nodeData.Key.Split('_');
414+
//var keys = nodeData.Key.Split('_');
374415
// TODO no need to parse, we should know these values? these are world cell grid coors
375416
// TODO take reserved grid cells earlier, when reading points! not here on 2nd pass..
376-
cellX = int.Parse(keys[0]);
377-
cellY = int.Parse(keys[1]);
378-
cellZ = int.Parse(keys[2]);
417+
//cellX = int.Parse(keys[0]);
418+
//cellY = int.Parse(keys[1]);
419+
//cellZ = int.Parse(keys[2]);
379420
// offset point inside local tile
421+
(int restoredX, int restoredY, int restoredZ) = Unhash(nodeData.Key);
422+
cellX = restoredX;
423+
cellY = restoredY;
424+
cellZ = restoredZ;
380425
px -= (cellX * fixedGridSize);
381426
py -= (cellY * fixedGridSize);
382427
pz -= (cellZ * fixedGridSize);

0 commit comments

Comments
 (0)