Copy changes from dev-branch into main

History of main branch was difficult to merge. Take a copy of dev-branch, and merge both ways between dev and main after the release.
This commit is contained in:
Magne Sjaastad
2023-10-23 08:12:19 +02:00
parent 5688838899
commit 06f9c6126d
1778 changed files with 35036 additions and 12457 deletions

View File

@@ -1,14 +1,11 @@
set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RivCellEdgeEffectGenerator.h
${CMAKE_CURRENT_LIST_DIR}/RivFaultPartMgr.h
${CMAKE_CURRENT_LIST_DIR}/RivFaultGeometryGenerator.h
${CMAKE_CURRENT_LIST_DIR}/RivNNCGeometryGenerator.h
${CMAKE_CURRENT_LIST_DIR}/RivGridPartMgr.h
${CMAKE_CURRENT_LIST_DIR}/RivTernarySaturationOverlayItem.h
${CMAKE_CURRENT_LIST_DIR}/RivReservoirPartMgr.h
${CMAKE_CURRENT_LIST_DIR}/RivReservoirViewPartMgr.h
${CMAKE_CURRENT_LIST_DIR}/RivPipeGeometryGenerator.h
${CMAKE_CURRENT_LIST_DIR}/RivReservoirFaultsPartMgr.h
${CMAKE_CURRENT_LIST_DIR}/RivReservoirSimWellsPartMgr.h
${CMAKE_CURRENT_LIST_DIR}/RivSourceInfo.h
${CMAKE_CURRENT_LIST_DIR}/RivWellPathSourceInfo.h
@@ -60,16 +57,15 @@ set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RivCellFilterPartMgr.h
${CMAKE_CURRENT_LIST_DIR}/RivDrawableSpheres.h
${CMAKE_CURRENT_LIST_DIR}/RivBoxGeometryGenerator.h
${CMAKE_CURRENT_LIST_DIR}/RivAnnotationTools.h
${CMAKE_CURRENT_LIST_DIR}/RivAnnotationSourceInfo.h
)
set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RivCellEdgeEffectGenerator.cpp
${CMAKE_CURRENT_LIST_DIR}/RivFaultPartMgr.cpp
${CMAKE_CURRENT_LIST_DIR}/RivNNCGeometryGenerator.cpp
${CMAKE_CURRENT_LIST_DIR}/RivFaultGeometryGenerator.cpp
${CMAKE_CURRENT_LIST_DIR}/RivGridPartMgr.cpp
${CMAKE_CURRENT_LIST_DIR}/RivTernarySaturationOverlayItem.cpp
${CMAKE_CURRENT_LIST_DIR}/RivReservoirFaultsPartMgr.cpp
${CMAKE_CURRENT_LIST_DIR}/RivReservoirPartMgr.cpp
${CMAKE_CURRENT_LIST_DIR}/RivReservoirViewPartMgr.cpp
${CMAKE_CURRENT_LIST_DIR}/RivPipeGeometryGenerator.cpp
@@ -119,6 +115,8 @@ set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RivCellFilterPartMgr.cpp
${CMAKE_CURRENT_LIST_DIR}/RivDrawableSpheres.cpp
${CMAKE_CURRENT_LIST_DIR}/RivBoxGeometryGenerator.cpp
${CMAKE_CURRENT_LIST_DIR}/RivAnnotationTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RivAnnotationSourceInfo.cpp
)
list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})

View File

@@ -0,0 +1,23 @@
set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RivFaultGeometryGenerator.h
${CMAKE_CURRENT_LIST_DIR}/RivFaultPartMgr.h
${CMAKE_CURRENT_LIST_DIR}/RivReservoirFaultsPartMgr.h
${CMAKE_CURRENT_LIST_DIR}/RivFaultReactivationModelPartMgr.h
)
set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RivFaultGeometryGenerator.cpp
${CMAKE_CURRENT_LIST_DIR}/RivFaultPartMgr.cpp
${CMAKE_CURRENT_LIST_DIR}/RivReservoirFaultsPartMgr.cpp
${CMAKE_CURRENT_LIST_DIR}/RivFaultReactivationModelPartMgr.cpp
)
list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})
list(APPEND CODE_SOURCE_FILES ${SOURCE_GROUP_SOURCE_FILES})
source_group(
"ModelVisualization\\Faults"
FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES}
${CMAKE_CURRENT_LIST_DIR}/CMakeLists_files.cmake
)

View File

@@ -80,7 +80,7 @@ cvf::ref<cvf::DrawableGeo> RivFaultGeometryGenerator::generateSurface( bool only
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::DrawableGeo> RivFaultGeometryGenerator::createMeshDrawable()
{
if ( !( m_vertices.notNull() && m_vertices->size() != 0 ) ) return nullptr;
if ( !m_vertices.notNull() || m_vertices->size() == 0 ) return nullptr;
cvf::ref<cvf::DrawableGeo> geo = new cvf::DrawableGeo;
geo->setVertexArray( m_vertices.p() );
@@ -99,7 +99,7 @@ cvf::ref<cvf::DrawableGeo> RivFaultGeometryGenerator::createMeshDrawable()
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::DrawableGeo> RivFaultGeometryGenerator::createOutlineMeshDrawable( double creaseAngle )
{
if ( !( m_vertices.notNull() && m_vertices->size() != 0 ) ) return nullptr;
if ( !m_vertices.notNull() || m_vertices->size() == 0 ) return nullptr;
cvf::OutlineEdgeExtractor ee( creaseAngle, *m_vertices );

View File

@@ -104,7 +104,7 @@ void RivFaultPartMgr::setCellVisibility( cvf::UByteArray* cellVisibilities )
void RivFaultPartMgr::applySingleColorEffect()
{
m_defaultColor = m_rimFault->faultColor();
this->updatePartEffect();
updatePartEffect();
}
//--------------------------------------------------------------------------------------------------
@@ -137,7 +137,7 @@ void RivFaultPartMgr::updateCellResultColor( size_t timeStepIndex, RimEclipseCel
m_nativeFaultFacesTextureCoords.p(),
mapper,
m_opacityLevel,
this->faceCullingMode(),
faceCullingMode(),
eclipseView->isLightingDisabled() );
}
else
@@ -159,7 +159,7 @@ void RivFaultPartMgr::updateCellResultColor( size_t timeStepIndex, RimEclipseCel
m_nativeFaultFacesTextureCoords.p(),
mapper,
m_opacityLevel,
this->faceCullingMode(),
faceCullingMode(),
eclipseView->isLightingDisabled() );
}
}
@@ -182,7 +182,7 @@ void RivFaultPartMgr::updateCellResultColor( size_t timeStepIndex, RimEclipseCel
m_oppositeFaultFacesTextureCoords.p(),
mapper,
m_opacityLevel,
this->faceCullingMode(),
faceCullingMode(),
eclipseView->isLightingDisabled() );
}
else
@@ -204,7 +204,7 @@ void RivFaultPartMgr::updateCellResultColor( size_t timeStepIndex, RimEclipseCel
m_oppositeFaultFacesTextureCoords.p(),
mapper,
m_opacityLevel,
this->faceCullingMode(),
faceCullingMode(),
eclipseView->isLightingDisabled() );
}
}
@@ -232,7 +232,7 @@ void RivFaultPartMgr::updateCellEdgeResultColor( size_t timeStepI
cellEdgeResultColors,
m_opacityLevel,
m_defaultColor,
this->faceCullingMode(),
faceCullingMode(),
cellResultColors->reservoirView()->isLightingDisabled() );
m_nativeFaultFaces->setEffect( eff.p() );
@@ -252,7 +252,7 @@ void RivFaultPartMgr::updateCellEdgeResultColor( size_t timeStepI
cellEdgeResultColors,
m_opacityLevel,
m_defaultColor,
this->faceCullingMode(),
faceCullingMode(),
cellResultColors->reservoirView()->isLightingDisabled() );
m_oppositeFaultFaces->setEffect( eff.p() );
@@ -581,36 +581,24 @@ void RivFaultPartMgr::createLabelWithAnchorLine( const cvf::Part* part )
cvf::Font* font = app->defaultWellLabelFont();
cvf::ref<cvf::DrawableText> drawableText = new cvf::DrawableText;
drawableText->setFont( font );
drawableText->setCheckPosVisible( false );
drawableText->setDrawBorder( false );
drawableText->setDrawBackground( false );
drawableText->setVerticalAlignment( cvf::TextDrawer::CENTER );
cvf::Color3f defWellLabelColor = app->preferences()->defaultWellLabelColor();
{
auto parentObject = m_rimFault->firstAncestorOrThisOfType<RimFaultInViewCollection>();
if ( parentObject )
{
auto parentObject = m_rimFault->firstAncestorOrThisOfType<RimFaultInViewCollection>();
if ( parentObject )
{
defWellLabelColor = parentObject->faultLabelColor();
}
defWellLabelColor = parentObject->faultLabelColor();
}
}
drawableText->setTextColor( defWellLabelColor );
cvf::String cvfString = cvfqt::Utils::toString( m_rimFault->name() );
cvf::Vec3f textCoord( labelPosition );
double characteristicCellSize = bb.extent().z() / 20;
textCoord.z() += characteristicCellSize;
drawableText->addText( cvfString, textCoord );
auto drawableText =
RivAnnotationTools::createDrawableTextNoBackground( font, defWellLabelColor, m_rimFault->name().toStdString(), textCoord );
cvf::ref<cvf::Part> labelPart = new cvf::Part;
labelPart->setName( "RivFaultPart : text " + cvfString );
labelPart->setName( "RivFaultPart : text " + m_rimFault->name().toStdString() );
labelPart->setDrawable( drawableText.p() );
cvf::ref<cvf::Effect> eff = new cvf::Effect;
@@ -618,7 +606,7 @@ void RivFaultPartMgr::createLabelWithAnchorLine( const cvf::Part* part )
labelPart->setEffect( eff.p() );
labelPart->setPriority( RivPartPriority::PartType::Text );
labelPart->setSourceInfo( new RivTextLabelSourceInfo( m_rimFault, cvfString, textCoord ) );
labelPart->setSourceInfo( new RivTextLabelSourceInfo( m_rimFault, m_rimFault->name().toStdString(), textCoord ) );
m_faultLabelPart = labelPart;
}

View File

@@ -0,0 +1,147 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2023 Equinor ASA
//
// 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 "RivFaultReactivationModelPartMgr.h"
#include "RiaGuiApplication.h"
#include "RigBasicPlane.h"
#include "RigFaultReactivationModel.h"
#include "RivPartPriority.h"
#include "RivPolylineGenerator.h"
#include "RivPolylinePartMgr.h"
#include "Rim3dView.h"
#include "RimFaultReactivationModel.h"
#include "cafDisplayCoordTransform.h"
#include "cafEffectGenerator.h"
#include "cafPdmObject.h"
#include "cvfLibCore.h"
#include "cvfLibGeometry.h"
#include "cvfLibRender.h"
#include "cvfModelBasicList.h"
#include "cvfPart.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RivFaultReactivationModelPartMgr::RivFaultReactivationModelPartMgr( RimFaultReactivationModel* frm )
: m_frm( frm )
{
CVF_ASSERT( frm );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivFaultReactivationModelPartMgr::appendPolylinePartsToModel( Rim3dView* view,
cvf::ModelBasicList* vizModel,
const caf::DisplayCoordTransform* transform,
const cvf::BoundingBox& boundingBox )
{
if ( m_polylinePartMgr.isNull() ) m_polylinePartMgr = new RivPolylinePartMgr( view, m_frm.p(), m_frm.p() );
m_polylinePartMgr->appendDynamicGeometryPartsToModel( vizModel, transform, boundingBox );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivFaultReactivationModelPartMgr::appendMeshPartsToModel( Rim3dView* view,
cvf::ModelBasicList* vizModel,
const caf::DisplayCoordTransform* transform,
const cvf::BoundingBox& boundingBox )
{
auto model2d = m_frm->model();
if ( model2d.notNull() && model2d->isValid() && m_frm->isChecked() && m_frm->showModel() )
{
for ( auto gridPart : m_frm->model()->allGridParts() )
{
auto& lines = m_frm->model()->meshLines( gridPart );
std::vector<std::vector<cvf::Vec3d>> displayPoints;
for ( const auto& pts : lines )
{
displayPoints.push_back( transform->transformToDisplayCoords( pts ) );
}
cvf::ref<cvf::DrawableGeo> drawableGeo = RivPolylineGenerator::createSetOfLines( displayPoints );
cvf::ref<cvf::Part> part = new cvf::Part;
part->setName( "FaultReactMeshLines" );
part->setDrawable( drawableGeo.p() );
caf::MeshEffectGenerator effgen( cvf::Color3::LIGHT_GRAY );
effgen.setLineWidth( 1.5 );
effgen.setLineStipple( false );
cvf::ref<cvf::Effect> eff = effgen.generateCachedEffect();
part->setEffect( eff.p() );
part->setPriority( RivPartPriority::PartType::MeshLines );
vizModel->addPart( part.p() );
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivFaultReactivationModelPartMgr::appendGeometryPartsToModel( cvf::ModelBasicList* vizModel,
const caf::DisplayCoordTransform* displayCoordTransform,
const cvf::BoundingBox& boundingBox )
{
if ( !m_canUseShaders ) return;
auto plane = m_frm->faultPlane();
if ( plane->isValid() && m_frm->showFaultPlane() )
{
cvf::Vec3dArray displayPoints;
displayPoints.reserve( plane->rect().size() );
for ( auto& vOrg : plane->rect() )
{
displayPoints.add( displayCoordTransform->transformToDisplayCoord( vOrg ) );
}
cvf::ref<cvf::Part> quadPart = createSingleTexturedQuadPart( displayPoints, plane->texture(), false );
vizModel->addPart( quadPart.p() );
}
auto theModel = m_frm->model();
if ( theModel->isValid() && m_frm->showModel() )
{
for ( auto part : theModel->allModelParts() )
{
cvf::Vec3dArray displayPoints;
displayPoints.reserve( theModel->rect( part ).size() );
for ( auto& vOrg : theModel->rect( part ) )
{
displayPoints.add( displayCoordTransform->transformToDisplayCoord( vOrg ) );
}
cvf::ref<cvf::Part> quadPart = createSingleTexturedQuadPart( displayPoints, theModel->texture( part ), false );
vizModel->addPart( quadPart.p() );
}
}
}

View File

@@ -0,0 +1,67 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2023 Equinor ASA
//
// 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 "RivTexturePartMgr.h"
#include "cafPdmPointer.h"
#include "cvfArray.h"
#include "cvfObject.h"
namespace cvf
{
class ModelBasicList;
class Part;
class DrawableGeo;
class BoundingBox;
class TextureImage;
} // namespace cvf
namespace caf
{
class DisplayCoordTransform;
}
class RimFaultReactivationModel;
class Rim3dView;
class RivPolylinePartMgr;
class RivFaultReactivationModelPartMgr : public RivTexturePartMgr
{
public:
explicit RivFaultReactivationModelPartMgr( RimFaultReactivationModel* frm );
void appendGeometryPartsToModel( cvf::ModelBasicList* vizModel,
const caf::DisplayCoordTransform* displayCoordTransform,
const cvf::BoundingBox& boundingBox ) override;
void appendPolylinePartsToModel( Rim3dView* view,
cvf::ModelBasicList* vizModel,
const caf::DisplayCoordTransform* displayCoordTransform,
const cvf::BoundingBox& boundingBox ) override;
void appendMeshPartsToModel( Rim3dView* view,
cvf::ModelBasicList* vizModel,
const caf::DisplayCoordTransform* displayCoordTransform,
const cvf::BoundingBox& boundingBox );
private:
caf::PdmPointer<RimFaultReactivationModel> m_frm;
cvf::ref<RivPolylinePartMgr> m_polylinePartMgr;
};

View File

@@ -364,9 +364,9 @@ void RivGridBoxGenerator::createGridBoxFaceParts()
m_gridBoxFaceParts.clear();
CVF_ASSERT( m_displayCoordsBoundingBox.isValid() );
CVF_ASSERT( m_displayCoordsXValues.size() > 0 );
CVF_ASSERT( m_displayCoordsYValues.size() > 0 );
CVF_ASSERT( m_displayCoordsZValues.size() > 0 );
CVF_ASSERT( !m_displayCoordsXValues.empty() );
CVF_ASSERT( !m_displayCoordsYValues.empty() );
CVF_ASSERT( !m_displayCoordsZValues.empty() );
cvf::Vec3d min = m_displayCoordsBoundingBox.min();
cvf::Vec3d max = m_displayCoordsBoundingBox.max();
@@ -456,9 +456,9 @@ void RivGridBoxGenerator::createGridBoxLegendParts()
m_gridBoxLegendParts.clear();
CVF_ASSERT( m_displayCoordsBoundingBox.isValid() );
CVF_ASSERT( m_displayCoordsXValues.size() > 0 );
CVF_ASSERT( m_displayCoordsYValues.size() > 0 );
CVF_ASSERT( m_displayCoordsZValues.size() > 0 );
CVF_ASSERT( !m_displayCoordsXValues.empty() );
CVF_ASSERT( !m_displayCoordsYValues.empty() );
CVF_ASSERT( !m_displayCoordsZValues.empty() );
for ( int edge = POS_Z_POS_X; edge <= NEG_X_NEG_Y; edge++ )
{

View File

@@ -67,8 +67,8 @@ void RivPatchGenerator::setSubdivisions( const std::vector<double>& uValues, con
//--------------------------------------------------------------------------------------------------
void RivPatchGenerator::generate( cvf::GeometryBuilder* builder )
{
CVF_ASSERT( m_uValues.size() > 0 );
CVF_ASSERT( m_vValues.size() > 0 );
CVF_ASSERT( !m_uValues.empty() );
CVF_ASSERT( !m_vValues.empty() );
size_t numVertices = m_uValues.size() * m_vValues.size();

View File

@@ -57,14 +57,7 @@ RivBoxIntersectionGeometryGenerator::~RivBoxIntersectionGeometryGenerator()
//--------------------------------------------------------------------------------------------------
bool RivBoxIntersectionGeometryGenerator::isAnyGeometryPresent() const
{
if ( m_triangleVxes->size() == 0 )
{
return false;
}
else
{
return true;
}
return m_triangleVxes->size() != 0;
}
//--------------------------------------------------------------------------------------------------
@@ -89,7 +82,7 @@ cvf::ref<cvf::DrawableGeo> RivBoxIntersectionGeometryGenerator::generateSurface(
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::DrawableGeo> RivBoxIntersectionGeometryGenerator::createMeshDrawable()
{
if ( !( m_cellBorderLineVxes.notNull() && m_cellBorderLineVxes->size() != 0 ) ) return nullptr;
if ( !m_cellBorderLineVxes.notNull() || m_cellBorderLineVxes->size() == 0 ) return nullptr;
cvf::ref<cvf::DrawableGeo> geo = new cvf::DrawableGeo;
geo->setVertexArray( m_cellBorderLineVxes.p() );

View File

@@ -75,7 +75,7 @@ RivBoxIntersectionPartMgr::RivBoxIntersectionPartMgr( RimBoxIntersection* inters
void RivBoxIntersectionPartMgr::applySingleColorEffect()
{
m_defaultColor = cvf::Color3f::OLIVE; // m_rimCrossSection->CrossSectionColor();
this->updatePartEffect();
updatePartEffect();
}
//--------------------------------------------------------------------------------------------------

View File

@@ -68,7 +68,7 @@ bool RivEclipseIntersectionGrid::useCell( size_t cellIndex ) const
{
const RigCell& cell = m_mainGrid->globalCellArray()[cellIndex];
if ( m_showInactiveCells )
return !( cell.isInvalid() || ( cell.subGrid() != nullptr ) );
return !cell.isInvalid() && ( cell.subGrid() == nullptr );
else
return m_activeCellInfo->isActive( cellIndex ) && ( cell.subGrid() == nullptr );
}

View File

@@ -23,7 +23,6 @@
#include "RigResultAccessor.h"
#include "RigSurface.h"
#include "RigSurfaceResampler.h"
#include "RigWellPath.h"
#include "Rim3dView.h"
#include "RimCase.h"
@@ -188,15 +187,15 @@ void RivExtrudedCurveIntersectionGeometryGenerator::calculateSurfaceIntersection
// Resample polyline to required resolution
const double maxLineSegmentLength = 1.0;
auto resampledPolyline = computeResampledPolyline( firstPolyLine, maxLineSegmentLength );
const auto resampledPolyline = RigSurfaceResampler::computeResampledPolylineWithSegmentInfo( firstPolyLine, maxLineSegmentLength );
for ( auto [point, segmentIndex] : resampledPolyline )
for ( const auto& [point, segmentIndex] : resampledPolyline )
{
cvf::Vec3d pointAbove = cvf::Vec3d( point.x(), point.y(), 10000.0 );
cvf::Vec3d pointBelow = cvf::Vec3d( point.x(), point.y(), -10000.0 );
cvf::Vec3d intersectionPoint;
bool foundMatch = RigSurfaceResampler::resamplePoint( surface, pointAbove, pointBelow, intersectionPoint );
bool foundMatch = RigSurfaceResampler::findClosestPointOnSurface( surface, pointAbove, pointBelow, intersectionPoint );
if ( foundMatch )
{
const size_t lineIndex = 0;
@@ -638,7 +637,7 @@ cvf::ref<cvf::DrawableGeo> RivExtrudedCurveIntersectionGeometryGenerator::genera
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::DrawableGeo> RivExtrudedCurveIntersectionGeometryGenerator::createMeshDrawable()
{
if ( !( m_cellBorderLineVxes.notNull() && m_cellBorderLineVxes->size() != 0 ) ) return nullptr;
if ( !m_cellBorderLineVxes.notNull() || m_cellBorderLineVxes->size() == 0 ) return nullptr;
cvf::ref<cvf::DrawableGeo> geo = new cvf::DrawableGeo;
geo->setVertexArray( m_cellBorderLineVxes.p() );
@@ -655,7 +654,7 @@ cvf::ref<cvf::DrawableGeo> RivExtrudedCurveIntersectionGeometryGenerator::create
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::DrawableGeo> RivExtrudedCurveIntersectionGeometryGenerator::createFaultMeshDrawable()
{
if ( !( m_faultCellBorderLineVxes.notNull() && m_faultCellBorderLineVxes->size() != 0 ) ) return nullptr;
if ( !m_faultCellBorderLineVxes.notNull() || m_faultCellBorderLineVxes->size() == 0 ) return nullptr;
cvf::ref<cvf::DrawableGeo> geo = new cvf::DrawableGeo;
geo->setVertexArray( m_faultCellBorderLineVxes.p() );
@@ -809,58 +808,6 @@ cvf::Vec3d RivExtrudedCurveIntersectionGeometryGenerator::transformPointByPolyli
return domainCoord.getTransformedPoint( m_lineSegmentTransforms[lineIndex][segmentIndex] );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::pair<cvf::Vec3d, size_t>>
RivExtrudedCurveIntersectionGeometryGenerator::computeResampledPolyline( const std::vector<cvf::Vec3d>& polyline, double resamplingDistance )
{
// Segments along the original polyline must be provided to be able to find the associated transform matrix
std::vector<std::pair<cvf::Vec3d, size_t>> resampledPolyline;
if ( polyline.size() > 1 )
{
std::vector<double> measuredDepth;
{
double aggregatedLength = 0.0;
cvf::Vec3d previousPoint = polyline.front();
measuredDepth.push_back( aggregatedLength );
for ( size_t i = 1; i < polyline.size(); i++ )
{
aggregatedLength += ( previousPoint - polyline[i] ).length();
previousPoint = polyline[i];
measuredDepth.push_back( aggregatedLength );
}
}
// Use RigWellPath to perform the interpolation along a line based on measured depth
RigWellPath dummyWellPath( polyline, measuredDepth );
for ( size_t i = 1; i < polyline.size(); i++ )
{
const auto& lineSegmentStart = polyline[i - 1];
const auto& lineSegmentEnd = polyline[i];
auto startMD = measuredDepth[i - 1];
auto endMD = measuredDepth[i];
const size_t segmentIndex = i - 1;
resampledPolyline.emplace_back( lineSegmentStart, segmentIndex );
for ( auto md = startMD + resamplingDistance; md < endMD; md += resamplingDistance )
{
resampledPolyline.emplace_back( dummyWellPath.interpolatedPointAlongWellPath( md ), segmentIndex );
}
resampledPolyline.emplace_back( lineSegmentEnd, segmentIndex );
}
}
return resampledPolyline;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -894,12 +841,7 @@ cvf::Mat4d RivExtrudedCurveIntersectionGeometryGenerator::unflattenTransformMatr
//--------------------------------------------------------------------------------------------------
bool RivExtrudedCurveIntersectionGeometryGenerator::isAnyGeometryPresent() const
{
if ( m_triangleVxes->size() == 0 )
{
return false;
}
return true;
return m_triangleVxes->size() != 0;
}
//--------------------------------------------------------------------------------------------------

View File

@@ -97,9 +97,6 @@ private:
const std::vector<std::vector<cvf::Vec3d>>& flattenedOrOffsettedPolyLines();
cvf::Vec3d transformPointByPolylineSegmentIndex( const cvf::Vec3d& domainCoord, size_t lineIndex, size_t segmentIndex );
static std::vector<std::pair<cvf::Vec3d, size_t>> computeResampledPolyline( const std::vector<cvf::Vec3d>& polyline,
double resamplingDistance );
private:
RimExtrudedCurveIntersection* m_intersection;
cvf::ref<RivIntersectionHexGridInterface> m_hexGrid;

View File

@@ -51,6 +51,7 @@
#include "RiuGeoMechXfTensorResultAccessor.h"
#include "RivAnnotationSourceInfo.h"
#include "RivExtrudedCurveIntersectionGeometryGenerator.h"
#include "RivExtrudedCurveIntersectionSourceInfo.h"
#include "RivIntersectionHexGridInterface.h"
@@ -231,7 +232,7 @@ void RivIntersectionResultsColoringTools::calculateNodeOrElementNodeBasedGeoMech
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivExtrudedCurveIntersectionPartMgr::generatePartGeometry( cvf::UByteArray* visibleCells )
void RivExtrudedCurveIntersectionPartMgr::generatePartGeometry( cvf::UByteArray* visibleCells, cvf::Transform* scaleTransform )
{
if ( m_intersectionGenerator.isNull() ) return;
@@ -324,7 +325,7 @@ void RivExtrudedCurveIntersectionPartMgr::generatePartGeometry( cvf::UByteArray*
applySingleColorEffect();
createAnnotationSurfaceParts( useBufferObjects );
createAnnotationSurfaceParts( useBufferObjects, scaleTransform );
}
//--------------------------------------------------------------------------------------------------
@@ -601,7 +602,7 @@ void RivExtrudedCurveIntersectionPartMgr::createExtrusionDirParts( bool useBuffe
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivExtrudedCurveIntersectionPartMgr::createAnnotationSurfaceParts( bool useBufferObjects )
void RivExtrudedCurveIntersectionPartMgr::createAnnotationSurfaceParts( bool useBufferObjects, cvf::Transform* scaleTransform )
{
m_annotationParts.clear();
@@ -619,9 +620,10 @@ void RivExtrudedCurveIntersectionPartMgr::createAnnotationSurfaceParts( bool use
auto part = createCurvePart( polylines,
useBufferObjects,
surface->userDescription(),
surface->fullName(),
curve->lineAppearance()->color(),
curve->lineAppearance()->thickness() );
curve->lineAppearance()->thickness(),
scaleTransform );
if ( part.notNull() ) m_annotationParts.push_back( part.p() );
}
@@ -645,18 +647,20 @@ void RivExtrudedCurveIntersectionPartMgr::createAnnotationSurfaceParts( bool use
{
auto part = createCurvePart( polylineA,
useBufferObjects,
surface1->userDescription(),
surface1->fullName(),
band->lineAppearance()->color(),
band->lineAppearance()->thickness() );
band->lineAppearance()->thickness(),
scaleTransform );
if ( part.notNull() ) m_annotationParts.push_back( part.p() );
}
{
auto part = createCurvePart( polylineB,
useBufferObjects,
surface2->userDescription(),
surface2->fullName(),
band->lineAppearance()->color(),
band->lineAppearance()->thickness() );
band->lineAppearance()->thickness(),
scaleTransform );
if ( part.notNull() ) m_annotationParts.push_back( part.p() );
}
@@ -730,7 +734,8 @@ cvf::ref<cvf::Part> RivExtrudedCurveIntersectionPartMgr::createCurvePart( const
bool useBufferObjects,
const QString& description,
const cvf::Color3f& color,
float lineWidth )
float lineWidth,
cvf::Transform* scaleTransform )
{
auto polylineGeo = RivPolylineGenerator::createLineAlongPolylineDrawable( polylines );
if ( polylineGeo.notNull() )
@@ -761,6 +766,31 @@ cvf::ref<cvf::Part> RivExtrudedCurveIntersectionPartMgr::createCurvePart( const
eff->setRenderState( polyOffset.p() );
part->setEffect( eff.p() );
if ( part.notNull() && scaleTransform )
{
// The polylines are defined in the display coordinate system without Z-scaling. The z-scaling is applied to the visualization
// parts using Part::setTransform(Transform* transform)
// The annotation objects are defined by display coordinates, so apply the Z-scaling to the coordinates
std::vector<cvf::Vec3d> displayCoords;
const auto& mat = scaleTransform->worldTransform();
for ( const auto& p : polylines )
{
displayCoords.push_back( p.getTransformedPoint( mat ) );
}
// Add annotation info to be used to display label in Rim3dView::onViewNavigationChanged()
// Set the source info on one part only, as this data is only used for display of labels
auto annoObj = new RivAnnotationSourceInfo( description.toStdString(), displayCoords );
annoObj->setLabelPositionStrategyHint( RivAnnotationTools::LabelPositionStrategy::RIGHT );
annoObj->setShowColor( true );
annoObj->setColor( color );
part->setSourceInfo( annoObj );
}
return part;
}

View File

@@ -81,19 +81,20 @@ public:
const RivIntersectionGeometryGeneratorInterface* intersectionGeometryGenerator() const;
void generatePartGeometry( cvf::UByteArray* visibleCells );
void generatePartGeometry( cvf::UByteArray* visibleCells, cvf::Transform* scaleTransfor );
private:
void createFaultLabelParts( const std::vector<std::pair<QString, cvf::Vec3d>>& labelAndAnchors );
void createPolyLineParts( bool useBufferObjects );
void createExtrusionDirParts( bool useBufferObjects );
void createAnnotationSurfaceParts( bool useBufferObjects );
void createAnnotationSurfaceParts( bool useBufferObjects, cvf::Transform* scaleTransform );
cvf::ref<cvf::Part> createCurvePart( const std::vector<cvf::Vec3d>& polylines,
bool useBufferObjects,
const QString& description,
const cvf::Color3f& color,
float lineWidth );
float lineWidth,
cvf::Transform* scaleTransform );
private:
caf::PdmPointer<RimExtrudedCurveIntersection> m_rimIntersection;

View File

@@ -110,7 +110,7 @@ void RivFemIntersectionGrid::cellCornerIndices( size_t globalCellIndex, size_t c
auto [part, elementIdx] = m_femParts->partAndElementIndex( globalCellIndex );
RigElementType elmType = part->elementType( elementIdx );
if ( !( elmType == HEX8 || elmType == HEX8P ) ) return;
if ( elmType != HEX8 && elmType != HEX8P ) return;
int elmIdx = static_cast<int>( elementIdx );
const int partId = part->elementPartId();

View File

@@ -32,6 +32,7 @@
#include "RimRegularLegendConfig.h"
#include "RimTernaryLegendConfig.h"
#include "RigFemAddressDefines.h"
#include "RigFemPartCollection.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
@@ -223,12 +224,8 @@ void RivIntersectionResultsColoringTools::updateGeoMechCellResultColors( const R
cvf::Part* intersectionFacesPart,
cvf::Vec2fArray* intersectionFacesTextureCoords )
{
RigGeoMechCaseData* caseData = nullptr;
RigFemResultAddress resVarAddress;
{
caseData = geomResultDef->ownerCaseData();
resVarAddress = geomResultDef->resultAddress();
}
RigGeoMechCaseData* caseData = geomResultDef->ownerCaseData();
RigFemResultAddress resVarAddress = RigFemAddressDefines::getResultLookupAddress( geomResultDef->resultAddress() );
if ( !caseData ) return;
@@ -291,12 +288,6 @@ void RivIntersectionResultsColoringTools::updateGeoMechCellResultColors( const R
}
else
{
// Do a "Hack" to show elm nodal and not nodal POR results
if ( resVarAddress.resultPosType == RIG_NODAL && resVarAddress.fieldName == "POR-Bar" )
{
resVarAddress.resultPosType = RIG_ELEMENT_NODAL;
}
bool isElementNodalResult = !( resVarAddress.resultPosType == RIG_NODAL );
if ( caseData->femPartResults()->partCount() == 1 )
@@ -377,7 +368,7 @@ void RivIntersectionResultsColoringTools::calculateElementBasedGeoMechTextureCoo
{
textureCoords->resize( triangleToCellIdx.size() * 3 );
if ( resultValues.size() == 0 )
if ( resultValues.empty() )
{
textureCoords->setAll( cvf::Vec2f( 0.0, 1.0f ) );
}

View File

@@ -273,9 +273,7 @@ bool Riv3dWellLogCurveGeometryGenerator::findClosestPointOnCurve( const cvf::Vec
}
}
if ( closestPoint->isUndefined() ) return false;
return true;
return !closestPoint->isUndefined();
}
//--------------------------------------------------------------------------------------------------

View File

@@ -86,15 +86,17 @@ bool Riv3dWellLogDrawSurfaceGenerator::createDrawSurface( const caf::DisplayCoor
size_t indexToFirstVisibleSegment = 0u;
if ( wellPathCollection->wellPathClip )
{
double clipZDistance = wellPathCollection->wellPathClipZDistance;
cvf::Vec3d clipLocation = wellPathClipBoundingBox.max() + clipZDistance * cvf::Vec3d( 0, 0, 1 );
clipLocation = displayCoordTransform->transformToDisplayCoord( clipLocation );
double horizontalLengthAlongWellToClipPoint;
double clipZDistance = wellPathCollection->wellPathClipZDistance;
cvf::Vec3d clipLocation = wellPathClipBoundingBox.max() + clipZDistance * cvf::Vec3d::Z_AXIS;
auto clipLocationDisplay = displayCoordTransform->transformToDisplayCoord( clipLocation );
double horizontalLengthAlongWellToClipPoint = 0.0;
double measuredDepthAtFirstClipPoint = 0.0;
wellPathDisplayCoords = RigWellPath::clipPolylineStartAboveZ( wellPathDisplayCoords,
clipLocation.z(),
&horizontalLengthAlongWellToClipPoint,
&indexToFirstVisibleSegment );
clipLocationDisplay.z(),
horizontalLengthAlongWellToClipPoint,
measuredDepthAtFirstClipPoint,
indexToFirstVisibleSegment );
}
// Create curve normal vectors using the unclipped well path points and normals.

View File

@@ -173,7 +173,7 @@ double Riv3dWellLogPlanePartMgr::wellPathCenterToPlotStartOffset( Rim3dWellLogCu
}
else
{
double cellSize = m_gridView->ownerCase()->characteristicCellSize();
double cellSize = m_gridView->characteristicCellSize();
double wellPathOffset = std::min( m_wellPath->wellPathRadius( cellSize ), 0.1 * planeWidth() );
return m_wellPath->wellPathRadius( cellSize ) + wellPathOffset;
}
@@ -186,7 +186,7 @@ double Riv3dWellLogPlanePartMgr::planeWidth() const
{
if ( !m_gridView ) return 0;
double cellSize = m_gridView->ownerCase()->characteristicCellSize();
double cellSize = m_gridView->characteristicCellSize();
const Rim3dWellLogCurveCollection* curveCollection = m_wellPath->rim3dWellLogCurveCollection();
return cellSize * curveCollection->planeWidthScaling();
}

View File

@@ -0,0 +1,115 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2023- Equinor ASA
//
// 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 "RivAnnotationSourceInfo.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RivAnnotationSourceInfo::RivAnnotationSourceInfo( const std::string& text, const std::vector<cvf::Vec3d>& displayCoords )
: m_text( text )
, m_showColor( false )
, m_color( cvf::Color3f( cvf::Color3f::BLACK ) )
, m_labelPositionHint( RivAnnotationTools::LabelPositionStrategy::RIGHT )
, m_anchorPointsInDisplayCoords( displayCoords )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RivAnnotationSourceInfo::RivAnnotationSourceInfo( const std::vector<std::string>& texts, const std::vector<cvf::Vec3d>& displayCoords )
: m_showColor( false )
, m_color( cvf::Color3f( cvf::Color3f::BLACK ) )
, m_labelPositionHint( RivAnnotationTools::LabelPositionStrategy::COUNT_HINT )
, m_anchorPointsInDisplayCoords( displayCoords )
, m_texts( texts )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RivAnnotationTools::LabelPositionStrategy RivAnnotationSourceInfo::labelPositionStrategyHint() const
{
return m_labelPositionHint;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivAnnotationSourceInfo::setLabelPositionStrategyHint( RivAnnotationTools::LabelPositionStrategy strategy )
{
m_labelPositionHint = strategy;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::string RivAnnotationSourceInfo::text() const
{
return m_text;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::string> RivAnnotationSourceInfo::texts() const
{
return m_texts;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3d> RivAnnotationSourceInfo::anchorPointsInDisplayCoords() const
{
return m_anchorPointsInDisplayCoords;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RivAnnotationSourceInfo::showColor() const
{
return m_showColor;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivAnnotationSourceInfo::setShowColor( bool showColor )
{
m_showColor = showColor;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Color3f RivAnnotationSourceInfo::color() const
{
return m_color;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivAnnotationSourceInfo::setColor( const cvf::Color3f& color )
{
m_color = color;
}

View File

@@ -0,0 +1,60 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2023- Equinor ASA
//
// 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 "RivAnnotationTools.h"
#include "cvfObject.h"
#include "cvfVector3.h"
//==================================================================================================
///
///
//==================================================================================================
class RivAnnotationSourceInfo : public cvf::Object
{
public:
// Construct an object used to display a single text that can be positioned at several candidate positions. Can be used to display a
// label for a long and narrow structure like a surface intersection line.
RivAnnotationSourceInfo( const std::string& text, const std::vector<cvf::Vec3d>& displayCoords );
// Construct an object used to display a text at a single position. Can be used to display measured depth as labels along a well path.
RivAnnotationSourceInfo( const std::vector<std::string>& texts, const std::vector<cvf::Vec3d>& displayCoords );
RivAnnotationTools::LabelPositionStrategy labelPositionStrategyHint() const;
void setLabelPositionStrategyHint( RivAnnotationTools::LabelPositionStrategy strategy );
std::string text() const;
std::vector<std::string> texts() const;
std::vector<cvf::Vec3d> anchorPointsInDisplayCoords() const;
bool showColor() const;
void setShowColor( bool showColor );
cvf::Color3f color() const;
void setColor( const cvf::Color3f& color );
private:
std::string m_text;
bool m_showColor;
cvf::Color3f m_color;
RivAnnotationTools::LabelPositionStrategy m_labelPositionHint;
std::vector<cvf::Vec3d> m_anchorPointsInDisplayCoords;
std::vector<std::string> m_texts;
};

View File

@@ -0,0 +1,425 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2023 Equinor ASA
//
// 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 "RivAnnotationTools.h"
#include "RiaColorTools.h"
#include "RiaFontCache.h"
#include "RivAnnotationSourceInfo.h"
#include "RivObjectSourceInfo.h"
#include "RivPartPriority.h"
#include "RivPolylineGenerator.h"
#include "cafAppEnum.h"
#include "cafEffectGenerator.h"
#include "cvfCamera.h"
#include "cvfDrawableGeo.h"
#include "cvfDrawableText.h"
#include "cvfModelBasicList.h"
#include "cvfPart.h"
#include "cvfViewport.h"
#include <algorithm>
#include <cmath>
#include <optional>
namespace caf
{
template <>
void caf::AppEnum<RivAnnotationTools::LabelPositionStrategy>::setUp()
{
addItem( RivAnnotationTools::LabelPositionStrategy::LEFT, "LEFT", "Left" );
addItem( RivAnnotationTools::LabelPositionStrategy::RIGHT, "RIGHT", "Right" );
addItem( RivAnnotationTools::LabelPositionStrategy::LEFT_AND_RIGHT, "LEFT_AND_RIGHT", "Left and Right" );
addItem( RivAnnotationTools::LabelPositionStrategy::COUNT_HINT, "COUNT_HINT", "Count Hint" );
addItem( RivAnnotationTools::LabelPositionStrategy::ALL, "All", "All" );
addItem( RivAnnotationTools::LabelPositionStrategy::NONE, "None", "Disabled" );
// RivAnnotationTools::LabelPositionStrategy::UNKNOWN is not included, as this is enum is not supposed to be displayed in GUI
setDefault( RivAnnotationTools::LabelPositionStrategy::RIGHT );
}
} // End namespace caf
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RivAnnotationTools::RivAnnotationTools()
: m_overrideStrategy( RivAnnotationTools::LabelPositionStrategy::UNDEFINED )
, m_labelCountHint( 5 )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivAnnotationTools::setOverrideLabelPositionStrategy( LabelPositionStrategy strategy )
{
// By default, each annotation object has a label position strategy. Use this method to override the default.
m_overrideStrategy = strategy;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivAnnotationTools::setCountHint( int countHint )
{
m_labelCountHint = countHint;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::Part> RivAnnotationTools::createPartFromPolyline( const cvf::Color3f& color, const std::vector<cvf::Vec3d>& polyLine )
{
cvf::ref<cvf::DrawableGeo> drawableGeo = RivPolylineGenerator::createLineAlongPolylineDrawable( polyLine );
if ( drawableGeo.isNull() ) return nullptr;
cvf::ref<cvf::Part> part = new cvf::Part;
part->setDrawable( drawableGeo.p() );
caf::MeshEffectGenerator colorEffgen( color );
cvf::ref<cvf::Effect> eff = colorEffgen.generateCachedEffect();
part->setEffect( eff.p() );
part->setPriority( RivPartPriority::PartType::MeshLines );
return part;
}
struct LabelTextAndPosition
{
std::string label;
cvf::Vec3d labelPosition;
cvf::Vec3d lineAnchorPosition;
};
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
auto computeScalingFactorFromZoom = []( const cvf::Camera* camera ) -> double
{
double scalingFactor = 1.0;
if ( camera )
{
auto viewPort = camera->viewport();
cvf::Vec3d vpCorner1( 0, viewPort->height(), 0 );
cvf::Vec3d vpCorner2( viewPort->width(), 0, 0 );
bool unprojOk = true;
cvf::Vec3d corner1Display, corner2Display, e1;
unprojOk &= camera->unproject( vpCorner1, &corner1Display );
unprojOk &= camera->unproject( vpCorner2, &corner2Display );
if ( unprojOk )
{
scalingFactor = 10 * ( corner1Display - corner2Display ).length();
}
}
return scalingFactor;
};
//--------------------------------------------------------------------------------------------------
/// Project candidate coordinates to screen space, and compare with the normalized viewport position. Create a label item for the closest
/// coordinate.
//--------------------------------------------------------------------------------------------------
auto createLabelForClosestCoordinate = []( const cvf::Camera* camera,
const RivAnnotationSourceInfo* annotationObject,
const double viewportWidth,
const double normalizedXPosition,
const double anchorLineScalingFactor ) -> std::optional<LabelTextAndPosition>
{
if ( !camera || !annotationObject ) return std::nullopt;
cvf::Vec3d anchorPosition;
double smallestDistance = std::numeric_limits<double>::max();
for ( const auto& displayCoord : annotationObject->anchorPointsInDisplayCoords() )
{
cvf::Vec3d screenCoord;
camera->project( displayCoord, &screenCoord );
double horizontalDistance = std::fabs( normalizedXPosition * viewportWidth - screenCoord.x() );
if ( horizontalDistance < smallestDistance )
{
smallestDistance = horizontalDistance;
anchorPosition = displayCoord;
}
}
if ( smallestDistance == std::numeric_limits<double>::max() ) return std::nullopt;
const cvf::Vec3d directionPointToCam = ( camera->position() - anchorPosition ).getNormalized();
cvf::Vec3d labelPosition = anchorPosition + directionPointToCam * anchorLineScalingFactor;
const double maxScreenSpaceAdjustment = viewportWidth * 0.05;
if ( smallestDistance < maxScreenSpaceAdjustment )
{
// Establish a fixed horizontal anchor point for the label in screen coordinates. Achieved through conversion to screen coordinates,
// adjusting the x-coordinate, and then reverting to display coordinates.
cvf::Vec3d screenCoord;
camera->project( labelPosition, &screenCoord );
screenCoord.x() = normalizedXPosition * viewportWidth;
camera->unproject( screenCoord, &labelPosition );
}
LabelTextAndPosition info = { annotationObject->text(), anchorPosition, labelPosition };
return info;
};
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
auto createMultipleLabels = []( const cvf::Camera* camera,
const RivAnnotationSourceInfo* annotationObject,
const double viewportWidth,
const double viewportHeight,
const double anchorLineScalingFactor ) -> std::vector<LabelTextAndPosition>
{
if ( !annotationObject || annotationObject->texts().empty() ) return {};
std::vector<LabelTextAndPosition> labelInfo;
std::vector<cvf::Vec3d> labelCoords;
std::vector<std::string> labelTexts;
const auto candidateCoords = annotationObject->anchorPointsInDisplayCoords();
const auto candidateLabels = annotationObject->texts();
if ( candidateCoords.size() == candidateLabels.size() )
{
for ( size_t i = 0; i < annotationObject->anchorPointsInDisplayCoords().size(); i++ )
{
const auto& displayCoord = candidateCoords[i];
cvf::Vec3d screenCoord;
camera->project( displayCoord, &screenCoord );
if ( screenCoord.x() > 0 && screenCoord.x() < viewportWidth && screenCoord.y() > 0 && screenCoord.y() < viewportHeight )
{
const auto& text = candidateLabels[i];
labelCoords.push_back( displayCoord );
labelTexts.push_back( text );
}
}
for ( size_t i = 0; i < labelCoords.size(); i++ )
{
const cvf::Vec3d lineAnchorPosition = labelCoords[i];
const cvf::Vec3d directionPointToCam = ( camera->position() - lineAnchorPosition ).getNormalized();
const cvf::Vec3d labelPosition = lineAnchorPosition + directionPointToCam * anchorLineScalingFactor;
labelInfo.push_back( { labelTexts[i], lineAnchorPosition, labelPosition } );
}
}
return labelInfo;
};
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivAnnotationTools::addAnnotationLabels( const cvf::Collection<cvf::Part>& partCollection,
const cvf::Camera* camera,
cvf::ModelBasicList* model,
bool computeScalingFactor )
{
if ( !camera || !model ) return;
// The scaling factor is computed using the camera, and this does not work for the flat intersection view
const double anchorLineScalingFactor = computeScalingFactor ? computeScalingFactorFromZoom( camera ) : 1.0;
for ( auto p : partCollection )
{
auto annotationObject = dynamic_cast<RivAnnotationSourceInfo*>( p->sourceInfo() );
if ( annotationObject )
{
std::vector<LabelTextAndPosition> labels;
const auto viewportWidth = camera->viewport()->width();
const auto viewportHeight = camera->viewport()->height();
if ( !annotationObject->texts().empty() )
{
labels = createMultipleLabels( camera, annotationObject, viewportWidth, viewportHeight, anchorLineScalingFactor );
}
else
{
auto strategy = annotationObject->labelPositionStrategyHint();
if ( m_overrideStrategy != LabelPositionStrategy::UNDEFINED )
{
// Can override annotation object strategy defined in Rim3dView::updateScreenSpaceModel()
strategy = m_overrideStrategy;
}
if ( strategy == LabelPositionStrategy::RIGHT || strategy == LabelPositionStrategy::LEFT_AND_RIGHT )
{
// Close to the right edge of the visible screen area
const auto normalizedXPosition = 0.9;
auto labelCandidate =
createLabelForClosestCoordinate( camera, annotationObject, viewportWidth, normalizedXPosition, anchorLineScalingFactor );
if ( labelCandidate.has_value() ) labels.push_back( labelCandidate.value() );
}
if ( strategy == LabelPositionStrategy::LEFT || strategy == LabelPositionStrategy::LEFT_AND_RIGHT )
{
// Close to the left edge of the visible screen area
const auto normalizedXPosition = 0.1;
auto labelCandidate =
createLabelForClosestCoordinate( camera, annotationObject, viewportWidth, normalizedXPosition, anchorLineScalingFactor );
if ( labelCandidate.has_value() ) labels.push_back( labelCandidate.value() );
}
if ( strategy == LabelPositionStrategy::COUNT_HINT || strategy == LabelPositionStrategy::ALL )
{
std::vector<cvf::Vec3d> visibleCoords;
for ( const auto& v : annotationObject->anchorPointsInDisplayCoords() )
{
cvf::Vec3d screenCoord;
camera->project( v, &screenCoord );
if ( screenCoord.x() > 0 && screenCoord.x() < viewportWidth && screenCoord.y() > 0 && screenCoord.y() < viewportHeight )
visibleCoords.push_back( v );
}
size_t stride = 1;
if ( strategy == LabelPositionStrategy::COUNT_HINT )
{
stride = std::max( size_t( 1 ), visibleCoords.size() / std::max( 1, m_labelCountHint - 1 ) );
}
for ( size_t i = 0; i < visibleCoords.size(); i += stride )
{
size_t adjustedIndex = std::min( i, visibleCoords.size() - 1 );
const cvf::Vec3d lineAnchorPosition = visibleCoords[adjustedIndex];
const cvf::Vec3d directionPointToCam = ( camera->position() - lineAnchorPosition ).getNormalized();
const cvf::Vec3d labelPosition = lineAnchorPosition + directionPointToCam * anchorLineScalingFactor;
labels.push_back( { annotationObject->text(), lineAnchorPosition, labelPosition } );
}
}
}
for ( const auto& [labelText, lineAnchorPosition, labelPosition] : labels )
{
{
// Line part
std::vector<cvf::Vec3d> points = { lineAnchorPosition, labelPosition };
auto anchorLineColor = cvf::Color3f::BLACK;
auto part = RivAnnotationTools::createPartFromPolyline( anchorLineColor, points );
if ( part.notNull() )
{
part->setName( "AnnotationObjectAnchorPoints" );
model->addPart( part.p() );
}
}
{
// Text part
auto backgroundColor = annotationObject->showColor() ? annotationObject->color() : cvf::Color3f::LIGHT_GRAY;
auto textColor = RiaColorTools::contrastColor( backgroundColor );
auto fontSize = 10;
auto font = RiaFontCache::getFont( fontSize );
auto drawableText = createDrawableText( font.p(), textColor, backgroundColor, labelText, cvf::Vec3f( labelPosition ) );
auto part = createPart( drawableText.p() );
part->setName( "RivAnnotationTools: " + labelText );
model->addPart( part.p() );
}
}
}
}
model->updateBoundingBoxesRecursive();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::DrawableText> RivAnnotationTools::createDrawableText( cvf::Font* font,
const cvf::Color3f& textColor,
const cvf::Color3f& backgroundColor,
const std::string& text,
const cvf::Vec3f& position )
{
auto drawableText = new cvf::DrawableText;
drawableText->setFont( font );
drawableText->setCheckPosVisible( false );
drawableText->setUseDepthBuffer( true );
drawableText->setDrawBorder( true );
drawableText->setDrawBackground( true );
drawableText->setVerticalAlignment( cvf::TextDrawer::BASELINE );
drawableText->setBackgroundColor( backgroundColor );
drawableText->setBorderColor( RiaColorTools::computeOffsetColor( backgroundColor, 0.5f ) );
drawableText->setTextColor( textColor );
drawableText->addText( cvf::String( text ), position );
return drawableText;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::DrawableText> RivAnnotationTools::createDrawableTextNoBackground( cvf::Font* font,
const cvf::Color3f& textColor,
const std::string& text,
const cvf::Vec3f& position )
{
cvf::ref<cvf::DrawableText> drawableText = new cvf::DrawableText;
drawableText->setFont( font );
drawableText->setCheckPosVisible( false );
drawableText->setDrawBorder( false );
drawableText->setDrawBackground( false );
drawableText->setVerticalAlignment( cvf::TextDrawer::CENTER );
drawableText->setTextColor( textColor );
drawableText->addText( cvf::String( text ), position );
return drawableText;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::Part> RivAnnotationTools::createPart( cvf::DrawableText* drawableText )
{
auto part = new cvf::Part;
part->setDrawable( drawableText );
auto eff = new cvf::Effect();
part->setEffect( eff );
part->setPriority( RivPartPriority::PartType::Text );
return part;
}

View File

@@ -0,0 +1,82 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2023 Equinor ASA
//
// 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 "cvfCollection.h"
#include "cvfColor3.h"
#include "cvfObject.h"
#include "cvfVector3.h"
#include <string>
#include <vector>
namespace cvf
{
class Part;
class Camera;
class ModelBasicList;
class DrawableText;
class Font;
} // namespace cvf
class RivAnnotationTools
{
public:
enum class LabelPositionStrategy
{
RIGHT,
LEFT,
LEFT_AND_RIGHT,
COUNT_HINT,
ALL,
NONE,
UNDEFINED
};
RivAnnotationTools();
// By default, each annotation object has a label position strategy. Use this method to override the default.
void setOverrideLabelPositionStrategy( LabelPositionStrategy strategy );
// When using COUNT_HINT, this number is used to determine the number of labels to show.
void setCountHint( int countHint );
// Create labels for the given collection of parts. The labels are added to the given model.
void addAnnotationLabels( const cvf::Collection<cvf::Part>& partCollection,
const cvf::Camera* camera,
cvf::ModelBasicList* model,
bool computeScalingFactor );
static cvf::ref<cvf::Part> createPartFromPolyline( const cvf::Color3f& color, const std::vector<cvf::Vec3d>& polyLine );
static cvf::ref<cvf::DrawableText> createDrawableText( cvf::Font* font,
const cvf::Color3f& textColor,
const cvf::Color3f& backgroundColor,
const std::string& text,
const cvf::Vec3f& position );
static cvf::ref<cvf::DrawableText>
createDrawableTextNoBackground( cvf::Font* font, const cvf::Color3f& textColor, const std::string& text, const cvf::Vec3f& position );
static cvf::ref<cvf::Part> createPart( cvf::DrawableText* drawableText );
private:
LabelPositionStrategy m_overrideStrategy;
int m_labelCountHint;
};

View File

@@ -51,7 +51,7 @@ cvf::ref<cvf::Part> RivBoxGeometryGenerator::createBoxFromVertices( const std::v
cvf::ref<cvf::Vec3fArray> cvfVertices = new cvf::Vec3fArray;
cvfVertices->assign( boxVertices );
if ( !( cvfVertices.notNull() && cvfVertices->size() != 0 ) ) return nullptr;
if ( !cvfVertices.notNull() || cvfVertices->size() == 0 ) return nullptr;
geo->setVertexArray( cvfVertices.p() );

View File

@@ -275,7 +275,6 @@ void CellEdgeEffectGenerator::updateForShaderBasedRendering( cvf::Effect* effect
// Polygon offset
if ( true )
{
cvf::ref<cvf::RenderStatePolygonOffset> polyOffset = new cvf::RenderStatePolygonOffset;
polyOffset->configurePolygonPositiveOffset();

View File

@@ -78,7 +78,7 @@ void RivContourMapProjectionPartMgr::appendPickPointVisToModel( cvf::ModelBasicL
{
caf::MeshEffectGenerator meshEffectGen( cvf::Color3::MAGENTA );
meshEffectGen.setLineWidth( 1.0f );
meshEffectGen.createAndConfigurePolygonOffsetRenderState( caf::PO_2 );
caf::MeshEffectGenerator::createAndConfigurePolygonOffsetRenderState( caf::PO_2 );
cvf::ref<cvf::Effect> effect = meshEffectGen.generateCachedEffect();
cvf::ref<cvf::Part> part = new cvf::Part;
@@ -153,7 +153,7 @@ void RivContourMapProjectionPartMgr::appendContourLinesToModel( const cvf::Camer
{
caf::MeshEffectGenerator meshEffectGen( lineColor );
meshEffectGen.setLineWidth( 1.0f );
meshEffectGen.createAndConfigurePolygonOffsetRenderState( caf::PO_1 );
caf::MeshEffectGenerator::createAndConfigurePolygonOffsetRenderState( caf::PO_1 );
cvf::ref<cvf::Effect> effect = meshEffectGen.generateCachedEffect();
@@ -302,7 +302,7 @@ std::vector<std::vector<cvf::ref<cvf::Drawable>>>
lineBBox.add( displayVertex2 );
bool addOriginalSegment = true;
if ( labelBBoxes.size() > 0 )
if ( !labelBBoxes.empty() )
{
for ( const cvf::BoundingBox& existingBBox : labelBBoxes[i] )
{

View File

@@ -268,7 +268,7 @@ void RivElementVectorResultPartMgr::appendDynamicGeometryPartsToModel( cvf::Mode
for ( int nIdx = 0; nIdx < static_cast<int>( nncData->eclipseConnectionCount() ); ++nIdx )
{
const RigConnection& conn = nncData->availableConnections()[nIdx];
if ( conn.polygon().size() )
if ( !conn.polygon().empty() )
{
double resultValue = 0.0;
for ( size_t flIdx = 0; flIdx < nncResultVals.size(); flIdx++ )

View File

@@ -60,7 +60,7 @@ void RivFishbonesSubsPartMgr::appendGeometryPartsToModel( cvf::ModelBasicList*
if ( !m_rimFishbonesSubs->isActive() ) return;
if ( m_parts.size() == 0 )
if ( m_parts.empty() )
{
buildParts( displayCoordTransform, characteristicCellSize );
}

View File

@@ -96,7 +96,7 @@ void RivNNCGeometryGenerator::computeArrays()
const RigConnection& conn = m_nncData->allConnections()[conIdx];
if ( conn.polygon().size() )
if ( !conn.polygon().empty() )
{
bool isVisible = true;
if ( isVisibilityCalcActive )
@@ -176,7 +176,7 @@ void RivNNCGeometryGenerator::textureCoordinates( cvf::Vec2fArray*
nncResultVals = m_nncData->generatedConnectionScalarResult( resVarAddr, nativeTimeStepIndex );
}
if ( !nncResultVals || nncResultVals->size() == 0 )
if ( !nncResultVals || nncResultVals->empty() )
{
textureCoords->setAll( cvf::Vec2f( 0.0f, 1.0f ) );
return;

View File

@@ -120,3 +120,45 @@ cvf::ref<cvf::DrawableGeo> RivPolylineGenerator::createPointsFromPolylineDrawabl
return geo;
}
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::DrawableGeo> RivPolylineGenerator::createSetOfLines( const std::vector<std::vector<cvf::Vec3d>>& lines )
{
std::vector<cvf::uint> lineIndices;
std::vector<cvf::Vec3f> vertices;
for ( const std::vector<cvf::Vec3d>& polyLine : lines )
{
if ( polyLine.size() < 2 ) continue;
size_t verticesCount = vertices.size();
for ( size_t i = 0; i < polyLine.size(); i += 2 )
{
vertices.emplace_back( polyLine[i] );
vertices.emplace_back( polyLine[i + 1] );
if ( i < polyLine.size() - 1 )
{
lineIndices.push_back( static_cast<cvf::uint>( verticesCount + i ) );
lineIndices.push_back( static_cast<cvf::uint>( verticesCount + i + 1 ) );
}
}
}
if ( vertices.empty() ) return nullptr;
cvf::ref<cvf::Vec3fArray> vx = new cvf::Vec3fArray;
vx->assign( vertices );
cvf::ref<cvf::UIntArray> idxes = new cvf::UIntArray;
idxes->assign( lineIndices );
cvf::ref<cvf::PrimitiveSetIndexedUInt> prim = new cvf::PrimitiveSetIndexedUInt( cvf::PT_LINES );
prim->setIndices( idxes.p() );
cvf::ref<cvf::DrawableGeo> polylineGeo = new cvf::DrawableGeo;
polylineGeo->setVertexArray( vx.p() );
polylineGeo->addPrimitiveSet( prim.p() );
return polylineGeo;
}

View File

@@ -19,19 +19,19 @@
#pragma once
#include "cvfObject.h"
#include <cvfVector3.h>
#include <vector>
namespace cvf
{
class DrawableGeo;
}
} // namespace cvf
//==================================================================================================
///
//==================================================================================================
class RivPolylineGenerator : public cvf::Object
class RivPolylineGenerator
{
public:
static cvf::ref<cvf::DrawableGeo> createLineAlongPolylineDrawable( const std::vector<cvf::Vec3d>& polyLine, bool closeLine = false );
@@ -40,4 +40,6 @@ public:
static cvf::ref<cvf::DrawableGeo> createPointsFromPolylineDrawable( const std::vector<cvf::Vec3d>& polyLine );
static cvf::ref<cvf::DrawableGeo> createPointsFromPolylineDrawable( const std::vector<std::vector<cvf::Vec3d>>& polyLines );
static cvf::ref<cvf::DrawableGeo> createSetOfLines( const std::vector<std::vector<cvf::Vec3d>>& lines );
};

View File

@@ -82,7 +82,7 @@ bool RivPolylinePartMgr::isPolylinesInBoundingBox( std::vector<std::vector<cvf::
void RivPolylinePartMgr::buildPolylineParts( const caf::DisplayCoordTransform* displayXf, const cvf::BoundingBox& boundingBox )
{
auto polylineDef = m_polylineInterface->polyLinesData();
if ( polylineDef.isNull() || polylineDef->polyLines().size() == 0 )
if ( polylineDef.isNull() || polylineDef->polyLines().empty() )
{
clearAllGeometry();
return;

View File

@@ -720,9 +720,13 @@ void RivReservoirViewPartMgr::computeFilterVisibility( RivCellSetEnum
if ( cellFilterColl->hasActiveFilters() || m_reservoirView->wellCollection()->hasVisibleWellCells() )
{
cvf::UByteArray indexIncludeVisibility = ( *cellVisibility );
cvf::UByteArray indexExcludeVisibility = ( *cellVisibility );
// Build cell filter for current grid
cvf::CellRangeFilter gridCellRangeFilter;
cellFilterColl->compoundCellRangeFilter( &gridCellRangeFilter, grid->gridIndex() );
cellFilterColl->updateCellVisibilityByIndex( &indexIncludeVisibility, &indexExcludeVisibility, grid->gridIndex() );
const RigLocalGrid* lgr = nullptr;
cvf::ref<cvf::UByteArray> parentGridVisibilities;
@@ -745,7 +749,9 @@ void RivReservoirViewPartMgr::computeFilterVisibility( RivCellSetEnum
parentGridVisibilities = reservoirGridPartMgr->cellVisibility( parentGridIndex );
}
bool hasAdditiveFilters = cellFilterColl->hasActiveIncludeFilters() || m_reservoirView->wellCollection()->hasVisibleWellCells();
bool hasAdditiveRangeFilters = cellFilterColl->hasActiveIncludeRangeFilters() ||
m_reservoirView->wellCollection()->hasVisibleWellCells();
bool hasAdditiveIndexFilters = cellFilterColl->hasActiveIncludeIndexFilters();
#pragma omp parallel for
for ( int cellIndex = 0; cellIndex < static_cast<int>( grid->cellCount() ); cellIndex++ )
@@ -770,18 +776,26 @@ void RivReservoirViewPartMgr::computeFilterVisibility( RivCellSetEnum
bool nativeRangeVisibility = false;
if ( hasAdditiveFilters )
if ( hasAdditiveRangeFilters )
{
nativeRangeVisibility = gridCellRangeFilter.isCellVisible( mainGridI, mainGridJ, mainGridK, isInSubGridArea );
if ( hasAdditiveIndexFilters )
{
nativeRangeVisibility = indexIncludeVisibility[cellIndex] ||
gridCellRangeFilter.isCellVisible( mainGridI, mainGridJ, mainGridK, isInSubGridArea );
}
else
{
nativeRangeVisibility = gridCellRangeFilter.isCellVisible( mainGridI, mainGridJ, mainGridK, isInSubGridArea );
}
}
else
{
// Special handling when no include filters are present. Use native visibility
nativeRangeVisibility = ( *nativeVisibility )[cellIndex];
nativeRangeVisibility = indexIncludeVisibility[cellIndex];
}
( *cellVisibility )[cellIndex] = ( visibleDueToParentGrid || nativeRangeVisibility ) &&
!gridCellRangeFilter.isCellExcluded( mainGridI, mainGridJ, mainGridK, isInSubGridArea );
!gridCellRangeFilter.isCellExcluded( mainGridI, mainGridJ, mainGridK, isInSubGridArea ) &&
indexExcludeVisibility[cellIndex];
}
}
}

View File

@@ -161,7 +161,7 @@ void RivSimWellPipesPartMgr::buildWellPipeParts( const caf::DisplayCoordTransfor
int branchIndex,
size_t frameIndex )
{
if ( !this->viewWithSettings() ) return;
if ( !viewWithSettings() ) return;
m_wellBranches.clear();
m_flattenedBranchWellHeadOffsets.clear();
@@ -406,7 +406,7 @@ void RivSimWellPipesPartMgr::appendValvesGeo( const RimEclipseView*
if ( !m_simWellInView || !m_simWellInView->isWellValvesVisible( frameIndex ) ) return;
if ( !eclipseView || !eclipseView->ownerCase() ) return;
const auto characteristicCellSize = eclipseView->ownerCase()->characteristicCellSize();
const auto characteristicCellSize = eclipseView->characteristicCellSize();
const auto coords = pbd.m_pipeGeomGenerator->pipeCenterCoords();
std::set<std::pair<size_t, size_t>> resultPointWithValve;

View File

@@ -465,7 +465,7 @@ void RivTensorResultPartMgr::createResultColorTextureCoords( cvf::Vec2fArray*
//--------------------------------------------------------------------------------------------------
bool RivTensorResultPartMgr::isTensorAddress( RigFemResultAddress address )
{
if ( !( address.resultPosType == RIG_ELEMENT_NODAL || address.resultPosType == RIG_INTEGRATION_POINT ) )
if ( address.resultPosType != RIG_ELEMENT_NODAL && address.resultPosType != RIG_INTEGRATION_POINT )
{
return false;
}
@@ -509,12 +509,7 @@ bool RivTensorResultPartMgr::isValid( cvf::Vec3f resultVector )
//--------------------------------------------------------------------------------------------------
bool RivTensorResultPartMgr::isPressure( float principalValue )
{
if ( principalValue >= 0 )
{
return true;
}
return false;
return principalValue >= 0;
}
//--------------------------------------------------------------------------------------------------

View File

@@ -52,7 +52,7 @@ RivTernarySaturationOverlayItem::~RivTernarySaturationOverlayItem()
//--------------------------------------------------------------------------------------------------
void RivTernarySaturationOverlayItem::setAxisLabelsColor( const cvf::Color3f& color )
{
this->setTextColor( color );
setTextColor( color );
}
//--------------------------------------------------------------------------------------------------
@@ -92,14 +92,14 @@ void RivTernarySaturationOverlayItem::renderGeneric( cvf::OpenGLContext* oglCont
camera.applyOpenGL();
camera.viewport()->applyOpenGL( oglContext, cvf::Viewport::CLEAR_DEPTH );
if ( this->backgroundEnabled() )
if ( backgroundEnabled() )
{
if ( software )
{
caf::InternalLegendRenderTools::renderBackgroundImmediateMode( oglContext,
cvf::Vec2f( sizeFrameBox ),
this->backgroundColor(),
this->backgroundFrameColor() );
backgroundColor(),
backgroundFrameColor() );
}
else
{
@@ -108,22 +108,22 @@ void RivTernarySaturationOverlayItem::renderGeneric( cvf::OpenGLContext* oglCont
caf::InternalLegendRenderTools::renderBackgroundUsingShaders( oglContext,
matrixState,
cvf::Vec2f( sizeFrameBox ),
this->backgroundColor(),
this->backgroundFrameColor() );
backgroundColor(),
backgroundFrameColor() );
}
border = 8.0f;
}
cvf::TextDrawer textDrawer( this->font() );
textDrawer.setTextColor( this->textColor() );
cvf::TextDrawer textDrawer( font() );
textDrawer.setTextColor( textColor() );
float lineHeightInPixels = (float)( this->font()->textExtent( "SWAT" ).y() + 2 );
float lineHeightInPixels = (float)( font()->textExtent( "SWAT" ).y() + 2 );
float textPosY = static_cast<float>( size.y() - lineHeightInPixels - border );
for ( size_t it = 0; it < this->titleStrings().size(); it++ )
for ( size_t it = 0; it < titleStrings().size(); it++ )
{
cvf::Vec2f pos( border, textPosY );
textDrawer.addText( this->titleStrings()[it], pos );
textDrawer.addText( titleStrings()[it], pos );
textPosY -= lineHeightInPixels;
}
@@ -134,10 +134,10 @@ void RivTernarySaturationOverlayItem::renderGeneric( cvf::OpenGLContext* oglCont
textPosY -= border;
{
cvf::uint sgasTextWidth = this->font()->textExtent( "SGAS" ).x();
cvf::uint sgasTextWidth = font()->textExtent( "SGAS" ).x();
textDrawer.addText( "SGAS", cvf::Vec2f( static_cast<float>( ( size.x() / 2 ) - sgasTextWidth / 2 ), textPosY ) );
cvf::uint sgasRangeTextWidth = this->font()->textExtent( m_sgasRange ).x();
cvf::uint sgasRangeTextWidth = font()->textExtent( m_sgasRange ).x();
textPosY -= lineHeightInPixels;
textDrawer.addText( m_sgasRange, cvf::Vec2f( static_cast<float>( ( size.x() / 2 ) - sgasRangeTextWidth / 2 ), textPosY ) );
}
@@ -146,10 +146,10 @@ void RivTernarySaturationOverlayItem::renderGeneric( cvf::OpenGLContext* oglCont
textDrawer.addText( m_swatRange, cvf::Vec2f( (float)border, (float)border ) );
{
cvf::uint soilTextWidth = this->font()->textExtent( "SOIL" ).x();
cvf::uint soilTextWidth = font()->textExtent( "SOIL" ).x();
textDrawer.addText( "SOIL", cvf::Vec2f( static_cast<float>( size.x() - soilTextWidth - border ), lineHeightInPixels + border ) );
cvf::uint soilRangeTextWidth = this->font()->textExtent( m_soilRange ).x();
cvf::uint soilRangeTextWidth = font()->textExtent( m_soilRange ).x();
float soilRangePos = static_cast<float>( size.x() ) - soilRangeTextWidth - border;
textDrawer.addText( m_soilRange, cvf::Vec2f( soilRangePos, (float)border ) );
@@ -187,7 +187,7 @@ void RivTernarySaturationOverlayItem::renderAxisImmediateMode( float
cvf::Color3ub colB( cvf::Color3::GREEN );
cvf::Color3ub colC( cvf::Color3::RED );
// float upperBoundY = static_cast<float>(this->sizeHint().y() - 20);
// float upperBoundY = static_cast<float>(sizeHint().y() - 20);
cvf::Vec3f a( float( border ), lowerBoundY, 0 );
cvf::Vec3f b( static_cast<float>( totalWidth - border ), lowerBoundY, 0 );

View File

@@ -98,17 +98,8 @@ void RivTextAnnotationPartMgr::buildParts( const caf::DisplayCoordTransform* dis
{
std::vector<cvf::Vec3d> points = { anchorPosition, labelPosition };
cvf::ref<cvf::DrawableGeo> drawableGeo = RivPolylineGenerator::createLineAlongPolylineDrawable( points );
cvf::ref<cvf::Part> part = new cvf::Part;
auto part = RivAnnotationTools::createPartFromPolyline( anchorLineColor, points );
part->setName( "RivTextAnnotationPartMgr" );
part->setDrawable( drawableGeo.p() );
caf::MeshEffectGenerator colorEffgen( anchorLineColor );
cvf::ref<cvf::Effect> eff = colorEffgen.generateUnCachedEffect();
part->setEffect( eff.p() );
part->setPriority( RivPartPriority::PartType::MeshLines );
part->setSourceInfo( new RivObjectSourceInfo( rimAnnotation() ) );
m_linePart = part;
@@ -116,30 +107,14 @@ void RivTextAnnotationPartMgr::buildParts( const caf::DisplayCoordTransform* dis
// Text part
{
auto font = RiaFontCache::getFont( fontSize );
cvf::ref<cvf::DrawableText> drawableText = new cvf::DrawableText;
drawableText->setFont( font.p() );
drawableText->setCheckPosVisible( false );
drawableText->setUseDepthBuffer( true );
drawableText->setDrawBorder( true );
drawableText->setDrawBackground( true );
drawableText->setVerticalAlignment( cvf::TextDrawer::BASELINE );
drawableText->setBackgroundColor( backgroundColor );
drawableText->setBorderColor( RiaColorTools::computeOffsetColor( backgroundColor, 0.3f ) );
drawableText->setTextColor( fontColor );
auto font = RiaFontCache::getFont( fontSize );
auto drawableText =
RivAnnotationTools::createDrawableText( font.p(), fontColor, backgroundColor, text.toStdString(), cvf::Vec3f( labelPosition ) );
auto part = RivAnnotationTools::createPart( drawableText.p() );
cvf::String cvfString = cvfqt::Utils::toString( text );
cvf::Vec3f textCoord( labelPosition );
drawableText->addText( cvfString, textCoord );
cvf::ref<cvf::Part> part = new cvf::Part;
part->setName( "RivTextAnnotationPartMgr: " + cvfString );
part->setDrawable( drawableText.p() );
cvf::ref<cvf::Effect> eff = new cvf::Effect();
part->setEffect( eff.p() );
part->setPriority( RivPartPriority::PartType::MeshLines );
m_labelPart = part;
}
@@ -182,10 +157,8 @@ bool RivTextAnnotationPartMgr::isTextInBoundingBox( const cvf::BoundingBox& boun
if ( !coll ) return false;
auto effectiveBoundingBox = RiaBoundingBoxTools::inflate( boundingBox, 3 );
if ( effectiveBoundingBox.contains( getAnchorPointInDomain( coll->snapAnnotations(), coll->annotationPlaneZ() ) ) ||
effectiveBoundingBox.contains( getLabelPointInDomain( coll->snapAnnotations(), coll->annotationPlaneZ() ) ) )
return true;
return false;
return effectiveBoundingBox.contains( getAnchorPointInDomain( coll->snapAnnotations(), coll->annotationPlaneZ() ) ) ||
effectiveBoundingBox.contains( getLabelPointInDomain( coll->snapAnnotations(), coll->annotationPlaneZ() ) );
}
//--------------------------------------------------------------------------------------------------

View File

@@ -63,12 +63,7 @@ RivTextureCoordsCreator::RivTextureCoordsCreator( RimEclipseCellColors*
//--------------------------------------------------------------------------------------------------
bool RivTextureCoordsCreator::isValid()
{
if ( m_quadMapper.isNull() || m_resultAccessor.isNull() || m_texMapper.isNull() )
{
return false;
}
return true;
return !( m_quadMapper.isNull() || m_resultAccessor.isNull() || m_texMapper.isNull() );
}
//--------------------------------------------------------------------------------------------------

View File

@@ -173,7 +173,7 @@ void RivWellConnectionFactorPartMgr::appendDynamicGeometryPartsToModel( cvf::Mod
if ( !completionVizDataItems.empty() )
{
double characteristicCellSize = eclView->ownerCase()->characteristicCellSize();
double characteristicCellSize = eclView->characteristicCellSize();
double radius = m_rimWellPath->wellPathRadius( characteristicCellSize ) * m_virtualPerforationResult->geometryScaleFactor();
radius *= 2.0; // Enlarge the radius slightly to make the connection factor visible if geometry scale factor is

View File

@@ -86,7 +86,7 @@ void RivWellDiskPartMgr::buildWellDiskParts( size_t frameIndex, const caf::Displ
RimSimWellInView* well = m_rimWell;
double characteristicCellSize = viewWithSettings()->ownerCase()->characteristicCellSize();
double characteristicCellSize = viewWithSettings()->characteristicCellSize();
cvf::Vec3d whEndPos;
cvf::Vec3d whStartPos;

View File

@@ -91,7 +91,7 @@ void RivWellFracturePartMgr::appendGeometryPartsToModel( cvf::ModelBasicList* mo
m_visibleFracturePolygons.clear();
double characteristicCellSize = eclView.ownerCase()->characteristicCellSize();
double characteristicCellSize = eclView.characteristicCellSize();
cvf::Collection<cvf::Part> parts;
RimMeshFractureTemplate* stimPlanFracTemplate = dynamic_cast<RimMeshFractureTemplate*>( m_rimFracture->fractureTemplate() );
@@ -928,7 +928,7 @@ void RivWellFracturePartMgr::appendFracturePerforationLengthParts( const RimEcli
auto displayCoordTransform = activeView.displayCoordTransform();
if ( displayCoordTransform.isNull() ) return;
double characteristicCellSize = activeView.ownerCase()->characteristicCellSize();
double characteristicCellSize = activeView.characteristicCellSize();
double wellPathRadius = 1.0;
{
@@ -1141,8 +1141,8 @@ std::vector<cvf::Vec3f> RivWellFracturePartMgr::transformToFractureDisplayCoords
cvf::ref<cvf::DrawableGeo> RivWellFracturePartMgr::buildDrawableGeoFromTriangles( const std::vector<cvf::uint>& triangleIndices,
const std::vector<cvf::Vec3f>& nodeCoords )
{
CVF_ASSERT( triangleIndices.size() > 0 );
CVF_ASSERT( nodeCoords.size() > 0 );
CVF_ASSERT( !triangleIndices.empty() );
CVF_ASSERT( !nodeCoords.empty() );
cvf::ref<cvf::DrawableGeo> geo = new cvf::DrawableGeo;

View File

@@ -78,7 +78,7 @@ void RivWellHeadPartMgr::buildWellHeadParts( size_t frameIndex, const caf::Displ
RimSimWellInView* well = m_rimWell;
double characteristicCellSize = viewWithSettings()->ownerCase()->characteristicCellSize();
double characteristicCellSize = viewWithSettings()->characteristicCellSize();
cvf::Vec3d whEndPos;
cvf::Vec3d whStartPos;
@@ -290,20 +290,13 @@ void RivWellHeadPartMgr::buildWellHeadParts( size_t frameIndex, const caf::Displ
// well disk labels are preferred since they have more info.
if ( well->showWellLabel() && !well->name().isEmpty() && !well->showWellDisks() )
{
cvf::Font* font = RiaGuiApplication::instance()->defaultWellLabelFont();
cvf::ref<cvf::DrawableText> drawableText = new cvf::DrawableText;
drawableText->setFont( font );
drawableText->setCheckPosVisible( false );
drawableText->setDrawBorder( false );
drawableText->setDrawBackground( false );
drawableText->setVerticalAlignment( cvf::TextDrawer::CENTER );
drawableText->setTextColor( simWellInViewCollection()->wellLabelColor() );
cvf::Font* font = RiaGuiApplication::instance()->defaultWellLabelFont();
cvf::String cvfString = cvfqt::Utils::toString( m_rimWell->name() );
cvf::Vec3f textCoord( textPosition );
drawableText->addText( cvfString, textCoord );
auto drawableText = RivAnnotationTools::createDrawableTextNoBackground( font,
simWellInViewCollection()->wellLabelColor(),
m_rimWell->name().toStdString(),
cvf::Vec3f( textPosition ) );
cvf::ref<cvf::Part> part = new cvf::Part;
part->setName( "RivWellHeadPartMgr: text " + cvfString );
@@ -314,7 +307,7 @@ void RivWellHeadPartMgr::buildWellHeadParts( size_t frameIndex, const caf::Displ
part->setEffect( eff.p() );
part->setPriority( RivPartPriority::PartType::Text );
part->setSourceInfo( new RivTextLabelSourceInfo( m_rimWell, cvfString, textCoord ) );
part->setSourceInfo( new RivTextLabelSourceInfo( m_rimWell, cvfString, cvf::Vec3f( textPosition ) ) );
m_wellHeadLabelPart = part;
}

View File

@@ -55,6 +55,7 @@
#include "RimWellPathValve.h"
#include "Riv3dWellLogPlanePartMgr.h"
#include "RivAnnotationSourceInfo.h"
#include "RivBoxGeometryGenerator.h"
#include "RivDrawableSpheres.h"
#include "RivFishbonesSubsPartMgr.h"
@@ -151,7 +152,7 @@ bool RivWellPathPartMgr::isWellPathEnabled( const cvf::BoundingBox& wellPathClip
if ( wellPathCollection->wellPathVisibility() == RimWellPathCollection::FORCE_ALL_OFF ) return false;
if ( wellPathCollection->wellPathVisibility() == RimWellPathCollection::ALL_ON && m_rimWellPath->showWellPath() == false ) return false;
if ( wellPathCollection->wellPathVisibility() == RimWellPathCollection::ALL_ON && !m_rimWellPath->showWellPath() ) return false;
if ( !isWellPathWithinBoundingBox( wellPathClipBoundingBox ) ) return false;
@@ -235,7 +236,10 @@ void RivWellPathPartMgr::appendWellPathAttributesToModel( cvf::ModelBasicList*
cvf::ref<RivObjectSourceInfo> objectSourceInfo = new RivObjectSourceInfo( attribute );
cvf::Collection<cvf::Part> parts;
geoGenerator.tubeWithCenterLinePartsAndVariableWidth( &parts, displayCoords, radii, attribute->defaultComponentColor() );
RivPipeGeometryGenerator::tubeWithCenterLinePartsAndVariableWidth( &parts,
displayCoords,
radii,
attribute->defaultComponentColor() );
for ( auto part : parts )
{
part->setSourceInfo( objectSourceInfo.p() );
@@ -267,7 +271,10 @@ void RivWellPathPartMgr::appendWellPathAttributesToModel( cvf::ModelBasicList*
cvf::ref<RivObjectSourceInfo> objectSourceInfo = new RivObjectSourceInfo( attribute );
cvf::Collection<cvf::Part> parts;
geoGenerator.tubeWithCenterLinePartsAndVariableWidth( &parts, displayCoords, radii, attribute->defaultComponentColor() );
RivPipeGeometryGenerator::tubeWithCenterLinePartsAndVariableWidth( &parts,
displayCoords,
radii,
attribute->defaultComponentColor() );
for ( auto part : parts )
{
part->setSourceInfo( objectSourceInfo.p() );
@@ -351,7 +358,7 @@ void RivWellPathPartMgr::appendWellMeasurementsToModel( cvf::ModelBasicList*
// Use the view legend config to find color, if only one type of measurement is selected.
cvf::Color3f color = cvf::Color3f( wellMeasurementInView->legendConfig()->scalarMapper()->mapToColor( wellMeasurement->value() ) );
geoGenerator.tubeWithCenterLinePartsAndVariableWidth( &parts, displayCoords, radii, color );
RivPipeGeometryGenerator::tubeWithCenterLinePartsAndVariableWidth( &parts, displayCoords, radii, color );
for ( auto part : parts )
{
part->setSourceInfo( objectSourceInfo.p() );
@@ -620,14 +627,16 @@ void RivWellPathPartMgr::buildWellPathParts( const caf::DisplayCoordTransform* d
m_pipeGeomGenerator->setCrossSectionVertexCount( wellPathCollection->wellPathCrossSectionVertexCount() );
double horizontalLengthAlongWellToClipPoint = 0.0;
double measuredDepthAtFirstClipPoint = 0.0;
size_t idxToFirstVisibleSegment = 0;
if ( wellPathCollection->wellPathClip )
{
double maxZClipHeight = wellPathClipBoundingBox.max().z() + wellPathCollection->wellPathClipZDistance;
clippedWellPathCenterLine = RigWellPath::clipPolylineStartAboveZ( wellpathCenterLine,
maxZClipHeight,
&horizontalLengthAlongWellToClipPoint,
&idxToFirstVisibleSegment );
horizontalLengthAlongWellToClipPoint,
measuredDepthAtFirstClipPoint,
idxToFirstVisibleSegment );
}
else
{
@@ -694,6 +703,32 @@ void RivWellPathPartMgr::buildWellPathParts( const caf::DisplayCoordTransform* d
cvf::ref<cvf::Effect> eff = gen.generateCachedEffect();
m_centerLinePart->setEffect( eff.p() );
if ( m_rimWellPath->measuredDepthLabelInterval().has_value() && clippedWellPathCenterLine.size() > 2 )
{
const double distanceBetweenLabels = m_rimWellPath->measuredDepthLabelInterval().value();
// Create a round number as start for measured depth label
const double startMeasuredDepth =
( static_cast<int>( measuredDepthAtFirstClipPoint / distanceBetweenLabels ) + 1 ) * distanceBetweenLabels;
std::vector<std::string> labelTexts;
std::vector<cvf::Vec3d> labelDisplayCoords;
double measuredDepth = startMeasuredDepth;
while ( measuredDepth < wellPathGeometry->measuredDepths().back() )
{
labelTexts.push_back( std::to_string( static_cast<int>( measuredDepth ) ) );
auto domainCoord = wellPathGeometry->interpolatedPointAlongWellPath( measuredDepth );
auto displayCoord = displayCoordTransform->transformToDisplayCoord( domainCoord );
labelDisplayCoords.push_back( displayCoord );
measuredDepth += distanceBetweenLabels;
}
m_centerLinePart->setSourceInfo( new RivAnnotationSourceInfo( labelTexts, labelDisplayCoords ) );
}
}
// Generate label with well-path name at a position that is slightly offset towards the end of the well path
@@ -708,21 +743,13 @@ void RivWellPathPartMgr::buildWellPathParts( const caf::DisplayCoordTransform* d
{
cvf::Font* font = RiaGuiApplication::instance()->defaultWellLabelFont();
cvf::ref<cvf::DrawableText> drawableText = new cvf::DrawableText;
drawableText->setFont( font );
drawableText->setCheckPosVisible( false );
drawableText->setDrawBorder( false );
drawableText->setDrawBackground( false );
drawableText->setVerticalAlignment( cvf::TextDrawer::CENTER );
drawableText->setTextColor( wellPathCollection->wellPathLabelColor() );
cvf::String cvfString = cvfqt::Utils::toString( m_rimWellPath->name() );
cvf::Vec3f textCoord( textPosition );
drawableText->addText( cvfString, textCoord );
auto drawableText = RivAnnotationTools::createDrawableTextNoBackground( font,
wellPathCollection->wellPathLabelColor(),
m_rimWellPath->name().toStdString(),
cvf::Vec3f( textPosition ) );
cvf::ref<cvf::Part> part = new cvf::Part;
part->setName( "RivWellHeadPartMgr: text " + cvfString );
part->setName( "RivWellHeadPartMgr: text " + m_rimWellPath->name().toStdString() );
part->setDrawable( drawableText.p() );
cvf::ref<cvf::Effect> eff = new cvf::Effect;
@@ -730,7 +757,7 @@ void RivWellPathPartMgr::buildWellPathParts( const caf::DisplayCoordTransform* d
part->setEffect( eff.p() );
part->setPriority( RivPartPriority::Text );
part->setSourceInfo( new RivTextLabelSourceInfo( m_rimWellPath, cvfString, textCoord ) );
part->setSourceInfo( new RivTextLabelSourceInfo( m_rimWellPath, m_rimWellPath->name().toStdString(), cvf::Vec3f( textPosition ) ) );
m_wellLabelPart = part;
}

View File

@@ -1,11 +1,13 @@
set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RivSeismicSectionPartMgr.h
${CMAKE_CURRENT_LIST_DIR}/RivSeismicSectionSourceInfo.h
${CMAKE_CURRENT_LIST_DIR}/RivTexturePartMgr.h
)
set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RivSeismicSectionPartMgr.cpp
${CMAKE_CURRENT_LIST_DIR}/RivSeismicSectionSourceInfo.cpp
${CMAKE_CURRENT_LIST_DIR}/RivTexturePartMgr.cpp
)
list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})

View File

@@ -20,18 +20,25 @@
#include "RiaGuiApplication.h"
#include "RivPartPriority.h"
#include "RivPolylinePartMgr.h"
#include "RivSeismicSectionSourceInfo.h"
#include "Rim3dView.h"
#include "RimRegularLegendConfig.h"
#include "RimSeismicAlphaMapper.h"
#include "RimSeismicSection.h"
#include "RimSeismicSectionCollection.h"
#include "RimSurface.h"
#include "RimSurfaceCollection.h"
#include "RimTools.h"
#include "RigSurfaceResampler.h"
#include "RigTexturedSection.h"
#include "RivAnnotationSourceInfo.h"
#include "RivObjectSourceInfo.h"
#include "RivPartPriority.h"
#include "RivPolylineGenerator.h"
#include "RivPolylinePartMgr.h"
#include "RivSeismicSectionSourceInfo.h"
#include "cafDisplayCoordTransform.h"
#include "cafEffectGenerator.h"
#include "cafPdmObject.h"
@@ -50,17 +57,8 @@
//--------------------------------------------------------------------------------------------------
RivSeismicSectionPartMgr::RivSeismicSectionPartMgr( RimSeismicSection* section )
: m_section( section )
, m_canUseShaders( true )
{
CVF_ASSERT( section );
m_canUseShaders = RiaGuiApplication::instance()->useShaders();
cvf::ShaderProgramGenerator gen( "Texturing", cvf::ShaderSourceProvider::instance() );
gen.addVertexCode( cvf::ShaderSourceRepository::vs_Standard );
gen.addFragmentCode( cvf::ShaderSourceRepository::src_Texture );
gen.addFragmentCode( cvf::ShaderSourceRepository::fs_Unlit );
m_textureShaderProg = gen.generate();
}
//--------------------------------------------------------------------------------------------------
@@ -87,7 +85,7 @@ void RivSeismicSectionPartMgr::appendGeometryPartsToModel( cvf::ModelBasicList*
auto texSection = m_section->texturedSection();
for ( int i = 0; i < (int)texSection->partsCount(); i++ )
for ( int i = 0; i < texSection->partsCount(); i++ )
{
auto& part = texSection->part( i );
@@ -106,7 +104,7 @@ void RivSeismicSectionPartMgr::appendGeometryPartsToModel( cvf::ModelBasicList*
part.texture = createImageFromData( part.sliceData.get() );
}
cvf::ref<cvf::Part> quadPart = createSingleTexturedQuadPart( displayPoints, part.texture );
cvf::ref<cvf::Part> quadPart = createSingleTexturedQuadPart( displayPoints, part.texture, m_section->isTransparent() );
cvf::ref<RivSeismicSectionSourceInfo> si = new RivSeismicSectionSourceInfo( m_section, i );
quadPart->setSourceInfo( si.p() );
@@ -115,85 +113,6 @@ void RivSeismicSectionPartMgr::appendGeometryPartsToModel( cvf::ModelBasicList*
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::Part> RivSeismicSectionPartMgr::createSingleTexturedQuadPart( const cvf::Vec3dArray& cornerPoints,
cvf::ref<cvf::TextureImage> image )
{
cvf::ref<cvf::Part> part = new cvf::Part;
cvf::ref<cvf::DrawableGeo> geo = createXYPlaneQuadGeoWithTexCoords( cornerPoints );
cvf::ref<cvf::Texture> texture = new cvf::Texture( image.p() );
cvf::ref<cvf::Sampler> sampler = new cvf::Sampler;
sampler->setMinFilter( cvf::Sampler::LINEAR );
sampler->setMagFilter( cvf::Sampler::NEAREST );
sampler->setWrapModeS( cvf::Sampler::CLAMP_TO_EDGE );
sampler->setWrapModeT( cvf::Sampler::CLAMP_TO_EDGE );
cvf::ref<cvf::RenderStateTextureBindings> textureBindings = new cvf::RenderStateTextureBindings;
textureBindings->addBinding( texture.p(), sampler.p(), "u_texture2D" );
cvf::ref<cvf::Effect> eff = new cvf::Effect;
eff->setRenderState( textureBindings.p() );
eff->setShaderProgram( m_textureShaderProg.p() );
if ( m_section->isTransparent() )
{
part->setPriority( RivPartPriority::PartType::TransparentSeismic );
cvf::ref<cvf::RenderStateBlending> blending = new cvf::RenderStateBlending;
blending->configureTransparencyBlending();
eff->setRenderState( blending.p() );
}
part->setDrawable( geo.p() );
part->setEffect( eff.p() );
return part;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::DrawableGeo> RivSeismicSectionPartMgr::createXYPlaneQuadGeoWithTexCoords( const cvf::Vec3dArray& cornerPoints )
{
cvf::ref<cvf::Vec3fArray> vertices = new cvf::Vec3fArray;
vertices->reserve( 4 );
for ( const auto& v : cornerPoints )
{
vertices->add( cvf::Vec3f( v ) );
}
cvf::ref<cvf::Vec2fArray> texCoords = new cvf::Vec2fArray;
texCoords->reserve( 4 );
texCoords->add( cvf::Vec2f( 0, 0 ) );
texCoords->add( cvf::Vec2f( 1, 0 ) );
texCoords->add( cvf::Vec2f( 1, 1 ) );
texCoords->add( cvf::Vec2f( 0, 1 ) );
cvf::ref<cvf::DrawableGeo> geo = new cvf::DrawableGeo;
geo->setVertexArray( vertices.p() );
geo->setTextureCoordArray( texCoords.p() );
cvf::ref<cvf::UIntArray> indices = new cvf::UIntArray;
indices->reserve( 6 );
for ( uint i : { 0, 1, 2, 0, 2, 3 } )
{
indices->add( i );
}
cvf::ref<cvf::PrimitiveSetIndexedUInt> primSet = new cvf::PrimitiveSetIndexedUInt( cvf::PT_TRIANGLES );
primSet->setIndices( indices.p() );
geo->addPrimitiveSet( primSet.p() );
geo->computeNormals();
return geo;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -236,3 +155,122 @@ cvf::TextureImage* RivSeismicSectionPartMgr::createImageFromData( ZGYAccess::Sei
return textureImage;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::vector<cvf::Vec3d>>
RivSeismicSectionPartMgr::projectPolyLineOntoSurface( std::vector<cvf::Vec3d> polyLine,
RimSurface* surface,
const caf::DisplayCoordTransform* displayCoordTransform )
{
std::vector<std::vector<cvf::Vec3d>> displayPolygonCurves;
const double resamplingDistance = 5.0;
std::vector<cvf::Vec3d> resampledPolyline = RigSurfaceResampler::computeResampledPolyline( polyLine, resamplingDistance );
std::vector<cvf::Vec3d> domainCurvePoints;
for ( const auto& point : resampledPolyline )
{
cvf::Vec3d pointAbove = cvf::Vec3d( point.x(), point.y(), 10000.0 );
cvf::Vec3d pointBelow = cvf::Vec3d( point.x(), point.y(), -10000.0 );
cvf::Vec3d intersectionPoint;
bool foundMatch = RigSurfaceResampler::computeIntersectionWithLine( surface->surfaceData(), pointAbove, pointBelow, intersectionPoint );
if ( foundMatch )
{
domainCurvePoints.emplace_back( intersectionPoint );
}
// Create a line segment if we did not find an intersection point or if we are at the end of the polyline
if ( !foundMatch || ( point == resampledPolyline.back() ) )
{
if ( domainCurvePoints.size() > 1 )
{
// Add intersection curve in display coordinates
auto displayCoords = displayCoordTransform->transformToDisplayCoords( domainCurvePoints );
displayPolygonCurves.push_back( displayCoords );
}
// Start a new line
domainCurvePoints.clear();
}
}
return displayPolygonCurves;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivSeismicSectionPartMgr::appendSurfaceIntersectionLines( cvf::ModelBasicList* model,
const caf::DisplayCoordTransform* displayCoordTransform,
double lineThickness,
const std::vector<RimSurface*>& surfaces )
{
for ( auto surface : surfaces )
{
if ( !surface ) continue;
surface->loadDataIfRequired();
if ( !surface->surfaceData() ) continue;
std::vector<cvf::Vec3d> completePolyLine;
cvf::Part* firstPart = nullptr;
auto texSection = m_section->texturedSection();
for ( int i = 0; i < texSection->partsCount(); i++ )
{
const auto& texturePart = texSection->part( i );
// Each part of the seismic section is a rectangle, use two corners of the rectangle to create a polyline
std::vector<cvf::Vec3d> polyLineForSection = { texturePart.rect[0], texturePart.rect[1] };
bool closePolyLine = false;
auto polyLineDisplayCoords = projectPolyLineOntoSurface( polyLineForSection, surface, displayCoordTransform );
cvf::ref<cvf::DrawableGeo> drawableGeo =
RivPolylineGenerator::createLineAlongPolylineDrawable( polyLineDisplayCoords, closePolyLine );
if ( drawableGeo.isNull() ) continue;
cvf::ref<cvf::Part> part = new cvf::Part;
part->setName( "RivSeismicSectionPartMgr::SurfaceIntersectionLine" );
part->setDrawable( drawableGeo.p() );
caf::MeshEffectGenerator effgen( surface->color() );
effgen.setLineWidth( lineThickness );
cvf::ref<cvf::Effect> eff = effgen.generateCachedEffect();
cvf::ref<cvf::RenderStatePolygonOffset> polyOffset = new cvf::RenderStatePolygonOffset;
polyOffset->enableFillMode( true );
polyOffset->setFactor( -5 );
const double maxOffsetFactor = -1000;
polyOffset->setUnits( maxOffsetFactor );
eff->setRenderState( polyOffset.p() );
part->setEffect( eff.p() );
part->setPriority( RivPartPriority::PartType::MeshLines );
model->addPart( part.p() );
if ( !firstPart ) firstPart = part.p();
for ( const auto& coords : polyLineDisplayCoords )
{
completePolyLine.insert( completePolyLine.end(), coords.begin(), coords.end() );
}
}
if ( firstPart )
{
// Add annotation info to be used to display label in Rim3dView::onViewNavigationChanged()
// Set the source info on one part only, as this data is only used for display of labels
auto annoObj = new RivAnnotationSourceInfo( surface->fullName().toStdString(), completePolyLine );
annoObj->setLabelPositionStrategyHint( RivAnnotationTools::LabelPositionStrategy::RIGHT );
annoObj->setShowColor( true );
annoObj->setColor( surface->color() );
firstPart->setSourceInfo( annoObj );
}
}
}

View File

@@ -17,16 +17,15 @@
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RivTexturePartMgr.h"
#include "cafPdmPointer.h"
#include "cvfArray.h"
#include "cvfObject.h"
namespace cvf
{
class ModelBasicList;
class Transform;
class Part;
class ScalarMapper;
class DrawableGeo;
class BoundingBox;
class ShaderProgram;
@@ -43,35 +42,38 @@ namespace ZGYAccess
class SeismicSliceData;
}
class RimSeismicSectionCollection;
class RimSeismicSection;
class RimSurface;
class Rim3dView;
class RivPolylinePartMgr;
class RivSeismicSectionPartMgr : public cvf::Object
class RivSeismicSectionPartMgr : public RivTexturePartMgr
{
public:
explicit RivSeismicSectionPartMgr( RimSeismicSection* section );
void appendGeometryPartsToModel( cvf::ModelBasicList* model,
const caf::DisplayCoordTransform* displayCoordTransform,
const cvf::BoundingBox& boundingBox );
const cvf::BoundingBox& boundingBox ) override;
void appendPolylinePartsToModel( Rim3dView* view,
cvf::ModelBasicList* model,
const caf::DisplayCoordTransform* displayCoordTransform,
const cvf::BoundingBox& boundingBox );
const cvf::BoundingBox& boundingBox ) override;
void appendSurfaceIntersectionLines( cvf::ModelBasicList* model,
const caf::DisplayCoordTransform* displayCoordTransform,
double lineThickness,
const std::vector<RimSurface*>& surfaces );
protected:
cvf::ref<cvf::DrawableGeo> createXYPlaneQuadGeoWithTexCoords( const cvf::Vec3dArray& cornerPoints );
cvf::ref<cvf::Part> createSingleTexturedQuadPart( const cvf::Vec3dArray& cornerPoints, cvf::ref<cvf::TextureImage> image );
cvf::TextureImage* createImageFromData( ZGYAccess::SeismicSliceData* data );
static std::vector<std::vector<cvf::Vec3d>> projectPolyLineOntoSurface( std::vector<cvf::Vec3d> polyLine,
RimSurface* surface,
const caf::DisplayCoordTransform* displayCoordTransform );
private:
caf::PdmPointer<RimSeismicSection> m_section;
cvf::ref<RivPolylinePartMgr> m_polylinePartMgr;
cvf::ref<cvf::ShaderProgram> m_textureShaderProg;
bool m_canUseShaders;
};

View File

@@ -0,0 +1,137 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2023 Equinor ASA
//
// 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 "RivTexturePartMgr.h"
#include "RiaGuiApplication.h"
#include "RivPartPriority.h"
#include "RigTexturedSection.h"
#include "cafDisplayCoordTransform.h"
#include "cafEffectGenerator.h"
#include "cafPdmObject.h"
#include "cvfLibCore.h"
#include "cvfLibGeometry.h"
#include "cvfLibRender.h"
#include "cvfModelBasicList.h"
#include "cvfPart.h"
#include "cvfScalarMapper.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RivTexturePartMgr::RivTexturePartMgr()
: m_canUseShaders( true )
{
m_canUseShaders = RiaGuiApplication::instance()->useShaders();
cvf::ShaderProgramGenerator gen( "Texturing", cvf::ShaderSourceProvider::instance() );
gen.addVertexCode( cvf::ShaderSourceRepository::vs_Standard );
gen.addFragmentCode( cvf::ShaderSourceRepository::src_Texture );
gen.addFragmentCode( cvf::ShaderSourceRepository::fs_Unlit );
m_textureShaderProg = gen.generate();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RivTexturePartMgr::~RivTexturePartMgr()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::Part>
RivTexturePartMgr::createSingleTexturedQuadPart( const cvf::Vec3dArray& cornerPoints, cvf::ref<cvf::TextureImage> image, bool transparent )
{
cvf::ref<cvf::Part> part = new cvf::Part;
cvf::ref<cvf::DrawableGeo> geo = createXYPlaneQuadGeoWithTexCoords( cornerPoints );
cvf::ref<cvf::Texture> texture = new cvf::Texture( image.p() );
cvf::ref<cvf::Sampler> sampler = new cvf::Sampler;
sampler->setMinFilter( cvf::Sampler::LINEAR );
sampler->setMagFilter( cvf::Sampler::NEAREST );
sampler->setWrapModeS( cvf::Sampler::CLAMP_TO_EDGE );
sampler->setWrapModeT( cvf::Sampler::CLAMP_TO_EDGE );
cvf::ref<cvf::RenderStateTextureBindings> textureBindings = new cvf::RenderStateTextureBindings;
textureBindings->addBinding( texture.p(), sampler.p(), "u_texture2D" );
cvf::ref<cvf::Effect> eff = new cvf::Effect;
eff->setRenderState( textureBindings.p() );
eff->setShaderProgram( m_textureShaderProg.p() );
if ( transparent )
{
part->setPriority( RivPartPriority::PartType::TransparentSeismic );
cvf::ref<cvf::RenderStateBlending> blending = new cvf::RenderStateBlending;
blending->configureTransparencyBlending();
eff->setRenderState( blending.p() );
}
part->setDrawable( geo.p() );
part->setEffect( eff.p() );
return part;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::DrawableGeo> RivTexturePartMgr::createXYPlaneQuadGeoWithTexCoords( const cvf::Vec3dArray& cornerPoints )
{
cvf::ref<cvf::Vec3fArray> vertices = new cvf::Vec3fArray;
vertices->reserve( 4 );
for ( const auto& v : cornerPoints )
{
vertices->add( cvf::Vec3f( v ) );
}
cvf::ref<cvf::Vec2fArray> texCoords = new cvf::Vec2fArray;
texCoords->reserve( 4 );
texCoords->add( cvf::Vec2f( 0, 0 ) );
texCoords->add( cvf::Vec2f( 1, 0 ) );
texCoords->add( cvf::Vec2f( 1, 1 ) );
texCoords->add( cvf::Vec2f( 0, 1 ) );
cvf::ref<cvf::DrawableGeo> geo = new cvf::DrawableGeo;
geo->setVertexArray( vertices.p() );
geo->setTextureCoordArray( texCoords.p() );
cvf::ref<cvf::UIntArray> indices = new cvf::UIntArray;
indices->reserve( 6 );
for ( uint i : { 0, 1, 2, 0, 2, 3 } )
{
indices->add( i );
}
cvf::ref<cvf::PrimitiveSetIndexedUInt> primSet = new cvf::PrimitiveSetIndexedUInt( cvf::PT_TRIANGLES );
primSet->setIndices( indices.p() );
geo->addPrimitiveSet( primSet.p() );
geo->computeNormals();
return geo;
}

View File

@@ -0,0 +1,63 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2023 Equinor ASA
//
// 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 "cafPdmPointer.h"
#include "cvfArray.h"
#include "cvfObject.h"
namespace cvf
{
class ModelBasicList;
class Part;
class DrawableGeo;
class BoundingBox;
class ShaderProgram;
class TextureImage;
} // namespace cvf
namespace caf
{
class DisplayCoordTransform;
}
class Rim3dView;
class RivTexturePartMgr : public cvf::Object
{
public:
RivTexturePartMgr();
~RivTexturePartMgr() override;
virtual void appendGeometryPartsToModel( cvf::ModelBasicList* model,
const caf::DisplayCoordTransform* displayCoordTransform,
const cvf::BoundingBox& boundingBox ) = 0;
virtual void appendPolylinePartsToModel( Rim3dView* view,
cvf::ModelBasicList* model,
const caf::DisplayCoordTransform* displayCoordTransform,
const cvf::BoundingBox& boundingBox ) = 0;
protected:
static cvf::ref<cvf::DrawableGeo> createXYPlaneQuadGeoWithTexCoords( const cvf::Vec3dArray& cornerPoints );
cvf::ref<cvf::Part> createSingleTexturedQuadPart( const cvf::Vec3dArray& cornerPoints, cvf::ref<cvf::TextureImage> image, bool transparent );
cvf::ref<cvf::ShaderProgram> m_textureShaderProg;
bool m_canUseShaders;
};

View File

@@ -312,7 +312,7 @@ cvf::ref<cvf::DrawableGeo> RivSurfaceIntersectionGeometryGenerator::generateSurf
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::DrawableGeo> RivSurfaceIntersectionGeometryGenerator::createMeshDrawable()
{
if ( !( m_cellBorderLineVxes.notNull() && m_cellBorderLineVxes->size() != 0 ) ) return nullptr;
if ( !m_cellBorderLineVxes.notNull() || m_cellBorderLineVxes->size() == 0 ) return nullptr;
cvf::ref<cvf::DrawableGeo> geo = new cvf::DrawableGeo;
geo->setVertexArray( m_cellBorderLineVxes.p() );
@@ -329,7 +329,7 @@ cvf::ref<cvf::DrawableGeo> RivSurfaceIntersectionGeometryGenerator::createMeshDr
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::DrawableGeo> RivSurfaceIntersectionGeometryGenerator::createFaultMeshDrawable()
{
if ( !( m_faultCellBorderLineVxes.notNull() && m_faultCellBorderLineVxes->size() != 0 ) ) return nullptr;
if ( !m_faultCellBorderLineVxes.notNull() || m_faultCellBorderLineVxes->size() == 0 ) return nullptr;
cvf::ref<cvf::DrawableGeo> geo = new cvf::DrawableGeo;
geo->setVertexArray( m_faultCellBorderLineVxes.p() );
@@ -389,10 +389,5 @@ RimSurfaceInView* RivSurfaceIntersectionGeometryGenerator::intersection() const
//--------------------------------------------------------------------------------------------------
bool RivSurfaceIntersectionGeometryGenerator::isAnyGeometryPresent() const
{
if ( m_triangleVxes->size() == 0 )
{
return false;
}
return true;
return m_triangleVxes->size() != 0;
}

View File

@@ -49,18 +49,30 @@
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RivSurfacePartMgr::RivSurfacePartMgr( RimSurfaceInView* surface )
RivSurfacePartMgr::RivSurfacePartMgr( RimSurfaceInView* surface, bool nativeOnly )
: m_surfaceInView( surface )
, m_useNativePartsOnly( nativeOnly )
{
CVF_ASSERT( surface );
cvf::ref<RivIntersectionHexGridInterface> hexGrid = m_surfaceInView->createHexGridInterface();
m_intersectionGenerator = new RivSurfaceIntersectionGeometryGenerator( m_surfaceInView, hexGrid.p() );
if ( !nativeOnly )
{
cvf::ref<RivIntersectionHexGridInterface> hexGrid = m_surfaceInView->createHexGridInterface();
m_intersectionGenerator = new RivSurfaceIntersectionGeometryGenerator( m_surfaceInView, hexGrid.p() );
}
m_intersectionFacesTextureCoords = new cvf::Vec2fArray;
m_nativeTrianglesTextureCoords = new cvf::Vec2fArray;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RivSurfacePartMgr::isNativePartMgr() const
{
return m_useNativePartsOnly;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -74,7 +86,7 @@ void RivSurfacePartMgr::appendNativeGeometryPartsToModel( cvf::ModelBasicList* m
if ( m_nativeTrianglesPart.notNull() )
{
m_nativeTrianglesPart->setTransform( scaleTransform );
this->updateNativeSurfaceColors();
updateNativeSurfaceColors();
model->addPart( m_nativeTrianglesPart.p() );
@@ -369,8 +381,9 @@ void RivSurfacePartMgr::generatePartGeometry()
//--------------------------------------------------------------------------------------------------
void RivSurfacePartMgr::generateNativePartGeometry()
{
auto ownerCase = m_surfaceInView->firstAncestorOrThisOfTypeAsserted<RimCase>();
cvf::Vec3d displayModOffsett = ownerCase->displayModelOffset();
cvf::Vec3d displayModOffset( 0, 0, 0 );
auto ownerCase = m_surfaceInView->firstAncestorOrThisOfType<RimCase>();
if ( ownerCase ) displayModOffset = ownerCase->displayModelOffset();
m_usedSurfaceData = m_surfaceInView->surface()->surfaceData();
if ( m_usedSurfaceData.isNull() ) return;
@@ -381,7 +394,7 @@ void RivSurfacePartMgr::generateNativePartGeometry()
cvf::ref<cvf::Vec3fArray> cvfVertices = new cvf::Vec3fArray( vertices.size() );
for ( size_t i = 0; i < vertices.size(); ++i )
{
( *cvfVertices )[i] = cvf::Vec3f( vertices[i] - displayModOffsett );
( *cvfVertices )[i] = cvf::Vec3f( vertices[i] - displayModOffset );
}
const std::vector<unsigned>& triangleIndices = m_usedSurfaceData->triangleIndices();

View File

@@ -41,7 +41,7 @@ class RivIntersectionGeometryGeneratorInterface;
class RivSurfacePartMgr : public cvf::Object
{
public:
explicit RivSurfacePartMgr( RimSurfaceInView* surface );
explicit RivSurfacePartMgr( RimSurfaceInView* surface, bool nativeOnly = false );
void updateNativeSurfaceColors();
void updateCellResultColor( int timeStepIndex );
@@ -53,11 +53,15 @@ public:
const RivIntersectionGeometryGeneratorInterface* intersectionGeometryGenerator() const;
bool isNativePartMgr() const;
private:
void generatePartGeometry();
void generateNativePartGeometry();
bool m_useNativePartsOnly;
cvf::ref<RivSurfaceIntersectionGeometryGenerator> m_intersectionGenerator;
caf::PdmPointer<RimSurfaceInView> m_surfaceInView;

View File

@@ -249,7 +249,7 @@ bool RivWindowEdgeAxesOverlayItem::pick( int oglXCoord, int oglYCoord, const Vec
//--------------------------------------------------------------------------------------------------
void RivWindowEdgeAxesOverlayItem::renderGeneric( OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size, bool software )
{
if ( size.x() <= 0 || size.y() <= 0 || ( m_windowTickXValues.size() == 0 && m_windowTickYValues.size() == 0 ) )
if ( size.x() <= 0 || size.y() <= 0 || ( m_windowTickXValues.empty() && m_windowTickYValues.empty() ) )
{
return;
}