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,
52 const Handle(SMESHDS_Mesh)& meshDS,
53 const TopoDS_Shape & aSubShape)
55 //MESSAGE("SMESH_subMesh::SMESH_subMesh");
56 _subShape = aSubShape;
58 _subMeshDS = meshDS->MeshElements(_subShape); // may be null ...
61 _vertexSet = false; // only for Vertex subMesh
62 _dependenceAnalysed = false;
63 _dependantsFound = false;
65 if (_subShape.ShapeType() == TopAbs_VERTEX)
68 _computeState = READY_TO_COMPUTE;
73 _computeState = NOT_READY;
77 //=============================================================================
81 //=============================================================================
83 SMESH_subMesh::~SMESH_subMesh()
85 MESSAGE("SMESH_subMesh::~SMESH_subMesh");
89 //=============================================================================
93 //=============================================================================
95 int SMESH_subMesh::GetId()
97 //MESSAGE("SMESH_subMesh::GetId");
101 //=============================================================================
103 * Given a subShape, find the subMesh is associated to this subShape or
104 * to a collection of shapes containing this subShape. Collection = compsolid,
107 //=============================================================================
109 // bool SMESH_subMesh::Contains(const TopoDS_Shape & aSubShape)
110 // throw (SALOME_Exception)
112 // //MESSAGE("SMESH_subMesh::Contains");
113 // bool contains = false;
114 // int type = _subShape.ShapeType();
115 // int typesub = aSubShape.ShapeType();
120 // // case TopAbs_COMPOUND:
122 // // //MESSAGE("---");
123 // // throw SALOME_Exception(LOCALIZED("Compound not yet treated"));
126 // case TopAbs_COMPSOLID:
129 // for (TopExp_Explorer exp(aSubShape,TopAbs_SOLID);exp.More();exp.Next())
131 // contains = _subShape.IsSame(exp.Current());
132 // if (contains) break;
136 // case TopAbs_SHELL:
139 // for (TopExp_Explorer exp(aSubShape,TopAbs_FACE);exp.More();exp.Next())
141 // contains = _subShape.IsSame(exp.Current());
142 // if (contains) break;
149 // for (TopExp_Explorer exp(aSubShape,TopAbs_EDGE);exp.More();exp.Next())
151 // contains = _subShape.IsSame(exp.Current());
152 // if (contains) break;
156 // case TopAbs_COMPOUND:
157 // case TopAbs_SOLID:
160 // case TopAbs_VERTEX:
163 // contains = _subShape.IsSame(aSubShape);
171 // //SCRUTE(contains);
175 //=============================================================================
179 //=============================================================================
181 const Handle(SMESHDS_SubMesh)& SMESH_subMesh::GetSubMeshDS()
182 throw (SALOME_Exception)
184 //MESSAGE("SMESH_subMesh::GetSubMeshDS");
185 if (_subMeshDS.IsNull())
187 //MESSAGE("subMesh pointer still null, trying to get it...");
188 _subMeshDS = _meshDS->MeshElements(_subShape); // may be null ...
189 if (_subMeshDS.IsNull())
191 MESSAGE("problem... subMesh still empty");
193 //NRI throw SALOME_Exception(LOCALIZED(subMesh still empty));
199 //=============================================================================
203 //=============================================================================
205 SMESH_subMesh* SMESH_subMesh::GetFirstToCompute()
206 throw (SALOME_Exception)
208 //MESSAGE("SMESH_subMesh::GetFirstToCompute");
209 const map<int, SMESH_subMesh*>& subMeshes = DependsOn();
210 SMESH_subMesh* firstToCompute = 0;
212 map<int, SMESH_subMesh*>::const_iterator itsub;
213 for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
215 SMESH_subMesh* sm = (*itsub).second;
216 // SCRUTE(sm->GetId());
217 // SCRUTE(sm->GetComputeState());
218 bool readyToCompute = (sm->GetComputeState() == READY_TO_COMPUTE);
222 //SCRUTE(sm->GetId());
228 //MESSAGE("--- submesh to compute");
229 return firstToCompute; // a subMesh of this
231 if (_computeState == READY_TO_COMPUTE)
233 //MESSAGE("--- this to compute");
236 //MESSAGE("--- nothing to compute");
237 return 0; // nothing to compute
240 //=============================================================================
244 //=============================================================================
246 bool SMESH_subMesh::SubMeshesComputed()
247 throw (SALOME_Exception)
249 //MESSAGE("SMESH_subMesh::SubMeshesComputed");
250 const map<int, SMESH_subMesh*>& subMeshes = DependsOn();
252 bool subMeshesComputed = true;
253 map<int, SMESH_subMesh*>::const_iterator itsub;
254 for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
256 SMESH_subMesh* sm = (*itsub).second;
257 // SCRUTE(sm->GetId());
258 // SCRUTE(sm->GetComputeState());
259 bool computeOk = (sm->GetComputeState() == COMPUTE_OK);
262 subMeshesComputed = false;
267 return subMeshesComputed;
270 //=============================================================================
274 //=============================================================================
276 bool SMESH_subMesh::SubMeshesReady()
278 MESSAGE("SMESH_subMesh::SubMeshesReady");
279 const map<int, SMESH_subMesh*>& subMeshes = DependsOn();
281 bool subMeshesReady = true;
282 map<int, SMESH_subMesh*>::const_iterator itsub;
283 for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
285 SMESH_subMesh* sm = (*itsub).second;
286 // SCRUTE(sm->GetId());
287 // SCRUTE(sm->GetComputeState());
288 bool computeOk = ( (sm->GetComputeState() == COMPUTE_OK)
289 || (sm->GetComputeState() == READY_TO_COMPUTE)) ;
292 subMeshesReady = false;
297 return subMeshesReady;
300 //=============================================================================
302 * Construct dependence on first level subMeshes. complex shapes (compsolid,
303 * shell, wire) are not analysed the same way as simple shapes (solid, face,
305 * For collection shapes (compsolid, shell, wire) prepare a list of submeshes
306 * with possible multiples occurences. Multiples occurences corresponds to
307 * internal frontiers within shapes of the collection and must not be keeped.
308 * See FinalizeDependence.
310 //=============================================================================
312 const map<int, SMESH_subMesh*>& SMESH_subMesh::DependsOn()
314 if (_dependenceAnalysed) return _mapDepend;
316 //MESSAGE("SMESH_subMesh::DependsOn");
318 int type = _subShape.ShapeType();
322 case TopAbs_COMPOUND:
324 //MESSAGE("compound");
325 list<TopoDS_Shape> shellInSolid;
326 for (TopExp_Explorer exp(_subShape,TopAbs_SOLID);exp.More();exp.Next())
328 InsertDependence(exp.Current());
330 exp2(exp.Current(),TopAbs_SHELL);exp2.More();exp2.Next())
332 shellInSolid.push_back(exp2.Current());
335 for (TopExp_Explorer exp(_subShape,TopAbs_SHELL);exp.More();exp.Next())
337 list<TopoDS_Shape>::iterator it1;
338 bool isInSolid = false;
339 for (it1 = shellInSolid.begin(); it1 != shellInSolid.end(); it1++)
341 TopoDS_Shape aShape = (*it1);
342 if (aShape.IsSame(exp.Current()))
349 InsertDependence(exp.Current()); //only shell not in solid
351 for (TopExp_Explorer exp(_subShape,TopAbs_FACE);exp.More();exp.Next())
353 InsertDependence(exp.Current());
355 for (TopExp_Explorer exp(_subShape,TopAbs_EDGE);exp.More();exp.Next())
357 InsertDependence(exp.Current());
361 case TopAbs_COMPSOLID:
363 //MESSAGE("compsolid");
364 for (TopExp_Explorer exp(_subShape,TopAbs_SOLID);exp.More();exp.Next())
366 InsertDependence(exp.Current());
368 // list<TopoDS_Shape> shapeList;
369 // for (TopExp_Explorer exp(_subShape,TopAbs_SOLID);exp.More();exp.Next())
371 // for (TopExp_Explorer
372 // exp2(exp.Current(),TopAbs_FACE);exp2.More();exp2.Next())
374 // shapeList.push_back(exp2.Current());
377 // FinalizeDependence(shapeList);
383 for (TopExp_Explorer exp(_subShape,TopAbs_FACE);exp.More();exp.Next())
385 InsertDependence(exp.Current());
387 // list<TopoDS_Shape> shapeList;
388 // for (TopExp_Explorer exp(_subShape,TopAbs_FACE);exp.More();exp.Next())
390 // for (TopExp_Explorer
391 // exp2(exp.Current(),TopAbs_EDGE);exp2.More();exp2.Next())
393 // shapeList.push_back(exp2.Current());
396 // FinalizeDependence(shapeList);
402 for (TopExp_Explorer exp(_subShape,TopAbs_EDGE);exp.More();exp.Next())
404 InsertDependence(exp.Current());
406 // list<TopoDS_Shape> shapeList;
407 // for (TopExp_Explorer exp(_subShape,TopAbs_EDGE);exp.More();exp.Next())
409 // for (TopExp_Explorer
410 // exp2(exp.Current(),TopAbs_VERTEX);exp2.More();exp2.Next())
412 // shapeList.push_back(exp2.Current());
415 // FinalizeDependence(shapeList);
421 // for (TopExp_Explorer exp(_subShape,TopAbs_SHELL);exp.More();exp.Next())
423 // InsertDependence(exp.Current());
425 for (TopExp_Explorer exp(_subShape,TopAbs_FACE);exp.More();exp.Next())
427 InsertDependence(exp.Current());
434 // for (TopExp_Explorer exp(_subShape,TopAbs_WIRE);exp.More();exp.Next())
436 // InsertDependence(exp.Current());
438 for (TopExp_Explorer exp(_subShape,TopAbs_EDGE);exp.More();exp.Next())
440 InsertDependence(exp.Current());
447 for (TopExp_Explorer exp(_subShape,TopAbs_VERTEX);exp.More();exp.Next())
449 InsertDependence(exp.Current());
462 _dependenceAnalysed = true;
466 //=============================================================================
468 * For simple Shapes (solid, face, edge): add subMesh into dependence list.
470 //=============================================================================
472 void SMESH_subMesh::InsertDependence(const TopoDS_Shape aSubShape)
474 //MESSAGE("SMESH_subMesh::InsertDependence");
475 //SMESH_subMesh* aSubMesh = _father->GetSubMeshContaining(aSubShape);
477 //if (! aSubMesh) aSubMesh = _father->GetSubMesh(aSubShape);
479 SMESH_subMesh* aSubMesh = _father->GetSubMesh(aSubShape);
480 int type = aSubShape.ShapeType();
481 int ordType = 9 - type; // 2 = Vertex, 8 = CompSolid
482 int cle = aSubMesh->GetId();
483 cle += 10000000 * ordType; // sort map by ordType then index
484 if (_mapDepend.find(cle) == _mapDepend.end())
486 _mapDepend[cle] = aSubMesh;
487 const map<int, SMESH_subMesh*>& subMap = aSubMesh->DependsOn();
488 map<int, SMESH_subMesh*>::const_iterator im;
489 for (im = subMap.begin(); im != subMap.end(); im++)
491 int clesub = (*im).first;
492 SMESH_subMesh* sm = (*im).second;
493 if (_mapDepend.find(clesub) == _mapDepend.end())
494 _mapDepend[clesub] = sm;
500 //=============================================================================
502 * For collection shapes (compsolid, shell, wire).
503 * Add only subMesh figuring only once in multiset to dependence list
505 //=============================================================================
507 // void SMESH_subMesh::FinalizeDependence(list<TopoDS_Shape>& shapeList)
509 // //MESSAGE("SMESH_subMesh::FinalizeDependence");
510 // list<TopoDS_Shape>::iterator it1, it2;
511 // for(it1 = shapeList.begin(); it1 != shapeList.end(); it1++)
513 // TopoDS_Shape aSubShape = (*it1);
515 // for(it2 = shapeList.begin(); it2 != shapeList.end(); it2++)
517 // TopoDS_Shape other = (*it2);
518 // if (other.IsSame(aSubShape)) count++;
520 // if (count == 1) InsertDependence(aSubShape);
525 //=============================================================================
529 //=============================================================================
531 const TopoDS_Shape& SMESH_subMesh::GetSubShape()
533 //MESSAGE("SMESH_subMesh::GetSubShape");
537 //=============================================================================
541 //=============================================================================
543 bool SMESH_subMesh::AlgoStateEngine(int event, SMESH_Hypothesis* anHyp)
544 throw (SALOME_Exception)
546 // MESSAGE("SMESH_subMesh::AlgoStateEngine");
547 //SCRUTE(_algoState);
550 // **** les retour des evenement shape sont significatifs
551 // (add ou remove fait ou non)
552 // le retour des evenement father n'indiquent pas que add ou remove fait
553 int dim = SMESH_Gen::GetShapeDim(_subShape);
558 //SCRUTE(_algoState);
562 SMESH_Gen* gen =_father->GetGen();
564 _oldAlgoState = _algoState;
565 bool modifiedHyp = false; // if set to true, force event MODIF_ALGO_STATE
566 // in ComputeStateEngine
571 // ----------------------------------------------------------------------
577 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
578 ret = _meshDS->AddHypothesis(_subShape, anHyp);
581 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
582 if (anHyp->GetDim() <= SMESH_Gen::GetShapeDim(_subShape))
584 ret = _meshDS->AddHypothesis(_subShape, anHyp);
585 // if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)))
586 // if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType()))
587 if (ret &&(anHyp->GetShapeType() & (1<< _subShape.ShapeType())))
589 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
591 ret = algo->CheckHypothesis((*_father),_subShape);
592 if (ret) SetAlgoState(HYP_OK);
593 else SetAlgoState(MISSING_HYP);
598 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
599 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
602 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
603 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
605 case ADD_FATHER_HYP: // nothing to do
607 case ADD_FATHER_ALGO: // Algo just added in father
608 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
609 // if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))
610 // if (anHyp->GetShapeType() == _subShape.ShapeType())
611 if (anHyp->GetShapeType() & (1<< _subShape.ShapeType()))
613 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
615 ret = algo->CheckHypothesis((*_father),_subShape);
616 if (ret) SetAlgoState(HYP_OK);
617 else SetAlgoState(MISSING_HYP);
620 case REMOVE_FATHER_HYP: // nothing to do
622 case REMOVE_FATHER_ALGO: // nothing to do
630 // ----------------------------------------------------------------------
636 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
637 ret = _meshDS->AddHypothesis(_subShape, anHyp);
640 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
642 ret = algo->CheckHypothesis((*_father),_subShape);
643 if (ret) SetAlgoState(HYP_OK);
644 else SetAlgoState(MISSING_HYP);
647 case ADD_ALGO: //already existing algo : on father ?
648 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
649 if (anHyp->GetDim() <= SMESH_Gen::GetShapeDim(_subShape))
651 ret = _meshDS->AddHypothesis(_subShape, anHyp);
652 // if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)))
653 // if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType()))
654 if (ret &&(anHyp->GetShapeType() & (1<< _subShape.ShapeType())))
656 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
657 if (algo == NULL) // two algo on the same subShape...
659 MESSAGE("two algo on the same subshape not allowed");
660 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
665 ret = algo->CheckHypothesis((*_father),_subShape);
666 if (ret) SetAlgoState(HYP_OK);
667 else SetAlgoState(MISSING_HYP);
673 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
674 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
676 case REMOVE_ALGO: // perhaps a father algo applies ?
677 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
678 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
679 // if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)))
680 // if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType()))
681 if (ret &&(anHyp->GetShapeType() & (1<<_subShape.ShapeType())))
683 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
684 if (algo == NULL) // no more algo applying on subShape...
686 SetAlgoState(NO_ALGO);
690 ret = algo->CheckHypothesis((*_father),_subShape);
691 if (ret) SetAlgoState(HYP_OK);
692 else SetAlgoState(MISSING_HYP);
697 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
699 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
701 ret = algo->CheckHypothesis((*_father),_subShape);
702 if (ret) SetAlgoState(HYP_OK);
703 else SetAlgoState(MISSING_HYP);
706 case ADD_FATHER_ALGO: // detect if two algo of same dim on father
707 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
708 // if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))
709 // if (anHyp->GetShapeType() == _subShape.ShapeType())
710 if (anHyp->GetShapeType() & (1<< _subShape.ShapeType()))
712 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
713 if (algo == NULL) // two applying algo on father
715 MESSAGE("two applying algo on fatherShape...");
716 SetAlgoState(NO_ALGO);
720 ret = algo->CheckHypothesis((*_father),_subShape);
721 if (ret) SetAlgoState(HYP_OK);
722 else SetAlgoState(MISSING_HYP);
726 case REMOVE_FATHER_HYP: // nothing to do
728 case REMOVE_FATHER_ALGO:
729 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
730 // if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))
731 // if (anHyp->GetShapeType() == _subShape.ShapeType())
732 if (anHyp->GetShapeType() & (1<< _subShape.ShapeType()))
734 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
735 if (algo == NULL) // no more applying algo on father
737 SetAlgoState(NO_ALGO);
741 ret = algo->CheckHypothesis((*_father),_subShape);
742 if (ret) SetAlgoState(HYP_OK);
743 else SetAlgoState(MISSING_HYP);
753 // ----------------------------------------------------------------------
760 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
761 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
763 list<SMESHDS_Hypothesis*> originalUsedHyps
764 = algo->GetUsedHypothesis((*_father), _subShape); // copy
766 ret = _meshDS->AddHypothesis(_subShape, anHyp);
769 ret = algo->CheckHypothesis((*_father),_subShape);
772 INFOS("two applying algo on the same shape not allowed");
773 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
776 else // compare SMESHDS_Hypothesis* lists (order important)
779 const list<SMESHDS_Hypothesis*>& newUsedHyps
780 = algo->GetUsedHypothesis((*_father), _subShape);
781 modifiedHyp = (originalUsedHyps != newUsedHyps);
786 case ADD_ALGO: //already existing algo : on father ?
787 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
788 if (anHyp->GetDim() <= SMESH_Gen::GetShapeDim(_subShape))
790 ret = _meshDS->AddHypothesis(_subShape, anHyp);
791 // if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)))
792 // if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType()))
793 if (ret &&(anHyp->GetShapeType() & (1<< _subShape.ShapeType())))
795 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
796 if (algo == NULL) // two algo on the same subShape...
798 INFOS("two algo on the same subshape not allowed");
799 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
804 ret = algo->CheckHypothesis((*_father),_subShape);
805 if (ret) SetAlgoState(HYP_OK);
806 else SetAlgoState(MISSING_HYP);
812 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
813 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
816 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
818 ret = algo->CheckHypothesis((*_father),_subShape);
819 if (ret) SetAlgoState(HYP_OK);
820 else SetAlgoState(MISSING_HYP);
824 case REMOVE_ALGO: // perhaps a father algo applies ?
825 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
826 ret = _meshDS->RemoveHypothesis(_subShape, anHyp);
827 // if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)))
828 // if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType()))
829 if (ret &&(anHyp->GetShapeType() & (1<< _subShape.ShapeType())))
831 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
832 if (algo == NULL) // no more algo applying on subShape...
834 SetAlgoState(NO_ALGO);
838 ret = algo->CheckHypothesis((*_father),_subShape);
839 if (ret) SetAlgoState(HYP_OK);
840 else SetAlgoState(MISSING_HYP);
845 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
847 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
849 ret = algo->CheckHypothesis((*_father),_subShape);
850 if (ret) SetAlgoState(HYP_OK);
851 else SetAlgoState(MISSING_HYP);
854 case ADD_FATHER_ALGO: // detect if two algo of same dim on father
855 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
856 // if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))
857 // if (anHyp->GetShapeType() == _subShape.ShapeType())
858 if (anHyp->GetShapeType() & (1<< _subShape.ShapeType()))
860 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
861 if (algo == NULL) // two applying algo on father
863 MESSAGE("two applying algo on fatherShape...");
864 SetAlgoState(NO_ALGO);
868 ret = algo->CheckHypothesis((*_father),_subShape);
869 if (ret) SetAlgoState(HYP_OK);
870 else SetAlgoState(MISSING_HYP);
874 case REMOVE_FATHER_HYP:
875 ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO);
877 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
879 ret = algo->CheckHypothesis((*_father),_subShape);
880 if (ret) SetAlgoState(HYP_OK);
881 else SetAlgoState(MISSING_HYP);
884 case REMOVE_FATHER_ALGO:
885 ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO);
886 // if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))
887 // if (anHyp->GetShapeType() == _subShape.ShapeType())
888 if (anHyp->GetShapeType() & (1<< _subShape.ShapeType()))
890 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
891 if (algo == NULL) // no more applying algo on father
893 SetAlgoState(NO_ALGO);
897 ret = algo->CheckHypothesis((*_father),_subShape);
898 if (ret) SetAlgoState(HYP_OK);
899 else SetAlgoState(MISSING_HYP);
909 // ----------------------------------------------------------------------
915 //SCRUTE(_algoState);
916 if ((_algoState != _oldAlgoState) || modifiedHyp)
917 int retc = ComputeStateEngine(MODIF_ALGO_STATE);
921 //=============================================================================
925 //=============================================================================
927 void SMESH_subMesh::SetAlgoState(int state)
929 if (state != _oldAlgoState)
930 // int retc = ComputeStateEngine(MODIF_ALGO_STATE);
934 //=============================================================================
938 //=============================================================================
940 void SMESH_subMesh::SubMeshesAlgoStateEngine(int event,
941 SMESH_Hypothesis* anHyp)
942 throw (SALOME_Exception)
944 //MESSAGE("SMESH_subMesh::SubMeshesAlgoStateEngine");
945 int dim = SMESH_Gen::GetShapeDim(_subShape);
948 const map<int, SMESH_subMesh*>& subMeshes = DependsOn();
950 map<int, SMESH_subMesh*>::const_iterator itsub;
951 for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
953 SMESH_subMesh* sm = (*itsub).second;
954 sm->AlgoStateEngine(event, anHyp);
959 //=============================================================================
963 //=============================================================================
965 void SMESH_subMesh::DumpAlgoState(bool isMain)
967 int dim = SMESH_Gen::GetShapeDim(_subShape);
968 // if (dim < 1) return;
971 const map<int, SMESH_subMesh*>& subMeshes = DependsOn();
973 map<int, SMESH_subMesh*>::const_iterator itsub;
974 for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
976 SMESH_subMesh* sm = (*itsub).second;
977 sm->DumpAlgoState(false);
980 int type = _subShape.ShapeType();
981 MESSAGE("dim = " << dim << " type of shape " << type);
984 case NO_ALGO: MESSAGE(" AlgoState = NO_ALGO"); break;
985 case MISSING_HYP: MESSAGE(" AlgoState = MISSING_HYP"); break;
986 case HYP_OK: MESSAGE(" AlgoState = HYP_OK"); break;
988 switch (_computeState)
990 case NOT_READY: MESSAGE(" ComputeState = NOT_READY"); break;
991 case READY_TO_COMPUTE: MESSAGE(" ComputeState = READY_TO_COMPUTE"); break;
992 case COMPUTE_OK: MESSAGE(" ComputeState = COMPUTE_OK"); break;
993 case FAILED_TO_COMPUTE: MESSAGE(" ComputeState = FAILED_TO_COMPUTE");break;
997 //=============================================================================
1001 //=============================================================================
1003 bool SMESH_subMesh::ComputeStateEngine(int event)
1004 throw (SALOME_Exception)
1006 //MESSAGE("SMESH_subMesh::ComputeStateEngine");
1007 //SCRUTE(_computeState);
1010 int dim = SMESH_Gen::GetShapeDim(_subShape);
1014 if (_vertexSet) _computeState = COMPUTE_OK;
1015 else _computeState = READY_TO_COMPUTE;
1016 //SCRUTE(_computeState);
1019 SMESH_Gen* gen =_father->GetGen();
1020 SMESH_Algo* algo = 0;
1023 switch(_computeState)
1026 // ----------------------------------------------------------------------
1031 case MODIF_HYP: // nothing to do
1033 case MODIF_ALGO_STATE:
1034 if (_algoState == HYP_OK)
1035 _computeState = READY_TO_COMPUTE;
1037 case COMPUTE: // nothing to do
1039 case CLEAN: // nothing to do
1041 case CLEANDEP: // nothing to do
1042 RemoveSubMeshElementsAndNodes(); // recursive call...
1044 case SUBMESH_COMPUTED: // nothing to do
1052 // ----------------------------------------------------------------------
1054 case READY_TO_COMPUTE:
1057 case MODIF_HYP: // nothing to do
1059 case MODIF_ALGO_STATE:
1060 _computeState = NOT_READY;
1061 algo = gen->GetAlgo((*_father), _subShape);
1064 ret = algo->CheckHypothesis((*_father),_subShape);
1065 if (ret) _computeState = READY_TO_COMPUTE;
1070 algo = gen->GetAlgo((*_father), _subShape);
1072 ret = algo->CheckHypothesis((*_father),_subShape);
1075 MESSAGE("***** verify compute state *****");
1076 _computeState = NOT_READY;
1079 ret = SubMeshesComputed();
1082 MESSAGE("Some SubMeshes not computed");
1083 _computeState = FAILED_TO_COMPUTE;
1086 ret = algo->Compute((*_father),_subShape);
1089 MESSAGE("problem in algo execution: failed to compute");
1090 _computeState = FAILED_TO_COMPUTE;
1095 _computeState = COMPUTE_OK;
1096 UpdateDependantsState(); // send event SUBMESH_COMPUTED
1101 _computeState = NOT_READY;
1102 algo = gen->GetAlgo((*_father), _subShape);
1105 ret = algo->CheckHypothesis((*_father),_subShape);
1106 if (ret) _computeState = READY_TO_COMPUTE;
1110 RemoveSubMeshElementsAndNodes();
1111 _computeState = NOT_READY;
1112 algo = gen->GetAlgo((*_father), _subShape);
1115 ret = algo->CheckHypothesis((*_father),_subShape);
1116 if (ret) _computeState = READY_TO_COMPUTE;
1119 case SUBMESH_COMPUTED: // nothing to do
1127 // ----------------------------------------------------------------------
1133 CleanDependants(); // recursive recall with event CLEANDEP
1135 case MODIF_ALGO_STATE:
1136 CleanDependants(); // recursive recall with event CLEANDEP
1138 case COMPUTE: // nothing to do
1141 CleanDependants(); // recursive recall with event CLEANDEP
1144 RemoveSubMeshElementsAndNodes();
1145 _computeState = NOT_READY;
1146 algo = gen->GetAlgo((*_father), _subShape);
1149 ret = algo->CheckHypothesis((*_father),_subShape);
1150 if (ret) _computeState = READY_TO_COMPUTE;
1153 case SUBMESH_COMPUTED: // nothing to do
1161 // ----------------------------------------------------------------------
1163 case FAILED_TO_COMPUTE:
1167 if (_algoState == HYP_OK)
1168 _computeState = READY_TO_COMPUTE;
1169 else _computeState = NOT_READY;
1171 case MODIF_ALGO_STATE:
1172 if (_algoState == HYP_OK)
1173 _computeState = READY_TO_COMPUTE;
1174 else _computeState = NOT_READY;
1176 case COMPUTE: // nothing to do
1181 RemoveSubMeshElementsAndNodes();
1182 if (_algoState == HYP_OK)
1183 _computeState = READY_TO_COMPUTE;
1184 else _computeState = NOT_READY;
1186 case SUBMESH_COMPUTED: // allow retry compute
1187 if (_algoState == HYP_OK)
1188 _computeState = READY_TO_COMPUTE;
1189 else _computeState = NOT_READY;
1197 // ----------------------------------------------------------------------
1203 //SCRUTE(_computeState);
1207 //=============================================================================
1211 //=============================================================================
1213 void SMESH_subMesh::UpdateDependantsState()
1215 //MESSAGE("SMESH_subMesh::UpdateDependantsState");
1217 const map<int, SMESH_subMesh*>& dependants = Dependants();
1218 map<int, SMESH_subMesh*>::const_iterator its;
1219 for (its = dependants.begin(); its != dependants.end(); its++)
1221 SMESH_subMesh* sm = (*its).second;
1222 //SCRUTE((*its).first);
1223 sm->ComputeStateEngine(SUBMESH_COMPUTED);
1227 //=============================================================================
1231 //=============================================================================
1233 void SMESH_subMesh::CleanDependants()
1235 MESSAGE("SMESH_subMesh::CleanDependants");
1236 // **** parcourir les ancetres dans l'ordre de dépendance
1238 const map<int, SMESH_subMesh*>& dependants = Dependants();
1239 map<int, SMESH_subMesh*>::const_iterator its;
1240 for (its = dependants.begin(); its != dependants.end(); its++)
1242 SMESH_subMesh* sm = (*its).second;
1243 SCRUTE((*its).first);
1244 sm->ComputeStateEngine(CLEANDEP);
1246 ComputeStateEngine(CLEANDEP);
1248 //=============================================================================
1252 //=============================================================================
1254 void SMESH_subMesh::RemoveSubMeshElementsAndNodes()
1256 MESSAGE("SMESH_subMesh::RemoveSubMeshElementsAndNodes");
1257 SCRUTE(_subShape.ShapeType());
1260 _subMeshDS = _meshDS->MeshElements(_subShape);
1261 if (!_subMeshDS.IsNull())
1263 const TColStd_ListOfInteger& indElt
1264 = _subMeshDS->GetIDElements();
1265 TColStd_ListIteratorOfListOfInteger ite(indElt);
1266 for (; ite.More(); ite.Next())
1268 int eltId = ite.Value();
1270 Handle (SMDS_MeshElement) elt = _meshDS->FindElement(eltId);
1271 _subMeshDS->RemoveElement(elt);
1272 _meshDS->RemoveElement(eltId);
1275 const TColStd_ListOfInteger& indNodes
1276 = _subMeshDS->GetIDNodes();
1277 TColStd_ListIteratorOfListOfInteger itn(indNodes);
1278 for (; itn.More(); itn.Next())
1280 int nodeId = itn.Value();
1282 Handle (SMDS_MeshElement) elt = _meshDS->FindNode(nodeId);
1283 Handle (SMDS_MeshNode) node = _meshDS->GetNode(1, elt);
1284 _subMeshDS->RemoveNode(node);
1285 _meshDS->RemoveNode(nodeId);
1290 //=============================================================================
1294 //=============================================================================
1296 const map<int, SMESH_subMesh*>& SMESH_subMesh::Dependants()
1298 if (_dependantsFound) return _mapDependants;
1300 //MESSAGE("SMESH_subMesh::Dependants");
1302 int shapeType = _subShape.ShapeType();
1303 //SCRUTE(shapeType);
1304 TopTools_IndexedDataMapOfShapeListOfShape M;
1305 TopoDS_Shape mainShape = _meshDS->ShapeToMesh();
1313 TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_WIRE, M);
1314 TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_FACE, M);
1315 TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_SHELL, M);
1316 TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_SOLID, M);
1317 TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_COMPSOLID, M);
1318 ExtractDependants(M, TopAbs_EDGE);
1322 TopExp::MapShapesAndAncestors(mainShape, TopAbs_FACE, TopAbs_SHELL, M);
1323 TopExp::MapShapesAndAncestors(mainShape, TopAbs_FACE, TopAbs_SOLID, M);
1324 TopExp::MapShapesAndAncestors(mainShape, TopAbs_FACE, TopAbs_COMPSOLID, M);
1325 ExtractDependants(M, TopAbs_FACE);
1328 case TopAbs_COMPSOLID:
1329 TopExp::MapShapesAndAncestors(mainShape, TopAbs_SOLID, TopAbs_COMPSOLID, M);
1330 ExtractDependants(M, TopAbs_SOLID);
1332 case TopAbs_COMPOUND:
1336 _dependantsFound = true;
1337 return _mapDependants;
1340 //=============================================================================
1344 //=============================================================================
1346 void SMESH_subMesh::ExtractDependants(const TopTools_IndexedDataMapOfShapeListOfShape& M,
1347 const TopAbs_ShapeEnum etype)
1349 //MESSAGE("SMESH_subMesh::ExtractDependants");
1351 TopoDS_Shape mainShape = _meshDS->ShapeToMesh();
1352 int lg = M.Extent();
1355 int shapeType = _subShape.ShapeType();
1364 const TopTools_ListOfShape& ancestors = M.FindFromKey(_subShape);
1365 TopTools_ListIteratorOfListOfShape it(ancestors);
1366 for ( ; it.More();it.Next())
1368 TopoDS_Shape ancestor = it.Value();
1369 SMESH_subMesh* aSubMesh = _father->GetSubMeshContaining(ancestor);
1370 // if (! aSubMesh) aSubMesh = _father->GetSubMesh(ancestor);
1373 int type = aSubMesh->_subShape.ShapeType();
1374 int cle = aSubMesh->GetId();
1375 cle += 10000000 * type; // sort map by ordType then index
1376 if (_mapDependants.find(cle) == _mapDependants.end())
1378 _mapDependants[cle] = aSubMesh;
1387 case TopAbs_COMPSOLID:
1388 for (TopExp_Explorer expE(_subShape, etype); expE.More(); expE.Next())
1390 TopoDS_Shape aShape = expE.Current();
1391 const TopTools_ListOfShape& ancestors = M.FindFromKey( aShape);
1392 TopTools_ListIteratorOfListOfShape it(ancestors);
1393 for ( ; it.More();it.Next())
1396 TopoDS_Shape ancestor = it.Value();
1397 SMESH_subMesh* aSubMesh = _father->GetSubMeshContaining(ancestor);
1398 if (! aSubMesh) aSubMesh = _father->GetSubMesh(ancestor);
1399 int type = aSubMesh->_subShape.ShapeType();
1400 int cle = aSubMesh->GetId();
1401 cle += 10000000 * type; // sort map by ordType then index
1402 if (_mapDependants.find(cle) == _mapDependants.end())
1404 _mapDependants[cle] = aSubMesh;
1410 case TopAbs_COMPOUND: