Skip to content

Commit 4a23fb6

Browse files
committed
v3: add XYZ+RGB+INTENSITY packing (v3 format 4), add separate INTENSITY file output support, reset progressbar on start, allow importing Both RGB & Intensity, Allow disabling Randomize points, #BUILD
1 parent fb412ab commit 4a23fb6

File tree

8 files changed

+298
-82
lines changed

8 files changed

+298
-82
lines changed

MainWindow.xaml.cs

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ namespace PointCloudConverter
2626
{
2727
public partial class MainWindow : Window
2828
{
29-
static readonly string version = "25.01.2024";
29+
static readonly string version = "11.02.2024";
3030
static readonly string appname = "PointCloud Converter - " + version;
3131
static readonly string rootFolder = AppDomain.CurrentDomain.BaseDirectory;
3232

@@ -214,6 +214,12 @@ static void ProgressTick(object sender, EventArgs e)
214214
mainWindowStatic.progressBarPoints.Value = progressPoint / (float)progressTotalPoints;
215215
mainWindowStatic.lblStatus.Content = lastStatusMessage;
216216
}
217+
else
218+
{
219+
mainWindowStatic.progressBarFiles.Value = 0;
220+
mainWindowStatic.progressBarPoints.Value = 0;
221+
mainWindowStatic.lblStatus.Content = "";
222+
}
217223
}
218224

219225
// process single file
@@ -345,10 +351,31 @@ static void ParseFile(ImportSettings importSettings, int fileIndex)
345351
}
346352

347353
// get point color
348-
Color rgb = importSettings.reader.GetRGB();
354+
Color rgb = (default);
355+
Color intensity = (default);
356+
357+
if (importSettings.importRGB == true)
358+
{
359+
rgb = importSettings.reader.GetRGB();
360+
}
349361

350-
// collect this point XYZ and RGB into node
351-
importSettings.writer.AddPoint(i, (float)point.x, (float)point.y, (float)point.z, rgb.r, rgb.g, rgb.b);
362+
// TODO get intensity as separate value, TODO is this float or rgb?
363+
if (importSettings.importIntensity == true)
364+
{
365+
intensity = importSettings.reader.GetIntensity();
366+
//if (i < 100) Console.WriteLine(intensity.r);
367+
368+
// if no rgb, then replace RGB with intensity
369+
if (importSettings.importRGB == false)
370+
{
371+
rgb.r = intensity.r;
372+
rgb.g = intensity.r;
373+
rgb.b = intensity.r;
374+
}
375+
}
376+
377+
// collect this point XYZ and RGB into node, optionally intensity also
378+
importSettings.writer.AddPoint(i, (float)point.x, (float)point.y, (float)point.z, rgb.r, rgb.g, rgb.b, importSettings.importIntensity, intensity.r);
352379
progressPoint = i;
353380
}
354381

@@ -380,6 +407,11 @@ static void ParseFile(ImportSettings importSettings, int fileIndex)
380407

381408
private void btnConvert_Click(object sender, RoutedEventArgs e)
382409
{
410+
// reset progress
411+
progressTotalFiles = 0;
412+
progressTotalPoints = 0;
413+
ProgressTick(null, null);
414+
383415
gridProcessingPanel.Visibility = Visibility.Visible;
384416
SaveSettings();
385417
StartProcess();
@@ -692,7 +724,7 @@ private void chkImportRGB_Checked(object sender, RoutedEventArgs e)
692724
// not available at init
693725
if (isInitialiazing == true) return;
694726

695-
chkImportIntensity.IsChecked = false;
727+
//chkImportIntensity.IsChecked = false;
696728
Properties.Settings.Default.importRGB = true;
697729
Properties.Settings.Default.Save();
698730
}
@@ -701,7 +733,7 @@ private void chkImportIntensity_Checked(object sender, RoutedEventArgs e)
701733
{
702734
if (isInitialiazing == true) return;
703735

704-
chkImportRGB.IsChecked = false;
736+
//chkImportRGB.IsChecked = false;
705737
Properties.Settings.Default.importIntensity = true;
706738
Properties.Settings.Default.Save();
707739
}

Readers/IReader.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,6 @@ public interface IReader
1616
Color GetRGB();
1717
// close filestream
1818
void Close();
19+
Color GetIntensity();
1920
}
2021
}

Readers/LAZ.cs

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,15 @@ public class LAZ : IReader
1818
laszip_dll lazReader = new laszip_dll();
1919
bool compressed = false;
2020
bool importRGB = true;
21+
bool importIntensity = false;
2122
bool customIntensityRange = false;
2223

2324
bool IReader.InitReader(ImportSettings importSettings, int fileIndex)
2425
{
2526
// TODO check errors
2627
var file = importSettings.inputFiles[fileIndex];
2728
importRGB = importSettings.importRGB;
28-
//importIntensity = importSettings.readIntensity;
29+
importIntensity = importSettings.importIntensity;
2930
customIntensityRange = importSettings.useCustomIntensityRange;
3031
lazReader.laszip_open_reader(file, ref compressed);
3132
return true;
@@ -59,41 +60,45 @@ Color IReader.GetRGB()
5960
// get point reference
6061
var p = lazReader.point;
6162

62-
if (importRGB == true)
63+
// try to detect if colors are outside 0-255 range? TODO just check value?
64+
if (p.rgb[0].ToString("X").Length > 2)
6365
{
64-
// try to detect if colors are outside 0-255 range? TODO just check value?
65-
if (p.rgb[0].ToString("X").Length > 2)
66-
{
67-
c.r = Tools.LUT255[(byte)(p.rgb[0] / 256f)];
68-
c.g = Tools.LUT255[(byte)(p.rgb[1] / 256f)];
69-
c.b = Tools.LUT255[(byte)(p.rgb[2] / 256f)];
70-
}
71-
else // its 0-255
72-
{
73-
c.r = Tools.LUT255[(byte)(p.rgb[0])];
74-
c.g = Tools.LUT255[(byte)(p.rgb[1])];
75-
c.b = Tools.LUT255[(byte)(p.rgb[2])];
76-
}
66+
c.r = Tools.LUT255[(byte)(p.rgb[0] / 256f)];
67+
c.g = Tools.LUT255[(byte)(p.rgb[1] / 256f)];
68+
c.b = Tools.LUT255[(byte)(p.rgb[2] / 256f)];
7769
}
78-
else // use intensity
70+
else // its 0-255
7971
{
80-
float i = 0;
81-
if (customIntensityRange) // NOTE now only supports 65535 as custom range
82-
{
83-
i = Tools.LUT255[(byte)(p.intensity / 255f)];
84-
}
85-
else
86-
{
87-
i = Tools.LUT255[(byte)(p.intensity)];
88-
}
89-
c.r = i;
90-
c.g = i;
91-
c.b = i;
72+
c.r = Tools.LUT255[(byte)(p.rgb[0])];
73+
c.g = Tools.LUT255[(byte)(p.rgb[1])];
74+
c.b = Tools.LUT255[(byte)(p.rgb[2])];
9275
}
9376

9477
return c;
9578
}
9679

80+
Color IReader.GetIntensity()
81+
{
82+
var c = new Color();
83+
84+
// get point reference
85+
var p = lazReader.point;
86+
87+
float i = 0;
88+
if (customIntensityRange) // NOTE now only supports 65535 as custom range
89+
{
90+
i = Tools.LUT255[(byte)(p.intensity / 255f)];
91+
}
92+
else
93+
{
94+
i = Tools.LUT255[(byte)(p.intensity)];
95+
}
96+
c.r = i;
97+
c.g = i;
98+
c.b = i;
99+
return c;
100+
}
101+
97102
Float3 IReader.GetXYZ()
98103
{
99104
var f = new Float3();

Tools/ArgParser.cs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -692,9 +692,15 @@ public static ImportSettings Parse(string[] args, string rootFolder)
692692
}
693693

694694
// cannot have both rgb & intensity
695-
if (importSettings.importRGB == true && importSettings.importIntensity == true)
695+
//if (importSettings.importRGB == true && importSettings.importIntensity == true)
696+
//{
697+
// importSettings.errors.Add("Cannot have both -rgb and -intensity enabled");
698+
//}
699+
700+
// must have at least one
701+
if (importSettings.importRGB == false && importSettings.importIntensity == false)
696702
{
697-
importSettings.errors.Add("Cannot have both -rgb and -intensity enabled");
703+
importSettings.errors.Add("Must have -rgb OR -intensity enabled");
698704
}
699705

700706
//// check mismatching settings for v2 vs v3
@@ -720,10 +726,11 @@ public static ImportSettings Parse(string[] args, string rootFolder)
720726
Log.WriteLine("No import format defined, using Default: " + importSettings.importFormat.ToString());
721727
}
722728

723-
if (importSettings.randomize == false && importSettings.exportFormat == ExportFormat.PCROOT)
724-
{
725-
importSettings.errors.Add("V3 pcroot export format requires -randomize=true to randomize points");
726-
}
729+
// disable this error, if user really wants to use it
730+
//if (importSettings.randomize == false && importSettings.exportFormat == ExportFormat.PCROOT)
731+
//{
732+
// importSettings.errors.Add("V3 pcroot export format requires -randomize=true to randomize points");
733+
//}
727734

728735
//if (decimatePoints == true && (skipPoints == true || keepPoints == true))
729736
//{

Tools/Tools.cs

Lines changed: 90 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
using System;
1+
using PointCloudConverter.Structs;
2+
using System;
23
using System.Collections.Generic;
34
using System.Globalization;
45
using System.IO;
6+
using System.Numerics;
57
using System.Reflection;
68
using System.Threading;
9+
using System.Windows.Documents;
710

811
namespace PointCloudConverter
912
{
@@ -83,12 +86,58 @@ public static String HumanReadableFileSize(long byteCount)
8386
return (Math.Sign(byteCount) * num).ToString() + suf[place];
8487
}
8588

86-
public static float SuperPacker(float coord, float color, float range)
89+
public static float SuperPacker(float color, float coord, float range)
8790
{
88-
float truncated = (float)Math.Truncate(color * range);
89-
return truncated + coord;
91+
float truncated = (float)Math.Truncate(coord * range);
92+
return truncated + color;
9093
}
9194

95+
public static Vector2 SuperUnpacker(float f, float GridSizeAndPackMagic)
96+
{
97+
return new Vector2((float)(f - Math.Floor(f)), (float)(Math.Floor(f) / GridSizeAndPackMagic));
98+
}
99+
100+
//public static int PackInt2Int(int a, int b)
101+
//{
102+
// int a2 = a << 8;
103+
// int b2 = b & 0x000000FF;
104+
// return a2 | b2;
105+
//}
106+
107+
//public static void Unpack2Ints(int packed, out int a, out int b)
108+
//{
109+
// a = packed >> 8;
110+
// b = packed & 0x000000FF;
111+
//}
112+
113+
//public static Vector3 SuperUnpacker2(float f, float GridSizeAndPackMagic)
114+
//{
115+
// //float i = f / 16581375f;
116+
// float i = f / 64000f;
117+
// return new Vector3((float)(i - Math.Floor(i)), (float)(Math.Floor(i) / GridSizeAndPackMagic), i);
118+
//}
119+
120+
//// https://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/
121+
//public static float SuperPacker4(float a, float b, float c, float d)
122+
//{
123+
// return Dot(a, b, c, d, 1.0f, 1 / 255.0f, 1 / 65025.0f, 1 / 16581375.0f);
124+
//}
125+
126+
//public static float SuperPacker3(float a, float b, float c)
127+
//{
128+
// return Dot(a, b, c, 1.0f, 1 / 255.0f, 1 / 65025.0f);
129+
//}
130+
131+
//static float Dot(float ax, float ay, float az, float aw, float bx, float by, float bz, float bw)
132+
//{
133+
// return (ax * bx + ay * by + az * bz + aw * bw);
134+
//}
135+
136+
//static float Dot(float ax, float ay, float az, float bx, float by, float bz)
137+
//{
138+
// return (ax * bx + ay * by + az * bz);
139+
//}
140+
92141
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)
93142
{
94143
int index = array1.Count;
@@ -122,6 +171,43 @@ public static void Shuffle<T>(Random rng, ref List<T> array1, ref List<T> array2
122171
}
123172
}
124173

174+
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<T> arrayIntensity)
175+
{
176+
int index = array1.Count;
177+
while (index > 1)
178+
{
179+
int rnd = rng.Next(index--);
180+
181+
T temp = array1[index];
182+
array1[index] = array1[rnd];
183+
array1[rnd] = temp;
184+
185+
T temp2 = array2[index];
186+
array2[index] = array2[rnd];
187+
array2[rnd] = temp2;
188+
189+
T temp3 = array3[index];
190+
array3[index] = array3[rnd];
191+
array3[rnd] = temp3;
192+
193+
T tempR = arrayR[index];
194+
arrayR[index] = arrayR[rnd];
195+
arrayR[rnd] = tempR;
196+
197+
T tempG = arrayG[index];
198+
arrayG[index] = arrayG[rnd];
199+
arrayG[rnd] = tempG;
200+
201+
T tempB = arrayB[index];
202+
arrayB[index] = arrayB[rnd];
203+
arrayB[rnd] = tempB;
204+
205+
T tempI = arrayIntensity[index];
206+
arrayIntensity[index] = arrayIntensity[rnd];
207+
arrayIntensity[rnd] = tempI;
208+
}
209+
}
210+
125211
// https://stackoverflow.com/a/110570/5452781
126212
public static void ShuffleXYZ<T>(Random rng, ref T[] array1)
127213
{

Writers/IWriter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public interface IWriter
1313
// output R,G,B values (float 0-1) to file
1414
void WriteRGB(float r, float g, float b);
1515
// optional: if you need to collect points for later processing
16-
void AddPoint(int index, float x, float y, float z, float r, float g, float b);
16+
void AddPoint(int index, float x, float y, float z, float r, float g, float b, bool hasIntensity, float i);
1717
// optional: randomizes points (to use dynamic resolution/tile LOD in Unity)
1818
void Randomize();
1919
// called after all points have been looped through

0 commit comments

Comments
 (0)