PAL11544: Optimize sub-meshes cleaning on hypothesis modification.

This commit is contained in:
jfa 2006-02-15 15:46:29 +00:00
parent 135b5c7bcf
commit a668071aa4
6 changed files with 161 additions and 42 deletions

View File

@ -2075,6 +2075,57 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
delete s1;
}
///////////////////////////////////////////////////////////////////////////////
///@param elem The element to delete
///////////////////////////////////////////////////////////////////////////////
void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
{
SMDSAbs_ElementType aType = elem->GetType();
if (aType == SMDSAbs_Node) {
// only free node can be removed by this method
const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>(elem);
SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
if (!itFe->more()) { // free node
myNodes.Remove(const_cast<SMDS_MeshNode*>(n));
myNodeIDFactory->ReleaseID(elem->GetID());
delete elem;
}
} else {
if (hasConstructionEdges() || hasConstructionFaces())
// this methods is only for meshes without descendants
return;
// Remove element from <InverseElements> of its nodes
SMDS_ElemIteratorPtr itn = elem->nodesIterator();
while (itn->more()) {
SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
(const_cast<SMDS_MeshElement *>(itn->next()));
n->RemoveInverseElement(elem);
}
// in meshes without descendants elements are always free
switch (aType) {
case SMDSAbs_Edge:
myEdges.Remove(static_cast<SMDS_MeshEdge*>
(const_cast<SMDS_MeshElement*>(elem)));
break;
case SMDSAbs_Face:
myFaces.Remove(static_cast<SMDS_MeshFace*>
(const_cast<SMDS_MeshElement*>(elem)));
break;
case SMDSAbs_Volume:
myVolumes.Remove(static_cast<SMDS_MeshVolume*>
(const_cast<SMDS_MeshElement*>(elem)));
break;
default:
break;
}
myElementIDFactory->ReleaseID(elem->GetID());
delete elem;
}
}
/*!
* Checks if the element is present in mesh.
* Useful to determine dead pointers.
@ -2200,4 +2251,4 @@ SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem )
}
else
return elem->GetType();
}
}

View File

@ -245,6 +245,12 @@ public:
virtual void RemoveEdge(const SMDS_MeshEdge * edge);
virtual void RemoveFace(const SMDS_MeshFace * face);
virtual void RemoveVolume(const SMDS_MeshVolume * volume);
/*! Remove only the given element and only if it is free.
* Method does not work for meshes with descendants.
* Implemented for fast cleaning of meshes.
*/
virtual void RemoveFreeElement(const SMDS_MeshElement * elem);
virtual bool RemoveFromParent();
virtual bool RemoveSubMesh(const SMDS_Mesh * aMesh);

View File

@ -1028,17 +1028,17 @@ SMESH_Hypothesis::Hypothesis_Status
void SMESH_subMesh::CleanDependsOn()
{
//MESSAGE("SMESH_subMesh::CleanDependsOn");
// **** parcourir les ancetres dans l'ordre de dépendance
// **** parcourir les ancetres dans l'ordre de dépendance
ComputeStateEngine(CLEAN);
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 = (*its).second;
sm->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 = (*its).second;
sm->ComputeStateEngine(CLEAN);
}
}
//=============================================================================
@ -1102,26 +1102,26 @@ void SMESH_subMesh::DumpAlgoState(bool isMain)
static void cleanSubMesh( SMESH_subMesh * subMesh )
{
if ( subMesh )
if (SMESHDS_SubMesh * subMeshDS = subMesh->GetSubMeshDS())
{
if (subMesh) {
if (SMESHDS_SubMesh * subMeshDS = subMesh->GetSubMeshDS()) {
SMESHDS_Mesh * meshDS = subMesh->GetFather()->GetMeshDS();
SMDS_ElemIteratorPtr ite=subMeshDS->GetElements();
while(ite->more())
{
SMDS_ElemIteratorPtr ite = subMeshDS->GetElements();
while (ite->more()) {
const SMDS_MeshElement * elt = ite->next();
//MESSAGE( " RM elt: "<<elt->GetID()<<" ( "<<elt->NbNodes()<<" )" );
meshDS->RemoveElement(elt);
//meshDS->RemoveElement(elt);
meshDS->RemoveFreeElement(elt, subMeshDS);
}
SMDS_NodeIteratorPtr itn=subMeshDS->GetNodes();
while(itn->more())
{
SMDS_NodeIteratorPtr itn = subMeshDS->GetNodes();
while (itn->more()) {
const SMDS_MeshNode * node = itn->next();
//MESSAGE( " RM node: "<<node->GetID());
meshDS->RemoveNode(node);
//meshDS->RemoveNode(node);
meshDS->RemoveFreeNode(node, subMeshDS);
}
}
}
}
//=============================================================================
@ -1167,13 +1167,11 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
_computeState = READY_TO_COMPUTE;
}
break;
case COMPUTE: // nothing to do
case COMPUTE: // nothing to do
break;
case CLEAN:
RemoveSubMeshElementsAndNodes();
//break; submeshes dependent on me should be cleaned as well
case CLEANDEP:
CleanDependants();
RemoveSubMeshElementsAndNodes();
break;
case SUBMESH_COMPUTED: // nothing to do
break;
@ -1270,6 +1268,7 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
}
break;
case CLEAN:
CleanDependants();
RemoveSubMeshElementsAndNodes();
_computeState = NOT_READY;
algo = gen->GetAlgo((*_father), _subShape);
@ -1279,9 +1278,6 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
if (ret)
_computeState = READY_TO_COMPUTE;
}
//break; submeshes dependent on me should be cleaned as well
case CLEANDEP:
CleanDependants();
break;
case SUBMESH_COMPUTED: // nothing to do
break;
@ -1313,11 +1309,12 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
ComputeStateEngine( CLEAN );
algo = gen->GetAlgo((*_father), _subShape);
if (algo && !algo->NeedDescretBoundary())
CleanDependsOn(); // remove sub-mesh with event CLEANDEP
CleanDependsOn(); // clean sub-meshes with event CLEAN
break;
case COMPUTE: // nothing to do
case COMPUTE: // nothing to do
break;
case CLEAN:
CleanDependants(); // clean sub-meshes, dependant on this one, with event CLEAN
RemoveSubMeshElementsAndNodes();
_computeState = NOT_READY;
algo = gen->GetAlgo((*_father), _subShape);
@ -1327,9 +1324,6 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
if (ret)
_computeState = READY_TO_COMPUTE;
}
// break; submeshes dependent on me should be cleaned as well
case CLEANDEP:
CleanDependants(); // recursive recall with event CLEANDEP
break;
case SUBMESH_COMPUTED: // nothing to do
break;
@ -1375,14 +1369,12 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
case COMPUTE: // nothing to do
break;
case CLEAN:
CleanDependants(); // submeshes dependent on me should be cleaned as well
RemoveSubMeshElementsAndNodes();
if (_algoState == HYP_OK)
_computeState = READY_TO_COMPUTE;
else
_computeState = NOT_READY;
// break; submeshes dependent on me should be cleaned as well
case CLEANDEP:
CleanDependants();
break;
case SUBMESH_COMPUTED: // allow retry compute
if (_algoState == HYP_OK)
@ -1554,7 +1546,7 @@ void SMESH_subMesh::RemoveSubMeshElementsAndNodes()
int dim = SMESH_Gen::GetShapeDim( _subShape );
int type = _subShape.ShapeType() + 1;
for ( ; type <= TopAbs_EDGE; type++)
for ( ; type <= TopAbs_EDGE; type++) {
if ( dim == SMESH_Gen::GetShapeDim( (TopAbs_ShapeEnum) type ))
{
TopExp_Explorer exp( _subShape, (TopAbs_ShapeEnum) type );
@ -1563,6 +1555,7 @@ void SMESH_subMesh::RemoveSubMeshElementsAndNodes()
}
else
break;
}
}
//=======================================================================

View File

@ -93,7 +93,7 @@ class SMESH_subMesh
enum compute_event
{
MODIF_HYP, MODIF_ALGO_STATE, COMPUTE,
CLEAN, CLEANDEP, SUBMESH_COMPUTED, SUBMESH_RESTORED,
CLEAN, SUBMESH_COMPUTED, SUBMESH_RESTORED,
MESH_ENTITY_REMOVED, CHECK_COMPUTE_STATE
};

View File

@ -607,10 +607,10 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolume
//purpose :
//=======================================================================
static void removeFromContainers (map<int,SMESHDS_SubMesh*> & theSubMeshes,
set<SMESHDS_GroupBase*>& theGroups,
list<const SMDS_MeshElement *> & theElems,
const bool isNode)
static void removeFromContainers (map<int,SMESHDS_SubMesh*>& theSubMeshes,
set<SMESHDS_GroupBase*>& theGroups,
list<const SMDS_MeshElement*>& theElems,
const bool isNode)
{
if ( theElems.empty() )
return;
@ -682,6 +682,32 @@ void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n)
removeFromContainers( myShapeIndexToSubMesh, myGroups, removedNodes, true );
}
//=======================================================================
//function : RemoveFreeNode
//purpose :
//=======================================================================
void SMESHDS_Mesh::RemoveFreeNode(const SMDS_MeshNode * n, SMESHDS_SubMesh * subMesh)
{
myScript->RemoveNode(n->GetID());
// Rm from group
// Node can belong to several groups
if (!myGroups.empty()) {
set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
for (; GrIt != myGroups.end(); GrIt++) {
SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>(*GrIt);
if (!group || group->IsEmpty()) continue;
group->SMDSGroup().Remove(n);
}
}
// Rm from sub-mesh
// Node should belong to only one sub-mesh
subMesh->RemoveNode(n);
SMDS_Mesh::RemoveFreeElement(n);
}
//=======================================================================
//function : RemoveElement
//purpose :
@ -704,6 +730,41 @@ void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt)
removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
}
//=======================================================================
//function : RemoveFreeElement
//purpose :
//========================================================================
void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt, SMESHDS_SubMesh * subMesh)
{
if (elt->GetType() == SMDSAbs_Node) {
RemoveFreeNode( static_cast<const SMDS_MeshNode*>(elt), subMesh);
return;
}
if (hasConstructionEdges() || hasConstructionFaces())
// this methods is only for meshes without descendants
return;
myScript->RemoveElement(elt->GetID());
// Rm from group
// Node can belong to several groups
if (!myGroups.empty()) {
set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
for (; GrIt != myGroups.end(); GrIt++) {
SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>(*GrIt);
if (!group || group->IsEmpty()) continue;
group->SMDSGroup().Remove(elt);
}
}
// Rm from sub-mesh
// Element should belong to only one sub-mesh
subMesh->RemoveElement(elt);
SMDS_Mesh::RemoveFreeElement(elt);
}
//================================================================================
/*!
* \brief return submesh by shape

View File

@ -196,6 +196,14 @@ public:
void MoveNode(const SMDS_MeshNode *, double x, double y, double z);
virtual void RemoveNode(const SMDS_MeshNode *);
void RemoveElement(const SMDS_MeshElement *);
/*! Remove only the given element/node and only if it is free.
* Methods do not work for meshes with descendants.
* Implemented for fast cleaning of meshes.
*/
void RemoveFreeNode(const SMDS_MeshNode *, SMESHDS_SubMesh *);
void RemoveFreeElement(const SMDS_MeshElement *, SMESHDS_SubMesh *);
bool ChangeElementNodes(const SMDS_MeshElement * elem,
const SMDS_MeshNode * nodes[],
const int nbnodes);