#3345 HoloLens: Started work on exporting HoloLens visualization data from ResInsight

This commit is contained in:
sigurdp
2018-09-18 15:39:24 +02:00
parent 43ac06ca98
commit f1f234a04a
6 changed files with 630 additions and 2 deletions

View File

@@ -3,14 +3,20 @@ set (SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RicHoloLensExportToFolderFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicHoloLensExportToFolderUi.h
${CMAKE_CURRENT_LIST_DIR}/RicHoloLensExportImpl.h
${CMAKE_CURRENT_LIST_DIR}/VdeArrayDataPacket.h
${CMAKE_CURRENT_LIST_DIR}/VdeExportPart.h
${CMAKE_CURRENT_LIST_DIR}/VdeFileExporter.h
)
set (SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RicHoloLensExportToFolderFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicHoloLensExportImpl.cpp
${CMAKE_CURRENT_LIST_DIR}/RicHoloLensExportToFolderUi.cpp
${CMAKE_CURRENT_LIST_DIR}/VdeArrayDataPacket.cpp
${CMAKE_CURRENT_LIST_DIR}/VdeExportPart.cpp
${CMAKE_CURRENT_LIST_DIR}/VdeFileExporter.cpp
)

View File

@@ -20,6 +20,8 @@
#include "RicHoloLensExportImpl.h"
#include "RicHoloLensExportToFolderUi.h"
#include "VdeFileExporter.h"
#include "RiaApplication.h"
#include "RimCase.h"
#include "RimDialogData.h"
@@ -57,12 +59,12 @@ void RicHoloLensExportToFolderFeature::onActionTriggered(bool isChecked)
RicHoloLensExportToFolderUi* featureUi = RiaApplication::instance()->project()->dialogData()->holoLensExportToFolderData();
featureUi->setViewForExport(activeView);
caf::PdmUiPropertyViewDialog propertyDialog(
nullptr, featureUi, "HoloLens - Export Data Folder", "", QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
caf::PdmUiPropertyViewDialog propertyDialog(nullptr, featureUi, "HoloLens - Export Data Folder", "", QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
propertyDialog.resize(QSize(400, 330));
if (propertyDialog.exec() == QDialog::Accepted && !featureUi->exportFolder().isEmpty())
{
/*
cvf::Collection<cvf::Part> allPartsColl;
RimGridView* viewForExport = featureUi->viewForExport();
@@ -102,6 +104,17 @@ void RicHoloLensExportToFolderFeature::onActionTriggered(bool isChecked)
}
}
}
*/
RimGridView* viewForExport = featureUi->viewForExport();
if (!viewForExport) return;
QDir dir(featureUi->exportFolder());
const QString absOutputFolder = dir.absolutePath();
VdeFileExporter exporter(absOutputFolder);
exporter.exportViewContents(*viewForExport);
}
}

View File

@@ -0,0 +1,170 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "VdeArrayDataPacket.h"
//==================================================================================================
//
//
//
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
VdeArrayDataPacket::VdeArrayDataPacket()
: m_packetId(-1),
m_elementType(Unknown),
m_elementCount(0)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool VdeArrayDataPacket::assign(int packetId, ElementType elementType, size_t elementCount, const char* payloadPtr, size_t payloadSizeInBytes)
{
const size_t headerByteCount = 3*sizeof(int);
const size_t totalSizeBytes = headerByteCount + payloadSizeInBytes;
m_dataBytes.resize(totalSizeBytes);
int* headerIntPtr = reinterpret_cast<int*>(m_dataBytes.data());
headerIntPtr[0] = packetId;
headerIntPtr[1] = elementType;
headerIntPtr[2] = static_cast<int>(elementCount);
m_dataBytes.insert(m_dataBytes.begin() + headerByteCount, payloadPtr, payloadPtr + payloadSizeInBytes);
m_packetId = packetId;
m_elementType = elementType;
m_elementCount = elementCount;
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
VdeArrayDataPacket::ElementType VdeArrayDataPacket::elementType() const
{
return m_elementType;
}
//--------------------------------------------------------------------------------------------------
/// Size of each element in bytes
//--------------------------------------------------------------------------------------------------
size_t VdeArrayDataPacket::elementSize() const
{
switch (m_elementType)
{
case Uint32: return sizeof(unsigned int);
case Float32: return sizeof(float);
case Unknown: return 0;
}
return 0;
}
//--------------------------------------------------------------------------------------------------
/// Return number of elements in the array
//--------------------------------------------------------------------------------------------------
size_t VdeArrayDataPacket::elementCount() const
{
return m_elementCount;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const char* VdeArrayDataPacket::arrayData() const
{
const size_t headerByteCount = 3*sizeof(int);
const char* ptr = m_dataBytes.data();
return ptr + headerByteCount;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
VdeArrayDataPacket VdeArrayDataPacket::fromFloat32Arr(int packetId, const float* srcArr, size_t srcArrElementCount)
{
size_t payloadByteCount = srcArrElementCount*sizeof(float);
const char* rawSrcPtr = reinterpret_cast<const char*>(srcArr);
VdeArrayDataPacket packet;
packet.assign(packetId, Float32, srcArrElementCount, rawSrcPtr, payloadByteCount);
return packet;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
VdeArrayDataPacket VdeArrayDataPacket::fromUint32Arr(int packetId, const unsigned int* srcArr, size_t srcArrElementCount)
{
size_t payloadByteCount = srcArrElementCount*sizeof(unsigned int);
const char* rawSrcPtr = reinterpret_cast<const char*>(srcArr);
VdeArrayDataPacket packet;
packet.assign(packetId, Uint32, srcArrElementCount, rawSrcPtr, payloadByteCount);
return packet;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
VdeArrayDataPacket VdeArrayDataPacket::fromRawPacketBuffer(const char* rawPacketBuffer, size_t bufferByteSize)
{
const size_t headerByteCount = 3*sizeof(int);
if (bufferByteSize < headerByteCount)
{
return VdeArrayDataPacket();
}
const int* headerIntPtr = reinterpret_cast<const int*>(rawPacketBuffer);
const int packetId = headerIntPtr[0];
const ElementType elementType = static_cast<ElementType>(headerIntPtr[1]);
const size_t elementCount = headerIntPtr[2];
const char* payloadPtr = rawPacketBuffer + headerByteCount;
const size_t payloadSizeInBytes = bufferByteSize - headerByteCount;
VdeArrayDataPacket packet;
packet.assign(packetId, elementType, elementCount, payloadPtr, payloadSizeInBytes);
return packet;
}
//--------------------------------------------------------------------------------------------------
/// Size of the complete packet, including header, in bytes
//--------------------------------------------------------------------------------------------------
size_t VdeArrayDataPacket::fullPacketSize() const
{
return m_dataBytes.size();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const char* VdeArrayDataPacket::fullPacketRawPtr() const
{
return m_dataBytes.data();
}

View File

@@ -0,0 +1,65 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <vector>
//==================================================================================================
//
//
//
//==================================================================================================
class VdeArrayDataPacket
{
public:
enum ElementType
{
Unknown = 0,
Uint32,
Float32
};
public:
ElementType elementType() const;
size_t elementSize() const;
size_t elementCount() const;
const char* arrayData() const;
size_t fullPacketSize() const;
const char* fullPacketRawPtr() const;
static VdeArrayDataPacket fromFloat32Arr(int packetId, const float* srcArr, size_t srcArrElementCount);
static VdeArrayDataPacket fromUint32Arr(int packetId, const unsigned int* srcArr, size_t srcArrElementCount);
static VdeArrayDataPacket fromRawPacketBuffer(const char* rawPacketBuffer, size_t bufferByteSize);
private:
VdeArrayDataPacket();
bool assign(int packetId, ElementType elementType, size_t elementCount, const char* payloadPtr, size_t payloadSizeInBytes);
private:
int m_packetId;
ElementType m_elementType;
size_t m_elementCount;
std::vector<char> m_dataBytes;
};

View File

@@ -0,0 +1,300 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "VdeFileExporter.h"
#include "VdeArrayDataPacket.h"
#include "RicHoloLensExportImpl.h"
#include "RimGridView.h"
#include "RimSimWellInView.h"
#include "RimWellPath.h"
#include "RivSimWellPipeSourceInfo.h"
#include "RivSourceInfo.h"
#include "RivWellPathSourceInfo.h"
#include "RiuViewer.h"
#include "RifJsonEncodeDecode.h"
#include "cvfPart.h"
#include "cvfScene.h"
#include "cvfDrawableGeo.h"
#include "cvfPrimitiveSet.h"
#include "cvfTrace.h"
#include <QString>
#include <QDir>
#include <QFile>
//==================================================================================================
//
//
//
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
VdeFileExporter::VdeFileExporter(QString absOutputFolder)
: m_absOutputFolder(absOutputFolder)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool VdeFileExporter::exportViewContents(const RimGridView& view)
{
cvf::Collection<cvf::Part> allPartsColl;
RicHoloLensExportImpl::partsForExport(&view, &allPartsColl);
std::vector<RicHoloLensMesh> meshArr;
for (size_t i = 0; i < allPartsColl.size(); i++)
{
const cvf::Part* part = allPartsColl.at(i);
if (part)
{
RicHoloLensMesh mesh;
if (extractMeshFromPart(view, *part, &mesh))
{
meshArr.push_back(mesh);
}
}
}
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;
int nextArrayId = 0;
for (size_t i = 0; i < meshArr.size(); i++)
{
const RicHoloLensMesh& mesh = meshArr[i];
const size_t primCount = mesh.connArr.size()/3;
cvf::Trace::show("%d: primCount=%d meshSourceObjName='%s'", i, primCount, mesh.meshSourceObjName.toLatin1().constData());
MeshIds meshIds;
{
meshIds.vertexArrId = nextArrayId++;
QString fileName = arrayDataFileNameTrunk + QString::number(meshIds.vertexArrId) + ".bin";
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly))
{
return false;
}
cvf::cref<cvf::Vec3fArray> vertexArrToExport;
vertexArrToExport = mesh.vertexArr;
const float* floatArr = reinterpret_cast<const float*>(vertexArrToExport->ptr());
VdeArrayDataPacket dataPacket = VdeArrayDataPacket::fromFloat32Arr(meshIds.vertexArrId, floatArr, 3*vertexArrToExport->size());
file.write(dataPacket.fullPacketRawPtr(), dataPacket.fullPacketSize());
{
VdeArrayDataPacket testPacket = VdeArrayDataPacket::fromRawPacketBuffer(dataPacket.fullPacketRawPtr(), dataPacket.fullPacketSize());
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]);
}
}
}
{
meshIds.connArrId = nextArrayId++;
QString fileName = arrayDataFileNameTrunk + QString::number(meshIds.connArrId) + ".bin";
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly))
{
return false;
}
const unsigned int* uintArr = mesh.connArr.data();
VdeArrayDataPacket dataPacket = VdeArrayDataPacket::fromUint32Arr(meshIds.connArrId, uintArr, mesh.connArr.size());
file.write(dataPacket.fullPacketRawPtr(), dataPacket.fullPacketSize());
{
VdeArrayDataPacket testPacket = VdeArrayDataPacket::fromRawPacketBuffer(dataPacket.fullPacketRawPtr(), dataPacket.fullPacketSize());
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]);
}
}
}
meshIdsArr.push_back(meshIds);
}
{
QVariantList meshVariantList;
for (size_t i = 0; i < meshArr.size(); i++)
{
const RicHoloLensMesh& mesh = meshArr[i];
const MeshIds& meshIds = meshIdsArr[i];
QMap<QString, QVariant> meshMeta;
meshMeta["meshSourceObjType"] = "grid";
meshMeta["meshSourceObjName"] = mesh.meshSourceObjName;
meshMeta["verticesPerPrimitive"] = mesh.verticesPerPrimitive;
meshMeta["vertexArrId"] = meshIds.vertexArrId;
meshMeta["connArrId"] = meshIds.connArrId;
meshVariantList.push_back(meshMeta);
}
QMap<QString, QVariant> modelMetaJson;
modelMetaJson["meshArr"] = meshVariantList;
ResInsightInternalJson::Json jsonCodec;
const bool prettifyJson = true;
QByteArray jsonStr = jsonCodec.encode(modelMetaJson, 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;
}
}
/*
QDir outputDir(m_absOutputFolder);
//QByteArray jsonStr = "Dette er en test\nlinje2";
QMap<QString, QVariant> json;
json["sigurd"] = "er kul";
json["testDouble"] = 1.23;
json["testInt"] = 1;
QMap<QString, QVariant> sub;
sub["keyA"] = 123;
QVariantList l;
l.push_back(1);
l.push_back(2);
l.push_back(3);
sub["keyB"] = l;
json["theSub"] = sub;
ResInsightInternalJson::Json jsonCodec;
QByteArray jsonStr = jsonCodec.encode(json).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 true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool VdeFileExporter::extractMeshFromPart(const RimGridView& view, const cvf::Part& part, RicHoloLensMesh* mesh)
{
const cvf::DrawableGeo* geo = dynamic_cast<const cvf::DrawableGeo*>(part.drawable());
if (!geo)
{
return false;
}
const cvf::Vec3fArray* vertexArr = geo->vertexArray();
const cvf::PrimitiveSet* primSet = geo->primitiveSetCount() > 0 ? geo->primitiveSet(0) : nullptr;
if (!vertexArr || !primSet)
{
return false;
}
if (primSet->primitiveType() != cvf::PT_TRIANGLES || primSet->faceCount() == 0)
{
return false;
}
mesh->verticesPerPrimitive = 3;
mesh->vertexArr = vertexArr;
cvf::UIntArray faceConn;
const size_t faceCount = primSet->faceCount();
for (size_t i = 0; i < faceCount; i++)
{
primSet->getFaceIndices(i, &faceConn);
mesh->connArr.insert(mesh->connArr.end(), faceConn.begin(), faceConn.end());
}
const QString nameOfObject = RicHoloLensExportImpl::nameFromPart(&part);
mesh->meshSourceObjName = nameOfObject;
return true;
}

View File

@@ -0,0 +1,74 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cvfBase.h"
#include "cvfCollection.h"
#include "cvfArray.h"
#include <QString>
class RimGridView;
namespace cvf
{
class Part;
}
//==================================================================================================
//
//
//
//==================================================================================================
struct RicHoloLensMesh
{
QString meshSourceObjName;
int verticesPerPrimitive;
cvf::cref<cvf::Vec3fArray> vertexArr;
std::vector<cvf::uint> connArr;
RicHoloLensMesh()
: verticesPerPrimitive(-1)
{}
};
//==================================================================================================
//
//
//
//==================================================================================================
class VdeFileExporter
{
public:
VdeFileExporter(QString absOutputFolder);
bool exportViewContents(const RimGridView& view);
private:
static bool extractMeshFromPart(const RimGridView& view, const cvf::Part& part, RicHoloLensMesh* mesh);
private:
QString m_absOutputFolder;
};