#include <LightApp_SelectionMgr.h>
#include <LightApp_UpdateFlags.h>
+#include <SUIT_MessageBox.h>
+#include <SUIT_Desktop.h>
+
#include <OCCViewer_ViewManager.h>
#include <OCCViewer_ViewModel.h>
#include <OCCViewer_ViewWindow.h>
-
+#include <gp_Ax1.hxx>
+#include <gp_Ax2.hxx>
+#include <gp_Ax3.hxx>
+#include <gp_Vec.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_Pln.hxx>
+#include <gp.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS.hxx>
+#include <BRepBuilderAPI_MakeFace.hxx>
HYDROGUI_StreamOp::HYDROGUI_StreamOp( HYDROGUI_Module* theModule, bool theIsEdit )
: HYDROGUI_Operation( theModule ),
myIsEdit( theIsEdit ),
// We start operation in the document
startDocOperation();
+ // Get panel and reset its state
HYDROGUI_StreamDlg* aPanel = (HYDROGUI_StreamDlg*)inputPanel();
-
- aPanel->blockSignals( true );
-
aPanel->reset();
- if( myIsEdit )
+ // Get/create the edited object
+ if( myIsEdit ) {
myEditedObject = Handle(HYDROData_Stream)::DownCast( HYDROGUI_Tool::GetSelectedObject( module() ) );
- else
- myEditedObject = Handle(HYDROData_Stream)::DownCast( doc()->CreateObject( KIND_STREAM ) );
-
- QString aSelectedAxis;
- QStringList aSelectedProfiles;
-
- QString anObjectName = HYDROGUI_Tool::GenerateObjectName( module(), tr( "DEFAULT_STREAM_NAME" ) );
- if ( myIsEdit && !myEditedObject.IsNull() )
- {
- anObjectName = myEditedObject->GetName();
-
- Handle(HYDROData_PolylineXY) aHydraulicAxis = myEditedObject->GetHydraulicAxis();
- if ( !aHydraulicAxis.IsNull() )
- aSelectedAxis = aHydraulicAxis->GetName();
-
- HYDROData_SequenceOfObjects aProfiles = myEditedObject->GetProfiles();
- for ( int i = 1, n = aProfiles.Length(); i <= n; ++i )
- {
- Handle(HYDROData_Profile) aProfile =
- Handle(HYDROData_Profile)::DownCast( aProfiles.Value( i ) );
- if ( aProfile.IsNull() )
- continue;
-
- QString aProfileName = aProfile->GetName();
- aSelectedProfiles << aProfileName;
+ if ( !myEditedObject.IsNull() && myEditedObject->IsMustBeUpdated() ) {
+ myEditedObject->Update();
}
+ } else {
+ myEditedObject = Handle(HYDROData_Stream)::DownCast( doc()->CreateObject( KIND_STREAM ) );
}
- QStringList anAxises = HYDROGUI_Tool::FindExistingObjectsNames( doc(), KIND_POLYLINEXY );
-
- // Temporary, to be removed
- if ( aSelectedProfiles.isEmpty() )
- {
- aSelectedProfiles = HYDROGUI_Tool::FindExistingObjectsNames( doc(), KIND_PROFILE );
+ // Get the edited object name
+ QString anObjectName;
+ if ( !myIsEdit ) {
+ anObjectName = HYDROGUI_Tool::GenerateObjectName( module(), tr( "DEFAULT_STREAM_NAME" ) );
+ } else if ( !myEditedObject.IsNull() ) {
+ anObjectName = myEditedObject->GetName();
}
+ // Update the panel
+ // set the edited object name
aPanel->setObjectName( anObjectName );
- aPanel->setAxisNames( anAxises );
- aPanel->setAxisName( aSelectedAxis );
- aPanel->setSelectedProfiles( aSelectedProfiles );
+ // set the existing 2D polylines names to the panel
+ aPanel->setAxisNames( HYDROGUI_Tool::FindExistingObjectsNames( doc(), KIND_POLYLINEXY ) );
+ // synchronize the panel state with the edited object state
+ updatePanelData();
- aPanel->blockSignals( false );
-
- onCreatePreview();
+ // Create preview
+ createPreview();
}
void HYDROGUI_StreamOp::abortOperation()
HYDROGUI_InputPanel* HYDROGUI_StreamOp::createInputPanel() const
{
HYDROGUI_StreamDlg* aPanel = new HYDROGUI_StreamDlg( module(), getName() );
- connect( aPanel, SIGNAL( CreatePreview() ), this, SLOT( onCreatePreview() ) );
+
+ connect( aPanel, SIGNAL( AddProfiles() ), this, SLOT( onAddProfiles() ) );
+ connect( aPanel, SIGNAL( RemoveProfiles( const QStringList& ) ),
+ this, SLOT( onRemoveProfiles( const QStringList& ) ) );
+ connect( aPanel, SIGNAL( AxisChanged( const QString& ) ),
+ this, SLOT( onAxisChanged( const QString& ) ) );
+
return aPanel;
}
QString& theErrorMsg )
{
HYDROGUI_StreamDlg* aPanel = ::qobject_cast<HYDROGUI_StreamDlg*>( inputPanel() );
- if ( !aPanel )
+ if ( !aPanel || myEditedObject.IsNull() ) {
return false;
+ }
+ // Check whether the object name is not empty
QString anObjectName = aPanel->getObjectName().simplified();
- if ( anObjectName.isEmpty() )
- {
+ if ( anObjectName.isEmpty() ) {
theErrorMsg = tr( "INCORRECT_OBJECT_NAME" );
return false;
}
- if( !myIsEdit || ( !myEditedObject.IsNull() && myEditedObject->GetName() != anObjectName ) )
+ // Check that there are no other objects with the same name in the document
+ if( myEditedObject->GetName() != anObjectName )
{
- // check that there are no other objects with the same name in the document
Handle(HYDROData_Entity) anObject = HYDROGUI_Tool::FindObjectByName( module(), anObjectName );
- if( !anObject.IsNull() )
- {
+ if( !anObject.IsNull() ) {
theErrorMsg = tr( "OBJECT_EXISTS_IN_DOCUMENT" ).arg( anObjectName );
return false;
}
}
- if ( myEditedObject.IsNull() )
+ // Check if the axis is set
+ Handle(HYDROData_PolylineXY) aHydraulicAxis = myEditedObject->GetHydraulicAxis();
+ if ( aHydraulicAxis.IsNull() ) {
+ theErrorMsg = tr( "AXIS_NOT_DEFINED" );
return false;
+ }
+ // Check if at least 2 profiles is set
+ HYDROData_SequenceOfObjects aProfiles = myEditedObject->GetProfiles();
+ if ( aProfiles.Length() < 2 ) {
+ theErrorMsg = tr( "PROFILES_NOT_DEFINED" );
+ return false;
+ }
+
+ // Set the object name
myEditedObject->SetName( anObjectName );
+ if ( !myIsEdit )
+ {
+ myEditedObject->SetFillingColor( HYDROData_Stream::DefaultFillingColor() );
+ myEditedObject->SetBorderColor( HYDROData_Stream::DefaultBorderColor() );
+ }
+
+ // Erase preview
erasePreview();
- if( !myIsEdit )
+ // Show the object in case of creation mode of the operation
+ if( !myIsEdit ) {
module()->setObjectVisible( HYDROGUI_Tool::GetActiveOCCViewId( module() ), myEditedObject, true );
+ }
- theUpdateFlags = UF_Model | UF_OCCViewer | UF_OCC_Forced;
+ module()->setIsToUpdate( myEditedObject );
+
+ // Set update flags
+ theUpdateFlags = UF_Model | UF_OCCViewer | UF_OCC_Forced | UF_VTKViewer;
return true;
}
-void HYDROGUI_StreamOp::onCreatePreview()
+void HYDROGUI_StreamOp::createPreview()
{
- HYDROGUI_StreamDlg* aPanel = ::qobject_cast<HYDROGUI_StreamDlg*>( inputPanel() );
- if ( !aPanel )
+ if ( myEditedObject.IsNull() ) {
return;
+ }
- QString anAxisName = aPanel->getAxisName();
- QStringList aProfiles = aPanel->getSelectedProfiles();
- if ( anAxisName.isEmpty() || aProfiles.isEmpty() )
- {
- erasePreview();
- return;
+ LightApp_Application* anApp = module()->getApp();
+ if ( !myViewManager ) {
+ myViewManager = ::qobject_cast<OCCViewer_ViewManager*>(
+ anApp->getViewManager( OCCViewer_Viewer::Type(), true ) );
}
- if ( myEditedObject.IsNull() )
- return;
+ if ( myViewManager && !myPreviewPrs ) {
+ if ( OCCViewer_Viewer* aViewer = myViewManager->getOCCViewer() ) {
+ Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
+ if ( !aCtx.IsNull() ) {
+ myPreviewPrs = new HYDROGUI_Shape( aCtx, myEditedObject );
+ }
+ }
+ }
+
+ if ( myPreviewPrs ) {
+ myPreviewPrs->update( true, true );
+ }
+}
- // At first we remove all references from stream
- myEditedObject->RemoveProfiles();
+void HYDROGUI_StreamOp::erasePreview()
+{
+ if( myPreviewPrs ) {
+ delete myPreviewPrs;
+ myPreviewPrs = 0;
+ }
+}
- Handle(HYDROData_PolylineXY) anAxis = Handle(HYDROData_PolylineXY)::DownCast(
- HYDROGUI_Tool::FindObjectByName( module(), anAxisName, KIND_POLYLINEXY ) );
- myEditedObject->SetHydraulicAxis( anAxis );
+void HYDROGUI_StreamOp::onAddProfiles()
+{
+ if ( myEditedObject.IsNull() ) {
+ return;
+ }
- HYDROData_SequenceOfObjects aProfileObjects =
- HYDROGUI_Tool::FindObjectsByNames( module(), aProfiles, KIND_PROFILE );
- for ( int i = 1, n = aProfileObjects.Length(); i <= n; ++i )
- {
+ // Get the current profiles list
+ HYDROData_SequenceOfObjects aProfiles = myEditedObject->GetProfiles();
+
+ // TODO: to be optimized
+ QStringList aCurrentProfiles;
+ for( int i = 1, n = aProfiles.Length(); i <= n; i++ ) {
+ Handle(HYDROData_Profile) aProfile =
+ Handle(HYDROData_Profile)::DownCast( aProfiles.Value( i ) );
+ if ( !aProfile.IsNull() ) {
+ aCurrentProfiles << aProfile->GetName();
+ }
+ }
+
+ // Get the selected profiles ( in the Object Browser )
+ QStringList anInvalidProfiles, anExistingProfiles, aHasNoIntersectionProfiles;
+
+ HYDROData_SequenceOfObjects aVerifiedProfiles;
+ HYDROData_SequenceOfObjects aSelectedProfiles = HYDROGUI_Tool::GetSelectedObjects( module() );
+ Handle(HYDROData_PolylineXY) aHydAxis = myEditedObject->GetHydraulicAxis();
+ if ( aHydAxis.IsNull() )
+ return;
+ TopoDS_Face aPlane;
+ if(!myEditedObject->BuildFace(aHydAxis, aPlane))
+ return;
+ Standard_Real aPar(.0);
+ for( int i = 1, n = aSelectedProfiles.Length(); i <= n; i++ ) {
Handle(HYDROData_Profile) aProfile =
- Handle(HYDROData_Profile)::DownCast( aProfileObjects.Value( i ) );
- if ( aProfile.IsNull() )
- continue;
+ Handle(HYDROData_Profile)::DownCast( aSelectedProfiles.Value( i ) );
+ if ( !aProfile.IsNull() ) {
+ QString aProfileName = aProfile->GetName();
+
+ // Check the profile, if all is ok - add it to the list
+ if ( !aProfile->IsValid() ) { // check whether the profile is valid
+ anInvalidProfiles << aProfileName;
+ } else if ( aCurrentProfiles.contains( aProfileName ) ) { // check whether the profile is already added
+ anExistingProfiles << aProfileName;
+ } else if ( !myEditedObject->HasIntersection( aProfile, aPlane, aPar ) ) { // check whether the profile has intersection
+ aHasNoIntersectionProfiles << aProfileName;
+ } else {
+ aVerifiedProfiles.Append( aProfile );
+ }
+ }
+ }
+
+ // Show message box with the ignored profiles
+ if ( !anInvalidProfiles.isEmpty() || !anExistingProfiles.isEmpty() ||
+ !aHasNoIntersectionProfiles.isEmpty() ) {
+ QString aMessage = tr( "IGNORED_PROFILES" );
+ if ( !anInvalidProfiles.isEmpty() ) {
+ aMessage.append( "\n\n" );
+ aMessage.append( tr("INVALID_PROFILES").arg( anInvalidProfiles.join( "\n" ) ) );
+ }
+ if ( !anExistingProfiles.isEmpty() ) {
+ aMessage.append( "\n\n" );
+ aMessage.append( tr("EXISTING_PROFILES").arg( anExistingProfiles.join( "\n" ) ) );
+ }
+ if ( !aHasNoIntersectionProfiles.isEmpty() ) {
+ aMessage.append( "\n\n" );
+ aMessage.append( tr("NOT_INTERSECTED_PROFILES").arg( aHasNoIntersectionProfiles.join( "\n" ) ) );
+ }
+ SUIT_MessageBox::warning( module()->getApp()->desktop(), tr( "WARNING" ), aMessage );
+ }
+
+ // Update the stream object
+ for( int i = 1, n = aVerifiedProfiles.Length(); i <= n; i++ ) {
+ Handle(HYDROData_Profile) aProfile =
+ Handle(HYDROData_Profile)::DownCast( aVerifiedProfiles.Value( i ) );
myEditedObject->AddProfile( aProfile );
}
-
- myEditedObject->Update();
+ myEditedObject->UpdatePrs();
+ // Update the panel
+ updatePanelData();
- LightApp_Application* anApp = module()->getApp();
- if ( !myViewManager )
- myViewManager = ::qobject_cast<OCCViewer_ViewManager*>(
- anApp->getViewManager( OCCViewer_Viewer::Type(), true ) );
+ // Update preview
+ createPreview();
+}
- if ( myViewManager && !myPreviewPrs )
- {
- if ( OCCViewer_Viewer* aViewer = myViewManager->getOCCViewer() )
- {
- Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
- if ( !aCtx.IsNull() )
- myPreviewPrs = new HYDROGUI_Shape( aCtx, myEditedObject );
+void HYDROGUI_StreamOp::onRemoveProfiles( const QStringList& theProfilesToRemove )
+{
+ if ( myEditedObject.IsNull() ) {
+ return;
+ }
+
+ bool isRemoved = false;
+
+ // Take the Object Browser selection into account
+ HYDROData_SequenceOfObjects aSelectedObjects = HYDROGUI_Tool::GetSelectedObjects( module() );
+ for( int i = 1, n = aSelectedObjects.Length(); i <= n; i++ ) {
+ Handle(HYDROData_Profile) aProfile =
+ Handle(HYDROData_Profile)::DownCast( aSelectedObjects.Value( i ) );
+ if ( !aProfile.IsNull() && !theProfilesToRemove.contains(aProfile->GetName()) ) {
+ if ( myEditedObject->RemoveProfile( aProfile ) ) {
+ isRemoved = true;
+ }
}
}
- if ( !myViewManager || !myPreviewPrs )
+ // Remove profiles
+ foreach( const QString& aProfileName, theProfilesToRemove ) {
+ Handle(HYDROData_Profile) aProfile = Handle(HYDROData_Profile)::DownCast(
+ HYDROGUI_Tool::FindObjectByName( module(), aProfileName, KIND_PROFILE ) );
+ if ( myEditedObject->RemoveProfile( aProfile ) ) {
+ isRemoved = true;
+ }
+ }
+
+ if ( isRemoved ) {
+ // Update the edited stream object
+ myEditedObject->UpdatePrs();
+
+ // Update the panel
+ updatePanelData();
+
+ // Update preview
+ createPreview();
+ }
+}
+
+void HYDROGUI_StreamOp::onAxisChanged( const QString& theNewAxis )
+{
+ if ( myEditedObject.IsNull() ) {
+ return;
+ }
+
+ // Get axis object
+ Handle(HYDROData_PolylineXY) anAxis = Handle(HYDROData_PolylineXY)::DownCast(
+ HYDROGUI_Tool::FindObjectByName( module(), theNewAxis, KIND_POLYLINEXY ) );
+
+ // Prepare data for intersection check
+ TopoDS_Face aPlane;
+ if ( !myEditedObject->BuildFace(anAxis, aPlane) ) {
+ SUIT_MessageBox::critical( module()->getApp()->desktop(),
+ tr( "BAD_SELECTED_POLYLINE_TLT" ),
+ tr( "BAD_SELECTED_POLYLINE_MSG" ).arg( theNewAxis ) );
+ // To restore the old axis
+ updatePanelData();
return;
+ }
- myPreviewPrs->update();
+ Standard_Real aPar(.0);
+
+ // Get list of profiles which do not intersect the axis
+ QStringList aHasNoIntersectionProfiles;
+ HYDROData_SequenceOfObjects aCurrentProfiles = myEditedObject->GetProfiles();
+ for( int anIndex = 1, aLength = aCurrentProfiles.Length(); anIndex <= aLength; anIndex++ ) {
+ Handle(HYDROData_Profile) aProfile =
+ Handle(HYDROData_Profile)::DownCast( aCurrentProfiles.Value( anIndex ) );
+ if ( !aProfile.IsNull() ) {
+ if ( !HYDROData_Stream::HasIntersection( anAxis, aProfile, aPlane, aPar ) ) {
+ aHasNoIntersectionProfiles << aProfile->GetName();
+ }
+ }
+ }
+
+ // If there are profiles which don't intersect the new axis - show confirmation message box
+ bool isConfirmed = true;
+ if ( !aHasNoIntersectionProfiles.isEmpty() ) {
+ SUIT_MessageBox::StandardButtons aButtons =
+ SUIT_MessageBox::Yes | SUIT_MessageBox::No;
+
+ QString aMsg = aHasNoIntersectionProfiles.join( "\n" );
+ isConfirmed = SUIT_MessageBox::question( module()->getApp()->desktop(),
+ tr( "CONFIRMATION" ),
+ tr( "CONFIRM_AXIS_CHANGE" ).arg( aMsg ),
+ aButtons,
+ SUIT_MessageBox::Yes) == SUIT_MessageBox::Yes;
+ }
+
+ // Check if the user has confirmed axis change
+ if ( !isConfirmed ) {
+ // To restore the old axis
+ updatePanelData();
+ } else {
+ // Set axis
+ myEditedObject->SetHydraulicAxis( anAxis );
+ myEditedObject->UpdatePrs();
+
+ // Update the panel
+ updatePanelData();
+
+ // Update preview
+ createPreview();
+ }
}
-void HYDROGUI_StreamOp::erasePreview()
+void HYDROGUI_StreamOp::updatePanelData()
{
- if( myPreviewPrs )
- {
- delete myPreviewPrs;
- myPreviewPrs = 0;
+ HYDROGUI_StreamDlg* aPanel = ::qobject_cast<HYDROGUI_StreamDlg*>( inputPanel() );
+ if ( !aPanel || myEditedObject.IsNull() ) {
+ return;
+ }
+
+ // Hydraulic axis
+ Handle(HYDROData_PolylineXY) aHydraulicAxis = myEditedObject->GetHydraulicAxis();
+ if ( !aHydraulicAxis.IsNull() ) {
+ aPanel->setAxisName( aHydraulicAxis->GetName() );
+ } else {
+ aPanel->setAxisName( "" );
}
+
+ // Stream profiles
+ QStringList aProfiles;
+
+ HYDROData_SequenceOfObjects aStreamProfiles = myEditedObject->GetProfiles();
+ for ( int i = 1, n = aStreamProfiles.Length(); i <= n; ++i ) {
+ Handle(HYDROData_Profile) aProfile =
+ Handle(HYDROData_Profile)::DownCast( aStreamProfiles.Value( i ) );
+ if ( !aProfile.IsNull() ) {
+ QString aProfileName = aProfile->GetName();
+ aProfiles << aProfileName;
+ }
+ }
+
+ aPanel->setProfiles( aProfiles );
}