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