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