Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add 4byte rgb format #770

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Assets/Scripts/Editor/PointCloud/PointElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ public enum PointElementName
X, Y, Z,
R, G, B,
I,
RGB,
}

public struct PointElement
{
public PointElementType Type;
Expand Down
13 changes: 7 additions & 6 deletions Assets/Scripts/Editor/PointCloud/Trees/PcdPointProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ private DefaultHeaderData ReadHeader()
string[] fields = null;
string[] sizes = null;
string[] types = null;

using (var view = file.CreateViewStream(0, 4096, MemoryMappedFileAccess.Read))
{
var buffer = new byte[4096];
Expand Down Expand Up @@ -76,7 +76,7 @@ private DefaultHeaderData ReadHeader()

if (line.StartsWith("VERSION"))
{
var version = line.Split(new[] {' '}, 2);
var version = line.Split(new[] { ' ' }, 2);
if (version[1] != "0.7")
{
throw new Exception($"Unsupported PCD version: {version[1]}");
Expand Down Expand Up @@ -104,20 +104,20 @@ private DefaultHeaderData ReadHeader()
}
else if (line.StartsWith("HEIGHT"))
{
var height = line.Split(new[] {' '}, 2);
var height = line.Split(new[] { ' ' }, 2);
if (height[1] != "1")
{
throw new Exception($"Unsupported PCD height: {height[1]}");
}
}
else if (line.StartsWith("POINTS"))
{
var points = line.Split(new[] {' '}, 2);
var points = line.Split(new[] { ' ' }, 2);
result.DataCount = long.Parse(points[1]);
}
else if (line.StartsWith("DATA"))
{
var data = line.Split(new[] {' '}, 2);
var data = line.Split(new[] { ' ' }, 2);
if (data[1] != "binary")
{
throw new Exception($"Unsupported PCD data format: {data[1]}");
Expand Down Expand Up @@ -154,6 +154,7 @@ private DefaultHeaderData ReadHeader()
if (fields[i] == "z") name = PointElementName.Z;
if (fields[i] == "intensity") name = PointElementName.I;
if (fields[i] == "scalar_intensity") name = PointElementName.I;
if (fields[i] == "rgb") name = PointElementName.RGB;

if (types[i] == "U" && elementSize == 1) type = PointElementType.Byte;
if (types[i] == "F" && elementSize == 4) type = PointElementType.Float;
Expand All @@ -162,7 +163,7 @@ private DefaultHeaderData ReadHeader()
if (type.HasValue && name.HasValue)
{
result.Elements.Add(new PointElement()
{Type = type.Value, Name = name.Value, Offset = elementOffset});
{ Type = type.Value, Name = name.Value, Offset = elementOffset });
}

elementOffset += elementSize;
Expand Down
95 changes: 55 additions & 40 deletions Assets/Scripts/Editor/PointCloud/Trees/PointImportJobs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ public double this[int index]
{
unsafe
{
void* ptr = (byte*) Data + index * Stride;
return Size == 4 ? *(float*) ptr : *(double*) ptr;
void* ptr = (byte*)Data + index * Stride;
return Size == 4 ? *(float*)ptr : *(double*)ptr;
}
}
}
Expand All @@ -50,6 +50,9 @@ private struct ColorAccess
[NativeDisableUnsafePtrRestriction]
public unsafe void* Color;

[NativeDisableUnsafePtrRestriction]
public unsafe void* ColorF;

[NativeDisableUnsafePtrRestriction]
public unsafe void* Intensity;

Expand All @@ -69,37 +72,45 @@ public uint this[int index]
byte b = 0;
if (Color != null)
{
var ptr = (byte*) Color + index * Stride;
var ptr = (byte*)Color + index * Stride;
r = ptr[0];
g = ptr[1];
b = ptr[2];
color = (uint) ((b << 16) | (g << 8) | r);
color = (uint)((b << 16) | (g << 8) | r);
}
else if (ColorF != null)
{
var ptr = (byte*)ColorF + index * Stride;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If field type is float then why this ptr is read as 3 bytes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I know, I've only seen data in which 32bit is forcibly packed with 8bit rgb value.

r = ptr[2];
g = ptr[1];
b = ptr[0];
color = (uint)((b << 16) | (g << 8) | r);
}

if (Intensity != null || IntensityF != null)
{
byte intensity;
if (Intensity != null)
{
var ptr = (byte*) Intensity + index * Stride;
var ptr = (byte*)Intensity + index * Stride;
intensity = *ptr;
}
else
{
var ptr = (float*) ((byte*) IntensityF + index * Stride);
intensity = (byte) *ptr;
var ptr = (float*)((byte*)IntensityF + index * Stride);
intensity = (byte)*ptr;
}

color |= (uint) intensity << 24;
color |= (uint)intensity << 24;
if (Color == null)
{
color |= (uint) ((intensity << 16) | (intensity << 8) | intensity);
color |= (uint)((intensity << 16) | (intensity << 8) | intensity);
}
}
else if (Color != null)
else if (Color != null || ColorF != null)
{
var intensity = (byte) ((r + g + b) / 3);
color |= (uint) intensity << 24;
var intensity = (byte)((r + g + b) / 3);
color |= (uint)intensity << 24;
}

return color;
Expand Down Expand Up @@ -162,7 +173,7 @@ public void Execute(int index)
var y = (Y[index] + OutputCenterY) * OutputScaleY;
var z = (Z[index] + OutputCenterZ) * OutputScaleZ;

var pt = Transform.MultiplyVector(new Vector3((float) x, (float) y, (float) z));
var pt = Transform.MultiplyVector(new Vector3((float)x, (float)y, (float)z));

Output[index] = new PointCloudPoint()
{
Expand Down Expand Up @@ -215,7 +226,7 @@ unsafe struct LasConvertJob : IJobParallelFor

public void Execute(int index)
{
int* data = (int*) (Input + Stride * index);
int* data = (int*)(Input + Stride * index);

double x = data[0] * InputScaleX + InputOffsetX;
double y = data[1] * InputScaleY + InputOffsetY;
Expand All @@ -225,43 +236,43 @@ public void Execute(int index)
y = (y + OutputCenterY) * OutputScaleY;
z = (z + OutputCenterZ) * OutputScaleZ;

var pt = Transform.MultiplyVector(new Vector3((float) x, (float) y, (float) z));
var pt = Transform.MultiplyVector(new Vector3((float)x, (float)y, (float)z));

byte intensity;
{
ushort* iptr = (ushort*) (Input + Stride * index + 12);
ushort* iptr = (ushort*)(Input + Stride * index + 12);
if (LasRGB8BitWorkaround)
{
intensity = (byte) *iptr;
intensity = (byte)*iptr;
}
else
{
intensity = (byte) (*iptr >> 8);
intensity = (byte)(*iptr >> 8);
}
}

uint color = (uint) (intensity << 24);
uint color = (uint)(intensity << 24);
if (ColorInput == null)
{
color |= (uint) ((intensity << 16) | (intensity << 8) | intensity);
color |= (uint)((intensity << 16) | (intensity << 8) | intensity);
}
else
{
ushort* rgb = (ushort*) (ColorInput + Stride * index);
ushort* rgb = (ushort*)(ColorInput + Stride * index);

if (LasRGB8BitWorkaround)
{
byte r = (byte) rgb[0];
byte g = (byte) rgb[1];
byte b = (byte) rgb[2];
color |= (uint) ((b << 16) | (g << 8) | r);
byte r = (byte)rgb[0];
byte g = (byte)rgb[1];
byte b = (byte)rgb[2];
color |= (uint)((b << 16) | (g << 8) | r);
}
else
{
byte r = (byte) (rgb[0] >> 8);
byte g = (byte) (rgb[1] >> 8);
byte b = (byte) (rgb[2] >> 8);
color |= (uint) ((b << 16) | (g << 8) | r);
byte r = (byte)(rgb[0] >> 8);
byte g = (byte)(rgb[1] >> 8);
byte b = (byte)(rgb[2] >> 8);
color |= (uint)((b << 16) | (g << 8) | r);
}
}

Expand Down Expand Up @@ -309,18 +320,18 @@ public static PointCloudBounds CalculateBounds(MemoryMappedViewAccessor accessor
X = GetInputAccess(PointElementName.X, elements, ptr, stride),
Y = GetInputAccess(PointElementName.Y, elements, ptr, stride),
Z = GetInputAccess(PointElementName.Z, elements, ptr, stride),
Bounds = (PointCloudBounds*) bounds.GetUnsafePtr(),
Counts = (int*) counts.GetUnsafePtr(),
Bounds = (PointCloudBounds*)bounds.GetUnsafePtr(),
Counts = (int*)counts.GetUnsafePtr(),
ThreadIndex = 0,
};

var h = job.Schedule((int) count, 65536);
var h = job.Schedule((int)count, 65536);
while (!h.IsCompleted)
{
System.Threading.Thread.Sleep(100);

var processed = counts.Sum();
var progress = (float) ((double) processed / count);
var progress = (float)((double)processed / count);

EditorUtility.DisplayProgressBar(
string.IsNullOrEmpty(progressBarTitle) ? "Calculating bounds" : progressBarTitle,
Expand Down Expand Up @@ -399,17 +410,17 @@ public static void ConvertData(MemoryMappedViewAccessor accessor, PointCloudPoin
OutputScaleY = transformationData.OutputScaleY,
OutputScaleZ = transformationData.OutputScaleZ,

Counts = (int*) counts.GetUnsafePtr(),
Counts = (int*)counts.GetUnsafePtr(),
ThreadIndex = 0,
};

var h = job.Schedule((int) count, 65536);
var h = job.Schedule((int)count, 65536);
while (!h.IsCompleted)
{
System.Threading.Thread.Sleep(100);

var processed = counts.Sum();
var progress = (float) ((double) processed / count);
var progress = (float)((double)processed / count);
EditorUtility.DisplayProgressBar(
string.IsNullOrEmpty(progressBarTitle) ? $"Applying transformation" : progressBarTitle,
$"{processed:N0} points", progress);
Expand Down Expand Up @@ -462,7 +473,7 @@ public static void ConvertLasData(MemoryMappedViewAccessor accessor, PointCloudP
OutputScaleY = transformationData.OutputScaleY,
OutputScaleZ = transformationData.OutputScaleZ,

Counts = (int*) counts.GetUnsafePtr(),
Counts = (int*)counts.GetUnsafePtr(),
ThreadIndex = 0,
};

Expand All @@ -486,7 +497,7 @@ public static void ConvertLasData(MemoryMappedViewAccessor accessor, PointCloudP
System.Threading.Thread.Sleep(100);

int processed = counts.Sum();
float progress = (float) ((double) processed / count);
float progress = (float)((double)processed / count);
EditorUtility.DisplayProgressBar(
string.IsNullOrEmpty(progressBarTitle) ? $"Applying transformation" : progressBarTitle,
$"{processed:N0} points", progress);
Expand All @@ -511,7 +522,7 @@ private static unsafe InputAccess GetInputAccess(PointElementName name, List<Poi
if (element.Type == PointElementType.Float || element.Type == PointElementType.Double)
{
var elementSize = PointElement.GetSize(element.Type);
return new InputAccess() {Size = elementSize, Stride = stride, Data = data + element.Offset};
return new InputAccess() { Size = elementSize, Stride = stride, Data = data + element.Offset };
}
else
{
Expand Down Expand Up @@ -540,6 +551,10 @@ private static unsafe ColorAccess GetColorAccess(List<PointElement> elements, by
{
result.IntensityF = data + elements[i].Offset;
}
else if (elements[i].Name == PointElementName.RGB && elements[i].Type == PointElementType.Float)
{
result.ColorF = data + elements[i].Offset;
}
else if (i < elements.Count - 2
&& elements[i].Name == PointElementName.R
&& elements[i + 1].Name == PointElementName.G
Expand All @@ -552,7 +567,7 @@ private static unsafe ColorAccess GetColorAccess(List<PointElement> elements, by
}
}

if (result.Intensity == null && result.IntensityF == null && result.Color == null)
if (result.Intensity == null && result.IntensityF == null && result.Color == null && result.ColorF == null)
{
Debug.LogError("Point Cloud has no color and intensity data. Everything will be black!");
}
Expand Down