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