2 //=============================================================================
3 // File : SMESH_subMesh.cxx
4 // Created : jeu mai 30 13:28:32 CEST 2002
5 // Author : Paul RASCLE, EDF
7 // Copyright : EDF 2002
9 //=============================================================================
13 #include "SMESH_subMesh.hxx"
14 #include "SMESH_Gen.hxx"
15 #include "SMESH_Mesh.hxx"
16 #include "SMESH_Hypothesis.hxx"
17 #include "SMESH_Algo.hxx"
18 #include "utilities.h"
22 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
23 #include <TopTools_ListOfShape.hxx>
24 #include <TopTools_ListIteratorOfListOfShape.hxx>
25 #include <TColStd_ListIteratorOfListOfInteger.hxx>
27 //=============================================================================
29 * default constructor:
31 //=============================================================================
33 SMESH_subMesh::SMESH_subMesh(int Id,
35 const Handle(SMESHDS_Mesh)& meshDS,
36 const TopoDS_Shape & aSubShape)
38 //MESSAGE("SMESH_subMesh::SMESH_subMesh");
39 _subShape = aSubShape;
41 _subMeshDS = meshDS->MeshElements(_subShape); // may be null ...
44 _vertexSet = false; // only for Vertex subMesh
45 _dependenceAnalysed = false;
46 _dependantsFound = false;
48 if (_subShape.ShapeType() == TopAbs_VERTEX)
51 _computeState = READY_TO_COMPUTE;
56 _computeState = NOT_READY;
60 //=============================================================================
64 //=============================================================================
66 SMESH_subMesh::~SMESH_subMesh()
68 MESSAGE("SMESH_subMesh::~SMESH_subMesh");
72 //=============================================================================
76 //=============================================================================
78 int SMESH_subMesh::GetId()
80 //MESSAGE("SMESH_subMesh::GetId");
84 //=============================================================================
86 * Given a subShape, find the subMesh is associated to this subShape or
87 * to a collection of shapes containing this subShape. Collection = compsolid,
90 //=============================================================================
92 // bool SMESH_subMesh::Contains(const TopoDS_Shape & aSubShape)
93 // throw (SALOME_Exception)
95 // //MESSAGE("SMESH_subMesh::Contains");
96 // bool contains = false;
97 // int type = _subShape.ShapeType();
98 // int typesub = aSubShape.ShapeType();
103 // // case TopAbs_COMPOUND:
105 // // //MESSAGE("---");
106 // // throw SALOME_Exception(LOCALIZED("Compound not yet treated"));
109 // case TopAbs_COMPSOLID:
112 // for (TopExp_Explorer exp(aSubShape,TopAbs_SOLID);exp.More();exp.Next())
114 // contains = _subShape.IsSame(exp.Current());
115 // if (contains) break;
119 // case TopAbs_SHELL:
122 // for (TopExp_Explorer exp(aSubShape,TopAbs_FACE);exp.More();exp.Next())
124 // contains = _subShape.IsSame(exp.Current());
125 // if (contains) break;
132 // for (TopExp_Explorer exp(aSubShape,TopAbs_EDGE);exp.More();exp.Next())
134 // contains = _subShape.IsSame(exp.Current());
135 // if (contains) break;
139 // case TopAbs_COMPOUND:
140 // case TopAbs_SOLID:
143 // case TopAbs_VERTEX:
146 // contains = _subShape.IsSame(aSubShape);
154 // //SCRUTE(contains);
158 //=============================================================================
162 //=============================================================================
164 const Handle(SMESHDS_SubMesh)& SMESH_subMesh::GetSubMeshDS()
165 throw (SALOME_Exception)
167 //MESSAGE("SMESH_subMesh::GetSubMeshDS");
168 if (_subMeshDS.IsNull())
170 //MESSAGE("subMesh pointer still null, trying to get it...");
171 _subMeshDS = _meshDS->MeshElements(_subShape); // may be null ...
172 if (_subMeshDS.IsNull())
174 MESSAGE("problem... subMesh still empty");
176 //NRI throw SALOME_Exception(LOCALIZED(subMesh still empty));
182 //=============================================================================
186 //=============================================================================
188 SMESH_subMesh* SMESH_subMesh::GetFirstToCompute()
189 throw (SALOME_Exception)
191 //MESSAGE("SMESH_subMesh::GetFirstToCompute");
192 const map<int, SMESH_subMesh*>& subMeshes = DependsOn();
193 SMESH_subMesh* firstToCompute = 0;
195 map<int, SMESH_subMesh*>::const_iterator itsub;
196 for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
198 SMESH_subMesh* sm = (*itsub).second;
199 // SCRUTE(sm->GetId());
200 // SCRUTE(sm->GetComputeState());
201 bool readyToCompute = (sm->GetComputeState() == READY_TO_COMPUTE);
205 //SCRUTE(sm->GetId());
211 //MESSAGE("--- submesh to compute");
212 return firstToCompute; // a subMesh of this
214 if (_computeState == READY_TO_COMPUTE)
216 //MESSAGE("--- this to compute");
219 //MESSAGE("--- nothing to compute");
220 return 0; // nothing to compute
223 //=============================================================================
227 //=============================================================================
229 bool SMESH_subMesh::SubMeshesComputed()
230 throw (SALOME_Exception)
232 //MESSAGE("SMESH_subMesh::SubMeshesComputed");
233 const map<int, SMESH_subMesh*>& subMeshes = DependsOn();
235 bool subMeshesComputed = true;
236 map<int, SMESH_subMesh*>::const_iterator itsub;
237 for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
239 SMESH_subMesh* sm = (*itsub).second;
240 // SCRUTE(sm->GetId());
241 // SCRUTE(sm->GetComputeState());
242 bool computeOk = (sm->GetComputeState() == COMPUTE_OK);
245 subMeshesComputed = false;
250 return subMeshesComputed;
253 //=============================================================================
257 //=============================================================================
259 bool SMESH_subMesh::SubMeshesReady()
261 MESSAGE("SMESH_subMesh::SubMeshesReady");
262 const map<int, SMESH_subMesh*>& subMeshes = DependsOn();
264 bool subMeshesReady = true;
265 map<int, SMESH_subMesh*>::const_iterator itsub;
266 for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
268 SMESH_subMesh* sm = (*itsub).second;
269 // SCRUTE(sm->GetId());
270 // SCRUTE(sm->GetComputeState());
271 bool computeOk = ( (sm->GetComputeState() == COMPUTE_OK)
272 || (sm->GetComputeState() == READY_TO_COMPUTE)) ;
275 subMeshesReady = false;
280 return subMeshesReady;
283 //=============================================================================
285 * Construct dependence on first level subMeshes. complex shapes (compsolid,
286 * shell, wire) are not analysed the same way as simple shapes (solid, face,
288 * For collection shapes (compsolid, shell, wire) prepare a list of submeshes
289 * with possible multiples occurences. Multiples occurences corresponds to
290 * internal frontiers within shapes of the collection and must not be keeped.
291 * See FinalizeDependence.
293 //=============================================================================
295 const map<int, SMESH_subMesh*>& SMESH_subMesh::DependsOn()
297 if (_dependenceAnalysed) return _mapDepend;
299 //MESSAGE("SMESH_subMesh::DependsOn");
301 int type = _subShape.ShapeType();
305 case TopAbs_COMPOUND:
307 //MESSAGE("compound");
308 list<TopoDS_Shape> shellInSolid;
309 for (TopExp_Explorer exp(_subShape,TopAbs_SOLID);exp.More();exp.Next())
311 InsertDependence(exp.Current());
313 exp2(exp.Current(),TopAbs_SHELL);exp2.More();exp2.Next())
315 shellInSolid.push_back(exp2.Current());
318 for (TopExp_Explorer exp(_subShape,TopAbs_SHELL);exp.More();exp.Next())
320 list<TopoDS_Shape>::iterator it1;
321 bool isInSolid = false;
322 for (it1 = shellInSolid.begin(); it1 != shellInSolid.end(); it1++)
324 TopoDS_Shape aShape = (*it1);
325 if (aShape.IsSame(exp.Current()))
332 InsertDependence(exp.Current()); //only shell not in solid
334 for (TopExp_Explorer exp(_subShape,TopAbs_FACE);exp.More();exp.Next())
336 InsertDependence(exp.Current());
338 for (TopExp_Explorer exp(_subShape,TopAbs_EDGE);exp.More();exp.Next())
340 InsertDependence(exp.Current());
344 case TopAbs_COMPSOLID:
346 //MESSAGE("compsolid");
347 for (TopExp_Explorer exp(_subShape,TopAbs_SOLID);exp.More();exp.Next())
349 InsertDependence(exp.Current());
351 // list<TopoDS_Shape> shapeList;
352 // for (TopExp_Explorer exp(_subShape,TopAbs_SOLID);exp.More();exp.Next())
354 // for (TopExp_Explorer
355 // exp2(exp.Current(),TopAbs_FACE);exp2.More();exp2.Next())
357 // shapeList.push_back(exp2.Current());
360 // FinalizeDependence(shapeList);
366 for (TopExp_Explorer exp(_subShape,TopAbs_FACE);exp.More();exp.Next())
368 InsertDependence(exp.Current());
370 // list<TopoDS_Shape> shapeList;
371 // for (TopExp_Explorer exp(_subShape,TopAbs_FACE);exp.More();exp.Next())
373 // for (TopExp_Explorer
374 // exp2(exp.Current(),TopAbs_EDGE);exp2.More();exp2.Next())
376 // shapeList.push_back(exp2.Current());
379 // FinalizeDependence(shapeList);
385 for (TopExp_Explorer exp(_subShape,TopAbs_EDGE);exp.More();exp.Next())
387 InsertDependence(exp.Current());
389 // list<TopoDS_Shape> shapeList;
390 // for (TopExp_Explorer exp(_subShape,TopAbs_EDGE);exp.More();exp.Next())
392 // for (TopExp_Explorer
393 // exp2(exp.Current(),TopAbs_VERTEX);exp2.More();exp2.Next())
395 // shapeList.push_back(exp2.Current());
398 // FinalizeDependence(shapeList);
404 // for (TopExp_Explorer exp(_subShape,TopAbs_SHELL);exp.More();exp.Next())
406 // InsertDependence(exp.Current());
408 for (TopExp_Explorer exp(_subShape,TopAbs_FACE);exp.More();exp.Next())
410 InsertDependence(exp.Current());
417 // for (TopExp_Explorer exp(_subShape,TopAbs_WIRE);exp.More();exp.Next())
419 // InsertDependence(exp.Current());
421 for (TopExp_Explorer exp(_subShape,TopAbs_EDGE);exp.More();exp.Next())
423 InsertDependence(exp.Current());
430 for (TopExp_Explorer exp(_subShape,TopAbs_VERTEX);exp.More();exp.Next())
432 InsertDependence(exp.Current());
445 _dependenceAnalysed = true;
449 //=============================================================================
451 * For simple Shapes (solid, face, edge): add subMesh into dependence list.
453 //=============================================================================
455 void SMESH_subMesh::InsertDependence(const TopoDS_Shape aSubShape)
457 //MESSAGE("SMESH_subMesh::InsertDependence");
458 //SMESH_subMesh* aSubMesh = _father->GetSubMeshContaining(aSubShape);
460 //if (! aSubMesh) aSubMesh = _father->GetSubMesh(aSubShape);
462 SMESH_subMesh* aSubMesh = _father->GetSubMesh(aSubShape);
463 int type = aSubShape.ShapeType();
464 int ordType = 9 - type; // 2 = Vertex, 8 = CompSolid
465 int cle = aSubMesh->GetId();
466 cle += 10000000 * ordType; // sort map by ordType then index
467 if (_mapDepend.find(cle) == _mapDepend.end())
469 _mapDepend[cle] = aSubMesh;
470 const map<int, SMESH_subMesh*>& subMap = aSubMesh->DependsOn();
471 map<int, SMESH_subMesh*>::const_iterator im;
472 for (im = subMap.begin(); im != subMap.end(); im++)
474 int clesub = (*im).first;
475 SMESH_subMesh* sm = (*im).second;
476 if (_mapDepend.find(clesub) == _mapDepend.end())
477 _mapDepend[clesub] = sm;
483 //=============================================================================
485 * For collection shapes (compsolid, shell, wire).
486 * Add only subMesh figuring only once in multiset to dependence list
488 //=============================================================================
490 // void SMESH_subMesh::FinalizeDependence(list<TopoDS_Shape>& shapeList)
492 // //MESSAGE("SMESH_subMesh::FinalizeDependence");
493 // list<TopoDS_Shape>::iterator it1, it2;
494 // for(it1 = shapeList.begin(); it1 != shapeList.end(); it1++)
496 // TopoDS_Shape aSubShape = (*it1);
498 // for(it2 = shapeList.begin(); it2 != shapeList.end(); it2++)
500 // TopoDS_Shape other = (*it2);
501 // if (other.IsSame(aSubShape)) count++;
503 // if (count == 1) InsertDependence(aSubShape);
508 //=============================================================================
512 //=============================================================================
514 const TopoDS_Shape& SMESH_subMesh::GetSubShape()
516 //MESSAGE("SMESH_subMesh::GetSubShape");
520 //=============================================================================
524 //=============================================================================
526 bool SMESH_subMesh::AlgoStateEngine(int event, SMESH_Hypothesis* anHyp)
527 throw (SALOME_Exception)
529 // MESSAGE("SMESH_subMesh::AlgoStateEngine");
530 //SCRUTE(_algoState);
533 // **** les retour des evenement shape sont significatifs
534 // (add ou remove fait ou non)
535 // le retour des evenement father n'indiquent pas que add ou remove fait
536 int dim = SMESH_Gen::GetShapeDim(_subShape);
541 //SCRUTE(_algoState);
545 SMESH_Gen* gen =_father->GetGen();
547 _oldAlgoState = _algoState;
548 bool modifiedHyp = false; // if set to true, force event MODIF_ALGO_STATE
549 // in ComputeStateEngine
554 // ----------------------------------------------------------------------
560 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
561 ret = _meshDS->AddHypothesis(_subShape, anHyp);
564 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
565 if (anHyp->GetDim() <= SMESH_Gen::GetShapeDim(_subShape))
567 ret = _meshDS->AddHypothesis(_subShape, anHyp);
568 // if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)))
569 // if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType()))
570 if (ret &&(anHyp->GetShapeType() & (1<< _subShape.ShapeType())))
572 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
574 ret = algo->CheckHypothesis((*_father),_subShape);
575 if (ret) SetAlgoState(HYP_OK);
576 else SetAlgoState(MISSING_HYP);
581 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
582 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
585 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
586 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
588 case ADD_FATHER_HYP: // nothing to do
590 case ADD_FATHER_ALGO: // Algo just added in father
591 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
592 // if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))
593 // if (anHyp->GetShapeType() == _subShape.ShapeType())
594 if (anHyp->GetShapeType() & (1<< _subShape.ShapeType()))
596 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
598 ret = algo->CheckHypothesis((*_father),_subShape);
599 if (ret) SetAlgoState(HYP_OK);
600 else SetAlgoState(MISSING_HYP);
603 case REMOVE_FATHER_HYP: // nothing to do
605 case REMOVE_FATHER_ALGO: // nothing to do
613 // ----------------------------------------------------------------------
619 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
620 ret = _meshDS->AddHypothesis(_subShape, anHyp);
623 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
625 ret = algo->CheckHypothesis((*_father),_subShape);
626 if (ret) SetAlgoState(HYP_OK);
627 else SetAlgoState(MISSING_HYP);
630 case ADD_ALGO: //already existing algo : on father ?
631 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
632 if (anHyp->GetDim() <= SMESH_Gen::GetShapeDim(_subShape))
634 ret = _meshDS->AddHypothesis(_subShape, anHyp);
635 // if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)))
636 // if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType()))
637 if (ret &&(anHyp->GetShapeType() & (1<< _subShape.ShapeType())))
639 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
640 if (algo == NULL) // two algo on the same subShape...
642 MESSAGE("two algo on the same subshape not allowed");
643 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
648 ret = algo->CheckHypothesis((*_father),_subShape);
649 if (ret) SetAlgoState(HYP_OK);
650 else SetAlgoState(MISSING_HYP);
656 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
657 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
659 case REMOVE_ALGO: // perhaps a father algo applies ?
660 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
661 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
662 // if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)))
663 // if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType()))
664 if (ret &&(anHyp->GetShapeType() & (1<<_subShape.ShapeType())))
666 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
667 if (algo == NULL) // no more algo applying on subShape...
669 SetAlgoState(NO_ALGO);
673 ret = algo->CheckHypothesis((*_father),_subShape);
674 if (ret) SetAlgoState(HYP_OK);
675 else SetAlgoState(MISSING_HYP);
680 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
682 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
684 ret = algo->CheckHypothesis((*_father),_subShape);
685 if (ret) SetAlgoState(HYP_OK);
686 else SetAlgoState(MISSING_HYP);
689 case ADD_FATHER_ALGO: // detect if two algo of same dim on father
690 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
691 // if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))
692 // if (anHyp->GetShapeType() == _subShape.ShapeType())
693 if (anHyp->GetShapeType() & (1<< _subShape.ShapeType()))
695 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
696 if (algo == NULL) // two applying algo on father
698 MESSAGE("two applying algo on fatherShape...");
699 SetAlgoState(NO_ALGO);
703 ret = algo->CheckHypothesis((*_father),_subShape);
704 if (ret) SetAlgoState(HYP_OK);
705 else SetAlgoState(MISSING_HYP);
709 case REMOVE_FATHER_HYP: // nothing to do
711 case REMOVE_FATHER_ALGO:
712 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
713 // if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))
714 // if (anHyp->GetShapeType() == _subShape.ShapeType())
715 if (anHyp->GetShapeType() & (1<< _subShape.ShapeType()))
717 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
718 if (algo == NULL) // no more applying algo on father
720 SetAlgoState(NO_ALGO);
724 ret = algo->CheckHypothesis((*_father),_subShape);
725 if (ret) SetAlgoState(HYP_OK);
726 else SetAlgoState(MISSING_HYP);
736 // ----------------------------------------------------------------------
743 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
744 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
746 list<SMESHDS_Hypothesis*> originalUsedHyps
747 = algo->GetUsedHypothesis((*_father), _subShape); // copy
749 ret = _meshDS->AddHypothesis(_subShape, anHyp);
752 ret = algo->CheckHypothesis((*_father),_subShape);
755 INFOS("two applying algo on the same shape not allowed");
756 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
759 else // compare SMESHDS_Hypothesis* lists (order important)
762 const list<SMESHDS_Hypothesis*>& newUsedHyps
763 = algo->GetUsedHypothesis((*_father), _subShape);
764 modifiedHyp = (originalUsedHyps != newUsedHyps);
769 case ADD_ALGO: //already existing algo : on father ?
770 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
771 if (anHyp->GetDim() <= SMESH_Gen::GetShapeDim(_subShape))
773 ret = _meshDS->AddHypothesis(_subShape, anHyp);
774 // if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)))
775 // if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType()))
776 if (ret &&(anHyp->GetShapeType() & (1<< _subShape.ShapeType())))
778 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
779 if (algo == NULL) // two algo on the same subShape...
781 INFOS("two algo on the same subshape not allowed");
782 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
787 ret = algo->CheckHypothesis((*_father),_subShape);
788 if (ret) SetAlgoState(HYP_OK);
789 else SetAlgoState(MISSING_HYP);
795 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
796 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
799 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
801 ret = algo->CheckHypothesis((*_father),_subShape);
802 if (ret) SetAlgoState(HYP_OK);
803 else SetAlgoState(MISSING_HYP);
807 case REMOVE_ALGO: // perhaps a father algo applies ?
808 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
809 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
810 // if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)))
811 // if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType()))
812 if (ret &&(anHyp->GetShapeType() & (1<< _subShape.ShapeType())))
814 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
815 if (algo == NULL) // no more algo applying on subShape...
817 SetAlgoState(NO_ALGO);
821 ret = algo->CheckHypothesis((*_father),_subShape);
822 if (ret) SetAlgoState(HYP_OK);
823 else SetAlgoState(MISSING_HYP);
828 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
830 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
832 ret = algo->CheckHypothesis((*_father),_subShape);
833 if (ret) SetAlgoState(HYP_OK);
834 else SetAlgoState(MISSING_HYP);
837 case ADD_FATHER_ALGO: // detect if two algo of same dim on father
838 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
839 // if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))
840 // if (anHyp->GetShapeType() == _subShape.ShapeType())
841 if (anHyp->GetShapeType() & (1<< _subShape.ShapeType()))
843 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
844 if (algo == NULL) // two applying algo on father
846 MESSAGE("two applying algo on fatherShape...");
847 SetAlgoState(NO_ALGO);
851 ret = algo->CheckHypothesis((*_father),_subShape);
852 if (ret) SetAlgoState(HYP_OK);
853 else SetAlgoState(MISSING_HYP);
857 case REMOVE_FATHER_HYP:
858 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
860 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
862 ret = algo->CheckHypothesis((*_father),_subShape);
863 if (ret) SetAlgoState(HYP_OK);
864 else SetAlgoState(MISSING_HYP);
867 case REMOVE_FATHER_ALGO:
868 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
869 // if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))
870 // if (anHyp->GetShapeType() == _subShape.ShapeType())
871 if (anHyp->GetShapeType() & (1<< _subShape.ShapeType()))
873 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
874 if (algo == NULL) // no more applying algo on father
876 SetAlgoState(NO_ALGO);
880 ret = algo->CheckHypothesis((*_father),_subShape);
881 if (ret) SetAlgoState(HYP_OK);
882 else SetAlgoState(MISSING_HYP);
892 // ----------------------------------------------------------------------
898 //SCRUTE(_algoState);
899 if ((_algoState != _oldAlgoState) || modifiedHyp)
900 int retc = ComputeStateEngine(MODIF_ALGO_STATE);
904 //=============================================================================
908 //=============================================================================
910 void SMESH_subMesh::SetAlgoState(int state)
912 if (state != _oldAlgoState)
913 // int retc = ComputeStateEngine(MODIF_ALGO_STATE);
917 //=============================================================================
921 //=============================================================================
923 void SMESH_subMesh::SubMeshesAlgoStateEngine(int event,
924 SMESH_Hypothesis* anHyp)
925 throw (SALOME_Exception)
927 //MESSAGE("SMESH_subMesh::SubMeshesAlgoStateEngine");
928 int dim = SMESH_Gen::GetShapeDim(_subShape);
931 const map<int, SMESH_subMesh*>& subMeshes = DependsOn();
933 map<int, SMESH_subMesh*>::const_iterator itsub;
934 for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
936 SMESH_subMesh* sm = (*itsub).second;
937 sm->AlgoStateEngine(event, anHyp);
942 //=============================================================================
946 //=============================================================================
948 void SMESH_subMesh::DumpAlgoState(bool isMain)
950 int dim = SMESH_Gen::GetShapeDim(_subShape);
951 // if (dim < 1) return;
954 const map<int, SMESH_subMesh*>& subMeshes = DependsOn();
956 map<int, SMESH_subMesh*>::const_iterator itsub;
957 for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
959 SMESH_subMesh* sm = (*itsub).second;
960 sm->DumpAlgoState(false);
963 int type = _subShape.ShapeType();
964 MESSAGE("dim = " << dim << " type of shape " << type);
967 case NO_ALGO: MESSAGE(" AlgoState = NO_ALGO"); break;
968 case MISSING_HYP: MESSAGE(" AlgoState = MISSING_HYP"); break;
969 case HYP_OK: MESSAGE(" AlgoState = HYP_OK"); break;
971 switch (_computeState)
973 case NOT_READY: MESSAGE(" ComputeState = NOT_READY"); break;
974 case READY_TO_COMPUTE: MESSAGE(" ComputeState = READY_TO_COMPUTE"); break;
975 case COMPUTE_OK: MESSAGE(" ComputeState = COMPUTE_OK"); break;
976 case FAILED_TO_COMPUTE: MESSAGE(" ComputeState = FAILED_TO_COMPUTE");break;
980 //=============================================================================
984 //=============================================================================
986 bool SMESH_subMesh::ComputeStateEngine(int event)
987 throw (SALOME_Exception)
989 //MESSAGE("SMESH_subMesh::ComputeStateEngine");
990 //SCRUTE(_computeState);
993 int dim = SMESH_Gen::GetShapeDim(_subShape);
997 if (_vertexSet) _computeState = COMPUTE_OK;
998 else _computeState = READY_TO_COMPUTE;
999 //SCRUTE(_computeState);
1002 SMESH_Gen* gen =_father->GetGen();
1003 SMESH_Algo* algo = 0;
1006 switch(_computeState)
1009 // ----------------------------------------------------------------------
1014 case MODIF_HYP: // nothing to do
1016 case MODIF_ALGO_STATE:
1017 if (_algoState == HYP_OK)
1018 _computeState = READY_TO_COMPUTE;
1020 case COMPUTE: // nothing to do
1022 case CLEAN: // nothing to do
1024 case CLEANDEP: // nothing to do
1025 RemoveSubMeshElementsAndNodes(); // recursive call...
1027 case SUBMESH_COMPUTED: // nothing to do
1035 // ----------------------------------------------------------------------
1037 case READY_TO_COMPUTE:
1040 case MODIF_HYP: // nothing to do
1042 case MODIF_ALGO_STATE:
1043 _computeState = NOT_READY;
1044 algo = gen->GetAlgo((*_father), _subShape);
1047 ret = algo->CheckHypothesis((*_father),_subShape);
1048 if (ret) _computeState = READY_TO_COMPUTE;
1053 algo = gen->GetAlgo((*_father), _subShape);
1055 ret = algo->CheckHypothesis((*_father),_subShape);
1058 MESSAGE("***** verify compute state *****");
1059 _computeState = NOT_READY;
1062 ret = SubMeshesComputed();
1065 MESSAGE("Some SubMeshes not computed");
1066 _computeState = FAILED_TO_COMPUTE;
1069 ret = algo->Compute((*_father),_subShape);
1072 MESSAGE("problem in algo execution: failed to compute");
1073 _computeState = FAILED_TO_COMPUTE;
1078 _computeState = COMPUTE_OK;
1079 UpdateDependantsState(); // send event SUBMESH_COMPUTED
1084 _computeState = NOT_READY;
1085 algo = gen->GetAlgo((*_father), _subShape);
1088 ret = algo->CheckHypothesis((*_father),_subShape);
1089 if (ret) _computeState = READY_TO_COMPUTE;
1093 RemoveSubMeshElementsAndNodes();
1094 _computeState = NOT_READY;
1095 algo = gen->GetAlgo((*_father), _subShape);
1098 ret = algo->CheckHypothesis((*_father),_subShape);
1099 if (ret) _computeState = READY_TO_COMPUTE;
1102 case SUBMESH_COMPUTED: // nothing to do
1110 // ----------------------------------------------------------------------
1116 CleanDependants(); // recursive recall with event CLEANDEP
1118 case MODIF_ALGO_STATE:
1119 CleanDependants(); // recursive recall with event CLEANDEP
1121 case COMPUTE: // nothing to do
1124 CleanDependants(); // recursive recall with event CLEANDEP
1127 RemoveSubMeshElementsAndNodes();
1128 _computeState = NOT_READY;
1129 algo = gen->GetAlgo((*_father), _subShape);
1132 ret = algo->CheckHypothesis((*_father),_subShape);
1133 if (ret) _computeState = READY_TO_COMPUTE;
1136 case SUBMESH_COMPUTED: // nothing to do
1144 // ----------------------------------------------------------------------
1146 case FAILED_TO_COMPUTE:
1150 if (_algoState == HYP_OK)
1151 _computeState = READY_TO_COMPUTE;
1152 else _computeState = NOT_READY;
1154 case MODIF_ALGO_STATE:
1155 if (_algoState == HYP_OK)
1156 _computeState = READY_TO_COMPUTE;
1157 else _computeState = NOT_READY;
1159 case COMPUTE: // nothing to do
1164 RemoveSubMeshElementsAndNodes();
1165 if (_algoState == HYP_OK)
1166 _computeState = READY_TO_COMPUTE;
1167 else _computeState = NOT_READY;
1169 case SUBMESH_COMPUTED: // allow retry compute
1170 if (_algoState == HYP_OK)
1171 _computeState = READY_TO_COMPUTE;
1172 else _computeState = NOT_READY;
1180 // ----------------------------------------------------------------------
1186 //SCRUTE(_computeState);
1190 //=============================================================================
1194 //=============================================================================
1196 void SMESH_subMesh::UpdateDependantsState()
1198 //MESSAGE("SMESH_subMesh::UpdateDependantsState");
1200 const map<int, SMESH_subMesh*>& dependants = Dependants();
1201 map<int, SMESH_subMesh*>::const_iterator its;
1202 for (its = dependants.begin(); its != dependants.end(); its++)
1204 SMESH_subMesh* sm = (*its).second;
1205 //SCRUTE((*its).first);
1206 sm->ComputeStateEngine(SUBMESH_COMPUTED);
1210 //=============================================================================
1214 //=============================================================================
1216 void SMESH_subMesh::CleanDependants()
1218 MESSAGE("SMESH_subMesh::CleanDependants");
1219 // **** parcourir les ancetres dans l'ordre de dépendance
1221 const map<int, SMESH_subMesh*>& dependants = Dependants();
1222 map<int, SMESH_subMesh*>::const_iterator its;
1223 for (its = dependants.begin(); its != dependants.end(); its++)
1225 SMESH_subMesh* sm = (*its).second;
1226 SCRUTE((*its).first);
1227 sm->ComputeStateEngine(CLEANDEP);
1229 ComputeStateEngine(CLEANDEP);
1231 //=============================================================================
1235 //=============================================================================
1237 void SMESH_subMesh::RemoveSubMeshElementsAndNodes()
1239 MESSAGE("SMESH_subMesh::RemoveSubMeshElementsAndNodes");
1240 SCRUTE(_subShape.ShapeType());
1243 _subMeshDS = _meshDS->MeshElements(_subShape);
1244 if (!_subMeshDS.IsNull())
1246 const TColStd_ListOfInteger& indElt
1247 = _subMeshDS->GetIDElements();
1248 TColStd_ListIteratorOfListOfInteger ite(indElt);
1249 for (; ite.More(); ite.Next())
1251 int eltId = ite.Value();
1253 Handle (SMDS_MeshElement) elt = _meshDS->FindElement(eltId);
1254 _subMeshDS->RemoveElement(elt);
1255 _meshDS->RemoveElement(eltId);
1258 const TColStd_ListOfInteger& indNodes
1259 = _subMeshDS->GetIDNodes();
1260 TColStd_ListIteratorOfListOfInteger itn(indNodes);
1261 for (; itn.More(); itn.Next())
1263 int nodeId = itn.Value();
1265 Handle (SMDS_MeshElement) elt = _meshDS->FindNode(nodeId);
1266 Handle (SMDS_MeshNode) node = _meshDS->GetNode(1, elt);
1267 _subMeshDS->RemoveNode(node);
1268 _meshDS->RemoveNode(nodeId);
1273 //=============================================================================
1277 //=============================================================================
1279 const map<int, SMESH_subMesh*>& SMESH_subMesh::Dependants()
1281 if (_dependantsFound) return _mapDependants;
1283 //MESSAGE("SMESH_subMesh::Dependants");
1285 int shapeType = _subShape.ShapeType();
1286 //SCRUTE(shapeType);
1287 TopTools_IndexedDataMapOfShapeListOfShape M;
1288 TopoDS_Shape mainShape = _meshDS->ShapeToMesh();
1296 TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_WIRE, M);
1297 TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_FACE, M);
1298 TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_SHELL, M);
1299 TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_SOLID, M);
1300 TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_COMPSOLID, M);
1301 ExtractDependants(M, TopAbs_EDGE);
1305 TopExp::MapShapesAndAncestors(mainShape, TopAbs_FACE, TopAbs_SHELL, M);
1306 TopExp::MapShapesAndAncestors(mainShape, TopAbs_FACE, TopAbs_SOLID, M);
1307 TopExp::MapShapesAndAncestors(mainShape, TopAbs_FACE, TopAbs_COMPSOLID, M);
1308 ExtractDependants(M, TopAbs_FACE);
1311 case TopAbs_COMPSOLID:
1312 TopExp::MapShapesAndAncestors(mainShape, TopAbs_SOLID, TopAbs_COMPSOLID, M);
1313 ExtractDependants(M, TopAbs_SOLID);
1315 case TopAbs_COMPOUND:
1319 _dependantsFound = true;
1320 return _mapDependants;
1323 //=============================================================================
1327 //=============================================================================
1329 void SMESH_subMesh::ExtractDependants(const TopTools_IndexedDataMapOfShapeListOfShape& M,
1330 const TopAbs_ShapeEnum etype)
1332 //MESSAGE("SMESH_subMesh::ExtractDependants");
1334 TopoDS_Shape mainShape = _meshDS->ShapeToMesh();
1335 int lg = M.Extent();
1338 int shapeType = _subShape.ShapeType();
1347 const TopTools_ListOfShape& ancestors = M.FindFromKey(_subShape);
1348 TopTools_ListIteratorOfListOfShape it(ancestors);
1349 for ( ; it.More();it.Next())
1351 TopoDS_Shape ancestor = it.Value();
1352 SMESH_subMesh* aSubMesh = _father->GetSubMeshContaining(ancestor);
1353 // if (! aSubMesh) aSubMesh = _father->GetSubMesh(ancestor);
1356 int type = aSubMesh->_subShape.ShapeType();
1357 int cle = aSubMesh->GetId();
1358 cle += 10000000 * type; // sort map by ordType then index
1359 if (_mapDependants.find(cle) == _mapDependants.end())
1361 _mapDependants[cle] = aSubMesh;
1370 case TopAbs_COMPSOLID:
1371 for (TopExp_Explorer expE(_subShape, etype); expE.More(); expE.Next())
1373 TopoDS_Shape aShape = expE.Current();
1374 const TopTools_ListOfShape& ancestors = M.FindFromKey( aShape);
1375 TopTools_ListIteratorOfListOfShape it(ancestors);
1376 for ( ; it.More();it.Next())
1379 TopoDS_Shape ancestor = it.Value();
1380 SMESH_subMesh* aSubMesh = _father->GetSubMeshContaining(ancestor);
1381 if (! aSubMesh) aSubMesh = _father->GetSubMesh(ancestor);
1382 int type = aSubMesh->_subShape.ShapeType();
1383 int cle = aSubMesh->GetId();
1384 cle += 10000000 * type; // sort map by ordType then index
1385 if (_mapDependants.find(cle) == _mapDependants.end())
1387 _mapDependants[cle] = aSubMesh;
1393 case TopAbs_COMPOUND: