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