mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-10 23:46:00 -06:00
#3561 HoloLens: Establish sharing server session and publish visualization data to sharing server
This commit is contained in:
parent
23d6e8ee2a
commit
8ca73960f4
@ -34,7 +34,7 @@
|
||||
#include "RicImportInputEclipseCaseFeature.h"
|
||||
#include "RicImportSummaryCasesFeature.h"
|
||||
#include "ExportCommands/RicSnapshotAllViewsToFileFeature.h"
|
||||
#include "HoloLensCommands/RicHoloLensSession.h"
|
||||
#include "HoloLensCommands/RicHoloLensSessionManager.h"
|
||||
|
||||
#include "Rim2dIntersectionViewCollection.h"
|
||||
#include "RimCellRangeFilterCollection.h"
|
||||
@ -996,8 +996,8 @@ bool RiaApplication::saveProjectAs(const QString& fileName)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaApplication::closeProject()
|
||||
{
|
||||
RicHoloLensSession::instance()->terminateSession();
|
||||
RicHoloLensSession::refreshToolbarState();
|
||||
RicHoloLensSessionManager::instance()->terminateSession();
|
||||
RicHoloLensSessionManager::refreshToolbarState();
|
||||
|
||||
RiuMainWindow* mainWnd = RiuMainWindow::instance();
|
||||
|
||||
|
@ -6,14 +6,18 @@ ${CMAKE_CURRENT_LIST_DIR}/RicHoloLensExportImpl.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicHoloLensExportToSharingServerFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicHoloLensCreateSessionFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicHoloLensTerminateSessionFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicHoloLensRestClient.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicHoloLensServerSettings.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicHoloLensCreateSessionUi.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicHoloLensSession.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicHoloLensSessionManager.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicHoloLensCreateDummyFileBackedSessionFeature.h
|
||||
|
||||
${CMAKE_CURRENT_LIST_DIR}/VdeArrayDataPacket.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/VdeExportPart.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/VdeFileExporter.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/VdePacketDirectory.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/VdeVizDataExtractor.h
|
||||
)
|
||||
|
||||
set (SOURCE_GROUP_SOURCE_FILES
|
||||
@ -23,14 +27,18 @@ ${CMAKE_CURRENT_LIST_DIR}/RicHoloLensExportToFolderUi.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicHoloLensExportToSharingServerFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicHoloLensCreateSessionFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicHoloLensTerminateSessionFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicHoloLensRestClient.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicHoloLensServerSettings.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicHoloLensCreateSessionUi.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicHoloLensSession.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicHoloLensSessionManager.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicHoloLensCreateDummyFileBackedSessionFeature.cpp
|
||||
|
||||
${CMAKE_CURRENT_LIST_DIR}/VdeArrayDataPacket.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/VdeExportPart.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/VdeFileExporter.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/VdePacketDirectory.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/VdeVizDataExtractor.cpp
|
||||
)
|
||||
|
||||
|
||||
@ -42,4 +50,11 @@ list(APPEND CODE_SOURCE_FILES
|
||||
${SOURCE_GROUP_SOURCE_FILES}
|
||||
)
|
||||
|
||||
set (QT_MOC_HEADERS
|
||||
${QT_MOC_HEADERS}
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicHoloLensRestClient.h
|
||||
)
|
||||
|
||||
|
||||
|
||||
source_group( "CommandFeature\\HoloLens" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CMAKE_CURRENT_LIST_DIR}/CMakeLists_files.cmake )
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
#include "RicHoloLensCreateDummyFileBackedSessionFeature.h"
|
||||
|
||||
#include "RicHoloLensSession.h"
|
||||
#include "RicHoloLensSessionManager.h"
|
||||
|
||||
#include "RiaQIconTools.h"
|
||||
|
||||
@ -31,7 +31,7 @@ CAF_CMD_SOURCE_INIT(RicHoloLensCreateDummyFiledBackedSessionFeature, "RicHoloLen
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicHoloLensCreateDummyFiledBackedSessionFeature::isCommandEnabled()
|
||||
{
|
||||
return !RicHoloLensSession::instance()->isSessionValid();
|
||||
return RicHoloLensSessionManager::instance()->session() ? false : true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -39,9 +39,9 @@ bool RicHoloLensCreateDummyFiledBackedSessionFeature::isCommandEnabled()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicHoloLensCreateDummyFiledBackedSessionFeature::onActionTriggered(bool isChecked)
|
||||
{
|
||||
RicHoloLensSession::instance()->createDummyFileBackedSession();
|
||||
RicHoloLensSessionManager::instance()->createDummyFileBackedSession();
|
||||
|
||||
RicHoloLensSession::refreshToolbarState();
|
||||
RicHoloLensSessionManager::refreshToolbarState();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
#include "RicHoloLensCreateSessionUi.h"
|
||||
#include "RicHoloLensServerSettings.h"
|
||||
#include "RicHoloLensSession.h"
|
||||
#include "RicHoloLensSessionManager.h"
|
||||
|
||||
#include "cafPdmSettings.h"
|
||||
#include "cafPdmUiPropertyViewDialog.h"
|
||||
@ -37,7 +37,7 @@ CAF_CMD_SOURCE_INIT(RicHoloLensCreateSessionFeature, "RicHoloLensCreateSessionFe
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicHoloLensCreateSessionFeature::isCommandEnabled()
|
||||
{
|
||||
return !RicHoloLensSession::instance()->isSessionValid();
|
||||
return RicHoloLensSessionManager::instance()->session() ? false : true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -60,10 +60,10 @@ void RicHoloLensCreateSessionFeature::onActionTriggered(bool isChecked)
|
||||
|
||||
propertyDialog.exec();
|
||||
|
||||
RicHoloLensSession::instance()->createSession(
|
||||
RicHoloLensSessionManager::instance()->createSession(
|
||||
createSessionUi.serverUrl(), createSessionUi.sessionName(), createSessionUi.sessionPinCode());
|
||||
|
||||
RicHoloLensSession::refreshToolbarState();
|
||||
RicHoloLensSessionManager::refreshToolbarState();
|
||||
|
||||
}
|
||||
|
||||
|
@ -17,13 +17,12 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RicHoloLensExportToSharingServerFeature.h"
|
||||
|
||||
#include "RicHoloLensSessionManager.h"
|
||||
#include "RicHoloLensSession.h"
|
||||
|
||||
#include "VdeFileExporter.h"
|
||||
|
||||
#include "RiaApplication.h"
|
||||
#include "RiaQIconTools.h"
|
||||
#include "RiaLogging.h"
|
||||
|
||||
#include "RimGridView.h"
|
||||
|
||||
@ -36,7 +35,15 @@ CAF_CMD_SOURCE_INIT(RicHoloLensExportToSharingServerFeature, "RicHoloLensExportT
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicHoloLensExportToSharingServerFeature::isCommandEnabled()
|
||||
{
|
||||
return RicHoloLensSession::instance()->isSessionValid();
|
||||
RicHoloLensSession* session = RicHoloLensSessionManager::instance()->session();
|
||||
if (session && session->isSessionValid())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -44,12 +51,22 @@ bool RicHoloLensExportToSharingServerFeature::isCommandEnabled()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicHoloLensExportToSharingServerFeature::onActionTriggered(bool isChecked)
|
||||
{
|
||||
RicHoloLensSession* session = RicHoloLensSessionManager::instance()->session();
|
||||
if (!session || !session->isSessionValid())
|
||||
{
|
||||
RiaLogging::error("No valid HoloLens session present");
|
||||
return;
|
||||
}
|
||||
|
||||
RimGridView* activeView = RiaApplication::instance()->activeGridView();
|
||||
if (!activeView)
|
||||
{
|
||||
RiaLogging::error("No active view");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!activeView) return;
|
||||
|
||||
VdeFileExporter exporter("dummypath");
|
||||
exporter.exportViewContents(*activeView);
|
||||
session->updateSessionDataFromView(*activeView);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -0,0 +1,360 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "RicHoloLensRestClient.h"
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfTrace.h"
|
||||
|
||||
#include <QNetworkRequest>
|
||||
#include <QSslConfiguration>
|
||||
|
||||
|
||||
#ifndef QT_NO_OPENSSL
|
||||
// Uncomment to enable experimental SSL support
|
||||
// The experimental support must be revised before shipping
|
||||
#define EXPERIMENTAL_SSL_SUPPORT
|
||||
#endif
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RicHoloLensRestClient::RicHoloLensRestClient(QString serverUrl, QString sessionName, RicHoloLensRestResponseHandler* responseHandler)
|
||||
: m_serverUrl(serverUrl),
|
||||
m_sessionName(sessionName),
|
||||
m_responseHandler(responseHandler)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicHoloLensRestClient::clearResponseHandler()
|
||||
{
|
||||
m_responseHandler = nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicHoloLensRestClient::createSession()
|
||||
{
|
||||
const QString url = m_serverUrl + "/sessions/create/" + m_sessionName;
|
||||
cvf::Trace::show("createSession: POST on url: %s", url.toLatin1().constData());
|
||||
|
||||
QNetworkRequest request(url);
|
||||
//request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/x-www-form-urlencoded"));
|
||||
|
||||
#ifdef EXPERIMENTAL_SSL_SUPPORT
|
||||
// NOTE !!!
|
||||
// Apparently something like this is currently needed in order to get SSL/HTTPS going
|
||||
// Still, can't quite figure it out since it appears to be sufficient to do this on the first request
|
||||
// This will have to be investigated further, SP 20181924
|
||||
QSslConfiguration sslConf = request.sslConfiguration();
|
||||
|
||||
// Needed this one to be able to connect to sharing server
|
||||
sslConf.setProtocol(QSsl::AnyProtocol);
|
||||
|
||||
// !!MUST!! remove this code in production
|
||||
sslConf.setPeerVerifyMode(QSslSocket::VerifyNone);
|
||||
|
||||
request.setSslConfiguration(sslConf);
|
||||
#endif
|
||||
|
||||
QNetworkReply* reply = m_accessManager.post(request, QByteArray());
|
||||
connect(reply, SIGNAL(finished()), SLOT(slotCreateSessionFinished()));
|
||||
|
||||
#ifdef EXPERIMENTAL_SSL_SUPPORT
|
||||
connect(reply, SIGNAL(sslErrors(const QList<QSslError>&)), SLOT(slotSslErrors(const QList<QSslError>&)));
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicHoloLensRestClient::slotCreateSessionFinished()
|
||||
{
|
||||
QNetworkReply* reply = dynamic_cast<QNetworkReply*>(sender());
|
||||
if (!reply)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (detectAndHandleErrorReply("createSession", reply))
|
||||
{
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
|
||||
cvf::Trace::show("createSession OK");
|
||||
if (m_responseHandler)
|
||||
{
|
||||
m_responseHandler->handleSuccessfulCreateSession();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicHoloLensRestClient::deleteSession()
|
||||
{
|
||||
const QString url = m_serverUrl + "/sessions/delete/" + m_sessionName;
|
||||
cvf::Trace::show("deleteSession: DELETE on url: %s", url.toLatin1().constData());
|
||||
|
||||
QNetworkRequest request(url);
|
||||
//request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/x-www-form-urlencoded"));
|
||||
|
||||
QNetworkReply* reply = m_accessManager.deleteResource(request);
|
||||
connect(reply, SIGNAL(finished()), SLOT(slotDeleteSessionFinished()));
|
||||
|
||||
#ifdef EXPERIMENTAL_SSL_SUPPORT
|
||||
connect(reply, SIGNAL(sslErrors(const QList<QSslError>&)), SLOT(slotSslErrors(const QList<QSslError>&)));
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicHoloLensRestClient::slotDeleteSessionFinished()
|
||||
{
|
||||
QNetworkReply* reply = dynamic_cast<QNetworkReply*>(sender());
|
||||
if (!reply)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (detectAndHandleErrorReply("deleteSession", reply))
|
||||
{
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
|
||||
cvf::Trace::show("deleteSession OK");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicHoloLensRestClient::sendMetaData(int metaDataSequenceNumber, const QString& jsonMetaDataString)
|
||||
{
|
||||
const QString url = m_serverUrl + "/sessions/" + m_sessionName + "/metadata";
|
||||
cvf::Trace::show("sendMetaData (metaDataSequenceNumber=%d): POST on url: %s", metaDataSequenceNumber, url.toLatin1().constData());
|
||||
|
||||
QNetworkRequest request(url);
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));
|
||||
|
||||
const QByteArray jsonByteArr = jsonMetaDataString.toLatin1();
|
||||
|
||||
QNetworkReply* reply = m_accessManager.post(request, jsonByteArr);
|
||||
reply->setProperty("metaDataSequenceNumber", QVariant(metaDataSequenceNumber));
|
||||
|
||||
connect(reply, SIGNAL(finished()), SLOT(slotSendMetaDataFinished()));
|
||||
|
||||
#ifdef EXPERIMENTAL_SSL_SUPPORT
|
||||
connect(reply, SIGNAL(sslErrors(const QList<QSslError>&)), SLOT(slotSslErrors(const QList<QSslError>&)));
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicHoloLensRestClient::slotSendMetaDataFinished()
|
||||
{
|
||||
QNetworkReply* reply = dynamic_cast<QNetworkReply*>(sender());
|
||||
if (!reply)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (detectAndHandleErrorReply("sendMetaData", reply))
|
||||
{
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
int metaDataSequenceNumber = -1;
|
||||
{
|
||||
QVariant var = reply->property("metaDataSequenceNumber");
|
||||
if (var.type() == QVariant::Int)
|
||||
{
|
||||
metaDataSequenceNumber = var.toInt();
|
||||
}
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
|
||||
cvf::Trace::show("sendMetaData (metaDataSequenceNumber=%d) OK", metaDataSequenceNumber);
|
||||
if (m_responseHandler)
|
||||
{
|
||||
m_responseHandler->handleSuccessfulSendMetaData(metaDataSequenceNumber);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicHoloLensRestClient::sendBinaryData(const QByteArray& binaryDataArr)
|
||||
{
|
||||
const QString url = m_serverUrl + "/sessions/" + m_sessionName + "/data";
|
||||
cvf::Trace::show("sendBinaryData: POST on url: %s", url.toLatin1().constData());
|
||||
|
||||
QNetworkRequest request(url);
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));
|
||||
|
||||
QNetworkReply* reply = m_accessManager.post(request, binaryDataArr);
|
||||
connect(reply, SIGNAL(finished()), SLOT(slotSendBinaryDataFinished()));
|
||||
|
||||
#ifdef EXPERIMENTAL_SSL_SUPPORT
|
||||
connect(reply, SIGNAL(sslErrors(const QList<QSslError>&)), SLOT(slotSslErrors(const QList<QSslError>&)));
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicHoloLensRestClient::slotSendBinaryDataFinished()
|
||||
{
|
||||
QNetworkReply* reply = dynamic_cast<QNetworkReply*>(sender());
|
||||
if (!reply)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (detectAndHandleErrorReply("sendBinaryData", reply))
|
||||
{
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
|
||||
cvf::Trace::show("sendBinaryData OK");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicHoloLensRestClient::slotSslErrors(const QList<QSslError>& errors)
|
||||
{
|
||||
#ifdef EXPERIMENTAL_SSL_SUPPORT
|
||||
cvf::Trace::show("RicHoloLensRestClient::slotSslErrors()");
|
||||
for (int i = 0; i < errors.size(); i++)
|
||||
{
|
||||
cvf::Trace::show(" %s", errors[i].errorString().toLatin1().constData());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicHoloLensRestClient::detectAndHandleErrorReply(QString operationName, QNetworkReply* reply)
|
||||
{
|
||||
CVF_ASSERT(reply);
|
||||
|
||||
const QNetworkReply::NetworkError nwErrCode = reply->error();
|
||||
const int httpStatusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
if (nwErrCode == QNetworkReply::NoError && httpStatusCode == 200)
|
||||
{
|
||||
// No error detected
|
||||
return false;
|
||||
}
|
||||
|
||||
QString mainErrMsg = operationName + " FAILED";
|
||||
if (nwErrCode != QNetworkReply::NoError)
|
||||
{
|
||||
const QString nwErrCodeAsString = networkErrorCodeAsString(nwErrCode);
|
||||
const QString errText = reply->errorString();
|
||||
mainErrMsg += QString(" [nwErr='%1'(%2) httpStatus=%3]: %4").arg(nwErrCodeAsString).arg(nwErrCode).arg(httpStatusCode).arg(errText);
|
||||
}
|
||||
else
|
||||
{
|
||||
mainErrMsg += QString(" [httpStatus=%1]").arg(httpStatusCode);
|
||||
}
|
||||
|
||||
cvf::Trace::show(mainErrMsg.toLatin1().constData());
|
||||
|
||||
reply->errorString();
|
||||
|
||||
const QString url = reply->url().toString();
|
||||
cvf::Trace::show(" url: %s", url.toLatin1().constData());
|
||||
|
||||
const QByteArray serverData = reply->readAll();
|
||||
cvf::Trace::show(" serverResponse: %s", serverData.constData());
|
||||
|
||||
if (m_responseHandler)
|
||||
{
|
||||
m_responseHandler->handleError(mainErrMsg, url, serverData);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RicHoloLensRestClient::networkErrorCodeAsString(QNetworkReply::NetworkError nwErr)
|
||||
{
|
||||
switch (nwErr)
|
||||
{
|
||||
case QNetworkReply::NoError: return "NoError";
|
||||
|
||||
case QNetworkReply::ConnectionRefusedError: return "ConnectionRefusedError";
|
||||
case QNetworkReply::RemoteHostClosedError: return "RemoteHostClosedError";
|
||||
case QNetworkReply::HostNotFoundError: return "HostNotFoundError";
|
||||
case QNetworkReply::TimeoutError: return "TimeoutError";
|
||||
case QNetworkReply::OperationCanceledError: return "OperationCanceledError";
|
||||
case QNetworkReply::SslHandshakeFailedError: return "SslHandshakeFailedError";
|
||||
//case QNetworkReply::TemporaryNetworkFailureError: return "TemporaryNetworkFailureError";
|
||||
case QNetworkReply::UnknownNetworkError: return "UnknownNetworkError";
|
||||
|
||||
case QNetworkReply::ProxyConnectionRefusedError: return "ProxyConnectionRefusedError";
|
||||
case QNetworkReply::ProxyConnectionClosedError: return "ProxyConnectionClosedError";
|
||||
case QNetworkReply::ProxyNotFoundError: return "ProxyNotFoundError";
|
||||
case QNetworkReply::ProxyTimeoutError: return "ProxyTimeoutError";
|
||||
case QNetworkReply::ProxyAuthenticationRequiredError: return "ProxyAuthenticationRequiredError";
|
||||
case QNetworkReply::UnknownProxyError: return "UnknownProxyError";
|
||||
|
||||
case QNetworkReply::ContentAccessDenied: return "ContentAccessDenied";
|
||||
case QNetworkReply::ContentOperationNotPermittedError: return "ContentOperationNotPermittedError";
|
||||
case QNetworkReply::ContentNotFoundError: return "ContentNotFoundError";
|
||||
case QNetworkReply::AuthenticationRequiredError: return "AuthenticationRequiredError";
|
||||
case QNetworkReply::ContentReSendError: return "ContentReSendError";
|
||||
case QNetworkReply::UnknownContentError: return "UnknownContentError";
|
||||
|
||||
case QNetworkReply::ProtocolUnknownError: return "ProtocolUnknownError";
|
||||
case QNetworkReply::ProtocolInvalidOperationError: return "ProtocolInvalidOperationError";
|
||||
case QNetworkReply::ProtocolFailure: return "ProtocolFailure";
|
||||
};
|
||||
|
||||
return "UnknownErrorCode";
|
||||
}
|
||||
|
@ -0,0 +1,79 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 <QObject>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
class RicHoloLensRestResponseHandler
|
||||
{
|
||||
public:
|
||||
virtual void handleSuccessfulCreateSession() = 0;
|
||||
virtual void handleSuccessfulSendMetaData(int metaDataSequenceNumber) = 0;
|
||||
|
||||
virtual void handleError(const QString& errMsg, const QString& url, const QString& serverData) = 0;
|
||||
};
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
class RicHoloLensRestClient : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RicHoloLensRestClient(QString serverUrl, QString sessionName, RicHoloLensRestResponseHandler* responseHandler);
|
||||
|
||||
void clearResponseHandler();
|
||||
|
||||
void createSession();
|
||||
void deleteSession();
|
||||
void sendMetaData(int metaDataSequenceNumber, const QString& jsonMetaDataString);
|
||||
void sendBinaryData(const QByteArray& binaryDataArr);
|
||||
|
||||
private:
|
||||
bool detectAndHandleErrorReply(QString operationName, QNetworkReply* reply);
|
||||
static QString networkErrorCodeAsString(QNetworkReply::NetworkError nwErr);
|
||||
|
||||
private slots:
|
||||
void slotCreateSessionFinished();
|
||||
void slotDeleteSessionFinished();
|
||||
void slotSendMetaDataFinished();
|
||||
void slotSendBinaryDataFinished();
|
||||
|
||||
void slotSslErrors(const QList<QSslError>& errors);
|
||||
|
||||
private:
|
||||
QNetworkAccessManager m_accessManager;
|
||||
QString m_serverUrl;
|
||||
QString m_sessionName;
|
||||
RicHoloLensRestResponseHandler* m_responseHandler;
|
||||
};
|
@ -17,64 +17,99 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RicHoloLensSession.h"
|
||||
#include "RicHoloLensSessionManager.h"
|
||||
|
||||
#include "RiaLogging.h"
|
||||
#include "RiaPreferences.h"
|
||||
|
||||
#include "cafCmdFeatureManager.h"
|
||||
#include "VdeVizDataExtractor.h"
|
||||
#include "VdeFileExporter.h"
|
||||
#include "VdePacketDirectory.h"
|
||||
#include "VdeArrayDataPacket.h"
|
||||
|
||||
#include "cvfAssert.h"
|
||||
|
||||
#include <QDir>
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RicHoloLensSession::RicHoloLensSession()
|
||||
: m_isSessionValid(false)
|
||||
, m_isIsFileBackedSessionValid(false)
|
||||
: m_isSessionValid(false),
|
||||
m_lastExtractionMetaDataSequenceNumber(-1),
|
||||
m_dbgEnableFileExport(false)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RicHoloLensSession* RicHoloLensSession::instance()
|
||||
RicHoloLensSession::~RicHoloLensSession()
|
||||
{
|
||||
static RicHoloLensSession theInstance;
|
||||
|
||||
return &theInstance;
|
||||
destroySession();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicHoloLensSession::createSession(const QString& serverUrl, const QString& sessionName, const QString& sessionPinCode)
|
||||
RicHoloLensSession* RicHoloLensSession::createSession(const QString& serverUrl, const QString& sessionName)
|
||||
{
|
||||
if (isSessionValid())
|
||||
RicHoloLensSession* newSession = new RicHoloLensSession;
|
||||
|
||||
newSession->m_restClient = new RicHoloLensRestClient(serverUrl, sessionName, newSession);
|
||||
newSession->m_restClient->createSession();
|
||||
|
||||
// For now, leave this on!!!
|
||||
// We probably want to export this as a preference parameter
|
||||
newSession->m_dbgEnableFileExport = true;
|
||||
|
||||
return newSession;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RicHoloLensSession* RicHoloLensSession::createDummyFileBackedSession()
|
||||
{
|
||||
RicHoloLensSession* newSession = new RicHoloLensSession;
|
||||
|
||||
newSession->m_isSessionValid = true;
|
||||
|
||||
newSession->m_dbgEnableFileExport = true;
|
||||
|
||||
return newSession;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicHoloLensSession::destroySession()
|
||||
{
|
||||
if (m_restClient)
|
||||
{
|
||||
RiaLogging::error("Terminate existing session before creating a new session");
|
||||
|
||||
return false;
|
||||
if (m_isSessionValid)
|
||||
{
|
||||
m_restClient->deleteSession();
|
||||
}
|
||||
|
||||
m_restClient->clearResponseHandler();
|
||||
m_restClient->deleteLater();
|
||||
m_restClient = nullptr;
|
||||
}
|
||||
|
||||
RiaLogging::info("url : " + serverUrl + " name : " + sessionName + " pinCode : " + sessionPinCode);
|
||||
m_isSessionValid = false;
|
||||
|
||||
m_isSessionValid = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicHoloLensSession::createDummyFileBackedSession()
|
||||
{
|
||||
if (isSessionValid())
|
||||
{
|
||||
RiaLogging::error("Terminate existing session before creating a new session");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
m_isIsFileBackedSessionValid = true;
|
||||
|
||||
return true;
|
||||
m_lastExtractionMetaDataSequenceNumber = -1;
|
||||
m_lastExtractionAllReferencedPacketIdsArr.clear();
|
||||
m_packetDirectory.clear();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -82,50 +117,117 @@ bool RicHoloLensSession::createDummyFileBackedSession()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicHoloLensSession::isSessionValid() const
|
||||
{
|
||||
if (m_isIsFileBackedSessionValid) return true;
|
||||
|
||||
return m_isSessionValid;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicHoloLensSession::isFileBackedSessionValid() const
|
||||
{
|
||||
return m_isIsFileBackedSessionValid;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicHoloLensSession::updateSessionDataFromView(RimGridView* activeView)
|
||||
void RicHoloLensSession::updateSessionDataFromView(const RimGridView& activeView)
|
||||
{
|
||||
RiaLogging::info("HoloLens : updateSessionDataFromView");
|
||||
}
|
||||
RiaLogging::info("HoloLens: Updating visualization data");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicHoloLensSession::terminateSession()
|
||||
{
|
||||
if (!isSessionValid()) return;
|
||||
QString modelMetaJsonStr;
|
||||
std::vector<int> allReferencedPacketIds;
|
||||
m_packetDirectory.clear();
|
||||
|
||||
RiaLogging::info("Terminating HoloLens Session");
|
||||
VdeVizDataExtractor extractor(activeView);
|
||||
extractor.extractViewContents(&modelMetaJsonStr, &allReferencedPacketIds, &m_packetDirectory);
|
||||
|
||||
m_isIsFileBackedSessionValid = false;
|
||||
m_isSessionValid = false;
|
||||
m_lastExtractionMetaDataSequenceNumber++;
|
||||
m_lastExtractionAllReferencedPacketIdsArr = allReferencedPacketIds;
|
||||
|
||||
if (m_restClient)
|
||||
{
|
||||
RiaLogging::info(QString("HoloLens: Sending updated meta data to sharing server (sequenceNumber=%1)").arg(m_lastExtractionMetaDataSequenceNumber));
|
||||
m_restClient->sendMetaData(m_lastExtractionMetaDataSequenceNumber, modelMetaJsonStr);
|
||||
}
|
||||
|
||||
// Debug export to file
|
||||
if (m_dbgEnableFileExport)
|
||||
{
|
||||
const QString folderName = RiaApplication::instance()->preferences()->holoLensExportFolder();
|
||||
if (folderName.isEmpty())
|
||||
{
|
||||
RiaLogging::warning("HoloLens: Debug export to file enabled, but no export folder has been set");
|
||||
return;
|
||||
}
|
||||
|
||||
const QDir outputDir(folderName);
|
||||
const QString absOutputFolder = outputDir.absolutePath();
|
||||
|
||||
if (!outputDir.mkpath("."))
|
||||
{
|
||||
RiaLogging::error(QString("HoloLens: Could not create debug file export folder: %1").arg(absOutputFolder));
|
||||
return;
|
||||
}
|
||||
|
||||
RiaLogging::info(QString("HoloLens: Doing debug export of data to folder: %1").arg(absOutputFolder));
|
||||
VdeFileExporter fileExporter(absOutputFolder);
|
||||
if (!fileExporter.exportToFile(modelMetaJsonStr, m_packetDirectory, allReferencedPacketIds))
|
||||
{
|
||||
RiaLogging::error("HoloLens: Error exporting debug data to folder");
|
||||
}
|
||||
|
||||
RiaLogging::info("HoloLens: Done exporting debug data");
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicHoloLensSession::refreshToolbarState()
|
||||
void RicHoloLensSession::handleSuccessfulCreateSession()
|
||||
{
|
||||
QStringList commandIds;
|
||||
RiaLogging::info("HoloLens: Session successfully created");
|
||||
m_isSessionValid = true;
|
||||
|
||||
commandIds << "RicHoloLensCreateSessionFeature";
|
||||
commandIds << "RicHoloLensExportToSharingServerFeature";
|
||||
commandIds << "RicHoloLensTerminateSessionFeature";
|
||||
|
||||
caf::CmdFeatureManager::instance()->refreshEnabledState(commandIds);
|
||||
// Slight hack here - reaching out to the manager to update GUI
|
||||
// We should really just be notifying the manager that our state has changed
|
||||
RicHoloLensSessionManager::refreshToolbarState();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Handle the server response we receive after sending new meta data
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicHoloLensSession::handleSuccessfulSendMetaData(int metaDataSequenceNumber)
|
||||
{
|
||||
RiaLogging::info(QString("HoloLens: Processing server response to meta data (sequenceNumber=%1)").arg(metaDataSequenceNumber));
|
||||
|
||||
if (m_lastExtractionMetaDataSequenceNumber != metaDataSequenceNumber)
|
||||
{
|
||||
RiaLogging::warning(QString("HoloLens: Ignoring server response, the sequenceNumber(%1) has been superseded").arg(metaDataSequenceNumber));
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_lastExtractionAllReferencedPacketIdsArr.size() > 0)
|
||||
{
|
||||
QByteArray combinedPacketArr;
|
||||
if (!m_packetDirectory.getPacketsAsCombinedBuffer(m_lastExtractionAllReferencedPacketIdsArr, &combinedPacketArr))
|
||||
{
|
||||
RiaLogging::warning("HoloLens: Error gathering the requested packets, no data will be sent");
|
||||
return;
|
||||
}
|
||||
|
||||
RiaLogging::info(QString("HoloLens: Sending new data to sharing server (%1 packets)").arg(m_lastExtractionAllReferencedPacketIdsArr.size()));
|
||||
|
||||
m_restClient->sendBinaryData(combinedPacketArr);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicHoloLensSession::handleError(const QString& errMsg, const QString& url, const QString& serverData)
|
||||
{
|
||||
QString fullMsg = "HoloLens communication error: " + errMsg;
|
||||
|
||||
if (!serverData.isEmpty())
|
||||
{
|
||||
fullMsg += "\n serverMsg: " + serverData;
|
||||
}
|
||||
|
||||
fullMsg += "\n url: " + url;
|
||||
|
||||
RiaLogging::error(fullMsg);
|
||||
}
|
||||
|
||||
|
@ -18,32 +18,54 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RicHoloLensRestClient.h"
|
||||
|
||||
#include "VdePacketDirectory.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QPointer>
|
||||
|
||||
#include <vector>
|
||||
|
||||
class RimGridView;
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
class RicHoloLensSession
|
||||
class RicHoloLensSession : public QObject, private RicHoloLensRestResponseHandler
|
||||
{
|
||||
public:
|
||||
RicHoloLensSession();
|
||||
~RicHoloLensSession();
|
||||
|
||||
static RicHoloLensSession* instance();
|
||||
static RicHoloLensSession* createSession(const QString& serverUrl, const QString& sessionName);
|
||||
static RicHoloLensSession* createDummyFileBackedSession();
|
||||
void destroySession();
|
||||
|
||||
bool createSession(const QString& serverUrl, const QString& sessionName, const QString& sessionPinCode);
|
||||
bool createDummyFileBackedSession();
|
||||
bool isSessionValid() const;
|
||||
|
||||
bool isSessionValid() const;
|
||||
bool isFileBackedSessionValid() const;
|
||||
|
||||
void updateSessionDataFromView(RimGridView* activeView);
|
||||
void terminateSession();
|
||||
|
||||
static void refreshToolbarState();
|
||||
void updateSessionDataFromView(const RimGridView& activeView);
|
||||
|
||||
private:
|
||||
bool m_isSessionValid;
|
||||
bool m_isIsFileBackedSessionValid;
|
||||
RicHoloLensSession();
|
||||
|
||||
virtual void handleSuccessfulCreateSession() override;
|
||||
virtual void handleSuccessfulSendMetaData(int metaDataSequenceNumber) override;
|
||||
virtual void handleError(const QString& errMsg, const QString& url, const QString& serverData) override;
|
||||
|
||||
private:
|
||||
bool m_isSessionValid;
|
||||
QPointer<RicHoloLensRestClient> m_restClient;
|
||||
|
||||
int m_lastExtractionMetaDataSequenceNumber;
|
||||
std::vector<int> m_lastExtractionAllReferencedPacketIdsArr;
|
||||
VdePacketDirectory m_packetDirectory;
|
||||
|
||||
bool m_dbgEnableFileExport;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,127 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "RicHoloLensSessionManager.h"
|
||||
#include "RicHoloLensSession.h"
|
||||
|
||||
#include "RiaLogging.h"
|
||||
|
||||
#include "cafCmdFeatureManager.h"
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RicHoloLensSessionManager::RicHoloLensSessionManager()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RicHoloLensSessionManager* RicHoloLensSessionManager::instance()
|
||||
{
|
||||
static RicHoloLensSessionManager theInstance;
|
||||
return &theInstance;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicHoloLensSessionManager::createSession(const QString& serverUrl, const QString& sessionName, const QString& /*sessionPinCode*/)
|
||||
{
|
||||
if (m_session)
|
||||
{
|
||||
RiaLogging::error("Terminate existing session before creating a new session");
|
||||
return false;
|
||||
}
|
||||
|
||||
RiaLogging::info(QString("Creating HoloLens session: '%1', server url: %2").arg(sessionName).arg(serverUrl));
|
||||
m_session = RicHoloLensSession::createSession(serverUrl, sessionName);
|
||||
|
||||
refreshToolbarState();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicHoloLensSessionManager::createDummyFileBackedSession()
|
||||
{
|
||||
if (m_session)
|
||||
{
|
||||
RiaLogging::error("Terminate existing session before creating a new session");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_session = RicHoloLensSession::createDummyFileBackedSession();
|
||||
RiaLogging::info("Created dummy file-backed HoloLens session");
|
||||
|
||||
refreshToolbarState();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicHoloLensSessionManager::terminateSession()
|
||||
{
|
||||
if (!m_session)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RiaLogging::info("Terminating HoloLens session");
|
||||
m_session->destroySession();
|
||||
m_session->deleteLater();
|
||||
m_session = nullptr;
|
||||
|
||||
refreshToolbarState();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RicHoloLensSession* RicHoloLensSessionManager::session()
|
||||
{
|
||||
return m_session;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicHoloLensSessionManager::refreshToolbarState()
|
||||
{
|
||||
QStringList commandIds;
|
||||
|
||||
commandIds << "RicHoloLensCreateSessionFeature";
|
||||
commandIds << "RicHoloLensExportToSharingServerFeature";
|
||||
commandIds << "RicHoloLensTerminateSessionFeature";
|
||||
|
||||
caf::CmdFeatureManager::instance()->refreshEnabledState(commandIds);
|
||||
}
|
||||
|
@ -0,0 +1,53 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "RicHoloLensRestClient.h"
|
||||
|
||||
#include <QPointer>
|
||||
|
||||
class RicHoloLensSession;
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
class RicHoloLensSessionManager
|
||||
{
|
||||
public:
|
||||
static RicHoloLensSessionManager* instance();
|
||||
|
||||
bool createSession(const QString& serverUrl, const QString& sessionName, const QString& sessionPinCode);
|
||||
bool createDummyFileBackedSession();
|
||||
void terminateSession();
|
||||
|
||||
RicHoloLensSession* session();
|
||||
|
||||
static void refreshToolbarState();
|
||||
|
||||
private:
|
||||
RicHoloLensSessionManager();
|
||||
|
||||
private:
|
||||
QPointer<RicHoloLensSession> m_session;
|
||||
};
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
#include "RicHoloLensTerminateSessionFeature.h"
|
||||
|
||||
#include "RicHoloLensSession.h"
|
||||
#include "RicHoloLensSessionManager.h"
|
||||
|
||||
#include "RiaLogging.h"
|
||||
#include "RiaQIconTools.h"
|
||||
@ -32,7 +32,7 @@ CAF_CMD_SOURCE_INIT(RicHoloLensTerminateSessionFeature, "RicHoloLensTerminateSes
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicHoloLensTerminateSessionFeature::isCommandEnabled()
|
||||
{
|
||||
return RicHoloLensSession::instance()->isSessionValid();
|
||||
return RicHoloLensSessionManager::instance()->session() ? true : false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -40,9 +40,9 @@ bool RicHoloLensTerminateSessionFeature::isCommandEnabled()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicHoloLensTerminateSessionFeature::onActionTriggered(bool isChecked)
|
||||
{
|
||||
RicHoloLensSession::instance()->terminateSession();
|
||||
RicHoloLensSessionManager::instance()->terminateSession();
|
||||
|
||||
RicHoloLensSession::refreshToolbarState();
|
||||
RicHoloLensSessionManager::refreshToolbarState();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -18,24 +18,10 @@
|
||||
|
||||
#include "VdeFileExporter.h"
|
||||
#include "VdeArrayDataPacket.h"
|
||||
#include "VdePacketDirectory.h"
|
||||
|
||||
#include "RicHoloLensExportImpl.h"
|
||||
|
||||
#include "RifJsonEncodeDecode.h"
|
||||
|
||||
#include "RiaLogging.h"
|
||||
|
||||
#include "cvfPart.h"
|
||||
#include "cvfScene.h"
|
||||
#include "cvfDrawableGeo.h"
|
||||
#include "cvfPrimitiveSet.h"
|
||||
#include "cvfTransform.h"
|
||||
#include "cvfRenderStateTextureBindings.h"
|
||||
#include "cvfTexture.h"
|
||||
#include "cvfEffect.h"
|
||||
#include "cvfTrace.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
|
||||
@ -58,90 +44,35 @@ VdeFileExporter::VdeFileExporter(QString absOutputFolder)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool VdeFileExporter::exportViewContents(const RimGridView& view)
|
||||
bool VdeFileExporter::exportToFile(const QString& modelMetaJsonStr, const VdePacketDirectory& packetDirectory, const std::vector<int>& packetIdsToExport)
|
||||
{
|
||||
std::vector<VdeExportPart> exportPartsArr = RicHoloLensExportImpl::partsForExport(view);
|
||||
std::vector<VdeMesh> meshArr;
|
||||
for (const auto& exportPart : exportPartsArr)
|
||||
{
|
||||
VdeMesh mesh;
|
||||
if (extractMeshFromExportPart(exportPart, &mesh))
|
||||
{
|
||||
meshArr.push_back(mesh);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<VdeMeshArrayIds> meshArrayIdsArr;
|
||||
|
||||
const size_t meshCount = meshArr.size();
|
||||
cvf::Trace::show("Exporting %d meshes", meshCount);
|
||||
size_t totNumPrimitives = 0;
|
||||
int nextArrayId = 0;
|
||||
for (size_t i = 0; i < meshCount; i++)
|
||||
{
|
||||
const VdeMesh& mesh = meshArr[i];
|
||||
|
||||
const size_t primCount = mesh.connArr.size()/mesh.verticesPerPrimitive;
|
||||
totNumPrimitives += primCount;
|
||||
cvf::Trace::show(" %2d: primCount=%d meshSourceObjName='%s'", i, primCount, mesh.meshSourceObjName.toLatin1().constData());
|
||||
|
||||
VdeMeshArrayIds meshArrayIds;
|
||||
|
||||
{
|
||||
cvf::Trace::show(" exporting vertices");
|
||||
meshArrayIds.vertexArrId = nextArrayId++;
|
||||
const float* floatArr = reinterpret_cast<const float*>(mesh.vertexArr->ptr());
|
||||
VdeArrayDataPacket dataPacket = VdeArrayDataPacket::fromFloat32Arr(meshArrayIds.vertexArrId, floatArr, 3*mesh.vertexArr->size());
|
||||
writeDataPacketToFile(dataPacket.arrayId(), dataPacket);
|
||||
|
||||
// Debug testing of decoding
|
||||
//debugComparePackets(dataPacket, VdeArrayDataPacket::fromRawPacketBuffer(dataPacket.fullPacketRawPtr(), dataPacket.fullPacketSize(), nullptr));
|
||||
}
|
||||
{
|
||||
cvf::Trace::show(" exporting connectivities");
|
||||
meshArrayIds.connArrId = nextArrayId++;
|
||||
const unsigned int* uintArr = mesh.connArr.data();
|
||||
VdeArrayDataPacket dataPacket = VdeArrayDataPacket::fromUint32Arr(meshArrayIds.connArrId, uintArr, mesh.connArr.size());
|
||||
writeDataPacketToFile(dataPacket.arrayId(), dataPacket);
|
||||
|
||||
// Debug testing of decoding
|
||||
//debugComparePackets(dataPacket, VdeArrayDataPacket::fromRawPacketBuffer(dataPacket.fullPacketRawPtr(), dataPacket.fullPacketSize(), nullptr));
|
||||
}
|
||||
|
||||
if (mesh.texCoordArr.notNull() && mesh.texImage.notNull())
|
||||
{
|
||||
{
|
||||
cvf::Trace::show(" exporting texture coords");
|
||||
meshArrayIds.texCoordsArrId = nextArrayId++;
|
||||
const float* floatArr = reinterpret_cast<const float*>(mesh.texCoordArr->ptr());
|
||||
VdeArrayDataPacket dataPacket = VdeArrayDataPacket::fromFloat32Arr(meshArrayIds.texCoordsArrId, floatArr, 2*mesh.texCoordArr->size());
|
||||
writeDataPacketToFile(dataPacket.arrayId(), dataPacket);
|
||||
|
||||
// Debug testing of decoding
|
||||
//debugComparePackets(dataPacket, VdeArrayDataPacket::fromRawPacketBuffer(dataPacket.fullPacketRawPtr(), dataPacket.fullPacketSize(), nullptr));
|
||||
}
|
||||
{
|
||||
cvf::Trace::show(" exporting texture image");
|
||||
meshArrayIds.texImageArrId = nextArrayId++;
|
||||
cvf::ref<cvf::UByteArray> byteArr = mesh.texImage->toRgb();
|
||||
VdeArrayDataPacket dataPacket = VdeArrayDataPacket::fromUint8ImageRGBArr(meshArrayIds.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));
|
||||
}
|
||||
}
|
||||
|
||||
meshArrayIdsArr.push_back(meshArrayIds);
|
||||
}
|
||||
cvf::Trace::show("Exporting to folder: %s", m_absOutputFolder.toLatin1().constData());
|
||||
|
||||
QString jsonFileName = m_absOutputFolder + "/modelMeta.json";
|
||||
if (!writeModelMetaJsonFile(meshArr, meshArrayIdsArr, jsonFileName))
|
||||
if (!writeModelMetaJsonFile(modelMetaJsonStr, jsonFileName))
|
||||
{
|
||||
cvf::Trace::show("Error writing: %s", jsonFileName.toLatin1().constData());
|
||||
return false;
|
||||
}
|
||||
|
||||
cvf::Trace::show("Total number of primitives exported: %d", totNumPrimitives);
|
||||
for (const int packetArrayId : packetIdsToExport)
|
||||
{
|
||||
const VdeArrayDataPacket* dataPacket = packetDirectory.lookupPacket(packetArrayId);
|
||||
if (!dataPacket)
|
||||
{
|
||||
cvf::Trace::show("Error during export, no data for arrayId %d", packetArrayId);
|
||||
return false;
|
||||
}
|
||||
|
||||
CVF_ASSERT(packetArrayId == dataPacket->arrayId());
|
||||
if (!writeDataPacketToFile(dataPacket->arrayId(), *dataPacket))
|
||||
{
|
||||
cvf::Trace::show("Error writing packet data to file, arrayId %d", packetArrayId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
cvf::Trace::show("Data exported to folder: %s", m_absOutputFolder.toLatin1().constData());
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -149,107 +80,23 @@ bool VdeFileExporter::exportViewContents(const RimGridView& view)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool VdeFileExporter::extractMeshFromExportPart(const VdeExportPart& exportPart, VdeMesh* mesh)
|
||||
bool VdeFileExporter::exportViewContents(const RimGridView& view)
|
||||
{
|
||||
const cvf::Part* cvfPart = exportPart.part();
|
||||
const cvf::DrawableGeo* geo = dynamic_cast<const cvf::DrawableGeo*>(cvfPart ? cvfPart->drawable() : nullptr);
|
||||
if (!geo)
|
||||
QString modelMetaJsonStr;
|
||||
std::vector<int> allReferencedArrayIds;
|
||||
VdePacketDirectory packetDirectory;
|
||||
|
||||
VdeVizDataExtractor extractor(view);
|
||||
extractor.extractViewContents(&modelMetaJsonStr, &allReferencedArrayIds, &packetDirectory);
|
||||
|
||||
if (!exportToFile(modelMetaJsonStr, packetDirectory, allReferencedArrayIds))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (geo->primitiveSetCount() != 1)
|
||||
{
|
||||
RiaLogging::debug("Only geometries with exactly one primitive set is supported");
|
||||
return false;
|
||||
}
|
||||
|
||||
const cvf::Vec3fArray* vertexArr = geo->vertexArray();
|
||||
const cvf::PrimitiveSet* primSet = geo->primitiveSet(0);
|
||||
if (!vertexArr || !primSet || primSet->faceCount() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Support 2 or 3 vertices per primitive
|
||||
const cvf::PrimitiveType primType = primSet->primitiveType();
|
||||
if (primType != cvf::PT_TRIANGLES && primType != cvf::PT_LINES)
|
||||
{
|
||||
RiaLogging::debug(QString("Currently only triangle and line primitive sets are supported (saw primitive type: %1)").arg(primType));
|
||||
return false;
|
||||
}
|
||||
|
||||
const int vertsPerPrimitive = (primType == cvf::PT_TRIANGLES) ? 3 : 2;
|
||||
|
||||
mesh->verticesPerPrimitive = vertsPerPrimitive;
|
||||
|
||||
// Possibly transform the vertices
|
||||
if (cvfPart->transform())
|
||||
{
|
||||
const size_t vertexCount = vertexArr->size();
|
||||
cvf::ref<cvf::Vec3fArray> transVertexArr = new cvf::Vec3fArray(vertexArr->size());
|
||||
|
||||
cvf::Mat4f m = cvf::Mat4f(cvfPart->transform()->worldTransform());
|
||||
for (size_t i = 0; i < vertexCount; i++)
|
||||
{
|
||||
transVertexArr->set(i, vertexArr->get(i).getTransformedPoint(m));
|
||||
}
|
||||
|
||||
mesh->vertexArr = transVertexArr.p();
|
||||
}
|
||||
else
|
||||
{
|
||||
mesh->vertexArr = vertexArr;
|
||||
}
|
||||
|
||||
// Fetch connectivities
|
||||
// Using getFaceIndices() allows us to access strips and fans in the same way as triangles
|
||||
// Note that HoloLens visualization wants triangles in clockwise order so we try and fix the winding
|
||||
// This point might be moot if the HoloLens visualization always has to use two-sideded lighting to get good results
|
||||
cvf::UIntArray faceConn;
|
||||
const size_t faceCount = primSet->faceCount();
|
||||
for (size_t iface = 0; iface < faceCount; iface++)
|
||||
{
|
||||
primSet->getFaceIndices(iface, &faceConn);
|
||||
|
||||
if (vertsPerPrimitive == 3 && exportPart.winding() == VdeExportPart::COUNTERCLOCKWISE)
|
||||
{
|
||||
// Reverse the winding
|
||||
const size_t numConn = faceConn.size();
|
||||
for (size_t i = 0; i < numConn; i++)
|
||||
{
|
||||
mesh->connArr.push_back(faceConn[numConn - i - 1]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mesh->connArr.insert(mesh->connArr.end(), faceConn.begin(), faceConn.end());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (exportPart.textureImage() && geo->textureCoordArray())
|
||||
{
|
||||
mesh->texCoordArr = geo->textureCoordArray();
|
||||
mesh->texImage = exportPart.textureImage();
|
||||
}
|
||||
|
||||
|
||||
QString srcObjType = "unknown";
|
||||
if (exportPart.sourceObjectType() == VdeExportPart::OBJ_TYPE_GRID) srcObjType = "grid";
|
||||
else if (exportPart.sourceObjectType() == VdeExportPart::OBJ_TYPE_PIPE) srcObjType = "pipe";
|
||||
mesh->meshSourceObjTypeStr = srcObjType;
|
||||
|
||||
mesh->meshSourceObjName = exportPart.sourceObjectName();
|
||||
|
||||
mesh->color = exportPart.color();
|
||||
mesh->opacity = exportPart.opacity();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -274,50 +121,9 @@ bool VdeFileExporter::writeDataPacketToFile(int arrayId, const VdeArrayDataPacke
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool VdeFileExporter::writeModelMetaJsonFile(const std::vector<VdeMesh>& meshArr, const std::vector<VdeMeshArrayIds>& meshContentIdsArr, QString fileName)
|
||||
bool VdeFileExporter::writeModelMetaJsonFile(const QString& modelMetaJsonStr, QString fileName)
|
||||
{
|
||||
QVariantList jsonMeshMetaList;
|
||||
|
||||
for (size_t i = 0; i < meshArr.size(); i++)
|
||||
{
|
||||
const VdeMesh& mesh = meshArr[i];
|
||||
const VdeMeshArrayIds& 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"] = mesh.opacity;
|
||||
|
||||
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();
|
||||
const QByteArray jsonByteArr = modelMetaJsonStr.toLatin1();
|
||||
|
||||
QFile file(fileName);
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
|
||||
@ -325,7 +131,7 @@ bool VdeFileExporter::writeModelMetaJsonFile(const std::vector<VdeMesh>& meshArr
|
||||
return false;
|
||||
}
|
||||
|
||||
if (file.write(jsonStr) == -1)
|
||||
if (file.write(jsonByteArr) == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -333,20 +139,3 @@ bool VdeFileExporter::writeModelMetaJsonFile(const std::vector<VdeMesh>& meshArr
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,72 +18,15 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfCollection.h"
|
||||
#include "cvfArray.h"
|
||||
#include "cvfTextureImage.h"
|
||||
#include "VdeVizDataExtractor.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
class VdeArrayDataPacket;
|
||||
class VdeExportPart;
|
||||
class VdePacketDirectory;
|
||||
|
||||
class RimGridView;
|
||||
|
||||
namespace cvf
|
||||
{
|
||||
class Part;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
struct VdeMesh
|
||||
{
|
||||
QString meshSourceObjTypeStr;
|
||||
QString meshSourceObjName;
|
||||
|
||||
cvf::Color3f color;
|
||||
float opacity;
|
||||
|
||||
int verticesPerPrimitive;
|
||||
cvf::cref<cvf::Vec3fArray> vertexArr;
|
||||
cvf::cref<cvf::Vec2fArray> texCoordArr;
|
||||
std::vector<cvf::uint> connArr;
|
||||
cvf::cref<cvf::TextureImage> texImage;
|
||||
|
||||
VdeMesh()
|
||||
: color(1,1,1),
|
||||
opacity(1),
|
||||
verticesPerPrimitive(-1)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
struct VdeMeshArrayIds
|
||||
{
|
||||
int vertexArrId;
|
||||
int connArrId;
|
||||
int texImageArrId;
|
||||
int texCoordsArrId;
|
||||
|
||||
VdeMeshArrayIds()
|
||||
: vertexArrId(-1),
|
||||
connArrId(-1),
|
||||
texImageArrId(-1),
|
||||
texCoordsArrId(-1)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
@ -96,13 +39,11 @@ class VdeFileExporter
|
||||
public:
|
||||
VdeFileExporter(QString absOutputFolder);
|
||||
|
||||
bool exportToFile(const QString& modelMetaJsonStr, const VdePacketDirectory& packetDirectory, const std::vector<int>& packetIdsToExport);
|
||||
bool exportViewContents(const RimGridView& view);
|
||||
|
||||
private:
|
||||
static bool extractMeshFromExportPart(const VdeExportPart& exportPart, VdeMesh* mesh);
|
||||
static bool writeModelMetaJsonFile(const std::vector<VdeMesh>& meshArr, const std::vector<VdeMeshArrayIds>& meshContentIdsArr, QString fileName);
|
||||
static void debugComparePackets(const VdeArrayDataPacket& packetA, const VdeArrayDataPacket& packetB);
|
||||
|
||||
static bool writeModelMetaJsonFile(const QString& modelMetaJsonStr, QString fileName);
|
||||
bool writeDataPacketToFile(int arrayId, const VdeArrayDataPacket& packet) const;
|
||||
|
||||
private:
|
||||
|
@ -0,0 +1,87 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "VdePacketDirectory.h"
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
VdePacketDirectory::VdePacketDirectory()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void VdePacketDirectory::addPacket(const VdeArrayDataPacket& packet)
|
||||
{
|
||||
const int id = packet.arrayId();
|
||||
m_idToPacketMap[id] = std::unique_ptr<VdeArrayDataPacket>(new VdeArrayDataPacket(packet));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const VdeArrayDataPacket* VdePacketDirectory::lookupPacket(int arrayId) const
|
||||
{
|
||||
IdToPacketMap_T::const_iterator it = m_idToPacketMap.find(arrayId);
|
||||
if (it == m_idToPacketMap.end())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return it->second.get();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void VdePacketDirectory::clear()
|
||||
{
|
||||
m_idToPacketMap.clear();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool VdePacketDirectory::getPacketsAsCombinedBuffer(const std::vector<int>& packetIdsToGet, QByteArray* combinedPacketArr) const
|
||||
{
|
||||
for (const int arrayId : packetIdsToGet)
|
||||
{
|
||||
IdToPacketMap_T::const_iterator it = m_idToPacketMap.find(arrayId);
|
||||
if (it == m_idToPacketMap.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const VdeArrayDataPacket& packet = *it->second;
|
||||
*combinedPacketArr += QByteArray::fromRawData(packet.fullPacketRawPtr(), static_cast<int>(packet.fullPacketSize()));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,50 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "VdeArrayDataPacket.h"
|
||||
|
||||
#include <QByteArray>
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
class VdePacketDirectory
|
||||
{
|
||||
public:
|
||||
VdePacketDirectory();
|
||||
|
||||
void addPacket(const VdeArrayDataPacket& packet);
|
||||
const VdeArrayDataPacket* lookupPacket(int arrayId) const;
|
||||
void clear();
|
||||
|
||||
bool getPacketsAsCombinedBuffer(const std::vector<int>& packetIdsToGet, QByteArray* combinedPacketArr) const;
|
||||
|
||||
private:
|
||||
typedef std::map<int, std::unique_ptr<VdeArrayDataPacket>> IdToPacketMap_T;
|
||||
|
||||
IdToPacketMap_T m_idToPacketMap;
|
||||
};
|
||||
|
@ -0,0 +1,331 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "VdeVizDataExtractor.h"
|
||||
#include "VdeArrayDataPacket.h"
|
||||
#include "VdePacketDirectory.h"
|
||||
|
||||
#include "RicHoloLensExportImpl.h"
|
||||
|
||||
#include "RifJsonEncodeDecode.h"
|
||||
|
||||
#include "RiaLogging.h"
|
||||
|
||||
#include "cvfDrawableGeo.h"
|
||||
#include "cvfPrimitiveSet.h"
|
||||
#include "cvfTransform.h"
|
||||
#include "cvfTrace.h"
|
||||
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
VdeVizDataExtractor::VdeVizDataExtractor(const RimGridView& view)
|
||||
: m_view(view)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void VdeVizDataExtractor::extractViewContents(QString* modelMetaJsonStr, std::vector<int>* allReferencedArrayIds, VdePacketDirectory* packetDirectory)
|
||||
{
|
||||
// First extract the parts (cvfPart + info) to be exported from from the ResInsight view
|
||||
const std::vector<VdeExportPart> exportPartsArr = RicHoloLensExportImpl::partsForExport(m_view);
|
||||
|
||||
// Convert this to an array of export ready meshes
|
||||
const std::vector<VdeMesh> meshArr = buildMeshArray(exportPartsArr);
|
||||
const size_t meshCount = meshArr.size();
|
||||
cvf::Trace::show("Extracting %d meshes", meshCount);
|
||||
|
||||
std::vector<VdeMeshArrayIds> meshArrayIdsArr;
|
||||
|
||||
size_t totNumPrimitives = 0;
|
||||
int nextArrayId = 0;
|
||||
for (size_t i = 0; i < meshCount; i++)
|
||||
{
|
||||
const VdeMesh& mesh = meshArr[i];
|
||||
|
||||
const size_t primCount = mesh.connArr.size()/mesh.verticesPerPrimitive;
|
||||
totNumPrimitives += primCount;
|
||||
cvf::Trace::show(" %2d: primCount=%d meshSourceObjName='%s'", i, primCount, mesh.meshSourceObjName.toLatin1().constData());
|
||||
|
||||
VdeMeshArrayIds meshArrayIds;
|
||||
|
||||
{
|
||||
cvf::Trace::show(" exporting vertices");
|
||||
meshArrayIds.vertexArrId = nextArrayId++;
|
||||
const float* floatArr = reinterpret_cast<const float*>(mesh.vertexArr->ptr());
|
||||
VdeArrayDataPacket dataPacket = VdeArrayDataPacket::fromFloat32Arr(meshArrayIds.vertexArrId, floatArr, 3*mesh.vertexArr->size());
|
||||
packetDirectory->addPacket(dataPacket);
|
||||
|
||||
// Debug testing of decoding
|
||||
debugComparePackets(dataPacket, VdeArrayDataPacket::fromRawPacketBuffer(dataPacket.fullPacketRawPtr(), dataPacket.fullPacketSize(), nullptr));
|
||||
}
|
||||
{
|
||||
cvf::Trace::show(" exporting connectivities");
|
||||
meshArrayIds.connArrId = nextArrayId++;
|
||||
const unsigned int* uintArr = mesh.connArr.data();
|
||||
VdeArrayDataPacket dataPacket = VdeArrayDataPacket::fromUint32Arr(meshArrayIds.connArrId, uintArr, mesh.connArr.size());
|
||||
packetDirectory->addPacket(dataPacket);
|
||||
|
||||
// Debug testing of decoding
|
||||
debugComparePackets(dataPacket, VdeArrayDataPacket::fromRawPacketBuffer(dataPacket.fullPacketRawPtr(), dataPacket.fullPacketSize(), nullptr));
|
||||
}
|
||||
|
||||
if (mesh.texCoordArr.notNull() && mesh.texImage.notNull())
|
||||
{
|
||||
{
|
||||
cvf::Trace::show(" exporting texture coords");
|
||||
meshArrayIds.texCoordsArrId = nextArrayId++;
|
||||
const float* floatArr = reinterpret_cast<const float*>(mesh.texCoordArr->ptr());
|
||||
VdeArrayDataPacket dataPacket = VdeArrayDataPacket::fromFloat32Arr(meshArrayIds.texCoordsArrId, floatArr, 2*mesh.texCoordArr->size());
|
||||
packetDirectory->addPacket(dataPacket);
|
||||
|
||||
// Debug testing of decoding
|
||||
debugComparePackets(dataPacket, VdeArrayDataPacket::fromRawPacketBuffer(dataPacket.fullPacketRawPtr(), dataPacket.fullPacketSize(), nullptr));
|
||||
}
|
||||
{
|
||||
cvf::Trace::show(" exporting texture image");
|
||||
meshArrayIds.texImageArrId = nextArrayId++;
|
||||
cvf::ref<cvf::UByteArray> byteArr = mesh.texImage->toRgb();
|
||||
VdeArrayDataPacket dataPacket = VdeArrayDataPacket::fromUint8ImageRGBArr(meshArrayIds.texImageArrId, mesh.texImage->width(), mesh.texImage->height(), byteArr->ptr(), byteArr->size());
|
||||
packetDirectory->addPacket(dataPacket);
|
||||
|
||||
// Debug testing of decoding
|
||||
debugComparePackets(dataPacket, VdeArrayDataPacket::fromRawPacketBuffer(dataPacket.fullPacketRawPtr(), dataPacket.fullPacketSize(), nullptr));
|
||||
}
|
||||
}
|
||||
|
||||
meshArrayIdsArr.push_back(meshArrayIds);
|
||||
}
|
||||
|
||||
cvf::Trace::show("Total number of primitives extracted: %d", totNumPrimitives);
|
||||
|
||||
|
||||
*modelMetaJsonStr = createModelMetaJsonString(meshArr, meshArrayIdsArr);
|
||||
|
||||
// Find all unique packet array IDs referenced
|
||||
std::set<int> referencedIdsSet;
|
||||
for (const VdeMeshArrayIds& meshArrayIds : meshArrayIdsArr)
|
||||
{
|
||||
if (meshArrayIds.vertexArrId != -1) referencedIdsSet.insert(meshArrayIds.vertexArrId);
|
||||
if (meshArrayIds.connArrId != -1) referencedIdsSet.insert(meshArrayIds.connArrId);
|
||||
if (meshArrayIds.texImageArrId != -1) referencedIdsSet.insert(meshArrayIds.texImageArrId);
|
||||
if (meshArrayIds.texCoordsArrId != -1) referencedIdsSet.insert(meshArrayIds.texCoordsArrId);
|
||||
}
|
||||
|
||||
allReferencedArrayIds->assign(referencedIdsSet.begin(), referencedIdsSet.end());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<VdeMesh> VdeVizDataExtractor::buildMeshArray(const std::vector<VdeExportPart>& exportPartsArr)
|
||||
{
|
||||
std::vector<VdeMesh> meshArr;
|
||||
for (const VdeExportPart& exportPart : exportPartsArr)
|
||||
{
|
||||
VdeMesh mesh;
|
||||
if (extractMeshFromExportPart(exportPart, &mesh))
|
||||
{
|
||||
meshArr.push_back(mesh);
|
||||
}
|
||||
}
|
||||
|
||||
return meshArr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool VdeVizDataExtractor::extractMeshFromExportPart(const VdeExportPart& exportPart, VdeMesh* mesh)
|
||||
{
|
||||
const cvf::Part* cvfPart = exportPart.part();
|
||||
const cvf::DrawableGeo* geo = dynamic_cast<const cvf::DrawableGeo*>(cvfPart ? cvfPart->drawable() : nullptr);
|
||||
if (!geo)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (geo->primitiveSetCount() != 1)
|
||||
{
|
||||
RiaLogging::debug("Only geometries with exactly one primitive set is supported");
|
||||
return false;
|
||||
}
|
||||
|
||||
const cvf::Vec3fArray* vertexArr = geo->vertexArray();
|
||||
const cvf::PrimitiveSet* primSet = geo->primitiveSet(0);
|
||||
if (!vertexArr || !primSet || primSet->faceCount() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Support 2 or 3 vertices per primitive
|
||||
const cvf::PrimitiveType primType = primSet->primitiveType();
|
||||
if (primType != cvf::PT_TRIANGLES && primType != cvf::PT_LINES)
|
||||
{
|
||||
RiaLogging::debug(QString("Currently only triangle and line primitive sets are supported (saw primitive type: %1)").arg(primType));
|
||||
return false;
|
||||
}
|
||||
|
||||
const int vertsPerPrimitive = (primType == cvf::PT_TRIANGLES) ? 3 : 2;
|
||||
|
||||
mesh->verticesPerPrimitive = vertsPerPrimitive;
|
||||
|
||||
// Possibly transform the vertices
|
||||
if (cvfPart->transform())
|
||||
{
|
||||
const size_t vertexCount = vertexArr->size();
|
||||
cvf::ref<cvf::Vec3fArray> transVertexArr = new cvf::Vec3fArray(vertexArr->size());
|
||||
|
||||
cvf::Mat4f m = cvf::Mat4f(cvfPart->transform()->worldTransform());
|
||||
for (size_t i = 0; i < vertexCount; i++)
|
||||
{
|
||||
transVertexArr->set(i, vertexArr->get(i).getTransformedPoint(m));
|
||||
}
|
||||
|
||||
mesh->vertexArr = transVertexArr.p();
|
||||
}
|
||||
else
|
||||
{
|
||||
mesh->vertexArr = vertexArr;
|
||||
}
|
||||
|
||||
// Fetch connectivities
|
||||
// Using getFaceIndices() allows us to access strips and fans in the same way as triangles
|
||||
// Note that HoloLens visualization wants triangles in clockwise order so we try and fix the winding
|
||||
// This point might be moot if the HoloLens visualization always has to use two-sideded lighting to get good results
|
||||
cvf::UIntArray faceConn;
|
||||
const size_t faceCount = primSet->faceCount();
|
||||
for (size_t iface = 0; iface < faceCount; iface++)
|
||||
{
|
||||
primSet->getFaceIndices(iface, &faceConn);
|
||||
|
||||
if (vertsPerPrimitive == 3 && exportPart.winding() == VdeExportPart::COUNTERCLOCKWISE)
|
||||
{
|
||||
// Reverse the winding
|
||||
const size_t numConn = faceConn.size();
|
||||
for (size_t i = 0; i < numConn; i++)
|
||||
{
|
||||
mesh->connArr.push_back(faceConn[numConn - i - 1]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mesh->connArr.insert(mesh->connArr.end(), faceConn.begin(), faceConn.end());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (exportPart.textureImage() && geo->textureCoordArray())
|
||||
{
|
||||
mesh->texCoordArr = geo->textureCoordArray();
|
||||
mesh->texImage = exportPart.textureImage();
|
||||
}
|
||||
|
||||
|
||||
QString srcObjType = "unknown";
|
||||
if (exportPart.sourceObjectType() == VdeExportPart::OBJ_TYPE_GRID) srcObjType = "grid";
|
||||
else if (exportPart.sourceObjectType() == VdeExportPart::OBJ_TYPE_PIPE) srcObjType = "pipe";
|
||||
mesh->meshSourceObjTypeStr = srcObjType;
|
||||
|
||||
mesh->meshSourceObjName = exportPart.sourceObjectName();
|
||||
|
||||
mesh->color = exportPart.color();
|
||||
mesh->opacity = exportPart.opacity();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString VdeVizDataExtractor::createModelMetaJsonString(const std::vector<VdeMesh>& meshArr, const std::vector<VdeMeshArrayIds>& meshContentIdsArr)
|
||||
{
|
||||
QVariantList jsonMeshMetaList;
|
||||
|
||||
for (size_t i = 0; i < meshArr.size(); i++)
|
||||
{
|
||||
const VdeMesh& mesh = meshArr[i];
|
||||
const VdeMeshArrayIds& 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"] = mesh.opacity;
|
||||
|
||||
jsonMeshMetaList.push_back(jsonMeshMeta);
|
||||
}
|
||||
|
||||
QMap<QString, QVariant> jsonModelMeta;
|
||||
jsonModelMeta["modelName"] = "ResInsightExport";
|
||||
jsonModelMeta["meshArr"] = jsonMeshMetaList;
|
||||
|
||||
ResInsightInternalJson::Json jsonCodec;
|
||||
const bool prettifyJson = true;
|
||||
QString jsonStr = jsonCodec.encode(jsonModelMeta, prettifyJson);
|
||||
return jsonStr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void VdeVizDataExtractor::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]);
|
||||
}
|
||||
}
|
||||
|
105
ApplicationCode/Commands/HoloLensCommands/VdeVizDataExtractor.h
Normal file
105
ApplicationCode/Commands/HoloLensCommands/VdeVizDataExtractor.h
Normal file
@ -0,0 +1,105 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "cvfColor3.h"
|
||||
#include "cvfArray.h"
|
||||
#include "cvfTextureImage.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
class VdeArrayDataPacket;
|
||||
class VdePacketDirectory;
|
||||
class VdeExportPart;
|
||||
|
||||
class RimGridView;
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
struct VdeMesh
|
||||
{
|
||||
QString meshSourceObjTypeStr;
|
||||
QString meshSourceObjName;
|
||||
|
||||
cvf::Color3f color;
|
||||
float opacity;
|
||||
|
||||
int verticesPerPrimitive;
|
||||
cvf::cref<cvf::Vec3fArray> vertexArr;
|
||||
cvf::cref<cvf::Vec2fArray> texCoordArr;
|
||||
std::vector<cvf::uint> connArr;
|
||||
cvf::cref<cvf::TextureImage> texImage;
|
||||
|
||||
VdeMesh()
|
||||
: color(1,1,1),
|
||||
opacity(1),
|
||||
verticesPerPrimitive(-1)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
struct VdeMeshArrayIds
|
||||
{
|
||||
int vertexArrId;
|
||||
int connArrId;
|
||||
int texImageArrId;
|
||||
int texCoordsArrId;
|
||||
|
||||
VdeMeshArrayIds()
|
||||
: vertexArrId(-1),
|
||||
connArrId(-1),
|
||||
texImageArrId(-1),
|
||||
texCoordsArrId(-1)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
class VdeVizDataExtractor
|
||||
{
|
||||
public:
|
||||
VdeVizDataExtractor(const RimGridView& view);
|
||||
|
||||
void extractViewContents(QString* modelMetaJsonStr, std::vector<int>* allReferencedArrayIds, VdePacketDirectory* packetDirectory);
|
||||
|
||||
private:
|
||||
static std::vector<VdeMesh> buildMeshArray(const std::vector<VdeExportPart>& exportPartsArr);
|
||||
static bool extractMeshFromExportPart(const VdeExportPart& exportPart, VdeMesh* mesh);
|
||||
static QString createModelMetaJsonString(const std::vector<VdeMesh>& meshArr, const std::vector<VdeMeshArrayIds>& meshContentIdsArr);
|
||||
static void debugComparePackets(const VdeArrayDataPacket& packetA, const VdeArrayDataPacket& packetB);
|
||||
|
||||
private:
|
||||
const RimGridView& m_view;
|
||||
|
||||
};
|
Loading…
Reference in New Issue
Block a user