Salome HOME
NRI : First integration.
[modules/smesh.git] / src / SMESH / SMESH_subMesh.cxx
1 using namespace std;
2 //=============================================================================
3 // File      : SMESH_subMesh.cxx
4 // Created   : jeu mai 30 13:28:32 CEST 2002
5 // Author    : Paul RASCLE, EDF
6 // Project   : SALOME
7 // Copyright : EDF 2002
8 // $Header$
9 //=============================================================================
10
11 using namespace std;
12
13 #include "SMESH_subMesh.hxx"
14 #include "SMESH_Gen.hxx"
15 #include "SMESH_Mesh.hxx"
16 #include "SMESH_Hypothesis.hxx"
17 #include "SMESH_Algo.hxx"
18 #include "utilities.h"
19 #include "OpUtil.hxx"
20
21 #include <TopExp.hxx>
22 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
23 #include <TopTools_ListOfShape.hxx>
24 #include <TopTools_ListIteratorOfListOfShape.hxx>
25 #include <TColStd_ListIteratorOfListOfInteger.hxx>
26
27 //=============================================================================
28 /*!
29  *  default constructor:
30  */
31 //=============================================================================
32
33 SMESH_subMesh::SMESH_subMesh(int Id, 
34                              SMESH_Mesh* father,
35                              const Handle(SMESHDS_Mesh)& meshDS,
36                              const TopoDS_Shape & aSubShape)
37 {
38   //MESSAGE("SMESH_subMesh::SMESH_subMesh");
39   _subShape = aSubShape;
40   _meshDS = meshDS;
41   _subMeshDS =  meshDS->MeshElements(_subShape); // may be null ...
42   _father = father;
43   _Id = Id;
44   _vertexSet = false;        // only for Vertex subMesh
45   _dependenceAnalysed = false;
46   _dependantsFound = false;
47
48   if (_subShape.ShapeType() == TopAbs_VERTEX)
49     {
50       _algoState = HYP_OK;
51       _computeState = READY_TO_COMPUTE;
52     }
53   else
54     {
55       _algoState = NO_ALGO;
56       _computeState = NOT_READY;
57     }
58 }
59
60 //=============================================================================
61 /*!
62  * 
63  */
64 //=============================================================================
65
66 SMESH_subMesh::~SMESH_subMesh()
67 {
68   MESSAGE("SMESH_subMesh::~SMESH_subMesh");
69   // ****
70 }
71
72 //=============================================================================
73 /*!
74  * 
75  */
76 //=============================================================================
77
78 int  SMESH_subMesh::GetId()
79 {
80   //MESSAGE("SMESH_subMesh::GetId");
81   return _Id;
82 }
83
84 //=============================================================================
85 /*!
86  * Given a subShape, find the subMesh is associated to this subShape or
87  * to a collection of shapes containing this subShape. Collection = compsolid,
88  * shell, wire
89  */
90 //=============================================================================
91
92 // bool SMESH_subMesh::Contains(const TopoDS_Shape & aSubShape)
93 //   throw (SALOME_Exception)
94 // {
95 //   //MESSAGE("SMESH_subMesh::Contains");
96 //   bool contains = false;
97 //   int type = _subShape.ShapeType();
98 //   int typesub = aSubShape.ShapeType();
99 //   //SCRUTE(type)
100 //   //SCRUTE(typesub)
101 //   switch (type)
102 //     {
103 // //     case TopAbs_COMPOUND:
104 // //       {
105 // //   //MESSAGE("---");
106 // //   throw SALOME_Exception(LOCALIZED("Compound not yet treated"));
107 // //   break;
108 // //       }
109 //     case TopAbs_COMPSOLID:
110 //       {
111 //      //MESSAGE("---");
112 //      for (TopExp_Explorer exp(aSubShape,TopAbs_SOLID);exp.More();exp.Next())
113 //        {
114 //          contains = _subShape.IsSame(exp.Current());
115 //          if (contains) break;
116 //        }
117 //      break;
118 //       }
119 //     case TopAbs_SHELL:
120 //       {
121 //      //MESSAGE("---");
122 //      for (TopExp_Explorer exp(aSubShape,TopAbs_FACE);exp.More();exp.Next())
123 //        {
124 //          contains = _subShape.IsSame(exp.Current());
125 //          if (contains) break;
126 //        }
127 //      break;
128 //       }
129 //     case TopAbs_WIRE:
130 //       {
131 //      //MESSAGE("---");
132 //      for (TopExp_Explorer exp(aSubShape,TopAbs_EDGE);exp.More();exp.Next())
133 //        {
134 //          contains = _subShape.IsSame(exp.Current());
135 //          if (contains) break;
136 //        }
137 //      break;
138 //       }
139 //     case TopAbs_COMPOUND:
140 //     case TopAbs_SOLID:
141 //     case TopAbs_FACE:
142 //     case TopAbs_EDGE:
143 //     case TopAbs_VERTEX:
144 //       {
145 //      //MESSAGE("---");
146 //      contains = _subShape.IsSame(aSubShape);
147 //      break;
148 //       }
149 //     default:
150 //       {
151 //      break;
152 //       }
153 //     }
154 //   //SCRUTE(contains);
155 //   return contains;
156 // }
157
158 //=============================================================================
159 /*!
160  * 
161  */
162 //=============================================================================
163
164 const Handle(SMESHDS_SubMesh)& SMESH_subMesh::GetSubMeshDS()
165   throw (SALOME_Exception)
166 {
167   //MESSAGE("SMESH_subMesh::GetSubMeshDS");
168   if (_subMeshDS.IsNull())
169     {
170       //MESSAGE("subMesh pointer still null, trying to get it...");
171       _subMeshDS =  _meshDS->MeshElements(_subShape); // may be null ...
172       if (_subMeshDS.IsNull())
173         {
174           MESSAGE("problem... subMesh still empty");
175           //NRI   ASSERT(0);
176           //NRI   throw SALOME_Exception(LOCALIZED(subMesh still empty));
177         }
178     }
179   return _subMeshDS;
180 }
181
182 //=============================================================================
183 /*!
184  * 
185  */
186 //=============================================================================
187
188 SMESH_subMesh* SMESH_subMesh::GetFirstToCompute()
189   throw (SALOME_Exception)
190 {
191   //MESSAGE("SMESH_subMesh::GetFirstToCompute");
192   const map<int, SMESH_subMesh*>& subMeshes = DependsOn();
193   SMESH_subMesh* firstToCompute = 0;
194
195   map<int, SMESH_subMesh*>::const_iterator itsub;
196   for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
197     {
198       SMESH_subMesh* sm = (*itsub).second;
199 //       SCRUTE(sm->GetId());
200 //       SCRUTE(sm->GetComputeState());
201       bool readyToCompute = (sm->GetComputeState() == READY_TO_COMPUTE);
202       if (readyToCompute)
203         {
204           firstToCompute = sm; 
205           //SCRUTE(sm->GetId());
206           break;
207         }
208     }
209   if (firstToCompute)
210     {
211       //MESSAGE("--- submesh to compute");
212       return firstToCompute;       // a subMesh of this
213     }
214   if (_computeState == READY_TO_COMPUTE)
215     {
216       //MESSAGE("--- this to compute");
217       return this;  // this
218     }
219   //MESSAGE("--- nothing to compute");
220   return 0;                                            // nothing to compute
221 }
222
223 //=============================================================================
224 /*!
225  * 
226  */
227 //=============================================================================
228
229 bool SMESH_subMesh::SubMeshesComputed()
230   throw (SALOME_Exception)
231 {
232   //MESSAGE("SMESH_subMesh::SubMeshesComputed");
233   const map<int, SMESH_subMesh*>& subMeshes = DependsOn();
234
235   bool subMeshesComputed = true;
236   map<int, SMESH_subMesh*>::const_iterator itsub;
237   for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
238     {
239       SMESH_subMesh* sm = (*itsub).second;
240 //       SCRUTE(sm->GetId());
241 //       SCRUTE(sm->GetComputeState());
242       bool computeOk =  (sm->GetComputeState() == COMPUTE_OK);
243       if (! computeOk)
244         {
245           subMeshesComputed = false;
246           SCRUTE(sm->GetId());
247           break;
248         }
249     }
250    return subMeshesComputed; 
251 }
252
253 //=============================================================================
254 /*!
255  * 
256  */
257 //=============================================================================
258
259 bool SMESH_subMesh::SubMeshesReady()
260 {
261   MESSAGE("SMESH_subMesh::SubMeshesReady");
262   const map<int, SMESH_subMesh*>& subMeshes = DependsOn();
263
264   bool subMeshesReady = true;
265   map<int, SMESH_subMesh*>::const_iterator itsub;
266   for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
267     {
268       SMESH_subMesh* sm = (*itsub).second;
269 //       SCRUTE(sm->GetId());
270 //       SCRUTE(sm->GetComputeState());
271       bool computeOk = (    (sm->GetComputeState() == COMPUTE_OK)
272                          || (sm->GetComputeState() == READY_TO_COMPUTE)) ;
273       if (! computeOk)
274         {
275           subMeshesReady = false;
276           SCRUTE(sm->GetId());
277           break;
278         }
279     }
280   return subMeshesReady; 
281 }
282
283 //=============================================================================
284 /*!
285  * Construct dependence on first level subMeshes. complex shapes (compsolid, 
286  * shell, wire) are not analysed the same way as simple shapes (solid, face,
287  * edge). 
288  * For collection shapes (compsolid, shell, wire) prepare a list of submeshes
289  * with possible multiples occurences. Multiples occurences corresponds to
290  * internal frontiers within shapes of the collection and must not be keeped.
291  * See FinalizeDependence.
292  */
293 //=============================================================================
294
295 const map<int, SMESH_subMesh*>& SMESH_subMesh::DependsOn()
296 {
297  if (_dependenceAnalysed) return _mapDepend;
298
299  //MESSAGE("SMESH_subMesh::DependsOn");
300
301   int type = _subShape.ShapeType();
302   //SCRUTE(type);
303   switch (type)
304     {
305     case TopAbs_COMPOUND:
306       {
307         //MESSAGE("compound");
308         list<TopoDS_Shape> shellInSolid;
309         for (TopExp_Explorer exp(_subShape,TopAbs_SOLID);exp.More();exp.Next())
310           {
311             InsertDependence(exp.Current());
312             for (TopExp_Explorer 
313                    exp2(exp.Current(),TopAbs_SHELL);exp2.More();exp2.Next())
314               {
315                 shellInSolid.push_back(exp2.Current()); 
316               }
317           }
318         for (TopExp_Explorer exp(_subShape,TopAbs_SHELL);exp.More();exp.Next())
319           {
320             list<TopoDS_Shape>::iterator it1;
321             bool isInSolid = false;
322             for (it1 = shellInSolid.begin(); it1 != shellInSolid.end(); it1++)
323               {
324                 TopoDS_Shape aShape = (*it1);
325                 if (aShape.IsSame(exp.Current())) 
326                 {
327                   isInSolid = true;
328                   break;
329                 }
330               }
331             if (!isInSolid)
332               InsertDependence(exp.Current()); //only shell not in solid
333           }
334         for (TopExp_Explorer exp(_subShape,TopAbs_FACE);exp.More();exp.Next())
335           {
336             InsertDependence(exp.Current());
337           }
338         for (TopExp_Explorer exp(_subShape,TopAbs_EDGE);exp.More();exp.Next())
339           {
340             InsertDependence(exp.Current());
341           }
342         break;
343       }
344     case TopAbs_COMPSOLID:
345       {
346         //MESSAGE("compsolid");
347         for (TopExp_Explorer exp(_subShape,TopAbs_SOLID);exp.More();exp.Next())
348           {
349             InsertDependence(exp.Current());
350           }
351 //      list<TopoDS_Shape> shapeList;
352 //      for (TopExp_Explorer exp(_subShape,TopAbs_SOLID);exp.More();exp.Next())
353 //        {
354 //          for (TopExp_Explorer 
355 //                 exp2(exp.Current(),TopAbs_FACE);exp2.More();exp2.Next())
356 //            {
357 //              shapeList.push_back(exp2.Current()); 
358 //            }
359 //        }
360 //      FinalizeDependence(shapeList);
361         break;
362       }
363     case TopAbs_SHELL:
364       {
365         //MESSAGE("shell");
366         for (TopExp_Explorer exp(_subShape,TopAbs_FACE);exp.More();exp.Next())
367           {
368             InsertDependence(exp.Current());
369           }
370 //      list<TopoDS_Shape> shapeList;
371 //      for (TopExp_Explorer exp(_subShape,TopAbs_FACE);exp.More();exp.Next())
372 //        {
373 //          for (TopExp_Explorer 
374 //                 exp2(exp.Current(),TopAbs_EDGE);exp2.More();exp2.Next())
375 //            {
376 //              shapeList.push_back(exp2.Current()); 
377 //            }
378 //        }
379 //      FinalizeDependence(shapeList);
380         break;
381       }
382     case TopAbs_WIRE:
383       {
384         //MESSAGE("wire");
385         for (TopExp_Explorer exp(_subShape,TopAbs_EDGE);exp.More();exp.Next())
386           {
387             InsertDependence(exp.Current());
388           }
389 //      list<TopoDS_Shape> shapeList;
390 //      for (TopExp_Explorer exp(_subShape,TopAbs_EDGE);exp.More();exp.Next())
391 //        {
392 //          for (TopExp_Explorer 
393 //                 exp2(exp.Current(),TopAbs_VERTEX);exp2.More();exp2.Next())
394 //            {
395 //              shapeList.push_back(exp2.Current()); 
396 //            }
397 //        }
398 //      FinalizeDependence(shapeList);
399         break;
400       }
401     case TopAbs_SOLID:
402       {
403         //MESSAGE("solid");
404 //      for (TopExp_Explorer exp(_subShape,TopAbs_SHELL);exp.More();exp.Next())
405 //        {
406 //          InsertDependence(exp.Current());
407 //        }
408         for (TopExp_Explorer exp(_subShape,TopAbs_FACE);exp.More();exp.Next())
409           {
410             InsertDependence(exp.Current());
411           }
412         break;
413       }
414     case TopAbs_FACE:
415       {
416         //MESSAGE("face");
417 //      for (TopExp_Explorer exp(_subShape,TopAbs_WIRE);exp.More();exp.Next())
418 //        {
419 //          InsertDependence(exp.Current());
420 //        }
421         for (TopExp_Explorer exp(_subShape,TopAbs_EDGE);exp.More();exp.Next())
422           {
423             InsertDependence(exp.Current());
424           }
425         break;
426       }
427     case TopAbs_EDGE:
428       {
429         //MESSAGE("edge");
430         for (TopExp_Explorer exp(_subShape,TopAbs_VERTEX);exp.More();exp.Next())
431           {
432             InsertDependence(exp.Current());
433           }
434         break;
435       }
436     case TopAbs_VERTEX:
437       {
438         break;
439       }
440     default:
441       {
442         break;
443       }
444     }
445   _dependenceAnalysed = true;
446   return _mapDepend;
447 }
448
449 //=============================================================================
450 /*!
451  * For simple Shapes (solid, face, edge): add subMesh into dependence list.
452  */
453 //=============================================================================
454
455 void SMESH_subMesh::InsertDependence(const TopoDS_Shape aSubShape)
456 {
457   //MESSAGE("SMESH_subMesh::InsertDependence");
458   //SMESH_subMesh* aSubMesh = _father->GetSubMeshContaining(aSubShape);
459   //SCRUTE(aSubMesh);
460   //if (! aSubMesh) aSubMesh = _father->GetSubMesh(aSubShape);
461
462   SMESH_subMesh* aSubMesh = _father->GetSubMesh(aSubShape);
463   int type = aSubShape.ShapeType();
464   int ordType = 9 - type; // 2 = Vertex, 8 = CompSolid
465   int cle = aSubMesh->GetId();
466   cle += 10000000 * ordType; // sort map by ordType then index
467   if (_mapDepend.find(cle) == _mapDepend.end())
468     {
469       _mapDepend[cle] = aSubMesh;
470       const map<int, SMESH_subMesh*>& subMap = aSubMesh->DependsOn();
471       map<int, SMESH_subMesh*>::const_iterator im;
472       for (im = subMap.begin(); im != subMap.end(); im++)
473         {
474           int clesub = (*im).first;
475           SMESH_subMesh* sm = (*im).second;
476           if (_mapDepend.find(clesub) == _mapDepend.end())
477             _mapDepend[clesub] = sm;
478         }
479     }
480
481 }
482  
483 //=============================================================================
484 /*!
485  * For collection shapes (compsolid, shell, wire).
486  * Add only subMesh figuring only once in multiset to dependence list 
487  */
488 //=============================================================================
489
490 // void SMESH_subMesh::FinalizeDependence(list<TopoDS_Shape>& shapeList)
491 // {
492 //   //MESSAGE("SMESH_subMesh::FinalizeDependence");
493 //   list<TopoDS_Shape>::iterator it1, it2;
494 //   for(it1 = shapeList.begin(); it1 != shapeList.end(); it1++)
495 //     {
496 //       TopoDS_Shape aSubShape = (*it1);
497 //       int count = 0;
498 //       for(it2 = shapeList.begin(); it2 != shapeList.end(); it2++)
499 //      {
500 //        TopoDS_Shape other = (*it2);
501 //        if (other.IsSame(aSubShape)) count++;
502 //      }
503 //       if (count == 1) InsertDependence(aSubShape);
504 //       SCRUTE(count);
505 //     }
506 // }
507
508 //=============================================================================
509 /*!
510  * 
511  */
512 //=============================================================================
513
514  const TopoDS_Shape& SMESH_subMesh::GetSubShape()
515 {
516   //MESSAGE("SMESH_subMesh::GetSubShape");
517   return _subShape;
518 }
519
520 //=============================================================================
521 /*!
522  * 
523  */
524 //=============================================================================
525
526 bool SMESH_subMesh::AlgoStateEngine(int event, SMESH_Hypothesis* anHyp)
527   throw (SALOME_Exception)
528 {
529   //  MESSAGE("SMESH_subMesh::AlgoStateEngine");
530   //SCRUTE(_algoState);
531   //SCRUTE(event);
532
533   // **** les retour des evenement shape sont significatifs
534   // (add ou remove fait ou non)
535   // le retour des evenement father n'indiquent pas que add ou remove fait
536   int dim = SMESH_Gen::GetShapeDim(_subShape);
537
538   if (dim < 1)
539     {
540       _algoState = HYP_OK;
541       //SCRUTE(_algoState);
542       return true;
543     }
544
545   SMESH_Gen* gen =_father->GetGen();
546   bool ret;
547   _oldAlgoState = _algoState;
548   bool modifiedHyp = false;  // if set to true, force event MODIF_ALGO_STATE
549                              // in ComputeStateEngine
550
551   switch (_algoState)
552     {
553
554       // ----------------------------------------------------------------------
555
556     case NO_ALGO:
557       switch (event)
558         {
559         case ADD_HYP:
560           ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
561           ret = _meshDS->AddHypothesis(_subShape, anHyp);
562           break;
563         case ADD_ALGO:
564           ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
565           if (anHyp->GetDim() <= SMESH_Gen::GetShapeDim(_subShape))
566             {
567               ret = _meshDS->AddHypothesis(_subShape, anHyp);
568 //            if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)))
569 //            if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType()))
570               if (ret &&(anHyp->GetShapeType() & (1<< _subShape.ShapeType())))
571                 {
572                   SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
573                   ASSERT(algo);
574                   ret = algo->CheckHypothesis((*_father),_subShape);
575                   if (ret) SetAlgoState(HYP_OK);
576                   else SetAlgoState(MISSING_HYP);
577                 }
578             }
579           break;
580         case REMOVE_HYP:
581           ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
582           ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
583           break;
584         case REMOVE_ALGO:
585           ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
586           ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
587           break;
588         case ADD_FATHER_HYP:      // nothing to do
589           break;
590         case ADD_FATHER_ALGO:     // Algo just added in father
591           ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
592 //        if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))
593 //        if (anHyp->GetShapeType() == _subShape.ShapeType())
594           if (anHyp->GetShapeType() & (1<< _subShape.ShapeType()))
595             {
596               SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
597               ASSERT(algo);
598               ret = algo->CheckHypothesis((*_father),_subShape);
599               if (ret) SetAlgoState(HYP_OK);
600               else SetAlgoState(MISSING_HYP);
601             }
602           break;
603         case REMOVE_FATHER_HYP:    // nothing to do
604           break;
605         case REMOVE_FATHER_ALGO:   // nothing to do
606           break;
607         default:
608           ASSERT(0);
609           break;
610         }
611       break;
612
613       // ----------------------------------------------------------------------
614
615     case MISSING_HYP:
616       switch (event)
617         {
618         case ADD_HYP:
619           ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
620           ret = _meshDS->AddHypothesis(_subShape, anHyp);
621           if (ret)
622             {
623               SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
624               ASSERT(algo);
625               ret = algo->CheckHypothesis((*_father),_subShape);
626               if (ret) SetAlgoState(HYP_OK);
627               else SetAlgoState(MISSING_HYP);
628             }
629           break;
630         case ADD_ALGO:            //already existing algo : on father ?
631           ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
632           if (anHyp->GetDim() <= SMESH_Gen::GetShapeDim(_subShape))
633             {
634               ret = _meshDS->AddHypothesis(_subShape, anHyp);
635 //            if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)))
636 //            if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType()))
637               if (ret &&(anHyp->GetShapeType() & (1<< _subShape.ShapeType())))
638                 {
639                   SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
640                   if (algo == NULL) // two algo on the same subShape...
641                     {
642                       MESSAGE("two algo on the same subshape not allowed");
643                       ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
644                       ret = false;
645                     }
646                   else
647                     {
648                       ret = algo->CheckHypothesis((*_father),_subShape);
649                       if (ret) SetAlgoState(HYP_OK);
650                       else SetAlgoState(MISSING_HYP);
651                     }
652                 }
653             }
654           break;
655         case REMOVE_HYP:
656           ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);  
657           ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
658           break;
659         case REMOVE_ALGO:         // perhaps a father algo applies ?
660           ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
661           ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
662 //        if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)))
663 //        if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType()))
664           if (ret &&(anHyp->GetShapeType() & (1<<_subShape.ShapeType())))
665             {
666               SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
667               if (algo == NULL)  // no more algo applying on subShape...
668                 {
669                   SetAlgoState(NO_ALGO);
670                 }
671               else
672                 {
673                   ret = algo->CheckHypothesis((*_father),_subShape);
674                   if (ret) SetAlgoState(HYP_OK);
675                   else SetAlgoState(MISSING_HYP);
676                 }
677             }
678           break;
679         case ADD_FATHER_HYP:
680           ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
681           {
682             SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
683             ASSERT(algo);
684             ret = algo->CheckHypothesis((*_father),_subShape);
685             if (ret) SetAlgoState(HYP_OK);
686             else SetAlgoState(MISSING_HYP);
687           }
688           break;
689         case ADD_FATHER_ALGO:     // detect if two algo of same dim on father
690           ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
691 //        if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))
692 //        if (anHyp->GetShapeType() == _subShape.ShapeType())
693           if (anHyp->GetShapeType() & (1<< _subShape.ShapeType()))
694             {
695               SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
696               if (algo == NULL)  // two applying algo on father
697                 {
698                   MESSAGE("two applying algo on fatherShape...");
699                   SetAlgoState(NO_ALGO);
700                 }
701               else
702                 {
703                   ret = algo->CheckHypothesis((*_father),_subShape);
704                   if (ret) SetAlgoState(HYP_OK);
705                   else SetAlgoState(MISSING_HYP);
706                 }
707             }
708           break;
709         case REMOVE_FATHER_HYP:    // nothing to do
710           break;
711         case REMOVE_FATHER_ALGO:
712           ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
713 //        if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))
714 //        if (anHyp->GetShapeType() == _subShape.ShapeType())
715           if (anHyp->GetShapeType() & (1<< _subShape.ShapeType()))
716             {
717               SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
718               if (algo == NULL)  // no more applying algo on father
719                 {
720                   SetAlgoState(NO_ALGO);
721                 }
722               else
723                 {
724                   ret = algo->CheckHypothesis((*_father),_subShape);
725                   if (ret) SetAlgoState(HYP_OK);
726                   else SetAlgoState(MISSING_HYP);
727                 }
728             }
729           break;
730         default:
731           ASSERT(0);
732           break;
733         }
734       break;
735
736       // ----------------------------------------------------------------------
737
738     case HYP_OK:
739       switch (event)
740         {
741         case ADD_HYP:
742           {
743             ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
744             SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
745             ASSERT(algo);
746             list<SMESHDS_Hypothesis*> originalUsedHyps
747               = algo->GetUsedHypothesis((*_father), _subShape); // copy
748             
749             ret = _meshDS->AddHypothesis(_subShape, anHyp);
750             if (ret)
751               {
752                 ret = algo->CheckHypothesis((*_father),_subShape);
753                 if (! ret) 
754                   {
755                     INFOS("two applying algo on the same shape not allowed");
756                     ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
757                     ret = false;
758                   }
759                 else  // compare SMESHDS_Hypothesis* lists (order important)
760                   {
761                     MESSAGE("---");
762                     const list<SMESHDS_Hypothesis*>& newUsedHyps
763                       = algo->GetUsedHypothesis((*_father), _subShape);
764                     modifiedHyp = (originalUsedHyps != newUsedHyps); 
765                   }
766               }
767           }
768           break;
769         case ADD_ALGO:            //already existing algo : on father ?
770           ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
771           if (anHyp->GetDim() <= SMESH_Gen::GetShapeDim(_subShape))
772             {
773               ret = _meshDS->AddHypothesis(_subShape, anHyp);
774 //            if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)))
775 //            if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType()))
776               if (ret &&(anHyp->GetShapeType() & (1<< _subShape.ShapeType())))
777                 {
778                   SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
779                   if (algo == NULL) // two algo on the same subShape...
780                     {
781                       INFOS("two algo on the same subshape not allowed");
782                       ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
783                       ret = false;
784                     }
785                   else
786                     {
787                       ret = algo->CheckHypothesis((*_father),_subShape);
788                       if (ret) SetAlgoState(HYP_OK);
789                       else SetAlgoState(MISSING_HYP);
790                     }
791                 }
792             }
793           break;
794         case REMOVE_HYP:
795           ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
796           ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
797           if (ret)
798             {
799               SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
800               ASSERT(algo);
801               ret = algo->CheckHypothesis((*_father),_subShape);
802               if (ret) SetAlgoState(HYP_OK);
803               else SetAlgoState(MISSING_HYP);
804               modifiedHyp = true;
805             }
806           break;
807         case REMOVE_ALGO:         // perhaps a father algo applies ?
808           ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
809           ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
810 //        if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)))
811 //        if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType()))
812           if (ret &&(anHyp->GetShapeType() & (1<< _subShape.ShapeType())))
813             {
814               SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
815               if (algo == NULL)   // no more algo applying on subShape...
816                 {
817                   SetAlgoState(NO_ALGO);
818                 }
819               else
820                 {
821                   ret = algo->CheckHypothesis((*_father),_subShape);
822                   if (ret) SetAlgoState(HYP_OK);
823                   else SetAlgoState(MISSING_HYP);
824                 }
825             }
826           break;
827         case ADD_FATHER_HYP:
828           ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
829           {
830             SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
831             ASSERT(algo);
832             ret = algo->CheckHypothesis((*_father),_subShape);
833             if (ret) SetAlgoState(HYP_OK);
834             else SetAlgoState(MISSING_HYP);
835           }
836           break;
837         case ADD_FATHER_ALGO:     // detect if two algo of same dim on father
838           ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
839 //        if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))
840 //        if (anHyp->GetShapeType() == _subShape.ShapeType())
841           if (anHyp->GetShapeType() & (1<< _subShape.ShapeType()))
842             {
843               SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
844               if (algo == NULL)  // two applying algo on father
845                 {
846                   MESSAGE("two applying algo on fatherShape...");
847                   SetAlgoState(NO_ALGO);
848                 }
849               else
850                 {
851                   ret = algo->CheckHypothesis((*_father),_subShape);
852                   if (ret) SetAlgoState(HYP_OK);
853                   else SetAlgoState(MISSING_HYP);
854                 }
855             }
856           break;
857         case REMOVE_FATHER_HYP:
858           ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
859           {
860             SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
861             ASSERT(algo);
862             ret = algo->CheckHypothesis((*_father),_subShape);
863             if (ret) SetAlgoState(HYP_OK);
864             else SetAlgoState(MISSING_HYP);
865           }
866           break;
867         case REMOVE_FATHER_ALGO:
868           ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
869 //        if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))
870 //        if (anHyp->GetShapeType() == _subShape.ShapeType())
871           if (anHyp->GetShapeType() & (1<< _subShape.ShapeType()))
872             {
873               SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
874               if (algo == NULL)  // no more applying algo on father
875                 {
876                   SetAlgoState(NO_ALGO);
877                 }
878               else
879                 {
880                   ret = algo->CheckHypothesis((*_father),_subShape);
881                   if (ret) SetAlgoState(HYP_OK);
882                   else SetAlgoState(MISSING_HYP);
883                 }
884             }
885           break;
886         default:
887           ASSERT(0);
888           break;
889         }
890       break;
891
892       // ----------------------------------------------------------------------
893
894     default:
895       ASSERT(0);
896       break;
897     }
898   //SCRUTE(_algoState);
899   if ((_algoState != _oldAlgoState) || modifiedHyp)
900     int retc = ComputeStateEngine(MODIF_ALGO_STATE);
901   return ret;
902 }
903
904 //=============================================================================
905 /*!
906  * 
907  */
908 //=============================================================================
909
910 void SMESH_subMesh::SetAlgoState(int state)
911 {
912   if (state != _oldAlgoState)
913 //     int retc = ComputeStateEngine(MODIF_ALGO_STATE);
914   _algoState = state;
915 }
916
917 //=============================================================================
918 /*!
919  * 
920  */
921 //=============================================================================
922
923 void SMESH_subMesh::SubMeshesAlgoStateEngine(int event,
924                                              SMESH_Hypothesis* anHyp)
925     throw (SALOME_Exception)
926 {
927   //MESSAGE("SMESH_subMesh::SubMeshesAlgoStateEngine");
928   int dim = SMESH_Gen::GetShapeDim(_subShape);
929   if (dim > 1)
930     {
931       const map<int, SMESH_subMesh*>& subMeshes = DependsOn();
932       
933       map<int, SMESH_subMesh*>::const_iterator itsub;
934       for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
935         {
936           SMESH_subMesh* sm = (*itsub).second;
937           sm->AlgoStateEngine(event, anHyp);
938         }
939     }
940 }
941
942 //=============================================================================
943 /*!
944  * 
945  */
946 //=============================================================================
947
948 void SMESH_subMesh::DumpAlgoState(bool isMain)
949 {
950   int dim = SMESH_Gen::GetShapeDim(_subShape);
951 //   if (dim < 1) return;
952   if (isMain)
953     {
954       const map<int, SMESH_subMesh*>& subMeshes = DependsOn();
955       
956       map<int, SMESH_subMesh*>::const_iterator itsub;
957       for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
958         {
959           SMESH_subMesh* sm = (*itsub).second;
960           sm->DumpAlgoState(false);
961         } 
962     }
963   int type = _subShape.ShapeType();
964   MESSAGE("dim = " << dim << " type of shape " << type);
965   switch(_algoState)
966     {
967     case NO_ALGO: MESSAGE(" AlgoState = NO_ALGO"); break;
968     case MISSING_HYP: MESSAGE(" AlgoState = MISSING_HYP"); break;
969     case HYP_OK: MESSAGE(" AlgoState = HYP_OK"); break;
970     }
971   switch (_computeState)
972     {
973     case NOT_READY: MESSAGE(" ComputeState = NOT_READY"); break;
974     case READY_TO_COMPUTE: MESSAGE(" ComputeState = READY_TO_COMPUTE"); break;
975     case COMPUTE_OK: MESSAGE(" ComputeState = COMPUTE_OK"); break;
976     case FAILED_TO_COMPUTE: MESSAGE(" ComputeState = FAILED_TO_COMPUTE");break;
977     }
978 }
979
980 //=============================================================================
981 /*!
982  * 
983  */
984 //=============================================================================
985
986 bool SMESH_subMesh::ComputeStateEngine(int event)
987   throw (SALOME_Exception)
988 {
989   //MESSAGE("SMESH_subMesh::ComputeStateEngine");
990   //SCRUTE(_computeState);
991   //SCRUTE(event);
992
993   int dim = SMESH_Gen::GetShapeDim(_subShape);
994
995   if (dim < 1)
996     {
997       if (_vertexSet) _computeState = COMPUTE_OK;
998       else _computeState = READY_TO_COMPUTE;
999       //SCRUTE(_computeState);
1000       return true;
1001     }
1002   SMESH_Gen* gen =_father->GetGen();
1003   SMESH_Algo* algo = 0;
1004   bool ret;
1005
1006   switch(_computeState)
1007     {
1008
1009       // ----------------------------------------------------------------------
1010
1011     case NOT_READY:
1012       switch (event)
1013         {
1014         case MODIF_HYP:                // nothing to do
1015           break;
1016         case MODIF_ALGO_STATE:
1017           if (_algoState == HYP_OK)
1018             _computeState = READY_TO_COMPUTE;
1019           break;
1020         case COMPUTE:                  // nothing to do
1021           break;
1022         case CLEAN:                    // nothing to do
1023           break;
1024         case CLEANDEP:                 // nothing to do
1025           RemoveSubMeshElementsAndNodes(); // recursive call...
1026           break;
1027         case SUBMESH_COMPUTED:         // nothing to do
1028           break;
1029         default:
1030           ASSERT(0);
1031           break;
1032         }
1033       break;
1034
1035       // ----------------------------------------------------------------------
1036
1037     case READY_TO_COMPUTE:
1038       switch (event)
1039         {
1040         case MODIF_HYP:                // nothing to do
1041           break;
1042         case MODIF_ALGO_STATE:
1043           _computeState = NOT_READY;
1044           algo = gen->GetAlgo((*_father), _subShape);
1045           if (algo)
1046             {
1047               ret = algo->CheckHypothesis((*_father),_subShape);
1048               if (ret) _computeState = READY_TO_COMPUTE;
1049             }
1050           break;
1051         case COMPUTE:
1052           {
1053             algo = gen->GetAlgo((*_father), _subShape);
1054             ASSERT(algo);
1055             ret = algo->CheckHypothesis((*_father),_subShape);
1056             if (! ret)
1057               {
1058                 MESSAGE("***** verify compute state *****");
1059                 _computeState = NOT_READY;
1060                 break;
1061               }
1062             ret = SubMeshesComputed();
1063             if (!ret)
1064               {
1065                 MESSAGE("Some SubMeshes not computed");
1066                 _computeState = FAILED_TO_COMPUTE;
1067                 break;
1068               }
1069             ret = algo->Compute((*_father),_subShape);
1070             if (!ret)
1071               {
1072                 MESSAGE("problem in algo execution: failed to compute");
1073                 _computeState = FAILED_TO_COMPUTE;
1074                 break;
1075               }
1076             else
1077               {
1078                 _computeState = COMPUTE_OK;
1079                 UpdateDependantsState(); // send event SUBMESH_COMPUTED
1080               }
1081           }
1082           break;
1083         case CLEAN:
1084           _computeState = NOT_READY;
1085           algo = gen->GetAlgo((*_father), _subShape);
1086           if (algo)
1087             {
1088               ret = algo->CheckHypothesis((*_father),_subShape);
1089               if (ret) _computeState = READY_TO_COMPUTE;
1090             }
1091           break;
1092         case CLEANDEP:
1093           RemoveSubMeshElementsAndNodes();
1094           _computeState = NOT_READY;
1095           algo = gen->GetAlgo((*_father), _subShape);
1096           if (algo)
1097             {
1098               ret = algo->CheckHypothesis((*_father),_subShape);
1099               if (ret) _computeState = READY_TO_COMPUTE;
1100             }
1101           break;
1102         case SUBMESH_COMPUTED:         // nothing to do
1103           break;
1104         default:
1105           ASSERT(0);
1106           break;
1107         }
1108       break;
1109
1110       // ----------------------------------------------------------------------
1111
1112     case COMPUTE_OK:
1113       switch (event)
1114         {
1115         case MODIF_HYP:
1116           CleanDependants();           // recursive recall with event CLEANDEP
1117           break;
1118         case MODIF_ALGO_STATE:
1119           CleanDependants();           // recursive recall with event CLEANDEP
1120           break;
1121         case COMPUTE:                  // nothing to do
1122           break;
1123         case CLEAN:
1124           CleanDependants();           // recursive recall with event CLEANDEP
1125           break;
1126         case CLEANDEP:
1127           RemoveSubMeshElementsAndNodes();
1128           _computeState = NOT_READY;
1129           algo = gen->GetAlgo((*_father), _subShape);
1130           if (algo)
1131             {
1132               ret = algo->CheckHypothesis((*_father),_subShape);
1133               if (ret) _computeState = READY_TO_COMPUTE;
1134             }
1135           break;
1136         case SUBMESH_COMPUTED:         // nothing to do
1137           break;
1138         default:
1139           ASSERT(0);
1140           break;
1141         }
1142       break;
1143
1144       // ----------------------------------------------------------------------
1145
1146     case FAILED_TO_COMPUTE:
1147       switch (event)
1148         {
1149         case MODIF_HYP:
1150           if (_algoState == HYP_OK)
1151             _computeState = READY_TO_COMPUTE;
1152           else _computeState = NOT_READY;
1153           break;
1154         case MODIF_ALGO_STATE:
1155           if (_algoState == HYP_OK)
1156             _computeState = READY_TO_COMPUTE;
1157           else _computeState = NOT_READY;
1158           break;
1159         case COMPUTE:                  // nothing to do
1160           break;
1161         case CLEAN:
1162           break;
1163         case CLEANDEP:
1164           RemoveSubMeshElementsAndNodes();
1165           if (_algoState == HYP_OK)
1166             _computeState = READY_TO_COMPUTE;
1167           else _computeState = NOT_READY;
1168           break;
1169         case SUBMESH_COMPUTED:         // allow retry compute
1170           if (_algoState == HYP_OK)
1171             _computeState = READY_TO_COMPUTE;
1172           else _computeState = NOT_READY;
1173           break;
1174         default:
1175           ASSERT(0);
1176           break;
1177         }
1178       break;
1179
1180       // ----------------------------------------------------------------------
1181     default:
1182       ASSERT(0);
1183       break;
1184     }
1185
1186   //SCRUTE(_computeState);
1187   return ret;
1188 }
1189
1190 //=============================================================================
1191 /*!
1192  * 
1193  */
1194 //=============================================================================
1195
1196 void SMESH_subMesh::UpdateDependantsState()
1197 {
1198   //MESSAGE("SMESH_subMesh::UpdateDependantsState");
1199
1200   const map<int, SMESH_subMesh*>& dependants = Dependants();
1201   map<int, SMESH_subMesh*>::const_iterator its;
1202   for (its = dependants.begin(); its != dependants.end(); its++)
1203     {
1204       SMESH_subMesh* sm = (*its).second;
1205       //SCRUTE((*its).first);
1206       sm->ComputeStateEngine(SUBMESH_COMPUTED);
1207     }
1208 }
1209
1210 //=============================================================================
1211 /*!
1212  * 
1213  */
1214 //=============================================================================
1215
1216 void SMESH_subMesh::CleanDependants()
1217 {
1218   MESSAGE("SMESH_subMesh::CleanDependants");
1219   // **** parcourir les ancetres dans l'ordre de dépendance
1220
1221   const map<int, SMESH_subMesh*>& dependants = Dependants();
1222   map<int, SMESH_subMesh*>::const_iterator its;
1223   for (its = dependants.begin(); its != dependants.end(); its++)
1224     {
1225       SMESH_subMesh* sm = (*its).second;
1226       SCRUTE((*its).first);
1227       sm->ComputeStateEngine(CLEANDEP);
1228     }
1229   ComputeStateEngine(CLEANDEP);
1230 }
1231 //=============================================================================
1232 /*!
1233  * 
1234  */
1235 //=============================================================================
1236
1237 void SMESH_subMesh::RemoveSubMeshElementsAndNodes()
1238 {
1239   MESSAGE("SMESH_subMesh::RemoveSubMeshElementsAndNodes");
1240   SCRUTE(_subShape.ShapeType());
1241   SCRUTE(_Id);
1242
1243   _subMeshDS =  _meshDS->MeshElements(_subShape);
1244   if (!_subMeshDS.IsNull())
1245     {
1246       const TColStd_ListOfInteger& indElt
1247         = _subMeshDS->GetIDElements();
1248       TColStd_ListIteratorOfListOfInteger ite(indElt);
1249       for (; ite.More(); ite.Next())
1250         {
1251           int eltId = ite.Value();
1252           SCRUTE(eltId);
1253           Handle (SMDS_MeshElement) elt = _meshDS->FindElement(eltId);
1254           _subMeshDS->RemoveElement(elt);
1255           _meshDS->RemoveElement(eltId);
1256         }
1257   
1258       const TColStd_ListOfInteger& indNodes
1259         = _subMeshDS->GetIDNodes();
1260       TColStd_ListIteratorOfListOfInteger itn(indNodes);
1261       for (; itn.More(); itn.Next())
1262         {
1263           int nodeId = itn.Value();
1264           SCRUTE(nodeId);
1265           Handle (SMDS_MeshElement) elt = _meshDS->FindNode(nodeId);
1266           Handle (SMDS_MeshNode) node = _meshDS->GetNode(1, elt);
1267           _subMeshDS->RemoveNode(node);
1268           _meshDS->RemoveNode(nodeId);
1269         }
1270     }
1271 }
1272
1273 //=============================================================================
1274 /*!
1275  * 
1276  */
1277 //=============================================================================
1278
1279 const map<int, SMESH_subMesh*>& SMESH_subMesh::Dependants()
1280 {
1281   if (_dependantsFound) return _mapDependants;
1282
1283   //MESSAGE("SMESH_subMesh::Dependants");
1284
1285   int shapeType = _subShape.ShapeType();
1286   //SCRUTE(shapeType);
1287   TopTools_IndexedDataMapOfShapeListOfShape M;
1288   TopoDS_Shape mainShape = _meshDS->ShapeToMesh();
1289
1290   switch (shapeType)
1291     {
1292     case TopAbs_VERTEX:
1293       break;
1294     case TopAbs_EDGE:
1295     case TopAbs_WIRE:
1296       TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_WIRE, M);
1297       TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_FACE, M);
1298       TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_SHELL, M);
1299       TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_SOLID, M);
1300       TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_COMPSOLID, M);
1301       ExtractDependants(M, TopAbs_EDGE);
1302       break;
1303     case TopAbs_FACE:
1304     case TopAbs_SHELL:
1305       TopExp::MapShapesAndAncestors(mainShape, TopAbs_FACE, TopAbs_SHELL, M);
1306       TopExp::MapShapesAndAncestors(mainShape, TopAbs_FACE, TopAbs_SOLID, M);
1307       TopExp::MapShapesAndAncestors(mainShape, TopAbs_FACE, TopAbs_COMPSOLID, M);
1308       ExtractDependants(M, TopAbs_FACE);
1309       break;
1310     case TopAbs_SOLID:
1311     case TopAbs_COMPSOLID:
1312       TopExp::MapShapesAndAncestors(mainShape, TopAbs_SOLID, TopAbs_COMPSOLID, M);
1313       ExtractDependants(M, TopAbs_SOLID);
1314       break;
1315      case TopAbs_COMPOUND:
1316       break;
1317    }
1318
1319   _dependantsFound = true;
1320   return _mapDependants;
1321 }
1322
1323 //=============================================================================
1324 /*!
1325  * 
1326  */
1327 //=============================================================================
1328
1329 void SMESH_subMesh::ExtractDependants(const TopTools_IndexedDataMapOfShapeListOfShape& M,
1330                                       const TopAbs_ShapeEnum etype)
1331 {
1332   //MESSAGE("SMESH_subMesh::ExtractDependants");
1333
1334   TopoDS_Shape mainShape = _meshDS->ShapeToMesh();
1335   int lg = M.Extent();
1336   //SCRUTE(lg);
1337
1338   int shapeType = _subShape.ShapeType();
1339   switch (shapeType)
1340     {
1341     case TopAbs_VERTEX:
1342       break;
1343     case TopAbs_EDGE:
1344     case TopAbs_FACE:
1345     case TopAbs_SOLID:
1346       {
1347         const TopTools_ListOfShape& ancestors = M.FindFromKey(_subShape);
1348         TopTools_ListIteratorOfListOfShape it(ancestors);
1349         for ( ; it.More();it.Next())
1350           {
1351             TopoDS_Shape ancestor = it.Value();
1352             SMESH_subMesh* aSubMesh = _father->GetSubMeshContaining(ancestor);
1353             //      if (! aSubMesh) aSubMesh = _father->GetSubMesh(ancestor);
1354             if (aSubMesh)
1355               {
1356                 int type = aSubMesh->_subShape.ShapeType();
1357                 int cle = aSubMesh->GetId();
1358                 cle += 10000000 * type; // sort map by ordType then index
1359                 if (_mapDependants.find(cle) == _mapDependants.end())
1360                   {
1361                     _mapDependants[cle] = aSubMesh;
1362                     //SCRUTE(cle);
1363                   }
1364               } 
1365           }
1366       }
1367       break;
1368     case TopAbs_WIRE:
1369     case TopAbs_SHELL:
1370     case TopAbs_COMPSOLID:
1371       for (TopExp_Explorer expE(_subShape, etype); expE.More(); expE.Next())
1372         {
1373           TopoDS_Shape aShape = expE.Current();
1374           const TopTools_ListOfShape& ancestors = M.FindFromKey( aShape);
1375           TopTools_ListIteratorOfListOfShape it(ancestors);
1376           for ( ; it.More();it.Next())
1377             {
1378               MESSAGE("---");
1379               TopoDS_Shape ancestor = it.Value();
1380               SMESH_subMesh* aSubMesh = _father->GetSubMeshContaining(ancestor);
1381               if (! aSubMesh) aSubMesh = _father->GetSubMesh(ancestor);
1382               int type = aSubMesh->_subShape.ShapeType();
1383               int cle = aSubMesh->GetId();
1384               cle += 10000000 * type; // sort map by ordType then index
1385               if (_mapDependants.find(cle) == _mapDependants.end())
1386                 {
1387                   _mapDependants[cle] = aSubMesh;
1388                   SCRUTE(cle);
1389                 }
1390             }   
1391         } 
1392       break;
1393      case TopAbs_COMPOUND:
1394       break;
1395    }
1396 }
1397