Salome HOME
Merge with version on tag OCC-V2_1_0d
[modules/smesh.git] / src / SMESH_I / SMESH_Gen_i_1.cxx
1 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
2 //
3 //  Copyright (C) 2003  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. 
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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 // File      : SMESH_Gen_i_1.cxx
24 // Created   : Thu Oct 21 17:24:06 2004
25 // Author    : Edward AGAPOV (eap)
26 // Module    : SMESH
27 // $Header: 
28
29 #include "SMESH_Gen_i.hxx"
30
31 #include "SMESH_Mesh_i.hxx"
32 #include "SMESH_Hypothesis_i.hxx"
33 #include "SMESH_Algo_i.hxx"
34 #include "SMESH_Group_i.hxx"
35
36 #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
37
38 #include "utilities.h"
39 #include "Utils_ExceptHandlers.hxx"
40
41 #include <TCollection_AsciiString.hxx>
42
43 #ifdef _DEBUG_
44 static int MYDEBUG = 0;
45 #else
46 static int MYDEBUG = 0;
47 #endif
48
49 // Tags definition ===========================================================
50 // Top level
51 long Tag_HypothesisRoot         = 1; // hypotheses root
52 long Tag_AlgorithmsRoot         = 2; // algorithms root
53 // Mesh/Submesh
54 long Tag_RefOnShape             = 1; // references to shape
55 long Tag_RefOnAppliedHypothesis = 2; // applied hypotheses root
56 long Tag_RefOnAppliedAlgorithms = 3; // applied algorithms root
57 // Mesh only
58 long Tag_SubMeshOnVertex        = 4; // sub-meshes roots by type
59 long Tag_SubMeshOnEdge          = 5; // ...
60 long Tag_SubMeshOnWire          = 6; // ...
61 long Tag_SubMeshOnFace          = 7; // ...
62 long Tag_SubMeshOnShell         = 8; // ...
63 long Tag_SubMeshOnSolid         = 9; // ...
64 long Tag_SubMeshOnCompound      = 10; // ...
65 long Tag_NodeGroups             = 11; // Group roots by type
66 long Tag_EdgeGroups             = 12; // ...
67 long Tag_FaceGroups             = 13; // ...
68 long Tag_VolumeGroups           = 14; // ...
69 // ===========================================================================
70
71 //=============================================================================
72 /*!
73  *  Get...Tag [ static ]
74  *
75  *  Methods which determine SMESH data model structure
76  */
77 //=============================================================================
78
79 long SMESH_Gen_i::GetHypothesisRootTag()
80 {
81   return Tag_HypothesisRoot;
82 }
83
84 long SMESH_Gen_i::GetAlgorithmsRootTag()
85 {
86   return Tag_AlgorithmsRoot;
87 }
88
89 long SMESH_Gen_i::GetRefOnShapeTag()
90 {
91   return Tag_RefOnShape;
92 }
93
94 long SMESH_Gen_i::GetRefOnAppliedHypothesisTag()
95 {
96   return Tag_RefOnAppliedHypothesis;
97 }
98
99 long SMESH_Gen_i::GetRefOnAppliedAlgorithmsTag()
100 {
101   return Tag_RefOnAppliedAlgorithms;
102 }
103
104 long SMESH_Gen_i::GetSubMeshOnVertexTag()
105 {
106   return Tag_SubMeshOnVertex;
107 }
108
109 long SMESH_Gen_i::GetSubMeshOnEdgeTag()
110 {
111   return Tag_SubMeshOnEdge;
112 }
113
114 long SMESH_Gen_i::GetSubMeshOnFaceTag()
115 {
116   return Tag_SubMeshOnFace;
117 }
118
119 long SMESH_Gen_i::GetSubMeshOnSolidTag()
120 {
121   return Tag_SubMeshOnSolid;
122 }
123
124 long SMESH_Gen_i::GetSubMeshOnCompoundTag()
125 {
126   return Tag_SubMeshOnCompound;
127 }
128
129 long SMESH_Gen_i::GetSubMeshOnWireTag()
130 {
131   return Tag_SubMeshOnWire;
132 }
133
134 long SMESH_Gen_i::GetSubMeshOnShellTag()
135 {
136   return Tag_SubMeshOnShell;
137 }
138
139 long SMESH_Gen_i::GetNodeGroupsTag()
140 {
141   return Tag_NodeGroups;
142 }
143
144 long SMESH_Gen_i::GetEdgeGroupsTag()
145 {
146   return Tag_EdgeGroups;
147 }
148
149 long SMESH_Gen_i::GetFaceGroupsTag()
150 {
151   return Tag_FaceGroups;
152 }
153
154 long SMESH_Gen_i::GetVolumeGroupsTag()
155 {
156   return Tag_VolumeGroups;
157 }
158
159 //=============================================================================
160 /*!
161  *  SMESH_Gen_i::CanPublishInStudy
162  *
163  *  Returns true if object can be published in the study
164  */
165 //=============================================================================
166
167 bool SMESH_Gen_i::CanPublishInStudy(CORBA::Object_ptr theIOR)
168 {
169   if(MYDEBUG) MESSAGE("CanPublishInStudy");
170   SMESH::SMESH_Mesh_var aMesh       = SMESH::SMESH_Mesh::_narrow(theIOR);
171   if( !aMesh->_is_nil() )
172     return true;
173
174   SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow(theIOR);
175   if( !aSubMesh->_is_nil() )
176     return true;
177
178   SMESH::SMESH_Hypothesis_var aHyp  = SMESH::SMESH_Hypothesis::_narrow(theIOR);
179   if( !aHyp->_is_nil() )
180     return true;
181
182   SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(theIOR);
183   if( !aGroup->_is_nil() )
184     return true;
185
186   if(MYDEBUG) MESSAGE("CanPublishInStudy--CANT");
187   return false;
188 }
189
190 //=======================================================================
191 //function : ObjectToSObject
192 //purpose  : 
193 //=======================================================================
194
195 SALOMEDS::SObject_ptr SMESH_Gen_i::ObjectToSObject(SALOMEDS::Study_ptr theStudy,
196                                                    CORBA::Object_ptr   theObject)
197 {
198   SALOMEDS::SObject_var aSO;
199   if ( !CORBA::is_nil( theStudy ) && !CORBA::is_nil( theObject ))
200     aSO = theStudy->FindObjectIOR( SMESH_Gen_i::GetORB()->object_to_string( theObject ) );
201   return aSO._retn();
202 }
203
204 //=======================================================================
205 //function : objectToServant
206 //purpose  : 
207 //=======================================================================
208
209 template<typename T> static inline T* objectToServant( CORBA::Object_ptr theIOR )
210 {
211   return dynamic_cast<T*>( SMESH_Gen_i::GetServant( theIOR ).in() );
212 }
213
214 //=======================================================================
215 //function : ShapeToGeomObject
216 //purpose  : 
217 //=======================================================================
218
219 GEOM::GEOM_Object_ptr SMESH_Gen_i::ShapeToGeomObject (const TopoDS_Shape& theShape )
220 {
221   GEOM::GEOM_Object_var aShapeObj;
222   if ( !theShape.IsNull() ) {
223     GEOM_Client* aClient = GetShapeReader();
224     TCollection_AsciiString IOR;
225     if ( aClient && aClient->Find( theShape, IOR ))
226       aShapeObj = GEOM::GEOM_Object::_narrow
227         ( GetORB()->string_to_object( IOR.ToCString() ) );
228   }
229   return aShapeObj._retn();
230 }
231
232 //=======================================================================
233 //function : GeomObjectToShape
234 //purpose  : 
235 //=======================================================================
236
237 TopoDS_Shape SMESH_Gen_i::GeomObjectToShape(GEOM::GEOM_Object_ptr theGeomObject)
238 {
239   TopoDS_Shape S;
240   if ( !theGeomObject->_is_nil() ) {
241     GEOM_Client* aClient = GetShapeReader();
242     GEOM::GEOM_Gen_var aGeomEngine = GetGeomEngine();
243     if ( aClient && !aGeomEngine->_is_nil () )
244       S = aClient->GetShape( aGeomEngine, theGeomObject );
245   }
246   return S;
247 }
248
249 //=======================================================================
250 //function : publish
251 //purpose  : 
252 //=======================================================================
253
254 static SALOMEDS::SObject_ptr publish(SALOMEDS::Study_ptr   theStudy,
255                                      CORBA::Object_ptr     theIOR,
256                                      SALOMEDS::SObject_ptr theFatherObject,
257                                      const int             theTag = 0,
258                                      const char*           thePixMap = 0,
259                                      const bool            theSelectable = true)
260 {
261   SALOMEDS::SObject_var SO = SMESH_Gen_i::ObjectToSObject( theStudy, theIOR );
262   SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
263   if ( SO->_is_nil() ) {
264     if ( theTag == 0 )
265       SO = aStudyBuilder->NewObject( theFatherObject );
266     else if ( !theFatherObject->FindSubObject( theTag, SO ))
267       SO = aStudyBuilder->NewObjectToTag( theFatherObject, theTag );
268   }
269
270   SALOMEDS::GenericAttribute_var anAttr;
271   if ( !CORBA::is_nil( theIOR )) {
272     anAttr = aStudyBuilder->FindOrCreateAttribute( SO, "AttributeIOR" );
273     SALOMEDS::AttributeIOR::_narrow(anAttr)->SetValue
274       ( SMESH_Gen_i::GetORB()->object_to_string( theIOR ) );
275   }
276   if ( thePixMap ) {
277     anAttr  = aStudyBuilder->FindOrCreateAttribute( SO, "AttributePixMap" );
278     SALOMEDS::AttributePixMap::_narrow( anAttr )->SetPixMap( thePixMap );
279   }
280   if ( !theSelectable ) {
281     anAttr   = aStudyBuilder->FindOrCreateAttribute( SO, "AttributeSelectable" );
282     SALOMEDS::AttributeSelectable::_narrow( anAttr )->SetSelectable( false );
283   }
284   return SO._retn();
285 }
286
287 //=======================================================================
288 //function : setName
289 //purpose  : 
290 //=======================================================================
291
292 void SMESH_Gen_i::SetName(SALOMEDS::SObject_ptr theSObject,
293                           const char*           theName,
294                           const char*           theDefaultName)
295 {
296   if ( !theSObject->_is_nil() ) {
297     SALOMEDS::StudyBuilder_var aStudyBuilder = theSObject->GetStudy()->NewBuilder();
298     SALOMEDS::GenericAttribute_var anAttr =
299       aStudyBuilder->FindOrCreateAttribute( theSObject, "AttributeName" );
300     SALOMEDS::AttributeName_var aNameAttr = SALOMEDS::AttributeName::_narrow( anAttr );
301     if ( theName && strlen( theName ) != 0 )
302       aNameAttr->SetValue( theName );
303     else {
304       CORBA::String_var curName = CORBA::string_dup( aNameAttr->Value() );
305       if ( strlen( curName ) == 0 ) {
306         TCollection_AsciiString aName( (char*) theDefaultName );
307         aName += TCollection_AsciiString("_") + TCollection_AsciiString( theSObject->Tag() );
308         aNameAttr->SetValue( aName.ToCString() );
309       }
310     }
311   }
312 }
313
314 //=======================================================================
315 //function : addReference
316 //purpose  : 
317 //=======================================================================
318
319 static void addReference (SALOMEDS::Study_ptr   theStudy,
320                           SALOMEDS::SObject_ptr theSObject,
321                           CORBA::Object_ptr     theToObject,
322                           int                   theTag = 0)
323 {
324   SALOMEDS::SObject_var aToObjSO = SMESH_Gen_i::ObjectToSObject( theStudy, theToObject );
325   if ( !aToObjSO->_is_nil() && !theSObject->_is_nil() ) {
326     SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
327     SALOMEDS::SObject_var aReferenceSO;
328     if ( !theTag ) {
329       bool isReferred = false;
330       SALOMEDS::ChildIterator_var anIter = theStudy->NewChildIterator( theSObject );
331       for ( ; !isReferred && anIter->More(); anIter->Next() ) {
332         if ( anIter->Value()->ReferencedObject( aReferenceSO ) &&
333             strcmp( aReferenceSO->GetID(), aToObjSO->GetID() ) == 0 )
334           isReferred = true;
335       }
336       if ( !isReferred ) {
337         aReferenceSO = aStudyBuilder->NewObject( theSObject );
338         aStudyBuilder->Addreference( aReferenceSO, aToObjSO );
339       }
340     }
341     else {
342       if ( !theSObject->FindSubObject( theTag, aReferenceSO ))
343         aReferenceSO = aStudyBuilder->NewObjectToTag( theSObject, theTag );
344       aStudyBuilder->Addreference( aReferenceSO, aToObjSO );
345     }
346   }
347 }
348
349 //=============================================================================
350 /*!
351  *  SMESH_Gen_i::PublishInStudy
352  *
353  *  Publish object in the study
354  */
355 //=============================================================================
356
357 SALOMEDS::SObject_ptr SMESH_Gen_i::PublishInStudy(SALOMEDS::Study_ptr   theStudy,
358                                                   SALOMEDS::SObject_ptr theSObject,
359                                                   CORBA::Object_ptr     theIOR,
360                                                   const char*           theName)
361      throw (SALOME::SALOME_Exception)
362 {
363   Unexpect aCatch(SALOME_SalomeException);
364   SALOMEDS::SObject_var aSO;
365   if ( CORBA::is_nil( theStudy ) || CORBA::is_nil( theIOR ))
366     return aSO._retn();
367   if(MYDEBUG) MESSAGE("PublishInStudy");
368
369   // Publishing a mesh
370   SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( theIOR );
371   if( !aMesh->_is_nil() )
372     aSO = PublishMesh( theStudy, aMesh, theName );
373
374   // Publishing a sub-mesh
375   SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( theIOR );
376   if( aSO->_is_nil() && !aSubMesh->_is_nil() ) {
377     GEOM::GEOM_Object_var aShapeObject = aSubMesh->GetSubShape();
378     aMesh = aSubMesh->GetFather();
379     aSO = PublishSubMesh( theStudy, aMesh, aSubMesh, aShapeObject, theName );
380   }
381
382   // Publishing a hypothesis or algorithm
383   SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( theIOR );
384   if ( aSO->_is_nil() && !aHyp->_is_nil() )
385     aSO = PublishHypothesis( theStudy, aHyp );
386
387   // Publishing a group
388   SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(theIOR);
389   if ( aSO->_is_nil() && !aGroup->_is_nil() ) {
390     GEOM::GEOM_Object_var aShapeObject;
391     aMesh = aGroup->GetMesh();
392     aSO = PublishGroup( theStudy, aMesh, aGroup, aShapeObject, theName );
393   }
394   if(MYDEBUG) MESSAGE("PublishInStudy_END");
395
396   return aSO._retn();
397 }
398
399 //=======================================================================
400 //function : PublishComponent
401 //purpose  : 
402 //=======================================================================
403
404 SALOMEDS::SComponent_ptr SMESH_Gen_i::PublishComponent(SALOMEDS::Study_ptr theStudy)
405 {
406   if ( CORBA::is_nil( theStudy ))
407     return SALOMEDS::SComponent::_nil();
408   if(MYDEBUG) MESSAGE("PublishComponent");
409
410   SALOMEDS::SComponent_var father =
411     SALOMEDS::SComponent::_narrow( theStudy->FindComponent( ComponentDataType() ) );
412   if ( !CORBA::is_nil( father ) )
413     return father._retn();
414
415   SALOME_ModuleCatalog::ModuleCatalog_var aCat =
416     SALOME_ModuleCatalog::ModuleCatalog::_narrow( GetNS()->Resolve("/Kernel/ModulCatalog") );
417   if ( CORBA::is_nil( aCat ) )
418     return father._retn();
419
420   SALOME_ModuleCatalog::Acomponent_var aComp = aCat->GetComponent( ComponentDataType() );
421   if ( CORBA::is_nil( aComp ) )
422     return father._retn();
423
424   SALOMEDS::StudyBuilder_var     aStudyBuilder = theStudy->NewBuilder(); 
425   SALOMEDS::GenericAttribute_var anAttr;
426   SALOMEDS::AttributePixMap_var  aPixmap;
427
428   father  = aStudyBuilder->NewComponent( ComponentDataType() );
429   aStudyBuilder->DefineComponentInstance( father, SMESH_Gen::_this() );
430   anAttr  = aStudyBuilder->FindOrCreateAttribute( father, "AttributePixMap" );
431   aPixmap = SALOMEDS::AttributePixMap::_narrow( anAttr );
432   aPixmap ->SetPixMap( "ICON_OBJBROWSER_SMESH" );
433   SetName( father, aComp->componentusername(), "MESH" );
434   if(MYDEBUG) MESSAGE("PublishComponent--END");
435
436   return father._retn();
437 }
438
439 //=============================================================================
440 /*!
441  *  findMaxChildTag [ static internal ]
442  *
443  *  Finds maximum child tag for the given object
444  */
445 //=============================================================================
446
447 static long findMaxChildTag( SALOMEDS::SObject_ptr theSObject )
448 {
449   long aTag = 0;
450   if ( !theSObject->_is_nil() ) {
451     SALOMEDS::Study_var aStudy = theSObject->GetStudy();
452     if ( !aStudy->_is_nil() ) {
453       SALOMEDS::ChildIterator_var anIter = aStudy->NewChildIterator( theSObject );
454       for ( ; anIter->More(); anIter->Next() ) {
455         long nTag = anIter->Value()->Tag();
456         if ( nTag > aTag )
457           aTag = nTag;
458       }
459     }
460   }
461   return aTag;
462 }
463
464 //=======================================================================
465 //function : PublishMesh
466 //purpose  : 
467 //=======================================================================
468
469 SALOMEDS::SObject_ptr SMESH_Gen_i::PublishMesh (SALOMEDS::Study_ptr   theStudy,
470                                                 SMESH::SMESH_Mesh_ptr theMesh,
471                                                 const char*           theName)
472 {
473   if ( CORBA::is_nil( theStudy ) ||
474        CORBA::is_nil( theMesh ))
475     return SALOMEDS::SComponent::_nil();
476   if(MYDEBUG) MESSAGE("PublishMesh--IN");
477
478   // find or publish a mesh
479
480   SALOMEDS::SObject_var aMeshSO = ObjectToSObject( theStudy, theMesh );
481   if ( aMeshSO->_is_nil() )
482   {
483     SALOMEDS::SComponent_var father = PublishComponent( theStudy );
484     if ( father->_is_nil() )
485       return aMeshSO._retn();
486
487     // Find correct free tag
488     long aTag = findMaxChildTag( father.in() );
489     if ( aTag <= GetAlgorithmsRootTag() )
490       aTag = GetAlgorithmsRootTag() + 1;
491     else
492       aTag++;
493
494     aMeshSO = publish (theStudy, theMesh, father, aTag, "ICON_SMESH_TREE_MESH" );
495     if ( aMeshSO->_is_nil() )
496       return aMeshSO._retn();
497   }
498   SetName( aMeshSO, theName, "Mesh" );
499
500   // Add shape reference
501
502   GEOM::GEOM_Object_var aShapeObject = theMesh->GetShapeToMesh();
503   if ( !CORBA::is_nil( aShapeObject )) {
504     addReference( theStudy, aMeshSO, aShapeObject, GetRefOnShapeTag() );
505
506     // Publish global hypotheses
507
508     SMESH::ListOfHypothesis * hypList = theMesh->GetHypothesisList( aShapeObject );
509     if ( hypList )
510       for ( int i = 0; i < hypList->length(); i++ ) {
511         SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( (*hypList)[ i ]);
512         PublishHypothesis( theStudy, aHyp );
513         AddHypothesisToShape( theStudy, theMesh, aShapeObject, aHyp );
514       }
515   }
516
517   // Publish submeshes
518
519   SMESH_Mesh_i* mesh_i = objectToServant<SMESH_Mesh_i>( theMesh );
520   if ( !mesh_i )
521     return aMeshSO._retn();
522   map<int, SMESH_subMesh_i*>& subMap = mesh_i->_mapSubMesh_i;
523   map<int, SMESH_subMesh_i*>::iterator subIt = subMap.begin();
524   for ( ; subIt != subMap.end(); subIt++ ) {
525     SMESH::SMESH_subMesh_ptr aSubMesh = (*subIt).second->_this();
526     if ( !CORBA::is_nil( aSubMesh )) {
527       aShapeObject = aSubMesh->GetSubShape();
528       PublishSubMesh( theStudy, theMesh, aSubMesh, aShapeObject );
529     }
530   }
531
532   // Publish groups
533   const map<int, SMESH::SMESH_GroupBase_ptr>& grMap = mesh_i->getGroups();
534   map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = grMap.begin();
535   for ( ; it != grMap.end(); it++ )
536   {
537     SMESH::SMESH_GroupBase_ptr aGroup = (*it).second;
538     if ( !aGroup->_is_nil() ) {
539       GEOM::GEOM_Object_var  aShapeObj;
540       SMESH::SMESH_GroupOnGeom_var aGeomGroup =
541         SMESH::SMESH_GroupOnGeom::_narrow( aGroup );
542       if ( !aGeomGroup->_is_nil() )
543         aShapeObj = aGeomGroup->GetShape();
544       PublishGroup( theStudy, theMesh, aGroup, aShapeObj );
545     }
546   }
547
548   if(MYDEBUG) MESSAGE("PublishMesh_END");
549   return aMeshSO._retn();
550 }
551
552 //=======================================================================
553 //function : PublishSubMesh
554 //purpose  : 
555 //=======================================================================
556
557 SALOMEDS::SObject_ptr SMESH_Gen_i::PublishSubMesh (SALOMEDS::Study_ptr      theStudy,
558                                                    SMESH::SMESH_Mesh_ptr    theMesh,
559                                                    SMESH::SMESH_subMesh_ptr theSubMesh,
560                                                    GEOM::GEOM_Object_ptr    theShapeObject,
561                                                    const char*              theName)
562 {
563   if (theStudy->_is_nil() || theMesh->_is_nil() ||
564       theSubMesh->_is_nil() || theShapeObject->_is_nil() )
565     return SALOMEDS::SObject::_nil();
566
567   SALOMEDS::SObject_var aSubMeshSO = ObjectToSObject( theStudy, theSubMesh );
568   if ( aSubMeshSO->_is_nil() )
569   {
570     SALOMEDS::SObject_var aMeshSO = ObjectToSObject( theStudy, theMesh );
571     if ( aMeshSO->_is_nil() ) {
572       aMeshSO = PublishMesh( theStudy, theMesh );
573       if ( aMeshSO->_is_nil())
574         return SALOMEDS::SObject::_nil();
575     }
576     // Find submesh sub-tree tag
577     long aRootTag;
578     char* aRootName = "";
579     switch ( theShapeObject->GetShapeType() ) {
580     case GEOM::VERTEX:
581       aRootTag  = GetSubMeshOnVertexTag();
582       aRootName = "SubMeshes on Vertex";
583       break;
584     case GEOM::EDGE:
585       aRootTag  = GetSubMeshOnEdgeTag();
586       aRootName = "SubMeshes on Edge";
587       break;
588     case GEOM::WIRE:
589       aRootTag  = GetSubMeshOnWireTag();
590       aRootName = "SubMeshes on Wire";
591       break;
592     case GEOM::FACE:
593       aRootTag  = GetSubMeshOnFaceTag();
594       aRootName = "SubMeshes on Face";    
595       break;
596     case GEOM::SHELL:
597       aRootTag  = GetSubMeshOnShellTag();
598       aRootName = "SubMeshes on Shell";   
599       break;
600     case GEOM::SOLID:
601       aRootTag  = GetSubMeshOnSolidTag();
602       aRootName = "SubMeshes on Solid";
603       break;
604     default:
605       aRootTag  = GetSubMeshOnCompoundTag();
606       aRootName = "SubMeshes on Compound";
607       break;
608     }
609
610     // Find or create submesh root
611     SALOMEDS::SObject_var aRootSO = publish (theStudy, CORBA::Object::_nil(),
612                                              aMeshSO, aRootTag, 0, false );
613     SetName( aRootSO, aRootName );
614
615     // Add new submesh to corresponding sub-tree
616     aSubMeshSO = publish (theStudy, theSubMesh, aRootSO, 0, "ICON_SMESH_TREE_MESH");
617     if ( aSubMeshSO->_is_nil() )
618       return aSubMeshSO._retn();
619   }
620   SetName( aSubMeshSO, theName, "SubMesh" );
621
622   // Add reference to theShapeObject
623
624   addReference( theStudy, aSubMeshSO, theShapeObject, 1 );
625
626   // Publish hypothesis
627
628   SMESH::ListOfHypothesis * hypList = theMesh->GetHypothesisList( theShapeObject );
629   if ( hypList )
630     for ( int i = 0; i < hypList->length(); i++ ) {
631       SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( (*hypList)[ i ]);
632       PublishHypothesis( theStudy, aHyp );
633       AddHypothesisToShape( theStudy, theMesh, theShapeObject, aHyp );
634     }
635
636   return aSubMeshSO._retn();
637 }
638
639 //=======================================================================
640 //function : PublishGroup
641 //purpose  : 
642 //=======================================================================
643
644 SALOMEDS::SObject_ptr SMESH_Gen_i::PublishGroup (SALOMEDS::Study_ptr    theStudy,
645                                                  SMESH::SMESH_Mesh_ptr  theMesh,
646                                                  SMESH::SMESH_GroupBase_ptr theGroup,
647                                                  GEOM::GEOM_Object_ptr  theShapeObject,
648                                                  const char*            theName)
649 {
650   if (theStudy->_is_nil() || theMesh->_is_nil() || theGroup->_is_nil() )
651     return SALOMEDS::SObject::_nil();
652
653   SALOMEDS::SObject_var aGroupSO = ObjectToSObject( theStudy, theGroup );
654   if ( aGroupSO->_is_nil() )
655   {
656     SALOMEDS::SObject_var aMeshSO = ObjectToSObject( theStudy, theMesh );
657     if ( aMeshSO->_is_nil() ) {
658       aMeshSO = PublishInStudy( theStudy, SALOMEDS::SObject::_nil(), theMesh, "");
659       if ( aMeshSO->_is_nil())
660         return SALOMEDS::SObject::_nil();
661     }
662     int aType = (int)theGroup->GetType();
663     const char* aRootNames[] = {
664       "Compound Groups", "Groups of Nodes",
665       "Groups of Edges", "Groups of Faces", "Groups of Volumes" };
666
667     // Currently, groups with heterogenous content are not supported
668     if ( aType != SMESH::ALL ) {
669       long aRootTag = GetNodeGroupsTag() + aType - 1;
670
671       // Find or create groups root
672       SALOMEDS::SObject_var aRootSO = publish (theStudy, CORBA::Object::_nil(),
673                                                aMeshSO, aRootTag, 0, false );
674       if ( aType < 5 )
675         SetName( aRootSO, aRootNames[aType] );
676
677       // Add new group to corresponding sub-tree
678       aGroupSO = publish (theStudy, theGroup, aRootSO, 0, "ICON_SMESH_TREE_GROUP" );
679     }
680     if ( aGroupSO->_is_nil() )
681       return aGroupSO._retn();
682   }
683
684   SetName( aGroupSO, theName, "Group" );
685
686   //Add reference to geometry
687   if ( !theShapeObject->_is_nil() )
688     addReference( theStudy, aGroupSO, theShapeObject, 1 );
689
690   return aGroupSO._retn();
691 }
692
693 //=======================================================================
694 //function : PublishHypothesis
695 //purpose  : 
696 //=======================================================================
697
698 SALOMEDS::SObject_ptr
699   SMESH_Gen_i::PublishHypothesis (SALOMEDS::Study_ptr         theStudy,
700                                   SMESH::SMESH_Hypothesis_ptr theHyp,
701                                   const char*                 theName)
702 {
703   if(MYDEBUG) MESSAGE("PublishHypothesis")
704   if (theStudy->_is_nil() || theHyp->_is_nil())
705     return SALOMEDS::SObject::_nil();
706
707   SALOMEDS::SObject_var aHypSO = ObjectToSObject( theStudy, theHyp );
708   if ( aHypSO->_is_nil() )
709   {
710     SALOMEDS::SComponent_var father = PublishComponent( theStudy );
711     if ( father->_is_nil() )
712       return aHypSO._retn();
713
714     //Find or Create Hypothesis root
715     bool isAlgo = ( !SMESH::SMESH_Algo::_narrow( theHyp )->_is_nil() );
716     int aRootTag = isAlgo ? GetAlgorithmsRootTag() : GetHypothesisRootTag();
717     SALOMEDS::SObject_var aRootSO =
718       publish (theStudy, CORBA::Object::_nil(),father, aRootTag,
719                isAlgo ? "ICON_SMESH_TREE_ALGO" : "ICON_SMESH_TREE_HYPO", false);
720     SetName( aRootSO, isAlgo ?  "Algorithms" : "Hypotheses" );
721
722     // Add New Hypothesis
723     string aPmName = isAlgo ? "ICON_SMESH_TREE_ALGO_" : "ICON_SMESH_TREE_HYPO_";
724     aPmName += theHyp->GetName();
725     aHypSO = publish( theStudy, theHyp, aRootSO, 0, aPmName.c_str() );
726   }
727
728   if ( !aHypSO->_is_nil() ) {
729     CORBA::String_var aHypName = CORBA::string_dup( theHyp->GetName() );
730     SetName( aHypSO, theName, aHypName );
731   }
732
733   if(MYDEBUG) MESSAGE("PublishHypothesis--END")
734   return aHypSO._retn();
735 }
736
737 //=======================================================================
738 //function : GetMeshOrSubmeshByShape
739 //purpose  : 
740 //=======================================================================
741
742 SALOMEDS::SObject_ptr
743   SMESH_Gen_i::GetMeshOrSubmeshByShape (SALOMEDS::Study_ptr   theStudy,
744                                         SMESH::SMESH_Mesh_ptr theMesh,
745                                         GEOM::GEOM_Object_ptr theShape)
746 {
747   if(MYDEBUG) MESSAGE("GetMeshOrSubmeshByShape")
748   SALOMEDS::SObject_var aMeshOrSubMesh;
749   if ( theShape->_is_nil() || theMesh->_is_nil() )
750     return aMeshOrSubMesh._retn();
751
752   TopoDS_Shape aShape = GeomObjectToShape( theShape );
753   SMESH_Mesh_i* mesh_i = objectToServant<SMESH_Mesh_i>( theMesh );
754
755   if ( !aShape.IsNull() && mesh_i && mesh_i->GetImpl().GetMeshDS() ) {
756     SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
757     if ( aShape.IsSame( meshDS->ShapeToMesh() ))
758       aMeshOrSubMesh = ObjectToSObject( theStudy, theMesh );
759     else {
760       int shapeID = meshDS->ShapeToIndex( aShape );
761       SMESH::SMESH_subMesh_var aSubMesh = mesh_i->getSubMesh(shapeID);
762       if ( !aSubMesh->_is_nil() )
763         aMeshOrSubMesh = ObjectToSObject( theStudy, aSubMesh );
764     }
765   }
766   if(MYDEBUG) MESSAGE("GetMeshOrSubmeshByShape--END")
767   return aMeshOrSubMesh._retn();
768 }
769
770 //=======================================================================
771 //function : AddHypothesisToShape
772 //purpose  : 
773 //=======================================================================
774
775 bool SMESH_Gen_i::AddHypothesisToShape(SALOMEDS::Study_ptr         theStudy,
776                                        SMESH::SMESH_Mesh_ptr       theMesh,
777                                        GEOM::GEOM_Object_ptr       theShape,
778                                        SMESH::SMESH_Hypothesis_ptr theHyp)
779 {
780   if(MYDEBUG) MESSAGE("AddHypothesisToShape")
781   if (theStudy->_is_nil() || theMesh->_is_nil() ||
782       theHyp->_is_nil() || theShape->_is_nil() )
783     return false;
784
785   SALOMEDS::SObject_var aMeshSO = ObjectToSObject( theStudy, theMesh );
786   if ( aMeshSO->_is_nil() )
787     aMeshSO = PublishMesh( theStudy, theMesh );
788   SALOMEDS::SObject_var aHypSO = PublishHypothesis( theStudy, theHyp );
789   if ( aMeshSO->_is_nil() || aHypSO->_is_nil())
790     return false;
791
792   // Find a mesh or submesh refering to theShape
793   SALOMEDS::SObject_var aMeshOrSubMesh =
794     GetMeshOrSubmeshByShape( theStudy, theMesh, theShape );
795   if ( aMeshOrSubMesh->_is_nil() )
796     return false;
797
798   //Find or Create Applied Hypothesis root
799   bool aIsAlgo = !SMESH::SMESH_Algo::_narrow( theHyp )->_is_nil();
800   SALOMEDS::SObject_var AHR =
801     publish (theStudy, CORBA::Object::_nil(), aMeshOrSubMesh,
802              aIsAlgo ? GetRefOnAppliedAlgorithmsTag() : GetRefOnAppliedHypothesisTag(),
803              aIsAlgo ? "ICON_SMESH_TREE_ALGO" : "ICON_SMESH_TREE_HYPO", false);
804   SetName( AHR, aIsAlgo ? "Applied algorithms" : "Applied hypotheses" );
805   if ( AHR->_is_nil() )
806     return false;
807
808   addReference( theStudy, AHR, theHyp );
809   if(MYDEBUG) MESSAGE("AddHypothesisToShape--END")
810   return true;
811 }
812
813 //=======================================================================
814 //function : RemoveHypothesisFromShape
815 //purpose  : 
816 //=======================================================================
817
818 bool SMESH_Gen_i::RemoveHypothesisFromShape(SALOMEDS::Study_ptr         theStudy,
819                                             SMESH::SMESH_Mesh_ptr       theMesh,
820                                             GEOM::GEOM_Object_ptr       theShape,
821                                             SMESH::SMESH_Hypothesis_ptr theHyp)
822 {
823   if (theStudy->_is_nil() || theMesh->_is_nil() ||
824       theHyp->_is_nil() || theShape->_is_nil() )
825     return false;
826
827   SALOMEDS::SObject_var aHypSO = ObjectToSObject( theStudy, theHyp );
828   if ( aHypSO->_is_nil() )
829     return false;
830
831   // Find a mesh or submesh refering to theShape
832   SALOMEDS::SObject_var aMeshOrSubMesh =
833     GetMeshOrSubmeshByShape( theStudy, theMesh, theShape );
834   if ( aMeshOrSubMesh->_is_nil() )
835     return false;
836
837   // Find and remove a reference to aHypSO
838   SALOMEDS::SObject_var aRef, anObj;
839   CORBA::String_var     anID = CORBA::string_dup( aHypSO->GetID() );
840   SALOMEDS::ChildIterator_var it = theStudy->NewChildIterator( aMeshOrSubMesh );
841   for ( it->InitEx( true ); it->More(); it->Next() ) {
842     anObj = it->Value();
843     if (anObj->ReferencedObject( aRef ) && strcmp( aRef->GetID(), anID ) == 0 ) {
844       theStudy->NewBuilder()->RemoveObject( anObj );
845       break;
846     }
847   }
848   return true;
849 }
850