#3345 HoloLens: Refactor and initial format support for textures/texture coordinates

This commit is contained in:
sigurdp
2018-09-19 12:42:19 +02:00
parent a70c8659c0
commit c1c87a0370
4 changed files with 240 additions and 132 deletions

View File

@@ -59,7 +59,10 @@ static const size_t VDE_PACKET_VERSION = 1;
VdeArrayDataPacket::VdeArrayDataPacket()
: m_arrayId(-1),
m_elementType(Unknown),
m_elementCount(0)
m_elementCount(0),
m_imageWidth(0),
m_imageHeight(0),
m_imageComponentCount(0)
{
}
@@ -136,6 +139,30 @@ const char* VdeArrayDataPacket::arrayData() const
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
unsigned short VdeArrayDataPacket::imageWidth() const
{
return m_imageWidth;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
unsigned short VdeArrayDataPacket::imageHeight() const
{
return m_imageHeight;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
unsigned char VdeArrayDataPacket::imageComponentCount() const
{
return m_imageComponentCount;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -145,7 +172,7 @@ VdeArrayDataPacket VdeArrayDataPacket::fromFloat32Arr(int arrayId, const float*
const char* rawSrcPtr = reinterpret_cast<const char*>(srcArr);
VdeArrayDataPacket packet;
packet.assign(arrayId, Float32, srcArrElementCount, rawSrcPtr, payloadByteCount);
packet.assign(arrayId, Float32, srcArrElementCount, 0, 0, 0, rawSrcPtr, payloadByteCount);
return packet;
}
@@ -158,7 +185,20 @@ VdeArrayDataPacket VdeArrayDataPacket::fromUint32Arr(int arrayId, const unsigned
const char* rawSrcPtr = reinterpret_cast<const char*>(srcArr);
VdeArrayDataPacket packet;
packet.assign(arrayId, Uint32, srcArrElementCount, rawSrcPtr, payloadByteCount);
packet.assign(arrayId, Uint32, srcArrElementCount, 0, 0, 0, rawSrcPtr, payloadByteCount);
return packet;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
VdeArrayDataPacket VdeArrayDataPacket::fromUint8ImageRGBArr(int arrayId, unsigned short imageWidth, unsigned short imageHeight, const unsigned char* srcArr, size_t srcArrElementCount)
{
size_t payloadByteCount = srcArrElementCount*sizeof(unsigned int);
const char* rawSrcPtr = reinterpret_cast<const char*>(srcArr);
VdeArrayDataPacket packet;
packet.assign(arrayId, Uint8, srcArrElementCount, imageWidth, imageHeight, 3, rawSrcPtr, payloadByteCount);
return packet;
}
@@ -185,11 +225,15 @@ VdeArrayDataPacket VdeArrayDataPacket::fromRawPacketBuffer(const char* rawPacket
const ElementType elementType = static_cast<ElementType>(bufferReader.getUint8(VDE_BYTEOFFSET_ELEMENT_TYPE));
const size_t elementCount = bufferReader.getUint32(VDE_BYTEOFFSET_ELEMENT_COUNT);
const unsigned char imageCompCount = bufferReader.getUint8(VDE_BYTEOFFSET_IMAGE_COMPONENT_COUNT);
const unsigned short imageWidth = bufferReader.getUint16(VDE_BYTEOFFSET_IMAGE_WIDTH);
const unsigned short imageHeight = bufferReader.getUint16(VDE_BYTEOFFSET_IMAGE_HEIGHT);
const char* payloadPtr = rawPacketBuffer + VDE_HEADER_SIZE;
const size_t payloadSizeInBytes = bufferSize - VDE_HEADER_SIZE;
VdeArrayDataPacket packet;
packet.assign(packetId, elementType, elementCount, payloadPtr, payloadSizeInBytes);
packet.assign(packetId, elementType, elementCount, imageWidth, imageHeight, imageCompCount, payloadPtr, payloadSizeInBytes);
return packet;
}
@@ -197,9 +241,9 @@ VdeArrayDataPacket VdeArrayDataPacket::fromRawPacketBuffer(const char* rawPacket
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool VdeArrayDataPacket::assign(int arrayId, ElementType elementType, size_t elementCount, const char* payloadPtr, size_t payloadSizeInBytes)
bool VdeArrayDataPacket::assign(int arrayId, ElementType elementType, size_t elementCount, unsigned short imageWidth, unsigned short imageHeight, unsigned char imageCompCount, const char* arrayDataPtr, size_t arrayDataSizeInBytes)
{
const size_t totalSizeBytes = VDE_HEADER_SIZE + payloadSizeInBytes;
const size_t totalSizeBytes = VDE_HEADER_SIZE + arrayDataSizeInBytes;
m_packetBytes.resize(totalSizeBytes);
VdeBufferWriter bufferWriter(m_packetBytes.data(), m_packetBytes.size());
@@ -207,16 +251,20 @@ bool VdeArrayDataPacket::assign(int arrayId, ElementType elementType, size_t ele
bufferWriter.setUint32(VDE_BYTEOFFSET_ARRAY_ID, arrayId);
bufferWriter.setUint32(VDE_BYTEOFFSET_ELEMENT_COUNT, static_cast<unsigned int>(elementCount));
bufferWriter.setUint8( VDE_BYTEOFFSET_ELEMENT_TYPE, static_cast<unsigned char>(elementType));
bufferWriter.setUint16(VDE_BYTEOFFSET_IMAGE_COMPONENT_COUNT, 0);
bufferWriter.setUint16(VDE_BYTEOFFSET_IMAGE_WIDTH, 0);
bufferWriter.setUint16(VDE_BYTEOFFSET_IMAGE_HEIGHT, 0);
bufferWriter.setUint16(VDE_BYTEOFFSET_IMAGE_COMPONENT_COUNT, imageCompCount);
bufferWriter.setUint16(VDE_BYTEOFFSET_IMAGE_WIDTH, imageWidth);
bufferWriter.setUint16(VDE_BYTEOFFSET_IMAGE_HEIGHT, imageHeight);
m_packetBytes.insert(m_packetBytes.begin() + VDE_HEADER_SIZE, payloadPtr, payloadPtr + payloadSizeInBytes);
m_packetBytes.insert(m_packetBytes.begin() + VDE_HEADER_SIZE, arrayDataPtr, arrayDataPtr + arrayDataSizeInBytes);
m_arrayId = arrayId;
m_elementType = elementType;
m_elementCount = elementCount;
m_imageComponentCount = imageCompCount;
m_imageWidth = imageWidth;
m_imageHeight = imageHeight;
return true;
}

View File

@@ -50,24 +50,31 @@ public:
size_t elementCount() const;
const char* arrayData() const;
unsigned short imageWidth() const;
unsigned short imageHeight() const;
unsigned char imageComponentCount() const;
size_t fullPacketSize() const;
const char* fullPacketRawPtr() const;
static VdeArrayDataPacket fromFloat32Arr(int arrayId, const float* srcArr, size_t srcArrElementCount);
static VdeArrayDataPacket fromUint32Arr(int arrayId, const unsigned int* srcArr, size_t srcArrElementCount);
//static VdeArrayDataPacket fromUint8ImageRGBArr(int arrayId, unsigned short imageWidth, unsigned short imageHeight, const unsigned char* srcArr, size_t srcArrElementCount);
static VdeArrayDataPacket fromUint8ImageRGBArr(int arrayId, unsigned short imageWidth, unsigned short imageHeight, const unsigned char* srcArr, size_t srcArrElementCount);
static VdeArrayDataPacket fromRawPacketBuffer(const char* rawPacketBuffer, size_t bufferSize, std::string* errString);
private:
bool assign(int arrayId, ElementType elementType, size_t elementCount, const char* payloadPtr, size_t payloadSizeInBytes);
bool assign(int arrayId, ElementType elementType, size_t elementCount, unsigned short imageWidth, unsigned short imageHeight, unsigned char imageCompCount, const char* arrayDataPtr, size_t arrayDataSizeInBytes);
private:
int m_arrayId;
ElementType m_elementType;
size_t m_elementCount;
unsigned short m_imageWidth;
unsigned short m_imageHeight;
unsigned char m_imageComponentCount;
std::vector<char> m_packetBytes;
};

View File

@@ -87,21 +87,7 @@ bool VdeFileExporter::exportViewContents(const RimGridView& view)
}
const QDir outputDir(m_absOutputFolder);
const QString arrayDataFileNameTrunk = outputDir.absoluteFilePath("arrayData_");
struct MeshIds
{
int vertexArrId;
int connArrId;
MeshIds()
: vertexArrId(-1),
connArrId(-1)
{}
};
std::vector<MeshIds> meshIdsArr;
std::vector<VdeMeshContentIds> meshContentIdsArr;
int nextArrayId = 0;
for (size_t i = 0; i < meshArr.size(); i++)
@@ -110,119 +96,56 @@ bool VdeFileExporter::exportViewContents(const RimGridView& view)
const size_t primCount = mesh.connArr.size()/3;
cvf::Trace::show("%d: primCount=%d meshSourceObjName='%s'", i, primCount, mesh.meshSourceObjName.toLatin1().constData());
MeshIds meshIds;
VdeMeshContentIds meshContentIds;
{
meshIds.vertexArrId = nextArrayId++;
QString fileName = arrayDataFileNameTrunk + QString::number(meshIds.vertexArrId) + ".bin";
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly))
{
return false;
}
meshContentIds.vertexArrId = nextArrayId++;
const float* floatArr = reinterpret_cast<const float*>(mesh.vertexArr->ptr());
VdeArrayDataPacket dataPacket = VdeArrayDataPacket::fromFloat32Arr(meshIds.vertexArrId, floatArr, 3*mesh.vertexArr->size());
file.write(dataPacket.fullPacketRawPtr(), dataPacket.fullPacketSize());
VdeArrayDataPacket dataPacket = VdeArrayDataPacket::fromFloat32Arr(meshContentIds.vertexArrId, floatArr, 3*mesh.vertexArr->size());
writeDataPacketToFile(dataPacket.arrayId(), dataPacket);
// Testing decoding
{
VdeArrayDataPacket testPacket = VdeArrayDataPacket::fromRawPacketBuffer(dataPacket.fullPacketRawPtr(), dataPacket.fullPacketSize(), nullptr);
CVF_ASSERT(dataPacket.elementCount() == testPacket.elementCount());
CVF_ASSERT(dataPacket.elementSize() == testPacket.elementSize());
CVF_ASSERT(dataPacket.elementType() == testPacket.elementType());
const float* testArr = reinterpret_cast<const float*>(testPacket.arrayData());
for (size_t j = 0; j < testPacket.elementCount(); j++)
{
CVF_ASSERT(testArr[j] == floatArr[j]);
}
}
// Debug testing of decoding
debugComparePackets(dataPacket, VdeArrayDataPacket::fromRawPacketBuffer(dataPacket.fullPacketRawPtr(), dataPacket.fullPacketSize(), nullptr));
}
{
meshIds.connArrId = nextArrayId++;
QString fileName = arrayDataFileNameTrunk + QString::number(meshIds.connArrId) + ".bin";
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly))
{
return false;
}
meshContentIds.connArrId = nextArrayId++;
const unsigned int* uintArr = mesh.connArr.data();
VdeArrayDataPacket dataPacket = VdeArrayDataPacket::fromUint32Arr(meshIds.connArrId, uintArr, mesh.connArr.size());
file.write(dataPacket.fullPacketRawPtr(), dataPacket.fullPacketSize());
VdeArrayDataPacket dataPacket = VdeArrayDataPacket::fromUint32Arr(meshContentIds.connArrId, uintArr, mesh.connArr.size());
writeDataPacketToFile(dataPacket.arrayId(), dataPacket);
// Testing decoding
// Debug testing of decoding
debugComparePackets(dataPacket, VdeArrayDataPacket::fromRawPacketBuffer(dataPacket.fullPacketRawPtr(), dataPacket.fullPacketSize(), nullptr));
}
if (mesh.texCoordArr.notNull() && mesh.texImage.notNull())
{
{
VdeArrayDataPacket testPacket = VdeArrayDataPacket::fromRawPacketBuffer(dataPacket.fullPacketRawPtr(), dataPacket.fullPacketSize(), nullptr);
CVF_ASSERT(dataPacket.elementCount() == testPacket.elementCount());
CVF_ASSERT(dataPacket.elementSize() == testPacket.elementSize());
CVF_ASSERT(dataPacket.elementType() == testPacket.elementType());
const unsigned int* testArr = reinterpret_cast<const unsigned int*>(testPacket.arrayData());
for (size_t j = 0; j < testPacket.elementCount(); j++)
{
CVF_ASSERT(testArr[j] == uintArr[j]);
}
meshContentIds.texCoordsArrId = nextArrayId++;
const float* floatArr = reinterpret_cast<const float*>(mesh.texCoordArr->ptr());
VdeArrayDataPacket dataPacket = VdeArrayDataPacket::fromFloat32Arr(meshContentIds.texCoordsArrId, floatArr, 3*mesh.vertexArr->size());
writeDataPacketToFile(dataPacket.arrayId(), dataPacket);
// Debug testing of decoding
debugComparePackets(dataPacket, VdeArrayDataPacket::fromRawPacketBuffer(dataPacket.fullPacketRawPtr(), dataPacket.fullPacketSize(), nullptr));
}
{
meshContentIds.texImageArrId = nextArrayId++;
cvf::ref<cvf::UByteArray> byteArr = mesh.texImage->toRgb();
VdeArrayDataPacket dataPacket = VdeArrayDataPacket::fromUint8ImageRGBArr(meshContentIds.texImageArrId, mesh.texImage->width(), mesh.texImage->height(), byteArr->ptr(), byteArr->size());
writeDataPacketToFile(dataPacket.arrayId(), dataPacket);
// Debug testing of decoding
debugComparePackets(dataPacket, VdeArrayDataPacket::fromRawPacketBuffer(dataPacket.fullPacketRawPtr(), dataPacket.fullPacketSize(), nullptr));
}
}
meshIdsArr.push_back(meshIds);
meshContentIdsArr.push_back(meshContentIds);
}
QString jsonFileName = m_absOutputFolder + "/modelMeta.json";
if (!writeModelMetaJsonFile(meshArr, meshContentIdsArr, jsonFileName))
{
QVariantList jsonMeshMetaList;
for (size_t i = 0; i < meshArr.size(); i++)
{
const VdeMesh& mesh = meshArr[i];
const MeshIds& meshIds = meshIdsArr[i];
QMap<QString, QVariant> jsonMeshMeta;
jsonMeshMeta["meshSourceObjType"] = mesh.meshSourceObjTypeStr;
jsonMeshMeta["meshSourceObjName"] = mesh.meshSourceObjName;
jsonMeshMeta["verticesPerPrimitive"] = mesh.verticesPerPrimitive;
jsonMeshMeta["vertexArrId"] = meshIds.vertexArrId;
jsonMeshMeta["connArrId"] = meshIds.connArrId;
{
QMap<QString, QVariant> jsonColor;
jsonColor["r"] = mesh.color.r();
jsonColor["g"] = mesh.color.g();
jsonColor["b"] = mesh.color.b();
jsonMeshMeta["color"] = jsonColor;
}
jsonMeshMeta["opacity"] = 1.0;
jsonMeshMetaList.push_back(jsonMeshMeta);
}
QMap<QString, QVariant> jsonModelMeta;
jsonModelMeta["modelName"] = "ResInsightExport";
jsonModelMeta["meshArr"] = jsonMeshMetaList;
ResInsightInternalJson::Json jsonCodec;
const bool prettifyJson = true;
QByteArray jsonStr = jsonCodec.encode(jsonModelMeta, prettifyJson).toLatin1();
QString jsonFileName = outputDir.absoluteFilePath("modelMeta.json");
QFile file(jsonFileName);
if (!file.open(QIODevice::WriteOnly))
{
return false;
}
if (file.write(jsonStr) == -1)
{
return false;
}
return false;
}
return true;
@@ -308,3 +231,103 @@ bool VdeFileExporter::extractMeshFromPart(const RimGridView& view, const cvf::Pa
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool VdeFileExporter::writeDataPacketToFile(int arrayId, const VdeArrayDataPacket& packet) const
{
const QString fileName = m_absOutputFolder + QString("/arrayData_%1.bin").arg(arrayId);
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly))
{
return false;
}
if (file.write(packet.fullPacketRawPtr(), packet.fullPacketSize()) == -1)
{
return false;
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool VdeFileExporter::writeModelMetaJsonFile(const std::vector<VdeMesh>& meshArr, const std::vector<VdeMeshContentIds>& meshContentIdsArr, QString fileName)
{
QVariantList jsonMeshMetaList;
for (size_t i = 0; i < meshArr.size(); i++)
{
const VdeMesh& mesh = meshArr[i];
const VdeMeshContentIds& meshIds = meshContentIdsArr[i];
QMap<QString, QVariant> jsonMeshMeta;
jsonMeshMeta["meshSourceObjType"] = mesh.meshSourceObjTypeStr;
jsonMeshMeta["meshSourceObjName"] = mesh.meshSourceObjName;
jsonMeshMeta["verticesPerPrimitive"] = mesh.verticesPerPrimitive;
jsonMeshMeta["vertexArrId"] = meshIds.vertexArrId;
jsonMeshMeta["connArrId"] = meshIds.connArrId;
if (meshIds.texCoordsArrId >= 0 && meshIds.texImageArrId >= 0)
{
jsonMeshMeta["texCoordsArrId"] = meshIds.texCoordsArrId;
jsonMeshMeta["texImageArrId"] = meshIds.texImageArrId;
}
else
{
QMap<QString, QVariant> jsonColor;
jsonColor["r"] = mesh.color.r();
jsonColor["g"] = mesh.color.g();
jsonColor["b"] = mesh.color.b();
jsonMeshMeta["color"] = jsonColor;
}
jsonMeshMeta["opacity"] = 1.0;
jsonMeshMetaList.push_back(jsonMeshMeta);
}
QMap<QString, QVariant> jsonModelMeta;
jsonModelMeta["modelName"] = "ResInsightExport";
jsonModelMeta["meshArr"] = jsonMeshMetaList;
ResInsightInternalJson::Json jsonCodec;
const bool prettifyJson = true;
QByteArray jsonStr = jsonCodec.encode(jsonModelMeta, prettifyJson).toLatin1();
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly))
{
return false;
}
if (file.write(jsonStr) == -1)
{
return false;
}
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void VdeFileExporter::debugComparePackets(const VdeArrayDataPacket& packetA, const VdeArrayDataPacket& packetB)
{
CVF_ASSERT(packetA.elementCount() == packetB.elementCount());
CVF_ASSERT(packetA.elementSize() == packetB.elementSize());
CVF_ASSERT(packetA.elementType() == packetB.elementType());
const char* arrA = packetA.arrayData();
const char* arrB = packetB.arrayData();
for (size_t i = 0; i < packetA.elementCount(); i++)
{
CVF_ASSERT(arrA[i] == arrB[i]);
}
}

View File

@@ -21,9 +21,12 @@
#include "cvfBase.h"
#include "cvfCollection.h"
#include "cvfArray.h"
#include "cvfTextureImage.h"
#include <QString>
class VdeArrayDataPacket;
class RimGridView;
namespace cvf
@@ -40,14 +43,16 @@ class Part;
//==================================================================================================
struct VdeMesh
{
QString meshSourceObjTypeStr;
QString meshSourceObjName;
QString meshSourceObjTypeStr;
QString meshSourceObjName;
cvf::Color3f color;
cvf::Color3f color;
int verticesPerPrimitive;
cvf::cref<cvf::Vec3fArray> vertexArr;
std::vector<cvf::uint> connArr;
int verticesPerPrimitive;
cvf::cref<cvf::Vec3fArray> vertexArr;
cvf::cref<cvf::Vec2fArray> texCoordArr;
std::vector<cvf::uint> connArr;
cvf::cref<cvf::TextureImage> texImage;
VdeMesh()
: verticesPerPrimitive(-1)
@@ -55,6 +60,27 @@ struct VdeMesh
};
//==================================================================================================
//
//
//
//==================================================================================================
struct VdeMeshContentIds
{
int vertexArrId;
int connArrId;
int texImageArrId;
int texCoordsArrId;
VdeMeshContentIds()
: vertexArrId(-1),
connArrId(-1),
texImageArrId(-1),
texCoordsArrId(-1)
{}
};
//==================================================================================================
//
@@ -70,6 +96,10 @@ public:
private:
static bool extractMeshFromPart(const RimGridView& view, const cvf::Part& part, VdeMesh* mesh);
static bool writeModelMetaJsonFile(const std::vector<VdeMesh>& meshArr, const std::vector<VdeMeshContentIds>& meshContentIdsArr, QString fileName);
static void debugComparePackets(const VdeArrayDataPacket& packetA, const VdeArrayDataPacket& packetB);
bool writeDataPacketToFile(int arrayId, const VdeArrayDataPacket& packet) const;
private:
QString m_absOutputFolder;