mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Merged down changes from Resinsight dev branch
This commit is contained in:
commit
cc72c7b2f6
@ -38,6 +38,9 @@
|
||||
|
||||
#include "RigCaseData.h"
|
||||
#include "RifReaderEclipseInput.h"
|
||||
#include "RifEclipseInputFileTools.h"
|
||||
|
||||
#include <QFile>
|
||||
|
||||
#if 0
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -100,6 +103,8 @@ TEST(RigReservoirTest, WellTestErt)
|
||||
|
||||
well_info_free( well_info );
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// This file contains test code taken from the test cases in ERT source code.
|
||||
// There is a typedef issue (center) between ERT and QTextStream, so this file does not include any
|
||||
@ -107,12 +112,88 @@ TEST(RigReservoirTest, WellTestErt)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(RigReservoirTest, ElipseInputGridFile)
|
||||
{
|
||||
RigReservoir res;
|
||||
RigCaseData res;
|
||||
RifReaderEclipseInput inputReader;
|
||||
bool result = inputReader.open("TEST10K_FLT_LGR_NNC.grdecl", &res);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(size_t(1), res.mainGrid()->cells().size());
|
||||
EXPECT_EQ(size_t(1), res.mainGrid()->globalMatrixModelActiveCellCount());
|
||||
}
|
||||
|
||||
|
||||
TEST(RigReservoirTest, ReadFaults)
|
||||
{
|
||||
// QString filename("d:/Models/Statoil/testcase_juli_2011/data/grid_local.grdecl");
|
||||
//
|
||||
// std::vector< RifKeywordAndFilePos > fileKeywords;
|
||||
// RifEclipseInputFileTools::findKeywordsOnFile(filename, fileKeywords);
|
||||
//
|
||||
// cvf::Collection<RigFault> faults;
|
||||
//
|
||||
// RifEclipseInputFileTools::readFaults(filename, faults, fileKeywords);
|
||||
|
||||
// for (size_t j = 0; j < faults.size(); j++)
|
||||
// {
|
||||
// printf(faults.at(j)->name().toLatin1());
|
||||
// printf("\n");
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(RigReservoirTest, ReadFaultsRecursively)
|
||||
{
|
||||
//TODO: Establish a way to define location of test model files
|
||||
|
||||
QString filename("d:/Models/Statoil/TEST_RKMFAULTS/TEST_RKMFAULTS.DATA");
|
||||
// QString filename("d:/gitroot/ResInsight/TestModels/fault_test/regular27cell.DATA");
|
||||
|
||||
QString outFilename = "c:/tmp/TestModels/TEST_RKMFAULTS/msj_faults.txt";
|
||||
QFile outputFile(outFilename);
|
||||
{
|
||||
if (!outputFile.open(QIODevice::WriteOnly))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QTextStream outStream(&outputFile);
|
||||
|
||||
cvf::Collection<RigFault> faults;
|
||||
|
||||
RifEclipseInputFileTools::readFaultsInGridSection(filename, faults);
|
||||
|
||||
// EXPECT_EQ(4, faults.size());
|
||||
|
||||
for (size_t j = 0; j < faults.size(); j++)
|
||||
{
|
||||
const RigFault* rigFault = faults.at(j);
|
||||
|
||||
printf(rigFault->name().toLatin1());
|
||||
|
||||
for (size_t faceType = 0; faceType < 6; faceType++)
|
||||
{
|
||||
cvf::StructGridInterface::FaceType faceEnum = cvf::StructGridInterface::FaceType(faceType);
|
||||
const std::vector<cvf::CellRange>& cellRanges = rigFault->cellRangeForFace(faceEnum);
|
||||
|
||||
for (size_t i = 0; i < cellRanges.size(); i++)
|
||||
{
|
||||
cvf::Vec3st min, max;
|
||||
cellRanges[i].range(min, max);
|
||||
|
||||
QString tmp;
|
||||
tmp = tmp.sprintf("min i=%3d j=%3d k=%3d - max i=%3d j=%3d k=%3d \n", min.x(), min.y(), min.z(), max.x(), max.y(), max.z());
|
||||
|
||||
outStream << tmp;
|
||||
|
||||
// printf("min i=%3d j=%3d k=%3d - max i=%3d j=%3d k=%3d ", min.x(), min.y(), min.z(), max.x(), max.y(), max.z());
|
||||
// printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include <iostream>
|
||||
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
#include <QTextStream>
|
||||
#include <QDebug>
|
||||
|
||||
@ -35,10 +37,14 @@
|
||||
#include "well_state.h"
|
||||
#include "util.h"
|
||||
#include <fstream>
|
||||
#include "RigGridScalarDataAccess.h"
|
||||
|
||||
|
||||
|
||||
QString includeKeyword("INCLUDE");
|
||||
QString faultsKeyword("FAULTS");
|
||||
QString editKeyword("EDIT");
|
||||
QString gridKeyword("GRID");
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Constructor
|
||||
@ -65,13 +71,16 @@ bool RifEclipseInputFileTools::openGridFile(const QString& fileName, RigCaseData
|
||||
{
|
||||
CVF_ASSERT(eclipseCase);
|
||||
|
||||
std::vector< RifKeywordAndFilePos > keywordsAndFilePos;
|
||||
findKeywordsOnFile(fileName, keywordsAndFilePos);
|
||||
|
||||
qint64 coordPos = -1;
|
||||
qint64 zcornPos = -1;
|
||||
qint64 specgridPos = -1;
|
||||
qint64 actnumPos = -1;
|
||||
qint64 mapaxesPos = -1;
|
||||
|
||||
findGridKeywordPositions(fileName, &coordPos, &zcornPos, &specgridPos, &actnumPos, &mapaxesPos);
|
||||
findGridKeywordPositions(keywordsAndFilePos, &coordPos, &zcornPos, &specgridPos, &actnumPos, &mapaxesPos);
|
||||
|
||||
if (coordPos < 0 || zcornPos < 0 || specgridPos < 0)
|
||||
{
|
||||
@ -99,7 +108,7 @@ bool RifEclipseInputFileTools::openGridFile(const QString& fileName, RigCaseData
|
||||
ecl_kw_type* mapAxesKw = NULL;
|
||||
|
||||
// Try to read all the needed keywords. Early exit if some are not found
|
||||
caf::ProgressInfo progress(7, "Read Grid from Eclipse Input file");
|
||||
caf::ProgressInfo progress(8, "Read Grid from Eclipse Input file");
|
||||
|
||||
|
||||
|
||||
@ -157,6 +166,15 @@ bool RifEclipseInputFileTools::openGridFile(const QString& fileName, RigCaseData
|
||||
RifReaderEclipseOutput::transferGeometry(inputGrid, eclipseCase);
|
||||
|
||||
progress.setProgress(7);
|
||||
progress.setProgressDescription("Read faults ...");
|
||||
|
||||
cvf::Collection<RigFault> faults;
|
||||
RifEclipseInputFileTools::readFaults(fileName, faults, keywordsAndFilePos);
|
||||
|
||||
RigMainGrid* mainGrid = eclipseCase->mainGrid();
|
||||
mainGrid->setFaults(faults);
|
||||
|
||||
progress.setProgress(8);
|
||||
progress.setProgressDescription("Cleaning up ...");
|
||||
|
||||
ecl_kw_free(specGridKw);
|
||||
@ -189,7 +207,8 @@ std::map<QString, QString> RifEclipseInputFileTools::readProperties(const QStri
|
||||
caf::ProgressInfo mainProgress(2, "Reading Eclipse Input properties");
|
||||
caf::ProgressInfo startProgress(knownKeywordSet.size(), "Scanning for known properties");
|
||||
|
||||
std::vector<RifKeywordAndFilePos> fileKeywords = RifEclipseInputFileTools::findKeywordsOnFile(fileName);
|
||||
std::vector<RifKeywordAndFilePos> fileKeywords;
|
||||
RifEclipseInputFileTools::findKeywordsOnFile(fileName, fileKeywords);
|
||||
|
||||
mainProgress.setProgress(1);
|
||||
caf::ProgressInfo progress(fileKeywords.size(), "Reading properties");
|
||||
@ -242,10 +261,8 @@ std::map<QString, QString> RifEclipseInputFileTools::readProperties(const QStri
|
||||
// https://bugreports.qt-project.org/browse/QTBUG-9814
|
||||
//
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector< RifKeywordAndFilePos > RifEclipseInputFileTools::findKeywordsOnFile(const QString &fileName)
|
||||
void RifEclipseInputFileTools::findKeywordsOnFile(const QString &fileName, std::vector< RifKeywordAndFilePos >& keywords)
|
||||
{
|
||||
std::vector< RifKeywordAndFilePos > keywords;
|
||||
|
||||
char buf[1024];
|
||||
|
||||
QFile data(fileName);
|
||||
@ -274,8 +291,6 @@ std::vector< RifKeywordAndFilePos > RifEclipseInputFileTools::findKeywordsOnFile
|
||||
}
|
||||
}
|
||||
while (lineLength != -1);
|
||||
|
||||
return keywords;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -484,12 +499,10 @@ void RifEclipseInputFileTools::writeDataToTextFile(QFile* file, const QString& e
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifEclipseInputFileTools::findGridKeywordPositions(const QString& filename, qint64* coordPos, qint64* zcornPos, qint64* specgridPos, qint64* actnumPos, qint64* mapaxesPos)
|
||||
void RifEclipseInputFileTools::findGridKeywordPositions(const std::vector< RifKeywordAndFilePos >& keywordsAndFilePos, qint64* coordPos, qint64* zcornPos, qint64* specgridPos, qint64* actnumPos, qint64* mapaxesPos)
|
||||
{
|
||||
CVF_ASSERT(coordPos && zcornPos && specgridPos && actnumPos && mapaxesPos);
|
||||
|
||||
|
||||
std::vector< RifKeywordAndFilePos > keywordsAndFilePos = findKeywordsOnFile(filename);
|
||||
size_t i;
|
||||
for (i = 0; i < keywordsAndFilePos.size(); i++)
|
||||
{
|
||||
@ -549,3 +562,294 @@ bool RifEclipseInputFileTools::readPropertyAtFilePosition(const QString& fileNam
|
||||
util_fclose(filePointer);
|
||||
return isOk;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifEclipseInputFileTools::readFaults(const QString& fileName, cvf::Collection<RigFault>& faults, const std::vector<RifKeywordAndFilePos>& fileKeywords)
|
||||
{
|
||||
QFile data(fileName);
|
||||
if (!data.open(QFile::ReadOnly))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < fileKeywords.size(); i++)
|
||||
{
|
||||
if (fileKeywords[i].keyword.compare(editKeyword, Qt::CaseInsensitive) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (fileKeywords[i].keyword.compare(faultsKeyword, Qt::CaseInsensitive) != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
qint64 filePos = fileKeywords[i].filePos;
|
||||
|
||||
bool isEditKeywordDetected = false;
|
||||
readFaults(data, filePos, faults, &isEditKeywordDetected);
|
||||
|
||||
if (isEditKeywordDetected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifEclipseInputFileTools::readFaultsInGridSection(const QString& fileName, cvf::Collection<RigFault>& faults)
|
||||
{
|
||||
QFile data(fileName);
|
||||
if (!data.open(QFile::ReadOnly))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QString gridKeyword("GRID");
|
||||
|
||||
// Search for keyword grid
|
||||
|
||||
qint64 gridPos = findKeyword(gridKeyword, data);
|
||||
if (gridPos < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool isEditKeywordDetected = false;
|
||||
|
||||
readFaultsAndParseIncludeStatementsRecursively(data, gridPos, faults, &isEditKeywordDetected);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RifEclipseInputFileTools::findFaultByName(const cvf::Collection<RigFault>& faults, const QString& name)
|
||||
{
|
||||
for (size_t i = 0; i < faults.size(); i++)
|
||||
{
|
||||
if (faults.at(i)->name() == name)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return cvf::UNDEFINED_SIZE_T;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
qint64 RifEclipseInputFileTools::findKeyword(const QString& keyword, QFile& file)
|
||||
{
|
||||
QString line;
|
||||
|
||||
do
|
||||
{
|
||||
line = file.readLine();
|
||||
if (line.startsWith("--", Qt::CaseInsensitive))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
line = line.trimmed();
|
||||
|
||||
if (line.startsWith(keyword, Qt::CaseInsensitive))
|
||||
{
|
||||
return file.pos();
|
||||
}
|
||||
|
||||
} while (!file.atEnd());
|
||||
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifEclipseInputFileTools::readFaultsAndParseIncludeStatementsRecursively(QFile& file, qint64 startPos, cvf::Collection<RigFault>& faults, bool* isEditKeywordDetected)
|
||||
{
|
||||
QString line;
|
||||
|
||||
if (!file.seek(startPos))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool continueParsing = true;
|
||||
|
||||
do
|
||||
{
|
||||
line = file.readLine();
|
||||
if (line.startsWith("--", Qt::CaseInsensitive))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (line.startsWith(editKeyword, Qt::CaseInsensitive))
|
||||
{
|
||||
if (isEditKeywordDetected)
|
||||
{
|
||||
*isEditKeywordDetected = true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
line = line.trimmed();
|
||||
if (line.startsWith(includeKeyword, Qt::CaseInsensitive))
|
||||
{
|
||||
QString nextLine = file.readLine();
|
||||
|
||||
int firstQuote = nextLine.indexOf("'");
|
||||
int lastQuote = nextLine.lastIndexOf("'");
|
||||
|
||||
if (!(firstQuote < 0 || lastQuote < 0 || firstQuote == lastQuote))
|
||||
{
|
||||
QDir currentFileFolder;
|
||||
{
|
||||
QFileInfo fi(file.fileName());
|
||||
currentFileFolder = fi.absoluteDir();
|
||||
}
|
||||
|
||||
// Read include file name, and both relative and absolute path is supported
|
||||
QString includeFilename = nextLine.mid(firstQuote + 1, lastQuote - firstQuote - 1);
|
||||
QFileInfo fi(currentFileFolder, includeFilename);
|
||||
if (fi.exists())
|
||||
{
|
||||
QString absoluteFilename = fi.canonicalFilePath();
|
||||
QFile includeFile(absoluteFilename);
|
||||
if (includeFile.open(QFile::ReadOnly))
|
||||
{
|
||||
qDebug() << "Found include statement, and start parsing of\n " << absoluteFilename;
|
||||
|
||||
if (!readFaultsAndParseIncludeStatementsRecursively(includeFile, 0, faults, isEditKeywordDetected))
|
||||
{
|
||||
qDebug() << "Error when parsing include file : " << absoluteFilename;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (line.startsWith(faultsKeyword, Qt::CaseInsensitive))
|
||||
{
|
||||
readFaults(file, file.pos(), faults, isEditKeywordDetected);
|
||||
}
|
||||
|
||||
if (isEditKeywordDetected && *isEditKeywordDetected)
|
||||
{
|
||||
continueParsing = false;
|
||||
}
|
||||
|
||||
if (file.atEnd())
|
||||
{
|
||||
continueParsing = false;
|
||||
}
|
||||
|
||||
} while (continueParsing);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// The file pointer is pointing at the line following the FAULTS keyword.
|
||||
/// Parse content of this keyword until end of file or
|
||||
/// end of keyword when a single line with '/' is found
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifEclipseInputFileTools::readFaults(QFile &data, qint64 filePos, cvf::Collection<RigFault> &faults, bool* isEditKeywordDetected)
|
||||
{
|
||||
if (!data.seek(filePos))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "Reading faults from\n " << data.fileName();
|
||||
|
||||
RigFault* fault = NULL;
|
||||
|
||||
do
|
||||
{
|
||||
QString line = data.readLine();
|
||||
line = line.trimmed();
|
||||
|
||||
if (line.startsWith("--", Qt::CaseInsensitive))
|
||||
{
|
||||
// Skip comment lines
|
||||
continue;
|
||||
}
|
||||
else if (line.startsWith("/", Qt::CaseInsensitive))
|
||||
{
|
||||
// Detected end of keyword data section
|
||||
return;
|
||||
}
|
||||
else if (line.startsWith(editKeyword, Qt::CaseInsensitive))
|
||||
{
|
||||
// End parsing when edit keyword is detected
|
||||
|
||||
if (isEditKeywordDetected)
|
||||
{
|
||||
*isEditKeywordDetected = true;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Replace tab with space to be able to split the string using space as splitter
|
||||
line.replace("\t", " ");
|
||||
|
||||
QStringList entries = line.split(" ", QString::SkipEmptyParts);
|
||||
if (entries.size() < 8)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
QString name = entries[0];
|
||||
name.remove("'");
|
||||
|
||||
int i1, i2, j1, j2, k1, k2;
|
||||
i1 = entries[1].toInt();
|
||||
i2 = entries[2].toInt();
|
||||
j1 = entries[3].toInt();
|
||||
j2 = entries[4].toInt();
|
||||
k1 = entries[5].toInt();
|
||||
k2 = entries[6].toInt();
|
||||
|
||||
QString faceString = entries[7];
|
||||
faceString.remove("'");
|
||||
|
||||
cvf::StructGridInterface::FaceEnum cellFaceEnum = cvf::StructGridInterface::FaceEnum::fromText(faceString);
|
||||
|
||||
cvf::CellRange cellrange(i1 - 1, j1 - 1, k1 - 1, i2 - 1, j2 - 1, k2 - 1); // Adjust from 1-based to 0-based cell indices
|
||||
|
||||
if (!(fault && fault->name() == name))
|
||||
{
|
||||
if (findFaultByName(faults, name) == cvf::UNDEFINED_SIZE_T)
|
||||
{
|
||||
RigFault* newFault = new RigFault;
|
||||
newFault->setName(name);
|
||||
|
||||
faults.push_back(newFault);
|
||||
}
|
||||
|
||||
size_t faultIndex = findFaultByName(faults, name);
|
||||
if (faultIndex == cvf::UNDEFINED_SIZE_T)
|
||||
{
|
||||
CVF_ASSERT(faultIndex != cvf::UNDEFINED_SIZE_T);
|
||||
continue;
|
||||
}
|
||||
|
||||
fault = faults.at(faultIndex);
|
||||
}
|
||||
|
||||
CVF_ASSERT(fault);
|
||||
|
||||
fault->addCellRangeForFace(cellFaceEnum, cellrange);
|
||||
|
||||
} while (!data.atEnd());
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include <QString>
|
||||
#include "RifReaderInterface.h"
|
||||
#include "RigFault.h"
|
||||
|
||||
|
||||
class RigCaseData;
|
||||
@ -58,15 +59,27 @@ public:
|
||||
static std::map<QString, QString> readProperties(const QString& fileName, RigCaseData* eclipseCase);
|
||||
static bool readProperty (const QString& fileName, RigCaseData* eclipseCase, const QString& eclipseKeyWord, const QString& resultName );
|
||||
static bool readPropertyAtFilePosition (const QString& fileName, RigCaseData* eclipseCase, const QString& eclipseKeyWord, qint64 filePos, const QString& resultName );
|
||||
|
||||
|
||||
static void readFaultsInGridSection(const QString& fileName, cvf::Collection<RigFault>& faults);
|
||||
static void readFaults(const QString& fileName, cvf::Collection<RigFault>& faults, const std::vector< RifKeywordAndFilePos >& fileKeywords);
|
||||
|
||||
static std::vector< RifKeywordAndFilePos > findKeywordsOnFile(const QString &fileName);
|
||||
static void readFaults(QFile &data, qint64 filePos, cvf::Collection<RigFault> &faults, bool* isEditKeywordDetected);
|
||||
static void findKeywordsOnFile(const QString &fileName, std::vector< RifKeywordAndFilePos >& keywords);
|
||||
|
||||
static const std::vector<QString>& knownPropertyKeywords();
|
||||
|
||||
static bool writePropertyToTextFile(const QString& fileName, RigCaseData* eclipseCase, size_t timeStep, const QString& resultName, const QString& eclipseKeyWord);
|
||||
static bool writeBinaryResultToTextFile(const QString& fileName, RigCaseData* eclipseCase, RifReaderInterface::PorosityModelResultType porosityModel, size_t timeStep, const QString& resultName, const QString& eclipseKeyWord, const double undefinedValue);
|
||||
|
||||
static bool readFaultsAndParseIncludeStatementsRecursively(QFile& file, qint64 startPos, cvf::Collection<RigFault>& faults, bool* isEditKeywordDetected);
|
||||
|
||||
private:
|
||||
static void writeDataToTextFile(QFile* file, const QString& eclipseKeyWord, const std::vector<double>& resultData);
|
||||
static void findGridKeywordPositions(const QString& filename, qint64* coordPos, qint64* zcornPos, qint64* specgridPos, qint64* actnumPos, qint64* mapaxesPos);
|
||||
static void findGridKeywordPositions(const std::vector< RifKeywordAndFilePos >& keywords, qint64* coordPos, qint64* zcornPos, qint64* specgridPos, qint64* actnumPos, qint64* mapaxesPos);
|
||||
|
||||
static size_t findFaultByName(const cvf::Collection<RigFault>& faults, const QString& name);
|
||||
|
||||
static qint64 findKeyword(const QString& keyword, QFile& file);
|
||||
|
||||
};
|
||||
|
@ -36,6 +36,7 @@
|
||||
|
||||
#include "cafProgressInfo.h"
|
||||
#include <map>
|
||||
#include "RifEclipseInputFileTools.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// ECLIPSE cell numbering layout:
|
||||
@ -368,17 +369,37 @@ bool RifReaderEclipseOutput::open(const QString& fileName, RigCaseData* eclipseC
|
||||
progInfo.setProgressDescription("Transferring grid geometry");
|
||||
|
||||
if (!transferGeometry(mainEclGrid, eclipseCase)) return false;
|
||||
|
||||
progInfo.incrementProgress();
|
||||
progInfo.setProgressDescription("Reading faults");
|
||||
progInfo.setNextProgressIncrement(10);
|
||||
|
||||
foreach (QString fname, fileSet)
|
||||
{
|
||||
if (fname.endsWith(".DATA"))
|
||||
{
|
||||
cvf::Collection<RigFault> faults;
|
||||
RifEclipseInputFileTools::readFaultsInGridSection(fname, faults);
|
||||
|
||||
RigMainGrid* mainGrid = eclipseCase->mainGrid();
|
||||
mainGrid->setFaults(faults);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
progInfo.incrementProgress();
|
||||
|
||||
m_eclipseCase = eclipseCase;
|
||||
|
||||
progInfo.setProgressDescription("Reading Result index");
|
||||
progInfo.setNextProgressIncrement(60);
|
||||
progInfo.setNextProgressIncrement(50);
|
||||
|
||||
// Build results meta data
|
||||
buildMetaData();
|
||||
progInfo.incrementProgress();
|
||||
|
||||
|
||||
|
||||
progInfo.incrementProgress();
|
||||
progInfo.setNextProgressIncrement(8);
|
||||
progInfo.setProgressDescription("Reading Well information");
|
||||
readWellCells(mainEclGrid);
|
||||
|
@ -6,6 +6,10 @@ endif()
|
||||
|
||||
set (SOURCE_GROUP_HEADER_FILES
|
||||
${CEE_CURRENT_LIST_DIR}RivCellEdgeEffectGenerator.h
|
||||
${CEE_CURRENT_LIST_DIR}RivColorTableArray.h
|
||||
${CEE_CURRENT_LIST_DIR}RivFaultPart.h
|
||||
${CEE_CURRENT_LIST_DIR}RivFaultPartMgr.h
|
||||
${CEE_CURRENT_LIST_DIR}RivFaultGeometryGenerator.h
|
||||
${CEE_CURRENT_LIST_DIR}RivGridPartMgr.h
|
||||
${CEE_CURRENT_LIST_DIR}RivReservoirPartMgr.h
|
||||
${CEE_CURRENT_LIST_DIR}RivReservoirViewPartMgr.h
|
||||
@ -19,6 +23,10 @@ ${CEE_CURRENT_LIST_DIR}RivWellHeadPartMgr.h
|
||||
|
||||
set (SOURCE_GROUP_SOURCE_FILES
|
||||
${CEE_CURRENT_LIST_DIR}RivCellEdgeEffectGenerator.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RivColorTableArray.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RivFaultPart.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RivFaultPartMgr.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RivFaultGeometryGenerator.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RivGridPartMgr.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RivReservoirPartMgr.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RivReservoirViewPartMgr.cpp
|
||||
|
43
ApplicationCode/ModelVisualization/RivColorTableArray.cpp
Normal file
43
ApplicationCode/ModelVisualization/RivColorTableArray.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) Statoil ASA, Ceetron Solutions AS
|
||||
//
|
||||
// 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 "RivColorTableArray.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::ref<cvf::Color3fArray> RivColorTableArray::colorTableArray()
|
||||
{
|
||||
cvf::ref<cvf::Color3fArray> partColors = new cvf::Color3fArray();
|
||||
partColors->reserve(10);
|
||||
|
||||
partColors->add(cvf::Color3f(101.0f/255, 132.0f/255, 96.0f/255)); // Dark green
|
||||
partColors->add(cvf::Color3f(255.0f/255, 131.0f/255, 140.0f/255)); // Old pink
|
||||
partColors->add(cvf::Color3f(210.0f/255, 176.0f/255, 112.0f/255)); // Light Brown
|
||||
partColors->add(cvf::Color3f(140.0f/255, 171.0f/255, 238.0f/255)); // Light gray blue
|
||||
partColors->add(cvf::Color3f(255.0f/255, 205.0f/255, 131.0f/255)); // Peach
|
||||
partColors->add(cvf::Color3f(220.0f/255, 212.0f/255, 166.0f/255)); // Dark off white
|
||||
partColors->add(cvf::Color3f(130.0f/255, 255.0f/255, 120.0f/255)); // Light green
|
||||
partColors->add(cvf::Color3f(166.0f/255, 220.0f/255, 215.0f/255)); // Light gray torquise
|
||||
partColors->add(cvf::Color3f(168.0f/255, 220.0f/255, 166.0f/255)); // Light gray green
|
||||
partColors->add(cvf::Color3f(255.0f/255, 64.0f/255, 236.0f/255)); // Magneta
|
||||
|
||||
return partColors;
|
||||
}
|
||||
|
29
ApplicationCode/ModelVisualization/RivColorTableArray.h
Normal file
29
ApplicationCode/ModelVisualization/RivColorTableArray.h
Normal file
@ -0,0 +1,29 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) Statoil ASA, Ceetron Solutions AS
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfObject.h"
|
||||
#include "cvfArray.h"
|
||||
|
||||
class RivColorTableArray
|
||||
{
|
||||
public:
|
||||
static cvf::ref<cvf::Color3fArray> colorTableArray();
|
||||
};
|
309
ApplicationCode/ModelVisualization/RivFaultGeometryGenerator.cpp
Normal file
309
ApplicationCode/ModelVisualization/RivFaultGeometryGenerator.cpp
Normal file
@ -0,0 +1,309 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) Statoil ASA, Ceetron Solutions AS
|
||||
//
|
||||
// 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 "RivFaultGeometryGenerator.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "cvfDrawableGeo.h"
|
||||
#include "cvfPrimitiveSetIndexedUInt.h"
|
||||
#include "cvfOutlineEdgeExtractor.h"
|
||||
#include "cvfStructGridScalarDataAccess.h"
|
||||
#include "cvfScalarMapper.h"
|
||||
|
||||
#include "RigFault.h"
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RivFaultGeometryGenerator::RivFaultGeometryGenerator(const cvf::StructGridInterface* grid, const RigFault* fault)
|
||||
: m_grid(grid),
|
||||
m_fault(fault)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RivFaultGeometryGenerator::~RivFaultGeometryGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Generate surface drawable geo from the specified region
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::ref<cvf::DrawableGeo> RivFaultGeometryGenerator::generateSurface()
|
||||
{
|
||||
computeArrays();
|
||||
|
||||
CVF_ASSERT(m_vertices.notNull());
|
||||
|
||||
if (m_vertices->size() == 0) return NULL;
|
||||
|
||||
cvf::ref<cvf::DrawableGeo> geo = new cvf::DrawableGeo;
|
||||
geo->setFromQuadVertexArray(m_vertices.p());
|
||||
|
||||
return geo;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Generates simplified mesh as line drawing
|
||||
/// Must call generateSurface first
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::ref<cvf::DrawableGeo> RivFaultGeometryGenerator::createMeshDrawable()
|
||||
{
|
||||
|
||||
if (!(m_vertices.notNull() && m_vertices->size() != 0)) return NULL;
|
||||
|
||||
cvf::ref<cvf::DrawableGeo> geo = new cvf::DrawableGeo;
|
||||
geo->setVertexArray(m_vertices.p());
|
||||
|
||||
cvf::ref<cvf::UIntArray> indices = lineIndicesFromQuadVertexArray(m_vertices.p());
|
||||
cvf::ref<cvf::PrimitiveSetIndexedUInt> prim = new cvf::PrimitiveSetIndexedUInt(cvf::PT_LINES);
|
||||
prim->setIndices(indices.p());
|
||||
|
||||
geo->addPrimitiveSet(prim.p());
|
||||
return geo;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::ref<cvf::DrawableGeo> RivFaultGeometryGenerator::createOutlineMeshDrawable(double creaseAngle)
|
||||
{
|
||||
if (!(m_vertices.notNull() && m_vertices->size() != 0)) return NULL;
|
||||
|
||||
cvf::OutlineEdgeExtractor ee(creaseAngle, *m_vertices);
|
||||
|
||||
cvf::ref<cvf::UIntArray> indices = lineIndicesFromQuadVertexArray(m_vertices.p());
|
||||
ee.addPrimitives(4, *indices);
|
||||
|
||||
cvf::ref<cvf::UIntArray> lineIndices = ee.lineIndices();
|
||||
if (lineIndices->size() == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cvf::ref<cvf::PrimitiveSetIndexedUInt> prim = new cvf::PrimitiveSetIndexedUInt(cvf::PT_LINES);
|
||||
prim->setIndices(lineIndices.p());
|
||||
|
||||
cvf::ref<cvf::DrawableGeo> geo = new cvf::DrawableGeo;
|
||||
geo->setVertexArray(m_vertices.p());
|
||||
geo->addPrimitiveSet(prim.p());
|
||||
|
||||
return geo;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::ref<cvf::UIntArray> RivFaultGeometryGenerator::lineIndicesFromQuadVertexArray(const cvf::Vec3fArray* vertexArray)
|
||||
{
|
||||
CVF_ASSERT(vertexArray);
|
||||
|
||||
size_t numVertices = vertexArray->size();
|
||||
int numQuads = static_cast<int>(numVertices/4);
|
||||
CVF_ASSERT(numVertices%4 == 0);
|
||||
|
||||
cvf::ref<cvf::UIntArray> indices = new cvf::UIntArray;
|
||||
indices->resize(numQuads*8);
|
||||
|
||||
#pragma omp parallel for
|
||||
for (int i = 0; i < numQuads; i++)
|
||||
{
|
||||
int idx = 8*i;
|
||||
indices->set(idx + 0, i*4 + 0);
|
||||
indices->set(idx + 1, i*4 + 1);
|
||||
indices->set(idx + 2, i*4 + 1);
|
||||
indices->set(idx + 3, i*4 + 2);
|
||||
indices->set(idx + 4, i*4 + 2);
|
||||
indices->set(idx + 5, i*4 + 3);
|
||||
indices->set(idx + 6, i*4 + 3);
|
||||
indices->set(idx + 7, i*4 + 0);
|
||||
}
|
||||
|
||||
return indices;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivFaultGeometryGenerator::computeArrays()
|
||||
{
|
||||
std::vector<cvf::Vec3f> vertices;
|
||||
m_quadsToGridCells.clear();
|
||||
m_quadsToFace.clear();
|
||||
|
||||
cvf::Vec3d offset = m_grid->displayModelOffset();
|
||||
|
||||
|
||||
for (size_t faceType = 0; faceType < 6; faceType++)
|
||||
{
|
||||
cvf::StructGridInterface::FaceType faceEnum = cvf::StructGridInterface::FaceType(faceType);
|
||||
const std::vector<cvf::CellRange>& cellRanges = m_fault->cellRangeForFace(faceEnum);
|
||||
|
||||
for (size_t i = 0; i < cellRanges.size(); i++)
|
||||
{
|
||||
const cvf::CellRange& cellRange = cellRanges[i];
|
||||
|
||||
std::vector<size_t> gridCellIndices;
|
||||
computeGlobalCellIndices(cellRange, gridCellIndices);
|
||||
|
||||
for (size_t gIdx = 0; gIdx < gridCellIndices.size(); gIdx++)
|
||||
{
|
||||
size_t cellIndex = gridCellIndices[gIdx];
|
||||
|
||||
if (!(*m_cellVisibility)[cellIndex]) continue;
|
||||
|
||||
cvf::Vec3d cornerVerts[8];
|
||||
m_grid->cellCornerVertices(cellIndex, cornerVerts);
|
||||
|
||||
cvf::ubyte faceConn[4];
|
||||
m_grid->cellFaceVertexIndices(faceEnum, faceConn);
|
||||
|
||||
// Critical section to avoid two threads accessing the arrays at the same time.
|
||||
#pragma omp critical
|
||||
{
|
||||
int n;
|
||||
for (n = 0; n < 4; n++)
|
||||
{
|
||||
vertices.push_back(cvf::Vec3f(cornerVerts[faceConn[n]] - offset));
|
||||
}
|
||||
|
||||
// Keep track of the source cell index per quad
|
||||
m_quadsToGridCells.push_back(cellIndex);
|
||||
m_quadsToFace.push_back(faceEnum);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_vertices = new cvf::Vec3fArray;
|
||||
m_vertices->assign(vertices);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Calculates the texture coordinates in a "nearly" one dimensional texture.
|
||||
/// Undefined values are coded with a y-texture coordinate value of 1.0 instead of the normal 0.5
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivFaultGeometryGenerator::textureCoordinates(cvf::Vec2fArray* textureCoords, const cvf::StructGridScalarDataAccess* dataAccessObject, const cvf::ScalarMapper* mapper) const
|
||||
{
|
||||
if (!dataAccessObject) return;
|
||||
|
||||
size_t numVertices = m_quadsToGridCells.size()*4;
|
||||
|
||||
textureCoords->resize(numVertices);
|
||||
cvf::Vec2f* rawPtr = textureCoords->ptr();
|
||||
|
||||
double cellScalarValue;
|
||||
cvf::Vec2f texCoord;
|
||||
|
||||
#pragma omp parallel for private(texCoord, cellScalarValue)
|
||||
for (int i = 0; i < static_cast<int>(m_quadsToGridCells.size()); i++)
|
||||
{
|
||||
cellScalarValue = dataAccessObject->cellScalar(m_quadsToGridCells[i]);
|
||||
texCoord = mapper->mapToTextureCoord(cellScalarValue);
|
||||
if (cellScalarValue == HUGE_VAL || cellScalarValue != cellScalarValue) // a != a is true for NAN's
|
||||
{
|
||||
texCoord[1] = 1.0f;
|
||||
}
|
||||
|
||||
size_t j;
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
rawPtr[i*4 + j] = texCoord;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::ref<cvf::Array<size_t> > RivFaultGeometryGenerator::triangleToSourceGridCellMap() const
|
||||
{
|
||||
cvf::ref<cvf::Array<size_t> > triangles = new cvf::Array<size_t>(2*m_quadsToGridCells.size());
|
||||
#pragma omp parallel for
|
||||
for (int i = 0; i < static_cast<int>(m_quadsToGridCells.size()); i++)
|
||||
{
|
||||
triangles->set(i*2, m_quadsToGridCells[i]);
|
||||
triangles->set(i*2+1, m_quadsToGridCells[i]);
|
||||
}
|
||||
|
||||
return triangles;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivFaultGeometryGenerator::setCellVisibility(const cvf::UByteArray* cellVisibility)
|
||||
{
|
||||
m_cellVisibility = cellVisibility;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const std::vector<size_t>& RivFaultGeometryGenerator::quadToGridCellIndices() const
|
||||
{
|
||||
return m_quadsToGridCells;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const std::vector<cvf::StructGridInterface::FaceType>& RivFaultGeometryGenerator::quadToFace() const
|
||||
{
|
||||
return m_quadsToFace;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivFaultGeometryGenerator::computeGlobalCellIndices(const cvf::CellRange& cellRange, std::vector<size_t>& gridCellIndices) const
|
||||
{
|
||||
cvf::Vec3st min, max;
|
||||
cellRange.range(min, max);
|
||||
|
||||
for (size_t i = min.x(); i <= max.x(); i++)
|
||||
{
|
||||
if (i >= m_grid->cellCountI())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (size_t j = min.y(); j <= max.y(); j++)
|
||||
{
|
||||
if (j >= m_grid->cellCountJ())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (size_t k = min.z(); k <= max.z(); k++)
|
||||
{
|
||||
if (k >= m_grid->cellCountK())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
gridCellIndices.push_back(m_grid->cellIndexFromIJK(i, j, k));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,85 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) Statoil ASA, Ceetron Solutions AS
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
#include "cvfBase.h"
|
||||
#include "cvfObject.h"
|
||||
|
||||
#include "cvfStructGridGeometryGenerator.h"
|
||||
#include "cvfCellRange.h"
|
||||
|
||||
namespace cvf
|
||||
{
|
||||
class StructGridInterface;
|
||||
class ModelBasicList;
|
||||
class Transform;
|
||||
class Part;
|
||||
}
|
||||
|
||||
class RigFault;
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
class RivFaultGeometryGenerator : public cvf::Object
|
||||
{
|
||||
public:
|
||||
RivFaultGeometryGenerator(const cvf::StructGridInterface* grid, const RigFault* fault);
|
||||
~RivFaultGeometryGenerator();
|
||||
|
||||
void setCellVisibility(const cvf::UByteArray* cellVisibilities );
|
||||
|
||||
void textureCoordinates(cvf::Vec2fArray* textureCoords,
|
||||
const cvf::StructGridScalarDataAccess* dataAccessObject,
|
||||
const cvf::ScalarMapper* mapper) const;
|
||||
|
||||
// Mapping between cells and geometry
|
||||
cvf::ref<cvf::Array<size_t> > triangleToSourceGridCellMap() const;
|
||||
|
||||
const std::vector<size_t>& quadToGridCellIndices() const;
|
||||
const std::vector<cvf::StructGridInterface::FaceType>& quadToFace() const;
|
||||
|
||||
// Generated geometry
|
||||
cvf::ref<cvf::DrawableGeo> generateSurface();
|
||||
cvf::ref<cvf::DrawableGeo> createMeshDrawable();
|
||||
cvf::ref<cvf::DrawableGeo> createOutlineMeshDrawable(double creaseAngle);
|
||||
|
||||
private:
|
||||
static cvf::ref<cvf::UIntArray> lineIndicesFromQuadVertexArray(const cvf::Vec3fArray* vertexArray);
|
||||
|
||||
void computeGlobalCellIndices(const cvf::CellRange& cellRange, std::vector<size_t>& gridCellIndices) const;
|
||||
|
||||
void computeArrays();
|
||||
|
||||
private:
|
||||
// Input
|
||||
cvf::cref<cvf::StructGridInterface> m_grid;
|
||||
cvf::cref<RigFault> m_fault;
|
||||
cvf::cref<cvf::UByteArray> m_cellVisibility;
|
||||
|
||||
// Created arrays
|
||||
cvf::ref<cvf::Vec3fArray> m_vertices;
|
||||
|
||||
// Mappings
|
||||
std::vector<size_t> m_triangleIndexToGridCellIndex;
|
||||
std::vector<size_t> m_quadsToGridCells;
|
||||
std::vector<cvf::StructGridInterface::FaceType> m_quadsToFace;
|
||||
};
|
289
ApplicationCode/ModelVisualization/RivFaultPart.cpp
Normal file
289
ApplicationCode/ModelVisualization/RivFaultPart.cpp
Normal file
@ -0,0 +1,289 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) Statoil ASA, Ceetron Solutions AS
|
||||
//
|
||||
// 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 "RivFaultPart.h"
|
||||
|
||||
#include "cvfPart.h"
|
||||
#include "cafEffectGenerator.h"
|
||||
#include "cvfStructGrid.h"
|
||||
#include "cvfDrawableGeo.h"
|
||||
#include "cvfModelBasicList.h"
|
||||
#include "RivCellEdgeEffectGenerator.h"
|
||||
#include "RimReservoirView.h"
|
||||
#include "RimResultSlot.h"
|
||||
#include "RimCellEdgeResultSlot.h"
|
||||
#include "RigCaseCellResultsData.h"
|
||||
#include "RigCaseData.h"
|
||||
#include "RiaApplication.h"
|
||||
#include "RiaPreferences.h"
|
||||
|
||||
#include "RimCase.h"
|
||||
#include "RimWellCollection.h"
|
||||
#include "cafPdmFieldCvfMat4d.h"
|
||||
#include "cafPdmFieldCvfColor.h"
|
||||
#include "RimCellRangeFilterCollection.h"
|
||||
#include "RimCellPropertyFilterCollection.h"
|
||||
#include "Rim3dOverlayInfoConfig.h"
|
||||
#include "RimReservoirCellResultsCacher.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RivFaultPart::RivFaultPart(const RigGridBase* grid, const RimFault* rimFault)
|
||||
: m_faultGenerator(grid, rimFault->faultGeometry()),
|
||||
m_grid(grid),
|
||||
m_rimFault(rimFault),
|
||||
m_opacityLevel(1.0f),
|
||||
m_defaultColor(cvf::Color3::WHITE)
|
||||
{
|
||||
m_faultFacesTextureCoords = new cvf::Vec2fArray;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivFaultPart::setCellVisibility(cvf::UByteArray* cellVisibilities)
|
||||
{
|
||||
m_faultGenerator.setCellVisibility(cellVisibilities);
|
||||
|
||||
generatePartGeometry();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivFaultPart::updateCellColor(cvf::Color4f color)
|
||||
{
|
||||
m_defaultColor = color;
|
||||
|
||||
updatePartEffect();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivFaultPart::updateCellResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot)
|
||||
{
|
||||
CVF_ASSERT(cellResultSlot);
|
||||
|
||||
size_t scalarSetIndex = cellResultSlot->gridScalarIndex();
|
||||
const cvf::ScalarMapper* mapper = cellResultSlot->legendConfig()->scalarMapper();
|
||||
|
||||
// If the result is static, only read that.
|
||||
size_t resTimeStepIdx = timeStepIndex;
|
||||
if (cellResultSlot->hasStaticResult()) resTimeStepIdx = 0;
|
||||
|
||||
RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultSlot->porosityModel());
|
||||
|
||||
RigCaseData* eclipseCase = cellResultSlot->reservoirView()->eclipseCase()->reservoirData();
|
||||
cvf::ref<cvf::StructGridScalarDataAccess> dataAccessObject = eclipseCase->dataAccessObject(m_grid.p(), porosityModel, resTimeStepIdx, scalarSetIndex);
|
||||
|
||||
if (dataAccessObject.isNull()) return;
|
||||
|
||||
|
||||
// Faults
|
||||
if (m_faultFaces.notNull())
|
||||
{
|
||||
m_faultGenerator.textureCoordinates(m_faultFacesTextureCoords.p(), dataAccessObject.p(), mapper);
|
||||
|
||||
if (m_opacityLevel < 1.0f )
|
||||
{
|
||||
const std::vector<cvf::ubyte>& isWellPipeVisible = cellResultSlot->reservoirView()->wellCollection()->isWellPipesVisible(timeStepIndex);
|
||||
cvf::ref<cvf::UIntArray> gridCellToWellindexMap = eclipseCase->gridCellToWellIndex(m_grid->gridIndex());
|
||||
const std::vector<size_t>& quadsToGridCells = m_faultGenerator.quadToGridCellIndices();
|
||||
|
||||
for(size_t i = 0; i < m_faultFacesTextureCoords->size(); ++i)
|
||||
{
|
||||
if ((*m_faultFacesTextureCoords)[i].y() == 1.0f) continue; // Do not touch undefined values
|
||||
|
||||
size_t quadIdx = i/4;
|
||||
size_t cellIndex = quadsToGridCells[quadIdx];
|
||||
cvf::uint wellIndex = gridCellToWellindexMap->get(cellIndex);
|
||||
if (wellIndex != cvf::UNDEFINED_UINT)
|
||||
{
|
||||
if ( !isWellPipeVisible[wellIndex])
|
||||
{
|
||||
(*m_faultFacesTextureCoords)[i].y() = 0; // Set the Y texture coordinate to the opaque line in the texture
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cvf::DrawableGeo* dg = dynamic_cast<cvf::DrawableGeo*>(m_faultFaces->drawable());
|
||||
if (dg) dg->setTextureCoordArray(m_faultFacesTextureCoords.p());
|
||||
|
||||
bool usePolygonOffset = true;
|
||||
caf::ScalarMapperEffectGenerator scalarEffgen(mapper, usePolygonOffset);
|
||||
|
||||
scalarEffgen.setOpacityLevel(m_opacityLevel);
|
||||
|
||||
cvf::ref<cvf::Effect> scalarEffect = scalarEffgen.generateEffect();
|
||||
|
||||
m_faultFaces->setEffect(scalarEffect.p());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivFaultPart::updateCellEdgeResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot, RimCellEdgeResultSlot* cellEdgeResultSlot)
|
||||
{
|
||||
|
||||
/*
|
||||
if (m_faultFaces.notNull())
|
||||
{
|
||||
cvf::DrawableGeo* dg = dynamic_cast<cvf::DrawableGeo*>(m_faultFaces->drawable());
|
||||
if (dg)
|
||||
{
|
||||
RivCellEdgeGeometryGenerator::addCellEdgeResultsToDrawableGeo(timeStepIndex, cellResultSlot, cellEdgeResultSlot,
|
||||
&m_faultGenerator, dg, m_grid->gridIndex(), m_opacityLevel);
|
||||
|
||||
cvf::ScalarMapper* cellScalarMapper = NULL;
|
||||
if (cellResultSlot->hasResult()) cellScalarMapper = cellResultSlot->legendConfig()->scalarMapper();
|
||||
|
||||
CellEdgeEffectGenerator cellFaceEffectGen(cellEdgeResultSlot->legendConfig()->scalarMapper(), cellScalarMapper);
|
||||
cellFaceEffectGen.setOpacityLevel(m_opacityLevel);
|
||||
cellFaceEffectGen.setDefaultCellColor(m_defaultColor);
|
||||
|
||||
cvf::ref<cvf::Effect> eff = cellFaceEffectGen.generateEffect();
|
||||
|
||||
m_faultFaces->setEffect(eff.p());
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivFaultPart::appendPartsToModel(cvf::ModelBasicList* model)
|
||||
{
|
||||
CVF_ASSERT(model != NULL);
|
||||
|
||||
if (m_rimFault && m_rimFault->showFault())
|
||||
{
|
||||
if(m_faultFaces.notNull() ) model->addPart(m_faultFaces.p() );
|
||||
if(m_faultGridLines.notNull() ) model->addPart(m_faultGridLines.p() );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivFaultPart::generatePartGeometry()
|
||||
{
|
||||
bool useBufferObjects = true;
|
||||
// Surface geometry
|
||||
{
|
||||
cvf::ref<cvf::DrawableGeo> geo = m_faultGenerator.generateSurface();
|
||||
if (geo.notNull())
|
||||
{
|
||||
geo->computeNormals();
|
||||
|
||||
if (useBufferObjects)
|
||||
{
|
||||
geo->setRenderMode(cvf::DrawableGeo::BUFFER_OBJECT);
|
||||
}
|
||||
|
||||
cvf::ref<cvf::Part> part = new cvf::Part;
|
||||
part->setName("Grid " + cvf::String(static_cast<int>(m_grid->gridIndex())));
|
||||
part->setId(m_grid->gridIndex()); // !! For now, use grid index as part ID (needed for pick info)
|
||||
part->setDrawable(geo.p());
|
||||
//part->setTransform(m_scaleTransform.p());
|
||||
|
||||
// Set mapping from triangle face index to cell index
|
||||
part->setSourceInfo(m_faultGenerator.triangleToSourceGridCellMap().p());
|
||||
|
||||
part->updateBoundingBox();
|
||||
part->setEnableMask(faultBit);
|
||||
|
||||
m_faultFaces = part;
|
||||
}
|
||||
}
|
||||
|
||||
// Mesh geometry
|
||||
{
|
||||
cvf::ref<cvf::DrawableGeo> geoMesh = m_faultGenerator.createMeshDrawable();
|
||||
if (geoMesh.notNull())
|
||||
{
|
||||
if (useBufferObjects)
|
||||
{
|
||||
geoMesh->setRenderMode(cvf::DrawableGeo::BUFFER_OBJECT);
|
||||
}
|
||||
|
||||
cvf::ref<cvf::Part> part = new cvf::Part;
|
||||
part->setName("Grid mesh" + cvf::String(static_cast<int>(m_grid->gridIndex())));
|
||||
part->setDrawable(geoMesh.p());
|
||||
|
||||
//part->setTransform(m_scaleTransform.p());
|
||||
part->updateBoundingBox();
|
||||
part->setEnableMask(meshFaultBit);
|
||||
|
||||
m_faultGridLines = part;
|
||||
}
|
||||
}
|
||||
|
||||
updatePartEffect();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivFaultPart::updatePartEffect()
|
||||
{
|
||||
if (m_faultFaces.notNull())
|
||||
{
|
||||
cvf::Color3f partColor = m_defaultColor.toColor3f();
|
||||
|
||||
if (m_rimFault->showFaultColor())
|
||||
{
|
||||
partColor = m_rimFault->faultColor();
|
||||
}
|
||||
|
||||
if (m_defaultColor.a() < 1.0f)
|
||||
{
|
||||
// Set priority to make sure this transparent geometry are rendered last
|
||||
m_faultFaces->setPriority(100);
|
||||
}
|
||||
|
||||
m_opacityLevel = m_defaultColor.a();
|
||||
|
||||
// Set default effect
|
||||
caf::SurfaceEffectGenerator geometryEffgen(partColor, true);
|
||||
cvf::ref<cvf::Effect> geometryOnlyEffect = geometryEffgen.generateEffect();
|
||||
|
||||
m_faultFaces->setEffect(geometryOnlyEffect.p());
|
||||
}
|
||||
|
||||
if (m_faultGridLines.notNull())
|
||||
{
|
||||
// Update mesh colors as well, in case of change
|
||||
RiaPreferences* prefs = RiaApplication::instance()->preferences();
|
||||
|
||||
cvf::ref<cvf::Effect> eff;
|
||||
caf::MeshEffectGenerator faultEffGen(prefs->defaultFaultGridLineColors());
|
||||
eff = faultEffGen.generateEffect();
|
||||
m_faultGridLines->setEffect(eff.p());
|
||||
}
|
||||
}
|
79
ApplicationCode/ModelVisualization/RivFaultPart.h
Normal file
79
ApplicationCode/ModelVisualization/RivFaultPart.h
Normal file
@ -0,0 +1,79 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) Statoil ASA, Ceetron Solutions AS
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
#include "cvfBase.h"
|
||||
#include "cvfObject.h"
|
||||
|
||||
#include "RigGridBase.h"
|
||||
#include "RimFault.h"
|
||||
#include "RivFaultGeometryGenerator.h"
|
||||
#include "cvfColor4.h"
|
||||
|
||||
namespace cvf
|
||||
{
|
||||
class StructGridInterface;
|
||||
class ModelBasicList;
|
||||
class Transform;
|
||||
class Part;
|
||||
}
|
||||
|
||||
class RimResultSlot;
|
||||
class RimCellEdgeResultSlot;
|
||||
class RimFaultCollection;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
class RivFaultPart : public cvf::Object
|
||||
{
|
||||
public:
|
||||
RivFaultPart(const RigGridBase* grid, const RimFault* rimFault);
|
||||
|
||||
void setCellVisibility(cvf::UByteArray* cellVisibilities);
|
||||
|
||||
void updatePartEffect();
|
||||
|
||||
void updateCellColor(cvf::Color4f color);
|
||||
void updateCellResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot);
|
||||
void updateCellEdgeResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot, RimCellEdgeResultSlot* cellEdgeResultSlot);
|
||||
|
||||
void appendPartsToModel(cvf::ModelBasicList* model);
|
||||
|
||||
private:
|
||||
void generatePartGeometry();
|
||||
|
||||
private:
|
||||
cvf::cref<RigGridBase> m_grid;
|
||||
|
||||
RivFaultGeometryGenerator m_faultGenerator;
|
||||
cvf::ref<cvf::Part> m_faultFaces;
|
||||
cvf::ref<cvf::Vec2fArray> m_faultFacesTextureCoords;
|
||||
|
||||
float m_opacityLevel;
|
||||
cvf::Color4f m_defaultColor;
|
||||
|
||||
|
||||
cvf::ref<cvf::Part> m_faultGridLines;
|
||||
|
||||
cvf::ref<cvf::UByteArray> m_cellVisibility;
|
||||
|
||||
const RimFault* m_rimFault;
|
||||
};
|
140
ApplicationCode/ModelVisualization/RivFaultPartMgr.cpp
Normal file
140
ApplicationCode/ModelVisualization/RivFaultPartMgr.cpp
Normal file
@ -0,0 +1,140 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) Statoil ASA, Ceetron Solutions AS
|
||||
//
|
||||
// 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 "RivFaultPartMgr.h"
|
||||
|
||||
#include "cvfPart.h"
|
||||
#include "cvfModelBasicList.h"
|
||||
#include "cvfColor3.h"
|
||||
#include "cvfTransform.h"
|
||||
|
||||
#include "cafPdmFieldCvfColor.h"
|
||||
|
||||
#include "RimFaultCollection.h"
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RivFaultPartMgr::RivFaultPartMgr(const RigGridBase* grid, size_t gridIdx, const RimFaultCollection* faultCollection)
|
||||
: m_gridIdx(gridIdx),
|
||||
m_grid(grid),
|
||||
m_faultCollection(faultCollection)
|
||||
{
|
||||
CVF_ASSERT(grid);
|
||||
|
||||
if (faultCollection)
|
||||
{
|
||||
for (size_t i = 0; i < faultCollection->faults.size(); i++)
|
||||
{
|
||||
m_faultParts.push_back(new RivFaultPart(grid, faultCollection->faults[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RivFaultPartMgr::~RivFaultPartMgr()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivFaultPartMgr::setTransform(cvf::Transform* scaleTransform)
|
||||
{
|
||||
m_scaleTransform = scaleTransform;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivFaultPartMgr::setCellVisibility(cvf::UByteArray* cellVisibilities)
|
||||
{
|
||||
CVF_ASSERT(cellVisibilities);
|
||||
|
||||
for (size_t i = 0; i < m_faultParts.size(); i++)
|
||||
{
|
||||
m_faultParts.at(i)->setCellVisibility(cellVisibilities);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivFaultPartMgr::appendPartsToModel(cvf::ModelBasicList* model)
|
||||
{
|
||||
CVF_ASSERT(model != NULL);
|
||||
|
||||
// Faults are only present for main grid
|
||||
if (!m_grid->isMainGrid()) return;
|
||||
|
||||
if (!m_faultCollection->showFaultCollection()) return;
|
||||
|
||||
cvf::ModelBasicList parts;
|
||||
|
||||
for (size_t i = 0; i < m_faultParts.size(); i++)
|
||||
{
|
||||
m_faultParts[i]->appendPartsToModel(&parts);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < parts.partCount(); i++)
|
||||
{
|
||||
cvf::Part* part = parts.part(i);
|
||||
part->setTransform(m_scaleTransform.p());
|
||||
|
||||
model->addPart(part);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivFaultPartMgr::updateCellColor(cvf::Color4f color)
|
||||
{
|
||||
for (size_t i = 0; i < m_faultParts.size(); i++)
|
||||
{
|
||||
m_faultParts[i]->updateCellColor(color);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot)
|
||||
{
|
||||
for (size_t i = 0; i < m_faultParts.size(); i++)
|
||||
{
|
||||
m_faultParts[i]->updateCellResultColor(timeStepIndex, cellResultSlot);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivFaultPartMgr::updateCellEdgeResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot, RimCellEdgeResultSlot* cellEdgeResultSlot)
|
||||
{
|
||||
for (size_t i = 0; i < m_faultParts.size(); i++)
|
||||
{
|
||||
m_faultParts[i]->updateCellEdgeResultColor(timeStepIndex, cellResultSlot, cellEdgeResultSlot);
|
||||
}
|
||||
}
|
||||
|
62
ApplicationCode/ModelVisualization/RivFaultPartMgr.h
Normal file
62
ApplicationCode/ModelVisualization/RivFaultPartMgr.h
Normal file
@ -0,0 +1,62 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) Statoil ASA, Ceetron Solutions AS
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfObject.h"
|
||||
|
||||
#include "RigGridBase.h"
|
||||
#include "RivFaultPart.h"
|
||||
|
||||
namespace cvf
|
||||
{
|
||||
class Transform;
|
||||
}
|
||||
|
||||
class RimResultSlot;
|
||||
class RimCellEdgeResultSlot;
|
||||
class RimFaultCollection;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RivFaultPartMgr : public cvf::Object
|
||||
{
|
||||
public:
|
||||
RivFaultPartMgr(const RigGridBase* grid, size_t gridIdx, const RimFaultCollection* faultCollection);
|
||||
~RivFaultPartMgr();
|
||||
|
||||
void setTransform(cvf::Transform* scaleTransform);
|
||||
void setCellVisibility(cvf::UByteArray* cellVisibilities);
|
||||
|
||||
void updateCellColor(cvf::Color4f color);
|
||||
void updateCellResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot);
|
||||
void updateCellEdgeResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot,
|
||||
RimCellEdgeResultSlot* cellEdgeResultSlot);
|
||||
|
||||
void appendPartsToModel(cvf::ModelBasicList* model);
|
||||
|
||||
|
||||
private:
|
||||
size_t m_gridIdx;
|
||||
cvf::cref<RigGridBase> m_grid;
|
||||
cvf::ref<cvf::Transform> m_scaleTransform;
|
||||
const RimFaultCollection* m_faultCollection;
|
||||
cvf::Collection<RivFaultPart> m_faultParts;
|
||||
};
|
@ -47,7 +47,7 @@
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RivGridPartMgr::RivGridPartMgr(const RigGridBase* grid, size_t gridIdx)
|
||||
RivGridPartMgr::RivGridPartMgr(const RigGridBase* grid, size_t gridIdx, const RimFaultCollection* rimFaultCollection)
|
||||
: m_surfaceGenerator(grid),
|
||||
m_faultGenerator(grid),
|
||||
m_gridIdx(gridIdx),
|
||||
@ -55,7 +55,8 @@ RivGridPartMgr::RivGridPartMgr(const RigGridBase* grid, size_t gridIdx)
|
||||
m_surfaceFaceFilter(grid),
|
||||
m_faultFaceFilter(grid),
|
||||
m_opacityLevel(1.0f),
|
||||
m_defaultColor(cvf::Color3::WHITE)
|
||||
m_defaultColor(cvf::Color3::WHITE),
|
||||
m_rimFaultCollection(rimFaultCollection)
|
||||
{
|
||||
CVF_ASSERT(grid);
|
||||
m_cellVisibility = new cvf::UByteArray;
|
||||
@ -82,13 +83,9 @@ void RivGridPartMgr::setCellVisibility(cvf::UByteArray* cellVisibilities)
|
||||
m_cellVisibility = cellVisibilities;
|
||||
|
||||
m_surfaceGenerator.setCellVisibility(cellVisibilities);
|
||||
m_surfaceFaceFilter.m_showExternalFaces = true;
|
||||
m_surfaceFaceFilter.m_showFaultFaces = false;
|
||||
m_surfaceGenerator.addFaceVisibilityFilter(&m_surfaceFaceFilter);
|
||||
|
||||
m_faultGenerator.setCellVisibility(cellVisibilities);
|
||||
m_faultFaceFilter.m_showExternalFaces = false;
|
||||
m_faultFaceFilter.m_showFaultFaces = true;
|
||||
m_faultGenerator.addFaceVisibilityFilter(&m_faultFaceFilter);
|
||||
|
||||
generatePartGeometry(m_surfaceGenerator, false);
|
||||
@ -192,8 +189,12 @@ void RivGridPartMgr::appendPartsToModel(cvf::ModelBasicList* model)
|
||||
|
||||
if(m_surfaceFaces.notNull() ) model->addPart(m_surfaceFaces.p() );
|
||||
if(m_surfaceGridLines.notNull()) model->addPart(m_surfaceGridLines.p());
|
||||
if(m_faultFaces.notNull() ) model->addPart(m_faultFaces.p() );
|
||||
if(m_faultGridLines.notNull() ) model->addPart(m_faultGridLines.p() );
|
||||
|
||||
if (m_rimFaultCollection && m_rimFaultCollection->showGeometryDetectedFaults())
|
||||
{
|
||||
if(m_faultFaces.notNull() ) model->addPart(m_faultFaces.p() );
|
||||
if(m_faultGridLines.notNull() ) model->addPart(m_faultGridLines.p() );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -33,6 +33,7 @@ namespace cvf
|
||||
|
||||
class RimResultSlot;
|
||||
class RimCellEdgeResultSlot;
|
||||
class RimFaultCollection;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
@ -45,7 +46,7 @@ class RimCellEdgeResultSlot;
|
||||
class RivGridPartMgr: public cvf::Object
|
||||
{
|
||||
public:
|
||||
RivGridPartMgr(const RigGridBase* grid, size_t gridIdx);
|
||||
RivGridPartMgr(const RigGridBase* grid, size_t gridIdx, const RimFaultCollection* rimFaultCollection);
|
||||
~RivGridPartMgr();
|
||||
void setTransform(cvf::Transform* scaleTransform);
|
||||
void setCellVisibility(cvf::UByteArray* cellVisibilities );
|
||||
@ -58,13 +59,6 @@ public:
|
||||
|
||||
void appendPartsToModel(cvf::ModelBasicList* model);
|
||||
|
||||
enum PartRenderMaskEnum
|
||||
{
|
||||
surfaceBit = 0x00000001,
|
||||
meshSurfaceBit = 0x00000002,
|
||||
faultBit = 0x00000004,
|
||||
meshFaultBit = 0x00000008,
|
||||
};
|
||||
|
||||
private:
|
||||
void generatePartGeometry(cvf::StructGridGeometryGenerator& geoBuilder, bool faultGeometry);
|
||||
@ -87,13 +81,13 @@ private:
|
||||
|
||||
// Fault visualization
|
||||
cvf::StructGridGeometryGenerator m_faultGenerator;
|
||||
RigGridCellFaceVisibilityFilter m_faultFaceFilter;
|
||||
RigFaultFaceVisibilityFilter m_faultFaceFilter;
|
||||
cvf::ref<cvf::Part> m_faultFaces;
|
||||
cvf::ref<cvf::Vec2fArray> m_faultFacesTextureCoords;
|
||||
|
||||
cvf::ref<cvf::Part> m_faultGridLines;
|
||||
|
||||
cvf::ref<cvf::UByteArray> m_cellVisibility;
|
||||
cvf::ref<cvf::UByteArray> m_cellVisibility;
|
||||
|
||||
//cvf::ref<cvf::Part> m_gridOutlines;
|
||||
const RimFaultCollection* m_rimFaultCollection;
|
||||
};
|
||||
|
@ -18,25 +18,33 @@
|
||||
|
||||
#include "RiaStdInclude.h"
|
||||
#include "RivReservoirPartMgr.h"
|
||||
#include "RivGridPartMgr.h"
|
||||
|
||||
#include "cvfStructGrid.h"
|
||||
#include "cvfModelBasicList.h"
|
||||
|
||||
#include "RigCaseData.h"
|
||||
#include "RivGridPartMgr.h"
|
||||
#include "RivFaultPartMgr.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirPartMgr::clearAndSetReservoir(const RigCaseData* eclipseCase)
|
||||
void RivReservoirPartMgr::clearAndSetReservoir(const RigCaseData* eclipseCase, const RimFaultCollection* faultCollection)
|
||||
{
|
||||
m_allGrids.clear();
|
||||
m_faults.clear();
|
||||
|
||||
if (eclipseCase)
|
||||
{
|
||||
std::vector<const RigGridBase*> grids;
|
||||
eclipseCase->allGrids(&grids);
|
||||
for (size_t i = 0; i < grids.size() ; ++i)
|
||||
{
|
||||
m_allGrids.push_back(new RivGridPartMgr(grids[i], i) );
|
||||
m_allGrids.push_back(new RivGridPartMgr(grids[i], i, faultCollection));
|
||||
}
|
||||
|
||||
// Faults read from file are present only on main grid
|
||||
m_faults.push_back(new RivFaultPartMgr(eclipseCase->mainGrid(), 0, faultCollection));
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,6 +57,11 @@ void RivReservoirPartMgr::setTransform(cvf::Transform* scaleTransform)
|
||||
{
|
||||
m_allGrids[i]->setTransform(scaleTransform);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_faults.size() ; ++i)
|
||||
{
|
||||
m_faults[i]->setTransform(scaleTransform);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -58,6 +71,11 @@ void RivReservoirPartMgr::setCellVisibility(size_t gridIndex, cvf::UByteArray* c
|
||||
{
|
||||
CVF_ASSERT(gridIndex < m_allGrids.size());
|
||||
m_allGrids[gridIndex]->setCellVisibility(cellVisibilities);
|
||||
|
||||
if (gridIndex < m_faults.size())
|
||||
{
|
||||
m_faults[gridIndex]->setCellVisibility(cellVisibilities);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -78,6 +96,11 @@ void RivReservoirPartMgr::updateCellColor(cvf::Color4f color)
|
||||
{
|
||||
m_allGrids[i]->updateCellColor(color);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_faults.size() ; ++i)
|
||||
{
|
||||
m_faults[i]->updateCellColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -89,6 +112,12 @@ void RivReservoirPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultS
|
||||
{
|
||||
m_allGrids[i]->updateCellResultColor(timeStepIndex, cellResultSlot);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_faults.size() ; ++i)
|
||||
{
|
||||
m_faults[i]->updateCellResultColor(timeStepIndex, cellResultSlot);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -100,6 +129,11 @@ void RivReservoirPartMgr::updateCellEdgeResultColor(size_t timeStepIndex, RimRes
|
||||
{
|
||||
m_allGrids[i]->updateCellEdgeResultColor(timeStepIndex, cellResultSlot, cellEdgeResultSlot);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_faults.size() ; ++i)
|
||||
{
|
||||
m_faults[i]->updateCellEdgeResultColor(timeStepIndex, cellResultSlot, cellEdgeResultSlot);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -111,6 +145,11 @@ void RivReservoirPartMgr::appendPartsToModel(cvf::ModelBasicList* model)
|
||||
{
|
||||
m_allGrids[i]->appendPartsToModel(model);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_faults.size() ; ++i)
|
||||
{
|
||||
m_faults[i]->appendPartsToModel(model);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -124,5 +163,10 @@ void RivReservoirPartMgr::appendPartsToModel(cvf::ModelBasicList* model, const s
|
||||
{
|
||||
m_allGrids[gridIndices[i]]->appendPartsToModel(model);
|
||||
}
|
||||
|
||||
if (gridIndices[i] < m_faults.size())
|
||||
{
|
||||
m_faults[gridIndices[i]]->appendPartsToModel(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include "cvfArray.h"
|
||||
#include "cvfCollection.h"
|
||||
|
||||
#include "RivFaultPartMgr.h"
|
||||
|
||||
namespace cvf
|
||||
{
|
||||
class ModelBasicList;
|
||||
@ -31,7 +33,7 @@ class RimResultSlot;
|
||||
class RimCellEdgeResultSlot;
|
||||
class RivGridPartMgr;
|
||||
class RigCaseData;
|
||||
|
||||
class RimFaultCollection;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
@ -43,7 +45,7 @@ class RigCaseData;
|
||||
class RivReservoirPartMgr: public cvf::Object
|
||||
{
|
||||
public:
|
||||
void clearAndSetReservoir(const RigCaseData* eclipseCase);
|
||||
void clearAndSetReservoir(const RigCaseData* eclipseCase, const RimFaultCollection* faultCollection);
|
||||
void setTransform(cvf::Transform* scaleTransform);
|
||||
void setCellVisibility(size_t gridIndex, cvf::UByteArray* cellVisibilities );
|
||||
|
||||
@ -62,4 +64,5 @@ public:
|
||||
private:
|
||||
|
||||
cvf::Collection<RivGridPartMgr> m_allGrids; // Main grid and all LGR's
|
||||
cvf::Collection<RivFaultPartMgr> m_faults;
|
||||
};
|
||||
|
@ -151,7 +151,7 @@ void RivReservoirViewPartMgr::clearGeometryCache(ReservoirGeometryCacheType geom
|
||||
m_propFilteredGeometryFramesNeedsRegen[i] = true;
|
||||
if (m_propFilteredGeometryFrames[i].notNull())
|
||||
{
|
||||
m_propFilteredGeometryFrames[i]->clearAndSetReservoir(eclipseCase);
|
||||
m_propFilteredGeometryFrames[i]->clearAndSetReservoir(eclipseCase, m_reservoirView->faultCollection());
|
||||
m_propFilteredGeometryFrames[i]->setTransform(m_scaleTransform.p());
|
||||
}
|
||||
}
|
||||
@ -163,7 +163,7 @@ void RivReservoirViewPartMgr::clearGeometryCache(ReservoirGeometryCacheType geom
|
||||
m_propFilteredWellGeometryFramesNeedsRegen[i] = true;
|
||||
if (m_propFilteredWellGeometryFrames[i].notNull())
|
||||
{
|
||||
m_propFilteredWellGeometryFrames[i]->clearAndSetReservoir(eclipseCase);
|
||||
m_propFilteredWellGeometryFrames[i]->clearAndSetReservoir(eclipseCase, m_reservoirView->faultCollection());
|
||||
m_propFilteredWellGeometryFrames[i]->setTransform(m_scaleTransform.p());
|
||||
}
|
||||
}
|
||||
@ -171,7 +171,7 @@ void RivReservoirViewPartMgr::clearGeometryCache(ReservoirGeometryCacheType geom
|
||||
else
|
||||
{
|
||||
m_geometriesNeedsRegen[geomType] = true;
|
||||
m_geometries[geomType].clearAndSetReservoir(eclipseCase);
|
||||
m_geometries[geomType].clearAndSetReservoir(eclipseCase, m_reservoirView->faultCollection());
|
||||
m_geometries[geomType].setTransform(m_scaleTransform.p());
|
||||
}
|
||||
}
|
||||
@ -238,7 +238,7 @@ void RivReservoirViewPartMgr::appendDynamicGeometryPartsToModel(cvf::ModelBasicL
|
||||
void RivReservoirViewPartMgr::createGeometry(ReservoirGeometryCacheType geometryType)
|
||||
{
|
||||
RigCaseData* res = m_reservoirView->eclipseCase()->reservoirData();
|
||||
m_geometries[geometryType].clearAndSetReservoir(res);
|
||||
m_geometries[geometryType].clearAndSetReservoir(res, m_reservoirView->faultCollection());
|
||||
m_geometries[geometryType].setTransform(m_scaleTransform.p());
|
||||
std::vector<RigGridBase*> grids;
|
||||
res->allGrids(&grids);
|
||||
@ -393,7 +393,7 @@ void RivReservoirViewPartMgr::createPropertyFilteredNoneWellCellGeometry(size_t
|
||||
|
||||
if ( m_propFilteredGeometryFrames[frameIndex].isNull()) m_propFilteredGeometryFrames[frameIndex] = new RivReservoirPartMgr;
|
||||
|
||||
m_propFilteredGeometryFrames[frameIndex]->clearAndSetReservoir(res);
|
||||
m_propFilteredGeometryFrames[frameIndex]->clearAndSetReservoir(res, m_reservoirView->faultCollection());
|
||||
m_propFilteredGeometryFrames[frameIndex]->setTransform(m_scaleTransform.p());
|
||||
|
||||
std::vector<RigGridBase*> grids;
|
||||
@ -470,7 +470,7 @@ void RivReservoirViewPartMgr::createPropertyFilteredWellGeometry(size_t frameInd
|
||||
|
||||
if ( m_propFilteredWellGeometryFrames[frameIndex].isNull()) m_propFilteredWellGeometryFrames[frameIndex] = new RivReservoirPartMgr;
|
||||
|
||||
m_propFilteredWellGeometryFrames[frameIndex]->clearAndSetReservoir(res);
|
||||
m_propFilteredWellGeometryFrames[frameIndex]->clearAndSetReservoir(res, m_reservoirView->faultCollection());
|
||||
m_propFilteredWellGeometryFrames[frameIndex]->setTransform(m_scaleTransform.p());
|
||||
|
||||
std::vector<RigGridBase*> grids;
|
||||
|
@ -44,6 +44,8 @@ ${CEE_CURRENT_LIST_DIR}RimStatisticsCaseEvaluator.h
|
||||
${CEE_CURRENT_LIST_DIR}RimMimeData.h
|
||||
${CEE_CURRENT_LIST_DIR}RimCommandObject.h
|
||||
${CEE_CURRENT_LIST_DIR}RimTools.h
|
||||
${CEE_CURRENT_LIST_DIR}RimFault.h
|
||||
${CEE_CURRENT_LIST_DIR}RimFaultCollection.h
|
||||
)
|
||||
|
||||
set (SOURCE_GROUP_SOURCE_FILES
|
||||
@ -86,6 +88,8 @@ ${CEE_CURRENT_LIST_DIR}RimStatisticsCaseEvaluator.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RimMimeData.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RimCommandObject.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RimTools.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RimFault.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RimFaultCollection.cpp
|
||||
)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES
|
||||
|
126
ApplicationCode/ProjectDataModel/RimFault.cpp
Normal file
126
ApplicationCode/ProjectDataModel/RimFault.cpp
Normal file
@ -0,0 +1,126 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) Statoil ASA, Ceetron Solutions AS
|
||||
//
|
||||
// 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 "RimFault.h"
|
||||
|
||||
#include "RigFault.h"
|
||||
|
||||
#include "RimReservoirView.h"
|
||||
#include "RimResultSlot.h"
|
||||
#include "RimCellEdgeResultSlot.h"
|
||||
#include "Rim3dOverlayInfoConfig.h"
|
||||
#include "RimCellPropertyFilterCollection.h"
|
||||
#include "RimCellRangeFilterCollection.h"
|
||||
#include "RimWellCollection.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimFault, "Fault");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimFault::RimFault()
|
||||
{
|
||||
CAF_PDM_InitObject("RimFault", ":/draw_style_faults_24x24.png", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&name, "FaultName", "Name", "", "", "");
|
||||
name.setUiHidden(true);
|
||||
name.setUiReadOnly(true);
|
||||
|
||||
CAF_PDM_InitField(&showFault, "ShowFault", true, "Show fault", "", "", "");
|
||||
showFault.setUiHidden(true);
|
||||
|
||||
CAF_PDM_InitField(&showFaultLabel, "ShowFaultLabel", true, "Show fault label", "", "", "");
|
||||
|
||||
CAF_PDM_InitField(&showFaultColor, "ShowFaultColor", true, "Show fault color", "", "", "");
|
||||
CAF_PDM_InitField(&faultColor, "Color", cvf::Color3f(0.588f, 0.588f, 0.804f), "Fault color", "", "", "");
|
||||
|
||||
|
||||
m_rigFault = NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimFault::~RimFault()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
caf::PdmFieldHandle* RimFault::userDescriptionField()
|
||||
{
|
||||
return &name;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFault::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
|
||||
{
|
||||
if (&showFault == changedField)
|
||||
{
|
||||
this->updateUiIconFromState(showFault);
|
||||
|
||||
RimReservoirView* reservoirView = NULL;
|
||||
this->firstAncestorOfType(reservoirView);
|
||||
|
||||
if (reservoirView)
|
||||
{
|
||||
reservoirView->scheduleCreateDisplayModelAndRedraw();
|
||||
}
|
||||
}
|
||||
|
||||
if (&faultColor == changedField)
|
||||
{
|
||||
RimReservoirView* reservoirView = NULL;
|
||||
this->firstAncestorOfType(reservoirView);
|
||||
|
||||
if (reservoirView)
|
||||
{
|
||||
reservoirView->scheduleCreateDisplayModelAndRedraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
caf::PdmFieldHandle* RimFault::objectToggleField()
|
||||
{
|
||||
return &showFault;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFault::setFaultGeometry(const RigFault* faultGeometry)
|
||||
{
|
||||
m_rigFault = faultGeometry;
|
||||
|
||||
this->name = faultGeometry->name();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const RigFault* RimFault::faultGeometry() const
|
||||
{
|
||||
return m_rigFault;
|
||||
}
|
||||
|
62
ApplicationCode/ProjectDataModel/RimFault.h
Normal file
62
ApplicationCode/ProjectDataModel/RimFault.h
Normal file
@ -0,0 +1,62 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) Statoil ASA, Ceetron Solutions AS
|
||||
//
|
||||
// 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 "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmPointer.h"
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfColor3.h"
|
||||
#include "cafPdmFieldCvfColor.h"
|
||||
|
||||
class RigFault;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimFault : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
public:
|
||||
|
||||
RimFault();
|
||||
virtual ~RimFault();
|
||||
|
||||
void setFaultGeometry(const RigFault* faultGeometry);
|
||||
const RigFault* faultGeometry() const;
|
||||
|
||||
virtual caf::PdmFieldHandle* userDescriptionField();
|
||||
virtual caf::PdmFieldHandle* objectToggleField();
|
||||
|
||||
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue);
|
||||
|
||||
caf::PdmField<bool> showFault;
|
||||
|
||||
caf::PdmField<QString> name;
|
||||
caf::PdmField<bool> showFaultLabel;
|
||||
|
||||
caf::PdmField<bool> showFaultColor;
|
||||
caf::PdmField<cvf::Color3f> faultColor;
|
||||
|
||||
|
||||
private:
|
||||
const RigFault* m_rigFault;
|
||||
};
|
165
ApplicationCode/ProjectDataModel/RimFaultCollection.cpp
Normal file
165
ApplicationCode/ProjectDataModel/RimFaultCollection.cpp
Normal file
@ -0,0 +1,165 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) Statoil ASA, Ceetron Solutions AS
|
||||
//
|
||||
// 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 "RimFaultCollection.h"
|
||||
|
||||
#include "cafAppEnum.h"
|
||||
#include "cafPdmFieldCvfColor.h"
|
||||
#include "cafPdmFieldCvfMat4d.h"
|
||||
#include "RimReservoirView.h"
|
||||
|
||||
#include "RimResultSlot.h"
|
||||
#include "RimCellRangeFilterCollection.h"
|
||||
#include "RimCellPropertyFilterCollection.h"
|
||||
#include "RimWellCollection.h"
|
||||
|
||||
#include "Rim3dOverlayInfoConfig.h"
|
||||
#include "RimCellEdgeResultSlot.h"
|
||||
#include "RiaApplication.h"
|
||||
#include "RiaPreferences.h"
|
||||
|
||||
#include "RimCase.h"
|
||||
#include "RimReservoirCellResultsCacher.h"
|
||||
#include "RigCaseData.h"
|
||||
#include "RivColorTableArray.h"
|
||||
|
||||
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimFaultCollection, "Faults");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimFaultCollection::RimFaultCollection()
|
||||
{
|
||||
CAF_PDM_InitObject("Faults", ":/draw_style_faults_24x24.png", "", "");
|
||||
|
||||
CAF_PDM_InitField(&showFaultCollection, "Active", true, "Active", "", "", "");
|
||||
showFaultCollection.setUiHidden(true);
|
||||
|
||||
CAF_PDM_InitField(&showGeometryDetectedFaults, "ShowGeometryDetectedFaults", true, "Show geometry detected faults", "", "", "");
|
||||
|
||||
CAF_PDM_InitField(&showFaultLabel, "ShowFaultLabel", true, "Show fault labels", "", "", "");
|
||||
cvf::Color3f defWellLabelColor = RiaApplication::instance()->preferences()->defaultWellLabelColor();
|
||||
CAF_PDM_InitField(&faultLabelColor, "FaultLabelColor", defWellLabelColor, "Fault label color", "", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&faults, "Faults", "Faults", "", "", "");
|
||||
|
||||
m_reservoirView = NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimFaultCollection::~RimFaultCollection()
|
||||
{
|
||||
faults.deleteAllChildObjects();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFaultCollection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
|
||||
{
|
||||
if (&showFaultCollection == changedField)
|
||||
{
|
||||
this->updateUiIconFromState(showFaultCollection);
|
||||
|
||||
if (m_reservoirView)
|
||||
{
|
||||
m_reservoirView->scheduleCreateDisplayModelAndRedraw();
|
||||
}
|
||||
}
|
||||
|
||||
if (&showGeometryDetectedFaults == changedField)
|
||||
{
|
||||
if (m_reservoirView)
|
||||
{
|
||||
m_reservoirView->scheduleCreateDisplayModelAndRedraw();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFaultCollection::setReservoirView(RimReservoirView* ownerReservoirView)
|
||||
{
|
||||
m_reservoirView = ownerReservoirView;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
caf::PdmFieldHandle* RimFaultCollection::objectToggleField()
|
||||
{
|
||||
return &showFaultCollection;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimFault* RimFaultCollection::findFaultByName(QString name)
|
||||
{
|
||||
for (size_t i = 0; i < this->faults().size(); ++i)
|
||||
{
|
||||
if (this->faults()[i]->name() == name)
|
||||
{
|
||||
return this->faults()[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFaultCollection::syncronizeFaults()
|
||||
{
|
||||
if (!(m_reservoirView && m_reservoirView->eclipseCase() && m_reservoirView->eclipseCase()->reservoirData()) ) return;
|
||||
|
||||
cvf::ref<cvf::Color3fArray> partColors = RivColorTableArray::colorTableArray();
|
||||
|
||||
const cvf::Collection<RigFault> rigFaults = m_reservoirView->eclipseCase()->reservoirData()->mainGrid()->faults();
|
||||
|
||||
std::vector<caf::PdmPointer<RimFault> > newFaults;
|
||||
|
||||
// Find corresponding fault from data model, or create a new
|
||||
|
||||
for (size_t fIdx = 0; fIdx < rigFaults.size(); ++fIdx)
|
||||
{
|
||||
RimFault* rimFault = this->findFaultByName(rigFaults[fIdx]->name());
|
||||
|
||||
if (!rimFault)
|
||||
{
|
||||
rimFault = new RimFault();
|
||||
rimFault->faultColor = partColors->get(fIdx % partColors->size());
|
||||
}
|
||||
|
||||
rimFault->setFaultGeometry(rigFaults[fIdx].p());
|
||||
|
||||
newFaults.push_back(rimFault);
|
||||
}
|
||||
|
||||
this->faults().clear();
|
||||
this->faults().insert(0, newFaults);
|
||||
}
|
||||
|
68
ApplicationCode/ProjectDataModel/RimFaultCollection.h
Normal file
68
ApplicationCode/ProjectDataModel/RimFaultCollection.h
Normal file
@ -0,0 +1,68 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) Statoil ASA, Ceetron Solutions AS
|
||||
//
|
||||
// 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 "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmPointer.h"
|
||||
#include "cafAppEnum.h"
|
||||
#include <QString>
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfColor3.h"
|
||||
|
||||
#include "RimFault.h"
|
||||
|
||||
class RimReservoirView;
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimFaultCollection : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
public:
|
||||
|
||||
RimFaultCollection();
|
||||
virtual ~RimFaultCollection();
|
||||
|
||||
void setReservoirView(RimReservoirView* ownerReservoirView);
|
||||
void syncronizeFaults();
|
||||
|
||||
caf::PdmField<bool> showGeometryDetectedFaults;
|
||||
|
||||
caf::PdmField<bool> showFaultLabel;
|
||||
caf::PdmField<cvf::Color3f> faultLabelColor;
|
||||
|
||||
caf::PdmField<bool> showFaultCollection;
|
||||
|
||||
caf::PdmPointersField<RimFault*> faults;
|
||||
|
||||
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue);
|
||||
virtual caf::PdmFieldHandle* objectToggleField();
|
||||
|
||||
private:
|
||||
RimFault* findFaultByName(QString name);
|
||||
|
||||
private:
|
||||
RimReservoirView* m_reservoirView;
|
||||
|
||||
};
|
@ -262,7 +262,9 @@ void RimInputCase::loadAndSyncronizeInputProperties()
|
||||
|
||||
if (isExistingFile)
|
||||
{
|
||||
std::vector< RifKeywordAndFilePos > fileKeywords = RifEclipseInputFileTools::findKeywordsOnFile(filenames[i]);
|
||||
std::vector< RifKeywordAndFilePos > fileKeywords;
|
||||
RifEclipseInputFileTools::findKeywordsOnFile(filenames[i], fileKeywords);
|
||||
|
||||
for_all(fileKeywords, fkIt) fileKeywordSet.insert(fileKeywords[fkIt].keyword);
|
||||
}
|
||||
|
||||
|
@ -73,6 +73,7 @@
|
||||
|
||||
#include <limits.h>
|
||||
#include "cafCeetronPlusNavigation.h"
|
||||
#include "RimFaultCollection.h"
|
||||
|
||||
namespace caf {
|
||||
|
||||
@ -99,11 +100,6 @@ void caf::AppEnum< RimReservoirView::SurfaceModeType >::setUp()
|
||||
|
||||
|
||||
|
||||
const cvf::uint surfaceBit = 0x00000001;
|
||||
const cvf::uint meshSurfaceBit = 0x00000002;
|
||||
const cvf::uint faultBit = 0x00000004;
|
||||
const cvf::uint meshFaultBit = 0x00000008;
|
||||
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimReservoirView, "ReservoirView");
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -145,6 +141,9 @@ RimReservoirView::RimReservoirView()
|
||||
CAF_PDM_InitFieldNoDefault(&wellCollection, "WellCollection", "Simulation Wells", "", "", "");
|
||||
wellCollection = new RimWellCollection;
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&faultCollection, "FaultCollection", "Faults", "", "", "");
|
||||
faultCollection = new RimFaultCollection;
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&rangeFilterCollection, "RangeFilters", "Range Filters", "", "", "");
|
||||
rangeFilterCollection = new RimCellRangeFilterCollection();
|
||||
rangeFilterCollection->setReservoirView(this);
|
||||
@ -198,6 +197,7 @@ RimReservoirView::~RimReservoirView()
|
||||
delete rangeFilterCollection();
|
||||
delete propertyFilterCollection();
|
||||
delete wellCollection();
|
||||
delete faultCollection();
|
||||
|
||||
if (m_viewer)
|
||||
{
|
||||
@ -890,6 +890,9 @@ void RimReservoirView::loadDataAndUpdate()
|
||||
|
||||
this->propertyFilterCollection()->loadAndInitializePropertyFilters();
|
||||
|
||||
this->faultCollection()->setReservoirView(this);
|
||||
this->faultCollection()->syncronizeFaults();
|
||||
|
||||
m_reservoirGridPartManager->clearGeometryCache();
|
||||
|
||||
syncronizeWellsWithResults();
|
||||
@ -1104,30 +1107,35 @@ void RimReservoirView::appendCellResultInfo(size_t gridIndex, size_t cellIndex,
|
||||
void RimReservoirView::updateDisplayModelVisibility()
|
||||
{
|
||||
if (m_viewer.isNull()) return;
|
||||
|
||||
const cvf::uint uintSurfaceBit = surfaceBit;
|
||||
const cvf::uint uintMeshSurfaceBit = meshSurfaceBit;
|
||||
const cvf::uint uintFaultBit = faultBit;
|
||||
const cvf::uint uintMeshFaultBit = meshFaultBit;
|
||||
|
||||
// Initialize the mask to show everything except the the bits controlled here
|
||||
unsigned int mask = 0xffffffff & ~surfaceBit & ~faultBit & ~meshSurfaceBit & ~meshFaultBit ;
|
||||
unsigned int mask = 0xffffffff & ~uintSurfaceBit & ~uintFaultBit & ~uintMeshSurfaceBit & ~uintMeshFaultBit ;
|
||||
|
||||
// Then turn the appropriate bits on according to the user settings
|
||||
|
||||
if (surfaceMode == SURFACE)
|
||||
{
|
||||
mask |= surfaceBit;
|
||||
mask |= faultBit;
|
||||
mask |= uintSurfaceBit;
|
||||
mask |= uintFaultBit;
|
||||
}
|
||||
else if (surfaceMode == FAULTS)
|
||||
{
|
||||
mask |= faultBit;
|
||||
mask |= uintFaultBit;
|
||||
}
|
||||
|
||||
if (meshMode == FULL_MESH)
|
||||
{
|
||||
mask |= meshSurfaceBit;
|
||||
mask |= meshFaultBit;
|
||||
mask |= uintMeshSurfaceBit;
|
||||
mask |= uintMeshFaultBit;
|
||||
}
|
||||
else if (meshMode == FAULTS_MESH)
|
||||
{
|
||||
mask |= meshFaultBit;
|
||||
mask |= uintMeshFaultBit;
|
||||
}
|
||||
|
||||
m_viewer->setEnableMask(mask);
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include <QPointer>
|
||||
#include <QString>
|
||||
|
||||
#include "RimFaultCollection.h"
|
||||
|
||||
class RimCase;
|
||||
class RimResultSlot;
|
||||
class RimCellEdgeResultSlot;
|
||||
@ -49,6 +51,7 @@ class RiuViewer;
|
||||
class RigGridBase;
|
||||
class RigGridCellFaceVisibilityFilter;
|
||||
class RimReservoirCellResultsStorage;
|
||||
|
||||
namespace cvf
|
||||
{
|
||||
class Transform;
|
||||
@ -56,14 +59,15 @@ namespace cvf
|
||||
class ModelBasicList;
|
||||
}
|
||||
|
||||
enum ViewState
|
||||
enum PartRenderMaskEnum
|
||||
{
|
||||
GEOMETRY_ONLY,
|
||||
STATIC_RESULT,
|
||||
DYNAMIC_RESULT,
|
||||
CELL_FACE_COMBINED_RESULT
|
||||
surfaceBit = 0x00000001,
|
||||
meshSurfaceBit = 0x00000002,
|
||||
faultBit = 0x00000004,
|
||||
meshFaultBit = 0x00000008,
|
||||
};
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
@ -99,6 +103,8 @@ public:
|
||||
|
||||
caf::PdmField<RimWellCollection*> wellCollection;
|
||||
|
||||
caf::PdmField<RimFaultCollection*> faultCollection;
|
||||
|
||||
caf::PdmField<Rim3dOverlayInfoConfig*> overlayInfoConfig;
|
||||
|
||||
// Visualization setup fields
|
||||
|
@ -18,6 +18,7 @@ ${CEE_CURRENT_LIST_DIR}RigCaseCellResultsData.h
|
||||
${CEE_CURRENT_LIST_DIR}RigSingleWellResultsData.h
|
||||
${CEE_CURRENT_LIST_DIR}RigStatisticsMath.h
|
||||
${CEE_CURRENT_LIST_DIR}RigWellPath.h
|
||||
${CEE_CURRENT_LIST_DIR}RigFault.h
|
||||
)
|
||||
|
||||
set (SOURCE_GROUP_SOURCE_FILES
|
||||
@ -34,6 +35,7 @@ ${CEE_CURRENT_LIST_DIR}RigCaseCellResultsData.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RigSingleWellResultsData.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RigStatisticsMath.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RigWellPath.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RigFault.cpp
|
||||
)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES
|
||||
|
66
ApplicationCode/ReservoirDataModel/RigFault.cpp
Normal file
66
ApplicationCode/ReservoirDataModel/RigFault.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) Statoil ASA, Ceetron Solutions AS
|
||||
//
|
||||
// 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 "RigFault.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigFault::RigFault()
|
||||
{
|
||||
m_cellRangesForFaces.resize(6);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigFault::addCellRangeForFace(cvf::StructGridInterface::FaceType face, const cvf::CellRange& cellRange)
|
||||
{
|
||||
size_t faceIndex = static_cast<size_t>(face);
|
||||
CVF_ASSERT(faceIndex < m_cellRangesForFaces.size());
|
||||
|
||||
m_cellRangesForFaces[faceIndex].push_back(cellRange);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigFault::setName(const QString& name)
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RigFault::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const std::vector<cvf::CellRange>& RigFault::cellRangeForFace(cvf::StructGridInterface::FaceType face) const
|
||||
{
|
||||
size_t faceIndex = static_cast<size_t>(face);
|
||||
CVF_ASSERT(faceIndex < m_cellRangesForFaces.size());
|
||||
|
||||
return m_cellRangesForFaces[faceIndex];
|
||||
}
|
50
ApplicationCode/ReservoirDataModel/RigFault.h
Normal file
50
ApplicationCode/ReservoirDataModel/RigFault.h
Normal file
@ -0,0 +1,50 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) Statoil ASA, Ceetron Solutions AS
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfObject.h"
|
||||
#include "cvfVector3.h"
|
||||
#include "cvfBoundingBox.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <QString>
|
||||
#include "cvfStructGrid.h"
|
||||
#include "cvfCellRange.h"
|
||||
|
||||
|
||||
|
||||
class RigFault : public cvf::Object
|
||||
{
|
||||
public:
|
||||
RigFault();
|
||||
|
||||
void setName(const QString& name);
|
||||
QString name() const;
|
||||
|
||||
void addCellRangeForFace(cvf::StructGridInterface::FaceType face, const cvf::CellRange& cellRange);
|
||||
|
||||
const std::vector<cvf::CellRange>& cellRangeForFace(cvf::StructGridInterface::FaceType face) const;
|
||||
|
||||
private:
|
||||
QString m_name;
|
||||
|
||||
std::vector< std::vector<cvf::CellRange> > m_cellRangesForFaces;
|
||||
};
|
@ -538,6 +538,14 @@ cvf::BoundingBox RigGridBase::boundingBox()
|
||||
return m_boundingBox;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigGridBase::setFaults(const cvf::Collection<RigFault>& faults)
|
||||
{
|
||||
m_faults = faults;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -545,49 +553,51 @@ bool RigGridCellFaceVisibilityFilter::isFaceVisible(size_t i, size_t j, size_t k
|
||||
{
|
||||
CVF_TIGHT_ASSERT(m_grid);
|
||||
|
||||
if (m_showFaultFaces)
|
||||
size_t cellIndex = m_grid->cellIndexFromIJK(i, j, k);
|
||||
if (m_grid->cell(cellIndex).subGrid())
|
||||
{
|
||||
size_t cellIndex = m_grid->cellIndexFromIJK(i, j, k);
|
||||
if (m_grid->cell(cellIndex).isCellFaceFault(face))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// Do not show any faces in the place where a LGR is present
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_showExternalFaces)
|
||||
size_t ni, nj, nk;
|
||||
cvf::StructGridInterface::neighborIJKAtCellFace(i, j, k, face, &ni, &nj, &nk);
|
||||
|
||||
// If the cell is on the edge of the grid, Interpret as having an invisible neighbour
|
||||
if (ni >= m_grid->cellCountI() || nj >= m_grid->cellCountJ() || nk >= m_grid->cellCountK())
|
||||
{
|
||||
size_t cellIndex = m_grid->cellIndexFromIJK(i, j, k);
|
||||
if (m_grid->cell(cellIndex).subGrid())
|
||||
{
|
||||
// Do not show any faces in the place where a LGR is present
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t ni, nj, nk;
|
||||
cvf::StructGridInterface::neighborIJKAtCellFace(i, j, k, face, &ni, &nj, &nk);
|
||||
|
||||
// If the cell is on the edge of the grid, Interpret as having an invisible neighbour
|
||||
if (ni >= m_grid->cellCountI() || nj >= m_grid->cellCountJ() || nk >= m_grid->cellCountK())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t neighborCellIndex = m_grid->cellIndexFromIJK(ni, nj, nk);
|
||||
size_t neighborCellIndex = m_grid->cellIndexFromIJK(ni, nj, nk);
|
||||
|
||||
// Do show the faces in the boarder between this grid and a possible LGR. Some of the LGR cells
|
||||
// might not be visible.
|
||||
if (m_grid->cell(neighborCellIndex).subGrid())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// Do show the faces in the boarder between this grid and a possible LGR. Some of the LGR cells
|
||||
// might not be visible.
|
||||
if (m_grid->cell(neighborCellIndex).subGrid())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the neighbour cell is invisible, we need to draw the face
|
||||
if ((cellVisibility != NULL) && !(*cellVisibility)[neighborCellIndex])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// If the neighbour cell is invisible, we need to draw the face
|
||||
if ((cellVisibility != NULL) && !(*cellVisibility)[neighborCellIndex])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigFaultFaceVisibilityFilter::isFaceVisible(size_t i, size_t j, size_t k, cvf::StructGridInterface::FaceType face, const cvf::UByteArray* cellVisibility) const
|
||||
{
|
||||
size_t cellIndex = m_grid->cellIndexFromIJK(i, j, k);
|
||||
if (m_grid->cell(cellIndex).isCellFaceFault(face))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -22,15 +22,17 @@
|
||||
|
||||
#include "cvfVector3.h"
|
||||
#include "cvfBoundingBox.h"
|
||||
|
||||
#include "cvfStructGrid.h"
|
||||
#include "cvfStructGridGeometryGenerator.h"
|
||||
#include "cvfStructGridScalarDataAccess.h"
|
||||
|
||||
#include "cafFixedArray.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "cvfStructGridScalarDataAccess.h"
|
||||
|
||||
#include "RifReaderInterface.h"
|
||||
#include "cafFixedArray.h"
|
||||
#include "RigFault.h"
|
||||
|
||||
|
||||
class RigMainGrid;
|
||||
@ -75,6 +77,9 @@ public:
|
||||
void coarseningBox(size_t coarseningBoxIndex, size_t* i1, size_t* i2, size_t* j1, size_t* j2, size_t* k1, size_t* k2) const;
|
||||
|
||||
cvf::BoundingBox boundingBox();
|
||||
|
||||
void setFaults(const cvf::Collection<RigFault>& faults);
|
||||
const cvf::Collection<RigFault>& faults() { return m_faults; }
|
||||
|
||||
protected:
|
||||
friend class RigMainGrid;//::initAllSubGridsParentGridPointer();
|
||||
@ -116,6 +121,8 @@ private:
|
||||
cvf::BoundingBox m_boundingBox;
|
||||
|
||||
std::vector<caf::SizeTArray6> m_coarseningBoxInfo;
|
||||
|
||||
cvf::Collection<RigFault> m_faults;
|
||||
};
|
||||
|
||||
|
||||
@ -123,17 +130,25 @@ class RigGridCellFaceVisibilityFilter : public cvf::CellFaceVisibilityFilter
|
||||
{
|
||||
public:
|
||||
RigGridCellFaceVisibilityFilter(const RigGridBase* grid)
|
||||
: m_grid(grid),
|
||||
m_showFaultFaces(true),
|
||||
m_showExternalFaces(true)
|
||||
: m_grid(grid)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool isFaceVisible( size_t i, size_t j, size_t k, cvf::StructGridInterface::FaceType face, const cvf::UByteArray* cellVisibility ) const;
|
||||
|
||||
private:
|
||||
const RigGridBase* m_grid;
|
||||
};
|
||||
|
||||
class RigFaultFaceVisibilityFilter : public cvf::CellFaceVisibilityFilter
|
||||
{
|
||||
public:
|
||||
bool m_showFaultFaces;
|
||||
bool m_showExternalFaces;
|
||||
RigFaultFaceVisibilityFilter(const RigGridBase* grid)
|
||||
: m_grid(grid)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool isFaceVisible( size_t i, size_t j, size_t k, cvf::StructGridInterface::FaceType face, const cvf::UByteArray* cellVisibility ) const;
|
||||
|
||||
private:
|
||||
const RigGridBase* m_grid;
|
||||
|
@ -24,6 +24,8 @@ add_library( ${PROJECT_NAME}
|
||||
cafUtils.h
|
||||
cvfStructGrid.cpp
|
||||
cvfStructGrid.h
|
||||
cvfCellRange.cpp
|
||||
cvfCellRange.h
|
||||
|
||||
|
||||
cvfStructGridGeometryGenerator.cpp
|
||||
|
133
Fwk/AppFwk/CommonCode/cvfCellRange.cpp
Normal file
133
Fwk/AppFwk/CommonCode/cvfCellRange.cpp
Normal file
@ -0,0 +1,133 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2013 Ceetron AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// This library 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.
|
||||
//
|
||||
// This library 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.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
|
||||
|
||||
#include "cvfCellRange.h"
|
||||
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
CellRange::CellRange()
|
||||
{
|
||||
m_min = cvf::Vec3st::UNDEFINED;
|
||||
m_max = cvf::Vec3st::UNDEFINED;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
CellRange::CellRange(cvf::Vec3st min, cvf::Vec3st max)
|
||||
{
|
||||
setRange(min, max);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
CellRange::CellRange(size_t minI, size_t minJ, size_t minK, size_t maxI, size_t maxJ, size_t maxK)
|
||||
{
|
||||
setRange(Vec3st(minI, minJ, minK), Vec3st(maxI, maxJ, maxK));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void CellRange::setRange(const cvf::Vec3st& min, const cvf::Vec3st& max)
|
||||
{
|
||||
m_min = min;
|
||||
m_max = max;
|
||||
|
||||
CVF_ASSERT(normalize());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void CellRange::range(cvf::Vec3st& min, cvf::Vec3st& max) const
|
||||
{
|
||||
min = m_min;
|
||||
max = m_max;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool CellRange::normalize()
|
||||
{
|
||||
if (m_min == cvf::Vec3st::UNDEFINED || m_max == cvf::Vec3st::UNDEFINED)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint i = 0; i < 3; i++)
|
||||
{
|
||||
if (m_min[i] > m_max[i])
|
||||
{
|
||||
size_t tmp = m_max[i];
|
||||
m_max[i] = m_min[i];
|
||||
m_min[i] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool CellRange::isInRange(size_t i, size_t j, size_t k) const
|
||||
{
|
||||
cvf::Vec3st test(i, j, k);
|
||||
|
||||
for (uint idx = 0; idx < 3; idx++)
|
||||
{
|
||||
if (test[idx] < m_min[idx] || m_max[idx] <= test[idx])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace cvf
|
69
Fwk/AppFwk/CommonCode/cvfCellRange.h
Normal file
69
Fwk/AppFwk/CommonCode/cvfCellRange.h
Normal file
@ -0,0 +1,69 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2013 Ceetron AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// This library 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.
|
||||
//
|
||||
// This library 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.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfVector3.h"
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//==================================================================================================
|
||||
class CellRange
|
||||
{
|
||||
public:
|
||||
CellRange();
|
||||
CellRange(cvf::Vec3st min, cvf::Vec3st max);
|
||||
CellRange(size_t minI, size_t minJ, size_t minK, size_t maxI, size_t maxJ, size_t maxK);
|
||||
|
||||
void setRange(const cvf::Vec3st& min, const cvf::Vec3st& max);
|
||||
void range(cvf::Vec3st& min, cvf::Vec3st& max) const;
|
||||
|
||||
bool normalize();
|
||||
|
||||
bool isInRange(size_t i, size_t j, size_t k) const;
|
||||
|
||||
private:
|
||||
cvf::Vec3st m_min;
|
||||
cvf::Vec3st m_max;
|
||||
};
|
||||
|
||||
|
||||
} // End namespace cvf
|
@ -39,6 +39,20 @@
|
||||
#include "cvfBase.h"
|
||||
#include "cvfStructGrid.h"
|
||||
|
||||
namespace caf
|
||||
{
|
||||
template<>
|
||||
void cvf::StructGridInterface::FaceEnum::setUp()
|
||||
{
|
||||
addItem(cvf::StructGridInterface::POS_I, "X", "");
|
||||
addItem(cvf::StructGridInterface::NEG_I, "X-", "");
|
||||
addItem(cvf::StructGridInterface::POS_J, "Y", "");
|
||||
addItem(cvf::StructGridInterface::NEG_J, "Y-", "");
|
||||
addItem(cvf::StructGridInterface::POS_K, "Z", "");
|
||||
addItem(cvf::StructGridInterface::NEG_K, "Z-", "");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
@ -40,6 +40,8 @@
|
||||
#include "cvfObject.h"
|
||||
#include "cvfVector3.h"
|
||||
|
||||
#include "../cafProjectDataModel/cafAppEnum.h"
|
||||
|
||||
|
||||
|
||||
namespace cvf {
|
||||
@ -63,6 +65,9 @@ public:
|
||||
NEG_K
|
||||
};
|
||||
|
||||
typedef caf::AppEnum<StructGridInterface::FaceType> FaceEnum;
|
||||
|
||||
|
||||
public:
|
||||
StructGridInterface();;
|
||||
|
||||
|
@ -161,7 +161,7 @@ protected:
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
/// Specialization for pointers, but only applicable to PdmObjectBase derived objects.
|
||||
/// Specialization for pointers, but only applicable to PdmObject derived objects.
|
||||
/// The pointer is guarded, meaning that it will be set to NULL if the object pointed to
|
||||
/// is deleted. The referenced object will be printed in place in the xml-file
|
||||
//==================================================================================================
|
||||
|
@ -10,6 +10,8 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CEE_STRICT_CXX_FLAGS}")
|
||||
set(CEE_HEADER_FILES
|
||||
cvfArray.h
|
||||
cvfArray.inl
|
||||
cvfArrayWrapperConst.h
|
||||
cvfArrayWrapperToEdit.h
|
||||
cvfAssert.h
|
||||
cvfBase.h
|
||||
cvfBase64.h
|
||||
|
@ -229,6 +229,8 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="cvfArray.h" />
|
||||
<ClInclude Include="cvfArrayWrapperConst.h" />
|
||||
<ClInclude Include="cvfArrayWrapperToEdit.h" />
|
||||
<ClInclude Include="cvfAssert.h" />
|
||||
<ClInclude Include="cvfBase.h" />
|
||||
<ClInclude Include="cvfBase64.h" />
|
||||
|
@ -42,6 +42,8 @@
|
||||
<ClInclude Include="cvfLogDestination.h" />
|
||||
<ClInclude Include="cvfLogDestinationConsole.h" />
|
||||
<ClInclude Include="cvfLogDestinationFile.h" />
|
||||
<ClInclude Include="cvfArrayWrapperConst.h" />
|
||||
<ClInclude Include="cvfArrayWrapperToEdit.h" />
|
||||
<ClInclude Include="cvfProgramOptions.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@ -89,4 +91,4 @@
|
||||
<ClCompile Include="cvfLogDestinationFile.cpp" />
|
||||
<ClCompile Include="cvfProgramOptions.cpp" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
153
Fwk/VizFwk/LibCore/cvfArrayWrapperConst.h
Normal file
153
Fwk/VizFwk/LibCore/cvfArrayWrapperConst.h
Normal file
@ -0,0 +1,153 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) Ceetron Solutions AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// This library 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.
|
||||
//
|
||||
// This library 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.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace cvf {
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
/// \class cvf::ArrayWrapperConst
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// A wrapper class for const access to make it possible to use different array types with
|
||||
/// different element types in the same algorithms.
|
||||
///
|
||||
/// The implementation has a specialization for bare pointer arrays.
|
||||
/// The reason for the bare pointer specialization is the [] access implementation
|
||||
/// which is different. (*array)[] vs array[]
|
||||
///
|
||||
/// The convenience functions wrapArrayConst() are available to simplify wrapping of your data making it
|
||||
/// possible to do:
|
||||
/// myFunction (wrapArrayConst(myNodeArray), wrapArrayConst(myIndexArray), ...);
|
||||
/// when calling a template function using ArrayWrapperConst's as input.
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
template < typename ArrayType, typename ElmType >
|
||||
class ArrayWrapperConst
|
||||
{
|
||||
public:
|
||||
ArrayWrapperConst(const ArrayType* array, size_t size) : m_array(array), m_size(size) { }
|
||||
|
||||
inline size_t size() const { return m_size; }
|
||||
inline const ElmType& operator[] (const size_t index) const { return (*m_array)[index]; }
|
||||
|
||||
private:
|
||||
const ArrayType * m_array;
|
||||
size_t m_size;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Const bare-pointer array wrapper specialization
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template < typename ElmType >
|
||||
class ArrayWrapperConst <const ElmType*, ElmType>
|
||||
{
|
||||
public:
|
||||
ArrayWrapperConst(const ElmType* array, size_t size) : m_array(array), m_size(size) { }
|
||||
|
||||
inline size_t size() const { return m_size; }
|
||||
|
||||
inline const ElmType& operator[](const size_t index) const { return m_array[index]; }
|
||||
|
||||
private:
|
||||
const ElmType * m_array;
|
||||
size_t m_size;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#include "cvfArray.h"
|
||||
#include <vector>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// const cvf::Array specialization
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename ElmType>
|
||||
inline const ArrayWrapperConst< const cvf::Array<ElmType>, ElmType > wrapArrayConst(const cvf::Array<ElmType>* array )
|
||||
{
|
||||
const ArrayWrapperConst<const cvf::Array<ElmType>, ElmType> warr(array, array->size());
|
||||
return warr;
|
||||
}
|
||||
|
||||
template <typename ElmType>
|
||||
inline const ArrayWrapperConst< const cvf::Array<ElmType>, ElmType > wrapArrayConst( cvf::Array<ElmType>* array )
|
||||
{
|
||||
const ArrayWrapperConst<const cvf::Array<ElmType>, ElmType> warr(array, array->size());
|
||||
return warr;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// const std::vector specialization
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
template <typename ElmType>
|
||||
inline const ArrayWrapperConst< const std::vector<ElmType>, ElmType > wrapArrayConst( const std::vector<ElmType>* array )
|
||||
{
|
||||
const ArrayWrapperConst< const std::vector<ElmType>, ElmType> warr(array, array->size());
|
||||
return warr;
|
||||
}
|
||||
|
||||
|
||||
template <typename ElmType>
|
||||
inline const ArrayWrapperConst< const std::vector<ElmType>, ElmType > wrapArrayConst( std::vector<ElmType>* array )
|
||||
{
|
||||
const ArrayWrapperConst< const std::vector<ElmType>, ElmType> warr(array, array->size());
|
||||
return warr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// const Bare-pointer specialization
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
template <typename ElmType>
|
||||
inline const ArrayWrapperConst< const ElmType*, ElmType > wrapArrayConst( const ElmType* array, size_t size )
|
||||
{
|
||||
const ArrayWrapperConst<const ElmType*, ElmType> warr(array, size);
|
||||
return warr;
|
||||
}
|
||||
|
||||
|
||||
template <typename ElmType>
|
||||
inline const ArrayWrapperConst< const ElmType*, ElmType > wrapArrayConst( ElmType* array, size_t size )
|
||||
{
|
||||
const ArrayWrapperConst<const ElmType*, ElmType> warr(array, size);
|
||||
return warr;
|
||||
}
|
||||
|
||||
}
|
132
Fwk/VizFwk/LibCore/cvfArrayWrapperToEdit.h
Normal file
132
Fwk/VizFwk/LibCore/cvfArrayWrapperToEdit.h
Normal file
@ -0,0 +1,132 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) Ceetron Solutions AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// This library 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.
|
||||
//
|
||||
// This library 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.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace cvf {
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
/// \class cvf::ArrayWrapperToEdit
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// A wrapper class to make it possible to use different array types with
|
||||
/// different element types in the same algorithms.
|
||||
///
|
||||
/// The implementation has a specialization for bare pointer arrays.
|
||||
/// The reason for the bare pointer specialization is the [] access implementation
|
||||
/// which is different. (*array)[] vs array[]
|
||||
///
|
||||
/// The convenience functions wrapArrayToEdit() are available to simplify wrapping of your data making it
|
||||
/// possible to do:
|
||||
/// myFunction (wrapArrayToEdit(myNodeArray), wrapArrayToEdit(myIndexArray), ...);
|
||||
/// when calling a template function using ArrayWrapperToEdit's as input.
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
template < typename ArrayType, typename ElmType >
|
||||
class ArrayWrapperToEdit
|
||||
{
|
||||
public:
|
||||
ArrayWrapperToEdit(ArrayType* array, size_t size) : m_array(array), m_size(size) { }
|
||||
|
||||
inline size_t size() const { return m_size; }
|
||||
|
||||
inline ElmType& operator[](const size_t index) { return (*m_array)[index]; }
|
||||
inline const ElmType& operator[](const size_t index) const { return (*m_array)[index]; }
|
||||
|
||||
private:
|
||||
ArrayType * m_array;
|
||||
size_t m_size;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Bare-pointer array wrapper specialization
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
template < typename ElmType >
|
||||
class ArrayWrapperToEdit <ElmType*, ElmType>
|
||||
{
|
||||
public:
|
||||
ArrayWrapperToEdit(ElmType* array, size_t size) : m_array(array), m_size(size) { }
|
||||
|
||||
inline size_t size() const { return m_size; }
|
||||
|
||||
inline ElmType& operator[](const size_t index) { return m_array[index]; }
|
||||
inline const ElmType& operator[](const size_t index) const { return m_array[index]; }
|
||||
|
||||
private:
|
||||
ElmType * m_array;
|
||||
size_t m_size;
|
||||
};
|
||||
|
||||
|
||||
#include "cvfArray.h"
|
||||
#include <vector>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// cvf::Array specialization
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename ElmType>
|
||||
inline ArrayWrapperToEdit< cvf::Array<ElmType>, ElmType > wrapArrayToEdit(cvf::Array<ElmType>* array )
|
||||
{
|
||||
ArrayWrapperToEdit<cvf::Array<ElmType>, ElmType> warr(array, array->size());
|
||||
return warr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// std::vector specialization
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
template <typename ElmType>
|
||||
inline ArrayWrapperToEdit< std::vector<ElmType>, ElmType > wrapArrayToEdit(std::vector<ElmType>* array )
|
||||
{
|
||||
ArrayWrapperToEdit<std::vector<ElmType>, ElmType> warr(array, array->size());
|
||||
return warr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Bare-pointer specialization
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
template <typename ElmType>
|
||||
inline ArrayWrapperToEdit< ElmType*, ElmType > wrapArrayToEdit(ElmType* array, size_t size )
|
||||
{
|
||||
ArrayWrapperToEdit<ElmType*, ElmType> warr(array, size);
|
||||
return warr;
|
||||
}
|
||||
|
||||
}
|
@ -13,6 +13,7 @@ include_directories(../LibCore)
|
||||
set(CEE_HEADER_FILES
|
||||
cvfArrowGenerator.h
|
||||
cvfBoundingBox.h
|
||||
cvfBoundingBoxTree.h
|
||||
cvfBoxGenerator.h
|
||||
cvfEdgeKey.h
|
||||
cvfFrustum.h
|
||||
@ -34,6 +35,7 @@ cvfVertexWelder.h
|
||||
set(CEE_SOURCE_FILES
|
||||
cvfArrowGenerator.cpp
|
||||
cvfBoundingBox.cpp
|
||||
cvfBoundingBoxTree.cpp
|
||||
cvfBoxGenerator.cpp
|
||||
cvfFrustum.cpp
|
||||
cvfEdgeKey.cpp
|
||||
|
@ -241,6 +241,7 @@
|
||||
<ItemGroup>
|
||||
<ClInclude Include="cvfArrowGenerator.h" />
|
||||
<ClInclude Include="cvfBoundingBox.h" />
|
||||
<ClInclude Include="cvfBoundingBoxTree.h" />
|
||||
<ClInclude Include="cvfBoxGenerator.h" />
|
||||
<ClInclude Include="cvfEdgeKey.h" />
|
||||
<ClInclude Include="cvfFrustum.h" />
|
||||
@ -261,6 +262,7 @@
|
||||
<ItemGroup>
|
||||
<ClCompile Include="cvfArrowGenerator.cpp" />
|
||||
<ClCompile Include="cvfBoundingBox.cpp" />
|
||||
<ClCompile Include="cvfBoundingBoxTree.cpp" />
|
||||
<ClCompile Include="cvfBoxGenerator.cpp" />
|
||||
<ClCompile Include="cvfEdgeKey.cpp" />
|
||||
<ClCompile Include="cvfFrustum.cpp" />
|
||||
|
@ -19,6 +19,7 @@
|
||||
<ClInclude Include="cvfTriangleVertexSplitter.h" />
|
||||
<ClInclude Include="cvfVertexCompactor.h" />
|
||||
<ClInclude Include="cvfTriangleMeshEdgeExtractor.h" />
|
||||
<ClInclude Include="cvfBoundingBoxTree.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="CMakeLists.txt" />
|
||||
@ -41,5 +42,6 @@
|
||||
<ClCompile Include="cvfTriangleVertexSplitter.cpp" />
|
||||
<ClCompile Include="cvfVertexCompactor.cpp" />
|
||||
<ClCompile Include="cvfTriangleMeshEdgeExtractor.cpp" />
|
||||
<ClCompile Include="cvfBoundingBoxTree.cpp" />
|
||||
</ItemGroup>
|
||||
</Project>
|
977
Fwk/VizFwk/LibGeometry/cvfBoundingBoxTree.cpp
Normal file
977
Fwk/VizFwk/LibGeometry/cvfBoundingBoxTree.cpp
Normal file
@ -0,0 +1,977 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) Ceetron Solutions AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// This library 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.
|
||||
//
|
||||
// This library 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.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#include "cvfBoundingBoxTree.h"
|
||||
|
||||
#include "cvfLibCore.h"
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfObject.h"
|
||||
#include "cvfBoundingBox.h"
|
||||
#include <cmath>
|
||||
|
||||
|
||||
namespace cvf {
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::BoundingBoxTree
|
||||
/// \ingroup Geometry
|
||||
///
|
||||
/// An axis-aligned bounding-box search tree
|
||||
///
|
||||
/// This class can be used to quickly do an approximate search for geometry using a bounding box.
|
||||
/// The geometry entities to search for must be enclosed in bounding boxes which are inserted
|
||||
/// together with an ID.
|
||||
///
|
||||
/// When intersecting, the ID's or the indexes of the intersected boundingboxes are returned,
|
||||
/// depending on whether explicit id's where supplied.
|
||||
//==================================================================================================
|
||||
|
||||
enum NodeType
|
||||
{
|
||||
AB_UNDEFINED,
|
||||
AB_LEAF,
|
||||
AB_INTERNAL,
|
||||
AB_LEAF_GROUP
|
||||
};
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
class AABBTreeNode
|
||||
{
|
||||
public:
|
||||
AABBTreeNode();
|
||||
virtual ~AABBTreeNode() {}
|
||||
|
||||
const cvf::BoundingBox& boundingBox() const;
|
||||
void setBoundingBox(const cvf::BoundingBox bb);
|
||||
|
||||
NodeType type() const;
|
||||
|
||||
protected:
|
||||
NodeType m_type;
|
||||
|
||||
private:
|
||||
cvf::BoundingBox m_boundingBox;
|
||||
};
|
||||
|
||||
|
||||
//=================================================================================================================================
|
||||
/// Internal node in the AABB tree. It have at least two child nodes, but can have many more (grand-children etc.). Both the Left
|
||||
/// and right tree node pointes must exist (or else it should be a leaf node).
|
||||
//=================================================================================================================================
|
||||
class AABBTreeNodeInternal : public AABBTreeNode
|
||||
{
|
||||
public:
|
||||
AABBTreeNodeInternal();
|
||||
AABBTreeNodeInternal(AABBTreeNode* left, AABBTreeNode* right);
|
||||
|
||||
void setLeft(AABBTreeNode* left);
|
||||
AABBTreeNode* left();
|
||||
const AABBTreeNode* left() const;
|
||||
|
||||
void setRight(AABBTreeNode* right);
|
||||
AABBTreeNode* right();
|
||||
const AABBTreeNode* right() const;
|
||||
|
||||
private:
|
||||
AABBTreeNode* m_pLeft; ///< Left child of this internal node in the binary AABB tree
|
||||
AABBTreeNode* m_pRight; ///< Right child of this internal node in the binary AABB tree
|
||||
};
|
||||
|
||||
|
||||
//=================================================================================================================================
|
||||
/// Standard leaf node in the AABB tree. The leaf node contains only an index, and the interpretation of this index is depending on
|
||||
/// the type of AABB tree using the node.
|
||||
//=================================================================================================================================
|
||||
class AABBTreeNodeLeaf : public AABBTreeNode
|
||||
{
|
||||
public:
|
||||
AABBTreeNodeLeaf(size_t index);
|
||||
|
||||
size_t index() const;
|
||||
|
||||
private:
|
||||
size_t m_index; ///< An index of the leaf node. The interpretation of this index is depending on which tree the node is in.
|
||||
};
|
||||
|
||||
|
||||
//=================================================================================================================================
|
||||
/// Group leaf node in the AABB tree. The leaf node contains an array with indices, and the interpretation of these are depending on
|
||||
/// the type of AABB tree using the node.
|
||||
//=================================================================================================================================
|
||||
class AABBTreeNodeLeafGroup : public AABBTreeNode
|
||||
{
|
||||
public:
|
||||
AABBTreeNodeLeafGroup();
|
||||
|
||||
size_t addIndex(size_t index);
|
||||
const std::vector<size_t>& indices() const;
|
||||
|
||||
void sort();
|
||||
|
||||
private:
|
||||
std::vector<size_t> m_indices; ///< The interpretation of these indices is depending on which tree the node is in.
|
||||
};
|
||||
|
||||
|
||||
|
||||
//=================================================================================================================================
|
||||
//
|
||||
/// An axis oriented bounding box tree. This is an abstract base class for AABB trees used for searching and intersection testing.
|
||||
/// All classes deriving from this must implement the CreateLeaves() method. This method creates all the leaf nodes in the AABB
|
||||
/// tree and is called as a part of the BuildTree() process.
|
||||
///
|
||||
/// This base class handles the building of the tree with all the internal nodes. It also handles basic intersection and searching,
|
||||
/// but the IntersectLeafLeaf() and IntersectBoxLeaf() methods should be implemented in any tree classes used for intersection
|
||||
/// testing.
|
||||
///
|
||||
/// The Find() method only searches for matches in bounding boxes, and must be reimplemented in the decendant classes for
|
||||
/// accurate testing of leaf nodes when the leaf node properties are known.
|
||||
//=================================================================================================================================
|
||||
class AABBTree : public cvf::Object
|
||||
{
|
||||
public:
|
||||
AABBTree();
|
||||
virtual ~AABBTree();
|
||||
|
||||
|
||||
virtual void free();
|
||||
|
||||
bool buildTree();
|
||||
|
||||
size_t treeSize() const;
|
||||
size_t leavesCount() const;
|
||||
bool boundingBox(cvf::BoundingBox* pBox) const;
|
||||
|
||||
cvf::String treeInfo() const;
|
||||
|
||||
protected:
|
||||
virtual bool createLeaves() = 0;
|
||||
virtual size_t treeNodeSize(const AABBTreeNode* pNode) const;
|
||||
|
||||
virtual AABBTreeNodeLeafGroup* createGroupNode(size_t iStartIdx, size_t iEndIdx);
|
||||
|
||||
void freeThis();
|
||||
void deleteInternalNodes(AABBTreeNode* pNode);
|
||||
|
||||
size_t treeSize(const AABBTreeNode* pNode) const;
|
||||
size_t treeHeight(const AABBTreeNode* pNode, size_t iLevel, size_t* piMin, size_t* piMax) const;
|
||||
void leafBoundingBox(cvf::BoundingBox& pBox, size_t iStartIdx, size_t iEndIdx) const;
|
||||
bool buildTree(AABBTreeNodeInternal* pNode, size_t iFromIdx, size_t iToIdx);
|
||||
|
||||
// Queries
|
||||
bool intersect(const AABBTreeNode* pA, const AABBTreeNode* pB) const;
|
||||
|
||||
|
||||
protected:
|
||||
std::vector<AABBTreeNodeLeaf*> m_ppLeaves;
|
||||
size_t m_iNumLeaves;
|
||||
|
||||
AABBTreeNode* m_pRoot;
|
||||
|
||||
bool m_bUseGroupNodes;
|
||||
size_t m_iGroupLimit;
|
||||
};
|
||||
|
||||
class BoundingBoxTreeImpl : public AABBTree
|
||||
{
|
||||
BoundingBoxTreeImpl() {}
|
||||
|
||||
private:
|
||||
friend class BoundingBoxTree;
|
||||
|
||||
bool createLeaves();
|
||||
void findIntersections(const cvf::BoundingBox& bb, std::vector<size_t>& bbIds) const;
|
||||
|
||||
void findIntersections(const cvf::BoundingBox& bb, const AABBTreeNode* node, std::vector<size_t>& indices) const;
|
||||
|
||||
const std::vector<cvf::BoundingBox>* m_boundingBoxes;
|
||||
const std::vector<size_t>* m_optionalBoundingBoxIds;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
namespace cvf {
|
||||
|
||||
using cvf::ref;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int largestComponent(const cvf::Vec3d v)
|
||||
{
|
||||
double maxLength = v.x();
|
||||
int idx = 0;
|
||||
|
||||
if (v.y() > maxLength)
|
||||
{
|
||||
maxLength = v.y();
|
||||
idx = 1;
|
||||
}
|
||||
|
||||
if (v.z() > maxLength)
|
||||
{
|
||||
maxLength = v.z();
|
||||
idx = 2;
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
||||
double largestComponent(const cvf::Vec3d v, cvf::uint* largestIndex)
|
||||
{
|
||||
double length = v.x();
|
||||
cvf::uint idx = 0;
|
||||
|
||||
if (v.y() > length)
|
||||
{
|
||||
length = v.y();
|
||||
idx = 1;
|
||||
}
|
||||
|
||||
if (v.z() > length)
|
||||
{
|
||||
length = v.z();
|
||||
idx = 2;
|
||||
}
|
||||
|
||||
if (largestIndex) *largestIndex = idx;
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
AABBTreeNode::AABBTreeNode()
|
||||
{
|
||||
m_type = AB_UNDEFINED;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const cvf::BoundingBox& AABBTreeNode::boundingBox() const
|
||||
{
|
||||
return m_boundingBox;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
NodeType AABBTreeNode::type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void AABBTreeNode::setBoundingBox(const cvf::BoundingBox bb)
|
||||
{
|
||||
m_boundingBox = bb;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
AABBTreeNodeInternal::AABBTreeNodeInternal(AABBTreeNode* left, AABBTreeNode* right)
|
||||
{
|
||||
m_type = AB_INTERNAL;
|
||||
|
||||
CVF_ASSERT(left);
|
||||
CVF_ASSERT(right);
|
||||
|
||||
m_pLeft = left;
|
||||
m_pRight = right;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
AABBTreeNodeInternal::AABBTreeNodeInternal()
|
||||
{
|
||||
m_type = AB_INTERNAL;
|
||||
|
||||
m_pLeft = NULL;
|
||||
m_pRight = NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const AABBTreeNode* AABBTreeNodeInternal::left() const
|
||||
{
|
||||
return m_pLeft;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
AABBTreeNode* AABBTreeNodeInternal::left()
|
||||
{
|
||||
return m_pLeft;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const AABBTreeNode* AABBTreeNodeInternal::right() const
|
||||
{
|
||||
return m_pRight;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
AABBTreeNode* AABBTreeNodeInternal::right()
|
||||
{
|
||||
return m_pRight;
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void AABBTreeNodeInternal::setLeft(AABBTreeNode* left)
|
||||
{
|
||||
CVF_ASSERT(left);
|
||||
m_pLeft = left;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void AABBTreeNodeInternal::setRight(AABBTreeNode* right)
|
||||
{
|
||||
CVF_ASSERT(right);
|
||||
m_pRight = right;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
AABBTreeNodeLeaf::AABBTreeNodeLeaf(size_t index)
|
||||
{
|
||||
m_type = AB_LEAF;
|
||||
|
||||
m_index = index;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t AABBTreeNodeLeaf::index() const
|
||||
{
|
||||
return m_index;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t AABBTreeNodeLeafGroup::addIndex(size_t index)
|
||||
{
|
||||
m_indices.push_back(index);
|
||||
|
||||
return m_indices.size() - 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const std::vector<size_t>& AABBTreeNodeLeafGroup::indices() const
|
||||
{
|
||||
return m_indices;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
AABBTreeNodeLeafGroup::AABBTreeNodeLeafGroup()
|
||||
{
|
||||
m_type = AB_LEAF_GROUP;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void AABBTreeNodeLeafGroup::sort()
|
||||
{
|
||||
std::sort(m_indices.begin(), m_indices.end());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
AABBTree::AABBTree()
|
||||
{
|
||||
m_pRoot = NULL;
|
||||
m_iNumLeaves = 0;
|
||||
|
||||
m_bUseGroupNodes = false;
|
||||
m_iGroupLimit = 33;
|
||||
|
||||
// ResetStatistics();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
AABBTree::~AABBTree()
|
||||
{
|
||||
freeThis();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void AABBTree::free()
|
||||
{
|
||||
freeThis();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool AABBTree::buildTree()
|
||||
{
|
||||
|
||||
// Possibly delete the tree before building it
|
||||
freeThis();
|
||||
|
||||
// First, create all the leaves
|
||||
if (!createLeaves()) return false;
|
||||
|
||||
if (m_iNumLeaves == 0) return true;
|
||||
|
||||
// Then find the bounding box of all items in the tree
|
||||
cvf::BoundingBox box;
|
||||
leafBoundingBox(box, 0, m_iNumLeaves - 1);
|
||||
|
||||
// Create the root
|
||||
if (m_iNumLeaves == 1)
|
||||
{
|
||||
m_pRoot = m_ppLeaves[0];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
m_pRoot = new AABBTreeNodeInternal();
|
||||
m_pRoot->setBoundingBox(box);
|
||||
|
||||
bool bRes = buildTree((AABBTreeNodeInternal*)m_pRoot, 0, m_iNumLeaves - 1);
|
||||
|
||||
return bRes;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool AABBTree::buildTree(AABBTreeNodeInternal* pNode, size_t iFromIdx, size_t iToIdx)
|
||||
{
|
||||
if (!pNode->boundingBox().isValid()) return false;
|
||||
|
||||
int iLongestAxis = largestComponent(pNode->boundingBox().extent());
|
||||
|
||||
double splitValue = pNode->boundingBox().center()[iLongestAxis];
|
||||
size_t i = iFromIdx;
|
||||
size_t iMid = iToIdx;
|
||||
|
||||
//=================================================================================================================================
|
||||
//
|
||||
// Geometric split tree - best!
|
||||
//
|
||||
//=================================================================================================================================
|
||||
// Order the leaves according to the position of the center of each BB in comparison with longest axis of the BB
|
||||
while (i < iMid)
|
||||
{
|
||||
if (!(m_ppLeaves[i]->boundingBox().isValid()) || m_ppLeaves[i]->boundingBox().center()[iLongestAxis] < splitValue)
|
||||
{
|
||||
// Ok, move on
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Swap, and move iMid back
|
||||
AABBTreeNodeLeaf* pTemp = m_ppLeaves[i];
|
||||
m_ppLeaves[i] = m_ppLeaves[iMid];
|
||||
m_ppLeaves[iMid] = pTemp;
|
||||
|
||||
iMid--;
|
||||
}
|
||||
}
|
||||
|
||||
if ((iMid == iFromIdx) || (iMid == iToIdx))
|
||||
{
|
||||
iMid = (iToIdx + iFromIdx)/2;
|
||||
}
|
||||
|
||||
// Create the left tree
|
||||
if (iMid > iFromIdx)
|
||||
{
|
||||
if (m_bUseGroupNodes && ((iMid - iFromIdx + 1) < m_iGroupLimit))
|
||||
{
|
||||
|
||||
pNode->setLeft(createGroupNode(iFromIdx, iMid));
|
||||
}
|
||||
else
|
||||
{
|
||||
cvf::BoundingBox box;
|
||||
leafBoundingBox(box, iFromIdx, iMid);
|
||||
|
||||
AABBTreeNodeInternal* newNode = new AABBTreeNodeInternal;
|
||||
newNode->setBoundingBox(box);
|
||||
pNode->setLeft(newNode);
|
||||
|
||||
if (!buildTree((AABBTreeNodeInternal*)pNode->left(), iFromIdx, iMid)) return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pNode->setLeft(m_ppLeaves[iFromIdx]);
|
||||
}
|
||||
|
||||
// Create the right tree
|
||||
if (iMid < (iToIdx - 1))
|
||||
{
|
||||
if (m_bUseGroupNodes && ((iToIdx - (iMid + 1) + 1) < m_iGroupLimit))
|
||||
{
|
||||
pNode->setRight(createGroupNode(iMid + 1, iToIdx));
|
||||
}
|
||||
else
|
||||
{
|
||||
cvf::BoundingBox box;
|
||||
leafBoundingBox(box, iMid + 1, iToIdx);
|
||||
|
||||
AABBTreeNodeInternal* newNode = new AABBTreeNodeInternal;
|
||||
newNode->setBoundingBox(box);
|
||||
pNode->setRight(newNode);
|
||||
|
||||
if (!buildTree((AABBTreeNodeInternal*)pNode->right(), iMid + 1, iToIdx)) return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pNode->setRight(m_ppLeaves[iToIdx]);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void AABBTree::freeThis()
|
||||
{
|
||||
// Delete all the internal nodes
|
||||
if (m_pRoot)
|
||||
{
|
||||
// This also deletes m_pRoot if not a leaf. If it is a leaf, it is deleted below
|
||||
deleteInternalNodes(m_pRoot);
|
||||
|
||||
m_pRoot = NULL;
|
||||
}
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < m_iNumLeaves; i++)
|
||||
{
|
||||
// Might be NULL if group nodes are used
|
||||
if (m_ppLeaves[i])
|
||||
{
|
||||
delete(m_ppLeaves[i]);
|
||||
}
|
||||
}
|
||||
|
||||
m_ppLeaves.clear();
|
||||
|
||||
m_iNumLeaves = 0;
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void AABBTree::deleteInternalNodes(AABBTreeNode* pNode)
|
||||
{
|
||||
CVF_ASSERT(pNode);
|
||||
|
||||
if (pNode->type() == AB_LEAF) return;
|
||||
|
||||
if (pNode->type() == AB_LEAF_GROUP)
|
||||
{
|
||||
delete(pNode);
|
||||
return;
|
||||
}
|
||||
|
||||
AABBTreeNodeInternal* pInt = (AABBTreeNodeInternal*)pNode;
|
||||
|
||||
deleteInternalNodes(pInt->left());
|
||||
deleteInternalNodes(pInt->right());
|
||||
|
||||
delete(pNode);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
AABBTreeNodeLeafGroup* AABBTree::createGroupNode(size_t iStartIdx, size_t iEndIdx)
|
||||
{
|
||||
size_t iNumItems = iEndIdx - iStartIdx + 1;
|
||||
CVF_ASSERT(iNumItems > 1);
|
||||
|
||||
AABBTreeNodeLeafGroup* pNode = new AABBTreeNodeLeafGroup;
|
||||
if (!pNode) return NULL;
|
||||
|
||||
cvf::BoundingBox bb;
|
||||
leafBoundingBox(bb, iStartIdx, iEndIdx);
|
||||
pNode->setBoundingBox(bb);
|
||||
|
||||
size_t i;
|
||||
for (i = iStartIdx; i <= iEndIdx; i++)
|
||||
{
|
||||
pNode->addIndex(m_ppLeaves[i]->index());
|
||||
|
||||
// Delete the original leaf
|
||||
delete(m_ppLeaves[i]);
|
||||
|
||||
m_ppLeaves[i] = NULL;
|
||||
}
|
||||
|
||||
// Sort the element indices (this is not really required)
|
||||
// This is done to give then same result as the old implementation that did just a linear search in cases where
|
||||
// the points are on the element surfaces and thus will give multiple hits.
|
||||
//
|
||||
// The performance hit of this seems very small.
|
||||
pNode->sort();
|
||||
|
||||
return pNode;
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void AABBTree::leafBoundingBox(cvf::BoundingBox& bb, size_t iStartIdx, size_t iEndIdx) const
|
||||
{
|
||||
CVF_ASSERT(iStartIdx <= iEndIdx);
|
||||
|
||||
bb.reset();
|
||||
|
||||
size_t i;
|
||||
for (i = iStartIdx; i <= iEndIdx; i++)
|
||||
{
|
||||
CVF_ASSERT(m_ppLeaves[i]);
|
||||
bb.add(m_ppLeaves[i]->boundingBox());
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t AABBTree::treeSize(const AABBTreeNode* pNode) const
|
||||
{
|
||||
CVF_ASSERT(pNode);
|
||||
|
||||
if (pNode->type() == AB_LEAF)
|
||||
{
|
||||
return treeNodeSize(pNode);
|
||||
}
|
||||
|
||||
if (pNode->type() == AB_LEAF_GROUP)
|
||||
{
|
||||
return treeNodeSize(pNode);
|
||||
}
|
||||
|
||||
const AABBTreeNodeInternal* pInt = (const AABBTreeNodeInternal*)pNode;
|
||||
|
||||
return treeNodeSize(pInt) + treeSize(pInt->left()) + treeSize(pInt->right());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t AABBTree::treeSize() const
|
||||
{
|
||||
if (m_pRoot) return treeSize(m_pRoot);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t AABBTree::treeNodeSize(const AABBTreeNode* pNode) const
|
||||
{
|
||||
CVF_ASSERT(pNode);
|
||||
|
||||
if (pNode->type() == AB_INTERNAL) return sizeof(AABBTreeNodeInternal);
|
||||
if (pNode->type() == AB_LEAF) return sizeof(AABBTreeNodeLeaf);
|
||||
if (pNode->type() == AB_LEAF_GROUP)
|
||||
{
|
||||
const AABBTreeNodeLeafGroup* pLeafGroup = (const AABBTreeNodeLeafGroup*)pNode;
|
||||
|
||||
return static_cast<size_t>(sizeof(AABBTreeNodeLeafGroup) + static_cast<size_t>(pLeafGroup->indices().size()) * sizeof(cvf::uint));
|
||||
}
|
||||
|
||||
// Should not get here...
|
||||
CVF_ASSERT(0);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t AABBTree::treeHeight(const AABBTreeNode* pNode, size_t iLevel, size_t* piMin, size_t* piMax) const
|
||||
{
|
||||
CVF_ASSERT(pNode);
|
||||
|
||||
if ((pNode->type() == AB_LEAF) || (pNode->type() == AB_LEAF_GROUP))
|
||||
{
|
||||
if (iLevel < *piMin) *piMin = iLevel;
|
||||
if (iLevel > *piMax) *piMax = iLevel;
|
||||
|
||||
return iLevel;
|
||||
}
|
||||
|
||||
const AABBTreeNodeInternal* pInt = (const AABBTreeNodeInternal*)pNode;
|
||||
|
||||
iLevel++;
|
||||
|
||||
return treeHeight(pInt->left(), iLevel, piMin, piMax) + treeHeight(pInt->right(), iLevel, piMin, piMax);
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::String AABBTree::treeInfo() const
|
||||
{
|
||||
cvf::String sInfo;
|
||||
|
||||
/*
|
||||
sInfo = cvf::String("Tree size: %1 \n").arg(static_cast<int>(treeSize()));
|
||||
sInfo += cvf::String("Num leaves: %1 \n").arg(static_cast<int>(leavesCount()));
|
||||
|
||||
size_t iMin = cvf::UNDEFINED_UINT;
|
||||
size_t iMax = 0;
|
||||
size_t iSumHeight = treeHeight(m_pRoot, 1, &iMin, &iMax);
|
||||
size_t iAvgHeigth = 0;
|
||||
size_t iIdealHeigth = 0;
|
||||
|
||||
if (leavesCount() > 0 ) iAvgHeigth = iSumHeight/leavesCount();
|
||||
|
||||
sInfo += VTString::MakeForm("Tree height: Min: %d - Max: %d - Avg: %d - Ideal: %d\n", iMin, iMax, iAvgHeigth, (VTint)ceil((log((VTfloat)GetNumLeaves())/log(2.0f))));
|
||||
iIdealHeigth = (cvf::uint)ceil((log((float)leavesCount())/log(2.0f)));
|
||||
sInfo = cvf::String("Tree height: Min: %1 - Max: %2 - Avg: %3 - Ideal: %4\n").arg(iMin).arg(iMax).arg(iAvgHeigth).arg(iIdealHeigth);
|
||||
|
||||
cvf::BoundingBox bb;
|
||||
boundingBox(&bb);
|
||||
sInfo += bb.debugString();
|
||||
*/
|
||||
|
||||
return sInfo;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool AABBTree::boundingBox(cvf::BoundingBox* pBox) const
|
||||
{
|
||||
CVF_ASSERT(pBox);
|
||||
|
||||
if (!m_pRoot) return false;
|
||||
|
||||
*pBox = m_pRoot->boundingBox();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t AABBTree::leavesCount() const
|
||||
{
|
||||
return m_iNumLeaves;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool AABBTree::intersect(const AABBTreeNode* pA, const AABBTreeNode* pB) const
|
||||
{
|
||||
return pA->boundingBox().intersects(pB->boundingBox());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Creates leafs for the supplied valid bounding boxes, keeping the original index
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool BoundingBoxTreeImpl::createLeaves()
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < m_boundingBoxes->size(); i++)
|
||||
{
|
||||
if (!(*m_boundingBoxes)[i].isValid()) continue;
|
||||
size_t bbId = i;
|
||||
if (m_optionalBoundingBoxIds) bbId = (*m_optionalBoundingBoxIds)[i];
|
||||
|
||||
AABBTreeNodeLeaf* leaf = new AABBTreeNodeLeaf(bbId);
|
||||
|
||||
leaf->setBoundingBox((*m_boundingBoxes)[i]);
|
||||
|
||||
m_ppLeaves.push_back(leaf);
|
||||
}
|
||||
|
||||
m_iNumLeaves = m_ppLeaves.size();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Find all indices to all bounding boxes intersecting the given bounding box and add them to indices
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void BoundingBoxTreeImpl::findIntersections(const cvf::BoundingBox& bb, std::vector<size_t>& indices) const
|
||||
{
|
||||
if (bb.isValid())
|
||||
{
|
||||
findIntersections(bb, m_pRoot, indices);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void BoundingBoxTreeImpl::findIntersections(const cvf::BoundingBox& bb, const AABBTreeNode* node, std::vector<size_t>& cvIndices) const
|
||||
{
|
||||
CVF_TIGHT_ASSERT(bb.isValid());
|
||||
|
||||
if (node && bb.intersects(node->boundingBox()))
|
||||
{
|
||||
if (node->type() == AB_LEAF)
|
||||
{
|
||||
const AABBTreeNodeLeaf* leaf = static_cast<const AABBTreeNodeLeaf*>(node);
|
||||
{
|
||||
cvIndices.push_back(leaf->index());
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (node->type() == AB_INTERNAL)
|
||||
{
|
||||
const AABBTreeNodeInternal* internalNode = static_cast<const AABBTreeNodeInternal*>(node);
|
||||
|
||||
findIntersections(bb, internalNode->left(), cvIndices);
|
||||
findIntersections(bb, internalNode->right(), cvIndices);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
BoundingBoxTree::BoundingBoxTree()
|
||||
{
|
||||
m_implTree = new BoundingBoxTreeImpl;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
BoundingBoxTree::~BoundingBoxTree()
|
||||
{
|
||||
delete m_implTree;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Build a tree representation of valid bounding boxes. Invalid bounding boxes are ignored
|
||||
/// The supplied ID array is the ID's returned in the intersection method.
|
||||
/// If the ID array is omitted, the index of the bounding boxes are returned.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void BoundingBoxTree::buildTreeFromBoundingBoxes(const std::vector<cvf::BoundingBox>& boundingBoxes,
|
||||
const std::vector<size_t>* optionalBoundingBoxIds)
|
||||
{
|
||||
if (optionalBoundingBoxIds) CVF_ASSERT(boundingBoxes.size() == optionalBoundingBoxIds->size());
|
||||
|
||||
m_implTree->m_boundingBoxes = &boundingBoxes;
|
||||
m_implTree->m_optionalBoundingBoxIds = optionalBoundingBoxIds;
|
||||
|
||||
m_implTree->buildTree();
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Find all indices to all bounding boxes intersecting the given bounding box and add them to indices
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void BoundingBoxTree::findIntersections(const cvf::BoundingBox& bb, std::vector<size_t>* bbIdsOrIndices) const
|
||||
{
|
||||
CVF_ASSERT(bbIdsOrIndices);
|
||||
|
||||
m_implTree->findIntersections(bb, *bbIdsOrIndices);
|
||||
}
|
||||
|
||||
} // namespace cvf
|
||||
|
69
Fwk/VizFwk/LibGeometry/cvfBoundingBoxTree.h
Normal file
69
Fwk/VizFwk/LibGeometry/cvfBoundingBoxTree.h
Normal file
@ -0,0 +1,69 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) Ceetron Solutions AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// This library 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.
|
||||
//
|
||||
// This library 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.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfObject.h"
|
||||
#include "cvfBoundingBox.h"
|
||||
|
||||
namespace cvf {
|
||||
|
||||
class BoundingBoxTreeImpl;
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// An axis-aligned bounding-box search tree class
|
||||
//
|
||||
//==================================================================================================
|
||||
class BoundingBoxTree : public cvf::Object
|
||||
{
|
||||
public:
|
||||
BoundingBoxTree();
|
||||
~BoundingBoxTree();
|
||||
|
||||
void buildTreeFromBoundingBoxes(const std::vector<cvf::BoundingBox>& boundingBoxes,
|
||||
const std::vector<size_t>* optionalBoundingBoxIds);
|
||||
|
||||
void findIntersections(const cvf::BoundingBox& inputBB, std::vector<size_t>* bbIdsOrIndexesIntersected) const;
|
||||
|
||||
private:
|
||||
|
||||
BoundingBoxTreeImpl* m_implTree;
|
||||
};
|
||||
|
||||
} // Namespace cvf
|
||||
|
@ -13,6 +13,7 @@ set(CEE_LIBS LibCore)
|
||||
|
||||
set(CEE_SOURCE_FILES
|
||||
cvfArray-Test.cpp
|
||||
cvfArrayWrapper-Test.cpp
|
||||
cvfBase-Test.cpp
|
||||
cvfBase64-Test.cpp
|
||||
cvfCharArray-Test.cpp
|
||||
|
@ -250,6 +250,7 @@
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\ThirdParty\gtest\gtest-all.cpp" />
|
||||
<ClCompile Include="cvfArray-Test.cpp" />
|
||||
<ClCompile Include="cvfArrayWrapper-Test.cpp" />
|
||||
<ClCompile Include="cvfBase-Test.cpp" />
|
||||
<ClCompile Include="cvfBase64-Test.cpp" />
|
||||
<ClCompile Include="cvfCharArray-Test.cpp" />
|
||||
|
@ -32,6 +32,7 @@
|
||||
<ClCompile Include="cvfLogger-Test.cpp" />
|
||||
<ClCompile Include="cvfLogEvent-Test.cpp" />
|
||||
<ClCompile Include="cvfCodeLocation-Test.cpp" />
|
||||
<ClCompile Include="cvfArrayWrapper-Test.cpp" />
|
||||
<ClCompile Include="cvfProgramOptions-Test.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@ -40,4 +41,4 @@
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="TriggerTBBCopy.txt" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
189
Fwk/VizFwk/Tests/LibCore_UnitTests/cvfArrayWrapper-Test.cpp
Normal file
189
Fwk/VizFwk/Tests/LibCore_UnitTests/cvfArrayWrapper-Test.cpp
Normal file
@ -0,0 +1,189 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) Ceetron Solutions AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// This library 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.
|
||||
//
|
||||
// This library 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.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfArray.h"
|
||||
#include "cvfArrayWrapperToEdit.h"
|
||||
#include "cvfArrayWrapperConst.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace cvf;
|
||||
|
||||
|
||||
|
||||
template <typename ArrayType, typename ElmType>
|
||||
void arrayWrapperConstTestFunction(const ArrayWrapperConst< ArrayType, ElmType> cinRefArray)
|
||||
{
|
||||
ElmType e;
|
||||
size_t size;
|
||||
|
||||
size = cinRefArray.size();
|
||||
e = cinRefArray[size-1];
|
||||
CVF_UNUSED(e);
|
||||
// cinRefArray[size-1] = e;
|
||||
{
|
||||
const ElmType& cre = cinRefArray[size-1];
|
||||
CVF_UNUSED(cre);
|
||||
|
||||
//ElmType& re = cinRefArray[size-1];
|
||||
//re = e;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ArrayType, typename ElmType>
|
||||
void arrayWrapperConstRefTestFunction(const ArrayWrapperConst< ArrayType, ElmType>& cinRefArray)
|
||||
{
|
||||
ElmType e;
|
||||
size_t size;
|
||||
|
||||
size = cinRefArray.size();
|
||||
e = cinRefArray[size-1];
|
||||
CVF_UNUSED(e);
|
||||
// cinRefArray[size-1] = e;
|
||||
{
|
||||
const ElmType& cre = cinRefArray[size-1];
|
||||
CVF_UNUSED(cre);
|
||||
//ElmType& re = cinRefArray[size-1];
|
||||
//re = e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename ArrayType, typename ElmType>
|
||||
void arrayWrapperTestFunction(ArrayWrapperToEdit< ArrayType, ElmType> cinRefArray)
|
||||
{
|
||||
ElmType e, e2;
|
||||
size_t size;
|
||||
|
||||
size = cinRefArray.size();
|
||||
e = cinRefArray[size-1];
|
||||
e2 = cinRefArray[0];
|
||||
cinRefArray[0] = e;
|
||||
{
|
||||
const ElmType& cre = cinRefArray[size-1];
|
||||
CVF_UNUSED(cre);
|
||||
ElmType& re = cinRefArray[size-1];
|
||||
re = e2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(ArrayWrapperTest, AllSpecializations)
|
||||
{
|
||||
std::vector<cvf::Vec3d> vec3dStdVector;
|
||||
vec3dStdVector.push_back(Vec3d::ZERO);
|
||||
vec3dStdVector.push_back(Vec3d(1,1,1));
|
||||
|
||||
const std::vector<cvf::Vec3d> &cvec3dStdVector = vec3dStdVector;
|
||||
|
||||
cvf::Vec3dArray vec3dCvfArray(vec3dStdVector);
|
||||
const cvf::Vec3dArray& cvec3dCvfArray = vec3dCvfArray;
|
||||
|
||||
cvf::Array<size_t> siztCvfArray(2);
|
||||
siztCvfArray[0] = 0;
|
||||
siztCvfArray[1] = 1;
|
||||
|
||||
cvf::Array<uint> uintCvfArray(2);
|
||||
uintCvfArray[0] = 0;
|
||||
uintCvfArray[1] = 1;
|
||||
const cvf::Array<uint>& cuintCvfArray = uintCvfArray;
|
||||
|
||||
size_t siztBarePtrArray[2] = {0, 1};
|
||||
|
||||
size_t* siztBarePtr = new size_t[2];
|
||||
siztBarePtr[0] = 0;
|
||||
siztBarePtr[1] = 1;
|
||||
|
||||
const size_t* csiztBarePtr = siztBarePtr;
|
||||
|
||||
cvf::uint* uintBarePtr = new cvf::uint[2];
|
||||
uintBarePtr[0] = 0;
|
||||
uintBarePtr[1] = 1;
|
||||
|
||||
double* doubleBarePtr = new double[2];
|
||||
doubleBarePtr[0] = 0;
|
||||
doubleBarePtr[1] = 1;
|
||||
const double* cdoubleBarePtr = doubleBarePtr;
|
||||
|
||||
arrayWrapperConstTestFunction(wrapArrayConst(&vec3dStdVector));
|
||||
arrayWrapperConstTestFunction(wrapArrayConst(&cvec3dStdVector));
|
||||
arrayWrapperConstTestFunction(wrapArrayConst(&vec3dCvfArray));
|
||||
arrayWrapperConstTestFunction(wrapArrayConst(&cvec3dCvfArray));
|
||||
arrayWrapperConstTestFunction(wrapArrayConst(&uintCvfArray));
|
||||
arrayWrapperConstTestFunction(wrapArrayConst(&cuintCvfArray));
|
||||
arrayWrapperConstTestFunction(wrapArrayConst(siztBarePtrArray, 2));
|
||||
arrayWrapperConstTestFunction(wrapArrayConst(siztBarePtr, 2));
|
||||
arrayWrapperConstTestFunction(wrapArrayConst(csiztBarePtr, 2));
|
||||
arrayWrapperConstTestFunction(wrapArrayConst(doubleBarePtr,2));
|
||||
arrayWrapperConstTestFunction(wrapArrayConst(cdoubleBarePtr, 2));
|
||||
|
||||
arrayWrapperConstRefTestFunction(wrapArrayConst(&vec3dStdVector));
|
||||
arrayWrapperConstRefTestFunction(wrapArrayConst(&cvec3dStdVector));
|
||||
arrayWrapperConstRefTestFunction(wrapArrayConst(&vec3dCvfArray));
|
||||
arrayWrapperConstRefTestFunction(wrapArrayConst(&cvec3dCvfArray));
|
||||
arrayWrapperConstRefTestFunction(wrapArrayConst(&uintCvfArray));
|
||||
arrayWrapperConstRefTestFunction(wrapArrayConst(&cuintCvfArray));
|
||||
arrayWrapperConstRefTestFunction(wrapArrayConst(siztBarePtrArray, 2));
|
||||
arrayWrapperConstRefTestFunction(wrapArrayConst(siztBarePtr, 2));
|
||||
arrayWrapperConstRefTestFunction(wrapArrayConst(csiztBarePtr, 2));
|
||||
arrayWrapperConstRefTestFunction(wrapArrayConst(doubleBarePtr,2));
|
||||
arrayWrapperConstRefTestFunction(wrapArrayConst(cdoubleBarePtr, 2));
|
||||
|
||||
arrayWrapperTestFunction(wrapArrayToEdit(&vec3dStdVector));
|
||||
//arrayWrapperTestFunction3(wrapArray(&cvec3dStdVector));
|
||||
EXPECT_EQ(Vec3d::ZERO, vec3dStdVector[1]);
|
||||
EXPECT_EQ(Vec3d(1,1,1), vec3dStdVector[0]);
|
||||
|
||||
arrayWrapperTestFunction(wrapArrayToEdit(&vec3dCvfArray));
|
||||
EXPECT_EQ(Vec3d::ZERO, vec3dCvfArray[1]);
|
||||
EXPECT_EQ(Vec3d(1,1,1), vec3dStdVector[0]);
|
||||
//arrayWrapperTestFunction3(wrapArray(&cvec3dCvfArray));
|
||||
arrayWrapperTestFunction(wrapArrayToEdit(&uintCvfArray));
|
||||
//arrayWrapperTestFunction3(wrapArray(&cuintCvfArray));
|
||||
arrayWrapperTestFunction(wrapArrayToEdit(siztBarePtrArray, 2));
|
||||
//arrayWrapperTestFunction3(wrapArray(csiztBarePtr, 2));
|
||||
arrayWrapperTestFunction(wrapArrayToEdit(doubleBarePtr,2));
|
||||
//arrayWrapperTestFunction3(wrapArray(cdoubleBarePtr, 2));
|
||||
EXPECT_EQ(0.0, doubleBarePtr[1]);
|
||||
EXPECT_EQ(1.0, doubleBarePtr[0]);
|
||||
}
|
@ -15,6 +15,7 @@ set(CEE_LIBS LibGeometry LibCore)
|
||||
set(CEE_SOURCE_FILES
|
||||
cvfArrowGenerator-Test.cpp
|
||||
cvfBoundingBox-Test.cpp
|
||||
cvfBoundingBoxTree-Test.cpp
|
||||
cvfBoxGenerator-Test.cpp
|
||||
cvfFrustum-Test.cpp
|
||||
cvfEdgeKey-Test.cpp
|
||||
|
@ -251,6 +251,7 @@
|
||||
<ClCompile Include="..\..\ThirdParty\gtest\gtest-all.cpp" />
|
||||
<ClCompile Include="cvfArrowGenerator-Test.cpp" />
|
||||
<ClCompile Include="cvfBoundingBox-Test.cpp" />
|
||||
<ClCompile Include="cvfBoundingBoxTree-Test.cpp" />
|
||||
<ClCompile Include="cvfBoxGenerator-Test.cpp" />
|
||||
<ClCompile Include="cvfEdgeKey-Test.cpp" />
|
||||
<ClCompile Include="cvfFrustum-Test.cpp" />
|
||||
|
@ -20,6 +20,7 @@
|
||||
<ClCompile Include="cvfTriangleVertexSplitter-Test.cpp" />
|
||||
<ClCompile Include="cvfVertexCompactor-Test.cpp" />
|
||||
<ClCompile Include="cvfTriangleMeshEdgeExtractor-Test.cpp" />
|
||||
<ClCompile Include="cvfBoundingBoxTree-Test.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="CMakeLists.txt" />
|
||||
|
@ -0,0 +1,105 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) Ceetron Solutions AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// This library 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.
|
||||
//
|
||||
// This library 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.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#include "cvfBoundingBoxTree.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
using namespace cvf;
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, const std::vector<size_t>& array)
|
||||
{
|
||||
for (size_t i = 0; i < array.size(); ++i)
|
||||
{
|
||||
stream << array[i] << " ";
|
||||
}
|
||||
stream << std::endl;
|
||||
return stream;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(BoundingBoxTree, Intersection)
|
||||
{
|
||||
BoundingBoxTree bbtree;
|
||||
|
||||
std::vector<cvf::BoundingBox> bbs;
|
||||
bbs.push_back(cvf::BoundingBox(Vec3d(0,0,0), Vec3d(1,1,1)));
|
||||
bbs.push_back(cvf::BoundingBox(Vec3d(1,0,0), Vec3d(2,1,1)));
|
||||
bbs.push_back(cvf::BoundingBox(Vec3d(2,0,0), Vec3d(3,1,1)));
|
||||
bbs.push_back(cvf::BoundingBox(Vec3d(3,0,0), Vec3d(4,1,1)));
|
||||
bbs.push_back(cvf::BoundingBox(Vec3d(4,0,0), Vec3d(5,1,1)));
|
||||
bbs.push_back(cvf::BoundingBox(Vec3d(0.5,0.5,0), Vec3d(5.5,1.5,1)));
|
||||
|
||||
|
||||
std::vector<size_t> ids;
|
||||
ids.push_back(10);
|
||||
ids.push_back(11);
|
||||
ids.push_back(12);
|
||||
ids.push_back(13);
|
||||
ids.push_back(14);
|
||||
ids.push_back(15);
|
||||
|
||||
bbtree.buildTreeFromBoundingBoxes(bbs, &ids);
|
||||
|
||||
{
|
||||
std::vector<size_t> intIds;
|
||||
bbtree.findIntersections(cvf::BoundingBox(Vec3d(0.25,0.25,0.25), Vec3d(4.5,0.4,0.4)), &intIds);
|
||||
size_t numBB = intIds.size();
|
||||
EXPECT_EQ(5, numBB);
|
||||
EXPECT_EQ(intIds[4], 13);
|
||||
//std::cout << intIds;
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<size_t> intIds;
|
||||
bbtree.findIntersections(cvf::BoundingBox(Vec3d(0.25,0.75,0.25), Vec3d(4.5,0.8,0.4)), &intIds);
|
||||
size_t numBB = intIds.size();
|
||||
EXPECT_EQ(6, numBB);
|
||||
EXPECT_EQ(intIds[5], 15);
|
||||
//std::cout << intIds;
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<size_t> intIds;
|
||||
bbtree.findIntersections(cvf::BoundingBox(Vec3d(2,0,0), Vec3d(3,1,1)), &intIds);
|
||||
size_t numBB = intIds.size();
|
||||
EXPECT_EQ(4, numBB);
|
||||
EXPECT_EQ(intIds[0], 11);
|
||||
//std::cout << intIds;
|
||||
}
|
||||
}
|
9
TestModels/fault_test/include/grid_faults.grdecl
Normal file
9
TestModels/fault_test/include/grid_faults.grdecl
Normal file
@ -0,0 +1,9 @@
|
||||
FAULTS
|
||||
-- NAME IX1 IX2 IY1 IY2 IZ1 IZ2 FACE
|
||||
|
||||
'grid_C202' 1 1 1 1 1 3 'X-' /
|
||||
'grid_C202' 1 1 1 1 1 3 'Z-' /
|
||||
'grid_C202' 1 2 1 1 1 3 'X-' /
|
||||
'grid_C202' 1 2 1 1 1 2 'Z-' /
|
||||
|
||||
/
|
14
TestModels/fault_test/include/mother_grid_faults.grdecl
Normal file
14
TestModels/fault_test/include/mother_grid_faults.grdecl
Normal file
@ -0,0 +1,14 @@
|
||||
|
||||
INCLUDE
|
||||
'grid_faults.grdecl' /
|
||||
|
||||
FAULTS
|
||||
-- NAME IX1 IX2 IY1 IY2 IZ1 IZ2 FACE
|
||||
|
||||
'mother_grid_C202' 1 1 1 1 1 3 'X-' /
|
||||
'mother_grid_C202' 1 1 1 1 1 3 'Z-' /
|
||||
'mother_grid_C202' 1 2 1 1 1 3 'X-' /
|
||||
'mother_grid_C202' 1 2 1 1 1 2 'Z-' /
|
||||
|
||||
/
|
||||
|
12
TestModels/fault_test/main_faults.grdecl
Normal file
12
TestModels/fault_test/main_faults.grdecl
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
INCLUDE
|
||||
'./include/mother_grid_faults.grdecl' /
|
||||
|
||||
FAULTS
|
||||
-- NAME IX1 IX2 IY1 IY2 IZ1 IZ2 FACE
|
||||
|
||||
'MAIN' 2 3 1 1 1 3 'X-' /
|
||||
|
||||
/
|
||||
|
||||
-- More data
|
31
TestModels/fault_test/regular27cell.DATA
Normal file
31
TestModels/fault_test/regular27cell.DATA
Normal file
@ -0,0 +1,31 @@
|
||||
|
||||
-- ==========================================================================
|
||||
--
|
||||
-- *************************** GRID SECTION ******************************
|
||||
--
|
||||
-- Specification of geometry of computational grid, and of rock
|
||||
-- properties in each grid block.
|
||||
--
|
||||
-- ==========================================================================
|
||||
|
||||
GRID
|
||||
|
||||
-- GEOMETRY
|
||||
INCLUDE
|
||||
'./regular27cell.grdecl' /
|
||||
|
||||
|
||||
-- FAULTS
|
||||
INCLUDE
|
||||
'./main_faults.grdecl' /
|
||||
|
||||
|
||||
FAULTS
|
||||
-- NAME IX1 IX2 IY1 IY2 IZ1 IZ2 FACE
|
||||
|
||||
'DATA_FILE_MAIN' 2 3 1 1 1 3 'X-' /
|
||||
|
||||
/
|
||||
|
||||
|
||||
EDIT
|
88
TestModels/fault_test/regular27cell.grdecl
Normal file
88
TestModels/fault_test/regular27cell.grdecl
Normal file
@ -0,0 +1,88 @@
|
||||
|
||||
SPECGRID
|
||||
3 3 3 1 F /
|
||||
|
||||
|
||||
COORD
|
||||
0.000 0.000 0.000 0.000 0.000 1.000
|
||||
0.500 0.000 0.000 0.500 0.000 1.000
|
||||
1.000 0.000 0.000 1.000 0.000 1.000
|
||||
1.500 0.000 0.000 1.500 0.000 1.000
|
||||
0.000 0.500 0.000 0.000 0.500 1.000
|
||||
0.500 0.500 0.000 0.500 0.500 1.000
|
||||
1.000 0.500 0.000 1.000 0.500 1.000
|
||||
1.500 0.500 0.000 1.500 0.500 1.000
|
||||
0.000 1.000 0.000 0.000 1.000 1.000
|
||||
0.500 1.000 0.000 0.500 1.000 1.000
|
||||
1.000 1.000 0.000 1.000 1.000 1.000
|
||||
1.500 1.000 0.000 1.500 1.000 1.000
|
||||
0.000 1.500 0.000 0.000 1.500 1.000
|
||||
0.500 1.500 0.000 0.500 1.500 1.000
|
||||
1.000 1.500 0.000 1.000 1.500 1.000
|
||||
1.500 1.500 0.000 1.500 1.500 1.000
|
||||
/
|
||||
|
||||
|
||||
ZCORN
|
||||
0.000 0.000 0.000 0.000 0.000 0.000
|
||||
0.000 0.000 0.000 0.000 0.000 0.000
|
||||
0.000 0.000 0.000 0.000 0.000 0.000
|
||||
0.000 0.000 0.000 0.000 0.000 0.000
|
||||
0.000 0.000 0.000 0.000 0.000 0.000
|
||||
0.000 0.000 0.000 0.000 0.000 0.000
|
||||
0.500 0.500 0.500 0.500 0.500 0.500
|
||||
0.500 0.500 0.500 0.500 0.500 0.500
|
||||
0.500 0.500 0.500 0.500 0.500 0.500
|
||||
0.500 0.500 0.500 0.500 0.500 0.500
|
||||
0.500 0.500 0.500 0.500 0.500 0.500
|
||||
0.500 0.500 0.500 0.500 0.500 0.500
|
||||
0.500 0.500 0.500 0.500 0.500 0.500
|
||||
0.500 0.500 0.500 0.500 0.500 0.500
|
||||
0.500 0.500 0.500 0.500 0.500 0.500
|
||||
0.500 0.500 0.500 0.500 0.500 0.500
|
||||
0.500 0.500 0.500 0.500 0.500 0.500
|
||||
0.500 0.500 0.500 0.500 0.500 0.500
|
||||
1.000 1.000 1.000 1.000 1.000 1.000
|
||||
1.000 1.000 1.000 1.000 1.000 1.000
|
||||
1.000 1.000 1.000 1.000 1.000 1.000
|
||||
1.000 1.000 1.000 1.000 1.000 1.000
|
||||
1.000 1.000 1.000 1.000 1.000 1.000
|
||||
1.000 1.000 1.000 1.000 1.000 1.000
|
||||
1.000 1.000 1.000 1.000 1.000 1.000
|
||||
1.000 1.000 1.000 1.000 1.000 1.000
|
||||
1.000 1.000 1.000 1.000 1.000 1.000
|
||||
1.000 1.000 1.000 1.000 1.000 1.000
|
||||
1.000 1.000 1.000 1.000 1.000 1.000
|
||||
1.000 1.000 1.000 1.000 1.000 1.000
|
||||
1.500 1.500 1.500 1.500 1.500 1.500
|
||||
1.500 1.500 1.500 1.500 1.500 1.500
|
||||
1.500 1.500 1.500 1.500 1.500 1.500
|
||||
1.500 1.500 1.500 1.500 1.500 1.500
|
||||
1.500 1.500 1.500 1.500 1.500 1.500
|
||||
1.500 1.500 1.500 1.500 1.500 1.500
|
||||
/
|
||||
|
||||
ACTNUM
|
||||
1 1 1 1 1 1 1 1 1
|
||||
1 1 1 1 1 1 1 1 1
|
||||
1 1 1 1 1 1 1 1 1
|
||||
/
|
||||
|
||||
PERMX
|
||||
1 2 3 4 5 6 7 8 9
|
||||
1 2 3 4 5 6 7 8 9
|
||||
1 2 3 4 5 6 7 8 9
|
||||
/
|
||||
|
||||
PORO
|
||||
0.2 0.2 0.4 0.4 0.6 0.6 0.8 0.8 0.5
|
||||
0.2 0.2 0.4 0.4 0.6 0.6 0.8 0.8 0.5
|
||||
0.2 0.2 0.4 0.4 0.6 0.6 0.8 0.8 0.5
|
||||
/
|
||||
|
||||
SATNUM
|
||||
1 1 1 1 1 1 1 1 1
|
||||
2 2 2 2 2 2 2 2 2
|
||||
3 3 3 3 3 3 3 3 3
|
||||
/
|
||||
|
Loading…
Reference in New Issue
Block a user