X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMESH%2FSMESH_MesherHelper.cxx;h=28ef9ae55a06300ba1bf87064e5c6f99cc29a7ec;hb=d9f4b53e489dd5857db264ede6acded7b076c9f1;hp=43f3de4ebab14c3de15c4e969da73ab2aee160f4;hpb=2f4749af530095df28f5b514808356070190192d;p=modules%2Fsmesh.git diff --git a/src/SMESH/SMESH_MesherHelper.cxx b/src/SMESH/SMESH_MesherHelper.cxx index 43f3de4eb..28ef9ae55 100644 --- a/src/SMESH/SMESH_MesherHelper.cxx +++ b/src/SMESH/SMESH_MesherHelper.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2020 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -658,10 +659,10 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F, // corresponding EDGE from FACE, get pcurve for this // EDGE and retrieve value from this pcurve SMDS_EdgePositionPtr epos = pos; - const int edgeID = n->getshapeId(); - const TopoDS_Edge& E = TopoDS::Edge( GetMeshDS()->IndexToShape( edgeID )); + const int edgeID = n->getshapeId(); + const TopoDS_Edge& E = TopoDS::Edge( GetMeshDS()->IndexToShape( edgeID )); double f, l, u = epos->GetUParameter(); - Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface( E, F, f, l ); + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface( E, F, f, l ); bool validU = ( !C2d.IsNull() && ( f < u ) && ( u < l )); if ( validU ) uv = C2d->Value( u ); else uv.SetCoord( Precision::Infinite(),0.); @@ -769,6 +770,17 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F, if ( isSeam ) uv = getUVOnSeam( uv, GetNodeUV( F, n2, 0 )); } + else if ( myParIndex && n2 ) + { + gp_Pnt2d oldUV = uv; + gp_Pnt2d uv2 = GetNodeUV( F, n2, 0 ); + if ( myParIndex & 1 ) + uv.SetX( uv.X() + ShapeAnalysis::AdjustToPeriod( uv.X(), myPar1[0], myPar2[0])); + if ( myParIndex & 2 ) + uv.SetY( uv.Y() + ShapeAnalysis::AdjustToPeriod( uv.Y(), myPar1[1], myPar2[1])); + if ( uv.SquareDistance( uv2 ) > oldUV.SquareDistance( uv2 )) + uv = oldUV; + } } } else @@ -864,6 +876,51 @@ GeomAPI_ProjectPointOnSurf& SMESH_MesherHelper::GetProjector(const TopoDS_Face& return *( i_proj->second ); } +//======================================================================= +//function : GetProjector +//purpose : Return projector initialized by given face, which is returned +//======================================================================= + +GeomAPI_ProjectPointOnSurf& SMESH_MesherHelper::GetProjector(const TopoDS_Face& F, + double tol ) const +{ + Handle(Geom_Surface) surface = BRep_Tool::Surface( F ); + int faceID = GetMeshDS()->ShapeToIndex( F ); + TID2ProjectorOnSurf& i2proj = const_cast< TID2ProjectorOnSurf&>( myFace2Projector ); + TID2ProjectorOnSurf::iterator i_proj = i2proj.find( faceID ); + if ( i_proj == i2proj.end() ) + { + if ( tol == 0 ) tol = BRep_Tool::Tolerance( F ); + double U1, U2, V1, V2; + surface->Bounds(U1, U2, V1, V2); + GeomAPI_ProjectPointOnSurf* proj = new GeomAPI_ProjectPointOnSurf(); + proj->Init( surface, U1, U2, V1, V2, tol ); + i_proj = i2proj.insert( make_pair( faceID, proj )).first; + } + return *( i_proj->second ); +} + +//======================================================================= +//function : GetPCProjector +//purpose : Return projector initialized by given EDGE +//======================================================================= + +GeomAPI_ProjectPointOnCurve& SMESH_MesherHelper::GetPCProjector(const TopoDS_Edge& E ) const +{ + int edgeID = GetMeshDS()->ShapeToIndex( E ); + TID2ProjectorOnCurve& i2proj = const_cast< TID2ProjectorOnCurve&>( myEdge2Projector ); + TID2ProjectorOnCurve::iterator i_proj = i2proj.insert( make_pair( edgeID, nullptr )).first; + if ( !i_proj->second ) + { + double f,l; + Handle(Geom_Curve) curve = BRep_Tool::Curve( E,f,l ); + i_proj->second = new GeomAPI_ProjectPointOnCurve(); + i_proj->second->Init( curve, f, l ); + } + GeomAPI_ProjectPointOnCurve* projector = i_proj->second; + return *projector; +} + //======================================================================= //function : GetSurface //purpose : Return a cached ShapeAnalysis_Surface of a FACE @@ -1110,27 +1167,17 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge& E, { setPosOnShapeValidity( shapeID, false ); // u incorrect, project the node to the curve - int edgeID = GetMeshDS()->ShapeToIndex( E ); - TID2ProjectorOnCurve& i2proj = const_cast< TID2ProjectorOnCurve&>( myEdge2Projector ); - TID2ProjectorOnCurve::iterator i_proj = - i2proj.insert( make_pair( edgeID, (GeomAPI_ProjectPointOnCurve*) 0 )).first; - if ( !i_proj->second ) - { - i_proj->second = new GeomAPI_ProjectPointOnCurve(); - i_proj->second->Init( curve, f, l ); - } - GeomAPI_ProjectPointOnCurve* projector = i_proj->second; - projector->Perform( nodePnt ); - if ( projector->NbPoints() < 1 ) - { - MESSAGE( "SMESH_MesherHelper::CheckNodeU() failed to project" ); - return false; - } - Standard_Real U = projector->LowerDistanceParameter(); - u = double( U ); - curvPnt = curve->Value( u ); - dist = nodePnt.Distance( curvPnt ); + //GeomAPI_ProjectPointOnCurve& projector = GetPCProjector( E ); -- bug in OCCT-7.5.3p1 + GeomAdaptor_Curve curveAd( curve, f, l ); + ShapeAnalysis_Curve projector; + dist = projector.Project( curveAd, nodePnt, tol, curvPnt, u, false ); + // if ( projector.NbPoints() < 1 ) + // { + // MESSAGE( "SMESH_MesherHelper::CheckNodeU() failed to project" ); + // return false; + // } if ( distXYZ ) { + curvPnt = curve->Value( u ); curvPnt.Transform( loc ); distXYZ[0] = dist; distXYZ[1] = curvPnt.X(); distXYZ[2] = curvPnt.Y(); distXYZ[3]=curvPnt.Z(); @@ -1143,7 +1190,7 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge& E, // store the fixed U on the edge if ( myShape.IsSame(E) && shapeID == myShapeID && myFixNodeParameters ) const_cast(n)->SetPosition - ( SMDS_PositionPtr( new SMDS_EdgePosition( U ))); + ( SMDS_PositionPtr( new SMDS_EdgePosition( u ))); } else if ( fabs( u ) > numeric_limits::min() ) { @@ -1924,7 +1971,7 @@ const SMDS_MeshNode* SMESH_MesherHelper::getMediumNodeOnComposedWire(const SMDS_ //purpose : Creates a node //======================================================================= -SMDS_MeshNode* SMESH_MesherHelper::AddNode(double x, double y, double z, int ID, +SMDS_MeshNode* SMESH_MesherHelper::AddNode(double x, double y, double z, smIdType ID, double u, double v) { SMESHDS_Mesh * meshDS = GetMeshDS(); @@ -1953,7 +2000,7 @@ SMDS_MeshNode* SMESH_MesherHelper::AddNode(double x, double y, double z, int ID, SMDS_MeshEdge* SMESH_MesherHelper::AddEdge(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2, - const int id, + const smIdType id, const bool force3d) { SMESHDS_Mesh * meshDS = GetMeshDS(); @@ -1987,7 +2034,7 @@ SMDS_MeshEdge* SMESH_MesherHelper::AddEdge(const SMDS_MeshNode* n1, SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2, const SMDS_MeshNode* n3, - const int id, + const smIdType id, const bool force3d) { SMESHDS_Mesh * meshDS = GetMeshDS(); @@ -2037,7 +2084,7 @@ SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2, const SMDS_MeshNode* n3, const SMDS_MeshNode* n4, - const int id, + const smIdType id, const bool force3d) { SMESHDS_Mesh * meshDS = GetMeshDS(); @@ -2101,7 +2148,7 @@ SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1, //======================================================================= SMDS_MeshFace* SMESH_MesherHelper::AddPolygonalFace (const vector& nodes, - const int id, + const smIdType id, const bool force3d) { SMESHDS_Mesh * meshDS = GetMeshDS(); @@ -2147,7 +2194,7 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1, const SMDS_MeshNode* n4, const SMDS_MeshNode* n5, const SMDS_MeshNode* n6, - const int id, + const smIdType id, const bool force3d) { SMESHDS_Mesh * meshDS = GetMeshDS(); @@ -2210,7 +2257,7 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2, const SMDS_MeshNode* n3, const SMDS_MeshNode* n4, - const int id, + const smIdType id, const bool force3d) { SMESHDS_Mesh * meshDS = GetMeshDS(); @@ -2251,7 +2298,7 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1, const SMDS_MeshNode* n3, const SMDS_MeshNode* n4, const SMDS_MeshNode* n5, - const int id, + const smIdType id, const bool force3d) { SMDS_MeshVolume* elem = 0; @@ -2301,7 +2348,7 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1, const SMDS_MeshNode* n6, const SMDS_MeshNode* n7, const SMDS_MeshNode* n8, - const int id, + const smIdType id, const bool force3d) { SMESHDS_Mesh * meshDS = GetMeshDS(); @@ -2420,7 +2467,7 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1, const SMDS_MeshNode* n10, const SMDS_MeshNode* n11, const SMDS_MeshNode* n12, - const int id, + const smIdType id, bool /*force3d*/) { SMESHDS_Mesh * meshDS = GetMeshDS(); @@ -2442,7 +2489,7 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1, SMDS_MeshVolume* SMESH_MesherHelper::AddPolyhedralVolume (const std::vector& nodes, const std::vector& quantities, - const int id, + const smIdType id, const bool force3d) { SMESHDS_Mesh * meshDS = GetMeshDS(); @@ -2724,33 +2771,30 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2 theParam2ColumnMap.begin()->second.size() == prevNbRows + expectNbRows ); } -namespace +//================================================================================ +/*! + * \brief Return true if a node is at a corner of a 2D structured mesh of FACE + */ +//================================================================================ + +bool SMESH_MesherHelper::IsCornerOfStructure( const SMDS_MeshNode* n, + const SMESHDS_SubMesh* faceSM, + SMESH_MesherHelper& faceAnalyser ) { - //================================================================================ - /*! - * \brief Return true if a node is at a corner of a 2D structured mesh of FACE - */ - //================================================================================ + int nbFacesInSM = 0; + if ( n ) { + SMDS_ElemIteratorPtr fIt = n->GetInverseElementIterator( SMDSAbs_Face ); + while ( fIt->more() ) + nbFacesInSM += faceSM->Contains( fIt->next() ); + } + if ( nbFacesInSM == 1 ) + return true; - bool isCornerOfStructure( const SMDS_MeshNode* n, - const SMESHDS_SubMesh* faceSM, - SMESH_MesherHelper& faceAnalyser ) + if ( nbFacesInSM == 2 && n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX ) { - int nbFacesInSM = 0; - if ( n ) { - SMDS_ElemIteratorPtr fIt = n->GetInverseElementIterator( SMDSAbs_Face ); - while ( fIt->more() ) - nbFacesInSM += faceSM->Contains( fIt->next() ); - } - if ( nbFacesInSM == 1 ) - return true; - - if ( nbFacesInSM == 2 && n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX ) - { - return faceAnalyser.IsRealSeam( n->getshapeId() ); - } - return false; + return faceAnalyser.IsRealSeam( n->getshapeId() ); } + return false; } //======================================================================= @@ -2785,7 +2829,7 @@ bool SMESH_MesherHelper::IsStructured( SMESH_subMesh* faceSM ) int nbRemainEdges = nbEdgesInWires.front(); do { TopoDS_Vertex V = IthVertex( 0, edges.front() ); - isCorner = isCornerOfStructure( SMESH_Algo::VertexNode( V, meshDS ), + isCorner = IsCornerOfStructure( SMESH_Algo::VertexNode( V, meshDS ), fSM, faceAnalyser); if ( !isCorner ) { edges.splice( edges.end(), edges, edges.begin() ); @@ -2826,7 +2870,7 @@ bool SMESH_MesherHelper::IsStructured( SMESH_subMesh* faceSM ) for ( ; n != nodes.end(); ++n ) { ++nbEdges; - if ( isCornerOfStructure( *n, fSM, faceAnalyser )) { + if ( IsCornerOfStructure( *n, fSM, faceAnalyser )) { nbEdgesInSide.push_back( nbEdges ); nbEdges = 0; } @@ -2972,7 +3016,7 @@ bool SMESH_MesherHelper::IsReversedSubMesh (const TopoDS_Face& theFace) if ( !aSubMeshDSFace ) return isReversed; - // find an element on a bounday of theFace + // find an element on a boundary of theFace SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements(); const SMDS_MeshNode* nn[2]; while ( iteratorElem->more() ) // loop on elements on theFace @@ -3413,9 +3457,9 @@ TopoDS_Shape SMESH_MesherHelper::GetShapeOfHypothesis( const SMESHDS_Hypothesis SMESH_MesherHelper:: MType SMESH_MesherHelper::IsQuadraticMesh() { - int NbAllEdgsAndFaces=0; - int NbQuadFacesAndEdgs=0; - int NbFacesAndEdges=0; + smIdType NbAllEdgsAndFaces=0; + smIdType NbQuadFacesAndEdgs=0; + smIdType NbFacesAndEdges=0; //All faces and edges NbAllEdgsAndFaces = myMesh->NbEdges() + myMesh->NbFaces(); if ( NbAllEdgsAndFaces == 0 ) @@ -4132,30 +4176,30 @@ namespace { // Structures used by FixQuadraticElements() */ //================================================================================ - bool QFace::IsSpoiled(const QLink* bentLink ) const // todo: unused - { - // code is valid for convex faces only - gp_XYZ gc(0,0,0); - for ( TIDSortedNodeSet::const_iterator n = begin(); n != end(); ++n ) - gc += XYZ( *n ) / double( size() ); - for ( size_t i = 0; i < _sides.size(); ++i ) - { - if ( _sides[i] == bentLink ) continue; - gp_Vec linkNorm = _normal ^ gp_Vec( XYZ(_sides[i]->node1()), XYZ(_sides[i]->node2())); - gp_Vec vecOut( gc, _sides[i]->MiddlePnt() ); - if ( linkNorm * vecOut < 0 ) - linkNorm.Reverse(); - double mag2 = linkNorm.SquareMagnitude(); - if ( mag2 > numeric_limits::min() ) - linkNorm /= sqrt( mag2 ); - gp_Vec vecBent ( _sides[i]->MiddlePnt(), bentLink->MediumPnt()); - gp_Vec vecStraight( _sides[i]->MiddlePnt(), bentLink->MiddlePnt()); - if ( vecBent * linkNorm > -0.1*vecStraight.Magnitude() ) - return true; - } - return false; + // bool QFace::IsSpoiled(const QLink* bentLink ) const + // { + // // code is valid for convex faces only + // gp_XYZ gc(0,0,0); + // for ( TIDSortedNodeSet::const_iterator n = begin(); n != end(); ++n ) + // gc += XYZ( *n ) / double( size() ); + // for ( size_t i = 0; i < _sides.size(); ++i ) + // { + // if ( _sides[i] == bentLink ) continue; + // gp_Vec linkNorm = _normal ^ gp_Vec( XYZ(_sides[i]->node1()), XYZ(_sides[i]->node2())); + // gp_Vec vecOut( gc, _sides[i]->MiddlePnt() ); + // if ( linkNorm * vecOut < 0 ) + // linkNorm.Reverse(); + // double mag2 = linkNorm.SquareMagnitude(); + // if ( mag2 > numeric_limits::min() ) + // linkNorm /= sqrt( mag2 ); + // gp_Vec vecBent ( _sides[i]->MiddlePnt(), bentLink->MediumPnt()); + // gp_Vec vecStraight( _sides[i]->MiddlePnt(), bentLink->MiddlePnt()); + // if ( vecBent * linkNorm > -0.1*vecStraight.Magnitude() ) + // return true; + // } + // return false; - } + // } //================================================================================ /*! @@ -4941,13 +4985,20 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError, SMESH_MesherHelper h(*myMesh); h.SetSubShape( s.Current() ); h.ToFixNodeParameters(true); - h.FixQuadraticElements( compError, false ); + try { + OCC_CATCH_SIGNALS; + h.FixQuadraticElements( compError, false ); + } + catch(...) { + if ( compError && compError->myComment.empty() ) + compError->myComment = "SMESH_MesherHelper::FixQuadraticElements() failed"; + } } } // fix nodes on geom faces #ifdef _DEBUG_ int nbfaces = nbSolids; - nbfaces = faces.Extent(); /*avoid "unused varianbles": */ nbfaces++, nbfaces--; + nbfaces = faces.Extent(); /*avoid "unused varianbles": */ nbfaces++, nbfaces--; #endif for ( TopTools_MapIteratorOfMapOfShape fIt( faces ); fIt.More(); fIt.Next() ) { MESSAGE("FIX FACE " << nbfaces-- << " #" << GetMeshDS()->ShapeToIndex(fIt.Key())); @@ -4955,7 +5006,14 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError, SMESH_MesherHelper h(*myMesh); h.SetSubShape( fIt.Key() ); h.ToFixNodeParameters(true); - h.FixQuadraticElements( compError, true); + try { + OCC_CATCH_SIGNALS; + h.FixQuadraticElements( compError, true); + } + catch(...) { + if ( compError && compError->myComment.empty() ) + compError->myComment = "SMESH_MesherHelper::FixQuadraticElements() failed"; + } } //perf_print_all_meters(1); if ( compError && compError->myName == EDITERR_NO_MEDIUM_ON_GEOM ) @@ -5163,8 +5221,10 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError, while ( len < numeric_limits::min() ) { // remove degenerated link if ( savedChain.empty() ) savedChain = chain; link1 = chain.erase( link1 ); - if ( link1 == chain.end() ) + if ( link1 == chain.end() ) { + link1 = --chain.end(); break; + } len = ((*link0)->MiddlePnt() - (*link1)->MiddlePnt()).Modulus(); } chainLen += len; @@ -5181,6 +5241,9 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError, linkPos.push_back( chainLen ); } } + if ( chain.begin() == --chain.end() ) // chain.size() == 1 + continue; + gp_Vec move0 = chain.front()->_nodeMove; gp_Vec move1 = chain.back ()->_nodeMove;