Skip to content

Commit

Permalink
Small refactor of Ply in prep for saving
Browse files Browse the repository at this point in the history
  • Loading branch information
hyperlogic committed Jun 28, 2024
1 parent 6d61c2a commit 60e642e
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 38 deletions.
75 changes: 47 additions & 28 deletions src/ply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@

#include "core/log.h"

static size_t propertyTypeSizeArr[Ply::PropertyType::NumTypes] = {
0, // Unknown
1, // Char
1, // UChar
2, // Short
2, // UShort
4, // Int
4, // UInt
4, // Float
8 // Double
};

static bool CheckLine(std::ifstream& plyFile, const std::string& validLine)
{
std::string line;
Expand All @@ -37,6 +49,11 @@ static bool GetNextPlyLine(std::ifstream& plyFile, std::string& lineOut)
return false;
}

Ply::Ply() : vertexCount(0), vertexSize(0)
{
;
}

bool Ply::ParseHeader(std::ifstream& plyFile)
{
ZoneScopedNC("Ply::ParseHeader", tracy::Color::Green);
Expand Down Expand Up @@ -90,7 +107,6 @@ bool Ply::ParseHeader(std::ifstream& plyFile)
// TODO: support other "element" types faces, edges etc?
// at the moment I only care about ply files with vertex elements.

size_t offset = 0;
while (true)
{
if (!GetNextPlyLine(plyFile, line))
Expand All @@ -104,8 +120,6 @@ bool Ply::ParseHeader(std::ifstream& plyFile)
break;
}

using PropInfoPair = std::pair<std::string, PropertyInfo>;

iss.str(line);
iss.clear();
iss >> token1 >> token2 >> token3;
Expand All @@ -116,43 +130,35 @@ bool Ply::ParseHeader(std::ifstream& plyFile)
}
if (token2 == "char" || token2 == "int8")
{
propertyInfoMap.emplace(PropInfoPair(token3, {offset, 1, Ply::Type::Char}));
offset += 1;
AddPropertyInfo(token3, PropertyType::Char);
}
else if (token2 == "uchar" || token2 == "uint8")
{
propertyInfoMap.emplace(PropInfoPair(token3, {offset, 1, Ply::Type::UChar}));
offset += 1;
AddPropertyInfo(token3, PropertyType::UChar);
}
else if (token2 == "short" || token2 == "int16")
{
propertyInfoMap.emplace(PropInfoPair(token3, {offset, 2, Ply::Type::Short}));
offset += 2;
AddPropertyInfo(token3, PropertyType::Short);
}
else if (token2 == "ushort" || token2 == "uint16")
{
propertyInfoMap.emplace(PropInfoPair(token3, {offset, 2, Ply::Type::UShort}));
offset += 2;
AddPropertyInfo(token3, PropertyType::UShort);
}
else if (token2 == "int" || token2 == "int32")
{
propertyInfoMap.emplace(PropInfoPair(token3, {offset, 4, Ply::Type::Int}));
offset += 4;
AddPropertyInfo(token3, PropertyType::Int);
}
else if (token2 == "uint" || token2 == "uint32")
{
propertyInfoMap.emplace(PropInfoPair(token3, {offset, 4, Ply::Type::UInt}));
offset += 4;
AddPropertyInfo(token3, PropertyType::UInt);
}
else if (token2 == "float" || token2 == "float32")
{
propertyInfoMap.emplace(PropInfoPair(token3, {offset, 4, Ply::Type::Float}));
offset += 4;
AddPropertyInfo(token3, PropertyType::Float);
}
else if (token2 == "double" || token2 == "float64")
{
propertyInfoMap.emplace(PropInfoPair(token3, {offset, 8, Ply::Type::Double}));
offset += 8;
AddPropertyInfo(token3, PropertyType::Double);
}
else
{
Expand All @@ -161,8 +167,6 @@ bool Ply::ParseHeader(std::ifstream& plyFile)
}
}

vertexSize = offset;

return true;
}

Expand All @@ -173,17 +177,17 @@ bool Ply::Parse(std::ifstream& plyFile)
return false;
}

// read rest of file into dataVec
// read rest of file into data ptr
{
ZoneScopedNC("Ply::Parse() read data", tracy::Color::Yellow);
dataVec.resize(vertexSize * vertexCount);
plyFile.read((char*)dataVec.data(), vertexSize * vertexCount);
AllocData(vertexCount);
plyFile.read((char*)data.get(), vertexSize * vertexCount);
}

return true;
}

bool Ply::GetPropertyInfo(const std::string& key, Ply::PropertyInfo& propertyInfoOut) const
bool Ply::GetPropertyInfo(const std::string& key, PropertyInfo& propertyInfoOut) const
{
auto iter = propertyInfoMap.find(key);
if (iter != propertyInfoMap.end())
Expand All @@ -194,12 +198,27 @@ bool Ply::GetPropertyInfo(const std::string& key, Ply::PropertyInfo& propertyInf
return false;
}

void Ply::AddPropertyInfo(const std::string& key, PropertyType type)
{
using PropInfoPair = std::pair<std::string, PropertyInfo>;

size_t propSize = propertyTypeSizeArr[(int)type];
propertyInfoMap.emplace(PropInfoPair(key, {vertexSize, propSize, PropertyType::Char, (uint16_t)propertyInfoMap.size()}));
vertexSize += propSize;
}

void Ply::AllocData(size_t numVertices)
{
data.reset(new uint8_t[vertexSize * numVertices]);
}

void Ply::ForEachVertex(const VertexCallback& cb) const
{
const uint8_t* vertexPtr = dataVec.data();
const uint8_t* ptr = data.get();
for (size_t i = 0; i < vertexCount; i++)
{
cb(vertexPtr, vertexSize);
vertexPtr += vertexSize;
cb(ptr, vertexSize);
ptr += vertexSize;
}
}

23 changes: 15 additions & 8 deletions src/ply.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,22 @@

#pragma once


#include <cassert>
#include <cstdint>
#include <functional>
#include <memory>
#include <string>
#include <cstdint>
#include <unordered_map>
#include <vector>

class Ply
{
public:
Ply();
bool Parse(std::ifstream& plyFile);

enum class Type
enum class PropertyType : uint16_t
{
Unknown,
Char,
Expand All @@ -27,22 +30,24 @@ class Ply
Int,
UInt,
Float,
Double
Double,
NumTypes
};

struct PropertyInfo
{
PropertyInfo() : type(Type::Unknown) {}
PropertyInfo(size_t offsetIn, size_t sizeIn, Type typeIn) : offset(offsetIn), size(sizeIn), type(typeIn) {}
PropertyInfo() : type(PropertyType::Unknown) {}
PropertyInfo(size_t offsetIn, size_t sizeIn, PropertyType typeIn, uint16_t indexIn) : offset(offsetIn), size(sizeIn), type(typeIn), index(indexIn) {}

size_t offset;
size_t size;
Type type;
PropertyType type;
uint16_t index;

template <typename T>
const T Get(const uint8_t* data) const
{
if (type == Type::Unknown)
if (type == PropertyType::Unknown)
{
return 0;
}
Expand All @@ -55,6 +60,8 @@ class Ply
};

bool GetPropertyInfo(const std::string& key, PropertyInfo& propertyInfoOut) const;
void AddPropertyInfo(const std::string& key, PropertyType type);
void AllocData(size_t numVertices);

using VertexCallback = std::function<void(const uint8_t*, size_t)>;
void ForEachVertex(const VertexCallback& cb) const;
Expand All @@ -65,7 +72,7 @@ class Ply
bool ParseHeader(std::ifstream& plyFile);

std::unordered_map<std::string, PropertyInfo> propertyInfoMap;
std::vector<uint8_t> dataVec;
std::unique_ptr<uint8_t> data;
size_t vertexCount;
size_t vertexSize;
};
28 changes: 26 additions & 2 deletions src/pointcloud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ bool PointCloud::ImportPly(const std::string& plyFilename)
Log::E("Error parsing ply file \"%s\", missing position property\n", plyFilename.c_str());
}

bool useDoubles = (props.x.type == Ply::Type::Double && props.y.type == Ply::Type::Double && props.z.type == Ply::Type::Double);
bool useDoubles = (props.x.type == Ply::PropertyType::Double &&
props.y.type == Ply::PropertyType::Double &&
props.z.type == Ply::PropertyType::Double);

if (!ply.GetPropertyInfo("red", props.red) ||
!ply.GetPropertyInfo("green", props.green) ||
Expand Down Expand Up @@ -130,7 +132,7 @@ bool PointCloud::ImportPly(const std::string& plyFilename)

bool PointCloud::ExportPly(const std::string& plyFilename) const
{
// AJT: TODO FIXME BROKEN
// AJT: TODO
return false;

std::ofstream plyFile(plyFilename, std::ios::binary);
Expand All @@ -140,6 +142,27 @@ bool PointCloud::ExportPly(const std::string& plyFilename) const
return false;
}

Ply ply;
ply.AddPropertyInfo("x", Ply::PropertyType::Float);
ply.AddPropertyInfo("y", Ply::PropertyType::Float);
ply.AddPropertyInfo("z", Ply::PropertyType::Float);
ply.AddPropertyInfo("nx", Ply::PropertyType::Float);
ply.AddPropertyInfo("ny", Ply::PropertyType::Float);
ply.AddPropertyInfo("nz", Ply::PropertyType::Float);
ply.AddPropertyInfo("red", Ply::PropertyType::UChar);
ply.AddPropertyInfo("green", Ply::PropertyType::UChar);
ply.AddPropertyInfo("blue", Ply::PropertyType::UChar);

ply.AllocData(numPoints);

/*
ply.ForEachVertex([this](uint8_t* data, size_t size))
{
positionAttrib.Set
}
*/

/*
// ply files have unix line endings.
plyFile << "ply\n";
plyFile << "format binary_little_endian 1.0\n";
Expand All @@ -154,6 +177,7 @@ bool PointCloud::ExportPly(const std::string& plyFilename) const
plyFile << "property uchar green\n";
plyFile << "property uchar blue\n";
plyFile << "end_header\n";
*/

/*
const size_t POINT_SIZE = 27;
Expand Down

0 comments on commit 60e642e

Please sign in to comment.