diff --git a/doc/salome/gui/SMESH/CMakeLists.txt b/doc/salome/gui/SMESH/CMakeLists.txt index b15f60980..2f4f8b280 100644 --- a/doc/salome/gui/SMESH/CMakeLists.txt +++ b/doc/salome/gui/SMESH/CMakeLists.txt @@ -58,7 +58,9 @@ IF(WINDOWS) SET(CALL_STR "call") ELSE(WINDOWS) SET(DOC_PYTHONPATH "${CMAKE_INSTALL_PREFIX}/bin/salome:${CMAKE_INSTALL_PREFIX}/lib/python${PYTHON_VERSION}/site-packages/salome:${MED_ROOT_DIR}/lib/python${PYTHON_VERSION}/site-packages/salome:${GEOM_ROOT_DIR}/bin/salome:${GEOM_ROOT_DIR}/lib/python${PYTHON_VERSION}/site-packages/salome:${KERNEL_ROOT_DIR}/bin/salome:${KERNEL_ROOT_DIR}/lib/python${PYTHON_VERSION}/site-packages/salome:${OMNIORB_ROOT_USER}/lib/python${PYTHON_VERSION}/site-packages:${OMNIORB_ROOT_USER}/lib64/python${PYTHON_VERSION}/site-packages") - SET(SCR "export PYTHONPATH=${DOC_PYTHONPATH}:${PYTHONPATH} + SET(DOC_LD_LIBRARY_PATH "${CMAKE_INSTALL_PREFIX}/lib/salome:${MED_ROOT_DIR}/lib/salome:${GEOM_ROOT_DIR}/lib/salome:${KERNEL_ROOT_DIR}/lib/salome") + SET(SCR "export PYTHONPATH=${DOC_PYTHONPATH}:\${PYTHONPATH} + export LD_LIBRARY_PATH=${DOC_LD_LIBRARY_PATH}:\${LD_LIBRARY_PATH} export SMESH_MeshersList=${DOC_SMESH_MeshersList} ") SET(EXT "sh") @@ -68,7 +70,7 @@ ENDIF(WINDOWS) FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/tmp_env.${EXT} "${SCR}") ADD_CUSTOM_TARGET(usr_docs ${PYTHON_EXECUTABLE} ${f} smesh.py ${CMAKE_SOURCE_DIR}/src/SMESH_SWIG/smeshDC.py smesh - COMMAND mkdir tmp && ${CALL_STR} ${CMAKE_CURRENT_BINARY_DIR}/tmp_env.${EXT} && ${PYTHON_EXECUTABLE} ${f1} -o tmp/smesh.py StdMeshers + COMMAND mkdir -p tmp && ${CALL_STR} ${CMAKE_CURRENT_BINARY_DIR}/tmp_env.${EXT} && ${PYTHON_EXECUTABLE} ${f1} -o tmp/smesh.py StdMeshers COMMAND ${DOXYGEN_EXECUTABLE} doxyfile_py COMMAND ${DOXYGEN_EXECUTABLE} doxyfile COMMAND ${PYTHON_EXECUTABLE} -c "import os, shutil; os.remove(r'''smesh.py'''); shutil.rmtree(r'''tmp''')" @@ -76,3 +78,5 @@ ADD_CUSTOM_TARGET(usr_docs ${PYTHON_EXECUTABLE} ${f} smesh.py ${CMAKE_SOURCE_DIR VERBATIM WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) + +ADD_DEPENDENCIES(usr_docs html_docs) diff --git a/doc/salome/gui/SMESH/static/header.html.in b/doc/salome/gui/SMESH/static/header.html.in index 4571b4363..d434d830d 100755 --- a/doc/salome/gui/SMESH/static/header.html.in +++ b/doc/salome/gui/SMESH/static/header.html.in @@ -5,6 +5,8 @@ $title + + $treeview $search $mathjax diff --git a/doc/salome/gui/SMESH/static/header_py.html.in b/doc/salome/gui/SMESH/static/header_py.html.in index 61414bb57..22abb143c 100644 --- a/doc/salome/gui/SMESH/static/header_py.html.in +++ b/doc/salome/gui/SMESH/static/header_py.html.in @@ -5,6 +5,8 @@ $title + + $treeview $search $mathjax diff --git a/doc/salome/tui/static/header.html.in b/doc/salome/tui/static/header.html.in index 4571b4363..d434d830d 100755 --- a/doc/salome/tui/static/header.html.in +++ b/doc/salome/tui/static/header.html.in @@ -5,6 +5,8 @@ $title + + $treeview $search $mathjax diff --git a/src/Controls/SMESH_Controls.cxx b/src/Controls/SMESH_Controls.cxx index eb1e5bdb9..0e6cc8cec 100644 --- a/src/Controls/SMESH_Controls.cxx +++ b/src/Controls/SMESH_Controls.cxx @@ -1294,7 +1294,11 @@ double Warping::GetValue( const TSequenceOfXYZ& P ) double A3 = ComputeA( P( 3 ), P( 4 ), P( 1 ), G ); double A4 = ComputeA( P( 4 ), P( 1 ), P( 2 ), G ); - return Max( Max( A1, A2 ), Max( A3, A4 ) ); + double val = Max( Max( A1, A2 ), Max( A3, A4 ) ); + + const double eps = 0.1; // val is in degrees + + return val < eps ? 0. : val; } double Warping::ComputeA( const gp_XYZ& thePnt1, @@ -1362,7 +1366,11 @@ double Taper::GetValue( const TSequenceOfXYZ& P ) double T3 = fabs( ( J3 - JA ) / JA ); double T4 = fabs( ( J4 - JA ) / JA ); - return Max( Max( T1, T2 ), Max( T3, T4 ) ); + double val = Max( Max( T1, T2 ), Max( T3, T4 ) ); + + const double eps = 0.01; + + return val < eps ? 0. : val; } double Taper::GetBadRate( double Value, int /*nbNodes*/ ) const @@ -1402,7 +1410,7 @@ double Skew::GetValue( const TSequenceOfXYZ& P ) return 0.; // Compute skew - static double PI2 = M_PI / 2.; + const double PI2 = M_PI / 2.; if ( P.size() == 3 ) { double A0 = fabs( PI2 - skewAngle( P( 3 ), P( 1 ), P( 2 ) ) ); @@ -1422,11 +1430,11 @@ double Skew::GetValue( const TSequenceOfXYZ& P ) double A = v1.Magnitude() <= gp::Resolution() || v2.Magnitude() <= gp::Resolution() ? 0. : fabs( PI2 - v1.Angle( v2 ) ); - //BUG SWP12743 - if ( A < theEps ) - return theInf; + double val = A * 180. / M_PI; - return A * 180. / M_PI; + const double eps = 0.1; // val is in degrees + + return val < eps ? 0. : val; } } diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index 2e8a96307..44e5a46d3 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -63,18 +63,16 @@ using namespace std; SMESH_Gen::SMESH_Gen() { - MESSAGE("SMESH_Gen::SMESH_Gen"); - _localId = 0; - _hypId = 0; - _segmentation = _nbSegments = 10; - SMDS_Mesh::_meshList.clear(); - MESSAGE(SMDS_Mesh::_meshList.size()); - //_counters = new counters(100); -#ifdef WITH_SMESH_CANCEL_COMPUTE - _compute_canceled = false; - _sm_current = NULL; -#endif - //vtkDebugLeaks::SetExitError(0); + MESSAGE("SMESH_Gen::SMESH_Gen"); + _localId = 0; + _hypId = 0; + _segmentation = _nbSegments = 10; + SMDS_Mesh::_meshList.clear(); + MESSAGE(SMDS_Mesh::_meshList.size()); + //_counters = new counters(100); + _compute_canceled = false; + _sm_current = NULL; + //vtkDebugLeaks::SetExitError(0); } //============================================================================= @@ -145,6 +143,11 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, const int globalAlgoDim = 100; SMESH_subMeshIteratorPtr smIt; + SMESH_subMesh::compute_event computeEvent; + if ( !anUpward && aShape.IsSame( aMesh.GetShapeToMesh() )) + computeEvent = SMESH_subMesh::COMPUTE; + else + computeEvent = SMESH_subMesh::COMPUTE_SUBMESH; if ( anUpward ) // is called from below code here { @@ -172,15 +175,11 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, if (smToCompute->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE) { -#ifdef WITH_SMESH_CANCEL_COMPUTE if (_compute_canceled) return false; _sm_current = smToCompute; -#endif - smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE ); -#ifdef WITH_SMESH_CANCEL_COMPUTE + smToCompute->ComputeStateEngine( computeEvent ); _sm_current = NULL; -#endif } // we check all the submeshes here and detect if any of them failed to compute @@ -258,15 +257,11 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, } else { -#ifdef WITH_SMESH_CANCEL_COMPUTE if (_compute_canceled) return false; _sm_current = smToCompute; -#endif - smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE ); -#ifdef WITH_SMESH_CANCEL_COMPUTE + smToCompute->ComputeStateEngine( computeEvent ); _sm_current = NULL; -#endif if ( aShapesId ) aShapesId->insert( smToCompute->GetId() ); } @@ -342,15 +337,11 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, if ( aShapesId && GetShapeDim( aShType ) > (int)aDim ) continue; -#ifdef WITH_SMESH_CANCEL_COMPUTE if (_compute_canceled) return false; _sm_current = sm; -#endif - sm->ComputeStateEngine( SMESH_subMesh::COMPUTE ); -#ifdef WITH_SMESH_CANCEL_COMPUTE + sm->ComputeStateEngine( computeEvent ); _sm_current = NULL; -#endif if ( aShapesId ) aShapesId->insert( sm->GetId() ); } diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index a6a4d9b71..73ad58659 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -7656,6 +7656,12 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) //MESSAGE(" node to remove " << nToRemove->GetID()); rmNodeIds.push_back( nToRemove->GetID() ); AddToSameGroups( nToKeep, nToRemove, aMesh ); + // set _alwaysComputed to a sub-mesh of VERTEX to enable mesh computing + // after MergeNodes() w/o creating node in place of merged ones. + const SMDS_PositionPtr& pos = nToRemove->GetPosition(); + if ( pos && pos->GetTypeOfPosition() == SMDS_TOP_VERTEX ) + if ( SMESH_subMesh* sm = myMesh->GetSubMeshContaining( nToRemove->getshapeId() )) + sm->SetIsAlwaysComputed( true ); } SMDS_ElemIteratorPtr invElemIt = nToRemove->GetInverseElementIterator(); diff --git a/src/SMESH/SMESH_MesherHelper.cxx b/src/SMESH/SMESH_MesherHelper.cxx index e1f970970..258c8ff8a 100644 --- a/src/SMESH/SMESH_MesherHelper.cxx +++ b/src/SMESH/SMESH_MesherHelper.cxx @@ -513,6 +513,7 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F, bool* check) const { gp_Pnt2d uv( Precision::Infinite(), Precision::Infinite() ); + const SMDS_PositionPtr Pos = n->GetPosition(); bool uvOK = false; if(Pos->GetTypeOfPosition()==SMDS_TOP_FACE) @@ -797,7 +798,8 @@ double SMESH_MesherHelper::GetNodeU(const TopoDS_Edge& E, const SMDS_MeshNode* inEdgeNode, bool* check) { - double param = 0; + double param = Precision::Infinite(); + const SMDS_PositionPtr pos = n->GetPosition(); if ( pos->GetTypeOfPosition()==SMDS_TOP_EDGE ) { @@ -1134,8 +1136,8 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetCentralNode(const SMDS_MeshNode* n1, Handle( Geom_Surface ) S = BRep_Tool::Surface( F, loc ); P = S->Value( uvAvg.X(), uvAvg.Y() ).Transformed( loc ); centralNode = meshDS->AddNode( P.X(), P.Y(), P.Z() ); - if ( mySetElemOnShape ) - meshDS->SetNodeOnFace( centralNode, faceID, uvAvg.X(), uvAvg.Y() ); + // if ( mySetElemOnShape ) node is not elem! + meshDS->SetNodeOnFace( centralNode, faceID, uvAvg.X(), uvAvg.Y() ); myMapWithCentralNode.insert( std::make_pair( keyOfMap, centralNode ) ); return centralNode; } @@ -1147,23 +1149,23 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetCentralNode(const SMDS_MeshNode* n1, SMESH_TNodeXYZ( n4 ) ) / 4; centralNode = meshDS->AddNode( P.X(), P.Y(), P.Z() ); - if ( mySetElemOnShape ) + if ( !F.IsNull() ) { - if ( !F.IsNull() ) - { - uvAvg = (GetNodeUV(F,n1,n3) + - GetNodeUV(F,n2,n4) + - GetNodeUV(F,n3,n1) + - GetNodeUV(F,n4,n2)) / 4; - CheckNodeUV( F, centralNode, uvAvg, 2*BRep_Tool::Tolerance( F ), /*force=*/true); - meshDS->SetNodeOnFace( centralNode, faceID, uvAvg.X(), uvAvg.Y() ); - } - else if ( shapeID > 0 ) - meshDS->SetNodeInVolume( centralNode, shapeID ); - else if ( myShapeID > 0 ) - meshDS->SetMeshElementOnShape( centralNode, myShapeID ); + uvAvg = (GetNodeUV(F,n1,n3) + + GetNodeUV(F,n2,n4) + + GetNodeUV(F,n3,n1) + + GetNodeUV(F,n4,n2)) / 4; + CheckNodeUV( F, centralNode, uvAvg, 2*BRep_Tool::Tolerance( F ), /*force=*/true); + meshDS->SetNodeOnFace( centralNode, faceID, uvAvg.X(), uvAvg.Y() ); + } + else if ( shapeID > 0 ) + { + meshDS->SetNodeInVolume( centralNode, shapeID ); + } + else if ( myShapeID > 0 && mySetElemOnShape ) + { + meshDS->SetMeshElementOnShape( centralNode, myShapeID ); } - myMapWithCentralNode.insert( std::make_pair( keyOfMap, centralNode ) ); return centralNode; } @@ -1247,8 +1249,8 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1, gp_XY UV = GetMiddleUV( S, uv[0], uv[1] ); gp_Pnt P = S->Value( UV.X(), UV.Y() ).Transformed(loc); n12 = meshDS->AddNode(P.X(), P.Y(), P.Z()); - if ( mySetElemOnShape ) - meshDS->SetNodeOnFace(n12, faceID, UV.X(), UV.Y()); + // if ( mySetElemOnShape ) node is not elem! + meshDS->SetNodeOnFace(n12, faceID, UV.X(), UV.Y()); myTLinkNodeMap.insert(make_pair(link,n12)); return n12; } @@ -1272,8 +1274,8 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1, gp_Pnt P = C->Value( U ); n12 = meshDS->AddNode(P.X(), P.Y(), P.Z()); - if ( mySetElemOnShape ) - meshDS->SetNodeOnEdge(n12, edgeID, U); + //if ( mySetElemOnShape ) node is not elem! + meshDS->SetNodeOnEdge(n12, edgeID, U); myTLinkNodeMap.insert(make_pair(link,n12)); return n12; } @@ -1286,21 +1288,21 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1, double z = ( n1->Z() + n2->Z() )/2.; n12 = meshDS->AddNode(x,y,z); - if ( mySetElemOnShape ) + //if ( mySetElemOnShape ) node is not elem! { if ( !F.IsNull() ) { gp_XY UV = ( uv[0] + uv[1] ) / 2.; - CheckNodeUV( F, n12, UV, 2*BRep_Tool::Tolerance( F ), /*force=*/true); + CheckNodeUV( F, n12, UV, 2 * BRep_Tool::Tolerance( F ), /*force=*/true); meshDS->SetNodeOnFace(n12, faceID, UV.X(), UV.Y() ); } else if ( !E.IsNull() ) { double U = ( u[0] + u[1] ) / 2.; - CheckNodeU( E, n12, U, 2*BRep_Tool::Tolerance( E ), /*force=*/true); + CheckNodeU( E, n12, U, 2 * BRep_Tool::Tolerance( E ), /*force=*/true); meshDS->SetNodeOnEdge(n12, edgeID, U); } - else if ( myShapeID > 0 ) + else if ( myShapeID > 0 && mySetElemOnShape ) { meshDS->SetMeshElementOnShape(n12, myShapeID); } @@ -1375,8 +1377,8 @@ const SMDS_MeshNode* SMESH_MesherHelper::getMediumNodeOnComposedWire(const SMDS_ GetMeshDS()->MoveNode( n12, p.X(), p.Y(), p.Z() ); } - if ( mySetElemOnShape ) - GetMeshDS()->SetNodeOnEdge(n12, edges[iOkEdge], u); + //if ( mySetElemOnShape ) node is not elem! + GetMeshDS()->SetNodeOnEdge(n12, edges[iOkEdge], u); myTLinkNodeMap.insert( make_pair( SMESH_TLink(n1,n2), n12 )); @@ -1397,7 +1399,7 @@ SMDS_MeshNode* SMESH_MesherHelper::AddNode(double x, double y, double z, int ID, node = meshDS->AddNodeWithID( x, y, z, ID ); else node = meshDS->AddNode( x, y, z ); - if ( mySetElemOnShape && myShapeID > 0 ) { + if ( mySetElemOnShape && myShapeID > 0 ) { // node is not elem ? switch ( myShape.ShapeType() ) { case TopAbs_SOLID: meshDS->SetNodeInVolume( node, myShapeID); break; case TopAbs_SHELL: meshDS->SetNodeInVolume( node, myShapeID); break; @@ -2015,7 +2017,6 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2 if ( theParam2ColumnMap.empty() ) { // get data of edges for normalization of params - vector< double > length; double fullLen = 0; list::const_iterator edge; @@ -2039,8 +2040,8 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2 map< double, const SMDS_MeshNode*>::iterator u_n = sortedBaseNN.begin(); if ( theProxyMesh ) // from sortedBaseNN remove nodes not shared by faces of faceSubMesh { - const SMDS_MeshNode* n1 = sortedBaseNN.begin()->second; - const SMDS_MeshNode* n2 = sortedBaseNN.rbegin()->second; + const SMDS_MeshNode* n1 = (++sortedBaseNN.begin())->second; + const SMDS_MeshNode* n2 = (++sortedBaseNN.rbegin())->second; bool allNodesAreProxy = ( n1 != theProxyMesh->GetProxyNode( n1 ) && n2 != theProxyMesh->GetProxyNode( n2 )); if ( allNodesAreProxy ) @@ -2052,7 +2053,7 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2 while ( ++u_n != sortedBaseNN.end() && !isNodeInSubMesh( u_n->second, faceSubMesh )); sortedBaseNN.erase( sortedBaseNN.begin(), u_n ); } - else if ( u_n = --sortedBaseNN.end(), !isNodeInSubMesh( u_n->second, faceSubMesh )) + if ( u_n = --sortedBaseNN.end(), !isNodeInSubMesh( u_n->second, faceSubMesh )) { while ( u_n != sortedBaseNN.begin() && !isNodeInSubMesh( (--u_n)->second, faceSubMesh )); sortedBaseNN.erase( ++u_n, sortedBaseNN.end() ); diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index 08b033dc9..9afb7677c 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -1336,6 +1336,7 @@ bool SMESH_subMesh::ComputeStateEngine(int event) switch ( event ) { case MODIF_ALGO_STATE: case COMPUTE: + case COMPUTE_SUBMESH: //case COMPUTE_CANCELED: case CLEAN: //case SUBMESH_COMPUTED: @@ -1351,7 +1352,8 @@ bool SMESH_subMesh::ComputeStateEngine(int event) { _computeState = READY_TO_COMPUTE; SMESHDS_SubMesh* smDS = GetSubMeshDS(); - if ( smDS && smDS->NbNodes() ) { + if ( smDS && smDS->NbNodes() ) + { if ( event == CLEAN ) { cleanDependants(); cleanSubMesh( this ); @@ -1359,7 +1361,9 @@ bool SMESH_subMesh::ComputeStateEngine(int event) else _computeState = COMPUTE_OK; } - else if ( event == COMPUTE && !_alwaysComputed ) { + else if (( event == COMPUTE || event == COMPUTE_SUBMESH ) + && !_alwaysComputed ) + { const TopoDS_Vertex & V = TopoDS::Vertex( _subShape ); gp_Pnt P = BRep_Tool::Pnt(V); if ( SMDS_MeshNode * n = _father->GetMeshDS()->AddNode(P.X(), P.Y(), P.Z()) ) { @@ -1393,11 +1397,10 @@ bool SMESH_subMesh::ComputeStateEngine(int event) _computeState = READY_TO_COMPUTE; break; case COMPUTE: // nothing to do + case COMPUTE_SUBMESH: break; -#ifdef WITH_SMESH_CANCEL_COMPUTE - case COMPUTE_CANCELED: // nothing to do + case COMPUTE_CANCELED: // nothing to do break; -#endif case CLEAN: cleanDependants(); removeSubMeshElementsAndNodes(); @@ -1440,6 +1443,7 @@ bool SMESH_subMesh::ComputeStateEngine(int event) } break; case COMPUTE: + case COMPUTE_SUBMESH: { algo = GetAlgo(); ASSERT(algo); @@ -1455,10 +1459,16 @@ bool SMESH_subMesh::ComputeStateEngine(int event) // check submeshes needed if (_father->HasShapeToMesh() ) { bool subComputed = false, subFailed = false; - if (!algo->OnlyUnaryInput()) - shape = getCollection( gen, algo, subComputed, subFailed ); - else + if (!algo->OnlyUnaryInput()) { + if ( event == COMPUTE && + ( algo->NeedDiscreteBoundary() || algo->SupportSubmeshes() )) + shape = getCollection( gen, algo, subComputed, subFailed ); + else + subComputed = SubMeshesComputed( & subFailed ); + } + else { subComputed = SubMeshesComputed(); + } ret = ( algo->NeedDiscreteBoundary() ? subComputed : algo->SupportSubmeshes() ? !subFailed : ( !subComputed || _father->IsNotConformAllowed() )); @@ -1607,10 +1617,8 @@ bool SMESH_subMesh::ComputeStateEngine(int event) } } break; -#ifdef WITH_SMESH_CANCEL_COMPUTE case COMPUTE_CANCELED: // nothing to do break; -#endif case CLEAN: cleanDependants(); removeSubMeshElementsAndNodes(); @@ -1664,10 +1672,8 @@ bool SMESH_subMesh::ComputeStateEngine(int event) break; case COMPUTE: // nothing to do break; -#ifdef WITH_SMESH_CANCEL_COMPUTE - case COMPUTE_CANCELED: // nothing to do + case COMPUTE_CANCELED: // nothing to do break; -#endif case CLEAN: cleanDependants(); // clean sub-meshes, dependant on this one, with event CLEAN removeSubMeshElementsAndNodes(); @@ -1721,7 +1727,8 @@ bool SMESH_subMesh::ComputeStateEngine(int event) else _computeState = NOT_READY; break; - case COMPUTE: // nothing to do + case COMPUTE: // nothing to do + case COMPUTE_SUBMESH: break; case COMPUTE_CANCELED: { @@ -2369,6 +2376,7 @@ void SMESH_subMeshEventListener::ProcessEvent(const int event, (*smIt)->ComputeStateEngine( event ); break; case SMESH_subMesh::COMPUTE: + case SMESH_subMesh::COMPUTE_SUBMESH: if ( subMesh->GetComputeState() == SMESH_subMesh::COMPUTE_OK ) for ( ; smIt != smEnd; ++ smIt) (*smIt)->ComputeStateEngine( SMESH_subMesh::SUBMESH_COMPUTED ); diff --git a/src/SMESH/SMESH_subMesh.hxx b/src/SMESH/SMESH_subMesh.hxx index 669ef7164..5e0abcd72 100644 --- a/src/SMESH/SMESH_subMesh.hxx +++ b/src/SMESH/SMESH_subMesh.hxx @@ -107,7 +107,7 @@ class SMESH_EXPORT SMESH_subMesh }; enum compute_event { - MODIF_ALGO_STATE, COMPUTE, COMPUTE_CANCELED, + MODIF_ALGO_STATE, COMPUTE, COMPUTE_SUBMESH, COMPUTE_CANCELED, CLEAN, SUBMESH_COMPUTED, SUBMESH_RESTORED, SUBMESH_LOADED, MESH_ENTITY_REMOVED, CHECK_COMPUTE_STATE }; diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx index 826100787..c165c4366 100644 --- a/src/SMESHGUI/SMESHGUI.cxx +++ b/src/SMESHGUI/SMESHGUI.cxx @@ -1800,6 +1800,15 @@ } } + // Call mesh->Clear() to prevent loading mesh from file caused by hypotheses removal + for( It.Initialize( selected ); It.More(); It.Next()) // loop on selected IO's + { + Handle(SALOME_InteractiveObject) IObject = It.Value(); + SMESH::SMESH_Mesh_var mesh = SMESH::IObjectToInterface< SMESH::SMESH_Mesh >( IObject ); + if ( !mesh->_is_nil() ) + mesh->Clear(); + } + // Treat SO's in the list starting from the back aStudyBuilder->NewCommand(); // There is a transaction for ( ritSO = listSO.rbegin(); ritSO != listSO.rend(); ++ritSO ) diff --git a/src/SMESH_I/SMESH_2smeshpy.cxx b/src/SMESH_I/SMESH_2smeshpy.cxx index 5b10f9914..a30417611 100644 --- a/src/SMESH_I/SMESH_2smeshpy.cxx +++ b/src/SMESH_I/SMESH_2smeshpy.cxx @@ -179,6 +179,24 @@ namespace { void CheckObjectPresence( const Handle(_pyCommand)& cmd, set<_pyID> & presentObjects) { + // either comment or erase a command including NotPublishedObjectName() + if ( cmd->GetString().Location( TPythonDump::NotPublishedObjectName(), 1, cmd->Length() )) + { + bool isResultPublished = false; + for ( int i = 0; i < cmd->GetNbResultValues(); i++ ) + { + _pyID objID = cmd->GetResultValue( i+1 ); + if ( cmd->IsStudyEntry( objID )) + isResultPublished = (! theGen->IsNotPublished( objID )); + theGen->ObjectCreationRemoved( objID ); // objID.SetName( name ) is not needed + } + if ( isResultPublished ) + cmd->Comment(); + else + cmd->Clear(); + return; + } + // comment a command having not created args for ( int iArg = cmd->GetNbArgs(); iArg; --iArg ) { const _pyID& arg = cmd->GetArg( iArg ); @@ -192,14 +210,23 @@ namespace { cmd->Comment(); cmd->GetString() += " ### " ; cmd->GetString() += *id + " has not been yet created"; + for ( int i = 0; i < cmd->GetNbResultValues(); i++ ) { + _pyID objID = cmd->GetResultValue( i+1 ); + theGen->ObjectCreationRemoved( objID ); // objID.SetName( name ) is not needed + } return; } } + // comment a command having not created Object const _pyID& obj = cmd->GetObject(); if ( !obj.IsEmpty() && cmd->IsStudyEntry( obj ) && !presentObjects.count( obj )) { cmd->Comment(); cmd->GetString() += " ### not created object" ; + for ( int i = 0; i < cmd->GetNbResultValues(); i++ ) { + _pyID objID = cmd->GetResultValue( i+1 ); + theGen->ObjectCreationRemoved( objID ); // objID.SetName( name ) is not needed + } } const _pyID& result = cmd->GetResultValue(); if ( result.IsEmpty() || result.Value( 1 ) == '"' || result.Value( 1 ) == '\'' ) @@ -318,13 +345,15 @@ namespace { //================================================================================ /*! - * \brief Convert python script using commands of smesh.py - * \param theScript - Input script - * \retval TCollection_AsciiString - Convertion result - * \param theToKeepAllCommands - to keep all commands or - * to exclude commands relating to objects removed from study - * - * Class SMESH_2smeshpy declared in SMESH_PythonDump.hxx + * \brief Convert a python script using commands of smesh.py + * \param theScript - Input script + * \param theEntry2AccessorMethod - returns method names to access to + * objects wrapped with python class + * \param theObjectNames - names of objects + * \param theRemovedObjIDs - entries of objects whose created commands were removed + * \param theHistoricalDump - true means to keep all commands, false means + * to exclude commands relating to objects removed from study + * \retval TCollection_AsciiString - Convertion result */ //================================================================================ @@ -332,10 +361,15 @@ TCollection_AsciiString SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString& theScript, Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod, Resource_DataMapOfAsciiStringAsciiString& theObjectNames, + std::set< TCollection_AsciiString >& theRemovedObjIDs, SALOMEDS::Study_ptr& theStudy, const bool theToKeepAllCommands) { - theGen = new _pyGen( theEntry2AccessorMethod, theObjectNames, theStudy, theToKeepAllCommands ); + theGen = new _pyGen( theEntry2AccessorMethod, + theObjectNames, + theRemovedObjIDs, + theStudy, + theToKeepAllCommands ); // split theScript into separate commands @@ -345,9 +379,9 @@ SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString& theScrip while ( from < end && ( to = theScript.Location( "\n", from, end ))) { if ( to != from ) - // cut out and store a command - aNoteBook->AddCommand( theScript.SubString( from, to - 1 )); - from = to + 1; + // cut out and store a command + aNoteBook->AddCommand( theScript.SubString( from, to - 1 )); + from = to + 1; } aNoteBook->ReplaceVariables(); @@ -416,12 +450,14 @@ SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString& theScrip _pyGen::_pyGen(Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod, Resource_DataMapOfAsciiStringAsciiString& theObjectNames, + std::set< TCollection_AsciiString >& theRemovedObjIDs, SALOMEDS::Study_ptr& theStudy, const bool theToKeepAllCommands) : _pyObject( new _pyCommand( "", 0 )), myNbCommands( 0 ), myID2AccessorMethod( theEntry2AccessorMethod ), myObjectNames( theObjectNames ), + myRemovedObjIDs( theRemovedObjIDs ), myNbFilters( 0 ), myToKeepAllCommands( theToKeepAllCommands ), myStudy( SALOMEDS::Study::_duplicate( theStudy )), @@ -787,7 +823,7 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand ) method == "CreateMeshesFromSAUV"|| method == "CreateMeshesFromGMF" ) { - for(int ind = 0;indGetNbResultValues();ind++) + for ( int ind = 0; ind < theCommand->GetNbResultValues(); ind++ ) { _pyID meshID = theCommand->GetResultValue(ind+1); if ( !theCommand->IsStudyEntry( meshID ) ) continue; @@ -1368,6 +1404,19 @@ bool _pyGen::IsNotPublished(const _pyID& theObjID) const return true; // SMESH object not in study } +//================================================================================ +/*! + * \brief Remove object name from myObjectNames that leads to that SetName() for + * this object is not dumped + * \param [in] theObjID - entry of the object whose creation command was eliminated + */ +//================================================================================ + +void _pyGen::ObjectCreationRemoved(const _pyID& theObjID) +{ + myRemovedObjIDs.insert( theObjID ); +} + //================================================================================ /*! * \brief Return reader of hypotheses of plugins @@ -3184,22 +3233,21 @@ const TCollection_AsciiString & _pyCommand::GetResultValue() //================================================================================ /*! * \brief Return number of python command result value ResultValue = Obj.Meth() - * \retval const int */ //================================================================================ -const int _pyCommand::GetNbResultValues() +int _pyCommand::GetNbResultValues() { + int nb = 0; int begPos = 1; - int Nb=0; int endPos = myString.Location( "=", 1, Length() ); - TCollection_AsciiString str = ""; - while ( begPos < endPos) { - str = GetWord( myString, begPos, true ); + while ( begPos < endPos ) + { + _AString str = GetWord( myString, begPos, true ); begPos = begPos+ str.Length(); - Nb++; + nb++; } - return (Nb-1); + return (nb-1); } diff --git a/src/SMESH_I/SMESH_2smeshpy.hxx b/src/SMESH_I/SMESH_2smeshpy.hxx index feb720f5f..184a475e4 100644 --- a/src/SMESH_I/SMESH_2smeshpy.hxx +++ b/src/SMESH_I/SMESH_2smeshpy.hxx @@ -123,7 +123,7 @@ public: bool IsEmpty() const { return myString.IsEmpty(); } _AString GetIndentation(); const _AString & GetResultValue(); - const int GetNbResultValues(); + int GetNbResultValues(); _AString GetResultValue(int res); const _AString & GetObject(); const _AString & GetMethod(); @@ -223,6 +223,7 @@ class _pyGen: public _pyObject public: _pyGen(Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod, Resource_DataMapOfAsciiStringAsciiString& theObjectNames, + std::set< TCollection_AsciiString >& theRemovedObjIDs, SALOMEDS::Study_ptr& theStudy, const bool theToKeepAllCommands); Handle(_pyCommand) AddCommand( const _AString& theCommand ); @@ -236,8 +237,8 @@ public: _pyID GenerateNewID( const _pyID& theID ); void AddObject( Handle(_pyObject)& theObj ); void SetProxyObject( const _pyID& theID, Handle(_pyObject)& theObj ); - Handle(_pyObject) FindObject( const _pyID& theObjID ) const; - Handle(_pySubMesh) FindSubMesh( const _pyID& theSubMeshID ); + Handle(_pyObject) FindObject( const _pyID& theObjID ) const; + Handle(_pySubMesh) FindSubMesh( const _pyID& theSubMeshID ); Handle(_pyHypothesis) FindHyp( const _pyID& theHypID ); Handle(_pyHypothesis) FindAlgo( const _pyID& theGeom, const _pyID& theMesh, const Handle(_pyHypothesis)& theHypothesis); @@ -249,6 +250,7 @@ public: bool IsGeomObject(const _pyID& theObjID) const; bool IsNotPublished(const _pyID& theObjID) const; + void ObjectCreationRemoved(const _pyID& theObjID); bool IsToKeepAllCommands() const { return myToKeepAllCommands; } void AddExportedMesh(const _AString& file, const ExportedMeshData& mesh ) { myFile2ExportedMesh[ file ] = mesh; } @@ -268,21 +270,22 @@ private: const bool theIsAfter ); private: - std::map< _pyID, Handle(_pyMesh) > myMeshes; - std::map< _pyID, Handle(_pyMeshEditor) > myMeshEditors; - std::map< _pyID, Handle(_pyObject) > myObjects; - std::list< Handle(_pyHypothesis) > myHypos; - std::list< Handle(_pyCommand) > myCommands; - int myNbCommands; + std::map< _pyID, Handle(_pyMesh) > myMeshes; + std::map< _pyID, Handle(_pyMeshEditor) > myMeshEditors; + std::map< _pyID, Handle(_pyObject) > myObjects; + std::list< Handle(_pyHypothesis) > myHypos; + std::list< Handle(_pyCommand) > myCommands; + int myNbCommands; Resource_DataMapOfAsciiStringAsciiString& myID2AccessorMethod; Resource_DataMapOfAsciiStringAsciiString& myObjectNames; - Handle(_pyCommand) myLastCommand; - int myNbFilters; - bool myToKeepAllCommands; - SALOMEDS::Study_var myStudy; - int myGeomIDNb, myGeomIDIndex; - std::map< _AString, ExportedMeshData > myFile2ExportedMesh; - Handle( _pyHypothesisReader ) myHypReader; + std::set< TCollection_AsciiString >& myRemovedObjIDs; + Handle(_pyCommand) myLastCommand; + int myNbFilters; + bool myToKeepAllCommands; + SALOMEDS::Study_var myStudy; + int myGeomIDNb, myGeomIDIndex; + std::map< _AString, ExportedMeshData > myFile2ExportedMesh; + Handle( _pyHypothesisReader ) myHypReader; DEFINE_STANDARD_RTTI (_pyGen) }; diff --git a/src/SMESH_I/SMESH_DumpPython.cxx b/src/SMESH_I/SMESH_DumpPython.cxx index 34c1c32cc..cebc6e37e 100644 --- a/src/SMESH_I/SMESH_DumpPython.cxx +++ b/src/SMESH_I/SMESH_DumpPython.cxx @@ -43,15 +43,11 @@ static int MYDEBUG = 0; static int MYDEBUG = 0; #endif -static TCollection_AsciiString NotPublishedObjectName() -{ - return "__NOT__Published__Object__"; -} - namespace SMESH { size_t TPythonDump::myCounter = 0; + const char theNotPublishedObjectName[] = "__NOT__Published__Object__"; TVar::TVar(CORBA::Double value):myVals(1) { myVals[0] = SMESH_Comment(value); } TVar::TVar(CORBA::Long value):myVals(1) { myVals[0] = SMESH_Comment(value); } @@ -279,7 +275,7 @@ namespace SMESH myStream << entry.in(); } else { - myStream << NotPublishedObjectName(); + myStream << theNotPublishedObjectName; } return *this; } @@ -298,7 +294,7 @@ namespace SMESH if ( aSMESHGen->CanPublishInStudy( theArg )) // not published SMESH object myStream << "smeshObj_" << size_t(theArg); else - myStream << NotPublishedObjectName(); + myStream << theNotPublishedObjectName; } else myStream << "None"; @@ -343,7 +339,7 @@ namespace SMESH SMESH::ElementType type = types->length() ? types[0] : SMESH::ALL; return *this << mesh << ".GetIDSource(" << anElementsId << ", " << type << ")"; } - return *this; + return *this << theNotPublishedObjectName; } TPythonDump& @@ -505,6 +501,10 @@ namespace SMESH DumpArray( theList, *this ); return *this; } + const char* TPythonDump::NotPublishedObjectName() + { + return theNotPublishedObjectName; + } TCollection_AsciiString myLongStringStart( "TPythonDump::LongStringStart" ); TCollection_AsciiString myLongStringEnd ( "TPythonDump::LongStringEnd" ); @@ -679,7 +679,7 @@ Engines::TMPFile* SMESH_Gen_i::DumpPython (CORBA::Object_ptr theStudy, CORBA::Octet* anOctetBuf = (CORBA::Octet*)aBuffer; Engines::TMPFile_var aStreamFile = new Engines::TMPFile(aLen+1, aLen+1, anOctetBuf, 1); - bool hasNotPublishedObjects = aScript.Location( NotPublishedObjectName(), 1, aLen); + bool hasNotPublishedObjects = aScript.Location( SMESH::theNotPublishedObjectName, 1, aLen); isValidScript = isValidScript && !hasNotPublishedObjects; return aStreamFile._retn(); @@ -915,9 +915,11 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl // Some objects are wrapped with python classes and // Resource_DataMapOfAsciiStringAsciiString holds methods returning wrapped objects Resource_DataMapOfAsciiStringAsciiString anEntry2AccessorMethod; + std::set< TCollection_AsciiString > aRemovedObjIDs; if ( !getenv("NO_2smeshpy_conversion")) aScript = SMESH_2smeshpy::ConvertScript( aScript, anEntry2AccessorMethod, - theObjectNames, theStudy, isHistoricalDump ); + theObjectNames, aRemovedObjIDs, + theStudy, isHistoricalDump ); // Replace characters used instead of quote marks to quote notebook variables { @@ -1017,6 +1019,7 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl anUpdatedScript += "\n\taStudyBuilder = theStudy.NewBuilder()"; } for (int ir = 1; ir <= seqRemoved.Length(); ir++) { + if ( aRemovedObjIDs.count( seqRemoved.Value(ir) )) continue; anUpdatedScript += "\n\tSO = theStudy.FindObjectIOR(theStudy.ConvertObjectToIOR("; anUpdatedScript += seqRemoved.Value(ir); // for object wrapped by class of smesh.py @@ -1037,13 +1040,14 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl for (Standard_Integer i = 1; i <= aLen; i += 2) { anEntry = aScript.SubString(aSeq->Value(i), aSeq->Value(i + 1)); - aName = geom->GetDumpName( anEntry.ToCString() ); + aName = geom->GetDumpName( anEntry.ToCString() ); if (aName.IsEmpty() && // Not a GEOM object theNames.IsBound(anEntry) && + !aRemovedObjIDs.count(anEntry) && // a command creating anEntry was erased !mapEntries.IsBound(anEntry) && // Not yet processed !mapRemoved.IsBound(anEntry)) // Was not removed { - aName = theObjectNames.Find(anEntry); + aName = theObjectNames.Find(anEntry); aGUIName = theNames.Find(anEntry); mapEntries.Bind(anEntry, aName); anUpdatedScript += helper + "\n\t" + aSMESHGen + ".SetName(" + aName; diff --git a/src/SMESH_I/SMESH_PythonDump.hxx b/src/SMESH_I/SMESH_PythonDump.hxx index 4ff5cfc28..0646d94d1 100644 --- a/src/SMESH_I/SMESH_PythonDump.hxx +++ b/src/SMESH_I/SMESH_PythonDump.hxx @@ -31,6 +31,7 @@ #include #include +#include class SMESH_Gen_i; class SMESH_MeshEditor_i; @@ -51,8 +52,10 @@ public: /*! * \brief Convert a python script using commands of smesh.py * \param theScript - Input script - * \param theEntry2AccessorMethod - The returning method names to access to + * \param theEntry2AccessorMethod - returns method names to access to * objects wrapped with python class + * \param theObjectNames - names of objects + * \param theRemovedObjIDs - entries of objects whose created commands were removed * \param theHistoricalDump - true means to keep all commands, false means * to exclude commands relating to objects removed from study * \retval TCollection_AsciiString - Convertion result @@ -61,6 +64,7 @@ public: ConvertScript(const TCollection_AsciiString& theScript, Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod, Resource_DataMapOfAsciiStringAsciiString& theObjectNames, + std::set< TCollection_AsciiString >& theRemovedObjIDs, SALOMEDS::Study_ptr& theStudy, const bool theHistoricalDump); @@ -213,6 +217,7 @@ namespace SMESH static const char* SMESHGenName() { return "smeshgen"; } static const char* MeshEditorName() { return "mesh_editor"; } + static const char* NotPublishedObjectName(); /*! * \brief Return marker of long string literal beginning diff --git a/src/SMESH_SWIG/smeshDC.py b/src/SMESH_SWIG/smeshDC.py index 7c0e108e0..4f15ee606 100644 --- a/src/SMESH_SWIG/smeshDC.py +++ b/src/SMESH_SWIG/smeshDC.py @@ -276,15 +276,15 @@ def AssureGeomPublished(mesh, geom, name=''): ## Return the first vertex of a geomertical edge by ignoring orienation def FirstVertexOnCurve(edge): - from geompy import SubShapeAll, ShapeType, KindOfShape, PointCoordinates + from geompy import SubShapeAll, ShapeType, MakeVertexOnCurve, PointCoordinates vv = SubShapeAll( edge, ShapeType["VERTEX"]) if not vv: raise TypeError, "Given object has no vertices" if len( vv ) == 1: return vv[0] - info = KindOfShape(edge) - xyz = info[1:4] # coords of the first vertex - xyz1 = PointCoordinates( vv[0] ) - xyz2 = PointCoordinates( vv[1] ) + v0 = MakeVertexOnCurve(edge,0.) + xyz = PointCoordinates( v0 ) # coords of the first vertex + xyz1 = PointCoordinates( vv[0] ) + xyz2 = PointCoordinates( vv[1] ) dist1, dist2 = 0,0 for i in range(3): dist1 += abs( xyz[i] - xyz1[i] ) @@ -3666,7 +3666,7 @@ class Mesh: ## Translates the elements # @param IDsOfElements list of elements ids - # @param Vector the direction of translation (DirStruct or vector) + # @param Vector the direction of translation (DirStruct or vector or 3 vector components) # @param Copy allows copying the translated elements # @param MakeGroups forces the generation of new groups from existing ones (if Copy) # @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise @@ -3676,6 +3676,8 @@ class Mesh: IDsOfElements = self.GetElementsId() if ( isinstance( Vector, geompyDC.GEOM._objref_GEOM_Object)): Vector = self.smeshpyD.GetDirStruct(Vector) + if isinstance( Vector, list ): + Vector = self.smeshpyD.MakeDirStruct(*Vector) self.mesh.SetParameters(Vector.PS.parameters) if Copy and MakeGroups: return self.editor.TranslateMakeGroups(IDsOfElements, Vector) @@ -3684,7 +3686,7 @@ class Mesh: ## Creates a new mesh of translated elements # @param IDsOfElements list of elements ids - # @param Vector the direction of translation (DirStruct or vector) + # @param Vector the direction of translation (DirStruct or vector or 3 vector components) # @param MakeGroups forces the generation of new groups from existing ones # @param NewMeshName the name of the newly created mesh # @return instance of Mesh class @@ -3694,13 +3696,15 @@ class Mesh: IDsOfElements = self.GetElementsId() if ( isinstance( Vector, geompyDC.GEOM._objref_GEOM_Object)): Vector = self.smeshpyD.GetDirStruct(Vector) + if isinstance( Vector, list ): + Vector = self.smeshpyD.MakeDirStruct(*Vector) self.mesh.SetParameters(Vector.PS.parameters) mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName) return Mesh ( self.smeshpyD, self.geompyD, mesh ) ## Translates the object # @param theObject the object to translate (mesh, submesh, or group) - # @param Vector direction of translation (DirStruct or geom vector) + # @param Vector direction of translation (DirStruct or geom vector or 3 vector components) # @param Copy allows copying the translated elements # @param MakeGroups forces the generation of new groups from existing ones (if Copy) # @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise @@ -3710,6 +3714,8 @@ class Mesh: theObject = theObject.GetMesh() if ( isinstance( Vector, geompyDC.GEOM._objref_GEOM_Object)): Vector = self.smeshpyD.GetDirStruct(Vector) + if isinstance( Vector, list ): + Vector = self.smeshpyD.MakeDirStruct(*Vector) self.mesh.SetParameters(Vector.PS.parameters) if Copy and MakeGroups: return self.editor.TranslateObjectMakeGroups(theObject, Vector) @@ -3718,16 +3724,18 @@ class Mesh: ## Creates a new mesh from the translated object # @param theObject the object to translate (mesh, submesh, or group) - # @param Vector the direction of translation (DirStruct or geom vector) + # @param Vector the direction of translation (DirStruct or geom vector or 3 vector components) # @param MakeGroups forces the generation of new groups from existing ones # @param NewMeshName the name of the newly created mesh # @return instance of Mesh class # @ingroup l2_modif_trsf def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""): - if (isinstance(theObject, Mesh)): + if isinstance( theObject, Mesh ): theObject = theObject.GetMesh() - if (isinstance(Vector, geompyDC.GEOM._objref_GEOM_Object)): + if isinstance( Vector, geompyDC.GEOM._objref_GEOM_Object ): Vector = self.smeshpyD.GetDirStruct(Vector) + if isinstance( Vector, list ): + Vector = self.smeshpyD.MakeDirStruct(*Vector) self.mesh.SetParameters(Vector.PS.parameters) mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName) return Mesh( self.smeshpyD, self.geompyD, mesh ) diff --git a/src/SMESH_SWIG/smesh_algorithm.py b/src/SMESH_SWIG/smesh_algorithm.py index 9b3acf00d..e71c3c631 100644 --- a/src/SMESH_SWIG/smesh_algorithm.py +++ b/src/SMESH_SWIG/smesh_algorithm.py @@ -71,6 +71,7 @@ class Mesh_Algorithm: # @return SMESH.SMESH_Hypothesis def FindHypothesis (self, hypname, args, CompareMethod, smeshpyD): study = smeshpyD.GetCurrentStudy() + if not study: return None #to do: find component by smeshpyD object, not by its data type scomp = study.FindComponent(smeshpyD.ComponentDataType()) if scomp is not None: diff --git a/src/StdMeshers/StdMeshers_AutomaticLength.cxx b/src/StdMeshers/StdMeshers_AutomaticLength.cxx index d12f51a34..5d2543666 100644 --- a/src/StdMeshers/StdMeshers_AutomaticLength.cxx +++ b/src/StdMeshers/StdMeshers_AutomaticLength.cxx @@ -117,15 +117,29 @@ namespace { */ //================================================================================ - const double a14divPI = 14. / M_PI; + //const double a14divPI = 14. / M_PI; + const double a2div7divPI = 2. / 7. / M_PI; inline double segLength(double S0, double edgeLen, double minLen ) { // PAL10237 - // S = S0 * f(L/Lmin) where f(x) = 1 + (2/Pi * 7 * atan(x/5) ) + // S = S0 * f(L/Lmin) where + // f(x) = 1 + (7 * 2/Pi * atan(x/5)) // => // S = S0 * ( 1 + 14/PI * atan( L / ( 5 * Lmin ))) - return S0 * ( 1. + a14divPI * atan( edgeLen / ( 5 * minLen ))); + // + // return S0 * ( 1. + a14divPI * atan( edgeLen / ( 5 * minLen ))); + + // The above formular gives too short segments when Lmax/Lmin is too high + // because by this formular the largest segment is only 8 times longer than the + // shortest one ( 2/Pi * atan(x/5) varies within [0,1] ). So a new formular is: + // + // f(x) = 1 + (x/7 * 2/Pi * atan(x/5)) + // => + // S = S0 * ( 1 + 2/7/PI * L/Lmin * atan( 5 * L/Lmin )) + // + const double Lratio = edgeLen / minLen; + return S0 * ( 1. + a2div7divPI * Lratio * atan( 5 * Lratio )); } //================================================================================ @@ -164,22 +178,22 @@ namespace { theTShapeToLengthMap.insert( make_pair( getTShape( edge ), L )); } - // Compute S0 + // Compute S0 - minimal segement length, is computed by the shortest EDGE - // image attached to PAL10237 - - // NbSeg - // ^ - // | - // 10|\ - // | \ - // | \ - // | \ - // 5| -------- - // | - // +------------> - // 1 10 Lmax/Lmin + /* image attached to PAL10237 + NbSeg (on the shortest EDGE) + ^ + | + 10|\ + | \ + | \ + | \ + 5| -------- + | + +------------> + 1 10 Lmax/Lmin + */ const int NbSegMin = 5, NbSegMax = 10; // on axis NbSeg const double Lrat1 = 1., Lrat2 = 10.; // on axis Lmax/Lmin @@ -192,6 +206,7 @@ namespace { MESSAGE( "S0 = " << S0 << ", Lmin = " << Lmin << ", Nbseg = " << (int) NbSeg); // Compute segments length for all edges + map::iterator tshape_length = theTShapeToLengthMap.begin(); for ( ; tshape_length != theTShapeToLengthMap.end(); ++tshape_length ) { diff --git a/src/StdMeshers/StdMeshers_Prism_3D.cxx b/src/StdMeshers/StdMeshers_Prism_3D.cxx index 8b72f7b9b..a248d1f4e 100644 --- a/src/StdMeshers/StdMeshers_Prism_3D.cxx +++ b/src/StdMeshers/StdMeshers_Prism_3D.cxx @@ -68,6 +68,11 @@ using namespace std; // gp_Pnt p (xyz); \ // cout << msg << " ("<< p.X() << "; " < meshedFaces, notQuadMeshedFaces, notQuadFaces; const bool meshHasQuads = ( theMesh.NbQuadrangles() > 0 ); + //StdMeshers_Quadrangle_2D* quadAlgo = TQuadrangleAlgo::instance( this ); for ( int iF = 1; iF < faceToSolids.Extent(); ++iF ) { const TopoDS_Face& face = TopoDS::Face( faceToSolids.FindKey( iF )); @@ -480,10 +486,13 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh else meshedFaces.push_back( face ); } - else if ( myHelper->Count( face, TopAbs_EDGE, /*ignoreSame=*/false ) != 4 ) - { - notQuadFaces.push_back( face ); - } + // not add not quadrilateral FACE as we can't compute it + // else if ( !quadAlgo->CheckNbEdges( theMesh, face )) + // // not add not quadrilateral FACE as it can be a prism side + // // else if ( myHelper->Count( face, TopAbs_EDGE, /*ignoreSame=*/false ) != 4 ) + // { + // notQuadFaces.push_back( face ); + // } } // notQuadFaces are of medium priority, put them before ordinary meshed faces meshedFaces.splice( meshedFaces.begin(), notQuadFaces ); @@ -1043,6 +1052,7 @@ bool StdMeshers_Prism_3D::computeWalls(const Prism_3D::TPrismTopo& thePrism) { SMESH_Mesh* mesh = myHelper->GetMesh(); SMESHDS_Mesh* meshDS = myHelper->GetMeshDS(); + DBGOUT( endl << "COMPUTE Prism " << meshDS->ShapeToIndex( thePrism.myShape3D )); TProjction1dAlgo* projector1D = TProjction1dAlgo::instance( this ); StdMeshers_Quadrangle_2D* quadAlgo = TQuadrangleAlgo::instance( this, myHelper ); @@ -1108,6 +1118,7 @@ bool StdMeshers_Prism_3D::computeWalls(const Prism_3D::TPrismTopo& thePrism) const TopoDS_Edge& srcE = lftSide->Edge(i); SMESH_subMesh* srcSM = mesh->GetSubMesh( srcE ); if ( !srcSM->IsMeshComputed() ) { + DBGOUT( "COMPUTE V edge " << srcSM->GetId() ); srcSM->ComputeSubMeshStateEngine( SMESH_subMesh::COMPUTE ); srcSM->ComputeStateEngine ( SMESH_subMesh::COMPUTE ); if ( !srcSM->IsMeshComputed() ) @@ -1161,8 +1172,9 @@ bool StdMeshers_Prism_3D::computeWalls(const Prism_3D::TPrismTopo& thePrism) } // compute nodes on target EDGEs + DBGOUT( "COMPUTE V edge (proj) " << shapeID( lftSide->Edge(0))); rgtSide->Reverse(); // direct it same as the lftSide - myHelper->SetElementsOnShape( false ); + myHelper->SetElementsOnShape( false ); // myHelper holds the prism shape TopoDS_Edge tgtEdge; for ( size_t iN = 1; iN < srcNodeStr.size()-1; ++iN ) // add nodes { @@ -1173,25 +1185,24 @@ bool StdMeshers_Prism_3D::computeWalls(const Prism_3D::TPrismTopo& thePrism) } for ( size_t iN = 1; iN < srcNodeStr.size(); ++iN ) // add segments { - SMDS_MeshElement* newEdge = myHelper->AddEdge( newNodes[ iN-1 ], newNodes[ iN ] ); + // find an EDGE to set a new segment std::pair id2type = myHelper->GetMediumPos( newNodes[ iN-1 ], newNodes[ iN ] ); - if ( id2type.second == TopAbs_EDGE ) - { - meshDS->SetMeshElementOnShape( newEdge, id2type.first ); - } - else // new nodes are on different EDGEs; put one of them on VERTEX + if ( id2type.second != TopAbs_EDGE ) { + // new nodes are on different EDGEs; put one of them on VERTEX const int edgeIndex = rgtSide->EdgeIndex( srcNodeStr[ iN-1 ].normParam ); const double vertexParam = rgtSide->LastParameter( edgeIndex ); const gp_Pnt p = BRep_Tool::Pnt( rgtSide->LastVertex( edgeIndex )); const int isPrev = ( Abs( srcNodeStr[ iN-1 ].normParam - vertexParam ) < Abs( srcNodeStr[ iN ].normParam - vertexParam )); - meshDS->SetMeshElementOnShape( newEdge, newNodes[ iN-(1-isPrev) ]->getshapeId() ); meshDS->UnSetNodeOnShape( newNodes[ iN-isPrev ] ); meshDS->SetNodeOnVertex ( newNodes[ iN-isPrev ], rgtSide->LastVertex( edgeIndex )); - meshDS->MoveNode( newNodes[ iN-isPrev ], p.X(), p.Y(), p.Z() ); + meshDS->MoveNode ( newNodes[ iN-isPrev ], p.X(), p.Y(), p.Z() ); + id2type.first = newNodes[ iN-(1-isPrev) ]->getshapeId(); } + SMDS_MeshElement* newEdge = myHelper->AddEdge( newNodes[ iN-1 ], newNodes[ iN ] ); + meshDS->SetMeshElementOnShape( newEdge, id2type.first ); } myHelper->SetElementsOnShape( true ); for ( int i = 0; i < rgtSide->NbEdges(); ++i ) // update state of sub-meshes @@ -1228,28 +1239,43 @@ bool StdMeshers_Prism_3D::computeWalls(const Prism_3D::TPrismTopo& thePrism) // Top EDGEs must be projections from the bottom ones // to compute stuctured quad mesh on wall FACEs // --------------------------------------------------- - const TopoDS_Edge& botE = (*quad)->side[ QUAD_BOTTOM_SIDE ]->Edge(0); - const TopoDS_Edge& topE = (*quad)->side[ QUAD_TOP_SIDE ]->Edge(0); - - projector1D->myHyp.SetSourceEdge( botE ); - - SMESH_subMesh* tgtEdgeSm = mesh->GetSubMesh( topE ); - if ( !tgtEdgeSm->IsMeshComputed() ) { - // compute nodes on VERTEXes - tgtEdgeSm->ComputeSubMeshStateEngine( SMESH_subMesh::COMPUTE ); - // project segments - projector1D->InitComputeError(); - bool ok = projector1D->Compute( *mesh, topE ); - if ( !ok ) + const TopoDS_Edge& botE = (*quad)->side[ QUAD_BOTTOM_SIDE ]->Edge(0); + const TopoDS_Edge& topE = (*quad)->side[ QUAD_TOP_SIDE ]->Edge(0); + SMESH_subMesh* botSM = mesh->GetSubMesh( botE ); + SMESH_subMesh* topSM = mesh->GetSubMesh( topE ); + SMESH_subMesh* srcSM = botSM; + SMESH_subMesh* tgtSM = topSM; + if ( !srcSM->IsMeshComputed() && topSM->IsMeshComputed() ) + std::swap( srcSM, tgtSM ); + + if ( !srcSM->IsMeshComputed() ) { - SMESH_ComputeErrorPtr err = projector1D->GetComputeError(); - if ( err->IsOK() ) err->myName = COMPERR_ALGO_FAILED; - tgtEdgeSm->GetComputeError() = err; - return false; + DBGOUT( "COMPUTE H edge " << srcSM->GetId()); + srcSM->ComputeSubMeshStateEngine( SMESH_subMesh::COMPUTE ); // nodes on VERTEXes + srcSM->ComputeStateEngine( SMESH_subMesh::COMPUTE ); // segments on the EDGE } + srcSM->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); + + if ( !tgtSM->IsMeshComputed() ) + { + // compute nodes on VERTEXes + tgtSM->ComputeSubMeshStateEngine( SMESH_subMesh::COMPUTE ); + // project segments + DBGOUT( "COMPUTE H edge (proj) " << tgtSM->GetId()); + projector1D->myHyp.SetSourceEdge( TopoDS::Edge( srcSM->GetSubShape() )); + projector1D->InitComputeError(); + bool ok = projector1D->Compute( *mesh, tgtSM->GetSubShape() ); + if ( !ok ) + { + SMESH_ComputeErrorPtr err = projector1D->GetComputeError(); + if ( err->IsOK() ) err->myName = COMPERR_ALGO_FAILED; + tgtSM->GetComputeError() = err; + return false; + } + } + tgtSM->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); } - tgtEdgeSm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); // Compute quad mesh on wall FACEs // ------------------------------- @@ -1264,6 +1290,7 @@ bool StdMeshers_Prism_3D::computeWalls(const Prism_3D::TPrismTopo& thePrism) "Not all edges have valid algorithm and hypothesis")); // mesh the quadAlgo->InitComputeError(); + DBGOUT( "COMPUTE Quad face " << fSM->GetId()); bool ok = quadAlgo->Compute( *mesh, face ); fSM->GetComputeError() = quadAlgo->GetComputeError(); if ( !ok ) @@ -1545,7 +1572,7 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top() _gen->Compute( *myHelper->GetMesh(), botSM->GetSubShape() ); botSMDS = botSM->GetSubMeshDS(); if ( !botSMDS || botSMDS->NbElements() == 0 ) - return toSM( error(TCom("No elememts on face #") << botSM->GetId() )); + return toSM( error(TCom("No elements on face #") << botSM->GetId() )); } bool needProject = !topSM->IsMeshComputed(); diff --git a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx index 0fddea3c7..5cfccaa1c 100644 --- a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx +++ b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx @@ -2044,7 +2044,7 @@ bool StdMeshers_ProjectionUtils::MakeComputed(SMESH_subMesh * sm, const int iter return true; SMESH_Mesh* mesh = sm->GetFather(); - SMESH_Gen* gen = mesh->GetGen(); + SMESH_Gen* gen = mesh->GetGen(); SMESH_Algo* algo = sm->GetAlgo(); if ( !algo ) {