Salome HOME
Profile dialog backgound like it is in OCC viewer.
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_Shape.cxx
index 9a6c0ca700144bd562ff588259b0508e277063a9..799c09f2b36eb4763ae8c2cba2d89e94ff5971fe 100644 (file)
@@ -26,6 +26,7 @@
 #include "HYDROGUI_Tool.h"
 
 #include <AIS_Drawer.hxx>
+#include <AIS_TexturedShape.hxx>
 
 #include <BRepBuilderAPI_MakeEdge.hxx>
 #include <BRepBuilderAPI_MakeWire.hxx>
 #include <HYDROData_Document.h>
 #include <HYDROData_Image.h>
 #include <HYDROData_ImmersibleZone.h>
-#include <HYDROData_Polyline.h>
+#include <HYDROData_PolylineXY.h>
 #include <HYDROData_Region.h>
 #include <HYDROData_Zone.h>
+#include <HYDROData_Obstacle.h>
 
 #include <TopoDS.hxx>
 #include <TopoDS_Wire.hxx>
 #include <TopoDS_Face.hxx>
 
+#include <TopExp_Explorer.hxx>
+
+#include <BRep_Builder.hxx>
+
 #include <Precision.hxx>
 
 #include <Prs3d_ShadingAspect.hxx>
 #include <Prs3d_LineAspect.hxx>
 #include <Prs3d_IsoAspect.hxx>
 
+#include <SUIT_MessageBox.h>
+
 #include <QColor>
 #include <QFile>
 
@@ -113,27 +121,45 @@ void HYDROGUI_Shape::update( const bool theIsUpdateViewer )
       Handle(HYDROData_ImmersibleZone) aZoneObj =
         Handle(HYDROData_ImmersibleZone)::DownCast( myObject );
 
+      TopoDS_Shape aZoneShape = aZoneObj->GetTopShape();
+      if ( !aZoneShape.IsNull() ) {
+        if ( aZoneShape.ShapeType() == TopAbs_FACE ) {
+          TopoDS_Face aZoneFace = TopoDS::Face( aZoneShape );
+          setFace( aZoneFace, false, false );
+        } else {
+          myTopoShape = aZoneShape;
+          myDisplayMode = myTextureFileName.isEmpty() ? AIS_Shaded : AIS_Shaded+2;
+
+          buildShape();
+          updateShape( false, false );
+        }
+      }
+
       QColor aFillingColor = aZoneObj->GetFillingColor();
       QColor aBorderColor = aZoneObj->GetBorderColor();
-      TopoDS_Face aZoneFace = TopoDS::Face( aZoneObj->GetTopShape() );
 
       setFillingColor( aFillingColor, false, false );
       setBorderColor( aBorderColor, false, false );
-      setFace( aZoneFace, false, false );
     }
-    else if ( myObject->IsKind( STANDARD_TYPE(HYDROData_Polyline) ) )
+    else if ( myObject->IsKind( STANDARD_TYPE(HYDROData_PolylineXY) ) )
     {
-      Handle(HYDROData_Polyline) aPolyline =
-        Handle(HYDROData_Polyline)::DownCast( myObject );
-
-      TopoDS_Wire aPolylineWire = TopoDS::Wire( aPolyline->GetTopShape() );
-
-      setWire( aPolylineWire, false, false );
-    }
-    else if ( myObject->IsKind( STANDARD_TYPE(HYDROData_Region) ) )
-    {
-      Handle(HYDROData_Region) aRegion =
-        Handle(HYDROData_Region)::DownCast( myObject );
+      Handle(HYDROData_PolylineXY) aPolyline =
+        Handle(HYDROData_PolylineXY)::DownCast( myObject );
+
+      TopoDS_Shape aPolylineShape = aPolyline->GetShape();
+
+      if ( !aPolylineShape.IsNull() ) {
+        if ( aPolylineShape.ShapeType() == TopAbs_WIRE ) {
+          TopoDS_Wire aPolylineWire = TopoDS::Wire( aPolylineShape );
+          setWire( aPolylineWire, false, false );  
+        } else {
+          myTopoShape = aPolylineShape;
+          myDisplayMode = AIS_WireFrame;
+
+          buildShape();
+          updateShape( false, false );
+        }
+      }
     }
     else if ( myObject->IsKind( STANDARD_TYPE(HYDROData_Zone) ) )
     {
@@ -191,14 +217,29 @@ void HYDROGUI_Shape::update( const bool theIsUpdateViewer )
       QTransform anInversion = QTransform::fromScale( -1, -1 );
       anImage = anImage.transformed( anInversion * aTrsf, Qt::SmoothTransformation );
 
+      // 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 = reduceTexture( anImage, 500 );
-      anImageToSave.save( aTextureFileName );
+      QImage anImageToSave = anImage; //RKV:reduceTexture( anImage, 500 );
+
+      bool isSaved = anImageToSave.save( aTextureFileName );
+      if ( !isSaved ) {
+        QString aTitle = QObject::tr( "FILE_ERROR" );
+        QString aMessage = QObject::tr( "FILE_CAN_NOT_BE_CREATED" ).arg( aTextureFileName );
+        SUIT_MessageBox::warning( 0, aTitle, aMessage );
+      }
 
-      QPointF aPoint1( 0, 0 );
-      QPointF aPoint2( aWidth, 0 );
-      QPointF aPoint3( aWidth, aHeight );
-      QPointF aPoint4( 0, aHeight );
+      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 );
@@ -219,12 +260,33 @@ void HYDROGUI_Shape::update( const bool theIsUpdateViewer )
       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 );
     }
-  }
+    else if ( myObject->IsKind( STANDARD_TYPE(HYDROData_Obstacle) ) )
+    {
+      Handle(HYDROData_Obstacle) anObstacle =
+        Handle(HYDROData_Obstacle)::DownCast( myObject );
+
+      //TODO BEGIN of the block of code to be reimplemented
+      //TODO GetTopShape() to be used in future
+      myTopoShape = anObstacle->GetShape3D();
+      myDisplayMode = AIS_Shaded;
 
+      QColor aFillingColor = anObstacle->GetFillingColor();
+      QColor aBorderColor = anObstacle->GetBorderColor();
+
+      setFillingColor( aFillingColor, false, false );
+      setBorderColor( aBorderColor, false, false );
+
+      buildShape();
+      updateShape( false, false );
+      //TODO END of the block of code to be reimplemented
+    }
+  }
   if ( myShape.IsNull() || !isVisible() )
     return;
 
@@ -278,6 +340,35 @@ void HYDROGUI_Shape::setWire( const TopoDS_Wire& theWire,
   updateShape( theToDisplay, theIsUpdateViewer );
 }
 
+void HYDROGUI_Shape::setFaces( const TopoDS_Compound& theWires,
+                               const bool             theToDisplay,
+                               const bool             theIsUpdateViewer )
+{
+  TopExp_Explorer anExp( theWires, TopAbs_WIRE );
+  TopoDS_Compound aCompound;
+  BRep_Builder aBuilder;
+    aBuilder.MakeCompound( aCompound );
+
+  for ( ; anExp.More(); anExp.Next() ) {
+    TopoDS_Wire aWire = TopoDS::Wire( anExp.Current() );
+    if ( aWire.IsNull() ) {
+      continue;
+    }
+
+    BRepBuilderAPI_MakeFace aMakeFace( aWire, Standard_True );
+    aMakeFace.Build();
+    if( aMakeFace.IsDone() ) {
+      aBuilder.Add( aCompound, aMakeFace.Face() );
+    }
+  }
+
+  myTopoShape = aCompound;
+  myDisplayMode = AIS_Shaded;
+
+  buildShape();
+  updateShape( theToDisplay, theIsUpdateViewer );
+}
+
 void HYDROGUI_Shape::setFace( const TopoDS_Wire& theWire,
                               const bool         theToDisplay,
                               const bool         theIsUpdateViewer )
@@ -296,7 +387,20 @@ void HYDROGUI_Shape::setFace( const TopoDS_Face& theFace,
                               const bool         theIsUpdateViewer )
 {
   myTopoShape = theFace;
-  myDisplayMode = myTextureFileName.isEmpty() ? AIS_Shaded : AIS_ExactHLR;
+  myDisplayMode = myTextureFileName.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
+
+  buildShape();
+  updateShape( theToDisplay, theIsUpdateViewer );
+}
+
+void HYDROGUI_Shape::setShape( const TopoDS_Shape& theShape,
+                               const bool          theToDisplay,
+                               const bool          theIsUpdateViewer )
+{
+  myTopoShape = theShape;
+  myDisplayMode = AIS_Shaded;
 
   buildShape();
   updateShape( theToDisplay, theIsUpdateViewer );
@@ -359,7 +463,17 @@ void HYDROGUI_Shape::buildShape()
   if ( myTopoShape.IsNull() )
     return;
 
-  myShape = new AIS_TexturedShape( myTopoShape );
+  QString aTextureFileName = getTextureFileName();
+  bool anIsTexture = !aTextureFileName.isEmpty();
+
+  if ( anIsTexture )
+  {
+    myShape = new AIS_TexturedShape( myTopoShape );
+  }
+  else
+  {
+    myShape = new AIS_Shape( myTopoShape );
+  }
 
   if ( !myObject.IsNull() )
     myShape->SetOwner( myObject );
@@ -367,12 +481,16 @@ void HYDROGUI_Shape::buildShape()
   myShape->SetTransparency( 0 );
   myShape->SetDisplayMode( (AIS_DisplayMode)myDisplayMode );
 
-  QString aTextureFileName = getTextureFileName();
-  if( !aTextureFileName.isEmpty() )
+  if( anIsTexture )
   {
-    myShape->SetTextureFileName( HYDROGUI_Tool::ToAsciiString( aTextureFileName ) );
-    myShape->SetTextureMapOn();
-    myShape->DisableTextureModulate();
+    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