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;
253 const TopoDS_Shape & ss = sm->GetSubShape();
254 int type = ss.ShapeType();
255 // SCRUTE(sm->GetId());
256 // SCRUTE(sm->GetComputeState());
257 bool computeOk = (sm->GetComputeState() == COMPUTE_OK);
260 subMeshesComputed = false;
264 case TopAbs_COMPOUND:
266 MESSAGE("The not computed sub mesh is a COMPOUND");
269 case TopAbs_COMPSOLID:
271 MESSAGE("The not computed sub mesh is a COMPSOLID");
276 MESSAGE("The not computed sub mesh is a SHEL");
281 MESSAGE("The not computed sub mesh is a WIRE");
286 MESSAGE("The not computed sub mesh is a SOLID");
291 MESSAGE("The not computed sub mesh is a FACE");
296 MESSAGE("The not computed sub mesh is a EDGE");
301 MESSAGE("The not computed sub mesh is of unknown type");
310 return subMeshesComputed;
313 //=============================================================================
317 //=============================================================================
319 bool SMESH_subMesh::SubMeshesReady()
321 MESSAGE("SMESH_subMesh::SubMeshesReady");
322 const map < int, SMESH_subMesh * >&subMeshes = DependsOn();
324 bool subMeshesReady = true;
325 map < int, SMESH_subMesh * >::const_iterator itsub;
326 for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
328 SMESH_subMesh *sm = (*itsub).second;
329 // SCRUTE(sm->GetId());
330 // SCRUTE(sm->GetComputeState());
331 bool computeOk = ((sm->GetComputeState() == COMPUTE_OK)
332 || (sm->GetComputeState() == READY_TO_COMPUTE));
335 subMeshesReady = false;
340 return subMeshesReady;
343 //=============================================================================
345 * Construct dependence on first level subMeshes. complex shapes (compsolid,
346 * shell, wire) are not analysed the same way as simple shapes (solid, face,
348 * For collection shapes (compsolid, shell, wire) prepare a list of submeshes
349 * with possible multiples occurences. Multiples occurences corresponds to
350 * internal frontiers within shapes of the collection and must not be keeped.
351 * See FinalizeDependence.
353 //=============================================================================
355 const map < int, SMESH_subMesh * >&SMESH_subMesh::DependsOn()
357 if (_dependenceAnalysed)
360 //MESSAGE("SMESH_subMesh::DependsOn");
362 int type = _subShape.ShapeType();
366 case TopAbs_COMPOUND:
368 //MESSAGE("compound");
369 list < TopoDS_Shape > shellInSolid;
370 for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More();
373 InsertDependence(exp.Current());
375 exp2(exp.Current(), TopAbs_SHELL); exp2.More(); exp2.Next())
377 shellInSolid.push_back(exp2.Current());
380 for (TopExp_Explorer exp(_subShape, TopAbs_SHELL); exp.More();
383 list < TopoDS_Shape >::iterator it1;
384 bool isInSolid = false;
385 for (it1 = shellInSolid.begin(); it1 != shellInSolid.end(); it1++)
387 TopoDS_Shape aShape = (*it1);
388 if (aShape.IsSame(exp.Current()))
395 InsertDependence(exp.Current()); //only shell not in solid
397 for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More();
400 InsertDependence(exp.Current());
402 for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More();
405 InsertDependence(exp.Current());
409 case TopAbs_COMPSOLID:
411 //MESSAGE("compsolid");
412 for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More();
415 InsertDependence(exp.Current());
417 // list<TopoDS_Shape> shapeList;
418 // for (TopExp_Explorer exp(_subShape,TopAbs_SOLID);exp.More();exp.Next())
420 // for (TopExp_Explorer
421 // exp2(exp.Current(),TopAbs_FACE);exp2.More();exp2.Next())
423 // shapeList.push_back(exp2.Current());
426 // FinalizeDependence(shapeList);
432 for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More();
435 InsertDependence(exp.Current());
437 // list<TopoDS_Shape> shapeList;
438 // for (TopExp_Explorer exp(_subShape,TopAbs_FACE);exp.More();exp.Next())
440 // for (TopExp_Explorer
441 // exp2(exp.Current(),TopAbs_EDGE);exp2.More();exp2.Next())
443 // shapeList.push_back(exp2.Current());
446 // FinalizeDependence(shapeList);
452 for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More();
455 InsertDependence(exp.Current());
457 // list<TopoDS_Shape> shapeList;
458 // for (TopExp_Explorer exp(_subShape,TopAbs_EDGE);exp.More();exp.Next())
460 // for (TopExp_Explorer
461 // exp2(exp.Current(),TopAbs_VERTEX);exp2.More();exp2.Next())
463 // shapeList.push_back(exp2.Current());
466 // FinalizeDependence(shapeList);
472 // for (TopExp_Explorer exp(_subShape,TopAbs_SHELL);exp.More();exp.Next())
474 // InsertDependence(exp.Current());
476 for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More();
479 InsertDependence(exp.Current());
486 // for (TopExp_Explorer exp(_subShape,TopAbs_WIRE);exp.More();exp.Next())
488 // InsertDependence(exp.Current());
490 for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More();
493 InsertDependence(exp.Current());
500 for (TopExp_Explorer exp(_subShape, TopAbs_VERTEX); exp.More();
503 InsertDependence(exp.Current());
516 _dependenceAnalysed = true;
520 //=============================================================================
522 * For simple Shapes (solid, face, edge): add subMesh into dependence list.
524 //=============================================================================
526 void SMESH_subMesh::InsertDependence(const TopoDS_Shape aSubShape)
528 //MESSAGE("SMESH_subMesh::InsertDependence");
529 //SMESH_subMesh* aSubMesh = _father->GetSubMeshContaining(aSubShape);
531 //if (! aSubMesh) aSubMesh = _father->GetSubMesh(aSubShape);
533 SMESH_subMesh *aSubMesh = _father->GetSubMesh(aSubShape);
534 int type = aSubShape.ShapeType();
535 int ordType = 9 - type; // 2 = Vertex, 8 = CompSolid
536 int cle = aSubMesh->GetId();
537 cle += 10000000 * ordType; // sort map by ordType then index
538 if (_mapDepend.find(cle) == _mapDepend.end())
540 _mapDepend[cle] = aSubMesh;
541 const map < int, SMESH_subMesh * >&subMap = aSubMesh->DependsOn();
542 map < int, SMESH_subMesh * >::const_iterator im;
543 for (im = subMap.begin(); im != subMap.end(); im++)
545 int clesub = (*im).first;
546 SMESH_subMesh *sm = (*im).second;
547 if (_mapDepend.find(clesub) == _mapDepend.end())
548 _mapDepend[clesub] = sm;
554 //=============================================================================
556 * For collection shapes (compsolid, shell, wire).
557 * Add only subMesh figuring only once in multiset to dependence list
559 //=============================================================================
561 // void SMESH_subMesh::FinalizeDependence(list<TopoDS_Shape>& shapeList)
563 // //MESSAGE("SMESH_subMesh::FinalizeDependence");
564 // list<TopoDS_Shape>::iterator it1, it2;
565 // for(it1 = shapeList.begin(); it1 != shapeList.end(); it1++)
567 // TopoDS_Shape aSubShape = (*it1);
569 // for(it2 = shapeList.begin(); it2 != shapeList.end(); it2++)
571 // TopoDS_Shape other = (*it2);
572 // if (other.IsSame(aSubShape)) count++;
574 // if (count == 1) InsertDependence(aSubShape);
579 //=============================================================================
583 //=============================================================================
585 const TopoDS_Shape & SMESH_subMesh::GetSubShape()
587 //MESSAGE("SMESH_subMesh::GetSubShape");
591 //=============================================================================
595 //=============================================================================
597 bool SMESH_subMesh::AlgoStateEngine(int event, SMESH_Hypothesis * anHyp)
598 throw(SALOME_Exception)
600 // MESSAGE("SMESH_subMesh::AlgoStateEngine");
601 //SCRUTE(_algoState);
604 // **** les retour des evenement shape sont significatifs
605 // (add ou remove fait ou non)
606 // le retour des evenement father n'indiquent pas que add ou remove fait
607 int dim = SMESH_Gen::GetShapeDim(_subShape);
612 //SCRUTE(_algoState);
616 SMESH_Gen *gen = _father->GetGen();
618 _oldAlgoState = _algoState;
619 bool modifiedHyp = false; // if set to true, force event MODIF_ALGO_STATE
620 // in ComputeStateEngine
625 // ----------------------------------------------------------------------
631 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
632 ret = _meshDS->AddHypothesis(_subShape, anHyp);
635 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
636 if (anHyp->GetDim() <= SMESH_Gen::GetShapeDim(_subShape))
638 ret = _meshDS->AddHypothesis(_subShape, anHyp);
639 // if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)))
640 // if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType()))
642 (anHyp->GetShapeType() & (1 << _subShape.ShapeType())))
644 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
646 ret = algo->CheckHypothesis((*_father), _subShape);
648 SetAlgoState(HYP_OK);
650 SetAlgoState(MISSING_HYP);
655 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
656 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
659 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
660 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
662 case ADD_FATHER_HYP: // nothing to do
664 case ADD_FATHER_ALGO: // Algo just added in father
665 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
666 // if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))
667 // if (anHyp->GetShapeType() == _subShape.ShapeType())
668 if (anHyp->GetShapeType() & (1 << _subShape.ShapeType()))
670 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
672 ret = algo->CheckHypothesis((*_father), _subShape);
674 SetAlgoState(HYP_OK);
676 SetAlgoState(MISSING_HYP);
679 case REMOVE_FATHER_HYP: // nothing to do
681 case REMOVE_FATHER_ALGO: // nothing to do
689 // ----------------------------------------------------------------------
695 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
696 ret = _meshDS->AddHypothesis(_subShape, anHyp);
699 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
701 ret = algo->CheckHypothesis((*_father), _subShape);
703 SetAlgoState(HYP_OK);
705 SetAlgoState(MISSING_HYP);
708 case ADD_ALGO: //already existing algo : on father ?
709 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
710 if (anHyp->GetDim() <= SMESH_Gen::GetShapeDim(_subShape))
712 ret = _meshDS->AddHypothesis(_subShape, anHyp);
713 // if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)))
714 // if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType()))
716 (anHyp->GetShapeType() & (1 << _subShape.ShapeType())))
718 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
719 if (algo == NULL) // two algo on the same subShape...
721 MESSAGE("two algo on the same subshape not allowed");
722 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
727 ret = algo->CheckHypothesis((*_father), _subShape);
729 SetAlgoState(HYP_OK);
731 SetAlgoState(MISSING_HYP);
737 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
738 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
740 case REMOVE_ALGO: // perhaps a father algo applies ?
741 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
742 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
743 // if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)))
744 // if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType()))
745 if (ret && (anHyp->GetShapeType() & (1 << _subShape.ShapeType())))
747 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
748 if (algo == NULL) // no more algo applying on subShape...
750 SetAlgoState(NO_ALGO);
754 ret = algo->CheckHypothesis((*_father), _subShape);
756 SetAlgoState(HYP_OK);
758 SetAlgoState(MISSING_HYP);
763 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
765 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
767 ret = algo->CheckHypothesis((*_father), _subShape);
769 SetAlgoState(HYP_OK);
771 SetAlgoState(MISSING_HYP);
774 case ADD_FATHER_ALGO: // detect if two algo of same dim on father
775 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
776 // if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))
777 // if (anHyp->GetShapeType() == _subShape.ShapeType())
778 if (anHyp->GetShapeType() & (1 << _subShape.ShapeType()))
780 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
781 if (algo == NULL) // two applying algo on father
783 MESSAGE("two applying algo on fatherShape...");
784 SetAlgoState(NO_ALGO);
788 ret = algo->CheckHypothesis((*_father), _subShape);
790 SetAlgoState(HYP_OK);
792 SetAlgoState(MISSING_HYP);
796 case REMOVE_FATHER_HYP: // nothing to do
798 case REMOVE_FATHER_ALGO:
799 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
800 // if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))
801 // if (anHyp->GetShapeType() == _subShape.ShapeType())
802 if (anHyp->GetShapeType() & (1 << _subShape.ShapeType()))
804 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
805 if (algo == NULL) // no more applying algo on father
807 SetAlgoState(NO_ALGO);
811 ret = algo->CheckHypothesis((*_father), _subShape);
813 SetAlgoState(HYP_OK);
815 SetAlgoState(MISSING_HYP);
825 // ----------------------------------------------------------------------
832 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
833 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
835 list<const SMESHDS_Hypothesis *> originalUsedHyps = algo->GetUsedHypothesis((*_father), _subShape); // copy
837 ret = _meshDS->AddHypothesis(_subShape, anHyp);
840 ret = algo->CheckHypothesis((*_father), _subShape);
843 INFOS("two applying algo on the same shape not allowed");
844 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
847 else // compare SMESHDS_Hypothesis* lists (order important)
850 const list <const SMESHDS_Hypothesis *> & newUsedHyps
851 = algo->GetUsedHypothesis((*_father), _subShape);
852 modifiedHyp = (originalUsedHyps != newUsedHyps);
857 case ADD_ALGO: //already existing algo : on father ?
858 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
859 if (anHyp->GetDim() <= SMESH_Gen::GetShapeDim(_subShape))
861 ret = _meshDS->AddHypothesis(_subShape, anHyp);
862 // if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)))
863 // if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType()))
865 (anHyp->GetShapeType() & (1 << _subShape.ShapeType())))
867 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
868 if (algo == NULL) // two algo on the same subShape...
870 INFOS("two algo on the same subshape not allowed");
871 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
876 ret = algo->CheckHypothesis((*_father), _subShape);
878 SetAlgoState(HYP_OK);
880 SetAlgoState(MISSING_HYP);
886 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
887 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
890 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
892 ret = algo->CheckHypothesis((*_father), _subShape);
894 SetAlgoState(HYP_OK);
896 SetAlgoState(MISSING_HYP);
900 case REMOVE_ALGO: // perhaps a father algo applies ?
901 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
902 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
903 // if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)))
904 // if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType()))
905 if (ret && (anHyp->GetShapeType() & (1 << _subShape.ShapeType())))
907 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
908 if (algo == NULL) // no more algo applying on subShape...
910 SetAlgoState(NO_ALGO);
914 ret = algo->CheckHypothesis((*_father), _subShape);
916 SetAlgoState(HYP_OK);
918 SetAlgoState(MISSING_HYP);
923 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
925 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
927 ret = algo->CheckHypothesis((*_father), _subShape);
929 SetAlgoState(HYP_OK);
931 SetAlgoState(MISSING_HYP);
934 case ADD_FATHER_ALGO: // detect if two algo of same dim on father
935 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
936 // if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))
937 // if (anHyp->GetShapeType() == _subShape.ShapeType())
938 if (anHyp->GetShapeType() & (1 << _subShape.ShapeType()))
940 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
941 if (algo == NULL) // two applying algo on father
943 MESSAGE("two applying algo on fatherShape...");
944 SetAlgoState(NO_ALGO);
948 ret = algo->CheckHypothesis((*_father), _subShape);
950 SetAlgoState(HYP_OK);
952 SetAlgoState(MISSING_HYP);
956 case REMOVE_FATHER_HYP:
957 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
959 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
961 ret = algo->CheckHypothesis((*_father), _subShape);
963 SetAlgoState(HYP_OK);
965 SetAlgoState(MISSING_HYP);
968 case REMOVE_FATHER_ALGO:
969 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
970 // if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))
971 // if (anHyp->GetShapeType() == _subShape.ShapeType())
972 if (anHyp->GetShapeType() & (1 << _subShape.ShapeType()))
974 SMESH_Algo *algo = gen->GetAlgo((*_father), _subShape);
975 if (algo == NULL) // no more applying algo on father
977 SetAlgoState(NO_ALGO);
981 ret = algo->CheckHypothesis((*_father), _subShape);
983 SetAlgoState(HYP_OK);
985 SetAlgoState(MISSING_HYP);
995 // ----------------------------------------------------------------------
1001 //SCRUTE(_algoState);
1002 if ((_algoState != _oldAlgoState) || modifiedHyp)
1003 int retc = ComputeStateEngine(MODIF_ALGO_STATE);
1007 //=============================================================================
1011 //=============================================================================
1013 void SMESH_subMesh::SetAlgoState(int state)
1015 if (state != _oldAlgoState)
1016 // int retc = ComputeStateEngine(MODIF_ALGO_STATE);
1020 //=============================================================================
1024 //=============================================================================
1026 void SMESH_subMesh::SubMeshesAlgoStateEngine(int event,
1027 SMESH_Hypothesis * anHyp) throw(SALOME_Exception)
1029 //MESSAGE("SMESH_subMesh::SubMeshesAlgoStateEngine");
1030 int dim = SMESH_Gen::GetShapeDim(_subShape);
1033 const map < int, SMESH_subMesh * >&subMeshes = DependsOn();
1035 map < int, SMESH_subMesh * >::const_iterator itsub;
1036 for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
1038 SMESH_subMesh *sm = (*itsub).second;
1039 sm->AlgoStateEngine(event, anHyp);
1044 //=============================================================================
1048 //=============================================================================
1050 void SMESH_subMesh::DumpAlgoState(bool isMain)
1052 int dim = SMESH_Gen::GetShapeDim(_subShape);
1053 // if (dim < 1) return;
1056 const map < int, SMESH_subMesh * >&subMeshes = DependsOn();
1058 map < int, SMESH_subMesh * >::const_iterator itsub;
1059 for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
1061 SMESH_subMesh *sm = (*itsub).second;
1062 sm->DumpAlgoState(false);
1065 int type = _subShape.ShapeType();
1066 MESSAGE("dim = " << dim << " type of shape " << type);
1070 MESSAGE(" AlgoState = NO_ALGO");
1073 MESSAGE(" AlgoState = MISSING_HYP");
1076 MESSAGE(" AlgoState = HYP_OK");
1079 switch (_computeState)
1082 MESSAGE(" ComputeState = NOT_READY");
1084 case READY_TO_COMPUTE:
1085 MESSAGE(" ComputeState = READY_TO_COMPUTE");
1088 MESSAGE(" ComputeState = COMPUTE_OK");
1090 case FAILED_TO_COMPUTE:
1091 MESSAGE(" ComputeState = FAILED_TO_COMPUTE");
1096 //=============================================================================
1100 //=============================================================================
1102 bool SMESH_subMesh::ComputeStateEngine(int event) throw(SALOME_Exception)
1104 //MESSAGE("SMESH_subMesh::ComputeStateEngine");
1105 //SCRUTE(_computeState);
1108 int dim = SMESH_Gen::GetShapeDim(_subShape);
1113 _computeState = COMPUTE_OK;
1115 _computeState = READY_TO_COMPUTE;
1116 //SCRUTE(_computeState);
1119 SMESH_Gen *gen = _father->GetGen();
1120 SMESH_Algo *algo = 0;
1123 switch (_computeState)
1126 // ----------------------------------------------------------------------
1131 case MODIF_HYP: // nothing to do
1133 case MODIF_ALGO_STATE:
1134 if (_algoState == HYP_OK)
1135 _computeState = READY_TO_COMPUTE;
1137 case COMPUTE: // nothing to do
1139 case CLEAN: // nothing to do
1141 case CLEANDEP: // nothing to do
1142 RemoveSubMeshElementsAndNodes(); // recursive call...
1144 case SUBMESH_COMPUTED: // nothing to do
1152 // ----------------------------------------------------------------------
1154 case READY_TO_COMPUTE:
1157 case MODIF_HYP: // nothing to do
1159 case MODIF_ALGO_STATE:
1160 _computeState = NOT_READY;
1161 algo = gen->GetAlgo((*_father), _subShape);
1164 ret = algo->CheckHypothesis((*_father), _subShape);
1166 _computeState = READY_TO_COMPUTE;
1171 algo = gen->GetAlgo((*_father), _subShape);
1173 ret = algo->CheckHypothesis((*_father), _subShape);
1176 MESSAGE("***** verify compute state *****");
1177 _computeState = NOT_READY;
1180 ret = SubMeshesComputed();
1183 MESSAGE("Some SubMeshes not computed");
1184 _computeState = FAILED_TO_COMPUTE;
1187 ret = algo->Compute((*_father), _subShape);
1190 MESSAGE("problem in algo execution: failed to compute");
1191 _computeState = FAILED_TO_COMPUTE;
1196 _computeState = COMPUTE_OK;
1197 UpdateDependantsState(); // send event SUBMESH_COMPUTED
1202 _computeState = NOT_READY;
1203 algo = gen->GetAlgo((*_father), _subShape);
1206 ret = algo->CheckHypothesis((*_father), _subShape);
1208 _computeState = READY_TO_COMPUTE;
1212 RemoveSubMeshElementsAndNodes();
1213 _computeState = NOT_READY;
1214 algo = gen->GetAlgo((*_father), _subShape);
1217 ret = algo->CheckHypothesis((*_father), _subShape);
1219 _computeState = READY_TO_COMPUTE;
1222 case SUBMESH_COMPUTED: // nothing to do
1230 // ----------------------------------------------------------------------
1236 CleanDependants(); // recursive recall with event CLEANDEP
1238 case MODIF_ALGO_STATE:
1239 CleanDependants(); // recursive recall with event CLEANDEP
1241 case COMPUTE: // nothing to do
1244 CleanDependants(); // recursive recall with event CLEANDEP
1247 RemoveSubMeshElementsAndNodes();
1248 _computeState = NOT_READY;
1249 algo = gen->GetAlgo((*_father), _subShape);
1252 ret = algo->CheckHypothesis((*_father), _subShape);
1254 _computeState = READY_TO_COMPUTE;
1257 case SUBMESH_COMPUTED: // nothing to do
1265 // ----------------------------------------------------------------------
1267 case FAILED_TO_COMPUTE:
1271 if (_algoState == HYP_OK)
1272 _computeState = READY_TO_COMPUTE;
1274 _computeState = NOT_READY;
1276 case MODIF_ALGO_STATE:
1277 if (_algoState == HYP_OK)
1278 _computeState = READY_TO_COMPUTE;
1280 _computeState = NOT_READY;
1282 case COMPUTE: // nothing to do
1287 RemoveSubMeshElementsAndNodes();
1288 if (_algoState == HYP_OK)
1289 _computeState = READY_TO_COMPUTE;
1291 _computeState = NOT_READY;
1293 case SUBMESH_COMPUTED: // allow retry compute
1294 if (_algoState == HYP_OK)
1295 _computeState = READY_TO_COMPUTE;
1297 _computeState = NOT_READY;
1305 // ----------------------------------------------------------------------
1311 //SCRUTE(_computeState);
1315 //=============================================================================
1319 //=============================================================================
1321 void SMESH_subMesh::UpdateDependantsState()
1323 //MESSAGE("SMESH_subMesh::UpdateDependantsState");
1325 const map < int, SMESH_subMesh * >&dependants = Dependants();
1326 map < int, SMESH_subMesh * >::const_iterator its;
1327 for (its = dependants.begin(); its != dependants.end(); its++)
1329 SMESH_subMesh *sm = (*its).second;
1330 //SCRUTE((*its).first);
1331 sm->ComputeStateEngine(SUBMESH_COMPUTED);
1335 //=============================================================================
1339 //=============================================================================
1341 void SMESH_subMesh::CleanDependants()
1343 MESSAGE("SMESH_subMesh::CleanDependants");
1344 // **** parcourir les ancetres dans l'ordre de dépendance
1346 const map < int, SMESH_subMesh * >&dependants = Dependants();
1347 map < int, SMESH_subMesh * >::const_iterator its;
1348 for (its = dependants.begin(); its != dependants.end(); its++)
1350 SMESH_subMesh *sm = (*its).second;
1351 SCRUTE((*its).first);
1352 sm->ComputeStateEngine(CLEANDEP);
1354 ComputeStateEngine(CLEANDEP);
1357 //=============================================================================
1361 //=============================================================================
1363 void SMESH_subMesh::RemoveSubMeshElementsAndNodes()
1365 MESSAGE("SMESH_subMesh::RemoveSubMeshElementsAndNodes");
1366 SCRUTE(_subShape.ShapeType());
1369 _subMeshDS = _meshDS->MeshElements(_subShape);
1370 if (_subMeshDS!=NULL)
1372 SMDS_Iterator<const SMDS_MeshElement *> * ite=_subMeshDS->GetElements();
1375 const SMDS_MeshElement * elt = ite->next();
1376 _subMeshDS->RemoveElement(elt);
1377 _meshDS->RemoveElement(elt);
1381 SMDS_Iterator<const SMDS_MeshNode *> * itn=_subMeshDS->GetNodes();
1384 const SMDS_MeshNode * node = itn->next();
1385 _subMeshDS->RemoveNode(node);
1386 _meshDS->RemoveNode(node);
1392 //=============================================================================
1396 //=============================================================================
1398 const map < int, SMESH_subMesh * >&SMESH_subMesh::Dependants()
1400 if (_dependantsFound)
1401 return _mapDependants;
1403 //MESSAGE("SMESH_subMesh::Dependants");
1405 int shapeType = _subShape.ShapeType();
1406 //SCRUTE(shapeType);
1407 TopTools_IndexedDataMapOfShapeListOfShape M;
1408 TopoDS_Shape mainShape = _meshDS->ShapeToMesh();
1416 TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_WIRE, M);
1417 TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_FACE, M);
1418 TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_SHELL, M);
1419 TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_SOLID, M);
1420 TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_COMPSOLID,
1422 ExtractDependants(M, TopAbs_EDGE);
1426 TopExp::MapShapesAndAncestors(mainShape, TopAbs_FACE, TopAbs_SHELL, M);
1427 TopExp::MapShapesAndAncestors(mainShape, TopAbs_FACE, TopAbs_SOLID, M);
1428 TopExp::MapShapesAndAncestors(mainShape, TopAbs_FACE, TopAbs_COMPSOLID,
1430 ExtractDependants(M, TopAbs_FACE);
1433 case TopAbs_COMPSOLID:
1434 TopExp::MapShapesAndAncestors(mainShape, TopAbs_SOLID, TopAbs_COMPSOLID,
1436 ExtractDependants(M, TopAbs_SOLID);
1438 case TopAbs_COMPOUND:
1442 _dependantsFound = true;
1443 return _mapDependants;
1446 //=============================================================================
1450 //=============================================================================
1452 void SMESH_subMesh::
1453 ExtractDependants(const TopTools_IndexedDataMapOfShapeListOfShape & M,
1454 const TopAbs_ShapeEnum etype)
1456 //MESSAGE("SMESH_subMesh::ExtractDependants");
1458 TopoDS_Shape mainShape = _meshDS->ShapeToMesh();
1459 int lg = M.Extent();
1462 int shapeType = _subShape.ShapeType();
1471 const TopTools_ListOfShape & ancestors = M.FindFromKey(_subShape);
1472 TopTools_ListIteratorOfListOfShape it(ancestors);
1473 for (; it.More(); it.Next())
1475 TopoDS_Shape ancestor = it.Value();
1476 SMESH_subMesh *aSubMesh = _father->GetSubMeshContaining(ancestor);
1477 // if (! aSubMesh) aSubMesh = _father->GetSubMesh(ancestor);
1480 int type = aSubMesh->_subShape.ShapeType();
1481 int cle = aSubMesh->GetId();
1482 cle += 10000000 * type; // sort map by ordType then index
1483 if (_mapDependants.find(cle) == _mapDependants.end())
1485 _mapDependants[cle] = aSubMesh;
1494 case TopAbs_COMPSOLID:
1495 for (TopExp_Explorer expE(_subShape, etype); expE.More(); expE.Next())
1497 TopoDS_Shape aShape = expE.Current();
1498 const TopTools_ListOfShape & ancestors = M.FindFromKey(aShape);
1499 TopTools_ListIteratorOfListOfShape it(ancestors);
1500 for (; it.More(); it.Next())
1503 TopoDS_Shape ancestor = it.Value();
1504 SMESH_subMesh *aSubMesh =
1505 _father->GetSubMeshContaining(ancestor);
1507 aSubMesh = _father->GetSubMesh(ancestor);
1508 int type = aSubMesh->_subShape.ShapeType();
1509 int cle = aSubMesh->GetId();
1510 cle += 10000000 * type; // sort map by ordType then index
1511 if (_mapDependants.find(cle) == _mapDependants.end())
1513 _mapDependants[cle] = aSubMesh;
1519 case TopAbs_COMPOUND: