mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Merge branch 'dev' into measurement
This commit is contained in:
commit
5976298267
@ -1,17 +1,18 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2018- Equinor ASA
|
||||
// Copyright (C) 2017 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>
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
@ -21,11 +22,13 @@
|
||||
#include <algorithm>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
/// Uses W3.org relative luminance calculation taking into account the different luminance of the different colors
|
||||
/// https://www.w3.org/TR/WCAG20-TECHS/G18.html
|
||||
/// Luminance is between [0, 1] so anything above 0.5 is considered in the bright half of the spectrum.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RiaColorTools::isBrightnessAboveThreshold(cvf::Color3f backgroundColor)
|
||||
{
|
||||
if (backgroundColor.r() + backgroundColor.g() + backgroundColor.b() > 1.5f)
|
||||
if (relativeLuminance(backgroundColor) > 0.5)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -34,7 +37,7 @@ bool RiaColorTools::isBrightnessAboveThreshold(cvf::Color3f backgroundColor)
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Color3f RiaColorTools::computeOffsetColor(cvf::Color3f color, float offsetFactor)
|
||||
{
|
||||
@ -55,13 +58,12 @@ cvf::Color3f RiaColorTools::computeOffsetColor(cvf::Color3f color, float offsetF
|
||||
gridB = color.b() + (1.0f - color.b()) * offsetFactor;
|
||||
}
|
||||
|
||||
return cvf::Color3f(cvf::Math::clamp(gridR, 0.0f, 1.0f),
|
||||
cvf::Math::clamp(gridG, 0.0f, 1.0f),
|
||||
cvf::Math::clamp(gridB, 0.0f, 1.0f));
|
||||
return cvf::Color3f(
|
||||
cvf::Math::clamp(gridR, 0.0f, 1.0f), cvf::Math::clamp(gridG, 0.0f, 1.0f), cvf::Math::clamp(gridB, 0.0f, 1.0f));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Color3f RiaColorTools::darkContrastColor()
|
||||
{
|
||||
@ -69,7 +71,7 @@ cvf::Color3f RiaColorTools::darkContrastColor()
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Color3f RiaColorTools::brightContrastColor()
|
||||
{
|
||||
@ -77,15 +79,35 @@ cvf::Color3f RiaColorTools::brightContrastColor()
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Color3f RiaColorTools::constrastColor(cvf::Color3f backgroundColor)
|
||||
cvf::Color3f RiaColorTools::darkContrastColorSofter()
|
||||
{
|
||||
return cvf::Color3f::fromByteColor(30, 30, 30);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Color3f RiaColorTools::brightContrastColorSofter()
|
||||
{
|
||||
return cvf::Color3f::fromByteColor(200, 200, 200);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Color3f RiaColorTools::constrastColor(cvf::Color3f backgroundColor, bool softerContrast)
|
||||
{
|
||||
if (isBrightnessAboveThreshold(backgroundColor))
|
||||
{
|
||||
if (softerContrast)
|
||||
return darkContrastColorSofter();
|
||||
return darkContrastColor();
|
||||
}
|
||||
|
||||
if (softerContrast)
|
||||
return brightContrastColorSofter();
|
||||
return brightContrastColor();
|
||||
}
|
||||
|
||||
@ -106,3 +128,38 @@ QColor RiaColorTools::toQColor(cvf::Color4f color)
|
||||
{
|
||||
return toQColor(color.toColor3f(), color.a());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float RiaColorTools::contrastRatio(cvf::Color3f color1, cvf::Color3f color2)
|
||||
{
|
||||
float L1 = relativeLuminance(color1);
|
||||
float L2 = relativeLuminance(color2);
|
||||
|
||||
float Lmin = std::min(L1, L2);
|
||||
float Lmax = std::max(L1, L2);
|
||||
|
||||
return (Lmax + 0.05) / (Lmin + 0.05);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float RiaColorTools::relativeLuminance(cvf::Color3f backgroundColor)
|
||||
{
|
||||
float R = calculateNonLinearColorValue(backgroundColor.r());
|
||||
float G = calculateNonLinearColorValue(backgroundColor.g());
|
||||
float B = calculateNonLinearColorValue(backgroundColor.b());
|
||||
|
||||
double luminance = 0.2126 * R + 0.7152 * G + 0.0722 * B;
|
||||
return luminance;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float RiaColorTools::calculateNonLinearColorValue(float colorFraction)
|
||||
{
|
||||
return colorFraction <= 0.03928 ? colorFraction / 12.92 : std::pow((colorFraction + 0.055) / 1.055, 2.4);
|
||||
}
|
||||
|
@ -1,17 +1,18 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2018- Equinor ASA
|
||||
// Copyright (C) 2017 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>
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
@ -35,7 +36,13 @@ public:
|
||||
static cvf::Color3f computeOffsetColor(cvf::Color3f color, float offsetFactor);
|
||||
static cvf::Color3f darkContrastColor();
|
||||
static cvf::Color3f brightContrastColor();
|
||||
static cvf::Color3f constrastColor(cvf::Color3f backgroundColor);
|
||||
static cvf::Color3f darkContrastColorSofter();
|
||||
static cvf::Color3f brightContrastColorSofter();
|
||||
static cvf::Color3f constrastColor(cvf::Color3f backgroundColor, bool softerContrast = false);
|
||||
static QColor toQColor(cvf::Color3f color, float alpha = 1.0f);
|
||||
static QColor toQColor(cvf::Color4f color);
|
||||
static float contrastRatio(cvf::Color3f color1, cvf::Color3f color2);
|
||||
private:
|
||||
static float relativeLuminance(cvf::Color3f backgroundColor);
|
||||
static float calculateNonLinearColorValue(float colorFraction);
|
||||
};
|
||||
|
@ -17,6 +17,7 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RiaSummaryCurveAnalyzer.h"
|
||||
#include "RiaStdStringTools.h"
|
||||
|
||||
#include "RiaSummaryCurveDefinition.h"
|
||||
|
||||
@ -62,6 +63,44 @@ std::set<std::string> RiaSummaryCurveAnalyzer::quantities() const
|
||||
return m_quantities;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<std::string> RiaSummaryCurveAnalyzer::quantityNamesWithHistory() const
|
||||
{
|
||||
assignCategoryToQuantities();
|
||||
|
||||
return m_quantitiesWithMatchingHistory;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<std::string> RiaSummaryCurveAnalyzer::quantityNamesNoHistory() const
|
||||
{
|
||||
assignCategoryToQuantities();
|
||||
|
||||
return m_quantitiesNoMatchingHistory;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::string RiaSummaryCurveAnalyzer::quantityNameForTitle() const
|
||||
{
|
||||
if (quantityNamesWithHistory().size() == 1 && quantityNamesNoHistory().empty())
|
||||
{
|
||||
return *quantityNamesWithHistory().begin();
|
||||
}
|
||||
|
||||
if (quantityNamesNoHistory().size() == 1 && quantityNamesWithHistory().empty())
|
||||
{
|
||||
return *quantityNamesNoHistory().begin();
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -130,7 +169,7 @@ std::vector<QString> RiaSummaryCurveAnalyzer::identifierTexts(RifEclipseSummaryA
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RifEclipseSummaryAddress>
|
||||
RiaSummaryCurveAnalyzer::addressesForCategory(const std::set<RifEclipseSummaryAddress>& addresses,
|
||||
RiaSummaryCurveAnalyzer::addressesForCategory(const std::set<RifEclipseSummaryAddress>& addresses,
|
||||
RifEclipseSummaryAddress::SummaryVarCategory category)
|
||||
{
|
||||
std::vector<RifEclipseSummaryAddress> filteredAddresses;
|
||||
@ -146,6 +185,24 @@ std::vector<RifEclipseSummaryAddress>
|
||||
return filteredAddresses;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::string RiaSummaryCurveAnalyzer::correspondingHistorySummaryCurveName(const std::string& curveName)
|
||||
{
|
||||
static std::string historyIdentifier = "H";
|
||||
|
||||
if (RiaStdStringTools::endsWith(curveName, historyIdentifier))
|
||||
{
|
||||
std::string candidate = curveName.substr(0, curveName.size() - 1);
|
||||
return candidate;
|
||||
}
|
||||
else
|
||||
{
|
||||
return curveName + historyIdentifier;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -158,6 +215,53 @@ void RiaSummaryCurveAnalyzer::clear()
|
||||
m_categories.clear();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaSummaryCurveAnalyzer::assignCategoryToQuantities() const
|
||||
{
|
||||
if (!m_quantities.empty())
|
||||
{
|
||||
if (m_quantitiesWithMatchingHistory.empty() && m_quantitiesNoMatchingHistory.empty())
|
||||
{
|
||||
computeQuantityNamesWithHistory();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaSummaryCurveAnalyzer::computeQuantityNamesWithHistory() const
|
||||
{
|
||||
m_quantitiesNoMatchingHistory.clear();
|
||||
m_quantitiesWithMatchingHistory.clear();
|
||||
|
||||
const std::string historyIdentifier("H");
|
||||
|
||||
for (const auto& s : m_quantities)
|
||||
{
|
||||
std::string correspondingHistoryCurve = correspondingHistorySummaryCurveName(s);
|
||||
|
||||
if (m_quantities.find(correspondingHistoryCurve) != m_quantities.end())
|
||||
{
|
||||
// Insert the curve name without H
|
||||
if (RiaStdStringTools::endsWith(s, historyIdentifier))
|
||||
{
|
||||
m_quantitiesWithMatchingHistory.insert(correspondingHistoryCurve);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_quantitiesWithMatchingHistory.insert(s);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_quantitiesNoMatchingHistory.insert(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -42,6 +42,11 @@ public:
|
||||
void clear();
|
||||
|
||||
std::set<std::string> quantities() const;
|
||||
std::set<std::string> quantityNamesWithHistory() const;
|
||||
std::set<std::string> quantityNamesNoHistory() const;
|
||||
|
||||
std::string quantityNameForTitle() const;
|
||||
|
||||
std::set<std::string> wellNames() const;
|
||||
std::set<std::string> wellGroupNames() const;
|
||||
std::set<int> regionNumbers() const;
|
||||
@ -53,11 +58,19 @@ public:
|
||||
static std::vector<RifEclipseSummaryAddress> addressesForCategory(const std::set<RifEclipseSummaryAddress>& addresses,
|
||||
RifEclipseSummaryAddress::SummaryVarCategory category);
|
||||
|
||||
static std::string correspondingHistorySummaryCurveName(const std::string& curveName);
|
||||
|
||||
private:
|
||||
void assignCategoryToQuantities() const;
|
||||
void computeQuantityNamesWithHistory() const;
|
||||
|
||||
void analyzeSingleAddress(const RifEclipseSummaryAddress& address);
|
||||
|
||||
private:
|
||||
std::set<std::string> m_quantities;
|
||||
mutable std::set<std::string> m_quantitiesWithMatchingHistory;
|
||||
mutable std::set<std::string> m_quantitiesNoMatchingHistory;
|
||||
|
||||
std::set<std::string> m_wellNames;
|
||||
std::set<std::string> m_wellGroupNames;
|
||||
std::set<int> m_regionNumbers;
|
||||
|
@ -399,12 +399,19 @@ if(RESINSIGHT_ENABLE_COTIRE)
|
||||
ModelVisualization/Intersections/RivIntersectionGeometryGenerator.cpp
|
||||
|
||||
# exclude file using Eigen
|
||||
ReservoirDataModel/RigTransmissibilityCondenser.cpp
|
||||
ReservoirDataModel/RigEclipseToStimPlanCellTransmissibilityCalculator.cpp
|
||||
ReservoirDataModel/RigCellGeometryTools.cpp
|
||||
ReservoirDataModel/Completions/RigTransmissibilityCondenser.cpp
|
||||
ReservoirDataModel/Completions/RigEclipseToStimPlanCellTransmissibilityCalculator.cpp
|
||||
ReservoirDataModel/Completions/RigEclipseToStimPlanCalculator.cpp
|
||||
|
||||
# exclude file using SolveSpace
|
||||
Application/Tools/RiaSCurveCalculator.cpp
|
||||
Application/Tools/WellPathTools/RiaSCurveCalculator.cpp
|
||||
|
||||
# QT 5
|
||||
qrc_cafAnimControl.cpp
|
||||
qrc_ResInsight.cpp
|
||||
ProjectDataModel/RimContourMapView.cpp
|
||||
Commands/CompletionExportCommands/RicExportFractureCompletionsImpl.cpp
|
||||
)
|
||||
|
||||
foreach (fileToExclude ${COTIRE_EXCLUDE_FILES})
|
||||
|
@ -31,7 +31,11 @@ CAF_CMD_SOURCE_INIT(RicLaunchUnitTestsFeature, "RicLaunchUnitTestsFeature");
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicLaunchUnitTestsFeature::isCommandEnabled()
|
||||
{
|
||||
#ifdef USE_UNIT_TESTS
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -15,6 +15,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicHoloLensSessionManager.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicHoloLensCreateDummyFileBackedSessionFeature.h
|
||||
|
||||
${CMAKE_CURRENT_LIST_DIR}/VdeArrayDataPacket.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/VdeCachingHashedIdFactory.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/VdeExportPart.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/VdeFileExporter.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/VdePacketDirectory.h
|
||||
@ -36,6 +37,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicHoloLensSessionManager.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicHoloLensCreateDummyFileBackedSessionFeature.cpp
|
||||
|
||||
${CMAKE_CURRENT_LIST_DIR}/VdeArrayDataPacket.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/VdeCachingHashedIdFactory.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/VdeExportPart.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/VdeFileExporter.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/VdePacketDirectory.cpp
|
||||
|
@ -28,9 +28,12 @@
|
||||
#include "VdeArrayDataPacket.h"
|
||||
|
||||
#include "cvfAssert.h"
|
||||
#include "cvfTimer.h"
|
||||
|
||||
#include <QDir>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
@ -129,18 +132,23 @@ void RicHoloLensSession::updateSessionDataFromView(const RimGridView& activeView
|
||||
{
|
||||
RiaLogging::info("HoloLens: Updating visualization data");
|
||||
|
||||
// Note
|
||||
// Currently we clear the packet directory each time we update the visualization data
|
||||
// This means we do no caching of actual packet data and we assume that the server will ask for data
|
||||
// packets/arrays right after having received updated meta data
|
||||
m_packetDirectory.clear();
|
||||
// Grab the current max ID as an easy way to detect if new IDs have been added for debugging purposes
|
||||
const int dbgMaxAssignedIdBeforeExtraction = m_cachingIdFactory.lastAssignedId();
|
||||
|
||||
VdeVizDataExtractor extractor(activeView);
|
||||
// Note that we pass the caching ID factory on the constructor which will try and detect data payloads that
|
||||
// are equal, and will then "recycle" the array IDs for these
|
||||
VdeVizDataExtractor extractor(activeView, &m_cachingIdFactory);
|
||||
|
||||
QString modelMetaJsonStr;
|
||||
std::vector<int> allReferencedPacketIds;
|
||||
extractor.extractViewContents(&modelMetaJsonStr, &allReferencedPacketIds, &m_packetDirectory);
|
||||
|
||||
// Note!
|
||||
// The packet directory should now contain all the packets that are being actively referenced.
|
||||
// We now prune out any packets that are no longer being referenced. This means we do no caching of actual packet
|
||||
// data over time and that we assume that the server will ask for data packets/arrays right after having received updated meta data
|
||||
m_packetDirectory.pruneUnreferencedPackets(allReferencedPacketIds);
|
||||
|
||||
m_lastExtractionMetaDataSequenceNumber++;
|
||||
m_lastExtractionAllReferencedPacketIdsArr = allReferencedPacketIds;
|
||||
|
||||
@ -171,9 +179,23 @@ void RicHoloLensSession::updateSessionDataFromView(const RimGridView& activeView
|
||||
return;
|
||||
}
|
||||
|
||||
RiaLogging::info(QString("HoloLens: Doing debug export of data to folder: %1").arg(absOutputFolder));
|
||||
// For debugging, write only the new packets to file
|
||||
// Determine which packets are new by comparing the IDs to the max known ID before extraction
|
||||
std::vector<int> packetIdsToWrite;
|
||||
for (int packetId : allReferencedPacketIds)
|
||||
{
|
||||
if (packetId > dbgMaxAssignedIdBeforeExtraction)
|
||||
{
|
||||
packetIdsToWrite.push_back(packetId);
|
||||
}
|
||||
}
|
||||
|
||||
// This will write all packets seen in this extraction to file
|
||||
//packetIdsToWrite = allReferencedPacketIds;
|
||||
|
||||
RiaLogging::info(QString("HoloLens: Doing debug export of data (%1 packets) to folder: %2").arg(packetIdsToWrite.size()).arg(absOutputFolder));
|
||||
VdeFileExporter fileExporter(absOutputFolder);
|
||||
if (!fileExporter.exportToFile(modelMetaJsonStr, m_packetDirectory, allReferencedPacketIds))
|
||||
if (!fileExporter.exportToFile(modelMetaJsonStr, m_packetDirectory, packetIdsToWrite))
|
||||
{
|
||||
RiaLogging::error("HoloLens: Error exporting debug data to folder");
|
||||
}
|
||||
@ -207,29 +229,135 @@ void RicHoloLensSession::handleFailedCreateSession()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Handle the server response we receive after sending new meta data
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicHoloLensSession::handleSuccessfulSendMetaData(int metaDataSequenceNumber, const QByteArray& /*jsonServerResponseString*/)
|
||||
void RicHoloLensSession::handleSuccessfulSendMetaData(int metaDataSequenceNumber, const QByteArray& jsonServerResponseString)
|
||||
{
|
||||
RiaLogging::info(QString("HoloLens: Processing server response to meta data (sequenceNumber=%1)").arg(metaDataSequenceNumber));
|
||||
cvf::Timer tim;
|
||||
|
||||
RiaLogging::info(QString("HoloLens: Processing server response (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));
|
||||
RiaLogging::warning(QString("HoloLens: Ignoring server response, the meta data sequenceNumber(%1) has been superseded").arg(metaDataSequenceNumber));
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_lastExtractionAllReferencedPacketIdsArr.size() > 0)
|
||||
std::vector<int> arrayIdsToSend;
|
||||
|
||||
//cvf::Trace::show("Raw JSON response from server: '%s'", jsonServerResponseString.data());
|
||||
QByteArray trimmedServerResponseString = jsonServerResponseString.trimmed();
|
||||
if (trimmedServerResponseString.size() > 0)
|
||||
{
|
||||
if (!parseJsonIntegerArray(trimmedServerResponseString, &arrayIdsToSend))
|
||||
{
|
||||
RiaLogging::error("HoloLens: Error parsing array server response with array Ids, no data will be sent to server");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// An empty server response means we should send all array referenced by the last sent meta data
|
||||
if (m_lastExtractionAllReferencedPacketIdsArr.size() > 0)
|
||||
{
|
||||
arrayIdsToSend = m_lastExtractionAllReferencedPacketIdsArr;
|
||||
RiaLogging::info("HoloLens: Empty server response, sending all arrays referenced by last meta data");
|
||||
}
|
||||
}
|
||||
|
||||
if (arrayIdsToSend.size() ==0)
|
||||
{
|
||||
RiaLogging::info("HoloLens: Nothing to do, no data requested by server");
|
||||
return;
|
||||
}
|
||||
|
||||
RiaLogging::info(QString("HoloLens: Start sending data to server, %1 data arrays have been requested").arg(arrayIdsToSend.size()));
|
||||
|
||||
size_t totalBytesSent = 0;
|
||||
size_t totalNumArraysSent = 0;
|
||||
|
||||
const bool sendAsIndividualPackets = false;
|
||||
|
||||
// Sending data packets one by one
|
||||
if (sendAsIndividualPackets)
|
||||
{
|
||||
for (size_t i = 0; i < arrayIdsToSend.size(); i++)
|
||||
{
|
||||
const int arrayId = arrayIdsToSend[i];
|
||||
const VdeArrayDataPacket* packet = m_packetDirectory.lookupPacket(arrayId);
|
||||
if (!packet)
|
||||
{
|
||||
RiaLogging::warning(QString("HoloLens: Could not get the requested data from cache, array id: %1 ").arg(arrayId));
|
||||
continue;
|
||||
}
|
||||
|
||||
QByteArray packetByteArr(packet->fullPacketRawPtr(), static_cast<int>(packet->fullPacketSize()));
|
||||
|
||||
RiaLogging::info(QString("HoloLens: sending array id: %1, %2KB (%3 bytes)").arg(arrayId).arg(packetByteArr.size()/1024.0, 0, 'f', 2).arg(packetByteArr.size()));
|
||||
|
||||
m_restClient->sendBinaryData(packetByteArr);
|
||||
|
||||
totalNumArraysSent++;
|
||||
totalBytesSent += packetByteArr.size();
|
||||
}
|
||||
}
|
||||
// Sending all requested arrays/packets in one combined packet
|
||||
else
|
||||
{
|
||||
QByteArray combinedPacketArr;
|
||||
if (!m_packetDirectory.getPacketsAsCombinedBuffer(m_lastExtractionAllReferencedPacketIdsArr, &combinedPacketArr))
|
||||
if (!m_packetDirectory.getPacketsAsCombinedBuffer(arrayIdsToSend, &combinedPacketArr))
|
||||
{
|
||||
RiaLogging::warning("HoloLens: Error gathering the requested packets, no data will be sent");
|
||||
RiaLogging::warning("HoloLens: Error gathering the requested arrays, no data will be sent");
|
||||
return;
|
||||
}
|
||||
|
||||
RiaLogging::info(QString("HoloLens: Sending new data to sharing server (%1 packets)").arg(m_lastExtractionAllReferencedPacketIdsArr.size()));
|
||||
totalNumArraysSent = arrayIdsToSend.size();
|
||||
totalBytesSent = combinedPacketArr.size();
|
||||
|
||||
RiaLogging::info(QString("HoloLens: Sending data to server (%1 arrays combined), %2KB (%3 bytes)").arg(totalNumArraysSent).arg(totalBytesSent/1024.0, 0, 'f', 2).arg(totalBytesSent));
|
||||
|
||||
m_restClient->sendBinaryData(combinedPacketArr);
|
||||
}
|
||||
|
||||
const double totalMb = totalBytesSent/(1024.0*1024.0);
|
||||
RiaLogging::info(QString("HoloLens: Finished sending data to server, %1 arrays, total %2MB (%3 bytes) in %4ms").arg(totalNumArraysSent).arg(totalMb, 0, 'f', 2).arg(totalBytesSent).arg(static_cast<int>(tim.time()*1000)));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicHoloLensSession::parseJsonIntegerArray(const QByteArray& jsonString, std::vector<int>* integerArr)
|
||||
{
|
||||
//cvf::Trace::show("jsonString: '%s'", jsonString.data());
|
||||
|
||||
const int openBraceIdx = jsonString.indexOf('[');
|
||||
const int closeBraceIdx = jsonString.lastIndexOf(']');
|
||||
if (openBraceIdx < 0 || closeBraceIdx < 0)
|
||||
{
|
||||
RiaLogging::debug("Error parsing JSON array, could not find opening or closing braces");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (closeBraceIdx <= openBraceIdx)
|
||||
{
|
||||
RiaLogging::debug("Error parsing JSON array, wrong placement of braces");
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray arrayContents = jsonString.mid(openBraceIdx + 1, closeBraceIdx - openBraceIdx - 1).trimmed();
|
||||
//cvf::Trace::show("arrayContents: '%s'", arrayContents.data());
|
||||
|
||||
QList<QByteArray> stringList = arrayContents.split(',');
|
||||
for (const QByteArray& entry : stringList)
|
||||
{
|
||||
bool convertOk = false;
|
||||
const int intVal = entry.toInt(&convertOk);
|
||||
if (convertOk)
|
||||
{
|
||||
integerArr->push_back(intVal);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "RicHoloLensRestClient.h"
|
||||
|
||||
#include "VdePacketDirectory.h"
|
||||
#include "VdeCachingHashedIdFactory.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QPointer>
|
||||
@ -57,6 +58,8 @@ private:
|
||||
virtual void handleSuccessfulSendMetaData(int metaDataSequenceNumber, const QByteArray& jsonServerResponseString) override;
|
||||
virtual void handleError(const QString& errMsg, const QString& url, const QString& serverData) override;
|
||||
|
||||
static bool parseJsonIntegerArray(const QByteArray& jsonString, std::vector<int>* integerArr);
|
||||
|
||||
void notifyObserver(RicHoloLensSessionObserver::Notification notification);
|
||||
|
||||
private:
|
||||
@ -65,6 +68,7 @@ private:
|
||||
|
||||
int m_lastExtractionMetaDataSequenceNumber;
|
||||
std::vector<int> m_lastExtractionAllReferencedPacketIdsArr;
|
||||
VdeCachingHashedIdFactory m_cachingIdFactory;
|
||||
VdePacketDirectory m_packetDirectory;
|
||||
|
||||
RicHoloLensSessionObserver* m_sessionObserver;
|
||||
|
@ -103,7 +103,7 @@ void RicHoloLensSessionManager::terminateSession()
|
||||
|
||||
refreshToolbarState();
|
||||
|
||||
m_session->deleteLater();
|
||||
sessionToDelete->deleteLater();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -178,40 +178,40 @@ unsigned char VdeArrayDataPacket::imageComponentCount() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
VdeArrayDataPacket VdeArrayDataPacket::fromFloat32Arr(int arrayId, const float* srcArr, size_t srcArrElementCount)
|
||||
std::unique_ptr<VdeArrayDataPacket> VdeArrayDataPacket::fromFloat32Arr(int arrayId, const float* srcArr, size_t srcArrElementCount)
|
||||
{
|
||||
size_t payloadByteCount = srcArrElementCount*sizeof(float);
|
||||
const char* rawSrcPtr = reinterpret_cast<const char*>(srcArr);
|
||||
|
||||
VdeArrayDataPacket packet;
|
||||
packet.assign(arrayId, Float32, srcArrElementCount, 0, 0, 0, rawSrcPtr, payloadByteCount);
|
||||
std::unique_ptr<VdeArrayDataPacket> packet(new VdeArrayDataPacket);
|
||||
packet->assign(arrayId, Float32, srcArrElementCount, 0, 0, 0, rawSrcPtr, payloadByteCount);
|
||||
return packet;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
VdeArrayDataPacket VdeArrayDataPacket::fromUint32Arr(int arrayId, const unsigned int* srcArr, size_t srcArrElementCount)
|
||||
std::unique_ptr<VdeArrayDataPacket> VdeArrayDataPacket::fromUint32Arr(int arrayId, 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(arrayId, Uint32, srcArrElementCount, 0, 0, 0, rawSrcPtr, payloadByteCount);
|
||||
std::unique_ptr<VdeArrayDataPacket> packet(new VdeArrayDataPacket);
|
||||
packet->assign(arrayId, Uint32, srcArrElementCount, 0, 0, 0, rawSrcPtr, payloadByteCount);
|
||||
return packet;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
VdeArrayDataPacket VdeArrayDataPacket::fromUint8ImageRGBArr(int arrayId, unsigned short imageWidth, unsigned short imageHeight, const unsigned char* srcArr, size_t srcArrElementCount)
|
||||
std::unique_ptr<VdeArrayDataPacket> VdeArrayDataPacket::fromUint8ImageRGBArr(int arrayId, unsigned short imageWidth, unsigned short imageHeight, const unsigned char* srcArr, size_t srcArrElementCount)
|
||||
{
|
||||
const char* rawSrcPtr = reinterpret_cast<const char*>(srcArr);
|
||||
|
||||
assert(3*imageWidth*imageHeight == srcArrElementCount);
|
||||
|
||||
VdeArrayDataPacket packet;
|
||||
packet.assign(arrayId, Uint8, srcArrElementCount, imageWidth, imageHeight, 3, rawSrcPtr, srcArrElementCount);
|
||||
std::unique_ptr<VdeArrayDataPacket> packet(new VdeArrayDataPacket);
|
||||
packet->assign(arrayId, Uint8, srcArrElementCount, imageWidth, imageHeight, 3, rawSrcPtr, srcArrElementCount);
|
||||
return packet;
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
@ -42,26 +43,26 @@ public:
|
||||
public:
|
||||
VdeArrayDataPacket();
|
||||
|
||||
bool isValid() const;
|
||||
int arrayId() const;
|
||||
bool isValid() const;
|
||||
int arrayId() const;
|
||||
|
||||
ElementType elementType() const;
|
||||
size_t elementSize() const;
|
||||
size_t elementCount() const;
|
||||
const char* arrayData() const;
|
||||
ElementType elementType() const;
|
||||
size_t elementSize() const;
|
||||
size_t elementCount() const;
|
||||
const char* arrayData() const;
|
||||
|
||||
unsigned short imageWidth() const;
|
||||
unsigned short imageHeight() const;
|
||||
unsigned char imageComponentCount() const;
|
||||
unsigned short imageWidth() const;
|
||||
unsigned short imageHeight() const;
|
||||
unsigned char imageComponentCount() const;
|
||||
|
||||
size_t fullPacketSize() const;
|
||||
const char* fullPacketRawPtr() const;
|
||||
size_t fullPacketSize() const;
|
||||
const char* fullPacketRawPtr() const;
|
||||
|
||||
static VdeArrayDataPacket fromFloat32Arr(int arrayId, const float* srcArr, size_t srcArrElementCount);
|
||||
static VdeArrayDataPacket fromUint32Arr(int arrayId, const unsigned int* srcArr, size_t srcArrElementCount);
|
||||
static VdeArrayDataPacket fromUint8ImageRGBArr(int arrayId, unsigned short imageWidth, unsigned short imageHeight, const unsigned char* srcArr, size_t srcArrElementCount);
|
||||
static std::unique_ptr<VdeArrayDataPacket> fromFloat32Arr(int arrayId, const float* srcArr, size_t srcArrElementCount);
|
||||
static std::unique_ptr<VdeArrayDataPacket> fromUint32Arr(int arrayId, const unsigned int* srcArr, size_t srcArrElementCount);
|
||||
static std::unique_ptr<VdeArrayDataPacket> fromUint8ImageRGBArr(int arrayId, unsigned short imageWidth, unsigned short imageHeight, const unsigned char* srcArr, size_t srcArrElementCount);
|
||||
|
||||
static VdeArrayDataPacket fromRawPacketBuffer(const char* rawPacketBuffer, size_t bufferSize, std::string* errString);
|
||||
static VdeArrayDataPacket fromRawPacketBuffer(const char* rawPacketBuffer, size_t bufferSize, std::string* errString);
|
||||
|
||||
private:
|
||||
bool assign(int arrayId, ElementType elementType, size_t elementCount, unsigned short imageWidth, unsigned short imageHeight, unsigned char imageCompCount, const char* arrayDataPtr, size_t arrayDataSizeInBytes);
|
||||
|
@ -0,0 +1,257 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "VdeCachingHashedIdFactory.h"
|
||||
|
||||
#define FARMHASH_NO_BUILTIN_EXPECT
|
||||
#define NAMESPACE_FOR_HASH_FUNCTIONS farmhash
|
||||
#include "farmhash/farmhash.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 4267 4307 4319 4244)
|
||||
#endif
|
||||
|
||||
#include "farmhash/farmhash.cc"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
class Checksum
|
||||
{
|
||||
public:
|
||||
static unsigned int crc(const void* data, size_t numBytes);
|
||||
};
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool VdeCachingHashedIdFactory::Key::operator<(const Key& other) const
|
||||
{
|
||||
if (hashVal != other.hashVal)
|
||||
{
|
||||
return hashVal < other.hashVal;
|
||||
}
|
||||
else if (role != other.role)
|
||||
{
|
||||
return role < other.role;
|
||||
}
|
||||
else if (elementType != other.elementType)
|
||||
{
|
||||
return elementType < other.elementType;
|
||||
}
|
||||
else
|
||||
{
|
||||
return elementCount < other.elementCount;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
VdeCachingHashedIdFactory::VdeCachingHashedIdFactory()
|
||||
: m_lastUsedId(-1)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int VdeCachingHashedIdFactory::getOrCreateIdForFloatArr(ArrayRole arrayRole, const void* floatArr, size_t elementCount)
|
||||
{
|
||||
return getOrCreateIdForArrOfType(arrayRole, Float32, sizeof(float), floatArr, elementCount);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int VdeCachingHashedIdFactory::getOrCreateIdForUint32Arr(ArrayRole arrayRole, const unsigned int* uint32Arr, size_t elementCount)
|
||||
{
|
||||
return getOrCreateIdForArrOfType(arrayRole, Uint32, sizeof(unsigned int), uint32Arr, elementCount);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int VdeCachingHashedIdFactory::getOrCreateIdForUint8Arr(ArrayRole arrayRole, const unsigned char* uint8Arr, size_t elementCount)
|
||||
{
|
||||
return getOrCreateIdForArrOfType(arrayRole, Uint8, sizeof(unsigned char), uint8Arr, elementCount);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int VdeCachingHashedIdFactory::lastAssignedId() const
|
||||
{
|
||||
return m_lastUsedId;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int VdeCachingHashedIdFactory::getOrCreateIdForArrOfType(ArrayRole arrayRole, ElementType elementType, size_t elementSizeInBytes, const void* data, size_t elementCount)
|
||||
{
|
||||
Key key;
|
||||
key.elementType = elementType;
|
||||
key.role = arrayRole;
|
||||
key.elementCount = elementCount;
|
||||
|
||||
const size_t arraySizeInBytes = elementCount*elementSizeInBytes;
|
||||
//key.hashVal = Checksum::crc(data, arraySizeInBytes);
|
||||
//key.hashVal = farmhash::Hash32(static_cast<const char*>(data), arraySizeInBytes);
|
||||
//key.hashVal = farmhash::Hash64(static_cast<const char*>(data), arraySizeInBytes);
|
||||
//key.hashVal = farmhash::Hash128to64(farmhash::Hash128(static_cast<const char*>(data), arraySizeInBytes));
|
||||
key.hashVal = farmhash::Hash128(static_cast<const char*>(data), arraySizeInBytes);
|
||||
|
||||
std::map<Key, int>::iterator it = m_keyToIdMap.find(key);
|
||||
if (it != m_keyToIdMap.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
const int newId = ++m_lastUsedId;
|
||||
|
||||
m_keyToIdMap[key] = newId;
|
||||
|
||||
return newId;
|
||||
|
||||
//const int newId = ++m_lastUsedId;
|
||||
//return newId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// CRC Stuff
|
||||
//
|
||||
//==================================================================================================
|
||||
|
||||
static const unsigned int crc_table[256] = {
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
|
||||
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
|
||||
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
|
||||
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
|
||||
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
|
||||
0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
|
||||
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
|
||||
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
|
||||
0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
|
||||
0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
|
||||
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
|
||||
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
|
||||
0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
|
||||
0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
|
||||
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
||||
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
|
||||
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
|
||||
0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
|
||||
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
|
||||
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
|
||||
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
|
||||
0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
|
||||
0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
|
||||
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
||||
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
|
||||
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
|
||||
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
|
||||
0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
|
||||
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
|
||||
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
|
||||
0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
|
||||
0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
|
||||
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
|
||||
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
|
||||
0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
|
||||
0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
|
||||
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
||||
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
|
||||
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
|
||||
0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
|
||||
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
|
||||
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
||||
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
|
||||
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
|
||||
0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
|
||||
0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
|
||||
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
unsigned int Checksum::crc(const void* data, size_t numBytes)
|
||||
{
|
||||
unsigned int sum = 0xffffffff;
|
||||
|
||||
const unsigned char* p = reinterpret_cast<const unsigned char*>(data);
|
||||
|
||||
// Compute crc
|
||||
{
|
||||
unsigned int tbl_idx;
|
||||
|
||||
while (numBytes--) {
|
||||
tbl_idx = (sum ^ *p) & 0xff;
|
||||
sum = (crc_table[tbl_idx] ^ (sum >> 8)) & 0xffffffff;
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
sum = sum & 0xffffffff;
|
||||
}
|
||||
|
||||
return sum ^ 0xffffffff;
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,73 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 <map>
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
class VdeCachingHashedIdFactory
|
||||
{
|
||||
public:
|
||||
enum ArrayRole
|
||||
{
|
||||
VertexArr,
|
||||
ConnArr,
|
||||
TexImage,
|
||||
TexCoordsArr
|
||||
};
|
||||
|
||||
public:
|
||||
VdeCachingHashedIdFactory();
|
||||
|
||||
int getOrCreateIdForFloatArr(ArrayRole arrayRole, const void* floatArr, size_t elementCount);
|
||||
int getOrCreateIdForUint32Arr(ArrayRole arrayRole, const unsigned int* uint32Arr, size_t elementCount);
|
||||
int getOrCreateIdForUint8Arr(ArrayRole arrayRole, const unsigned char* uint8Arr, size_t elementCount);
|
||||
|
||||
int lastAssignedId() const;
|
||||
|
||||
private:
|
||||
enum ElementType
|
||||
{
|
||||
Float32,
|
||||
Uint32,
|
||||
Uint8,
|
||||
};
|
||||
|
||||
struct Key
|
||||
{
|
||||
std::pair<uint64_t, uint64_t> hashVal;
|
||||
ArrayRole role;
|
||||
ElementType elementType;
|
||||
size_t elementCount;
|
||||
|
||||
bool operator<(const Key& other) const;
|
||||
};
|
||||
|
||||
private:
|
||||
int getOrCreateIdForArrOfType(ArrayRole arrayRole, ElementType elementType, size_t elementSizeInBytes, const void* data, size_t elementCount);
|
||||
|
||||
private:
|
||||
std::map<Key, int> m_keyToIdMap;
|
||||
int m_lastUsedId;
|
||||
};
|
@ -19,6 +19,7 @@
|
||||
#include "VdeFileExporter.h"
|
||||
#include "VdeArrayDataPacket.h"
|
||||
#include "VdePacketDirectory.h"
|
||||
#include "VdeCachingHashedIdFactory.h"
|
||||
|
||||
#include "cvfTrace.h"
|
||||
|
||||
@ -72,7 +73,7 @@ bool VdeFileExporter::exportToFile(const QString& modelMetaJsonStr, const VdePac
|
||||
}
|
||||
}
|
||||
|
||||
cvf::Trace::show("Data exported to folder: %s", m_absOutputFolder.toLatin1().constData());
|
||||
cvf::Trace::show("Data exported (%d packets) to folder: %s", packetIdsToExport.size(), m_absOutputFolder.toLatin1().constData());
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -82,11 +83,12 @@ bool VdeFileExporter::exportToFile(const QString& modelMetaJsonStr, const VdePac
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool VdeFileExporter::exportViewContents(const RimGridView& view)
|
||||
{
|
||||
VdeCachingHashedIdFactory localIdFactory;
|
||||
VdeVizDataExtractor extractor(view, &localIdFactory);
|
||||
|
||||
QString modelMetaJsonStr;
|
||||
std::vector<int> allReferencedArrayIds;
|
||||
VdePacketDirectory packetDirectory;
|
||||
|
||||
VdeVizDataExtractor extractor(view);
|
||||
extractor.extractViewContents(&modelMetaJsonStr, &allReferencedArrayIds, &packetDirectory);
|
||||
|
||||
if (!exportToFile(modelMetaJsonStr, packetDirectory, allReferencedArrayIds))
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "VdePacketDirectory.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
@ -36,10 +37,10 @@ VdePacketDirectory::VdePacketDirectory()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void VdePacketDirectory::addPacket(const VdeArrayDataPacket& packet)
|
||||
void VdePacketDirectory::addPacket(std::unique_ptr<VdeArrayDataPacket> packet)
|
||||
{
|
||||
const int id = packet.arrayId();
|
||||
m_idToPacketMap[id] = std::unique_ptr<VdeArrayDataPacket>(new VdeArrayDataPacket(packet));
|
||||
const int id = packet->arrayId();
|
||||
m_idToPacketMap[id] = std::move(packet);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -64,6 +65,29 @@ void VdePacketDirectory::clear()
|
||||
m_idToPacketMap.clear();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void VdePacketDirectory::pruneUnreferencedPackets(const std::vector<int>& packetIdsInUseArr)
|
||||
{
|
||||
std::vector<int> sortedPacketsIdsInUse(packetIdsInUseArr);
|
||||
std::sort(sortedPacketsIdsInUse.begin(), sortedPacketsIdsInUse.end());
|
||||
|
||||
IdToPacketMap_T::const_iterator it = m_idToPacketMap.cbegin();
|
||||
while (it != m_idToPacketMap.cend())
|
||||
{
|
||||
const int packetId = it->first;
|
||||
if (!std::binary_search(sortedPacketsIdsInUse.begin(), sortedPacketsIdsInUse.end(), packetId))
|
||||
{
|
||||
it = m_idToPacketMap.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -36,9 +36,11 @@ class VdePacketDirectory
|
||||
public:
|
||||
VdePacketDirectory();
|
||||
|
||||
void addPacket(const VdeArrayDataPacket& packet);
|
||||
void addPacket(std::unique_ptr<VdeArrayDataPacket> packet);
|
||||
const VdeArrayDataPacket* lookupPacket(int arrayId) const;
|
||||
|
||||
void clear();
|
||||
void pruneUnreferencedPackets(const std::vector<int>& packetIdsInUseArr);
|
||||
|
||||
bool getPacketsAsCombinedBuffer(const std::vector<int>& packetIdsToGet, QByteArray* combinedPacketArr) const;
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "VdeVizDataExtractor.h"
|
||||
#include "VdeArrayDataPacket.h"
|
||||
#include "VdePacketDirectory.h"
|
||||
#include "VdeCachingHashedIdFactory.h"
|
||||
|
||||
#include "RicHoloLensExportImpl.h"
|
||||
|
||||
@ -29,6 +30,8 @@
|
||||
#include "cvfDrawableGeo.h"
|
||||
#include "cvfPrimitiveSet.h"
|
||||
#include "cvfTransform.h"
|
||||
#include "cvfAssert.h"
|
||||
#include "cvfTimer.h"
|
||||
#include "cvfTrace.h"
|
||||
|
||||
|
||||
@ -43,9 +46,11 @@
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
VdeVizDataExtractor::VdeVizDataExtractor(const RimGridView& view)
|
||||
: m_view(view)
|
||||
VdeVizDataExtractor::VdeVizDataExtractor(const RimGridView& view, VdeCachingHashedIdFactory* cachingIdFactory)
|
||||
: m_view(view),
|
||||
m_cachingIdFactory(cachingIdFactory)
|
||||
{
|
||||
CVF_ASSERT(m_cachingIdFactory);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -53,84 +58,110 @@ VdeVizDataExtractor::VdeVizDataExtractor(const RimGridView& view)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void VdeVizDataExtractor::extractViewContents(QString* modelMetaJsonStr, std::vector<int>* allReferencedArrayIds, VdePacketDirectory* packetDirectory)
|
||||
{
|
||||
cvf::Timer tim;
|
||||
|
||||
// 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 std::vector<std::unique_ptr<VdeMesh> > meshArr = buildMeshArray(exportPartsArr);
|
||||
const int buildMeshes_ms = static_cast<int>(tim.lapTime()*1000);
|
||||
|
||||
|
||||
const size_t meshCount = meshArr.size();
|
||||
cvf::Trace::show("Extracting %d meshes", meshCount);
|
||||
|
||||
std::vector<VdeMeshArrayIds> meshArrayIdsArr;
|
||||
cvf::Trace::show("Analyzing and generating array packet data for %d meshes", meshCount);
|
||||
|
||||
std::vector<VdeMeshArrayIds> allMeshesArrayIdsArr;
|
||||
size_t totNumPrimitives = 0;
|
||||
int nextArrayId = 0;
|
||||
for (size_t i = 0; i < meshCount; i++)
|
||||
{
|
||||
const VdeMesh& mesh = meshArr[i];
|
||||
const VdeMesh* mesh = meshArr[i].get();
|
||||
|
||||
const size_t primCount = mesh.connArr.size()/mesh.verticesPerPrimitive;
|
||||
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());
|
||||
cvf::Trace::show(" mesh %2d: primCount=%d vertsPerPrim=%d meshSourceObjName='%s' meshSourceObjType='%s'", i, primCount, mesh->verticesPerPrimitive, mesh->meshSourceObjName.toLatin1().constData(), mesh->meshSourceObjTypeStr.toLatin1().constData());
|
||||
|
||||
VdeMeshArrayIds meshArrayIds;
|
||||
VdeMeshArrayIds arrayIdsThisMesh;
|
||||
|
||||
{
|
||||
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);
|
||||
const float* floatArr = reinterpret_cast<const float*>(mesh->vertexArr->ptr());
|
||||
const size_t arrElementCount = 3*mesh->vertexArr->size();
|
||||
arrayIdsThisMesh.vertexArrId = m_cachingIdFactory->getOrCreateIdForFloatArr(VdeCachingHashedIdFactory::VertexArr, floatArr, arrElementCount);
|
||||
|
||||
// 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())
|
||||
{
|
||||
if (!packetDirectory->lookupPacket(arrayIdsThisMesh.vertexArrId))
|
||||
{
|
||||
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);
|
||||
cvf::Trace::show(" generating vertices, arrayId=%d", arrayIdsThisMesh.vertexArrId);
|
||||
std::unique_ptr<VdeArrayDataPacket> dataPacket = VdeArrayDataPacket::fromFloat32Arr(arrayIdsThisMesh.vertexArrId, floatArr, arrElementCount);
|
||||
|
||||
// Debug testing of decoding
|
||||
debugComparePackets(dataPacket, VdeArrayDataPacket::fromRawPacketBuffer(dataPacket.fullPacketRawPtr(), dataPacket.fullPacketSize(), nullptr));
|
||||
//debugComparePackets(*dataPacket, VdeArrayDataPacket::fromRawPacketBuffer(dataPacket->fullPacketRawPtr(), dataPacket->fullPacketSize(), nullptr));
|
||||
|
||||
packetDirectory->addPacket(std::move(dataPacket));
|
||||
}
|
||||
}
|
||||
{
|
||||
const unsigned int* uintArr = mesh->connArr.data();
|
||||
const size_t arrElementCount = mesh->connArr.size();
|
||||
arrayIdsThisMesh.connArrId = m_cachingIdFactory->getOrCreateIdForUint32Arr(VdeCachingHashedIdFactory::ConnArr, uintArr, arrElementCount);
|
||||
|
||||
if (!packetDirectory->lookupPacket(arrayIdsThisMesh.connArrId))
|
||||
{
|
||||
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);
|
||||
cvf::Trace::show(" generating connectivities, arrayId=%d", arrayIdsThisMesh.connArrId);
|
||||
std::unique_ptr<VdeArrayDataPacket> dataPacket = VdeArrayDataPacket::fromUint32Arr(arrayIdsThisMesh.connArrId, uintArr, arrElementCount);
|
||||
|
||||
// Debug testing of decoding
|
||||
debugComparePackets(dataPacket, VdeArrayDataPacket::fromRawPacketBuffer(dataPacket.fullPacketRawPtr(), dataPacket.fullPacketSize(), nullptr));
|
||||
//debugComparePackets(*dataPacket, VdeArrayDataPacket::fromRawPacketBuffer(dataPacket->fullPacketRawPtr(), dataPacket->fullPacketSize(), nullptr));
|
||||
|
||||
packetDirectory->addPacket(std::move(dataPacket));
|
||||
}
|
||||
}
|
||||
|
||||
meshArrayIdsArr.push_back(meshArrayIds);
|
||||
if (mesh->texCoordArr.notNull() && mesh->texImage.notNull())
|
||||
{
|
||||
{
|
||||
const float* floatArr = reinterpret_cast<const float*>(mesh->texCoordArr->ptr());
|
||||
const size_t arrElementCount = 2*mesh->texCoordArr->size();
|
||||
arrayIdsThisMesh.texCoordsArrId = m_cachingIdFactory->getOrCreateIdForFloatArr(VdeCachingHashedIdFactory::TexCoordsArr, floatArr, arrElementCount);
|
||||
|
||||
if (!packetDirectory->lookupPacket(arrayIdsThisMesh.texCoordsArrId))
|
||||
{
|
||||
cvf::Trace::show(" generating texture coords, arrayId=%d", arrayIdsThisMesh.texCoordsArrId);
|
||||
std::unique_ptr<VdeArrayDataPacket> dataPacket = VdeArrayDataPacket::fromFloat32Arr(arrayIdsThisMesh.texCoordsArrId, floatArr, arrElementCount);
|
||||
|
||||
// Debug testing of decoding
|
||||
//debugComparePackets(*dataPacket, VdeArrayDataPacket::fromRawPacketBuffer(dataPacket->fullPacketRawPtr(), dataPacket->fullPacketSize(), nullptr));
|
||||
|
||||
packetDirectory->addPacket(std::move(dataPacket));
|
||||
}
|
||||
}
|
||||
{
|
||||
cvf::ref<cvf::UByteArray> byteArr = mesh->texImage->toRgb();
|
||||
arrayIdsThisMesh.texImageArrId = m_cachingIdFactory->getOrCreateIdForUint8Arr(VdeCachingHashedIdFactory::TexImage, byteArr->ptr(), byteArr->size());
|
||||
|
||||
if (!packetDirectory->lookupPacket(arrayIdsThisMesh.texImageArrId))
|
||||
{
|
||||
cvf::Trace::show(" generating texture image, arrayId=%d", arrayIdsThisMesh.texImageArrId);
|
||||
std::unique_ptr<VdeArrayDataPacket> dataPacket = VdeArrayDataPacket::fromUint8ImageRGBArr(arrayIdsThisMesh.texImageArrId, mesh->texImage->width(), mesh->texImage->height(), byteArr->ptr(), byteArr->size());
|
||||
|
||||
// Debug testing of decoding
|
||||
//debugComparePackets(*dataPacket, VdeArrayDataPacket::fromRawPacketBuffer(dataPacket->fullPacketRawPtr(), dataPacket->fullPacketSize(), nullptr));
|
||||
|
||||
packetDirectory->addPacket(std::move(dataPacket));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
allMeshesArrayIdsArr.push_back(arrayIdsThisMesh);
|
||||
}
|
||||
|
||||
cvf::Trace::show("Total number of primitives extracted: %d", totNumPrimitives);
|
||||
const int fillPacketDir_ms = static_cast<int>(tim.lapTime()*1000);
|
||||
|
||||
|
||||
*modelMetaJsonStr = createModelMetaJsonString(meshArr, meshArrayIdsArr);
|
||||
*modelMetaJsonStr = createModelMetaJsonString(meshArr, allMeshesArrayIdsArr);
|
||||
|
||||
// Find all unique packet array IDs referenced
|
||||
std::set<int> referencedIdsSet;
|
||||
for (const VdeMeshArrayIds& meshArrayIds : meshArrayIdsArr)
|
||||
for (const VdeMeshArrayIds& meshArrayIds : allMeshesArrayIdsArr)
|
||||
{
|
||||
if (meshArrayIds.vertexArrId != -1) referencedIdsSet.insert(meshArrayIds.vertexArrId);
|
||||
if (meshArrayIds.connArrId != -1) referencedIdsSet.insert(meshArrayIds.connArrId);
|
||||
@ -139,20 +170,24 @@ void VdeVizDataExtractor::extractViewContents(QString* modelMetaJsonStr, std::ve
|
||||
}
|
||||
|
||||
allReferencedArrayIds->assign(referencedIdsSet.begin(), referencedIdsSet.end());
|
||||
|
||||
RiaLogging::debug(QString("HoloLens: Extracted %1 meshes (total of %2 primitives) in %3ms (buildMeshes=%4ms, fillPacketDir=%5ms)").arg(meshCount).arg(totNumPrimitives).arg(static_cast<int>(tim.time()*1000)).arg(buildMeshes_ms).arg(fillPacketDir_ms));
|
||||
|
||||
//cvf::Trace::show("Total number of primitives extracted: %d in %dms", totNumPrimitives, static_cast<int>(tim.time()*1000));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<VdeMesh> VdeVizDataExtractor::buildMeshArray(const std::vector<VdeExportPart>& exportPartsArr)
|
||||
std::vector<std::unique_ptr<VdeMesh> > VdeVizDataExtractor::buildMeshArray(const std::vector<VdeExportPart>& exportPartsArr)
|
||||
{
|
||||
std::vector<VdeMesh> meshArr;
|
||||
std::vector<std::unique_ptr<VdeMesh> > meshArr;
|
||||
for (const VdeExportPart& exportPart : exportPartsArr)
|
||||
{
|
||||
VdeMesh mesh;
|
||||
if (extractMeshFromExportPart(exportPart, &mesh))
|
||||
std::unique_ptr<VdeMesh> mesh = createMeshFromExportPart(exportPart);
|
||||
if (mesh)
|
||||
{
|
||||
meshArr.push_back(mesh);
|
||||
meshArr.push_back(std::move(mesh));
|
||||
}
|
||||
}
|
||||
|
||||
@ -162,26 +197,28 @@ std::vector<VdeMesh> VdeVizDataExtractor::buildMeshArray(const std::vector<VdeEx
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool VdeVizDataExtractor::extractMeshFromExportPart(const VdeExportPart& exportPart, VdeMesh* mesh)
|
||||
std::unique_ptr<VdeMesh> VdeVizDataExtractor::createMeshFromExportPart(const VdeExportPart& exportPart)
|
||||
{
|
||||
//cvf::Timer tim;
|
||||
|
||||
const cvf::Part* cvfPart = exportPart.part();
|
||||
const cvf::DrawableGeo* geo = dynamic_cast<const cvf::DrawableGeo*>(cvfPart ? cvfPart->drawable() : nullptr);
|
||||
if (!geo)
|
||||
{
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (geo->primitiveSetCount() != 1)
|
||||
{
|
||||
RiaLogging::debug("Only geometries with exactly one primitive set is supported");
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const cvf::Vec3fArray* vertexArr = geo->vertexArray();
|
||||
const cvf::PrimitiveSet* primSet = geo->primitiveSet(0);
|
||||
if (!vertexArr || !primSet || primSet->faceCount() == 0)
|
||||
{
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@ -190,23 +227,24 @@ bool VdeVizDataExtractor::extractMeshFromExportPart(const VdeExportPart& exportP
|
||||
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;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const int vertsPerPrimitive = (primType == cvf::PT_TRIANGLES) ? 3 : 2;
|
||||
|
||||
|
||||
std::unique_ptr<VdeMesh> mesh(new VdeMesh);
|
||||
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());
|
||||
const cvf::Mat4f m = cvf::Mat4f(cvfPart->transform()->worldTransform());
|
||||
|
||||
cvf::Mat4f m = cvf::Mat4f(cvfPart->transform()->worldTransform());
|
||||
cvf::ref<cvf::Vec3fArray> transVertexArr = new cvf::Vec3fArray(*vertexArr);
|
||||
const size_t vertexCount = transVertexArr->size();
|
||||
for (size_t i = 0; i < vertexCount; i++)
|
||||
{
|
||||
transVertexArr->set(i, vertexArr->get(i).getTransformedPoint(m));
|
||||
transVertexArr->ptr(i)->transformPoint(m);
|
||||
}
|
||||
|
||||
mesh->vertexArr = transVertexArr.p();
|
||||
@ -216,12 +254,15 @@ bool VdeVizDataExtractor::extractMeshFromExportPart(const VdeExportPart& exportP
|
||||
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;
|
||||
// This point might be moot if the HoloLens visualization always has to use two-sided lighting to get good results
|
||||
const size_t faceCount = primSet->faceCount();
|
||||
mesh->connArr.reserve(faceCount*vertsPerPrimitive);
|
||||
|
||||
cvf::UIntArray faceConn;
|
||||
for (size_t iface = 0; iface < faceCount; iface++)
|
||||
{
|
||||
primSet->getFaceIndices(iface, &faceConn);
|
||||
@ -259,26 +300,28 @@ bool VdeVizDataExtractor::extractMeshFromExportPart(const VdeExportPart& exportP
|
||||
mesh->color = exportPart.color();
|
||||
mesh->opacity = exportPart.opacity();
|
||||
|
||||
return true;
|
||||
//cvf::Trace::show("createMeshFromExportPart(): numFaces=%d, time=%dms", faceCount, static_cast<int>(tim.time()*1000));
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString VdeVizDataExtractor::createModelMetaJsonString(const std::vector<VdeMesh>& meshArr, const std::vector<VdeMeshArrayIds>& meshContentIdsArr)
|
||||
QString VdeVizDataExtractor::createModelMetaJsonString(const std::vector<std::unique_ptr<VdeMesh> >& meshArr, const std::vector<VdeMeshArrayIds>& meshContentIdsArr)
|
||||
{
|
||||
QVariantList jsonMeshMetaList;
|
||||
|
||||
for (size_t i = 0; i < meshArr.size(); i++)
|
||||
{
|
||||
const VdeMesh& mesh = meshArr[i];
|
||||
const VdeMesh* mesh = meshArr[i].get();
|
||||
const VdeMeshArrayIds& meshIds = meshContentIdsArr[i];
|
||||
|
||||
QMap<QString, QVariant> jsonMeshMeta;
|
||||
jsonMeshMeta["meshSourceObjType"] = mesh.meshSourceObjTypeStr;
|
||||
jsonMeshMeta["meshSourceObjName"] = mesh.meshSourceObjName;
|
||||
jsonMeshMeta["meshSourceObjType"] = mesh->meshSourceObjTypeStr;
|
||||
jsonMeshMeta["meshSourceObjName"] = mesh->meshSourceObjName;
|
||||
|
||||
jsonMeshMeta["verticesPerPrimitive"] = mesh.verticesPerPrimitive;
|
||||
jsonMeshMeta["verticesPerPrimitive"] = mesh->verticesPerPrimitive;
|
||||
jsonMeshMeta["vertexArrId"] = meshIds.vertexArrId;
|
||||
jsonMeshMeta["connArrId"] = meshIds.connArrId;
|
||||
|
||||
@ -290,14 +333,14 @@ QString VdeVizDataExtractor::createModelMetaJsonString(const std::vector<VdeMesh
|
||||
else
|
||||
{
|
||||
QMap<QString, QVariant> jsonColor;
|
||||
jsonColor["r"] = mesh.color.r();
|
||||
jsonColor["g"] = mesh.color.g();
|
||||
jsonColor["b"] = mesh.color.b();
|
||||
jsonColor["r"] = mesh->color.r();
|
||||
jsonColor["g"] = mesh->color.g();
|
||||
jsonColor["b"] = mesh->color.b();
|
||||
|
||||
jsonMeshMeta["color"] = jsonColor;
|
||||
}
|
||||
|
||||
jsonMeshMeta["opacity"] = mesh.opacity;
|
||||
jsonMeshMeta["opacity"] = mesh->opacity;
|
||||
|
||||
jsonMeshMetaList.push_back(jsonMeshMeta);
|
||||
}
|
||||
|
@ -25,9 +25,12 @@
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include <memory>
|
||||
|
||||
class VdeArrayDataPacket;
|
||||
class VdePacketDirectory;
|
||||
class VdeExportPart;
|
||||
class VdeCachingHashedIdFactory;
|
||||
|
||||
class RimGridView;
|
||||
|
||||
@ -62,7 +65,7 @@ struct VdeMesh
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
// The set of array IDs that are needed for a mesh
|
||||
//
|
||||
//==================================================================================================
|
||||
struct VdeMeshArrayIds
|
||||
@ -89,17 +92,17 @@ struct VdeMeshArrayIds
|
||||
class VdeVizDataExtractor
|
||||
{
|
||||
public:
|
||||
VdeVizDataExtractor(const RimGridView& view);
|
||||
VdeVizDataExtractor(const RimGridView& view, VdeCachingHashedIdFactory* cachingIdFactory);
|
||||
|
||||
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);
|
||||
static std::vector<std::unique_ptr<VdeMesh> > buildMeshArray(const std::vector<VdeExportPart>& exportPartsArr);
|
||||
static std::unique_ptr<VdeMesh> createMeshFromExportPart(const VdeExportPart& exportPart);
|
||||
static QString createModelMetaJsonString(const std::vector<std::unique_ptr<VdeMesh> >& meshArr, const std::vector<VdeMeshArrayIds>& meshContentIdsArr);
|
||||
static void debugComparePackets(const VdeArrayDataPacket& packetA, const VdeArrayDataPacket& packetB);
|
||||
|
||||
private:
|
||||
const RimGridView& m_view;
|
||||
|
||||
const RimGridView& m_view;
|
||||
VdeCachingHashedIdFactory* m_cachingIdFactory;
|
||||
};
|
||||
|
11840
ApplicationCode/Commands/HoloLensCommands/farmhash/farmhash.cc
Normal file
11840
ApplicationCode/Commands/HoloLensCommands/farmhash/farmhash.cc
Normal file
File diff suppressed because it is too large
Load Diff
328
ApplicationCode/Commands/HoloLensCommands/farmhash/farmhash.h
Normal file
328
ApplicationCode/Commands/HoloLensCommands/farmhash/farmhash.h
Normal file
@ -0,0 +1,328 @@
|
||||
// Copyright (c) 2014 Google, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
// FarmHash, by Geoff Pike
|
||||
|
||||
//
|
||||
// http://code.google.com/p/farmhash/
|
||||
//
|
||||
// This file provides a few functions for hashing strings and other
|
||||
// data. All of them are high-quality functions in the sense that
|
||||
// they do well on standard tests such as Austin Appleby's SMHasher.
|
||||
// They're also fast. FarmHash is the successor to CityHash.
|
||||
//
|
||||
// Functions in the FarmHash family are not suitable for cryptography.
|
||||
//
|
||||
// WARNING: This code has been only lightly tested on big-endian platforms!
|
||||
// It is known to work well on little-endian platforms that have a small penalty
|
||||
// for unaligned reads, such as current Intel and AMD moderate-to-high-end CPUs.
|
||||
// It should work on all 32-bit and 64-bit platforms that allow unaligned reads;
|
||||
// bug reports are welcome.
|
||||
//
|
||||
// By the way, for some hash functions, given strings a and b, the hash
|
||||
// of a+b is easily derived from the hashes of a and b. This property
|
||||
// doesn't hold for any hash functions in this file.
|
||||
|
||||
#ifndef FARM_HASH_H_
|
||||
#define FARM_HASH_H_
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h> // for memcpy and memset
|
||||
#include <utility>
|
||||
|
||||
#ifndef NAMESPACE_FOR_HASH_FUNCTIONS
|
||||
#define NAMESPACE_FOR_HASH_FUNCTIONS util
|
||||
#endif
|
||||
|
||||
namespace NAMESPACE_FOR_HASH_FUNCTIONS {
|
||||
|
||||
#if defined(FARMHASH_UINT128_T_DEFINED)
|
||||
#if defined(__clang__)
|
||||
#if !defined(uint128_t)
|
||||
#define uint128_t __uint128_t
|
||||
#endif
|
||||
#endif
|
||||
inline uint64_t Uint128Low64(const uint128_t x) {
|
||||
return static_cast<uint64_t>(x);
|
||||
}
|
||||
inline uint64_t Uint128High64(const uint128_t x) {
|
||||
return static_cast<uint64_t>(x >> 64);
|
||||
}
|
||||
inline uint128_t Uint128(uint64_t lo, uint64_t hi) {
|
||||
return lo + (((uint128_t)hi) << 64);
|
||||
}
|
||||
#else
|
||||
typedef std::pair<uint64_t, uint64_t> uint128_t;
|
||||
inline uint64_t Uint128Low64(const uint128_t x) { return x.first; }
|
||||
inline uint64_t Uint128High64(const uint128_t x) { return x.second; }
|
||||
inline uint128_t Uint128(uint64_t lo, uint64_t hi) { return uint128_t(lo, hi); }
|
||||
#endif
|
||||
|
||||
|
||||
// BASIC STRING HASHING
|
||||
|
||||
// Hash function for a byte array.
|
||||
// May change from time to time, may differ on different platforms, may differ
|
||||
// depending on NDEBUG.
|
||||
size_t Hash(const char* s, size_t len);
|
||||
|
||||
// Hash function for a byte array. Most useful in 32-bit binaries.
|
||||
// May change from time to time, may differ on different platforms, may differ
|
||||
// depending on NDEBUG.
|
||||
uint32_t Hash32(const char* s, size_t len);
|
||||
|
||||
// Hash function for a byte array. For convenience, a 32-bit seed is also
|
||||
// hashed into the result.
|
||||
// May change from time to time, may differ on different platforms, may differ
|
||||
// depending on NDEBUG.
|
||||
uint32_t Hash32WithSeed(const char* s, size_t len, uint32_t seed);
|
||||
|
||||
// Hash function for a byte array.
|
||||
// May change from time to time, may differ on different platforms, may differ
|
||||
// depending on NDEBUG.
|
||||
uint64_t Hash64(const char* s, size_t len);
|
||||
|
||||
// Hash function for a byte array. For convenience, a 64-bit seed is also
|
||||
// hashed into the result.
|
||||
// May change from time to time, may differ on different platforms, may differ
|
||||
// depending on NDEBUG.
|
||||
uint64_t Hash64WithSeed(const char* s, size_t len, uint64_t seed);
|
||||
|
||||
// Hash function for a byte array. For convenience, two seeds are also
|
||||
// hashed into the result.
|
||||
// May change from time to time, may differ on different platforms, may differ
|
||||
// depending on NDEBUG.
|
||||
uint64_t Hash64WithSeeds(const char* s, size_t len,
|
||||
uint64_t seed0, uint64_t seed1);
|
||||
|
||||
// Hash function for a byte array.
|
||||
// May change from time to time, may differ on different platforms, may differ
|
||||
// depending on NDEBUG.
|
||||
uint128_t Hash128(const char* s, size_t len);
|
||||
|
||||
// Hash function for a byte array. For convenience, a 128-bit seed is also
|
||||
// hashed into the result.
|
||||
// May change from time to time, may differ on different platforms, may differ
|
||||
// depending on NDEBUG.
|
||||
uint128_t Hash128WithSeed(const char* s, size_t len, uint128_t seed);
|
||||
|
||||
// BASIC NON-STRING HASHING
|
||||
|
||||
// Hash 128 input bits down to 64 bits of output.
|
||||
// This is intended to be a reasonably good hash function.
|
||||
// May change from time to time, may differ on different platforms, may differ
|
||||
// depending on NDEBUG.
|
||||
inline uint64_t Hash128to64(uint128_t x) {
|
||||
// Murmur-inspired hashing.
|
||||
const uint64_t kMul = 0x9ddfea08eb382d69ULL;
|
||||
uint64_t a = (Uint128Low64(x) ^ Uint128High64(x)) * kMul;
|
||||
a ^= (a >> 47);
|
||||
uint64_t b = (Uint128High64(x) ^ a) * kMul;
|
||||
b ^= (b >> 47);
|
||||
b *= kMul;
|
||||
return b;
|
||||
}
|
||||
|
||||
// FINGERPRINTING (i.e., good, portable, forever-fixed hash functions)
|
||||
|
||||
// Fingerprint function for a byte array. Most useful in 32-bit binaries.
|
||||
uint32_t Fingerprint32(const char* s, size_t len);
|
||||
|
||||
// Fingerprint function for a byte array.
|
||||
uint64_t Fingerprint64(const char* s, size_t len);
|
||||
|
||||
// Fingerprint function for a byte array.
|
||||
uint128_t Fingerprint128(const char* s, size_t len);
|
||||
|
||||
// This is intended to be a good fingerprinting primitive.
|
||||
// See below for more overloads.
|
||||
inline uint64_t Fingerprint(uint128_t x) {
|
||||
// Murmur-inspired hashing.
|
||||
const uint64_t kMul = 0x9ddfea08eb382d69ULL;
|
||||
uint64_t a = (Uint128Low64(x) ^ Uint128High64(x)) * kMul;
|
||||
a ^= (a >> 47);
|
||||
uint64_t b = (Uint128High64(x) ^ a) * kMul;
|
||||
b ^= (b >> 44);
|
||||
b *= kMul;
|
||||
b ^= (b >> 41);
|
||||
b *= kMul;
|
||||
return b;
|
||||
}
|
||||
|
||||
// This is intended to be a good fingerprinting primitive.
|
||||
inline uint64_t Fingerprint(uint64_t x) {
|
||||
// Murmur-inspired hashing.
|
||||
const uint64_t kMul = 0x9ddfea08eb382d69ULL;
|
||||
uint64_t b = x * kMul;
|
||||
b ^= (b >> 44);
|
||||
b *= kMul;
|
||||
b ^= (b >> 41);
|
||||
b *= kMul;
|
||||
return b;
|
||||
}
|
||||
|
||||
#ifndef FARMHASH_NO_CXX_STRING
|
||||
|
||||
// Convenience functions to hash or fingerprint C++ strings.
|
||||
// These require that Str::data() return a pointer to the first char
|
||||
// (as a const char*) and that Str::length() return the string's length;
|
||||
// they work with std::string, for example.
|
||||
|
||||
// Hash function for a byte array.
|
||||
// May change from time to time, may differ on different platforms, may differ
|
||||
// depending on NDEBUG.
|
||||
template <typename Str>
|
||||
inline size_t Hash(const Str& s) {
|
||||
assert(sizeof(s[0]) == 1);
|
||||
return Hash(s.data(), s.length());
|
||||
}
|
||||
|
||||
// Hash function for a byte array. Most useful in 32-bit binaries.
|
||||
// May change from time to time, may differ on different platforms, may differ
|
||||
// depending on NDEBUG.
|
||||
template <typename Str>
|
||||
inline uint32_t Hash32(const Str& s) {
|
||||
assert(sizeof(s[0]) == 1);
|
||||
return Hash32(s.data(), s.length());
|
||||
}
|
||||
|
||||
// Hash function for a byte array. For convenience, a 32-bit seed is also
|
||||
// hashed into the result.
|
||||
// May change from time to time, may differ on different platforms, may differ
|
||||
// depending on NDEBUG.
|
||||
template <typename Str>
|
||||
inline uint32_t Hash32WithSeed(const Str& s, uint32_t seed) {
|
||||
assert(sizeof(s[0]) == 1);
|
||||
return Hash32WithSeed(s.data(), s.length(), seed);
|
||||
}
|
||||
|
||||
// Hash 128 input bits down to 64 bits of output.
|
||||
// Hash function for a byte array.
|
||||
// May change from time to time, may differ on different platforms, may differ
|
||||
// depending on NDEBUG.
|
||||
template <typename Str>
|
||||
inline uint64_t Hash64(const Str& s) {
|
||||
assert(sizeof(s[0]) == 1);
|
||||
return Hash64(s.data(), s.length());
|
||||
}
|
||||
|
||||
// Hash function for a byte array. For convenience, a 64-bit seed is also
|
||||
// hashed into the result.
|
||||
// May change from time to time, may differ on different platforms, may differ
|
||||
// depending on NDEBUG.
|
||||
template <typename Str>
|
||||
inline uint64_t Hash64WithSeed(const Str& s, uint64_t seed) {
|
||||
assert(sizeof(s[0]) == 1);
|
||||
return Hash64WithSeed(s.data(), s.length(), seed);
|
||||
}
|
||||
|
||||
// Hash function for a byte array. For convenience, two seeds are also
|
||||
// hashed into the result.
|
||||
// May change from time to time, may differ on different platforms, may differ
|
||||
// depending on NDEBUG.
|
||||
template <typename Str>
|
||||
inline uint64_t Hash64WithSeeds(const Str& s, uint64_t seed0, uint64_t seed1) {
|
||||
assert(sizeof(s[0]) == 1);
|
||||
return Hash64WithSeeds(s.data(), s.length(), seed0, seed1);
|
||||
}
|
||||
|
||||
// Hash function for a byte array.
|
||||
// May change from time to time, may differ on different platforms, may differ
|
||||
// depending on NDEBUG.
|
||||
template <typename Str>
|
||||
inline uint128_t Hash128(const Str& s) {
|
||||
assert(sizeof(s[0]) == 1);
|
||||
return Hash128(s.data(), s.length());
|
||||
}
|
||||
|
||||
// Hash function for a byte array. For convenience, a 128-bit seed is also
|
||||
// hashed into the result.
|
||||
// May change from time to time, may differ on different platforms, may differ
|
||||
// depending on NDEBUG.
|
||||
template <typename Str>
|
||||
inline uint128_t Hash128WithSeed(const Str& s, uint128_t seed) {
|
||||
assert(sizeof(s[0]) == 1);
|
||||
return Hash128(s.data(), s.length(), seed);
|
||||
}
|
||||
|
||||
// FINGERPRINTING (i.e., good, portable, forever-fixed hash functions)
|
||||
|
||||
// Fingerprint function for a byte array. Most useful in 32-bit binaries.
|
||||
template <typename Str>
|
||||
inline uint32_t Fingerprint32(const Str& s) {
|
||||
assert(sizeof(s[0]) == 1);
|
||||
return Fingerprint32(s.data(), s.length());
|
||||
}
|
||||
|
||||
// Fingerprint 128 input bits down to 64 bits of output.
|
||||
// Fingerprint function for a byte array.
|
||||
template <typename Str>
|
||||
inline uint64_t Fingerprint64(const Str& s) {
|
||||
assert(sizeof(s[0]) == 1);
|
||||
return Fingerprint64(s.data(), s.length());
|
||||
}
|
||||
|
||||
// Fingerprint function for a byte array.
|
||||
template <typename Str>
|
||||
inline uint128_t Fingerprint128(const Str& s) {
|
||||
assert(sizeof(s[0]) == 1);
|
||||
return Fingerprint128(s.data(), s.length());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace NAMESPACE_FOR_HASH_FUNCTIONS
|
||||
|
||||
/* gently define FARMHASH_BIG_ENDIAN when detected big-endian machine */
|
||||
#if defined(__BIG_ENDIAN__)
|
||||
#if !defined(FARMHASH_BIG_ENDIAN)
|
||||
#define FARMHASH_BIG_ENDIAN
|
||||
#endif
|
||||
#elif defined(__LITTLE_ENDIAN__)
|
||||
// nothing for little-endian
|
||||
#elif defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && (__BYTE_ORDER == __ORDER_LITTLE_ENDIAN__)
|
||||
// nothing for little-endian
|
||||
#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__BYTE_ORDER == __ORDER_BIG_ENDIAN__)
|
||||
#if !defined(FARMHASH_BIG_ENDIAN)
|
||||
#define FARMHASH_BIG_ENDIAN
|
||||
#endif
|
||||
#elif defined(__linux__) || defined(__CYGWIN__) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ )
|
||||
#include <endian.h> // libc6-dev, GLIBC
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#if !defined(FARMHASH_BIG_ENDIAN)
|
||||
#define FARMHASH_BIG_ENDIAN
|
||||
#endif
|
||||
#endif
|
||||
#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) || defined(__s390x__)
|
||||
#include <sys/endian.h>
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#if !defined(FARMHASH_BIG_ENDIAN)
|
||||
#define FARMHASH_BIG_ENDIAN
|
||||
#endif
|
||||
#endif
|
||||
#elif defined(_WIN32)
|
||||
// Windows is (currently) little-endian
|
||||
#else
|
||||
#error "Unable to determine endianness!"
|
||||
#endif /* __BIG_ENDIAN__ */
|
||||
|
||||
#endif // FARM_HASH_H_
|
@ -116,9 +116,12 @@ RicFileHierarchyDialog::RicFileHierarchyDialog(QWidget* parent)
|
||||
m_effectiveFilter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
m_fileListLabel->setText("Files found");
|
||||
m_fileListLabel->setVisible(false);
|
||||
|
||||
m_fileList->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
m_fileList->setVisible(false);
|
||||
m_fileList->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
m_fileList->setSortingEnabled(true);
|
||||
|
||||
m_browseButton->setText("...");
|
||||
m_browseButton->setFixedWidth(25);
|
||||
m_findOrCancelButton->setText(FIND_BUTTON_FIND_TEXT);
|
||||
|
@ -63,7 +63,8 @@ bool RicImportEnsembleFeature::isCommandEnabled()
|
||||
void RicImportEnsembleFeature::onActionTriggered(bool isChecked)
|
||||
{
|
||||
RiaApplication* app = RiaApplication::instance();
|
||||
QStringList fileNames = RicImportSummaryCasesFeature::runRecursiveSummaryCaseFileSearchDialog("Import Ensemble");
|
||||
QString pathCacheName = "ENSEMBLE_FILES";
|
||||
QStringList fileNames = RicImportSummaryCasesFeature::runRecursiveSummaryCaseFileSearchDialog("Import Ensemble", pathCacheName);
|
||||
|
||||
if (fileNames.isEmpty()) return;
|
||||
|
||||
|
@ -70,7 +70,8 @@ bool RicImportSummaryCasesFeature::isCommandEnabled()
|
||||
void RicImportSummaryCasesFeature::onActionTriggered(bool isChecked)
|
||||
{
|
||||
RiaApplication* app = RiaApplication::instance();
|
||||
QStringList fileNames = runRecursiveSummaryCaseFileSearchDialog("Import Summary Cases");
|
||||
QString pathCacheName = "INPUT_FILES";
|
||||
QStringList fileNames = runRecursiveSummaryCaseFileSearchDialog("Import Summary Cases", pathCacheName);
|
||||
|
||||
std::vector<RimSummaryCase*> cases;
|
||||
if (!fileNames.isEmpty()) createSummaryCasesFromFiles(fileNames, &cases);
|
||||
@ -217,10 +218,11 @@ void RicImportSummaryCasesFeature::addCasesToGroupIfRelevant(const std::vector<R
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QStringList RicImportSummaryCasesFeature::runRecursiveSummaryCaseFileSearchDialog(const QString& dialogTitle)
|
||||
QStringList RicImportSummaryCasesFeature::runRecursiveSummaryCaseFileSearchDialog(const QString& dialogTitle,
|
||||
const QString& pathCacheName)
|
||||
{
|
||||
RiaApplication* app = RiaApplication::instance();
|
||||
QString defaultDir = app->lastUsedDialogDirectory("INPUT_FILES");
|
||||
QString defaultDir = app->lastUsedDialogDirectory(pathCacheName);
|
||||
|
||||
RicFileHierarchyDialogResult result = RicFileHierarchyDialog::runRecursiveSearchDialog(nullptr,
|
||||
dialogTitle,
|
||||
@ -236,7 +238,7 @@ QStringList RicImportSummaryCasesFeature::runRecursiveSummaryCaseFileSearchDialo
|
||||
if (!result.ok) return QStringList();
|
||||
|
||||
// Remember the path to next time
|
||||
app->setLastUsedDialogDirectory("INPUT_FILES", QFileInfo(result.rootDir).absoluteFilePath());
|
||||
app->setLastUsedDialogDirectory(pathCacheName, QFileInfo(result.rootDir).absoluteFilePath());
|
||||
|
||||
return result.files;
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ public:
|
||||
static void addSummaryCases(const std::vector<RimSummaryCase*> cases);
|
||||
static void addCasesToGroupIfRelevant(const std::vector<RimSummaryCase*> cases);
|
||||
|
||||
static QStringList runRecursiveSummaryCaseFileSearchDialog(const QString& dialogTitle);
|
||||
static QStringList runRecursiveSummaryCaseFileSearchDialog(const QString& dialogTitle, const QString& pathCacheName);
|
||||
|
||||
protected:
|
||||
// Overrides
|
||||
|
@ -61,7 +61,8 @@ bool RicImportSummaryGroupFeature::isCommandEnabled()
|
||||
void RicImportSummaryGroupFeature::onActionTriggered(bool isChecked)
|
||||
{
|
||||
RiaApplication* app = RiaApplication::instance();
|
||||
QStringList fileNames = RicImportSummaryCasesFeature::runRecursiveSummaryCaseFileSearchDialog("Import Summary Case Group");
|
||||
QString pathCacheName = "INPUT_FILES";
|
||||
QStringList fileNames = RicImportSummaryCasesFeature::runRecursiveSummaryCaseFileSearchDialog("Import Summary Case Group", pathCacheName);
|
||||
|
||||
if (fileNames.isEmpty()) return;
|
||||
|
||||
|
@ -36,6 +36,10 @@ ${CMAKE_CURRENT_LIST_DIR}/RicNewSummaryEnsembleCurveSetFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicPasteEnsembleCurveSetFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewEnsembleCurveFilterFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewDerivedEnsembleFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicClearSourceSteppingSummaryCurveFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicSetSourceSteppingSummaryCurveFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicClearSourceSteppingEnsembleCurveSetFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicSetSourceSteppingEnsembleCurveSetFeature.h
|
||||
)
|
||||
|
||||
set (SOURCE_GROUP_SOURCE_FILES
|
||||
@ -75,6 +79,10 @@ ${CMAKE_CURRENT_LIST_DIR}/RicNewSummaryEnsembleCurveSetFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicPasteEnsembleCurveSetFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewEnsembleCurveFilterFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewDerivedEnsembleFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicClearSourceSteppingSummaryCurveFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicSetSourceSteppingSummaryCurveFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicClearSourceSteppingEnsembleCurveSetFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicSetSourceSteppingEnsembleCurveSetFeature.cpp
|
||||
)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES
|
||||
|
@ -0,0 +1,114 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2018- Equinor 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 "RicClearSourceSteppingEnsembleCurveSetFeature.h"
|
||||
|
||||
#include "RimEnsembleCurveSet.h"
|
||||
#include "RimEnsembleCurveSetCollection.h"
|
||||
#include "RimSummaryCurve.h"
|
||||
#include "RimSummaryCurveCollection.h"
|
||||
#include "RimSummaryPlot.h"
|
||||
|
||||
#include "RiuPlotMainWindowTools.h"
|
||||
|
||||
#include "cafSelectionManager.h"
|
||||
|
||||
#include <QAction>
|
||||
|
||||
CAF_CMD_SOURCE_INIT(RicClearSourceSteppingEnsembleCurveSetFeature, "RicClearSourceSteppingEnsembleCurveSetFeature");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicClearSourceSteppingEnsembleCurveSetFeature::isCommandEnabled()
|
||||
{
|
||||
std::vector<caf::PdmObject*> objects;
|
||||
caf::SelectionManager::instance()->objectsByType(&objects);
|
||||
|
||||
if (objects.size() == 1)
|
||||
{
|
||||
auto c = objects[0];
|
||||
|
||||
RimSummaryPlot* summaryPlot = nullptr;
|
||||
c->firstAncestorOrThisOfTypeAsserted(summaryPlot);
|
||||
if (summaryPlot)
|
||||
{
|
||||
if (summaryPlot->ensembleCurveSetCollection()->curveSetForSourceStepping()
|
||||
|| summaryPlot->summaryCurveCollection()->curveForSourceStepping())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicClearSourceSteppingEnsembleCurveSetFeature::onActionTriggered(bool isChecked)
|
||||
{
|
||||
std::vector<caf::PdmObject*> objects;
|
||||
caf::SelectionManager::instance()->objectsByType(&objects);
|
||||
|
||||
if (objects.size() == 1)
|
||||
{
|
||||
auto c = objects[0];
|
||||
|
||||
RimSummaryPlot* summaryPlot = nullptr;
|
||||
c->firstAncestorOrThisOfType(summaryPlot);
|
||||
if (summaryPlot)
|
||||
{
|
||||
clearAllSourceSteppingInSummaryPlot(summaryPlot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicClearSourceSteppingEnsembleCurveSetFeature::clearAllSourceSteppingInSummaryPlot(const RimSummaryPlot* summaryPlot)
|
||||
{
|
||||
RimEnsembleCurveSet* previousCurveSet = summaryPlot->ensembleCurveSetCollection()->curveSetForSourceStepping();
|
||||
summaryPlot->ensembleCurveSetCollection()->setCurveSetForSourceStepping(nullptr);
|
||||
|
||||
RimSummaryCurve* previousCurve = summaryPlot->summaryCurveCollection()->curveForSourceStepping();
|
||||
summaryPlot->summaryCurveCollection()->setCurveForSourceStepping(nullptr);
|
||||
|
||||
if (previousCurveSet)
|
||||
{
|
||||
previousCurveSet->updateConnectedEditors();
|
||||
}
|
||||
|
||||
if (previousCurve)
|
||||
{
|
||||
previousCurve->updateConnectedEditors();
|
||||
}
|
||||
|
||||
RiuPlotMainWindowTools::refreshToolbars();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicClearSourceSteppingEnsembleCurveSetFeature::setupActionLook(QAction* actionToSetup)
|
||||
{
|
||||
actionToSetup->setText("Clear Source Stepping Curve Set");
|
||||
actionToSetup->setIcon(QIcon(":/StepUpDown16x16.png"));
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2018- Equinor 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 "cafCmdFeature.h"
|
||||
|
||||
class RimSummaryPlot;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RicClearSourceSteppingEnsembleCurveSetFeature : public caf::CmdFeature
|
||||
{
|
||||
CAF_CMD_HEADER_INIT;
|
||||
|
||||
public:
|
||||
static void clearAllSourceSteppingInSummaryPlot(const RimSummaryPlot* summaryPlot);
|
||||
|
||||
protected:
|
||||
bool isCommandEnabled() override;
|
||||
void onActionTriggered(bool isChecked) override;
|
||||
|
||||
|
||||
void setupActionLook(QAction* actionToSetup) override;
|
||||
};
|
@ -0,0 +1,90 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2018- Equinor 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 "RicClearSourceSteppingSummaryCurveFeature.h"
|
||||
#include "RicClearSourceSteppingEnsembleCurveSetFeature.h"
|
||||
|
||||
#include "RimSummaryCurve.h"
|
||||
#include "RimSummaryCurveCollection.h"
|
||||
#include "RimSummaryPlot.h"
|
||||
|
||||
#include "RiuPlotMainWindowTools.h"
|
||||
|
||||
#include "cafSelectionManager.h"
|
||||
|
||||
#include <QAction>
|
||||
#include "RimEnsembleCurveSetCollection.h"
|
||||
|
||||
CAF_CMD_SOURCE_INIT(RicClearSourceSteppingSummaryCurveFeature, "RicClearSourceSteppingSummaryCurveFeature");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicClearSourceSteppingSummaryCurveFeature::isCommandEnabled()
|
||||
{
|
||||
std::vector<caf::PdmObject*> objects;
|
||||
caf::SelectionManager::instance()->objectsByType(&objects);
|
||||
|
||||
if (objects.size() == 1)
|
||||
{
|
||||
auto c = objects[0];
|
||||
|
||||
RimSummaryPlot* summaryPlot = nullptr;
|
||||
c->firstAncestorOrThisOfTypeAsserted(summaryPlot);
|
||||
if (summaryPlot)
|
||||
{
|
||||
if (summaryPlot->ensembleCurveSetCollection()->curveSetForSourceStepping()
|
||||
|| summaryPlot->summaryCurveCollection()->curveForSourceStepping())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicClearSourceSteppingSummaryCurveFeature::onActionTriggered(bool isChecked)
|
||||
{
|
||||
std::vector<RimSummaryCurve*> summaryCurves;
|
||||
caf::SelectionManager::instance()->objectsByType(&summaryCurves);
|
||||
|
||||
if (summaryCurves.size() == 1)
|
||||
{
|
||||
auto c = summaryCurves[0];
|
||||
|
||||
RimSummaryPlot* summaryPlot = nullptr;
|
||||
c->firstAncestorOrThisOfType(summaryPlot);
|
||||
if (summaryPlot)
|
||||
{
|
||||
RicClearSourceSteppingEnsembleCurveSetFeature::clearAllSourceSteppingInSummaryPlot(summaryPlot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicClearSourceSteppingSummaryCurveFeature::setupActionLook(QAction* actionToSetup)
|
||||
{
|
||||
actionToSetup->setText("Clear Source Stepping Curve");
|
||||
actionToSetup->setIcon(QIcon(":/StepUpDown16x16.png"));
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2018- Equinor 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 "cafCmdFeature.h"
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RicClearSourceSteppingSummaryCurveFeature : public caf::CmdFeature
|
||||
{
|
||||
CAF_CMD_HEADER_INIT;
|
||||
|
||||
protected:
|
||||
bool isCommandEnabled() override;
|
||||
void onActionTriggered(bool isChecked) override;
|
||||
void setupActionLook(QAction* actionToSetup) override;
|
||||
};
|
@ -19,6 +19,7 @@
|
||||
#include "RicNewSummaryCurveFeature.h"
|
||||
|
||||
#include "RiaApplication.h"
|
||||
#include "RiaColorTables.h"
|
||||
|
||||
#include "RimMainPlotCollection.h"
|
||||
#include "RimOilField.h"
|
||||
@ -31,8 +32,6 @@
|
||||
|
||||
#include "RiuPlotMainWindow.h"
|
||||
|
||||
#include "WellLogCommands/RicWellLogPlotCurveFeatureImpl.h"
|
||||
|
||||
#include "cafSelectionManager.h"
|
||||
|
||||
#include "cvfAssert.h"
|
||||
@ -62,7 +61,9 @@ void RicNewSummaryCurveFeature::onActionTriggered(bool isChecked)
|
||||
if (plot)
|
||||
{
|
||||
RimSummaryCurve* newCurve = new RimSummaryCurve();
|
||||
cvf::Color3f curveColor = RicWellLogPlotCurveFeatureImpl::curveColorFromTable(plot->curveCount());
|
||||
|
||||
// Use same counting as RicNewSummaryEnsembleCurveSetFeature::onActionTriggered
|
||||
cvf::Color3f curveColor = RiaColorTables::summaryCurveDefaultPaletteColors().cycledColor3f(plot->singleColorCurveCount());
|
||||
newCurve->setColor(curveColor);
|
||||
|
||||
plot->addCurveAndUpdate(newCurve);
|
||||
|
@ -67,12 +67,8 @@ void RicNewSummaryEnsembleCurveSetFeature::onActionTriggered(bool isChecked)
|
||||
{
|
||||
RimEnsembleCurveSet* curveSet = new RimEnsembleCurveSet();
|
||||
|
||||
// Set single curve set color
|
||||
auto allCurveSets = plot->ensembleCurveSetCollection()->curveSets();
|
||||
size_t colorIndex = std::count_if(allCurveSets.begin(), allCurveSets.end(), [](RimEnsembleCurveSet* curveSet)
|
||||
{
|
||||
return curveSet->colorMode() == RimEnsembleCurveSet::SINGLE_COLOR;
|
||||
});
|
||||
// Use same counting as RicNewSummaryCurveFeature::onActionTriggered
|
||||
auto colorIndex = plot->singleColorCurveCount();
|
||||
curveSet->setColor(RiaColorTables::summaryCurveDefaultPaletteColors().cycledColor3f(colorIndex));
|
||||
curveSet->legendConfig()->setColorRange(RimEnsembleCurveSetColorManager::cycledEnsembleColorRange(static_cast<int>(colorIndex)));
|
||||
|
||||
|
@ -0,0 +1,98 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2018- Equinor 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 "RicSetSourceSteppingEnsembleCurveSetFeature.h"
|
||||
|
||||
#include "RimEnsembleCurveSet.h"
|
||||
#include "RimEnsembleCurveSetCollection.h"
|
||||
|
||||
#include "RiuPlotMainWindowTools.h"
|
||||
|
||||
#include "cafSelectionManager.h"
|
||||
|
||||
#include <QAction>
|
||||
#include "RicClearSourceSteppingEnsembleCurveSetFeature.h"
|
||||
#include "RimSummaryPlot.h"
|
||||
|
||||
CAF_CMD_SOURCE_INIT(RicSetSourceSteppingEnsembleCurveSetFeature, "RicSetSourceSteppingEnsembleCurveSetFeature");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicSetSourceSteppingEnsembleCurveSetFeature::isCommandEnabled()
|
||||
{
|
||||
std::vector<RimEnsembleCurveSet*> ensembleCurveSets;
|
||||
caf::SelectionManager::instance()->objectsByType(&ensembleCurveSets);
|
||||
|
||||
if (ensembleCurveSets.size() == 1)
|
||||
{
|
||||
auto c = ensembleCurveSets[0];
|
||||
|
||||
RimEnsembleCurveSetCollection* coll = nullptr;
|
||||
c->firstAncestorOrThisOfType(coll);
|
||||
if (coll)
|
||||
{
|
||||
if (coll->curveSetForSourceStepping() != c)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicSetSourceSteppingEnsembleCurveSetFeature::onActionTriggered(bool isChecked)
|
||||
{
|
||||
std::vector<RimEnsembleCurveSet*> objects;
|
||||
caf::SelectionManager::instance()->objectsByType(&objects);
|
||||
|
||||
if (objects.size() == 1)
|
||||
{
|
||||
auto c = objects[0];
|
||||
|
||||
RimSummaryPlot* summaryPlot = nullptr;
|
||||
c->firstAncestorOrThisOfType(summaryPlot);
|
||||
if (summaryPlot)
|
||||
{
|
||||
RicClearSourceSteppingEnsembleCurveSetFeature::clearAllSourceSteppingInSummaryPlot(summaryPlot);
|
||||
}
|
||||
|
||||
RimEnsembleCurveSetCollection* coll = nullptr;
|
||||
c->firstAncestorOrThisOfType(coll);
|
||||
if (coll)
|
||||
{
|
||||
coll->setCurveSetForSourceStepping(c);
|
||||
c->updateConnectedEditors();
|
||||
|
||||
RiuPlotMainWindowTools::refreshToolbars();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicSetSourceSteppingEnsembleCurveSetFeature::setupActionLook(QAction* actionToSetup)
|
||||
{
|
||||
actionToSetup->setText("Set as Source Stepping Curve Set");
|
||||
actionToSetup->setIcon(QIcon(":/StepUpDown16x16.png"));
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2018- Equinor 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 "cafCmdFeature.h"
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RicSetSourceSteppingEnsembleCurveSetFeature : public caf::CmdFeature
|
||||
{
|
||||
CAF_CMD_HEADER_INIT;
|
||||
|
||||
protected:
|
||||
bool isCommandEnabled() override;
|
||||
void onActionTriggered(bool isChecked) override;
|
||||
void setupActionLook(QAction* actionToSetup) override;
|
||||
};
|
@ -0,0 +1,98 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2018- Equinor 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 "RicSetSourceSteppingSummaryCurveFeature.h"
|
||||
#include "RicClearSourceSteppingEnsembleCurveSetFeature.h"
|
||||
|
||||
#include "RimSummaryCurve.h"
|
||||
#include "RimSummaryCurveCollection.h"
|
||||
#include "RimSummaryPlot.h"
|
||||
|
||||
#include "RiuPlotMainWindowTools.h"
|
||||
|
||||
#include "cafSelectionManager.h"
|
||||
|
||||
#include <QAction>
|
||||
|
||||
CAF_CMD_SOURCE_INIT(RicSetSourceSteppingSummaryCurveFeature, "RicSetSourceSteppingSummaryCurveFeature");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicSetSourceSteppingSummaryCurveFeature::isCommandEnabled()
|
||||
{
|
||||
std::vector<RimSummaryCurve*> summaryCurves;
|
||||
caf::SelectionManager::instance()->objectsByType(&summaryCurves);
|
||||
|
||||
if (summaryCurves.size() == 1)
|
||||
{
|
||||
auto c = summaryCurves[0];
|
||||
|
||||
RimSummaryCurveCollection* coll = nullptr;
|
||||
c->firstAncestorOrThisOfTypeAsserted(coll);
|
||||
if (coll)
|
||||
{
|
||||
if (coll->curveForSourceStepping() != c)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicSetSourceSteppingSummaryCurveFeature::onActionTriggered(bool isChecked)
|
||||
{
|
||||
std::vector<RimSummaryCurve*> summaryCurves;
|
||||
caf::SelectionManager::instance()->objectsByType(&summaryCurves);
|
||||
|
||||
if (summaryCurves.size() == 1)
|
||||
{
|
||||
auto c = summaryCurves[0];
|
||||
|
||||
RimSummaryPlot* summaryPlot = nullptr;
|
||||
c->firstAncestorOrThisOfType(summaryPlot);
|
||||
if (summaryPlot)
|
||||
{
|
||||
RicClearSourceSteppingEnsembleCurveSetFeature::clearAllSourceSteppingInSummaryPlot(summaryPlot);
|
||||
}
|
||||
|
||||
RimSummaryCurveCollection* coll = nullptr;
|
||||
c->firstAncestorOrThisOfTypeAsserted(coll);
|
||||
if (coll)
|
||||
{
|
||||
coll->setCurveForSourceStepping(c);
|
||||
c->updateConnectedEditors();
|
||||
|
||||
RiuPlotMainWindowTools::refreshToolbars();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicSetSourceSteppingSummaryCurveFeature::setupActionLook(QAction* actionToSetup)
|
||||
{
|
||||
actionToSetup->setText("Set as Source Stepping Curve");
|
||||
actionToSetup->setIcon(QIcon(":/StepUpDown16x16.png"));
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2018- Equinor 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 "cafCmdFeature.h"
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RicSetSourceSteppingSummaryCurveFeature : public caf::CmdFeature
|
||||
{
|
||||
CAF_CMD_HEADER_INIT;
|
||||
|
||||
protected:
|
||||
bool isCommandEnabled() override;
|
||||
void onActionTriggered(bool isChecked) override;
|
||||
void setupActionLook(QAction* actionToSetup) override;
|
||||
};
|
@ -77,6 +77,14 @@ QString RifEclipseDataTableFormatter::tableRowPrependText() const
|
||||
return m_tableRowPrependText;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RifEclipseDataTableFormatter::tableRowAppendText() const
|
||||
{
|
||||
return m_tableRowAppendText;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -93,6 +101,14 @@ void RifEclipseDataTableFormatter::setTableRowLineAppendText(const QString& text
|
||||
m_tableRowAppendText = text;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RifEclipseDataTableFormatter::commentPrefix() const
|
||||
{
|
||||
return m_commentPrefix;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -129,7 +145,7 @@ void RifEclipseDataTableFormatter::outputBuffer()
|
||||
else if (line.lineType == CONTENTS)
|
||||
{
|
||||
QString lineText = m_tableRowPrependText;
|
||||
QString appendText = (line.appendTextSet ? line.appendText : m_tableRowAppendText) + "\n";
|
||||
QString appendText = (line.appendTextSet ? line.appendText : m_tableRowAppendText);
|
||||
|
||||
for (size_t i = 0; i < line.data.size(); ++i)
|
||||
{
|
||||
@ -147,7 +163,7 @@ void RifEclipseDataTableFormatter::outputBuffer()
|
||||
lineText += column;
|
||||
}
|
||||
|
||||
m_out << lineText << appendText;
|
||||
m_out << lineText << appendText << "\n";
|
||||
}
|
||||
}
|
||||
m_columns.clear();
|
||||
@ -456,12 +472,13 @@ int RifEclipseDataTableFormatter::measure(size_t num)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RifEclipseDataTableFormatter::tableWidth() const
|
||||
{
|
||||
int characterCount = 0;
|
||||
int characterCount = m_tableRowPrependText.length();
|
||||
|
||||
for (size_t i = 0u; i < m_columns.size(); ++i)
|
||||
{
|
||||
characterCount += formatColumn(" ", i).size();
|
||||
}
|
||||
characterCount += m_tableRowAppendText.length();
|
||||
|
||||
return characterCount;
|
||||
}
|
||||
|
@ -114,8 +114,10 @@ public:
|
||||
int columnSpacing() const;
|
||||
void setColumnSpacing(int spacing);
|
||||
QString tableRowPrependText() const;
|
||||
QString tableRowAppendText() const;
|
||||
void setTableRowPrependText(const QString& text);
|
||||
void setTableRowLineAppendText(const QString& text);
|
||||
QString commentPrefix() const;
|
||||
void setCommentPrefix(const QString& commentPrefix);
|
||||
|
||||
RifEclipseDataTableFormatter& keyword(const QString& keyword);
|
||||
@ -135,6 +137,8 @@ public:
|
||||
|
||||
static void addValueTable(QTextStream& stream, const QString& keyword, size_t columns, const std::vector<double>& values);
|
||||
|
||||
int tableWidth() const;
|
||||
static int maxEclipseRowWidth();
|
||||
|
||||
private:
|
||||
int measure(const QString str);
|
||||
@ -142,9 +146,6 @@ private:
|
||||
int measure(int num);
|
||||
int measure(size_t num);
|
||||
|
||||
int tableWidth() const;
|
||||
static int maxEclipseRowWidth();
|
||||
|
||||
QString format(double num, RifEclipseOutputTableDoubleFormatting doubleFormat);
|
||||
QString format(int num);
|
||||
QString format(size_t num);
|
||||
|
@ -520,14 +520,14 @@ RifEclipseSummaryAddress RifEclipseSummaryAddress::ensembleStatisticsAddress(con
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifEclipseSummaryAddress::isDependentOnWellName(const RifEclipseSummaryAddress& address)
|
||||
bool RifEclipseSummaryAddress::isDependentOnWellName(SummaryVarCategory category)
|
||||
{
|
||||
// clang-format off
|
||||
if (address.category() == SUMMARY_WELL ||
|
||||
address.category() == SUMMARY_WELL_COMPLETION ||
|
||||
address.category() == SUMMARY_WELL_COMPLETION_LGR ||
|
||||
address.category() == SUMMARY_WELL_LGR ||
|
||||
address.category() == SUMMARY_WELL_SEGMENT)
|
||||
if (category == SUMMARY_WELL ||
|
||||
category == SUMMARY_WELL_COMPLETION ||
|
||||
category == SUMMARY_WELL_COMPLETION_LGR ||
|
||||
category == SUMMARY_WELL_LGR ||
|
||||
category == SUMMARY_WELL_SEGMENT)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ public:
|
||||
static RifEclipseSummaryAddress importedAddress(const std::string& quantityName);
|
||||
static RifEclipseSummaryAddress ensembleStatisticsAddress(const std::string& quantityName, const std::string& dataQuantityName);
|
||||
|
||||
static bool isDependentOnWellName(const RifEclipseSummaryAddress& address);
|
||||
static bool isDependentOnWellName(SummaryVarCategory category);
|
||||
|
||||
// Access methods
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "RivContourMapProjectionPartMgr.h"
|
||||
|
||||
#include "RiaColorTools.h"
|
||||
#include "RiaFontCache.h"
|
||||
#include "RiaWeightedMeanCalculator.h"
|
||||
#include "RivMeshLinesSourceInfo.h"
|
||||
#include "RivScalarMapperUtils.h"
|
||||
@ -9,11 +11,13 @@
|
||||
|
||||
#include "cafEffectGenerator.h"
|
||||
|
||||
#include "cvfDrawableText.h"
|
||||
#include "cvfGeometryBuilderFaceList.h"
|
||||
#include "cvfGeometryUtils.h"
|
||||
#include "cvfMeshEdgeExtractor.h"
|
||||
#include "cvfPart.h"
|
||||
#include "cvfPrimitiveSetIndexedUInt.h"
|
||||
#include "cvfScalarMapper.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
@ -31,6 +35,8 @@ RivContourMapProjectionPartMgr::RivContourMapProjectionPartMgr(RimContourMapProj
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivContourMapProjectionPartMgr::appendProjectionToModel(cvf::ModelBasicList* model, const caf::DisplayCoordTransform* displayCoordTransform) const
|
||||
{
|
||||
cvf::ScalarMapper* mapper = m_contourMapProjection->legendConfig()->scalarMapper();
|
||||
|
||||
cvf::ref<cvf::DrawableGeo> drawable = createProjectionMapDrawable(displayCoordTransform);
|
||||
if (drawable.notNull() && drawable->boundingBox().isValid())
|
||||
{
|
||||
@ -38,7 +44,6 @@ void RivContourMapProjectionPartMgr::appendProjectionToModel(cvf::ModelBasicList
|
||||
part->setDrawable(drawable.p());
|
||||
|
||||
cvf::ref<cvf::Vec2fArray> textureCoords = createTextureCoords();
|
||||
cvf::ScalarMapper* mapper = m_contourMapProjection->legendConfig()->scalarMapper();
|
||||
RivScalarMapperUtils::applyTextureResultsToPart(part.p(), textureCoords.p(), mapper, 1.0f, caf::FC_NONE, true, m_parentContourMap->backgroundColor());
|
||||
|
||||
part->setSourceInfo(new RivObjectSourceInfo(m_contourMapProjection.p()));
|
||||
@ -48,22 +53,34 @@ void RivContourMapProjectionPartMgr::appendProjectionToModel(cvf::ModelBasicList
|
||||
|
||||
if (m_contourMapProjection->showContourLines())
|
||||
{
|
||||
std::vector<cvf::ref<cvf::DrawableGeo>> contourDrawables = createContourPolygons(displayCoordTransform);
|
||||
for (cvf::ref<cvf::DrawableGeo> contourDrawable : contourDrawables)
|
||||
std::vector<double> tickValues;
|
||||
mapper->majorTickValues(&tickValues);
|
||||
|
||||
std::vector<std::vector<cvf::ref<cvf::Drawable>>> contourDrawablesForAllLevels = createContourPolygons(displayCoordTransform);
|
||||
for (size_t i = 0; i < contourDrawablesForAllLevels.size(); ++i)
|
||||
{
|
||||
if (contourDrawable.notNull() && contourDrawable->boundingBox().isValid())
|
||||
std::vector<cvf::ref<cvf::Drawable>> contourDrawables = contourDrawablesForAllLevels[i];
|
||||
|
||||
cvf::Color3f backgroundColor(mapper->mapToColor(tickValues[i]));
|
||||
cvf::Color3f lineColor = RiaColorTools::constrastColor(backgroundColor, true);
|
||||
|
||||
for (cvf::ref<cvf::Drawable> contourDrawable : contourDrawables)
|
||||
{
|
||||
caf::MeshEffectGenerator meshEffectGen(cvf::Color3::BLACK);
|
||||
meshEffectGen.setLineWidth(1.0f);
|
||||
meshEffectGen.createAndConfigurePolygonOffsetRenderState(caf::PO_1);
|
||||
cvf::ref<cvf::Effect> effect = meshEffectGen.generateCachedEffect();
|
||||
if (contourDrawable.notNull() && contourDrawable->boundingBox().isValid())
|
||||
{
|
||||
caf::MeshEffectGenerator meshEffectGen(lineColor);
|
||||
meshEffectGen.setLineWidth(1.0f);
|
||||
meshEffectGen.createAndConfigurePolygonOffsetRenderState(caf::PO_1);
|
||||
|
||||
cvf::ref<cvf::Part> part = new cvf::Part;
|
||||
part->setDrawable(contourDrawable.p());
|
||||
part->setEffect(effect.p());
|
||||
part->setSourceInfo(new RivMeshLinesSourceInfo(m_contourMapProjection.p()));
|
||||
cvf::ref<cvf::Effect> effect = meshEffectGen.generateCachedEffect();
|
||||
|
||||
model->addPart(part.p());
|
||||
cvf::ref<cvf::Part> part = new cvf::Part;
|
||||
part->setDrawable(contourDrawable.p());
|
||||
part->setEffect(effect.p());
|
||||
part->setSourceInfo(new RivMeshLinesSourceInfo(m_contourMapProjection.p()));
|
||||
|
||||
model->addPart(part.p());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -148,13 +165,42 @@ cvf::ref<cvf::Vec2fArray> RivContourMapProjectionPartMgr::createTextureCoords()
|
||||
return textureCoords;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::ref<cvf::DrawableText> RivContourMapProjectionPartMgr::createTextLabel(const cvf::Color3f& textColor, const cvf::Color3f& backgroundColor)
|
||||
{
|
||||
auto font = RiaFontCache::getFont(RiaFontCache::FONT_SIZE_8);
|
||||
|
||||
cvf::ref<cvf::DrawableText> labelDrawable = new cvf::DrawableText();
|
||||
labelDrawable->setFont(font.p());
|
||||
labelDrawable->setCheckPosVisible(true);
|
||||
labelDrawable->setUseDepthBuffer(true);
|
||||
labelDrawable->setDrawBorder(true);
|
||||
labelDrawable->setDrawBackground(true);
|
||||
labelDrawable->setBackgroundColor(backgroundColor);
|
||||
labelDrawable->setVerticalAlignment(cvf::TextDrawer::BASELINE);
|
||||
labelDrawable->setTextColor(textColor);
|
||||
|
||||
return labelDrawable;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::ref<cvf::DrawableGeo> RivContourMapProjectionPartMgr::createProjectionMapDrawable(const caf::DisplayCoordTransform* displayCoordTransform) const
|
||||
{
|
||||
cvf::ref<cvf::Vec3fArray> vertexArray = new cvf::Vec3fArray;
|
||||
m_contourMapProjection->generateVertices(vertexArray.p(), displayCoordTransform);
|
||||
std::vector<cvf::Vec3d> vertices = m_contourMapProjection->generateVertices();
|
||||
if (vertices.empty()) return nullptr;
|
||||
|
||||
cvf::ref<cvf::Vec3fArray> vertexArray = new cvf::Vec3fArray(vertices.size());
|
||||
|
||||
for (size_t i = 0; i < vertices.size(); ++i)
|
||||
{
|
||||
cvf::Vec3f displayVertexPos (displayCoordTransform->transformToDisplayCoord(vertices[i]));
|
||||
(*vertexArray)[i] = displayVertexPos;
|
||||
}
|
||||
|
||||
cvf::Vec2ui patchSize = m_contourMapProjection->numberOfVerticesIJ();
|
||||
|
||||
// Surface
|
||||
@ -172,33 +218,86 @@ cvf::ref<cvf::DrawableGeo> RivContourMapProjectionPartMgr::createProjectionMapDr
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<cvf::ref<cvf::DrawableGeo>> RivContourMapProjectionPartMgr::createContourPolygons(const caf::DisplayCoordTransform* displayCoordTransform) const
|
||||
std::vector<std::vector<cvf::ref<cvf::Drawable>>> RivContourMapProjectionPartMgr::createContourPolygons(const caf::DisplayCoordTransform* displayCoordTransform) const
|
||||
{
|
||||
RimContourMapProjection::ContourPolygons contourPolygons = m_contourMapProjection->generateContourPolygons(displayCoordTransform);
|
||||
m_contourMapProjection->generateContourPolygons();
|
||||
const std::vector<RimContourMapProjection::ContourPolygons>& contourPolygons = m_contourMapProjection->contourPolygons();
|
||||
|
||||
std::vector<cvf::ref<cvf::DrawableGeo>> contourDrawables;
|
||||
contourDrawables.reserve(contourPolygons.size());
|
||||
for (size_t i = 0; i < contourPolygons.size(); ++i)
|
||||
const cvf::ScalarMapper* mapper = m_contourMapProjection->legendConfig()->scalarMapper();
|
||||
std::vector<double> tickValues;
|
||||
mapper->majorTickValues(&tickValues);
|
||||
|
||||
std::vector<std::vector<cvf::ref<cvf::Drawable>>> contourDrawablesForAllLevels;
|
||||
std::vector<cvf::ref<cvf::Drawable>> labelDrawables;
|
||||
for (int64_t i = (int64_t) contourPolygons.size() - 1; i > 0; --i)
|
||||
{
|
||||
cvf::ref<cvf::Vec3fArray> vertexArray = contourPolygons[i];
|
||||
std::vector<cvf::uint> indices;
|
||||
indices.reserve(contourPolygons[i]->size());
|
||||
for (cvf::uint j = 0; j < contourPolygons[i]->size(); ++j)
|
||||
std::vector<cvf::ref<cvf::Drawable>> contourDrawables;
|
||||
|
||||
cvf::Color3f backgroundColor(mapper->mapToColor(tickValues[i]));
|
||||
cvf::Color3f textColor = RiaColorTools::constrastColor(backgroundColor);
|
||||
|
||||
for (size_t j = 0; j < contourPolygons[i].size(); ++j)
|
||||
{
|
||||
indices.push_back(j);
|
||||
if (contourPolygons[i][j].vertices.empty()) continue;
|
||||
|
||||
size_t nVertices = contourPolygons[i][j].vertices.size();
|
||||
size_t nLabels = m_contourMapProjection->showContourLabels() ? std::max((size_t)1, nVertices / 150u) : 0u;
|
||||
for (size_t l = 0; l < nLabels; ++l)
|
||||
{
|
||||
cvf::ref<cvf::DrawableText> label = createTextLabel(textColor, backgroundColor);
|
||||
cvf::Vec3f labelVertex(displayCoordTransform->transformToDisplayCoord(contourPolygons[i][j].vertices[(nVertices * l) / nLabels]));
|
||||
labelVertex.z() += 3.0f;
|
||||
label->addText(contourPolygons[i][j].label, labelVertex);
|
||||
bool overlaps = false;
|
||||
cvf::BoundingBox bbox = label->boundingBox();
|
||||
for (cvf::ref<cvf::Drawable> existingLabel : labelDrawables)
|
||||
{
|
||||
if (existingLabel->boundingBox().intersects(bbox))
|
||||
{
|
||||
overlaps = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!overlaps)
|
||||
{
|
||||
labelDrawables.push_back(label);
|
||||
}
|
||||
}
|
||||
cvf::ref<cvf::Vec3fArray> vertexArray = new cvf::Vec3fArray(nVertices);
|
||||
for (size_t v = 0; v < nVertices; v += 2)
|
||||
{
|
||||
cvf::Vec3d displayVertex1 = displayCoordTransform->transformToDisplayCoord(contourPolygons[i][j].vertices[v]);
|
||||
cvf::Vec3d displayVertex2 = displayCoordTransform->transformToDisplayCoord(contourPolygons[i][j].vertices[v + 1]);
|
||||
(*vertexArray)[v] = cvf::Vec3f(displayVertex1);
|
||||
(*vertexArray)[v + 1] = cvf::Vec3f(displayVertex2);
|
||||
}
|
||||
|
||||
std::vector<cvf::uint> indices;
|
||||
indices.reserve(vertexArray->size());
|
||||
for (cvf::uint k = 0; k < vertexArray->size(); ++k)
|
||||
{
|
||||
indices.push_back(k);
|
||||
}
|
||||
|
||||
cvf::ref<cvf::PrimitiveSetIndexedUInt> indexedUInt = new cvf::PrimitiveSetIndexedUInt(cvf::PrimitiveType::PT_LINES);
|
||||
cvf::ref<cvf::UIntArray> indexArray = new cvf::UIntArray(indices);
|
||||
indexedUInt->setIndices(indexArray.p());
|
||||
|
||||
cvf::ref<cvf::DrawableGeo> geo = new cvf::DrawableGeo;
|
||||
|
||||
geo->addPrimitiveSet(indexedUInt.p());
|
||||
geo->setVertexArray(vertexArray.p());
|
||||
contourDrawables.push_back(geo);
|
||||
}
|
||||
for (cvf::ref<cvf::Drawable> labelDrawable : labelDrawables)
|
||||
{
|
||||
contourDrawables.push_back(labelDrawable);
|
||||
}
|
||||
|
||||
cvf::ref<cvf::PrimitiveSetIndexedUInt> indexedUInt = new cvf::PrimitiveSetIndexedUInt(cvf::PrimitiveType::PT_LINES);
|
||||
cvf::ref<cvf::UIntArray> indexArray = new cvf::UIntArray(indices);
|
||||
indexedUInt->setIndices(indexArray.p());
|
||||
|
||||
cvf::ref<cvf::DrawableGeo> geo = new cvf::DrawableGeo;
|
||||
|
||||
geo->addPrimitiveSet(indexedUInt.p());
|
||||
geo->setVertexArray(vertexArray.p());
|
||||
contourDrawables.push_back(geo);
|
||||
contourDrawablesForAllLevels.push_back(contourDrawables);
|
||||
}
|
||||
return contourDrawables;
|
||||
|
||||
return contourDrawablesForAllLevels;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -207,14 +306,25 @@ std::vector<cvf::ref<cvf::DrawableGeo>> RivContourMapProjectionPartMgr::createCo
|
||||
cvf::ref<cvf::DrawableGeo>
|
||||
RivContourMapProjectionPartMgr::createPickPointVisDrawable(const caf::DisplayCoordTransform* displayCoordTransform) const
|
||||
{
|
||||
cvf::ref<cvf::DrawableGeo> geo = nullptr;
|
||||
std::vector<cvf::Vec3d> pickPointPolygon = m_contourMapProjection->generatePickPointPolygon();
|
||||
if (pickPointPolygon.empty())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
cvf::ref<cvf::Vec3fArray> vertexArray = new cvf::Vec3fArray(pickPointPolygon.size());
|
||||
|
||||
cvf::ref<cvf::Vec3fArray> pickPointPolygon = m_contourMapProjection->generatePickPointPolygon(displayCoordTransform);
|
||||
if (pickPointPolygon.notNull() && pickPointPolygon->size() > 0u)
|
||||
for (size_t i = 0; i < pickPointPolygon.size(); ++i)
|
||||
{
|
||||
cvf::Vec3f displayPoint(displayCoordTransform->transformToDisplayCoord(pickPointPolygon[i]));
|
||||
(*vertexArray)[i] = displayPoint;
|
||||
}
|
||||
|
||||
cvf::ref<cvf::DrawableGeo> geo = nullptr;
|
||||
if (vertexArray->size() > 0u)
|
||||
{
|
||||
std::vector<cvf::uint> indices;
|
||||
indices.reserve(pickPointPolygon->size());
|
||||
for (cvf::uint j = 0; j < pickPointPolygon->size(); ++j)
|
||||
indices.reserve(vertexArray->size());
|
||||
for (cvf::uint j = 0; j < vertexArray->size(); ++j)
|
||||
{
|
||||
indices.push_back(j);
|
||||
}
|
||||
@ -226,7 +336,7 @@ cvf::ref<cvf::DrawableGeo>
|
||||
geo = new cvf::DrawableGeo;
|
||||
|
||||
geo->addPrimitiveSet(indexedUInt.p());
|
||||
geo->setVertexArray(pickPointPolygon.p());
|
||||
geo->setVertexArray(vertexArray.p());
|
||||
}
|
||||
return geo;
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfDrawableGeo.h"
|
||||
#include "cvfDrawableText.h"
|
||||
#include "cvfModelBasicList.h"
|
||||
#include "cvfObject.h"
|
||||
|
||||
@ -42,11 +43,12 @@ public:
|
||||
cvf::ref<cvf::Vec2fArray> createTextureCoords() const;
|
||||
|
||||
private:
|
||||
cvf::ref<cvf::DrawableGeo> createProjectionMapDrawable(const caf::DisplayCoordTransform* displayCoordTransform) const;
|
||||
std::vector<cvf::ref<cvf::DrawableGeo>> createContourPolygons(const caf::DisplayCoordTransform* displayCoordTransform) const;
|
||||
cvf::ref<cvf::DrawableGeo> createPickPointVisDrawable(const caf::DisplayCoordTransform* displayCoordTransform) const;
|
||||
static cvf::ref<cvf::DrawableText> createTextLabel(const cvf::Color3f& textColor, const cvf::Color3f& backgroundColor);
|
||||
cvf::ref<cvf::DrawableGeo> createProjectionMapDrawable(const caf::DisplayCoordTransform* displayCoordTransform) const;
|
||||
std::vector<std::vector<cvf::ref<cvf::Drawable>>> createContourPolygons(const caf::DisplayCoordTransform* displayCoordTransform) const;
|
||||
cvf::ref<cvf::DrawableGeo> createPickPointVisDrawable(const caf::DisplayCoordTransform* displayCoordTransform) const;
|
||||
private:
|
||||
caf::PdmPointer<RimContourMapProjection> m_contourMapProjection;
|
||||
caf::PdmPointer<RimContourMapView> m_parentContourMap;
|
||||
caf::PdmPointer<RimContourMapProjection> m_contourMapProjection;
|
||||
caf::PdmPointer<RimContourMapView> m_parentContourMap;
|
||||
};
|
||||
|
||||
|
@ -98,6 +98,7 @@ RimFishbonesMultipleSubs::RimFishbonesMultipleSubs()
|
||||
initialiseObsoleteFields();
|
||||
CAF_PDM_InitFieldNoDefault(&m_valveLocations, "ValveLocations", "Valve Locations", "", "", "");
|
||||
m_valveLocations = new RimMultipleValveLocations();
|
||||
m_valveLocations->findField("RangeValveCount")->uiCapability()->setUiName("Number of Subs");
|
||||
m_valveLocations.uiCapability()->setUiHidden(true);
|
||||
m_valveLocations.uiCapability()->setUiTreeChildrenHidden(true);
|
||||
|
||||
|
@ -36,7 +36,7 @@ namespace caf {
|
||||
template<>
|
||||
void AppEnum<RimMultipleValveLocations::LocationType>::setUp()
|
||||
{
|
||||
addItem(RimMultipleValveLocations::VALVE_COUNT, "VALVE_COUNT", "Start/End/Number of Valves");
|
||||
addItem(RimMultipleValveLocations::VALVE_COUNT, "VALVE_COUNT", "Start/End/Number");
|
||||
addItem(RimMultipleValveLocations::VALVE_SPACING, "VALVE_SPACING", "Start/End/Spacing");
|
||||
addItem(RimMultipleValveLocations::VALVE_CUSTOM, "VALVE_CUSTOM", "User Specification");
|
||||
setDefault(RimMultipleValveLocations::VALVE_COUNT);
|
||||
|
@ -237,6 +237,15 @@ void RimWellPathCompletions::setUnitSystemSpecificDefaults()
|
||||
m_perforationCollection->setUnitSystemSpecificDefaults();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QRegExp RimWellPathCompletions::wellNameForExportRegExp()
|
||||
{
|
||||
QRegExp rx("[\\w\\-\\_]{1,8}");
|
||||
return rx;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -295,9 +304,8 @@ void RimWellPathCompletions::defineEditorAttribute(const caf::PdmFieldHandle* fi
|
||||
caf::PdmUiLineEditorAttribute* lineEditorAttr = dynamic_cast<caf::PdmUiLineEditorAttribute*>(attribute);
|
||||
if (field == &m_wellNameForExport && lineEditorAttr)
|
||||
{
|
||||
QRegExp rx("[\\w\\-\\_]{1,8}");
|
||||
QRegExpValidator* validator = new QRegExpValidator(nullptr);
|
||||
validator->setRegExp(rx);
|
||||
validator->setRegExp(wellNameForExportRegExp());
|
||||
lineEditorAttr->validator = validator;
|
||||
}
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ public:
|
||||
bool hasCompletions() const;
|
||||
|
||||
void setUnitSystemSpecificDefaults();
|
||||
|
||||
static QRegExp wellNameForExportRegExp();
|
||||
protected:
|
||||
void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName) override;
|
||||
void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
|
||||
|
@ -486,12 +486,16 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection()
|
||||
{
|
||||
menuBuilder << "RicPasteSummaryCurveFeature";
|
||||
menuBuilder << "RicPasteSummaryCrossPlotCurveFeature";
|
||||
|
||||
menuBuilder << "Separator";
|
||||
menuBuilder << "RicNewSummaryCurveFeature";
|
||||
menuBuilder << "RicDuplicateSummaryCurveFeature";
|
||||
menuBuilder << "RicNewSummaryCrossPlotCurveFeature";
|
||||
menuBuilder << "RicDuplicateSummaryCrossPlotCurveFeature";
|
||||
menuBuilder << "Separator";
|
||||
menuBuilder << "RicSetSourceSteppingSummaryCurveFeature";
|
||||
menuBuilder << "RicClearSourceSteppingSummaryCurveFeature";
|
||||
menuBuilder << "Separator";
|
||||
menuBuilder << "RicCopyReferencesToClipboardFeature";
|
||||
menuBuilder << "Separator";
|
||||
menuBuilder << "RicEditSummaryCurveCalculationFeature";
|
||||
@ -513,6 +517,9 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection()
|
||||
else if (dynamic_cast<RimEnsembleCurveSet*>(uiItem))
|
||||
{
|
||||
menuBuilder << "RicNewSummaryEnsembleCurveSetFeature";
|
||||
menuBuilder << "Separator";
|
||||
menuBuilder << "RicSetSourceSteppingEnsembleCurveSetFeature";
|
||||
menuBuilder << "RicClearSourceSteppingEnsembleCurveSetFeature";
|
||||
}
|
||||
else if (dynamic_cast<RimEnsembleCurveFilterCollection*>(uiItem))
|
||||
{
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "RimEclipseResultDefinition.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimRegularLegendConfig.h"
|
||||
#include "RimTextAnnotation.h"
|
||||
|
||||
#include "cafContourLines.h"
|
||||
#include "cafPdmUiDoubleSliderEditor.h"
|
||||
@ -77,6 +78,7 @@ RimContourMapProjection::RimContourMapProjection()
|
||||
CAF_PDM_InitFieldNoDefault(&m_resultAggregation, "ResultAggregation", "Result Aggregation", "", "", "");
|
||||
|
||||
CAF_PDM_InitField(&m_showContourLines, "ContourLines", true, "Show Contour Lines", "", "", "");
|
||||
CAF_PDM_InitField(&m_showContourLabels, "ContourLabels", false, "Show Contour Labels", "", "", "");
|
||||
|
||||
CAF_PDM_InitField(&m_weightByParameter, "WeightByParameter", false, "Weight by Result Parameter", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&m_weightingResult, "WeightingResult", "", "", "", "");
|
||||
@ -84,6 +86,7 @@ RimContourMapProjection::RimContourMapProjection()
|
||||
m_weightingResult.uiCapability()->setUiTreeChildrenHidden(true);
|
||||
m_weightingResult = new RimEclipseResultDefinition;
|
||||
m_weightingResult->findField("MResultType")->uiCapability()->setUiName("Result Type");
|
||||
|
||||
setName("Map Projection");
|
||||
nameField()->uiCapability()->setUiReadOnly(true);
|
||||
|
||||
@ -102,11 +105,10 @@ RimContourMapProjection::~RimContourMapProjection()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimContourMapProjection::generateVertices(cvf::Vec3fArray* vertices, const caf::DisplayCoordTransform* displayCoordTransform)
|
||||
std::vector<cvf::Vec3d> RimContourMapProjection::generateVertices()
|
||||
{
|
||||
CVF_ASSERT(vertices);
|
||||
size_t nVertices = numberOfVertices();
|
||||
vertices->resize(nVertices);
|
||||
std::vector<cvf::Vec3d> vertices(nVertices, cvf::Vec3d::ZERO);
|
||||
|
||||
#pragma omp parallel for
|
||||
for (int index = 0; index < static_cast<int>(nVertices); ++index)
|
||||
@ -117,10 +119,10 @@ void RimContourMapProjection::generateVertices(cvf::Vec3fArray* vertices, const
|
||||
globalPos.x() -= m_sampleSpacing * 0.5;
|
||||
globalPos.y() -= m_sampleSpacing * 0.5;
|
||||
|
||||
cvf::Vec3d globalVertexPos(globalPos, m_fullBoundingBox.min().z() - 1.0);
|
||||
cvf::Vec3f displayVertexPos(displayCoordTransform->transformToDisplayCoord(globalVertexPos));
|
||||
(*vertices)[index] = displayVertexPos;
|
||||
cvf::Vec3d globalVertexPos(globalPos, m_fullBoundingBox.min().z());
|
||||
vertices[index] = globalVertexPos;
|
||||
}
|
||||
return vertices;
|
||||
}
|
||||
|
||||
|
||||
@ -128,9 +130,10 @@ void RimContourMapProjection::generateVertices(cvf::Vec3fArray* vertices, const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimContourMapProjection::ContourPolygons RimContourMapProjection::generateContourPolygons(const caf::DisplayCoordTransform* displayCoordTransform)
|
||||
void RimContourMapProjection::generateContourPolygons()
|
||||
{
|
||||
std::vector<cvf::ref<cvf::Vec3fArray>> contourPolygons;
|
||||
std::vector<ContourPolygons> contourPolygons;
|
||||
|
||||
if (minValue() != std::numeric_limits<double>::infinity() &&
|
||||
maxValue() != -std::numeric_limits<double>::infinity() &&
|
||||
std::fabs(maxValue() - minValue()) > 1.0e-8)
|
||||
@ -142,49 +145,51 @@ RimContourMapProjection::ContourPolygons RimContourMapProjection::generateContou
|
||||
int nContourLevels = static_cast<int>(contourLevels.size());
|
||||
if (nContourLevels > 2)
|
||||
{
|
||||
std::vector<double> fudgedContourLevels = contourLevels;
|
||||
if (legendConfig()->mappingMode() == RimRegularLegendConfig::LINEAR_CONTINUOUS || legendConfig()->mappingMode() == RimRegularLegendConfig::LINEAR_DISCRETE)
|
||||
{
|
||||
// Slight fudge to avoid very jagged contour lines at the very edge
|
||||
// Shift the contour levels inwards.
|
||||
contourLevels[0] += (contourLevels[1] - contourLevels[0]) * 0.1;
|
||||
contourLevels[nContourLevels - 1] -= (contourLevels[nContourLevels - 1] - contourLevels[nContourLevels - 2]) * 0.1;
|
||||
fudgedContourLevels[0] += (contourLevels[1] - contourLevels[0]) * 0.1;
|
||||
fudgedContourLevels[nContourLevels - 1] -= (contourLevels[nContourLevels - 1] - contourLevels[nContourLevels - 2]) * 0.1;
|
||||
}
|
||||
std::vector<std::vector<cvf::Vec2d>> contourLines;
|
||||
caf::ContourLines::create(m_aggregatedVertexResults, xVertexPositions(), yVertexPositions(), contourLevels, &contourLines);
|
||||
std::vector<caf::ContourLines::ClosedPolygons> closedContourLines =
|
||||
caf::ContourLines::create(m_aggregatedVertexResults, xVertexPositions(), yVertexPositions(), fudgedContourLevels);
|
||||
|
||||
contourPolygons.reserve(contourLines.size());
|
||||
for (size_t i = 0; i < contourLines.size(); ++i)
|
||||
contourPolygons.resize(closedContourLines.size());
|
||||
for (size_t i = 0; i < closedContourLines.size(); ++i)
|
||||
{
|
||||
if (!contourLines[i].empty())
|
||||
for (size_t j = 0; j < closedContourLines[i].size(); ++j)
|
||||
{
|
||||
cvf::ref<cvf::Vec3fArray> contourPolygon = new cvf::Vec3fArray(contourLines[i].size());
|
||||
for (size_t j = 0; j < contourLines[i].size(); ++j)
|
||||
ContourPolygon contourPolygon;
|
||||
contourPolygon.label = cvf::String(contourLevels[i]);
|
||||
contourPolygon.vertices.reserve(closedContourLines[i][j].size());
|
||||
for (size_t k = 0; k < closedContourLines[i][j].size(); ++k)
|
||||
{
|
||||
cvf::Vec3d contourPoint3d = cvf::Vec3d(contourLines[i][j], m_fullBoundingBox.min().z());
|
||||
cvf::Vec3d displayPoint3d = displayCoordTransform->transformToDisplayCoord(contourPoint3d);
|
||||
(*contourPolygon)[j] = cvf::Vec3f(displayPoint3d);
|
||||
cvf::Vec3d contourPoint3d = cvf::Vec3d(closedContourLines[i][j][k], m_fullBoundingBox.min().z());
|
||||
contourPolygon.vertices.push_back(contourPoint3d);
|
||||
}
|
||||
contourPolygons.push_back(contourPolygon);
|
||||
contourPolygons[i].push_back(contourPolygon);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return contourPolygons;
|
||||
m_contourPolygons = contourPolygons;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::ref<cvf::Vec3fArray>
|
||||
RimContourMapProjection::generatePickPointPolygon(const caf::DisplayCoordTransform* displayCoordTransform)
|
||||
std::vector<cvf::Vec3d>
|
||||
RimContourMapProjection::generatePickPointPolygon()
|
||||
{
|
||||
cvf::ref<cvf::Vec3fArray> pickPolygon;
|
||||
std::vector<cvf::Vec3d> points;
|
||||
|
||||
if (!m_pickPoint.isUndefined())
|
||||
{
|
||||
double zPos = m_fullBoundingBox.min().z();
|
||||
|
||||
std::vector<cvf::Vec3d> points;
|
||||
{
|
||||
cvf::Vec2d gridorigin(m_fullBoundingBox.min().x(), m_fullBoundingBox.min().y());
|
||||
|
||||
@ -209,16 +214,8 @@ RimContourMapProjection::generatePickPointPolygon(const caf::DisplayCoordTransfo
|
||||
points.push_back(cvf::Vec3d(m_pickPoint - cvf::Vec2d(0.0, 0.5 * m_sampleSpacing), zPos));
|
||||
points.push_back(cvf::Vec3d(m_pickPoint + cvf::Vec2d(0.0, 0.5 * m_sampleSpacing), zPos));
|
||||
}
|
||||
|
||||
pickPolygon = new cvf::Vec3fArray(points.size());
|
||||
|
||||
for (size_t i = 0; i < points.size(); ++i)
|
||||
{
|
||||
cvf::Vec3d displayPoint = displayCoordTransform->transformToDisplayCoord(points[i]);
|
||||
(*pickPolygon)[i] = cvf::Vec3f(displayPoint);
|
||||
}
|
||||
}
|
||||
return pickPolygon;
|
||||
return points;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -285,6 +282,14 @@ void RimContourMapProjection::generateResults()
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const std::vector<RimContourMapProjection::ContourPolygons>& RimContourMapProjection::contourPolygons() const
|
||||
{
|
||||
return m_contourPolygons;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -317,6 +322,14 @@ bool RimContourMapProjection::showContourLines() const
|
||||
return m_showContourLines();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimContourMapProjection::showContourLabels() const
|
||||
{
|
||||
return m_showContourLines() && m_showContourLabels();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -659,6 +672,8 @@ void RimContourMapProjection::defineUiOrdering(QString uiConfigName, caf::PdmUiO
|
||||
caf::PdmUiGroup* mainGroup = uiOrdering.addNewGroup("Projection Settings");
|
||||
mainGroup->add(&m_relativeSampleSpacing);
|
||||
mainGroup->add(&m_showContourLines);
|
||||
mainGroup->add(&m_showContourLabels);
|
||||
m_showContourLabels.uiCapability()->setUiReadOnly(!m_showContourLines());
|
||||
mainGroup->add(&m_resultAggregation);
|
||||
|
||||
caf::PdmUiGroup* weightingGroup = uiOrdering.addNewGroup("Mean Weighting Options");
|
||||
@ -1314,6 +1329,7 @@ void RimContourMapProjection::updateGridInformation()
|
||||
m_mainGrid = eclipseCase()->eclipseCaseData()->mainGrid();
|
||||
m_sampleSpacing = m_relativeSampleSpacing * m_mainGrid->characteristicIJCellSize();
|
||||
m_fullBoundingBox = eclipseCase()->activeCellsBoundingBox();
|
||||
m_fullBoundingBox.expand(m_sampleSpacing * 2.0);
|
||||
m_mapSize = calculateMapSize();
|
||||
|
||||
// Re-jig max point to be an exact multiple of cell size
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
#include "cvfBoundingBox.h"
|
||||
#include "cvfGeometryBuilderFaceList.h"
|
||||
#include "cvfString.h"
|
||||
#include "cvfVector2.h"
|
||||
|
||||
class RigMainGrid;
|
||||
@ -45,6 +46,12 @@ class RimContourMapProjection : public RimCheckableNamedObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
public:
|
||||
struct ContourPolygon
|
||||
{
|
||||
std::vector<cvf::Vec3d> vertices;
|
||||
cvf::String label;
|
||||
};
|
||||
|
||||
enum ResultAggregationEnum
|
||||
{
|
||||
RESULTS_TOP_VALUE,
|
||||
@ -60,49 +67,52 @@ public:
|
||||
RESULTS_HC_COLUMN
|
||||
};
|
||||
typedef caf::AppEnum<ResultAggregationEnum> ResultAggregation;
|
||||
typedef std::vector<cvf::ref<cvf::Vec3fArray>> ContourPolygons;
|
||||
typedef std::vector<ContourPolygon> ContourPolygons;
|
||||
|
||||
RimContourMapProjection();
|
||||
~RimContourMapProjection() override;
|
||||
|
||||
void generateVertices(cvf::Vec3fArray* vertices, const caf::DisplayCoordTransform* displayCoordTransform);
|
||||
ContourPolygons generateContourPolygons(const caf::DisplayCoordTransform* displayCoordTransform);
|
||||
cvf::ref<cvf::Vec3fArray> generatePickPointPolygon(const caf::DisplayCoordTransform* displayCoordTransform);
|
||||
void generateResults();
|
||||
std::vector<cvf::Vec3d> generateVertices();
|
||||
void generateContourPolygons();
|
||||
std::vector<cvf::Vec3d> generatePickPointPolygon();
|
||||
void generateResults();
|
||||
|
||||
ResultAggregation resultAggregation() const;
|
||||
double sampleSpacing() const;
|
||||
double sampleSpacingFactor() const;
|
||||
bool showContourLines() const;
|
||||
const std::vector<ContourPolygons>& contourPolygons() const;
|
||||
|
||||
QString resultAggregationText() const;
|
||||
QString resultDescriptionText() const;
|
||||
QString weightingParameter() const;
|
||||
ResultAggregation resultAggregation() const;
|
||||
double sampleSpacing() const;
|
||||
double sampleSpacingFactor() const;
|
||||
bool showContourLines() const;
|
||||
bool showContourLabels() const;
|
||||
|
||||
double maxValue() const;
|
||||
double minValue() const;
|
||||
double meanValue() const;
|
||||
double sumAllValues() const;
|
||||
QString resultAggregationText() const;
|
||||
QString resultDescriptionText() const;
|
||||
QString weightingParameter() const;
|
||||
|
||||
cvf::Vec2ui numberOfElementsIJ() const;
|
||||
cvf::Vec2ui numberOfVerticesIJ() const;
|
||||
double maxValue() const;
|
||||
double minValue() const;
|
||||
double meanValue() const;
|
||||
double sumAllValues() const;
|
||||
|
||||
bool isColumnResult() const;
|
||||
cvf::Vec2ui numberOfElementsIJ() const;
|
||||
cvf::Vec2ui numberOfVerticesIJ() const;
|
||||
|
||||
double valueAtVertex(uint i, uint j) const;
|
||||
bool hasResultAtVertex(uint i, uint j) const;
|
||||
bool isColumnResult() const;
|
||||
|
||||
RimRegularLegendConfig* legendConfig() const;
|
||||
void updateLegend();
|
||||
double valueAtVertex(uint i, uint j) const;
|
||||
bool hasResultAtVertex(uint i, uint j) const;
|
||||
|
||||
uint numberOfCells() const;
|
||||
uint numberOfValidCells() const;
|
||||
size_t numberOfVertices() const;
|
||||
RimRegularLegendConfig* legendConfig() const;
|
||||
void updateLegend();
|
||||
|
||||
void updatedWeightingResult();
|
||||
uint numberOfCells() const;
|
||||
uint numberOfValidCells() const;
|
||||
size_t numberOfVertices() const;
|
||||
|
||||
bool checkForMapIntersection(const cvf::Vec3d& localPoint3d, cvf::Vec2d* contourMapPoint, cvf::Vec2ui* contourMapCell, double* valueAtPoint) const;
|
||||
void setPickPoint(cvf::Vec2d pickedPoint);
|
||||
void updatedWeightingResult();
|
||||
|
||||
bool checkForMapIntersection(const cvf::Vec3d& localPoint3d, cvf::Vec2d* contourMapPoint, cvf::Vec2ui* contourMapCell, double* valueAtPoint) const;
|
||||
void setPickPoint(cvf::Vec2d pickedPoint);
|
||||
|
||||
protected:
|
||||
void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
|
||||
@ -159,8 +169,10 @@ protected:
|
||||
caf::PdmField<double> m_relativeSampleSpacing;
|
||||
caf::PdmField<ResultAggregation> m_resultAggregation;
|
||||
caf::PdmField<bool> m_showContourLines;
|
||||
caf::PdmField<bool> m_showContourLabels;
|
||||
caf::PdmField<bool> m_weightByParameter;
|
||||
caf::PdmChildField<RimEclipseResultDefinition*> m_weightingResult;
|
||||
|
||||
cvf::ref<cvf::UByteArray> m_cellGridIdxVisibility;
|
||||
|
||||
std::vector<double> m_aggregatedResults;
|
||||
@ -177,4 +189,5 @@ protected:
|
||||
cvf::Vec2ui m_mapSize;
|
||||
cvf::BoundingBox m_fullBoundingBox;
|
||||
double m_sampleSpacing;
|
||||
std::vector<ContourPolygons> m_contourPolygons;
|
||||
};
|
||||
|
@ -242,7 +242,6 @@ void RimEclipseResultCase::reloadEclipseGridFile()
|
||||
{
|
||||
m_gridAndWellDataIsReadFromFile = false;
|
||||
m_activeCellInfoIsReadFromFile = false;
|
||||
m_timeStepFilter->reset();
|
||||
setReservoirData(nullptr);
|
||||
openReserviorCase();
|
||||
}
|
||||
|
@ -181,21 +181,6 @@ bool RimTimeStepFilter::updateFilteredTimeStepsFromUi()
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimTimeStepFilter::reset()
|
||||
{
|
||||
m_filterType = TS_ALL;
|
||||
m_filteredTimeSteps.v().clear();
|
||||
m_filteredTimeStepsUi.v().clear();
|
||||
m_firstTimeStep = 0;
|
||||
m_lastTimeStep = 0;
|
||||
m_interval = 1;
|
||||
m_dateFormat = QString("yyyy-MM-dd");
|
||||
m_timeStepNamesFromFile.v().clear();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -52,9 +52,6 @@ public:
|
||||
void setTimeStepsFromFile(const std::vector<std::pair<QString, QDateTime>>& timeSteps);
|
||||
std::vector<size_t> filteredTimeSteps() const;
|
||||
bool updateFilteredTimeStepsFromUi();
|
||||
|
||||
void reset();
|
||||
|
||||
private:
|
||||
std::vector<std::pair<QString, QDateTime>> allTimeSteps() const;
|
||||
std::vector<int> filteredTimeStepIndicesFromUi() const;
|
||||
|
@ -660,6 +660,25 @@ void RimEnsembleCurveSet::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrd
|
||||
}
|
||||
|
||||
uiTreeOrdering.skipRemainingChildren(true);
|
||||
|
||||
// Reset dynamic icon
|
||||
this->setUiIcon(QIcon());
|
||||
// Get static one
|
||||
QIcon icon = this->uiIcon();
|
||||
|
||||
RimEnsembleCurveSetCollection* coll = nullptr;
|
||||
this->firstAncestorOrThisOfType(coll);
|
||||
if (coll && coll->curveSetForSourceStepping() == this)
|
||||
{
|
||||
QPixmap combined = icon.pixmap(16, 16);
|
||||
QPainter painter(&combined);
|
||||
QPixmap updownpixmap(":/StepUpDownCorner16x16.png");
|
||||
painter.drawPixmap(0,0,updownpixmap);
|
||||
|
||||
icon = QIcon(combined);
|
||||
}
|
||||
|
||||
this->setUiIcon(icon);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "RiaApplication.h"
|
||||
#include "RiaColorTables.h"
|
||||
#include "RiaStdStringTools.h"
|
||||
|
||||
#include "RifReaderEclipseSummary.h"
|
||||
|
||||
@ -50,6 +51,13 @@ RimEnsembleCurveSetCollection::RimEnsembleCurveSetCollection()
|
||||
|
||||
CAF_PDM_InitField(&m_showCurves, "IsActive", true, "Show Curves", "", "", "");
|
||||
m_showCurves.uiCapability()->setUiHidden(true);
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_ySourceStepping, "YSourceStepping", "", "", "", "");
|
||||
m_ySourceStepping = new RimSummaryPlotSourceStepping;
|
||||
m_ySourceStepping->setSourceSteppingType(RimSummaryPlotSourceStepping::Y_AXIS);
|
||||
m_ySourceStepping.uiCapability()->setUiHidden(true);
|
||||
m_ySourceStepping.uiCapability()->setUiTreeChildrenHidden(true);
|
||||
m_ySourceStepping.xmlCapability()->disableIO();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -193,6 +201,80 @@ size_t RimEnsembleCurveSetCollection::curveSetCount() const
|
||||
return m_curveSets.size();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<caf::PdmFieldHandle*> RimEnsembleCurveSetCollection::fieldsToShowInToolbar()
|
||||
{
|
||||
if (m_ySourceStepping)
|
||||
{
|
||||
return m_ySourceStepping->fieldsToShowInToolbar();
|
||||
}
|
||||
|
||||
return std::vector<caf::PdmFieldHandle*>();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEnsembleCurveSetCollection::setCurveSetForSourceStepping(RimEnsembleCurveSet* curveSet)
|
||||
{
|
||||
m_curveSetForSourceStepping = curveSet;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimEnsembleCurveSet* RimEnsembleCurveSetCollection::curveSetForSourceStepping() const
|
||||
{
|
||||
return m_curveSetForSourceStepping;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimEnsembleCurveSet*> RimEnsembleCurveSetCollection::curveSetsForSourceStepping() const
|
||||
{
|
||||
std::vector<RimEnsembleCurveSet*> steppingCurveSets;
|
||||
|
||||
if (m_curveSetForSourceStepping)
|
||||
{
|
||||
steppingCurveSets.push_back(m_curveSetForSourceStepping);
|
||||
|
||||
{
|
||||
// Add corresponding history/summary curve with or without H
|
||||
|
||||
const std::string historyIdentifier = "H";
|
||||
|
||||
std::string quantity = m_curveSetForSourceStepping->summaryAddress().quantityName();
|
||||
|
||||
std::string candidateName;
|
||||
if (RiaStdStringTools::endsWith(quantity, historyIdentifier))
|
||||
{
|
||||
candidateName = quantity.substr(0, quantity.size() - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
candidateName = quantity + historyIdentifier;
|
||||
}
|
||||
|
||||
for (const auto& c : curveSets())
|
||||
{
|
||||
if (c->summaryAddress().quantityName() == candidateName)
|
||||
{
|
||||
steppingCurveSets.push_back(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
steppingCurveSets = curveSets();
|
||||
}
|
||||
|
||||
return steppingCurveSets;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -228,6 +310,16 @@ void RimEnsembleCurveSetCollection::fieldChangedByUi(const caf::PdmFieldHandle*
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEnsembleCurveSetCollection::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
|
||||
{
|
||||
auto group = uiOrdering.addNewGroup("Data Source");
|
||||
|
||||
m_ySourceStepping()->uiOrdering(uiConfigName, *group);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
class RimEnsembleCurveSet;
|
||||
class RimSummaryPlotSourceStepping;
|
||||
class RimSummaryCurve;
|
||||
class QwtPlot;
|
||||
class QwtPlotCurve;
|
||||
|
||||
@ -55,9 +57,16 @@ public:
|
||||
std::vector<RimEnsembleCurveSet*> curveSets() const;
|
||||
size_t curveSetCount() const;
|
||||
|
||||
|
||||
void deleteAllCurveSets();
|
||||
|
||||
void setCurrentSummaryCurveSet(RimEnsembleCurveSet* curveSet);
|
||||
|
||||
// Functions related to source stepping
|
||||
std::vector<caf::PdmFieldHandle*> fieldsToShowInToolbar();
|
||||
void setCurveSetForSourceStepping(RimEnsembleCurveSet* curve);
|
||||
RimEnsembleCurveSet* curveSetForSourceStepping() const;
|
||||
std::vector<RimEnsembleCurveSet*> curveSetsForSourceStepping() const;
|
||||
|
||||
private:
|
||||
caf::PdmFieldHandle* objectToggleField() override;
|
||||
@ -65,10 +74,15 @@ private:
|
||||
void fieldChangedByUi(const caf::PdmFieldHandle* changedField,
|
||||
const QVariant& oldValue, const QVariant& newValue) override;
|
||||
|
||||
void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
|
||||
|
||||
private:
|
||||
caf::PdmField<bool> m_showCurves;
|
||||
caf::PdmChildArrayField<RimEnsembleCurveSet*> m_curveSets;
|
||||
|
||||
caf::PdmChildField<RimSummaryPlotSourceStepping*> m_ySourceStepping;
|
||||
|
||||
caf::PdmPointer<RimEnsembleCurveSet> m_currentEnsembleCurveSet;
|
||||
caf::PdmPointer<RimEnsembleCurveSet> m_curveSetForSourceStepping;
|
||||
};
|
||||
|
||||
|
@ -565,6 +565,33 @@ void RimSummaryCurve::updateLegendsInPlot()
|
||||
plot->updateAllLegendItems();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSummaryCurve::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/)
|
||||
{
|
||||
RimPlotCurve::defineUiTreeOrdering(uiTreeOrdering, uiConfigName);
|
||||
|
||||
// Reset dynamic icon
|
||||
this->setUiIcon(QIcon());
|
||||
// Get static one
|
||||
QIcon icon = this->uiIcon();
|
||||
|
||||
RimSummaryCurveCollection* coll = nullptr;
|
||||
this->firstAncestorOrThisOfType(coll);
|
||||
if (coll && coll->curveForSourceStepping() == this)
|
||||
{
|
||||
QPixmap combined = icon.pixmap(16, 16);
|
||||
QPainter painter(&combined);
|
||||
QPixmap updownpixmap(":/StepUpDownCorner16x16.png");
|
||||
painter.drawPixmap(0,0,updownpixmap);
|
||||
|
||||
icon = QIcon(combined);
|
||||
}
|
||||
|
||||
this->setUiIcon(icon);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -93,6 +93,9 @@ protected:
|
||||
|
||||
void updateLegendsInPlot() override;
|
||||
|
||||
|
||||
void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override;
|
||||
|
||||
private:
|
||||
RifSummaryReaderInterface* valuesSummaryReaderX() const;
|
||||
RifSummaryReaderInterface* valuesSummaryReaderY() const;
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "RimSummaryCurveCollection.h"
|
||||
|
||||
#include "RiaApplication.h"
|
||||
#include "RiaStdStringTools.h"
|
||||
|
||||
#include "RifReaderEclipseSummary.h"
|
||||
|
||||
@ -192,6 +193,72 @@ std::vector<RimSummaryCurve*> RimSummaryCurveCollection::curves() const
|
||||
return m_curves.childObjects();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimSummaryCurve*> RimSummaryCurveCollection::curvesForSourceStepping(RimSummaryPlotSourceStepping::SourceSteppingType steppingType) const
|
||||
{
|
||||
std::vector<RimSummaryCurve*> stepCurves;
|
||||
|
||||
if (m_curveForSourceStepping)
|
||||
{
|
||||
stepCurves.push_back(m_curveForSourceStepping);
|
||||
|
||||
{
|
||||
// Add corresponding history/summary curve with or without H
|
||||
|
||||
const std::string historyIdentifier = "H";
|
||||
|
||||
std::string quantity;
|
||||
|
||||
if (steppingType == RimSummaryPlotSourceStepping::X_AXIS)
|
||||
{
|
||||
quantity = m_curveForSourceStepping->summaryAddressX().quantityName();
|
||||
}
|
||||
else if (steppingType == RimSummaryPlotSourceStepping::Y_AXIS)
|
||||
{
|
||||
quantity = m_curveForSourceStepping->summaryAddressY().quantityName();
|
||||
}
|
||||
|
||||
std::string candidateName;
|
||||
if (RiaStdStringTools::endsWith(quantity, historyIdentifier))
|
||||
{
|
||||
candidateName = quantity.substr(0, quantity.size() - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
candidateName = quantity + historyIdentifier;
|
||||
}
|
||||
|
||||
for (const auto& c : curves())
|
||||
{
|
||||
if (steppingType == RimSummaryPlotSourceStepping::X_AXIS)
|
||||
{
|
||||
if (c->summaryCaseX() == m_curveForSourceStepping->summaryCaseX() &&
|
||||
c->summaryAddressX().quantityName() == candidateName)
|
||||
{
|
||||
stepCurves.push_back(c);
|
||||
}
|
||||
}
|
||||
else if (steppingType == RimSummaryPlotSourceStepping::Y_AXIS)
|
||||
{
|
||||
if (c->summaryCaseY() == m_curveForSourceStepping->summaryCaseY() &&
|
||||
c->summaryAddressY().quantityName() == candidateName)
|
||||
{
|
||||
stepCurves.push_back(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stepCurves = curves();
|
||||
}
|
||||
|
||||
return stepCurves;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -355,6 +422,22 @@ void RimSummaryCurveCollection::setCurveAsTopZWithinCategory(RimSummaryCurve* cu
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSummaryCurveCollection::setCurveForSourceStepping(RimSummaryCurve* curve)
|
||||
{
|
||||
m_curveForSourceStepping = curve;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSummaryCurve* RimSummaryCurveCollection::curveForSourceStepping() const
|
||||
{
|
||||
return m_curveForSourceStepping;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RimSummaryPlotSourceStepping.h"
|
||||
|
||||
#include "cafPdmChildArrayField.h"
|
||||
#include "cafPdmChildField.h"
|
||||
#include "cafPdmField.h"
|
||||
@ -29,7 +31,6 @@ class QwtPlot;
|
||||
class QwtPlotCurve;
|
||||
class RimSummaryCase;
|
||||
class RimSummaryCurve;
|
||||
class RimSummaryPlotSourceStepping;
|
||||
class QKeyEvent;
|
||||
|
||||
//==================================================================================================
|
||||
@ -56,6 +57,7 @@ public:
|
||||
void deleteCurve(RimSummaryCurve* curve);
|
||||
|
||||
std::vector<RimSummaryCurve*> curves() const;
|
||||
std::vector<RimSummaryCurve*> curvesForSourceStepping(RimSummaryPlotSourceStepping::SourceSteppingType steppingType) const;
|
||||
|
||||
void deleteCurvesAssosiatedWithCase(RimSummaryCase* summaryCase);
|
||||
void deleteAllCurves();
|
||||
@ -68,6 +70,9 @@ public:
|
||||
void handleKeyPressEvent(QKeyEvent* keyEvent);
|
||||
|
||||
void setCurveAsTopZWithinCategory(RimSummaryCurve* curve);
|
||||
|
||||
void setCurveForSourceStepping(RimSummaryCurve* curve);
|
||||
RimSummaryCurve* curveForSourceStepping() const;
|
||||
|
||||
private:
|
||||
caf::PdmFieldHandle* objectToggleField() override;
|
||||
@ -88,5 +93,6 @@ private:
|
||||
caf::PdmChildField<RimSummaryPlotSourceStepping*> m_unionSourceStepping;
|
||||
|
||||
caf::PdmPointer<RimSummaryCurve> m_currentSummaryCurve;
|
||||
caf::PdmPointer<RimSummaryCurve> m_curveForSourceStepping;
|
||||
};
|
||||
|
||||
|
@ -549,6 +549,22 @@ bool RimSummaryPlot::containsResamplableCurves() const
|
||||
return !m_gridTimeHistoryCurves.empty() || resamplableSummaryCurveCount > 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RimSummaryPlot::singleColorCurveCount() const
|
||||
{
|
||||
auto allCurveSets = ensembleCurveSetCollection()->curveSets();
|
||||
size_t colorIndex = std::count_if(allCurveSets.begin(), allCurveSets.end(), [](RimEnsembleCurveSet* curveSet)
|
||||
{
|
||||
return curveSet->colorMode() == RimEnsembleCurveSet::SINGLE_COLOR;
|
||||
});
|
||||
|
||||
colorIndex += curveCount();
|
||||
|
||||
return colorIndex;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -132,6 +132,8 @@ public:
|
||||
void updatePlotInfoLabel();
|
||||
|
||||
bool containsResamplableCurves() const;
|
||||
|
||||
size_t singleColorCurveCount() const;
|
||||
// RimViewWindow overrides
|
||||
public:
|
||||
QWidget* createViewWidget(QWidget* mainWindowParent) override;
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include "RifSummaryReaderInterface.h"
|
||||
|
||||
#include "RimDataSourceSteppingTools.h"
|
||||
#include "RimEnsembleCurveSet.h"
|
||||
#include "RimEnsembleCurveSetCollection.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimSummaryCase.h"
|
||||
#include "RimSummaryCaseMainCollection.h"
|
||||
@ -35,6 +37,7 @@
|
||||
|
||||
#include "RiuPlotMainWindow.h"
|
||||
|
||||
#include "RiaStdStringTools.h"
|
||||
#include "cafPdmUiComboBoxEditor.h"
|
||||
#include "cafPdmUiItem.h"
|
||||
#include "cafPdmUiListEditor.h"
|
||||
@ -51,11 +54,22 @@ RimSummaryPlotSourceStepping::RimSummaryPlotSourceStepping()
|
||||
CAF_PDM_InitObject("Summary Curves Modifier", "", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_summaryCase, "CurveCase", "Case", "", "", "");
|
||||
|
||||
CAF_PDM_InitField(&m_includeEnsembleCasesForCaseStepping,
|
||||
"IncludeEnsembleCasesForCaseStepping",
|
||||
false,
|
||||
"Allow Stepping on Ensemble cases",
|
||||
"",
|
||||
"",
|
||||
"");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_wellName, "WellName", "Well Name", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&m_wellGroupName, "GroupName", "Group Name", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&m_region, "Region", "Region", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&m_quantity, "Quantities", "Quantity", "", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_ensemble, "Ensemble", "Ensemble", "", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_placeholderForLabel, "Placeholder", "", "", "", "");
|
||||
m_placeholderForLabel = "No common identifiers detected";
|
||||
m_placeholderForLabel.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::TOP);
|
||||
@ -88,6 +102,22 @@ void RimSummaryPlotSourceStepping::applyPrevCase()
|
||||
modifyCurrentIndex(&m_summaryCase, -1);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSummaryPlotSourceStepping::applyNextEnsemble()
|
||||
{
|
||||
modifyCurrentIndex(&m_ensemble, 1);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSummaryPlotSourceStepping::applyPrevEnsemble()
|
||||
{
|
||||
modifyCurrentIndex(&m_ensemble, -1);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -162,85 +192,159 @@ void RimSummaryPlotSourceStepping::defineUiOrdering(QString uiConfigName, caf::P
|
||||
QList<caf::PdmOptionItemInfo> RimSummaryPlotSourceStepping::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions,
|
||||
bool* useOptionsOnly)
|
||||
{
|
||||
if (fieldNeedingOptions == &m_placeholderForLabel)
|
||||
QList<caf::PdmOptionItemInfo> options;
|
||||
|
||||
if (fieldNeedingOptions == &m_includeEnsembleCasesForCaseStepping)
|
||||
{
|
||||
return QList<caf::PdmOptionItemInfo>();
|
||||
return caf::PdmObject::calculateValueOptions(fieldNeedingOptions, useOptionsOnly);
|
||||
}
|
||||
|
||||
if (fieldNeedingOptions == &m_summaryCase)
|
||||
else if (fieldNeedingOptions == &m_placeholderForLabel)
|
||||
{
|
||||
QList<caf::PdmOptionItemInfo> options;
|
||||
|
||||
RimProject* proj = RiaApplication::instance()->project();
|
||||
for (auto sumCase : proj->allSummaryCases())
|
||||
options;
|
||||
}
|
||||
else if (fieldNeedingOptions == &m_summaryCase)
|
||||
{
|
||||
auto summaryCases = RimSummaryPlotSourceStepping::summaryCasesForSourceStepping();
|
||||
for (auto sumCase : summaryCases)
|
||||
{
|
||||
options.append(caf::PdmOptionItemInfo(sumCase->caseName(), sumCase));
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
else if (fieldNeedingOptions == &m_ensemble)
|
||||
{
|
||||
RimProject* proj = RiaApplication::instance()->project();
|
||||
for (auto ensemble : proj->summaryGroups())
|
||||
{
|
||||
if (ensemble->isEnsemble())
|
||||
{
|
||||
options.append(caf::PdmOptionItemInfo(ensemble->name(), ensemble));
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<QString> identifierTexts;
|
||||
return options;
|
||||
}
|
||||
|
||||
std::vector<RifSummaryReaderInterface*> readers = summaryReadersForCurves();
|
||||
if (!readers.empty())
|
||||
{
|
||||
RiaSummaryCurveAnalyzer* analyzer = analyzerForReader(readers.front());
|
||||
|
||||
if (fieldNeedingOptions == &m_wellName)
|
||||
if (fieldNeedingOptions == &m_quantity)
|
||||
{
|
||||
identifierTexts = analyzer->identifierTexts(RifEclipseSummaryAddress::SUMMARY_WELL);
|
||||
}
|
||||
else if (fieldNeedingOptions == &m_region)
|
||||
{
|
||||
identifierTexts = analyzer->identifierTexts(RifEclipseSummaryAddress::SUMMARY_REGION);
|
||||
}
|
||||
else if (fieldNeedingOptions == &m_wellGroupName)
|
||||
{
|
||||
identifierTexts = analyzer->identifierTexts(RifEclipseSummaryAddress::SUMMARY_WELL_GROUP);
|
||||
}
|
||||
else if (fieldNeedingOptions == &m_quantity)
|
||||
{
|
||||
RimSummaryCurveCollection* curveCollection = nullptr;
|
||||
this->firstAncestorOrThisOfTypeAsserted(curveCollection);
|
||||
|
||||
RifEclipseSummaryAddress::SummaryVarCategory category = RifEclipseSummaryAddress::SUMMARY_FIELD;
|
||||
|
||||
if (curveCollection->curves().size() > 0)
|
||||
auto addresses = addressesCurveCollection();
|
||||
if (!addresses.empty())
|
||||
{
|
||||
category = curveCollection->curves()[0]->summaryAddressY().category();
|
||||
category = addresses.begin()->category();
|
||||
}
|
||||
|
||||
RiaSummaryCurveAnalyzer quantityAnalyzer;
|
||||
std::map<QString, QString> displayAndValueStrings;
|
||||
|
||||
for (auto reader : readers)
|
||||
{
|
||||
if (reader != nullptr)
|
||||
RiaSummaryCurveAnalyzer quantityAnalyzer;
|
||||
|
||||
for (auto reader : readers)
|
||||
{
|
||||
auto subset = RiaSummaryCurveAnalyzer::addressesForCategory(reader->allResultAddresses(), category);
|
||||
quantityAnalyzer.appendAdresses(subset);
|
||||
if (reader != nullptr)
|
||||
{
|
||||
auto subset = RiaSummaryCurveAnalyzer::addressesForCategory(reader->allResultAddresses(), category);
|
||||
quantityAnalyzer.appendAdresses(subset);
|
||||
}
|
||||
}
|
||||
|
||||
RiaSummaryCurveAnalyzer analyzerForCurves;
|
||||
analyzerForCurves.appendAdresses(addressesCurveCollection());
|
||||
|
||||
if (analyzerForCurves.quantityNamesWithHistory().empty())
|
||||
{
|
||||
auto quantities = quantityAnalyzer.quantities();
|
||||
for (const auto& s : quantities)
|
||||
{
|
||||
QString valueString = QString::fromStdString(s);
|
||||
|
||||
displayAndValueStrings[valueString] = valueString;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto quantitiesWithHistory = quantityAnalyzer.quantityNamesWithHistory();
|
||||
for (const auto& s : quantitiesWithHistory)
|
||||
{
|
||||
QString valueString = QString::fromStdString(s);
|
||||
QString displayString = valueString + " (H)";
|
||||
|
||||
displayAndValueStrings[displayString] = valueString;
|
||||
}
|
||||
|
||||
auto quantitiesNoHistory = quantityAnalyzer.quantityNamesNoHistory();
|
||||
for (const auto& s : quantitiesNoHistory)
|
||||
{
|
||||
QString valueString = QString::fromStdString(s);
|
||||
|
||||
displayAndValueStrings[valueString] = valueString;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& quantity : quantityAnalyzer.quantities())
|
||||
for (const auto& displayAndValue : displayAndValueStrings)
|
||||
{
|
||||
identifierTexts.push_back(QString::fromStdString(quantity));
|
||||
options.append(caf::PdmOptionItemInfo(displayAndValue.first, displayAndValue.second));
|
||||
}
|
||||
|
||||
if (options.isEmpty())
|
||||
{
|
||||
options.push_back(caf::PdmOptionItemInfo("None", "None"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QList<caf::PdmOptionItemInfo> options;
|
||||
if (identifierTexts.size() > 0)
|
||||
{
|
||||
for (const auto& text : identifierTexts)
|
||||
else
|
||||
{
|
||||
options.append(caf::PdmOptionItemInfo(text, text));
|
||||
RifEclipseSummaryAddress::SummaryVarCategory category = RifEclipseSummaryAddress::SUMMARY_INVALID;
|
||||
|
||||
if (fieldNeedingOptions == &m_wellName)
|
||||
{
|
||||
category = RifEclipseSummaryAddress::SUMMARY_WELL;
|
||||
}
|
||||
else if (fieldNeedingOptions == &m_region)
|
||||
{
|
||||
category = RifEclipseSummaryAddress::SUMMARY_REGION;
|
||||
}
|
||||
else if (fieldNeedingOptions == &m_wellGroupName)
|
||||
{
|
||||
category = RifEclipseSummaryAddress::SUMMARY_WELL_GROUP;
|
||||
}
|
||||
|
||||
std::set<QString> identifierTexts;
|
||||
|
||||
if (category != RifEclipseSummaryAddress::SUMMARY_INVALID)
|
||||
{
|
||||
for (auto reader : readers)
|
||||
{
|
||||
auto analyzer = analyzerForReader(reader);
|
||||
|
||||
if (analyzer)
|
||||
{
|
||||
for (const auto& t : analyzer->identifierTexts(category))
|
||||
{
|
||||
identifierTexts.insert(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!identifierTexts.empty())
|
||||
{
|
||||
for (const auto& text : identifierTexts)
|
||||
{
|
||||
options.append(caf::PdmOptionItemInfo(text, text));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
options.push_back(caf::PdmOptionItemInfo("None", "None"));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
options.push_back(caf::PdmOptionItemInfo("None", "None"));
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
@ -252,27 +356,90 @@ void RimSummaryPlotSourceStepping::fieldChangedByUi(const caf::PdmFieldHandle* c
|
||||
const QVariant& oldValue,
|
||||
const QVariant& newValue)
|
||||
{
|
||||
std::vector<RimSummaryCurve*> curves;
|
||||
|
||||
RimSummaryCurveCollection* curveCollection = nullptr;
|
||||
this->firstAncestorOrThisOfTypeAsserted(curveCollection);
|
||||
this->firstAncestorOrThisOfType(curveCollection);
|
||||
if (curveCollection)
|
||||
{
|
||||
curves = curveCollection->curves();
|
||||
}
|
||||
|
||||
RimEnsembleCurveSetCollection* ensembleCurveColl = nullptr;
|
||||
this->firstAncestorOrThisOfType(ensembleCurveColl);
|
||||
|
||||
if (changedField == &m_includeEnsembleCasesForCaseStepping)
|
||||
{
|
||||
if (curveCollection)
|
||||
{
|
||||
curveCollection->updateConnectedEditors();
|
||||
}
|
||||
|
||||
if (ensembleCurveColl)
|
||||
{
|
||||
ensembleCurveColl->updateConnectedEditors();
|
||||
}
|
||||
|
||||
RiuPlotMainWindow* mainPlotWindow = RiaApplication::instance()->getOrCreateMainPlotWindow();
|
||||
bool forceUpdateOfFieldsInToolbar = true;
|
||||
mainPlotWindow->updateSummaryPlotToolBar(forceUpdateOfFieldsInToolbar);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool triggerLoadDataAndUpdate = false;
|
||||
|
||||
std::string oldValueString = oldValue.toString().toStdString();
|
||||
std::string newValueString = newValue.toString().toStdString();
|
||||
|
||||
if (changedField == &m_summaryCase)
|
||||
{
|
||||
if (m_summaryCase())
|
||||
{
|
||||
for (auto curve : curveCollection->curves())
|
||||
caf::PdmPointer<caf::PdmObjectHandle> variantHandle = oldValue.value<caf::PdmPointer<caf::PdmObjectHandle>>();
|
||||
RimSummaryCase* previousCase = dynamic_cast<RimSummaryCase*>(variantHandle.p());
|
||||
|
||||
for (auto curve : curves)
|
||||
{
|
||||
if (isYAxisStepping())
|
||||
{
|
||||
bool doSetAppearance = curve->summaryCaseY()->isObservedData() != m_summaryCase->isObservedData();
|
||||
curve->setSummaryCaseY(m_summaryCase);
|
||||
if (doSetAppearance) curve->forceUpdateCurveAppearanceFromCaseType();
|
||||
if (previousCase == curve->summaryCaseY())
|
||||
{
|
||||
bool doSetAppearance = curve->summaryCaseY()->isObservedData() != m_summaryCase->isObservedData();
|
||||
curve->setSummaryCaseY(m_summaryCase);
|
||||
if (doSetAppearance) curve->forceUpdateCurveAppearanceFromCaseType();
|
||||
}
|
||||
}
|
||||
|
||||
if (isXAxisStepping())
|
||||
{
|
||||
curve->setSummaryCaseX(m_summaryCase);
|
||||
if (previousCase == curve->summaryCaseX())
|
||||
{
|
||||
curve->setSummaryCaseX(m_summaryCase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
triggerLoadDataAndUpdate = true;
|
||||
}
|
||||
|
||||
m_wellName.uiCapability()->updateConnectedEditors();
|
||||
m_wellGroupName.uiCapability()->updateConnectedEditors();
|
||||
m_region.uiCapability()->updateConnectedEditors();
|
||||
m_quantity.uiCapability()->updateConnectedEditors();
|
||||
}
|
||||
else if (changedField == &m_ensemble)
|
||||
{
|
||||
if (m_ensemble() && ensembleCurveColl)
|
||||
{
|
||||
caf::PdmPointer<caf::PdmObjectHandle> variantHandle = oldValue.value<caf::PdmPointer<caf::PdmObjectHandle>>();
|
||||
RimSummaryCaseCollection* previousCollection = dynamic_cast<RimSummaryCaseCollection*>(variantHandle.p());
|
||||
|
||||
for (auto curveSet : ensembleCurveColl->curveSets())
|
||||
{
|
||||
if (curveSet->summaryCaseCollection() == previousCollection)
|
||||
{
|
||||
curveSet->setSummaryCaseCollection(m_ensemble);
|
||||
}
|
||||
}
|
||||
|
||||
@ -286,28 +453,30 @@ void RimSummaryPlotSourceStepping::fieldChangedByUi(const caf::PdmFieldHandle* c
|
||||
}
|
||||
else if (changedField == &m_wellName)
|
||||
{
|
||||
for (auto curve : curveCollection->curves())
|
||||
for (auto curve : curves)
|
||||
{
|
||||
if (isYAxisStepping())
|
||||
{
|
||||
RifEclipseSummaryAddress adr = curve->summaryAddressY();
|
||||
if (RifEclipseSummaryAddress::isDependentOnWellName(adr))
|
||||
{
|
||||
adr.setWellName(m_wellName().toStdString());
|
||||
|
||||
curve->setSummaryAddressY(adr);
|
||||
}
|
||||
updateAddressIfMatching(oldValue, newValue, RifEclipseSummaryAddress::SUMMARY_WELL, &adr);
|
||||
curve->setSummaryAddressY(adr);
|
||||
}
|
||||
|
||||
if (isXAxisStepping())
|
||||
{
|
||||
RifEclipseSummaryAddress adr = curve->summaryAddressX();
|
||||
if (RifEclipseSummaryAddress::isDependentOnWellName(adr))
|
||||
{
|
||||
adr.setWellName(m_wellName().toStdString());
|
||||
updateAddressIfMatching(oldValue, newValue, RifEclipseSummaryAddress::SUMMARY_WELL, &adr);
|
||||
curve->setSummaryAddressX(adr);
|
||||
}
|
||||
}
|
||||
|
||||
curve->setSummaryAddressX(adr);
|
||||
}
|
||||
if (ensembleCurveColl)
|
||||
{
|
||||
for (auto curveSet : ensembleCurveColl->curveSets())
|
||||
{
|
||||
auto adr = curveSet->summaryAddress();
|
||||
updateAddressIfMatching(oldValue, newValue, RifEclipseSummaryAddress::SUMMARY_WELL, &adr);
|
||||
curveSet->setSummaryAddress(adr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -315,28 +484,30 @@ void RimSummaryPlotSourceStepping::fieldChangedByUi(const caf::PdmFieldHandle* c
|
||||
}
|
||||
else if (changedField == &m_region)
|
||||
{
|
||||
for (auto curve : curveCollection->curves())
|
||||
for (auto curve : curves)
|
||||
{
|
||||
if (isYAxisStepping())
|
||||
{
|
||||
RifEclipseSummaryAddress adr = curve->summaryAddressY();
|
||||
if (adr.category() == RifEclipseSummaryAddress::SUMMARY_REGION)
|
||||
{
|
||||
adr.setRegion(m_region());
|
||||
|
||||
curve->setSummaryAddressY(adr);
|
||||
}
|
||||
updateAddressIfMatching(oldValue, newValue, RifEclipseSummaryAddress::SUMMARY_REGION, &adr);
|
||||
curve->setSummaryAddressY(adr);
|
||||
}
|
||||
|
||||
if (isXAxisStepping())
|
||||
{
|
||||
RifEclipseSummaryAddress adr = curve->summaryAddressX();
|
||||
if (adr.category() == RifEclipseSummaryAddress::SUMMARY_REGION)
|
||||
{
|
||||
adr.setRegion(m_region());
|
||||
updateAddressIfMatching(oldValue, newValue, RifEclipseSummaryAddress::SUMMARY_REGION, &adr);
|
||||
curve->setSummaryAddressX(adr);
|
||||
}
|
||||
}
|
||||
|
||||
curve->setSummaryAddressX(adr);
|
||||
}
|
||||
if (ensembleCurveColl)
|
||||
{
|
||||
for (auto curveSet : ensembleCurveColl->curveSets())
|
||||
{
|
||||
auto adr = curveSet->summaryAddress();
|
||||
updateAddressIfMatching(oldValue, newValue, RifEclipseSummaryAddress::SUMMARY_REGION, &adr);
|
||||
curveSet->setSummaryAddress(adr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -344,51 +515,61 @@ void RimSummaryPlotSourceStepping::fieldChangedByUi(const caf::PdmFieldHandle* c
|
||||
}
|
||||
else if (changedField == &m_quantity)
|
||||
{
|
||||
for (auto curve : curveCollection->curves())
|
||||
for (auto curve : curves)
|
||||
{
|
||||
if (isYAxisStepping())
|
||||
{
|
||||
RifEclipseSummaryAddress adr = curve->summaryAddressY();
|
||||
adr.setQuantityName(m_quantity().toStdString());
|
||||
|
||||
auto adr = curve->summaryAddressY();
|
||||
updateHistoryAndSummaryQuantityIfMatching(oldValue, newValue, &adr);
|
||||
curve->setSummaryAddressY(adr);
|
||||
}
|
||||
|
||||
if (isXAxisStepping())
|
||||
{
|
||||
RifEclipseSummaryAddress adr = curve->summaryAddressX();
|
||||
adr.setQuantityName(m_quantity().toStdString());
|
||||
|
||||
auto adr = curve->summaryAddressX();
|
||||
updateHistoryAndSummaryQuantityIfMatching(oldValue, newValue, &adr);
|
||||
curve->setSummaryAddressX(adr);
|
||||
}
|
||||
}
|
||||
|
||||
if (ensembleCurveColl)
|
||||
{
|
||||
for (auto curveSet : ensembleCurveColl->curveSets())
|
||||
{
|
||||
auto adr = curveSet->summaryAddress();
|
||||
updateHistoryAndSummaryQuantityIfMatching(oldValue, newValue, &adr);
|
||||
curveSet->setSummaryAddress(adr);
|
||||
}
|
||||
}
|
||||
|
||||
triggerLoadDataAndUpdate = true;
|
||||
}
|
||||
else if (changedField == &m_wellGroupName)
|
||||
{
|
||||
for (auto curve : curveCollection->curves())
|
||||
for (auto curve : curves)
|
||||
{
|
||||
if (isYAxisStepping())
|
||||
{
|
||||
RifEclipseSummaryAddress adr = curve->summaryAddressY();
|
||||
if (adr.category() == RifEclipseSummaryAddress::SUMMARY_WELL_GROUP)
|
||||
{
|
||||
adr.setWellGroupName(m_wellGroupName().toStdString());
|
||||
|
||||
curve->setSummaryAddressY(adr);
|
||||
}
|
||||
updateAddressIfMatching(oldValue, newValue, RifEclipseSummaryAddress::SUMMARY_WELL_GROUP, &adr);
|
||||
curve->setSummaryAddressY(adr);
|
||||
}
|
||||
|
||||
if (isXAxisStepping())
|
||||
{
|
||||
RifEclipseSummaryAddress adr = curve->summaryAddressX();
|
||||
if (adr.category() == RifEclipseSummaryAddress::SUMMARY_WELL_GROUP)
|
||||
{
|
||||
adr.setWellGroupName(m_wellGroupName().toStdString());
|
||||
updateAddressIfMatching(oldValue, newValue, RifEclipseSummaryAddress::SUMMARY_WELL_GROUP, &adr);
|
||||
curve->setSummaryAddressX(adr);
|
||||
}
|
||||
}
|
||||
|
||||
curve->setSummaryAddressX(adr);
|
||||
}
|
||||
if (ensembleCurveColl)
|
||||
{
|
||||
for (auto curveSet : ensembleCurveColl->curveSets())
|
||||
{
|
||||
auto adr = curveSet->summaryAddress();
|
||||
updateAddressIfMatching(oldValue, newValue, RifEclipseSummaryAddress::SUMMARY_WELL_GROUP, &adr);
|
||||
curveSet->setSummaryAddress(adr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -403,12 +584,20 @@ void RimSummaryPlotSourceStepping::fieldChangedByUi(const caf::PdmFieldHandle* c
|
||||
summaryPlot->updatePlotTitle();
|
||||
summaryPlot->loadDataAndUpdate();
|
||||
|
||||
if (ensembleCurveColl)
|
||||
{
|
||||
ensembleCurveColl->updateConnectedEditors();
|
||||
}
|
||||
|
||||
RimSummaryCrossPlot* summaryCrossPlot = dynamic_cast<RimSummaryCrossPlot*>(summaryPlot);
|
||||
if (summaryCrossPlot)
|
||||
{
|
||||
// Trigger update of curve collection (and summary toolbar in main window), as the visibility of combo boxes might
|
||||
// have been changed due to the updates in this function
|
||||
curveCollection->updateConnectedEditors();
|
||||
if (curveCollection)
|
||||
{
|
||||
curveCollection->updateConnectedEditors();
|
||||
}
|
||||
|
||||
RiuPlotMainWindow* mainPlotWindow = RiaApplication::instance()->mainPlotWindow();
|
||||
mainPlotWindow->updateSummaryPlotToolBar();
|
||||
@ -423,18 +612,38 @@ std::vector<RifSummaryReaderInterface*> RimSummaryPlotSourceStepping::summaryRea
|
||||
{
|
||||
std::vector<RifSummaryReaderInterface*> readers;
|
||||
RimSummaryCurveCollection* curveCollection = nullptr;
|
||||
this->firstAncestorOrThisOfTypeAsserted(curveCollection);
|
||||
this->firstAncestorOrThisOfType(curveCollection);
|
||||
|
||||
for (auto curve : curveCollection->curves())
|
||||
if (curveCollection)
|
||||
{
|
||||
if (isYAxisStepping() && curve->summaryCaseY())
|
||||
for (auto curve : curveCollection->curves())
|
||||
{
|
||||
readers.push_back(curve->summaryCaseY()->summaryReader());
|
||||
}
|
||||
if (isYAxisStepping() && curve->summaryCaseY())
|
||||
{
|
||||
readers.push_back(curve->summaryCaseY()->summaryReader());
|
||||
}
|
||||
|
||||
if (isXAxisStepping() && curve->summaryCaseX())
|
||||
if (isXAxisStepping() && curve->summaryCaseX())
|
||||
{
|
||||
readers.push_back(curve->summaryCaseX()->summaryReader());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RimEnsembleCurveSetCollection* ensembleCollection = nullptr;
|
||||
this->firstAncestorOrThisOfType(ensembleCollection);
|
||||
if (ensembleCollection)
|
||||
{
|
||||
auto curveSets = ensembleCollection->curveSets();
|
||||
for (const RimEnsembleCurveSet* curveSet : curveSets)
|
||||
{
|
||||
readers.push_back(curve->summaryCaseX()->summaryReader());
|
||||
for (auto curve : curveSet->curves())
|
||||
{
|
||||
if (isYAxisStepping() && curve->summaryCaseY())
|
||||
{
|
||||
readers.push_back(curve->summaryCaseY()->summaryReader());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -477,19 +686,31 @@ std::set<RifEclipseSummaryAddress> RimSummaryPlotSourceStepping::addressesCurveC
|
||||
RimSummaryCurveCollection* curveCollection = nullptr;
|
||||
this->firstAncestorOrThisOfType(curveCollection);
|
||||
|
||||
if (!curveCollection) return addresses;
|
||||
|
||||
auto curves = curveCollection->curves();
|
||||
for (auto c : curves)
|
||||
if (curveCollection)
|
||||
{
|
||||
if (isYAxisStepping())
|
||||
auto curves = curveCollection->curvesForSourceStepping(m_sourceSteppingType);
|
||||
for (auto c : curves)
|
||||
{
|
||||
addresses.insert(c->summaryAddressY());
|
||||
}
|
||||
if (isYAxisStepping())
|
||||
{
|
||||
addresses.insert(c->summaryAddressY());
|
||||
}
|
||||
|
||||
if (isXAxisStepping())
|
||||
if (isXAxisStepping())
|
||||
{
|
||||
addresses.insert(c->summaryAddressX());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RimEnsembleCurveSetCollection* ensembleCollection = nullptr;
|
||||
this->firstAncestorOrThisOfType(ensembleCollection);
|
||||
if (ensembleCollection)
|
||||
{
|
||||
auto curveSets = ensembleCollection->curveSetsForSourceStepping();
|
||||
for (const RimEnsembleCurveSet* curveSet : curveSets)
|
||||
{
|
||||
addresses.insert(c->summaryAddressX());
|
||||
addresses.insert(curveSet->summaryAddress());
|
||||
}
|
||||
}
|
||||
|
||||
@ -508,7 +729,7 @@ std::set<RimSummaryCase*> RimSummaryPlotSourceStepping::summaryCasesCurveCollect
|
||||
|
||||
if (!curveCollection) return sumCases;
|
||||
|
||||
auto curves = curveCollection->curves();
|
||||
auto curves = curveCollection->curvesForSourceStepping(m_sourceSteppingType);
|
||||
for (auto c : curves)
|
||||
{
|
||||
if (isYAxisStepping())
|
||||
@ -531,10 +752,12 @@ std::set<RimSummaryCase*> RimSummaryPlotSourceStepping::summaryCasesCurveCollect
|
||||
std::vector<caf::PdmFieldHandle*> RimSummaryPlotSourceStepping::computeVisibleFieldsAndSetFieldVisibility()
|
||||
{
|
||||
m_summaryCase.uiCapability()->setUiHidden(true);
|
||||
m_includeEnsembleCasesForCaseStepping.uiCapability()->setUiHidden(true);
|
||||
m_wellName.uiCapability()->setUiHidden(true);
|
||||
m_wellGroupName.uiCapability()->setUiHidden(true);
|
||||
m_region.uiCapability()->setUiHidden(true);
|
||||
m_quantity.uiCapability()->setUiHidden(true);
|
||||
m_ensemble.uiCapability()->setUiHidden(true);
|
||||
|
||||
std::vector<caf::PdmFieldHandle*> fields;
|
||||
|
||||
@ -549,61 +772,108 @@ std::vector<caf::PdmFieldHandle*> RimSummaryPlotSourceStepping::computeVisibleFi
|
||||
m_summaryCase.uiCapability()->setUiHidden(false);
|
||||
|
||||
fields.push_back(&m_summaryCase);
|
||||
|
||||
m_includeEnsembleCasesForCaseStepping.uiCapability()->setUiHidden(false);
|
||||
}
|
||||
}
|
||||
|
||||
RiaSummaryCurveAnalyzer analyzer;
|
||||
analyzer.appendAdresses(addressesCurveCollection());
|
||||
|
||||
RifEclipseSummaryAddress::SummaryVarCategory category = RifEclipseSummaryAddress::SUMMARY_INVALID;
|
||||
auto ensembleColl = ensembleCollection();
|
||||
if (ensembleColl.size() == 1)
|
||||
{
|
||||
if (analyzer.categories().size() == 1)
|
||||
RimProject* proj = RiaApplication::instance()->project();
|
||||
|
||||
if (proj->summaryGroups().size() > 1)
|
||||
{
|
||||
category = *(analyzer.categories().begin());
|
||||
m_ensemble = *(ensembleColl.begin());
|
||||
|
||||
m_ensemble.uiCapability()->setUiHidden(false);
|
||||
|
||||
fields.push_back(&m_ensemble);
|
||||
}
|
||||
}
|
||||
|
||||
if (category != RifEclipseSummaryAddress::SUMMARY_INVALID)
|
||||
std::vector<caf::PdmFieldHandle*> fieldsCommonForAllCurves;
|
||||
|
||||
{
|
||||
if (analyzer.wellNames().size() == 1)
|
||||
{
|
||||
QString txt = QString::fromStdString(*(analyzer.wellNames().begin()));
|
||||
m_wellName = txt;
|
||||
m_wellName.uiCapability()->setUiHidden(false);
|
||||
RiaSummaryCurveAnalyzer analyzer;
|
||||
analyzer.appendAdresses(addressesCurveCollection());
|
||||
|
||||
fields.push_back(&m_wellName);
|
||||
RifEclipseSummaryAddress::SummaryVarCategory category = RifEclipseSummaryAddress::SUMMARY_INVALID;
|
||||
{
|
||||
if (analyzer.categories().size() == 1)
|
||||
{
|
||||
category = *(analyzer.categories().begin());
|
||||
}
|
||||
}
|
||||
|
||||
if (analyzer.wellGroupNames().size() == 1)
|
||||
if (category != RifEclipseSummaryAddress::SUMMARY_INVALID)
|
||||
{
|
||||
QString txt = QString::fromStdString(*(analyzer.wellGroupNames().begin()));
|
||||
m_wellGroupName = txt;
|
||||
m_wellGroupName.uiCapability()->setUiHidden(false);
|
||||
if (analyzer.wellNames().size() == 1)
|
||||
{
|
||||
QString txt = QString::fromStdString(*(analyzer.wellNames().begin()));
|
||||
m_wellName = txt;
|
||||
m_wellName.uiCapability()->setUiHidden(false);
|
||||
|
||||
fields.push_back(&m_wellGroupName);
|
||||
fieldsCommonForAllCurves.push_back(&m_wellName);
|
||||
}
|
||||
|
||||
if (analyzer.wellGroupNames().size() == 1)
|
||||
{
|
||||
QString txt = QString::fromStdString(*(analyzer.wellGroupNames().begin()));
|
||||
m_wellGroupName = txt;
|
||||
m_wellGroupName.uiCapability()->setUiHidden(false);
|
||||
|
||||
fieldsCommonForAllCurves.push_back(&m_wellGroupName);
|
||||
}
|
||||
|
||||
if (analyzer.regionNumbers().size() == 1)
|
||||
{
|
||||
m_region = *(analyzer.regionNumbers().begin());
|
||||
m_region.uiCapability()->setUiHidden(false);
|
||||
|
||||
fieldsCommonForAllCurves.push_back(&m_region);
|
||||
}
|
||||
|
||||
if (!analyzer.quantityNameForTitle().empty())
|
||||
{
|
||||
QString txt = QString::fromStdString(analyzer.quantityNameForTitle());
|
||||
m_quantity = txt;
|
||||
m_quantity.uiCapability()->setUiHidden(false);
|
||||
|
||||
fieldsCommonForAllCurves.push_back(&m_quantity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (analyzer.regionNumbers().size() == 1)
|
||||
{
|
||||
m_region = *(analyzer.regionNumbers().begin());
|
||||
m_region.uiCapability()->setUiHidden(false);
|
||||
|
||||
fields.push_back(&m_region);
|
||||
}
|
||||
|
||||
if (analyzer.quantities().size() == 1)
|
||||
{
|
||||
QString txt = QString::fromStdString(*(analyzer.quantities().begin()));
|
||||
m_quantity = txt;
|
||||
m_quantity.uiCapability()->setUiHidden(false);
|
||||
|
||||
fields.push_back(&m_quantity);
|
||||
}
|
||||
for (const auto& f : fieldsCommonForAllCurves)
|
||||
{
|
||||
fields.push_back(f);
|
||||
}
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<RimSummaryCaseCollection*> RimSummaryPlotSourceStepping::ensembleCollection() const
|
||||
{
|
||||
std::set<RimSummaryCaseCollection*> sumCases;
|
||||
|
||||
RimEnsembleCurveSetCollection* curveCollection = nullptr;
|
||||
this->firstAncestorOrThisOfType(curveCollection);
|
||||
|
||||
if (!curveCollection) return sumCases;
|
||||
|
||||
auto curves = curveCollection->curveSets();
|
||||
for (auto c : curves)
|
||||
{
|
||||
sumCases.insert(c->summaryCaseCollection());
|
||||
}
|
||||
|
||||
return sumCases;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -656,6 +926,119 @@ void RimSummaryPlotSourceStepping::modifyCurrentIndex(caf::PdmValueField* valueF
|
||||
RimDataSourceSteppingTools::modifyCurrentIndex(valueField, options, indexOffset);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimSummaryPlotSourceStepping::updateAddressIfMatching(const QVariant& oldValue,
|
||||
const QVariant& newValue,
|
||||
RifEclipseSummaryAddress::SummaryVarCategory category,
|
||||
RifEclipseSummaryAddress* adr)
|
||||
{
|
||||
if (!adr) return false;
|
||||
|
||||
if (category == RifEclipseSummaryAddress::SUMMARY_REGION)
|
||||
{
|
||||
int oldInt = oldValue.toInt();
|
||||
int newInt = newValue.toInt();
|
||||
|
||||
if (adr->regionNumber() == oldInt)
|
||||
{
|
||||
adr->setRegion(newInt);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (category == RifEclipseSummaryAddress::SUMMARY_WELL_GROUP)
|
||||
{
|
||||
std::string oldString = oldValue.toString().toStdString();
|
||||
std::string newString = newValue.toString().toStdString();
|
||||
|
||||
if (adr->wellGroupName() == oldString)
|
||||
{
|
||||
adr->setWellGroupName(newString);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (RifEclipseSummaryAddress::isDependentOnWellName(category))
|
||||
{
|
||||
std::string oldString = oldValue.toString().toStdString();
|
||||
std::string newString = newValue.toString().toStdString();
|
||||
|
||||
if (adr->wellName() == oldString)
|
||||
{
|
||||
adr->setWellName(newString);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimSummaryPlotSourceStepping::updateHistoryAndSummaryQuantityIfMatching(const QVariant& oldValue,
|
||||
const QVariant& newValue,
|
||||
RifEclipseSummaryAddress* adr)
|
||||
{
|
||||
if (!adr) return false;
|
||||
|
||||
std::string oldString = oldValue.toString().toStdString();
|
||||
std::string newString = newValue.toString().toStdString();
|
||||
|
||||
if (adr->quantityName() == oldString)
|
||||
{
|
||||
adr->setQuantityName(newString);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string correspondingOldString = RiaSummaryCurveAnalyzer::correspondingHistorySummaryCurveName(oldString);
|
||||
std::string correspondingNewString = RiaSummaryCurveAnalyzer::correspondingHistorySummaryCurveName(newString);
|
||||
|
||||
if (adr->quantityName() == correspondingOldString)
|
||||
{
|
||||
adr->setQuantityName(correspondingNewString);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimSummaryCase*> RimSummaryPlotSourceStepping::summaryCasesForSourceStepping()
|
||||
{
|
||||
std::vector<RimSummaryCase*> cases;
|
||||
|
||||
RimProject* proj = RiaApplication::instance()->project();
|
||||
for (auto sumCase : proj->allSummaryCases())
|
||||
{
|
||||
if (sumCase->isObservedData()) continue;
|
||||
|
||||
RimSummaryCaseCollection* sumCaseColl = nullptr;
|
||||
sumCase->firstAncestorOrThisOfType(sumCaseColl);
|
||||
|
||||
if (sumCaseColl && sumCaseColl->isEnsemble())
|
||||
{
|
||||
if (m_includeEnsembleCasesForCaseStepping())
|
||||
{
|
||||
cases.push_back(sumCase);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cases.push_back(sumCase);
|
||||
}
|
||||
}
|
||||
|
||||
return cases;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -31,7 +31,9 @@
|
||||
#include <set>
|
||||
|
||||
class RimSummaryCase;
|
||||
class RimSummaryCurve;
|
||||
class RifSummaryReaderInterface;
|
||||
class RimSummaryCaseCollection;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
@ -56,6 +58,9 @@ public:
|
||||
void applyNextCase();
|
||||
void applyPrevCase();
|
||||
|
||||
void applyNextEnsemble();
|
||||
void applyPrevEnsemble();
|
||||
|
||||
void applyNextQuantity();
|
||||
void applyPrevQuantity();
|
||||
|
||||
@ -83,6 +88,7 @@ private:
|
||||
std::set<RifEclipseSummaryAddress> addressesCurveCollection() const;
|
||||
std::set<RimSummaryCase*> summaryCasesCurveCollection() const;
|
||||
std::vector<caf::PdmFieldHandle*> computeVisibleFieldsAndSetFieldVisibility();
|
||||
std::set<RimSummaryCaseCollection*> ensembleCollection() const;
|
||||
|
||||
bool isXAxisStepping() const;
|
||||
bool isYAxisStepping() const;
|
||||
@ -91,13 +97,29 @@ private:
|
||||
|
||||
void modifyCurrentIndex(caf::PdmValueField* valueField, int indexOffset);
|
||||
|
||||
static bool updateAddressIfMatching(const QVariant& oldValue,
|
||||
const QVariant& newValue,
|
||||
RifEclipseSummaryAddress::SummaryVarCategory category,
|
||||
RifEclipseSummaryAddress* adr);
|
||||
|
||||
static bool updateHistoryAndSummaryQuantityIfMatching(const QVariant& oldValue,
|
||||
const QVariant& newValue,
|
||||
RifEclipseSummaryAddress* adr);
|
||||
|
||||
std::vector<RimSummaryCase*> summaryCasesForSourceStepping();
|
||||
|
||||
private:
|
||||
caf::PdmPtrField<RimSummaryCase*> m_summaryCase;
|
||||
caf::PdmPtrField<RimSummaryCaseCollection*> m_ensemble;
|
||||
|
||||
caf::PdmField<QString> m_wellName;
|
||||
caf::PdmField<QString> m_wellGroupName;
|
||||
caf::PdmField<int> m_region;
|
||||
caf::PdmField<QString> m_quantity;
|
||||
caf::PdmField<QString> m_placeholderForLabel;
|
||||
|
||||
caf::PdmField<bool> m_includeEnsembleCasesForCaseStepping;
|
||||
|
||||
SourceSteppingType m_sourceSteppingType;
|
||||
|
||||
std::pair<RifSummaryReaderInterface*, RiaSummaryCurveAnalyzer> m_curveAnalyzerForReader;
|
||||
|
@ -140,6 +140,8 @@
|
||||
<file>ToggleOnOff16x16.png</file>
|
||||
<file>ToggleOnOthersOff16x16.png</file>
|
||||
<file>ExportCompletionsSymbol16x16.png</file>
|
||||
<file>StepUpDown16x16.png</file>
|
||||
<file>StepUpDownCorner16x16.png</file>
|
||||
<file>TextAnnotation16x16.png</file>
|
||||
<file>Annotations16x16.png</file>
|
||||
<file>PolylinesFromFile16x16.png</file>
|
||||
|
BIN
ApplicationCode/Resources/StepUpDown16x16.png
Normal file
BIN
ApplicationCode/Resources/StepUpDown16x16.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
BIN
ApplicationCode/Resources/StepUpDownCorner16x16.png
Normal file
BIN
ApplicationCode/Resources/StepUpDownCorner16x16.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
@ -53,6 +53,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RiaWeightedHarmonicMeanCalculator-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaCellDividingTools-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/Intersect-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifPerforationIntervalReader-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellPathCompletions-Test.cpp
|
||||
)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES
|
||||
|
@ -2,6 +2,9 @@
|
||||
|
||||
#include "RifEclipseDataTableFormatter.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
TEST(RifEclipseDataTableFormatter, BasicUsage)
|
||||
{
|
||||
QString tableText;
|
||||
@ -73,3 +76,142 @@ TEST(RifEclipseDataTableFormatter, NoPrefix)
|
||||
std::cout << tableText.toStdString();
|
||||
|
||||
}
|
||||
|
||||
TEST(RifEclipseDataTableFormatter, LongLine)
|
||||
{
|
||||
QString tableText;
|
||||
QTextStream stream(&tableText);
|
||||
RifEclipseDataTableFormatter formatter(stream);
|
||||
|
||||
std::vector<RifEclipseOutputTableColumn> header = {
|
||||
RifEclipseOutputTableColumn("50 Character Well Name"),
|
||||
RifEclipseOutputTableColumn("10 Int #1", RifEclipseOutputTableDoubleFormatting(), RIGHT),
|
||||
RifEclipseOutputTableColumn("10 Int #2", RifEclipseOutputTableDoubleFormatting(), RIGHT),
|
||||
RifEclipseOutputTableColumn("10 Int #3", RifEclipseOutputTableDoubleFormatting(), RIGHT),
|
||||
RifEclipseOutputTableColumn("10 Int #4", RifEclipseOutputTableDoubleFormatting(), RIGHT),
|
||||
RifEclipseOutputTableColumn("10 Int #5", RifEclipseOutputTableDoubleFormatting(), RIGHT),
|
||||
RifEclipseOutputTableColumn("10 Int #6", RifEclipseOutputTableDoubleFormatting(), RIGHT),
|
||||
RifEclipseOutputTableColumn("10 Int #7", RifEclipseOutputTableDoubleFormatting(), RIGHT),
|
||||
RifEclipseOutputTableColumn("10 Int #8", RifEclipseOutputTableDoubleFormatting(), RIGHT),
|
||||
};
|
||||
|
||||
formatter.header(header);
|
||||
QString fiftyCharacterWellName = "01234567890123456789012345678901234567890123456789";
|
||||
formatter.add(fiftyCharacterWellName);
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
formatter.add(std::numeric_limits<int>::max()); // 10 characters
|
||||
}
|
||||
int fullLineLength = formatter.tableRowPrependText().length() + 9 * formatter.columnSpacing() +
|
||||
50 + 8 * 10 + formatter.tableRowAppendText().length();
|
||||
int tableWidth = formatter.tableWidth();
|
||||
EXPECT_EQ(tableWidth, fullLineLength);
|
||||
EXPECT_GT(tableWidth, RifEclipseDataTableFormatter::maxEclipseRowWidth());
|
||||
|
||||
formatter.rowCompleted();
|
||||
formatter.tableCompleted();
|
||||
|
||||
QStringList tableLines = tableText.split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
|
||||
for (QString line : tableLines)
|
||||
{
|
||||
std::cout << QString("Line: \"%1\"").arg(line).toStdString() << std::endl;
|
||||
if (!line.startsWith(formatter.commentPrefix()))
|
||||
{
|
||||
EXPECT_LE(line.length(), RifEclipseDataTableFormatter::maxEclipseRowWidth());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(RifEclipseDataTableFormatter, LongLine132)
|
||||
{
|
||||
QString tableText;
|
||||
QTextStream stream(&tableText);
|
||||
RifEclipseDataTableFormatter formatter(stream);
|
||||
|
||||
std::vector<RifEclipseOutputTableColumn> header = {
|
||||
RifEclipseOutputTableColumn("10 Char"),
|
||||
RifEclipseOutputTableColumn("10 Int #1", RifEclipseOutputTableDoubleFormatting(), RIGHT),
|
||||
RifEclipseOutputTableColumn("10 Int #2", RifEclipseOutputTableDoubleFormatting(), RIGHT),
|
||||
RifEclipseOutputTableColumn("10 Int #3", RifEclipseOutputTableDoubleFormatting(), RIGHT),
|
||||
RifEclipseOutputTableColumn("10 Int #4", RifEclipseOutputTableDoubleFormatting(), RIGHT),
|
||||
RifEclipseOutputTableColumn("10 Int #5", RifEclipseOutputTableDoubleFormatting(), RIGHT),
|
||||
RifEclipseOutputTableColumn("10 Int #6", RifEclipseOutputTableDoubleFormatting(), RIGHT),
|
||||
RifEclipseOutputTableColumn("10 Int #7", RifEclipseOutputTableDoubleFormatting(), RIGHT),
|
||||
RifEclipseOutputTableColumn("I", RifEclipseOutputTableDoubleFormatting(), RIGHT),
|
||||
};
|
||||
|
||||
formatter.header(header);
|
||||
QString tenCharacterWellName = "0123456789";
|
||||
formatter.add(tenCharacterWellName);
|
||||
for (int i = 0; i < 7; ++i)
|
||||
{
|
||||
formatter.add(std::numeric_limits<int>::max()); // 10 characters
|
||||
}
|
||||
formatter.add(11);
|
||||
|
||||
int fullLineLength = formatter.tableRowPrependText().length() + 9 * formatter.columnSpacing() + 10 + 7 * 10 + 2 +
|
||||
formatter.tableRowAppendText().length();
|
||||
int tableWidth = formatter.tableWidth();
|
||||
EXPECT_GE(tableWidth, fullLineLength);
|
||||
EXPECT_EQ(RifEclipseDataTableFormatter::maxEclipseRowWidth(), fullLineLength);
|
||||
|
||||
formatter.rowCompleted();
|
||||
formatter.tableCompleted();
|
||||
|
||||
QStringList tableLines = tableText.split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
|
||||
for (QString line : tableLines)
|
||||
{
|
||||
std::cout << QString("Line: \"%1\"").arg(line).toStdString() << std::endl;
|
||||
if (line.startsWith("0"))
|
||||
{
|
||||
EXPECT_EQ(line.length(), RifEclipseDataTableFormatter::maxEclipseRowWidth());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(RifEclipseDataTableFormatter, LongLine133)
|
||||
{
|
||||
QString tableText;
|
||||
QTextStream stream(&tableText);
|
||||
RifEclipseDataTableFormatter formatter(stream);
|
||||
|
||||
std::vector<RifEclipseOutputTableColumn> header = {
|
||||
RifEclipseOutputTableColumn("10 Char"),
|
||||
RifEclipseOutputTableColumn("10 Int #1", RifEclipseOutputTableDoubleFormatting(), RIGHT),
|
||||
RifEclipseOutputTableColumn("10 Int #2", RifEclipseOutputTableDoubleFormatting(), RIGHT),
|
||||
RifEclipseOutputTableColumn("10 Int #3", RifEclipseOutputTableDoubleFormatting(), RIGHT),
|
||||
RifEclipseOutputTableColumn("10 Int #4", RifEclipseOutputTableDoubleFormatting(), RIGHT),
|
||||
RifEclipseOutputTableColumn("10 Int #5", RifEclipseOutputTableDoubleFormatting(), RIGHT),
|
||||
RifEclipseOutputTableColumn("10 Int #6", RifEclipseOutputTableDoubleFormatting(), RIGHT),
|
||||
RifEclipseOutputTableColumn("10 Int #7", RifEclipseOutputTableDoubleFormatting(), RIGHT),
|
||||
RifEclipseOutputTableColumn("I", RifEclipseOutputTableDoubleFormatting(), RIGHT),
|
||||
};
|
||||
|
||||
formatter.header(header);
|
||||
QString fiftyCharacterWellName = "0123456789";
|
||||
formatter.add(fiftyCharacterWellName);
|
||||
for (int i = 0; i < 7; ++i)
|
||||
{
|
||||
formatter.add(std::numeric_limits<int>::max()); // 10 characters
|
||||
}
|
||||
formatter.add(111);
|
||||
|
||||
int fullLineLength = formatter.tableRowPrependText().length() + 9 * formatter.columnSpacing() + 10 + 7 * 10 + 3 +
|
||||
formatter.tableRowAppendText().length();
|
||||
int tableWidth = formatter.tableWidth();
|
||||
EXPECT_GE(tableWidth, fullLineLength);
|
||||
EXPECT_LT(RifEclipseDataTableFormatter::maxEclipseRowWidth(), fullLineLength);
|
||||
|
||||
formatter.rowCompleted();
|
||||
formatter.tableCompleted();
|
||||
|
||||
QStringList tableLines = tableText.split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
|
||||
for (QString line : tableLines)
|
||||
{
|
||||
std::cout << QString("Line: \"%1\"").arg(line).toStdString() << std::endl;
|
||||
if (line.startsWith("0"))
|
||||
{
|
||||
EXPECT_LE(line.length(), RifEclipseDataTableFormatter::maxEclipseRowWidth());
|
||||
}
|
||||
}
|
||||
}
|
50
ApplicationCode/UnitTests/RimWellPathCompletions-Test.cpp
Normal file
50
ApplicationCode/UnitTests/RimWellPathCompletions-Test.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "RimWellPathCompletions.h"
|
||||
|
||||
#include <QRegExpValidator>
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(RimWellPathCompletions, WellNameRegExp)
|
||||
{
|
||||
std::vector<QString> validNames = { "RASASD", "gf0sdf", "sd-ASD12", "1-AA_b" };
|
||||
std::vector<QString> invalidNames = { ".AdSD", "+gf0sdf", "sd ASD12", "ABCDEFGHIJKL" };
|
||||
|
||||
QRegExp rx = RimWellPathCompletions::wellNameForExportRegExp();
|
||||
EXPECT_TRUE(rx.isValid());
|
||||
|
||||
for (QString validName : validNames)
|
||||
{
|
||||
EXPECT_TRUE(rx.exactMatch(validName));
|
||||
}
|
||||
for (QString invalidName : invalidNames)
|
||||
{
|
||||
EXPECT_FALSE(rx.exactMatch(invalidName));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(RimWellPathCompletions, WellNameRegExpValidator)
|
||||
{
|
||||
std::vector<QString> validNames = {"RASASD", "gf0sdf", "sd-ASD12", "1-AA_b"};
|
||||
std::vector<QString> invalidNames = {".AdSD", "+gf0sdf", "sd ASD12", "ABCDEFGHIJKL"};
|
||||
QString emptyString = "";
|
||||
|
||||
QRegExp rx = RimWellPathCompletions::wellNameForExportRegExp();
|
||||
QRegExpValidator validator (nullptr);
|
||||
validator.setRegExp(rx);
|
||||
|
||||
for (QString validName : validNames)
|
||||
{
|
||||
int dummyPos;
|
||||
EXPECT_EQ(QValidator::Acceptable, validator.validate(validName, dummyPos));
|
||||
}
|
||||
for (QString invalidName : invalidNames)
|
||||
{
|
||||
int dummyPos;
|
||||
EXPECT_EQ(QValidator::Invalid, validator.validate(invalidName, dummyPos));
|
||||
}
|
||||
|
||||
int dummyPos;
|
||||
EXPECT_EQ(QValidator::Intermediate, validator.validate(emptyString, dummyPos));
|
||||
}
|
@ -22,6 +22,7 @@
|
||||
#include "RiaBaseDefs.h"
|
||||
#include "RiaPreferences.h"
|
||||
|
||||
#include "RimEnsembleCurveSetCollection.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimSummaryCurveCollection.h"
|
||||
#include "RimSummaryPlot.h"
|
||||
@ -43,6 +44,7 @@
|
||||
#include "cafPdmUiToolBarEditor.h"
|
||||
#include "cafPdmUiTreeView.h"
|
||||
#include "cafQTreeViewStateSerializer.h"
|
||||
#include "cafSelectionManager.h"
|
||||
|
||||
#include <QCloseEvent>
|
||||
#include <QDockWidget>
|
||||
@ -494,18 +496,39 @@ void RiuPlotMainWindow::updateWellLogPlotToolBar()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuPlotMainWindow::updateSummaryPlotToolBar()
|
||||
void RiuPlotMainWindow::updateSummaryPlotToolBar(bool forceUpdateUi)
|
||||
{
|
||||
RimSummaryPlot* summaryPlot = dynamic_cast<RimSummaryPlot*>(m_activePlotViewWindow.p());
|
||||
if (summaryPlot)
|
||||
{
|
||||
std::vector<caf::PdmFieldHandle*> toolBarFields;
|
||||
toolBarFields = summaryPlot->summaryCurveCollection()->fieldsToShowInToolbar();
|
||||
|
||||
|
||||
RimEnsembleCurveSetCollection* ensembleCurveSetColl = nullptr;
|
||||
|
||||
caf::PdmObjectHandle* selectedObj =
|
||||
dynamic_cast<caf::PdmObjectHandle*>(caf::SelectionManager::instance()->selectedItem());
|
||||
if (selectedObj)
|
||||
{
|
||||
selectedObj->firstAncestorOrThisOfType(ensembleCurveSetColl);
|
||||
}
|
||||
|
||||
if (ensembleCurveSetColl)
|
||||
{
|
||||
toolBarFields = ensembleCurveSetColl->fieldsToShowInToolbar();
|
||||
}
|
||||
else
|
||||
{
|
||||
toolBarFields = summaryPlot->summaryCurveCollection()->fieldsToShowInToolbar();
|
||||
}
|
||||
|
||||
if (!m_summaryPlotToolBarEditor->isEditorDataValid(toolBarFields))
|
||||
{
|
||||
m_summaryPlotToolBarEditor->setFields(toolBarFields);
|
||||
}
|
||||
else if (forceUpdateUi)
|
||||
{
|
||||
m_summaryPlotToolBarEditor->updateUi();
|
||||
}
|
||||
|
||||
m_summaryPlotToolBarEditor->updateUi();
|
||||
|
||||
@ -694,6 +717,16 @@ void RiuPlotMainWindow::selectedObjectsChanged()
|
||||
|
||||
m_pdmUiPropertyView->showProperties(firstSelectedObject);
|
||||
|
||||
if (firstSelectedObject)
|
||||
{
|
||||
RimSummaryPlot* summaryPlot = nullptr;
|
||||
firstSelectedObject->firstAncestorOrThisOfType(summaryPlot);
|
||||
if (summaryPlot)
|
||||
{
|
||||
updateSummaryPlotToolBar();
|
||||
}
|
||||
}
|
||||
|
||||
if (uiItems.size() == 1 && m_allowActiveViewChangeFromSelection)
|
||||
{
|
||||
// Find the reservoir view or the Plot that the selected item is within
|
||||
|
@ -81,7 +81,7 @@ public:
|
||||
void addToTemporaryWidgets(QWidget* widget);
|
||||
|
||||
void updateWellLogPlotToolBar();
|
||||
void updateSummaryPlotToolBar();
|
||||
void updateSummaryPlotToolBar(bool forceUpdateUi = false);
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent* event) override;
|
||||
|
@ -399,6 +399,24 @@ set_property(TARGET
|
||||
PROPERTY FOLDER "AppFwk"
|
||||
)
|
||||
|
||||
option (RESINSIGHT_INCLUDE_APPFWK_TESTS "Enable AppFwk Tests" OFF)
|
||||
if (RESINSIGHT_INCLUDE_APPFWK_TESTS)
|
||||
# Unit Tests
|
||||
add_subdirectory(Fwk/AppFwk/cafProjectDataModel/cafProjectDataModel_UnitTests)
|
||||
set_property(TARGET cafProjectDataModel_UnitTests PROPERTY FOLDER "AppFwkTests")
|
||||
|
||||
add_subdirectory(Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests)
|
||||
set_property(TARGET cafPdmCore_UnitTests PROPERTY FOLDER "AppFwkTests")
|
||||
|
||||
add_subdirectory(Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXml_UnitTests)
|
||||
set_property(TARGET cafPdmXml_UnitTests PROPERTY FOLDER "AppFwkTests")
|
||||
|
||||
# Executables
|
||||
add_subdirectory(Fwk/AppFwk/cafTests/cafTestApplication)
|
||||
set_property(TARGET cafTestApplication PROPERTY FOLDER "AppFwkTests")
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
################################################################################
|
||||
# Installation settings
|
||||
|
@ -22,7 +22,9 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "cafContourLines.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <list>
|
||||
|
||||
const int caf::ContourLines::s_castab[3][3][3] =
|
||||
{
|
||||
@ -206,6 +208,104 @@ void caf::ContourLines::create(const std::vector<double>& dataXY, const std::vec
|
||||
} /* j */
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<caf::ContourLines::ClosedPolygons> caf::ContourLines::create(const std::vector<double>& dataXY,
|
||||
const std::vector<double>& xPositions,
|
||||
const std::vector<double>& yPositions,
|
||||
const std::vector<double>& contourLevels)
|
||||
{
|
||||
const double eps = 1.0e-4;
|
||||
std::vector<std::vector<cvf::Vec2d>> contourLineSegments;
|
||||
caf::ContourLines::create(dataXY, xPositions, yPositions, contourLevels, &contourLineSegments);
|
||||
|
||||
std::vector<ClosedPolygons> closedPolygonsPerLevel(contourLevels.size());
|
||||
|
||||
for (size_t i = 0; i < contourLevels.size(); ++i)
|
||||
{
|
||||
size_t nPoints = contourLineSegments[i].size();
|
||||
size_t nSegments = nPoints / 2;
|
||||
if (nSegments >= 3u) // Need at least three segments for a closed polygon
|
||||
{
|
||||
std::list<std::pair<cvf::Vec2d, cvf::Vec2d>> unorderedSegments;
|
||||
for (size_t j = 0; j < contourLineSegments[i].size(); j += 2)
|
||||
{
|
||||
unorderedSegments.push_back(std::make_pair(contourLineSegments[i][j], contourLineSegments[i][j + 1]));
|
||||
}
|
||||
|
||||
std::deque<cvf::Vec2d> closedPolygonDeque;
|
||||
while (!unorderedSegments.empty())
|
||||
{
|
||||
bool expandedPolygon = false;
|
||||
for (auto listIt = unorderedSegments.begin(); listIt != unorderedSegments.end(); ++listIt)
|
||||
{
|
||||
if (closedPolygonDeque.empty() || listIt->first == closedPolygonDeque.back())
|
||||
{
|
||||
closedPolygonDeque.push_back(listIt->first);
|
||||
closedPolygonDeque.push_back(listIt->second);
|
||||
unorderedSegments.erase(listIt);
|
||||
expandedPolygon = true;
|
||||
break;
|
||||
}
|
||||
else if (listIt->second == closedPolygonDeque.back())
|
||||
{
|
||||
closedPolygonDeque.push_back(listIt->second);
|
||||
closedPolygonDeque.push_back(listIt->first);
|
||||
unorderedSegments.erase(listIt);
|
||||
expandedPolygon = true;
|
||||
break;
|
||||
}
|
||||
else if (listIt->first == closedPolygonDeque.front())
|
||||
{
|
||||
closedPolygonDeque.push_front(listIt->first);
|
||||
closedPolygonDeque.push_front(listIt->second);
|
||||
unorderedSegments.erase(listIt);
|
||||
expandedPolygon = true;
|
||||
break;
|
||||
}
|
||||
else if (listIt->second == closedPolygonDeque.front())
|
||||
{
|
||||
closedPolygonDeque.push_front(listIt->second);
|
||||
closedPolygonDeque.push_front(listIt->first);
|
||||
unorderedSegments.erase(listIt);
|
||||
expandedPolygon = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!expandedPolygon || unorderedSegments.empty())
|
||||
{
|
||||
if (closedPolygonDeque.back() != closedPolygonDeque.front())
|
||||
{
|
||||
closedPolygonDeque.push_back(closedPolygonDeque.back());
|
||||
closedPolygonDeque.push_back(closedPolygonDeque.front());
|
||||
}
|
||||
|
||||
// Make sure it is counter clockwise. Use Shoelace formula to calculate signed area.
|
||||
// https://en.wikipedia.org/wiki/Shoelace_formula
|
||||
double signedArea = 0.0;
|
||||
for (size_t j = 0; j < closedPolygonDeque.size() - 1; ++j)
|
||||
{
|
||||
signedArea += (closedPolygonDeque[j + 1].x() - closedPolygonDeque[j].x()) *
|
||||
(closedPolygonDeque[j + 1].y() + closedPolygonDeque[j].y());
|
||||
}
|
||||
if (signedArea < 0.0)
|
||||
{
|
||||
closedPolygonsPerLevel[i].emplace_back(closedPolygonDeque.rbegin(), closedPolygonDeque.rend());
|
||||
}
|
||||
else
|
||||
{
|
||||
closedPolygonsPerLevel[i].emplace_back(closedPolygonDeque.begin(), closedPolygonDeque.end());
|
||||
}
|
||||
|
||||
closedPolygonDeque.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return closedPolygonsPerLevel;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfVector2.h"
|
||||
#include <deque>
|
||||
#include <vector>
|
||||
|
||||
namespace caf
|
||||
@ -32,12 +33,20 @@ namespace caf
|
||||
class ContourLines
|
||||
{
|
||||
public:
|
||||
typedef std::vector<cvf::Vec2d> ClosedPolygon;
|
||||
typedef std::vector<ClosedPolygon> ClosedPolygons;
|
||||
|
||||
static std::vector<ClosedPolygons> create(const std::vector<double>& dataXY,
|
||||
const std::vector<double>& xPositions,
|
||||
const std::vector<double>& yPositions,
|
||||
const std::vector<double>& contourLevels);
|
||||
|
||||
private:
|
||||
static void create(const std::vector<double>& dataXY,
|
||||
const std::vector<double>& xPositions,
|
||||
const std::vector<double>& yPositions,
|
||||
const std::vector<double>& contourLevels,
|
||||
std::vector<std::vector<cvf::Vec2d>>* polygons);
|
||||
private:
|
||||
static double contourRange(const std::vector<double>& contourLevels);
|
||||
static double invalidValue(const std::vector<double>& contourLevels);
|
||||
static double saneValue(int index, const std::vector<double>& dataXY, const std::vector<double>& contourLevels);
|
||||
|
@ -54,6 +54,120 @@ namespace caf
|
||||
|
||||
CAF_PDM_UI_FIELD_EDITOR_SOURCE_INIT(PdmUiComboBoxEditor);
|
||||
|
||||
|
||||
/* GIMP RGBA C-Source image dump (StepDown.c) */
|
||||
|
||||
static const struct {
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int bytes_per_pixel; /* 2:RGB16, 3:RGB, 4:RGBA */
|
||||
unsigned char pixel_data[16 * 16 * 4 + 1];
|
||||
} stepDownImageData = {
|
||||
16, 16, 4,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000AAA\001\030\030\030\001"
|
||||
"\037\037\037\001\020\020\020\001\004\004\004\001\016\016\016\001!!!\001\"\"\"\001(((\001\060\060\060\001$$"
|
||||
"$\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000UUU\014FFF\242\030\030\030\256\037\037\037\256"
|
||||
"\022\022\022\256\005\005\005\256\021\021\021\256'''\256...\256\061\061\061\256\067\067\067"
|
||||
"\256&&&\256AAAzTTT\010\000\000\000\000\000\000\000\000xxx\014```\273\033\033\033\377&&&\377\""
|
||||
"\"\"\377\017\017\017\377\"\"\"\377LLL\377___\377^^^\377^^^\377AAA\376OOOXTT"
|
||||
"T\001\000\000\000\000\000\000\000\000\000\000\000\000JJJ\071+++\343&&&\377%%%\377\017\017\017\377'''\377"
|
||||
"WWW\377]]]\377hhh\377WWW\376NNN\300\177\177\177\032\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000KKK\004\066\066\066z\040\040\040\370\"\"\"\377\014\014\014\377$$$\377SSS\377"
|
||||
"ccc\377bbb\377NNN\362\202\202\202=\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\064\064\064\040===\312\032\032\032\375\017\017\017\377$$$\377WWW\377bbb"
|
||||
"\377MMM\374LLL\200iii\006\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000W"
|
||||
"WW\001AAA\063###\330\007\007\007\377(((\377VVV\377UUU\377WWW\314\217\217\217\040\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000;;;\001\066\066"
|
||||
"\066}\027\027\027\371(((\377TTT\377FFF\360\\\\\\C\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000TTT\015\025\025\025\036\040\040\040!<<<<???\360\"\"\""
|
||||
"\377===\377ddd\266GGG\062\026\026\026\061\040\040\040\066\"\"\"\022\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000HHH\015\071\071\071\256\007\007\007\314\015\015\015\316\024\024\024\326\034\034\034"
|
||||
"\374\022\022\022\377!!!\377###\335###\326\035\035\035\336\032\032\032\343///\220A"
|
||||
"AA\010\000\000\000\000\000\000\000\000bbb\014QQQ\264%%%\355$$$\363\035\035\035\352\034\034\034\351"
|
||||
"&&&\353$$$\344)))\346\061\061\061\345\066\066\066\350\062\062\062\335\064\064\064\201"
|
||||
"???\007\000\000\000\000\000\000\000\000\000\000\000\000SSS\023@@@?\070\070\070E---=,,,<///>\"\"\"\067&&"
|
||||
"&\070$$$\070---:CCC\060;;;\015\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000",
|
||||
};
|
||||
|
||||
QIcon createStepDownIcon()
|
||||
{
|
||||
QImage img(stepDownImageData.pixel_data,stepDownImageData.width, stepDownImageData.height, QImage::Format_ARGB32 );
|
||||
QPixmap pxMap;
|
||||
pxMap = QPixmap::fromImage(img);
|
||||
|
||||
return QIcon(pxMap);
|
||||
}
|
||||
|
||||
static const QIcon& stepDownIcon()
|
||||
{
|
||||
static QIcon expandDownIcon(createStepDownIcon());
|
||||
return expandDownIcon;
|
||||
}
|
||||
|
||||
/* GIMP RGBA C-Source image dump (StepUp.c) */
|
||||
|
||||
static const struct {
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int bytes_per_pixel; /* 2:RGB16, 3:RGB, 4:RGBA */
|
||||
unsigned char pixel_data[16 * 16 * 4 + 1];
|
||||
} stepUpImageData = {
|
||||
16, 16, 4,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000;;;\015CCC\060---:"
|
||||
"$$$\070&&&\070\"\"\"\067///>,,,<---=\070\070\070E@@@?SSS\023\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000???\007\064\064\064\201\062\062\062\335\066\066\066\350\061\061\061\345)))\346$$$\344"
|
||||
"&&&\353\034\034\034\351\035\035\035\352$$$\363%%%\355QQQ\264bbb\014\000\000\000\000\000\000"
|
||||
"\000\000AAA\010///\220\032\032\032\343\035\035\035\336###\326###\335!!!\377\022\022\022"
|
||||
"\377\034\034\034\374\024\024\024\326\015\015\015\316\007\007\007\314\071\071\071\256HHH\015"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\"\"\"\022\040\040\040\066\026\026\026\061GGG\062ddd\266=="
|
||||
"=\377\"\"\"\377???\360<<<<\040\040\040!\025\025\025\036TTT\015\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\\\\\\CFFF\360TTT\377(((\377\027\027"
|
||||
"\027\371\066\066\066};;;\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\217\217\217\040WWW\314UUU\377VVV\377(((\377\007\007\007\377###\330"
|
||||
"AAA\063WWW\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000iii\006LLL\200M"
|
||||
"MM\374bbb\377WWW\377$$$\377\017\017\017\377\032\032\032\375===\312\064\064\064\040"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\202\202\202=NNN\362bbb\377"
|
||||
"ccc\377SSS\377$$$\377\014\014\014\377\"\"\"\377\040\040\040\370\066\066\066zKKK\004"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\177\177\177\032NNN\300WWW\376hhh\377]]]\377"
|
||||
"WWW\377'''\377\017\017\017\377%%%\377&&&\377+++\343JJJ\071\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000TTT\001OOOXAAA\376^^^\377^^^\377___\377LLL\377\"\"\"\377\017\017\017\377"
|
||||
"\"\"\"\377&&&\377\033\033\033\377```\273xxx\014\000\000\000\000\000\000\000\000TTT\010AAAz&&&"
|
||||
"\256\067\067\067\256\061\061\061\256...\256'''\256\021\021\021\256\005\005\005\256\022\022"
|
||||
"\022\256\037\037\037\256\030\030\030\256FFF\242UUU\014\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000$$$\001\060\060\060\001(((\001\"\"\"\001!!!\001\016\016\016\001\004\004\004\001\020\020\020\001\037"
|
||||
"\037\037\001\030\030\030\001AAA\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000",
|
||||
};
|
||||
|
||||
QIcon createStepUpIcon()
|
||||
{
|
||||
QImage img(stepUpImageData.pixel_data,stepUpImageData.width, stepUpImageData.height, QImage::Format_ARGB32 );
|
||||
QPixmap pxMap;
|
||||
pxMap = QPixmap::fromImage(img);
|
||||
|
||||
return QIcon(pxMap);
|
||||
}
|
||||
|
||||
static const QIcon& stepUpIcon()
|
||||
{
|
||||
static QIcon stepUpIcon(createStepUpIcon());
|
||||
return stepUpIcon;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -129,22 +243,22 @@ void PdmUiComboBoxEditor::configureAndUpdateUi(const QString& uiConfigName)
|
||||
|
||||
if (m_comboBox->count() == 0 || m_comboBox->currentIndex() <= 0)
|
||||
{
|
||||
QIcon disabledIcon(QApplication::style()->standardIcon(QStyle::SP_ArrowUp).pixmap(16, 16, QIcon::Disabled));
|
||||
QIcon disabledIcon(stepUpIcon().pixmap(16, 16, QIcon::Disabled));
|
||||
m_previousItemButton->setIcon(disabledIcon);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_previousItemButton->setIcon(QApplication::style()->standardIcon(QStyle::SP_ArrowUp));
|
||||
m_previousItemButton->setIcon(stepUpIcon());
|
||||
}
|
||||
|
||||
if (m_comboBox->count() == 0 || m_comboBox->currentIndex() >= m_comboBox->count() - 1)
|
||||
{
|
||||
QIcon disabledIcon(QApplication::style()->standardIcon(QStyle::SP_ArrowDown).pixmap(16, 16, QIcon::Disabled));
|
||||
QIcon disabledIcon(stepDownIcon().pixmap(16, 16, QIcon::Disabled));
|
||||
m_nextItemButton->setIcon(disabledIcon);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_nextItemButton->setIcon(QApplication::style()->standardIcon(QStyle::SP_ArrowDown));
|
||||
m_nextItemButton->setIcon(stepDownIcon());
|
||||
}
|
||||
|
||||
// Update button texts
|
||||
|
Loading…
Reference in New Issue
Block a user