#4210 Fix crash when creating contour map

This commit is contained in:
Gaute Lindkvist
2019-03-22 08:49:39 +01:00
parent 64fc6447f4
commit 4c3c01a661
7 changed files with 82 additions and 42 deletions

View File

@@ -13,6 +13,7 @@
#include "cafEffectGenerator.h"
#include "cafFixedAtlasFont.h"
#include "cafCategoryMapper.h"
#include "cvfCamera.h"
#include "cvfDrawableText.h"
@@ -365,13 +366,17 @@ std::vector<cvf::ref<cvf::Drawable>>
{
CVF_ASSERT(camera && displayCoordTransform && labelBBoxes);
std::vector<cvf::ref<cvf::Drawable>> labelDrawables;
labelBBoxes->clear();
labelBBoxes->resize(m_contourLinePolygons.size());
const cvf::ScalarMapper* mapper = m_contourMapProjection->legendConfig()->scalarMapper();
if (dynamic_cast<const caf::CategoryMapper*>(mapper) != nullptr)
return labelDrawables;
std::vector<double> tickValues;
mapper->majorTickValues(&tickValues);
std::vector<cvf::ref<cvf::Drawable>> labelDrawables;
labelBBoxes->clear();
labelBBoxes->resize(m_contourLinePolygons.size());
const RimContourMapProjection::ContourPolygons* previousLevel = nullptr;
for (int64_t i = (int64_t)m_contourLinePolygons.size() - 1; i > 0; --i)
{

View File

@@ -724,14 +724,12 @@ std::pair<double, double> RimContourMapProjection::minmaxValuesAllTimeSteps()
{
clearTimeStepRange();
m_minResultAllTimeSteps = std::min(m_minResultAllTimeSteps, minValue(m_aggregatedResults));
m_maxResultAllTimeSteps = std::max(m_maxResultAllTimeSteps, maxValue(m_aggregatedResults));
for (int i = 0; i < (int)baseView()->ownerCase()->timeStepStrings().size() - 1; ++i)
{
if (i == m_currentResultTimestep)
{
m_minResultAllTimeSteps = std::min(m_minResultAllTimeSteps, minValue(m_aggregatedResults));
m_maxResultAllTimeSteps = std::max(m_maxResultAllTimeSteps, maxValue(m_aggregatedResults));
}
else
if (i != m_currentResultTimestep)
{
std::vector<double> aggregatedResults = generateResults(i);
m_minResultAllTimeSteps = std::min(m_minResultAllTimeSteps, minValue(aggregatedResults));
@@ -1078,8 +1076,6 @@ void RimContourMapProjection::generateContourPolygons()
{
std::vector<ContourPolygons> contourPolygons;
const double simplifyEpsilon = m_smoothContourLines() ? 5.0e-2 * m_sampleSpacing : 1.0e-3 * m_sampleSpacing;
std::vector<double> contourLevels;
if (resultRangeIsValid() && legendConfig()->mappingMode() != RimRegularLegendConfig::CATEGORY_INTEGER)
{
@@ -1101,6 +1097,17 @@ void RimContourMapProjection::generateContourPolygons()
contourLevels.front() *= 0.5;
}
double simplifyEpsilon = m_smoothContourLines() ? 5.0e-2 * m_sampleSpacing : 1.0e-3 * m_sampleSpacing;
if (nContourLevels >= 10)
{
simplifyEpsilon *= 2.0;
}
if (numberOfCells() > 100000)
{
simplifyEpsilon *= 2.0;
}
std::vector<caf::ContourLines::ListOfLineSegments> unorderedLineSegmentsPerLevel =
caf::ContourLines::create(m_aggregatedVertexResults, xVertexPositions(), yVertexPositions(), contourLevels);

View File

@@ -202,7 +202,11 @@ std::vector<double> RimEclipseContourMapProjection::generateResults(int timeStep
else
{
m_currentResultName = cellColors->resultVariable();
gridResultValues = resultData->cellScalarResults(RigEclipseResultAddress( cellColors->resultType(), cellColors->resultVariable()), timeStep);
RigEclipseResultAddress resAddr(cellColors->resultType(), cellColors->resultVariable());
if (resAddr.isValid() && resultData->hasResultEntry(resAddr))
{
gridResultValues = resultData->cellScalarResults(resAddr, timeStep);
}
}
if (!gridResultValues.empty())
@@ -393,11 +397,13 @@ double RimEclipseContourMapProjection::calculateOverlapVolume(size_t globalCellI
localGrid->cellCornerVertices(localCellIdx, hexCorners.data());
cvf::BoundingBox overlapBBox;
std::array<cvf::Vec3d, 8> overlapCorners =
RigCellGeometryTools::estimateHexOverlapWithBoundingBox(hexCorners, bbox, &overlapBBox);
double overlapVolume = RigCellGeometryTools::calculateCellVolume(overlapCorners);
return overlapVolume;
std::array<cvf::Vec3d, 8> overlapCorners;
if (RigCellGeometryTools::estimateHexOverlapWithBoundingBox(hexCorners, bbox, &overlapCorners, &overlapBBox))
{
double overlapVolume = RigCellGeometryTools::calculateCellVolume(overlapCorners);
return overlapVolume;
}
return 0.0;
}
//--------------------------------------------------------------------------------------------------

View File

@@ -427,11 +427,13 @@ double RimGeoMechContourMapProjection::calculateOverlapVolume(size_t
m_femPartGrid->cellCornerVertices(globalCellIdx, hexCorners.data());
cvf::BoundingBox overlapBBox;
std::array<cvf::Vec3d, 8> overlapCorners =
RigCellGeometryTools::estimateHexOverlapWithBoundingBox(hexCorners, bbox, &overlapBBox);
double overlapVolume = RigCellGeometryTools::calculateCellVolume(overlapCorners);
return overlapVolume;
std::array<cvf::Vec3d, 8> overlapCorners;
if (RigCellGeometryTools::estimateHexOverlapWithBoundingBox(hexCorners, bbox, &overlapCorners, &overlapBBox))
{
double overlapVolume = RigCellGeometryTools::calculateCellVolume(overlapCorners);
return overlapVolume;
}
return 0.0;
}
//--------------------------------------------------------------------------------------------------

View File

@@ -85,16 +85,30 @@ double RigCellGeometryTools::calculateCellVolume(const std::array<cvf::Vec3d, 8>
}
//--------------------------------------------------------------------------------------------------
///
/// A reasonable approximation to the overlap volume
//--------------------------------------------------------------------------------------------------
std::array<cvf::Vec3d, 8> RigCellGeometryTools::estimateHexOverlapWithBoundingBox(const std::array<cvf::Vec3d, 8>& hexCorners, const cvf::BoundingBox& boundingBox, cvf::BoundingBox* overlapBoundingBox)
bool RigCellGeometryTools::estimateHexOverlapWithBoundingBox(const std::array<cvf::Vec3d, 8>& hexCorners, const cvf::BoundingBox& boundingBox, std::array<cvf::Vec3d, 8>* overlapElement, cvf::BoundingBox* overlapBoundingBox)
{
CVF_ASSERT(overlapBoundingBox);
CVF_ASSERT(overlapElement && overlapBoundingBox);
*overlapBoundingBox = cvf::BoundingBox();
std::array<cvf::Vec3d, 8> overlapCorners = hexCorners;
// A reasonable approximation to the overlap volume
cvf::Plane topPlane; topPlane.setFromPoints(hexCorners[0], hexCorners[1], hexCorners[2]);
cvf::Plane bottomPlane; bottomPlane.setFromPoints(hexCorners[4], hexCorners[5], hexCorners[6]);
std::vector<cvf::Vec3d> uniqueTopPoints = { hexCorners[0], hexCorners[1], hexCorners[2], hexCorners[3] };
uniqueTopPoints.erase(std::unique(uniqueTopPoints.begin(), uniqueTopPoints.end()), uniqueTopPoints.end());
if (uniqueTopPoints.size() < 3) return false;
cvf::Plane topPlane;
if (!topPlane.setFromPoints(uniqueTopPoints[0], uniqueTopPoints[1], uniqueTopPoints[2]))
return false;
std::vector<cvf::Vec3d> uniqueBottomPoints = {hexCorners[4], hexCorners[5], hexCorners[6], hexCorners[7]};
uniqueBottomPoints.erase(std::unique(uniqueBottomPoints.begin(), uniqueBottomPoints.end()), uniqueBottomPoints.end());
if (uniqueBottomPoints.size() < 3) return false;
cvf::Plane bottomPlane;
if (!bottomPlane.setFromPoints(uniqueBottomPoints[0], uniqueBottomPoints[1], uniqueBottomPoints[2]))
return false;
for (size_t i = 0; i < 4; ++i)
{
@@ -104,8 +118,8 @@ std::array<cvf::Vec3d, 8> RigCellGeometryTools::estimateHexOverlapWithBoundingBo
corner.z() = cvf::Math::clamp(corner.z(), boundingBox.min().z(), boundingBox.max().z());
cvf::Vec3d maxZCorner = corner; maxZCorner.z() = boundingBox.max().z();
cvf::Vec3d minZCorner = corner; minZCorner.z() = boundingBox.min().z();
topPlane.intersect(minZCorner, maxZCorner, &corner);
overlapBoundingBox->add(corner);
if (topPlane.intersect(minZCorner, maxZCorner, &corner))
overlapBoundingBox->add(corner);
}
for (size_t i = 4; i < 8; ++i)
{
@@ -115,10 +129,12 @@ std::array<cvf::Vec3d, 8> RigCellGeometryTools::estimateHexOverlapWithBoundingBo
corner.z() = cvf::Math::clamp(corner.z(), boundingBox.min().z(), boundingBox.max().z());
cvf::Vec3d maxZCorner = corner; maxZCorner.z() = boundingBox.max().z();
cvf::Vec3d minZCorner = corner; minZCorner.z() = boundingBox.min().z();
bottomPlane.intersect(minZCorner, maxZCorner, &corner);
overlapBoundingBox->add(corner);
if (bottomPlane.intersect(minZCorner, maxZCorner, &corner))
overlapBoundingBox->add(corner);
}
return overlapCorners;
*overlapElement = overlapCorners;
return true;
}
//--------------------------------------------------------------------------------------------------

View File

@@ -32,8 +32,9 @@ class RigCellGeometryTools
{
public:
static double calculateCellVolume(const std::array<cvf::Vec3d, 8>& hexCorners);
static std::array<cvf::Vec3d, 8> estimateHexOverlapWithBoundingBox(const std::array<cvf::Vec3d, 8>& hexCorners,
static bool estimateHexOverlapWithBoundingBox(const std::array<cvf::Vec3d, 8>& hexCorners,
const cvf::BoundingBox& boundingBox2dExtrusion,
std::array<cvf::Vec3d, 8>* overlapCorners,
cvf::BoundingBox* overlapBoundingBox);
static void createPolygonFromLineSegments(std::list<std::pair<cvf::Vec3d, cvf::Vec3d>>& intersectionLineSegments,

View File

@@ -46,7 +46,8 @@ TEST(RigCellGeometryTools, calculateCellVolumeTest)
// The overlap with the original bounding box should just yield the original bounding box
cvf::BoundingBox overlapBoundingBox;
std::array<cvf::Vec3d, 8> overlapVertices = RigCellGeometryTools::estimateHexOverlapWithBoundingBox(cornerVertices, bbox, &overlapBoundingBox);
std::array<cvf::Vec3d, 8> overlapVertices;
RigCellGeometryTools::estimateHexOverlapWithBoundingBox(cornerVertices, bbox, &overlapVertices, &overlapBoundingBox);
EXPECT_DOUBLE_EQ(bboxVolume, RigCellGeometryTools::calculateCellVolume(overlapVertices));
@@ -64,7 +65,8 @@ TEST(RigCellGeometryTools, calculateCellVolumeTest)
corner.x() += 0.5 * bbox.extent().x();
tetrahedronBBox.add(corner);
}
overlapVertices = RigCellGeometryTools::estimateHexOverlapWithBoundingBox(cornerVertices, tetrahedronBBox, &overlapBoundingBox);
overlapVertices;
RigCellGeometryTools::estimateHexOverlapWithBoundingBox(cornerVertices, tetrahedronBBox, &overlapVertices, &overlapBoundingBox);
EXPECT_DOUBLE_EQ(bboxVolume * 0.5 + extraVolume, RigCellGeometryTools::calculateCellVolume(overlapVertices));
@@ -76,13 +78,13 @@ TEST(RigCellGeometryTools, calculateCellVolumeTest)
corner.x() += 0.5 * bbox.extent().x();
tetrahedronBBox.add(corner);
}
overlapVertices = RigCellGeometryTools::estimateHexOverlapWithBoundingBox(cornerVertices, tetrahedronBBox, &overlapBoundingBox);
RigCellGeometryTools::estimateHexOverlapWithBoundingBox(cornerVertices, tetrahedronBBox, &overlapVertices, &overlapBoundingBox);
EXPECT_DOUBLE_EQ(extraVolume, RigCellGeometryTools::calculateCellVolume(overlapVertices));
// Expand original bounding box to be much larger than the hex
bbox.expand(2000);
overlapVertices = RigCellGeometryTools::estimateHexOverlapWithBoundingBox(cornerVertices, bbox, &overlapBoundingBox);
RigCellGeometryTools::estimateHexOverlapWithBoundingBox(cornerVertices, bbox, &overlapVertices, &overlapBoundingBox);
EXPECT_DOUBLE_EQ(bboxVolume + extraVolume, RigCellGeometryTools::calculateCellVolume(overlapVertices));
}
@@ -105,20 +107,21 @@ TEST(RigCellGeometryTools, calculateCellVolumeTest2)
double expectedOverlap = 50 * 50 * 25 + 0.5 * 50 * 50 * 50;
cvf::BoundingBox overlapBoundingBox;
std::array<cvf::Vec3d, 8> overlapVertices = RigCellGeometryTools::estimateHexOverlapWithBoundingBox(cornerVertices, innerBBox, &overlapBoundingBox);
std::array<cvf::Vec3d, 8> overlapVertices;
RigCellGeometryTools::estimateHexOverlapWithBoundingBox(cornerVertices, innerBBox, &overlapVertices, &overlapBoundingBox);
EXPECT_DOUBLE_EQ(expectedOverlap, RigCellGeometryTools::calculateCellVolume(overlapVertices));
cvf::BoundingBox smallerInnerBBox(cvf::Vec3d(25.0, 25.0, -10.0), cvf::Vec3d(75.0, 75.0, 25.0));
overlapVertices = RigCellGeometryTools::estimateHexOverlapWithBoundingBox(cornerVertices, smallerInnerBBox, &overlapBoundingBox);
RigCellGeometryTools::estimateHexOverlapWithBoundingBox(cornerVertices, smallerInnerBBox, &overlapVertices, &overlapBoundingBox);
EXPECT_DOUBLE_EQ(50 * 50 * 25, RigCellGeometryTools::calculateCellVolume(overlapVertices));
cvf::BoundingBox smallerBBox(cvf::Vec3d(50.0, 50.0, 0.0), cvf::Vec3d(100.0, 100.0, 100.0));
overlapVertices = RigCellGeometryTools::estimateHexOverlapWithBoundingBox(cornerVertices, smallerBBox, &overlapBoundingBox);
RigCellGeometryTools::estimateHexOverlapWithBoundingBox(cornerVertices, smallerBBox, &overlapVertices, &overlapBoundingBox);
double tipVolume = 50 * 50 * 50 * 0.5;
EXPECT_DOUBLE_EQ(tipVolume, RigCellGeometryTools::calculateCellVolume(overlapVertices));
cvf::BoundingBox smallerBBox2(cvf::Vec3d(0.0, 0.0, 0.0), cvf::Vec3d(50.0, 50.0, 100.0));
overlapVertices = RigCellGeometryTools::estimateHexOverlapWithBoundingBox(cornerVertices, smallerBBox2, &overlapBoundingBox);
RigCellGeometryTools::estimateHexOverlapWithBoundingBox(cornerVertices, smallerBBox2, &overlapVertices, &overlapBoundingBox);
double expectedVolume = (totalCellVolume - 2*tipVolume) * 0.5;
EXPECT_DOUBLE_EQ(expectedVolume, RigCellGeometryTools::calculateCellVolume(overlapVertices));
}