Salome HOME
Debug
[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   // Update string attribute (to display used variables)
564   if( SMESH_Mesh_i* aServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() ) )
565     aServant->UpdateStringAttribute();
566
567   if(MYDEBUG) MESSAGE("PublishMesh_END");
568   return aMeshSO._retn();
569 }
570
571 //=======================================================================
572 //function : PublishSubMesh
573 //purpose  : 
574 //=======================================================================
575
576 SALOMEDS::SObject_ptr SMESH_Gen_i::PublishSubMesh (SALOMEDS::Study_ptr      theStudy,
577                                                    SMESH::SMESH_Mesh_ptr    theMesh,
578                                                    SMESH::SMESH_subMesh_ptr theSubMesh,
579                                                    GEOM::GEOM_Object_ptr    theShapeObject,
580                                                    const char*              theName)
581 {
582   if (theStudy->_is_nil() || theMesh->_is_nil() ||
583       theSubMesh->_is_nil() || theShapeObject->_is_nil() )
584     return SALOMEDS::SObject::_nil();
585
586   SALOMEDS::SObject_var aSubMeshSO = ObjectToSObject( theStudy, theSubMesh );
587   if ( aSubMeshSO->_is_nil() )
588   {
589     SALOMEDS::SObject_var aMeshSO = ObjectToSObject( theStudy, theMesh );
590     if ( aMeshSO->_is_nil() ) {
591       aMeshSO = PublishMesh( theStudy, theMesh );
592       if ( aMeshSO->_is_nil())
593         return SALOMEDS::SObject::_nil();
594     }
595     // Find submesh sub-tree tag
596     long aRootTag;
597     const char* aRootName = "";
598     switch ( theShapeObject->GetShapeType() ) {
599     case GEOM::VERTEX:
600       aRootTag  = GetSubMeshOnVertexTag();
601       aRootName = "SubMeshes on Vertex";
602       break;
603     case GEOM::EDGE:
604       aRootTag  = GetSubMeshOnEdgeTag();
605       aRootName = "SubMeshes on Edge";
606       break;
607     case GEOM::WIRE:
608       aRootTag  = GetSubMeshOnWireTag();
609       aRootName = "SubMeshes on Wire";
610       break;
611     case GEOM::FACE:
612       aRootTag  = GetSubMeshOnFaceTag();
613       aRootName = "SubMeshes on Face";    
614       break;
615     case GEOM::SHELL:
616       aRootTag  = GetSubMeshOnShellTag();
617       aRootName = "SubMeshes on Shell";   
618       break;
619     case GEOM::SOLID:
620       aRootTag  = GetSubMeshOnSolidTag();
621       aRootName = "SubMeshes on Solid";
622       break;
623     default:
624       aRootTag  = GetSubMeshOnCompoundTag();
625       aRootName = "SubMeshes on Compound";
626       break;
627     }
628
629     // Find or create submesh root
630     SALOMEDS::SObject_var aRootSO = publish (theStudy, CORBA::Object::_nil(),
631                                              aMeshSO, aRootTag, 0, false );
632     SetName( aRootSO, aRootName );
633
634     // Add new submesh to corresponding sub-tree
635     aSubMeshSO = publish (theStudy, theSubMesh, aRootSO, 0, "ICON_SMESH_TREE_MESH_WARN");
636     if ( aSubMeshSO->_is_nil() )
637       return aSubMeshSO._retn();
638   }
639   SetName( aSubMeshSO, theName, "SubMesh" );
640
641   // Add reference to theShapeObject
642
643   addReference( theStudy, aSubMeshSO, theShapeObject, 1 );
644
645   // Publish hypothesis
646
647   SMESH::ListOfHypothesis * hypList = theMesh->GetHypothesisList( theShapeObject );
648   if ( hypList )
649     for ( int i = 0; i < hypList->length(); i++ ) {
650       SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( (*hypList)[ i ]);
651       PublishHypothesis( theStudy, aHyp );
652       AddHypothesisToShape( theStudy, theMesh, theShapeObject, aHyp );
653     }
654
655   return aSubMeshSO._retn();
656 }
657
658 //=======================================================================
659 //function : PublishGroup
660 //purpose  : 
661 //=======================================================================
662
663 SALOMEDS::SObject_ptr SMESH_Gen_i::PublishGroup (SALOMEDS::Study_ptr    theStudy,
664                                                  SMESH::SMESH_Mesh_ptr  theMesh,
665                                                  SMESH::SMESH_GroupBase_ptr theGroup,
666                                                  GEOM::GEOM_Object_ptr  theShapeObject,
667                                                  const char*            theName)
668 {
669   if (theStudy->_is_nil() || theMesh->_is_nil() || theGroup->_is_nil() )
670     return SALOMEDS::SObject::_nil();
671
672   SALOMEDS::SObject_var aGroupSO = ObjectToSObject( theStudy, theGroup );
673   if ( aGroupSO->_is_nil() )
674   {
675     SALOMEDS::SObject_var aMeshSO = ObjectToSObject( theStudy, theMesh );
676     if ( aMeshSO->_is_nil() ) {
677       aMeshSO = PublishInStudy( theStudy, SALOMEDS::SObject::_nil(), theMesh, "");
678       if ( aMeshSO->_is_nil())
679         return SALOMEDS::SObject::_nil();
680     }
681     int aType = (int)theGroup->GetType();
682     const char* aRootNames[] = {
683       "Compound Groups", "Groups of Nodes", "Groups of Edges",
684       "Groups of Faces", "Groups of Volumes", "Groups of 0D Elements" };
685
686     // Currently, groups with heterogenous content are not supported
687     if ( aType != SMESH::ALL ) {
688       long aRootTag = GetNodeGroupsTag() + aType - 1;
689
690       // Find or create groups root
691       SALOMEDS::SObject_var aRootSO = publish (theStudy, CORBA::Object::_nil(),
692                                                aMeshSO, aRootTag, 0, false );
693       if ( aType < 6 )
694         SetName( aRootSO, aRootNames[aType] );
695
696       // Add new group to corresponding sub-tree
697       aGroupSO = publish (theStudy, theGroup, aRootSO, 0, "ICON_SMESH_TREE_GROUP" );
698     }
699     if ( aGroupSO->_is_nil() )
700       return aGroupSO._retn();
701   }
702
703   SetName( aGroupSO, theName, "Group" );
704
705   //Add reference to geometry
706   if ( !theShapeObject->_is_nil() )
707     addReference( theStudy, aGroupSO, theShapeObject, 1 );
708
709   return aGroupSO._retn();
710 }
711
712 //=======================================================================
713 //function : PublishHypothesis
714 //purpose  : 
715 //=======================================================================
716
717 SALOMEDS::SObject_ptr
718   SMESH_Gen_i::PublishHypothesis (SALOMEDS::Study_ptr         theStudy,
719                                   SMESH::SMESH_Hypothesis_ptr theHyp,
720                                   const char*                 theName)
721 {
722   if(MYDEBUG) MESSAGE("PublishHypothesis")
723   if (theStudy->_is_nil() || theHyp->_is_nil())
724     return SALOMEDS::SObject::_nil();
725
726   SALOMEDS::SObject_var aHypSO = ObjectToSObject( theStudy, theHyp );
727   if ( aHypSO->_is_nil() )
728   {
729     SALOMEDS::SComponent_var father = PublishComponent( theStudy );
730     if ( father->_is_nil() )
731       return aHypSO._retn();
732
733     //Find or Create Hypothesis root
734     bool isAlgo = ( !SMESH::SMESH_Algo::_narrow( theHyp )->_is_nil() );
735     int aRootTag = isAlgo ? GetAlgorithmsRootTag() : GetHypothesisRootTag();
736     SALOMEDS::SObject_var aRootSO =
737       publish (theStudy, CORBA::Object::_nil(),father, aRootTag,
738                isAlgo ? "ICON_SMESH_TREE_ALGO" : "ICON_SMESH_TREE_HYPO", false);
739     SetName( aRootSO, isAlgo ?  "Algorithms" : "Hypotheses" );
740
741     // Add New Hypothesis
742     string aPmName = isAlgo ? "ICON_SMESH_TREE_ALGO_" : "ICON_SMESH_TREE_HYPO_";
743     aPmName += theHyp->GetName();
744     // prepend plugin name to pixmap name
745     string pluginName = myHypCreatorMap[string(theHyp->GetName())]->GetModuleName();
746     if ( pluginName != "StdMeshers" )
747       aPmName = pluginName + "::" + aPmName;
748     aHypSO = publish( theStudy, theHyp, aRootSO, 0, aPmName.c_str() );
749   }
750
751   if ( !aHypSO->_is_nil() ) {
752     CORBA::String_var aHypName = CORBA::string_dup( theHyp->GetName() );
753     SetName( aHypSO, theName, aHypName );
754   }
755
756   // Update string attribute (to display used variables)
757   if( SMESH_Hypothesis_i* aServant = dynamic_cast<SMESH_Hypothesis_i*>( GetServant( theHyp ).in() ) )
758     aServant->UpdateStringAttribute();
759
760   if(MYDEBUG) MESSAGE("PublishHypothesis--END")
761   return aHypSO._retn();
762 }
763
764 //=======================================================================
765 //function : GetMeshOrSubmeshByShape
766 //purpose  : 
767 //=======================================================================
768
769 SALOMEDS::SObject_ptr
770   SMESH_Gen_i::GetMeshOrSubmeshByShape (SALOMEDS::Study_ptr   theStudy,
771                                         SMESH::SMESH_Mesh_ptr theMesh,
772                                         GEOM::GEOM_Object_ptr theShape)
773 {
774   if(MYDEBUG) MESSAGE("GetMeshOrSubmeshByShape")
775   SALOMEDS::SObject_var aMeshOrSubMesh;
776   if (theMesh->_is_nil() || ( theShape->_is_nil() && theMesh->HasShapeToMesh()))
777     return aMeshOrSubMesh._retn();
778   
779   TopoDS_Shape aShape;
780   if(theMesh->HasShapeToMesh())
781     aShape = GeomObjectToShape( theShape );
782   else
783     aShape = SMESH_Mesh::PseudoShape();
784
785   SMESH_Mesh_i* mesh_i = objectToServant<SMESH_Mesh_i>( theMesh );
786
787   if ( !aShape.IsNull() && mesh_i && mesh_i->GetImpl().GetMeshDS() ) {
788     SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
789     if ( aShape.IsSame( meshDS->ShapeToMesh() ))
790       aMeshOrSubMesh = ObjectToSObject( theStudy, theMesh );
791     else {
792       int shapeID = meshDS->ShapeToIndex( aShape );
793       SMESH::SMESH_subMesh_var aSubMesh = mesh_i->getSubMesh(shapeID);
794       if ( !aSubMesh->_is_nil() )
795         aMeshOrSubMesh = ObjectToSObject( theStudy, aSubMesh );
796     }
797   }
798   if(MYDEBUG) MESSAGE("GetMeshOrSubmeshByShape--END")
799   return aMeshOrSubMesh._retn();
800 }
801
802 //=======================================================================
803 //function : AddHypothesisToShape
804 //purpose  : 
805 //=======================================================================
806
807 bool SMESH_Gen_i::AddHypothesisToShape(SALOMEDS::Study_ptr         theStudy,
808                                        SMESH::SMESH_Mesh_ptr       theMesh,
809                                        GEOM::GEOM_Object_ptr       theShape,
810                                        SMESH::SMESH_Hypothesis_ptr theHyp)
811 {
812   if(MYDEBUG) MESSAGE("AddHypothesisToShape")
813   if (theStudy->_is_nil() || theMesh->_is_nil() ||
814       theHyp->_is_nil() || (theShape->_is_nil()
815                             && theMesh->HasShapeToMesh()) )
816     return false;
817
818   SALOMEDS::SObject_var aMeshSO = ObjectToSObject( theStudy, theMesh );
819   if ( aMeshSO->_is_nil() )
820     aMeshSO = PublishMesh( theStudy, theMesh );
821   SALOMEDS::SObject_var aHypSO = PublishHypothesis( theStudy, theHyp );
822   if ( aMeshSO->_is_nil() || aHypSO->_is_nil())
823     return false;
824
825   // Find a mesh or submesh refering to theShape
826   SALOMEDS::SObject_var aMeshOrSubMesh =
827     GetMeshOrSubmeshByShape( theStudy, theMesh, theShape );
828   if ( aMeshOrSubMesh->_is_nil() )
829   {
830     // publish submesh
831     TopoDS_Shape aShape = GeomObjectToShape( theShape );
832     SMESH_Mesh_i* mesh_i = objectToServant<SMESH_Mesh_i>( theMesh );
833     if ( !aShape.IsNull() && mesh_i && mesh_i->GetImpl().GetMeshDS() ) {
834       SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
835       int shapeID = meshDS->ShapeToIndex( aShape );
836       SMESH::SMESH_subMesh_var aSubMesh = mesh_i->getSubMesh(shapeID);
837       aMeshOrSubMesh = PublishSubMesh( theStudy, theMesh, aSubMesh, theShape );
838     }
839     if ( aMeshOrSubMesh->_is_nil() )
840       return false;
841   }
842
843   //Find or Create Applied Hypothesis root
844   bool aIsAlgo = !SMESH::SMESH_Algo::_narrow( theHyp )->_is_nil();
845   SALOMEDS::SObject_var AHR =
846     publish (theStudy, CORBA::Object::_nil(), aMeshOrSubMesh,
847              aIsAlgo ? GetRefOnAppliedAlgorithmsTag() : GetRefOnAppliedHypothesisTag(),
848              aIsAlgo ? "ICON_SMESH_TREE_ALGO" : "ICON_SMESH_TREE_HYPO", false);
849   SetName( AHR, aIsAlgo ? "Applied algorithms" : "Applied hypotheses" );
850   if ( AHR->_is_nil() )
851     return false;
852
853   addReference( theStudy, AHR, theHyp );
854   if(MYDEBUG) MESSAGE("AddHypothesisToShape--END")
855   return true;
856 }
857
858 //=======================================================================
859 //function : RemoveHypothesisFromShape
860 //purpose  : 
861 //=======================================================================
862
863 bool SMESH_Gen_i::RemoveHypothesisFromShape(SALOMEDS::Study_ptr         theStudy,
864                                             SMESH::SMESH_Mesh_ptr       theMesh,
865                                             GEOM::GEOM_Object_ptr       theShape,
866                                             SMESH::SMESH_Hypothesis_ptr theHyp)
867 {
868   if (theStudy->_is_nil() || theMesh->_is_nil() ||
869       theHyp->_is_nil() || (theShape->_is_nil()
870                             && theMesh->HasShapeToMesh()))
871     return false;
872
873   SALOMEDS::SObject_var aHypSO = ObjectToSObject( theStudy, theHyp );
874   if ( aHypSO->_is_nil() )
875     return false;
876
877   // Find a mesh or submesh refering to theShape
878   SALOMEDS::SObject_var aMeshOrSubMesh =
879     GetMeshOrSubmeshByShape( theStudy, theMesh, theShape );
880   if ( aMeshOrSubMesh->_is_nil() )
881     return false;
882
883   // Find and remove a reference to aHypSO
884   SALOMEDS::SObject_var aRef, anObj;
885   CORBA::String_var     anID = CORBA::string_dup( aHypSO->GetID() );
886   SALOMEDS::ChildIterator_var it = theStudy->NewChildIterator( aMeshOrSubMesh );
887   for ( it->InitEx( true ); it->More(); it->Next() ) {
888     anObj = it->Value();
889     if (anObj->ReferencedObject( aRef ) && strcmp( aRef->GetID(), anID ) == 0 ) {
890       theStudy->NewBuilder()->RemoveObject( anObj );
891       break;
892     }
893   }
894   return true;
895 }