-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
//
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
// 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
#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;
- }
+ }
}
//=============================================================================
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;
}
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
{
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;
+ }
}
//================================================================================
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 );
algo->InitComputeError();
MemoryReserve aMemoryReserve;
SMDS_Mesh::CheckMemory();
+ Kernel_Utils::Localizer loc;
if ( !_father->HasShapeToMesh() ) // no shape
{
SMESH_MesherHelper helper( *_father );
else
ret = false;
}
- if (ret && !_alwaysComputed && shape == _subShape) { // 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)
{
bool ret = true;
if (_subShape.ShapeType() == TopAbs_VERTEX) {
- std::vector<int> aVec(SMDSEntity_Last);
- for(int i= SMDSEntity_Node; i < SMDSEntity_Last; i++)
- aVec[i] = 0;
+ vector<int> aVec(SMDSEntity_Last,0);
aVec[SMDSEntity_Node] = 1;
- aResMap.insert(std::make_pair(this,aVec));
+ aResMap.insert(make_pair(this,aVec));
return ret;
}
SMESH_Hypothesis::Hypothesis_Status hyp_status;
algo = gen->GetAlgo((*_father), _subShape);
- if(algo) {
+ if(algo && !aResMap.count(this) )
+ {
ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
if (!ret) return false;
- TopoDS_Shape shape = _subShape;
-
+ 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);
- ret = algo->Evaluate((*_father), shape, aResMap);
+ aResMap.insert( make_pair( this,vector<int>(0)));
}
return ret;
( 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();
+}