-// SMESH SMESH : implementaion of SMESH idl descriptions
+// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
//
-// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// Copyright (C) 2003-2007 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
-//
-//
+
+// SMESH SMESH : implementaion of SMESH idl descriptions
// File : SMESH_subMesh.cxx
// Author : Paul RASCLE, EDF
// Module : SMESH
-// $Header$
-
+//
#include "SMESH_subMesh.hxx"
#include "SMESH_Algo.hxx"
#include "SMESH_subMeshEventListener.hxx"
#include "SMESH_Comment.hxx"
#include "SMDS_SetIterator.hxx"
+#include "SMDSAbs_ElementType.hxx"
#include "utilities.h"
#include "OpUtil.hxx"
+#include "Basics_Utils.hxx"
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
#include <Standard_OutOfMemory.hxx>
#include <Standard_ErrorHandler.hxx>
+#include <numeric>
+
using namespace std;
//=============================================================================
SMESHDS_Mesh * meshDS,
const TopoDS_Shape & aSubShape)
{
- _subShape = aSubShape;
- _subMeshDS = meshDS->MeshElements(_subShape); // may be null ...
- _father = father;
- _Id = Id;
- _dependenceAnalysed = _alwaysComputed = false;
-
- if (_subShape.ShapeType() == TopAbs_VERTEX)
- {
- _algoState = HYP_OK;
- _computeState = READY_TO_COMPUTE;
- }
- else
- {
+ _subShape = aSubShape;
+ _subMeshDS = meshDS->MeshElements(_subShape); // may be null ...
+ _father = father;
+ _Id = Id;
+ _dependenceAnalysed = _alwaysComputed = false;
+
+ if (_subShape.ShapeType() == TopAbs_VERTEX)
+ {
+ _algoState = HYP_OK;
+ _computeState = READY_TO_COMPUTE;
+ }
+ else
+ {
_algoState = NO_ALGO;
_computeState = NOT_READY;
- }
+ }
}
//=============================================================================
ComputeStateEngine( CHECK_COMPUTE_STATE );
}
+//=======================================================================
+/*!
+ * \brief Return true if no mesh entities is bound to the submesh
+ */
+//=======================================================================
+
+bool SMESH_subMesh::IsEmpty() const
+{
+ if (SMESHDS_SubMesh * subMeshDS = ((SMESH_subMesh*)this)->GetSubMeshDS())
+ return (!subMeshDS->NbElements() && !subMeshDS->NbNodes());
+ return true;
+}
+
//=======================================================================
//function : IsMeshComputed
//purpose : check if _subMeshDS contains mesh elements
break; // the rest subMeshes are all of less dimension
SMESHDS_SubMesh * ds = sm->GetSubMeshDS();
bool computeOk = (sm->GetComputeState() == COMPUTE_OK ||
- (ds && ( ds->NbNodes() || ds->NbElements() )));
+ (ds && ( dimToCheck ? ds->NbElements() : ds->NbNodes() )));
if (!computeOk)
{
int type = ss.ShapeType();
case TopAbs_COMPOUND:
{
//MESSAGE("compound");
- for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More();
- exp.Next())
+ for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More();exp.Next())
{
InsertDependence(exp.Current());
}
- for (TopExp_Explorer exp(_subShape, TopAbs_SHELL, TopAbs_SOLID); exp.More();
- exp.Next())
+ for (TopExp_Explorer exp(_subShape, TopAbs_SHELL, TopAbs_SOLID); exp.More(); exp.Next())
{
+ if ( BRep_Tool::IsClosed(exp.Current() ))
InsertDependence(exp.Current()); //only shell not in solid
+ else
+ for (TopExp_Explorer expF(exp.Current(), TopAbs_FACE); expF.More();expF.Next())
+ InsertDependence(expF.Current()); // issue 0020959: HEXA_3D fails on shell
+
}
- for (TopExp_Explorer exp(_subShape, TopAbs_FACE, TopAbs_SHELL); exp.More();
- exp.Next())
+ for (TopExp_Explorer exp(_subShape, TopAbs_FACE, TopAbs_SHELL); exp.More();exp.Next())
{
InsertDependence(exp.Current());
}
- for (TopExp_Explorer exp(_subShape, TopAbs_EDGE, TopAbs_FACE); exp.More();
- exp.Next())
+ for (TopExp_Explorer exp(_subShape, TopAbs_EDGE, TopAbs_FACE); exp.More();exp.Next())
{
InsertDependence(exp.Current());
}
}
case TopAbs_COMPSOLID:
{
- //MESSAGE("compsolid");
- for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More();
- exp.Next())
+ //MESSAGE("compsolid");
+ for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More(); exp.Next())
{
InsertDependence(exp.Current());
}
case TopAbs_SHELL:
{
//MESSAGE("shell");
- for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More();
- exp.Next())
+ for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More(); exp.Next())
{
InsertDependence(exp.Current());
}
case TopAbs_WIRE:
{
//MESSAGE("wire");
- for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More();
- exp.Next())
+ for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More(); exp.Next())
{
InsertDependence(exp.Current());
}
{
//MESSAGE("solid");
if(_father->HasShapeToMesh()) {
- for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More();
- exp.Next())
+ for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More();exp.Next())
{
InsertDependence(exp.Current());
}
case TopAbs_FACE:
{
//MESSAGE("face");
- for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More();
- exp.Next())
+ for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More();exp.Next())
{
InsertDependence(exp.Current());
}
case TopAbs_EDGE:
{
//MESSAGE("edge");
- for (TopExp_Explorer exp(_subShape, TopAbs_VERTEX); exp.More();
- exp.Next())
+ for (TopExp_Explorer exp(_subShape, TopAbs_VERTEX); exp.More(); exp.Next())
{
- InsertDependence(exp.Current());
- }
+ InsertDependence(exp.Current());
+ }
break;
}
case TopAbs_VERTEX:
const TopoDS_Shape & SMESH_subMesh::GetSubShape() const
{
- //MESSAGE("SMESH_subMesh::GetSubShape");
- return _subShape;
+ //MESSAGE("SMESH_subMesh::GetSubShape");
+ return _subShape;
}
bool SMESH_subMesh::CanAddHypothesis(const SMESH_Hypothesis* theHypothesis) const
{
int aHypDim = theHypothesis->GetDim();
- if(_father->HasShapeToMesh()) {
- int aShapeDim = SMESH_Gen::GetShapeDim(_subShape);
- if ( aHypDim <= aShapeDim )
- return true;
+ int aShapeDim = SMESH_Gen::GetShapeDim(_subShape);
+ if (aHypDim == 3 && aShapeDim == 3) {
+ // check case of open shell
+ //if (_subShape.ShapeType() == TopAbs_SHELL && !_subShape.Closed())
+ if (_subShape.ShapeType() == TopAbs_SHELL && !BRep_Tool::IsClosed(_subShape))
+ return false;
}
- else
- //Only 3D hypothesis may be assigned to the mesh w/o geometry
- return aHypDim == 3;
-// if ( aHypDim < aShapeDim )
-// return ( _father->IsMainShape( _subShape ));
+ if ( aHypDim <= aShapeDim )
+ return true;
return false;
}
int oldAlgoState = _algoState;
bool modifiedHyp = (event == MODIF_HYP); // if set to true, force event MODIF_ALGO_STATE
+ bool needFullClean = false;
bool isApplicableHyp = IsApplicableHypotesis( anHyp );
// check if a shape needed by algo is present
// -------------------------------------------
algo = static_cast< SMESH_Algo* >( anHyp );
- if(_father->GetShapeToMesh() != SMESH_Mesh::PseudoShape())
- if ( !_father->HasShapeToMesh() && algo->NeedShape() )
- return SMESH_Hypothesis::HYP_BAD_GEOMETRY;
+ if ( !_father->HasShapeToMesh() && algo->NeedShape() )
+ return SMESH_Hypothesis::HYP_NEED_SHAPE;
// ----------------------
// check mesh conformity
// ----------------------
if (isApplicableHyp && !_father->IsNotConformAllowed() && !IsConform( algo ))
return SMESH_Hypothesis::HYP_NOTCONFORM;
+
+ // check if all-dimensional algo is hidden by other local one
+ if ( event == ADD_ALGO ) {
+ SMESH_HypoFilter filter( SMESH_HypoFilter::HasType( algo->GetType() ));
+ filter.Or( SMESH_HypoFilter::HasType( algo->GetType()+1 ));
+ filter.Or( SMESH_HypoFilter::HasType( algo->GetType()+2 ));
+ if ( SMESH_Algo * curAlgo = (SMESH_Algo*) _father->GetHypothesis( _subShape, filter, true ))
+ needFullClean = ( !curAlgo->NeedDescretBoundary() );
+ }
}
// ----------------------------------
if ( ! CanAddHypothesis( anHyp )) // check dimension
return SMESH_Hypothesis::HYP_BAD_DIM;
- if(anHyp->GetDim() == 3 && !_father->HasShapeToMesh()
- && event == ADD_ALGO) {
- //Only NETGEN_3D and GHS3D_3D can be assigned to the Mesh w/o geometryy
- bool isNetgen3D = (strcmp( "NETGEN_3D", anHyp->GetName()) == 0);
- bool isGhs3d = (strcmp( "GHS3D_3D", anHyp->GetName()) == 0);
- if( !isNetgen3D && !isGhs3d)
- return SMESH_Hypothesis::HYP_BAD_DIM;
- }
-
-
-
if ( /*!anHyp->IsAuxiliary() &&*/ GetSimilarAttached( _subShape, anHyp ) )
return SMESH_Hypothesis::HYP_ALREADY_EXIST;
// clean all mesh in the tree of the current submesh;
// we must perform it now because later
// we will have no information about the type of the removed algo
- CleanDependants();
- ComputeStateEngine( CLEAN );
- CleanDependsOn();
- ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE );
+ needFullClean = true;
}
}
}
break;
}
case REMOVE_FATHER_ALGO: {
+ // IPAL21346. Edges not removed when Netgen 1d-2d is removed from a SOLID.
+ // CLEAN was not called at event REMOVE_ALGO because the algo is not applicable to SOLID.
+ algo = dynamic_cast<SMESH_Algo*> (anHyp);
+ if (!algo->NeedDescretBoundary())
+ needFullClean = true;
+
algo = gen->GetAlgo((*_father), _subShape);
if (algo == NULL) // no more applying algo on father
{
TopTools_ListIteratorOfListOfShape it( _father->GetAncestors( _subShape ));
for ( ; ( ret == SMESH_Hypothesis::HYP_OK && it.More()); it.Next() ) {
if ( SMESH_Algo* upperAlgo = gen->GetAlgo( *_father, it.Value() ))
- if ( !upperAlgo->NeedDescretBoundary() )
+ if ( !upperAlgo->NeedDescretBoundary() && !upperAlgo->SupportSubmeshes())
ret = SMESH_Hypothesis::HYP_HIDDEN_ALGO;
}
// is algo hiding?
- if ( ret == SMESH_Hypothesis::HYP_OK && !algo->NeedDescretBoundary() ) {
+ if ( ret == SMESH_Hypothesis::HYP_OK &&
+ !algo->NeedDescretBoundary() &&
+ !algo->SupportSubmeshes()) {
+ TopoDS_Shape algoAssignedTo, otherAssignedTo;
+ gen->GetAlgo( *_father, _subShape, &algoAssignedTo );
map<int, SMESH_subMesh*>::reverse_iterator i_sm = _mapDepend.rbegin();
for ( ; ( ret == SMESH_Hypothesis::HYP_OK && i_sm != _mapDepend.rend()) ; ++i_sm )
- if ( gen->GetAlgo( *_father, i_sm->second->_subShape ))
+ if ( gen->GetAlgo( *_father, i_sm->second->_subShape, &otherAssignedTo ) &&
+ SMESH_MesherHelper::IsSubShape( /*sub=*/otherAssignedTo, /*main=*/algoAssignedTo ))
ret = SMESH_Hypothesis::HYP_HIDING_ALGO;
}
}
}
}
+ if ( needFullClean ) {
+ // added or removed algo is all-dimensional
+ ComputeStateEngine( CLEAN );
+ CleanDependsOn();
+ ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE );
+ }
+
if (stateChange || modifiedHyp)
ComputeStateEngine(MODIF_ALGO_STATE);
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 < 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;
- }
+ if (isMain)
+ {
+ 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;
+ }
}
//================================================================================
while (itn->more()) {
const SMDS_MeshNode * node = itn->next();
//MESSAGE( " RM node: "<<node->GetID());
- if ( node->NbInverseNodes() == 0 )
+ if ( node->NbInverseElements() == 0 )
meshDS->RemoveFreeNode(node, subMeshDS);
else // for StdMeshers_CompositeSegment_1D: node in one submesh, edge in another
meshDS->RemoveNode(node);
_computeState = READY_TO_COMPUTE;
SMESHDS_SubMesh* smDS = GetSubMeshDS();
if ( smDS && smDS->NbNodes() ) {
- _computeState = COMPUTE_OK;
+ if ( event == CLEAN ) {
+ CleanDependants();
+ cleanSubMesh( this );
+ }
+ else
+ _computeState = COMPUTE_OK;
}
else if ( event == COMPUTE && !_alwaysComputed ) {
const TopoDS_Vertex & V = TopoDS::Vertex( _subShape );
if ( _algoState == HYP_OK )
_computeState = READY_TO_COMPUTE;
break;
- case COMPUTE: // nothing to do
+ case COMPUTE: // nothing to do
break;
case CLEAN:
CleanDependants();
RemoveSubMeshElementsAndNodes();
break;
- case SUBMESH_COMPUTED: // nothing to do
+ case SUBMESH_COMPUTED: // nothing to do
break;
case SUBMESH_RESTORED:
ComputeSubMeshStateEngine( SUBMESH_RESTORED );
SetAlgoState(MISSING_HYP);
break;
}
+ TopoDS_Shape shape = _subShape;
// check submeshes needed
if (_father->HasShapeToMesh() ) {
- bool subComputed = SubMeshesComputed();
+ bool subComputed = false;
+ if (!algo->OnlyUnaryInput())
+ shape = GetCollection( gen, algo, subComputed );
+ else
+ subComputed = SubMeshesComputed();
ret = ( algo->NeedDescretBoundary() ? subComputed :
+ algo->SupportSubmeshes() ? true :
( !subComputed || _father->IsNotConformAllowed() ));
if (!ret) {
_computeState = FAILED_TO_COMPUTE;
ret = false;
_computeState = FAILED_TO_COMPUTE;
_computeError = SMESH_ComputeError::New(COMPERR_OK,"",algo);
- TopoDS_Shape shape = _subShape;
try {
#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
OCC_CATCH_SIGNALS;
algo->InitComputeError();
MemoryReserve aMemoryReserve;
SMDS_Mesh::CheckMemory();
+ Kernel_Utils::Localizer loc;
if ( !_father->HasShapeToMesh() ) // no shape
{
SMESH_MesherHelper helper( *_father );
}
else
{
- if (!algo->OnlyUnaryInput()) {
- shape = GetCollection( gen, algo );
- }
ret = algo->Compute((*_father), shape);
}
- if ( !ret )
+ if ( !_computeError || ( !ret && _computeError->IsOK() ) ) // algo can set _computeError of submesh
_computeError = algo->GetComputeError();
}
catch ( std::bad_alloc& exc ) {
- printf("std::bad_alloc thrown inside algo->Compute()\n");
+ MESSAGE("std::bad_alloc thrown inside algo->Compute()");
if ( _computeError ) {
_computeError->myName = COMPERR_MEMORY_PB;
//_computeError->myComment = exc.what();
throw exc;
}
catch ( Standard_OutOfMemory& exc ) {
- printf("Standard_OutOfMemory thrown inside algo->Compute()\n");
+ MESSAGE("Standard_OutOfMemory thrown inside algo->Compute()");
if ( _computeError ) {
_computeError->myName = COMPERR_MEMORY_PB;
//_computeError->myComment = exc.what();
else
ret = false;
}
- if (ret && !_alwaysComputed) { // check if anything was built
- ret = ( GetSubMeshDS() && ( GetSubMeshDS()->NbElements() || GetSubMeshDS()->NbNodes() ));
+ TopExp_Explorer subS(shape, _subShape.ShapeType());
+ if (ret) // check if anything was built
+ {
+ for (; ret && subS.More(); subS.Next())
+ ret = _father->GetSubMesh( subS.Current() )->IsMeshComputed();
}
bool isComputeErrorSet = !CheckComputeError( algo, shape );
if (!ret && !isComputeErrorSet)
{
// Set _computeError
- if ( !_computeError )
- _computeError = SMESH_ComputeError::New();
- if ( _computeError->IsOK() )
- _computeError->myName = COMPERR_ALGO_FAILED;
- _computeState = FAILED_TO_COMPUTE;
+ for (subS.ReInit(); subS.More(); subS.Next())
+ {
+ SMESH_subMesh* sm = _father->GetSubMesh( subS.Current() );
+ if ( !sm->IsMeshComputed() )
+ {
+ if ( !sm->_computeError )
+ sm->_computeError = SMESH_ComputeError::New();
+ if ( sm->_computeError->IsOK() )
+ sm->_computeError->myName = COMPERR_ALGO_FAILED;
+ sm->_computeState = FAILED_TO_COMPUTE;
+ sm->_computeError->myAlgo = algo;
+ }
+ }
}
if (ret)
{
ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE );
break;
case CHECK_COMPUTE_STATE:
- if ( !IsMeshComputed() )
+ if ( !IsMeshComputed() ) {
if (_algoState == HYP_OK)
_computeState = READY_TO_COMPUTE;
else
_computeState = NOT_READY;
+ }
break;
default:
ASSERT(0);
switch (event)
{
case MODIF_ALGO_STATE:
+ if ( !IsEmpty() )
+ ComputeStateEngine( CLEAN );
+ algo = gen->GetAlgo((*_father), _subShape);
+ if (algo && !algo->NeedDescretBoundary())
+ CleanDependsOn(); // clean sub-meshes with event CLEAN
if (_algoState == HYP_OK)
_computeState = READY_TO_COMPUTE;
else
return ret;
}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+bool SMESH_subMesh::Evaluate(MapShapeNbElems& aResMap)
+{
+ _computeError.reset();
+
+ bool ret = true;
+
+ if (_subShape.ShapeType() == TopAbs_VERTEX) {
+ vector<int> aVec(SMDSEntity_Last,0);
+ aVec[SMDSEntity_Node] = 1;
+ aResMap.insert(make_pair(this,aVec));
+ return ret;
+ }
+
+ SMESH_Gen *gen = _father->GetGen();
+ SMESH_Algo *algo = 0;
+ SMESH_Hypothesis::Hypothesis_Status hyp_status;
+
+ algo = gen->GetAlgo((*_father), _subShape);
+ if(algo && !aResMap.count(this) )
+ {
+ ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
+ if (!ret) return false;
+
+ if (_father->HasShapeToMesh() && algo->NeedDescretBoundary())
+ {
+ // check submeshes needed
+ bool subMeshEvaluated = true;
+ int dimToCheck = SMESH_Gen::GetShapeDim( _subShape ) - 1;
+ SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,/*complexShapeFirst=*/true);
+ while ( smIt->more() && subMeshEvaluated )
+ {
+ SMESH_subMesh* sm = smIt->next();
+ int dim = SMESH_Gen::GetShapeDim( sm->GetSubShape() );
+ if (dim < dimToCheck) break; // the rest subMeshes are all of less dimension
+ const vector<int> & nbs = aResMap[ sm ];
+ subMeshEvaluated = (std::accumulate( nbs.begin(), nbs.end(), 0 ) > 0 );
+ }
+ if ( !subMeshEvaluated )
+ return false;
+ }
+ _computeError = SMESH_ComputeError::New(COMPERR_OK,"",algo);
+ ret = algo->Evaluate((*_father), _subShape, aResMap);
+
+ aResMap.insert( make_pair( this,vector<int>(0)));
+ }
+
+ return ret;
+}
+
+
//=======================================================================
/*!
* \brief Update compute_state by _computeError and send proper events to
for (TopoDS_Iterator subIt( theShape ); subIt.More(); subIt.Next()) {
SMESH_subMesh* sm = _father->GetSubMesh( subIt.Value() );
if ( sm != this ) {
- if ( !sm->CheckComputeError( theAlgo ))
+ if ( !sm->CheckComputeError( theAlgo, sm->GetSubShape() ))
noErrors = false;
UpdateDependantsState( SUBMESH_COMPUTED ); // send event SUBMESH_COMPUTED
}
// Check my state
if ( !_computeError || _computeError->IsOK() )
{
- _computeState = COMPUTE_OK;
+ _computeState = IsMeshComputed() ? COMPUTE_OK : FAILED_TO_COMPUTE;
}
else
{
if ( _computeError->myComment.size() > 0 )
text << " \"" << _computeError->myComment << "\"";
-#ifdef _DEBUG_
- cout << text << endl;
- // Show vertices location of a failed shape
- TopTools_IndexedMapOfShape vMap;
- TopExp::MapShapes( _subShape, TopAbs_VERTEX, vMap );
- cout << "Subshape vertices " << ( vMap.Extent()>10 ? "(first 10):" : ":") << endl;
- for ( int iv = 1; iv <= vMap.Extent() && iv < 11; ++iv ) {
- gp_Pnt P( BRep_Tool::Pnt( TopoDS::Vertex( vMap( iv ) )));
- cout << "#" << _father->GetMeshDS()->ShapeToIndex( vMap( iv )) << " ";
- cout << P.X() << " " << P.Y() << " " << P.Z() << " " << endl;
- }
-#else
INFOS( text );
-#endif
+
_computeState = FAILED_TO_COMPUTE;
noErrors = false;
}
// meshed at once along with _subShape
//=======================================================================
-TopoDS_Shape SMESH_subMesh::GetCollection(SMESH_Gen * theGen, SMESH_Algo* theAlgo)
+TopoDS_Shape SMESH_subMesh::GetCollection(SMESH_Gen * theGen,
+ SMESH_Algo* theAlgo,
+ bool & theSubComputed)
{
MESSAGE("SMESH_subMesh::GetCollection");
+ theSubComputed = SubMeshesComputed();
+
TopoDS_Shape mainShape = _father->GetMeshDS()->ShapeToMesh();
if ( mainShape.IsSame( _subShape ))
else if ( subMesh->GetComputeState() == READY_TO_COMPUTE )
{
SMESH_Algo* anAlgo = theGen->GetAlgo( *_father, S );
- if (anAlgo == theAlgo &&
- anAlgo->GetUsedHypothesis( *_father, S, ignoreAuxiliaryHyps ) == aUsedHyp)
+ if (strcmp( anAlgo->GetName(), theAlgo->GetName()) == 0 && // same algo
+ anAlgo->GetUsedHypothesis( *_father, S, ignoreAuxiliaryHyps ) == aUsedHyp) // same hyps
aBuilder.Add( aCompound, S );
+ if ( !subMesh->SubMeshesComputed() )
+ theSubComputed = false;
}
}
* \brief Notify stored event listeners on the occured event
* \param event - algo_event or compute_event itself
* \param eventType - algo_event or compute_event
- * \param subMesh - the submesh where the event occures
- * \param data - listener data stored in the subMesh
* \param hyp - hypothesis, if eventType is algo_event
*/
//================================================================================
{
map< EventListener*, EventListenerData* >::iterator l_d = myEventListeners.begin();
for ( ; l_d != myEventListeners.end(); ++l_d )
- l_d->first->ProcessEvent( event, eventType, this, l_d->second, hyp );
+ if ( (*l_d).first->myBusySM.insert( this ).second )
+ {
+ l_d->first->ProcessEvent( event, eventType, this, l_d->second, hyp );
+ l_d->first->myBusySM.erase( this );
+ }
}
//================================================================================
SMESH_subMesh* prepend,
SMESH_subMesh* append): myIt(subIt),myAppend(append)
{
- myCur = prepend ? prepend : myIt->more() ? myIt->next() : 0;
+ myCur = prepend ? prepend : myIt->more() ? myIt->next() : append;
+ if ( myCur == append ) append = 0;
}
/// Return true if and only if there are other object in this iterator
virtual bool more()
( new _Iterator( new SMDS_mapIterator<TMap>( DependsOn() ), prepend, append ));
}
}
+
+//================================================================================
+/*!
+ * \brief Find common submeshes (based on shared subshapes with other
+ * \param theOther submesh to check
+ * \param theSetOfCommon set of common submesh
+ */
+//================================================================================
+
+bool SMESH_subMesh::FindIntersection(const SMESH_subMesh* theOther,
+ std::set<const SMESH_subMesh*>& theSetOfCommon ) const
+{
+ int oldNb = theSetOfCommon.size();
+ // check main submeshes
+ const map <int, SMESH_subMesh*>::const_iterator otherEnd = theOther->_mapDepend.end();
+ if ( theOther->_mapDepend.find(this->GetId()) != otherEnd )
+ theSetOfCommon.insert( this );
+ if ( _mapDepend.find(theOther->GetId()) != _mapDepend.end() )
+ theSetOfCommon.insert( theOther );
+ // check common submeshes
+ map <int, SMESH_subMesh*>::const_iterator mapIt = _mapDepend.begin();
+ for( ; mapIt != _mapDepend.end(); mapIt++ )
+ if ( theOther->_mapDepend.find((*mapIt).first) != otherEnd )
+ theSetOfCommon.insert( (*mapIt).second );
+ return oldNb < theSetOfCommon.size();
+}