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
31 #include "SMESH_subMesh.hxx"
32 #include "SMESH_Gen.hxx"
33 #include "SMESH_Mesh.hxx"
34 #include "SMESH_Hypothesis.hxx"
35 #include "SMESH_Algo.hxx"
36 #include "utilities.h"
40 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
41 #include <TopTools_ListOfShape.hxx>
42 #include <TopTools_ListIteratorOfListOfShape.hxx>
43 #include <TColStd_ListIteratorOfListOfInteger.hxx>
45 //=============================================================================
47 * default constructor:
49 //=============================================================================
51 SMESH_subMesh::SMESH_subMesh(int Id,
53 const Handle(SMESHDS_Mesh)& meshDS,
54 const TopoDS_Shape & aSubShape)
56 //MESSAGE("SMESH_subMesh::SMESH_subMesh");
57 _subShape = aSubShape;
59 _subMeshDS = meshDS->MeshElements(_subShape); // may be null ...
62 _vertexSet = false; // only for Vertex subMesh
63 _dependenceAnalysed = false;
64 _dependantsFound = false;
66 if (_subShape.ShapeType() == TopAbs_VERTEX)
69 _computeState = READY_TO_COMPUTE;
74 _computeState = NOT_READY;
78 //=============================================================================
82 //=============================================================================
84 SMESH_subMesh::~SMESH_subMesh()
86 MESSAGE("SMESH_subMesh::~SMESH_subMesh");
90 //=============================================================================
94 //=============================================================================
96 int SMESH_subMesh::GetId()
98 //MESSAGE("SMESH_subMesh::GetId");
102 //=============================================================================
104 * Given a subShape, find the subMesh is associated to this subShape or
105 * to a collection of shapes containing this subShape. Collection = compsolid,
108 //=============================================================================
110 // bool SMESH_subMesh::Contains(const TopoDS_Shape & aSubShape)
111 // throw (SALOME_Exception)
113 // //MESSAGE("SMESH_subMesh::Contains");
114 // bool contains = false;
115 // int type = _subShape.ShapeType();
116 // int typesub = aSubShape.ShapeType();
121 // // case TopAbs_COMPOUND:
123 // // //MESSAGE("---");
124 // // throw SALOME_Exception(LOCALIZED("Compound not yet treated"));
127 // case TopAbs_COMPSOLID:
130 // for (TopExp_Explorer exp(aSubShape,TopAbs_SOLID);exp.More();exp.Next())
132 // contains = _subShape.IsSame(exp.Current());
133 // if (contains) break;
137 // case TopAbs_SHELL:
140 // for (TopExp_Explorer exp(aSubShape,TopAbs_FACE);exp.More();exp.Next())
142 // contains = _subShape.IsSame(exp.Current());
143 // if (contains) break;
150 // for (TopExp_Explorer exp(aSubShape,TopAbs_EDGE);exp.More();exp.Next())
152 // contains = _subShape.IsSame(exp.Current());
153 // if (contains) break;
157 // case TopAbs_COMPOUND:
158 // case TopAbs_SOLID:
161 // case TopAbs_VERTEX:
164 // contains = _subShape.IsSame(aSubShape);
172 // //SCRUTE(contains);
176 //=============================================================================
180 //=============================================================================
182 const Handle(SMESHDS_SubMesh)& SMESH_subMesh::GetSubMeshDS()
183 throw (SALOME_Exception)
185 //MESSAGE("SMESH_subMesh::GetSubMeshDS");
186 if (_subMeshDS.IsNull())
188 //MESSAGE("subMesh pointer still null, trying to get it...");
189 _subMeshDS = _meshDS->MeshElements(_subShape); // may be null ...
190 if (_subMeshDS.IsNull())
192 MESSAGE("problem... subMesh still empty");
194 //NRI throw SALOME_Exception(LOCALIZED(subMesh still empty));
200 //=============================================================================
204 //=============================================================================
206 SMESH_subMesh* SMESH_subMesh::GetFirstToCompute()
207 throw (SALOME_Exception)
209 //MESSAGE("SMESH_subMesh::GetFirstToCompute");
210 const map<int, SMESH_subMesh*>& subMeshes = DependsOn();
211 SMESH_subMesh* firstToCompute = 0;
213 map<int, SMESH_subMesh*>::const_iterator itsub;
214 for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
216 SMESH_subMesh* sm = (*itsub).second;
217 // SCRUTE(sm->GetId());
218 // SCRUTE(sm->GetComputeState());
219 bool readyToCompute = (sm->GetComputeState() == READY_TO_COMPUTE);
223 //SCRUTE(sm->GetId());
229 //MESSAGE("--- submesh to compute");
230 return firstToCompute; // a subMesh of this
232 if (_computeState == READY_TO_COMPUTE)
234 //MESSAGE("--- this to compute");
237 //MESSAGE("--- nothing to compute");
238 return 0; // nothing to compute
241 //=============================================================================
245 //=============================================================================
247 bool SMESH_subMesh::SubMeshesComputed()
248 throw (SALOME_Exception)
250 //MESSAGE("SMESH_subMesh::SubMeshesComputed");
251 const map<int, SMESH_subMesh*>& subMeshes = DependsOn();
253 bool subMeshesComputed = true;
254 map<int, SMESH_subMesh*>::const_iterator itsub;
255 for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
257 SMESH_subMesh* sm = (*itsub).second;
258 // SCRUTE(sm->GetId());
259 // SCRUTE(sm->GetComputeState());
260 bool computeOk = (sm->GetComputeState() == COMPUTE_OK);
263 subMeshesComputed = false;
268 return subMeshesComputed;
271 //=============================================================================
275 //=============================================================================
277 bool SMESH_subMesh::SubMeshesReady()
279 MESSAGE("SMESH_subMesh::SubMeshesReady");
280 const map<int, SMESH_subMesh*>& subMeshes = DependsOn();
282 bool subMeshesReady = true;
283 map<int, SMESH_subMesh*>::const_iterator itsub;
284 for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
286 SMESH_subMesh* sm = (*itsub).second;
287 // SCRUTE(sm->GetId());
288 // SCRUTE(sm->GetComputeState());
289 bool computeOk = ( (sm->GetComputeState() == COMPUTE_OK)
290 || (sm->GetComputeState() == READY_TO_COMPUTE)) ;
293 subMeshesReady = false;
298 return subMeshesReady;
301 //=============================================================================
303 * Construct dependence on first level subMeshes. complex shapes (compsolid,
304 * shell, wire) are not analysed the same way as simple shapes (solid, face,
306 * For collection shapes (compsolid, shell, wire) prepare a list of submeshes
307 * with possible multiples occurences. Multiples occurences corresponds to
308 * internal frontiers within shapes of the collection and must not be keeped.
309 * See FinalizeDependence.
311 //=============================================================================
313 const map<int, SMESH_subMesh*>& SMESH_subMesh::DependsOn()
315 if (_dependenceAnalysed) return _mapDepend;
317 //MESSAGE("SMESH_subMesh::DependsOn");
319 int type = _subShape.ShapeType();
323 case TopAbs_COMPOUND:
325 //MESSAGE("compound");
326 list<TopoDS_Shape> shellInSolid;
327 for (TopExp_Explorer exp(_subShape,TopAbs_SOLID);exp.More();exp.Next())
329 InsertDependence(exp.Current());
331 exp2(exp.Current(),TopAbs_SHELL);exp2.More();exp2.Next())
333 shellInSolid.push_back(exp2.Current());
336 for (TopExp_Explorer exp(_subShape,TopAbs_SHELL);exp.More();exp.Next())
338 list<TopoDS_Shape>::iterator it1;
339 bool isInSolid = false;
340 for (it1 = shellInSolid.begin(); it1 != shellInSolid.end(); it1++)
342 TopoDS_Shape aShape = (*it1);
343 if (aShape.IsSame(exp.Current()))
350 InsertDependence(exp.Current()); //only shell not in solid
352 for (TopExp_Explorer exp(_subShape,TopAbs_FACE);exp.More();exp.Next())
354 InsertDependence(exp.Current());
356 for (TopExp_Explorer exp(_subShape,TopAbs_EDGE);exp.More();exp.Next())
358 InsertDependence(exp.Current());
362 case TopAbs_COMPSOLID:
364 //MESSAGE("compsolid");
365 for (TopExp_Explorer exp(_subShape,TopAbs_SOLID);exp.More();exp.Next())
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();exp.Next())
386 InsertDependence(exp.Current());
388 // list<TopoDS_Shape> shapeList;
389 // for (TopExp_Explorer exp(_subShape,TopAbs_FACE);exp.More();exp.Next())
391 // for (TopExp_Explorer
392 // exp2(exp.Current(),TopAbs_EDGE);exp2.More();exp2.Next())
394 // shapeList.push_back(exp2.Current());
397 // FinalizeDependence(shapeList);
403 for (TopExp_Explorer exp(_subShape,TopAbs_EDGE);exp.More();exp.Next())
405 InsertDependence(exp.Current());
407 // list<TopoDS_Shape> shapeList;
408 // for (TopExp_Explorer exp(_subShape,TopAbs_EDGE);exp.More();exp.Next())
410 // for (TopExp_Explorer
411 // exp2(exp.Current(),TopAbs_VERTEX);exp2.More();exp2.Next())
413 // shapeList.push_back(exp2.Current());
416 // FinalizeDependence(shapeList);
422 // for (TopExp_Explorer exp(_subShape,TopAbs_SHELL);exp.More();exp.Next())
424 // InsertDependence(exp.Current());
426 for (TopExp_Explorer exp(_subShape,TopAbs_FACE);exp.More();exp.Next())
428 InsertDependence(exp.Current());
435 // for (TopExp_Explorer exp(_subShape,TopAbs_WIRE);exp.More();exp.Next())
437 // InsertDependence(exp.Current());
439 for (TopExp_Explorer exp(_subShape,TopAbs_EDGE);exp.More();exp.Next())
441 InsertDependence(exp.Current());
448 for (TopExp_Explorer exp(_subShape,TopAbs_VERTEX);exp.More();exp.Next())
450 InsertDependence(exp.Current());
463 _dependenceAnalysed = true;
467 //=============================================================================
469 * For simple Shapes (solid, face, edge): add subMesh into dependence list.
471 //=============================================================================
473 void SMESH_subMesh::InsertDependence(const TopoDS_Shape aSubShape)
475 //MESSAGE("SMESH_subMesh::InsertDependence");
476 //SMESH_subMesh* aSubMesh = _father->GetSubMeshContaining(aSubShape);
478 //if (! aSubMesh) aSubMesh = _father->GetSubMesh(aSubShape);
480 SMESH_subMesh* aSubMesh = _father->GetSubMesh(aSubShape);
481 int type = aSubShape.ShapeType();
482 int ordType = 9 - type; // 2 = Vertex, 8 = CompSolid
483 int cle = aSubMesh->GetId();
484 cle += 10000000 * ordType; // sort map by ordType then index
485 if (_mapDepend.find(cle) == _mapDepend.end())
487 _mapDepend[cle] = aSubMesh;
488 const map<int, SMESH_subMesh*>& subMap = aSubMesh->DependsOn();
489 map<int, SMESH_subMesh*>::const_iterator im;
490 for (im = subMap.begin(); im != subMap.end(); im++)
492 int clesub = (*im).first;
493 SMESH_subMesh* sm = (*im).second;
494 if (_mapDepend.find(clesub) == _mapDepend.end())
495 _mapDepend[clesub] = sm;
501 //=============================================================================
503 * For collection shapes (compsolid, shell, wire).
504 * Add only subMesh figuring only once in multiset to dependence list
506 //=============================================================================
508 // void SMESH_subMesh::FinalizeDependence(list<TopoDS_Shape>& shapeList)
510 // //MESSAGE("SMESH_subMesh::FinalizeDependence");
511 // list<TopoDS_Shape>::iterator it1, it2;
512 // for(it1 = shapeList.begin(); it1 != shapeList.end(); it1++)
514 // TopoDS_Shape aSubShape = (*it1);
516 // for(it2 = shapeList.begin(); it2 != shapeList.end(); it2++)
518 // TopoDS_Shape other = (*it2);
519 // if (other.IsSame(aSubShape)) count++;
521 // if (count == 1) InsertDependence(aSubShape);
526 //=============================================================================
530 //=============================================================================
532 const TopoDS_Shape& SMESH_subMesh::GetSubShape()
534 //MESSAGE("SMESH_subMesh::GetSubShape");
538 //=============================================================================
542 //=============================================================================
544 bool SMESH_subMesh::AlgoStateEngine(int event, SMESH_Hypothesis* anHyp)
545 throw (SALOME_Exception)
547 // MESSAGE("SMESH_subMesh::AlgoStateEngine");
548 //SCRUTE(_algoState);
551 // **** les retour des evenement shape sont significatifs
552 // (add ou remove fait ou non)
553 // le retour des evenement father n'indiquent pas que add ou remove fait
554 int dim = SMESH_Gen::GetShapeDim(_subShape);
559 //SCRUTE(_algoState);
563 SMESH_Gen* gen =_father->GetGen();
565 _oldAlgoState = _algoState;
566 bool modifiedHyp = false; // if set to true, force event MODIF_ALGO_STATE
567 // in ComputeStateEngine
572 // ----------------------------------------------------------------------
578 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
579 ret = _meshDS->AddHypothesis(_subShape, anHyp);
582 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
583 if (anHyp->GetDim() <= SMESH_Gen::GetShapeDim(_subShape))
585 ret = _meshDS->AddHypothesis(_subShape, anHyp);
586 // if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)))
587 // if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType()))
588 if (ret &&(anHyp->GetShapeType() & (1<< _subShape.ShapeType())))
590 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
592 ret = algo->CheckHypothesis((*_father),_subShape);
593 if (ret) SetAlgoState(HYP_OK);
594 else SetAlgoState(MISSING_HYP);
599 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
600 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
603 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
604 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
606 case ADD_FATHER_HYP: // nothing to do
608 case ADD_FATHER_ALGO: // Algo just added in father
609 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
610 // if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))
611 // if (anHyp->GetShapeType() == _subShape.ShapeType())
612 if (anHyp->GetShapeType() & (1<< _subShape.ShapeType()))
614 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
616 ret = algo->CheckHypothesis((*_father),_subShape);
617 if (ret) SetAlgoState(HYP_OK);
618 else SetAlgoState(MISSING_HYP);
621 case REMOVE_FATHER_HYP: // nothing to do
623 case REMOVE_FATHER_ALGO: // nothing to do
631 // ----------------------------------------------------------------------
637 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
638 ret = _meshDS->AddHypothesis(_subShape, anHyp);
641 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
643 ret = algo->CheckHypothesis((*_father),_subShape);
644 if (ret) SetAlgoState(HYP_OK);
645 else SetAlgoState(MISSING_HYP);
648 case ADD_ALGO: //already existing algo : on father ?
649 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
650 if (anHyp->GetDim() <= SMESH_Gen::GetShapeDim(_subShape))
652 ret = _meshDS->AddHypothesis(_subShape, anHyp);
653 // if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)))
654 // if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType()))
655 if (ret &&(anHyp->GetShapeType() & (1<< _subShape.ShapeType())))
657 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
658 if (algo == NULL) // two algo on the same subShape...
660 MESSAGE("two algo on the same subshape not allowed");
661 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
666 ret = algo->CheckHypothesis((*_father),_subShape);
667 if (ret) SetAlgoState(HYP_OK);
668 else SetAlgoState(MISSING_HYP);
674 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
675 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
677 case REMOVE_ALGO: // perhaps a father algo applies ?
678 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
679 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
680 // if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)))
681 // if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType()))
682 if (ret &&(anHyp->GetShapeType() & (1<<_subShape.ShapeType())))
684 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
685 if (algo == NULL) // no more algo applying on subShape...
687 SetAlgoState(NO_ALGO);
691 ret = algo->CheckHypothesis((*_father),_subShape);
692 if (ret) SetAlgoState(HYP_OK);
693 else SetAlgoState(MISSING_HYP);
698 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
700 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
702 ret = algo->CheckHypothesis((*_father),_subShape);
703 if (ret) SetAlgoState(HYP_OK);
704 else SetAlgoState(MISSING_HYP);
707 case ADD_FATHER_ALGO: // detect if two algo of same dim on father
708 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
709 // if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))
710 // if (anHyp->GetShapeType() == _subShape.ShapeType())
711 if (anHyp->GetShapeType() & (1<< _subShape.ShapeType()))
713 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
714 if (algo == NULL) // two applying algo on father
716 MESSAGE("two applying algo on fatherShape...");
717 SetAlgoState(NO_ALGO);
721 ret = algo->CheckHypothesis((*_father),_subShape);
722 if (ret) SetAlgoState(HYP_OK);
723 else SetAlgoState(MISSING_HYP);
727 case REMOVE_FATHER_HYP: // nothing to do
729 case REMOVE_FATHER_ALGO:
730 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
731 // if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))
732 // if (anHyp->GetShapeType() == _subShape.ShapeType())
733 if (anHyp->GetShapeType() & (1<< _subShape.ShapeType()))
735 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
736 if (algo == NULL) // no more applying algo on father
738 SetAlgoState(NO_ALGO);
742 ret = algo->CheckHypothesis((*_father),_subShape);
743 if (ret) SetAlgoState(HYP_OK);
744 else SetAlgoState(MISSING_HYP);
754 // ----------------------------------------------------------------------
761 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
762 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
764 list<SMESHDS_Hypothesis*> originalUsedHyps
765 = algo->GetUsedHypothesis((*_father), _subShape); // copy
767 ret = _meshDS->AddHypothesis(_subShape, anHyp);
770 ret = algo->CheckHypothesis((*_father),_subShape);
773 INFOS("two applying algo on the same shape not allowed");
774 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
777 else // compare SMESHDS_Hypothesis* lists (order important)
780 const list<SMESHDS_Hypothesis*>& newUsedHyps
781 = algo->GetUsedHypothesis((*_father), _subShape);
782 modifiedHyp = (originalUsedHyps != newUsedHyps);
787 case ADD_ALGO: //already existing algo : on father ?
788 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
789 if (anHyp->GetDim() <= SMESH_Gen::GetShapeDim(_subShape))
791 ret = _meshDS->AddHypothesis(_subShape, anHyp);
792 // if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)))
793 // if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType()))
794 if (ret &&(anHyp->GetShapeType() & (1<< _subShape.ShapeType())))
796 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
797 if (algo == NULL) // two algo on the same subShape...
799 INFOS("two algo on the same subshape not allowed");
800 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
805 ret = algo->CheckHypothesis((*_father),_subShape);
806 if (ret) SetAlgoState(HYP_OK);
807 else SetAlgoState(MISSING_HYP);
813 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
814 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
817 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
819 ret = algo->CheckHypothesis((*_father),_subShape);
820 if (ret) SetAlgoState(HYP_OK);
821 else SetAlgoState(MISSING_HYP);
825 case REMOVE_ALGO: // perhaps a father algo applies ?
826 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
827 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
828 // if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)))
829 // if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType()))
830 if (ret &&(anHyp->GetShapeType() & (1<< _subShape.ShapeType())))
832 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
833 if (algo == NULL) // no more algo applying on subShape...
835 SetAlgoState(NO_ALGO);
839 ret = algo->CheckHypothesis((*_father),_subShape);
840 if (ret) SetAlgoState(HYP_OK);
841 else SetAlgoState(MISSING_HYP);
846 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
848 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
850 ret = algo->CheckHypothesis((*_father),_subShape);
851 if (ret) SetAlgoState(HYP_OK);
852 else SetAlgoState(MISSING_HYP);
855 case ADD_FATHER_ALGO: // detect if two algo of same dim on father
856 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
857 // if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))
858 // if (anHyp->GetShapeType() == _subShape.ShapeType())
859 if (anHyp->GetShapeType() & (1<< _subShape.ShapeType()))
861 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
862 if (algo == NULL) // two applying algo on father
864 MESSAGE("two applying algo on fatherShape...");
865 SetAlgoState(NO_ALGO);
869 ret = algo->CheckHypothesis((*_father),_subShape);
870 if (ret) SetAlgoState(HYP_OK);
871 else SetAlgoState(MISSING_HYP);
875 case REMOVE_FATHER_HYP:
876 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
878 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
880 ret = algo->CheckHypothesis((*_father),_subShape);
881 if (ret) SetAlgoState(HYP_OK);
882 else SetAlgoState(MISSING_HYP);
885 case REMOVE_FATHER_ALGO:
886 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
887 // if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))
888 // if (anHyp->GetShapeType() == _subShape.ShapeType())
889 if (anHyp->GetShapeType() & (1<< _subShape.ShapeType()))
891 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
892 if (algo == NULL) // no more applying algo on father
894 SetAlgoState(NO_ALGO);
898 ret = algo->CheckHypothesis((*_father),_subShape);
899 if (ret) SetAlgoState(HYP_OK);
900 else SetAlgoState(MISSING_HYP);
910 // ----------------------------------------------------------------------
916 //SCRUTE(_algoState);
917 if ((_algoState != _oldAlgoState) || modifiedHyp)
918 int retc = ComputeStateEngine(MODIF_ALGO_STATE);
922 //=============================================================================
926 //=============================================================================
928 void SMESH_subMesh::SetAlgoState(int state)
930 if (state != _oldAlgoState)
931 // int retc = ComputeStateEngine(MODIF_ALGO_STATE);
935 //=============================================================================
939 //=============================================================================
941 void SMESH_subMesh::SubMeshesAlgoStateEngine(int event,
942 SMESH_Hypothesis* anHyp)
943 throw (SALOME_Exception)
945 //MESSAGE("SMESH_subMesh::SubMeshesAlgoStateEngine");
946 int dim = SMESH_Gen::GetShapeDim(_subShape);
949 const map<int, SMESH_subMesh*>& subMeshes = DependsOn();
951 map<int, SMESH_subMesh*>::const_iterator itsub;
952 for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
954 SMESH_subMesh* sm = (*itsub).second;
955 sm->AlgoStateEngine(event, anHyp);
960 //=============================================================================
964 //=============================================================================
966 void SMESH_subMesh::DumpAlgoState(bool isMain)
968 int dim = SMESH_Gen::GetShapeDim(_subShape);
969 // if (dim < 1) return;
972 const map<int, SMESH_subMesh*>& subMeshes = DependsOn();
974 map<int, SMESH_subMesh*>::const_iterator itsub;
975 for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
977 SMESH_subMesh* sm = (*itsub).second;
978 sm->DumpAlgoState(false);
981 int type = _subShape.ShapeType();
982 MESSAGE("dim = " << dim << " type of shape " << type);
985 case NO_ALGO: MESSAGE(" AlgoState = NO_ALGO"); break;
986 case MISSING_HYP: MESSAGE(" AlgoState = MISSING_HYP"); break;
987 case HYP_OK: MESSAGE(" AlgoState = HYP_OK"); break;
989 switch (_computeState)
991 case NOT_READY: MESSAGE(" ComputeState = NOT_READY"); break;
992 case READY_TO_COMPUTE: MESSAGE(" ComputeState = READY_TO_COMPUTE"); break;
993 case COMPUTE_OK: MESSAGE(" ComputeState = COMPUTE_OK"); break;
994 case FAILED_TO_COMPUTE: MESSAGE(" ComputeState = FAILED_TO_COMPUTE");break;
998 //=============================================================================
1002 //=============================================================================
1004 bool SMESH_subMesh::ComputeStateEngine(int event)
1005 throw (SALOME_Exception)
1007 //MESSAGE("SMESH_subMesh::ComputeStateEngine");
1008 //SCRUTE(_computeState);
1011 int dim = SMESH_Gen::GetShapeDim(_subShape);
1015 if (_vertexSet) _computeState = COMPUTE_OK;
1016 else _computeState = READY_TO_COMPUTE;
1017 //SCRUTE(_computeState);
1020 SMESH_Gen* gen =_father->GetGen();
1021 SMESH_Algo* algo = 0;
1024 switch(_computeState)
1027 // ----------------------------------------------------------------------
1032 case MODIF_HYP: // nothing to do
1034 case MODIF_ALGO_STATE:
1035 if (_algoState == HYP_OK)
1036 _computeState = READY_TO_COMPUTE;
1038 case COMPUTE: // nothing to do
1040 case CLEAN: // nothing to do
1042 case CLEANDEP: // nothing to do
1043 RemoveSubMeshElementsAndNodes(); // recursive call...
1045 case SUBMESH_COMPUTED: // nothing to do
1053 // ----------------------------------------------------------------------
1055 case READY_TO_COMPUTE:
1058 case MODIF_HYP: // nothing to do
1060 case MODIF_ALGO_STATE:
1061 _computeState = NOT_READY;
1062 algo = gen->GetAlgo((*_father), _subShape);
1065 ret = algo->CheckHypothesis((*_father),_subShape);
1066 if (ret) _computeState = READY_TO_COMPUTE;
1071 algo = gen->GetAlgo((*_father), _subShape);
1073 ret = algo->CheckHypothesis((*_father),_subShape);
1076 MESSAGE("***** verify compute state *****");
1077 _computeState = NOT_READY;
1080 ret = SubMeshesComputed();
1083 MESSAGE("Some SubMeshes not computed");
1084 _computeState = FAILED_TO_COMPUTE;
1087 ret = algo->Compute((*_father),_subShape);
1090 MESSAGE("problem in algo execution: failed to compute");
1091 _computeState = FAILED_TO_COMPUTE;
1096 _computeState = COMPUTE_OK;
1097 UpdateDependantsState(); // send event SUBMESH_COMPUTED
1102 _computeState = NOT_READY;
1103 algo = gen->GetAlgo((*_father), _subShape);
1106 ret = algo->CheckHypothesis((*_father),_subShape);
1107 if (ret) _computeState = READY_TO_COMPUTE;
1111 RemoveSubMeshElementsAndNodes();
1112 _computeState = NOT_READY;
1113 algo = gen->GetAlgo((*_father), _subShape);
1116 ret = algo->CheckHypothesis((*_father),_subShape);
1117 if (ret) _computeState = READY_TO_COMPUTE;
1120 case SUBMESH_COMPUTED: // nothing to do
1128 // ----------------------------------------------------------------------
1134 CleanDependants(); // recursive recall with event CLEANDEP
1136 case MODIF_ALGO_STATE:
1137 CleanDependants(); // recursive recall with event CLEANDEP
1139 case COMPUTE: // nothing to do
1142 CleanDependants(); // recursive recall with event CLEANDEP
1145 RemoveSubMeshElementsAndNodes();
1146 _computeState = NOT_READY;
1147 algo = gen->GetAlgo((*_father), _subShape);
1150 ret = algo->CheckHypothesis((*_father),_subShape);
1151 if (ret) _computeState = READY_TO_COMPUTE;
1154 case SUBMESH_COMPUTED: // nothing to do
1162 // ----------------------------------------------------------------------
1164 case FAILED_TO_COMPUTE:
1168 if (_algoState == HYP_OK)
1169 _computeState = READY_TO_COMPUTE;
1170 else _computeState = NOT_READY;
1172 case MODIF_ALGO_STATE:
1173 if (_algoState == HYP_OK)
1174 _computeState = READY_TO_COMPUTE;
1175 else _computeState = NOT_READY;
1177 case COMPUTE: // nothing to do
1182 RemoveSubMeshElementsAndNodes();
1183 if (_algoState == HYP_OK)
1184 _computeState = READY_TO_COMPUTE;
1185 else _computeState = NOT_READY;
1187 case SUBMESH_COMPUTED: // allow retry compute
1188 if (_algoState == HYP_OK)
1189 _computeState = READY_TO_COMPUTE;
1190 else _computeState = NOT_READY;
1198 // ----------------------------------------------------------------------
1204 //SCRUTE(_computeState);
1208 //=============================================================================
1212 //=============================================================================
1214 void SMESH_subMesh::UpdateDependantsState()
1216 //MESSAGE("SMESH_subMesh::UpdateDependantsState");
1218 const map<int, SMESH_subMesh*>& dependants = Dependants();
1219 map<int, SMESH_subMesh*>::const_iterator its;
1220 for (its = dependants.begin(); its != dependants.end(); its++)
1222 SMESH_subMesh* sm = (*its).second;
1223 //SCRUTE((*its).first);
1224 sm->ComputeStateEngine(SUBMESH_COMPUTED);
1228 //=============================================================================
1232 //=============================================================================
1234 void SMESH_subMesh::CleanDependants()
1236 MESSAGE("SMESH_subMesh::CleanDependants");
1237 // **** parcourir les ancetres dans l'ordre de dépendance
1239 const map<int, SMESH_subMesh*>& dependants = Dependants();
1240 map<int, SMESH_subMesh*>::const_iterator its;
1241 for (its = dependants.begin(); its != dependants.end(); its++)
1243 SMESH_subMesh* sm = (*its).second;
1244 SCRUTE((*its).first);
1245 sm->ComputeStateEngine(CLEANDEP);
1247 ComputeStateEngine(CLEANDEP);
1249 //=============================================================================
1253 //=============================================================================
1255 void SMESH_subMesh::RemoveSubMeshElementsAndNodes()
1257 MESSAGE("SMESH_subMesh::RemoveSubMeshElementsAndNodes");
1258 SCRUTE(_subShape.ShapeType());
1261 _subMeshDS = _meshDS->MeshElements(_subShape);
1262 if (!_subMeshDS.IsNull())
1264 const TColStd_ListOfInteger& indElt
1265 = _subMeshDS->GetIDElements();
1266 TColStd_ListIteratorOfListOfInteger ite(indElt);
1267 for (; ite.More(); ite.Next())
1269 int eltId = ite.Value();
1271 Handle (SMDS_MeshElement) elt = _meshDS->FindElement(eltId);
1272 _subMeshDS->RemoveElement(elt);
1273 _meshDS->RemoveElement(eltId);
1276 const TColStd_ListOfInteger& indNodes
1277 = _subMeshDS->GetIDNodes();
1278 TColStd_ListIteratorOfListOfInteger itn(indNodes);
1279 for (; itn.More(); itn.Next())
1281 int nodeId = itn.Value();
1283 Handle (SMDS_MeshElement) elt = _meshDS->FindNode(nodeId);
1284 Handle (SMDS_MeshNode) node = _meshDS->GetNode(1, elt);
1285 _subMeshDS->RemoveNode(node);
1286 _meshDS->RemoveNode(nodeId);
1291 //=============================================================================
1295 //=============================================================================
1297 const map<int, SMESH_subMesh*>& SMESH_subMesh::Dependants()
1299 if (_dependantsFound) return _mapDependants;
1301 //MESSAGE("SMESH_subMesh::Dependants");
1303 int shapeType = _subShape.ShapeType();
1304 //SCRUTE(shapeType);
1305 TopTools_IndexedDataMapOfShapeListOfShape M;
1306 TopoDS_Shape mainShape = _meshDS->ShapeToMesh();
1314 TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_WIRE, M);
1315 TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_FACE, M);
1316 TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_SHELL, M);
1317 TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_SOLID, M);
1318 TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_COMPSOLID, M);
1319 ExtractDependants(M, TopAbs_EDGE);
1323 TopExp::MapShapesAndAncestors(mainShape, TopAbs_FACE, TopAbs_SHELL, M);
1324 TopExp::MapShapesAndAncestors(mainShape, TopAbs_FACE, TopAbs_SOLID, M);
1325 TopExp::MapShapesAndAncestors(mainShape, TopAbs_FACE, TopAbs_COMPSOLID, M);
1326 ExtractDependants(M, TopAbs_FACE);
1329 case TopAbs_COMPSOLID:
1330 TopExp::MapShapesAndAncestors(mainShape, TopAbs_SOLID, TopAbs_COMPSOLID, M);
1331 ExtractDependants(M, TopAbs_SOLID);
1333 case TopAbs_COMPOUND:
1337 _dependantsFound = true;
1338 return _mapDependants;
1341 //=============================================================================
1345 //=============================================================================
1347 void SMESH_subMesh::ExtractDependants(const TopTools_IndexedDataMapOfShapeListOfShape& M,
1348 const TopAbs_ShapeEnum etype)
1350 //MESSAGE("SMESH_subMesh::ExtractDependants");
1352 TopoDS_Shape mainShape = _meshDS->ShapeToMesh();
1353 int lg = M.Extent();
1356 int shapeType = _subShape.ShapeType();
1365 const TopTools_ListOfShape& ancestors = M.FindFromKey(_subShape);
1366 TopTools_ListIteratorOfListOfShape it(ancestors);
1367 for ( ; it.More();it.Next())
1369 TopoDS_Shape ancestor = it.Value();
1370 SMESH_subMesh* aSubMesh = _father->GetSubMeshContaining(ancestor);
1371 // if (! aSubMesh) aSubMesh = _father->GetSubMesh(ancestor);
1374 int type = aSubMesh->_subShape.ShapeType();
1375 int cle = aSubMesh->GetId();
1376 cle += 10000000 * type; // sort map by ordType then index
1377 if (_mapDependants.find(cle) == _mapDependants.end())
1379 _mapDependants[cle] = aSubMesh;
1388 case TopAbs_COMPSOLID:
1389 for (TopExp_Explorer expE(_subShape, etype); expE.More(); expE.Next())
1391 TopoDS_Shape aShape = expE.Current();
1392 const TopTools_ListOfShape& ancestors = M.FindFromKey( aShape);
1393 TopTools_ListIteratorOfListOfShape it(ancestors);
1394 for ( ; it.More();it.Next())
1397 TopoDS_Shape ancestor = it.Value();
1398 SMESH_subMesh* aSubMesh = _father->GetSubMeshContaining(ancestor);
1399 if (! aSubMesh) aSubMesh = _father->GetSubMesh(ancestor);
1400 int type = aSubMesh->_subShape.ShapeType();
1401 int cle = aSubMesh->GetId();
1402 cle += 10000000 * type; // sort map by ordType then index
1403 if (_mapDependants.find(cle) == _mapDependants.end())
1405 _mapDependants[cle] = aSubMesh;
1411 case TopAbs_COMPOUND: