From ff74c4bc9f90500b7dcc37a1555e1bca624fc646 Mon Sep 17 00:00:00 2001 From: prascle Date: Tue, 24 Aug 2010 15:51:28 +0000 Subject: [PATCH] merge from tag mergeto_BR_SMDS_MEMIMP_24aug10 --- configure.ac | 2 +- idl/SMESH_Mesh.idl | 7 + src/SMESH/SMESH_Mesh.cxx | 60 ++++++- src/SMESH/SMESH_Mesh.hxx | 16 ++ src/SMESHGUI/SMESHGUI_ComputeDlg.cxx | 5 + src/SMESHGUI/SMESH_msg_en.ts | 8 + src/SMESH_I/SMESH_Gen_i.cxx | 20 +++ src/SMESH_I/SMESH_MeshEditor_i.cxx | 222 ++++++++++++++++++------- src/SMESH_I/SMESH_Mesh_i.cxx | 13 ++ src/SMESH_I/SMESH_Mesh_i.hxx | 2 + src/SMESH_SWIG/smeshDC.py | 8 +- src/StdMeshers/StdMeshers_FaceSide.cxx | 26 ++- 12 files changed, 317 insertions(+), 72 deletions(-) diff --git a/configure.ac b/configure.ac index 0cfcd12fa..c55ac3594 100644 --- a/configure.ac +++ b/configure.ac @@ -24,7 +24,7 @@ # Modified by : Alexander BORODIN (OCN) - autotools usage # Created from configure.in.base # -AC_INIT([Salome2 Project SMESH module], [5.1.4], [webmaster.salome@opencascade.com], [SalomeSMESH]) +AC_INIT([Salome2 Project SMESH module], [6.1.0], [webmaster.salome@opencascade.com], [SalomeSMESH]) AC_CONFIG_AUX_DIR(adm_local/unix/config_files) AC_CANONICAL_HOST AC_CANONICAL_TARGET diff --git a/idl/SMESH_Mesh.idl b/idl/SMESH_Mesh.idl index 4f5639fb1..a06e663d5 100644 --- a/idl/SMESH_Mesh.idl +++ b/idl/SMESH_Mesh.idl @@ -520,6 +520,13 @@ module SMESH SMESH_MeshEditor GetMeshEditPreviewer() raises (SALOME::SALOME_Exception); + /*! + * Return true if the mesh has been edited since a total re-compute + * and those modifications may prevent successful partial re-compute + */ + boolean HasModificationsToDiscard() + raises (SALOME::SALOME_Exception); + /*! Check group names for duplications. * Consider maximum group name length stored in MED file. */ diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index 9dad8b967..5cf9ba6c5 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -99,6 +99,7 @@ SMESH_Mesh::SMESH_Mesh(int theLocalId, _myMeshDS = theDocument->GetMesh(_idDoc); _isShapeToMesh = false; _isAutoColor = false; + _isModified = false; _shapeDiagonal = 0.0; _myMeshDS->ShapeToMesh( PseudoShape() ); } @@ -187,6 +188,7 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape) _shapeDiagonal = 0.0; _myMeshDS->ShapeToMesh( PseudoShape() ); } + _isModified = false; } //======================================================================= @@ -267,6 +269,7 @@ void SMESH_Mesh::Clear() sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); } } + _isModified = false; } //======================================================================= @@ -496,6 +499,7 @@ SMESH_Hypothesis::Hypothesis_Status } } } + HasModificationsToDiscard(); // to reset _isModified flag if mesh become empty if(MYDEBUG) subMesh->DumpAlgoState(true); if(MYDEBUG) SCRUTE(ret); @@ -567,7 +571,9 @@ SMESH_Hypothesis::Hypothesis_Status } } } - + + HasModificationsToDiscard(); // to reset _isModified flag if mesh become empty + if(MYDEBUG) subMesh->DumpAlgoState(true); if(MYDEBUG) SCRUTE(ret); return ret; @@ -964,6 +970,7 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* h } } } + HasModificationsToDiscard(); // to reset _isModified flag if mesh become empty } //============================================================================= @@ -983,6 +990,57 @@ bool SMESH_Mesh::GetAutoColor() throw(SALOME_Exception) return _isAutoColor; } +//======================================================================= +//function : SetIsModified +//purpose : Set the flag meaning that the mesh has been edited "manually" +//======================================================================= + +void SMESH_Mesh::SetIsModified(bool isModified) +{ + _isModified = isModified; + + if ( _isModified ) + // check if mesh becomes empty as result of modification + HasModificationsToDiscard(); +} + +//======================================================================= +//function : HasModificationsToDiscard +//purpose : Return true if the mesh has been edited since a total re-compute +// and those modifications may prevent successful partial re-compute. +// As a side effect reset _isModified flag if mesh is empty +//issue : 0020693 +//======================================================================= + +bool SMESH_Mesh::HasModificationsToDiscard() const +{ + if ( ! _isModified ) + return false; + + // return true if there the next Compute() will be partial and + // existing but changed elements may prevent successful re-compute + bool hasComputed = false, hasNotComputed = false; + map ::const_iterator i_sm = _mapSubMesh.begin(); + for ( ; i_sm != _mapSubMesh.end() ; ++i_sm ) + switch ( i_sm->second->GetSubShape().ShapeType() ) + { + case TopAbs_EDGE: + case TopAbs_FACE: + case TopAbs_SOLID: + if ( i_sm->second->IsMeshComputed() ) + hasComputed = true; + else + hasNotComputed = true; + if ( hasComputed && hasNotComputed) + return true; + } + + if ( !hasComputed ) + const_cast(this)->_isModified = false; + + return false; +} + //============================================================================= /*! Export* methods. * To store mesh contents on disk in different formats. diff --git a/src/SMESH/SMESH_Mesh.hxx b/src/SMESH/SMESH_Mesh.hxx index 59e5edf39..ac504ced6 100644 --- a/src/SMESH/SMESH_Mesh.hxx +++ b/src/SMESH/SMESH_Mesh.hxx @@ -188,6 +188,21 @@ public: bool GetAutoColor() throw(SALOME_Exception); + /*! + * \brief Set the flag meaning that the mesh has been edited "manually". + * It is to set to false after Clear() and to set to true by MeshEditor + */ + void SetIsModified(bool isModified); + + bool GetIsModified() const { return _isModified; } + + /*! + * \brief Return true if the mesh has been edited since a total re-compute + * and those modifications may prevent successful partial re-compute. + * As a side effect reset _isModified flag if mesh is empty + */ + bool HasModificationsToDiscard() const; + /*! * \brief Return data map of descendant to ancestor shapes */ @@ -293,6 +308,7 @@ protected: SMESH_Gen * _gen; bool _isAutoColor; + bool _isModified; //!< modified since last total re-compute, issue 0020693 double _shapeDiagonal; //!< diagonal size of bounding box of shape to mesh diff --git a/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx b/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx index f23990352..06104aef2 100644 --- a/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx @@ -698,6 +698,11 @@ void SMESHGUI_BaseComputeOp::computeMesh() if ( errors->length() > 0 ) { aHypErrors = SMESH::GetMessageOnAlgoStateErrors( errors.in() ); } + if ( myMesh->HasModificationsToDiscard() && // issue 0020693 + SUIT_MessageBox::question( desktop(), tr( "SMESH_WARNING" ), + tr( "FULL_RECOMPUTE_QUESTION" ), + tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 1, 0 ) == 0 ) + myMesh->Clear(); SUIT_OverrideCursor aWaitCursor; try { #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 diff --git a/src/SMESHGUI/SMESH_msg_en.ts b/src/SMESHGUI/SMESH_msg_en.ts index 18a50ace6..790b7c1a8 100644 --- a/src/SMESHGUI/SMESH_msg_en.ts +++ b/src/SMESHGUI/SMESH_msg_en.ts @@ -3191,6 +3191,14 @@ Consider saving your work before application crash SMESH_PREF_area_precision Area precision + + FULL_RECOMPUTE_QUESTION + +The mesh has been edited since a last total re-compute +that may prevent successful computation. +Do you wish to re-compute the mesh totally to discard the modifications? + + SMESH_PREF_vol_precision Volume precision diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx index 6db942604..785a03846 100644 --- a/src/SMESH_I/SMESH_Gen_i.cxx +++ b/src/SMESH_I/SMESH_Gen_i.cxx @@ -2522,6 +2522,14 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aDataset->WriteOnDisk( anAutoColor ); aDataset->CloseOnDisk(); + // issue 0020693. Store _isModified flag + int isModified = myImpl->GetImpl().GetIsModified(); + aSize[ 0 ] = 1; + aDataset = new HDFdataset( "_isModified", aTopGroup, HDF_INT32, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( &isModified ); + aDataset->CloseOnDisk(); + // write reference on a shape if exists SALOMEDS::SObject_var myRef; bool shapeRefFound = false; @@ -3612,6 +3620,18 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, } } } + + // issue 0020693. Restore _isModified flag + if( aTopGroup->ExistInternalObject( "_isModified" ) ) + { + aDataset = new HDFdataset( "_isModified", aTopGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + int* isModified = new int[ size ]; + aDataset->ReadFromDisk( isModified ); + aDataset->CloseOnDisk(); + myNewMeshImpl->GetImpl().SetIsModified( bool(*isModified)); + } } } } diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index f573ba167..17ba61a84 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -312,6 +312,10 @@ SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements) // Update Python script TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )"; + + if ( IDsOfElements.length() ) + myMesh->SetIsModified( true ); // issue 0020693 + // Remove Elements return anEditor.Remove( IdList, false ); } @@ -334,6 +338,9 @@ CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNo // Update Python script TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )"; + if ( IDsOfNodes.length() ) + myMesh->SetIsModified( true ); // issue 0020693 + return anEditor.Remove( IdList, true ); } @@ -354,6 +361,8 @@ CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x, TPythonDump() << "nodeID = " << this << ".AddNode( " << x << ", " << y << ", " << z << " )"; + myMesh->SetIsModified( true ); // issue 0020693 + return N->GetID(); } @@ -372,6 +381,8 @@ CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode) // Update Python script TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )"; + myMesh->SetIsModified( true ); // issue 0020693 + if (elem) return elem->GetID(); @@ -413,7 +424,7 @@ CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes) } if(elem) - return elem->GetID(); + return myMesh->SetIsModified( true ), elem->GetID(); return 0; } @@ -461,7 +472,7 @@ CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes) TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )"; if(elem) - return elem->GetID(); + return myMesh->SetIsModified( true ), elem->GetID(); return 0; } @@ -485,7 +496,7 @@ CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsO // Update Python script TPythonDump() <<"faceID = "<GetID() : 0; + return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0; } //============================================================================= @@ -529,7 +540,7 @@ CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes) TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )"; if(elem) - return elem->GetID(); + return myMesh->SetIsModified( true ), elem->GetID(); return 0; } @@ -560,7 +571,7 @@ CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & I TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( " << IDsOfNodes << ", " << Quantities << " )"; - return elem ? elem->GetID() : 0; + return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0; } //============================================================================= @@ -592,7 +603,7 @@ CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_ar TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( " << IdsOfFaces << " )"; - return elem ? elem->GetID() : 0; + return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0; } //============================================================================= @@ -622,6 +633,8 @@ void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexI THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM); mesh->SetNodeOnVertex( node, VertexID ); + + myMesh->SetIsModified( true ); } //============================================================================= @@ -658,6 +671,8 @@ void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID, THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM); mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge ); + + myMesh->SetIsModified( true ); } //============================================================================= @@ -707,6 +722,8 @@ void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID, } mesh->SetNodeOnFace( node, FaceID, u, v ); + + myMesh->SetIsModified( true ); } //============================================================================= @@ -737,6 +754,8 @@ void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM); mesh->SetNodeInVolume( node, SolidID ); + + // myMesh->SetIsModified( true ); - SetNodeInVolume() can't prevent re-compute, I believe } //============================================================================= @@ -770,6 +789,8 @@ void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID, THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM); mesh->SetMeshElementOnShape( elem, ShapeID ); + + myMesh->SetIsModified( true ); } //============================================================================= @@ -792,6 +813,8 @@ CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1, TPythonDump() << "isDone = " << this << ".InverseDiag( " << NodeID1 << ", " << NodeID2 << " )"; + myMesh->SetIsModified( true ); + ::SMESH_MeshEditor aMeshEditor( myMesh ); return aMeshEditor.InverseDiag ( n1, n2 ); } @@ -820,6 +843,9 @@ CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1, bool stat = aMeshEditor.DeleteDiag ( n1, n2 ); + if ( stat ) + myMesh->SetIsModified( true ); // issue 0020693 + storeResult(aMeshEditor); return stat; @@ -846,6 +872,9 @@ CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfEleme // Update Python script TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )"; + if ( IDsOfElements.length() ) + myMesh->SetIsModified( true ); // issue 0020693 + return true; } @@ -860,15 +889,13 @@ CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theO { initData(); + TPythonDump aTPythonDump; // suppress dump in Reorient() + SMESH::long_array_var anElementsId = theObject->GetIDs(); CORBA::Boolean isDone = Reorient(anElementsId); - // Clear python line, created by Reorient() - SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); - aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID()); - // Update Python script - TPythonDump() << "isDone = " << this << ".ReorientObject( " << theObject << " )"; + aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )"; return isDone; } @@ -931,6 +958,8 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfE ::SMESH_MeshEditor anEditor( myMesh ); bool stat = anEditor.TriToQuad( faces, aCrit, MaxAngle ); + if ( stat ) + myMesh->SetIsModified( true ); // issue 0020693 storeResult(anEditor); @@ -949,19 +978,16 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr { initData(); + TPythonDump aTPythonDump; // suppress dump in TriToQuad() SMESH::long_array_var anElementsId = theObject->GetIDs(); CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle); - // Clear python line(s), created by TriToQuad() - SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); - aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID()); - SMESH::NumericalFunctor_i* aNumericalFunctor = SMESH::DownCast( Criterion ); // Update Python script - TPythonDump() << "isDone = " << this << ".TriToQuadObject(" - << theObject << ", " << aNumericalFunctor << ", " << MaxAngle << " )"; + aTPythonDump << "isDone = " << this << ".TriToQuadObject(" + << theObject << ", " << aNumericalFunctor << ", " << MaxAngle << " )"; return isDone; } @@ -995,6 +1021,8 @@ CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfE ::SMESH_MeshEditor anEditor( myMesh ); CORBA::Boolean stat = anEditor.QuadToTri( faces, aCrit ); + if ( stat ) + myMesh->SetIsModified( true ); // issue 0020693 storeResult(anEditor); @@ -1012,18 +1040,16 @@ CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr { initData(); + TPythonDump aTPythonDump; // suppress dump in QuadToTri() + SMESH::long_array_var anElementsId = theObject->GetIDs(); CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion); - // Clear python line(s), created by QuadToTri() - SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); - aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID()); - SMESH::NumericalFunctor_i* aNumericalFunctor = SMESH::DownCast( Criterion ); // Update Python script - TPythonDump() << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )"; + aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )"; return isDone; } @@ -1049,6 +1075,9 @@ CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfEle ::SMESH_MeshEditor anEditor( myMesh ); CORBA::Boolean stat = anEditor.QuadToTri( faces, Diag13 ); + if ( stat ) + myMesh->SetIsModified( true ); // issue 0020693 + storeResult(anEditor); @@ -1066,16 +1095,14 @@ CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr th { initData(); + TPythonDump aTPythonDump; // suppress dump in SplitQuad() + SMESH::long_array_var anElementsId = theObject->GetIDs(); CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13); - // Clear python line(s), created by SplitQuad() - SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); - aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID()); - // Update Python script - TPythonDump() << "isDone = " << this << ".SplitQuadObject( " - << theObject << ", " << Diag13 << " )"; + aTPythonDump << "isDone = " << this << ".SplitQuadObject( " + << theObject << ", " << Diag13 << " )"; return isDone; } @@ -1125,6 +1152,11 @@ void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems, ::SMESH_MeshEditor anEditor (myMesh); anEditor.SplitVolumesIntoTetra( elemSet, int( methodFlags )); + storeResult(anEditor); + +// if ( myLastCreatedElems.length() ) - it does not influence Compute() +// myMesh->SetIsModified( true ); // issue 0020693 + TPythonDump() << this << ".SplitVolumesIntoTetra( " << elems << ", " << methodFlags << " )"; } @@ -1233,6 +1265,8 @@ SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements, anEditor.Smooth(elements, fixedNodes, method, MaxNbOfIterations, MaxAspectRatio, IsParametric ); + myMesh->SetIsModified( true ); // issue 0020693 + storeResult(anEditor); // Update Python script @@ -1264,22 +1298,20 @@ SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObjec { initData(); + TPythonDump aTPythonDump; // suppress dump in smooth() + SMESH::long_array_var anElementsId = theObject->GetIDs(); CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations, MaxAspectRatio, Method, IsParametric); - // Clear python line(s), created by Smooth() - SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); - aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID()); - // Update Python script - TPythonDump() << "isDone = " << this << "." - << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ") - << theObject << ", " << IDsOfFixedNodes << ", " - << MaxNbOfIterations << ", " << MaxAspectRatio << ", " - << "SMESH.SMESH_MeshEditor." - << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ? - "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )"); + aTPythonDump << "isDone = " << this << "." + << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ") + << theObject << ", " << IDsOfFixedNodes << ", " + << MaxNbOfIterations << ", " << MaxAspectRatio << ", " + << "SMESH.SMESH_MeshEditor." + << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ? + "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )"); return isDone; } @@ -1373,6 +1405,8 @@ SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements, theNbOfSteps, theTolerance, theMakeGroups, makeWalls); storeResult(anEditor); + // myMesh->SetIsModified( true ); -- it does not influence Compute() + return theMakeGroups ? getGroups(groupIds.get()) : 0; } @@ -2723,9 +2757,11 @@ SMESH_MeshEditor_i::mirror(const SMESH::long_array & theIDsOfElements, ::SMESH_MeshEditor::PGroupIDs groupIds = anEditor.Transform (elements, aTrsf, theCopy, theMakeGroups, theTargetMesh); - if(theCopy) { + if(theCopy) storeResult(anEditor); - } + else + myMesh->SetIsModified( true ); + return theMakeGroups ? getGroups(groupIds.get()) : 0; } @@ -2932,6 +2968,8 @@ SMESH_MeshEditor_i::translate(const SMESH::long_array & theIDsOfElements, if(theCopy) storeResult(anEditor); + else + myMesh->SetIsModified( true ); return theMakeGroups ? getGroups(groupIds.get()) : 0; } @@ -3136,9 +3174,11 @@ SMESH_MeshEditor_i::rotate(const SMESH::long_array & theIDsOfElements, ::SMESH_MeshEditor::PGroupIDs groupIds = anEditor.Transform (elements, aTrsf, theCopy, theMakeGroups, theTargetMesh); - if(theCopy) { + if(theCopy) storeResult(anEditor); - } + else + myMesh->SetIsModified( true ); + return theMakeGroups ? getGroups(groupIds.get()) : 0; } @@ -3359,6 +3399,8 @@ SMESH_MeshEditor_i::scale(const SMESH::long_array & theIDsOfElements, if(theCopy) storeResult(anEditor); + else + myMesh->SetIsModified( true ); return theMakeGroups ? getGroups(groupIds.get()) : 0; } @@ -3505,8 +3547,9 @@ void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr SMESHDS_Mesh* aMesh = GetMeshDS(); set nodes; - if ( !CORBA::is_nil(SMESH::SMESH_GroupBase::_narrow(theObject)) && - SMESH::SMESH_GroupBase::_narrow(theObject)->GetType() == SMESH::NODE) { + SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject); + if ( !group->_is_nil() && group->GetType() == SMESH::NODE) + { for(int i = 0; i < aElementsId->length(); i++) { CORBA::Long ind = aElementsId[i]; const SMDS_MeshNode * elem = aMesh->FindNode(ind); @@ -3584,6 +3627,8 @@ void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfN anEditor.MergeNodes( aListOfListOfNodes ); aTPythonDump << "])"; + + myMesh->SetIsModified( true ); } //======================================================================= @@ -3594,8 +3639,10 @@ void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObj SMESH::array_of_long_array_out GroupsOfElementsID) { initData(); - if ( !(!CORBA::is_nil(SMESH::SMESH_GroupBase::_narrow(theObject)) && - SMESH::SMESH_GroupBase::_narrow(theObject)->GetType() == SMESH::NODE) ) { + + SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject); + if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) ) + { typedef list TListOfIDs; set elems; SMESH::long_array_var aElementsId = theObject->GetIDs(); @@ -3663,6 +3710,8 @@ void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsO ::SMESH_MeshEditor anEditor( myMesh ); anEditor.MergeElements(aListOfListOfElementsID); + myMesh->SetIsModified( true ); + aTPythonDump << "] )"; } @@ -3710,6 +3759,8 @@ CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID, TPythonDump() << "isDone = " << this << ".MoveNode( " << NodeID << ", " << x << ", " << y << ", " << z << " )"; + myMesh->SetIsModified( true ); + return true; } @@ -3799,10 +3850,13 @@ CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x, } } - if ( !myPreviewMode ) { + if ( !myPreviewMode ) + { TPythonDump() << "nodeID = " << this << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z << ", " << nodeID << " )"; + + myMesh->SetIsModified( true ); } return nodeID; @@ -3947,6 +4001,8 @@ SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1, storeResult(anEditor); + myMesh->SetIsModified( true ); + return error; } @@ -4002,6 +4058,8 @@ SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1, storeResult(anEditor); + myMesh->SetIsModified( true ); + return error; } @@ -4062,6 +4120,8 @@ SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder, storeResult(anEditor); + myMesh->SetIsModified( true ); + return error; } @@ -4117,6 +4177,8 @@ SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements, storeResult(anEditor); + myMesh->SetIsModified( true ); + return error; } @@ -4151,7 +4213,12 @@ CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide, TPythonDump() << "isDone = " << this << ".ChangeElemNodes( " << ide << ", " << newIDs << " )"; - return GetMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 ); + bool res = GetMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 ); + + if ( res ) + myMesh->SetIsModified( true ); + + return res; } //================================================================================ @@ -4299,6 +4366,7 @@ void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d) ::SMESH_MeshEditor anEditor( myMesh ); anEditor.ConvertToQuadratic(theForce3d); TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )"; + myMesh->SetIsModified( true ); } //======================================================================= @@ -4311,6 +4379,8 @@ CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic() ::SMESH_MeshEditor anEditor( myMesh ); CORBA::Boolean isDone = anEditor.ConvertFromQuadratic(); TPythonDump() << this << ".ConvertFromQuadratic()"; + if ( isDone ) + myMesh->SetIsModified( true ); return isDone; } @@ -4374,6 +4444,8 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNode bool aResult = aMeshEditor.DoubleNodes( aListOfNodes, aListOfElems ); storeResult( aMeshEditor) ; + if ( aResult ) + myMesh->SetIsModified( true ); return aResult; } @@ -4395,7 +4467,10 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeI SMESH::long_array_var aNodes = new SMESH::long_array; aNodes->length( 1 ); aNodes[ 0 ] = theNodeId; - return DoubleNodes( aNodes, theModifiedElems ); + bool done = DoubleNodes( aNodes, theModifiedElems ); + if ( done ) + myMesh->SetIsModified( true ); + return done; } //================================================================================ @@ -4426,7 +4501,12 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup( aModifiedElems->length( 0 ); } - return DoubleNodes( aNodes, aModifiedElems ); + bool done = DoubleNodes( aNodes, aModifiedElems ); + + if ( done ) + myMesh->SetIsModified( true ); + + return done; } //================================================================================ @@ -4477,6 +4557,9 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups( storeResult( aMeshEditor) ; + if ( aResult ) + myMesh->SetIsModified( true ); + return aResult; } @@ -4512,6 +4595,9 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theE storeResult( aMeshEditor) ; + if ( aResult ) + myMesh->SetIsModified( true ); + // Update Python script TPythonDump() << "isDone = " << this << ".DoubleNodes( " << theElems << ", " << theNodesNot << ", " << theAffectedElems << " )"; @@ -4552,6 +4638,9 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion storeResult( aMeshEditor) ; + if ( aResult ) + myMesh->SetIsModified( true ); + // Update Python script TPythonDump() << "isDone = " << this << ".DoubleNodesInRegion( " << theElems << ", " << theNodesNot << ", " << theShape << " )"; @@ -4582,11 +4671,9 @@ static void groupToSet(SMESH::SMESH_GroupBase_ptr theGrp, arrayToSet( anIDs, theMeshDS, theElemSet, theType); } -CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup( - SMESH::SMESH_GroupBase_ptr theElems, +CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems, SMESH::SMESH_GroupBase_ptr theNodesNot, - SMESH::SMESH_GroupBase_ptr theAffectedElems ) - + SMESH::SMESH_GroupBase_ptr theAffectedElems) { if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE ) return false; @@ -4605,6 +4692,9 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup( storeResult( aMeshEditor) ; + if ( aResult ) + myMesh->SetIsModified( true ); + // Update Python script TPythonDump() << "isDone = " << this << ".DoubleNodeGroup( " << theElems << ", " << theNodesNot << ", " << theAffectedElems << " )"; @@ -4647,6 +4737,9 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion( storeResult( aMeshEditor) ; + if ( aResult ) + myMesh->SetIsModified( true ); + // Update Python script TPythonDump() << "isDone = " << this << ".DoubleNodeGroupInRegion( " << theElems << ", " << theNodesNot << ", " << theShape << " )"; @@ -4683,10 +4776,9 @@ static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList, } } -CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups( - const SMESH::ListOfGroups& theElems, +CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems, const SMESH::ListOfGroups& theNodesNot, - const SMESH::ListOfGroups& theAffectedElems ) + const SMESH::ListOfGroups& theAffectedElems) { initData(); @@ -4702,6 +4794,9 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups( storeResult( aMeshEditor) ; + if ( aResult ) + myMesh->SetIsModified( true ); + // Update Python script TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", " << &theNodesNot << ", " << &theAffectedElems << " )"; @@ -4722,10 +4817,10 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups( */ //================================================================================ -CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion( - const SMESH::ListOfGroups& theElems, - const SMESH::ListOfGroups& theNodesNot, - GEOM::GEOM_Object_ptr theShape ) +CORBA::Boolean +SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems, + const SMESH::ListOfGroups& theNodesNot, + GEOM::GEOM_Object_ptr theShape ) { initData(); @@ -4741,6 +4836,9 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion( storeResult( aMeshEditor) ; + if ( aResult ) + myMesh->SetIsModified( true ); + // Update Python script TPythonDump() << "isDone = " << this << ".DoubleNodeGroupsInRegion( " << &theElems << ", " << &theNodesNot << ", " << theShape << " )"; diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index 9f0101a9a..01496d825 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -2233,6 +2233,19 @@ SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer() return aMesh._retn(); } +//================================================================================ +/*! + * \brief Return true if the mesh has been edited since a last total re-compute + * and those modifications may prevent successful partial re-compute + */ +//================================================================================ + +CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + return _impl->HasModificationsToDiscard(); +} + //============================================================================= /*! * diff --git a/src/SMESH_I/SMESH_Mesh_i.hxx b/src/SMESH_I/SMESH_Mesh_i.hxx index bed9819da..521633e51 100644 --- a/src/SMESH_I/SMESH_Mesh_i.hxx +++ b/src/SMESH_I/SMESH_Mesh_i.hxx @@ -162,6 +162,8 @@ public: SMESH::SMESH_MeshEditor_ptr GetMeshEditPreviewer(); + CORBA::Boolean HasModificationsToDiscard() throw (SALOME::SALOME_Exception); + void ClearLog() throw (SALOME::SALOME_Exception); diff --git a/src/SMESH_SWIG/smeshDC.py b/src/SMESH_SWIG/smeshDC.py index 96c77da34..baf49d3dc 100644 --- a/src/SMESH_SWIG/smeshDC.py +++ b/src/SMESH_SWIG/smeshDC.py @@ -438,6 +438,7 @@ def TreatHypoStatus(status, hypName, geomName, isAlgo): elif status == HYP_NOTCONFORM : reason = "a non-conform mesh would be built" elif status == HYP_ALREADY_EXIST : + if isAlgo: return # it does not influence anything reason = hypType + " of the same dimension is already assigned to this shape" elif status == HYP_BAD_DIM : reason = hypType + " mismatches the shape" @@ -1164,9 +1165,12 @@ class Mesh: ## Computes the mesh and returns the status of the computation + # @param discardModifs if True and the mesh has been edited since + # a last total re-compute and that may prevent successful partial re-compute, + # then the mesh is cleaned before Compute() # @return True or False # @ingroup l2_construct - def Compute(self, geom=0): + def Compute(self, geom=0, discardModifs=False): if geom == 0 or not isinstance(geom, geompyDC.GEOM._objref_GEOM_Object): if self.geom == 0: geom = self.mesh.GetShapeToMesh() @@ -1174,6 +1178,8 @@ class Mesh: geom = self.geom ok = False try: + if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693 + self.mesh.Clear() ok = self.smeshpyD.Compute(self.mesh, geom) except SALOME.SALOME_Exception, ex: print "Mesh computation failed, exception caught:" diff --git a/src/StdMeshers/StdMeshers_FaceSide.cxx b/src/StdMeshers/StdMeshers_FaceSide.cxx index 3a8d36530..dea555eaf 100644 --- a/src/StdMeshers/StdMeshers_FaceSide.cxx +++ b/src/StdMeshers/StdMeshers_FaceSide.cxx @@ -585,18 +585,17 @@ TSideVector StdMeshers_FaceSide::GetFaceWires(const TopoDS_Face& theFace, TError & theError) { TopoDS_Vertex V1; - list< TopoDS_Edge > edges; + list< TopoDS_Edge > edges, internalEdges; list< int > nbEdgesInWires; int nbWires = SMESH_Block::GetOrderedEdges (theFace, V1, edges, nbEdgesInWires); // split list of all edges into separate wires TSideVector wires( nbWires ); list< int >::iterator nbE = nbEdgesInWires.begin(); - list< TopoDS_Edge >::iterator from, to; - from = to = edges.begin(); - for ( int iW = 0; iW < nbWires; ++iW ) + list< TopoDS_Edge >::iterator from = edges.begin(), to = from; + for ( int iW = 0; iW < nbWires; ++iW, ++nbE ) { - std::advance( to, *nbE++ ); + std::advance( to, *nbE ); if ( *nbE == 0 ) // Issue 0020676 { --nbWires; @@ -608,6 +607,7 @@ TSideVector StdMeshers_FaceSide::GetFaceWires(const TopoDS_Face& theFace, // assure that there is a node on the first vertex // as StdMeshers_FaceSide::GetUVPtStruct() requires if ( wireEdges.front().Orientation() != TopAbs_INTERNAL ) // Issue 0020676 + { while ( !SMESH_Algo::VertexNode( TopExp::FirstVertex( wireEdges.front(), true), theMesh.GetMeshDS())) { @@ -619,12 +619,24 @@ TSideVector StdMeshers_FaceSide::GetFaceWires(const TopoDS_Face& theFace, return TSideVector(0); } } - const bool isForward = true; + } + else if ( *nbE > 1 ) // Issue 0020676 (Face_pb_netgen.brep) - several internal edges in a wire + { + internalEdges.splice( internalEdges.end(), wireEdges, ++wireEdges.begin(), wireEdges.end()); + } + StdMeshers_FaceSide* wire = new StdMeshers_FaceSide( theFace, wireEdges, &theMesh, - isForward, theIgnoreMediumNodes); + /*isForward=*/true, theIgnoreMediumNodes); wires[ iW ] = StdMeshers_FaceSidePtr( wire ); from = to; } + while ( !internalEdges.empty() ) + { + StdMeshers_FaceSide* wire = new StdMeshers_FaceSide( theFace, internalEdges.back(), &theMesh, + /*isForward=*/true, theIgnoreMediumNodes); + wires.push_back( StdMeshers_FaceSidePtr( wire )); + internalEdges.pop_back(); + } return wires; } -- 2.39.2