X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH%2FSMESH_subMesh.cxx;h=89e9e26849c2c05059b035d7c5687237a1127177;hp=1273bce7ae237c44973799e3c4e07cbeb9324431;hb=0febe018bcde111dc7aca1f3e44d4aa2995b59a2;hpb=0b959120c59670d73c0a1f6d46bfa72a6ceb49cf diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index 1273bce7a..89e9e2684 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -1,15 +1,32 @@ -using namespace std; -//============================================================================= -// File : SMESH_subMesh.cxx -// Created : jeu mai 30 13:28:32 CEST 2002 -// Author : Paul RASCLE, EDF -// Project : SALOME -// Copyright : EDF 2002 -// $Header$ -//============================================================================= +// SMESH SMESH : implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_subMesh.cxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ using namespace std; - #include "SMESH_subMesh.hxx" #include "SMESH_Gen.hxx" #include "SMESH_Mesh.hxx" @@ -23,6 +40,14 @@ using namespace std; #include #include #include +#include +#include + +#ifdef _DEBUG_ +#include +#include +#include +#endif //============================================================================= /*! @@ -30,261 +55,233 @@ using namespace std; */ //============================================================================= -SMESH_subMesh::SMESH_subMesh(int Id, - SMESH_Mesh* father, - const Handle(SMESHDS_Mesh)& meshDS, - const TopoDS_Shape & aSubShape) +SMESH_subMesh::SMESH_subMesh(int Id, SMESH_Mesh * father, SMESHDS_Mesh * meshDS, + const TopoDS_Shape & aSubShape) { - //MESSAGE("SMESH_subMesh::SMESH_subMesh"); - _subShape = aSubShape; - _meshDS = meshDS; - _subMeshDS = meshDS->MeshElements(_subShape); // may be null ... - _father = father; - _Id = Id; - _vertexSet = false; // only for Vertex subMesh - _dependenceAnalysed = false; - _dependantsFound = false; - - if (_subShape.ShapeType() == TopAbs_VERTEX) - { - _algoState = HYP_OK; - _computeState = READY_TO_COMPUTE; - } - else - { - _algoState = NO_ALGO; - _computeState = NOT_READY; - } + _subShape = aSubShape; + _meshDS = meshDS; + _subMeshDS = meshDS->MeshElements(_subShape); // may be null ... + _father = father; + _Id = Id; + _dependenceAnalysed = false; + + if (_subShape.ShapeType() == TopAbs_VERTEX) + { + _algoState = HYP_OK; + _computeState = READY_TO_COMPUTE; + } + else + { + _algoState = NO_ALGO; + _computeState = NOT_READY; + } } //============================================================================= /*! - * + * */ //============================================================================= SMESH_subMesh::~SMESH_subMesh() { - MESSAGE("SMESH_subMesh::~SMESH_subMesh"); - // **** + MESSAGE("SMESH_subMesh::~SMESH_subMesh"); + // **** } //============================================================================= /*! - * + * */ //============================================================================= -int SMESH_subMesh::GetId() +int SMESH_subMesh::GetId() const { - //MESSAGE("SMESH_subMesh::GetId"); - return _Id; + //MESSAGE("SMESH_subMesh::GetId"); + return _Id; } //============================================================================= /*! - * Given a subShape, find the subMesh is associated to this subShape or - * to a collection of shapes containing this subShape. Collection = compsolid, - * shell, wire + * */ //============================================================================= -// bool SMESH_subMesh::Contains(const TopoDS_Shape & aSubShape) -// throw (SALOME_Exception) -// { -// //MESSAGE("SMESH_subMesh::Contains"); -// bool contains = false; -// int type = _subShape.ShapeType(); -// int typesub = aSubShape.ShapeType(); -// //SCRUTE(type) -// //SCRUTE(typesub) -// switch (type) -// { -// // case TopAbs_COMPOUND: -// // { -// // //MESSAGE("---"); -// // throw SALOME_Exception(LOCALIZED("Compound not yet treated")); -// // break; -// // } -// case TopAbs_COMPSOLID: -// { -// //MESSAGE("---"); -// for (TopExp_Explorer exp(aSubShape,TopAbs_SOLID);exp.More();exp.Next()) -// { -// contains = _subShape.IsSame(exp.Current()); -// if (contains) break; -// } -// break; -// } -// case TopAbs_SHELL: -// { -// //MESSAGE("---"); -// for (TopExp_Explorer exp(aSubShape,TopAbs_FACE);exp.More();exp.Next()) -// { -// contains = _subShape.IsSame(exp.Current()); -// if (contains) break; -// } -// break; -// } -// case TopAbs_WIRE: -// { -// //MESSAGE("---"); -// for (TopExp_Explorer exp(aSubShape,TopAbs_EDGE);exp.More();exp.Next()) -// { -// contains = _subShape.IsSame(exp.Current()); -// if (contains) break; -// } -// break; -// } -// case TopAbs_COMPOUND: -// case TopAbs_SOLID: -// case TopAbs_FACE: -// case TopAbs_EDGE: -// case TopAbs_VERTEX: -// { -// //MESSAGE("---"); -// contains = _subShape.IsSame(aSubShape); -// break; -// } -// default: -// { -// break; -// } -// } -// //SCRUTE(contains); -// return contains; -// } +SMESHDS_SubMesh * SMESH_subMesh::GetSubMeshDS() +{ + //MESSAGE("SMESH_subMesh::GetSubMeshDS"); + if (_subMeshDS==NULL) + { + //MESSAGE("subMesh pointer still null, trying to get it..."); + _subMeshDS = _meshDS->MeshElements(_subShape); // may be null ... + if (_subMeshDS==NULL) + { + MESSAGE("problem... subMesh still empty"); + //NRI ASSERT(0); + //NRI throw SALOME_Exception(LOCALIZED(subMesh still empty)); + } + } + return _subMeshDS; +} //============================================================================= /*! - * + * */ //============================================================================= -const Handle(SMESHDS_SubMesh)& SMESH_subMesh::GetSubMeshDS() - throw (SALOME_Exception) +SMESHDS_SubMesh* SMESH_subMesh::CreateSubMeshDS() { - //MESSAGE("SMESH_subMesh::GetSubMeshDS"); - if (_subMeshDS.IsNull()) - { - //MESSAGE("subMesh pointer still null, trying to get it..."); - _subMeshDS = _meshDS->MeshElements(_subShape); // may be null ... - if (_subMeshDS.IsNull()) - { - MESSAGE("problem... subMesh still empty"); - //NRI ASSERT(0); - //NRI throw SALOME_Exception(LOCALIZED(subMesh still empty)); - } - } - return _subMeshDS; + if ( !GetSubMeshDS() ) + _meshDS->NewSubMesh( _meshDS->ShapeToIndex( _subShape ) ); + + return GetSubMeshDS(); } //============================================================================= /*! - * + * */ //============================================================================= -SMESH_subMesh* SMESH_subMesh::GetFirstToCompute() - throw (SALOME_Exception) +SMESH_subMesh *SMESH_subMesh::GetFirstToCompute() { //MESSAGE("SMESH_subMesh::GetFirstToCompute"); - const map& subMeshes = DependsOn(); - SMESH_subMesh* firstToCompute = 0; + const map < int, SMESH_subMesh * >&subMeshes = DependsOn(); + SMESH_subMesh *firstToCompute = 0; - map::const_iterator itsub; + map < int, SMESH_subMesh * >::const_iterator itsub; for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++) + { + SMESH_subMesh *sm = (*itsub).second; + // SCRUTE(sm->GetId()); + // SCRUTE(sm->GetComputeState()); + bool readyToCompute = (sm->GetComputeState() == READY_TO_COMPUTE); + if (readyToCompute) { - SMESH_subMesh* sm = (*itsub).second; -// SCRUTE(sm->GetId()); -// SCRUTE(sm->GetComputeState()); - bool readyToCompute = (sm->GetComputeState() == READY_TO_COMPUTE); - if (readyToCompute) - { - firstToCompute = sm; - //SCRUTE(sm->GetId()); - break; - } + firstToCompute = sm; + //SCRUTE(sm->GetId()); + break; } + } if (firstToCompute) - { - //MESSAGE("--- submesh to compute"); - return firstToCompute; // a subMesh of this - } + { + return firstToCompute; // a subMesh of this + } if (_computeState == READY_TO_COMPUTE) - { - //MESSAGE("--- this to compute"); - return this; // this - } - //MESSAGE("--- nothing to compute"); - return 0; // nothing to compute + { + return this; // this + } + return 0; // nothing to compute } //============================================================================= /*! - * + * */ //============================================================================= bool SMESH_subMesh::SubMeshesComputed() - throw (SALOME_Exception) { //MESSAGE("SMESH_subMesh::SubMeshesComputed"); - const map& subMeshes = DependsOn(); + const map < int, SMESH_subMesh * >&subMeshes = DependsOn(); bool subMeshesComputed = true; - map::const_iterator itsub; + map < int, SMESH_subMesh * >::const_iterator itsub; for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++) + { + SMESH_subMesh *sm = (*itsub).second; + + const TopoDS_Shape & ss = sm->GetSubShape(); + int type = ss.ShapeType(); + bool computeOk = (sm->GetComputeState() == COMPUTE_OK); + if (!computeOk) { - SMESH_subMesh* sm = (*itsub).second; -// SCRUTE(sm->GetId()); -// SCRUTE(sm->GetComputeState()); - bool computeOk = (sm->GetComputeState() == COMPUTE_OK); - if (! computeOk) - { - subMeshesComputed = false; - SCRUTE(sm->GetId()); - break; - } + subMeshesComputed = false; + + switch (type) + { + case TopAbs_COMPOUND: + { + MESSAGE("The not computed sub mesh is a COMPOUND"); + break; + } + case TopAbs_COMPSOLID: + { + MESSAGE("The not computed sub mesh is a COMPSOLID"); + break; + } + case TopAbs_SHELL: + { + MESSAGE("The not computed sub mesh is a SHEL"); + break; + } + case TopAbs_WIRE: + { + MESSAGE("The not computed sub mesh is a WIRE"); + break; + } + case TopAbs_SOLID: + { + MESSAGE("The not computed sub mesh is a SOLID"); + break; + } + case TopAbs_FACE: + { + MESSAGE("The not computed sub mesh is a FACE"); + break; + } + case TopAbs_EDGE: + { + MESSAGE("The not computed sub mesh is a EDGE"); + break; + } + default: + { + MESSAGE("The not computed sub mesh is of unknown type"); + break; + } + } + + break; } - return subMeshesComputed; + } + return subMeshesComputed; } //============================================================================= /*! - * + * */ //============================================================================= bool SMESH_subMesh::SubMeshesReady() { MESSAGE("SMESH_subMesh::SubMeshesReady"); - const map& subMeshes = DependsOn(); + const map < int, SMESH_subMesh * >&subMeshes = DependsOn(); bool subMeshesReady = true; - map::const_iterator itsub; + map < int, SMESH_subMesh * >::const_iterator itsub; for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++) + { + SMESH_subMesh *sm = (*itsub).second; + bool computeOk = ((sm->GetComputeState() == COMPUTE_OK) + || (sm->GetComputeState() == READY_TO_COMPUTE)); + if (!computeOk) { - SMESH_subMesh* sm = (*itsub).second; -// SCRUTE(sm->GetId()); -// SCRUTE(sm->GetComputeState()); - bool computeOk = ( (sm->GetComputeState() == COMPUTE_OK) - || (sm->GetComputeState() == READY_TO_COMPUTE)) ; - if (! computeOk) - { - subMeshesReady = false; - SCRUTE(sm->GetId()); - break; - } + subMeshesReady = false; + SCRUTE(sm->GetId()); + break; } - return subMeshesReady; + } + return subMeshesReady; } //============================================================================= /*! - * Construct dependence on first level subMeshes. complex shapes (compsolid, + * Construct dependence on first level subMeshes. complex shapes (compsolid, * shell, wire) are not analysed the same way as simple shapes (solid, face, - * edge). + * edge). * For collection shapes (compsolid, shell, wire) prepare a list of submeshes * with possible multiples occurences. Multiples occurences corresponds to * internal frontiers within shapes of the collection and must not be keeped. @@ -292,156 +289,111 @@ bool SMESH_subMesh::SubMeshesReady() */ //============================================================================= -const map& SMESH_subMesh::DependsOn() +const map < int, SMESH_subMesh * >&SMESH_subMesh::DependsOn() { - if (_dependenceAnalysed) return _mapDepend; + if (_dependenceAnalysed) + return _mapDepend; - //MESSAGE("SMESH_subMesh::DependsOn"); + //MESSAGE("SMESH_subMesh::DependsOn"); int type = _subShape.ShapeType(); //SCRUTE(type); switch (type) + { + case TopAbs_COMPOUND: { - case TopAbs_COMPOUND: + //MESSAGE("compound"); + for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More(); + exp.Next()) { - //MESSAGE("compound"); - list shellInSolid; - for (TopExp_Explorer exp(_subShape,TopAbs_SOLID);exp.More();exp.Next()) - { - InsertDependence(exp.Current()); - for (TopExp_Explorer - exp2(exp.Current(),TopAbs_SHELL);exp2.More();exp2.Next()) - { - shellInSolid.push_back(exp2.Current()); - } - } - for (TopExp_Explorer exp(_subShape,TopAbs_SHELL);exp.More();exp.Next()) - { - list::iterator it1; - bool isInSolid = false; - for (it1 = shellInSolid.begin(); it1 != shellInSolid.end(); it1++) - { - TopoDS_Shape aShape = (*it1); - if (aShape.IsSame(exp.Current())) - { - isInSolid = true; - break; - } - } - if (!isInSolid) - InsertDependence(exp.Current()); //only shell not in solid - } - for (TopExp_Explorer exp(_subShape,TopAbs_FACE);exp.More();exp.Next()) - { - InsertDependence(exp.Current()); - } - for (TopExp_Explorer exp(_subShape,TopAbs_EDGE);exp.More();exp.Next()) - { - InsertDependence(exp.Current()); - } - break; + InsertDependence(exp.Current()); } - case TopAbs_COMPSOLID: + for (TopExp_Explorer exp(_subShape, TopAbs_SHELL, TopAbs_SOLID); exp.More(); + exp.Next()) { - //MESSAGE("compsolid"); - for (TopExp_Explorer exp(_subShape,TopAbs_SOLID);exp.More();exp.Next()) - { - InsertDependence(exp.Current()); - } -// list shapeList; -// for (TopExp_Explorer exp(_subShape,TopAbs_SOLID);exp.More();exp.Next()) -// { -// for (TopExp_Explorer -// exp2(exp.Current(),TopAbs_FACE);exp2.More();exp2.Next()) -// { -// shapeList.push_back(exp2.Current()); -// } -// } -// FinalizeDependence(shapeList); - break; + InsertDependence(exp.Current()); //only shell not in solid } - case TopAbs_SHELL: + for (TopExp_Explorer exp(_subShape, TopAbs_FACE, TopAbs_SHELL); exp.More(); + exp.Next()) { - //MESSAGE("shell"); - for (TopExp_Explorer exp(_subShape,TopAbs_FACE);exp.More();exp.Next()) - { - InsertDependence(exp.Current()); - } -// list shapeList; -// for (TopExp_Explorer exp(_subShape,TopAbs_FACE);exp.More();exp.Next()) -// { -// for (TopExp_Explorer -// exp2(exp.Current(),TopAbs_EDGE);exp2.More();exp2.Next()) -// { -// shapeList.push_back(exp2.Current()); -// } -// } -// FinalizeDependence(shapeList); - break; + InsertDependence(exp.Current()); } - case TopAbs_WIRE: + for (TopExp_Explorer exp(_subShape, TopAbs_EDGE, TopAbs_FACE); exp.More(); + exp.Next()) { - //MESSAGE("wire"); - for (TopExp_Explorer exp(_subShape,TopAbs_EDGE);exp.More();exp.Next()) - { - InsertDependence(exp.Current()); - } -// list shapeList; -// for (TopExp_Explorer exp(_subShape,TopAbs_EDGE);exp.More();exp.Next()) -// { -// for (TopExp_Explorer -// exp2(exp.Current(),TopAbs_VERTEX);exp2.More();exp2.Next()) -// { -// shapeList.push_back(exp2.Current()); -// } -// } -// FinalizeDependence(shapeList); - break; + InsertDependence(exp.Current()); } - case TopAbs_SOLID: + break; + } + case TopAbs_COMPSOLID: + { + //MESSAGE("compsolid"); + for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More(); + exp.Next()) { - //MESSAGE("solid"); -// for (TopExp_Explorer exp(_subShape,TopAbs_SHELL);exp.More();exp.Next()) -// { -// InsertDependence(exp.Current()); -// } - for (TopExp_Explorer exp(_subShape,TopAbs_FACE);exp.More();exp.Next()) - { - InsertDependence(exp.Current()); - } - break; + InsertDependence(exp.Current()); } - case TopAbs_FACE: + break; + } + case TopAbs_SHELL: + { + //MESSAGE("shell"); + for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More(); + exp.Next()) { - //MESSAGE("face"); -// for (TopExp_Explorer exp(_subShape,TopAbs_WIRE);exp.More();exp.Next()) -// { -// InsertDependence(exp.Current()); -// } - for (TopExp_Explorer exp(_subShape,TopAbs_EDGE);exp.More();exp.Next()) - { - InsertDependence(exp.Current()); - } - break; + InsertDependence(exp.Current()); } - case TopAbs_EDGE: + break; + } + case TopAbs_WIRE: + { + //MESSAGE("wire"); + for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More(); + exp.Next()) { - //MESSAGE("edge"); - for (TopExp_Explorer exp(_subShape,TopAbs_VERTEX);exp.More();exp.Next()) - { - InsertDependence(exp.Current()); - } - break; + InsertDependence(exp.Current()); } - case TopAbs_VERTEX: + break; + } + case TopAbs_SOLID: + { + //MESSAGE("solid"); + for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More(); + exp.Next()) { - break; + InsertDependence(exp.Current()); } - default: + break; + } + case TopAbs_FACE: + { + //MESSAGE("face"); + for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More(); + exp.Next()) { - break; + InsertDependence(exp.Current()); } + break; + } + case TopAbs_EDGE: + { + //MESSAGE("edge"); + for (TopExp_Explorer exp(_subShape, TopAbs_VERTEX); exp.More(); + exp.Next()) + { + InsertDependence(exp.Current()); + } + break; + } + case TopAbs_VERTEX: + { + break; + } + default: + { + break; } + } _dependenceAnalysed = true; return _mapDepend; } @@ -455,536 +407,638 @@ const map& SMESH_subMesh::DependsOn() void SMESH_subMesh::InsertDependence(const TopoDS_Shape aSubShape) { //MESSAGE("SMESH_subMesh::InsertDependence"); - //SMESH_subMesh* aSubMesh = _father->GetSubMeshContaining(aSubShape); - //SCRUTE(aSubMesh); - //if (! aSubMesh) aSubMesh = _father->GetSubMesh(aSubShape); - - SMESH_subMesh* aSubMesh = _father->GetSubMesh(aSubShape); + SMESH_subMesh *aSubMesh = _father->GetSubMesh(aSubShape); int type = aSubShape.ShapeType(); - int ordType = 9 - type; // 2 = Vertex, 8 = CompSolid + int ordType = 9 - type; // 2 = Vertex, 8 = CompSolid int cle = aSubMesh->GetId(); - cle += 10000000 * ordType; // sort map by ordType then index + cle += 10000000 * ordType; // sort map by ordType then index if (_mapDepend.find(cle) == _mapDepend.end()) + { + _mapDepend[cle] = aSubMesh; + const map < int, SMESH_subMesh * >&subMap = aSubMesh->DependsOn(); + map < int, SMESH_subMesh * >::const_iterator im; + for (im = subMap.begin(); im != subMap.end(); im++) { - _mapDepend[cle] = aSubMesh; - const map& subMap = aSubMesh->DependsOn(); - map::const_iterator im; - for (im = subMap.begin(); im != subMap.end(); im++) - { - int clesub = (*im).first; - SMESH_subMesh* sm = (*im).second; - if (_mapDepend.find(clesub) == _mapDepend.end()) - _mapDepend[clesub] = sm; - } + int clesub = (*im).first; + SMESH_subMesh *sm = (*im).second; + if (_mapDepend.find(clesub) == _mapDepend.end()) + _mapDepend[clesub] = sm; } + } } - + //============================================================================= /*! - * For collection shapes (compsolid, shell, wire). - * Add only subMesh figuring only once in multiset to dependence list + * */ //============================================================================= -// void SMESH_subMesh::FinalizeDependence(list& shapeList) -// { -// //MESSAGE("SMESH_subMesh::FinalizeDependence"); -// list::iterator it1, it2; -// for(it1 = shapeList.begin(); it1 != shapeList.end(); it1++) -// { -// TopoDS_Shape aSubShape = (*it1); -// int count = 0; -// for(it2 = shapeList.begin(); it2 != shapeList.end(); it2++) -// { -// TopoDS_Shape other = (*it2); -// if (other.IsSame(aSubShape)) count++; -// } -// if (count == 1) InsertDependence(aSubShape); -// SCRUTE(count); -// } -// } +const TopoDS_Shape & SMESH_subMesh::GetSubShape() +{ + //MESSAGE("SMESH_subMesh::GetSubShape"); + return _subShape; +} -//============================================================================= -/*! - * - */ -//============================================================================= - const TopoDS_Shape& SMESH_subMesh::GetSubShape() +//======================================================================= +//function : CanAddHypothesis +//purpose : return true if theHypothesis can be attached to me: +// its dimention is checked +//======================================================================= + +bool SMESH_subMesh::CanAddHypothesis(const SMESH_Hypothesis* theHypothesis) const +{ + int aHypDim = theHypothesis->GetDim(); + int aShapeDim = SMESH_Gen::GetShapeDim(_subShape); + if ( aHypDim <= aShapeDim ) + return true; +// if ( aHypDim < aShapeDim ) +// return ( _father->IsMainShape( _subShape )); + + return false; +} + +//======================================================================= +//function : IsApplicableHypotesis +//purpose : return true if theHypothesis can be used to mesh me: +// its shape type is checked +//======================================================================= + +bool SMESH_subMesh::IsApplicableHypotesis(const SMESH_Hypothesis* theHypothesis) const { - //MESSAGE("SMESH_subMesh::GetSubShape"); - return _subShape; + if ( theHypothesis->GetType() > SMESHDS_Hypothesis::PARAM_ALGO) + // algorithm + return ( theHypothesis->GetShapeType() & (1<< _subShape.ShapeType())); + + // hypothesis + switch ( _subShape.ShapeType() ) { + case TopAbs_EDGE: + case TopAbs_FACE: + case TopAbs_SHELL: + case TopAbs_SOLID: { + int aHypDim = theHypothesis->GetDim(); + int aShapeDim = SMESH_Gen::GetShapeDim(_subShape); + return ( aHypDim == aShapeDim ); + } +// case TopAbs_VERTEX: +// case TopAbs_WIRE: +// case TopAbs_COMPSOLID: +// case TopAbs_COMPOUND: + default:; + } + + return false; } //============================================================================= /*! - * + * */ //============================================================================= -bool SMESH_subMesh::AlgoStateEngine(int event, SMESH_Hypothesis* anHyp) - throw (SALOME_Exception) +SMESH_Hypothesis::Hypothesis_Status + SMESH_subMesh::AlgoStateEngine(int event, SMESH_Hypothesis * anHyp) { // MESSAGE("SMESH_subMesh::AlgoStateEngine"); //SCRUTE(_algoState); //SCRUTE(event); + SMESH_Hypothesis::Hypothesis_Status aux_ret, ret = SMESH_Hypothesis::HYP_OK; + // **** les retour des evenement shape sont significatifs // (add ou remove fait ou non) // le retour des evenement father n'indiquent pas que add ou remove fait int dim = SMESH_Gen::GetShapeDim(_subShape); if (dim < 1) - { - _algoState = HYP_OK; - //SCRUTE(_algoState); - return true; - } + { + _algoState = HYP_OK; + if (event == ADD_HYP || event == ADD_ALGO) + return SMESH_Hypothesis::HYP_BAD_DIM; // do not allow to assign any hyp + else + return SMESH_Hypothesis::HYP_OK; + } SMESH_Gen* gen =_father->GetGen(); - bool ret; - _oldAlgoState = _algoState; +// bool ret = false; + int oldAlgoState = _algoState; bool modifiedHyp = false; // if set to true, force event MODIF_ALGO_STATE // in ComputeStateEngine + // ---------------------- + // check mesh conformity + // ---------------------- + if (event == ADD_ALGO) + { + if (IsApplicableHypotesis( anHyp ) && + !_father->IsNotConformAllowed() && + !IsConform( static_cast< SMESH_Algo* >( anHyp ))) + return SMESH_Hypothesis::HYP_NOTCONFORM; + } + + // ---------------------------------- + // add a hypothesis to DS if possible + // ---------------------------------- + if (event == ADD_HYP || event == ADD_ALGO) + { + if ( ! CanAddHypothesis( anHyp )) + return SMESH_Hypothesis::HYP_BAD_DIM; + + if ( GetSimilarAttached( _subShape, anHyp ) ) + return SMESH_Hypothesis::HYP_ALREADY_EXIST; + + if ( !_meshDS->AddHypothesis(_subShape, anHyp)) + return SMESH_Hypothesis::HYP_ALREADY_EXIST; + } + + // -------------------------- + // remove a hypothesis from DS + // -------------------------- + if (event == REMOVE_HYP || event == REMOVE_ALGO) + { + if (!_meshDS->RemoveHypothesis(_subShape, anHyp)) + return SMESH_Hypothesis::HYP_OK; // nothing changes + } + + // ------------------ + // analyse algo state + // ------------------ + if (!IsApplicableHypotesis( anHyp )) + return ret; // not applicable hypotheses do not change algo state + switch (_algoState) - { + { - // ---------------------------------------------------------------------- + // ---------------------------------------------------------------------- - case NO_ALGO: - switch (event) - { - case ADD_HYP: - ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO); - ret = _meshDS->AddHypothesis(_subShape, anHyp); - break; - case ADD_ALGO: - ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO); - if (anHyp->GetDim() <= SMESH_Gen::GetShapeDim(_subShape)) - { - ret = _meshDS->AddHypothesis(_subShape, anHyp); -// if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))) -// if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType())) - if (ret &&(anHyp->GetShapeType() & (1<< _subShape.ShapeType()))) - { - SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); - ASSERT(algo); - ret = algo->CheckHypothesis((*_father),_subShape); - if (ret) SetAlgoState(HYP_OK); - else SetAlgoState(MISSING_HYP); - } - } - break; - case REMOVE_HYP: - ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO); - ret = _meshDS->RemoveHypothesis(_subShape, anHyp); - break; - case REMOVE_ALGO: - ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO); - ret = _meshDS->RemoveHypothesis(_subShape, anHyp); - break; - case ADD_FATHER_HYP: // nothing to do - break; - case ADD_FATHER_ALGO: // Algo just added in father - ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO); -// if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)) -// if (anHyp->GetShapeType() == _subShape.ShapeType()) - if (anHyp->GetShapeType() & (1<< _subShape.ShapeType())) - { - SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); - ASSERT(algo); - ret = algo->CheckHypothesis((*_father),_subShape); - if (ret) SetAlgoState(HYP_OK); - else SetAlgoState(MISSING_HYP); - } - break; - case REMOVE_FATHER_HYP: // nothing to do - break; - case REMOVE_FATHER_ALGO: // nothing to do - break; - default: - ASSERT(0); - break; - } + case NO_ALGO: + switch (event) { + case ADD_HYP: break; - - // ---------------------------------------------------------------------- - - case MISSING_HYP: - switch (event) - { - case ADD_HYP: - ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO); - ret = _meshDS->AddHypothesis(_subShape, anHyp); - if (ret) - { - SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); - ASSERT(algo); - ret = algo->CheckHypothesis((*_father),_subShape); - if (ret) SetAlgoState(HYP_OK); - else SetAlgoState(MISSING_HYP); - } - break; - case ADD_ALGO: //already existing algo : on father ? - ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO); - if (anHyp->GetDim() <= SMESH_Gen::GetShapeDim(_subShape)) - { - ret = _meshDS->AddHypothesis(_subShape, anHyp); -// if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))) -// if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType())) - if (ret &&(anHyp->GetShapeType() & (1<< _subShape.ShapeType()))) - { - SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); - if (algo == NULL) // two algo on the same subShape... - { - MESSAGE("two algo on the same subshape not allowed"); - ret = _meshDS->RemoveHypothesis(_subShape, anHyp); - ret = false; - } - else - { - ret = algo->CheckHypothesis((*_father),_subShape); - if (ret) SetAlgoState(HYP_OK); - else SetAlgoState(MISSING_HYP); - } - } - } - break; - case REMOVE_HYP: - ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO); - ret = _meshDS->RemoveHypothesis(_subShape, anHyp); - break; - case REMOVE_ALGO: // perhaps a father algo applies ? - ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO); - ret = _meshDS->RemoveHypothesis(_subShape, anHyp); -// if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))) -// if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType())) - if (ret &&(anHyp->GetShapeType() & (1<<_subShape.ShapeType()))) - { - SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); - if (algo == NULL) // no more algo applying on subShape... - { - SetAlgoState(NO_ALGO); - } - else - { - ret = algo->CheckHypothesis((*_father),_subShape); - if (ret) SetAlgoState(HYP_OK); - else SetAlgoState(MISSING_HYP); - } - } - break; - case ADD_FATHER_HYP: - ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO); - { - SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); - ASSERT(algo); - ret = algo->CheckHypothesis((*_father),_subShape); - if (ret) SetAlgoState(HYP_OK); - else SetAlgoState(MISSING_HYP); - } - break; - case ADD_FATHER_ALGO: // detect if two algo of same dim on father - ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO); -// if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)) -// if (anHyp->GetShapeType() == _subShape.ShapeType()) - if (anHyp->GetShapeType() & (1<< _subShape.ShapeType())) - { - SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); - if (algo == NULL) // two applying algo on father - { - MESSAGE("two applying algo on fatherShape..."); - SetAlgoState(NO_ALGO); - } - else - { - ret = algo->CheckHypothesis((*_father),_subShape); - if (ret) SetAlgoState(HYP_OK); - else SetAlgoState(MISSING_HYP); - } - } - break; - case REMOVE_FATHER_HYP: // nothing to do - break; - case REMOVE_FATHER_ALGO: - ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO); -// if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)) -// if (anHyp->GetShapeType() == _subShape.ShapeType()) - if (anHyp->GetShapeType() & (1<< _subShape.ShapeType())) - { - SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); - if (algo == NULL) // no more applying algo on father - { - SetAlgoState(NO_ALGO); - } - else - { - ret = algo->CheckHypothesis((*_father),_subShape); - if (ret) SetAlgoState(HYP_OK); - else SetAlgoState(MISSING_HYP); - } - } - break; - default: - ASSERT(0); - break; - } + case ADD_ALGO: { + SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); + ASSERT(algo); + if (algo->CheckHypothesis((*_father),_subShape, aux_ret)) + SetAlgoState(HYP_OK); + else + SetAlgoState(MISSING_HYP); + break; + } + case REMOVE_HYP: + break; + case REMOVE_ALGO: + break; + case ADD_FATHER_HYP: + break; + case ADD_FATHER_ALGO: { // Algo just added in father + SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); + ASSERT(algo); + if ( algo == anHyp ) { + if ( algo->CheckHypothesis((*_father),_subShape, aux_ret)) + SetAlgoState(HYP_OK); + else + SetAlgoState(MISSING_HYP); + } + break; + } + case REMOVE_FATHER_HYP: + break; + case REMOVE_FATHER_ALGO: { + SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); + if (algo) + { + if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) + SetAlgoState(HYP_OK); + else + SetAlgoState(MISSING_HYP); + } + break; + } + default: + ASSERT(0); break; + } + break; - // ---------------------------------------------------------------------- + // ---------------------------------------------------------------------- - case HYP_OK: - switch (event) - { - case ADD_HYP: - { - ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO); - SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); - ASSERT(algo); - list originalUsedHyps - = algo->GetUsedHypothesis((*_father), _subShape); // copy - - ret = _meshDS->AddHypothesis(_subShape, anHyp); - if (ret) - { - ret = algo->CheckHypothesis((*_father),_subShape); - if (! ret) - { - INFOS("two applying algo on the same shape not allowed"); - ret = _meshDS->RemoveHypothesis(_subShape, anHyp); - ret = false; - } - else // compare SMESHDS_Hypothesis* lists (order important) - { - MESSAGE("---"); - const list& newUsedHyps - = algo->GetUsedHypothesis((*_father), _subShape); - modifiedHyp = (originalUsedHyps != newUsedHyps); - } - } - } - break; - case ADD_ALGO: //already existing algo : on father ? - ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO); - if (anHyp->GetDim() <= SMESH_Gen::GetShapeDim(_subShape)) - { - ret = _meshDS->AddHypothesis(_subShape, anHyp); -// if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))) -// if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType())) - if (ret &&(anHyp->GetShapeType() & (1<< _subShape.ShapeType()))) - { - SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); - if (algo == NULL) // two algo on the same subShape... - { - INFOS("two algo on the same subshape not allowed"); - ret = _meshDS->RemoveHypothesis(_subShape, anHyp); - ret = false; - } - else - { - ret = algo->CheckHypothesis((*_father),_subShape); - if (ret) SetAlgoState(HYP_OK); - else SetAlgoState(MISSING_HYP); - } - } - } - break; - case REMOVE_HYP: - ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO); - ret = _meshDS->RemoveHypothesis(_subShape, anHyp); - if (ret) - { - SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); - ASSERT(algo); - ret = algo->CheckHypothesis((*_father),_subShape); - if (ret) SetAlgoState(HYP_OK); - else SetAlgoState(MISSING_HYP); - modifiedHyp = true; - } - break; - case REMOVE_ALGO: // perhaps a father algo applies ? - ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO); - ret = _meshDS->RemoveHypothesis(_subShape, anHyp); -// if (ret &&(anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape))) -// if (ret &&(anHyp->GetShapeType() == _subShape.ShapeType())) - if (ret &&(anHyp->GetShapeType() & (1<< _subShape.ShapeType()))) - { - SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); - if (algo == NULL) // no more algo applying on subShape... - { - SetAlgoState(NO_ALGO); - } - else - { - ret = algo->CheckHypothesis((*_father),_subShape); - if (ret) SetAlgoState(HYP_OK); - else SetAlgoState(MISSING_HYP); - } - } - break; - case ADD_FATHER_HYP: - ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO); - { - SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); - ASSERT(algo); - ret = algo->CheckHypothesis((*_father),_subShape); - if (ret) SetAlgoState(HYP_OK); - else SetAlgoState(MISSING_HYP); - } - break; - case ADD_FATHER_ALGO: // detect if two algo of same dim on father - ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO); -// if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)) -// if (anHyp->GetShapeType() == _subShape.ShapeType()) - if (anHyp->GetShapeType() & (1<< _subShape.ShapeType())) - { - SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); - if (algo == NULL) // two applying algo on father - { - MESSAGE("two applying algo on fatherShape..."); - SetAlgoState(NO_ALGO); - } - else - { - ret = algo->CheckHypothesis((*_father),_subShape); - if (ret) SetAlgoState(HYP_OK); - else SetAlgoState(MISSING_HYP); - } - } - break; - case REMOVE_FATHER_HYP: - ASSERT(anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO); - { - SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); - ASSERT(algo); - ret = algo->CheckHypothesis((*_father),_subShape); - if (ret) SetAlgoState(HYP_OK); - else SetAlgoState(MISSING_HYP); - } - break; - case REMOVE_FATHER_ALGO: - ASSERT(anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO); -// if (anHyp->GetDim() == SMESH_Gen::GetShapeDim(_subShape)) -// if (anHyp->GetShapeType() == _subShape.ShapeType()) - if (anHyp->GetShapeType() & (1<< _subShape.ShapeType())) - { - SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); - if (algo == NULL) // no more applying algo on father - { - SetAlgoState(NO_ALGO); - } - else - { - ret = algo->CheckHypothesis((*_father),_subShape); - if (ret) SetAlgoState(HYP_OK); - else SetAlgoState(MISSING_HYP); - } - } - break; - default: - ASSERT(0); - break; - } + case MISSING_HYP: + switch (event) + { + case ADD_HYP: { + SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); + ASSERT(algo); + if ( algo->CheckHypothesis((*_father),_subShape, ret )) + SetAlgoState(HYP_OK); + if (SMESH_Hypothesis::IsStatusFatal( ret )) + _meshDS->RemoveHypothesis(_subShape, anHyp); + else if (!_father->IsUsedHypothesis( anHyp, _subShape )) + { + _meshDS->RemoveHypothesis(_subShape, anHyp); + ret = SMESH_Hypothesis::HYP_INCOMPATIBLE; + } + break; + } + case ADD_ALGO: { //already existing algo : on father ? + SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); + ASSERT(algo); + if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))// ignore hyp status + SetAlgoState(HYP_OK); + else + SetAlgoState(MISSING_HYP); + break; + } + case REMOVE_HYP: + break; + case REMOVE_ALGO: { // perhaps a father algo applies ? + SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); + if (algo == NULL) // no more algo applying on subShape... + { + SetAlgoState(NO_ALGO); + } + else + { + if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) + SetAlgoState(HYP_OK); + else + SetAlgoState(MISSING_HYP); + } + break; + } + case ADD_FATHER_HYP: { + SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); + ASSERT(algo); + if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) + SetAlgoState(HYP_OK); + else + SetAlgoState(MISSING_HYP); + } + break; + case ADD_FATHER_ALGO: { // new father algo + SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); + ASSERT( algo ); + if ( algo == anHyp ) { + if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) + SetAlgoState(HYP_OK); + else + SetAlgoState(MISSING_HYP); + } break; + } + case REMOVE_FATHER_HYP: // nothing to do + break; + case REMOVE_FATHER_ALGO: { + SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); + if (algo == NULL) // no more applying algo on father + { + SetAlgoState(NO_ALGO); + } + else + { + if ( algo->CheckHypothesis((*_father),_subShape , aux_ret )) + SetAlgoState(HYP_OK); + else + SetAlgoState(MISSING_HYP); + } + break; + } + default: + ASSERT(0); + break; + } + break; - // ---------------------------------------------------------------------- + // ---------------------------------------------------------------------- + case HYP_OK: + switch (event) + { + case ADD_HYP: { + SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); + ASSERT(algo); + if (!algo->CheckHypothesis((*_father),_subShape, ret )) + { + MESSAGE("two applying algo on the same shape not allowed"); + _meshDS->RemoveHypothesis(_subShape, anHyp); + if ( !SMESH_Hypothesis::IsStatusFatal( ret )) + // ret should be fatal: anHyp was not added + ret = SMESH_Hypothesis::HYP_INCOMPATIBLE; + } + else if (SMESH_Hypothesis::IsStatusFatal( ret )) + { + _meshDS->RemoveHypothesis(_subShape, anHyp); + } + else if (!_father->IsUsedHypothesis( anHyp, _subShape )) + { + _meshDS->RemoveHypothesis(_subShape, anHyp); + ret = SMESH_Hypothesis::HYP_INCOMPATIBLE; + } + else + { + modifiedHyp = true; + } + break; + } + case ADD_ALGO: { //already existing algo : on father ? + SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); + if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) + SetAlgoState(HYP_OK); + else + SetAlgoState(MISSING_HYP); + modifiedHyp = true; + break; + } + case REMOVE_HYP: { + SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); + ASSERT(algo); + if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) + SetAlgoState(HYP_OK); + else + SetAlgoState(MISSING_HYP); + modifiedHyp = true; + break; + } + case REMOVE_ALGO: { // perhaps a father algo applies ? + SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); + if (algo == NULL) // no more algo applying on subShape... + { + SetAlgoState(NO_ALGO); + } + else + { + if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) + SetAlgoState(HYP_OK); + else + SetAlgoState(MISSING_HYP); + // check if same algo remains + if ( anHyp != algo && strcmp( anHyp->GetName(), algo->GetName()) ) + modifiedHyp = true; + } + break; + } + case ADD_FATHER_HYP: { // new father hypothesis ? + SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); + ASSERT(algo); + if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) + { + SetAlgoState(HYP_OK); + if (_father->IsUsedHypothesis( anHyp, _subShape )) // new Hyp + modifiedHyp = true; + } + else + SetAlgoState(MISSING_HYP); + break; + } + case ADD_FATHER_ALGO: { // a new algo on father + SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); + if ( algo == anHyp ) { + if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) + SetAlgoState(HYP_OK); + else + SetAlgoState(MISSING_HYP); + modifiedHyp = true; + } + break; + } + case REMOVE_FATHER_HYP: { + SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); + ASSERT(algo); + if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) + SetAlgoState(HYP_OK); + else + SetAlgoState(MISSING_HYP); + // is there the same local hyp or maybe a new father algo applied? + if ( !GetSimilarAttached( _subShape, anHyp ) ) + modifiedHyp = true; + break; + } + case REMOVE_FATHER_ALGO: { + SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape); + if (algo == NULL) // no more applying algo on father + { + SetAlgoState(NO_ALGO); + } + else + { + if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) + SetAlgoState(HYP_OK); + else + SetAlgoState(MISSING_HYP); + // is there the same local algo or maybe a new father algo applied? + if ( !GetSimilarAttached( _subShape, anHyp )) + modifiedHyp = true; + } + break; + } default: ASSERT(0); break; } - //SCRUTE(_algoState); - if ((_algoState != _oldAlgoState) || modifiedHyp) + break; + + // ---------------------------------------------------------------------- + + default: + ASSERT(0); + break; + } + // ---------------------------------------- + // check concurent hypotheses on ansestors + // ---------------------------------------- + if (ret < SMESH_Hypothesis::HYP_CONCURENT && + (event == ADD_FATHER_HYP || + event == ADD_FATHER_ALGO || + event == REMOVE_FATHER_HYP || + event == REMOVE_FATHER_ALGO || + event == REMOVE_ALGO || + event == REMOVE_HYP)) + { + ret = CheckConcurentHypothesis( anHyp->GetType() ); + } + + if ((_algoState != oldAlgoState) || modifiedHyp) int retc = ComputeStateEngine(MODIF_ALGO_STATE); + return ret; } + +//======================================================================= +//function : IsConform +//purpose : check if a conform mesh will be produced by the Algo +//======================================================================= + +bool SMESH_subMesh::IsConform(const SMESH_Algo* theAlgo) +{ +// MESSAGE( "SMESH_subMesh::IsConform" ); + + if ( !theAlgo ) return false; + + // check only algo that doesn't NeedDescretBoundary(): because mesh made + // on a sub-shape will be ignored by theAlgo + if ( theAlgo->NeedDescretBoundary() ) + return true; + + SMESH_Gen* gen =_father->GetGen(); + + // only local algo is to be checked + if ( gen->IsGlobalAlgo( theAlgo, *_father )) + return true; + + // check algo attached to adjacent shapes + + // loop on one level down sub-meshes + TopoDS_Iterator itsub( _subShape ); + for (; itsub.More(); itsub.Next()) + { + // loop on adjacent subShapes + TopTools_ListIteratorOfListOfShape it( _father->GetAncestors( itsub.Value() )); + for (; it.More(); it.Next()) + { + const TopoDS_Shape& adjacent = it.Value(); + if ( _subShape.IsSame( adjacent )) continue; + if ( adjacent.ShapeType() != _subShape.ShapeType()) + break; + + // check algo attached to smAdjacent + SMESH_Algo * algo = gen->GetAlgo((*_father), adjacent); + if (algo && + //algo != theAlgo && + !algo->NeedDescretBoundary() /*&& + !gen->IsGlobalAlgo( algo, *_father )*/) + return false; // NOT CONFORM MESH WILL BE PRODUCED + } + } + + return true; +} + //============================================================================= /*! - * + * */ //============================================================================= void SMESH_subMesh::SetAlgoState(int state) { - if (state != _oldAlgoState) +// if (state != _oldAlgoState) // int retc = ComputeStateEngine(MODIF_ALGO_STATE); - _algoState = state; + _algoState = state; } //============================================================================= /*! - * + * */ //============================================================================= - -void SMESH_subMesh::SubMeshesAlgoStateEngine(int event, - SMESH_Hypothesis* anHyp) - throw (SALOME_Exception) +SMESH_Hypothesis::Hypothesis_Status + SMESH_subMesh::SubMeshesAlgoStateEngine(int event, + SMESH_Hypothesis * anHyp) { //MESSAGE("SMESH_subMesh::SubMeshesAlgoStateEngine"); - int dim = SMESH_Gen::GetShapeDim(_subShape); - if (dim > 1) + SMESH_Hypothesis::Hypothesis_Status ret = SMESH_Hypothesis::HYP_OK; + //EAP: a wire (dim==1) should notify edges (dim==1) + //EAP: int dim = SMESH_Gen::GetShapeDim(_subShape); + if (/*EAP:dim > 1*/ _subShape.ShapeType() < TopAbs_EDGE ) + { + const map < int, SMESH_subMesh * >&subMeshes = DependsOn(); + + map < int, SMESH_subMesh * >::const_iterator itsub; + for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++) { - const map& subMeshes = DependsOn(); - - map::const_iterator itsub; - for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++) + SMESH_subMesh *sm = (*itsub).second; + SMESH_Hypothesis::Hypothesis_Status ret2 = + sm->AlgoStateEngine(event, anHyp); + if ( ret2 > ret ) + ret = ret2; + } + } + return ret; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +void SMESH_subMesh::CleanDependsOn() +{ + MESSAGE("SMESH_subMesh::CleanDependsOn"); + // **** parcourir les ancetres dans l'ordre de dépendance + + ComputeStateEngine(CLEAN); + + const map < int, SMESH_subMesh * >&dependson = DependsOn(); + map < int, SMESH_subMesh * >::const_iterator its; + for (its = dependson.begin(); its != dependson.end(); its++) { - SMESH_subMesh* sm = (*itsub).second; - sm->AlgoStateEngine(event, anHyp); + SMESH_subMesh *sm = (*its).second; + SCRUTE((*its).first); + sm->ComputeStateEngine(CLEAN); } - } } //============================================================================= /*! - * + * */ //============================================================================= void SMESH_subMesh::DumpAlgoState(bool isMain) { - int dim = SMESH_Gen::GetShapeDim(_subShape); + int dim = SMESH_Gen::GetShapeDim(_subShape); // if (dim < 1) return; - if (isMain) - { - const map& subMeshes = DependsOn(); - - map::const_iterator itsub; - for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++) + if (isMain) { - SMESH_subMesh* sm = (*itsub).second; - sm->DumpAlgoState(false); - } - } - int type = _subShape.ShapeType(); - MESSAGE("dim = " << dim << " type of shape " << type); - switch(_algoState) - { - case NO_ALGO: MESSAGE(" AlgoState = NO_ALGO"); break; - case MISSING_HYP: MESSAGE(" AlgoState = MISSING_HYP"); break; - case HYP_OK: MESSAGE(" AlgoState = HYP_OK"); break; - } - switch (_computeState) - { - case NOT_READY: MESSAGE(" ComputeState = NOT_READY"); break; - case READY_TO_COMPUTE: MESSAGE(" ComputeState = READY_TO_COMPUTE"); break; - case COMPUTE_OK: MESSAGE(" ComputeState = COMPUTE_OK"); break; - case FAILED_TO_COMPUTE: MESSAGE(" ComputeState = FAILED_TO_COMPUTE");break; - } + const map < int, SMESH_subMesh * >&subMeshes = DependsOn(); + + map < int, SMESH_subMesh * >::const_iterator itsub; + for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++) + { + SMESH_subMesh *sm = (*itsub).second; + sm->DumpAlgoState(false); + } + } + int type = _subShape.ShapeType(); + MESSAGE("dim = " << dim << " type of shape " << type); + switch (_algoState) + { + case NO_ALGO: + MESSAGE(" AlgoState = NO_ALGO"); + break; + case MISSING_HYP: + MESSAGE(" AlgoState = MISSING_HYP"); + break; + case HYP_OK: + MESSAGE(" AlgoState = HYP_OK"); + break; + } + switch (_computeState) + { + case NOT_READY: + MESSAGE(" ComputeState = NOT_READY"); + break; + case READY_TO_COMPUTE: + MESSAGE(" ComputeState = READY_TO_COMPUTE"); + break; + case COMPUTE_OK: + MESSAGE(" ComputeState = COMPUTE_OK"); + break; + case FAILED_TO_COMPUTE: + MESSAGE(" ComputeState = FAILED_TO_COMPUTE"); + break; + } } //============================================================================= /*! - * + * */ //============================================================================= bool SMESH_subMesh::ComputeStateEngine(int event) - throw (SALOME_Exception) { //MESSAGE("SMESH_subMesh::ComputeStateEngine"); //SCRUTE(_computeState); @@ -993,405 +1047,604 @@ bool SMESH_subMesh::ComputeStateEngine(int event) int dim = SMESH_Gen::GetShapeDim(_subShape); if (dim < 1) - { - if (_vertexSet) _computeState = COMPUTE_OK; - else _computeState = READY_TO_COMPUTE; - //SCRUTE(_computeState); - return true; - } - SMESH_Gen* gen =_father->GetGen(); - SMESH_Algo* algo = 0; - bool ret; + { + if ( IsMeshComputed() ) + _computeState = COMPUTE_OK; + else + _computeState = READY_TO_COMPUTE; + return true; + } + SMESH_Gen *gen = _father->GetGen(); + SMESH_Algo *algo = 0; + bool ret = true; + SMESH_Hypothesis::Hypothesis_Status hyp_status; - switch(_computeState) - { + switch (_computeState) + { - // ---------------------------------------------------------------------- + // ---------------------------------------------------------------------- - case NOT_READY: - switch (event) - { - case MODIF_HYP: // nothing to do - break; - case MODIF_ALGO_STATE: - if (_algoState == HYP_OK) - _computeState = READY_TO_COMPUTE; - break; - case COMPUTE: // nothing to do - break; - case CLEAN: // nothing to do - break; - case CLEANDEP: // nothing to do - RemoveSubMeshElementsAndNodes(); // recursive call... - break; - case SUBMESH_COMPUTED: // nothing to do - break; - default: - ASSERT(0); - break; - } + case NOT_READY: + switch (event) + { + case MODIF_HYP: // nothing to do + break; + case MODIF_ALGO_STATE: + if (_algoState == HYP_OK) + { + _computeState = READY_TO_COMPUTE; + } + break; + case COMPUTE: // nothing to do + break; + case CLEAN: + RemoveSubMeshElementsAndNodes(); + break; + case CLEANDEP: + CleanDependants(); + break; + case SUBMESH_COMPUTED: // nothing to do + break; + case SUBMESH_RESTORED: + ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE ); + break; + case MESH_ENTITY_REMOVED: + break; + case CHECK_COMPUTE_STATE: + if ( IsMeshComputed() ) + _computeState = COMPUTE_OK; + break; + default: + ASSERT(0); break; + } + break; - // ---------------------------------------------------------------------- + // ---------------------------------------------------------------------- - case READY_TO_COMPUTE: - switch (event) - { - case MODIF_HYP: // nothing to do - break; - case MODIF_ALGO_STATE: - _computeState = NOT_READY; - algo = gen->GetAlgo((*_father), _subShape); - if (algo) - { - ret = algo->CheckHypothesis((*_father),_subShape); - if (ret) _computeState = READY_TO_COMPUTE; - } - break; - case COMPUTE: - { - algo = gen->GetAlgo((*_father), _subShape); - ASSERT(algo); - ret = algo->CheckHypothesis((*_father),_subShape); - if (! ret) - { - MESSAGE("***** verify compute state *****"); - _computeState = NOT_READY; - break; - } - ret = SubMeshesComputed(); - if (!ret) - { - MESSAGE("Some SubMeshes not computed"); - _computeState = FAILED_TO_COMPUTE; - break; - } - ret = algo->Compute((*_father),_subShape); - if (!ret) - { - MESSAGE("problem in algo execution: failed to compute"); - _computeState = FAILED_TO_COMPUTE; - break; - } - else - { - _computeState = COMPUTE_OK; - UpdateDependantsState(); // send event SUBMESH_COMPUTED - } - } - break; - case CLEAN: - _computeState = NOT_READY; - algo = gen->GetAlgo((*_father), _subShape); - if (algo) - { - ret = algo->CheckHypothesis((*_father),_subShape); - if (ret) _computeState = READY_TO_COMPUTE; - } - break; - case CLEANDEP: - RemoveSubMeshElementsAndNodes(); - _computeState = NOT_READY; - algo = gen->GetAlgo((*_father), _subShape); - if (algo) - { - ret = algo->CheckHypothesis((*_father),_subShape); - if (ret) _computeState = READY_TO_COMPUTE; - } - break; - case SUBMESH_COMPUTED: // nothing to do - break; - default: - ASSERT(0); - break; - } + case READY_TO_COMPUTE: + switch (event) + { + case MODIF_HYP: // nothing to do + break; + case MODIF_ALGO_STATE: + _computeState = NOT_READY; + algo = gen->GetAlgo((*_father), _subShape); + if (algo) + { + ret = algo->CheckHypothesis((*_father), _subShape, hyp_status); + if (ret) + _computeState = READY_TO_COMPUTE; + } + break; + case COMPUTE: + { + algo = gen->GetAlgo((*_father), _subShape); + ASSERT(algo); + ret = algo->CheckHypothesis((*_father), _subShape, hyp_status); + if (!ret) + { + MESSAGE("***** verify compute state *****"); + _computeState = NOT_READY; + break; + } + // check submeshes needed + if (algo->NeedDescretBoundary()) + ret = SubMeshesComputed(); + if (!ret) + { + MESSAGE("Some SubMeshes not computed"); + _computeState = FAILED_TO_COMPUTE; + break; + } + RemoveSubMeshElementsAndNodes(); + // compute + if (!algo->NeedDescretBoundary() && !algo->OnlyUnaryInput()) + ret = ApplyToCollection( algo, GetCollection( gen, algo ) ); + else + ret = algo->Compute((*_father), _subShape); + + if (!ret) + { + MESSAGE("problem in algo execution: failed to compute"); + _computeState = FAILED_TO_COMPUTE; + if (!algo->NeedDescretBoundary()) + UpdateSubMeshState( FAILED_TO_COMPUTE ); + +#ifdef _DEBUG_ + // Show vertices location of a failed shape + TopExp_Explorer exp( _subShape, TopAbs_VERTEX); + for ( ; exp.More(); exp.Next() ) { + gp_Pnt P( BRep_Tool::Pnt( TopoDS::Vertex( exp.Current() ))); + cout << P.X() << " " << P.Y() << " " << P.Z() << " " << endl; + } +#endif + break; + } + else + { + _computeState = COMPUTE_OK; + UpdateDependantsState( SUBMESH_COMPUTED ); // send event SUBMESH_COMPUTED + if (!algo->NeedDescretBoundary()) + UpdateSubMeshState( COMPUTE_OK ); + } + } + break; + case CLEAN: + RemoveSubMeshElementsAndNodes(); + _computeState = NOT_READY; + algo = gen->GetAlgo((*_father), _subShape); + if (algo) + { + ret = algo->CheckHypothesis((*_father), _subShape, hyp_status); + if (ret) + _computeState = READY_TO_COMPUTE; + } + break; + case CLEANDEP: + CleanDependants(); + break; + case SUBMESH_COMPUTED: // nothing to do + break; + case SUBMESH_RESTORED: + // check if a mesh is already computed that may + // happen after retrieval from a file + ComputeStateEngine( CHECK_COMPUTE_STATE ); + ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE ); + break; + case MESH_ENTITY_REMOVED: + break; + case CHECK_COMPUTE_STATE: + if ( IsMeshComputed() ) + _computeState = COMPUTE_OK; + break; + default: + ASSERT(0); break; + } + break; - // ---------------------------------------------------------------------- + // ---------------------------------------------------------------------- - case COMPUTE_OK: - switch (event) - { - case MODIF_HYP: - CleanDependants(); // recursive recall with event CLEANDEP - break; - case MODIF_ALGO_STATE: - CleanDependants(); // recursive recall with event CLEANDEP - break; - case COMPUTE: // nothing to do - break; - case CLEAN: - CleanDependants(); // recursive recall with event CLEANDEP - break; - case CLEANDEP: - RemoveSubMeshElementsAndNodes(); - _computeState = NOT_READY; - algo = gen->GetAlgo((*_father), _subShape); - if (algo) - { - ret = algo->CheckHypothesis((*_father),_subShape); - if (ret) _computeState = READY_TO_COMPUTE; - } - break; - case SUBMESH_COMPUTED: // nothing to do - break; - default: - ASSERT(0); - break; - } + case COMPUTE_OK: + switch (event) + { + case MODIF_HYP: + CleanDependants(); // recursive recall with event CLEANDEP + algo = gen->GetAlgo((*_father), _subShape); + if (algo && !algo->NeedDescretBoundary()) + CleanDependsOn(); // remove sub-mesh with event CLEANDEP + break; + case MODIF_ALGO_STATE: + CleanDependants(); // recursive recall with event CLEANDEP + algo = gen->GetAlgo((*_father), _subShape); + if (algo && !algo->NeedDescretBoundary()) + CleanDependsOn(); // remove sub-mesh with event CLEANDEP + break; + case COMPUTE: // nothing to do + break; + case CLEAN: + RemoveSubMeshElementsAndNodes(); + _computeState = NOT_READY; + algo = gen->GetAlgo((*_father), _subShape); + if (algo) + { + ret = algo->CheckHypothesis((*_father), _subShape, hyp_status); + if (ret) + _computeState = READY_TO_COMPUTE; + } + break; + case CLEANDEP: + CleanDependants(); // recursive recall with event CLEANDEP + break; + case SUBMESH_COMPUTED: // nothing to do + break; + case SUBMESH_RESTORED: + ComputeStateEngine( CHECK_COMPUTE_STATE ); + ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE ); + break; + case MESH_ENTITY_REMOVED: + UpdateDependantsState( CHECK_COMPUTE_STATE ); + ComputeStateEngine( CHECK_COMPUTE_STATE ); + ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE ); break; + case CHECK_COMPUTE_STATE: + if ( !IsMeshComputed() ) + if (_algoState == HYP_OK) + _computeState = READY_TO_COMPUTE; + else + _computeState = NOT_READY; + break; + default: + ASSERT(0); + break; + } + break; - // ---------------------------------------------------------------------- + // ---------------------------------------------------------------------- - case FAILED_TO_COMPUTE: - switch (event) - { - case MODIF_HYP: - if (_algoState == HYP_OK) - _computeState = READY_TO_COMPUTE; - else _computeState = NOT_READY; - break; - case MODIF_ALGO_STATE: - if (_algoState == HYP_OK) - _computeState = READY_TO_COMPUTE; - else _computeState = NOT_READY; - break; - case COMPUTE: // nothing to do - break; - case CLEAN: - break; - case CLEANDEP: - RemoveSubMeshElementsAndNodes(); - if (_algoState == HYP_OK) - _computeState = READY_TO_COMPUTE; - else _computeState = NOT_READY; - break; - case SUBMESH_COMPUTED: // allow retry compute - if (_algoState == HYP_OK) - _computeState = READY_TO_COMPUTE; - else _computeState = NOT_READY; - break; - default: - ASSERT(0); - break; - } + case FAILED_TO_COMPUTE: + switch (event) + { + case MODIF_HYP: + if (_algoState == HYP_OK) + _computeState = READY_TO_COMPUTE; + else + _computeState = NOT_READY; + break; + case MODIF_ALGO_STATE: + if (_algoState == HYP_OK) + _computeState = READY_TO_COMPUTE; + else + _computeState = NOT_READY; + break; + case COMPUTE: // nothing to do + break; + case CLEAN: + RemoveSubMeshElementsAndNodes(); + if (_algoState == HYP_OK) + _computeState = READY_TO_COMPUTE; + else + _computeState = NOT_READY; + break; + case CLEANDEP: + CleanDependants(); + break; + case SUBMESH_COMPUTED: // allow retry compute + if (_algoState == HYP_OK) + _computeState = READY_TO_COMPUTE; + else + _computeState = NOT_READY; + break; + case SUBMESH_RESTORED: + ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE ); + break; + case MESH_ENTITY_REMOVED: + break; + case CHECK_COMPUTE_STATE: + if ( IsMeshComputed() ) + _computeState = COMPUTE_OK; + else + if (_algoState == HYP_OK) + _computeState = READY_TO_COMPUTE; + else + _computeState = NOT_READY; break; - - // ---------------------------------------------------------------------- default: ASSERT(0); break; } + break; + + // ---------------------------------------------------------------------- + default: + ASSERT(0); + break; + } //SCRUTE(_computeState); return ret; } -//============================================================================= -/*! - * - */ -//============================================================================= +//======================================================================= +//function : ApplyToCollection +//purpose : Apply theAlgo to all subshapes in theCollection +//======================================================================= -void SMESH_subMesh::UpdateDependantsState() +bool SMESH_subMesh::ApplyToCollection (SMESH_Algo* theAlgo, + const TopoDS_Shape& theCollection) { - //MESSAGE("SMESH_subMesh::UpdateDependantsState"); + MESSAGE("SMESH_subMesh::ApplyToCollection"); + ASSERT ( !theAlgo->NeedDescretBoundary() ); + + bool ret = false; + - const map& dependants = Dependants(); - map::const_iterator its; - for (its = dependants.begin(); its != dependants.end(); its++) + ret = theAlgo->Compute( *_father, theCollection ); + + // set _computeState of subshapes + TopExp_Explorer anExplorer( theCollection, _subShape.ShapeType() ); + for ( ; anExplorer.More(); anExplorer.Next() ) + { + const TopoDS_Shape& aSubShape = anExplorer.Current(); + SMESH_subMesh* subMesh = _father->GetSubMeshContaining( aSubShape ); + if ( subMesh ) { - SMESH_subMesh* sm = (*its).second; - //SCRUTE((*its).first); - sm->ComputeStateEngine(SUBMESH_COMPUTED); + if (ret) + { + subMesh->_computeState = COMPUTE_OK; + subMesh->UpdateDependantsState( SUBMESH_COMPUTED ); + subMesh->UpdateSubMeshState( COMPUTE_OK ); + } + else + { + subMesh->_computeState = FAILED_TO_COMPUTE; + } } + } + return ret; +} + + +//======================================================================= +//function : UpdateSubMeshState +//purpose : +//======================================================================= + +void SMESH_subMesh::UpdateSubMeshState(const compute_state theState) +{ + const map& smMap = DependsOn(); + map::const_iterator itsub; + for (itsub = smMap.begin(); itsub != smMap.end(); itsub++) + { + SMESH_subMesh* sm = (*itsub).second; + sm->_computeState = theState; + } +} + +//======================================================================= +//function : ComputeSubMeshStateEngine +//purpose : +//======================================================================= + +void SMESH_subMesh::ComputeSubMeshStateEngine(int event) +{ + const map& smMap = DependsOn(); + map::const_iterator itsub; + for (itsub = smMap.begin(); itsub != smMap.end(); itsub++) + { + SMESH_subMesh* sm = (*itsub).second; + sm->ComputeStateEngine(event); + } +} + +//======================================================================= +//function : UpdateDependantsState +//purpose : +//======================================================================= + +void SMESH_subMesh::UpdateDependantsState(const compute_event theEvent) +{ + //MESSAGE("SMESH_subMesh::UpdateDependantsState"); + TopTools_ListIteratorOfListOfShape it( _father->GetAncestors( _subShape )); + for (; it.More(); it.Next()) + { + const TopoDS_Shape& ancestor = it.Value(); + SMESH_subMesh *aSubMesh = + _father->GetSubMeshContaining(ancestor); + if (aSubMesh) + aSubMesh->ComputeStateEngine( theEvent ); + } } //============================================================================= /*! - * + * */ //============================================================================= void SMESH_subMesh::CleanDependants() { - MESSAGE("SMESH_subMesh::CleanDependants"); - // **** parcourir les ancetres dans l'ordre de dépendance - - const map& dependants = Dependants(); - map::const_iterator its; - for (its = dependants.begin(); its != dependants.end(); its++) - { - SMESH_subMesh* sm = (*its).second; - SCRUTE((*its).first); - sm->ComputeStateEngine(CLEANDEP); - } - ComputeStateEngine(CLEANDEP); + //MESSAGE("SMESH_subMesh::CleanDependants: shape type " << _subShape.ShapeType() ); + + TopTools_ListIteratorOfListOfShape it( _father->GetAncestors( _subShape )); + for (; it.More(); it.Next()) + { + const TopoDS_Shape& ancestor = it.Value(); + //MESSAGE("ancestor shape type " << ancestor.ShapeType() ); + SMESH_subMesh *aSubMesh = _father->GetSubMeshContaining(ancestor); + if (aSubMesh) + aSubMesh->ComputeStateEngine(CLEANDEP); + } + ComputeStateEngine(CLEAN); } + + //============================================================================= /*! - * + * */ //============================================================================= -void SMESH_subMesh::RemoveSubMeshElementsAndNodes() +static void removeSubMesh( SMESHDS_Mesh * meshDS, const TopoDS_Shape& subShape) { - MESSAGE("SMESH_subMesh::RemoveSubMeshElementsAndNodes"); - SCRUTE(_subShape.ShapeType()); - SCRUTE(_Id); + SMESHDS_SubMesh * subMeshDS = meshDS->MeshElements(subShape); + if (subMeshDS!=NULL) + { + SMDS_ElemIteratorPtr ite=subMeshDS->GetElements(); + while(ite->more()) + { + const SMDS_MeshElement * elt = ite->next(); + //MESSAGE( " RM elt: "<GetID()<<" ( "<NbNodes()<<" )" ); + meshDS->RemoveElement(elt); + } - _subMeshDS = _meshDS->MeshElements(_subShape); - if (!_subMeshDS.IsNull()) + SMDS_NodeIteratorPtr itn=subMeshDS->GetNodes(); + while(itn->more()) { - const TColStd_ListOfInteger& indElt - = _subMeshDS->GetIDElements(); - TColStd_ListIteratorOfListOfInteger ite(indElt); - for (; ite.More(); ite.Next()) - { - int eltId = ite.Value(); - SCRUTE(eltId); - Handle (SMDS_MeshElement) elt = _meshDS->FindElement(eltId); - _subMeshDS->RemoveElement(elt); - _meshDS->RemoveElement(eltId); - } - - const TColStd_ListOfInteger& indNodes - = _subMeshDS->GetIDNodes(); - TColStd_ListIteratorOfListOfInteger itn(indNodes); - for (; itn.More(); itn.Next()) - { - int nodeId = itn.Value(); - SCRUTE(nodeId); - Handle (SMDS_MeshElement) elt = _meshDS->FindNode(nodeId); - Handle (SMDS_MeshNode) node = _meshDS->GetNode(1, elt); - _subMeshDS->RemoveNode(node); - _meshDS->RemoveNode(nodeId); - } + const SMDS_MeshNode * node = itn->next(); + //MESSAGE( " RM node: "<GetID()); + meshDS->RemoveNode(node); } + } } //============================================================================= /*! - * + * */ //============================================================================= -const map& SMESH_subMesh::Dependants() +void SMESH_subMesh::RemoveSubMeshElementsAndNodes() { - if (_dependantsFound) return _mapDependants; + SCRUTE(_subShape.ShapeType()); - //MESSAGE("SMESH_subMesh::Dependants"); + removeSubMesh( _meshDS, _subShape ); - int shapeType = _subShape.ShapeType(); - //SCRUTE(shapeType); - TopTools_IndexedDataMapOfShapeListOfShape M; - TopoDS_Shape mainShape = _meshDS->ShapeToMesh(); + // algo may bind a submesh not to _subShape, eg 3D algo + // sets nodes on SHELL while _subShape may be SOLID - switch (shapeType) + int dim = SMESH_Gen::GetShapeDim( _subShape ); + int type = _subShape.ShapeType() + 1; + for ( ; type <= TopAbs_EDGE; type++) + if ( dim == SMESH_Gen::GetShapeDim( (TopAbs_ShapeEnum) type )) { - case TopAbs_VERTEX: - break; - case TopAbs_EDGE: - case TopAbs_WIRE: - TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_WIRE, M); - TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_FACE, M); - TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_SHELL, M); - TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_SOLID, M); - TopExp::MapShapesAndAncestors(mainShape, TopAbs_EDGE, TopAbs_COMPSOLID, M); - ExtractDependants(M, TopAbs_EDGE); - break; - case TopAbs_FACE: - case TopAbs_SHELL: - TopExp::MapShapesAndAncestors(mainShape, TopAbs_FACE, TopAbs_SHELL, M); - TopExp::MapShapesAndAncestors(mainShape, TopAbs_FACE, TopAbs_SOLID, M); - TopExp::MapShapesAndAncestors(mainShape, TopAbs_FACE, TopAbs_COMPSOLID, M); - ExtractDependants(M, TopAbs_FACE); - break; - case TopAbs_SOLID: - case TopAbs_COMPSOLID: - TopExp::MapShapesAndAncestors(mainShape, TopAbs_SOLID, TopAbs_COMPSOLID, M); - ExtractDependants(M, TopAbs_SOLID); - break; - case TopAbs_COMPOUND: - break; - } - - _dependantsFound = true; - return _mapDependants; + TopExp_Explorer exp( _subShape, (TopAbs_ShapeEnum) type ); + for ( ; exp.More(); exp.Next() ) + removeSubMesh( _meshDS, exp.Current() ); + } + else + break; } -//============================================================================= -/*! - * - */ -//============================================================================= +//======================================================================= +//function : IsMeshComputed +//purpose : check if _subMeshDS contains mesh elements +//======================================================================= -void SMESH_subMesh::ExtractDependants(const TopTools_IndexedDataMapOfShapeListOfShape& M, - const TopAbs_ShapeEnum etype) +bool SMESH_subMesh::IsMeshComputed() const { - //MESSAGE("SMESH_subMesh::ExtractDependants"); - - TopoDS_Shape mainShape = _meshDS->ShapeToMesh(); - int lg = M.Extent(); - //SCRUTE(lg); + // algo may bind a submesh not to _subShape, eg 3D algo + // sets nodes on SHELL while _subShape may be SOLID - int shapeType = _subShape.ShapeType(); - switch (shapeType) + int dim = SMESH_Gen::GetShapeDim( _subShape ); + int type = _subShape.ShapeType(); + for ( ; type <= TopAbs_VERTEX; type++) { + if ( dim == SMESH_Gen::GetShapeDim( (TopAbs_ShapeEnum) type )) { - case TopAbs_VERTEX: - break; - case TopAbs_EDGE: - case TopAbs_FACE: - case TopAbs_SOLID: + TopExp_Explorer exp( _subShape, (TopAbs_ShapeEnum) type ); + for ( ; exp.More(); exp.Next() ) { - const TopTools_ListOfShape& ancestors = M.FindFromKey(_subShape); - TopTools_ListIteratorOfListOfShape it(ancestors); - for ( ; it.More();it.Next()) - { - TopoDS_Shape ancestor = it.Value(); - SMESH_subMesh* aSubMesh = _father->GetSubMeshContaining(ancestor); - // if (! aSubMesh) aSubMesh = _father->GetSubMesh(ancestor); - if (aSubMesh) - { - int type = aSubMesh->_subShape.ShapeType(); - int cle = aSubMesh->GetId(); - cle += 10000000 * type; // sort map by ordType then index - if (_mapDependants.find(cle) == _mapDependants.end()) - { - _mapDependants[cle] = aSubMesh; - //SCRUTE(cle); - } - } - } + SMESHDS_SubMesh * subMeshDS = _meshDS->MeshElements( exp.Current() ); + if ( subMeshDS != NULL && + (subMeshDS->GetElements()->more() || subMeshDS->GetNodes()->more())) { + return true; + } } + } + else break; - case TopAbs_WIRE: - case TopAbs_SHELL: - case TopAbs_COMPSOLID: - for (TopExp_Explorer expE(_subShape, etype); expE.More(); expE.Next()) - { - TopoDS_Shape aShape = expE.Current(); - const TopTools_ListOfShape& ancestors = M.FindFromKey( aShape); - TopTools_ListIteratorOfListOfShape it(ancestors); - for ( ; it.More();it.Next()) - { - MESSAGE("---"); - TopoDS_Shape ancestor = it.Value(); - SMESH_subMesh* aSubMesh = _father->GetSubMeshContaining(ancestor); - if (! aSubMesh) aSubMesh = _father->GetSubMesh(ancestor); - int type = aSubMesh->_subShape.ShapeType(); - int cle = aSubMesh->GetId(); - cle += 10000000 * type; // sort map by ordType then index - if (_mapDependants.find(cle) == _mapDependants.end()) - { - _mapDependants[cle] = aSubMesh; - SCRUTE(cle); - } - } - } - break; - case TopAbs_COMPOUND: - break; - } + } + + return false; } + +//======================================================================= +//function : GetCollection +//purpose : return a shape containing all sub-shapes of the MainShape that can be +// meshed at once along with _subShape +//======================================================================= + +TopoDS_Shape SMESH_subMesh::GetCollection(SMESH_Gen * theGen, SMESH_Algo* theAlgo) +{ + MESSAGE("SMESH_subMesh::GetCollection"); + ASSERT (!theAlgo->NeedDescretBoundary()); + + TopoDS_Shape mainShape = _father->GetMeshDS()->ShapeToMesh(); + + if ( mainShape.IsSame( _subShape )) + return _subShape; + + list aUsedHyp = + theAlgo->GetUsedHypothesis( *_father, _subShape ); // copy + + // put in a compound all shapes with the same hypothesis assigned + // and a good ComputState + + TopoDS_Compound aCompound; + BRep_Builder aBuilder; + aBuilder.MakeCompound( aCompound ); + + TopExp_Explorer anExplorer( mainShape, _subShape.ShapeType() ); + for ( ; anExplorer.More(); anExplorer.Next() ) + { + const TopoDS_Shape& S = anExplorer.Current(); + SMESH_subMesh* subMesh = _father->GetSubMesh( S ); + SMESH_Algo* anAlgo = theGen->GetAlgo( *_father, S ); + + if (subMesh->GetComputeState() == READY_TO_COMPUTE && + anAlgo == theAlgo && + anAlgo->GetUsedHypothesis( *_father, S ) == aUsedHyp) + { + aBuilder.Add( aCompound, S ); + } + } + + return aCompound; +} + +//======================================================================= +//function : GetSimilarAttached +//purpose : return nb of hypotheses attached to theShape. +// If theHyp is provided, similar but not same hypotheses +// are countered; else only applicable ones having theHypType +// are countered +//======================================================================= + +const SMESH_Hypothesis* SMESH_subMesh::GetSimilarAttached(const TopoDS_Shape& theShape, + const SMESH_Hypothesis * theHyp, + const int theHypType) +{ + const list& aHypList = + _father->GetHypothesisList( theShape ); + list::const_iterator it = aHypList.begin(); + for ( ; it != aHypList.end(); it++ ) + { + const SMESH_Hypothesis* hyp = static_cast< const SMESH_Hypothesis *>( *it ); + if ( theHyp ) + { + // find similar + if (hyp != theHyp && + hyp->GetType() == theHyp->GetType() && + hyp->GetDim() == theHyp->GetDim()) + return hyp; + } + else + { + if ( hyp->GetType() == theHypType && IsApplicableHypotesis( hyp )) + return hyp; + } + } + + return 0; +} + +//======================================================================= +//function : CheckConcurentHypothesis +//purpose : check if there are several applicable hypothesis attached to +// ansestors +//======================================================================= + +SMESH_Hypothesis::Hypothesis_Status + SMESH_subMesh::CheckConcurentHypothesis (const int theHypType) +{ + MESSAGE ("SMESH_subMesh::CheckConcurentHypothesis"); + + // is there local hypothesis on me? + if ( GetSimilarAttached( _subShape, 0, theHypType ) ) + return SMESH_Hypothesis::HYP_OK; + + + TopoDS_Shape aPrevWithHyp; + const SMESH_Hypothesis* aPrevHyp = 0; + TopTools_ListIteratorOfListOfShape it( _father->GetAncestors( _subShape )); + for (; it.More(); it.Next()) + { + const TopoDS_Shape& ancestor = it.Value(); + const SMESH_Hypothesis* hyp = GetSimilarAttached( ancestor, 0, theHypType ); + if ( hyp ) + { + if ( aPrevWithHyp.IsNull() || aPrevWithHyp.IsSame( ancestor )) + { + aPrevWithHyp = ancestor; + aPrevHyp = hyp; + } + else if ( aPrevWithHyp.ShapeType() == ancestor.ShapeType() && aPrevHyp != hyp ) + return SMESH_Hypothesis::HYP_CONCURENT; + else + return SMESH_Hypothesis::HYP_OK; + } + } + return SMESH_Hypothesis::HYP_OK; +}