1 // SMESH SMESH : implementaion of SMESH idl descriptions
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : SMESH_subMesh.cxx
25 // Author : Paul RASCLE, EDF
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"
39 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
40 #include <TopTools_ListOfShape.hxx>
41 #include <TopTools_ListIteratorOfListOfShape.hxx>
42 #include <TColStd_ListIteratorOfListOfInteger.hxx>
44 //=============================================================================
46 * default constructor:
48 //=============================================================================
50 SMESH_subMesh::SMESH_subMesh(int Id, SMESH_Mesh * father, SMESHDS_Mesh * meshDS,
51 const TopoDS_Shape & aSubShape)
53 //MESSAGE("SMESH_subMesh::SMESH_subMesh");
54 _subShape = aSubShape;
56 _subMeshDS = meshDS->MeshElements(_subShape); // may be null ...
59 _vertexSet = false; // only for Vertex subMesh
60 _dependenceAnalysed = false;
61 _dependantsFound = false;
63 if (_subShape.ShapeType() == TopAbs_VERTEX)
66 _computeState = READY_TO_COMPUTE;
71 _computeState = NOT_READY;
75 //=============================================================================
79 //=============================================================================
81 SMESH_subMesh::~SMESH_subMesh()
83 MESSAGE("SMESH_subMesh::~SMESH_subMesh");
87 //=============================================================================
91 //=============================================================================
93 int SMESH_subMesh::GetId()
95 //MESSAGE("SMESH_subMesh::GetId");
99 //=============================================================================
101 * Given a subShape, find the subMesh is associated to this subShape or
102 * to a collection of shapes containing this subShape. Collection = compsolid,
105 //=============================================================================
107 // bool SMESH_subMesh::Contains(const TopoDS_Shape & aSubShape)
108 // throw (SALOME_Exception)
110 // //MESSAGE("SMESH_subMesh::Contains");
111 // bool contains = false;
112 // int type = _subShape.ShapeType();
113 // int typesub = aSubShape.ShapeType();
118 // // case TopAbs_COMPOUND:
120 // // //MESSAGE("---");
121 // // throw SALOME_Exception(LOCALIZED("Compound not yet treated"));
124 // case TopAbs_COMPSOLID:
127 // for (TopExp_Explorer exp(aSubShape,TopAbs_SOLID);exp.More();exp.Next())
129 // contains = _subShape.IsSame(exp.Current());
130 // if (contains) break;
134 // case TopAbs_SHELL:
137 // for (TopExp_Explorer exp(aSubShape,TopAbs_FACE);exp.More();exp.Next())
139 // contains = _subShape.IsSame(exp.Current());
140 // if (contains) break;
147 // for (TopExp_Explorer exp(aSubShape,TopAbs_EDGE);exp.More();exp.Next())
149 // contains = _subShape.IsSame(exp.Current());
150 // if (contains) break;
154 // case TopAbs_COMPOUND:
155 // case TopAbs_SOLID:
158 // case TopAbs_VERTEX:
161 // contains = _subShape.IsSame(aSubShape);
169 // //SCRUTE(contains);
173 //=============================================================================
177 //=============================================================================
179 SMESHDS_SubMesh * SMESH_subMesh::GetSubMeshDS() throw(SALOME_Exception)
181 //MESSAGE("SMESH_subMesh::GetSubMeshDS");
182 if (_subMeshDS==NULL)
184 //MESSAGE("subMesh pointer still null, trying to get it...");
185 _subMeshDS = _meshDS->MeshElements(_subShape); // may be null ...
186 if (_subMeshDS==NULL)
188 MESSAGE("problem... subMesh still empty");
190 //NRI throw SALOME_Exception(LOCALIZED(subMesh still empty));
196 //=============================================================================
200 //=============================================================================
202 SMESH_subMesh *SMESH_subMesh::GetFirstToCompute() throw(SALOME_Exception)
204 //MESSAGE("SMESH_subMesh::GetFirstToCompute");
205 const map < int, SMESH_subMesh * >&subMeshes = DependsOn();
206 SMESH_subMesh *firstToCompute = 0;
208 map < int, SMESH_subMesh * >::const_iterator itsub;
209 for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
211 SMESH_subMesh *sm = (*itsub).second;
212 // SCRUTE(sm->GetId());
213 // SCRUTE(sm->GetComputeState());
214 bool readyToCompute = (sm->GetComputeState() == READY_TO_COMPUTE);
218 //SCRUTE(sm->GetId());
224 //MESSAGE("--- submesh to compute");
225 return firstToCompute; // a subMesh of this
227 if (_computeState == READY_TO_COMPUTE)
229 //MESSAGE("--- this to compute");
232 //MESSAGE("--- nothing to compute");
233 return 0; // nothing to compute
236 //=============================================================================
240 //=============================================================================
242 bool SMESH_subMesh::SubMeshesComputed() throw(SALOME_Exception)
244 //MESSAGE("SMESH_subMesh::SubMeshesComputed");
245 const map < int, SMESH_subMesh * >&subMeshes = DependsOn();
247 bool subMeshesComputed = true;
248 map < int, SMESH_subMesh * >::const_iterator itsub;
249 for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
251 SMESH_subMesh *sm = (*itsub).second;
252 // SCRUTE(sm->GetId());
253 // SCRUTE(sm->GetComputeState());
254 bool computeOk = (sm->GetComputeState() == COMPUTE_OK);
257 subMeshesComputed = false;
262 return subMeshesComputed;
265 //=============================================================================
269 //=============================================================================
271 bool SMESH_subMesh::SubMeshesReady()
273 MESSAGE("SMESH_subMesh::SubMeshesReady");
274 const map < int, SMESH_subMesh * >&subMeshes = DependsOn();
276 bool subMeshesReady = true;
277 map < int, SMESH_subMesh * >::const_iterator itsub;
278 for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
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));
287 subMeshesReady = false;
292 return subMeshesReady;
295 //=============================================================================
297 * Construct dependence on first level subMeshes. complex shapes (compsolid,
298 * shell, wire) are not analysed the same way as simple shapes (solid, face,
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.
305 //=============================================================================
307 const map < int, SMESH_subMesh * >&SMESH_subMesh::DependsOn()
309 if (_dependenceAnalysed)
312 //MESSAGE("SMESH_subMesh::DependsOn");
314 int type = _subShape.ShapeType();
318 case TopAbs_COMPOUND:
320 //MESSAGE("compound");
321 list < TopoDS_Shape > shellInSolid;
322 for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More();
325 InsertDependence(exp.Current());
327 exp2(exp.Current(), TopAbs_SHELL); exp2.More(); exp2.Next())
329 shellInSolid.push_back(exp2.Current());
332 for (TopExp_Explorer exp(_subShape, TopAbs_SHELL); exp.More();
335 list < TopoDS_Shape >::iterator it1;
336 bool isInSolid = false;
337 for (it1 = shellInSolid.begin(); it1 != shellInSolid.end(); it1++)
339 TopoDS_Shape aShape = (*it1);
340 if (aShape.IsSame(exp.Current()))
347 InsertDependence(exp.Current()); //only shell not in solid
349 for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More();
352 InsertDependence(exp.Current());
354 for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More();
357 InsertDependence(exp.Current());
361 case TopAbs_COMPSOLID:
363 //MESSAGE("compsolid");
364 for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More();
367 InsertDependence(exp.Current());
369 // list<TopoDS_Shape> shapeList;
370 // for (TopExp_Explorer exp(_subShape,TopAbs_SOLID);exp.More();exp.Next())
372 // for (TopExp_Explorer
373 // exp2(exp.Current(),TopAbs_FACE);exp2.More();exp2.Next())
375 // shapeList.push_back(exp2.Current());
378 // FinalizeDependence(shapeList);
384 for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More();
387 InsertDependence(exp.Current());
389 // list<TopoDS_Shape> shapeList;
390 // for (TopExp_Explorer exp(_subShape,TopAbs_FACE);exp.More();exp.Next())
392 // for (TopExp_Explorer
393 // exp2(exp.Current(),TopAbs_EDGE);exp2.More();exp2.Next())
395 // shapeList.push_back(exp2.Current());
398 // FinalizeDependence(shapeList);
404 for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More();
407 InsertDependence(exp.Current());
409 // list<TopoDS_Shape> shapeList;
410 // for (TopExp_Explorer exp(_subShape,TopAbs_EDGE);exp.More();exp.Next())
412 // for (TopExp_Explorer
413 // exp2(exp.Current(),TopAbs_VERTEX);exp2.More();exp2.Next())
415 // shapeList.push_back(exp2.Current());
418 // FinalizeDependence(shapeList);
424 // for (TopExp_Explorer exp(_subShape,TopAbs_SHELL);exp.More();exp.Next())
426 // InsertDependence(exp.Current());
428 for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More();
431 InsertDependence(exp.Current());
438 // for (TopExp_Explorer exp(_subShape,TopAbs_WIRE);exp.More();exp.Next())
440 // InsertDependence(exp.Current());
442 for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More();
445 InsertDependence(exp.Current());
452 for (TopExp_Explorer exp(_subShape, TopAbs_VERTEX); exp.More();
455 InsertDependence(exp.Current());
468 _dependenceAnalysed = true;
472 //=============================================================================
474 * For simple Shapes (solid, face, edge): add subMesh into dependence list.
476 //=============================================================================
478 void SMESH_subMesh::InsertDependence(const TopoDS_Shape aSubShape)
480 //MESSAGE("SMESH_subMesh::InsertDependence");
481 //SMESH_subMesh* aSubMesh = _father->GetSubMeshContaining(aSubShape);
483 //if (! aSubMesh) aSubMesh = _father->GetSubMesh(aSubShape);
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())
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++)
497 int clesub = (*im).first;
498 SMESH_subMesh *sm = (*im).second;
499 if (_mapDepend.find(clesub) == _mapDepend.end())
500 _mapDepend[clesub] = sm;
506 //=============================================================================
508 * For collection shapes (compsolid, shell, wire).
509 * Add only subMesh figuring only once in multiset to dependence list
511 //=============================================================================
513 // void SMESH_subMesh::FinalizeDependence(list<TopoDS_Shape>& shapeList)
515 // //MESSAGE("SMESH_subMesh::FinalizeDependence");
516 // list<TopoDS_Shape>::iterator it1, it2;
517 // for(it1 = shapeList.begin(); it1 != shapeList.end(); it1++)
519 // TopoDS_Shape aSubShape = (*it1);
521 // for(it2 = shapeList.begin(); it2 != shapeList.end(); it2++)
523 // TopoDS_Shape other = (*it2);
524 // if (other.IsSame(aSubShape)) count++;
526 // if (count == 1) InsertDependence(aSubShape);
531 //=============================================================================
535 //=============================================================================
537 const TopoDS_Shape & SMESH_subMesh::GetSubShape()
539 //MESSAGE("SMESH_subMesh::GetSubShape");
543 //=============================================================================
547 //=============================================================================
549 bool SMESH_subMesh::AlgoStateEngine(int event, SMESH_Hypothesis * anHyp)
550 throw(SALOME_Exception)
552 // MESSAGE("SMESH_subMesh::AlgoStateEngine");
553 //SCRUTE(_algoState);
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);
564 //SCRUTE(_algoState);
568 SMESH_Gen *gen = _father->GetGen();
570 _oldAlgoState = _algoState;
571 bool modifiedHyp = false; // if set to true, force event MODIF_ALGO_STATE
572 // in ComputeStateEngine
577 // ----------------------------------------------------------------------
583 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
584 ret = _meshDS->AddHypothesis(_subShape, anHyp);
587 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
588 if (anHyp->GetDim() <= SMESH_Gen::GetShapeDim(_subShape))
590 ret = _meshDS->AddHypothesis(_subShape, anHyp);
591 // if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)))
592 // if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType()))
594 (anHyp->GetShapeType() & (1 << _subShape.ShapeType())))
596 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
598 ret = algo->CheckHypothesis((*_father), _subShape);
600 SetAlgoState(HYP_OK);
602 SetAlgoState(MISSING_HYP);
607 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
608 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
611 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
612 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
614 case ADD_FATHER_HYP: // nothing to do
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()))
622 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
624 ret = algo->CheckHypothesis((*_father), _subShape);
626 SetAlgoState(HYP_OK);
628 SetAlgoState(MISSING_HYP);
631 case REMOVE_FATHER_HYP: // nothing to do
633 case REMOVE_FATHER_ALGO: // nothing to do
641 // ----------------------------------------------------------------------
647 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
648 ret = _meshDS->AddHypothesis(_subShape, anHyp);
651 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
653 ret = algo->CheckHypothesis((*_father), _subShape);
655 SetAlgoState(HYP_OK);
657 SetAlgoState(MISSING_HYP);
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))
664 ret = _meshDS->AddHypothesis(_subShape, anHyp);
665 // if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)))
666 // if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType()))
668 (anHyp->GetShapeType() & (1 << _subShape.ShapeType())))
670 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
671 if (algo == NULL) // two algo on the same subShape...
673 MESSAGE("two algo on the same subshape not allowed");
674 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
679 ret = algo->CheckHypothesis((*_father), _subShape);
681 SetAlgoState(HYP_OK);
683 SetAlgoState(MISSING_HYP);
689 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
690 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
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())))
699 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
700 if (algo == NULL) // no more algo applying on subShape...
702 SetAlgoState(NO_ALGO);
706 ret = algo->CheckHypothesis((*_father), _subShape);
708 SetAlgoState(HYP_OK);
710 SetAlgoState(MISSING_HYP);
715 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
717 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
719 ret = algo->CheckHypothesis((*_father), _subShape);
721 SetAlgoState(HYP_OK);
723 SetAlgoState(MISSING_HYP);
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()))
732 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
733 if (algo == NULL) // two applying algo on father
735 MESSAGE("two applying algo on fatherShape...");
736 SetAlgoState(NO_ALGO);
740 ret = algo->CheckHypothesis((*_father), _subShape);
742 SetAlgoState(HYP_OK);
744 SetAlgoState(MISSING_HYP);
748 case REMOVE_FATHER_HYP: // nothing to do
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()))
756 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
757 if (algo == NULL) // no more applying algo on father
759 SetAlgoState(NO_ALGO);
763 ret = algo->CheckHypothesis((*_father), _subShape);
765 SetAlgoState(HYP_OK);
767 SetAlgoState(MISSING_HYP);
777 // ----------------------------------------------------------------------
784 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
785 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
787 list<const SMESHDS_Hypothesis *> originalUsedHyps = algo->GetUsedHypothesis((*_father), _subShape); // copy
789 ret = _meshDS->AddHypothesis(_subShape, anHyp);
792 ret = algo->CheckHypothesis((*_father), _subShape);
795 INFOS("two applying algo on the same shape not allowed");
796 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
799 else // compare SMESHDS_Hypothesis* lists (order important)
802 const list <const SMESHDS_Hypothesis *> & newUsedHyps
803 = algo->GetUsedHypothesis((*_father), _subShape);
804 modifiedHyp = (originalUsedHyps != newUsedHyps);
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))
813 ret = _meshDS->AddHypothesis(_subShape, anHyp);
814 // if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)))
815 // if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType()))
817 (anHyp->GetShapeType() & (1 << _subShape.ShapeType())))
819 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
820 if (algo == NULL) // two algo on the same subShape...
822 INFOS("two algo on the same subshape not allowed");
823 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
828 ret = algo->CheckHypothesis((*_father), _subShape);
830 SetAlgoState(HYP_OK);
832 SetAlgoState(MISSING_HYP);
838 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
839 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
842 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
844 ret = algo->CheckHypothesis((*_father), _subShape);
846 SetAlgoState(HYP_OK);
848 SetAlgoState(MISSING_HYP);
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())))
859 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
860 if (algo == NULL) // no more algo applying on subShape...
862 SetAlgoState(NO_ALGO);
866 ret = algo->CheckHypothesis((*_father), _subShape);
868 SetAlgoState(HYP_OK);
870 SetAlgoState(MISSING_HYP);
875 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
877 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
879 ret = algo->CheckHypothesis((*_father), _subShape);
881 SetAlgoState(HYP_OK);
883 SetAlgoState(MISSING_HYP);
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()))
892 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
893 if (algo == NULL) // two applying algo on father
895 MESSAGE("two applying algo on fatherShape...");
896 SetAlgoState(NO_ALGO);
900 ret = algo->CheckHypothesis((*_father), _subShape);
902 SetAlgoState(HYP_OK);
904 SetAlgoState(MISSING_HYP);
908 case REMOVE_FATHER_HYP:
909 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
911 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
913 ret = algo->CheckHypothesis((*_father), _subShape);
915 SetAlgoState(HYP_OK);
917 SetAlgoState(MISSING_HYP);
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()))
926 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
927 if (algo == NULL) // no more applying algo on father
929 SetAlgoState(NO_ALGO);
933 ret = algo->CheckHypothesis((*_father), _subShape);
935 SetAlgoState(HYP_OK);
937 SetAlgoState(MISSING_HYP);
947 // ----------------------------------------------------------------------
953 //SCRUTE(_algoState);
954 if ((_algoState != _oldAlgoState) || modifiedHyp)
955 int retc = ComputeStateEngine(MODIF_ALGO_STATE);
959 //=============================================================================
963 //=============================================================================
965 void SMESH_subMesh::SetAlgoState(int state)
967 if (state != _oldAlgoState)
968 // int retc = ComputeStateEngine(MODIF_ALGO_STATE);
972 //=============================================================================
976 //=============================================================================
978 void SMESH_subMesh::SubMeshesAlgoStateEngine(int event,
979 SMESH_Hypothesis * anHyp) throw(SALOME_Exception)
981 //MESSAGE("SMESH_subMesh::SubMeshesAlgoStateEngine");
982 int dim = SMESH_Gen::GetShapeDim(_subShape);
985 const map < int, SMESH_subMesh * >&subMeshes = DependsOn();
987 map < int, SMESH_subMesh * >::const_iterator itsub;
988 for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
990 SMESH_subMesh *sm = (*itsub).second;
991 sm->AlgoStateEngine(event, anHyp);
996 //=============================================================================
1000 //=============================================================================
1002 void SMESH_subMesh::DumpAlgoState(bool isMain)
1004 int dim = SMESH_Gen::GetShapeDim(_subShape);
1005 // if (dim < 1) return;
1008 const map < int, SMESH_subMesh * >&subMeshes = DependsOn();
1010 map < int, SMESH_subMesh * >::const_iterator itsub;
1011 for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
1013 SMESH_subMesh *sm = (*itsub).second;
1014 sm->DumpAlgoState(false);
1017 int type = _subShape.ShapeType();
1018 MESSAGE("dim = " << dim << " type of shape " << type);
1022 MESSAGE(" AlgoState = NO_ALGO");
1025 MESSAGE(" AlgoState = MISSING_HYP");
1028 MESSAGE(" AlgoState = HYP_OK");
1031 switch (_computeState)
1034 MESSAGE(" ComputeState = NOT_READY");
1036 case READY_TO_COMPUTE:
1037 MESSAGE(" ComputeState = READY_TO_COMPUTE");
1040 MESSAGE(" ComputeState = COMPUTE_OK");
1042 case FAILED_TO_COMPUTE:
1043 MESSAGE(" ComputeState = FAILED_TO_COMPUTE");
1048 //=============================================================================
1052 //=============================================================================
1054 bool SMESH_subMesh::ComputeStateEngine(int event) throw(SALOME_Exception)
1056 //MESSAGE("SMESH_subMesh::ComputeStateEngine");
1057 //SCRUTE(_computeState);
1060 int dim = SMESH_Gen::GetShapeDim(_subShape);
1065 _computeState = COMPUTE_OK;
1067 _computeState = READY_TO_COMPUTE;
1068 //SCRUTE(_computeState);
1071 SMESH_Gen *gen = _father->GetGen();
1072 SMESH_Algo *algo = 0;
1075 switch (_computeState)
1078 // ----------------------------------------------------------------------
1083 case MODIF_HYP: // nothing to do
1085 case MODIF_ALGO_STATE:
1086 if (_algoState == HYP_OK)
1087 _computeState = READY_TO_COMPUTE;
1089 case COMPUTE: // nothing to do
1091 case CLEAN: // nothing to do
1093 case CLEANDEP: // nothing to do
1094 RemoveSubMeshElementsAndNodes(); // recursive call...
1096 case SUBMESH_COMPUTED: // nothing to do
1104 // ----------------------------------------------------------------------
1106 case READY_TO_COMPUTE:
1109 case MODIF_HYP: // nothing to do
1111 case MODIF_ALGO_STATE:
1112 _computeState = NOT_READY;
1113 algo = gen->GetAlgo((*_father), _subShape);
1116 ret = algo->CheckHypothesis((*_father), _subShape);
1118 _computeState = READY_TO_COMPUTE;
1123 algo = gen->GetAlgo((*_father), _subShape);
1125 ret = algo->CheckHypothesis((*_father), _subShape);
1128 MESSAGE("***** verify compute state *****");
1129 _computeState = NOT_READY;
1132 ret = SubMeshesComputed();
1135 MESSAGE("Some SubMeshes not computed");
1136 _computeState = FAILED_TO_COMPUTE;
1139 ret = algo->Compute((*_father), _subShape);
1142 MESSAGE("problem in algo execution: failed to compute");
1143 _computeState = FAILED_TO_COMPUTE;
1148 _computeState = COMPUTE_OK;
1149 UpdateDependantsState(); // send event SUBMESH_COMPUTED
1154 _computeState = NOT_READY;
1155 algo = gen->GetAlgo((*_father), _subShape);
1158 ret = algo->CheckHypothesis((*_father), _subShape);
1160 _computeState = READY_TO_COMPUTE;
1164 RemoveSubMeshElementsAndNodes();
1165 _computeState = NOT_READY;
1166 algo = gen->GetAlgo((*_father), _subShape);
1169 ret = algo->CheckHypothesis((*_father), _subShape);
1171 _computeState = READY_TO_COMPUTE;
1174 case SUBMESH_COMPUTED: // nothing to do
1182 // ----------------------------------------------------------------------
1188 CleanDependants(); // recursive recall with event CLEANDEP
1190 case MODIF_ALGO_STATE:
1191 CleanDependants(); // recursive recall with event CLEANDEP
1193 case COMPUTE: // nothing to do
1196 CleanDependants(); // recursive recall with event CLEANDEP
1199 RemoveSubMeshElementsAndNodes();
1200 _computeState = NOT_READY;
1201 algo = gen->GetAlgo((*_father), _subShape);
1204 ret = algo->CheckHypothesis((*_father), _subShape);
1206 _computeState = READY_TO_COMPUTE;
1209 case SUBMESH_COMPUTED: // nothing to do
1217 // ----------------------------------------------------------------------
1219 case FAILED_TO_COMPUTE:
1223 if (_algoState == HYP_OK)
1224 _computeState = READY_TO_COMPUTE;
1226 _computeState = NOT_READY;
1228 case MODIF_ALGO_STATE:
1229 if (_algoState == HYP_OK)
1230 _computeState = READY_TO_COMPUTE;
1232 _computeState = NOT_READY;
1234 case COMPUTE: // nothing to do
1239 RemoveSubMeshElementsAndNodes();
1240 if (_algoState == HYP_OK)
1241 _computeState = READY_TO_COMPUTE;
1243 _computeState = NOT_READY;
1245 case SUBMESH_COMPUTED: // allow retry compute
1246 if (_algoState == HYP_OK)
1247 _computeState = READY_TO_COMPUTE;
1249 _computeState = NOT_READY;
1257 // ----------------------------------------------------------------------
1263 //SCRUTE(_computeState);
1267 //=============================================================================
1271 //=============================================================================
1273 void SMESH_subMesh::UpdateDependantsState()
1275 //MESSAGE("SMESH_subMesh::UpdateDependantsState");
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++)
1281 SMESH_subMesh *sm = (*its).second;
1282 //SCRUTE((*its).first);
1283 sm->ComputeStateEngine(SUBMESH_COMPUTED);
1287 //=============================================================================
1291 //=============================================================================
1293 void SMESH_subMesh::CleanDependants()
1295 MESSAGE("SMESH_subMesh::CleanDependants");
1296 // **** parcourir les ancetres dans l'ordre de dépendance
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++)
1302 SMESH_subMesh *sm = (*its).second;
1303 SCRUTE((*its).first);
1304 sm->ComputeStateEngine(CLEANDEP);
1306 ComputeStateEngine(CLEANDEP);
1309 //=============================================================================
1313 //=============================================================================
1315 void SMESH_subMesh::RemoveSubMeshElementsAndNodes()
1317 MESSAGE("SMESH_subMesh::RemoveSubMeshElementsAndNodes");
1318 SCRUTE(_subShape.ShapeType());
1321 _subMeshDS = _meshDS->MeshElements(_subShape);
1322 if (_subMeshDS!=NULL)
1324 SMDS_Iterator<const SMDS_MeshElement *> * ite=_subMeshDS->GetElements();
1327 const SMDS_MeshElement * elt = ite->next();
1328 _subMeshDS->RemoveElement(elt);
1329 _meshDS->RemoveElement(elt);
1333 SMDS_Iterator<const SMDS_MeshNode *> * itn=_subMeshDS->GetNodes();
1336 const SMDS_MeshNode * node = itn->next();
1337 _subMeshDS->RemoveNode(node);
1338 _meshDS->RemoveNode(node);
1344 //=============================================================================
1348 //=============================================================================
1350 const map < int, SMESH_subMesh * >&SMESH_subMesh::Dependants()
1352 if (_dependantsFound)
1353 return _mapDependants;
1355 //MESSAGE("SMESH_subMesh::Dependants");
1357 int shapeType = _subShape.ShapeType();
1358 //SCRUTE(shapeType);
1359 TopTools_IndexedDataMapOfShapeListOfShape M;
1360 TopoDS_Shape mainShape = _meshDS->ShapeToMesh();
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,
1374 ExtractDependants(M, TopAbs_EDGE);
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,
1382 ExtractDependants(M, TopAbs_FACE);
1385 case TopAbs_COMPSOLID:
1386 TopExp::MapShapesAndAncestors(mainShape, TopAbs_SOLID, TopAbs_COMPSOLID,
1388 ExtractDependants(M, TopAbs_SOLID);
1390 case TopAbs_COMPOUND:
1394 _dependantsFound = true;
1395 return _mapDependants;
1398 //=============================================================================
1402 //=============================================================================
1404 void SMESH_subMesh::
1405 ExtractDependants(const TopTools_IndexedDataMapOfShapeListOfShape & M,
1406 const TopAbs_ShapeEnum etype)
1408 //MESSAGE("SMESH_subMesh::ExtractDependants");
1410 TopoDS_Shape mainShape = _meshDS->ShapeToMesh();
1411 int lg = M.Extent();
1414 int shapeType = _subShape.ShapeType();
1423 const TopTools_ListOfShape & ancestors = M.FindFromKey(_subShape);
1424 TopTools_ListIteratorOfListOfShape it(ancestors);
1425 for (; it.More(); it.Next())
1427 TopoDS_Shape ancestor = it.Value();
1428 SMESH_subMesh *aSubMesh = _father->GetSubMeshContaining(ancestor);
1429 // if (! aSubMesh) aSubMesh = _father->GetSubMesh(ancestor);
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())
1437 _mapDependants[cle] = aSubMesh;
1446 case TopAbs_COMPSOLID:
1447 for (TopExp_Explorer expE(_subShape, etype); expE.More(); expE.Next())
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())
1455 TopoDS_Shape ancestor = it.Value();
1456 SMESH_subMesh *aSubMesh =
1457 _father->GetSubMeshContaining(ancestor);
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())
1465 _mapDependants[cle] = aSubMesh;
1471 case TopAbs_COMPOUND: