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>
43 #include <TopoDS_Compound.hxx>
44 #include <BRep_Builder.hxx>
46 //=============================================================================
48 * default constructor:
50 //=============================================================================
52 SMESH_subMesh::SMESH_subMesh(int Id, SMESH_Mesh * father, SMESHDS_Mesh * meshDS,
53 const TopoDS_Shape & aSubShape)
55 _subShape = aSubShape;
57 _subMeshDS = meshDS->MeshElements(_subShape); // may be null ...
60 _vertexSet = false; // only for Vertex subMesh
61 _dependenceAnalysed = 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() const
95 //MESSAGE("SMESH_subMesh::GetId");
99 //=============================================================================
103 //=============================================================================
105 SMESHDS_SubMesh * SMESH_subMesh::GetSubMeshDS()
107 //MESSAGE("SMESH_subMesh::GetSubMeshDS");
108 if (_subMeshDS==NULL)
110 //MESSAGE("subMesh pointer still null, trying to get it...");
111 _subMeshDS = _meshDS->MeshElements(_subShape); // may be null ...
112 if (_subMeshDS==NULL)
114 MESSAGE("problem... subMesh still empty");
116 //NRI throw SALOME_Exception(LOCALIZED(subMesh still empty));
122 //=============================================================================
126 //=============================================================================
128 SMESHDS_SubMesh* SMESH_subMesh::CreateSubMeshDS()
130 if ( !GetSubMeshDS() )
131 _meshDS->NewSubMesh( _meshDS->ShapeToIndex( _subShape ) );
133 return GetSubMeshDS();
136 //=============================================================================
140 //=============================================================================
142 SMESH_subMesh *SMESH_subMesh::GetFirstToCompute()
144 //MESSAGE("SMESH_subMesh::GetFirstToCompute");
145 const map < int, SMESH_subMesh * >&subMeshes = DependsOn();
146 SMESH_subMesh *firstToCompute = 0;
148 map < int, SMESH_subMesh * >::const_iterator itsub;
149 for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
151 SMESH_subMesh *sm = (*itsub).second;
152 // SCRUTE(sm->GetId());
153 // SCRUTE(sm->GetComputeState());
154 bool readyToCompute = (sm->GetComputeState() == READY_TO_COMPUTE);
158 //SCRUTE(sm->GetId());
164 //MESSAGE("--- submesh to compute");
165 return firstToCompute; // a subMesh of this
167 if (_computeState == READY_TO_COMPUTE)
169 //MESSAGE("--- this to compute");
172 //MESSAGE("--- nothing to compute");
173 return 0; // nothing to compute
176 //=============================================================================
180 //=============================================================================
182 bool SMESH_subMesh::SubMeshesComputed()
184 //MESSAGE("SMESH_subMesh::SubMeshesComputed");
185 const map < int, SMESH_subMesh * >&subMeshes = DependsOn();
187 bool subMeshesComputed = true;
188 map < int, SMESH_subMesh * >::const_iterator itsub;
189 for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
191 SMESH_subMesh *sm = (*itsub).second;
193 const TopoDS_Shape & ss = sm->GetSubShape();
194 int type = ss.ShapeType();
195 // SCRUTE(sm->GetId());
196 // SCRUTE(sm->GetComputeState());
197 bool computeOk = (sm->GetComputeState() == COMPUTE_OK);
200 subMeshesComputed = false;
204 case TopAbs_COMPOUND:
206 MESSAGE("The not computed sub mesh is a COMPOUND");
209 case TopAbs_COMPSOLID:
211 MESSAGE("The not computed sub mesh is a COMPSOLID");
216 MESSAGE("The not computed sub mesh is a SHEL");
221 MESSAGE("The not computed sub mesh is a WIRE");
226 MESSAGE("The not computed sub mesh is a SOLID");
231 MESSAGE("The not computed sub mesh is a FACE");
236 MESSAGE("The not computed sub mesh is a EDGE");
241 MESSAGE("The not computed sub mesh is of unknown type");
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)
300 //MESSAGE("SMESH_subMesh::DependsOn");
302 int type = _subShape.ShapeType();
306 case TopAbs_COMPOUND:
308 //MESSAGE("compound");
309 list < TopoDS_Shape > shellInSolid;
310 for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More();
313 InsertDependence(exp.Current());
315 exp2(exp.Current(), TopAbs_SHELL); exp2.More(); exp2.Next())
317 shellInSolid.push_back(exp2.Current());
320 for (TopExp_Explorer exp(_subShape, TopAbs_SHELL); exp.More();
323 list < TopoDS_Shape >::iterator it1;
324 bool isInSolid = false;
325 for (it1 = shellInSolid.begin(); it1 != shellInSolid.end(); it1++)
327 TopoDS_Shape aShape = (*it1);
328 if (aShape.IsSame(exp.Current()))
335 InsertDependence(exp.Current()); //only shell not in solid
337 for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More();
340 InsertDependence(exp.Current());
342 for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More();
345 InsertDependence(exp.Current());
349 case TopAbs_COMPSOLID:
351 //MESSAGE("compsolid");
352 for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More();
355 InsertDependence(exp.Current());
357 // list<TopoDS_Shape> shapeList;
358 // for (TopExp_Explorer exp(_subShape,TopAbs_SOLID);exp.More();exp.Next())
360 // for (TopExp_Explorer
361 // exp2(exp.Current(),TopAbs_FACE);exp2.More();exp2.Next())
363 // shapeList.push_back(exp2.Current());
366 // FinalizeDependence(shapeList);
372 for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More();
375 InsertDependence(exp.Current());
377 // list<TopoDS_Shape> shapeList;
378 // for (TopExp_Explorer exp(_subShape,TopAbs_FACE);exp.More();exp.Next())
380 // for (TopExp_Explorer
381 // exp2(exp.Current(),TopAbs_EDGE);exp2.More();exp2.Next())
383 // shapeList.push_back(exp2.Current());
386 // FinalizeDependence(shapeList);
392 for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More();
395 InsertDependence(exp.Current());
397 // list<TopoDS_Shape> shapeList;
398 // for (TopExp_Explorer exp(_subShape,TopAbs_EDGE);exp.More();exp.Next())
400 // for (TopExp_Explorer
401 // exp2(exp.Current(),TopAbs_VERTEX);exp2.More();exp2.Next())
403 // shapeList.push_back(exp2.Current());
406 // FinalizeDependence(shapeList);
412 // for (TopExp_Explorer exp(_subShape,TopAbs_SHELL);exp.More();exp.Next())
414 // InsertDependence(exp.Current());
416 for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More();
419 InsertDependence(exp.Current());
426 // for (TopExp_Explorer exp(_subShape,TopAbs_WIRE);exp.More();exp.Next())
428 // InsertDependence(exp.Current());
430 for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More();
433 InsertDependence(exp.Current());
440 for (TopExp_Explorer exp(_subShape, TopAbs_VERTEX); exp.More();
443 InsertDependence(exp.Current());
456 _dependenceAnalysed = true;
460 //=============================================================================
462 * For simple Shapes (solid, face, edge): add subMesh into dependence list.
464 //=============================================================================
466 void SMESH_subMesh::InsertDependence(const TopoDS_Shape aSubShape)
468 //MESSAGE("SMESH_subMesh::InsertDependence");
469 SMESH_subMesh *aSubMesh = _father->GetSubMesh(aSubShape);
470 int type = aSubShape.ShapeType();
471 int ordType = 9 - type; // 2 = Vertex, 8 = CompSolid
472 int cle = aSubMesh->GetId();
473 cle += 10000000 * ordType; // sort map by ordType then index
474 if (_mapDepend.find(cle) == _mapDepend.end())
476 _mapDepend[cle] = aSubMesh;
477 const map < int, SMESH_subMesh * >&subMap = aSubMesh->DependsOn();
478 map < int, SMESH_subMesh * >::const_iterator im;
479 for (im = subMap.begin(); im != subMap.end(); im++)
481 int clesub = (*im).first;
482 SMESH_subMesh *sm = (*im).second;
483 if (_mapDepend.find(clesub) == _mapDepend.end())
484 _mapDepend[clesub] = sm;
490 //=============================================================================
494 //=============================================================================
496 const TopoDS_Shape & SMESH_subMesh::GetSubShape()
498 //MESSAGE("SMESH_subMesh::GetSubShape");
503 //=======================================================================
504 //function : CanAddHypothesis
505 //purpose : return true if theHypothesis can be attached to me:
506 // its dimention is checked
507 //=======================================================================
509 bool SMESH_subMesh::CanAddHypothesis(const SMESH_Hypothesis* theHypothesis) const
511 int aHypDim = theHypothesis->GetDim();
512 int aShapeDim = SMESH_Gen::GetShapeDim(_subShape);
513 if ( aHypDim <= aShapeDim )
515 // if ( aHypDim < aShapeDim )
516 // return ( _father->IsMainShape( _subShape ));
521 //=======================================================================
522 //function : IsApplicableHypotesis
523 //purpose : return true if theHypothesis can be used to mesh me:
524 // its shape type is checked
525 //=======================================================================
527 bool SMESH_subMesh::IsApplicableHypotesis(const SMESH_Hypothesis* theHypothesis) const
529 if ( theHypothesis->GetType() > SMESHDS_Hypothesis::PARAM_ALGO)
531 return ( theHypothesis->GetShapeType() & (1<< _subShape.ShapeType()));
534 switch ( _subShape.ShapeType() ) {
539 int aHypDim = theHypothesis->GetDim();
540 int aShapeDim = SMESH_Gen::GetShapeDim(_subShape);
541 return ( aHypDim == aShapeDim );
543 // case TopAbs_VERTEX:
545 // case TopAbs_COMPSOLID:
546 // case TopAbs_COMPOUND:
553 //=============================================================================
557 //=============================================================================
559 SMESH_Hypothesis::Hypothesis_Status
560 SMESH_subMesh::AlgoStateEngine(int event, SMESH_Hypothesis * anHyp)
562 // MESSAGE("SMESH_subMesh::AlgoStateEngine");
563 //SCRUTE(_algoState);
566 // **** les retour des evenement shape sont significatifs
567 // (add ou remove fait ou non)
568 // le retour des evenement father n'indiquent pas que add ou remove fait
569 int dim = SMESH_Gen::GetShapeDim(_subShape);
571 SMESH_Hypothesis::Hypothesis_Status aux_ret, ret = SMESH_Hypothesis::HYP_OK;
578 SMESH_Gen* gen =_father->GetGen();
580 int oldAlgoState = _algoState;
581 bool modifiedHyp = false; // if set to true, force event MODIF_ALGO_STATE
582 // in ComputeStateEngine
584 // ----------------------
585 // check mesh conformity
586 // ----------------------
587 if (event == ADD_ALGO)
589 if (IsApplicableHypotesis( anHyp ) &&
590 !_father->IsNotConformAllowed() &&
591 !IsConform( static_cast< SMESH_Algo* >( anHyp )))
592 return SMESH_Hypothesis::HYP_NOTCONFORM;
595 // ----------------------------------
596 // add a hypothesis to DS if possible
597 // ----------------------------------
598 if (event == ADD_HYP || event == ADD_ALGO)
600 if ( ! CanAddHypothesis( anHyp ))
601 return SMESH_Hypothesis::HYP_BAD_DIM;
603 if ( GetNbAttached( _subShape, anHyp ) > 0 )
604 return SMESH_Hypothesis::HYP_ALREADY_EXIST;
606 if ( !_meshDS->AddHypothesis(_subShape, anHyp))
607 return SMESH_Hypothesis::HYP_ALREADY_EXIST;
610 // --------------------------
611 // remove a hypothesis from DS
612 // --------------------------
613 if (event == REMOVE_HYP || event == REMOVE_ALGO)
615 if (!_meshDS->RemoveHypothesis(_subShape, anHyp))
616 return SMESH_Hypothesis::HYP_OK; // nothing changes
619 // ------------------
620 // analyse algo state
621 // ------------------
622 if (!IsApplicableHypotesis( anHyp ))
623 return ret; // not applicable hypotheses do not change algo state
628 // ----------------------------------------------------------------------
635 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
637 if (algo->CheckHypothesis((*_father),_subShape, ret))
638 SetAlgoState(HYP_OK);
640 SetAlgoState(MISSING_HYP);
649 case ADD_FATHER_ALGO: { // Algo just added in father
650 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
652 if ( algo == anHyp ) {
653 if ( algo->CheckHypothesis((*_father),_subShape, aux_ret))
654 SetAlgoState(HYP_OK);
656 SetAlgoState(MISSING_HYP);
660 case REMOVE_FATHER_HYP:
662 case REMOVE_FATHER_ALGO: {
663 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
666 if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
667 SetAlgoState(HYP_OK);
669 SetAlgoState(MISSING_HYP);
679 // ----------------------------------------------------------------------
685 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
687 if ( algo->CheckHypothesis((*_father),_subShape, ret ))
688 SetAlgoState(HYP_OK);
689 if (SMESH_Hypothesis::IsStatusFatal( ret ))
690 _meshDS->RemoveHypothesis(_subShape, anHyp);
691 else if (!_father->IsUsedHypothesis( anHyp, _subShape ))
693 _meshDS->RemoveHypothesis(_subShape, anHyp);
694 ret = SMESH_Hypothesis::HYP_INCOMPATIBLE;
698 case ADD_ALGO: { //already existing algo : on father ?
699 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
701 if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))// ignore hyp status
702 SetAlgoState(HYP_OK);
704 SetAlgoState(MISSING_HYP);
709 case REMOVE_ALGO: { // perhaps a father algo applies ?
710 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
711 if (algo == NULL) // no more algo applying on subShape...
713 SetAlgoState(NO_ALGO);
717 if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
718 SetAlgoState(HYP_OK);
720 SetAlgoState(MISSING_HYP);
724 case ADD_FATHER_HYP: {
725 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
727 if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
728 SetAlgoState(HYP_OK);
730 SetAlgoState(MISSING_HYP);
733 case ADD_FATHER_ALGO: { // new father algo
734 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
736 if ( algo == anHyp ) {
737 if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
738 SetAlgoState(HYP_OK);
740 SetAlgoState(MISSING_HYP);
744 case REMOVE_FATHER_HYP: // nothing to do
746 case REMOVE_FATHER_ALGO: {
747 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
748 if (algo == NULL) // no more applying algo on father
750 SetAlgoState(NO_ALGO);
754 if ( algo->CheckHypothesis((*_father),_subShape , aux_ret ))
755 SetAlgoState(HYP_OK);
757 SetAlgoState(MISSING_HYP);
767 // ----------------------------------------------------------------------
773 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
775 if (!algo->CheckHypothesis((*_father),_subShape, ret ))
777 MESSAGE("two applying algo on the same shape not allowed");
778 _meshDS->RemoveHypothesis(_subShape, anHyp);
779 //ret = SMESH_Hypothesis::HYP_ALREADY_EXIST;
781 else if (SMESH_Hypothesis::IsStatusFatal( ret ))
782 _meshDS->RemoveHypothesis(_subShape, anHyp);
783 else if (!_father->IsUsedHypothesis( anHyp, _subShape ))
785 _meshDS->RemoveHypothesis(_subShape, anHyp);
786 ret = SMESH_Hypothesis::HYP_INCOMPATIBLE;
788 modifiedHyp = _father->IsUsedHypothesis( anHyp, _subShape ); // new Hyp?
791 case ADD_ALGO: { //already existing algo : on father ?
792 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
793 if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
794 SetAlgoState(HYP_OK);
796 SetAlgoState(MISSING_HYP);
801 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
803 if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
804 SetAlgoState(HYP_OK);
806 SetAlgoState(MISSING_HYP);
808 // report only severe errors
809 if ( SMESH_Hypothesis::IsStatusFatal( aux_ret ))
813 case REMOVE_ALGO: { // perhaps a father algo applies ?
814 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
815 if (algo == NULL) // no more algo applying on subShape...
817 SetAlgoState(NO_ALGO);
821 if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
822 SetAlgoState(HYP_OK);
824 SetAlgoState(MISSING_HYP);
826 // report only severe errors
827 if ( SMESH_Hypothesis::IsStatusFatal( aux_ret ))
832 case ADD_FATHER_HYP: { // new father hypothesis ?
833 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
835 if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
837 SetAlgoState(HYP_OK);
838 if (_father->IsUsedHypothesis( anHyp, _subShape )) // new Hyp
842 SetAlgoState(MISSING_HYP);
845 case ADD_FATHER_ALGO: { // a new algo on father
846 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
847 if ( algo == anHyp ) {
848 if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
849 SetAlgoState(HYP_OK);
851 SetAlgoState(MISSING_HYP);
856 case REMOVE_FATHER_HYP: {
857 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
859 if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
860 SetAlgoState(HYP_OK);
862 SetAlgoState(MISSING_HYP);
866 case REMOVE_FATHER_ALGO: {
867 SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
868 if (algo == NULL) // no more applying algo on father
870 SetAlgoState(NO_ALGO);
874 if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
875 SetAlgoState(HYP_OK);
877 SetAlgoState(MISSING_HYP);
888 // ----------------------------------------------------------------------
894 // ----------------------------------------
895 // check concurent hypotheses on ansestors
896 // ----------------------------------------
897 if (ret < SMESH_Hypothesis::HYP_CONCURENT &&
898 (event == ADD_FATHER_HYP ||
899 event == ADD_FATHER_ALGO ||
900 event == REMOVE_FATHER_HYP ||
901 event == REMOVE_FATHER_ALGO ||
902 event == REMOVE_ALGO ||
903 event == REMOVE_HYP))
905 ret = CheckConcurentHypothesis( anHyp->GetType() );
908 if ((_algoState != oldAlgoState) || modifiedHyp)
909 int retc = ComputeStateEngine(MODIF_ALGO_STATE);
915 //=======================================================================
916 //function : IsConform
917 //purpose : check if a conform mesh will be produced by the Algo
918 //=======================================================================
920 bool SMESH_subMesh::IsConform(const SMESH_Algo* theAlgo)
922 MESSAGE( "SMESH_subMesh::IsConform" );
924 if ( !theAlgo ) return false;
926 // check only algo that doesn't NeedDescretBoundary(): because mesh made
927 // on a sub-shape will be ignored by theAlgo
928 if ( theAlgo->NeedDescretBoundary() )
931 SMESH_Gen* gen =_father->GetGen();
933 // only local algo is to be checked
934 if ( gen->IsGlobalAlgo( theAlgo, *_father ))
937 // check algo attached to adjacent shapes
939 // loop on one level down sub-meshes
940 TopoDS_Iterator itsub( _subShape );
941 for (; itsub.More(); itsub.Next())
943 // loop on adjacent subShapes
944 TopTools_ListIteratorOfListOfShape it( _father->GetAncestors( itsub.Value() ));
945 for (; it.More(); it.Next())
947 const TopoDS_Shape& adjacent = it.Value();
948 if ( _subShape.IsSame( adjacent )) continue;
949 if ( adjacent.ShapeType() != _subShape.ShapeType())
952 // check algo attached to smAdjacent
953 SMESH_Algo * algo = gen->GetAlgo((*_father), adjacent);
956 !algo->NeedDescretBoundary() /*&&
957 !gen->IsGlobalAlgo( algo, *_father )*/)
958 return false; // NOT CONFORM MESH WILL BE PRODUCED
965 //=============================================================================
969 //=============================================================================
971 void SMESH_subMesh::SetAlgoState(int state)
973 // if (state != _oldAlgoState)
974 // int retc = ComputeStateEngine(MODIF_ALGO_STATE);
978 //=============================================================================
982 //=============================================================================
983 SMESH_Hypothesis::Hypothesis_Status
984 SMESH_subMesh::SubMeshesAlgoStateEngine(int event,
985 SMESH_Hypothesis * anHyp)
987 //MESSAGE("SMESH_subMesh::SubMeshesAlgoStateEngine");
988 SMESH_Hypothesis::Hypothesis_Status ret = SMESH_Hypothesis::HYP_OK;
989 //EAP: a wire (dim==1) should notify edges (dim==1)
990 //EAP: int dim = SMESH_Gen::GetShapeDim(_subShape);
991 if (/*EAP:dim > 1*/ _subShape.ShapeType() < TopAbs_EDGE )
993 const map < int, SMESH_subMesh * >&subMeshes = DependsOn();
995 map < int, SMESH_subMesh * >::const_iterator itsub;
996 for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
998 SMESH_subMesh *sm = (*itsub).second;
999 SMESH_Hypothesis::Hypothesis_Status ret2 =
1000 sm->AlgoStateEngine(event, anHyp);
1008 //=============================================================================
1012 //=============================================================================
1014 void SMESH_subMesh::CleanDependsOn()
1016 MESSAGE("SMESH_subMesh::CleanDependsOn");
1017 // **** parcourir les ancetres dans l'ordre de dépendance
1019 ComputeStateEngine(CLEAN);
1021 const map < int, SMESH_subMesh * >&dependson = DependsOn();
1022 map < int, SMESH_subMesh * >::const_iterator its;
1023 for (its = dependson.begin(); its != dependson.end(); its++)
1025 SMESH_subMesh *sm = (*its).second;
1026 SCRUTE((*its).first);
1027 sm->ComputeStateEngine(CLEAN);
1031 //=============================================================================
1035 //=============================================================================
1037 void SMESH_subMesh::DumpAlgoState(bool isMain)
1039 int dim = SMESH_Gen::GetShapeDim(_subShape);
1040 // if (dim < 1) return;
1043 const map < int, SMESH_subMesh * >&subMeshes = DependsOn();
1045 map < int, SMESH_subMesh * >::const_iterator itsub;
1046 for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
1048 SMESH_subMesh *sm = (*itsub).second;
1049 sm->DumpAlgoState(false);
1052 int type = _subShape.ShapeType();
1053 MESSAGE("dim = " << dim << " type of shape " << type);
1057 MESSAGE(" AlgoState = NO_ALGO");
1060 MESSAGE(" AlgoState = MISSING_HYP");
1063 MESSAGE(" AlgoState = HYP_OK");
1066 switch (_computeState)
1069 MESSAGE(" ComputeState = NOT_READY");
1071 case READY_TO_COMPUTE:
1072 MESSAGE(" ComputeState = READY_TO_COMPUTE");
1075 MESSAGE(" ComputeState = COMPUTE_OK");
1077 case FAILED_TO_COMPUTE:
1078 MESSAGE(" ComputeState = FAILED_TO_COMPUTE");
1083 //=============================================================================
1087 //=============================================================================
1089 bool SMESH_subMesh::ComputeStateEngine(int event)
1091 //MESSAGE("SMESH_subMesh::ComputeStateEngine");
1092 //SCRUTE(_computeState);
1095 int dim = SMESH_Gen::GetShapeDim(_subShape);
1100 _computeState = COMPUTE_OK;
1102 _computeState = READY_TO_COMPUTE;
1103 //SCRUTE(_computeState);
1106 SMESH_Gen *gen = _father->GetGen();
1107 SMESH_Algo *algo = 0;
1109 SMESH_Hypothesis::Hypothesis_Status hyp_status;
1111 switch (_computeState)
1114 // ----------------------------------------------------------------------
1119 case MODIF_HYP: // nothing to do
1121 case MODIF_ALGO_STATE:
1122 if (_algoState == HYP_OK)
1124 _computeState = READY_TO_COMPUTE;
1127 case COMPUTE: // nothing to do
1130 RemoveSubMeshElementsAndNodes();
1135 case SUBMESH_COMPUTED: // nothing to do
1137 case SUBMESH_RESTORED:
1138 ComputeSubMeshStateEngine( SUBMESH_RESTORED );
1146 // ----------------------------------------------------------------------
1148 case READY_TO_COMPUTE:
1151 case MODIF_HYP: // nothing to do
1153 case MODIF_ALGO_STATE:
1154 _computeState = NOT_READY;
1155 algo = gen->GetAlgo((*_father), _subShape);
1158 ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
1160 _computeState = READY_TO_COMPUTE;
1165 algo = gen->GetAlgo((*_father), _subShape);
1167 ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
1170 MESSAGE("***** verify compute state *****");
1171 _computeState = NOT_READY;
1174 // check submeshes needed
1175 if (algo->NeedDescretBoundary())
1176 ret = SubMeshesComputed();
1179 MESSAGE("Some SubMeshes not computed");
1180 _computeState = FAILED_TO_COMPUTE;
1184 if (!algo->NeedDescretBoundary() && !algo->OnlyUnaryInput())
1185 ret = ApplyToCollection( algo, GetCollection( gen, algo ) );
1187 ret = algo->Compute((*_father), _subShape);
1191 MESSAGE("problem in algo execution: failed to compute");
1192 _computeState = FAILED_TO_COMPUTE;
1193 if (!algo->NeedDescretBoundary())
1194 UpdateSubMeshState( FAILED_TO_COMPUTE );
1199 _computeState = COMPUTE_OK;
1200 UpdateDependantsState( SUBMESH_COMPUTED ); // send event SUBMESH_COMPUTED
1201 if (!algo->NeedDescretBoundary())
1202 UpdateSubMeshState( COMPUTE_OK );
1207 RemoveSubMeshElementsAndNodes();
1208 _computeState = NOT_READY;
1209 algo = gen->GetAlgo((*_father), _subShape);
1212 ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
1214 _computeState = READY_TO_COMPUTE;
1220 case SUBMESH_COMPUTED: // nothing to do
1222 case SUBMESH_RESTORED:
1223 // check if a mesh is already computed that may
1224 // happen after retrieval from a file
1225 if ( IsMeshComputed() ) {
1226 _computeState = COMPUTE_OK;
1228 ComputeSubMeshStateEngine( SUBMESH_RESTORED );
1236 // ----------------------------------------------------------------------
1242 CleanDependants(); // recursive recall with event CLEANDEP
1243 algo = gen->GetAlgo((*_father), _subShape);
1244 if (algo && !algo->NeedDescretBoundary())
1245 CleanDependsOn(); // remove sub-mesh with event CLEANDEP
1247 case MODIF_ALGO_STATE:
1248 CleanDependants(); // recursive recall with event CLEANDEP
1249 algo = gen->GetAlgo((*_father), _subShape);
1250 if (algo && !algo->NeedDescretBoundary())
1251 CleanDependsOn(); // remove sub-mesh with event CLEANDEP
1253 case COMPUTE: // nothing to do
1256 RemoveSubMeshElementsAndNodes();
1257 _computeState = NOT_READY;
1258 algo = gen->GetAlgo((*_father), _subShape);
1261 ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
1263 _computeState = READY_TO_COMPUTE;
1267 CleanDependants(); // recursive recall with event CLEANDEP
1269 case SUBMESH_COMPUTED: // nothing to do
1271 case SUBMESH_RESTORED:
1272 ComputeSubMeshStateEngine( SUBMESH_RESTORED );
1280 // ----------------------------------------------------------------------
1282 case FAILED_TO_COMPUTE:
1286 if (_algoState == HYP_OK)
1287 _computeState = READY_TO_COMPUTE;
1289 _computeState = NOT_READY;
1291 case MODIF_ALGO_STATE:
1292 if (_algoState == HYP_OK)
1293 _computeState = READY_TO_COMPUTE;
1295 _computeState = NOT_READY;
1297 case COMPUTE: // nothing to do
1300 RemoveSubMeshElementsAndNodes();
1301 if (_algoState == HYP_OK)
1302 _computeState = READY_TO_COMPUTE;
1304 _computeState = NOT_READY;
1309 case SUBMESH_COMPUTED: // allow retry compute
1310 if (_algoState == HYP_OK)
1311 _computeState = READY_TO_COMPUTE;
1313 _computeState = NOT_READY;
1315 case SUBMESH_RESTORED:
1316 ComputeSubMeshStateEngine( SUBMESH_RESTORED );
1324 // ----------------------------------------------------------------------
1330 //SCRUTE(_computeState);
1334 //=======================================================================
1335 //function : ApplyToCollection
1336 //purpose : Apply theAlgo to all subshapes in theCollection
1337 //=======================================================================
1339 bool SMESH_subMesh::ApplyToCollection (SMESH_Algo* theAlgo,
1340 const TopoDS_Shape& theCollection)
1342 MESSAGE("SMESH_subMesh::ApplyToCollection");
1343 ASSERT ( !theAlgo->NeedDescretBoundary() );
1348 ret = theAlgo->Compute( *_father, theCollection );
1350 // set _computeState of subshapes
1351 TopExp_Explorer anExplorer( theCollection, _subShape.ShapeType() );
1352 for ( ; anExplorer.More(); anExplorer.Next() )
1354 const TopoDS_Shape& aSubShape = anExplorer.Current();
1355 SMESH_subMesh* subMesh = _father->GetSubMeshContaining( aSubShape );
1360 subMesh->_computeState = COMPUTE_OK;
1361 subMesh->UpdateDependantsState( SUBMESH_COMPUTED );
1362 subMesh->UpdateSubMeshState( COMPUTE_OK );
1366 subMesh->_computeState = FAILED_TO_COMPUTE;
1374 //=======================================================================
1375 //function : UpdateSubMeshState
1377 //=======================================================================
1379 void SMESH_subMesh::UpdateSubMeshState(const compute_state theState)
1381 const map<int, SMESH_subMesh*>& smMap = DependsOn();
1382 map<int, SMESH_subMesh*>::const_iterator itsub;
1383 for (itsub = smMap.begin(); itsub != smMap.end(); itsub++)
1385 SMESH_subMesh* sm = (*itsub).second;
1386 sm->_computeState = theState;
1390 //=======================================================================
1391 //function : ComputeSubMeshStateEngine
1393 //=======================================================================
1395 void SMESH_subMesh::ComputeSubMeshStateEngine(int event)
1397 const map<int, SMESH_subMesh*>& smMap = DependsOn();
1398 map<int, SMESH_subMesh*>::const_iterator itsub;
1399 for (itsub = smMap.begin(); itsub != smMap.end(); itsub++)
1401 SMESH_subMesh* sm = (*itsub).second;
1402 sm->ComputeStateEngine(event);
1406 //=======================================================================
1407 //function : UpdateDependantsState
1409 //=======================================================================
1411 void SMESH_subMesh::UpdateDependantsState(const compute_event theEvent)
1413 //MESSAGE("SMESH_subMesh::UpdateDependantsState");
1414 TopTools_ListIteratorOfListOfShape it( _father->GetAncestors( _subShape ));
1415 for (; it.More(); it.Next())
1417 const TopoDS_Shape& ancestor = it.Value();
1418 SMESH_subMesh *aSubMesh =
1419 _father->GetSubMeshContaining(ancestor);
1421 aSubMesh->ComputeStateEngine( theEvent );
1425 //=============================================================================
1429 //=============================================================================
1431 void SMESH_subMesh::CleanDependants()
1433 //MESSAGE("SMESH_subMesh::CleanDependants: shape type " << _subShape.ShapeType() );
1435 TopTools_ListIteratorOfListOfShape it( _father->GetAncestors( _subShape ));
1436 for (; it.More(); it.Next())
1438 const TopoDS_Shape& ancestor = it.Value();
1439 //MESSAGE("ancestor shape type " << ancestor.ShapeType() );
1440 SMESH_subMesh *aSubMesh = _father->GetSubMeshContaining(ancestor);
1442 aSubMesh->ComputeStateEngine(CLEANDEP);
1444 ComputeStateEngine(CLEAN);
1448 //=============================================================================
1452 //=============================================================================
1454 static void removeSubMesh( SMESHDS_Mesh * meshDS, const TopoDS_Shape& subShape)
1456 SMESHDS_SubMesh * subMeshDS = meshDS->MeshElements(subShape);
1457 if (subMeshDS!=NULL)
1459 SMDS_ElemIteratorPtr ite=subMeshDS->GetElements();
1462 const SMDS_MeshElement * elt = ite->next();
1463 //MESSAGE( " RM elt: "<<elt->GetID()<<" ( "<<elt->NbNodes()<<" )" );
1464 meshDS->RemoveElement(elt);
1467 SMDS_NodeIteratorPtr itn=subMeshDS->GetNodes();
1470 const SMDS_MeshNode * node = itn->next();
1471 meshDS->RemoveNode(node);
1476 //=============================================================================
1480 //=============================================================================
1482 void SMESH_subMesh::RemoveSubMeshElementsAndNodes()
1484 SCRUTE(_subShape.ShapeType());
1486 removeSubMesh( _meshDS, _subShape );
1488 // algo may bind a submesh not to _subShape, eg 3D algo
1489 // sets nodes on SHELL while _subShape may be SOLID
1491 int dim = SMESH_Gen::GetShapeDim( _subShape );
1492 int type = _subShape.ShapeType() + 1;
1493 for ( ; type <= TopAbs_EDGE; type++)
1494 if ( dim == SMESH_Gen::GetShapeDim( (TopAbs_ShapeEnum) type ))
1496 TopExp_Explorer exp( _subShape, (TopAbs_ShapeEnum) type );
1497 for ( ; exp.More(); exp.Next() )
1498 removeSubMesh( _meshDS, exp.Current() );
1504 //=======================================================================
1505 //function : IsMeshComputed
1506 //purpose : check if _subMeshDS contains mesh elements
1507 //=======================================================================
1509 bool SMESH_subMesh::IsMeshComputed() const
1511 // algo may bind a submesh not to _subShape, eg 3D algo
1512 // sets nodes on SHELL while _subShape may be SOLID
1514 int dim = SMESH_Gen::GetShapeDim( _subShape );
1515 int type = _subShape.ShapeType();
1516 for ( ; type <= TopAbs_VERTEX; type++) {
1517 if ( dim == SMESH_Gen::GetShapeDim( (TopAbs_ShapeEnum) type ))
1519 TopExp_Explorer exp( _subShape, (TopAbs_ShapeEnum) type );
1520 for ( ; exp.More(); exp.Next() )
1522 SMESHDS_SubMesh * subMeshDS = _meshDS->MeshElements( exp.Current() );
1523 if ( subMeshDS != NULL &&
1524 (subMeshDS->GetElements()->more() || subMeshDS->GetNodes()->more())) {
1537 //=======================================================================
1538 //function : GetCollection
1539 //purpose : return a shape containing all sub-shapes of the MainShape that can be
1540 // meshed at once along with _subShape
1541 //=======================================================================
1543 TopoDS_Shape SMESH_subMesh::GetCollection(SMESH_Gen * theGen, SMESH_Algo* theAlgo)
1545 MESSAGE("SMESH_subMesh::GetCollection");
1546 ASSERT (!theAlgo->NeedDescretBoundary());
1548 TopoDS_Shape mainShape = _father->GetMeshDS()->ShapeToMesh();
1550 if ( mainShape.IsSame( _subShape ))
1553 list<const SMESHDS_Hypothesis*> aUsedHyp =
1554 theAlgo->GetUsedHypothesis( *_father, _subShape ); // copy
1556 // put in a compound all shapes with the same hypothesis assigned
1557 // and a good ComputState
1559 TopoDS_Compound aCompound;
1560 BRep_Builder aBuilder;
1561 aBuilder.MakeCompound( aCompound );
1563 TopExp_Explorer anExplorer( mainShape, _subShape.ShapeType() );
1564 for ( ; anExplorer.More(); anExplorer.Next() )
1566 const TopoDS_Shape& S = anExplorer.Current();
1567 SMESH_subMesh* subMesh = _father->GetSubMesh( S );
1568 SMESH_Algo* anAlgo = theGen->GetAlgo( *_father, S );
1570 if (subMesh->GetComputeState() == READY_TO_COMPUTE &&
1571 anAlgo == theAlgo &&
1572 anAlgo->GetUsedHypothesis( *_father, S ) == aUsedHyp)
1574 aBuilder.Add( aCompound, S );
1581 //=======================================================================
1582 //function : GetNbAttached
1583 //purpose : return nb of hypotheses attached to theShape.
1584 // If theHyp is provided, similar but not same hypotheses
1585 // are countered; else only applicable ones are countered
1586 // depending on theAlgos flag
1587 //=======================================================================
1589 int SMESH_subMesh::GetNbAttached(const TopoDS_Shape& theShape,
1590 const SMESH_Hypothesis * theHyp,
1591 const bool theAlgos)
1595 const list<const SMESHDS_Hypothesis*>& aHypList =
1596 _father->GetHypothesisList( theShape );
1597 list<const SMESHDS_Hypothesis*>::const_iterator it = aHypList.begin();
1598 while (it!=aHypList.end())
1600 const SMESH_Hypothesis* hyp = static_cast< const SMESH_Hypothesis *>( *it );
1606 if (hyp != theHyp &&
1607 hyp->GetType() == theHyp->GetType() &&
1608 hyp->GetDim() == theHyp->GetDim())
1613 bool isAlgo = ( hyp->GetType() > SMESHDS_Hypothesis::PARAM_ALGO );
1614 if ( theAlgos == isAlgo && IsApplicableHypotesis( hyp ))
1622 //=======================================================================
1623 //function : CheckConcurentHypothesis
1624 //purpose : check if there are several applicable hypothesis on fathers
1625 //=======================================================================
1627 SMESH_Hypothesis::Hypothesis_Status
1628 SMESH_subMesh::CheckConcurentHypothesis (const int theHypType)
1630 MESSAGE ("SMESH_subMesh::CheckConcurentHypothesis");
1632 // is there local hypothesis on me?
1633 if ( GetNbAttached( _subShape, 0, theHypType > SMESHDS_Hypothesis::PARAM_ALGO ) > 0 )
1634 return SMESH_Hypothesis::HYP_OK;
1637 TopoDS_Shape aPrevWithHyp;
1638 TopTools_ListIteratorOfListOfShape it( _father->GetAncestors( _subShape ));
1639 for (; it.More(); it.Next())
1641 const TopoDS_Shape& ancestor = it.Value();
1642 if ( GetNbAttached( ancestor, 0, theHypType > SMESHDS_Hypothesis::PARAM_ALGO ) > 0 )
1644 if ( aPrevWithHyp.IsNull() || aPrevWithHyp.IsSame( ancestor ))
1645 aPrevWithHyp = ancestor;
1646 else if ( aPrevWithHyp.ShapeType() == ancestor.ShapeType() )
1647 return SMESH_Hypothesis::HYP_CONCURENT;
1649 return SMESH_Hypothesis::HYP_OK;
1652 return SMESH_Hypothesis::HYP_OK;