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