Salome HOME
e10909ddca19a73d142a7305a86791d3eeadbd55
[modules/geom.git] / src / GEOMBase / GEOMBase.cxx
1 // Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 // GEOM GEOMGUI : GUI for Geometry component
24 // File   : GEOMBase.cxx
25 // Author : Damien COQUERET, Open CASCADE S.A.S.
26 //
27 #include "GEOMBase.h"
28
29 #include <GeometryGUI.h>
30 #include <GEOM_Client.hxx>
31
32 ////  SALOME Includes
33 #include <GEOM_Actor.h>
34 #include <SVTK_ViewModel.h>
35 #include <SVTK_ViewWindow.h>
36 #include <OCCViewer_ViewPort3d.h>
37 #include <OCCViewer_ViewModel.h>
38 #include <OCCViewer_ViewWindow.h>
39 #include <SOCC_ViewModel.h>
40 #include <SOCC_Prs.h>
41
42 #include <SALOME_ListIO.hxx>
43
44 #include <SUIT_Desktop.h>
45 #include <SUIT_Session.h>
46 #include <SUIT_ViewManager.h>
47 #include <SUIT_ViewWindow.h>
48 #include <SUIT_MessageBox.h>
49 #include <SalomeApp_Application.h>
50 #include <SalomeApp_Study.h>
51
52 // // Open CASCADE Includes
53 #include <BRep_Tool.hxx>
54 #include <BRepAdaptor_Curve.hxx>
55 #include <BRepAdaptor_Surface.hxx>
56 #include <BRepPrimAPI_MakeCone.hxx>
57
58 #include <AIS_ListIteratorOfListOfInteractive.hxx>
59 #include <AIS_ListOfInteractive.hxx>
60
61 #include <TopAbs.hxx>
62 #include <TopExp.hxx>
63 #include <TopTools_IndexedMapOfShape.hxx>
64 #include <TopoDS.hxx>
65
66 #include <Precision.hxx>
67
68 #include <vtkRenderer.h>
69
70 #include <set>
71
72 //=====================================================================================
73 // function : GetShapeFromIOR()
74 // purpose  : Get shape data by the specified IOR
75 //=====================================================================================
76 TopoDS_Shape GEOMBase::GetShapeFromIOR( const QString& IOR )
77 {
78   GEOM::GEOM_Object_var geomObj = GEOMBase::GetObjectFromIOR( IOR );
79   TopoDS_Shape shape;
80   GetShape( geomObj, shape, TopAbs_SHAPE );
81   return shape;
82 }
83
84
85 //=====================================================================================
86 // function : GetIndex()
87 // purpose  : Get the index of a sub-shape in a main shape : index start at 1
88 //=====================================================================================
89 int GEOMBase::GetIndex( const TopoDS_Shape& subshape, const TopoDS_Shape& shape )
90 {
91   int idx = -1;
92   if ( !shape.IsNull() && !subshape.IsNull() ) {
93     TopTools_IndexedMapOfShape anIndices;
94     TopExp::MapShapes( shape, anIndices );
95     if ( anIndices.Contains( subshape ) ) 
96       idx = anIndices.FindIndex( subshape );
97   }
98   return idx;
99 }
100
101
102 //=======================================================================
103 // function : GetTopoFromSelection()
104 // purpose  : Define tds from a single selection and retuen true
105 //=======================================================================
106 TopoDS_Shape GEOMBase::GetTopoFromSelection( const SALOME_ListIO& IObjects )
107 {
108   TopoDS_Shape shape;
109   if ( IObjects.Extent() == 1 ){
110     Handle(SALOME_InteractiveObject) IO = IObjects.First();
111     SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
112     if ( IO->hasEntry() && study ) {
113       _PTR(Study) studyDS = study->studyDS();
114       _PTR(SObject) obj( studyDS->FindObjectID( IO->getEntry() ) );
115       _PTR(GenericAttribute) anAttr;
116       if ( obj && obj->FindAttribute( anAttr, "AttributeIOR" ) ) {
117         _PTR(AttributeIOR) anIOR( anAttr );
118         shape = GetShapeFromIOR( anIOR->Value().c_str() );
119       }
120     }
121   }
122   return shape;
123 }
124
125 //=======================================================================
126 // function : GetNameOfSelectedIObjects()
127 // purpose  : Define the name geom++ or other name of mono or multi sel.
128 //=======================================================================
129 int GEOMBase::GetNameOfSelectedIObjects( const SALOME_ListIO& IObjects,
130                                          QString&             name,
131                                          const bool           shapesOnly )
132 {
133   int nbSel = 0;
134   name = ""; // clear output name
135
136   if ( !shapesOnly ) {
137     nbSel = IObjects.Extent();
138     if ( nbSel == 1 ) {
139       Handle(SALOME_InteractiveObject) anIObj = IObjects.First();
140       SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
141       if ( anIObj->hasEntry() && study ) {
142         _PTR(Study) studyDS = study->studyDS();
143         _PTR(SObject) obj( studyDS->FindObjectID( anIObj->getEntry() ) );
144         _PTR(GenericAttribute) anAttr;
145         if ( obj && obj->FindAttribute( anAttr, "AttributeName" ) ) {
146           _PTR(AttributeName) aNameAttr ( anAttr );
147           name = aNameAttr->Value().c_str();
148         }
149       }
150     }
151   }
152   else {
153     GEOM::ListOfGO anObjs;
154     ConvertListOfIOInListOfGO( IObjects, anObjs, shapesOnly );
155     nbSel = anObjs.length();
156     if ( nbSel == 1 )
157       name = GetName( anObjs[ 0 ] );
158   }
159
160   if ( nbSel > 1 )
161     name = QObject::tr( "%1_objects" ).arg( nbSel );
162
163   return nbSel;
164 }
165
166
167 //=================================================================================
168 // function : GetShapeTypeString()
169 // purpose  : for a single shape
170 //=================================================================================
171 QString GEOMBase::GetShapeTypeString(const TopoDS_Shape& shape)
172 {
173   QString aTypeString;
174   if ( !shape.IsNull() ) {
175     switch ( shape.ShapeType() ) {
176     case TopAbs_COMPOUND:
177       {
178         aTypeString = QObject::tr( "GEOM_COMPOUND" );
179         break;
180       }
181     case TopAbs_COMPSOLID:
182       {
183         aTypeString = QObject::tr( "GEOM_COMPOUNDSOLID" );
184         break;
185       }
186     case TopAbs_SOLID:
187       {
188         aTypeString = QObject::tr( "GEOM_SOLID" );
189         break;
190       }
191     case TopAbs_SHELL:
192       {
193         aTypeString = QObject::tr( "GEOM_SHELL" );
194         break;
195       }
196     case TopAbs_FACE:
197       {
198         BRepAdaptor_Surface surf( TopoDS::Face( shape ) );
199         switch ( surf.GetType() ) {
200         case GeomAbs_Plane:
201           {
202             aTypeString = QObject::tr( "GEOM_PLANE" );
203             break;
204           }
205         case GeomAbs_Cylinder:
206           {
207             aTypeString = QObject::tr( "GEOM_SURFCYLINDER" );
208             break;
209           }
210         case GeomAbs_Sphere:
211           {
212             aTypeString = QObject::tr( "GEOM_SURFSPHERE" );
213             break;
214           }
215         case GeomAbs_Torus:
216           {
217             aTypeString = QObject::tr( "GEOM_SURFTORUS" );
218             break;
219           }
220         case GeomAbs_Cone:
221           {
222             aTypeString = QObject::tr( "GEOM_SURFCONE" );
223             break;
224           }
225         default:
226           {
227             aTypeString = QObject::tr( "GEOM_FACE" );
228             break;
229           }
230         }
231         break;
232       }
233     case TopAbs_WIRE:
234       {
235         aTypeString = QObject::tr( "GEOM_WIRE" );
236         break;
237       }
238     case TopAbs_EDGE:
239       {
240         BRepAdaptor_Curve curv( TopoDS::Edge( shape ) );
241         switch ( curv.GetType() ) {
242         case GeomAbs_Line:
243           {
244             aTypeString = ( qAbs( curv.FirstParameter() ) >= 1E6 || qAbs( curv.LastParameter() ) >= 1E6 ) ?
245               QObject::tr( "GEOM_LINE" ) : QObject::tr( "GEOM_EDGE" );
246             break;
247           }
248         case GeomAbs_Circle:
249           {
250             aTypeString = curv.IsClosed() ? QObject::tr( "GEOM_CIRCLE" ) : QObject::tr( "GEOM_ARC" );
251             break;
252           }
253         default:
254           {
255             aTypeString = QObject::tr( "GEOM_EDGE" );
256             break;
257           }
258         }
259         break;
260       }
261     case TopAbs_VERTEX:
262       {
263         aTypeString = QObject::tr( "GEOM_VERTEX" );
264         break;
265       }
266     case TopAbs_SHAPE:
267       {
268         aTypeString = QObject::tr( "GEOM_SHAPE" );
269         break;
270       }
271     default:
272       {
273         break;
274       }
275     }
276   }
277   return aTypeString;
278 }
279
280
281 //=======================================================================
282 // function : ConvertIORinGEOMAISShape()
283 // purpose  :
284 //=======================================================================
285 Handle(GEOM_AISShape) GEOMBase::ConvertIORinGEOMAISShape(const QString& IOR, bool onlyInActiveView)
286 {
287   Handle(GEOM_AISShape) shape;
288
289   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
290   if ( study ) {
291     _PTR(Study) studyDS = study->studyDS();
292     _PTR(SObject) obj( studyDS->FindObjectIOR( IOR.toLatin1().constData() ) );
293     if ( obj ) {
294       QList<SUIT_ViewWindow*> views;
295       if ( onlyInActiveView ) 
296         views.append( SUIT_Session::session()->activeApplication()->desktop()->activeWindow() );
297       else 
298         views = SUIT_Session::session()->activeApplication()->desktop()->windows();
299       foreach ( SUIT_ViewWindow* view, views ) {
300         if ( view && view->getViewManager()->getType() == OCCViewer_Viewer::Type() ) {
301           Handle(AIS_InteractiveContext) ic = ((OCCViewer_Viewer*)view->getViewManager()->getViewModel())->getAISContext();
302
303           AIS_ListOfInteractive displayed;
304           ic->DisplayedObjects( displayed );
305           AIS_ListIteratorOfListOfInteractive it( displayed );
306           while ( it.More() && shape.IsNull() ) {
307             if ( it.Value()->IsInstance( STANDARD_TYPE(GEOM_AISShape) ) ) {
308               Handle(GEOM_AISShape) sh = Handle(GEOM_AISShape)::DownCast( it.Value() );
309               if ( !sh.IsNull() && sh->hasIO() ) {
310                 Handle(SALOME_InteractiveObject) IO = Handle(SALOME_InteractiveObject)::DownCast( sh->getIO() );
311                 if ( !IO.IsNull() && IO->hasEntry() && obj->GetID() == IO->getEntry() )
312                   shape = sh;
313               }
314             }
315             it.Next();
316           }
317         }
318         if ( !shape.IsNull() ) break;
319       }
320     }
321   }
322   return shape;
323 }
324
325
326 //=======================================================================
327 // function : ConvertIORinGEOMActor()
328 // purpose  :
329 //=======================================================================
330 GEOM_Actor* GEOMBase::ConvertIORinGEOMActor(const QString& IOR, bool onlyInActiveView)
331 {
332   GEOM_Actor* actor = 0;
333
334   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
335   if ( study ) {
336     _PTR(Study) studyDS = study->studyDS();
337     _PTR(SObject) obj( studyDS->FindObjectIOR( IOR.toLatin1().constData() ) );
338     if ( obj ) {
339       QList<SUIT_ViewWindow*> views;
340       if ( onlyInActiveView ) 
341         views.append( SUIT_Session::session()->activeApplication()->desktop()->activeWindow() );
342       else 
343         views = SUIT_Session::session()->activeApplication()->desktop()->windows();
344       foreach ( SUIT_ViewWindow* view, views ) {
345         if ( view && view->getViewManager()->getType() == SVTK_Viewer::Type() ) {
346           SVTK_ViewWindow* aVTKViewWindow = dynamic_cast<SVTK_ViewWindow*>( view );
347           if( !aVTKViewWindow )
348             continue;
349           vtkRenderer* Renderer = aVTKViewWindow->getRenderer();
350           vtkActorCollection* theActors = Renderer->GetActors();
351           theActors->InitTraversal();
352           vtkActor* a = theActors->GetNextActor();
353           while( a && !actor ) {
354             if ( a->IsA( "GEOM_Actor" ) ) {
355               GEOM_Actor* ga = GEOM_Actor::SafeDownCast( a );
356               if ( ga && ga->hasIO() ) {
357                 Handle(SALOME_InteractiveObject) IO = Handle(SALOME_InteractiveObject)::DownCast( ga->getIO() );
358                 if ( !IO.IsNull() && IO->hasEntry() && obj->GetID() == IO->getEntry() )
359                   actor = ga;
360               }
361             }
362             a = theActors->GetNextActor();
363           }
364         }
365         if ( actor ) break;
366       }
367     }
368   }
369   return actor;
370 }
371
372 //=======================================================================
373 // function : GetAIS()
374 // purpose  :
375 //=======================================================================
376 Handle(AIS_InteractiveObject) GEOMBase::GetAIS( const Handle(SALOME_InteractiveObject)& IO,
377                                                 bool onlyInActiveView, bool onlyGeom )
378 {
379   Handle(AIS_InteractiveObject) aisObject;
380
381   if ( !IO.IsNull() && IO->hasEntry() ) {
382     QList<SUIT_ViewWindow*> views;
383     if ( onlyInActiveView ) 
384       views.append( SUIT_Session::session()->activeApplication()->desktop()->activeWindow() );
385     else 
386       views = SUIT_Session::session()->activeApplication()->desktop()->windows();
387     
388     foreach ( SUIT_ViewWindow* view, views ) {
389       if ( view && view->getViewManager()->getType() == OCCViewer_Viewer::Type() ) {
390         OCCViewer_Viewer* occViewer=(OCCViewer_Viewer*)view->getViewManager()->getViewModel();
391         SOCC_Viewer* soccViewer = dynamic_cast<SOCC_Viewer*>(occViewer);
392         if (soccViewer) {
393           SOCC_Prs* occPrs = dynamic_cast<SOCC_Prs*>( soccViewer->CreatePrs( IO->getEntry() ) );
394           if ( occPrs && !occPrs->IsNull() ) {
395             AIS_ListOfInteractive shapes; occPrs->GetObjects( shapes );
396             if( !shapes.Extent() ) continue;
397             aisObject=shapes.First();
398             delete occPrs;
399           }
400         }
401       }
402       if ( !aisObject.IsNull() ) break;
403     } // foreach
404   }
405
406   return aisObject;
407 }
408
409
410 //=======================================================================
411 // function : ConvertIOinGEOMAISShape()
412 // purpose  :
413 //=======================================================================
414 Handle(GEOM_AISShape) GEOMBase::ConvertIOinGEOMAISShape( const Handle(SALOME_InteractiveObject)& IO, bool onlyInActiveView )
415 {
416   return Handle(GEOM_AISShape)::DownCast( GetAIS( IO, onlyInActiveView, true ) );
417 }
418
419
420 //=======================================================================
421 // function : ConvertListOfIOInListOfIOR()
422 // purpose  :
423 //=======================================================================
424 QStringList GEOMBase::ConvertListOfIOInListOfIOR( const SALOME_ListIO& IObjects )
425 {
426   QStringList iors;
427   SALOME_ListIteratorOfListIO it( IObjects );
428   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
429   if ( study ) {
430     _PTR(Study) studyDS = study->studyDS();
431     for ( ; it.More(); it.Next() ) {
432       GEOM::GEOM_Object_var geomObj = ConvertIOinGEOMObject( it.Value() );
433       if ( !CORBA::is_nil( geomObj ) )
434         iors.append( GetIORFromObject( geomObj ) );
435     }
436   }
437   return iors;
438 }
439
440
441 //=======================================================================
442 // function : ConvertIOinGEOMObject()
443 // purpose  :
444 //=======================================================================
445 GEOM::GEOM_Object_ptr GEOMBase::ConvertIOinGEOMObject( const Handle(SALOME_InteractiveObject)& IO )
446 {
447   GEOM::GEOM_Object_var object;
448
449   if ( !IO.IsNull() && IO->hasEntry() ) {
450     SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
451     if ( study ) {
452       _PTR(Study) studyDS = study->studyDS();
453       _PTR(SObject) obj( studyDS->FindObjectID( IO->getEntry() ) );
454       if ( obj ) {
455         CORBA::Object_var corbaObj = GeometryGUI::ClientSObjectToObject( obj );
456         if ( !CORBA::is_nil( corbaObj ) )
457           object = GEOM::GEOM_Object::_narrow( corbaObj );
458       }
459     }
460   }
461   return object._retn();
462 }
463
464
465 //=======================================================================
466 // function : ConvertListOfIOInListOfGO()
467 // purpose  :
468 //=======================================================================
469 void GEOMBase::ConvertListOfIOInListOfGO( const SALOME_ListIO& IObjects,
470                                           GEOM::ListOfGO&      geomObjects,
471                                           bool                 shapesOnly )
472 {
473   geomObjects.length( 0 );
474
475   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
476   if ( study ) {
477     _PTR(Study) studyDS = study->studyDS();
478
479     geomObjects.length( IObjects.Extent() );
480     SALOME_ListIteratorOfListIO it( IObjects );
481
482     int i = 0;
483     for ( ; it.More(); it.Next() ) {
484       GEOM::GEOM_Object_var geomObj = ConvertIOinGEOMObject( it.Value() );
485       if ( !CORBA::is_nil( geomObj ) && ( !shapesOnly || IsShape( geomObj ) ) )
486         geomObjects[ i++ ] = geomObj;
487     }
488     geomObjects.length( i );
489   }
490 }
491
492
493 //=================================================================================
494 // function : CreateArrowForLinearEdge()
495 // purpose  : Create a cone topology to be used to display an arrow in the middle
496 //          : of an edge showing its orientation. (For simulation and Viewer OCC only)
497 //=================================================================================
498 TopoDS_Shape GEOMBase::CreateArrowForLinearEdge( const TopoDS_Shape& shape )
499 {
500   TopoDS_Shape ArrowCone;
501
502   SUIT_ViewWindow* view = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
503   if ( view && view->getViewManager()->getType() == OCCViewer_Viewer::Type() && shape.ShapeType() == TopAbs_EDGE ) {
504     Handle(V3d_View) view3d = ((OCCViewer_ViewWindow*)view)->getViewPort()->getView();
505     Standard_Real Width, Height;
506     view3d->Size( Width, Height );
507     const Standard_Real aHeight = (Width + Height) / 50.0;
508
509     try {
510       Standard_Real first, last;
511       Handle(Geom_Curve) curv = BRep_Tool::Curve( TopoDS::Edge( shape ), first, last );
512       if ( !curv.IsNull() && curv->IsCN(1) ) {
513         const Standard_Real param = ( first+last ) / 2.0;
514         gp_Pnt middleParamPoint;
515         gp_Vec V1;
516         curv->D1( param, middleParamPoint, V1 );
517         if ( V1.Magnitude() > Precision::Confusion() ) {
518           /* Topology orientation not geom orientation */
519           if ( shape.Orientation() == TopAbs_REVERSED )
520             V1 *= -1.0;
521
522           gp_Ax2 anAxis( middleParamPoint, gp_Dir( V1 ) );
523           const Standard_Real radius1 = aHeight / 5.0;
524           if ( radius1 > 10.0 * Precision::Confusion() && aHeight > 10.0 * Precision::Confusion() )
525             ArrowCone = BRepPrimAPI_MakeCone( anAxis, radius1, 0.0, aHeight ).Shape();
526         }
527       }
528     }
529     catch ( Standard_Failure ) {
530       // OCC failures are hard to catch in GUI.
531       // This is because of the position for #include <Standard_ErrorHandler.hxx> that is very critical to find
532       // in SALOME environment : compilation error !
533     }
534   }
535
536   return ArrowCone;
537 }
538
539
540 //=================================================================================
541 // function : VertexToPoint()
542 // purpose  : If S can be converted in a gp_Pnt returns true and the result is P
543 //=================================================================================
544 bool GEOMBase::VertexToPoint( const TopoDS_Shape& shape, gp_Pnt& point )
545 {
546   if ( shape.IsNull() || shape.ShapeType() != TopAbs_VERTEX )
547     return false;
548   point = BRep_Tool::Pnt( TopoDS::Vertex( shape ) );
549   return true;
550 }
551
552
553 //=================================================================================
554 // function : GetBipointDxDyDz()
555 // purpose  :
556 //=================================================================================
557 void GEOMBase::GetBipointDxDyDz( const gp_Pnt& point1, const gp_Pnt& point2, double& dx, double& dy, double& dz )
558 {
559   dx = point2.X() - point1.X();
560   dy = point2.Y() - point1.Y();
561   dz = point2.Z() - point1.Z();
562 }
563
564
565 //=================================================================================
566 // function : LinearEdgeExtremities()
567 // purpose  : If S can be converted in a linear edge and if initial an final points
568 //          : distance is sufficient, returns true else returns false.
569 //          : Resulting points are respectively P1 and P2
570 //=================================================================================
571 bool GEOMBase::LinearEdgeExtremities( const TopoDS_Shape& shape,  gp_Pnt& point1, gp_Pnt& point2 )
572 {
573   if ( shape.IsNull() || shape.ShapeType() != TopAbs_EDGE )
574     return false;
575
576   BRepAdaptor_Curve curv( TopoDS::Edge( shape ) );
577   if ( curv.GetType() != GeomAbs_Line )
578     return false;
579   
580   gp_Pnt p1, p2;
581
582   curv.D0( curv.FirstParameter(), p1 );
583   curv.D0( curv.LastParameter(),  p2 );
584
585   if ( p1.Distance( p2 ) <= Precision::Confusion() )
586     return false;
587
588   point1 = p1;
589   point2 = p2;
590   return true;
591 }
592
593
594 //=======================================================================
595 // function : SelectionByNameInDialogs()
596 // purpose  : Called when user has entered a name of object in a LineEdit.
597 //          : The selection is changed. Dialog box will receive the
598 //          : corresponding signal to manage this event.
599 //=======================================================================
600 bool GEOMBase::SelectionByNameInDialogs( QWidget* widget, const QString& objectUserName, const SALOME_ListIO& /*IObjects*/ )
601 {
602   /* Find SObject with name in component GEOM */
603   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
604   if ( !study ) return false;
605   _PTR(Study) studyDS = study->studyDS();
606
607   std::vector<_PTR(SObject)> listSO = studyDS->FindObjectByName( objectUserName.toStdString(), "GEOM" );
608
609   if ( listSO.size() < 1 ) {
610     SUIT_MessageBox::critical( widget, 
611                                QObject::tr( "GEOM_WRN_WARNING" ),
612                                QObject::tr( "GEOM_NAME_INCORRECT" ),
613                                QObject::tr( "GEOM_BUT_OK" ) );
614     return false;
615   }
616
617   /* More than one object with same name */
618   if ( listSO.size() > 1 ) {
619     SUIT_MessageBox::critical( widget,
620                                QObject::tr("GEOM_WRN_WARNING"),
621                                QObject::tr("GEOM_IDENTICAL_NAMES_SELECT_BY_MOUSE"),
622                                QObject::tr("GEOM_BUT_OK") );
623     return false;
624   }
625
626   /* Create a SALOME_InteractiveObject with a SALOME::SObject */
627   Handle(SALOME_InteractiveObject) IO = new SALOME_InteractiveObject( listSO[0]->GetID().c_str(),
628                                                                       "GEOM",
629                                                                       objectUserName.toLatin1().constData() );
630
631   /* Add as a selected object       */
632   /* Clear any previous selection : */
633   /* Warning the LineEdit is purged because of signal currentSelectionChanged ! */
634   // Sel->ClearIObjects(); //mzn
635   // Sel->AddIObject(SI); //mzn
636   return true;
637 }
638
639
640 //=======================================================================
641 // function : DefineDlgPosition()
642 // purpose  : Define x and y the default position for a dialog box
643 //=======================================================================
644 void GEOMBase::DefineDlgPosition( QWidget* dlg, int& x, int& y )
645 {
646   /* Here the position is on the bottom right corner - 10 */
647   SUIT_Desktop* d = SUIT_Session::session()->activeApplication()->desktop();
648   x = abs( d->x() + d->size().width()  - dlg->size().width()  - 10 );
649   y = abs( d->y() + d->size().height() - dlg->size().height() - 10 );
650 }
651
652
653 //=======================================================================
654 // function : GetDefaultName()
655 // purpose  : Generates default names
656 //=======================================================================
657 QString GEOMBase::GetDefaultName( const QString& operation, bool extractPrefix )
658 {
659   QString aName = "";
660
661   // collect all object names of GEOM component
662   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
663   if ( study ) {
664     _PTR(Study) studyDS = study->studyDS();
665
666     std::set<std::string> names;
667     _PTR(SComponent) component( studyDS->FindComponent( "GEOM" ) );
668     if ( component ) {
669       _PTR(ChildIterator) it( studyDS->NewChildIterator( component ) );
670       for ( it->InitEx( true ); it->More(); it->Next() ) {
671         names.insert( it->Value()->GetName() );
672       }
673     }
674
675     // build a unique name
676     int aNumber = 0;
677     bool isUnique = false;
678     QString prefix = operation;
679
680     if ( extractPrefix ) {
681       QStringList parts = prefix.split( "_", QString::KeepEmptyParts );
682       if ( parts.count() > 1 ) {
683         bool ok;
684         aNumber = parts.last().toLong( &ok );
685         if ( ok ) {
686           parts.removeLast();
687           prefix = parts.join( "_" );
688           aNumber--;
689         }
690       }
691     }
692     
693     while ( !isUnique ) {
694       aName = prefix + "_" + QString::number( ++aNumber );
695       isUnique = ( names.count( aName.toStdString()) == 0 );
696     }
697   }
698   return aName;
699 }
700
701
702 //=======================================================================
703 // function : ShowErrorMessage()
704 // purpose  : Shows message box with error code and comment
705 //=======================================================================
706 void GEOMBase::ShowErrorMessage( const QString& errorCode, const QString& comment )
707 {
708   QStringList text;
709   text << QObject::tr( "GEOM_PRP_ABORT" );
710   if ( !errorCode.isEmpty() )
711     text << QObject::tr( errorCode.toLatin1().constData() );
712   if ( !comment.isEmpty() )
713     text << QObject::tr( comment.toLatin1().constData() );
714
715   SUIT_MessageBox::critical( SUIT_Session::session()->activeApplication()->desktop(),
716                              QObject::tr( "GEOM_ERROR" ),
717                              text.join( "\n" ),
718                              QObject::tr( "GEOM_BUT_OK" ) );
719 }
720
721
722 //=======================================================================
723 // function : GetObjectFromIOR()
724 // purpose  : returns a GEOM_Object by given IOR (string)
725 //=======================================================================
726 GEOM::GEOM_Object_ptr GEOMBase::GetObjectFromIOR( const QString& IOR )
727 {
728   return GeometryGUI::GetObjectFromIOR (IOR);
729 }
730
731 //=======================================================================
732 // function : GetIORFromObject()
733 // purpose  : returns IOR of a given GEOM_Object
734 //=======================================================================
735 QString GEOMBase::GetIORFromObject( GEOM::GEOM_Object_ptr object )
736 {
737   return GeometryGUI::GetIORFromObject (object);
738 }
739
740 //=======================================================================
741 // function : GetShape()
742 // purpose  : returns a TopoDS_Shape stored in GEOM_Object
743 //=======================================================================
744 bool GEOMBase::GetShape( GEOM::GEOM_Object_ptr object, TopoDS_Shape& shape, const TopAbs_ShapeEnum type )
745 {
746   shape = TopoDS_Shape();
747   if ( !CORBA::is_nil( object ) ) {
748     TopAbs_ShapeEnum stype = (TopAbs_ShapeEnum)( object->GetShapeType() );
749     if ( type == TopAbs_SHAPE || type == stype )
750       shape = GEOM_Client::get_client().GetShape(  GeometryGUI::GetGeomGen(), object );
751   }
752   return !shape.IsNull();
753 }
754
755 //=======================================================================
756 // function : GetName()
757 // purpose  : Get name of object
758 //=======================================================================
759 QString GEOMBase::GetName( GEOM::GEOM_Object_ptr object )
760 {
761   QString name;
762   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
763   
764   if ( !CORBA::is_nil( object ) ) {
765     // 1. search if object is already published in the study
766     CORBA::String_var IOR = SalomeApp_Application::orb()->object_to_string( object );
767     if ( study && strcmp( IOR.in(), "" ) != 0 ) {
768       _PTR(SObject) aSObj( study->studyDS()->FindObjectIOR( std::string( IOR.in() ) ) );
769       _PTR(GenericAttribute) anAttr;
770       if ( aSObj && aSObj->FindAttribute( anAttr, "AttributeName") ) {
771         _PTR(AttributeName) aNameAttr( anAttr );
772         name = aNameAttr->Value().c_str();
773       }
774     }
775     
776     // 2. if object is not found in the study, try default name
777     if ( name.isEmpty() ) {
778       if ( object->IsMainShape() ) {
779         name = GetDefaultName( "geomObj" );
780       }
781       else {
782         GEOM::GEOM_Object_var mainShape = object->GetMainShape();
783         if ( !CORBA::is_nil( mainShape  ) ) { 
784           GEOM::ListOfLong_var indices = object->GetSubShapeIndices();
785           if ( indices->length() > 0 ) {
786             TopAbs_ShapeEnum type = (TopAbs_ShapeEnum)( object->GetShapeType() );
787             name = QString( "%1:%2_%3" ).arg( GetName( mainShape.in() ) )
788               .arg( TypeName( type ) ).arg( indices[0] );
789           }
790         }
791       }
792     }
793   }
794
795   return name;
796 }
797
798 //=======================================================================
799 // function : IsShape()
800 // purpose  : Return TRUE if object is valid and has shape
801 //=======================================================================
802 bool GEOMBase::IsShape( GEOM::GEOM_Object_ptr object )
803 {
804   return !object->_is_nil() && object->IsShape();
805 }
806
807 //=======================================================================
808 // function : TypeName()
809 // purpose  : Get string representation for the shape type
810 //=======================================================================
811 QString GEOMBase::TypeName( TopAbs_ShapeEnum type, bool capitalize )
812 {
813   QString name = "shape";
814   switch( type ) {
815   case TopAbs_COMPSOLID:
816     name = "compsolid"; break;
817   case TopAbs_COMPOUND:
818     name = "compound";  break;
819   case TopAbs_SOLID:
820     name = "solid";     break;
821   case TopAbs_SHELL:
822     name = "shell";     break;
823   case TopAbs_FACE:
824     name = "face";      break;
825   case TopAbs_WIRE:
826     name = "wire";      break;
827   case TopAbs_EDGE:
828     name = "edge";      break;
829   case TopAbs_VERTEX:
830     name = "vertex";    break;
831   default:
832     break;
833   }
834   if ( capitalize && !name.isEmpty() )
835     name = name.left(1).toUpper() + name.mid(1);
836   return name;
837 }
838
839 //================================================================
840 // Function : GetEntry
841 // Purpose  : Get study entry for the given object (if it is published)
842 //================================================================
843 QString GEOMBase::GetEntry( GEOM::GEOM_Object_ptr object )
844 {
845   QString entry;
846   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
847   if ( study && !CORBA::is_nil( object ) ) {
848     QString objIOR = GetIORFromObject( object );
849     if ( !objIOR.isEmpty() ) {
850       _PTR(SObject) SO( study->studyDS()->FindObjectIOR( objIOR.toLatin1().constData() ) );
851       if ( SO )
852         entry = SO->GetID().c_str();
853     }
854   }
855   return entry;
856 }
857
858 //================================================================
859 // Function : PublishSubObject
860 // Purpose  : Publish sub-shape under the main object
861 //================================================================
862 void GEOMBase::PublishSubObject( GEOM::GEOM_Object_ptr object )
863 {
864   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
865   if ( study && !CORBA::is_nil( object ) ) {
866     _PTR(Study) studyDS = study->studyDS();
867     QString entry = GetEntry( object );
868     GEOM::GEOM_Object_var father = object->GetMainShape();
869     QString fatherEntry = GetEntry( father );
870     if ( entry.isEmpty() && !CORBA::is_nil( father ) && !fatherEntry.isEmpty() ) {
871       QString name = GetName( object );
872       GeometryGUI::GetGeomGen()->AddInStudy( GeometryGUI::ClientStudyToStudy( studyDS ),
873                                              object, name.toLatin1().data(), father.in() );
874     }
875   }
876 }
877
878 //================================================================
879 // Function : synchronize
880 // Purpose  : 
881 //================================================================
882 void GEOMBase::Synchronize( QList<GEOM::GeomObjPtr>& left, QList<GEOM::GeomObjPtr>& right )
883 {
884   // 1. remove items from the "left" list that are not in the "right" list
885   QMutableListIterator<GEOM::GeomObjPtr> it1( left );
886   while ( it1.hasNext() ) {
887     GEOM::GeomObjPtr o1 = it1.next();
888     bool found = false;
889     QMutableListIterator<GEOM::GeomObjPtr> it2( right );
890     while ( it2.hasNext() && !found )
891       found = o1 == it2.next();
892     if ( !found )
893       it1.remove();
894   }
895   // 2. add items from the "right" list that are not in the "left" list (to keep selection order)
896   it1 = right;
897   while ( it1.hasNext() ) {
898     GEOM::GeomObjPtr o1 = it1.next();
899     bool found = false;
900     QMutableListIterator<GEOM::GeomObjPtr> it2( left );
901     while ( it2.hasNext() && !found )
902       found = o1 == it2.next();
903     if ( !found )
904       left << o1;
905   }
906 }