]> SALOME platform Git repositories - modules/hydro.git/blob - src/HYDROGUI/HYDROGUI_ProfileOp.cxx
Salome HOME
Merge remote-tracking branch 'remotes/origin/BR_2017' into BR_1334_3
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_ProfileOp.cxx
1 // Copyright (C) 2014-2015  EDF-R&D
2 // This library is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU Lesser General Public
4 // License as published by the Free Software Foundation; either
5 // version 2.1 of the License, or (at your option) any later version.
6 //
7 // This library is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10 // Lesser General Public License for more details.
11 //
12 // You should have received a copy of the GNU Lesser General Public
13 // License along with this library; if not, write to the Free Software
14 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
15 //
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
17 //
18
19 #include <HYDROGUI_Module.h>
20 #include <HYDROGUI_ProfileOp.h>
21 #include <HYDROGUI_ProfileDlg.h>
22 #include <HYDROGUI_Tool2.h>
23 #include <HYDROGUI_UpdateFlags.h>
24 #include <HYDROGUI_DataObject.h>
25 #include <HYDROData_Document.h>
26 #include <HYDROData_Profile.h>
27 #include <HYDROGUI_CurveCreatorProfile.h>
28 #include <HYDROGUI_DeleteOp.h>
29 #include <HYDROData_Tool.h>
30 #include <CurveCreator_Displayer.hxx>
31 #include <HYDROData_Entity.h>
32 #include <QSet>
33
34 #include <LightApp_Application.h>
35 #include <LightApp_SelectionMgr.h>
36 #include <LightApp_UpdateFlags.h>
37
38 #include <OCCViewer_ViewManager.h>
39 #include <OCCViewer_ViewModel.h>
40 #include <OCCViewer_ViewWindow.h>
41 #include <SUIT_MessageBox.h>
42 #include <SUIT_Desktop.h>
43 #include <OCCViewer_AISSelector.h>
44
45 #include <Precision.hxx>
46
47 //static int ZValueIncrement = 0;
48
49 static void ProfileUZToCurveCrProfile(const Handle(HYDROData_ProfileUZ)& aProfileUZ, 
50   HYDROGUI_CurveCreatorProfile* outProfile)
51 {
52   CurveCreator::Coordinates aCurveCoords;
53   CurveCreator::SectionsMap aSectionsMap;
54
55   HYDROData_ProfileUZ::PointsList aSectPointsList = aProfileUZ->GetPoints();
56   CurveCreator::PosPointsList aPoints;
57   for ( int k = 1, aNbPoints = aSectPointsList.Size(); k <= aNbPoints; ++k )
58   {
59     const HYDROData_ProfileUZ::Point& aSectPoint = aSectPointsList.Value( k );
60     aCurveCoords.clear();
61     aCurveCoords.push_back( aSectPoint.X() );
62     aCurveCoords.push_back( aSectPoint.Y() );
63
64     CurveCreator_PosPoint* aPosPoint = new CurveCreator_PosPoint( k, aCurveCoords );
65     aPoints.push_back( aPosPoint );
66   }
67
68   aSectionsMap[0] = aPoints;
69   outProfile->addPointsInternal( aSectionsMap );
70
71   HYDROData_ProfileUZ::SectionType aSectType = aProfileUZ->GetSectionType( 0 );
72
73   CurveCreator::SectionType aCurveType = CurveCreator::Polyline;
74   if( aSectType == HYDROData_ProfileUZ::SECTION_SPLINE )
75     aCurveType = CurveCreator::Spline;
76
77   outProfile->setSectionType( 0, aCurveType );
78 }
79
80 static int CurveCrProfileToHProfile(const HYDROGUI_CurveCreatorProfile* outProfile, 
81   Handle(HYDROData_Profile) theProfileObj,
82   const QString theProfileName,
83   bool IsEdit)
84 {
85   if( theProfileObj.IsNull() )
86     return 0;
87
88   Handle(HYDROData_ProfileUZ) aProfileUZ = theProfileObj->GetProfileUZ();
89   if ( aProfileUZ.IsNull() )
90     return 0;
91
92   theProfileObj->SetName(theProfileName);
93
94   HYDROData_ProfileUZ::PointsList aProfileParamPoints;
95
96   Handle(TColgp_HArray1OfPnt) aCurveCoords = outProfile->GetDifferentPoints( 0 );
97   if ( aCurveCoords.IsNull() || aCurveCoords->Size() <= 2 )
98     return -1;
99
100   for ( int k = aCurveCoords->Lower(); k <= aCurveCoords->Upper() ; k++ )
101   {
102     HYDROData_ProfileUZ::Point aProfileParamPoint;
103
104     aProfileParamPoint.SetX( aCurveCoords->Value( k ).X() );
105     aProfileParamPoint.SetY( aCurveCoords->Value( k ).Y() );
106
107     aProfileParamPoints.Append( aProfileParamPoint );
108   }
109   theProfileObj->SetParametricPoints( aProfileParamPoints );
110
111   HYDROData_ProfileUZ::SectionType aSectType = HYDROData_ProfileUZ::SECTION_POLYLINE;
112   if ( outProfile->getSectionType( 0 ) == CurveCreator::Spline )
113     aSectType = HYDROData_ProfileUZ::SECTION_SPLINE;
114
115   aProfileUZ->SetSectionType( 0, aSectType );
116
117   if ( !IsEdit )
118     theProfileObj->SetBorderColor( theProfileObj->DefaultBorderColor() );
119
120   // At first we update the child u,z profile object
121   aProfileUZ->Changed( HYDROData_Entity::Geom_2d );
122   aProfileUZ->Update();
123
124   // And now we update our edited object
125   theProfileObj->Update();
126   return 1;
127 }
128
129 HYDROGUI_ProfileOp::HYDROGUI_ProfileOp( HYDROGUI_Module* theModule, bool theIsEdit )
130 : HYDROGUI_Operation( theModule ), myIsEdit(theIsEdit), 
131    myDisplayer (NULL), mySingleProfileMode (false)
132 {
133   setName( theIsEdit ? tr( "EDIT_PROFILE" ) : tr( "CREATE_PROFILE" ) );
134 }
135
136 HYDROGUI_ProfileOp::~HYDROGUI_ProfileOp()
137 {
138   erasePreview();
139 }
140
141 /**
142  * Redirect the delete action to input panel
143  */
144 void HYDROGUI_ProfileOp::deleteSelected()
145 {
146   HYDROGUI_ProfileDlg* aPanel = (HYDROGUI_ProfileDlg*)inputPanel();
147   aPanel->deleteSelected();
148 }
149
150 /**
151  * Checks whether there are some to delete
152  */
153 #include <CurveCreator_Widget.h>
154 bool HYDROGUI_ProfileOp::deleteEnabled()
155 {
156   HYDROGUI_ProfileDlg* aPanel = (HYDROGUI_ProfileDlg*)inputPanel();
157   return aPanel->deleteEnabled();
158 }
159
160 void HYDROGUI_ProfileOp::startOperation()
161 {
162   if (!myProfiles.empty())
163   {
164     for (int i = 0; i < myProfiles.size(); i++)
165     {
166       delete myProfiles[i];
167       myProfiles[i] = NULL;
168     }
169     myProfiles.clear();
170   }
171
172   if (!myIsEdit)
173     myEditedObjects.Clear();
174
175   if (myCurveToProfile.IsEmpty())
176     myCurveToProfile.Clear();
177
178   if( myIsEdit && isApplyAndClose() )
179     myEditedObjects = HYDROGUI_Tool::GetSelectedObjects(module());
180
181   int lenP = myEditedObjects.Length();  
182   myProfiles.resize(lenP == 0 ? 1 : myEditedObjects.Length());
183   for (int i = 0; i < myProfiles.size(); i++)
184     myProfiles[i] = new HYDROGUI_CurveCreatorProfile();
185
186   mySingleProfileMode = myEditedObjects.IsEmpty() || lenP == 1;  
187   HYDROGUI_Operation::startOperation();
188
189   HYDROGUI_ProfileDlg* aPanel = (HYDROGUI_ProfileDlg*)inputPanel();
190   aPanel->myEditorWidget->setCurve(NULL);
191   aPanel->reset();
192   setPreviewManager( aPanel->viewManager() );
193   setCursor();
194
195   aPanel->SetSingleProfileMode(mySingleProfileMode); 
196   QMap<HYDROGUI_CurveCreatorProfile*, QColor> CurveToColor;
197   if( lenP )
198   {
199     for (int i = 1; i <= lenP; i++)
200     {
201       Handle(HYDROData_Profile) aCProfile = Handle(HYDROData_Profile)::DownCast(myEditedObjects(i)); 
202       QString aProfileName;
203       if( !aCProfile.IsNull() )
204       {
205         Handle(HYDROData_ProfileUZ) aProfileUZ = aCProfile->GetProfileUZ( false );
206         if ( !aProfileUZ.IsNull() )
207         {
208           HYDROGUI_CurveCreatorProfile* CP = new HYDROGUI_CurveCreatorProfile();
209           myProfiles[i-1] = CP;
210           ProfileUZToCurveCrProfile(aProfileUZ, CP);
211           myCurveToProfile.Bind(CP, aCProfile);
212         }
213       }
214     }
215     int ext = myCurveToProfile.Extent(); //ext should be equal to lenP
216     QVector<QColor> PColors;
217     if (!mySingleProfileMode)
218       HYDROData_Tool::GenerateRepeatableRandColors(ext, PColors);
219     else
220       PColors << QColor(0,0,255); //default color
221
222     for (int i = 0; i < myProfiles.size(); i++)
223     {
224       HYDROGUI_CurveCreatorProfile* CC = myProfiles[i];
225       const Handle(HYDROData_Profile)& CP = myCurveToProfile.Find(CC);
226       const QColor& CurCol = PColors[i]; 
227       CurveToColor[CC] = CurCol;
228       const QString& profName = CP->GetName();
229       const QColor& PColor = CurCol;
230       if (!mySingleProfileMode)
231         aPanel->addProfileName(profName, PColor);
232       else
233         aPanel->setProfileName(profName);
234     }
235   }
236
237   if (!myIsEdit)
238   {
239     QString aProfileName = HYDROGUI_Tool::GenerateObjectName( module(), tr( "DEFAULT_PROFILE_NAME" ) );
240     aPanel->setProfileName( aProfileName );
241   }
242
243   if (!myProfiles.empty())
244   {
245     aPanel->setProfile( myProfiles[0] );
246     aPanel->setProfilesPointer( &myProfiles );
247   }
248   displayPreviews(CurveToColor, 0, myProfiles.size(), true, true );
249 }
250
251 void HYDROGUI_ProfileOp::onAddProfiles()
252 {
253   if( !myIsEdit )
254     return;
255
256   QSet<QString> edObjNamesMap;
257   for (int i = 1; i <= myEditedObjects.Length(); i++)
258     edObjNamesMap.insert( myEditedObjects(i)->GetName());
259
260   HYDROData_SequenceOfObjects aSelectedObj = HYDROGUI_Tool::GetSelectedObjects( module() );;
261   int ExistingProfLen = myEditedObjects.Length();
262   for (int i = 1; i <= aSelectedObj.Length(); i++)
263   {
264     Handle(HYDROData_Entity) CurProf = Handle(HYDROData_Entity)::DownCast(aSelectedObj(i));
265     if (CurProf.IsNull())
266       continue;
267     if (!edObjNamesMap.contains(CurProf->GetName()))
268       myEditedObjects.Append(CurProf);
269   }
270
271   int NewLen = myEditedObjects.Length();
272   myProfiles.resize(myEditedObjects.Length());
273   for (int i = myProfiles.size() - 1; i < myEditedObjects.Length(); i++)
274     myProfiles[i] = new HYDROGUI_CurveCreatorProfile();
275     
276   HYDROGUI_ProfileDlg* aPanel = (HYDROGUI_ProfileDlg*)inputPanel();  
277   QMap<HYDROGUI_CurveCreatorProfile*, QColor> CurveToColor;
278   if( NewLen - ExistingProfLen )
279   {
280     //TODO move to ext func!
281     for (int i = ExistingProfLen + 1; i <= NewLen; i++)
282     {
283       Handle(HYDROData_Profile) aCProfile = Handle(HYDROData_Profile)::DownCast(myEditedObjects(i)); 
284       QString aProfileName;
285       if( !aCProfile.IsNull() )
286       {
287         Handle(HYDROData_ProfileUZ) aProfileUZ = aCProfile->GetProfileUZ( false );
288         if ( !aProfileUZ.IsNull() )
289         {
290           HYDROGUI_CurveCreatorProfile* CP = new HYDROGUI_CurveCreatorProfile();
291           myProfiles[i-1] = CP;
292           ProfileUZToCurveCrProfile(aProfileUZ, CP);
293           myCurveToProfile.Bind(CP, aCProfile);            
294         }
295       }
296     }
297     //int ext = myCurveToProfile.Extent(); //ext should be equal to lenP
298     QVector<QColor> PColors;
299     HYDROData_Tool::GenerateRepeatableRandColors(NewLen - ExistingProfLen, PColors);
300
301     for (int i = ExistingProfLen; i < NewLen; i++)
302     {
303       HYDROGUI_CurveCreatorProfile* CC = myProfiles[i];
304       const Handle(HYDROData_Profile)& CP = myCurveToProfile.Find(CC);
305       const QColor& CurCol = PColors[i-ExistingProfLen]; 
306       CurveToColor[CC] = CurCol;
307       const QString& profName = CP->GetName();
308       const QColor& PColor = CurCol;
309       if (!mySingleProfileMode)
310         aPanel->addProfileName(profName, PColor);
311       else
312         aPanel->setProfileName(profName);
313     }
314   }
315   displayPreviews(CurveToColor, ExistingProfLen, NewLen, false, false);
316 }
317
318 void HYDROGUI_ProfileOp::abortOperation()
319 {
320   erasePreview();
321   restoreCursor();
322
323   HYDROGUI_Operation::abortOperation();
324 }
325
326 void HYDROGUI_ProfileOp::commitOperation()
327 {
328   erasePreview();
329   restoreCursor();
330
331   HYDROGUI_Operation::commitOperation();
332 }
333
334 HYDROGUI_InputPanel* HYDROGUI_ProfileOp::createInputPanel() const
335 {
336   HYDROGUI_ProfileDlg* aDlg = new HYDROGUI_ProfileDlg( module(), getName(), mySingleProfileMode );
337   connect( aDlg, SIGNAL( AddProfiles() ), this, 
338     SLOT( onAddProfiles() ) );
339   connect( aDlg, SIGNAL( RemoveProfile(int) ), this, 
340     SLOT( onRemoveProfile(int) ) );  
341   return aDlg;
342 }
343 #include <set>
344 bool HYDROGUI_ProfileOp::processApply( int& theUpdateFlags,
345                                        QString& theErrorMsg,
346                                        QStringList& theBrowseObjectsEntries )
347 {
348   HYDROGUI_ProfileDlg* aPanel = ::qobject_cast<HYDROGUI_ProfileDlg*>( inputPanel() );
349   if ( !aPanel )
350     return false;
351
352   QStringList aProfileNames = aPanel->getProfileNames();
353   QVector<QString> aProfileNamesFiltered;
354   int i = 0;
355  // QSet<QString> edObjStrMap = aProfileNames.toSet();
356   QSet<QString> ObjStrMapNE ;
357   HYDROData_SequenceOfObjects allobj = doc()->CollectAllObjects();
358   for (int i=1;i<=allobj.Size();i++ )
359     ObjStrMapNE.insert(allobj(i)->GetName());
360   for (int i=1; i<=myEditedObjects.Size();i++)
361     ObjStrMapNE.remove(myEditedObjects(i)->GetName());
362   bool warn = false;
363   QString title = tr( "PROFILEOP_WARNING" );
364   QString mes = tr("PROFILE_RENAMING_NOTIF") + "\n";
365   foreach (QString profName, aProfileNames)
366   {
367     i++;
368     if( !myIsEdit || ObjStrMapNE.contains(profName) || profName.isEmpty() )
369     {
370       QString newName = HYDROData_Tool::GenerateObjectName(doc(), "Profile");
371       mes += profName + " => " + newName + "\n";
372       profName = newName;
373       warn = true;
374     }
375     aProfileNamesFiltered.append(profName);
376   }
377   if (warn)
378 #ifndef TEST_MODE
379     SUIT_MessageBox::warning( module()->getApp()->desktop(), title, mes );
380 #endif
381   //  
382   theUpdateFlags = UF_Model;
383   if (myIsEdit)
384   {
385     for (int i = 1; i <= myEditedObjects.Size(); i++)
386     {
387       Handle(HYDROData_Profile) HProf = Handle(HYDROData_Profile)::DownCast(myEditedObjects(i));
388       int stat = CurveCrProfileToHProfile(myProfiles[i-1], HProf, aProfileNamesFiltered[i-1], true);
389       if (stat == 0)
390         continue;
391       else if (stat == -1)
392       {    
393         theErrorMsg = tr( "NUMBER_OF_PROFILE_POINTS_INCORRECT" ); //TODO resolve this
394         continue;
395       }    
396       module()->setIsToUpdate( HProf );
397     }
398     theUpdateFlags |= UF_OCCViewer | UF_OCC_Forced | UF_VTKViewer;
399   }
400   else
401   {
402     Handle(HYDROData_Profile) aNewProfileObj = Handle(HYDROData_Profile)::DownCast( doc()->CreateObject( KIND_PROFILE ) ); 
403     int stat = CurveCrProfileToHProfile(myProfiles[0], aNewProfileObj, aProfileNamesFiltered[0], false);
404     if (stat == 0)
405       return false;
406     else if (stat == -1)
407     {    
408       theErrorMsg = tr( "NUMBER_OF_PROFILE_POINTS_INCORRECT" );
409       return false;
410     }    
411     module()->setIsToUpdate( aNewProfileObj );
412     QString anEntry = HYDROGUI_DataObject::dataObjectEntry( aNewProfileObj );
413     theBrowseObjectsEntries.append( anEntry );
414   }
415
416   return true;
417 }
418
419 void HYDROGUI_ProfileOp::displayPreviews(const QMap<HYDROGUI_CurveCreatorProfile*, QColor>& CurveToColor,
420   int firstIndProf, int lastIndProf, bool createNewDisplayer, bool SwitchToFirstProf)
421 {
422   HYDROGUI_ProfileDlg* aPanel = dynamic_cast<HYDROGUI_ProfileDlg*>( inputPanel() );
423   if( aPanel )
424   {
425     Handle(AIS_InteractiveContext) aCtx = aPanel->getAISContext();
426     if( !aCtx.IsNull() )
427     {
428       if (myDisplayer)
429       {
430         //delete myDisplayer;
431         //myDisplayer = NULL;
432       }
433       if (createNewDisplayer)
434         myDisplayer = new CurveCreator_Displayer( aCtx );
435       for (int i = firstIndProf; i < lastIndProf; i++ )
436       {
437         HYDROGUI_CurveCreatorProfile* CC = myProfiles[i];
438         QColor QCurCol = QColor(0,0,255); //def color
439         if (myIsEdit)
440           QCurCol = CurveToColor[CC];
441         Quantity_Color CurOCCCol = HYDROData_Tool::toOccColor(QCurCol);
442         CC->setDisplayer( myDisplayer );
443         CC->myPointAspectColor = CurOCCCol;
444         CC->myCurveColor = CurOCCCol;
445         CC->myLineWidth = 1;
446         myDisplayer->display( CC->getAISObject( true ), true );
447       }
448     }
449     if (SwitchToFirstProf && myProfiles.size() > 1)
450       aPanel->switchToFirstProfile();
451   }
452 }
453
454 void HYDROGUI_ProfileOp::erasePreview()
455 {
456   HYDROGUI_ProfileDlg* aPanel = dynamic_cast<HYDROGUI_ProfileDlg*>( inputPanel() );
457   //CurveCreator_Displayer* aDisplayer = myProfiles[0] ? myProfile[0]->getDisplayer() : 0;
458   if( aPanel && myDisplayer )
459   {
460     Handle(AIS_InteractiveContext) aCtx = aPanel->getAISContext();
461     if( !aCtx.IsNull() )
462     {
463       myDisplayer->eraseAll( true );
464     }
465   }
466   myCurveToProfile.Clear();
467 }
468
469 void HYDROGUI_ProfileOp::onRemoveProfile(int index)
470 {
471   if (index >= myProfiles.size() )
472     return;
473
474   if (!myIsEdit)
475     return;
476
477   HYDROGUI_CurveCreatorProfile* CP = myProfiles[index];
478   myProfiles.erase (myProfiles.begin()+index);
479   myEditedObjects.Remove(index+1);
480   myCurveToProfile.UnBind(CP);
481
482   HYDROGUI_ProfileDlg* aPanel = (HYDROGUI_ProfileDlg*)inputPanel();
483   //aPanel->reset();
484   //setPreviewManager( aPanel->viewManager() );
485   //setCursor();
486
487   aPanel->BlockProfileNameSignals(true);
488   aPanel->eraseProfile(index);
489
490   Handle(AIS_InteractiveContext) aCtx = aPanel->getAISContext();
491   if( !aCtx.IsNull() && myDisplayer)
492     myDisplayer->erase( CP->getAISObject(false), true);
493   CP->SetEraseAllState(false);
494   delete CP;
495   int selectedInd = aPanel->GetProfileSelectionIndex();
496   if (selectedInd > -1)
497     aPanel->SwitchToProfile(selectedInd);
498   aPanel->BlockProfileNameSignals(false);
499 }
500
501 bool HYDROGUI_ProfileOp::isValid( SUIT_Operation* theOtherOp ) const
502 {
503   HYDROGUI_DeleteOp* aDelOp = dynamic_cast<HYDROGUI_DeleteOp*>( theOtherOp );
504   if( aDelOp )
505     return true;
506   else
507     return false;
508 }