AppFwk: Add comparison view support to the Viewer.

Add a separate overlay rendering to make rendering of overlay items more flexible and to support the comparison view.
Add control of the Rendering Enable mask
This commit is contained in:
Jacob Støren 2019-10-10 17:53:36 +02:00
parent 6d2253ad26
commit 468cea28bc
2 changed files with 406 additions and 88 deletions

View File

@ -76,6 +76,7 @@
#include <QDebug> #include <QDebug>
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QInputEvent> #include <QInputEvent>
#include "cvfRenderingScissor.h"
namespace caf namespace caf
{ {
@ -103,6 +104,7 @@ private:
cvf::ref<cvf::UniformFloat> m_headlightPosition; cvf::ref<cvf::UniformFloat> m_headlightPosition;
}; };
} }
std::list<caf::Viewer*> caf::Viewer::sm_viewers; std::list<caf::Viewer*> caf::Viewer::sm_viewers;
@ -127,7 +129,9 @@ caf::Viewer::Viewer(const QGLFormat& format, QWidget* parent)
m_isOverlayPaintingEnabled(true), m_isOverlayPaintingEnabled(true),
m_offscreenViewportWidth(0), m_offscreenViewportWidth(0),
m_offscreenViewportHeight(0), m_offscreenViewportHeight(0),
m_parallelProjectionLightDirection(0, 0, -1) // Light directly from behind m_parallelProjectionLightDirection(0, 0, -1), // Light directly from behind
m_comparisonViewOffset(0, 0, 0),
m_comparisonWindowNormalizedRect(0.5f, 0.0f, 0.5f, 1.0f)
{ {
#if QT_VERSION >= 0x050000 #if QT_VERSION >= 0x050000
m_layoutWidget = new QWidget(parent); m_layoutWidget = new QWidget(parent);
@ -150,10 +154,19 @@ caf::Viewer::Viewer(const QGLFormat& format, QWidget* parent)
m_mainCamera = new cvf::Camera; m_mainCamera = new cvf::Camera;
m_mainCamera->setFromLookAt(cvf::Vec3d(0,0,-1), cvf::Vec3d(0,0,0), cvf::Vec3d(0,1,0)); m_mainCamera->setFromLookAt(cvf::Vec3d(0,0,-1), cvf::Vec3d(0,0,0), cvf::Vec3d(0,1,0));
m_comparisonMainCamera = new cvf::Camera;
m_comparisonMainCamera->setFromLookAt(cvf::Vec3d(0,0,-1), cvf::Vec3d(0,0,0), cvf::Vec3d(0,1,0));
m_renderingSequence = new cvf::RenderSequence(); m_renderingSequence = new cvf::RenderSequence();
m_renderingSequence->setDefaultFFLightPositional(cvf::Vec3f(0.5, 5.0, 7.0)); m_renderingSequence->setDefaultFFLightPositional(cvf::Vec3f(0.5, 5.0, 7.0));
m_mainRendering = new cvf::Rendering(); m_mainRendering = new cvf::Rendering("Main Rendering");
m_comparisonMainRendering = new cvf::Rendering("Comparison Rendering");
m_overlayItemsRendering = new cvf::Rendering("Overlay Rendering");
m_overlayItemsRendering->setClearMode(cvf::Viewport::DO_NOT_CLEAR);
m_comparisonRenderingScissor = new cvf::RenderingScissor;
m_comparisonMainRendering->setRenderingScissor(m_comparisonRenderingScissor.p());
m_animationControl = new caf::FrameAnimationControl(this); m_animationControl = new caf::FrameAnimationControl(this);
connect(m_animationControl, SIGNAL(changeFrame(int)), SLOT(slotSetCurrentFrame(int))); connect(m_animationControl, SIGNAL(changeFrame(int)), SLOT(slotSetCurrentFrame(int)));
@ -193,20 +206,32 @@ caf::Viewer::~Viewer()
void caf::Viewer::setupMainRendering() void caf::Viewer::setupMainRendering()
{ {
m_mainRendering->setCamera(m_mainCamera.p()); m_mainRendering->setCamera(m_mainCamera.p());
m_comparisonMainRendering->setCamera(m_comparisonMainCamera.p());
m_overlayItemsRendering->setCamera(m_mainCamera.p());
m_mainRendering->setRenderQueueSorter(new cvf::RenderQueueSorterBasic(cvf::RenderQueueSorterBasic::EFFECT_ONLY)); m_mainRendering->setRenderQueueSorter(new cvf::RenderQueueSorterBasic(cvf::RenderQueueSorterBasic::EFFECT_ONLY));
m_comparisonMainRendering->setRenderQueueSorter(new cvf::RenderQueueSorterBasic(cvf::RenderQueueSorterBasic::EFFECT_ONLY));
m_overlayItemsRendering->setRenderQueueSorter(new cvf::RenderQueueSorterBasic(cvf::RenderQueueSorterBasic::EFFECT_ONLY));
m_mainRendering->addGlobalDynamicUniformSet(m_globalUniformSet.p()); m_mainRendering->addGlobalDynamicUniformSet(m_globalUniformSet.p());
m_comparisonMainRendering->addGlobalDynamicUniformSet(m_globalUniformSet.p());
// Set fixed function rendering if QGLFormat does not support directRendering // Set fixed function rendering if QGLFormat does not support directRendering
if (!this->format().directRendering()) if (!this->format().directRendering())
{ {
m_mainRendering->renderEngine()->enableForcedImmediateMode(true); m_mainRendering->renderEngine()->enableForcedImmediateMode(true);
m_comparisonMainRendering->renderEngine()->enableForcedImmediateMode(true);
m_overlayItemsRendering->renderEngine()->enableForcedImmediateMode(true);
} }
if (contextGroup()->capabilities() && if (contextGroup()->capabilities() &&
contextGroup()->capabilities()->hasCapability(cvf::OpenGLCapabilities::FRAMEBUFFER_OBJECT)) contextGroup()->capabilities()->hasCapability(cvf::OpenGLCapabilities::FRAMEBUFFER_OBJECT))
{ {
m_offscreenFbo = new cvf::FramebufferObject; m_offscreenFbo = new cvf::FramebufferObject;
m_mainRendering->setTargetFramebuffer(m_offscreenFbo.p()); m_mainRendering->setTargetFramebuffer(m_offscreenFbo.p());
m_comparisonMainRendering->setTargetFramebuffer(m_offscreenFbo.p());
m_overlayItemsRendering->setTargetFramebuffer(m_offscreenFbo.p());
cvf::ref<cvf::RenderbufferObject> rbo = new cvf::RenderbufferObject(cvf::RenderbufferObject::DEPTH_COMPONENT24, 1, 1); cvf::ref<cvf::RenderbufferObject> rbo = new cvf::RenderbufferObject(cvf::RenderbufferObject::DEPTH_COMPONENT24, 1, 1);
m_offscreenFbo->attachDepthRenderbuffer(rbo.p()); m_offscreenFbo->attachDepthRenderbuffer(rbo.p());
@ -225,6 +250,8 @@ void caf::Viewer::setupMainRendering()
void caf::Viewer::setupRenderingSequence() void caf::Viewer::setupRenderingSequence()
{ {
m_renderingSequence->addRendering(m_mainRendering.p()); m_renderingSequence->addRendering(m_mainRendering.p());
m_renderingSequence->addRendering(m_comparisonMainRendering.p());
m_renderingSequence->addRendering(m_overlayItemsRendering.p());
if (m_offscreenFbo.notNull()) if (m_offscreenFbo.notNull())
{ {
@ -282,30 +309,94 @@ cvf::Camera* caf::Viewer::mainCamera()
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Set the scene to be rendered when the animation is inactive (Stopped) ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void caf::Viewer::setMainScene(cvf::Scene* scene) cvf::Camera* caf::Viewer::comparisonMainCamera()
{ {
appendAllStaticModelsToFrame(scene); return m_comparisonMainCamera.p();
m_mainScene = scene;
m_mainRendering->setScene(scene);
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
cvf::Scene* caf::Viewer::mainScene() void caf::Viewer::setComparisonViewEyePointOffset(const cvf::Vec3d& offset)
{ {
return m_mainScene.p(); m_comparisonViewOffset = offset;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const cvf::Vec3d caf::Viewer::comparisonViewEyePointOffset()
{
return m_comparisonViewOffset;
}
//--------------------------------------------------------------------------------------------------
/// setNormalizedComparisonViewRect
//--------------------------------------------------------------------------------------------------
void caf::Viewer::setComparisonViewVisibleNormalizedRect( const cvf::Rectf& visibleRect )
{
m_comparisonWindowNormalizedRect = visibleRect;
updateCamera(width(), height());
update();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Rectf caf::Viewer::comparisonViewVisibleNormalizedRect() const
{
return m_comparisonWindowNormalizedRect;
}
//--------------------------------------------------------------------------------------------------
/// Set the scene to be rendered when the animation is inactive (Stopped)
//--------------------------------------------------------------------------------------------------
void caf::Viewer::setMainScene(cvf::Scene* scene, bool isForComparisonView )
{
appendAllStaticModelsToFrame(scene, isForComparisonView);
if ( !isForComparisonView )
{
m_mainScene = scene;
m_mainRendering->setScene(scene);
}
else
{
m_comparisonMainScene = scene;
m_comparisonMainRendering->setScene(scene);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Scene* caf::Viewer::mainScene( bool isForComparisonView)
{
if (!isForComparisonView)
{
return m_mainScene.p();
}
else
{
return m_comparisonMainScene.p();
}
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Return the currently rendered scene /// Return the currently rendered scene
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
cvf::Scene* caf::Viewer::currentScene() cvf::Scene* caf::Viewer::currentScene(bool isForComparisonView)
{ {
return m_mainRendering->scene(); if (!isForComparisonView)
{
return m_mainRendering->scene();
}
else
{
return m_comparisonMainRendering->scene();
}
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -316,6 +407,11 @@ void caf::Viewer::updateCamera(int width, int height)
if (width < 1 || height < 1) return; if (width < 1 || height < 1) return;
m_mainCamera->viewport()->set(0, 0, width, height); m_mainCamera->viewport()->set(0, 0, width, height);
m_comparisonMainCamera->viewport()->set(0, 0, width, height);
m_comparisonRenderingScissor->setScissorRectangle(static_cast<int>(width * m_comparisonWindowNormalizedRect.min().x()),
static_cast<int>(height * m_comparisonWindowNormalizedRect.min().y()),
static_cast<int>(width * m_comparisonWindowNormalizedRect.width()),
static_cast<int>(height * m_comparisonWindowNormalizedRect.height()));
if (m_mainCamera->projection() == cvf::Camera::PERSPECTIVE) if (m_mainCamera->projection() == cvf::Camera::PERSPECTIVE)
{ {
@ -347,11 +443,66 @@ bool caf::Viewer::canRender() const
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void caf::Viewer::optimizeClippingPlanes() void caf::Viewer::optimizeClippingPlanes()
{ {
cvf::BoundingBox bb = m_mainRendering->boundingBox(); double nearPlaneDist = HUGE_VAL;
if (!bb.isValid()) return; double farPlaneDist = HUGE_VAL;
cvf::Vec3d eye = m_mainCamera->position(); cvf::Vec3d navPointOfinterest = m_navigationPolicy->pointOfInterest();
cvf::Vec3d viewdir = m_mainCamera->direction();
if ( calculateNearFarPlanes(m_mainRendering.p(), navPointOfinterest, &farPlaneDist, &nearPlaneDist) )
{
if ( m_mainCamera->projection() == cvf::Camera::PERSPECTIVE )
{
m_mainCamera->setProjectionAsPerspective(m_cameraFieldOfViewYDeg, nearPlaneDist, farPlaneDist);
}
else
{
m_mainCamera->setProjectionAsOrtho(m_mainCamera->frontPlaneFrustumHeight(), nearPlaneDist, farPlaneDist);
}
}
copyCameraView(m_mainCamera.p(), m_comparisonMainCamera.p() );
if ( m_comparisonMainRendering->scene() )
{
cvf::Vec3d camUp;
cvf::Vec3d camEye;
cvf::Vec3d camViewRefPoint;
m_comparisonMainCamera->toLookAt( &camEye, &camViewRefPoint, &camUp );
camEye += m_comparisonViewOffset;
camViewRefPoint += m_comparisonViewOffset;
m_comparisonMainCamera->setFromLookAt(camEye, camViewRefPoint, camUp);
if ( calculateNearFarPlanes(m_comparisonMainRendering.p(), navPointOfinterest, &farPlaneDist, &nearPlaneDist) )
{
if ( m_comparisonMainCamera->projection() == cvf::Camera::PERSPECTIVE )
{
m_comparisonMainCamera->setProjectionAsPerspective(m_cameraFieldOfViewYDeg, nearPlaneDist, farPlaneDist);
}
else
{
m_comparisonMainCamera->setProjectionAsOrtho(m_comparisonMainCamera->frontPlaneFrustumHeight(), nearPlaneDist, farPlaneDist);
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool caf::Viewer::calculateNearFarPlanes(const cvf::Rendering* rendering,
const cvf::Vec3d& navPointOfinterest,
double *farPlaneDist,
double *nearPlaneDist)
{
cvf::BoundingBox bb = rendering->boundingBox();
if ( !bb.isValid() ) return false;
cvf::Vec3d eye = rendering->camera()->position();
cvf::Vec3d viewdir = rendering->camera()->direction();
cvf::Vec3d bboxCorners[8]; cvf::Vec3d bboxCorners[8];
bb.cornerVertices(bboxCorners); bb.cornerVertices(bboxCorners);
@ -360,68 +511,60 @@ void caf::Viewer::optimizeClippingPlanes()
double maxDistEyeToCornerAlongViewDir = -HUGE_VAL; double maxDistEyeToCornerAlongViewDir = -HUGE_VAL;
double minDistEyeToCornerAlongViewDir = HUGE_VAL; double minDistEyeToCornerAlongViewDir = HUGE_VAL;
for (int bcIdx = 0; bcIdx < 8; ++bcIdx ) for ( int bcIdx = 0; bcIdx < 8; ++bcIdx )
{ {
double distEyeBoxCornerAlongViewDir = (bboxCorners[bcIdx] - eye)*viewdir; double distEyeBoxCornerAlongViewDir = (bboxCorners[bcIdx] - eye)*viewdir;
if (distEyeBoxCornerAlongViewDir > maxDistEyeToCornerAlongViewDir) if ( distEyeBoxCornerAlongViewDir > maxDistEyeToCornerAlongViewDir )
{ {
maxDistEyeToCornerAlongViewDir = distEyeBoxCornerAlongViewDir; maxDistEyeToCornerAlongViewDir = distEyeBoxCornerAlongViewDir;
} }
if (distEyeBoxCornerAlongViewDir < minDistEyeToCornerAlongViewDir) if ( distEyeBoxCornerAlongViewDir < minDistEyeToCornerAlongViewDir )
{ {
minDistEyeToCornerAlongViewDir = distEyeBoxCornerAlongViewDir; // Sometimes negative-> behind camera minDistEyeToCornerAlongViewDir = distEyeBoxCornerAlongViewDir; // Sometimes negative-> behind camera
} }
} }
double farPlaneDist = CVF_MIN(maxDistEyeToCornerAlongViewDir * 1.2, m_maxClipPlaneDistance); (*farPlaneDist) = CVF_MIN(maxDistEyeToCornerAlongViewDir * 1.2, m_maxClipPlaneDistance);
// Near-plane: // Near-plane:
bool isOrthoNearPlaneFollowingCamera = false; bool isOrthoNearPlaneFollowingCamera = false;
double nearPlaneDist = HUGE_VAL;
// If we have perspective projection, set the near plane just in front of camera, and not behind // If we have perspective projection, set the near plane just in front of camera, and not behind
if (m_mainCamera->projection() == cvf::Camera::PERSPECTIVE || isOrthoNearPlaneFollowingCamera) if ( rendering->camera()->projection() == cvf::Camera::PERSPECTIVE || isOrthoNearPlaneFollowingCamera )
{ {
// Choose the one furthest from the camera of: 0.8*bbox distance, m_minPerspectiveNearPlaneDistance. // Choose the one furthest from the camera of: 0.8*bbox distance, m_minPerspectiveNearPlaneDistance.
nearPlaneDist = CVF_MAX( m_defaultPerspectiveNearPlaneDistance, 0.8*minDistEyeToCornerAlongViewDir); (*nearPlaneDist) = CVF_MAX(m_defaultPerspectiveNearPlaneDistance, 0.8*minDistEyeToCornerAlongViewDir);
// If we are zooming into a detail, allow the near-plane to move towards camera beyond the m_minPerspectiveNearPlaneDistance // If we are zooming into a detail, allow the near-plane to move towards camera beyond the m_minPerspectiveNearPlaneDistance
if ( nearPlaneDist == m_defaultPerspectiveNearPlaneDistance // We are inside the bounding box if ( (*nearPlaneDist) == m_defaultPerspectiveNearPlaneDistance // We are inside the bounding box
&& m_navigationPolicy.notNull() && m_navigationPolicyEnabled) && m_navigationPolicy.notNull() && m_navigationPolicyEnabled )
{ {
double pointOfInterestDist = (eye - m_navigationPolicy->pointOfInterest()).length(); double pointOfInterestDist = (eye - navPointOfinterest).length();
nearPlaneDist = CVF_MIN(nearPlaneDist, pointOfInterestDist*0.2); (*nearPlaneDist) = CVF_MIN((*nearPlaneDist), pointOfInterestDist*0.2);
} }
// Guard against the zero nearplane possibility // Guard against the zero nearplane possibility
if (nearPlaneDist <= 0) nearPlaneDist = m_defaultPerspectiveNearPlaneDistance; if ( nearPlaneDist <= 0 ) (*nearPlaneDist) = m_defaultPerspectiveNearPlaneDistance;
} }
else // Orthographic projection. Set to encapsulate the complete boundingbox, possibly setting a negative nearplane else // Orthographic projection. Set to encapsulate the complete boundingbox, possibly setting a negative nearplane
{ {
if(minDistEyeToCornerAlongViewDir >= 0) if ( minDistEyeToCornerAlongViewDir >= 0 )
{ {
nearPlaneDist = CVF_MIN(0.8 * minDistEyeToCornerAlongViewDir, m_maxClipPlaneDistance); (*nearPlaneDist) = CVF_MIN(0.8 * minDistEyeToCornerAlongViewDir, m_maxClipPlaneDistance);
} }
else else
{ {
nearPlaneDist = CVF_MAX(1.2 * minDistEyeToCornerAlongViewDir, -m_maxClipPlaneDistance); (*nearPlaneDist) = CVF_MAX(1.2 * minDistEyeToCornerAlongViewDir, -m_maxClipPlaneDistance);
} }
} }
if (farPlaneDist <= nearPlaneDist) farPlaneDist = nearPlaneDist + 1.0; if ( (*farPlaneDist) <= (*nearPlaneDist) ) (*farPlaneDist) = (*nearPlaneDist) + 1.0;
if (m_mainCamera->projection() == cvf::Camera::PERSPECTIVE) return true;
{
m_mainCamera->setProjectionAsPerspective(m_cameraFieldOfViewYDeg, nearPlaneDist, farPlaneDist);
}
else
{
m_mainCamera->setProjectionAsOrtho(m_mainCamera->frontPlaneFrustumHeight(), nearPlaneDist, farPlaneDist);
}
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -644,9 +787,15 @@ void caf::Viewer::paintEvent(QPaintEvent* event)
optimizeClippingPlanes(); optimizeClippingPlanes();
m_renderingSequence->removeRendering(m_comparisonMainRendering.p());
if ( m_comparisonMainRendering->scene() )
{
m_renderingSequence->insertRendering( m_overlayItemsRendering.p(), m_comparisonMainRendering.p());
}
if ( m_poiVisualizationManager.notNull() ) if ( m_poiVisualizationManager.notNull() )
{ {
m_poiVisualizationManager->update(m_navigationPolicy->pointOfInterest()); m_poiVisualizationManager->update(m_navigationPolicy->pointOfInterest()); // Todo: Must be inserted in comparison scene as well, using the display offset
m_mainRendering->scene()->addModel(m_poiVisualizationManager->model()); m_mainRendering->scene()->addModel(m_poiVisualizationManager->model());
} }
@ -728,22 +877,39 @@ void caf::Viewer::zoomAll()
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void caf::Viewer::addFrame(cvf::Scene* scene) void caf::Viewer::addFrame(cvf::Scene* scene, bool isForComparisonView)
{ {
appendAllStaticModelsToFrame(scene); appendAllStaticModelsToFrame(scene, isForComparisonView);
m_frameScenes.push_back(scene); if ( !isForComparisonView )
m_animationControl->setNumFrames(static_cast<int>(m_frameScenes.size())); {
m_frameScenes.push_back(scene);
}
else
{
m_comparisonFrameScenes.push_back(scene);
}
m_animationControl->setNumFrames( static_cast<int>( frameCount() ) );
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void caf::Viewer::removeAllFrames() void caf::Viewer::removeAllFrames(bool isForComparisonView)
{ {
m_frameScenes.clear(); if ( !isForComparisonView )
m_animationControl->setNumFrames(0); {
m_mainRendering->setScene(m_mainScene.p()); m_frameScenes.clear();
m_mainRendering->setScene(m_mainScene.p());
}
else
{
m_comparisonFrameScenes.clear();
m_comparisonMainRendering->setScene(m_comparisonMainScene.p());
}
m_animationControl->setNumFrames(static_cast<int>(frameCount()));
} }
@ -776,15 +942,29 @@ void caf::Viewer::slotSetCurrentFrame(int frameIndex)
int clampedFrameIndex = clampFrameIndex(frameIndex); int clampedFrameIndex = clampFrameIndex(frameIndex);
if (m_frameScenes.at(clampedFrameIndex) == nullptr) return; //if (m_frameScenes.at(clampedFrameIndex) == nullptr) return;
if (m_releaseOGLResourcesEachFrame) if (m_releaseOGLResourcesEachFrame)
{ {
releaseOGlResourcesForCurrentFrame(); releaseOGlResourcesForCurrentFrame();
} }
m_mainRendering->setScene(m_frameScenes.at(clampedFrameIndex)); if (m_frameScenes.size() > clampedFrameIndex && m_frameScenes.at(clampedFrameIndex) != nullptr )
{
m_mainRendering->setScene(m_frameScenes.at(clampedFrameIndex));
}
else
{
m_mainRendering->setScene(nullptr);
}
if (m_comparisonFrameScenes.size() > clampedFrameIndex && m_comparisonFrameScenes.at(clampedFrameIndex) != nullptr )
{
m_comparisonMainRendering->setScene(m_comparisonFrameScenes.at(clampedFrameIndex));
}
else
{
m_comparisonMainRendering->setScene(nullptr);
}
update(); update();
} }
@ -881,10 +1061,6 @@ QImage caf::Viewer::snapshotImage()
m_offscreenFbo->bind(myOglContext.p()); m_offscreenFbo->bind(myOglContext.p());
// TODO: Consider refactor this code
// Creating a QImage from the bits in current frame buffer can be done by
// this->grabFrameBuffer()
GLint iOldPackAlignment = 0; GLint iOldPackAlignment = 0;
glGetIntegerv(GL_PACK_ALIGNMENT, &iOldPackAlignment); glGetIntegerv(GL_PACK_ALIGNMENT, &iOldPackAlignment);
glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ALIGNMENT, 1);
@ -924,12 +1100,22 @@ QImage caf::Viewer::snapshotImage()
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
cvf::Scene* caf::Viewer::frame(size_t frameIndex) cvf::Scene* caf::Viewer::frame(size_t frameIndex, bool isForComparisonView)
{ {
if (frameIndex < m_frameScenes.size()) if ( !isForComparisonView )
return m_frameScenes[frameIndex].p(); {
if ( frameIndex < m_frameScenes.size() )
return m_frameScenes[frameIndex].p();
else
return nullptr;
}
else else
return nullptr; {
if ( frameIndex < m_comparisonFrameScenes.size() )
return m_comparisonFrameScenes[frameIndex].p();
else
return nullptr;
}
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -1031,6 +1217,14 @@ void caf::Viewer::enableOverlayPainting(bool val)
updateOverlayImagePresence(); updateOverlayImagePresence();
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Rendering* caf::Viewer::overlayItemsRendering()
{
return m_overlayItemsRendering.p();
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -1038,11 +1232,11 @@ void caf::Viewer::updateOverlayImagePresence()
{ {
if (m_isOverlayPaintingEnabled || m_showPerfInfoHud) if (m_isOverlayPaintingEnabled || m_showPerfInfoHud)
{ {
m_mainRendering->addOverlayItem(m_overlayImage.p()); m_overlayItemsRendering->addOverlayItem(m_overlayImage.p());
} }
else else
{ {
m_mainRendering->removeOverlayItem(m_overlayImage.p()); m_overlayItemsRendering->removeOverlayItem(m_overlayImage.p());
} }
} }
@ -1057,13 +1251,22 @@ void caf::Viewer::navigationPolicyUpdate()
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void caf::Viewer::addStaticModelOnce(cvf::Model* model) void caf::Viewer::addStaticModelOnce(cvf::Model* model, bool isForComparisonView)
{ {
if (m_staticModels.contains(model)) return; if ( !isForComparisonView )
{
if ( m_staticModels.contains(model) ) return;
m_staticModels.push_back(model); m_staticModels.push_back(model);
}
else
{
if ( m_comparisonStaticModels.contains(model) ) return;
appendModelToAllFrames(model); m_comparisonStaticModels.push_back(model);
}
appendModelToAllFrames(model, isForComparisonView);
updateCachedValuesInScene(); updateCachedValuesInScene();
} }
@ -1076,6 +1279,7 @@ void caf::Viewer::removeStaticModel(cvf::Model* model)
removeModelFromAllFrames(model); removeModelFromAllFrames(model);
m_staticModels.erase(model); m_staticModels.erase(model);
m_comparisonStaticModels.erase(model);
updateCachedValuesInScene(); updateCachedValuesInScene();
} }
@ -1089,12 +1293,33 @@ void caf::Viewer::removeAllStaticModels()
{ {
removeModelFromAllFrames(m_staticModels.at(i)); removeModelFromAllFrames(m_staticModels.at(i));
} }
for (size_t i = 0; i < m_comparisonStaticModels.size(); i++)
{
removeModelFromAllFrames(m_comparisonStaticModels.at(i));
}
m_staticModels.clear(); m_staticModels.clear();
m_comparisonStaticModels.clear();
updateCachedValuesInScene(); updateCachedValuesInScene();
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf::Viewer::setEnableMask(unsigned int mask, bool isForComparisonView /*= false */)
{
if (!isForComparisonView)
{
m_mainRendering->setEnableMask(mask);
}
else
{
m_comparisonMainRendering->setEnableMask(mask);
}
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -1111,34 +1336,75 @@ void caf::Viewer::removeModelFromAllFrames(cvf::Model* model)
{ {
m_mainScene->removeModel(model); m_mainScene->removeModel(model);
} }
for (size_t i = 0; i < m_comparisonFrameScenes.size(); i++)
{
cvf::Scene* scene = m_comparisonFrameScenes.at(i);
scene->removeModel(model);
}
if (m_comparisonMainScene.notNull())
{
m_comparisonMainScene->removeModel(model);
}
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void caf::Viewer::appendModelToAllFrames(cvf::Model* model) void caf::Viewer::appendModelToAllFrames(cvf::Model* model, bool isForComparisonView )
{ {
for (size_t i = 0; i < m_frameScenes.size(); i++) if ( !isForComparisonView )
{ {
cvf::Scene* scene = m_frameScenes.at(i); for ( size_t i = 0; i < m_frameScenes.size(); i++ )
{
cvf::Scene* scene = m_frameScenes.at(i);
scene->addModel(model); scene->addModel(model);
}
if ( m_mainScene.notNull() )
{
m_mainScene->addModel(model);
}
} }
else
if (m_mainScene.notNull())
{ {
m_mainScene->addModel(model); for ( size_t i = 0; i < m_comparisonFrameScenes.size(); i++ )
{
cvf::Scene* scene = m_comparisonFrameScenes.at(i);
scene->addModel(model);
}
if ( m_comparisonMainScene.notNull() )
{
m_comparisonMainScene->addModel(model);
}
} }
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void caf::Viewer::appendAllStaticModelsToFrame(cvf::Scene* scene) void caf::Viewer::appendAllStaticModelsToFrame(cvf::Scene* scene, bool isForComparisonView )
{ {
for (size_t i = 0; i < m_staticModels.size(); i++) if (!scene) return;
if ( !isForComparisonView )
{ {
scene->addModel(m_staticModels.at(i)); for ( size_t i = 0; i < m_staticModels.size(); i++ )
{
scene->addModel(m_staticModels.at(i));
}
}
else
{
for ( size_t i = 0; i < m_comparisonStaticModels.size(); i++ )
{
scene->addModel(m_comparisonStaticModels.at(i));
}
} }
} }
@ -1147,12 +1413,12 @@ void caf::Viewer::appendAllStaticModelsToFrame(cvf::Scene* scene)
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
cvf::OverlayItem* caf::Viewer::overlayItem(int winPosX, int winPosY) cvf::OverlayItem* caf::Viewer::overlayItem(int winPosX, int winPosY)
{ {
if (m_mainRendering.isNull()) return nullptr; if (m_overlayItemsRendering.isNull()) return nullptr;
int translatedMousePosX = winPosX; int translatedMousePosX = winPosX;
int translatedMousePosY = height() - winPosY; int translatedMousePosY = height() - winPosY;
return m_mainRendering->overlayItemFromWindowCoordinates(translatedMousePosX, translatedMousePosY); return m_overlayItemsRendering->overlayItemFromWindowCoordinates(translatedMousePosX, translatedMousePosY);
} }
@ -1341,3 +1607,19 @@ int caf::Viewer::clampFrameIndex(int frameIndex) const
return clampedFrameIndex; return clampedFrameIndex;
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf::Viewer::copyCameraView(cvf::Camera* srcCamera, cvf::Camera* dstCamera)
{
if (srcCamera->projection() == cvf::Camera::PERSPECTIVE)
{
dstCamera->setProjectionAsPerspective(srcCamera->fieldOfViewYDeg(), srcCamera->nearPlane(), srcCamera->farPlane());
}
else
{
dstCamera->setProjectionAsOrtho(srcCamera->frontPlaneFrustumHeight(), srcCamera->nearPlane(), srcCamera->farPlane());
}
dstCamera->setViewMatrix(srcCamera->viewMatrix());
}

View File

@ -42,9 +42,11 @@
#include "cvfObject.h" #include "cvfObject.h"
#include "cvfCollection.h" #include "cvfCollection.h"
#include "cvfVector3.h" #include "cvfVector3.h"
#include "cvfRect.h"
#include "cvfOpenGL.h" #include "cvfOpenGL.h"
#include "cafOpenGLWidget.h" #include "cafOpenGLWidget.h"
#include "cvfRenderingScissor.h"
namespace cvf { namespace cvf {
@ -76,6 +78,7 @@ namespace caf
{ {
class GlobalViewerDynUniformSet; class GlobalViewerDynUniformSet;
class ScissorChanger;
class Viewer : public caf::OpenGLWidget class Viewer : public caf::OpenGLWidget
{ {
@ -86,24 +89,33 @@ public:
QWidget* layoutWidget() { return m_layoutWidget; } // Use this when putting it into something QWidget* layoutWidget() { return m_layoutWidget; } // Use this when putting it into something
cvf::Camera* mainCamera(); cvf::Camera* mainCamera();
cvf::Camera* comparisonMainCamera();
void setComparisonViewEyePointOffset(const cvf::Vec3d& offset);
const cvf::Vec3d comparisonViewEyePointOffset();
void setComparisonViewVisibleNormalizedRect( const cvf::Rectf& visibleRect );
cvf::Rectf comparisonViewVisibleNormalizedRect() const;
// Set the main scene : the scene active when the animation is not active. (Stopped) // Set the main scene : the scene active when the animation is not active. (Stopped)
void setMainScene(cvf::Scene* scene); void setMainScene(cvf::Scene* scene, bool isForComparisonView = false);
cvf::Scene* mainScene(); cvf::Scene* mainScene( bool isForComparisonView = false );
cvf::Scene* currentScene(); // The scene currently rendered cvf::Scene* currentScene( bool isForComparisonView = false ); // The scene currently rendered
// Frame scenes for animation control // Frame scenes for animation control
void addFrame(cvf::Scene* scene); void addFrame(cvf::Scene* scene, bool isForComparisonView = false);
size_t frameCount() const { return m_frameScenes.size(); } size_t frameCount() const { return std::max( m_frameScenes.size(), m_comparisonFrameScenes.size() ) ; }
cvf::Scene* frame(size_t frameIndex); cvf::Scene* frame(size_t frameIndex, bool isForComparisonView = false);
void removeAllFrames(); void removeAllFrames(bool isForComparisonView = false);
int currentFrameIndex() const; int currentFrameIndex() const;
// Static models to be shown in all frames // Static models to be shown in all frames
void addStaticModelOnce(cvf::Model* model); void addStaticModelOnce(cvf::Model* model, bool isForComparisonView = false);
void removeStaticModel(cvf::Model* model); void removeStaticModel(cvf::Model* model);
void removeAllStaticModels(); void removeAllStaticModels();
// Part enable/ disable mask
void setEnableMask( unsigned int mask, bool isForComparisonView = false );
// Recursively traverse all the scenes managed by the viewer and make sure all cached values are up-to-date // Recursively traverse all the scenes managed by the viewer and make sure all cached values are up-to-date
// Use when changing the contents inside the objects in the scene. // Use when changing the contents inside the objects in the scene.
@ -145,6 +157,7 @@ public:
bool isOverlayPaintingEnabled() const; bool isOverlayPaintingEnabled() const;
void enableOverlayPainting(bool val); void enableOverlayPainting(bool val);
cvf::Rendering* overlayItemsRendering();
// Performance information for debugging etc. // Performance information for debugging etc.
void enablePerfInfoHud(bool enable); void enablePerfInfoHud(bool enable);
@ -157,6 +170,8 @@ public:
QImage snapshotImage(); QImage snapshotImage();
static void copyCameraView(cvf::Camera* srcCamera, cvf::Camera* dstCamera);
public slots: public slots:
virtual void slotSetCurrentFrame(int frameIndex); virtual void slotSetCurrentFrame(int frameIndex);
virtual void slotEndAnimation(); virtual void slotEndAnimation();
@ -171,6 +186,11 @@ protected:
// Overridable methods to setup the render system // Overridable methods to setup the render system
virtual void optimizeClippingPlanes(); virtual void optimizeClippingPlanes();
bool calculateNearFarPlanes(const cvf::Rendering* rendering,
const cvf::Vec3d& navPointOfinterest,
double *farPlaneDist,
double *nearPlaneDist);
// Standard overrides. Not for overriding // Standard overrides. Not for overriding
void resizeGL(int width, int height) override; void resizeGL(int width, int height) override;
void paintEvent(QPaintEvent* event) override; void paintEvent(QPaintEvent* event) override;
@ -195,8 +215,8 @@ private:
void setupMainRendering(); void setupMainRendering();
void setupRenderingSequence(); void setupRenderingSequence();
void appendAllStaticModelsToFrame(cvf::Scene* scene); void appendAllStaticModelsToFrame(cvf::Scene* scene, bool isForComparisonView = false);
void appendModelToAllFrames(cvf::Model* model); void appendModelToAllFrames(cvf::Model* model, bool isForComparisonView = false);
void removeModelFromAllFrames(cvf::Model* model); void removeModelFromAllFrames(cvf::Model* model);
void updateCamera(int width, int height); void updateCamera(int width, int height);
@ -219,14 +239,27 @@ private:
// System to make sure we share OpenGL resources // System to make sure we share OpenGL resources
static Viewer* sharedWidget(); static Viewer* sharedWidget();
static cvf::OpenGLContextGroup* contextGroup(); static cvf::OpenGLContextGroup* contextGroup();
static std::list<Viewer*> sm_viewers; static std::list<Viewer*> sm_viewers;
static cvf::ref<cvf::OpenGLContextGroup> static cvf::ref<cvf::OpenGLContextGroup>
sm_openGLContextGroup; sm_openGLContextGroup;
caf::FrameAnimationControl* m_animationControl; caf::FrameAnimationControl* m_animationControl;
cvf::Collection<cvf::Scene> m_frameScenes; cvf::Collection<cvf::Scene> m_frameScenes;
cvf::Collection<cvf::Model> m_staticModels; cvf::Collection<cvf::Model> m_staticModels;
cvf::ref<cvf::Rendering> m_comparisonMainRendering;
cvf::ref<cvf::Camera> m_comparisonMainCamera;
cvf::ref<cvf::Scene> m_comparisonMainScene;
cvf::Collection<cvf::Scene> m_comparisonFrameScenes;
cvf::Collection<cvf::Model> m_comparisonStaticModels;
cvf::Vec3d m_comparisonViewOffset;
cvf::ref<cvf::RenderingScissor> m_comparisonRenderingScissor;
cvf::Rectf m_comparisonWindowNormalizedRect;
// Poi visualization // Poi visualization
cvf::ref<PointOfInterestVisualizer> m_poiVisualizationManager; cvf::ref<PointOfInterestVisualizer> m_poiVisualizationManager;
@ -241,6 +274,9 @@ private:
int m_offscreenViewportWidth; int m_offscreenViewportWidth;
int m_offscreenViewportHeight; int m_offscreenViewportHeight;
cvf::ref<cvf::Rendering> m_quadRendering; cvf::ref<cvf::Rendering> m_quadRendering;
cvf::ref<cvf::Rendering> m_overlayItemsRendering;
}; };
} // End namespace caf } // End namespace caf