Salome HOME
refs #1457
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_SplitPolylinesOp.cxx
index 233e79a38e9acc46cc4d8428d0b476f4fc7a7d0f..be1c18e38652cdabea107bd1eb44d8bb6a83a40b 100644 (file)
 
 #include <HYDROGUI_SplitPolylinesOp.h>
 #include <HYDROGUI_SplitPolylinesDlg.h>
+#include <HYDROGUI_Module.h>
+#include <HYDROGUI_UpdateFlags.h>
+#include <HYDROGUI_Shape.h>
+#include <HYDROData_PolylineOperator.h>
+#include <HYDROData_Document.h>
+#include <LightApp_Application.h>
+#include <OCCViewer_ViewModel.h>
+#include <OCCViewer_ViewManager.h>
+#include <OCCViewer_ViewPort3d.h>
+#include <OCCViewer_ViewWindow.h>
+#include <SUIT_Desktop.h>
+#include <SUIT_MessageBox.h>
+#include <CurveCreator_Utils.hxx>
+#include <gp_Pnt2d.hxx>
+#include <BRepLib_MakeVertex.hxx>
+#include <BRep_Builder.hxx>
+#include <BRepBuilderAPI_MakeVertex.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Compound.hxx>
+#include <AIS_Shape.hxx>
+
+#include <QMouseEvent>
 
 HYDROGUI_SplitPolylinesOp::HYDROGUI_SplitPolylinesOp( HYDROGUI_Module* theModule )
-: HYDROGUI_Operation( theModule )
+: HYDROGUI_Operation( theModule ),
+  myPreviewPrs( 0 ),
+  mySplitPointPreview( 0 )
 {
   setName( tr( "SPLIT_POLYLINES" ) );
 }
 
 HYDROGUI_SplitPolylinesOp::~HYDROGUI_SplitPolylinesOp()
 {
+  erasePreview();
 }
 
 void HYDROGUI_SplitPolylinesOp::startOperation()
 {
   HYDROGUI_Operation::startOperation();
 
-  //TODO
+  HYDROGUI_SplitPolylinesDlg* aPanel = 
+    ::qobject_cast<HYDROGUI_SplitPolylinesDlg*>( inputPanel() );
+  if ( !aPanel )
+    return;
+
+  aPanel->setPolylinesFromSelection();
+  LightApp_Application* anApp = module()->getApp();
+  OCCViewer_ViewManager* aViewManager =
+    dynamic_cast<OCCViewer_ViewManager*>( anApp->getViewManager( OCCViewer_Viewer::Type(), true ) );
+  aPanel->setOCCViewer( aViewManager ? aViewManager->getOCCViewer() : 0 );
+  setPreviewManager( aViewManager );
+
+  OnUpdatePreview();
 }
 
 HYDROGUI_InputPanel* HYDROGUI_SplitPolylinesOp::createInputPanel() const
 {
-  return new HYDROGUI_SplitPolylinesDlg( module(), getName() );
+  HYDROGUI_SplitPolylinesDlg* aDlg = new HYDROGUI_SplitPolylinesDlg( module(), getName() );
+  connect( aDlg, SIGNAL( pointMoved() ), this, SLOT( OnUpdatePreview() ) );
+  connect( aDlg, SIGNAL( modeChanged() ), this, SLOT( OnUpdatePreview() ) );
+  connect( aDlg, SIGNAL( selectionChanged() ), this, SLOT( OnUpdatePreview() ) );
+  return aDlg;
 }
 
 bool HYDROGUI_SplitPolylinesOp::processApply( int& theUpdateFlags,
                                               QString& theErrorMsg,
                                               QStringList& theBrowseObjectsEntries )
 {
-  /*TODO:
-  HYDROGUI_LocalCSDlg* aPanel = ::qobject_cast<HYDROGUI_LocalCSDlg*>( inputPanel() );
+  HYDROGUI_SplitPolylinesDlg* aPanel = ::qobject_cast<HYDROGUI_SplitPolylinesDlg*>( inputPanel() );
   if ( !aPanel )
     return false;
 
-  double aLX = aPanel->GetLocalX();
-  double aLY = aPanel->GetLocalY();
-  doc()->SetLocalCS( aLX, aLY );
+  //TODO: QString aName = aPanel->GetResultName();
+  Handle( HYDROData_PolylineXY ) aMainPolyline = aPanel->GetMainPolyline();
+  Handle( HYDROData_PolylineXY ) aToolPolyline = aPanel->GetToolPolyline();
+  HYDROData_SequenceOfObjects aPolylinesList = aPanel->GetPolylines();
+  gp_Pnt2d aPoint = aPanel->GetPoint();
+  double aTolerance = 1E-2; //TODO
+
+  HYDROData_PolylineOperator anOp;
+  switch( aPanel->GetMode() )
+  {
+  case HYDROGUI_SplitPolylinesDlg::ByPoint:
+    anOp.Split( doc(), aMainPolyline, aPoint, aTolerance );
+    break;
+  case HYDROGUI_SplitPolylinesDlg::ByTool:
+  {
+    bool isIntersected = false;
+    anOp.Split( doc(), aMainPolyline, aToolPolyline, aTolerance, isIntersected);
 
+    if (!isIntersected)
+    {
+      const QString aTitle = tr("SPLIT_POLYLINE_BY_TOOL_WARNING_TITLE");
+      const QString aMsg = tr("SPLIT_POLYLINE_BY_TOOL_WARNING_MSG");
+      SUIT_MessageBox::warning(module()->getApp()->desktop(), aTitle, aMsg);
+    }
+    break;
+  }
+  case HYDROGUI_SplitPolylinesDlg::Split:
+    anOp.Split( doc(), aPolylinesList, aTolerance );
+    break;
+  }
+  
   theUpdateFlags = UF_Model | UF_OCCViewer | UF_OCC_Forced | UF_VTKViewer;
-  */
   return true;
 }
+
+void HYDROGUI_SplitPolylinesOp::abortOperation()
+{
+  erasePreview();
+  HYDROGUI_Operation::abortOperation();
+}
+
+void HYDROGUI_SplitPolylinesOp::commitOperation()
+{
+  erasePreview();
+  HYDROGUI_Operation::commitOperation();
+}
+
+void HYDROGUI_SplitPolylinesOp::erasePreview()
+{
+  if( myPreviewPrs )
+  {
+    delete myPreviewPrs;
+    myPreviewPrs = 0;
+  }
+
+  HYDROGUI_SplitPolylinesDlg* aPanel = 
+    ::qobject_cast<HYDROGUI_SplitPolylinesDlg*>( inputPanel() );
+  if ( !aPanel )
+    return;
+
+  OCCViewer_ViewManager* aViewManager = getPreviewManager();
+  if ( aViewManager )
+  {
+    if ( OCCViewer_Viewer* aViewer = aViewManager->getOCCViewer() )
+    {
+      if ( mySplitPointPreview )
+      {
+        Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
+        if ( !aCtx.IsNull() )
+        {
+          if ( aCtx->HasOpenedContext() )
+            aCtx->CloseLocalContext();
+          aCtx->Erase( mySplitPointPreview, Standard_False );
+        }
+        mySplitPointPreview = 0;
+      }
+      
+      if ( aPanel->GetMode() == HYDROGUI_SplitPolylinesDlg::ByPoint )
+      {
+        disconnect(aViewManager, SIGNAL(mousePress(SUIT_ViewWindow*, QMouseEvent*)), 
+          this, SLOT(onMousePress(SUIT_ViewWindow*, QMouseEvent*)));
+        connect(aViewManager, SIGNAL(mousePress(SUIT_ViewWindow*, QMouseEvent*)), 
+          aViewer, SLOT(onMousePress(SUIT_ViewWindow*, QMouseEvent*)));
+      }
+    }
+  }
+}
+
+void HYDROGUI_SplitPolylinesOp::OnUpdatePreview()
+{
+  HYDROGUI_SplitPolylinesDlg* aPanel = ::qobject_cast<HYDROGUI_SplitPolylinesDlg*>( inputPanel() );
+
+  OCCViewer_ViewManager* aViewManager = getPreviewManager();
+  if ( aViewManager )
+  {
+    if ( OCCViewer_Viewer* aViewer = aViewManager->getOCCViewer() )
+    {
+      Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
+      if ( !aCtx.IsNull() )
+      {
+        if( !myPreviewPrs )
+        {
+          myPreviewPrs = new HYDROGUI_Shape( aCtx, NULL, getPreviewZLayer() );
+          myPreviewPrs->setSelectionMode( AIS_Shape::SelectionMode( TopAbs_FACE ) );
+        }
+
+        if ( mySplitPointPreview )
+        {
+          if ( aCtx->HasOpenedContext() )
+            aCtx->CloseLocalContext();
+          if ( aPanel->GetMode() == HYDROGUI_SplitPolylinesDlg::ByPoint )
+          {
+            if ( !aCtx->IsDisplayed( mySplitPointPreview ) )
+              aCtx->Display( mySplitPointPreview, Standard_False );
+          }
+          else
+            aCtx->Erase( mySplitPointPreview, Standard_False );  
+        }
+
+        aCtx->ClearSelected();
+      }
+
+      if ( aPanel->GetMode() == HYDROGUI_SplitPolylinesDlg::ByPoint )
+      {
+        disconnect(aViewManager, SIGNAL(mousePress(SUIT_ViewWindow*, QMouseEvent*)), 
+          aViewer, SLOT(onMousePress(SUIT_ViewWindow*, QMouseEvent*)));
+        connect(aViewManager, SIGNAL(mousePress(SUIT_ViewWindow*, QMouseEvent*)), 
+          this, SLOT(onMousePress(SUIT_ViewWindow*, QMouseEvent*)));
+      }
+      else
+      {
+        disconnect(aViewManager, SIGNAL(mousePress(SUIT_ViewWindow*, QMouseEvent*)), 
+          this, SLOT(onMousePress(SUIT_ViewWindow*, QMouseEvent*)));
+        connect(aViewManager, SIGNAL(mousePress(SUIT_ViewWindow*, QMouseEvent*)), 
+          aViewer, SLOT(onMousePress(SUIT_ViewWindow*, QMouseEvent*)));
+      }
+    }
+  }
+
+  if( myPreviewPrs && aPanel )
+  {
+    BRep_Builder aBB;
+    TopoDS_Compound aCmp;
+    aBB.MakeCompound( aCmp );
+
+    switch( aPanel->GetMode() )
+    {
+    case HYDROGUI_SplitPolylinesDlg::ByPoint:
+      {
+        gp_Pnt2d aPnt = aPanel->GetPoint();
+        TopoDS_Vertex aVertex = BRepLib_MakeVertex( gp_Pnt( aPnt.X(), aPnt.Y(), 0.0 ) );
+        if( !aPanel->GetMainPolyline().IsNull() )
+          aBB.Add( aCmp, aPanel->GetMainPolyline()->GetShape() );
+        aBB.Add( aCmp, aVertex );
+        break;
+      }
+    case HYDROGUI_SplitPolylinesDlg::ByTool:
+      {
+        if( !aPanel->GetMainPolyline().IsNull() )
+          aBB.Add( aCmp, aPanel->GetMainPolyline()->GetShape() );
+        if( !aPanel->GetToolPolyline().IsNull() )
+          aBB.Add( aCmp, aPanel->GetToolPolyline()->GetShape() );
+        break;
+      }
+    case HYDROGUI_SplitPolylinesDlg::Split:
+      {
+        HYDROData_SequenceOfObjects aPolylines = aPanel->GetPolylines();
+        for( int i=aPolylines.Lower(), n=aPolylines.Upper(); i<=n; i++ )
+        {
+          Handle( HYDROData_PolylineXY ) aPolyline = Handle( HYDROData_PolylineXY )::DownCast( aPolylines.Value( i ) );
+          if( !aPolyline.IsNull() )
+            aBB.Add( aCmp, aPolyline->GetShape() );
+        }
+        break;
+      }
+    }
+
+
+    myPreviewPrs->setShape( aCmp );
+  }
+}
+
+void HYDROGUI_SplitPolylinesOp::onMousePress(SUIT_ViewWindow* theWindow, QMouseEvent* theEvent)
+{
+  OCCViewer_ViewManager* aViewManager = getPreviewManager();
+  if ( !aViewManager )
+    return;
+
+  OCCViewer_ViewWindow* aViewWindow = (OCCViewer_ViewWindow*)aViewManager->getActiveView();
+  if ( !aViewWindow )
+    return;
+
+  OCCViewer_ViewPort3d* aViewPort = aViewWindow->getViewPort();
+  if ( !aViewPort )
+    return;
+
+  Handle(V3d_View) aView = aViewPort->getView();
+  if ( aView.IsNull() )
+    return;
+
+  OCCViewer_Viewer* aViewer = aViewManager->getOCCViewer();
+  if ( !aViewer )
+    return;
+
+  Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
+  if ( aCtx.IsNull() )
+    return;
+
+  gp_Pnt aPnt = CurveCreator_Utils::ConvertClickToPoint( theEvent->x(), theEvent->y(), aView );
+  BRep_Builder aBuilder;
+  TopoDS_Compound aShape;
+  aBuilder.MakeCompound(aShape);
+  aBuilder.Add(aShape, BRepBuilderAPI_MakeVertex( aPnt ) );
+  
+  if ( mySplitPointPreview )
+  {
+    if ( aCtx->HasOpenedContext() )
+      aCtx->CloseLocalContext();
+    aCtx->Erase( mySplitPointPreview, Standard_False );
+  }
+
+  mySplitPointPreview = new AIS_Shape( aShape );
+  if ( aCtx->HasOpenedContext() )
+    aCtx->CloseLocalContext();
+  aCtx->Display( mySplitPointPreview, Standard_False );
+  
+  aCtx->UpdateCurrentViewer();
+}