-// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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.
+// 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
#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_Session.h"
#include "SUIT_ResourceMgr.h"
+#include "ViewerData_AISShape.hxx"
+
+#include <Basics_OCCTVersion.hxx>
+
#include "QtxActionToolMgr.h"
#include "QtxBackgroundTool.h"
#include <QDesktopWidget>
#include <AIS_Axis.hxx>
-#include <AIS_Drawer.hxx>
+#if OCC_VERSION_LARGE > 0x06080000
+ #include <Prs3d_Drawer.hxx>
+#else
+ #include <AIS_Drawer.hxx>
+#endif
#include <AIS_ListOfInteractive.hxx>
#include <AIS_ListIteratorOfListOfInteractive.hxx>
+#include <Graphic3d_Texture2Dmanual.hxx>
+#include <Graphic3d_MaterialAspect.hxx>
+#include <Graphic3d_TextureParams.hxx>
+
#include <Geom_Axis2Placement.hxx>
#include <Prs3d_Drawer.hxx>
#include <Prs3d_DatumAspect.hxx>
#include <Prs3d_LineAspect.hxx>
-#include <Prs3d_LengthAspect.hxx>
-#include <Prs3d_AngleAspect.hxx>
#include <Prs3d_TextAspect.hxx>
#include <Visual3d_View.hxx>
-
-// VSR: Uncomment below line to allow texture background support in OCC viewer
-#define OCC_ENABLE_TEXTURED_BACKGROUND
-
/*!
Get data for supported background modes: gradient types, identifiers and supported image formats
*/
Diagonal1Gradient << Diagonal2Gradient <<
Corner1Gradient << Corner2Gradient <<
Corner3Gradient << Corner4Gradient;
-#if OCC_VERSION_LARGE > 0x06050200 // enabled since OCCT 6.5.3, since in previous version this functionality is buggy
-#ifdef OCC_ENABLE_TEXTURED_BACKGROUND
txtList << Qtx::CenterTexture << Qtx::TileTexture << Qtx::StretchTexture;
-#endif
-#endif
return tr("BG_IMAGE_FILES");
}
myBackgrounds(4, Qtx::BackgroundData( Qt::black )),
myIsRelative(true),
myTopLayerId( 0 ),
- myTrihedronSize(100)
+ myTrihedronSize(100),
+ myClippingDlg (NULL)
{
// init CasCade viewers
myV3dViewer = OCCViewer_VService::CreateViewer( TCollection_ExtendedString("Viewer3d").ToExtString() );
- myV3dViewer->Init();
-
-#if OCC_VERSION_LARGE <= 0x06060000 // Porting to OCCT higher 6.6.0 version
- myV3dCollector = OCCViewer_VService::CreateViewer( TCollection_ExtendedString("Collector3d").ToExtString() );
- myV3dCollector->Init();
-#endif
+ //myV3dViewer->Init(); // to avoid creation of the useless perspective view (see OCCT issue 0024267)
+ myV3dViewer->SetDefaultLights();
// init selector
-#if OCC_VERSION_LARGE <= 0x06060000
- myAISContext = new AIS_InteractiveContext( myV3dViewer, myV3dCollector );
-#else
myAISContext = new AIS_InteractiveContext( myV3dViewer );
-#endif
myAISContext->SelectionColor( Quantity_NOC_WHITE );
// display isoline on planar faces (box for ex.)
myAISContext->IsoOnPlane( true );
-
- /*
- double h = QApplication::desktop()->screenGeometry( QApplication::desktop()->primaryScreen() ).height() / 300. ;
- Handle(Prs3d_Drawer) drawer = myAISContext->DefaultDrawer();
- Handle(Prs3d_TextAspect) ta = drawer->TextAspect();
- ta->SetHeight(100); // VSR: workaround for CAS.CADE bug (is it really needed ???)
- ta->SetHeight(h);
- drawer->SetTextAspect(ta);
- drawer->AngleAspect()->SetTextAspect(ta);
- drawer->LengthAspect()->SetTextAspect(ta);
- */
/* create trihedron */
if ( DisplayTrihedron )
//myTrihedron->SetColor( Col );
myTrihedron->SetArrowColor( Col.Name() );
myTrihedron->SetSize(100);
- Handle(AIS_Drawer) drawer = myTrihedron->Attributes();
- if (drawer->HasDatumAspect()) {
+#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));
// selection
mySelectionEnabled = true;
myMultiSelectionEnabled = true;
-
-
- SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
- if(resMgr)
- myShowStaticTrihedron = resMgr->booleanValue( "3DViewer", "show_static_trihedron", true );
+
+ //set clipping color and texture to standard
+ myClippingColor = QColor( 50, 50, 50 );
+ myDefaultTextureUsed = true;
+ myClippingTexture = QString();
+ myTextureModulated = true;
+ myClippingTextureScale = 1.0;
+
}
/*!
{
myAISContext.Nullify();
myV3dViewer.Nullify();
-#if OCC_VERSION_LARGE <= 0x06060000
- myV3dCollector.Nullify();
-#endif
}
/*!
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*)));
}
}
}
initView( vw );
// set default background for view window
vw->setBackground( background(0) ); // 0 means MAIN_VIEW (other views are not yet created here)
- // connect signal from viewport
- connect(view->getViewPort(), SIGNAL(vpClosed()), this, SLOT(onViewClosed()));
- connect(view->getViewPort(), SIGNAL(vpMapped()), this, SLOT(onViewMapped()));
+
return view;
}
myEndPnt.setX(theEvent->x()); myEndPnt.setY(theEvent->y());
bool aHasShift = (theEvent->modifiers() & Qt::ShiftModifier);
- if (!aHasShift) emit deselection();
+ if (!aHasShift) {
+ myAISContext->ClearCurrents( false );
+ emit deselection();
+ }
if (myStartPnt == myEndPnt)
{
void OCCViewer_Viewer::onKeyPress(SUIT_ViewWindow* theWindow, QKeyEvent* theEvent)
{
if (!mySelectionEnabled) return;
- if (theEvent->key() != Qt::Key_S) return;
- if (!theWindow->inherits("OCCViewer_ViewWindow")) return;
- OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*) theWindow;
- if (!aView || aView->interactionStyle() != SUIT_ViewModel::KEY_FREE)
- return;
+ OCCViewer_ViewWindow* aView = qobject_cast<OCCViewer_ViewWindow*>( theWindow );
+ if ( !aView ) return;
- emit deselection();
+ bool aHasShift = (theEvent->modifiers() & Qt::ShiftModifier);
- if ( !isPreselectionEnabled() ) {
- Handle(V3d_View) aView3d = aView->getViewPort()->getView();
- if ( !aView3d.IsNull() ) {
- myAISContext->MoveTo(myCurPnt.x(), myCurPnt.y(), aView3d);
+ 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);
+ }
}
- }
- myAISContext->Select();
+ if (aHasShift && myMultiSelectionEnabled)
+ myAISContext->ShiftSelect();
+ else
+ myAISContext->Select();
- emit selectionChanged();
+ 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()
+void OCCViewer_Viewer::onViewClosed(OCCViewer_ViewPort3d*)
{
Standard_Integer aViewsNb = 0;
for ( myV3dViewer->InitActiveViews(); myV3dViewer->MoreActiveViews(); myV3dViewer->NextActiveViews())
}
}
-void OCCViewer_Viewer::onViewMapped()
+void OCCViewer_Viewer::onViewMapped(OCCViewer_ViewPort3d* viewPort)
{
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 OCC_VERSION_LARGE > 0x06050200
if ( myTopLayerId == 0 && !myAISContext->CurrentViewer().IsNull() )
myAISContext->CurrentViewer()->AddZLayer( myTopLayerId );
-#endif
return myTopLayerId;
}
win->enableSelection( isEnabled );
}
}
+
+
+ //clear current selection in the viewer
+ if(!isEnabled) {
+ myAISContext->ClearSelected( Standard_True );
+ }
+
}
/*!
}
}
+/*!
+ 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();
+}
+
+/*!
+ \return clipping color
+*/
+QColor OCCViewer_Viewer::clippingColor() const
+{
+ return myClippingColor;
+}
+
+// initialize a texture for clipped region
+Handle(Graphic3d_Texture2Dmanual) initClippingTexture( const bool isDefault, const QString& theTexture,
+ const bool isModulate, const double theScale )
+{
+ 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;
+}
+
+/*!
+ 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 )
+{
+ 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();
+}
+
+/*!
+ \return true if default texture is used
+*/
+bool OCCViewer_Viewer::isDefaultTextureUsed() const
+{
+ return myDefaultTextureUsed;
+}
+
+/*!
+ \return clipping texture
+*/
+QString OCCViewer_Viewer::clippingTexture() const
+{
+ return myClippingTexture;
+}
+
+/*!
+ \return true if texture is modulated
+*/
+bool OCCViewer_Viewer::isTextureModulated() const
+{
+ return myTextureModulated;
+}
+
+/*!
+ \return scale factor of texture
+*/
+double OCCViewer_Viewer::clippingTextureScale() const
+{
+ return myClippingTextureScale;
+}
+
/*!
Builds popup for occ viewer
*/
AIS_ListOfInteractive List;
myAISContext->DisplayedObjects(List);
-#if OCC_VERSION_LARGE <= 0x06060000
- if( !onlyInViewer )
- {
- AIS_ListOfInteractive List1;
- myAISContext->ObjectsInCollector(List1);
- List.Append(List1);
- }
-#endif
-
AIS_ListIteratorOfListOfInteractive ite(List);
for ( ; ite.More(); ite.Next() )
if( ite.Value()==obj )
*/
OCCViewer_ViewWindow* OCCViewer_Viewer::createSubWindow()
{
- return new OCCViewer_ViewWindow( 0, this);
+ return new OCCViewer_ViewWindow(0, this);
}
// obsolete
/*!
Set the show static trihedron flag
*/
-void OCCViewer_Viewer::setStaticTrihedronDisplayed(const bool on) {
- if(myShowStaticTrihedron != on) {
- OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*)(myViewManager->getActiveView());
- if(!aView)
- return;
-
- OCCViewer_ViewPort3d* vp3d = aView->getViewPort();
- if(vp3d) {
- myShowStaticTrihedron = on;
- vp3d->updateStaticTriedronVisibility();
- }
- }
+void OCCViewer_Viewer::setStaticTrihedronDisplayed(const bool on)
+{
+ OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*)(myViewManager->getActiveView());
+ if ( aView ) aView->showStaticTrihedron( on );
}
/*!
if ( view3d.IsNull() )
return false;
- double Xmin = 0, Ymin = 0, Zmin = 0, Xmax = 0, Ymax = 0, Zmax = 0;
- double aMaxSide;
-
- view3d->View()->MinMaxValues( Xmin, Ymin, Zmin, Xmax, Ymax, Zmax );
-
- if ( Xmin == RealFirst() || Ymin == RealFirst() || Zmin == RealFirst() ||
- Xmax == RealLast() || Ymax == RealLast() || Zmax == RealLast() )
- return false;
-
- aMaxSide = Xmax - Xmin;
- if ( aMaxSide < Ymax -Ymin ) aMaxSide = Ymax -Ymin;
- if ( aMaxSide < Zmax -Zmin ) aMaxSide = Zmax -Zmin;
+ double aMaxSide = computeSceneSize( view3d );
// IPAL21687
// The boundary box of the view may be initialized but nullified
theSize = getTrihedron()->Size();
theNewSize = aMaxSide*aSizeInPercents / 100.0;
- return fabs( theNewSize - theSize ) > theSize * EPS ||
- fabs( theNewSize - theSize) > theNewSize * EPS;
+ 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;
}
/*!
{
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;
+ }
}