X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FOCCViewer%2FOCCViewer_ViewModel.cxx;h=d7eae71b8e218e1880be08f8efc94bb9277f26d6;hb=e6caa123c65e3c4a3017364ec5bb4225fd898465;hp=5de1e756ad55883c2865af098a47b955ca3bb876;hpb=0be39b934a6050f16fcf52cd0f97631b4c1c94a9;p=modules%2Fgui.git diff --git a/src/OCCViewer/OCCViewer_ViewModel.cxx b/src/OCCViewer/OCCViewer_ViewModel.cxx index 5de1e756a..d7eae71b8 100755 --- a/src/OCCViewer/OCCViewer_ViewModel.cxx +++ b/src/OCCViewer/OCCViewer_ViewModel.cxx @@ -1,47 +1,121 @@ +// Copyright (C) 2007-2015 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 +// +// 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// #include "OCCViewer_ViewModel.h" #include "OCCViewer_ViewWindow.h" +#include "OCCViewer_ViewFrame.h" #include "OCCViewer_VService.h" #include "OCCViewer_ViewPort3d.h" +#include "OCCViewer_ClippingDlg.h" +#include "OCCViewer_Utilities.h" #include "SUIT_ViewWindow.h" +#include "SUIT_ViewManager.h" #include "SUIT_Desktop.h" #include "SUIT_Session.h" +#include "SUIT_ResourceMgr.h" -#include -#include -#include -#include -#include +#include "ViewerData_AISShape.hxx" + +#include + +#include "QtxActionToolMgr.h" +#include "QtxBackgroundTool.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include +#if OCC_VERSION_LARGE > 0x06080000 + #include +#else + #include +#endif +#include #include +#include +#include +#include + #include +#include #include #include +#include -OCCViewer_Viewer::OCCViewer_Viewer( bool DisplayTrihedron ) -:SUIT_ViewModel() -{ - // init CasCade viewers - myV3dViewer = OCCViewer_VService::Viewer3d( "", (short*) "Viewer3d", "", 1000., - V3d_XposYnegZpos, true, true ); - - myV3dViewer->Init(); - - myV3dCollector = OCCViewer_VService::Viewer3d( "", (short*) "Collector3d", "", 1000., - V3d_XposYnegZpos, true, true ); - myV3dCollector->Init(); - - // init selector - myAISContext = new AIS_InteractiveContext( myV3dViewer, myV3dCollector); +#include - clearViewAspects(); +/*! + Get data for supported background modes: gradient types, identifiers and supported image formats +*/ +QString OCCViewer_Viewer::backgroundData( QStringList& gradList, QIntList& idList, QIntList& txtList ) +{ + gradList << tr("GT_HORIZONTALGRADIENT") << tr("GT_VERTICALGRADIENT") << + tr("GT_FIRSTDIAGONALGRADIENT") << tr("GT_SECONDDIAGONALGRADIENT") << + tr("GT_FIRSTCORNERGRADIENT") << tr("GT_SECONDCORNERGRADIENT") << + tr("GT_THIRDCORNERGRADIENT") << tr("GT_FORTHCORNERGRADIENT"); + idList << HorizontalGradient << VerticalGradient << + Diagonal1Gradient << Diagonal2Gradient << + Corner1Gradient << Corner2Gradient << + Corner3Gradient << Corner4Gradient; + txtList << Qtx::CenterTexture << Qtx::TileTexture << Qtx::StretchTexture; + return tr("BG_IMAGE_FILES"); +} +/*! + Constructor + \param DisplayTrihedron - is trihedron displayed +*/ +OCCViewer_Viewer::OCCViewer_Viewer( bool DisplayTrihedron) +: SUIT_ViewModel(), + myBackgrounds(4, Qtx::BackgroundData( Qt::black )), + myIsRelative(true), + myTopLayerId( 0 ), + myTrihedronSize(100), + myClippingDlg (NULL) +{ + // init CasCade viewers + myV3dViewer = OCCViewer_VService::CreateViewer( TCollection_ExtendedString("Viewer3d").ToExtString() ); + //myV3dViewer->Init(); // to avoid creation of the useless perspective view (see OCCT issue 0024267) + myV3dViewer->SetDefaultLights(); + + // init selector + myAISContext = new AIS_InteractiveContext( myV3dViewer ); + myAISContext->SelectionColor( Quantity_NOC_WHITE ); + + // display isoline on planar faces (box for ex.) + myAISContext->IsoOnPlane( true ); + /* create trihedron */ - if( DisplayTrihedron ) + if ( DisplayTrihedron ) { Handle(Geom_Axis2Placement) anAxis = new Geom_Axis2Placement(gp::XOY()); myTrihedron = new AIS_Trihedron(anAxis); @@ -51,37 +125,133 @@ OCCViewer_Viewer::OCCViewer_Viewer( bool DisplayTrihedron ) //myTrihedron->SetColor( Col ); myTrihedron->SetArrowColor( Col.Name() ); myTrihedron->SetSize(100); - Handle(AIS_Drawer) drawer = myTrihedron->Attributes(); - if (drawer->HasDatumAspect()) { - Handle(Prs3d_DatumAspect) daspect = drawer->DatumAspect(); - daspect->FirstAxisAspect()->SetColor(Quantity_Color(1.0, 0.0, 0.0, Quantity_TOC_RGB)); - daspect->SecondAxisAspect()->SetColor(Quantity_Color(0.0, 1.0, 0.0, Quantity_TOC_RGB)); - daspect->ThirdAxisAspect()->SetColor(Quantity_Color(0.0, 0.0, 1.0, Quantity_TOC_RGB)); +#if OCC_VERSION_LARGE > 0x06080000 + Handle(Prs3d_Drawer) drawer = myTrihedron->Attributes(); + if (drawer->HasOwnDatumAspect()) { +#else + Handle(AIS_Drawer) drawer = myTrihedron->Attributes(); + if (drawer->HasDatumAspect()) { +#endif + Handle(Prs3d_DatumAspect) daspect = drawer->DatumAspect(); + daspect->FirstAxisAspect()->SetColor(Quantity_Color(1.0, 0.0, 0.0, Quantity_TOC_RGB)); + daspect->SecondAxisAspect()->SetColor(Quantity_Color(0.0, 1.0, 0.0, Quantity_TOC_RGB)); + daspect->ThirdAxisAspect()->SetColor(Quantity_Color(0.0, 0.0, 1.0, Quantity_TOC_RGB)); } - - myAISContext->Display(myTrihedron); - myAISContext->Deactivate(myTrihedron); } + // set interaction style to standard + myInteractionStyle = 0; + + // set zooming style to standard + myZoomingStyle = 0; + + // preselection + myPreselectionEnabled = true; + // selection mySelectionEnabled = true; myMultiSelectionEnabled = true; -} + //set clipping color and texture to standard + myClippingColor = QColor( 50, 50, 50 ); + myDefaultTextureUsed = true; + myClippingTexture = QString(); + myTextureModulated = true; + myClippingTextureScale = 1.0; +} + +/*! + Destructor +*/ OCCViewer_Viewer::~OCCViewer_Viewer() { + myAISContext.Nullify(); + myV3dViewer.Nullify(); +} + +/*! + [obsolete] + \return background color of viewer +*/ +QColor OCCViewer_Viewer::backgroundColor() const +{ + return backgroundColor(0); +} + +/*! + \return background data of viewer +*/ +Qtx::BackgroundData OCCViewer_Viewer::background() const +{ + return background(0); +} + +/*! + Sets background color [obsolete] + \param c - new background color +*/ +void OCCViewer_Viewer::setBackgroundColor( const QColor& c ) +{ + setBackgroundColor( 0, c ); +} + +/*! + Sets background data + \param d - new background data +*/ +void OCCViewer_Viewer::setBackground( const Qtx::BackgroundData& theBackground ) +{ + setBackground( 0, theBackground ); } +/*! + Start initialization of view window + \param view - view window to be initialized +*/ +void OCCViewer_Viewer::initView( OCCViewer_ViewWindow* view ) +{ + if ( view ) { + view->initLayout(); + view->initSketchers(); + view->setInteractionStyle( interactionStyle() ); + view->setZoomingStyle( zoomingStyle() ); + view->enablePreselection( isPreselectionEnabled() ); + view->enableSelection( isSelectionEnabled() ); + + OCCViewer_ViewPort3d* vp3d = view->getViewPort(); + if ( vp3d ) + { + vp3d->getView()->SetSurfaceDetail(V3d_TEX_ALL); + // connect signal from viewport + connect(vp3d, SIGNAL(vpClosed(OCCViewer_ViewPort3d*)), this, SLOT(onViewClosed(OCCViewer_ViewPort3d*))); + connect(vp3d, SIGNAL(vpMapped(OCCViewer_ViewPort3d*)), this, SLOT(onViewMapped(OCCViewer_ViewPort3d*))); + } + } +} -SUIT_ViewWindow* OCCViewer_Viewer::createView(SUIT_Desktop* theDesktop) +/*! + Creates new view window + \param theDesktop - main window of application +*/ +SUIT_ViewWindow* OCCViewer_Viewer::createView( SUIT_Desktop* theDesktop ) { - OCCViewer_ViewWindow* res = new OCCViewer_ViewWindow(theDesktop, this); - res->initLayout(); - return res; + // create view frame + OCCViewer_ViewFrame* view = new OCCViewer_ViewFrame(theDesktop, this); + // get main view window (created by view frame) + OCCViewer_ViewWindow* vw = view->getView(OCCViewer_ViewFrame::MAIN_VIEW); + // initialize main view window + initView( vw ); + // set default background for view window + vw->setBackground( background(0) ); // 0 means MAIN_VIEW (other views are not yet created here) + + return view; } -//********************************************************************* +/*! + Sets new view manager + \param theViewManager - new view manager +*/ void OCCViewer_Viewer::setViewManager(SUIT_ViewManager* theViewManager) { SUIT_ViewModel::setViewManager(theViewManager); @@ -94,42 +264,77 @@ void OCCViewer_Viewer::setViewManager(SUIT_ViewManager* theViewManager) connect(theViewManager, SIGNAL(mouseRelease(SUIT_ViewWindow*, QMouseEvent*)), this, SLOT(onMouseRelease(SUIT_ViewWindow*, QMouseEvent*))); + + connect(theViewManager, SIGNAL(keyPress(SUIT_ViewWindow*, QKeyEvent*)), + this, SLOT(onKeyPress(SUIT_ViewWindow*, QKeyEvent*))); } } - -//********************************************************************* +/*! + SLOT: called on mouse button press, stores current mouse position as start point for transformations +*/ void OCCViewer_Viewer::onMousePress(SUIT_ViewWindow* theWindow, QMouseEvent* theEvent) { myStartPnt.setX(theEvent->x()); myStartPnt.setY(theEvent->y()); } - -//********************************************************************* +/*! + SLOT: called on mouse move, processes transformation or hilighting +*/ void OCCViewer_Viewer::onMouseMove(SUIT_ViewWindow* theWindow, QMouseEvent* theEvent) { if (!mySelectionEnabled) return; if (!theWindow->inherits("OCCViewer_ViewWindow")) return; OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*) theWindow; - myAISContext->MoveTo(theEvent->x(), theEvent->y(), aView->getViewPort()->getView()); + + myCurPnt.setX(theEvent->x()); myCurPnt.setY(theEvent->y()); + + if ( isSelectionEnabled() && isPreselectionEnabled() ) { + if (aView->getViewPort()->isBusy()) { + QCoreApplication::processEvents(); + return; // Check that the ViewPort initialization completed + // To Prevent call move event if the View port is not initialized + // IPAL 20883 + } + Handle(V3d_View) aView3d = aView->getViewPort()->getView(); + if ( !aView3d.IsNull() ) { + myAISContext->MoveTo(theEvent->x(), theEvent->y(), aView3d); + } + } } -//********************************************************************* +/*! + SLOT: called on mouse button release, finishes transformation or selection +*/ void OCCViewer_Viewer::onMouseRelease(SUIT_ViewWindow* theWindow, QMouseEvent* theEvent) { if (!mySelectionEnabled) return; if (theEvent->button() != Qt::LeftButton) return; if (!theWindow->inherits("OCCViewer_ViewWindow")) return; + OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*) theWindow; + if (!aView ) + return; myEndPnt.setX(theEvent->x()); myEndPnt.setY(theEvent->y()); - OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*) theWindow; - bool aHasShift = (theEvent->state() & Qt::ShiftButton); + bool aHasShift = (theEvent->modifiers() & Qt::ShiftModifier); + + if (!aHasShift) { + myAISContext->ClearCurrents( false ); + emit deselection(); + } if (myStartPnt == myEndPnt) { + if ( !isPreselectionEnabled() ) { + Handle(V3d_View) aView3d = aView->getViewPort()->getView(); + if ( !aView3d.IsNull() ) { + myAISContext->MoveTo(myEndPnt.x(), myEndPnt.y(), aView3d); + } + } + if (aHasShift && myMultiSelectionEnabled) myAISContext->ShiftSelect(); else @@ -163,129 +368,445 @@ void OCCViewer_Viewer::onMouseRelease(SUIT_ViewWindow* theWindow, QMouseEvent* t emit selectionChanged(); } +/*! + SLOT: called on key press, processes selection in "key free" interaction style +*/ +void OCCViewer_Viewer::onKeyPress(SUIT_ViewWindow* theWindow, QKeyEvent* theEvent) +{ + if (!mySelectionEnabled) return; -//********************************************************************* -void OCCViewer_Viewer::enableSelection(bool isEnabled) + OCCViewer_ViewWindow* aView = qobject_cast( theWindow ); + if ( !aView ) return; + + bool aHasShift = (theEvent->modifiers() & Qt::ShiftModifier); + + switch ( theEvent->key() ) { + case Qt::Key_S: + if (!aHasShift) { + myAISContext->ClearCurrents( false ); + emit deselection(); + } + + if ( !isPreselectionEnabled() ) { + Handle(V3d_View) aView3d = aView->getViewPort()->getView(); + if ( !aView3d.IsNull() ) { + myAISContext->MoveTo(myCurPnt.x(), myCurPnt.y(), aView3d); + } + } + + if (aHasShift && myMultiSelectionEnabled) + myAISContext->ShiftSelect(); + else + myAISContext->Select(); + + emit selectionChanged(); + + break; + case Qt::Key_N: + if ( isPreselectionEnabled() ) { + if ( getAISContext()->HasOpenedContext() ) + getAISContext()->HilightNextDetected( aView->getViewPort()->getView() ); + } + break; + case Qt::Key_P: + if ( isPreselectionEnabled() ) { + if ( getAISContext()->HasOpenedContext() ) + getAISContext()->HilightPreviousDetected( aView->getViewPort()->getView() ); + } + break; + default: + break; + } +} + +void OCCViewer_Viewer::onViewClosed(OCCViewer_ViewPort3d*) { - mySelectionEnabled = isEnabled; - //!! To be done for view windows + Standard_Integer aViewsNb = 0; + for ( myV3dViewer->InitActiveViews(); myV3dViewer->MoreActiveViews(); myV3dViewer->NextActiveViews()) + ++aViewsNb; + if ( aViewsNb < 2 ) { + //clean up presentations before last view is closed + myAISContext->RemoveAll(Standard_False); + } } -//********************************************************************* -void OCCViewer_Viewer::enableMultiselection(bool isEnable) +void OCCViewer_Viewer::onViewMapped(OCCViewer_ViewPort3d* viewPort) { - myMultiSelectionEnabled = isEnable; + setTrihedronShown( true ); + bool showStaticTrihedron = true; + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + if ( resMgr ) showStaticTrihedron = resMgr->booleanValue( "3DViewer", "show_static_trihedron", true ); + viewPort->showStaticTrihedron( showStaticTrihedron ); +} + +int OCCViewer_Viewer::getTopLayerId() +{ + if ( myTopLayerId == 0 && !myAISContext->CurrentViewer().IsNull() ) + myAISContext->CurrentViewer()->AddZLayer( myTopLayerId ); + + return myTopLayerId; +} + +/*! + \return interaction style +*/ +int OCCViewer_Viewer::interactionStyle() const +{ + return myInteractionStyle; +} + +/*! + Sets interaction style: 0 - standard, 1 - keyboard free interaction + \param theStyle - new interaction style +*/ +void OCCViewer_Viewer::setInteractionStyle( const int theStyle ) +{ + myInteractionStyle = theStyle; //!! To be done for view windows + if ( !myViewManager ) + return; + + QVector wins = myViewManager->getViews(); + for ( int i = 0; i < (int)wins.count(); i++ ) + { + OCCViewer_ViewWindow* win = ::qobject_cast( wins.at( i ) ); + if ( win ) + win->setInteractionStyle( theStyle ); + } } -//********************************************************************* -void OCCViewer_Viewer::contextMenuPopup(QPopupMenu* thePopup) +/*! + \return zooming style +*/ +int OCCViewer_Viewer::zoomingStyle() const { - thePopup->insertItem( tr( "MEN_DUMP_VIEW" ), this, SLOT( onDumpView() ) ); - thePopup->insertItem( tr( "MEN_CHANGE_BACKGROUD" ), this, SLOT( onChangeBgColor() ) ); + return myZoomingStyle; +} - thePopup->insertSeparator(); +/*! + Sets zooming style: 0 - standard, 1 - advanced (at cursor) + \param theStyle - new zooming style +*/ +void OCCViewer_Viewer::setZoomingStyle( const int theStyle ) +{ + myZoomingStyle = theStyle; + //!! To be done for view windows + if ( !myViewManager ) + return; - OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*)(myViewManager->getActiveView()); - if ( aView && !aView->getToolBar()->isVisible() ) - thePopup->insertItem( tr( "MEN_SHOW_TOOLBAR" ), this, SLOT( onShowToolbar() ) ); + QVector wins = myViewManager->getViews(); + for ( int i = 0; i < (int)wins.count(); i++ ) + { + OCCViewer_ViewWindow* win = ::qobject_cast( wins.at( i ) ); + if ( win ) + win->setZoomingStyle( theStyle ); + } } -void OCCViewer_Viewer::onDumpView() +/*! + \return true if preselection is enabled +*/ +bool OCCViewer_Viewer::isPreselectionEnabled() const +{ + return myPreselectionEnabled; +} + +/*! + Enables/disables preselection + \param isEnabled - new status +*/ +void OCCViewer_Viewer::enablePreselection(bool isEnabled) { - OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*)(myViewManager->getActiveView()); - if ( aView ) - aView->onDumpView(); + myPreselectionEnabled = isEnabled; + + if ( !myViewManager ) + return; + + QVector wins = myViewManager->getViews(); + for ( int i = 0; i < (int)wins.count(); i++ ) + { + OCCViewer_ViewWindow* win = ::qobject_cast( wins.at( i ) ); + if ( win ) { + win->enablePreselection( isEnabled ); + } + } +} + +/*! + \return true if selection is enabled +*/ +bool OCCViewer_Viewer::isSelectionEnabled() const +{ + return mySelectionEnabled; } -//********************************************************************* -void OCCViewer_Viewer::onChangeBgColor() +/*! + Enables/disables selection + \param isEnabled - new status +*/ +void OCCViewer_Viewer::enableSelection(bool isEnabled) { - OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*)(myViewManager->getActiveView()); - if( !aView ) + mySelectionEnabled = isEnabled; + + //!! To be done for view windows + if ( !myViewManager ) return; - OCCViewer_ViewPort3d* aViewPort3d = aView->getViewPort(); - if( !aViewPort3d ) + + QVector wins = myViewManager->getViews(); + for ( int i = 0; i < (int)wins.count(); i++ ) + { + OCCViewer_ViewWindow* win = ::qobject_cast( wins.at( i ) ); + if ( win ) { + win->updateEnabledDrawMode(); + win->enableSelection( isEnabled ); + } + } + + + //clear current selection in the viewer + if(!isEnabled) { + myAISContext->ClearSelected( Standard_True ); + } + +} + +/*! + Sets multiselection enabled status + \param isEnabled - new status +*/ +void OCCViewer_Viewer::enableMultiselection(bool isEnable) +{ + myMultiSelectionEnabled = isEnable; + //!! To be done for view windows + if ( !myViewManager ) return; - QColor aColorActive = aViewPort3d->backgroundColor(); - QColor selColor = QColorDialog::getColor( aColorActive, aView); - if ( selColor.isValid() ) - aViewPort3d->setBackgroundColor(selColor); + QVector wins = myViewManager->getViews(); + for ( int i = 0; i < (int)wins.count(); i++ ) + { + OCCViewer_ViewWindow* win = ::qobject_cast( wins.at( i ) ); + if ( win ) + win->updateEnabledDrawMode(); + } } -//********************************************************************* -void OCCViewer_Viewer::onShowToolbar() { - OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*)(myViewManager->getActiveView()); - if ( aView ) - aView->getToolBar()->show(); +/*! + Sets a color of the clipped region + \param theColor - a new color of the clipped region +*/ +void OCCViewer_Viewer::setClippingColor( const QColor& theColor ) +{ + myClippingColor = theColor; + + if( myInternalClipPlanes.IsEmpty() ) + return; + + Graphic3d_MaterialAspect aMaterialAspect = Graphic3d_MaterialAspect(); + aMaterialAspect.SetColor( Quantity_Color( theColor.redF(), theColor.greenF(), + theColor.blueF(), Quantity_TOC_RGB ) ); + + for( int i = 1; i <= myInternalClipPlanes.Size(); i++ ) + myInternalClipPlanes.Value(i)->SetCappingMaterial( aMaterialAspect ); + + update(); } -//********************************************************************* -void OCCViewer_Viewer::update() +/*! + \return clipping color +*/ +QColor OCCViewer_Viewer::clippingColor() const { - if (!myV3dViewer.IsNull()) - myV3dViewer->Update(); + return myClippingColor; } -//********************************************************************* -void OCCViewer_Viewer::getSelectedObjects(AIS_ListOfInteractive& theList) +// initialize a texture for clipped region +Handle(Graphic3d_Texture2Dmanual) initClippingTexture( const bool isDefault, const QString& theTexture, + const bool isModulate, const double theScale ) { - theList.Clear(); - for (myAISContext->InitSelected(); myAISContext->MoreSelected(); myAISContext->NextSelected()) - theList.Append(myAISContext->SelectedInteractive()); + QString aTextureFile = isDefault ? ":images/hatch.png" : theTexture; + QPixmap px( aTextureFile ); + const Handle(Image_PixMap) aPixmap = OCCViewer_Utilities::imageToPixmap( px.toImage() ); + Handle(Graphic3d_Texture2Dmanual) aTexture = new Graphic3d_Texture2Dmanual( aPixmap ); + if( aTexture->IsDone() ) { + aTexture->EnableRepeat(); + isModulate ? aTexture->EnableModulate() : aTexture->DisableModulate(); + aTexture->GetParams()->SetScale( Graphic3d_Vec2( 1/( theScale*100 ), -1 / ( theScale*100 ) ) ); + } + return aTexture; } -//********************************************************************* -void OCCViewer_Viewer::setObjectsSelected(const AIS_ListOfInteractive& theList) +/*! + Sets default texture parameters + \param isDefault - use/non-use default texture + \param theTexture - new texture of the clipped region + \param isModulate - enable/disable texture modulate mode + \param theScale - scale factor. +*/ +void OCCViewer_Viewer::setClippingTextureParams( const bool isDefault, const QString& theTexture, + const bool isModulate, const double theScale ) { - AIS_ListIteratorOfListOfInteractive aIt; - for (aIt.Initialize(theList); aIt.More(); aIt.Next()) - myAISContext->SetSelected(aIt.Value(), false); - myAISContext->UpdateCurrentViewer(); + myDefaultTextureUsed = isDefault; + myClippingTexture = theTexture; + myTextureModulated = isModulate; + myClippingTextureScale = theScale; + + if( myInternalClipPlanes.IsEmpty() ) + return; + + Handle(Graphic3d_Texture2Dmanual) aTexture = + initClippingTexture( myDefaultTextureUsed, myClippingTexture, + myTextureModulated, myClippingTextureScale ); + + for( int i = 1; i <= myInternalClipPlanes.Size(); i++ ) + myInternalClipPlanes.Value(i)->SetCappingTexture( aTexture ); + + update(); } -//********************************************************************* -void OCCViewer_Viewer::performSelectionChanged() +/*! + \return true if default texture is used +*/ +bool OCCViewer_Viewer::isDefaultTextureUsed() const { - emit selectionChanged(); + return myDefaultTextureUsed; } -//**************************************************************** +/*! + \return clipping texture +*/ +QString OCCViewer_Viewer::clippingTexture() const +{ + return myClippingTexture; +} -void OCCViewer_Viewer::onClearViewAspects() +/*! + \return true if texture is modulated +*/ +bool OCCViewer_Viewer::isTextureModulated() const { - clearViewAspects(); + return myTextureModulated; } -//**************************************************************** +/*! + \return scale factor of texture +*/ +double OCCViewer_Viewer::clippingTextureScale() const +{ + return myClippingTextureScale; +} -void OCCViewer_Viewer::clearViewAspects() +/*! + Builds popup for occ viewer +*/ +void OCCViewer_Viewer::contextMenuPopup(QMenu* thePopup) { - myViewAspects.clear(); + thePopup->addAction( tr( "MEN_DUMP_VIEW" ), this, SLOT( onDumpView() ) ); + thePopup->addAction( tr( "MEN_CHANGE_BACKGROUND" ), this, SLOT( onChangeBackground() ) ); + + thePopup->addSeparator(); + + OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*)(myViewManager->getActiveView()); + + //Support of several toolbars in the popup menu + QList lst = qFindChildren( aView ); + QList::const_iterator it = lst.begin(), last = lst.end(); + for ( ; it!=last; it++ ) { + if ( (*it)->parentWidget()->isVisible() ) + thePopup->addAction( (*it)->toggleViewAction() ); + } } -//**************************************************************** +/*! + SLOT: called on dump view operation is activated, stores scene to raster file +*/ +void OCCViewer_Viewer::onDumpView() +{ + OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*)(myViewManager->getActiveView()); + if ( aView ) + aView->onDumpView(); +} -const viewAspectList& OCCViewer_Viewer::getViewAspects() +/*! + SLOT: called if background color is to be changed changed, passes new color to view port +*/ +void OCCViewer_Viewer::onChangeBackground() { - return myViewAspects; + OCCViewer_ViewWindow* aView = dynamic_cast(myViewManager->getActiveView()); + if ( !aView ) + return; + + // get supported gradient types + QStringList gradList; + QIntList idList, txtList; + QString formats = backgroundData( gradList, idList, txtList ); + + // invoke dialog box + Qtx::BackgroundData bgData = QtxBackgroundDialog::getBackground( aView->background(), // initial background + aView, // parent for dialog box + txtList, // allowed texture modes + true, // enable solid color mode + true, // enable gradient mode + false, // disable custom gradient mode + !txtList.isEmpty(), // enable/disable texture mode + gradList, // gradient names + idList, // gradient identifiers + formats ); // image formats + + // set chosen background data to the viewer + if ( bgData.isValid() ) + aView->setBackground( bgData ); } -//**************************************************************** +/*! + Updates OCC 3D viewer +*/ +void OCCViewer_Viewer::update() +{ + if (!myV3dViewer.IsNull()) + myV3dViewer->Update(); + + OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*)(myViewManager->getActiveView()); + if ( aView ) + aView->updateGravityCoords(); +} -void OCCViewer_Viewer::appendViewAspect( const viewAspect& aParams ) +/*! + \return objects selected in 3D viewer + \param theList - list to be filled with selected objects +*/ +void OCCViewer_Viewer::getSelectedObjects(AIS_ListOfInteractive& theList) { - myViewAspects.append( aParams ); + theList.Clear(); + for (myAISContext->InitSelected(); myAISContext->MoreSelected(); myAISContext->NextSelected()) + theList.Append(myAISContext->SelectedInteractive()); } -//**************************************************************** +/*! + Selects objects in 3D viewer. Other selected objects are left as selected + \param theList - list objects to be selected +*/ +void OCCViewer_Viewer::setObjectsSelected(const AIS_ListOfInteractive& theList) +{ + AIS_ListIteratorOfListOfInteractive aIt; + for (aIt.Initialize(theList); aIt.More(); aIt.Next()) + myAISContext->AddOrRemoveSelected(aIt.Value(), false); + myAISContext->UpdateCurrentViewer(); +} -void OCCViewer_Viewer::updateViewAspects( const viewAspectList& aViewList ) +/*! + Auxiliary method to emit signal selectionChanged() +*/ +void OCCViewer_Viewer::performSelectionChanged() { - myViewAspects = aViewList; + emit selectionChanged(); } +/*! + Hilights/unhilights object in viewer + \param obj - object to be updated + \param hilight - if it is true, object will be hilighted, otherwise it will be unhilighted + \param update - update current viewer +*/ bool OCCViewer_Viewer::highlight( const Handle(AIS_InteractiveObject)& obj, bool hilight, bool update ) { @@ -305,28 +826,40 @@ bool OCCViewer_Viewer::highlight( const Handle(AIS_InteractiveObject)& obj, return false; } -bool OCCViewer_Viewer::unHighlightAll( bool updateviewer ) +/*! + Unhilights all objects in viewer + \param updateviewer - update current viewer +*/ +bool OCCViewer_Viewer::unHighlightAll( bool updateviewer, bool unselect ) { - if ( myAISContext->HasOpenedContext() ) - myAISContext->ClearSelected( updateviewer ); - else - myAISContext->ClearCurrents( updateviewer ); + if ( myAISContext->HasOpenedContext() ) { + if ( unselect ) { + myAISContext->ClearSelected( updateviewer ); + } else { + myAISContext->UnhilightSelected( updateviewer ); + } + } else { + if ( unselect ) { + myAISContext->ClearCurrents( updateviewer ); + } else { + myAISContext->UnhilightCurrents( updateviewer ); + } + } + return false; } +/*! + \return true if object is in viewer or in collector + \param obj - object to be checked + \param onlyInViewer - search object only in viewer (so object must be displayed) +*/ bool OCCViewer_Viewer::isInViewer( const Handle(AIS_InteractiveObject)& obj, bool onlyInViewer ) { AIS_ListOfInteractive List; myAISContext->DisplayedObjects(List); - if( !onlyInViewer ) - { - AIS_ListOfInteractive List1; - myAISContext->ObjectsInCollector(List1); - List.Append(List1); - } - AIS_ListIteratorOfListOfInteractive ite(List); for ( ; ite.More(); ite.Next() ) if( ite.Value()==obj ) @@ -335,11 +868,21 @@ bool OCCViewer_Viewer::isInViewer( const Handle(AIS_InteractiveObject)& obj, return false; } +/*! + \return true if object is displayed in viewer + \param obj - object to be checked +*/ bool OCCViewer_Viewer::isVisible( const Handle(AIS_InteractiveObject)& obj ) { return myAISContext->IsDisplayed( obj ); } +/*! + Sets color of object + \param obj - object to be updated + \param color - new color + \param update - update current viewer +*/ void OCCViewer_Viewer::setColor( const Handle(AIS_InteractiveObject)& obj, const QColor& color, bool update ) @@ -357,14 +900,26 @@ void OCCViewer_Viewer::setColor( const Handle(AIS_InteractiveObject)& obj, myV3dViewer->Update(); } +/*! + Changes display mode of object + \param obj - object to be processed + \param mode - new display mode + \param update - update current viewer +*/ void OCCViewer_Viewer::switchRepresentation( const Handle(AIS_InteractiveObject)& obj, int mode, bool update ) { - myAISContext->SetDisplayMode( obj, (Standard_Integer)mode, true ); + myAISContext->SetDisplayMode( obj, (Standard_Integer)mode, update ); if( update ) myV3dViewer->Update(); } +/*! + Changes transparency of object + \param obj - object to be processed + \param trans - new transparency + \param update - update current viewer +*/ void OCCViewer_Viewer::setTransparency( const Handle(AIS_InteractiveObject)& obj, float trans, bool update ) { @@ -373,3 +928,332 @@ void OCCViewer_Viewer::setTransparency( const Handle(AIS_InteractiveObject)& obj if( update ) myV3dViewer->Update(); } + +/*! + Changes visibility of trihedron to opposite +*/ +void OCCViewer_Viewer::toggleTrihedron() +{ + setTrihedronShown( !isTrihedronVisible() ); +} + +/*! + \return true if trihedron is visible +*/ +bool OCCViewer_Viewer::isTrihedronVisible() const +{ + return !myTrihedron.IsNull() && !myAISContext.IsNull() && myAISContext->IsDisplayed( myTrihedron ); +} + +/*! + Sets visibility state of trihedron + \param on - new state +*/ + +void OCCViewer_Viewer::setTrihedronShown( const bool on ) +{ + if ( myTrihedron.IsNull() ) + return; + + if ( on ) { + myAISContext->Display( myTrihedron ); + myAISContext->Deactivate(myTrihedron); + } + else { + myAISContext->Erase( myTrihedron ); + } +} + +/*! + \return trihedron size +*/ +double OCCViewer_Viewer::trihedronSize() const +{ + double sz = 0; + if ( !myTrihedron.IsNull() ) + sz = myTrihedron->Size(); + return sz; +} + +/*! + Changes trihedron size + \param sz - new size +*/ +void OCCViewer_Viewer::setTrihedronSize( const double sz, bool isRelative ) +{ + if ( myTrihedronSize != sz || isRelative != myIsRelative) { + myTrihedronSize = sz; + myIsRelative = isRelative; + updateTrihedron(); + } +} + +/*! + Set number of isolines + \param u - u-isolines (first parametric co-ordinate) + \param v - v-isolines (second parametric co-ordinate) +*/ +void OCCViewer_Viewer::setIsos( const int u, const int v ) +{ + Handle(AIS_InteractiveContext) ic = getAISContext(); + if ( ic.IsNull() ) + return; + + ic->SetIsoNumber( u, AIS_TOI_IsoU ); + ic->SetIsoNumber( v, AIS_TOI_IsoV ); +} + +/*! + \return number of isolines + \param u - to return u-isolines (first parametric co-ordinate) + \param v - to return v-isolines (second parametric co-ordinate) +*/ +void OCCViewer_Viewer::isos( int& u, int& v ) const +{ + Handle(AIS_InteractiveContext) ic = getAISContext(); + if ( !ic.IsNull() ) + { + u = ic->IsoNumber( AIS_TOI_IsoU ); + v = ic->IsoNumber( AIS_TOI_IsoV ); + } +} + +/* + * Returns a new OCCViewer_ViewWindow instance which will be placed as a sub window in ViewFrame + */ +OCCViewer_ViewWindow* OCCViewer_Viewer::createSubWindow() +{ + return new OCCViewer_ViewWindow(0, this); +} + +// obsolete +QColor OCCViewer_Viewer::backgroundColor( int theViewId ) const +{ + return background( theViewId ).color(); +} + +Qtx::BackgroundData OCCViewer_Viewer::background( int theViewId ) const +{ + return ( theViewId >= 0 && theViewId < myBackgrounds.count() ) ? myBackgrounds[theViewId] : Qtx::BackgroundData(); +} + +// obsolete +void OCCViewer_Viewer::setBackgroundColor( int theViewId, const QColor& theColor ) +{ + if ( theColor.isValid() ) { + Qtx::BackgroundData bg = background( theViewId ); + bg.setColor( theColor ); + setBackground( theViewId, bg ); + } +} + +void OCCViewer_Viewer::setBackground( int theViewId, const Qtx::BackgroundData& theBackground ) +{ + if ( theBackground.isValid() && theViewId >= 0 && theViewId < myBackgrounds.count() ) + myBackgrounds[theViewId] = theBackground; +} + + +/*! + Set the show static trihedron flag +*/ +void OCCViewer_Viewer::setStaticTrihedronDisplayed(const bool on) +{ + OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*)(myViewManager->getActiveView()); + if ( aView ) aView->showStaticTrihedron( on ); +} + +/*! + Get new and current trihedron size corresponding to the current model size +*/ +bool OCCViewer_Viewer::computeTrihedronSize( double& theNewSize, double& theSize ) +{ + theNewSize = 100; + theSize = 100; + + //SRN: BUG IPAL8996, a usage of method ActiveView without an initialization + Handle(V3d_Viewer) viewer = getViewer3d(); + viewer->InitActiveViews(); + if(!viewer->MoreActiveViews()) return false; + + Handle(V3d_View) view3d = viewer->ActiveView(); + //SRN: END of fix + + if ( view3d.IsNull() ) + return false; + + double aMaxSide = computeSceneSize( view3d ); + + // IPAL21687 + // The boundary box of the view may be initialized but nullified + // (case of infinite objects) + if ( aMaxSide < Precision::Confusion() ) + return false; + + float aSizeInPercents = SUIT_Session::session()->resourceMgr()->doubleValue("3DViewer","trihedron_size", 100.); + + static float EPS = 5.0E-3; + theSize = getTrihedron()->Size(); + theNewSize = aMaxSide*aSizeInPercents / 100.0; + + return fabs( theNewSize - theSize ) > theSize * EPS || + fabs( theNewSize - theSize ) > theNewSize * EPS; +} + +/*! + * Compute scene size + */ +double OCCViewer_Viewer::computeSceneSize(const Handle(V3d_View)& view3d) const +{ + double aMaxSide = 0; + double Xmin = 0, Ymin = 0, Zmin = 0, Xmax = 0, Ymax = 0, Zmax = 0; + +#if OCC_VERSION_LARGE > 0x06070100 + Bnd_Box aBox = view3d->View()->MinMaxValues(); + Xmin = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().X(); + Ymin = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().Y(); + Zmin = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().Z(); + Xmax = aBox.IsVoid() ? RealLast() : aBox.CornerMax().X(); + Ymax = aBox.IsVoid() ? RealLast() : aBox.CornerMax().Y(); + Zmax = aBox.IsVoid() ? RealLast() : aBox.CornerMax().Z(); +#else + view3d->View()->MinMaxValues( Xmin, Ymin, Zmin, Xmax, Ymax, Zmax ); +#endif + + if ( Xmin != RealFirst() && Ymin != RealFirst() && Zmin != RealFirst() && + Xmax != RealLast() && Ymax != RealLast() && Zmax != RealLast() ) + { + aMaxSide = Xmax - Xmin; + if ( aMaxSide < Ymax -Ymin ) aMaxSide = Ymax -Ymin; + if ( aMaxSide < Zmax -Zmin ) aMaxSide = Zmax -Zmin; + } + + return aMaxSide; +} + +/*! + * Update the size of the trihedron + */ +void OCCViewer_Viewer::updateTrihedron() { + if ( myTrihedron.IsNull() ) + return; + + if(myIsRelative){ + double newSz, oldSz; + + if(computeTrihedronSize(newSz, oldSz)) + myTrihedron->SetSize(newSz); + + } else if(myTrihedron->Size() != myTrihedronSize) { + myTrihedron->SetSize(myTrihedronSize); + } +} + +/*! + Set number of isolines + \param u - u-isolines (first parametric co-ordinate) + \param v - v-isolines (second parametric co-ordinate) +*/ +void OCCViewer_Viewer::setSelectionOptions( bool isPreselectionEnabled, bool isSelectionEnabled ) +{ + myPreselectionEnabled = isPreselectionEnabled; + mySelectionEnabled = isSelectionEnabled; + //clear current selection in the viewer + + if(!mySelectionEnabled) { + myAISContext->ClearSelected( Standard_True ); + } +} + +/*! + Creates clipping plane based on the incoming plane +*/ +Handle(Graphic3d_ClipPlane) OCCViewer_Viewer::createClipPlane(const gp_Pln& thePlane, const Standard_Boolean theIsOn) +{ + Handle(Graphic3d_ClipPlane) aGraphic3dPlane = new Graphic3d_ClipPlane( thePlane ); + aGraphic3dPlane->SetOn( theIsOn ); + aGraphic3dPlane->SetCapping( Standard_True ); + + // set capping color + Graphic3d_MaterialAspect aMaterialAspect = Graphic3d_MaterialAspect(); + aMaterialAspect.SetColor( Quantity_Color( myClippingColor.redF(), myClippingColor.greenF(), + myClippingColor.blueF(), Quantity_TOC_RGB ) ); + aGraphic3dPlane->SetCappingMaterial( aMaterialAspect ); + + // set capping texture + aGraphic3dPlane->SetCappingTexture( initClippingTexture( myDefaultTextureUsed, myClippingTexture, + myTextureModulated, myClippingTextureScale ) ); + + return aGraphic3dPlane; +} +/*! + Applies clipping planes to clippable objects +*/ +void OCCViewer_Viewer::setClipPlanes(ClipPlanesList theList) +{ + // 1. Remove existing clipping planes + myClipPlanes.clear(); + myInternalClipPlanes.Clear(); + + // 2. Create new clipping planes + ClipPlanesList::iterator inIt = theList.begin(); + for (;inIt != theList.end(); inIt++ ) + { + OCCViewer_ClipPlane aPlane = *inIt; + + double aDx = 0.0, aDy = 0.0, aDz = 0.0; + aPlane.OrientationToXYZ( aDx, aDy, aDz ); + + gp_Pnt anOrigin( aPlane.X, aPlane.Y, aPlane.Z ); + gp_Dir aDirection( aDx, aDy, aDz ); + + myInternalClipPlanes.Append( createClipPlane( gp_Pln( anOrigin, aDirection ), aPlane.IsOn ) ); + myClipPlanes.push_back( aPlane ); + } + + // 3. Apply clipping planes + AIS_ListOfInteractive aList; + myAISContext->DisplayedObjects (aList); + for ( AIS_ListIteratorOfListOfInteractive anIter (aList); anIter.More(); anIter.Next() ) { + Handle(AIS_InteractiveObject) anObj = anIter.Value(); + Handle(ViewerData_AISShape) aShape = Handle(ViewerData_AISShape)::DownCast (anObj); + if (!aShape.IsNull() && aShape->IsClippable()) { + aShape->SetClipPlanes(myInternalClipPlanes); + } + } +} + +/*! + Returns the clipping planes applied to the displayed objects. +*/ +ClipPlanesList OCCViewer_Viewer::getClipPlanes() const { + return myClipPlanes; +} +/*! + Applies clipping planes to given object objects +*/ +void OCCViewer_Viewer::applyExistingClipPlanesToObject (const Handle(AIS_InteractiveObject)& theObject) +{ + Handle(ViewerData_AISShape) aShape = Handle(ViewerData_AISShape)::DownCast (theObject); + if (!aShape.IsNull() && aShape->IsClippable()) + { + aShape->SetClipPlanes (myInternalClipPlanes); + } +} + +/*! + Returns the pointer to the clipping dialog box. +*/ +OCCViewer_ClippingDlg* OCCViewer_Viewer::getClippingDlg() const{ + return myClippingDlg; +} + + +/*! + Stores pointer to the clipping dialog box. +*/ +void OCCViewer_Viewer::setClippingDlg(OCCViewer_ClippingDlg* theDlg) { + if(myClippingDlg != theDlg) { + myClippingDlg = theDlg; + } +}