Well cell transparency: Turned off well cell transparency when no well pipe is visible.

For results visulaization, cell edge and faults faces.
Not yet done for visualization without result colors.
p4#: 21462
This commit is contained in:
Jacob Støren
2013-04-26 16:46:38 +02:00
parent 2e2212d7ea
commit 3806ff9baf
14 changed files with 193 additions and 27 deletions

View File

@@ -63,7 +63,9 @@ void RivCellEdgeGeometryGenerator::addCellEdgeResultsToDrawableGeo(
RimResultSlot* cellResultSlot,
RimCellEdgeResultSlot* cellEdgeResultSlot,
cvf::StructGridGeometryGenerator* generator,
cvf::DrawableGeo* geo)
cvf::DrawableGeo* geo,
size_t gridIndex,
float opacityLevel)
{
const std::vector<size_t>& quadToCell = generator->quadToGridCellIndices();
const std::vector<cvf::StructGridInterface::FaceType>& quadToFace = generator->quadToFace();
@@ -136,6 +138,15 @@ void RivCellEdgeGeometryGenerator::addCellEdgeResultsToDrawableGeo(
double ignoredScalarValue = cellEdgeResultSlot->ignoredScalarValue();
const std::vector<cvf::ubyte>* isWellPipeVisible = NULL;
cvf::ref<cvf::UIntArray> gridCellToWellindexMap;
if (opacityLevel < 1.0f)
{
isWellPipeVisible = &(cellResultSlot->reservoirView()->wellCollection()->isWellPipesVisible(timeStepIndex));
gridCellToWellindexMap = eclipseCase->gridCellToWellIndex( gridIndex );
}
#pragma omp parallel for
for (int quadIdx = 0; quadIdx < static_cast<int>(quadCount); quadIdx++)
{
@@ -162,7 +173,21 @@ void RivCellEdgeGeometryGenerator::addCellEdgeResultsToDrawableGeo(
if (scalarValue != HUGE_VAL)
{
cellColorTextureCoord = cellResultScalarMapper->mapToTextureCoord(scalarValue)[0];
// If we are dealing with wellcells, the default is transparent.
// we need to make cells opaque if there are no wellpipe through them.
if (opacityLevel < 1.0f)
{
cvf::uint wellIndex = gridCellToWellindexMap->get(cellIndex);
if (wellIndex != cvf::UNDEFINED_UINT)
{
if ( !(*isWellPipeVisible)[wellIndex])
{
cellColorTextureCoord += 2.0f; // The shader must interpret values in the range 2-3 as "opaque"
}
}
}
}
else
{

View File

@@ -38,7 +38,9 @@ public:
RimResultSlot* cellResultSlot,
RimCellEdgeResultSlot* cellEdgeResultSlot,
cvf::StructGridGeometryGenerator* generator,
cvf::DrawableGeo* geo);
cvf::DrawableGeo* geo,
size_t gridIndex,
float opacityLevel);
};

View File

@@ -249,16 +249,36 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot*
if (dataAccessObject.isNull()) return;
// Outer surface
if (m_surfaceFaces.notNull())
{
m_surfaceGenerator.textureCoordinates(m_surfaceFacesTextureCoords.p(), dataAccessObject.p(), mapper);
for(size_t i = 0; i < m_surfaceFacesTextureCoords->size(); ++i)
// if this gridpart manager is set to have some transparency, we
// interpret it as we are displaying beeing wellcells. The cells are then transparent by default, but
// we turn that off for particular cells, if the well pipe is not shown for that cell
if (m_opacityLevel < 1.0f )
{
if ((*m_surfaceFacesTextureCoords)[i].y() != 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_surfaceGenerator.quadToGridCellIndices();
for(size_t i = 0; i < m_surfaceFacesTextureCoords->size(); ++i)
{
if (m_opacityLevel == 1.0f) (*m_surfaceFacesTextureCoords)[i].y() = 0;
if ((*m_surfaceFacesTextureCoords)[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_surfaceFacesTextureCoords)[i].y() = 0; // Set the Y texture coordinate to the opaque line in the texture
}
}
}
}
@@ -280,11 +300,26 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot*
{
m_faultGenerator.textureCoordinates(m_faultFacesTextureCoords.p(), dataAccessObject.p(), mapper);
for(size_t i = 0; i < m_faultFacesTextureCoords->size(); ++i)
if (m_opacityLevel < 1.0f )
{
if ((*m_faultFacesTextureCoords)[i].y() != 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_opacityLevel == 1.0f) (*m_faultFacesTextureCoords)[i].y() = 0;
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
}
}
}
}
@@ -312,7 +347,8 @@ void RivGridPartMgr::updateCellEdgeResultColor(size_t timeStepIndex, RimResultSl
cvf::DrawableGeo* dg = dynamic_cast<cvf::DrawableGeo*>(m_surfaceFaces->drawable());
if (dg)
{
RivCellEdgeGeometryGenerator::addCellEdgeResultsToDrawableGeo(timeStepIndex, cellResultSlot, cellEdgeResultSlot, &m_surfaceGenerator, dg);
RivCellEdgeGeometryGenerator::addCellEdgeResultsToDrawableGeo(timeStepIndex, cellResultSlot, cellEdgeResultSlot,
&m_surfaceGenerator, dg, m_grid->gridIndex(), m_opacityLevel );
cvf::ScalarMapper* cellScalarMapper = NULL;
if (cellResultSlot->hasResult()) cellScalarMapper = cellResultSlot->legendConfig()->scalarMapper();
@@ -331,7 +367,8 @@ void RivGridPartMgr::updateCellEdgeResultColor(size_t timeStepIndex, RimResultSl
cvf::DrawableGeo* dg = dynamic_cast<cvf::DrawableGeo*>(m_faultFaces->drawable());
if (dg)
{
RivCellEdgeGeometryGenerator::addCellEdgeResultsToDrawableGeo(timeStepIndex, cellResultSlot, cellEdgeResultSlot, &m_faultGenerator, 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();

View File

@@ -270,7 +270,7 @@ void RivWellHeadPartMgr::appendDynamicGeometryPartsToModel(cvf::ModelBasicList*
if (m_rimWell.isNull()) return;
if (m_rimReservoirView.isNull()) return;
if (m_rimReservoirView->wellCollection()->showWellHead() == false) return;
if (!m_rimWell->isWellVisible(frameIndex)) return;
if (!m_rimWell->isWellPipeVisible(frameIndex)) return;
buildWellHeadParts(frameIndex);

View File

@@ -326,7 +326,7 @@ void RivWellPipesPartMgr::appendDynamicGeometryPartsToModel(cvf::ModelBasicList*
{
if (m_rimReservoirView.isNull()) return;
if (m_rimWell.isNull()) return;
if (!m_rimWell->isWellVisible(frameIndex)) return;
if (!m_rimWell->isWellPipeVisible(frameIndex)) return;
if (m_needsTransformUpdate) buildWellPipeParts();

View File

@@ -507,6 +507,7 @@ void RimReservoirView::createDisplayModel()
bool isAnimationActive = m_viewer->isAnimationActive();
m_viewer->removeAllFrames();
wellCollection->scheduleIsWellPipesVisibleRecalculation();
// Create vector of grid indices to render
std::vector<size_t> gridIndices;
@@ -1178,9 +1179,19 @@ void RimReservoirView::syncronizeWellsWithResults()
cvf::Collection<RigSingleWellResultsData> wellResults = m_reservoir->reservoirData()->wellResults();
std::vector<caf::PdmPointer<RimWell> > newWells;
// Clear the possible well results data present
for (size_t wIdx = 0; wIdx < this->wellCollection()->wells().size(); ++wIdx)
{
RimWell* well = this->wellCollection()->wells()[wIdx];
well->setWellResults(NULL);
}
// Find corresponding well from well result, or create a new
size_t wIdx;
for (wIdx = 0; wIdx < wellResults.size(); ++wIdx)
for (size_t wIdx = 0; wIdx < wellResults.size(); ++wIdx)
{
RimWell* well = this->wellCollection()->findWell(wellResults[wIdx]->m_wellName);
@@ -1188,28 +1199,33 @@ void RimReservoirView::syncronizeWellsWithResults()
{
well = new RimWell;
well->name = wellResults[wIdx]->m_wellName;
this->wellCollection()->wells().push_back(well);
}
newWells.push_back(well);
well->setWellIndex(wIdx);
well->setWellResults(wellResults[wIdx].p());
}
// Remove all wells that does not have a result
// Delete all wells that does not have a result
for (wIdx = 0; wIdx < this->wellCollection()->wells().size(); ++wIdx)
for (size_t wIdx = 0; wIdx < this->wellCollection()->wells().size(); ++wIdx)
{
RimWell* well = this->wellCollection()->wells()[wIdx];
RigSingleWellResultsData* wellRes = well->wellResults();
if (wellRes == NULL)
{
delete well;
this->wellCollection()->wells().erase(wIdx);
}
}
this->wellCollection()->wells().clear();
// Set the new wells into the field.
this->wellCollection()->wells().insert(0, newWells);
// Make sure all the wells have their reservoirView ptr setup correctly
this->wellCollection()->setReservoirView(this);
for (wIdx = 0; wIdx < this->wellCollection()->wells().size(); ++wIdx)
for (size_t wIdx = 0; wIdx < this->wellCollection()->wells().size(); ++wIdx)
{
this->wellCollection()->wells()[wIdx]->setReservoirView(this);
}

View File

@@ -49,6 +49,8 @@ RimWell::RimWell()
name.setUiHidden(true);
name.setUiReadOnly(true);
m_wellIndex = cvf::UNDEFINED_SIZE_T;
m_reservoirView = NULL;
}
@@ -134,7 +136,7 @@ caf::PdmFieldHandle* RimWell::objectToggleField()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWell::isWellVisible(size_t frameIndex)
bool RimWell::calculateWellPipeVisibility(size_t frameIndex)
{
if (m_reservoirView == NULL) return false;
if (this->wellResults() == NULL) return false;
@@ -144,6 +146,9 @@ bool RimWell::isWellVisible(size_t frameIndex)
|| frameIndex >= this->wellResults()->m_wellCellsTimeSteps.size())
return false;
if (!m_reservoirView->wellCollection()->active())
return false;
if (m_reservoirView->wellCollection()->wellPipeVisibility() == RimWellCollection::PIPES_FORCE_ALL_ON)
return true;
@@ -220,3 +225,12 @@ void RimWell::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrder
filterGroup->add(&showWellCellFence);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWell::isWellPipeVisible(size_t frameIndex)
{
// Return the possibly cached value
return m_reservoirView->wellCollection()->isWellPipesVisible(frameIndex)[m_wellIndex];
}

View File

@@ -40,11 +40,14 @@ public:
virtual ~RimWell();
void setReservoirView(RimReservoirView* ownerReservoirView);
void setWellIndex(size_t val) { m_wellIndex = val; }
void setWellResults(RigSingleWellResultsData* wellResults) { m_wellResults = wellResults;}
RigSingleWellResultsData* wellResults() { return m_wellResults.p(); }
bool isWellVisible(size_t frameIndex);
bool isWellPipeVisible(size_t frameIndex);
bool calculateWellPipeVisibility(size_t frameIndex);
virtual caf::PdmFieldHandle* userDescriptionField();
virtual caf::PdmFieldHandle* objectToggleField();
@@ -64,6 +67,7 @@ public:
private:
cvf::ref<RigSingleWellResultsData> m_wellResults;
size_t m_wellIndex;
RimReservoirView* m_reservoirView;
};

View File

@@ -276,3 +276,39 @@ caf::PdmFieldHandle* RimWellCollection::objectToggleField()
return &active;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<cvf::ubyte>& RimWellCollection::isWellPipesVisible(size_t frameIndex)
{
calculateIsWellPipesVisible(frameIndex);
return m_isWellPipesVisible[frameIndex];
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellCollection::scheduleIsWellPipesVisibleRecalculation()
{
m_isWellPipesVisible.clear();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellCollection::calculateIsWellPipesVisible(size_t frameIndex)
{
if (m_isWellPipesVisible.size() > frameIndex && m_isWellPipesVisible[frameIndex].size()) return;
if (m_isWellPipesVisible.size() <= frameIndex)
m_isWellPipesVisible.resize(frameIndex+1);
if (m_isWellPipesVisible[frameIndex].size() <= wells().size())
m_isWellPipesVisible[frameIndex].resize(wells().size(), false);
for (size_t i = 0; i < wells().size(); ++i)
{
m_isWellPipesVisible[frameIndex][i] = wells[i]->calculateWellPipeVisibility(frameIndex);
}
}

View File

@@ -90,9 +90,17 @@ public:
bool hasVisibleWellCells();
bool hasVisibleWellPipes();
const std::vector<cvf::ubyte>& isWellPipesVisible(size_t frameIndex);
void scheduleIsWellPipesVisibleRecalculation();
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue);
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering);
virtual caf::PdmFieldHandle* objectToggleField();
private:
void calculateIsWellPipesVisible(size_t frameIndex);
RimReservoirView* m_reservoirView;
std::vector< std::vector< cvf::ubyte > >
m_isWellPipesVisible;
};

View File

@@ -136,6 +136,7 @@ void RigCaseData::computeWellCellsPrGrid()
// Allocate and initialize the arrays
m_wellCellsInGrid.resize(grids.size());
m_gridCellToWellIndex.resize(grids.size());
for (gIdx = 0; gIdx < grids.size(); ++gIdx)
{
@@ -144,8 +145,11 @@ void RigCaseData::computeWellCellsPrGrid()
m_wellCellsInGrid[gIdx] = new cvf::UByteArray;
m_wellCellsInGrid[gIdx]->resize(grids[gIdx]->cellCount());
m_gridCellToWellIndex[gIdx] = new cvf::UIntArray;
m_gridCellToWellIndex[gIdx]->resize(grids[gIdx]->cellCount());
}
m_wellCellsInGrid[gIdx]->setAll(false);
m_gridCellToWellIndex[gIdx]->setAll(cvf::UNDEFINED_UINT);
}
// Fill arrays with data
@@ -162,6 +166,7 @@ void RigCaseData::computeWellCellsPrGrid()
CVF_ASSERT(gridIndex < m_wellCellsInGrid.size() && gridCellIndex < m_wellCellsInGrid[gridIndex]->size());
m_wellCellsInGrid[gridIndex]->set(gridCellIndex, true);
m_gridCellToWellIndex[gridIndex]->set(gridCellIndex, static_cast<cvf::uint>(wIdx));
size_t sIdx;
for (sIdx = 0; sIdx < wellCells.m_wellResultBranches.size(); ++sIdx)
@@ -176,6 +181,7 @@ void RigCaseData::computeWellCellsPrGrid()
CVF_ASSERT(gridIndex < m_wellCellsInGrid.size() && gridCellIndex < m_wellCellsInGrid[gridIndex]->size());
m_wellCellsInGrid[gridIndex]->set(gridCellIndex, true);
m_gridCellToWellIndex[gridIndex]->set(gridCellIndex, static_cast<cvf::uint>(wIdx));
}
}
}
@@ -189,6 +195,8 @@ void RigCaseData::setWellResults(const cvf::Collection<RigSingleWellResultsData>
{
m_wellResults = data;
m_wellCellsInGrid.clear();
m_gridCellToWellIndex.clear();
computeWellCellsPrGrid();
}
@@ -203,6 +211,18 @@ cvf::UByteArray* RigCaseData::wellCellsInGrid(size_t gridIndex)
return m_wellCellsInGrid[gridIndex].p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::UIntArray* RigCaseData::gridCellToWellIndex(size_t gridIndex)
{
computeWellCellsPrGrid();
CVF_ASSERT(gridIndex < m_gridCellToWellIndex.size());
return m_gridCellToWellIndex[gridIndex].p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -63,6 +63,7 @@ public:
const cvf::Collection<RigSingleWellResultsData>& wellResults() { return m_wellResults; }
cvf::UByteArray* wellCellsInGrid(size_t gridIndex);
cvf::UIntArray* gridCellToWellIndex(size_t gridIndex);
RigCell& cellFromWellResultCell(const RigWellResultCell& wellResultCell);
bool findSharedSourceFace(cvf::StructGridInterface::FaceType& sharedSourceFace, const RigWellResultCell& sourceWellCellResult, const RigWellResultCell& otherWellCellResult) const;
@@ -73,7 +74,6 @@ private:
void computeActiveCellIJKBBox();
void computeWellCellsPrGrid();
void computeActiveCellsGeometryBoundingBox();
private:
cvf::ref<RigMainGrid> m_mainGrid;
@@ -85,4 +85,5 @@ private:
cvf::Collection<RigSingleWellResultsData> m_wellResults; //< A WellResults object for each well in the reservoir
cvf::Collection<cvf::UByteArray> m_wellCellsInGrid; //< A bool array pr grid with one bool pr cell telling wether the cell is a well cell or not
cvf::Collection<cvf::UIntArray> m_gridCellToWellIndex; //< Array pr grid with index to well pr cell telling which well a cell is in
};

View File

@@ -75,8 +75,10 @@ void main()
if ( a_colorCell < 0.0)
v_cellColor = vec4(0.75, 0.75, 0.75, 1); // Light grayish
else
v_cellColor = texture2D(u_cellTexture2D, vec2( a_colorCell, 0.5f));
else if ( a_colorCell >= 2.0)
v_cellColor = texture2D(u_cellTexture2D, vec2( a_colorCell-2.0f, 0f)); // Opaque, because the y=0 texcoord points to the opaque part of an modified texture
else
v_cellColor = texture2D(u_cellTexture2D, vec2( a_colorCell, 0.5f)); // Default, transparent if the texture is modified
/*
// Performance test code

View File

@@ -362,7 +362,8 @@ void StructGridGeometryGenerator::computeArrays()
//--------------------------------------------------------------------------------------------------
///
/// Calculates the texture coordinates in a "nearly" one dimentional texture.
/// Undefined values are coded with a y-texturecoordinate value of 1.0 instead of the normal 0.5
//--------------------------------------------------------------------------------------------------
void StructGridGeometryGenerator::textureCoordinates(Vec2fArray* textureCoords, const StructGridScalarDataAccess* dataAccessObject, const ScalarMapper* mapper) const
{