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; 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. * Checks if the element is present in mesh.
* Useful to determine dead pointers. * Useful to determine dead pointers.
@ -2200,4 +2251,4 @@ SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem )
} }
else else
return elem->GetType(); return elem->GetType();
} }

View File

@ -245,6 +245,12 @@ public:
virtual void RemoveEdge(const SMDS_MeshEdge * edge); virtual void RemoveEdge(const SMDS_MeshEdge * edge);
virtual void RemoveFace(const SMDS_MeshFace * face); virtual void RemoveFace(const SMDS_MeshFace * face);
virtual void RemoveVolume(const SMDS_MeshVolume * volume); 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 RemoveFromParent();
virtual bool RemoveSubMesh(const SMDS_Mesh * aMesh); virtual bool RemoveSubMesh(const SMDS_Mesh * aMesh);

View File

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

View File

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

View File

@ -607,10 +607,10 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolume
//purpose : //purpose :
//======================================================================= //=======================================================================
static void removeFromContainers (map<int,SMESHDS_SubMesh*> & theSubMeshes, static void removeFromContainers (map<int,SMESHDS_SubMesh*>& theSubMeshes,
set<SMESHDS_GroupBase*>& theGroups, set<SMESHDS_GroupBase*>& theGroups,
list<const SMDS_MeshElement *> & theElems, list<const SMDS_MeshElement*>& theElems,
const bool isNode) const bool isNode)
{ {
if ( theElems.empty() ) if ( theElems.empty() )
return; return;
@ -682,6 +682,32 @@ void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n)
removeFromContainers( myShapeIndexToSubMesh, myGroups, removedNodes, true ); 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 //function : RemoveElement
//purpose : //purpose :
@ -704,6 +730,41 @@ void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt)
removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false ); 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 * \brief return submesh by shape

View File

@ -196,6 +196,14 @@ public:
void MoveNode(const SMDS_MeshNode *, double x, double y, double z); void MoveNode(const SMDS_MeshNode *, double x, double y, double z);
virtual void RemoveNode(const SMDS_MeshNode *); virtual void RemoveNode(const SMDS_MeshNode *);
void RemoveElement(const SMDS_MeshElement *); 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, bool ChangeElementNodes(const SMDS_MeshElement * elem,
const SMDS_MeshNode * nodes[], const SMDS_MeshNode * nodes[],
const int nbnodes); const int nbnodes);