X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FHYDROGUI%2FHYDROGUI_OCCDisplayer.cxx;h=40256a51b2e6b54640a4812ff8cd00e5e8df8d62;hb=d6e19029f8b41f295db878e9aecf451c2edda4af;hp=d20db2484db4ddc086d0555884daf1000bc1470c;hpb=0c405019de08dccfacd64f71f18211cbe912cc1d;p=modules%2Fhydro.git diff --git a/src/HYDROGUI/HYDROGUI_OCCDisplayer.cxx b/src/HYDROGUI/HYDROGUI_OCCDisplayer.cxx index d20db248..40256a51 100644 --- a/src/HYDROGUI/HYDROGUI_OCCDisplayer.cxx +++ b/src/HYDROGUI/HYDROGUI_OCCDisplayer.cxx @@ -1,12 +1,8 @@ -// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// +// Copyright (C) 2014-2015 EDF-R&D // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either -// version 2.1 of the License. +// version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -25,21 +21,33 @@ #include "HYDROGUI_DataModel.h" #include "HYDROGUI_Module.h" #include "HYDROGUI_Tool.h" -#include "HYDROGUI_Shape.h" +#include +#include +#include "HYDROGUI_Operation.h" +#include "HYDROGUI_DataObject.h" +#include "HYDROGUI_ZLayers.h" +#include #include #include #include +#include + +#include + +#include +#include + #include #include #include - -#include +#include HYDROGUI_OCCDisplayer::HYDROGUI_OCCDisplayer( HYDROGUI_Module* theModule ) -: myModule( theModule ) +: HYDROGUI_AbstractDisplayer( theModule ) { + myToUpdateColorScale = false; } HYDROGUI_OCCDisplayer::~HYDROGUI_OCCDisplayer() @@ -49,17 +57,17 @@ HYDROGUI_OCCDisplayer::~HYDROGUI_OCCDisplayer() void HYDROGUI_OCCDisplayer::SetToUpdate( const HYDROData_SequenceOfObjects& theObjs, const int theViewerId ) { - OCCViewer_Viewer* aViewer = myModule->getOCCViewer( theViewerId ); + OCCViewer_Viewer* aViewer = module()->getOCCViewer( theViewerId ); if( !aViewer ) return; for ( int i = 1, n = theObjs.Length(); i <= n; i++ ) { - Handle(HYDROData_Object) anObj = theObjs.Value( i ); + Handle(HYDROData_Entity) anObj = theObjs.Value( i ); if( anObj.IsNull() ) continue; - HYDROGUI_Shape* anObjShape = myModule->getObjectShape( (size_t)aViewer, anObj ); + HYDROGUI_Shape* anObjShape = module()->getObjectShape( (size_t)aViewer, anObj ); if ( !anObjShape ) continue; @@ -67,147 +75,223 @@ void HYDROGUI_OCCDisplayer::SetToUpdate( const HYDROData_SequenceOfObjects& theO } } -void HYDROGUI_OCCDisplayer::UpdateAll( const int theViewerId, - const bool theIsInit, - const bool theIsForced ) +int HYDROGUI_OCCDisplayer::AddPreviewZLayer( OCCViewer_ViewManager* theMgr ) { - if ( theIsInit ) - EraseAll( theViewerId ); + int aLayer = -1; + OCCViewer_Viewer* aViewer = theMgr->getOCCViewer(); + if ( !aViewer ) + return aLayer; + + aLayer = CreateTopZLayer( aViewer->getViewer3d() ); + + // Hilight presentation should be on top + Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext(); + if( !aCtx.IsNull() ) { + int aTopLayer = CreateTopZLayer( aViewer->getViewer3d() ); + if ( aTopLayer > 0 ) { + UpdateZLayersOfHilightPresentationsOfDisplayedObjects( aCtx, aTopLayer ); + } + } - DisplayAll( theViewerId, theIsForced ); + return aLayer; } -void HYDROGUI_OCCDisplayer::EraseAll( const int theViewerId ) +void HYDROGUI_OCCDisplayer::RemoveZLayer( OCCViewer_ViewManager* theMgr, + const int theLayer ) { - OCCViewer_Viewer* aViewer = myModule->getOCCViewer( theViewerId ); - if( !aViewer ) + if ( theLayer < 0 ) return; - myModule->removeViewShapes( (size_t)aViewer ); -} + OCCViewer_Viewer* aViewer = theMgr->getOCCViewer(); + if ( !aViewer ) + return; -void HYDROGUI_OCCDisplayer::DisplayAll( const int theViewerId, - const bool theIsForced ) -{ - HYDROData_SequenceOfObjects aSeq; - HYDROGUI_Tool::GetPrsSubObjects( myModule, aSeq ); - Update( aSeq, theViewerId, theIsForced ); + // Get existing Z layers + TColStd_SequenceOfInteger anExistingZLayers; + aViewer->getViewer3d()->GetAllZLayers( anExistingZLayers ); + int aNbLayers = anExistingZLayers.Length(); + + if ( theLayer < aNbLayers ) + aViewer->getViewer3d()->RemoveZLayer( theLayer ); } -void HYDROGUI_OCCDisplayer::Update( const HYDROData_SequenceOfObjects& theObjs, - const int theViewerId, - const bool theIsForced ) +void HYDROGUI_OCCDisplayer::EraseAll( const int theViewerId ) { - // First of all, kill all bad presentations - purgeObjects( theViewerId ); - - // Now dig in the data model - HYDROData_SequenceOfObjects anObjectsToErase, anObjectsToDisplay; - - for( int i = 1, n = theObjs.Length(); i <= n; i++ ) - { - const Handle(HYDROData_Object)& anObj = theObjs.Value( i ); - if( anObj.IsNull() ) - anObjectsToErase.Append( anObj ); - else - anObjectsToDisplay.Append( anObj ); - } + OCCViewer_Viewer* aViewer = module()->getOCCViewer( theViewerId ); + if( !aViewer ) + return; - if( anObjectsToErase.Length() ) - Erase( anObjectsToErase, theViewerId ); - if( anObjectsToDisplay.Length() ) - Display( anObjectsToDisplay, theViewerId, theIsForced ); + module()->removeViewShapes( (size_t)aViewer ); + UpdateColorScale( aViewer ); } void HYDROGUI_OCCDisplayer::Erase( const HYDROData_SequenceOfObjects& theObjs, const int theViewerId ) { - OCCViewer_Viewer* aViewer = myModule->getOCCViewer( theViewerId ); + OCCViewer_Viewer* aViewer = module()->getOCCViewer( theViewerId ); if( !aViewer ) return; for ( int i = 1, n = theObjs.Length(); i <= n; i++ ) { - Handle(HYDROData_Object) anObj = theObjs.Value( i ); + Handle(HYDROData_Entity) anObj = theObjs.Value( i ); if( anObj.IsNull() ) continue; - myModule->removeObjectShape( (size_t)aViewer, anObj ); + module()->removeObjectShape( (size_t)aViewer, anObj ); } + aViewer->update(); + UpdateColorScale( aViewer ); } HYDROGUI_Shape* HYDROGUI_OCCDisplayer::createShape( const int theViewerId, const Handle(AIS_InteractiveContext)& theContext, - const Handle(HYDROData_Object)& theObject ) + const Handle(HYDROData_Entity)& theObject ) { HYDROGUI_Shape* aResShape = NULL; if ( theContext.IsNull() || theObject.IsNull() ) return aResShape; - ObjectKind anObjectKind = theObject->GetKind(); - if ( anObjectKind != KIND_POLYLINE && - anObjectKind != KIND_ZONE ) + if ( !HYDROGUI_Tool::IsObjectHasPresentation( theObject, OCCViewer_Viewer::Type() ) ) return aResShape; - aResShape = new HYDROGUI_Shape( theContext, theObject ); - myModule->setObjectShape( theViewerId, theObject, aResShape ); + if( theObject->IsKind( STANDARD_TYPE( HYDROData_Image ) ) ) + aResShape = new HYDROGUI_ShapeImage( theContext, Handle_HYDROData_Image::DownCast( theObject ) ); + else if( theObject->IsKind( STANDARD_TYPE( HYDROData_Bathymetry ) ) ) + aResShape = new HYDROGUI_ShapeBathymetry( this, theContext, Handle_HYDROData_Bathymetry::DownCast( theObject ) ); + else + aResShape = new HYDROGUI_Shape( theContext, theObject ); + + module()->setObjectShape( theViewerId, theObject, aResShape ); return aResShape; } void HYDROGUI_OCCDisplayer::Display( const HYDROData_SequenceOfObjects& theObjs, const int theViewerId, - const bool theIsForced ) + const bool theIsForced, + const bool theDoFitAll ) { - OCCViewer_Viewer* aViewer = myModule->getOCCViewer( theViewerId ); + // Get OCC viewer by id + OCCViewer_Viewer* aViewer = module()->getOCCViewer( theViewerId ); if( !aViewer ) return; + // Get interactive context Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext(); if( aCtx.IsNull() ) return; - for ( int i = 1, n = theObjs.Length(); i <= n; i++ ) - { - Handle(HYDROData_Object) anObj = theObjs.Value( i ); - if ( anObj.IsNull() || anObj->IsRemoved() ) - continue; - - HYDROGUI_Shape* anObjShape = myModule->getObjectShape( (size_t)aViewer, anObj ); - - if ( !anObjShape || anObjShape->getIsToUpdate() || theIsForced ) - { - if ( !anObjShape ) - anObjShape = createShape( (size_t)aViewer, aCtx, anObj ); + // Get the document + Handle(HYDROData_Document) aDoc = HYDROData_Document::Document( module()->getStudyId() ); + if ( !aDoc ) + return; + + // Assign Z layer indexes to the objects + aDoc->Show( theObjs ); + + // Sort objects by display order ( needed for Z layers assignment only ) + HYDROData_SequenceOfObjects anUnorderedToDisplay = theObjs; + HYDROData_SequenceOfObjects anOrderedToDisplay; + HYDROData_SequenceOfObjects anAllOrderedObjects = aDoc->GetObjectsLayerOrder(); + + HYDROData_SequenceOfObjects::Iterator anAllOrderedIter( anAllOrderedObjects ); + for ( ; anAllOrderedIter.More(); anAllOrderedIter.Next() ) { + QString anOrderedEntry = + HYDROGUI_DataObject::dataObjectEntry( anAllOrderedIter.Value() ); + + HYDROData_SequenceOfObjects::Iterator aToDisplayIter( anUnorderedToDisplay ); + for ( ; aToDisplayIter.More(); aToDisplayIter.Next() ) { + Handle(HYDROData_Entity) anObjToDisplay = aToDisplayIter.Value(); + QString anEntry = HYDROGUI_DataObject::dataObjectEntry( anObjToDisplay ); + if ( anEntry == anOrderedEntry ) { + anOrderedToDisplay.Prepend( anObjToDisplay ); + anUnorderedToDisplay.Remove( aToDisplayIter ); + break; + } + } + } + + // Get 3d viewer + Handle(V3d_Viewer) aViewer3d = aViewer->getViewer3d(); + + // Display objects: + HYDROGUI_ZLayersIterator aZLayersIt( aViewer->getViewer3d() ); + if ( !aZLayersIt.More() ) { + aZLayersIt.Next(); + } - if ( anObjShape ) - anObjShape->update( false ); + // 1. Display the ordered objects: + HYDROData_SequenceOfObjects::Iterator anOrderedIter( anOrderedToDisplay ); + for ( ; anOrderedIter.More(); anOrderedIter.Next() ) { + Handle(HYDROData_Entity) anObj = anOrderedIter.Value(); + if ( Display( anObj, aViewer, theIsForced ) ) { + // set Z layer ( one Z layer for each ordered object ) + int aZLayerId = aZLayersIt.LayerId(); + SetZLayer( aViewer, anObj, aZLayerId ); + SetZLayerSettings( aViewer3d, aZLayerId, true ); + aZLayersIt.Next(); } + } - if ( anObjShape ) - { - bool anIsVisible = myModule->isObjectVisible( (size_t)aViewer, anObj ); - anObjShape->setVisible( anIsVisible, false ); + // 2. Display the unordered objects: + bool isDisplayed = false; + int anUnorderedZLayerId = aZLayersIt.LayerId(); + HYDROData_SequenceOfObjects::Iterator anUnorderedIter( anUnorderedToDisplay ); + for ( ; anUnorderedIter.More(); anUnorderedIter.Next() ) { + Handle(HYDROData_Entity) anObj = anUnorderedIter.Value(); + if ( Display( anObj, aViewer, theIsForced) ) { + // set Z layer ( one Z layer for all unordered objects ) + SetZLayer( aViewer, anObj, anUnorderedZLayerId ); + if ( !isDisplayed ) { + SetZLayerSettings( aViewer3d, anUnorderedZLayerId, false ); + } + isDisplayed = true; } } + + // 3. Update the top Z layer index + if ( isDisplayed ) { + aZLayersIt.Next(); + } - OCCViewer_ViewManager* aViewManager - = ::qobject_cast( aViewer->getViewManager() ); - if ( aViewManager ) - { - OCCViewer_ViewWindow* aViewWindow = - ::qobject_cast( aViewManager->getActiveView() ); - if ( aViewWindow ) - { - QApplication::processEvents(); //Process the draw events for viewer - aViewWindow->onFitAll(); + // Update Z layer of the active operation + int aPreviewZLayerId = aZLayersIt.LayerId(); + + HYDROGUI_Module* aModule = module(); + SUIT_Operation* anOp = aModule->activeOperation(); + HYDROGUI_Operation* aHOp = anOp ? dynamic_cast( anOp ) : 0; + if ( aHOp && aHOp->getPreviewZLayer() >= 0 ) { + aHOp->updatePreviewZLayer( aPreviewZLayerId ); + aZLayersIt.Next(); + } + + // Update Z layer of hilight presentations + int aHilightLayer = aZLayersIt.TopLayer(); + UpdateZLayersOfHilightPresentationsOfDisplayedObjects( aCtx, aHilightLayer ); + + // Fit all / update selection + if ( theDoFitAll ) { + OCCViewer_ViewManager* aViewManager + = ::qobject_cast( aViewer->getViewManager() ); + if ( aViewManager ) { + OCCViewer_ViewWindow* aViewWindow = + ::qobject_cast( aViewManager->getActiveView() ); + if ( aViewWindow ) { + aViewWindow->onFitAll(); + } } + } + else if ( !aCtx.IsNull() ) { // TODO: determine if this code is necessary (added as a fix for issue# 359) + aCtx->UpdateSelected(); } + + UpdateColorScale( aViewer ); } void HYDROGUI_OCCDisplayer::purgeObjects( const int theViewerId ) { - OCCViewer_Viewer* aViewer = myModule->getOCCViewer( theViewerId ); + OCCViewer_Viewer* aViewer = module()->getOCCViewer( theViewerId ); if( !aViewer ) return; @@ -225,11 +309,166 @@ void HYDROGUI_OCCDisplayer::purgeObjects( const int theViewerId ) if ( aPrsObj.IsNull() ) continue; - Handle(HYDROData_Object) anOwnerObj = - Handle(HYDROData_Object)::DownCast( aPrsObj->GetOwner() ); + Handle(HYDROData_Entity) anOwnerObj = + Handle(HYDROData_Entity)::DownCast( aPrsObj->GetOwner() ); if ( !anOwnerObj.IsNull() && anOwnerObj->IsRemoved() ) - myModule->removeObjectShape( (size_t)aViewer, anOwnerObj ); + module()->removeObjectShape( (size_t)aViewer, anOwnerObj ); + } +} + +QString HYDROGUI_OCCDisplayer::GetType() const +{ + return OCCViewer_Viewer::Type(); +} + +bool HYDROGUI_OCCDisplayer::Display( const Handle(HYDROData_Entity)& theObject, + const OCCViewer_Viewer* theViewer, + const bool theIsForced ) +{ + bool aRes = false; + + if ( theObject.IsNull() || theObject->IsRemoved() || !theViewer ) { + return aRes; + } + + // Get interactive context + Handle(AIS_InteractiveContext) aCtx = theViewer->getAISContext(); + if( aCtx.IsNull() ) { + return aRes; + } + + // Viewer id + size_t aViewerId = (size_t)theViewer; + + // Object shape + HYDROGUI_Shape* anObjShape = module()->getObjectShape( aViewerId, theObject ); + // create if needed + if ( !anObjShape ) { + anObjShape = createShape( aViewerId, aCtx, theObject ); + if ( anObjShape ) { + anObjShape->setIsToUpdate( true ); + } } + + // Process the shape + if ( anObjShape ) { + // update if needed + if ( anObjShape->getIsToUpdate() || theIsForced ) { + anObjShape->update( false, false ); + } + + // Set visibility + bool anIsVisible = module()->isObjectVisible( aViewerId, theObject ); + anObjShape->setVisible( anIsVisible, false ); + + aRes = true; + } + + return aRes; +} + +void HYDROGUI_OCCDisplayer::SetZLayer( const OCCViewer_Viewer* theViewer, + const Handle(HYDROData_Entity)& theObject, + const int theZLayerId ) +{ + if ( !theViewer /*|| ( theZLayerId < 0 )*/ ) { + return; + } + + // Get interactive context + Handle(AIS_InteractiveContext) aCtx = theViewer->getAISContext(); + if( aCtx.IsNull() ) { + return; + } + + // Get viewer id + size_t aViewerId = (size_t)theViewer; + + // Get object shape + HYDROGUI_Shape* anObjShape = module()->getObjectShape( aViewerId, theObject ); + + // Set Z layer + if ( anObjShape ) { + aCtx->SetZLayer( anObjShape->getAISObject(), theZLayerId ); + } +} + +void HYDROGUI_OCCDisplayer::SetToUpdateColorScale() +{ + myToUpdateColorScale = true; } +void HYDROGUI_OCCDisplayer::UpdateColorScale( const OCCViewer_Viewer* theViewer ) +{ + if( !myToUpdateColorScale ) + return; + + OCCViewer_ViewWindow* aWnd = dynamic_cast( theViewer->getViewManager()->getActiveView() ); + Handle(V3d_View) aView = aWnd->getViewPort()->getView(); + + int aViewerId = (size_t)theViewer;//TODO: check if viewer id is correct + QList aShapes = module()->getObjectShapes( aViewerId, KIND_BATHYMETRY ); + + bool isDisplayColorScale = !aShapes.empty(); + Standard_Real anXPos = 0.05; //TODO + Standard_Real anYPos = 0.1; //TODO + Standard_Real aWidth = 0.2; //TODO + Standard_Real aHeight = 0.5; //TODO + Standard_Integer aTextHeight = 14; //TODO + Standard_Integer aNbIntervals = 20; //TODO + TCollection_ExtendedString aColorScaleTitle = "";//TODO + + Standard_Real aColorScaleMin = 0, aColorScaleMax = 1, aMin, aMax; + bool isFirst = true; + foreach( HYDROGUI_Shape* aShape, aShapes ) + { + HYDROGUI_ShapeBathymetry* aBathShape = dynamic_cast( aShape ); + if( !aBathShape || !aBathShape->isVisible() ) + continue; + + aBathShape->GetRange( aMin, aMax ); + + if( isFirst || aMin < aColorScaleMin ) + aColorScaleMin = aMin; + if( isFirst || aMax > aColorScaleMax ) + aColorScaleMax = aMax; + + isFirst = false; + } + if( isDisplayColorScale ) + { + Handle(Aspect_ColorScale) aColorScale = aView->ColorScale(); + if( !aColorScale.IsNull() ) + { + aColorScale->SetXPosition( anXPos ); + aColorScale->SetYPosition( anYPos ); + aColorScale->SetWidth( aWidth ); + aColorScale->SetHeight( aHeight ); + + aColorScale->SetTextHeight( aTextHeight ); + aColorScale->SetNumberOfIntervals( aNbIntervals ); + + aColorScale->SetTitle( aColorScaleTitle ); + aColorScale->SetRange( aColorScaleMin, aColorScaleMax ); + + foreach( HYDROGUI_Shape* aShape, aShapes ) + { + HYDROGUI_ShapeBathymetry* aBathShape = dynamic_cast( aShape ); + if( !aBathShape || !aBathShape->isVisible() ) + continue; + + aBathShape->UpdateWithColorScale( aColorScale ); + } + } + if( !aView->ColorScaleIsDisplayed() ) + aView->ColorScaleDisplay(); + } + else + { + if( aView->ColorScaleIsDisplayed() ) + aView->ColorScaleErase(); + } + + myToUpdateColorScale = false; +}