Salome HOME
Update of CheckDone
[modules/smesh.git] / src / SMESH_I / SMESH_Gen_i_1.cxx
1 // Copyright (C) 2007-2024  CEA, EDF, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //  File      : SMESH_Gen_i_1.cxx
23 //  Created   : Thu Oct 21 17:24:06 2004
24 //  Author    : Edward AGAPOV (eap)
25 //  Module    : SMESH
26
27 #include "SMESH_Gen_i.hxx"
28
29 #include "SMESHDS_Mesh.hxx"
30 #include "SMESH_Algo_i.hxx"
31 #include "SMESH_Comment.hxx"
32 #include "SMESH_Group_i.hxx"
33 #include "SMESH_Hypothesis_i.hxx"
34 #include "SMESH_Mesh_i.hxx"
35 #include "SMESH_subMesh_i.hxx"
36
37 #include <utilities.h>
38 #include <Utils_ExceptHandlers.hxx>
39 #include <SALOMEDS_wrap.hxx>
40 #include <SALOMEDS_Attributes_wrap.hxx>
41 #include "SALOME_KernelServices.hxx"
42 #include "SALOME_ModuleCatalog_impl.hxx"
43
44 #include <TCollection_AsciiString.hxx>
45 #include <TopoDS_Solid.hxx>
46
47 #include <cctype>
48
49 using namespace std;
50
51 //=============================================================================
52 /*!
53  *  Get...Tag [ static ]
54  *
55  *  Methods which determine SMESH data model structure
56  */
57 //=============================================================================
58
59 long SMESH_Gen_i::GetHypothesisRootTag()
60 {
61   return SMESH::Tag_HypothesisRoot;
62 }
63
64 long SMESH_Gen_i::GetAlgorithmsRootTag()
65 {
66   return SMESH::Tag_AlgorithmsRoot;
67 }
68
69 long SMESH_Gen_i::GetRefOnShapeTag()
70 {
71   return SMESH::Tag_RefOnShape;
72 }
73
74 long SMESH_Gen_i::GetRefOnAppliedHypothesisTag()
75 {
76   return SMESH::Tag_RefOnAppliedHypothesis;
77 }
78
79 long SMESH_Gen_i::GetRefOnAppliedAlgorithmsTag()
80 {
81   return SMESH::Tag_RefOnAppliedAlgorithms;
82 }
83
84 long SMESH_Gen_i::GetSubMeshOnVertexTag()
85 {
86   return SMESH::Tag_SubMeshOnVertex;
87 }
88
89 long SMESH_Gen_i::GetSubMeshOnEdgeTag()
90 {
91   return SMESH::Tag_SubMeshOnEdge;
92 }
93
94 long SMESH_Gen_i::GetSubMeshOnFaceTag()
95 {
96   return SMESH::Tag_SubMeshOnFace;
97 }
98
99 long SMESH_Gen_i::GetSubMeshOnSolidTag()
100 {
101   return SMESH::Tag_SubMeshOnSolid;
102 }
103
104 long SMESH_Gen_i::GetSubMeshOnCompoundTag()
105 {
106   return SMESH::Tag_SubMeshOnCompound;
107 }
108
109 long SMESH_Gen_i::GetSubMeshOnWireTag()
110 {
111   return SMESH::Tag_SubMeshOnWire;
112 }
113
114 long SMESH_Gen_i::GetSubMeshOnShellTag()
115 {
116   return SMESH::Tag_SubMeshOnShell;
117 }
118
119 long SMESH_Gen_i::GetNodeGroupsTag()
120 {
121   return SMESH::Tag_NodeGroups;
122 }
123
124 long SMESH_Gen_i::GetEdgeGroupsTag()
125 {
126   return SMESH::Tag_EdgeGroups;
127 }
128
129 long SMESH_Gen_i::GetFaceGroupsTag()
130 {
131   return SMESH::Tag_FaceGroups;
132 }
133
134 long SMESH_Gen_i::GetVolumeGroupsTag()
135 {
136   return SMESH::Tag_VolumeGroups;
137 }
138
139 long SMESH_Gen_i::Get0DElementsGroupsTag()
140 {
141   return SMESH::Tag_0DElementsGroups;
142 }
143
144 long SMESH_Gen_i::GetBallElementsGroupsTag()
145 {
146   return SMESH::Tag_BallElementsGroups;
147 }
148
149 //=============================================================================
150 /*!
151  *  SMESH_Gen_i::CanPublishInStudy
152  *
153  *  Returns true if object can be published in the study
154  */
155 //=============================================================================
156
157 bool SMESH_Gen_i::CanPublishInStudy(CORBA::Object_ptr theIOR)
158 {
159   MESSAGE("CanPublishInStudy - "<<!CORBA::is_nil(getStudyServant()));
160   
161   if ( !myIsEnablePublish )
162     return false;
163
164   SMESH::SMESH_Mesh_var aMesh       = SMESH::SMESH_Mesh::_narrow(theIOR);
165   if( !aMesh->_is_nil() )
166     return true;
167
168   SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow(theIOR);
169   if( !aSubMesh->_is_nil() )
170     return true;
171
172   SMESH::SMESH_Hypothesis_var aHyp  = SMESH::SMESH_Hypothesis::_narrow(theIOR);
173   if( !aHyp->_is_nil() )
174     return true;
175
176   SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(theIOR);
177   if( !aGroup->_is_nil() )
178     return true;
179
180   MESSAGE("CanPublishInStudy--CANT");
181   return false;
182 }
183
184 //=======================================================================
185 //function : ObjectToSObject
186 //purpose  : Put a result into a SALOMEDS::SObject_wrap or call UnRegister()!
187 //=======================================================================
188
189 SALOMEDS::SObject_ptr SMESH_Gen_i::ObjectToSObject(CORBA::Object_ptr theObject)
190 {
191   SALOMEDS::SObject_wrap aSO;
192   try {
193     if ( !CORBA::is_nil( theObject ))
194     {
195       CORBA::String_var objStr = SMESH_Gen_i::GetORB()->object_to_string( theObject );
196       aSO = getStudyServant()->FindObjectIOR( objStr.in() );
197     }
198   }
199   catch (...)
200   {
201   }
202   return aSO._retn();
203 }
204
205 //=======================================================================
206 //function : objectToServant
207 //purpose  : 
208 //=======================================================================
209
210 template<typename T> static inline T* objectToServant( CORBA::Object_ptr theIOR )
211 {
212   return dynamic_cast<T*>( SMESH_Gen_i::GetServant( theIOR ).in() );
213 }
214
215 //=======================================================================
216 //function : ShapeToGeomObject
217 //purpose  : 
218 //=======================================================================
219
220 GEOM::GEOM_Object_ptr SMESH_Gen_i::ShapeToGeomObject (const TopoDS_Shape& theShape )
221 {
222   GEOM::GEOM_Object_var aShapeObj;
223   if ( !theShape.IsNull() && mySMESHGen ) {
224     GEOM_Client* aClient = mySMESHGen->GetShapeReader();
225     TCollection_AsciiString IOR;
226     if ( aClient && aClient->Find( theShape, IOR ))
227     {
228       CORBA::Object_var obj = GetORB()->string_to_object( IOR.ToCString() );
229       if ( !obj->_non_existent() )
230         aShapeObj = GEOM::GEOM_Object::_narrow ( obj );
231     }
232   }
233   return aShapeObj._retn();
234 }
235
236 //=======================================================================
237 //function : GeomObjectToShape
238 //purpose  : 
239 //=======================================================================
240
241 TopoDS_Shape SMESH_Gen_i::GeomObjectToShape(GEOM::GEOM_Object_ptr theGeomObject)
242 {
243   TopoDS_Shape S;
244   if ( mySMESHGen && !theGeomObject->_is_nil() && !theGeomObject->_non_existent() )
245   {
246     GEOM_Client*           aClient = mySMESHGen->GetShapeReader();
247     GEOM::GEOM_Gen_var aGeomEngine = GetGeomEngine( theGeomObject );
248     if ( aClient && !aGeomEngine->_is_nil () )
249       S = aClient->GetShape( aGeomEngine, theGeomObject );
250   }
251   return S;
252 }
253
254 //================================================================================
255 /*!
256  * \brief Get GEOM Object by its study entry
257  */
258 //================================================================================
259
260 GEOM::GEOM_Object_ptr SMESH_Gen_i::GetGeomObjectByEntry( const std::string& entry )
261 {
262   GEOM::GEOM_Object_var go;
263   if ( !entry.empty() && mySMESHGen )
264   {
265     SALOMEDS::SObject_wrap so = mySMESHGen->getStudyServant()->FindObjectID( entry.c_str() );
266     CORBA::Object_var     obj = SObjectToObject( so );
267     go = GEOM::GEOM_Object::_narrow( obj );
268   }
269   return go._retn();
270 }
271
272
273 //=======================================================================
274 //function : publish
275 //purpose  :
276 //=======================================================================
277
278 SALOMEDS::SObject_ptr SMESH_Gen_i::publish(CORBA::Object_ptr     theIOR,
279                                            SALOMEDS::SObject_ptr theFatherObject,
280                                            const int             theTag,
281                                            const char*           thePixMap,
282                                            const bool            theSelectable)
283 {
284   SALOMEDS::Study_var theStudy = getStudyServant();
285   SALOMEDS::SObject_wrap SO = ObjectToSObject( theIOR );
286   SALOMEDS::StudyBuilder_var     aStudyBuilder = theStudy->NewBuilder();
287   SALOMEDS::UseCaseBuilder_wrap useCaseBuilder = theStudy->GetUseCaseBuilder();
288   bool isNewSO = false, isInUseCaseTree = false;
289   if ( SO->_is_nil() )
290   {
291     if ( theTag == 0 ) {
292       SO = aStudyBuilder->NewObject( theFatherObject );
293       isNewSO = true;
294     }
295     else if ( !theFatherObject->FindSubObject( theTag, SO.inout() ))
296     {
297       SO = aStudyBuilder->NewObjectToTag( theFatherObject, theTag );
298       isNewSO = true;
299     }
300     else
301     {
302       isInUseCaseTree = useCaseBuilder->IsUseCaseNode( SO );
303     }
304   }
305   else
306   {
307     isInUseCaseTree = useCaseBuilder->IsUseCaseNode( SO );
308   }
309
310   SALOMEDS::GenericAttribute_wrap anAttr;
311   if ( !CORBA::is_nil( theIOR ))
312   {
313     anAttr = aStudyBuilder->FindOrCreateAttribute( SO, "AttributeIOR" );
314     CORBA::String_var objStr = SMESH_Gen_i::GetORB()->object_to_string( theIOR );
315     SALOMEDS::AttributeIOR_wrap iorAttr = anAttr;
316     CORBA::String_var objStrCur = iorAttr->Value();
317     bool sameIOR = ( objStrCur.in() && strcmp( objStr.in(), objStrCur.in() ) == 0 );
318     if ( !sameIOR )
319     {
320       iorAttr->SetValue( objStr.in() );
321       // UnRegister() !!! --> random problems when meshing in parallel (yacs foreach) in
322       // distributed python scripts, because simultaneously created meshes are
323       // published into the same SO; as a result the mesh published first dies
324       SALOME::GenericObj_var genObj = SALOME::GenericObj::_narrow( theIOR );
325       if ( !genObj->_is_nil() )
326         genObj->UnRegister();
327     }
328   }
329
330   if ( thePixMap ) {
331     anAttr  = aStudyBuilder->FindOrCreateAttribute( SO, "AttributePixMap" );
332     SALOMEDS::AttributePixMap_wrap pm = anAttr;
333     pm->SetPixMap( thePixMap );
334   }
335
336   if ( !theSelectable ) {
337     anAttr = aStudyBuilder->FindOrCreateAttribute( SO, "AttributeSelectable" );
338     SALOMEDS::AttributeSelectable_wrap selAttr = anAttr;
339     selAttr->SetSelectable( false );
340   }
341
342   if ( !isNewSO )
343     aStudyBuilder->RemoveReference( SO );// remove garbage reference (23336)
344
345   // add object to the use case tree
346   // (to support tree representation customization and drag-n-drop)
347   if ( isNewSO || !isInUseCaseTree )
348   {
349     // define the next tag after given one in the data tree to insert SObject
350     SALOMEDS::SObject_wrap curObj, objAfter;
351     if ( theFatherObject->GetLastChildTag() > theTag && theTag > 0 )
352     {
353       SALOMEDS::UseCaseIterator_wrap
354         anUseCaseIter = useCaseBuilder->GetUseCaseIterator(theFatherObject);
355       for ( ; anUseCaseIter->More(); anUseCaseIter->Next() ) {
356         curObj = anUseCaseIter->Value();
357         if ( curObj->Tag() > theTag  ) {
358           objAfter = curObj;
359           break;
360         }
361       }
362     }
363     if ( !CORBA::is_nil( objAfter ))
364       useCaseBuilder->InsertBefore( SO, objAfter );    // insert at given tag
365     else if ( !isInUseCaseTree )
366       useCaseBuilder->AppendTo( theFatherObject, SO ); // append to the end of list
367   }
368   return SO._retn();
369 }
370
371 //=======================================================================
372 //function : setName
373 //purpose  :
374 //=======================================================================
375
376 void SMESH_Gen_i::SetName(SALOMEDS::SObject_ptr theSObject,
377                           const char*           theName,
378                           const char*           theDefaultName)
379 {
380   if ( !theSObject->_is_nil() ) {
381     SALOMEDS::StudyBuilder_var aStudyBuilder = getStudyServant()->NewBuilder();
382     SALOMEDS::GenericAttribute_wrap   anAttr =
383       aStudyBuilder->FindOrCreateAttribute( theSObject, "AttributeName" );
384     SALOMEDS::AttributeName_wrap aNameAttr = anAttr;
385     if ( theName && theName[0] ) {
386       std::string name( theName ); // trim trailing white spaces
387       for ( size_t i = name.size()-1; i > 0; --i )
388         if ( isspace( name[i] )) name[i] = '\0';
389         else                     break;
390       aNameAttr->SetValue( name.c_str() );
391     }
392     else
393     {
394       CORBA::String_var curName = aNameAttr->Value();
395       if ( strlen( curName.in() ) == 0 ) {
396         SMESH_Comment aName(theDefaultName);
397         aNameAttr->SetValue( ( aName<< "_" << theSObject->Tag()).c_str() );
398       }
399     }
400   }
401 }
402
403 //=======================================================================
404 //function : SetPixMap
405 //purpose  :
406 //=======================================================================
407
408 void SMESH_Gen_i::SetPixMap(SALOMEDS::SObject_ptr theSObject,
409                             const char*           thePixMap)
410 {
411   if ( !theSObject->_is_nil() && thePixMap && thePixMap && thePixMap[0] )
412   {
413     SALOMEDS::StudyBuilder_var aStudyBuilder = getStudyServant()->NewBuilder();
414     SALOMEDS::GenericAttribute_wrap anAttr =
415       aStudyBuilder->FindOrCreateAttribute( theSObject, "AttributePixMap" );
416     SALOMEDS::AttributePixMap_wrap aPMAttr = anAttr;
417     aPMAttr->SetPixMap( thePixMap );
418   }
419 }
420
421 //=======================================================================
422 //function : addReference
423 //purpose  : 
424 //=======================================================================
425
426 void SMESH_Gen_i::addReference (SALOMEDS::SObject_ptr theSObject, CORBA::Object_ptr theToObject, int theTag)
427 {
428   SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
429   SALOMEDS::SObject_wrap aToObjSO = SMESH_Gen_i::ObjectToSObject( theToObject );
430   if ( !aToObjSO->_is_nil() && !theSObject->_is_nil() ) {
431     SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
432     SALOMEDS::SObject_wrap aReferenceSO;
433     if ( !theTag ) {
434       // check if the reference to theToObject already exists
435       // and find a free label for the reference object
436       bool isReferred = false;
437       int tag = 1;
438       SALOMEDS::ChildIterator_wrap anIter = aStudy->NewChildIterator( theSObject );
439       for ( ; !isReferred && anIter->More(); anIter->Next(), ++tag ) {
440         SALOMEDS::SObject_wrap curSO = anIter->Value();
441         if ( curSO->ReferencedObject( aReferenceSO.inout() )) {
442           CORBA::String_var refEntry = aReferenceSO->GetID();
443           CORBA::String_var  toEntry = aToObjSO->GetID();
444           if ( strcmp( refEntry, toEntry ) == 0 )
445             isReferred = true;
446         }
447         else if ( !theTag ) {
448           SALOMEDS::GenericAttribute_wrap anAttr;
449           if ( !curSO->FindAttribute( anAttr.inout(), "AttributeIOR" ))
450             theTag = tag;
451         }
452       }
453       if ( isReferred )
454         return;
455       if ( !theTag )
456         theTag = tag;
457     }
458     if ( !theSObject->FindSubObject( theTag, aReferenceSO.inout() ))
459       aReferenceSO = aStudyBuilder->NewObjectToTag( theSObject, theTag );
460
461     aStudyBuilder->Addreference( aReferenceSO, aToObjSO );
462
463     // make the reference visible (invisible ref is created by createInvalidSubMesh())
464     aStudyBuilder->RemoveAttribute( aReferenceSO, "AttributeDrawable" );
465
466     // add reference to the use case tree
467     // (to support tree representation customization and drag-n-drop)
468     SALOMEDS::UseCaseBuilder_wrap  useCaseBuilder = aStudy->GetUseCaseBuilder();
469     SALOMEDS::UseCaseIterator_wrap    useCaseIter = useCaseBuilder->GetUseCaseIterator(theSObject);
470     for ( ; useCaseIter->More(); useCaseIter->Next() )
471     {
472       SALOMEDS::SObject_wrap curSO = useCaseIter->Value();
473       if ( curSO->Tag() == theTag )
474         return;
475     }
476     useCaseBuilder->AppendTo( theSObject, aReferenceSO );
477   }
478 }
479
480 //=============================================================================
481 /*!
482  *  SMESH_Gen_i::PublishInStudy
483  *
484  *  Publish object in the study
485  */
486 //=============================================================================
487
488 SALOMEDS::SObject_ptr SMESH_Gen_i::PublishInStudy(SALOMEDS::SObject_ptr /*theSObject*/,
489                                                   CORBA::Object_ptr     theIOR,
490                                                   const char*           theName)
491 {
492   Unexpect aCatch(SALOME_SalomeException);
493   SALOMEDS::SObject_wrap aSO;
494   if ( !myIsEnablePublish )
495     return aSO._retn();
496   if ( CORBA::is_nil( theIOR ))
497     return aSO._retn();
498   MESSAGE("PublishInStudy");
499
500   // Publishing a mesh
501   SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( theIOR );
502   if( !aMesh->_is_nil() )
503     aSO = PublishMesh( aMesh, theName );
504
505   // Publishing a sub-mesh
506   SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( theIOR );
507   if( aSO->_is_nil() && !aSubMesh->_is_nil() ) {
508     GEOM::GEOM_Object_var aShapeObject = aSubMesh->GetSubShape();
509     aMesh = aSubMesh->GetFather();
510     aSO = PublishSubMesh( aMesh, aSubMesh, aShapeObject, theName );
511   }
512
513   // Publishing a hypothesis or algorithm
514   SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( theIOR );
515   if ( aSO->_is_nil() && !aHyp->_is_nil() )
516     aSO = PublishHypothesis( aHyp, theName );
517
518   // Publishing a group
519   SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(theIOR);
520   if ( aSO->_is_nil() && !aGroup->_is_nil() ) {
521     GEOM::GEOM_Object_var aShapeObject;
522     aMesh = aGroup->GetMesh();
523     aSO = PublishGroup( aMesh, aGroup, aShapeObject, theName );
524   }
525   MESSAGE("PublishInStudy_END");
526
527   return aSO._retn();
528 }
529
530 //=======================================================================
531 //function : PublishComponent
532 //purpose  :
533 //=======================================================================
534
535 SALOMEDS::SComponent_ptr SMESH_Gen_i::PublishComponent()
536 {
537   MESSAGE("PublishComponent");
538   if ( !myIsEnablePublish )
539     return SALOMEDS::SComponent::_nil();
540
541   SALOMEDS::StudyBuilder_var    aStudyBuilder  = getStudyServant()->NewBuilder();
542   SALOMEDS::UseCaseBuilder_wrap useCaseBuilder = getStudyServant()->GetUseCaseBuilder();
543
544   CORBA::String_var compDataType = ComponentDataType(); // SMESH module's data type
545   std::string ior;
546   {
547     CORBA::String_var iorString = GetORB()->object_to_string( SMESH_Gen::_this() );
548     ior = std::string( iorString.in() ); // IOR of this SMESH engine
549   }
550   // Find study component which corresponds to this SMESH engine
551
552   SALOMEDS::SComponent_wrap father;
553   SALOMEDS::SComponentIterator_wrap citer = getStudyServant()->NewComponentIterator();
554   for ( ; citer->More(); citer->Next()) {
555     SALOMEDS::SComponent_wrap f_i = citer->Value();
556     CORBA::String_var ior_i;
557     bool ok = f_i->ComponentIOR(ior_i.out());
558     CORBA::String_var cdt(f_i->ComponentDataType());
559     if ( ok && strcmp( compDataType.in(), cdt.in() ) == 0 && ior == ior_i.in())
560     {
561       father = f_i;
562       break;
563     }
564   }
565
566   if ( !CORBA::is_nil( father ) ) {
567     // check that the component is added to the use case browser
568     if ( !useCaseBuilder->IsUseCaseNode( father ) ) {
569       useCaseBuilder->SetRootCurrent();
570       useCaseBuilder->Append( father ); // component object is added as the top level item
571     }
572     return father._retn();
573   }
574
575   // If component for this SMESH engine does not exist in the study, create it
576
577   SALOME_ModuleCatalog::ModuleCatalog_var aCat = this->getModuleCatalog();
578   if ( CORBA::is_nil( aCat ) )
579     return father._retn();
580
581   SALOME_ModuleCatalog::Acomponent_var aComp = aCat->GetComponent( compDataType.in() );
582   if ( CORBA::is_nil( aComp ) )
583     return father._retn();
584
585   SALOMEDS::GenericAttribute_wrap anAttr;
586   SALOMEDS::AttributePixMap_wrap  aPixmap;
587
588   father  = aStudyBuilder->NewComponent( compDataType.in() );
589   aStudyBuilder->DefineComponentInstance( father, SMESH_Gen::_this() );
590   anAttr  = aStudyBuilder->FindOrCreateAttribute( father, "AttributePixMap" );
591   aPixmap = anAttr;
592   aPixmap->SetPixMap( "ICON_OBJBROWSER_SMESH" );
593   CORBA::String_var userName = aComp->componentusername();
594   SetName( father, userName.in(), "MESH" );
595   // add component to the use case tree
596   // (to support tree representation customization and drag-n-drop)
597   useCaseBuilder->SetRootCurrent();
598   useCaseBuilder->Append( father ); // component object is added as the top level item
599   MESSAGE("PublishComponent--END");
600
601   return father._retn();
602 }
603
604 //=======================================================================
605 //function : PublishMesh
606 //purpose  : 
607 //=======================================================================
608
609 SALOMEDS::SObject_ptr SMESH_Gen_i::PublishMesh (SMESH::SMESH_Mesh_ptr theMesh,
610                                                 const char*           theName)
611 {
612   if ( !myIsEnablePublish )
613     return SALOMEDS::SObject::_nil();
614   if ( CORBA::is_nil( theMesh ))
615     return SALOMEDS::SObject::_nil();
616   MESSAGE("PublishMesh--IN");
617
618   // find or publish a mesh
619
620   SALOMEDS::SObject_wrap aMeshSO = ObjectToSObject( theMesh );
621   if ( aMeshSO->_is_nil() )
622   {
623     SALOMEDS::SComponent_wrap father = PublishComponent();
624     if ( father->_is_nil() )
625       return aMeshSO._retn();
626
627     // Find correct free tag
628     long aTag = father->GetLastChildTag();
629     if ( aTag <= GetAlgorithmsRootTag() )
630       aTag = GetAlgorithmsRootTag() + 1;
631     else
632       aTag++;
633
634     aMeshSO = publish( theMesh, father, aTag, "ICON_SMESH_TREE_MESH_WARN" );
635     if ( aMeshSO->_is_nil() )
636       return aMeshSO._retn();
637   }
638   SetName( aMeshSO, theName, "Mesh" );
639
640   // Add shape reference
641
642   GEOM::GEOM_Object_var aShapeObject = theMesh->GetShapeToMesh();
643   if ( !CORBA::is_nil( aShapeObject )) {
644     addReference( aMeshSO, aShapeObject, GetRefOnShapeTag() );
645
646     // Publish global hypotheses
647
648     SMESH::ListOfHypothesis_var hypList = theMesh->GetHypothesisList( aShapeObject );
649     for ( CORBA::ULong i = 0; i < hypList->length(); i++ )
650     {
651       SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( hypList[ i ]);
652       SALOMEDS::SObject_wrap so = PublishHypothesis( aHyp );
653       AddHypothesisToShape( theMesh, aShapeObject, aHyp );
654     }
655   }
656
657   // Publish submeshes
658
659   SMESH_Mesh_i* mesh_i = objectToServant<SMESH_Mesh_i>( theMesh );
660   if ( !mesh_i )
661     return aMeshSO._retn();
662   map<int, SMESH_subMesh_i*>& subMap = mesh_i->_mapSubMesh_i;
663   map<int, SMESH_subMesh_i*>::iterator subIt = subMap.begin();
664   for ( ; subIt != subMap.end(); subIt++ ) {
665     SMESH::SMESH_subMesh_ptr aSubMesh = (*subIt).second->_this();
666     if ( !CORBA::is_nil( aSubMesh )) {
667       aShapeObject = aSubMesh->GetSubShape();
668       SALOMEDS::SObject_wrap( PublishSubMesh( theMesh, aSubMesh, aShapeObject ));
669     }
670   }
671
672   // Publish groups
673   const map<int, SMESH::SMESH_GroupBase_ptr>& grMap = mesh_i->getGroups();
674   map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = grMap.begin();
675   for ( ; it != grMap.end(); it++ )
676   {
677     SMESH::SMESH_GroupBase_ptr aGroup = (*it).second;
678     if ( !aGroup->_is_nil() ) {
679       GEOM::GEOM_Object_var aShapeObj;
680       SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup );
681       if ( !aGeomGroup->_is_nil() )
682         aShapeObj = aGeomGroup->GetShape();
683       SALOMEDS::SObject_wrap( PublishGroup( theMesh, aGroup, aShapeObj ));
684     }
685   }
686
687   MESSAGE("PublishMesh_END");
688   return aMeshSO._retn();
689 }
690
691 //=======================================================================
692 //function : PublishSubMesh
693 //purpose  : 
694 //=======================================================================
695
696 SALOMEDS::SObject_ptr SMESH_Gen_i::PublishSubMesh (SMESH::SMESH_Mesh_ptr    theMesh,
697                                                    SMESH::SMESH_subMesh_ptr theSubMesh,
698                                                    GEOM::GEOM_Object_ptr    theShapeObject,
699                                                    const char*              theName)
700 {
701   if ( !myIsEnablePublish )
702     return SALOMEDS::SObject::_nil();
703   if ( theMesh->_is_nil() || theSubMesh->_is_nil() || theShapeObject->_is_nil() )
704     return SALOMEDS::SObject::_nil();
705
706   std::string newName( theName ? theName : "" );
707
708   SALOMEDS::SObject_wrap aSubMeshSO = ObjectToSObject( theSubMesh );
709   if ( aSubMeshSO->_is_nil() )
710   {
711     SALOMEDS::SObject_wrap aMeshSO = ObjectToSObject( theMesh );
712     if ( aMeshSO->_is_nil() ) {
713       aMeshSO = PublishMesh( theMesh );
714       if ( aMeshSO->_is_nil())
715         return SALOMEDS::SObject::_nil();
716     }
717     // Find submesh sub-tree tag
718     long aRootTag;
719     const char* aRootName = "";
720     switch ( theShapeObject->GetShapeType() ) {
721     case GEOM::VERTEX:
722       aRootTag  = GetSubMeshOnVertexTag();
723       aRootName = "SubMeshes on Vertex";
724       break;
725     case GEOM::EDGE:
726       aRootTag  = GetSubMeshOnEdgeTag();
727       aRootName = "SubMeshes on Edge";
728       break;
729     case GEOM::WIRE:
730       aRootTag  = GetSubMeshOnWireTag();
731       aRootName = "SubMeshes on Wire";
732       break;
733     case GEOM::FACE:
734       aRootTag  = GetSubMeshOnFaceTag();
735       aRootName = "SubMeshes on Face";    
736       break;
737     case GEOM::SHELL:
738       aRootTag  = GetSubMeshOnShellTag();
739       aRootName = "SubMeshes on Shell";   
740       break;
741     case GEOM::SOLID:
742       aRootTag  = GetSubMeshOnSolidTag();
743       aRootName = "SubMeshes on Solid";
744       break;
745     default:
746       aRootTag  = GetSubMeshOnCompoundTag();
747       aRootName = "SubMeshes on Compound";
748       break;
749     }
750
751     // Find or create submesh root
752     SALOMEDS::SObject_wrap aRootSO = publish ( CORBA::Object::_nil(),
753                                                aMeshSO, aRootTag, 0, false );
754     if ( aRootSO->_is_nil() )
755       return aSubMeshSO._retn();
756
757     SetName( aRootSO, aRootName );
758
759     // Add new sub-mesh to corresponding sub-tree
760     int tag = 0; // to use a new SObject
761     if ( theName && theName[0] == '0' )
762     {
763       // theName can be an entry of an invalid sub-mesh which theSubMesh should replace
764       SALOMEDS::SObject_wrap aSObj = getStudyServant()->FindObjectID( theName );
765       if ( aSObj )
766       {
767         CORBA::String_var oldName = aSObj->GetName();
768         newName = oldName.in();
769         SALOMEDS::SObject_wrap aRootSO2 = aSObj->GetFather();
770         if ( aRootSO->Tag() == aRootSO2->Tag() ) // same parent
771           tag = aSObj->Tag(); // to use the same SObject
772         else
773         {
774           CORBA::Object_var anObj = SObjectToObject( aSObj );
775           SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( anObj );
776           theMesh->RemoveSubMesh( sm );
777         }
778       }
779     }
780     SMESH::array_of_ElementType_var elemTypes = theSubMesh->GetTypes();
781     const int isEmpty = ( elemTypes->length() == 0 );
782     const char* pm[2] = { "ICON_SMESH_TREE_MESH", "ICON_SMESH_TREE_MESH_WARN" };
783     aSubMeshSO = publish ( theSubMesh, aRootSO, tag, pm[isEmpty] );
784     if ( aSubMeshSO->_is_nil() )
785       return aSubMeshSO._retn();
786
787     highLightInvalid( aSubMeshSO, false ); // now it is valid
788   }
789   SetName( aSubMeshSO, newName.c_str(), "SubMesh" );
790
791   // Add reference to theShapeObject
792
793   addReference( aSubMeshSO, theShapeObject, GetRefOnShapeTag() );
794
795   // Publish hypothesis
796
797   SMESH::ListOfHypothesis_var hypList = theMesh->GetHypothesisList( theShapeObject );
798   for ( CORBA::ULong i = 0; i < hypList->length(); i++ )
799   {
800     SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( hypList[ i ]);
801     SALOMEDS::SObject_wrap so = PublishHypothesis( aHyp );
802     AddHypothesisToShape( theMesh, theShapeObject, aHyp );
803   }
804
805   return aSubMeshSO._retn();
806 }
807
808 //=======================================================================
809 //function : PublishGroup
810 //purpose  : 
811 //=======================================================================
812
813 SALOMEDS::SObject_ptr SMESH_Gen_i::PublishGroup (SMESH::SMESH_Mesh_ptr  theMesh,
814                                                  SMESH::SMESH_GroupBase_ptr theGroup,
815                                                  GEOM::GEOM_Object_ptr  theShapeObject,
816                                                  const char*            theName)
817 {
818   if ( !myIsEnablePublish )
819     return SALOMEDS::SObject::_nil();
820   if (theMesh->_is_nil() || theGroup->_is_nil() )
821     return SALOMEDS::SObject::_nil();
822
823   SALOMEDS::SObject_wrap aGroupSO = ObjectToSObject( theGroup );
824   if ( aGroupSO->_is_nil() )
825   {
826     SALOMEDS::SObject_wrap aMeshSO = ObjectToSObject( theMesh );
827     if ( aMeshSO->_is_nil() ) {
828       aMeshSO = PublishInStudy( SALOMEDS::SObject::_nil(), theMesh, "");
829       if ( aMeshSO->_is_nil())
830         return SALOMEDS::SObject::_nil();
831     }
832     size_t aType = (int)theGroup->GetType();
833     const char* aRootNames[] = {
834       "Compound Groups", "Groups of Nodes", "Groups of Edges",
835       "Groups of Faces", "Groups of Volumes", "Groups of 0D Elements",
836       "Groups of Balls" };
837
838     // Currently, groups with heterogeneous content are not supported
839     if ( aType != SMESH::ALL )
840     {
841       long aRootTag = GetNodeGroupsTag() + aType - 1;
842
843       // Find or create groups root
844       SALOMEDS::SObject_wrap aRootSO = publish ( CORBA::Object::_nil(),
845                                                  aMeshSO, aRootTag, 0, false );
846       if ( aRootSO->_is_nil() ) return SALOMEDS::SObject::_nil();
847
848       if ( aType < sizeof(aRootNames)/sizeof(char*) )
849         SetName( aRootSO, aRootNames[aType] );
850
851       // Add new group to corresponding sub-tree
852       int isEmpty = ( theMesh->NbNodes() == 0 );
853       std::string pm[2] = { "ICON_SMESH_TREE_GROUP", "ICON_SMESH_TREE_MESH_WARN" };
854       if ( !isEmpty )
855       {
856         if ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup )) // on filter
857         {
858           pm[0] = "ICON_SMESH_TREE_GROUP_ON_FILTER";
859
860           if ( theGroup->GetType() != SMESH::NODE )
861           {
862             isEmpty = true;
863             SMESH::array_of_ElementType_var allElemTypes = theMesh->GetTypes();
864             for ( size_t i =0; i < allElemTypes->length() && isEmpty; ++i )
865               isEmpty = ( allElemTypes[i] != theGroup->GetType() );
866           }
867         }
868         else // standalone or on geometry
869         {
870           isEmpty = ( theGroup->Size() == 0 );
871         }
872       }
873       aGroupSO = publish ( theGroup, aRootSO, 0, pm[isEmpty].c_str() );
874     }
875     if ( aGroupSO->_is_nil() )
876       return aGroupSO._retn();
877   }
878
879   SetName( aGroupSO, theName, "Group" );
880
881   //Add reference to geometry
882   if ( !theShapeObject->_is_nil() )
883     addReference( aGroupSO, theShapeObject, GetRefOnShapeTag() );
884
885   return aGroupSO._retn();
886 }
887
888 //=======================================================================
889 //function : PublishHypothesis
890 //purpose  :
891 //=======================================================================
892
893 SALOMEDS::SObject_ptr
894 SMESH_Gen_i::PublishHypothesis (SMESH::SMESH_Hypothesis_ptr theHyp,
895                                 const char*                 theName)
896 {
897   MESSAGE("PublishHypothesis");
898   if ( !myIsEnablePublish )
899     return SALOMEDS::SObject::_nil();
900   if (theHyp->_is_nil())
901     return SALOMEDS::SObject::_nil();
902
903   CORBA::String_var hypType = theHyp->GetName();
904
905   SALOMEDS::SObject_wrap aHypSO = ObjectToSObject( theHyp );
906   if ( aHypSO->_is_nil() )
907   {
908     SALOMEDS::SComponent_wrap father = PublishComponent();
909     if ( father->_is_nil() )
910       return aHypSO._retn();
911
912     //Find or Create Hypothesis root
913     bool isAlgo = ( !SMESH::SMESH_Algo::_narrow( theHyp )->_is_nil() );
914     int aRootTag = isAlgo ? GetAlgorithmsRootTag() : GetHypothesisRootTag();
915     SALOMEDS::SObject_wrap aRootSO =
916       publish (CORBA::Object::_nil(),father, aRootTag,
917                isAlgo ? "ICON_SMESH_TREE_ALGO" : "ICON_SMESH_TREE_HYPO", false);
918     SetName( aRootSO, isAlgo ?  "Algorithms" : "Hypotheses" );
919
920     // Add New Hypothesis
921     string aPmName = isAlgo ? "ICON_SMESH_TREE_ALGO_" : "ICON_SMESH_TREE_HYPO_";
922     aPmName += hypType.in();
923     // prepend plugin name to pixmap name
924     string pluginName = myHypCreatorMap[ hypType.in() ]->GetModuleName();
925     if ( pluginName != "StdMeshers" )
926       aPmName = pluginName + "::" + aPmName;
927     aHypSO = publish( theHyp, aRootSO, 0, aPmName.c_str() );
928   }
929
930   SetName( aHypSO, theName, hypType.in() );
931
932   MESSAGE("PublishHypothesis--END");
933   return aHypSO._retn();
934 }
935
936 //=======================================================================
937 //function : UpdateIcons
938 //purpose  : update icons of a mesh and its children upon mesh modification
939 //=======================================================================
940
941 void SMESH_Gen_i::UpdateIcons( SMESH::SMESH_Mesh_ptr theMesh )
942 {
943   SMESH_Mesh_i* mesh_i = SMESH::DownCast< SMESH_Mesh_i* >( theMesh );
944   if ( ! mesh_i )
945     return;
946
947   SALOMEDS::SObject_wrap so = ObjectToSObject( theMesh );
948   if ( so->_is_nil() )
949     return;
950
951   // set icon of the mesh
952   if ( mesh_i->NbNodes() == 0 )
953     SetPixMap( so, "ICON_SMESH_TREE_MESH_WARN" );
954   else if ( mesh_i->IsComputedOK() )
955     SetPixMap( so, "ICON_SMESH_TREE_MESH" );
956   else if ( mesh_i->HasShapeToMesh() )
957     SetPixMap( so, "ICON_SMESH_TREE_MESH_PARTIAL" );
958   else
959     SetPixMap( so, "ICON_SMESH_TREE_MESH_IMPORTED" );
960
961   // set icons of sub-objects
962   SALOMEDS::Study_var         study = getStudyServant();
963   SALOMEDS::ChildIterator_wrap iter = study->NewChildIterator( so );
964   for ( ; iter->More(); iter->Next() )
965   {
966     so = iter->Value(); // 1st level child - root of algos, hyps, sub-meshes or groups
967     if ( so->Tag() < SMESH::Tag_FirstSubMesh )
968       continue;
969
970     SALOMEDS::ChildIterator_wrap subIter = study->NewChildIterator( so );
971     for ( ; subIter->More(); subIter->Next() )
972     {
973       so = subIter->Value(); // 2nd level child - a sub-mesh or group
974
975       CORBA::Object_var           obj = SObjectToObject( so );
976       SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( obj );
977       if ( idSrc->_is_nil() )
978         continue;
979
980       SMESH::SMESH_GroupBase_var     grp = SMESH::SMESH_GroupBase::_narrow( obj );
981       SMESH::SMESH_GroupOnFilter_var gof = SMESH::SMESH_GroupOnFilter::_narrow( obj );
982       const bool         isGroup = !grp->_is_nil();
983       const bool isGroupOnFilter = !gof->_is_nil();
984
985       bool isEmpty = ( mesh_i->NbNodes() == 0 );
986       if ( !isEmpty )
987       {
988         if ( isGroupOnFilter ) // GetTypes() can be very long on GroupOnFilter!
989         {
990           SMESH::smIdType_array_var nbByType = mesh_i->GetNbElementsByType();
991           isEmpty = ( nbByType[ grp->GetType() ] == 0 );
992         }
993         else
994         {
995           SMESH::array_of_ElementType_var elemTypes = idSrc->GetTypes();
996           isEmpty = ( elemTypes->length() == 0 );
997
998           if ( !isEmpty )
999           {
1000             // check if all sub-shapes of sub-mesh on group are computed
1001             // (pb: "Compute sub-mesh" menu is missing if a sub-mesh is partially computed)
1002             SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_narrow( obj );
1003             if ( !subMesh->_is_nil() )
1004               if ( SMESH_subMesh* sm = mesh_i->GetImpl().GetSubMeshContaining( subMesh->GetId() ))
1005                 if ( sm->IsComputedPartially() )
1006                 {
1007                   SetPixMap( so, "ICON_SMESH_TREE_MESH_PARTIAL" );
1008                   continue;
1009                 }
1010           }
1011         }
1012       }
1013
1014       if ( isEmpty )
1015         SetPixMap( so, "ICON_SMESH_TREE_MESH_WARN");
1016       else if ( !isGroup )
1017         SetPixMap( so, "ICON_SMESH_TREE_MESH" );
1018       else if ( isGroupOnFilter )
1019         SetPixMap( so, "ICON_SMESH_TREE_GROUP_ON_FILTER" );
1020       else
1021         SetPixMap( so, "ICON_SMESH_TREE_GROUP" );
1022
1023     } // loop on sub-meshes or groups
1024   } // loop on roots
1025 }
1026
1027 //=======================================================================
1028 //function : HighLightInvalid
1029 //purpose  : change font color of a object in the Object Browser
1030 //=======================================================================
1031
1032 void SMESH_Gen_i::HighLightInvalid( CORBA::Object_ptr theObject, bool isInvalid )
1033 {
1034   SALOMEDS::SObject_wrap so = ObjectToSObject(theObject);
1035   highLightInvalid( so.in(), isInvalid );
1036 }
1037
1038 //=======================================================================
1039 //function : highLightInvalid
1040 //purpose  : change font color of a object in the Object Browser
1041 //=======================================================================
1042
1043 void SMESH_Gen_i::highLightInvalid( SALOMEDS::SObject_ptr theSObject, bool isInvalid )
1044 {
1045   if ( !theSObject->_is_nil() )
1046   {
1047     SALOMEDS::StudyBuilder_var studyBuilder = getStudyServant()->NewBuilder();
1048     if ( isInvalid )
1049     {
1050       SALOMEDS::Color red = { 178,34,34 }; // to differ from reference color
1051       SALOMEDS::GenericAttribute_wrap attr =
1052         studyBuilder->FindOrCreateAttribute( theSObject, "AttributeTextColor" );
1053       SALOMEDS::AttributeTextColor_wrap colorAttr = attr;
1054       colorAttr->SetTextColor( red );
1055     }
1056     else
1057     {
1058       studyBuilder->RemoveAttribute( theSObject, "AttributeTextColor" );
1059     }
1060   }
1061 }
1062
1063 //=======================================================================
1064 //function : IsInvalid
1065 //purpose  : Check object validity == absence of AttributeTextColor=(178,34,34)
1066 //=======================================================================
1067
1068 bool SMESH_Gen_i::IsInvalid( SALOMEDS::SObject_ptr theSObject )
1069 {
1070   bool isValid = true;
1071   if ( !theSObject->_is_nil() )
1072   {
1073     SALOMEDS::GenericAttribute_wrap attr;
1074     SALOMEDS::StudyBuilder_var studyBuilder = getStudyServant()->NewBuilder();
1075     if ( studyBuilder->FindAttribute( theSObject, attr.inout(), "AttributeTextColor" ))
1076     {
1077       SALOMEDS::AttributeTextColor_wrap colorAttr = attr;
1078       SALOMEDS::Color color = colorAttr->TextColor();
1079       isValid = ( color.R != 178 || color.G != 34 || color.B != 34 );
1080     }
1081   }
1082   return isValid;
1083 }
1084
1085 //=======================================================================
1086 //function : GetMeshOrSubmeshByShape
1087 //purpose  : 
1088 //=======================================================================
1089
1090 SALOMEDS::SObject_ptr
1091 SMESH_Gen_i::GetMeshOrSubmeshByShape (SMESH::SMESH_Mesh_ptr theMesh,
1092                                       GEOM::GEOM_Object_ptr theShape)
1093 {
1094   MESSAGE("GetMeshOrSubmeshByShape");
1095   SALOMEDS::SObject_wrap aMeshOrSubMesh;
1096   if (theMesh->_is_nil() || ( theShape->_is_nil() && theMesh->HasShapeToMesh()))
1097     return aMeshOrSubMesh._retn();
1098   
1099   TopoDS_Shape aShape;
1100   if(theMesh->HasShapeToMesh())
1101     aShape = GeomObjectToShape( theShape );
1102   else
1103     aShape = SMESH_Mesh::PseudoShape();
1104
1105   SMESH_Mesh_i* mesh_i = objectToServant<SMESH_Mesh_i>( theMesh );
1106
1107   if ( !aShape.IsNull() && mesh_i && mesh_i->GetImpl().GetMeshDS() ) {
1108     SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
1109     if ( aShape.IsSame( meshDS->ShapeToMesh() ))
1110       aMeshOrSubMesh = ObjectToSObject( theMesh );
1111     else {
1112       int shapeID = meshDS->ShapeToIndex( aShape );
1113       SMESH::SMESH_subMesh_var aSubMesh = mesh_i->getSubMesh(shapeID);
1114       if ( !aSubMesh->_is_nil() )
1115         aMeshOrSubMesh = ObjectToSObject( aSubMesh );
1116     }
1117   }
1118   MESSAGE("GetMeshOrSubmeshByShape--END");
1119   return aMeshOrSubMesh._retn();
1120 }
1121
1122 //=======================================================================
1123 //function : AddHypothesisToShape
1124 //purpose  : 
1125 //=======================================================================
1126
1127 bool SMESH_Gen_i::AddHypothesisToShape(SMESH::SMESH_Mesh_ptr       theMesh,
1128                                        GEOM::GEOM_Object_ptr       theShape,
1129                                        SMESH::SMESH_Hypothesis_ptr theHyp)
1130 {
1131   MESSAGE("AddHypothesisToShape");
1132   if (theMesh->_is_nil() ||
1133       theHyp->_is_nil() || (theShape->_is_nil()
1134                             && theMesh->HasShapeToMesh()) )
1135     return false;
1136
1137   SALOMEDS::SObject_wrap aMeshSO = ObjectToSObject( theMesh );
1138   if ( aMeshSO->_is_nil() )
1139     aMeshSO = PublishMesh( theMesh );
1140   SALOMEDS::SObject_wrap aHypSO = PublishHypothesis( theHyp );
1141   if ( aMeshSO->_is_nil() || aHypSO->_is_nil())
1142     return false;
1143
1144   // Find a mesh or submesh referring to theShape
1145   SALOMEDS::SObject_wrap aMeshOrSubMesh =
1146     GetMeshOrSubmeshByShape( theMesh, theShape );
1147   if ( aMeshOrSubMesh->_is_nil() )
1148   {
1149     // publish submesh
1150     TopoDS_Shape aShape = GeomObjectToShape( theShape );
1151     SMESH_Mesh_i* mesh_i = objectToServant<SMESH_Mesh_i>( theMesh );
1152     if ( !aShape.IsNull() && mesh_i && mesh_i->GetImpl().GetMeshDS() ) {
1153       SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
1154       int shapeID = meshDS->ShapeToIndex( aShape );
1155       SMESH::SMESH_subMesh_var aSubMesh = mesh_i->getSubMesh(shapeID);
1156       aMeshOrSubMesh = PublishSubMesh( theMesh, aSubMesh, theShape );
1157     }
1158     if ( aMeshOrSubMesh->_is_nil() )
1159       return false;
1160   }
1161
1162   //Find or Create Applied Hypothesis root
1163   bool aIsAlgo = !SMESH::SMESH_Algo::_narrow( theHyp )->_is_nil();
1164   SALOMEDS::SObject_wrap AHR =
1165     publish (CORBA::Object::_nil(), aMeshOrSubMesh,
1166              aIsAlgo ? GetRefOnAppliedAlgorithmsTag() : GetRefOnAppliedHypothesisTag(),
1167              aIsAlgo ? "ICON_SMESH_TREE_ALGO" : "ICON_SMESH_TREE_HYPO", false);
1168   SetName( AHR, aIsAlgo ? "Applied algorithms" : "Applied hypotheses" );
1169
1170   addReference( AHR, theHyp );
1171
1172   MESSAGE("AddHypothesisToShape--END");
1173   return true;
1174 }
1175
1176 //=======================================================================
1177 //function : RemoveHypothesisFromShape
1178 //purpose  : 
1179 //=======================================================================
1180
1181 bool SMESH_Gen_i::RemoveHypothesisFromShape(SMESH::SMESH_Mesh_ptr       theMesh,
1182                                             GEOM::GEOM_Object_ptr       theShape,
1183                                             SMESH::SMESH_Hypothesis_ptr theHyp)
1184 {
1185   if (theMesh->_is_nil() ||
1186       theHyp->_is_nil() || (theShape->_is_nil()
1187                             && theMesh->HasShapeToMesh()))
1188     return false;
1189
1190   SALOMEDS::SObject_wrap aHypSO = ObjectToSObject( theHyp );
1191   if ( aHypSO->_is_nil() )
1192     return false;
1193
1194   CORBA::String_var hypEntry = aHypSO->GetID();
1195
1196   // Find a mesh or sub-mesh referring to theShape
1197   SALOMEDS::SObject_wrap aMeshOrSubMesh =
1198     GetMeshOrSubmeshByShape( theMesh, theShape );
1199   if ( aMeshOrSubMesh->_is_nil() )
1200     return false;
1201
1202   // Find and remove a reference to aHypSO
1203   SALOMEDS::SObject_wrap aRef, anObj;
1204   SALOMEDS::ChildIterator_wrap it = getStudyServant()->NewChildIterator( aMeshOrSubMesh );
1205   bool found = false;
1206   for ( it->InitEx( true ); ( it->More() && !found ); it->Next() ) {
1207     anObj = it->Value();
1208     if (anObj->ReferencedObject( aRef.inout() ))
1209     {
1210       CORBA::String_var refEntry = aRef->GetID();
1211       found = ( strcmp( refEntry, hypEntry ) == 0 );
1212     }
1213     if ( found )
1214     {
1215       SALOMEDS::StudyBuilder_var builder = getStudyServant()->NewBuilder();
1216       builder->RemoveObject( anObj );
1217     }
1218   }
1219
1220   return true;
1221 }
1222
1223 //================================================================================
1224 /*!
1225  * \brief Stores names of variables that WILL be passes as parameters when calling
1226  *        some method of a given object.
1227  *  \param [in] theObject - the object whose a method WILL be called with \a theParameters.
1228  *  \param [in] theParameters - a string containing parameters separated by ':'.
1229  */
1230 //================================================================================
1231
1232 void SMESH_Gen_i::UpdateParameters(CORBA::Object_ptr theObject, const char* theParameters)
1233 {
1234   // find variable names within theParameters
1235
1236   myLastObj.clear();
1237   myLastParameters.clear();
1238   myLastParamIndex.clear(); /* vector holding indices of virables within the string
1239                                of all variables used for theObject */ 
1240   int nbVars = 0;
1241   int pos = 0, prevPos = 0, len = strlen( theParameters );
1242   if ( len == 0 ) return;
1243   while ( pos <= len )
1244   {
1245     if ( pos == len || theParameters[pos] == ':' )
1246     {
1247       if ( prevPos < pos )
1248       {
1249         string val( theParameters + prevPos, theParameters + pos );
1250         if ( !getStudyServant()->IsVariable( val.c_str() ))
1251           val.clear();
1252         myLastParameters.push_back( val );
1253         nbVars += (! myLastParameters.back().empty() );
1254       }
1255       else
1256       {
1257         myLastParameters.push_back("");
1258       }
1259       prevPos = pos+1;
1260     }
1261     ++pos;
1262   }
1263
1264   if ( nbVars < 1 )
1265     return;
1266
1267   // store
1268   // (1) variable names in the string of all variables used for theObject and
1269   // (2) indices of found variables in myLastParamIndex.
1270
1271   // remember theObject
1272   SALOMEDS::SObject_wrap aSObj =  ObjectToSObject(theObject);
1273   if ( aSObj->_is_nil() )
1274     return;
1275   CORBA::String_var anObjEntry = aSObj->GetID();
1276   myLastObj = anObjEntry.in();
1277
1278   // get a string of variable names
1279   SALOMEDS::StudyBuilder_var   aStudyBuilder = getStudyServant()->NewBuilder();
1280   SALOMEDS::GenericAttribute_wrap     anAttr =
1281     aStudyBuilder->FindOrCreateAttribute( aSObj, "AttributeString" );
1282   SALOMEDS::AttributeString_wrap aStringAttr = anAttr;
1283   CORBA::String_var                  oldVars = aStringAttr->Value();
1284   std::string                         varStr = oldVars.in();
1285
1286   // add new variables and find indices of variables
1287   for ( size_t i = 0; i < myLastParameters.size(); ++i )
1288   {
1289     int varIndex = -1;
1290     if ( !myLastParameters[i].empty() )
1291     {
1292       // find index of myLastParameters[i] in varStr
1293       int curIndex  = 0;
1294       bool varFound = false;
1295       size_t pos    = 0;
1296       // varStr can be "A|B::C;*=2|D"
1297       const std::string separators(":|;*=");
1298       while ( pos < varStr.size() && !varFound )
1299       {
1300         // skip separators
1301         while ( separators.find( varStr[ pos ]) != std::string::npos )
1302           if ( ++pos >= varStr.size() )
1303             break;
1304         // skip repetition number following '='
1305         if ( varStr[ pos-1 ] == '=' )
1306         {
1307           while ( '0' <= varStr[ pos ] && varStr[ pos ] <= '9' )
1308             ++pos;
1309           continue; // to skip next separator
1310         }
1311         // compare variable name
1312         if ( pos < varStr.size() )
1313         {
1314           varFound = ( varStr.compare( pos, myLastParameters[i].size(), myLastParameters[i] ) == 0 &&
1315                        // same string beginning but is length same?
1316                        ( pos + myLastParameters[i].size() >= varStr.size() ||
1317                          separators.find( varStr[ pos+1 ]) != std::string::npos ));
1318           if ( varFound )
1319             varIndex = curIndex;
1320           else
1321             pos = varStr.find_first_of( separators, pos ); // goto the next separator
1322           ++curIndex;
1323         }
1324       }
1325       // add new variable
1326       if ( !varFound )
1327       {
1328         varStr += ":" + myLastParameters[i];
1329         varIndex = curIndex;
1330       }
1331     }
1332     myLastParamIndex.push_back( varIndex );
1333   }
1334   aStringAttr->SetValue( varStr.c_str() );
1335 }
1336
1337 //================================================================================
1338 /*!
1339  * \brief Return all variables used to create an object
1340  *  \param [in] theObjectEntry - an object entry in the current study
1341  *  \return std::vector< std::string > - all variable names (or values of removed variables)
1342  */
1343 //================================================================================
1344
1345 std::vector< std::string > SMESH_Gen_i::GetAllParameters(const std::string& theObjectEntry) const
1346 {
1347   std::vector< std::string > varNames;
1348
1349   SALOMEDS::SObject_wrap aSObj = getStudyServant()->FindObjectID( theObjectEntry.c_str() );
1350
1351   // get a string of variable names
1352   SALOMEDS::StudyBuilder_var   aStudyBuilder = getStudyServant()->NewBuilder();
1353   SALOMEDS::GenericAttribute_wrap     anAttr =
1354     aStudyBuilder->FindOrCreateAttribute( aSObj, "AttributeString" );
1355   SALOMEDS::AttributeString_wrap aStringAttr = anAttr;
1356   CORBA::String_var                  oldVars = aStringAttr->Value();
1357   std::string                         varStr = oldVars.in();
1358
1359   // separate variables within varStr;
1360   // varStr can be "A|B::C;*=2|D"
1361   size_t pos = 0;
1362   const std::string separators(":|;*=");
1363   while ( pos < varStr.size() )
1364   {
1365     // skip separators
1366     pos = varStr.find_first_not_of( separators, pos );
1367     // while ( separators.find( varStr[ pos ]) != std::string::npos )
1368     //   if ( ++pos >= varStr.size() )
1369     //     break;
1370     // skip repetition number following '='
1371     if ( varStr[ pos-1 ] == '=' )
1372     {
1373       while ( '0' <= varStr[ pos ] && varStr[ pos ] <= '9' )
1374         ++pos;
1375       continue; // to skip next separator
1376     }
1377     // store variable name
1378     if ( pos < varStr.size() )
1379     {
1380       size_t pos2 = varStr.find_first_of( separators, pos );
1381       varNames.push_back( varStr.substr( pos, pos2 - pos));
1382       pos = pos2;
1383     }
1384   }
1385   return varNames;
1386 }
1387
1388 //=======================================================================
1389 //function : ParseParameters
1390 //purpose  : Replace variables by their values
1391 //=======================================================================
1392 // char* SMESH_Gen_i::ParseParameters(const char* theParameters)
1393 // {
1394 //   //const char* aParameters = theParameters;
1395 // //   const char* aParameters = CORBA::string_dup(theParameters);
1396 //   TCollection_AsciiString anInputParams;
1397 //   SALOMEDS::Study_var aStudy = getStudyServant();
1398 //   if( !aStudy->_is_nil() ) {
1399 // //     SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(theParameters);
1400 // //     for(int j=0;j<aSections->length();j++) {
1401 // //       SALOMEDS::ListOfStrings aVars= aSections[j];
1402 // //       for(int i=0;i<aVars.length();i++ ) {
1403 // //         anInputParams += aStudy->IsVariable(aVars[i].in()) ? 
1404 // //           TCollection_AsciiString(aVars[i].in()) : TCollection_AsciiString("");
1405 // //         if(i != aVars.length()-1)
1406 // //           anInputParams+=":";
1407 // //       }
1408 // //       if(j!=aSections->length()-1)
1409 // //         anInputParams+="|";
1410 // //     }
1411 //     TCollection_AsciiString paramStr( theParameters );
1412 //     int beg = 0, end;
1413 //     char sep, *pParams = (char*)paramStr.ToCString();
1414 //     while ( beg < paramStr.Length() )
1415 //     {
1416 //       end = beg-1;
1417 //       while ( ++end < paramStr.Length() )
1418 //         if ( pParams[end] == ':' || pParams[end] == '|')
1419 //           break;
1420 //       if ( end < paramStr.Length())
1421 //       {
1422 //         sep = pParams[end];
1423 //         pParams[end] = '\0';
1424 //       }
1425 //       if ( aStudy->IsVariable( pParams+beg ))
1426 //         anInputParams += pParams+beg;
1427 //       if ( end < paramStr.Length() )
1428 //         anInputParams += sep;
1429 //       else
1430 //         break;
1431 //       beg = end + 1;
1432 //     }
1433 //   }
1434 //   return CORBA::string_dup(anInputParams.ToCString());
1435 // }
1436
1437 //=======================================================================
1438 //function : GetParameters
1439 //purpose  : 
1440 //=======================================================================
1441
1442 char* SMESH_Gen_i::GetParameters(CORBA::Object_ptr theObject)
1443 {
1444   CORBA::String_var aResult("");
1445
1446   SALOMEDS::SObject_wrap aSObj = ObjectToSObject( theObject );
1447   if ( !aSObj->_is_nil() )
1448   {
1449     SALOMEDS::GenericAttribute_wrap attr;
1450     if ( aSObj->FindAttribute( attr.inout(), "AttributeString"))
1451     {
1452       SALOMEDS::AttributeString_wrap strAttr = attr;
1453       aResult = strAttr->Value();
1454     }
1455   }
1456   return aResult._retn();
1457 }
1458
1459 //================================================================================
1460 /*!
1461  * \brief Create a sub-mesh on a geometry that is not a sub-shape of the main shape
1462  * for the case where a valid sub-shape not found by CopyMeshWithGeom().
1463  * The invalid sub-mesh has GetId() < 0.
1464  */
1465 //================================================================================
1466
1467 SMESH::SMESH_subMesh_ptr
1468 SMESH_Gen_i::createInvalidSubMesh(SMESH::SMESH_Mesh_ptr theMesh,
1469                                   GEOM::GEOM_Object_ptr theStrangerGeom,
1470                                   const char*           theName)
1471 {
1472   SMESH::SMESH_subMesh_var subMesh;
1473
1474   try
1475   {
1476     SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( theMesh );
1477     subMesh = mesh_i->createSubMesh( theStrangerGeom );
1478
1479     if ( !subMesh->_is_nil() && CanPublishInStudy( subMesh ))
1480     {
1481       SALOMEDS::SObject_wrap so = PublishSubMesh( theMesh, subMesh, theStrangerGeom, theName );
1482
1483       // hide a reference to geometry
1484       if ( !so->_is_nil() )
1485       {
1486         SALOMEDS::SObject_wrap refSO;
1487         if ( so->FindSubObject( GetRefOnShapeTag(), refSO.inout() ))
1488         {
1489           SALOMEDS::StudyBuilder_var studyBuilder = getStudyServant()->NewBuilder();
1490           SALOMEDS::GenericAttribute_wrap attr =
1491             studyBuilder->FindOrCreateAttribute( refSO, "AttributeDrawable" );
1492           SALOMEDS::AttributeDrawable_wrap ga = attr;
1493           ga->SetDrawable( false );
1494         }
1495       }
1496     }
1497   }
1498   catch (...) {
1499   }
1500
1501   return subMesh._retn();
1502 }
1503
1504
1505 // ==============
1506 // Study context
1507 // ==============
1508
1509 //=======================================================================
1510 //function : addObject
1511 //purpose  : register object in the internal map and return its id
1512 //=======================================================================
1513
1514 int StudyContext::addObject( const std::string& theIOR )
1515 {
1516   int nextId = getNextId();
1517   mapIdToIOR.Bind( nextId, theIOR );
1518   return nextId;
1519 }
1520
1521 //=======================================================================
1522 //function : findId
1523 //purpose  : find the object id in the internal map by the IOR
1524 //=======================================================================
1525
1526 int StudyContext::findId( const std::string& theIOR )
1527 {
1528   TInt2StringMap::iterator imap;
1529   for ( imap = mapIdToIOR.begin(); imap != mapIdToIOR.end(); ++imap ) {
1530     if ( *imap == theIOR )
1531       return imap.Iterator().Key();
1532   }
1533   return 0;
1534 }
1535
1536 //=======================================================================
1537 //function : getIORbyId
1538 //purpose  : get object's IOR by id
1539 //=======================================================================
1540
1541 std::string StudyContext::getIORbyId( const int theId )
1542 {
1543   if ( mapIdToIOR.IsBound( theId ) )
1544     return mapIdToIOR( theId );
1545   return std::string();
1546 }
1547
1548 //=======================================================================
1549 //function : getIORbyOldId
1550 //purpose  : get object's IOR by old id
1551 //=======================================================================
1552
1553 std::string StudyContext::getIORbyOldId( const int theOldId )
1554 {
1555   if ( mapIdToId.IsBound( theOldId ) )
1556     return getIORbyId( mapIdToId( theOldId ));
1557   return std::string();
1558 }
1559
1560 //=======================================================================
1561 //function : mapOldToNew
1562 //purpose  : maps old object id to the new one (used when restoring data)
1563 //=======================================================================
1564
1565 void StudyContext::mapOldToNew( const int oldId, const int newId )
1566 {
1567   mapIdToId.Bind( oldId, newId );
1568 }
1569
1570 //=======================================================================
1571 //function : getOldId
1572 //purpose  : get old id by a new one
1573 //=======================================================================
1574
1575 int StudyContext::getOldId( const int newId )
1576 {
1577   TInt2IntMap::iterator imap;
1578   for ( imap = mapIdToId.begin(); imap != mapIdToId.end(); ++imap ) {
1579     if ( *imap == newId )
1580       return imap.Iterator().Key();
1581   }
1582   return 0;
1583 }
1584
1585 //=======================================================================
1586 //function : Clear
1587 //purpose  : clear data
1588 //=======================================================================
1589
1590 void StudyContext::Clear()
1591 {
1592   mapIdToIOR.Clear();
1593   mapIdToId.Clear();
1594 }