X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_ViscousLayers2D.cxx;h=f422b91cb6e9b63a87ba56e0b8b27d28fce2bf07;hp=585bcaf7164c2181e35fecb80b4cf8ca08f94f87;hb=refs%2Ftags%2FV9_7_0b1;hpb=7eda9ca931ed2a11cb5e4637e4ffe19f5c061115 diff --git a/src/StdMeshers/StdMeshers_ViscousLayers2D.cxx b/src/StdMeshers/StdMeshers_ViscousLayers2D.cxx index 585bcaf71..f422b91cb 100644 --- a/src/StdMeshers/StdMeshers_ViscousLayers2D.cxx +++ b/src/StdMeshers/StdMeshers_ViscousLayers2D.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -30,6 +30,7 @@ #include "SMDS_SetIterator.hxx" #include "SMESHDS_Group.hxx" #include "SMESHDS_Hypothesis.hxx" +#include "SMESHDS_Mesh.hxx" #include "SMESH_Algo.hxx" #include "SMESH_ComputeError.hxx" #include "SMESH_ControlsDef.hxx" @@ -37,6 +38,7 @@ #include "SMESH_Group.hxx" #include "SMESH_HypoFilter.hxx" #include "SMESH_Mesh.hxx" +#include "SMESH_MeshEditor.hxx" #include "SMESH_MesherHelper.hxx" #include "SMESH_ProxyMesh.hxx" #include "SMESH_Quadtree.hxx" @@ -81,6 +83,7 @@ #include #include #include +#include #include #include @@ -109,14 +112,15 @@ namespace VISCOUS_2D // Proxy sub-mesh of an EDGE. It contains nodes in _uvPtStructVec. struct _EdgeSubMesh : public SMESH_ProxyMesh::SubMesh { - _EdgeSubMesh(int index=0): SubMesh(index) {} + _EdgeSubMesh(const SMDS_Mesh* mesh, int index=0): SubMesh(mesh,index) {} //virtual int NbElements() const { return _elements.size()+1; } - virtual int NbNodes() const { return Max( 0, _uvPtStructVec.size()-2 ); } + virtual smIdType NbNodes() const { return Max( 0, _uvPtStructVec.size()-2 ); } void SetUVPtStructVec(UVPtStructVec& vec) { _uvPtStructVec.swap( vec ); } + UVPtStructVec& GetUVPtStructVec() { return _uvPtStructVec; } }; _ProxyMeshOfFace(const SMESH_Mesh& mesh): SMESH_ProxyMesh(mesh) {} _EdgeSubMesh* GetEdgeSubMesh(int ID) { return (_EdgeSubMesh*) getProxySubMesh(ID); } - virtual SubMesh* newSubmesh(int index=0) const { return new _EdgeSubMesh(index); } + virtual SubMesh* newSubmesh(int index=0) const { return new _EdgeSubMesh( GetMeshDS(), index); } }; //-------------------------------------------------------------------------------- /*! @@ -147,7 +151,7 @@ namespace VISCOUS_2D // Treat events void ProcessEvent(const int event, const int eventType, - SMESH_subMesh* subMesh, + SMESH_subMesh* /*subMesh*/, EventListenerData* data, const SMESH_Hypothesis* /*hyp*/) { @@ -174,7 +178,7 @@ namespace VISCOUS_2D */ struct _Segment { - const gp_XY* _uv[2]; // poiter to _LayerEdge::_uvIn + const gp_XY* _uv[2]; // pointer to _LayerEdge::_uvIn int _indexInLine; // position in _PolyLine _Segment() {} @@ -299,6 +303,8 @@ namespace VISCOUS_2D double _D; // _vec1.Crossed( _vec2 ) double _param1, _param2; // intersection param on _seg1 and _seg2 + _SegmentIntersection(): _D(0), _param1(0), _param2(0) {} + bool Compute(const _Segment& seg1, const _Segment& seg2, bool seg2IsRay = false ) { // !!! If seg2IsRay, returns true at any _param2 !!! @@ -497,15 +503,15 @@ namespace VISCOUS_2D //================================================================================ // StdMeshers_ViscousLayers hypothesis // -StdMeshers_ViscousLayers2D::StdMeshers_ViscousLayers2D(int hypId, int studyId, SMESH_Gen* gen) - :StdMeshers_ViscousLayers(hypId, studyId, gen) +StdMeshers_ViscousLayers2D::StdMeshers_ViscousLayers2D(int hypId, SMESH_Gen* gen) + :StdMeshers_ViscousLayers(hypId, gen) { _name = StdMeshers_ViscousLayers2D::GetHypType(); _param_algo_dim = -2; // auxiliary hyp used by 2D algos } // -------------------------------------------------------------------------------- -bool StdMeshers_ViscousLayers2D::SetParametersByMesh(const SMESH_Mesh* theMesh, - const TopoDS_Shape& theShape) +bool StdMeshers_ViscousLayers2D::SetParametersByMesh(const SMESH_Mesh* /*theMesh*/, + const TopoDS_Shape& /*theShape*/) { // TODO ??? return false; @@ -515,29 +521,53 @@ SMESH_ProxyMesh::Ptr StdMeshers_ViscousLayers2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Face& theFace) { - SMESH_ProxyMesh::Ptr pm; - + using namespace VISCOUS_2D; vector< const StdMeshers_ViscousLayers2D* > hyps; vector< TopoDS_Shape > hypShapes; - if ( VISCOUS_2D::findHyps( theMesh, theFace, hyps, hypShapes )) + + SMESH_ProxyMesh::Ptr pm = _ProxyMeshHolder::FindProxyMeshOfFace( theFace, theMesh ); + if ( !pm ) { - VISCOUS_2D::_ViscousBuilder2D builder( theMesh, theFace, hyps, hypShapes ); - pm = builder.Compute(); - SMESH_ComputeErrorPtr error = builder.GetError(); - if ( error && !error->IsOK() ) - theMesh.GetSubMesh( theFace )->GetComputeError() = error; - else if ( !pm ) + if ( findHyps( theMesh, theFace, hyps, hypShapes )) + { + VISCOUS_2D::_ViscousBuilder2D builder( theMesh, theFace, hyps, hypShapes ); + pm = builder.Compute(); + SMESH_ComputeErrorPtr error = builder.GetError(); + if ( error && !error->IsOK() ) + theMesh.GetSubMesh( theFace )->GetComputeError() = error; + else if ( !pm ) + pm.reset( new SMESH_ProxyMesh( theMesh )); + if ( getenv("__ONLY__VL2D__")) + pm.reset(); + } + else + { pm.reset( new SMESH_ProxyMesh( theMesh )); - if ( getenv("__ONLY__VL2D__")) - pm.reset(); - } - else - { - pm.reset( new SMESH_ProxyMesh( theMesh )); + } } return pm; } // -------------------------------------------------------------------------------- +void StdMeshers_ViscousLayers2D::SetProxyMeshOfEdge( const StdMeshers_FaceSide& edgeNodes ) +{ + using namespace VISCOUS_2D; + SMESH_ProxyMesh::Ptr pm = + _ProxyMeshHolder::FindProxyMeshOfFace( edgeNodes.Face(), *edgeNodes.GetMesh() ); + if ( !pm ) { + _ProxyMeshOfFace* proxyMeshOfFace = new _ProxyMeshOfFace( *edgeNodes.GetMesh() ); + pm.reset( proxyMeshOfFace ); + new _ProxyMeshHolder( edgeNodes.Face(), pm ); + } + _ProxyMeshOfFace* proxyMeshOfFace = static_cast<_ProxyMeshOfFace*>( pm.get() ); + _ProxyMeshOfFace::_EdgeSubMesh* sm = proxyMeshOfFace->GetEdgeSubMesh( edgeNodes.EdgeID(0) ); + sm->GetUVPtStructVec() = edgeNodes.GetUVPtStruct(); +} +// -------------------------------------------------------------------------------- +bool StdMeshers_ViscousLayers2D::HasProxyMesh( const TopoDS_Face& face, SMESH_Mesh& mesh ) +{ + return VISCOUS_2D::_ProxyMeshHolder::FindProxyMeshOfFace( face, mesh ).get(); +} +// -------------------------------------------------------------------------------- SMESH_ComputeErrorPtr StdMeshers_ViscousLayers2D::CheckHypothesis(SMESH_Mesh& theMesh, const TopoDS_Shape& theShape, @@ -557,7 +587,7 @@ StdMeshers_ViscousLayers2D::CheckHypothesis(SMESH_Mesh& VISCOUS_2D::_ViscousBuilder2D builder( theMesh, face, hyps, hypShapes ); builder._faceSideVec = StdMeshers_FaceSide::GetFaceWires( face, theMesh, true, error, - SMESH_ProxyMesh::Ptr(), + NULL, SMESH_ProxyMesh::Ptr(), /*theCheckVertexNodes=*/false); if ( error->IsOK() && !builder.findEdgesWithLayers()) { @@ -572,7 +602,7 @@ StdMeshers_ViscousLayers2D::CheckHypothesis(SMESH_Mesh& // -------------------------------------------------------------------------------- void StdMeshers_ViscousLayers2D::RestoreListeners() const { - StudyContextStruct* sc = _gen->GetStudyContext( _studyId ); + StudyContextStruct* sc = _gen->GetStudyContext(); std::map < int, SMESH_Mesh * >::iterator i_smesh = sc->mapMesh.begin(); for ( ; i_smesh != sc->mapMesh.end(); ++i_smesh ) { @@ -658,7 +688,7 @@ bool _ViscousBuilder2D::error(const string& text ) SMESH_ProxyMesh::Ptr _ViscousBuilder2D::Compute() { - _faceSideVec = StdMeshers_FaceSide::GetFaceWires( _face, *_mesh, true, _error); + _faceSideVec = StdMeshers_FaceSide::GetFaceWires( _face, *_mesh, true, _error, &_helper ); if ( !_error->IsOK() ) return _proxyMesh; @@ -1235,7 +1265,7 @@ void _ViscousBuilder2D::adjustCommonEdge( _PolyLine& LL, _PolyLine& LR ) if ( isR ) LR._lEdges.erase( LR._lEdges.begin()+1, eIt ); else - LL._lEdges.erase( eIt, --LL._lEdges.end() ); + LL._lEdges.erase( eIt+1, --LL._lEdges.end() ); // eIt = isR ? L._lEdges.begin()+1 : L._lEdges.end()-2; // for ( size_t i = 1; i < iLE; ++i, eIt += dIt ) // eIt->_isBlocked = true; @@ -1290,7 +1320,7 @@ void _ViscousBuilder2D::setLayerEdgeData( _LayerEdge& lEdge, faceProj->Perform( p ); if ( !faceProj->IsDone() || faceProj->NbPoints() < 1 ) return setLayerEdgeData( lEdge, u, pcurve, curve, p, reverse, NULL ); - Quantity_Parameter U,V; + Standard_Real U,V; faceProj->LowerDistanceParameters(U,V); lEdge._normal2D.SetCoord( U - uv.X(), V - uv.Y() ); lEdge._normal2D.Normalize(); @@ -1716,11 +1746,13 @@ bool _ViscousBuilder2D::shrink() } } // loop on FACEs sharing E + // Check if L is an already shrinked seam + if ( adjFace.IsNull() && _helper.IsRealSeam( edgeID )) + if ( L._wire->Edge( L._edgeInd ).Orientation() == TopAbs_FORWARD ) + continue; // Commented as a case with a seam EDGE (issue 0052461) is hard to support // because SMESH_ProxyMesh can't hold different sub-meshes for two // 2D representations of the seam. But such a case is not a real practice one. - // Check if L is an already shrinked seam - // if ( adjFace.IsNull() && _helper.IsRealSeam( edgeID )) // { // for ( int iL2 = iL1-1; iL2 > -1; --iL2 ) // { @@ -1794,7 +1826,7 @@ bool _ViscousBuilder2D::shrink() // x-x-x-x-----x-----x---- // | | | | e1 e2 e3 - int isRShrinkedForAdjacent; + int isRShrinkedForAdjacent = 0; UVPtStructVec nodeDataForAdjacent; for ( int isR = 0; isR < 2; ++isR ) { @@ -1968,7 +2000,7 @@ bool _ViscousBuilder2D::shrink() throw SALOME_Exception(SMESH_Comment("ViscousBuilder2D: not SMDS_TOP_EDGE node position: ") << oldNode->GetPosition()->GetTypeOfPosition() << " of node " << oldNode->GetID()); - SMDS_EdgePosition* pos = static_cast( oldNode->GetPosition() ); + SMDS_EdgePositionPtr pos = oldNode->GetPosition(); pos->SetUParameter( nodeDataVec[iP].param ); gp_Pnt newP = curve.Value( nodeDataVec[iP].param ); @@ -2157,7 +2189,7 @@ bool _ViscousBuilder2D::refine() vector< double > segLen( L._lEdges.size() ); segLen[0] = 0.0; - // check if length modification is usefull: look for _LayerEdge's + // check if length modification is useful: look for _LayerEdge's // with length limited due to collisions bool lenLimited = false; for ( size_t iLE = 1; ( iLE < L._lEdges.size()-1 && !lenLimited ); ++iLE ) @@ -2371,6 +2403,17 @@ bool _ViscousBuilder2D::refine() outerNodes.swap( innerNodes ); } + // Add faces to a group + SMDS_MeshGroup* group = StdMeshers_ViscousLayers::CreateGroup( hyp->GetGroupName(), + *_helper.GetMesh(), + SMDSAbs_Face ); + if ( group ) + { + TIDSortedElemSet::iterator fIt = L._newFaces.begin(); + for ( ; fIt != L._newFaces.end(); ++fIt ) + group->Add( *fIt ); + } + // faces between not shared _LayerEdge's (at concave VERTEX) for ( int isR = 0; isR < 2; ++isR ) { @@ -2382,15 +2425,22 @@ bool _ViscousBuilder2D::refine() if ( lNodes.empty() || rNodes.empty() || lNodes.size() != rNodes.size() ) continue; + const SMDS_MeshElement* face = 0; for ( size_t i = 1; i < lNodes.size(); ++i ) - _helper.AddFace( lNodes[ i+prev ], rNodes[ i+prev ], - rNodes[ i+cur ], lNodes[ i+cur ]); + { + face = _helper.AddFace( lNodes[ i+prev ], rNodes[ i+prev ], + rNodes[ i+cur ], lNodes[ i+cur ]); + if ( group ) + group->Add( face ); + } const UVPtStruct& ptOnVertex = points[ isR ? L._lastPntInd : L._firstPntInd ]; if ( isReverse ) - _helper.AddFace( ptOnVertex.node, lNodes[ 0 ], rNodes[ 0 ]); + face = _helper.AddFace( ptOnVertex.node, lNodes[ 0 ], rNodes[ 0 ]); else - _helper.AddFace( ptOnVertex.node, rNodes[ 0 ], lNodes[ 0 ]); + face = _helper.AddFace( ptOnVertex.node, rNodes[ 0 ], lNodes[ 0 ]); + if ( group ) + group->Add( face ); } // Fill the _ProxyMeshOfFace @@ -2410,6 +2460,19 @@ bool _ViscousBuilder2D::refine() nodeDataVec.front().param = L._wire->FirstU( L._edgeInd ); nodeDataVec.back() .param = L._wire->LastU ( L._edgeInd ); + if (( nodeDataVec[0].node == nodeDataVec.back().node ) && + ( _helper.GetPeriodicIndex() == 1 || _helper.GetPeriodicIndex() == 2 )) // closed EDGE + { + const int iCoord = _helper.GetPeriodicIndex(); + gp_XY uv = nodeDataVec[0].UV(); + uv.SetCoord( iCoord, L._lEdges[0]._uvOut.Coord( iCoord )); + nodeDataVec[0].SetUV( uv ); + + uv = nodeDataVec.back().UV(); + uv.SetCoord( iCoord, L._lEdges.back()._uvOut.Coord( iCoord )); + nodeDataVec.back().SetUV( uv ); + } + _ProxyMeshOfFace::_EdgeSubMesh* edgeSM = getProxyMesh()->GetEdgeSubMesh( L._wire->EdgeID( L._edgeInd )); edgeSM->SetUVPtStructVec( nodeDataVec );