#include "SMESH_Mesh.hxx"
#include "SMESH_Hypothesis.hxx"
#include "SMESH_Algo.hxx"
+#include "SMESH_HypoFilter.hxx"
+
#include "utilities.h"
#include "OpUtil.hxx"
+#include <BRep_Builder.hxx>
+
#include <TopExp.hxx>
-#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopoDS_Compound.hxx>
+#include <TopTools_MapOfShape.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <TColStd_ListIteratorOfListOfInteger.hxx>
-#include <TopoDS_Compound.hxx>
-#include <BRep_Builder.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#ifdef _DEBUG_
#include <gp_Pnt.hxx>
#include <BRep_Tool.hxx>
#include <TopoDS.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
#endif
//=============================================================================
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);
+ SMESHDS_SubMesh * ds = sm->GetSubMeshDS();
+ // PAL10974.
+ // There are some tricks with compute states, e.g. Penta_3D leaves
+ // one face with READY_TO_COMPUTE state in order to be able to
+ // recompute 3D when a locale triangle hypo changes (see PAL7428).
+ // So we check if mesh is really present
+ //bool computeOk = (sm->GetComputeState() == COMPUTE_OK);
+ bool computeOk = ( ds && ds->GetNodes()->more() );
if (!computeOk)
{
+ const TopoDS_Shape & ss = sm->GetSubShape();
+ int type = ss.ShapeType();
+
subMeshesComputed = false;
switch (type)
//=======================================================================
//function : IsApplicableHypotesis
-//purpose : return true if theHypothesis can be used to mesh me:
-// its shape type is checked
+//purpose :
//=======================================================================
-bool SMESH_subMesh::IsApplicableHypotesis(const SMESH_Hypothesis* theHypothesis) const
+bool SMESH_subMesh::IsApplicableHypotesis(const SMESH_Hypothesis* theHypothesis,
+ const TopAbs_ShapeEnum theShapeType)
{
if ( theHypothesis->GetType() > SMESHDS_Hypothesis::PARAM_ALGO)
// algorithm
- return ( theHypothesis->GetShapeType() & (1<< _subShape.ShapeType()));
+ return ( theHypothesis->GetShapeType() & (1<< theShapeType));
// 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 );
- }
+ int aShapeDim = 100;
+ switch ( theShapeType ) {
+ case TopAbs_EDGE: aShapeDim = 1; break;
+ case TopAbs_FACE: aShapeDim = 2; break;
+ case TopAbs_SHELL:aShapeDim = 3; break;
+ case TopAbs_SOLID:aShapeDim = 3; break;
// case TopAbs_VERTEX:
// case TopAbs_WIRE:
// case TopAbs_COMPSOLID:
// case TopAbs_COMPOUND:
- default:;
+ default: return false;
}
- return false;
+ return ( theHypothesis->GetDim() == aShapeDim );
}
//=============================================================================
//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
+
+ SMESH_Hypothesis::Hypothesis_Status aux_ret, ret = SMESH_Hypothesis::HYP_OK;
+
int dim = SMESH_Gen::GetShapeDim(_subShape);
if (dim < 1)
if ( !_meshDS->AddHypothesis(_subShape, anHyp))
return SMESH_Hypothesis::HYP_ALREADY_EXIST;
+
+ // Serve Propagation of 1D hypothesis
+ if (event == ADD_HYP) {
+ bool isPropagationOk = true;
+ string hypName = anHyp->GetName();
+
+ if (hypName == "Propagation") {
+ TopExp_Explorer exp (_subShape, TopAbs_EDGE);
+ TopTools_MapOfShape aMap;
+ for (; exp.More(); exp.Next()) {
+ if (aMap.Add(exp.Current())) {
+ if (!_father->BuildPropagationChain(exp.Current())) {
+ isPropagationOk = false;
+ }
+ }
+ }
+ }
+ else if (anHyp->GetDim() == 1) { // Only 1D hypothesis can be propagated
+ TopExp_Explorer exp (_subShape, TopAbs_EDGE);
+ TopTools_MapOfShape aMap;
+ for (; exp.More(); exp.Next()) {
+ if (aMap.Add(exp.Current())) {
+ TopoDS_Shape aMainEdge;
+ if (_father->IsPropagatedHypothesis(exp.Current(), aMainEdge)) {
+ isPropagationOk = _father->RebuildPropagationChains();
+ } else if (_father->IsPropagationHypothesis(exp.Current())) {
+ isPropagationOk = _father->BuildPropagationChain(exp.Current());
+ } else {
+ }
+ }
+ }
+ } else {
+ }
+
+ if (!isPropagationOk && ret < SMESH_Hypothesis::HYP_CONCURENT) {
+ ret = SMESH_Hypothesis::HYP_CONCURENT;
+ }
+ } // Serve Propagation of 1D hypothesis
}
// --------------------------
{
if (!_meshDS->RemoveHypothesis(_subShape, anHyp))
return SMESH_Hypothesis::HYP_OK; // nothing changes
+
+ // Serve Propagation of 1D hypothesis
+ if (event == REMOVE_HYP)
+ {
+ bool isPropagationOk = true;
+ SMESH_HypoFilter propagFilter( SMESH_HypoFilter::HasName( "Propagation" ));
+ if ( propagFilter.IsOk( anHyp, _subShape ))
+ {
+ TopExp_Explorer exp (_subShape, TopAbs_EDGE);
+ TopTools_MapOfShape aMap;
+ for (; exp.More(); exp.Next()) {
+ if (aMap.Add(exp.Current()) &&
+ !_father->GetHypothesis( exp.Current(), propagFilter, true )) {
+ // no more Propagation on the current edge
+ if (!_father->RemovePropagationChain(exp.Current())) {
+ return SMESH_Hypothesis::HYP_UNKNOWN_FATAL;
+ }
+ }
+ }
+ // rebuild propagation chains, because removing one
+ // chain can resolve concurention, existing before
+ isPropagationOk = _father->RebuildPropagationChains();
+ }
+ else if (anHyp->GetDim() == 1) // Only 1D hypothesis can be propagated
+ {
+ isPropagationOk = _father->RebuildPropagationChains();
+ }
+
+ if (!isPropagationOk && ret < SMESH_Hypothesis::HYP_CONCURENT) {
+ ret = SMESH_Hypothesis::HYP_CONCURENT;
+ }
+ } // Serve Propagation of 1D hypothesis
}
// ------------------
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 ))
+ ret = SMESH_Hypothesis::HYP_INCOMPATIBLE;
+
+ if (SMESH_Hypothesis::IsStatusFatal( ret ))
{
+ MESSAGE("do not add extra hypothesis");
_meshDS->RemoveHypothesis(_subShape, anHyp);
- ret = SMESH_Hypothesis::HYP_INCOMPATIBLE;
}
else
{
}
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);
+ if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) {
+ // check if algo changes
+ SMESH_HypoFilter f;
+ f.Init( SMESH_HypoFilter::IsAlgo() );
+ f.And( SMESH_HypoFilter::IsApplicableTo( _subShape ));
+ f.AndNot( SMESH_HypoFilter::Is( algo ));
+ const SMESH_Hypothesis * prevAlgo = _father->GetHypothesis( _subShape, f, true );
+ if (prevAlgo &&
+ string(algo->GetName()) != string(prevAlgo->GetName()) )
+ modifiedHyp = true;
+ }
else
SetAlgoState(MISSING_HYP);
- modifiedHyp = true;
break;
}
case REMOVE_HYP: {
}
else
{
- if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
- SetAlgoState(HYP_OK);
+ if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) {
+ // check if algo remains
+ if ( anHyp != algo && strcmp( anHyp->GetName(), algo->GetName()) )
+ modifiedHyp = true;
+ }
else
SetAlgoState(MISSING_HYP);
- // check if same algo remains
- if ( anHyp != algo && strcmp( anHyp->GetName(), algo->GetName()) )
- modifiedHyp = true;
}
break;
}
ASSERT(algo);
if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
{
- SetAlgoState(HYP_OK);
if (_father->IsUsedHypothesis( anHyp, _subShape )) // new Hyp
modifiedHyp = true;
}
SetAlgoState(MISSING_HYP);
break;
}
- case ADD_FATHER_ALGO: { // a new algo on father
+ case ADD_FATHER_ALGO: {
SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
- if ( algo == anHyp ) {
- if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
- SetAlgoState(HYP_OK);
+ if ( algo == anHyp ) { // a new algo on father
+ if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) {
+ // check if algo changes
+ SMESH_HypoFilter f;
+ f.Init( SMESH_HypoFilter::IsAlgo() );
+ f.And( SMESH_HypoFilter::IsApplicableTo( _subShape ));
+ f.AndNot( SMESH_HypoFilter::Is( algo ));
+ const SMESH_Hypothesis* prevAlgo = _father->GetHypothesis( _subShape, f, true );
+ if (prevAlgo &&
+ string(algo->GetName()) != string(prevAlgo->GetName()) )
+ modifiedHyp = true;
+ }
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);
+ if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) {
+ // is there the same local hyp or maybe a new father algo applied?
+ if ( !GetSimilarAttached( _subShape, anHyp ) )
+ modifiedHyp = true;
+ }
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: {
}
else
{
- if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
- SetAlgoState(HYP_OK);
+ if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) {
+ // check if algo changes
+ if ( string(algo->GetName()) != string( anHyp->GetName()) )
+ modifiedHyp = true;
+ }
else
SetAlgoState(MISSING_HYP);
- // is there the same local algo or maybe a new father algo applied?
- if ( !GetSimilarAttached( _subShape, anHyp ))
- modifiedHyp = true;
}
break;
}
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);
+ ComputeStateEngine(MODIF_ALGO_STATE);
return ret;
}
SMESH_Gen* gen =_father->GetGen();
// only local algo is to be checked
- if ( gen->IsGlobalAlgo( theAlgo, *_father ))
+ if ( gen->IsGlobalHypothesis( theAlgo, *_father ))
return true;
// check algo attached to adjacent shapes
if (algo &&
//algo != theAlgo &&
!algo->NeedDescretBoundary() /*&&
- !gen->IsGlobalAlgo( algo, *_father )*/)
+ !gen->IsGlobalHypothesis( algo, *_father )*/)
return false; // NOT CONFORM MESH WILL BE PRODUCED
}
}
*/
//=============================================================================
+static void removeSubMesh( SMESHDS_Mesh * meshDS, const TopoDS_Shape& subShape)
+{
+ 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: "<<elt->GetID()<<" ( "<<elt->NbNodes()<<" )" );
+ meshDS->RemoveElement(elt);
+ }
+
+ SMDS_NodeIteratorPtr itn=subMeshDS->GetNodes();
+ while(itn->more())
+ {
+ const SMDS_MeshNode * node = itn->next();
+ //MESSAGE( " RM node: "<<node->GetID());
+ meshDS->RemoveNode(node);
+ }
+ }
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
bool SMESH_subMesh::ComputeStateEngine(int event)
{
//MESSAGE("SMESH_subMesh::ComputeStateEngine");
_computeState = FAILED_TO_COMPUTE;
break;
}
- RemoveSubMeshElementsAndNodes();
// compute
+ removeSubMesh( _meshDS, _subShape );
if (!algo->NeedDescretBoundary() && !algo->OnlyUnaryInput())
ret = ApplyToCollection( algo, GetCollection( gen, algo ) );
else
#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() )));
+ TopTools_IndexedMapOfShape vMap;
+ TopExp::MapShapes( _subShape, TopAbs_VERTEX, vMap );
+ for ( int iv = 1; iv <= vMap.Extent(); ++iv ) {
+ gp_Pnt P( BRep_Tool::Pnt( TopoDS::Vertex( vMap( iv ) )));
cout << P.X() << " " << P.Y() << " " << P.Z() << " " << endl;
}
#endif
void SMESH_subMesh::CleanDependants()
{
- //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);
-}
-
-
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-static void removeSubMesh( SMESHDS_Mesh * meshDS, const TopoDS_Shape& subShape)
-{
- 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: "<<elt->GetID()<<" ( "<<elt->NbNodes()<<" )" );
- meshDS->RemoveElement(elt);
- }
-
- SMDS_NodeIteratorPtr itn=subMeshDS->GetNodes();
- while(itn->more())
- {
- const SMDS_MeshNode * node = itn->next();
- //MESSAGE( " RM node: "<<node->GetID());
- meshDS->RemoveNode(node);
+ // PAL8021. do not go upper than SOLID, else ComputeStateEngine(CLEANDEP)
+ // will erase mesh on other shapes in a compound
+ if ( ancestor.ShapeType() >= TopAbs_SOLID ) {
+ SMESH_subMesh *aSubMesh = _father->GetSubMeshContaining(ancestor);
+ if (aSubMesh)
+ aSubMesh->ComputeStateEngine(CLEANDEP);
}
}
+ ComputeStateEngine(CLEAN);
}
//=============================================================================
void SMESH_subMesh::RemoveSubMeshElementsAndNodes()
{
- SCRUTE(_subShape.ShapeType());
+ //SCRUTE(_subShape.ShapeType());
removeSubMesh( _meshDS, _subShape );
const SMESH_Hypothesis * theHyp,
const int theHypType)
{
- const list<const SMESHDS_Hypothesis*>& aHypList =
- _father->GetHypothesisList( theShape );
- list<const SMESHDS_Hypothesis*>::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;
- }
+ SMESH_HypoFilter filter;
+ filter.Init( SMESH_HypoFilter::HasType( theHyp ? theHyp->GetType() : theHypType ));
+ if ( theHyp ) {
+ filter.And( SMESH_HypoFilter::HasDim( theHyp->GetDim() ));
+ filter.AndNot( SMESH_HypoFilter::Is( theHyp ));
}
+ else
+ filter.And( SMESH_HypoFilter::IsApplicableTo( theShape ));
- return 0;
+ return _father->GetHypothesis( theShape, filter, false );
}
//=======================================================================