From: jfa Date: Wed, 15 Feb 2006 15:46:29 +0000 (+0000) Subject: PAL11544: Optimize sub-meshes cleaning on hypothesis modification. X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=a668071aa4deb2eb3442956aec7353a5cd491e38;p=modules%2Fsmesh.git PAL11544: Optimize sub-meshes cleaning on hypothesis modification. --- diff --git a/src/SMDS/SMDS_Mesh.cxx b/src/SMDS/SMDS_Mesh.cxx index 6381e547e..58f3e52c2 100644 --- a/src/SMDS/SMDS_Mesh.cxx +++ b/src/SMDS/SMDS_Mesh.cxx @@ -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(elem); + SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); + if (!itFe->more()) { // free node + myNodes.Remove(const_cast(n)); + myNodeIDFactory->ReleaseID(elem->GetID()); + delete elem; + } + } else { + if (hasConstructionEdges() || hasConstructionFaces()) + // this methods is only for meshes without descendants + return; + + // Remove element from of its nodes + SMDS_ElemIteratorPtr itn = elem->nodesIterator(); + while (itn->more()) { + SMDS_MeshNode * n = static_cast + (const_cast(itn->next())); + n->RemoveInverseElement(elem); + } + + // in meshes without descendants elements are always free + switch (aType) { + case SMDSAbs_Edge: + myEdges.Remove(static_cast + (const_cast(elem))); + break; + case SMDSAbs_Face: + myFaces.Remove(static_cast + (const_cast(elem))); + break; + case SMDSAbs_Volume: + myVolumes.Remove(static_cast + (const_cast(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(); -} \ No newline at end of file +} diff --git a/src/SMDS/SMDS_Mesh.hxx b/src/SMDS/SMDS_Mesh.hxx index 612082ce4..11f201cc8 100644 --- a/src/SMDS/SMDS_Mesh.hxx +++ b/src/SMDS/SMDS_Mesh.hxx @@ -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); diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index 385bc08c0..b3f104ae2 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -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: "<GetID()<<" ( "<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: "<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; + } } //======================================================================= diff --git a/src/SMESH/SMESH_subMesh.hxx b/src/SMESH/SMESH_subMesh.hxx index 8251c6b94..e2af61ac0 100644 --- a/src/SMESH/SMESH_subMesh.hxx +++ b/src/SMESH/SMESH_subMesh.hxx @@ -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 }; diff --git a/src/SMESHDS/SMESHDS_Mesh.cxx b/src/SMESHDS/SMESHDS_Mesh.cxx index 94147bcc6..028e7e254 100644 --- a/src/SMESHDS/SMESHDS_Mesh.cxx +++ b/src/SMESHDS/SMESHDS_Mesh.cxx @@ -607,10 +607,10 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolume //purpose : //======================================================================= -static void removeFromContainers (map & theSubMeshes, - set& theGroups, - list & theElems, - const bool isNode) +static void removeFromContainers (map& theSubMeshes, + set& theGroups, + list& 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::iterator GrIt = myGroups.begin(); + for (; GrIt != myGroups.end(); GrIt++) { + SMESHDS_Group* group = dynamic_cast(*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(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::iterator GrIt = myGroups.begin(); + for (; GrIt != myGroups.end(); GrIt++) { + SMESHDS_Group* group = dynamic_cast(*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 diff --git a/src/SMESHDS/SMESHDS_Mesh.hxx b/src/SMESHDS/SMESHDS_Mesh.hxx index edcbcf3c0..88c531c9e 100644 --- a/src/SMESHDS/SMESHDS_Mesh.hxx +++ b/src/SMESHDS/SMESHDS_Mesh.hxx @@ -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);