mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#3630 Implement volume calculation on grid
This commit is contained in:
parent
8ebfe074f1
commit
ef4b70d6e5
@ -293,6 +293,14 @@ QString RiaDefines::combinedRiAreaNormTranResultName()
|
||||
return "riTRANXYZbyArea";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RiaDefines::riCellVolumeResultName()
|
||||
{
|
||||
return "riCELLVOLUME";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -84,6 +84,7 @@ namespace RiaDefines
|
||||
QString riAreaNormTranZResultName();
|
||||
QString combinedRiAreaNormTranResultName();
|
||||
|
||||
QString riCellVolumeResultName();
|
||||
QString mobilePoreVolumeName();
|
||||
|
||||
QString completionTypeResultName();
|
||||
|
@ -291,6 +291,33 @@ double Rim2dGridProjection::minValue() const
|
||||
return minV;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double Rim2dGridProjection::meanValue() const
|
||||
{
|
||||
return sumAllValues() / validVertexCount();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double Rim2dGridProjection::sumAllValues() const
|
||||
{
|
||||
double sum = 0.0;
|
||||
|
||||
int nVertices = vertexCount();
|
||||
|
||||
for (int index = 0; index < nVertices; ++index)
|
||||
{
|
||||
if (m_aggregatedResults[index] != std::numeric_limits<double>::infinity())
|
||||
{
|
||||
sum += m_aggregatedResults[index];
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -443,7 +470,7 @@ double Rim2dGridProjection::calculateValue(uint i, uint j) const
|
||||
for (auto cellIdxAndWeight : matchingCells)
|
||||
{
|
||||
size_t cellIdx = cellIdxAndWeight.first;
|
||||
double cellValue = m_resultAccessor->cellScalarGlobIdx(cellIdx);
|
||||
double cellValue = m_resultAccessor->cellScalarGlobIdx(cellIdx);
|
||||
sum += cellValue * cellIdxAndWeight.second;
|
||||
}
|
||||
return sum;
|
||||
@ -507,6 +534,23 @@ uint Rim2dGridProjection::vertexCount() const
|
||||
return gridSize2d.x() * gridSize2d.y();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
uint Rim2dGridProjection::validVertexCount() const
|
||||
{
|
||||
uint validCount = 0u;
|
||||
for (uint i = 0; i < vertexCount(); ++i)
|
||||
{
|
||||
cvf::Vec2ui ij = ijFromGridIndex(i);
|
||||
if (hasResultAt(ij.x(), ij.y()))
|
||||
{
|
||||
validCount++;
|
||||
}
|
||||
}
|
||||
return validCount;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -699,7 +743,9 @@ std::vector<std::pair<size_t, float>> Rim2dGridProjection::visibleCellsAndWeight
|
||||
return std::get<2>(lhs) > std::get<2>(rhs);
|
||||
});
|
||||
|
||||
float adjustmentFactor = static_cast<float>(chopped2dBBoxVolume / totalOverlapVolume);
|
||||
float adjustmentFactor = 1.0;
|
||||
if (totalOverlapVolume > chopped2dBBoxVolume) // Don't scale up if overlap volume is smaller 2d extrusion!
|
||||
adjustmentFactor = static_cast<float>(chopped2dBBoxVolume / totalOverlapVolume);
|
||||
CVF_ASSERT(adjustmentFactor > 0.0f);
|
||||
for (const auto& visWeightHeight : matchingVisibleCellsWeightAndHeight)
|
||||
{
|
||||
@ -836,6 +882,22 @@ void Rim2dGridProjection::updateLegend()
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Rim2dGridProjection::ResultAggregation Rim2dGridProjection::resultAggregation() const
|
||||
{
|
||||
return m_resultAggregation();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString Rim2dGridProjection::resultAggregationText() const
|
||||
{
|
||||
return m_resultAggregation().uiText();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -68,6 +68,8 @@ public:
|
||||
void generateResults();
|
||||
double maxValue() const;
|
||||
double minValue() const;
|
||||
double meanValue() const;
|
||||
double sumAllValues() const;
|
||||
double sampleSpacing() const;
|
||||
bool showContourLines() const;
|
||||
|
||||
@ -81,12 +83,16 @@ public:
|
||||
|
||||
cvf::Vec2ui surfaceGridSize() const;
|
||||
uint vertexCount() const;
|
||||
uint validVertexCount() const;
|
||||
RimRegularLegendConfig* legendConfig() const;
|
||||
|
||||
size_t gridIndex(uint i, uint j) const;
|
||||
cvf::Vec2ui ijFromGridIndex(size_t gridIndex) const;
|
||||
void updateLegend();
|
||||
|
||||
ResultAggregation resultAggregation() const;
|
||||
QString resultAggregationText() const;
|
||||
|
||||
protected:
|
||||
double calculateValue(uint i, uint j) const;
|
||||
|
||||
|
@ -37,6 +37,8 @@
|
||||
#include "RigMainGrid.h"
|
||||
#include "RigStatisticsDataCache.h"
|
||||
|
||||
#include "Rim2dEclipseView.h"
|
||||
#include "Rim2dGridProjection.h"
|
||||
#include "Rim2dIntersectionView.h"
|
||||
#include "Rim2dIntersectionViewCollection.h"
|
||||
#include "Rim3dView.h"
|
||||
@ -174,9 +176,11 @@ Rim3dOverlayInfoConfig::HistogramData Rim3dOverlayInfoConfig::histogramData()
|
||||
{
|
||||
auto eclipseView = dynamic_cast<RimEclipseView*>(m_viewDef.p());
|
||||
auto geoMechView = dynamic_cast<RimGeoMechView*>(m_viewDef.p());
|
||||
auto contourMap = dynamic_cast<Rim2dEclipseView*>(eclipseView);
|
||||
|
||||
if (eclipseView) return histogramData(eclipseView);
|
||||
if (geoMechView) return histogramData(geoMechView);
|
||||
if (contourMap) return histogramData(contourMap);
|
||||
else if (eclipseView) return histogramData(eclipseView);
|
||||
else if (geoMechView) return histogramData(geoMechView);
|
||||
return HistogramData();
|
||||
}
|
||||
|
||||
@ -271,6 +275,29 @@ void Rim3dOverlayInfoConfig::setIsActive(bool active)
|
||||
m_active = active;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Rim3dOverlayInfoConfig::HistogramData Rim3dOverlayInfoConfig::histogramData(Rim2dEclipseView* contourMap)
|
||||
{
|
||||
HistogramData histData;
|
||||
|
||||
if (contourMap)
|
||||
{
|
||||
bool isResultsInfoRelevant = contourMap->grid2dProjection()->validVertexCount() > 0u;
|
||||
|
||||
if (isResultsInfoRelevant)
|
||||
{
|
||||
histData.min = contourMap->grid2dProjection()->minValue();
|
||||
histData.max = contourMap->grid2dProjection()->maxValue();
|
||||
histData.mean = contourMap->grid2dProjection()->meanValue();
|
||||
histData.sum = contourMap->grid2dProjection()->sumAllValues();
|
||||
}
|
||||
}
|
||||
return histData;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -467,35 +494,46 @@ QString Rim3dOverlayInfoConfig::caseInfoText(RimEclipseView* eclipseView)
|
||||
|
||||
if (eclipseView)
|
||||
{
|
||||
QString caseName;
|
||||
QString totCellCount;
|
||||
QString activeCellCountText;
|
||||
QString fractureActiveCellCount;
|
||||
QString iSize, jSize, kSize;
|
||||
QString zScale;
|
||||
QString caseName = eclipseView->eclipseCase()->caseUserDescription();
|
||||
|
||||
if (eclipseView->mainGrid())
|
||||
Rim2dEclipseView* contourMap = dynamic_cast<Rim2dEclipseView*>(eclipseView);
|
||||
if (contourMap && contourMap->grid2dProjection())
|
||||
{
|
||||
caseName = eclipseView->eclipseCase()->caseUserDescription();
|
||||
totCellCount = QString::number(eclipseView->mainGrid()->globalCellArray().size());
|
||||
QString totCellCount = QString::number(contourMap->grid2dProjection()->vertexCount());
|
||||
cvf::uint validCellCount = contourMap->grid2dProjection()->validVertexCount();
|
||||
QString activeCellCountText = QString::number(validCellCount);
|
||||
QString iSize = QString::number(contourMap->grid2dProjection()->surfaceGridSize().x());
|
||||
QString jSize = QString::number(contourMap->grid2dProjection()->surfaceGridSize().y());
|
||||
QString aggregationType = contourMap->grid2dProjection()->resultAggregationText();
|
||||
|
||||
infoText += QString(
|
||||
"<p><b>-- %1 --</b><p> "
|
||||
"<b>Cell count. Total:</b> %2 <b>Valid Result:</b> %3 <br>"
|
||||
"<b>2d Projection [%4] I,J, Aggregation Type:</b> %5, %6 <br>").arg(caseName, totCellCount, activeCellCountText, aggregationType, iSize, jSize);
|
||||
}
|
||||
else if (eclipseView->mainGrid())
|
||||
{
|
||||
QString totCellCount = QString::number(eclipseView->mainGrid()->globalCellArray().size());
|
||||
size_t mxActCellCount = eclipseView->eclipseCase()->eclipseCaseData()->activeCellInfo(RiaDefines::MATRIX_MODEL)->reservoirActiveCellCount();
|
||||
size_t frActCellCount = eclipseView->eclipseCase()->eclipseCaseData()->activeCellInfo(RiaDefines::FRACTURE_MODEL)->reservoirActiveCellCount();
|
||||
|
||||
QString activeCellCountText;
|
||||
if (frActCellCount > 0) activeCellCountText += "Matrix : ";
|
||||
activeCellCountText += QString::number(mxActCellCount);
|
||||
if (frActCellCount > 0) activeCellCountText += " Fracture : " + QString::number(frActCellCount);
|
||||
|
||||
iSize = QString::number(eclipseView->mainGrid()->cellCountI());
|
||||
jSize = QString::number(eclipseView->mainGrid()->cellCountJ());
|
||||
kSize = QString::number(eclipseView->mainGrid()->cellCountK());
|
||||
QString iSize = QString::number(eclipseView->mainGrid()->cellCountI());
|
||||
QString jSize = QString::number(eclipseView->mainGrid()->cellCountJ());
|
||||
QString kSize = QString::number(eclipseView->mainGrid()->cellCountK());
|
||||
|
||||
zScale = QString::number(eclipseView->scaleZ());
|
||||
QString zScale = QString::number(eclipseView->scaleZ());
|
||||
infoText += QString(
|
||||
"<p><b>-- %1 --</b><p> "
|
||||
"<b>Cell count. Total:</b> %2 <b>Active:</b> %3 <br>"
|
||||
"<b>Main Grid I,J,K:</b> %4, %5, %6 <b>Z-Scale:</b> %7<br>").arg(caseName, totCellCount, activeCellCountText, iSize, jSize, kSize, zScale);
|
||||
|
||||
}
|
||||
|
||||
infoText += QString(
|
||||
"<p><b>-- %1 --</b><p> "
|
||||
"<b>Cell count. Total:</b> %2 <b>Active:</b> %3 <br>"
|
||||
"<b>Main Grid I,J,K:</b> %4, %5, %6 <b>Z-Scale:</b> %7<br>").arg(caseName, totCellCount, activeCellCountText, iSize, jSize, kSize, zScale);
|
||||
}
|
||||
|
||||
return infoText;
|
||||
@ -535,7 +573,23 @@ QString Rim3dOverlayInfoConfig::resultInfoText(const HistogramData& histData, Ri
|
||||
{
|
||||
QString infoText;
|
||||
|
||||
if (eclipseView)
|
||||
Rim2dEclipseView* contourMap = dynamic_cast<Rim2dEclipseView*>(eclipseView);
|
||||
|
||||
if (contourMap)
|
||||
{
|
||||
bool isResultsInfoRelevant = contourMap->grid2dProjection()->validVertexCount() > 0u;
|
||||
if (isResultsInfoRelevant)
|
||||
{
|
||||
QString propName = eclipseView->cellResult()->resultVariableUiShortName();
|
||||
infoText += QString("<b>Cell Property:</b> %1 ").arg(propName);
|
||||
infoText += QString("<br><b>Statistics:</b> ");
|
||||
infoText += QString("<table border=0 cellspacing=5 >"
|
||||
"<tr> <td>Min</td> <td>Mean</td> <td>Max</td> <td>Sum</td> </tr>"
|
||||
"<tr> <td>%1</td> <td> %2</td> <td> %3</td> <td> %4</td> </tr>"
|
||||
"</table>").arg(histData.min).arg(histData.mean).arg(histData.max).arg(histData.sum);
|
||||
}
|
||||
}
|
||||
else if (eclipseView)
|
||||
{
|
||||
bool isResultsInfoRelevant = eclipseView->hasUserRequestedAnimation() && eclipseView->cellResult()->hasResult();
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <cmath>
|
||||
#include <memory>
|
||||
|
||||
class Rim2dEclipseView;
|
||||
class RimEclipseView;
|
||||
class RimGeoMechView;
|
||||
class RimGridView;
|
||||
@ -111,6 +112,7 @@ private:
|
||||
|
||||
QString timeStepText(RimEclipseView* eclipseView);
|
||||
QString timeStepText(RimGeoMechView* geoMechView);
|
||||
HistogramData histogramData(Rim2dEclipseView* contourMap);
|
||||
HistogramData histogramData(RimEclipseView* eclipseView);
|
||||
HistogramData histogramData(RimGeoMechView* geoMechView);
|
||||
QString caseInfoText(RimEclipseView* eclipseView);
|
||||
|
@ -961,6 +961,12 @@ void RigCaseCellResultsData::createPlaceholderResultEntries()
|
||||
}
|
||||
}
|
||||
|
||||
// Cell Volume
|
||||
{
|
||||
addStaticScalarResult(RiaDefines::STATIC_NATIVE, RiaDefines::riCellVolumeResultName(), false, 0);
|
||||
}
|
||||
|
||||
|
||||
// Mobile Pore Volume
|
||||
{
|
||||
if (findScalarResultIndex(RiaDefines::STATIC_NATIVE, "PORV") != cvf::UNDEFINED_SIZE_T)
|
||||
@ -1140,6 +1146,10 @@ size_t RigCaseCellResultsData::findOrLoadScalarResult(RiaDefines::ResultCatType
|
||||
progressInfo.incrementProgress();
|
||||
}
|
||||
}
|
||||
else if (resultName == RiaDefines::riCellVolumeResultName())
|
||||
{
|
||||
computeCellVolumes();
|
||||
}
|
||||
else if (resultName == RiaDefines::mobilePoreVolumeName())
|
||||
{
|
||||
computeMobilePV();
|
||||
@ -2404,6 +2414,30 @@ double RigCaseCellResultsData::darchysValue()
|
||||
return RiaEclipseUnitTools::darcysConstant(m_ownerCaseData->unitsType());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigCaseCellResultsData::computeCellVolumes()
|
||||
{
|
||||
size_t cellVolIdx = this->findOrCreateScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riCellVolumeResultName(), false);
|
||||
|
||||
std::vector<double>& cellVolumeResults = this->cellScalarResults(cellVolIdx)[0];
|
||||
|
||||
size_t cellResultCount = m_activeCellInfo->reservoirCellResultCount();
|
||||
cellVolumeResults.resize(cellResultCount, 0u);
|
||||
|
||||
#pragma omp parallel for
|
||||
for (int nativeResvCellIndex = 0; nativeResvCellIndex < static_cast<int>(m_ownerMainGrid->globalCellArray().size()); nativeResvCellIndex++)
|
||||
{
|
||||
size_t resultIndex = activeCellInfo()->cellResultIndex(nativeResvCellIndex);
|
||||
if (resultIndex != cvf::UNDEFINED_SIZE_T)
|
||||
{
|
||||
const RigCell& cell = m_ownerMainGrid->globalCellArray()[nativeResvCellIndex];
|
||||
cellVolumeResults[resultIndex] = cell.volume();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -154,6 +154,7 @@ private: // from RimReservoirCellResultsStorage
|
||||
void computeCompletionTypeForTimeStep(size_t timeStep);
|
||||
double darchysValue();
|
||||
|
||||
void computeCellVolumes();
|
||||
void computeMobilePV();
|
||||
|
||||
bool isDataPresent(size_t scalarResultIndex) const;
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
|
||||
#include "RigCell.h"
|
||||
#include "RigCellGeometryTools.h"
|
||||
#include "RigMainGrid.h"
|
||||
#include "cvfPlane.h"
|
||||
#include "cvfRay.h"
|
||||
@ -301,6 +302,21 @@ cvf::Vec3d RigCell::faceNormalWithAreaLenght(cvf::StructGridInterface::FaceType
|
||||
( nodeCoords[m_cornerIndices[faceVertexIndices[3]]] - nodeCoords[m_cornerIndices[faceVertexIndices[1]]]);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RigCell::volume() const
|
||||
{
|
||||
const std::vector<cvf::Vec3d>& nodeCoords = m_hostGrid->mainGrid()->nodes();
|
||||
|
||||
std::array<cvf::Vec3d, 8> hexCorners;
|
||||
for (size_t i = 0; i < 8; ++i)
|
||||
{
|
||||
hexCorners[i] = nodeCoords.at(m_cornerIndices[i]);
|
||||
}
|
||||
return RigCellGeometryTools::calculateCellVolume(hexCorners);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Find the intersection between the cell and the ray. The point closest to the ray origin is returned
|
||||
/// in \a intersectionPoint, while the return value is the total number of intersections with the 24 triangles
|
||||
|
@ -70,6 +70,8 @@ public:
|
||||
cvf::Vec3d center() const;
|
||||
cvf::Vec3d faceCenter(cvf::StructGridInterface::FaceType face) const;
|
||||
cvf::Vec3d faceNormalWithAreaLenght(cvf::StructGridInterface::FaceType face) const;
|
||||
double volume() const;
|
||||
|
||||
|
||||
int firstIntersectionPoint(const cvf::Ray& ray, cvf::Vec3d* intersectionPoint) const;
|
||||
bool isLongPyramidCell(double maxHeightFactor = 5, double nodeNearTolerance = 1e-3 ) const;
|
||||
|
@ -23,12 +23,64 @@
|
||||
|
||||
#include "cafHexGridIntersectionTools/cafHexGridIntersectionTools.h"
|
||||
#include "cvfBoundingBox.h"
|
||||
#include "cvfMatrix3.h"
|
||||
|
||||
#include "clipper/clipper.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <array>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Efficient Computation of Volume of Hexahedral Cells
|
||||
/// Jeffrey Grandy, Lawrence Livermore National Laboratory
|
||||
/// https://www.osti.gov/servlets/purl/632793/
|
||||
///
|
||||
/// Note that in the paper the following vertex numbering is used
|
||||
/// 6---------7
|
||||
/// /| /| |k
|
||||
/// / | / | | /j
|
||||
/// 4---------5 | |/
|
||||
/// | 2------|--3 *---i
|
||||
/// | / | /
|
||||
/// |/ |/
|
||||
/// 0---------1
|
||||
///
|
||||
/// While in ResInsight, this is the numbering. Thus 2<->3, 6<->7 from the paper.
|
||||
/// Note the negative k!
|
||||
/// 7---------6
|
||||
/// /| /| |-k
|
||||
/// / | / | | /j
|
||||
/// 4---------5 | |/
|
||||
/// | 3------|--2 *---i
|
||||
/// | / | /
|
||||
/// |/ |/
|
||||
/// 0---------1
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RigCellGeometryTools::calculateCellVolume(const std::array<cvf::Vec3d, 8>& x)
|
||||
{
|
||||
// 6 * 3 flops = 18 flops
|
||||
|
||||
// Perform index swap when retrieving corners but keep indices in variable names matching paper.
|
||||
cvf::Vec3d x3mx0 = x[6] - x[4]; // Swap 3->2, then negate z by 2->6 and 0->4
|
||||
cvf::Vec3d x5mx0 = x[1] - x[4]; // Negate z by Swap 5->1 and 0->4
|
||||
cvf::Vec3d x6mx0 = x[3] - x[4]; // Swap 6->7, then negate z by 7->3 and 0->4
|
||||
cvf::Vec3d x7mx1 = x[2] - x[5]; // Swap 7->6, then negate z by 6->2 and 1->5
|
||||
cvf::Vec3d x7mx2 = x[2] - x[7]; // Swap 7->6, 2->3, then negate z by 6->2 and 3->7
|
||||
cvf::Vec3d x7mx4 = x[2] - x[0]; // Swap 7->6 then negate z by 6->2 and 4->0
|
||||
|
||||
// 3 flops for summation + 5 for dot product + 9 flops for cross product = 17 flops
|
||||
double det1 = (x7mx1 + x6mx0) * (x7mx2 ^ x3mx0);
|
||||
// 3 flops for summation + 5 for dot product + 9 flops for cross product = 17 flops
|
||||
double det2 = x6mx0 * ((x7mx2 + x5mx0) ^ x7mx4);
|
||||
// 3 flops for summation + 5 for dot product + 9 flops for cross product = 17 flops
|
||||
double det3 = x7mx1 * (x5mx0 ^ (x7mx4 + x3mx0));
|
||||
|
||||
// 2 flops for summation + 1 for division = 3 flops
|
||||
double volume = (det1 + det2 + det3) / 12.0;
|
||||
CVF_ASSERT(volume > 0.0);
|
||||
return volume;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -33,6 +33,7 @@
|
||||
class RigCellGeometryTools
|
||||
{
|
||||
public:
|
||||
static double calculateCellVolume(const std::array<cvf::Vec3d, 8>& hexCorners);
|
||||
|
||||
static void createPolygonFromLineSegments(std::list<std::pair<cvf::Vec3d, cvf::Vec3d>> &intersectionLineSegments, std::vector<std::vector<cvf::Vec3d>> &polygons);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user