From c5b55d324034874f3c9ab18be727b37c49e3640f Mon Sep 17 00:00:00 2001 From: jonjenssen Date: Thu, 12 Dec 2024 03:03:43 +0100 Subject: [PATCH] Work in progress --- ...reateGridCaseEnsemblesFromFilesFeature.cpp | 2 +- .../RicNewStatisticsContourMapViewFeature.cpp | 75 +- .../RicNewStatisticsContourMapViewFeature.h | 6 +- .../RimEclipseCaseEnsemble.cpp | 1 + .../RimEclipseViewCollection.cpp | 15 +- .../RimStatisticsContourMap.cpp | 32 +- .../RimStatisticsContourMap.h | 5 +- Fwk/VizFwk/LibGeometry/cvfBoundingBox.cpp | 791 +++++++++--------- Fwk/VizFwk/LibGeometry/cvfBoundingBox.h | 103 +-- 9 files changed, 545 insertions(+), 485 deletions(-) diff --git a/ApplicationLibCode/Commands/EclipseCommands/RicCreateGridCaseEnsemblesFromFilesFeature.cpp b/ApplicationLibCode/Commands/EclipseCommands/RicCreateGridCaseEnsemblesFromFilesFeature.cpp index 2810064dcd..fddcbe2425 100644 --- a/ApplicationLibCode/Commands/EclipseCommands/RicCreateGridCaseEnsemblesFromFilesFeature.cpp +++ b/ApplicationLibCode/Commands/EclipseCommands/RicCreateGridCaseEnsemblesFromFilesFeature.cpp @@ -107,7 +107,7 @@ RimEclipseCaseEnsemble* RicCreateGridCaseEnsemblesFromFilesFeature::importSingle caf::ProgressInfo progInfo( fileNames.size() + 1, "Creating Grid Ensembles" ); - for ( auto caseFileName : fileNames ) + for ( const auto& caseFileName : fileNames ) { auto task = progInfo.task( "Loading files", 1 ); diff --git a/ApplicationLibCode/Commands/RicNewStatisticsContourMapViewFeature.cpp b/ApplicationLibCode/Commands/RicNewStatisticsContourMapViewFeature.cpp index 74d12fa253..3f7b99789a 100644 --- a/ApplicationLibCode/Commands/RicNewStatisticsContourMapViewFeature.cpp +++ b/ApplicationLibCode/Commands/RicNewStatisticsContourMapViewFeature.cpp @@ -58,36 +58,7 @@ void RicNewStatisticsContourMapViewFeature::onActionTriggered( bool isChecked ) auto contourMap = caf::SelectionManager::instance()->selectedItemOfType(); if ( !contourMap ) return; - RimEclipseCase* eclipseCase = contourMap->eclipseCase(); - if ( !eclipseCase ) return; - - if ( auto eclipseContourMap = createStatisticsContourMapView( contourMap, eclipseCase ) ) - { - // Must be run before buildViewItems, as wells are created in this function - eclipseContourMap->loadDataAndUpdate(); - - // make sure no surfaces are shown in the view when the contourmap is generated - if ( eclipseContourMap->surfaceInViewCollection() ) eclipseContourMap->surfaceInViewCollection()->setCheckState( Qt::Unchecked ); - - if ( eclipseCase ) - { - eclipseCase->updateConnectedEditors(); - eclipseContourMap->cellFilterCollection()->setCase( eclipseCase ); - } - caf::SelectionManager::instance()->setSelectedItem( eclipseContourMap ); - - eclipseContourMap->createDisplayModelAndRedraw(); - eclipseContourMap->zoomAll(); - - RimProject* project = RimProject::current(); - - RimOilField* oilField = project->activeOilField(); - - oilField->eclipseContourMapCollection()->updateConnectedEditors(); - - Riu3DMainWindowTools::setExpanded( eclipseContourMap ); - Riu3DMainWindowTools::selectAsCurrentItem( eclipseContourMap ); - } + createAndAddView( contourMap ); } //-------------------------------------------------------------------------------------------------- @@ -102,9 +73,11 @@ void RicNewStatisticsContourMapViewFeature::setupActionLook( QAction* actionToSe //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimStatisticsContourMapView* RicNewStatisticsContourMapViewFeature::createStatisticsContourMapView( RimStatisticsContourMap* statisticsContourMap, - RimEclipseCase* eclipseCase ) +RimStatisticsContourMapView* RicNewStatisticsContourMapViewFeature::createStatisticsContourMapView( RimStatisticsContourMap* statisticsContourMap ) { + RimEclipseCase* eclipseCase = statisticsContourMap->eclipseCase(); + if ( !eclipseCase ) return nullptr; + RimStatisticsContourMapView* contourMap = new RimStatisticsContourMapView; contourMap->setStatisticsContourMap( statisticsContourMap ); contourMap->setEclipseCase( eclipseCase ); @@ -126,3 +99,41 @@ RimStatisticsContourMapView* RicNewStatisticsContourMapViewFeature::createStatis return contourMap; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimStatisticsContourMapView* RicNewStatisticsContourMapViewFeature::createAndAddView( RimStatisticsContourMap* statisticsContourMap ) +{ + if ( auto eclipseContourMap = createStatisticsContourMapView( statisticsContourMap ) ) + { + // Must be run before buildViewItems, as wells are created in this function + eclipseContourMap->loadDataAndUpdate(); + + // make sure no surfaces are shown in the view when the contourmap is generated + if ( eclipseContourMap->surfaceInViewCollection() ) eclipseContourMap->surfaceInViewCollection()->setCheckState( Qt::Unchecked ); + + if ( auto eclipseCase = statisticsContourMap->eclipseCase() ) + { + eclipseCase->updateConnectedEditors(); + eclipseContourMap->cellFilterCollection()->setCase( eclipseCase ); + } + caf::SelectionManager::instance()->setSelectedItem( eclipseContourMap ); + + eclipseContourMap->createDisplayModelAndRedraw(); + eclipseContourMap->zoomAll(); + + RimProject* project = RimProject::current(); + + RimOilField* oilField = project->activeOilField(); + + oilField->eclipseContourMapCollection()->updateConnectedEditors(); + + Riu3DMainWindowTools::setExpanded( eclipseContourMap ); + Riu3DMainWindowTools::selectAsCurrentItem( eclipseContourMap ); + + return eclipseContourMap; + } + + return nullptr; +} diff --git a/ApplicationLibCode/Commands/RicNewStatisticsContourMapViewFeature.h b/ApplicationLibCode/Commands/RicNewStatisticsContourMapViewFeature.h index 836461b784..c1ab228939 100644 --- a/ApplicationLibCode/Commands/RicNewStatisticsContourMapViewFeature.h +++ b/ApplicationLibCode/Commands/RicNewStatisticsContourMapViewFeature.h @@ -20,7 +20,6 @@ #include "cafCmdFeature.h" -class RimEclipseCase; class RimStatisticsContourMapView; class RimStatisticsContourMap; @@ -31,11 +30,12 @@ class RicNewStatisticsContourMapViewFeature : public caf::CmdFeature { CAF_CMD_HEADER_INIT; + static RimStatisticsContourMapView* createAndAddView( RimStatisticsContourMap* statisticsContourMap ); + protected: bool isCommandEnabled() const override; void onActionTriggered( bool isChecked ) override; void setupActionLook( QAction* actionToSetup ) override; - static RimStatisticsContourMapView* createStatisticsContourMapView( RimStatisticsContourMap* statisticsContourMap, - RimEclipseCase* eclipseCase ); + static RimStatisticsContourMapView* createStatisticsContourMapView( RimStatisticsContourMap* statisticsContourMap ); }; diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseCaseEnsemble.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseCaseEnsemble.cpp index ea9499f7e7..c74806f47a 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseCaseEnsemble.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseCaseEnsemble.cpp @@ -201,4 +201,5 @@ void RimEclipseCaseEnsemble::addWellTargetsGenerator( RimWellTargetCandidatesGen void RimEclipseCaseEnsemble::addStatisticsContourMap( RimStatisticsContourMap* statisticsContourMap ) { m_statisticsContourMaps.push_back( statisticsContourMap ); + statisticsContourMap->setName( QString( "Statisics Contour Map #%1" ).arg( m_statisticsContourMaps.size() ) ); } diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseViewCollection.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseViewCollection.cpp index 4acdf4caf2..b9542114d9 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseViewCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseViewCollection.cpp @@ -27,6 +27,7 @@ #include "Rim3dView.h" #include "RimCase.h" #include "RimCellEdgeColors.h" +#include "RimEclipseCase.h" #include "RimEclipseCellColors.h" #include "RimEclipseView.h" #include "RimFaultInViewCollection.h" @@ -92,13 +93,6 @@ RimEclipseView* RimEclipseViewCollection::addView( RimEclipseCase* eclipseCase ) view->setEclipseCase( eclipseCase ); - // Set default values - if ( view->currentGridCellResults() ) - { - auto defaultResult = view->currentGridCellResults()->defaultResult(); - view->cellResult()->setFromEclipseResultAddress( defaultResult ); - } - auto prefs = RiaPreferences::current(); view->faultCollection()->setActive( prefs->enableFaultsByDefault() ); @@ -114,6 +108,13 @@ RimEclipseView* RimEclipseViewCollection::addView( RimEclipseCase* eclipseCase ) view->loadDataAndUpdate(); + // Set default values + if ( view->currentGridCellResults() ) + { + auto defaultResult = view->currentGridCellResults()->defaultResult(); + view->cellResult()->setFromEclipseResultAddress( defaultResult ); + } + updateConnectedEditors(); return view; diff --git a/ApplicationLibCode/ProjectDataModel/RimStatisticsContourMap.cpp b/ApplicationLibCode/ProjectDataModel/RimStatisticsContourMap.cpp index 493bc83629..69844a9646 100644 --- a/ApplicationLibCode/ProjectDataModel/RimStatisticsContourMap.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimStatisticsContourMap.cpp @@ -21,6 +21,8 @@ #include "RiaLogging.h" #include "RiaStatisticsTools.h" +#include "RicNewStatisticsContourMapViewFeature.h" + #include "RigCaseCellResultsData.h" #include "RigContourMapCalculator.h" #include "RigContourMapGrid.h" @@ -66,7 +68,10 @@ void caf::AppEnum::setUp() //-------------------------------------------------------------------------------------------------- RimStatisticsContourMap::RimStatisticsContourMap() { - CAF_PDM_InitObject( "StatisticsContourMap", ":/Histogram16x16.png" ); + CAF_PDM_InitObject( "Statistics Contour Map", ":/Histogram16x16.png" ); + + CAF_PDM_InitField( &m_boundingBoxExpPercent, "BoundingBoxExpPercent", 5.0, "Bounding Box Expansion (%)" ); + m_boundingBoxExpPercent.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleSliderEditor::uiEditorTypeName() ); CAF_PDM_InitField( &m_relativeSampleSpacing, "SampleSpacing", 0.9, "Sample Spacing Factor" ); m_relativeSampleSpacing.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleSliderEditor::uiEditorTypeName() ); @@ -85,6 +90,8 @@ RimStatisticsContourMap::RimStatisticsContourMap() CAF_PDM_InitFieldNoDefault( &m_computeStatisticsButton, "ComputeStatisticsButton", "" ); caf::PdmUiPushButtonEditor::configureEditorLabelLeft( &m_computeStatisticsButton ); m_computeStatisticsButton = false; + + setDeletable( true ); } //-------------------------------------------------------------------------------------------------- @@ -92,9 +99,11 @@ RimStatisticsContourMap::RimStatisticsContourMap() //-------------------------------------------------------------------------------------------------- void RimStatisticsContourMap::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) { - uiOrdering.add( &m_relativeSampleSpacing ); + uiOrdering.add( nameField() ); uiOrdering.add( &m_resultAggregation ); uiOrdering.add( &m_timeStep ); + uiOrdering.add( &m_relativeSampleSpacing ); + uiOrdering.add( &m_boundingBoxExpPercent ); caf::PdmUiGroup* resultDefinitionGroup = uiOrdering.addNewGroup( "Result Definition" ); m_resultDefinition->uiOrdering( uiConfigName, *resultDefinitionGroup ); @@ -162,8 +171,7 @@ void RimStatisticsContourMap::defineEditorAttribute( const caf::PdmFieldHandle* attrib->m_buttonText = "Compute"; } } - - if ( &m_relativeSampleSpacing == field ) + else if ( &m_relativeSampleSpacing == field ) { if ( auto myAttr = dynamic_cast( attribute ) ) { @@ -173,6 +181,15 @@ void RimStatisticsContourMap::defineEditorAttribute( const caf::PdmFieldHandle* myAttr->m_delaySliderUpdateUntilRelease = true; } } + else if ( &m_boundingBoxExpPercent == field ) + { + if ( auto myAttr = dynamic_cast( attribute ) ) + { + myAttr->m_minimum = 0.0; + myAttr->m_maximum = 25.0; + myAttr->m_delaySliderUpdateUntilRelease = true; + } + } } //-------------------------------------------------------------------------------------------------- @@ -205,6 +222,7 @@ void RimStatisticsContourMap::computeStatistics() RigContourMapCalculator::ResultAggregationType resultAggregation = m_resultAggregation(); cvf::BoundingBox gridBoundingBox = firstEclipseCase->activeCellsBoundingBox(); + gridBoundingBox.expandPercent( m_boundingBoxExpPercent() ); auto computeSampleSpacing = []( auto ec, double relativeSampleSpacing ) { @@ -215,7 +233,6 @@ void RimStatisticsContourMap::computeStatistics() return relativeSampleSpacing * mainGrid->characteristicIJCellSize(); } } - return 0.0; }; @@ -229,6 +246,8 @@ void RimStatisticsContourMap::computeStatistics() RigEclipseContourMapProjection contourMapProjection( *contourMapGrid, *firstEclipseCaseData, *firstResultData ); m_gridMapping = contourMapProjection.generateGridMapping( resultAggregation, {} ); + caf::ProgressInfo progInfo( ensemble->cases().size() + 1, "Reading Eclipse Ensemble" ); + std::vector> results; for ( RimEclipseCase* eclipseCase : ensemble->cases() ) { @@ -246,6 +265,7 @@ void RimStatisticsContourMap::computeStatistics() contourMapProjection.generateResults( m_resultDefinition()->eclipseResultAddress(), resultAggregation, m_timeStep() ); results.push_back( result ); } + progInfo.incrementProgress(); } if ( !results.empty() ) @@ -292,6 +312,8 @@ void RimStatisticsContourMap::computeStatistics() m_result[StatisticsType::MEAN] = meanResults; m_result[StatisticsType::MIN] = minResults; m_result[StatisticsType::MAX] = maxResults; + + RicNewStatisticsContourMapViewFeature::createAndAddView( this ); } } diff --git a/ApplicationLibCode/ProjectDataModel/RimStatisticsContourMap.h b/ApplicationLibCode/ProjectDataModel/RimStatisticsContourMap.h index 01b5a6c1c8..337291ee6c 100644 --- a/ApplicationLibCode/ProjectDataModel/RimStatisticsContourMap.h +++ b/ApplicationLibCode/ProjectDataModel/RimStatisticsContourMap.h @@ -18,8 +18,8 @@ #pragma once +#include "RimNamedObject.h" #include "cafPdmField.h" -#include "cafPdmObject.h" #include "RimContourMapProjection.h" @@ -34,7 +34,7 @@ class RimEclipseCaseEnsemble; // // //================================================================================================== -class RimStatisticsContourMap : public caf::PdmObject +class RimStatisticsContourMap : public RimNamedObject { CAF_PDM_HEADER_INIT; @@ -82,6 +82,7 @@ class RimStatisticsContourMap : public caf::PdmObject caf::PdmField m_relativeSampleSpacing; caf::PdmField m_resultAggregation; caf::PdmField m_timeStep; + caf::PdmField m_boundingBoxExpPercent; caf::PdmChildField m_resultDefinition; caf::PdmField m_computeStatisticsButton; diff --git a/Fwk/VizFwk/LibGeometry/cvfBoundingBox.cpp b/Fwk/VizFwk/LibGeometry/cvfBoundingBox.cpp index d2eba2cb4b..ac93cfb7b3 100644 --- a/Fwk/VizFwk/LibGeometry/cvfBoundingBox.cpp +++ b/Fwk/VizFwk/LibGeometry/cvfBoundingBox.cpp @@ -45,409 +45,432 @@ namespace cvf { -//================================================================================================== -/// -/// \class cvf::BoundingBox -/// \ingroup Geometry -/// -/// The BoundingBox class implements an axis-aligned bounding box. -/// -//================================================================================================== - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -BoundingBox::BoundingBox() -{ - reset(); -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -BoundingBox::BoundingBox(const Vec3d& min, const Vec3d& max) - : m_min(min), m_max(max) -{ -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -BoundingBox::BoundingBox(const Vec3f& min, const Vec3f& max) - : m_min(min), m_max(max) -{ -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -BoundingBox::BoundingBox(const BoundingBox& other) -: m_min(other.m_min), - m_max(other.m_max) -{ -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -BoundingBox& BoundingBox::operator=(const BoundingBox& rhs) -{ - m_min = rhs.m_min; - m_max = rhs.m_max; - - return *this; -} - - -//-------------------------------------------------------------------------------------------------- -/// Initialize bounding box -//-------------------------------------------------------------------------------------------------- -void BoundingBox::reset() -{ - const double maxDouble = std::numeric_limits::max(); - - m_max.set(-maxDouble, -maxDouble, -maxDouble); - m_min.set( maxDouble, maxDouble, maxDouble); -} - - -//-------------------------------------------------------------------------------------------------- -/// Returns false if no input has been given -//-------------------------------------------------------------------------------------------------- -bool BoundingBox::isValid() const -{ - if (m_min.x() <= m_max.x() && - m_min.y() <= m_max.y() && - m_min.z() <= m_max.z()) + //================================================================================================== + /// + /// \class cvf::BoundingBox + /// \ingroup Geometry + /// + /// The BoundingBox class implements an axis-aligned bounding box. + /// + //================================================================================================== + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + BoundingBox::BoundingBox() { - return true; + reset(); + } + + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + BoundingBox::BoundingBox(const Vec3d& min, const Vec3d& max) + : m_min(min), m_max(max) + { + } + + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + BoundingBox::BoundingBox(const Vec3f& min, const Vec3f& max) + : m_min(min), m_max(max) + { + } + + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + BoundingBox::BoundingBox(const BoundingBox& other) + : m_min(other.m_min), + m_max(other.m_max) + { + } + + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + BoundingBox& BoundingBox::operator=(const BoundingBox& rhs) + { + m_min = rhs.m_min; + m_max = rhs.m_max; + + return *this; + } + + + //-------------------------------------------------------------------------------------------------- + /// Initialize bounding box + //-------------------------------------------------------------------------------------------------- + void BoundingBox::reset() + { + const double maxDouble = std::numeric_limits::max(); + + m_max.set(-maxDouble, -maxDouble, -maxDouble); + m_min.set(maxDouble, maxDouble, maxDouble); + } + + + //-------------------------------------------------------------------------------------------------- + /// Returns false if no input has been given + //-------------------------------------------------------------------------------------------------- + bool BoundingBox::isValid() const + { + if (m_min.x() <= m_max.x() && + m_min.y() <= m_max.y() && + m_min.z() <= m_max.z()) + { + return true; + } + else + { + return false; + } + } + + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + void BoundingBox::add(const Vec3d& point) + { + if (point.x() < m_min.x()) m_min.x() = point.x(); + if (point.y() < m_min.y()) m_min.y() = point.y(); + if (point.z() < m_min.z()) m_min.z() = point.z(); + + if (point.x() > m_max.x()) m_max.x() = point.x(); + if (point.y() > m_max.y()) m_max.y() = point.y(); + if (point.z() > m_max.z()) m_max.z() = point.z(); + } + + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + void BoundingBox::add(const Vec3f& point) + { + if (point.x() < m_min.x()) m_min.x() = point.x(); + if (point.y() < m_min.y()) m_min.y() = point.y(); + if (point.z() < m_min.z()) m_min.z() = point.z(); + + if (point.x() > m_max.x()) m_max.x() = point.x(); + if (point.y() > m_max.y()) m_max.y() = point.y(); + if (point.z() > m_max.z()) m_max.z() = point.z(); + } + + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + void BoundingBox::add(const Vec3dArray& points) + { + size_t i; + for (i = 0; i < points.size(); i++) + { + add(points[i]); + } + } + + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + void BoundingBox::add(const Vec3fArray& points) + { + size_t i; + for (i = 0; i < points.size(); i++) + { + add(points[i]); + } + } + + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + void BoundingBox::add(const BoundingBox& bb) + { + if (bb.isValid()) + { + add(bb.min()); + add(bb.max()); + } + } + + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + void BoundingBox::addValid(const BoundingBox& bb) + { + if (bb.m_min.x() < m_min.x()) m_min.x() = bb.m_min.x(); + if (bb.m_min.y() < m_min.y()) m_min.y() = bb.m_min.y(); + if (bb.m_min.z() < m_min.z()) m_min.z() = bb.m_min.z(); + + if (bb.m_max.x() > m_max.x()) m_max.x() = bb.m_max.x(); + if (bb.m_max.y() > m_max.y()) m_max.y() = bb.m_max.y(); + if (bb.m_max.z() > m_max.z()) m_max.z() = bb.m_max.z(); + } + + //-------------------------------------------------------------------------------------------------- + /// Computes center of the bounding box + //-------------------------------------------------------------------------------------------------- + Vec3d BoundingBox::center() const + { + CVF_TIGHT_ASSERT(isValid()); + + return (m_min + m_max) / 2.0; } - else + + + //-------------------------------------------------------------------------------------------------- + /// Computes the total size of the bounding box + //-------------------------------------------------------------------------------------------------- + Vec3d BoundingBox::extent() const { - return false; + if (!isValid()) return { 0,0,0 }; + + return (m_max - m_min); } -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void BoundingBox::add(const Vec3d& point) -{ - if (point.x() < m_min.x()) m_min.x() = point.x(); - if (point.y() < m_min.y()) m_min.y() = point.y(); - if (point.z() < m_min.z()) m_min.z() = point.z(); - - if (point.x() > m_max.x()) m_max.x() = point.x(); - if (point.y() > m_max.y()) m_max.y() = point.y(); - if (point.z() > m_max.z()) m_max.z() = point.z(); -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void BoundingBox::add(const Vec3f& point) -{ - if (point.x() < m_min.x()) m_min.x() = point.x(); - if (point.y() < m_min.y()) m_min.y() = point.y(); - if (point.z() < m_min.z()) m_min.z() = point.z(); - - if (point.x() > m_max.x()) m_max.x() = point.x(); - if (point.y() > m_max.y()) m_max.y() = point.y(); - if (point.z() > m_max.z()) m_max.z() = point.z(); -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void BoundingBox::add(const Vec3dArray& points) -{ - size_t i; - for (i = 0; i < points.size(); i++) + + + //-------------------------------------------------------------------------------------------------- + /// Compute radius as half the length of the box's diagonal + //-------------------------------------------------------------------------------------------------- + double BoundingBox::radius() const { - add(points[i]); + if (!isValid()) return 0.0; + + return extent().length() / 2.0; } -} -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void BoundingBox::add(const Vec3fArray& points) -{ - size_t i; - for (i = 0; i < points.size(); i++) + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + const Vec3d& BoundingBox::min() const { - add(points[i]); + CVF_TIGHT_ASSERT(isValid()); + + return m_min; } -} -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void BoundingBox::add(const BoundingBox& bb) -{ - if (bb.isValid()) + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + const Vec3d& BoundingBox::max() const { - add(bb.min()); - add(bb.max()); + CVF_TIGHT_ASSERT(isValid()); + + return m_max; } -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void BoundingBox::addValid(const BoundingBox& bb) -{ - if (bb.m_min.x() < m_min.x()) m_min.x() = bb.m_min.x(); - if (bb.m_min.y() < m_min.y()) m_min.y() = bb.m_min.y(); - if (bb.m_min.z() < m_min.z()) m_min.z() = bb.m_min.z(); - - if (bb.m_max.x() > m_max.x()) m_max.x() = bb.m_max.x(); - if (bb.m_max.y() > m_max.y()) m_max.y() = bb.m_max.y(); - if (bb.m_max.z() > m_max.z()) m_max.z() = bb.m_max.z(); -} - -//-------------------------------------------------------------------------------------------------- -/// Computes center of the bounding box -//-------------------------------------------------------------------------------------------------- -Vec3d BoundingBox::center() const -{ - CVF_TIGHT_ASSERT(isValid()); - - return (m_min + m_max) / 2.0; -} - - -//-------------------------------------------------------------------------------------------------- -/// Computes the total size of the bounding box -//-------------------------------------------------------------------------------------------------- -Vec3d BoundingBox::extent() const -{ - if (!isValid()) return { 0,0,0 }; - - return (m_max - m_min); -} - - -//-------------------------------------------------------------------------------------------------- -/// Compute radius as half the length of the box's diagonal -//-------------------------------------------------------------------------------------------------- -double BoundingBox::radius() const -{ - if (!isValid()) return 0.0; - - return extent().length() / 2.0; -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -const Vec3d& BoundingBox::min() const -{ - CVF_TIGHT_ASSERT(isValid()); - - return m_min; -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -const Vec3d& BoundingBox::max() const -{ - CVF_TIGHT_ASSERT(isValid()); - - return m_max; -} - - -//-------------------------------------------------------------------------------------------------- -/// Check if the bounding box contains the specified point -/// -/// Note that a point on the box's surface is classified as being contained -//-------------------------------------------------------------------------------------------------- -bool BoundingBox::contains(const Vec3d& point) const -{ - if (!isValid()) return false; - - if (point.x() >= m_min.x() && point.x() <= m_max.x() && - point.y() >= m_min.y() && point.y() <= m_max.y() && - point.z() >= m_min.z() && point.z() <= m_max.z()) + + + //-------------------------------------------------------------------------------------------------- + /// Check if the bounding box contains the specified point + /// + /// Note that a point on the box's surface is classified as being contained + //-------------------------------------------------------------------------------------------------- + bool BoundingBox::contains(const Vec3d& point) const + { + if (!isValid()) return false; + + if (point.x() >= m_min.x() && point.x() <= m_max.x() && + point.y() >= m_min.y() && point.y() <= m_max.y() && + point.z() >= m_min.z() && point.z() <= m_max.z()) + { + return true; + } + else + { + return false; + } + } + + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + bool BoundingBox::intersects(const BoundingBox& box) const { + if (!isValid() || !box.isValid()) return false; + + if (m_max.x() < box.m_min.x() || m_min.x() > box.m_max.x()) return false; + if (m_max.y() < box.m_min.y() || m_min.y() > box.m_max.y()) return false; + if (m_max.z() < box.m_min.z() || m_min.z() > box.m_max.z()) return false; + return true; } - else + + + //-------------------------------------------------------------------------------------------------- + /// Get corner points of box + /// + /// \param corners Array of Vec3d. Must be allocated 8 vectors long. + /// + ///
+    ///        7---------6                
+    ///       /|        /|     |z       
+    ///      / |       / |     | / y    
+    ///     4---------5  |     |/       
+    ///     |  3------|--2     *---x    
+    ///     | /       | /           
+    ///     |/        |/            
+    ///     0---------1    
+ /// + //-------------------------------------------------------------------------------------------------- + void BoundingBox::cornerVertices(Vec3d corners[8]) const + { + corners[0].set(m_min.x(), m_min.y(), m_min.z()); + corners[1].set(m_max.x(), m_min.y(), m_min.z()); + corners[2].set(m_max.x(), m_max.y(), m_min.z()); + corners[3].set(m_min.x(), m_max.y(), m_min.z()); + corners[4].set(m_min.x(), m_min.y(), m_max.z()); + corners[5].set(m_max.x(), m_min.y(), m_max.z()); + corners[6].set(m_max.x(), m_max.y(), m_max.z()); + corners[7].set(m_min.x(), m_max.y(), m_max.z()); + } + + + //-------------------------------------------------------------------------------------------------- + /// Expands the bounding box by the given amount in all three directions + /// + /// If a bounding box is expanded by 2, the bounding box's size will increase by 2 in each direction + /// \sa extent() + //-------------------------------------------------------------------------------------------------- + void BoundingBox::expand(double amount) + { + double half = amount / 2; + m_min.x() -= half; + m_min.y() -= half; + m_min.z() -= half; + m_max.x() += half; + m_max.y() += half; + m_max.z() += half; + } + + //-------------------------------------------------------------------------------------------------- + /// Expands the bounding box by the given percent in all three directions + /// + /// If a bounding box is expanded by 10%, the bounding box's size will increase by 5% in each direction + //-------------------------------------------------------------------------------------------------- + void BoundingBox::expandPercent(double percent) + { + const auto ext = extent(); + const double factor = percent / 100.0; + + const double xHalf = (ext.x() / 2) * factor; + const double yHalf = (ext.y() / 2) * factor; + const double zHalf = (ext.z() / 2) * factor; + + m_min.x() -= xHalf; + m_min.y() -= yHalf; + m_min.z() -= zHalf; + m_max.x() += xHalf; + m_max.y() += yHalf; + m_max.z() += zHalf; + } + + + + //-------------------------------------------------------------------------------------------------- + /// Transform the min and max coordinate with the given transformation matrix + //-------------------------------------------------------------------------------------------------- + void BoundingBox::transform(const Mat4d& matrix) + { + // Check if box is invalid, and don't transform if so + if (!isValid()) return; + + BoundingBox newBox; + newBox.reset(); + + Vec3d node; + + node.set(m_min.x(), m_min.y(), m_min.z()); + node.transformPoint(matrix); + newBox.add(node); + + node.set(m_max.x(), m_min.y(), m_min.z()); + node.transformPoint(matrix); + newBox.add(node); + + node.set(m_max.x(), m_max.y(), m_min.z()); + node.transformPoint(matrix); + newBox.add(node); + + node.set(m_min.x(), m_max.y(), m_min.z()); + node.transformPoint(matrix); + newBox.add(node); + + node.set(m_min.x(), m_min.y(), m_max.z()); + node.transformPoint(matrix); + newBox.add(node); + + node.set(m_max.x(), m_min.y(), m_max.z()); + node.transformPoint(matrix); + newBox.add(node); + + node.set(m_max.x(), m_max.y(), m_max.z()); + node.transformPoint(matrix); + newBox.add(node); + + node.set(m_min.x(), m_max.y(), m_max.z()); + node.transformPoint(matrix); + newBox.add(node); + + *this = newBox; + } + + + //-------------------------------------------------------------------------------------------------- + /// Returns this BoundingBox transformed with the given transformation matrix + //-------------------------------------------------------------------------------------------------- + const BoundingBox BoundingBox::getTransformed(const Mat4d& matrix) const + { + BoundingBox box(*this); + box.transform(matrix); + + return box; + } + + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + String BoundingBox::debugString() const + { + String str = "BoundingBox:"; + str += " min: x=" + String::number(m_min.x()) + " y=" + String::number(m_min.y()) + " z=" + String::number(m_min.z()); + str += " max: x=" + String::number(m_max.x()) + " y=" + String::number(m_max.y()) + " z=" + String::number(m_max.z()); + return str; + } + + //-------------------------------------------------------------------------------------------------- + /// Cuts the box at the given depth, to never go below the given depth + /// + /// Note: cutting is a one time operation, adding new points to the box might extend the box below the cut depth + //-------------------------------------------------------------------------------------------------- + void BoundingBox::cutBelow(double depth) + { + if (m_min.z() < depth) m_min.z() = depth; + if (m_max.z() < depth) m_max.z() = depth; + } + + //-------------------------------------------------------------------------------------------------- + /// Cuts the box at the given depth, to never go above the given depth + /// + /// Note: cutting is a one time operation, adding new points to the box might extend the box below the cut depth + //-------------------------------------------------------------------------------------------------- + void BoundingBox::cutAbove(double depth) { - return false; + if (m_min.z() > depth) m_min.z() = depth; + if (m_max.z() > depth) m_max.z() = depth; } -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool BoundingBox::intersects(const BoundingBox& box) const -{ - if (!isValid() || !box.isValid()) return false; - - if (m_max.x() < box.m_min.x() || m_min.x() > box.m_max.x()) return false; - if (m_max.y() < box.m_min.y() || m_min.y() > box.m_max.y()) return false; - if (m_max.z() < box.m_min.z() || m_min.z() > box.m_max.z()) return false; - - return true; -} - - -//-------------------------------------------------------------------------------------------------- -/// Get corner points of box -/// -/// \param corners Array of Vec3d. Must be allocated 8 vectors long. -/// -///
-///        7---------6                
-///       /|        /|     |z       
-///      / |       / |     | / y    
-///     4---------5  |     |/       
-///     |  3------|--2     *---x    
-///     | /       | /           
-///     |/        |/            
-///     0---------1    
-/// -//-------------------------------------------------------------------------------------------------- -void BoundingBox::cornerVertices(Vec3d corners[8]) const -{ - corners[0].set(m_min.x(), m_min.y(), m_min.z()); - corners[1].set(m_max.x(), m_min.y(), m_min.z()); - corners[2].set(m_max.x(), m_max.y(), m_min.z()); - corners[3].set(m_min.x(), m_max.y(), m_min.z()); - corners[4].set(m_min.x(), m_min.y(), m_max.z()); - corners[5].set(m_max.x(), m_min.y(), m_max.z()); - corners[6].set(m_max.x(), m_max.y(), m_max.z()); - corners[7].set(m_min.x(), m_max.y(), m_max.z()); -} - - -//-------------------------------------------------------------------------------------------------- -/// Expands the bounding box by the given amount in all three directions -/// -/// If a bounding box is expanded by 2, the bounding box's size will increase by 2 in each direction -/// \sa extent() -//-------------------------------------------------------------------------------------------------- -void BoundingBox::expand(double amount) -{ - double half = amount/2; - m_min.x() -= half; - m_min.y() -= half; - m_min.z() -= half; - m_max.x() += half; - m_max.y() += half; - m_max.z() += half; -} - - -//-------------------------------------------------------------------------------------------------- -/// Transform the min and max coordinate with the given transformation matrix -//-------------------------------------------------------------------------------------------------- -void BoundingBox::transform(const Mat4d& matrix) -{ - // Check if box is invalid, and don't transform if so - if (!isValid()) return; - - BoundingBox newBox; - newBox.reset(); - - Vec3d node; - - node.set(m_min.x(), m_min.y(), m_min.z()); - node.transformPoint(matrix); - newBox.add(node); - - node.set(m_max.x(), m_min.y(), m_min.z()); - node.transformPoint(matrix); - newBox.add(node); - - node.set(m_max.x(), m_max.y(), m_min.z()); - node.transformPoint(matrix); - newBox.add(node); - - node.set(m_min.x(), m_max.y(), m_min.z()); - node.transformPoint(matrix); - newBox.add(node); - - node.set(m_min.x(), m_min.y(), m_max.z()); - node.transformPoint(matrix); - newBox.add(node); - - node.set(m_max.x(), m_min.y(), m_max.z()); - node.transformPoint(matrix); - newBox.add(node); - - node.set(m_max.x(), m_max.y(), m_max.z()); - node.transformPoint(matrix); - newBox.add(node); - - node.set(m_min.x(), m_max.y(), m_max.z()); - node.transformPoint(matrix); - newBox.add(node); - - *this = newBox; -} - - -//-------------------------------------------------------------------------------------------------- -/// Returns this BoundingBox transformed with the given transformation matrix -//-------------------------------------------------------------------------------------------------- -const BoundingBox BoundingBox::getTransformed(const Mat4d& matrix) const -{ - BoundingBox box(*this); - box.transform(matrix); - - return box; -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -String BoundingBox::debugString() const -{ - String str = "BoundingBox:"; - str += " min: x=" + String::number(m_min.x()) + " y=" + String::number(m_min.y()) + " z=" + String::number(m_min.z()); - str += " max: x=" + String::number(m_max.x()) + " y=" + String::number(m_max.y()) + " z=" + String::number(m_max.z()); - return str; -} - -//-------------------------------------------------------------------------------------------------- -/// Cuts the box at the given depth, to never go below the given depth -/// -/// Note: cutting is a one time operation, adding new points to the box might extend the box below the cut depth -//-------------------------------------------------------------------------------------------------- -void BoundingBox::cutBelow(double depth) -{ - if (m_min.z() < depth) m_min.z() = depth; - if (m_max.z() < depth) m_max.z() = depth; -} - -//-------------------------------------------------------------------------------------------------- -/// Cuts the box at the given depth, to never go above the given depth -/// -/// Note: cutting is a one time operation, adding new points to the box might extend the box below the cut depth -//-------------------------------------------------------------------------------------------------- -void BoundingBox::cutAbove(double depth) -{ - if (m_min.z() > depth) m_min.z() = depth; - if (m_max.z() > depth) m_max.z() = depth; -} diff --git a/Fwk/VizFwk/LibGeometry/cvfBoundingBox.h b/Fwk/VizFwk/LibGeometry/cvfBoundingBox.h index f2b02cda05..7339825379 100644 --- a/Fwk/VizFwk/LibGeometry/cvfBoundingBox.h +++ b/Fwk/VizFwk/LibGeometry/cvfBoundingBox.h @@ -44,56 +44,57 @@ namespace cvf { -//================================================================================================== -// -// Axis aligned bounding box -// -//================================================================================================== -class BoundingBox -{ -public: - BoundingBox(); - BoundingBox(const Vec3f& min, const Vec3f& max); - BoundingBox(const Vec3d& min, const Vec3d& max); - BoundingBox(const BoundingBox& other); - - BoundingBox& operator=(const BoundingBox& rhs); - - void reset(); - - bool isValid() const; - - void add(const Vec3f& vertex); - void add(const Vec3d& vertex); - void add(const Vec3fArray& vertices); - void add(const Vec3dArray& vertices); - void add(const BoundingBox& bb); - void addValid(const BoundingBox& bb); - - const Vec3d& min() const; - const Vec3d& max() const; - - Vec3d center() const; - Vec3d extent() const; - double radius() const; - - bool contains(const Vec3d& point) const; - bool intersects(const BoundingBox& box) const; - - void cornerVertices(Vec3d corners[8]) const; - - void expand(double amount); - void transform(const Mat4d& matrix); - const BoundingBox getTransformed(const Mat4d& matrix) const; - - void cutBelow(double depth); - void cutAbove(double depth); - - String debugString() const; - -private: - Vec3d m_min; - Vec3d m_max; -}; + //================================================================================================== + // + // Axis aligned bounding box + // + //================================================================================================== + class BoundingBox + { + public: + BoundingBox(); + BoundingBox(const Vec3f& min, const Vec3f& max); + BoundingBox(const Vec3d& min, const Vec3d& max); + BoundingBox(const BoundingBox& other); + + BoundingBox& operator=(const BoundingBox& rhs); + + void reset(); + + bool isValid() const; + + void add(const Vec3f& vertex); + void add(const Vec3d& vertex); + void add(const Vec3fArray& vertices); + void add(const Vec3dArray& vertices); + void add(const BoundingBox& bb); + void addValid(const BoundingBox& bb); + + const Vec3d& min() const; + const Vec3d& max() const; + + Vec3d center() const; + Vec3d extent() const; + double radius() const; + + bool contains(const Vec3d& point) const; + bool intersects(const BoundingBox& box) const; + + void cornerVertices(Vec3d corners[8]) const; + + void expand(double amount); + void expandPercent(double percent); + void transform(const Mat4d& matrix); + const BoundingBox getTransformed(const Mat4d& matrix) const; + + void cutBelow(double depth); + void cutAbove(double depth); + + String debugString() const; + + private: + Vec3d m_min; + Vec3d m_max; + }; }