From ee388ca4b0857ea3220a18b789cd9804ce2295e5 Mon Sep 17 00:00:00 2001 From: Gaute Lindkvist Date: Wed, 31 Oct 2018 16:09:14 +0100 Subject: [PATCH] #3591 Improve edges on contour map. --- .../Riv2dGridProjectionPartMgr.cpp | 50 ++++++++++++++++--- .../Riv2dGridProjectionPartMgr.h | 6 ++- .../RivScalarMapperUtils.cpp | 10 ++-- .../ModelVisualization/RivScalarMapperUtils.h | 6 ++- .../ProjectDataModel/Rim2dEclipseView.cpp | 19 ++++--- .../ProjectDataModel/Rim2dGridProjection.cpp | 44 ++++++++++------ .../ProjectDataModel/Rim2dGridProjection.h | 2 + ApplicationCode/ProjectDataModel/Rim3dView.h | 4 +- .../ProjectDataModel/RimEclipseCase.cpp | 1 + Fwk/AppFwk/CommonCode/cafContourLines.cpp | 32 ++++++++++-- Fwk/AppFwk/CommonCode/cafContourLines.h | 2 + 11 files changed, 131 insertions(+), 45 deletions(-) diff --git a/ApplicationCode/ModelVisualization/Riv2dGridProjectionPartMgr.cpp b/ApplicationCode/ModelVisualization/Riv2dGridProjectionPartMgr.cpp index e9194cda98..c07162b246 100644 --- a/ApplicationCode/ModelVisualization/Riv2dGridProjectionPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/Riv2dGridProjectionPartMgr.cpp @@ -1,8 +1,10 @@ #include "Riv2dGridProjectionPartMgr.h" +#include "RiaWeightedMeanCalculator.h" #include "RivMeshLinesSourceInfo.h" #include "RivScalarMapperUtils.h" +#include "Rim2dEclipseView.h" #include "Rim2dGridProjection.h" #include "cafEffectGenerator.h" @@ -16,9 +18,10 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -Riv2dGridProjectionPartMgr::Riv2dGridProjectionPartMgr(Rim2dGridProjection* gridProjection) +Riv2dGridProjectionPartMgr::Riv2dGridProjectionPartMgr(Rim2dGridProjection* gridProjection, Rim2dEclipseView* contourMap) { m_2dGridProjection = gridProjection; + m_parentContourMap = contourMap; } //-------------------------------------------------------------------------------------------------- @@ -34,7 +37,7 @@ void Riv2dGridProjectionPartMgr::appendProjectionToModel(cvf::ModelBasicList* mo cvf::ref textureCoords = createTextureCoords(); cvf::ScalarMapper* mapper = m_2dGridProjection->legendConfig()->scalarMapper(); - RivScalarMapperUtils::applyTextureResultsToPart(part.p(), textureCoords.p(), mapper, 1.0f, caf::FC_NONE, true); + RivScalarMapperUtils::applyTextureResultsToPart(part.p(), textureCoords.p(), mapper, 1.0f, caf::FC_NONE, true, m_parentContourMap->backgroundColor()); part->setSourceInfo(new RivMeshLinesSourceInfo(m_2dGridProjection.p())); @@ -82,7 +85,38 @@ cvf::ref Riv2dGridProjectionPartMgr::createTextureCoords() cons } else { - (*textureCoords)[i + j * patchSize.x()] = cvf::Vec2f(1.0, 1.0); + // Perform weighted averaging of the valid neighbors + RiaWeightedMeanCalculator calc; + for (int dj = -1; dj <= 1; ++dj) + { + int fullJ = static_cast(j) + dj; + if (fullJ >= 0 && fullJ < static_cast(patchSize.y())) + { + for (int di = -1; di <= 1; ++di) + { + if (di == 0 && dj == 0) continue; + + int fullI = static_cast(i) + di; + if (fullI >= 0 && fullI < static_cast(patchSize.x())) + { + if (m_2dGridProjection->hasResultAt(fullI, fullJ)) + { + double value = m_2dGridProjection->value(fullI, fullJ); + calc.addValueAndWeight(value, 1.0 / std::sqrt(di*di + dj * dj)); + } + } + } + } + } + if (calc.validAggregatedWeight()) + { + (*textureCoords)[i + j * patchSize.x()] = + m_2dGridProjection->legendConfig()->scalarMapper()->mapToTextureCoord(calc.weightedMean()); + } + else + { + (*textureCoords)[i + j * patchSize.x()] = cvf::Vec2f(1.0, 1.0); + } } } } @@ -98,17 +132,17 @@ void Riv2dGridProjectionPartMgr::removeTrianglesWithNoResult(cvf::UIntArray* ver for (size_t n = 0; n < vertices->size(); n += 3) { - bool anyInvalid = false; - for (size_t t = 0; !anyInvalid && t < 3; ++t) + bool anyValid = false; + for (size_t t = 0; !anyValid && t < 3; ++t) { cvf::uint vertexNumber = (*vertices)[n + t]; cvf::Vec2ui ij = m_2dGridProjection->ijFromGridIndex(vertexNumber); - if (!m_2dGridProjection->hasResultAt(ij.x(), ij.y())) + if (m_2dGridProjection->hasResultAt(ij.x(), ij.y())) { - anyInvalid = true; + anyValid = true; } } - for (size_t t = 0; !anyInvalid && t < 3; ++t) + for (size_t t = 0; anyValid && t < 3; ++t) { cvf::uint vertexNumber = (*vertices)[n + t]; trianglesWithResult.push_back(vertexNumber); diff --git a/ApplicationCode/ModelVisualization/Riv2dGridProjectionPartMgr.h b/ApplicationCode/ModelVisualization/Riv2dGridProjectionPartMgr.h index b7a452f3f9..2f481d2faa 100644 --- a/ApplicationCode/ModelVisualization/Riv2dGridProjectionPartMgr.h +++ b/ApplicationCode/ModelVisualization/Riv2dGridProjectionPartMgr.h @@ -26,12 +26,13 @@ #include "cvfModelBasicList.h" #include "cvfObject.h" +class Rim2dEclipseView; class Rim2dGridProjection; class Riv2dGridProjectionPartMgr : public cvf::Object { public: - Riv2dGridProjectionPartMgr(Rim2dGridProjection* gridProjection); + Riv2dGridProjectionPartMgr(Rim2dGridProjection* gridProjection, Rim2dEclipseView* contourMap); void appendProjectionToModel(cvf::ModelBasicList* model, const caf::DisplayCoordTransform* displayCoordTransform) const; @@ -43,6 +44,7 @@ private: cvf::ref createDrawable(const caf::DisplayCoordTransform* displayCoordTransform) const; std::vector> createContourPolygons(const caf::DisplayCoordTransform* displayCoordTransform) const; private: - caf::PdmPointer m_2dGridProjection; + caf::PdmPointer m_2dGridProjection; + caf::PdmPointer m_parentContourMap; }; diff --git a/ApplicationCode/ModelVisualization/RivScalarMapperUtils.cpp b/ApplicationCode/ModelVisualization/RivScalarMapperUtils.cpp index 36f83ac76e..ea6bad275b 100644 --- a/ApplicationCode/ModelVisualization/RivScalarMapperUtils.cpp +++ b/ApplicationCode/ModelVisualization/RivScalarMapperUtils.cpp @@ -19,8 +19,6 @@ #include "RivScalarMapperUtils.h" -#include "RiaColorTables.h" - #include "RimCellEdgeColors.h" #include "RimEclipseCellColors.h" #include "RimEclipseView.h" @@ -41,14 +39,14 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RivScalarMapperUtils::applyTextureResultsToPart(cvf::Part* part, cvf::Vec2fArray* textureCoords, const cvf::ScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling, bool disableLighting) +void RivScalarMapperUtils::applyTextureResultsToPart(cvf::Part* part, cvf::Vec2fArray* textureCoords, const cvf::ScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling, bool disableLighting, const cvf::Color3f& undefColor) { CVF_ASSERT(part && textureCoords && mapper); cvf::DrawableGeo* dg = dynamic_cast(part->drawable()); if (dg) dg->setTextureCoordArray(textureCoords); - cvf::ref scalarEffect = RivScalarMapperUtils::createScalarMapperEffect(mapper, opacityLevel, faceCulling, disableLighting); + cvf::ref scalarEffect = RivScalarMapperUtils::createScalarMapperEffect(mapper, opacityLevel, faceCulling, disableLighting, undefColor); part->setEffect(scalarEffect.p()); } @@ -122,7 +120,7 @@ cvf::ref RivScalarMapperUtils::createCellEdgeEffect(cvf::DrawableGe //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::ref RivScalarMapperUtils::createScalarMapperEffect(const cvf::ScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling, bool disableLighting) +cvf::ref RivScalarMapperUtils::createScalarMapperEffect(const cvf::ScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling, bool disableLighting, const cvf::Color3f& undefColor) { CVF_ASSERT(mapper); @@ -130,7 +128,7 @@ cvf::ref RivScalarMapperUtils::createScalarMapperEffect(const cvf:: caf::ScalarMapperEffectGenerator scalarEffgen(mapper, polygonOffset); scalarEffgen.setOpacityLevel(opacityLevel); scalarEffgen.setFaceCulling(faceCulling); - scalarEffgen.setUndefinedColor(RiaColorTables::undefinedCellColor()); + scalarEffgen.setUndefinedColor(undefColor); scalarEffgen.disableLighting(disableLighting); cvf::ref scalarEffect = scalarEffgen.generateCachedEffect(); diff --git a/ApplicationCode/ModelVisualization/RivScalarMapperUtils.h b/ApplicationCode/ModelVisualization/RivScalarMapperUtils.h index 808c9957d2..5be8f6ad9c 100644 --- a/ApplicationCode/ModelVisualization/RivScalarMapperUtils.h +++ b/ApplicationCode/ModelVisualization/RivScalarMapperUtils.h @@ -19,6 +19,8 @@ #pragma once +#include "RiaColorTables.h" + #include "cafEffectGenerator.h" #include "cvfBase.h" @@ -43,7 +45,7 @@ class RimCellEdgeColors; class RivScalarMapperUtils { public: - static void applyTextureResultsToPart(cvf::Part* part, cvf::Vec2fArray* textureCoords, const cvf::ScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling, bool disableLighting); + static void applyTextureResultsToPart(cvf::Part* part, cvf::Vec2fArray* textureCoords, const cvf::ScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling, bool disableLighting, const cvf::Color3f& undefColor = cvf::Color3f(RiaColorTables::undefinedCellColor())); static void applyTernaryTextureResultsToPart(cvf::Part* part, cvf::Vec2fArray* textureCoords, const RivTernaryScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling, bool disableLighting); static cvf::ref createCellEdgeEffect(cvf::DrawableGeo* dg, @@ -58,7 +60,7 @@ public: bool disableLighting); private: - static cvf::ref createScalarMapperEffect(const cvf::ScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling, bool disableLighting); + static cvf::ref createScalarMapperEffect(const cvf::ScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling, bool disableLighting, const cvf::Color3f& undefColor = cvf::Color3f(RiaColorTables::undefinedCellColor())); static cvf::ref createTernaryScalarMapperEffect(const RivTernaryScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling, bool disableLighting); }; diff --git a/ApplicationCode/ProjectDataModel/Rim2dEclipseView.cpp b/ApplicationCode/ProjectDataModel/Rim2dEclipseView.cpp index 6610c73e5c..12e86922ca 100644 --- a/ApplicationCode/ProjectDataModel/Rim2dEclipseView.cpp +++ b/ApplicationCode/ProjectDataModel/Rim2dEclipseView.cpp @@ -58,7 +58,7 @@ Rim2dEclipseView::Rim2dEclipseView() wellCollection()->isActive = false; faultCollection()->showFaultCollection = false; - m_grid2dProjectionPartMgr = new Riv2dGridProjectionPartMgr(grid2dProjection()); + m_grid2dProjectionPartMgr = new Riv2dGridProjectionPartMgr(grid2dProjection(), this); ((RiuViewerToViewInterface*)this)->setCameraPosition(defaultViewMatrix); } @@ -81,6 +81,7 @@ void Rim2dEclipseView::initAfterRead() setShowGridBox(false); meshMode.setValue(NO_MESH); surfaceMode.setValue(FAULTS); + scheduleCreateDisplayModelAndRedraw(); } //-------------------------------------------------------------------------------------------------- @@ -129,12 +130,13 @@ void Rim2dEclipseView::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrderi //-------------------------------------------------------------------------------------------------- void Rim2dEclipseView::updateCurrentTimeStep() { - RimEclipseView::updateCurrentTimeStep(); if (m_2dGridProjection->isChecked()) { m_2dGridProjection->generateResults(); } + RimEclipseView::updateCurrentTimeStep(); + cvf::Scene* frameScene = m_viewer->frame(m_currentTimeStep); if (m_2dGridProjection->isChecked()) @@ -166,10 +168,13 @@ void Rim2dEclipseView::updateLegends() if (m_2dGridProjection && m_2dGridProjection->isChecked()) { RimRegularLegendConfig* projectionLegend = m_2dGridProjection->legendConfig(); - if (projectionLegend && projectionLegend->showLegend()) + if (projectionLegend) { m_2dGridProjection->updateLegend(); - m_viewer->addColorLegendToBottomLeftCorner(projectionLegend->titledOverlayFrame()); + if (projectionLegend->showLegend()) + { + m_viewer->addColorLegendToBottomLeftCorner(projectionLegend->titledOverlayFrame()); + } } } } @@ -212,13 +217,15 @@ void Rim2dEclipseView::onLoadDataAndUpdate() //-------------------------------------------------------------------------------------------------- void Rim2dEclipseView::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) { + RimEclipseView::fieldChangedByUi(changedField, oldValue, newValue); + if (changedField == &m_showAxisLines) { m_viewer->showEdgeTickMarksXY(true, m_showAxisLines()); scheduleCreateDisplayModelAndRedraw(); } - else + else if (changedField == backgroundColorField()) { - RimEclipseView::fieldChangedByUi(changedField, oldValue, newValue); + scheduleCreateDisplayModelAndRedraw(); } } diff --git a/ApplicationCode/ProjectDataModel/Rim2dGridProjection.cpp b/ApplicationCode/ProjectDataModel/Rim2dGridProjection.cpp index 6c5467680c..e4744ea27b 100644 --- a/ApplicationCode/ProjectDataModel/Rim2dGridProjection.cpp +++ b/ApplicationCode/ProjectDataModel/Rim2dGridProjection.cpp @@ -69,6 +69,16 @@ Rim2dGridProjection::~Rim2dGridProjection() } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::BoundingBox Rim2dGridProjection::expandedBoundingBox() const +{ + cvf::BoundingBox boundingBox = eclipseCase()->activeCellsBoundingBox(); + //boundingBox.expand(m_sampleSpacing * 0.5); + return boundingBox; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -79,8 +89,7 @@ void Rim2dGridProjection::generateGridMapping() calculateCellRangeVisibility(); calculatePropertyFilterVisibility(); - cvf::BoundingBox boundingBox = eclipseCase()->activeCellsBoundingBox(); - cvf::Vec3d gridExtent = boundingBox.extent(); + cvf::Vec3d gridExtent = expandedBoundingBox().extent(); cvf::Vec2ui gridSize2d = surfaceGridSize(); @@ -110,7 +119,7 @@ void Rim2dGridProjection::generateVertices(cvf::Vec3fArray* vertices, const caf: vertices->resize(vertexCount()); cvf::Vec2ui gridSize2d = surfaceGridSize(); - cvf::BoundingBox boundingBox = eclipseCase()->activeCellsBoundingBox(); + cvf::BoundingBox boundingBox = expandedBoundingBox(); int nVertices = vertexCount(); @@ -135,7 +144,7 @@ Rim2dGridProjection::ContourPolygons Rim2dGridProjection::generateContourPolygon { std::vector> contourPolygons; - cvf::BoundingBox boundingBox = eclipseCase()->activeCellsBoundingBox(); + cvf::BoundingBox boundingBox = expandedBoundingBox(); std::vector contourLevels; legendConfig()->scalarMapper()->majorTickValues(&contourLevels); @@ -150,14 +159,17 @@ Rim2dGridProjection::ContourPolygons Rim2dGridProjection::generateContourPolygon contourPolygons.reserve(contourLines.size()); for (size_t i = 0; i < contourLines.size(); ++i) { - cvf::ref contourPolygon = new cvf::Vec3fArray(contourLines[i].size()); - for (size_t j = 0; j < contourLines[i].size(); ++j) + if (!contourLines[i].empty()) { - cvf::Vec3d contourPoint3d = cvf::Vec3d(contourLines[i][j], boundingBox.min().z()); - cvf::Vec3d displayPoint3d = displayCoordTransform->transformToDisplayCoord(contourPoint3d); - (*contourPolygon)[j] = cvf::Vec3f(displayPoint3d); + cvf::ref contourPolygon = new cvf::Vec3fArray(contourLines[i].size()); + for (size_t j = 0; j < contourLines[i].size(); ++j) + { + cvf::Vec3d contourPoint3d = cvf::Vec3d(contourLines[i][j], boundingBox.min().z()); + cvf::Vec3d displayPoint3d = displayCoordTransform->transformToDisplayCoord(contourPoint3d); + (*contourPolygon)[j] = cvf::Vec3f(displayPoint3d); + } + contourPolygons.push_back(contourPolygon); } - contourPolygons.push_back(contourPolygon); } } return contourPolygons; @@ -331,7 +343,7 @@ bool Rim2dGridProjection::hasResultAt(uint i, uint j) const //-------------------------------------------------------------------------------------------------- cvf::Vec2ui Rim2dGridProjection::surfaceGridSize() const { - cvf::BoundingBox boundingBox = eclipseCase()->activeCellsBoundingBox(); + cvf::BoundingBox boundingBox = expandedBoundingBox(); cvf::Vec3d gridExtent = boundingBox.extent(); uint projectionSizeX = static_cast(std::ceil(gridExtent.x() / m_sampleSpacing)) + 1u; @@ -425,7 +437,7 @@ void Rim2dGridProjection::calculatePropertyFilterVisibility() //-------------------------------------------------------------------------------------------------- cvf::Vec2d Rim2dGridProjection::globalPos2d(uint i, uint j) const { - cvf::BoundingBox boundingBox = eclipseCase()->activeCellsBoundingBox(); + cvf::BoundingBox boundingBox = expandedBoundingBox(); cvf::Vec3d gridExtent = boundingBox.extent(); cvf::Vec2d origin(boundingBox.min().x(), boundingBox.min().y()); cvf::Vec2ui gridSize2d = surfaceGridSize(); @@ -447,7 +459,7 @@ const std::vector>& Rim2dGridProjection::cellsAtPos2d(u //-------------------------------------------------------------------------------------------------- std::vector> Rim2dGridProjection::visibleCellsAndWeightMatching2dPoint(const cvf::Vec2d& globalPos2d) const { - cvf::BoundingBox boundingBox = eclipseCase()->activeCellsBoundingBox(); + cvf::BoundingBox boundingBox = expandedBoundingBox(); cvf::Vec3d highestPoint(globalPos2d, boundingBox.max().z()); cvf::Vec3d lowestPoint(globalPos2d, boundingBox.min().z()); @@ -471,7 +483,7 @@ std::vector> Rim2dGridProjection::visibleCellsAndWeight localGrid->cellCornerVertices(localCellIdx, hexCorners); std::vector intersections; float weight = 1.0f; - if (false && RigHexIntersectionTools::lineHexCellIntersection(highestPoint, lowestPoint, hexCorners, 0, &intersections)) + if (RigHexIntersectionTools::lineHexCellIntersection(highestPoint, lowestPoint, hexCorners, 0, &intersections)) { weight = std::max(1.0, (intersections.back().m_intersectionPoint - intersections.front().m_intersectionPoint).length()); } @@ -539,7 +551,7 @@ void Rim2dGridProjection::updateLegend() //-------------------------------------------------------------------------------------------------- std::vector Rim2dGridProjection::xPositions() const { - cvf::BoundingBox boundingBox = eclipseCase()->activeCellsBoundingBox(); + cvf::BoundingBox boundingBox = expandedBoundingBox(); cvf::Vec3d gridExtent = boundingBox.extent(); double origin = boundingBox.min().x(); @@ -560,7 +572,7 @@ std::vector Rim2dGridProjection::xPositions() const //-------------------------------------------------------------------------------------------------- std::vector Rim2dGridProjection::yPositions() const { - cvf::BoundingBox boundingBox = eclipseCase()->activeCellsBoundingBox(); + cvf::BoundingBox boundingBox = expandedBoundingBox(); cvf::Vec3d gridExtent = boundingBox.extent(); double origin = boundingBox.min().y(); cvf::Vec2ui gridSize2d = surfaceGridSize(); diff --git a/ApplicationCode/ProjectDataModel/Rim2dGridProjection.h b/ApplicationCode/ProjectDataModel/Rim2dGridProjection.h index b4c40b64ff..9e97ca393b 100644 --- a/ApplicationCode/ProjectDataModel/Rim2dGridProjection.h +++ b/ApplicationCode/ProjectDataModel/Rim2dGridProjection.h @@ -27,6 +27,7 @@ #include "cafPdmField.h" #include "cafPdmObject.h" +#include "cvfBoundingBox.h" #include "cvfGeometryBuilderFaceList.h" #include "cvfVector2.h" @@ -76,6 +77,7 @@ public: void updateLegend(); protected: + cvf::BoundingBox expandedBoundingBox() const; void generateGridMapping(); void calculateCellRangeVisibility(); void calculatePropertyFilterVisibility(); diff --git a/ApplicationCode/ProjectDataModel/Rim3dView.h b/ApplicationCode/ProjectDataModel/Rim3dView.h index dd85f0d276..2352d41e60 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dView.h +++ b/ApplicationCode/ProjectDataModel/Rim3dView.h @@ -101,6 +101,9 @@ public: void setName(const QString& name); QString name() const; + // Implementation of RiuViewerToViewInterface + cvf::Color3f backgroundColor() const override { return m_backgroundColor(); } + void setMeshOnlyDrawstyle(); void setMeshSurfDrawstyle(); void setSurfOnlyDrawstyle(); @@ -166,7 +169,6 @@ protected: void createHighlightAndGridBoxDisplayModel(); // Implementation of RiuViewerToViewInterface - cvf::Color3f backgroundColor() const override { return m_backgroundColor(); } void applyBackgroundColor(); // Abstract methods to implement in subclasses diff --git a/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp b/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp index d4bb6106b4..89eef133b8 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp @@ -361,6 +361,7 @@ Rim2dEclipseView* RimEclipseCase::create2dContourMap() contourMap->fractureColors()->setDefaultResultName(); contourMap->setBackgroundColor(cvf::Color3f(1.0f, 1.0f, 0.98f)); contourMap->initAfterReadRecursively(); + contourMap->zoomAll(); } caf::PdmDocument::updateUiIconStateRecursively(contourMap); diff --git a/Fwk/AppFwk/CommonCode/cafContourLines.cpp b/Fwk/AppFwk/CommonCode/cafContourLines.cpp index a45ce97575..a32c44cf1d 100644 --- a/Fwk/AppFwk/CommonCode/cafContourLines.cpp +++ b/Fwk/AppFwk/CommonCode/cafContourLines.cpp @@ -67,7 +67,7 @@ void caf::ContourLines::create(const std::vector& dataXY, const std::vec temp2 = std::max(saneValue(gridIndex1d(i + 1, j, nx), dataXY, contourLevels), saneValue(gridIndex1d(i + 1, j + 1, nx), dataXY, contourLevels)); double dmax = std::max(temp1, temp2); - if (dmax < contourLevels[0] && dmin > contourLevels[nContourLevels - 1]) + if (dmax < contourLevels[0] || dmin > contourLevels[nContourLevels - 1]) continue; for (int k = 0; k < nContourLevels; k++) @@ -78,7 +78,15 @@ void caf::ContourLines::create(const std::vector& dataXY, const std::vec { if (m > 0) { - h[m] = saneValue(gridIndex1d(i + im[m - 1], j + jm[m - 1], nx), dataXY, contourLevels) - contourLevels[k]; + double value = saneValue(gridIndex1d(i + im[m - 1], j + jm[m - 1], nx), dataXY, contourLevels); + if (value == invalidValue(contourLevels)) + { + h[m] = invalidValue(contourLevels); + } + else + { + h[m] = value - contourLevels[k]; + } xh[m] = xCoords[i + im[m - 1]]; yh[m] = yCoords[j + jm[m - 1]]; } @@ -198,18 +206,34 @@ void caf::ContourLines::create(const std::vector& dataXY, const std::vec } /* j */ } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double caf::ContourLines::contourRange(const std::vector& contourLevels) +{ + return std::max(1.0, contourLevels.back() - contourLevels.front()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double caf::ContourLines::invalidValue(const std::vector& contourLevels) +{ + return contourLevels.front() - 1000.0*contourRange(contourLevels); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- double caf::ContourLines::saneValue(int index, const std::vector& dataXY, const std::vector& contourLevels) { CVF_ASSERT(index >= 0 && index < static_cast(dataXY.size())); - double range = std::max(1.0, contourLevels.back() - contourLevels.front()); + // Place all invalid values below the bottom contour level. if (dataXY[index] == -std::numeric_limits::infinity() || dataXY[index] == std::numeric_limits::infinity()) { - return contourLevels.front() - range; + return invalidValue(contourLevels); } return dataXY[index]; } diff --git a/Fwk/AppFwk/CommonCode/cafContourLines.h b/Fwk/AppFwk/CommonCode/cafContourLines.h index 854e263d33..62ef94be6e 100644 --- a/Fwk/AppFwk/CommonCode/cafContourLines.h +++ b/Fwk/AppFwk/CommonCode/cafContourLines.h @@ -38,6 +38,8 @@ public: const std::vector& contourLevels, std::vector>* polygons); private: + static double contourRange(const std::vector& contourLevels); + static double invalidValue(const std::vector& contourLevels); static double saneValue(int index, const std::vector& dataXY, const std::vector& contourLevels); static double xsect(int p1, int p2, const std::vector& h, const std::vector& xh, const std::vector& yh); static double ysect(int p1, int p2, const std::vector& h, const std::vector& xh, const std::vector& yh);