From 4aa4bc7e0960d0ac780d9fa218a574a883184125 Mon Sep 17 00:00:00 2001 From: asl Date: Tue, 26 Aug 2014 11:37:06 +0000 Subject: [PATCH] refs #432: refactoring of the shape class --- src/HYDROGUI/CMakeLists.txt | 4 + src/HYDROGUI/HYDROGUI_CalculationOp.cxx | 6 +- src/HYDROGUI/HYDROGUI_DataObject.h | 11 +- src/HYDROGUI/HYDROGUI_ImmersibleZoneOp.cxx | 3 +- src/HYDROGUI/HYDROGUI_OCCDisplayer.cxx | 32 +- src/HYDROGUI/HYDROGUI_Shape.cxx | 350 ++++----------------- src/HYDROGUI/HYDROGUI_Shape.h | 62 ++-- src/HYDROGUI/HYDROGUI_ShapeBathymetry.cxx | 117 +++++++ src/HYDROGUI/HYDROGUI_ShapeBathymetry.h | 55 ++++ src/HYDROGUI/HYDROGUI_ShapeImage.cxx | 225 +++++++++++++ src/HYDROGUI/HYDROGUI_ShapeImage.h | 60 ++++ 11 files changed, 592 insertions(+), 333 deletions(-) create mode 100644 src/HYDROGUI/HYDROGUI_ShapeBathymetry.cxx create mode 100644 src/HYDROGUI/HYDROGUI_ShapeBathymetry.h create mode 100644 src/HYDROGUI/HYDROGUI_ShapeImage.cxx create mode 100644 src/HYDROGUI/HYDROGUI_ShapeImage.h diff --git a/src/HYDROGUI/CMakeLists.txt b/src/HYDROGUI/CMakeLists.txt index 26bb74a6..9b00fb98 100644 --- a/src/HYDROGUI/CMakeLists.txt +++ b/src/HYDROGUI/CMakeLists.txt @@ -58,6 +58,8 @@ set(PROJECT_HEADERS HYDROGUI_Region.h HYDROGUI_RemoveImageRefsOp.h HYDROGUI_Shape.h + HYDROGUI_ShapeBathymetry.h + HYDROGUI_ShapeImage.h HYDROGUI_ShowHideOp.h HYDROGUI_StreamDlg.h HYDROGUI_StreamOp.h @@ -155,6 +157,8 @@ set(PROJECT_SOURCES HYDROGUI_Region.cxx HYDROGUI_RemoveImageRefsOp.cxx HYDROGUI_Shape.cxx + HYDROGUI_ShapeBathymetry.cxx + HYDROGUI_ShapeImage.cxx HYDROGUI_ShowHideOp.cxx HYDROGUI_StreamDlg.cxx HYDROGUI_StreamOp.cxx diff --git a/src/HYDROGUI/HYDROGUI_CalculationOp.cxx b/src/HYDROGUI/HYDROGUI_CalculationOp.cxx index 954e789f..f3b4351c 100644 --- a/src/HYDROGUI/HYDROGUI_CalculationOp.cxx +++ b/src/HYDROGUI/HYDROGUI_CalculationOp.cxx @@ -296,13 +296,13 @@ void HYDROGUI_CalculationOp::onObjectsSelected() aName = anEntity->GetName(); isSelected = aSelectedObjsMap.contains( aName ); aShape->highlight( isSelected, false ); - aShape->update( false ); + aShape->update( false, false ); aLastShape = aShape; } } } if( aLastShape ) - aLastShape->update( true ); + aLastShape->update( true, false ); } void HYDROGUI_CalculationOp::onClickedInZonesBrowser( SUIT_DataObject* theItem ) @@ -407,7 +407,7 @@ void HYDROGUI_CalculationOp::onSetMergeType( int theMergeType, QString& theAltit HYDROGUI_Shape* aShape = module()->getObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, aZone->modelObject() ); if ( aShape ) { - aShape->update(); + aShape->update( true, false ); } } aPanel->refreshZonesBrowser(); diff --git a/src/HYDROGUI/HYDROGUI_DataObject.h b/src/HYDROGUI/HYDROGUI_DataObject.h index b35d60c0..5d4ffb89 100644 --- a/src/HYDROGUI/HYDROGUI_DataObject.h +++ b/src/HYDROGUI/HYDROGUI_DataObject.h @@ -25,13 +25,22 @@ #include -#include +#ifdef WIN32 + #pragma warning( disable: 4250 ) + #pragma warning( disable: 4251 ) +#endif +#include #include #include #include #include +#ifdef WIN32 + #pragma warning( disable: 4250 ) + #pragma warning( disable: 4251 ) +#endif + /** * \class HYDROGUI_DataObject * \brief Module data object, used for object browser tree creation. diff --git a/src/HYDROGUI/HYDROGUI_ImmersibleZoneOp.cxx b/src/HYDROGUI/HYDROGUI_ImmersibleZoneOp.cxx index b6c0fd02..82ec0181 100644 --- a/src/HYDROGUI/HYDROGUI_ImmersibleZoneOp.cxx +++ b/src/HYDROGUI/HYDROGUI_ImmersibleZoneOp.cxx @@ -44,6 +44,7 @@ #include #include +#include #include #include @@ -256,7 +257,7 @@ void HYDROGUI_ImmersibleZoneOp::onCreatePreview( const QString& thePolylineName TopoDS_Face aFace; if( !aZoneShape.IsNull() ) aFace = TopoDS::Face( aZoneShape ); - myPreviewPrs->setFace( aFace ); + myPreviewPrs->setFace( aFace, true, true, "" ); } QApplication::restoreOverrideCursor(); diff --git a/src/HYDROGUI/HYDROGUI_OCCDisplayer.cxx b/src/HYDROGUI/HYDROGUI_OCCDisplayer.cxx index 43df0948..c8cf6c69 100644 --- a/src/HYDROGUI/HYDROGUI_OCCDisplayer.cxx +++ b/src/HYDROGUI/HYDROGUI_OCCDisplayer.cxx @@ -25,10 +25,12 @@ #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 @@ -156,7 +158,13 @@ HYDROGUI_Shape* HYDROGUI_OCCDisplayer::createShape( const int if ( !HYDROGUI_Tool::IsObjectHasPresentation( theObject, OCCViewer_Viewer::Type() ) ) return aResShape; - aResShape = new HYDROGUI_Shape( theContext, theObject ); + 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( theContext, Handle_HYDROData_Bathymetry::DownCast( theObject ) ); + else + aResShape = new HYDROGUI_Shape( theContext, theObject ); + module()->setObjectShape( theViewerId, theObject, aResShape ); return aResShape; @@ -349,7 +357,7 @@ bool HYDROGUI_OCCDisplayer::Display( const Handle(HYDROData_Entity)& theObject, if ( anObjShape ) { // update if needed if ( anObjShape->getIsToUpdate() || theIsForced ) { - anObjShape->update( false ); + anObjShape->update( false, false ); } // Set visibility @@ -395,9 +403,9 @@ void HYDROGUI_OCCDisplayer::UpdateColorScale( const OCCViewer_Viewer* theViewer Handle(V3d_View) aView = aWnd->getViewPort()->getView(); int aViewerId = (size_t)theViewer;//TODO: check if viewer id is correct - QList aBaths = module()->getObjectShapes( aViewerId, KIND_BATHYMETRY ); + QList aShapes = module()->getObjectShapes( aViewerId, KIND_BATHYMETRY ); - bool isDisplayColorScale = !aBaths.empty(); + bool isDisplayColorScale = !aShapes.empty(); Standard_Real anXPos = 0.05; //TODO Standard_Real anYPos = 0.1; //TODO Standard_Real aWidth = 0.2; //TODO @@ -408,8 +416,12 @@ void HYDROGUI_OCCDisplayer::UpdateColorScale( const OCCViewer_Viewer* theViewer Standard_Real aColorScaleMin = 0, aColorScaleMax = 1, aMin, aMax; bool isFirst = true; - foreach( HYDROGUI_Shape* aBathShape, aBaths ) + foreach( HYDROGUI_Shape* aShape, aShapes ) { + HYDROGUI_ShapeBathymetry* aBathShape = dynamic_cast( aShape ); + if( !aBathShape ) + continue; + aBathShape->GetRange( aMin, aMax ); if( isFirst || aMin < aColorScaleMin ) @@ -436,8 +448,14 @@ void HYDROGUI_OCCDisplayer::UpdateColorScale( const OCCViewer_Viewer* theViewer aColorScale->SetTitle( aColorScaleTitle ); aColorScale->SetRange( aColorScaleMin, aColorScaleMax ); - foreach( HYDROGUI_Shape* aBathShape, aBaths ) + foreach( HYDROGUI_Shape* aShape, aShapes ) + { + HYDROGUI_ShapeBathymetry* aBathShape = dynamic_cast( aShape ); + if( !aBathShape ) + continue; + aBathShape->UpdateWithColorScale( aColorScale ); + } } if( !aView->ColorScaleIsDisplayed() ) aView->ColorScaleDisplay(); diff --git a/src/HYDROGUI/HYDROGUI_Shape.cxx b/src/HYDROGUI/HYDROGUI_Shape.cxx index f18e3870..5bdb0548 100644 --- a/src/HYDROGUI/HYDROGUI_Shape.cxx +++ b/src/HYDROGUI/HYDROGUI_Shape.cxx @@ -20,61 +20,31 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#include "HYDROGUI_Shape.h" - -#include "HYDROGUI_DataObject.h" -#include "HYDROGUI_Tool.h" - -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include -#include - -#include - +#include +#include #include #include -#include -#include -#include +#include #include #include #include -#include +#include #include -#include #include #include #include +#include +#include +#include +#include +#include +#include #include -#include #include - +#include #include -#include - -#include - -#include -#include -#include -#include -#include - -#include -#include - HYDROGUI_Shape::HYDROGUI_Shape( const Handle(AIS_InteractiveContext)& theContext, const Handle(HYDROData_Entity)& theObject, const int theZLayer ) @@ -97,8 +67,41 @@ HYDROGUI_Shape::~HYDROGUI_Shape() if ( !myShape.IsNull() ) myShape.Nullify(); +} + +Handle(AIS_InteractiveContext) HYDROGUI_Shape::getContext() const +{ + return myContext; +} + +Handle(HYDROData_Entity) HYDROGUI_Shape::getObject() const +{ + return myObject; +} + +TopoDS_Shape HYDROGUI_Shape::getTopoShape() const +{ + return myTopoShape; +} - removeTextureFile(); +bool HYDROGUI_Shape::getIsToUpdate() const +{ + return myIsToUpdate; +} + +void HYDROGUI_Shape::setIsToUpdate( bool theState ) +{ + myIsToUpdate = theState; +} + +bool HYDROGUI_Shape::isVisible() const +{ + return myIsVisible; +} + +Handle(AIS_InteractiveObject) HYDROGUI_Shape::getAISObject() const +{ + return myShape; } void HYDROGUI_Shape::display( const bool theIsUpdateViewer ) @@ -117,14 +120,15 @@ void HYDROGUI_Shape::erase( const bool theIsUpdateViewer ) myContext->Erase( myShape, theIsUpdateViewer ); } -void HYDROGUI_Shape::update( const bool theIsUpdateViewer ) +void HYDROGUI_Shape::update( bool isUpdateViewer, + bool isDeactivateSelection ) + { setIsToUpdate( false ); if ( myContext.IsNull() ) return; - bool isDeactivateSelection = false; // Try to retrieve information from object if ( !myObject.IsNull() ) { @@ -139,10 +143,11 @@ void HYDROGUI_Shape::update( const bool theIsUpdateViewer ) if ( !aZoneShape.IsNull() ) { if ( aZoneShape.ShapeType() == TopAbs_FACE ) { TopoDS_Face aZoneFace = TopoDS::Face( aZoneShape ); - setFace( aZoneFace, false, false ); + setFace( aZoneFace, false, false, "" ); } else { myTopoShape = aZoneShape; - myDisplayMode = myTextureFileName.isEmpty() ? AIS_Shaded : AIS_Shaded+2; + //TODO: myDisplayMode = myTextureFileName.isEmpty() ? AIS_Shaded : AIS_Shaded+2; + myDisplayMode = AIS_Shaded; buildShape(); updateShape( false, false ); @@ -212,7 +217,7 @@ void HYDROGUI_Shape::update( const bool theIsUpdateViewer ) TopoDS_Face aZoneFace = TopoDS::Face( aZone->GetShape() ); - setFace( aZoneFace, false, false ); + setFace( aZoneFace, false, false, "" ); if (aZone->IsMergingNeed() && aZone->GetMergeType() == HYDROData_Zone::Merge_UNKNOWN ) { // Red color for a zone with bathymetry conflict @@ -242,92 +247,6 @@ void HYDROGUI_Shape::update( const bool theIsUpdateViewer ) setFillingColor( HYDROGUI_Tool::GenerateFillingColor( aDocument, aGeomObjectsNames ) ); } } - else if ( myObject->IsKind( STANDARD_TYPE(HYDROData_Image) ) ) - { - Handle(HYDROData_Image) anImageObj = - Handle(HYDROData_Image)::DownCast( myObject ); - - removeTextureFile(); - - QString aTextureFileName = generateTextureFileName( anImageObj ); - - QImage anImage = anImageObj->Image(); - QString aFilePath = anImageObj->GetFilePath(); - QTransform aTrsf = anImageObj->Trsf(); - - int aWidth = anImage.width(); - int aHeight = anImage.height(); - - QString anImageError = ""; - - QTransform anInversion = QTransform::fromScale( -1, -1 ); - anImage = anImage.transformed( anInversion * aTrsf, Qt::SmoothTransformation ); - - if ( anImage.isNull() ) - anImageError = QObject::tr( "IMAGE_TRANSFORMATION_CAN_NOT_BE_APPLYED" ); - else - { - // Workaround: Scale the texture image to the nearest width multiple 4 due to the CASCADE bug 23813 - int aTrsfWidth = anImage.width(); - int aDelta = aTrsfWidth % 4; - if ( aDelta > 0 ) - { - aTrsfWidth += ( 4 - aDelta ); - } - anImage = anImage.scaledToWidth( aTrsfWidth ); - - // temporary optimization, to reduce the saved image size (and the texture quality) - QImage anImageToSave = anImage; //RKV:reduceTexture( anImage, 500 ); - - bool isSaved = anImageToSave.save( aTextureFileName ); - if ( !isSaved ) - anImageError = QObject::tr( "FILE_CAN_NOT_BE_CREATED" ).arg( aTextureFileName ); - else - QFile::setPermissions( aTextureFileName, (QFile::Permissions)0x4FFFF ); - } - - if ( !anImageError.isEmpty() ) - { - SUIT_MessageBox::warning( 0, QObject::tr( "SHAPE_IMAGE_ERROR" ), - QObject::tr( "IMAGE_CAN_NOT_BE_CREATED" ) + anImageError ); - } - - QPointF aPoint1( 0, 0 ); // 1: top left - QPointF aPoint2( aWidth, 0 ); // 2: top right - QPointF aPoint3( aWidth, aHeight ); // 3: bottom right - QPointF aPoint4( 0, aHeight ); // 4: bottom left - - aPoint1 = aTrsf.map( aPoint1 ); - aPoint2 = aTrsf.map( aPoint2 ); - aPoint3 = aTrsf.map( aPoint3 ); - aPoint4 = aTrsf.map( aPoint4 ); - - QPolygonF aPolygon = QPolygonF() << aPoint1 << aPoint2 << aPoint3 << aPoint4; - QRectF aRect = aPolygon.boundingRect(); - - gp_Pnt aPnt1( aRect.topLeft().x(), aRect.topLeft().y(), 0 ); - gp_Pnt aPnt2( aRect.topRight().x(), aRect.topRight().y(), 0 ); - gp_Pnt aPnt3( aRect.bottomRight().x(), aRect.bottomRight().y(), 0 ); - gp_Pnt aPnt4( aRect.bottomLeft().x(), aRect.bottomLeft().y(), 0 ); - - Handle_HYDROData_Document aDoc = HYDROData_Document::Document( anImageObj->Label() ); - aDoc->Transform( aPnt1, true ); - aDoc->Transform( aPnt2, true ); - aDoc->Transform( aPnt3, true ); - aDoc->Transform( aPnt4, true ); - - TopoDS_Edge anEdge1 = BRepBuilderAPI_MakeEdge( aPnt1, aPnt2 ).Edge(); - TopoDS_Edge anEdge2 = BRepBuilderAPI_MakeEdge( aPnt2, aPnt3 ).Edge(); - TopoDS_Edge anEdge3 = BRepBuilderAPI_MakeEdge( aPnt3, aPnt4 ).Edge(); - TopoDS_Edge anEdge4 = BRepBuilderAPI_MakeEdge( aPnt4, aPnt1 ).Edge(); - - TopoDS_Wire aWire = BRepBuilderAPI_MakeWire( anEdge1, anEdge2, anEdge3, anEdge4 ).Wire(); - aWire.Closed( true ); - - setTextureFileName( aTextureFileName, false, false ); - setFace( aWire, false, false ); - isDeactivateSelection = true; - } else if ( myObject->IsKind( STANDARD_TYPE(HYDROData_Profile) ) ) { Handle(HYDROData_Profile) aProfile = @@ -400,17 +319,12 @@ void HYDROGUI_Shape::update( const bool theIsUpdateViewer ) setShape( aCompound, false, false ); } - else if ( myObject->IsKind( STANDARD_TYPE(HYDROData_Bathymetry) ) ) - { - buildShape(); - updateShape( false, false ); - } } if ( myShape.IsNull() || !isVisible() ) return; - displayShape( theIsUpdateViewer ); + displayShape( isUpdateViewer ); if (isDeactivateSelection) myContext->Deactivate(myShape); @@ -498,23 +412,25 @@ void HYDROGUI_Shape::setFaces( const TopoDS_Compound& theWires, void HYDROGUI_Shape::setFace( const TopoDS_Wire& theWire, const bool theToDisplay, - const bool theIsUpdateViewer ) + const bool theIsUpdateViewer, + const QString& theTextureFileName ) { BRepBuilderAPI_MakeFace aFaceBuilder( theWire, Standard_True ); aFaceBuilder.Build(); if( aFaceBuilder.IsDone() ) { TopoDS_Face aFace = aFaceBuilder.Face(); - setFace( aFace, theToDisplay, theIsUpdateViewer ); + setFace( aFace, theToDisplay, theIsUpdateViewer, theTextureFileName ); } } void HYDROGUI_Shape::setFace( const TopoDS_Face& theFace, const bool theToDisplay, - const bool theIsUpdateViewer ) + const bool theIsUpdateViewer, + const QString& theTextureFileName ) { myTopoShape = theFace; - myDisplayMode = myTextureFileName.isEmpty() ? AIS_Shaded : AIS_Shaded+2; + myDisplayMode = theTextureFileName.isEmpty() ? AIS_Shaded : AIS_Shaded+2; //Note: AIS_Shaded+2 is the same as AIS_ExactHLR //TODO: it would be more suitable to use TexturedShape mode from GEOM_AISShape @@ -569,19 +485,6 @@ QColor HYDROGUI_Shape::getHighlightColor() const return myHighlightColor; } -void HYDROGUI_Shape::setTextureFileName( const QString& theFileName, - const bool theToDisplay, - const bool theIsUpdateViewer ) -{ - myTextureFileName = theFileName; - updateShape( theToDisplay, theIsUpdateViewer ); -} - -QString HYDROGUI_Shape::getTextureFileName() const -{ - return myTextureFileName; -} - void HYDROGUI_Shape::setZLayer( const int theZLayer ) { if ( myZLayer == theZLayer ) @@ -592,44 +495,20 @@ void HYDROGUI_Shape::setZLayer( const int theZLayer ) myContext->SetZLayer( myShape, myZLayer ); } -#include +Handle_AIS_InteractiveObject HYDROGUI_Shape::createShape() const +{ + if( myTopoShape.IsNull() ) + return Handle_AIS_InteractiveObject(); + else + return new AIS_Shape( myTopoShape ); +} + void HYDROGUI_Shape::buildShape() { // Erase previously created shape erase(); - Handle_HYDROData_Bathymetry aBath = Handle_HYDROData_Bathymetry::DownCast( myObject ); - bool isBath = !aBath.IsNull(); - - if( !isBath && myTopoShape.IsNull() ) { - myShape.Nullify(); - return; - } - - QString aTextureFileName = getTextureFileName(); - bool anIsTexture = !aTextureFileName.isEmpty(); - if ( anIsTexture ) - { - myShape = new AIS_TexturedShape( myTopoShape ); - } - else if( isBath ) - { - Handle_AIS_PointCloud aPntCloud = new AIS_PointCloud(); - aPntCloud->Attributes()->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_POINT, Quantity_NOC_WHITE, 1.0)); - - myShape = aPntCloud; - const HYDROData_Bathymetry::AltitudePoints& aBathPoints = aBath->GetAltitudePoints(); - int aLower = aBathPoints.Lower(); - int anUpper = aBathPoints.Upper(); - myCoords = new TColgp_HArray1OfPnt( aLower, anUpper ); - myColors = new Quantity_HArray1OfColor( aLower, anUpper ); - for( int i=aLower; i<=anUpper; i++ ) - myCoords->SetValue( i, aBathPoints.Value( i ) ); - } - else - { - myShape = new AIS_Shape( myTopoShape ); - } + myShape = createShape(); Handle_AIS_Shape anAISShape = Handle_AIS_Shape::DownCast( myShape ); if( !anAISShape.IsNull() ) @@ -641,18 +520,6 @@ void HYDROGUI_Shape::buildShape() myShape->SetTransparency( 0 ); myShape->SetDisplayMode( (AIS_DisplayMode)myDisplayMode ); - if( anIsTexture ) - { - Handle(AIS_TexturedShape) aTexturedShape = - Handle(AIS_TexturedShape)::DownCast( myShape ); - - aTexturedShape->SetTextureFileName( HYDROGUI_Tool::ToAsciiString( aTextureFileName ) ); - aTexturedShape->SetTextureMapOn(); - // Just use the texture image as is - aTexturedShape->DisableTextureModulate(); - aTexturedShape->SetTextureRepeat( false ); // don't repeat the texture image on the face - } - // Init default params for shape const Handle(AIS_Drawer)& anAttributes = myShape->Attributes(); if ( !anAttributes.IsNull() ) @@ -797,84 +664,3 @@ void HYDROGUI_Shape::colorShapeBorder( const QColor& theColor ) } } } - -QString HYDROGUI_Shape::generateTextureFileName( const Handle(HYDROData_Entity)& theImageObj ) -{ - QString aResult; - if( !theImageObj.IsNull() ) - { - QString aTempDir = HYDROGUI_Tool::GetTempDir( true ); - - int aStudyId = HYDROGUI_Tool::GetActiveStudyId(); - QString aPrefix = QString( "image_%1" ).arg( aStudyId ); - - QString anEntry = HYDROGUI_DataObject::dataObjectEntry( theImageObj, false ); - anEntry.replace( ':', '_' ); - - QString anExtension = "bmp"; - - aResult = QString( "%1/%2_%3.%4" ).arg( aTempDir, aPrefix, anEntry, anExtension ); - } - return aResult; -} - -void HYDROGUI_Shape::removeTextureFile() const -{ - QFile aFile( getTextureFileName() ); - if( aFile.exists() ) - aFile.remove(); -} - -QImage HYDROGUI_Shape::reduceTexture( const QImage& theImage, const int theSizeLimit ) -{ - double aSizeLimit = (double)theSizeLimit; - double aWidth = (double)theImage.width(); - double aHeight = (double)theImage.height(); - if( aWidth > aSizeLimit || aHeight > aSizeLimit ) - { - if( aWidth > aHeight ) - { - aHeight /= ( aWidth / aSizeLimit ); - aWidth = aSizeLimit; - } - else - { - aWidth /= ( aHeight / aSizeLimit ); - aHeight = aSizeLimit; - } - } - return theImage.scaled( aWidth, aHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation ); -} - -void HYDROGUI_Shape::GetRange( double& theMin, double& theMax ) const -{ - theMin = 0; - theMax = 0; - if( myCoords.IsNull() ) - return; - - bool isFirst = true; - for( int i=myCoords->Lower(), n=myCoords->Upper(); i<=n; i++ ) - { - double aValue = myCoords->Value( i ).Z(); - if( isFirst || aValue < theMin ) - theMin = aValue; - if( isFirst || aValue > theMax ) - theMax = aValue; - isFirst = false; - } -} - -void HYDROGUI_Shape::UpdateWithColorScale( const Handle(Aspect_ColorScale)& theColorScale ) -{ - for( int i=myCoords->Lower(), n=myCoords->Upper(); i<=n; i++ ) - { - double z = myCoords->Value( i ).Z(); - Quantity_Color aColor; - theColorScale->FindColor( z, aColor ); - myColors->SetValue( i, aColor ); - } - Handle_AIS_PointCloud aPntCloud = Handle_AIS_PointCloud::DownCast( myShape ); - aPntCloud->SetPoints( myCoords, myColors ); - myContext->Redisplay( aPntCloud, Standard_False ); -} diff --git a/src/HYDROGUI/HYDROGUI_Shape.h b/src/HYDROGUI/HYDROGUI_Shape.h index c5b3b41f..64548763 100644 --- a/src/HYDROGUI/HYDROGUI_Shape.h +++ b/src/HYDROGUI/HYDROGUI_Shape.h @@ -23,20 +23,16 @@ #ifndef HYDROGUI_SHAPE_H #define HYDROGUI_SHAPE_H -#include -#include -#include -#include -#include - #include +#include +#include + #include -#include -#include -#include -#include +class TopoDS_Compound; +class TopoDS_Face; +class TopoDS_Wire; class HYDROGUI_Shape { @@ -44,7 +40,7 @@ public: HYDROGUI_Shape( const Handle(AIS_InteractiveContext)& theContext, const Handle(HYDROData_Entity)& theObject, const int theZLayer = -1 ); - ~HYDROGUI_Shape(); + virtual ~HYDROGUI_Shape(); public: virtual void display( const bool theIsUpdateViewer = true ); @@ -53,14 +49,17 @@ public: virtual void highlight( bool theIsHighlight, bool isUpdateViewer ); virtual bool isHighlighted() const; - Handle(HYDROData_Entity) getObject() const { return myObject; } + Handle(AIS_InteractiveContext) getContext() const; + Handle(HYDROData_Entity) getObject() const; + TopoDS_Shape getTopoShape() const; - virtual void update( const bool theIsUpdateViewer = true ); + virtual void update( bool isUpdateViewer, + bool isDeactivateSelection ); - virtual bool getIsToUpdate() const { return myIsToUpdate; } - virtual void setIsToUpdate( bool theState ) { myIsToUpdate = theState; } + virtual bool getIsToUpdate() const; + virtual void setIsToUpdate( bool theState ); - virtual bool isVisible() const { return myIsVisible; } + virtual bool isVisible() const; virtual void setVisible( const bool theState, const bool theIsUpdateViewer = true ); @@ -73,12 +72,14 @@ public: const bool theIsUpdateViewer = true ); virtual void setFace( const TopoDS_Wire& theWire, - const bool theToDisplay = true, - const bool theIsUpdateViewer = true ); + const bool theToDisplay, + const bool theIsUpdateViewer, + const QString& theTextureFileName ); virtual void setFace( const TopoDS_Face& theFace, - const bool theToDisplay = true, - const bool theIsUpdateViewer = true ); + const bool theToDisplay, + const bool theIsUpdateViewer, + const QString& theTextureFileName ); virtual void setShape( const TopoDS_Shape& theShape, const bool theToDisplay = true, @@ -97,18 +98,10 @@ public: virtual void setHighlightColor( const QColor& theColor ); virtual QColor getHighlightColor() const; - virtual void setTextureFileName( const QString& theFileName, - const bool theToDisplay = true, - const bool theIsUpdateViewer = true ); - virtual QString getTextureFileName() const; - - virtual Handle(AIS_InteractiveObject) getAISObject() const { return myShape; } + virtual Handle(AIS_InteractiveObject) getAISObject() const; void setZLayer( const int theZLayer ); - void GetRange( double& theMin, double& theMax ) const; - void UpdateWithColorScale( const Handle(Aspect_ColorScale)& ); - protected: virtual void buildShape(); virtual void updateShape( const bool theToDisplay = true, @@ -116,16 +109,12 @@ protected: void displayShape( const bool theIsUpdateViewer ); virtual QColor getActiveColor() const; + virtual Handle_AIS_InteractiveObject createShape() const; private: static double getQuantityColorVal( const int theColorVal ); void colorShapeBorder( const QColor& theColor ); - static QString generateTextureFileName( const Handle(HYDROData_Entity)& theImageObj ); - void removeTextureFile() const; - - static QImage reduceTexture( const QImage& theImage, const int theSizeLimit ); - private: Handle(AIS_InteractiveContext) myContext; Handle(HYDROData_Entity) myObject; @@ -143,11 +132,6 @@ private: QColor myFillingColor; QColor myBorderColor; QColor myHighlightColor; - - QString myTextureFileName; - - Handle_TColgp_HArray1OfPnt myCoords; - Handle_Quantity_HArray1OfColor myColors; }; #endif diff --git a/src/HYDROGUI/HYDROGUI_ShapeBathymetry.cxx b/src/HYDROGUI/HYDROGUI_ShapeBathymetry.cxx new file mode 100644 index 00000000..a414b3c4 --- /dev/null +++ b/src/HYDROGUI/HYDROGUI_ShapeBathymetry.cxx @@ -0,0 +1,117 @@ +// 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 +// +// 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. +// +// 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 +#include + +#include +#include +#include +#include +#include + +HYDROGUI_ShapeBathymetry::HYDROGUI_ShapeBathymetry( const Handle(AIS_InteractiveContext)& theContext, + const Handle_HYDROData_Bathymetry& theBathymetry, + const int theZLayer ) +: HYDROGUI_Shape( theContext, theBathymetry, theZLayer ) +{ +} + +HYDROGUI_ShapeBathymetry::~HYDROGUI_ShapeBathymetry() +{ +} + +void HYDROGUI_ShapeBathymetry::update( bool theIsUpdateViewer, bool isDeactivateSelection ) +{ + setIsToUpdate( false ); + + // Try to retrieve information from object + + Handle(HYDROData_Bathymetry) aBath = Handle(HYDROData_Bathymetry)::DownCast( getObject() ); + + if ( !aBath.IsNull() ) + { + buildShape(); + updateShape( false, false ); + } + + HYDROGUI_Shape::update( theIsUpdateViewer, isDeactivateSelection ); +} + + +Handle_AIS_InteractiveObject HYDROGUI_ShapeBathymetry::createShape() const +{ + Handle_HYDROData_Bathymetry aBath = Handle_HYDROData_Bathymetry::DownCast( getObject() ); + if( !aBath.IsNull() ) + { + Handle_AIS_PointCloud aPntCloud = new AIS_PointCloud(); + aPntCloud->Attributes()->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_POINT, Quantity_NOC_WHITE, 1.0)); + + const HYDROData_Bathymetry::AltitudePoints& aBathPoints = aBath->GetAltitudePoints(); + int aLower = aBathPoints.Lower(); + int anUpper = aBathPoints.Upper(); + + HYDROGUI_ShapeBathymetry* aThat = const_cast( this ); + aThat->myCoords = new TColgp_HArray1OfPnt( aLower, anUpper ); + aThat->myColors = new Quantity_HArray1OfColor( aLower, anUpper ); + for( int i=aLower; i<=anUpper; i++ ) + aThat->myCoords->SetValue( i, aBathPoints.Value( i ) ); + + return aPntCloud; + } + else + return Handle_AIS_InteractiveObject(); +} + +void HYDROGUI_ShapeBathymetry::GetRange( double& theMin, double& theMax ) const +{ + theMin = 0; + theMax = 0; + if( myCoords.IsNull() ) + return; + + bool isFirst = true; + for( int i=myCoords->Lower(), n=myCoords->Upper(); i<=n; i++ ) + { + double aValue = myCoords->Value( i ).Z(); + if( isFirst || aValue < theMin ) + theMin = aValue; + if( isFirst || aValue > theMax ) + theMax = aValue; + isFirst = false; + } +} + +void HYDROGUI_ShapeBathymetry::UpdateWithColorScale( const Handle(Aspect_ColorScale)& theColorScale ) +{ + for( int i=myCoords->Lower(), n=myCoords->Upper(); i<=n; i++ ) + { + double z = myCoords->Value( i ).Z(); + Quantity_Color aColor; + theColorScale->FindColor( z, aColor ); + myColors->SetValue( i, aColor ); + } + Handle_AIS_PointCloud aPntCloud = Handle_AIS_PointCloud::DownCast( getAISObject() ); + aPntCloud->SetPoints( myCoords, myColors ); + getContext()->Redisplay( aPntCloud, Standard_False ); +} + diff --git a/src/HYDROGUI/HYDROGUI_ShapeBathymetry.h b/src/HYDROGUI/HYDROGUI_ShapeBathymetry.h new file mode 100644 index 00000000..840026ed --- /dev/null +++ b/src/HYDROGUI/HYDROGUI_ShapeBathymetry.h @@ -0,0 +1,55 @@ +// 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 +// +// 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. +// +// 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 +// + +#ifndef HYDROGUI_SHAPE_BATHYMETRY_H +#define HYDROGUI_SHAPE_BATHYMETRY_H + +#include +#include +#include + +class Handle_HYDROData_Bathymetry; +class Handle_Aspect_ColorScale; + +class HYDROGUI_ShapeBathymetry : public HYDROGUI_Shape +{ +public: + HYDROGUI_ShapeBathymetry( const Handle(AIS_InteractiveContext)& theContext, + const Handle_HYDROData_Bathymetry& theBathymetry, + const int theZLayer = -1 ); + virtual ~HYDROGUI_ShapeBathymetry(); + + void GetRange( double& theMin, double& theMax ) const; + void UpdateWithColorScale( const Handle_Aspect_ColorScale& ); + + virtual void update( bool isUpdateViewer, + bool isDeactivateSelection ); + +protected: + virtual Handle_AIS_InteractiveObject createShape() const; + +private: + Handle_TColgp_HArray1OfPnt myCoords; + Handle_Quantity_HArray1OfColor myColors; +}; + +#endif diff --git a/src/HYDROGUI/HYDROGUI_ShapeImage.cxx b/src/HYDROGUI/HYDROGUI_ShapeImage.cxx new file mode 100644 index 00000000..f82a6b90 --- /dev/null +++ b/src/HYDROGUI/HYDROGUI_ShapeImage.cxx @@ -0,0 +1,225 @@ +// 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 +// +// 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. +// +// 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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +HYDROGUI_ShapeImage::HYDROGUI_ShapeImage( const Handle(AIS_InteractiveContext)& theContext, + const Handle_HYDROData_Image& theImage, + const int theZLayer ) +: HYDROGUI_Shape( theContext, theImage, theZLayer ) +{ +} + +HYDROGUI_ShapeImage::~HYDROGUI_ShapeImage() +{ + removeTextureFile(); +} + +void HYDROGUI_ShapeImage::update( bool theIsUpdateViewer, bool isDeactivateSelection ) +{ + setIsToUpdate( false ); + + // Try to retrieve information from object + Handle(HYDROData_Image) anImageObj = Handle(HYDROData_Image)::DownCast( getObject() ); + + if( !anImageObj.IsNull() ) + { + removeTextureFile(); + + QString aTextureFileName = generateTextureFileName( anImageObj ); + + QImage anImage = anImageObj->Image(); + QString aFilePath = anImageObj->GetFilePath(); + QTransform aTrsf = anImageObj->Trsf(); + + int aWidth = anImage.width(); + int aHeight = anImage.height(); + + QString anImageError = ""; + + QTransform anInversion = QTransform::fromScale( -1, -1 ); + anImage = anImage.transformed( anInversion * aTrsf, Qt::SmoothTransformation ); + + if ( anImage.isNull() ) + anImageError = QObject::tr( "IMAGE_TRANSFORMATION_CAN_NOT_BE_APPLYED" ); + else + { + // Workaround: Scale the texture image to the nearest width multiple 4 due to the CASCADE bug 23813 + int aTrsfWidth = anImage.width(); + int aDelta = aTrsfWidth % 4; + if ( aDelta > 0 ) + { + aTrsfWidth += ( 4 - aDelta ); + } + anImage = anImage.scaledToWidth( aTrsfWidth ); + + // temporary optimization, to reduce the saved image size (and the texture quality) + QImage anImageToSave = anImage; //RKV:reduceTexture( anImage, 500 ); + + bool isSaved = anImageToSave.save( aTextureFileName ); + if ( !isSaved ) + anImageError = QObject::tr( "FILE_CAN_NOT_BE_CREATED" ).arg( aTextureFileName ); + else + QFile::setPermissions( aTextureFileName, (QFile::Permissions)0x4FFFF ); + } + + if ( !anImageError.isEmpty() ) + { + SUIT_MessageBox::warning( 0, QObject::tr( "SHAPE_IMAGE_ERROR" ), + QObject::tr( "IMAGE_CAN_NOT_BE_CREATED" ) + anImageError ); + } + + QPointF aPoint1( 0, 0 ); // 1: top left + QPointF aPoint2( aWidth, 0 ); // 2: top right + QPointF aPoint3( aWidth, aHeight ); // 3: bottom right + QPointF aPoint4( 0, aHeight ); // 4: bottom left + + aPoint1 = aTrsf.map( aPoint1 ); + aPoint2 = aTrsf.map( aPoint2 ); + aPoint3 = aTrsf.map( aPoint3 ); + aPoint4 = aTrsf.map( aPoint4 ); + + QPolygonF aPolygon = QPolygonF() << aPoint1 << aPoint2 << aPoint3 << aPoint4; + QRectF aRect = aPolygon.boundingRect(); + + gp_Pnt aPnt1( aRect.topLeft().x(), aRect.topLeft().y(), 0 ); + gp_Pnt aPnt2( aRect.topRight().x(), aRect.topRight().y(), 0 ); + gp_Pnt aPnt3( aRect.bottomRight().x(), aRect.bottomRight().y(), 0 ); + gp_Pnt aPnt4( aRect.bottomLeft().x(), aRect.bottomLeft().y(), 0 ); + + Handle_HYDROData_Document aDoc = HYDROData_Document::Document( anImageObj->Label() ); + aDoc->Transform( aPnt1, true ); + aDoc->Transform( aPnt2, true ); + aDoc->Transform( aPnt3, true ); + aDoc->Transform( aPnt4, true ); + + TopoDS_Edge anEdge1 = BRepBuilderAPI_MakeEdge( aPnt1, aPnt2 ).Edge(); + TopoDS_Edge anEdge2 = BRepBuilderAPI_MakeEdge( aPnt2, aPnt3 ).Edge(); + TopoDS_Edge anEdge3 = BRepBuilderAPI_MakeEdge( aPnt3, aPnt4 ).Edge(); + TopoDS_Edge anEdge4 = BRepBuilderAPI_MakeEdge( aPnt4, aPnt1 ).Edge(); + + TopoDS_Wire aWire = BRepBuilderAPI_MakeWire( anEdge1, anEdge2, anEdge3, anEdge4 ).Wire(); + aWire.Closed( true ); + + setTextureFileName( aTextureFileName, false, false ); + setFace( aWire, false, false, aTextureFileName ); + isDeactivateSelection = true; + } + + HYDROGUI_Shape::update( theIsUpdateViewer, isDeactivateSelection ); +} + +void HYDROGUI_ShapeImage::setTextureFileName( const QString& theFileName, + const bool theToDisplay, + const bool theIsUpdateViewer ) +{ + myTextureFileName = theFileName; + updateShape( theToDisplay, theIsUpdateViewer ); +} + +QString HYDROGUI_ShapeImage::getTextureFileName() const +{ + return myTextureFileName; +} + +QString HYDROGUI_ShapeImage::generateTextureFileName( const Handle(HYDROData_Entity)& theImageObj ) +{ + QString aResult; + if( !theImageObj.IsNull() ) + { + QString aTempDir = HYDROGUI_Tool::GetTempDir( true ); + + int aStudyId = HYDROGUI_Tool::GetActiveStudyId(); + QString aPrefix = QString( "image_%1" ).arg( aStudyId ); + + QString anEntry = HYDROGUI_DataObject::dataObjectEntry( theImageObj, false ); + anEntry.replace( ':', '_' ); + + QString anExtension = "bmp"; + + aResult = QString( "%1/%2_%3.%4" ).arg( aTempDir, aPrefix, anEntry, anExtension ); + } + return aResult; +} + +void HYDROGUI_ShapeImage::removeTextureFile() const +{ + QFile aFile( getTextureFileName() ); + if( aFile.exists() ) + aFile.remove(); +} + +QImage HYDROGUI_ShapeImage::reduceTexture( const QImage& theImage, const int theSizeLimit ) +{ + double aSizeLimit = (double)theSizeLimit; + double aWidth = (double)theImage.width(); + double aHeight = (double)theImage.height(); + if( aWidth > aSizeLimit || aHeight > aSizeLimit ) + { + if( aWidth > aHeight ) + { + aHeight /= ( aWidth / aSizeLimit ); + aWidth = aSizeLimit; + } + else + { + aWidth /= ( aHeight / aSizeLimit ); + aHeight = aSizeLimit; + } + } + return theImage.scaled( aWidth, aHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation ); +} + +Handle_AIS_InteractiveObject HYDROGUI_ShapeImage::createShape() const +{ + QString aTextureFileName = getTextureFileName(); + bool anIsTexture = !aTextureFileName.isEmpty(); + if ( anIsTexture ) + { + Handle_AIS_TexturedShape aTexturedShape = new AIS_TexturedShape( getTopoShape() ); + + aTexturedShape->SetTextureFileName( HYDROGUI_Tool::ToAsciiString( aTextureFileName ) ); + aTexturedShape->SetTextureMapOn(); + // Just use the texture image as is + aTexturedShape->DisableTextureModulate(); + aTexturedShape->SetTextureRepeat( false ); // don't repeat the texture image on the face + + return aTexturedShape; + } + else + return Handle_AIS_InteractiveObject(); +} + diff --git a/src/HYDROGUI/HYDROGUI_ShapeImage.h b/src/HYDROGUI/HYDROGUI_ShapeImage.h new file mode 100644 index 00000000..ac8a4d16 --- /dev/null +++ b/src/HYDROGUI/HYDROGUI_ShapeImage.h @@ -0,0 +1,60 @@ +// 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 +// +// 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. +// +// 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 +// + +#ifndef HYDROGUI_SHAPE_IMAGE_H +#define HYDROGUI_SHAPE_IMAGE_H + +#include + +class Handle_HYDROData_Image; +class QImage; + +class HYDROGUI_ShapeImage : public HYDROGUI_Shape +{ +public: + HYDROGUI_ShapeImage( const Handle(AIS_InteractiveContext)& theContext, + const Handle_HYDROData_Image& theImage, + const int theZLayer = -1 ); + virtual ~HYDROGUI_ShapeImage(); + + virtual void setTextureFileName( const QString& theFileName, + const bool theToDisplay = true, + const bool theIsUpdateViewer = true ); + virtual QString getTextureFileName() const; + + virtual void update( bool isUpdateViewer, + bool isDeactivateSelection ); + +protected: + virtual Handle_AIS_InteractiveObject createShape() const; + +private: + static QString generateTextureFileName( const Handle(HYDROData_Entity)& theImageObj ); + void removeTextureFile() const; + + static QImage reduceTexture( const QImage& theImage, const int theSizeLimit ); + +private: + QString myTextureFileName; +}; + +#endif -- 2.39.2