X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH%2FSMESH_MesherHelper.cxx;h=a1f9b3963a8c7be2ceabac23936ac6a3937e3ce5;hp=3877d8a7bf9f90a51a631cabc7b59224616be80e;hb=9b504e486741f715fe6169a33418954712c314c2;hpb=c98d9fcd7f02c1f1f5c24dd3e709ed75228d66c4 diff --git a/src/SMESH/SMESH_MesherHelper.cxx b/src/SMESH/SMESH_MesherHelper.cxx index 3877d8a7b..a1f9b3963 100644 --- a/src/SMESH/SMESH_MesherHelper.cxx +++ b/src/SMESH/SMESH_MesherHelper.cxx @@ -31,8 +31,10 @@ #include "SMDS_FacePosition.hxx" #include "SMDS_IteratorOnIterators.hxx" #include "SMDS_VolumeTool.hxx" +#include "SMESHDS_Mesh.hxx" #include "SMESH_Block.hxx" #include "SMESH_HypoFilter.hxx" +#include "SMESH_Mesh.hxx" #include "SMESH_MeshAlgos.hxx" #include "SMESH_ProxyMesh.hxx" #include "SMESH_subMesh.hxx" @@ -113,6 +115,28 @@ SMESH_MesherHelper::~SMESH_MesherHelper() } } +//================================================================================ +/*! + * \brief Return SMESH_Gen + */ +//================================================================================ + +SMESH_Gen* SMESH_MesherHelper::GetGen() const +{ + return GetMesh()->GetGen(); +} + +//================================================================================ +/*! + * \brief Return mesh DS + */ +//================================================================================ + +SMESHDS_Mesh* SMESH_MesherHelper::GetMeshDS() const +{ + return GetMesh()->GetMeshDS(); +} + //======================================================================= //function : IsQuadraticSubMesh //purpose : Check submesh for given shape: if all elements on this shape @@ -280,6 +304,7 @@ void SMESH_MesherHelper::SetSubShape(const TopoDS_Shape& aSh) double u2 = uv1.Coord(1); myPar1[0] = Min( u1, u2 ); myPar2[0] = Max( u1, u2 ); + myParIndex |= U_periodic; } else { @@ -289,6 +314,7 @@ void SMESH_MesherHelper::SetSubShape(const TopoDS_Shape& aSh) double v2 = uv1.Coord(2); myPar1[1] = Min( v1, v2 ); myPar2[1] = Max( v1, v2 ); + myParIndex |= V_periodic; } } else //if ( !isSeam ) @@ -308,11 +334,18 @@ void SMESH_MesherHelper::SetSubShape(const TopoDS_Shape& aSh) { double f,l, r = 0.2345; Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface( edge, face, f, l ); - uv2 = C2d->Value( f * r + l * ( 1.-r )); - if ( du < Precision::PConfusion() ) - isSeam = ( Abs( uv1.Coord(1) - uv2.Coord(1) ) < Precision::PConfusion() ); + if ( C2d.IsNull() ) + { + isSeam = false; + } else - isSeam = ( Abs( uv1.Coord(2) - uv2.Coord(2) ) < Precision::PConfusion() ); + { + uv2 = C2d->Value( f * r + l * ( 1.-r )); + if ( du < Precision::PConfusion() ) + isSeam = ( Abs( uv1.Coord(1) - uv2.Coord(1) ) < Precision::PConfusion() ); + else + isSeam = ( Abs( uv1.Coord(2) - uv2.Coord(2) ) < Precision::PConfusion() ); + } } } if ( isSeam ) @@ -340,6 +373,16 @@ void SMESH_MesherHelper::SetSubShape(const TopoDS_Shape& aSh) } } +//======================================================================= +//function : ShapeToIndex +//purpose : Convert a shape to its index in the SMESHDS_Mesh +//======================================================================= + +int SMESH_MesherHelper::ShapeToIndex( const TopoDS_Shape& S ) const +{ + return GetMeshDS()->ShapeToIndex( S ); +} + //======================================================================= //function : GetNodeUVneedInFaceNode //purpose : Check if inFaceNode argument is necessary for call GetNodeUV(F,..) @@ -653,8 +696,7 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F, { if ( !IsSubShape( V, F )) { - MESSAGE ( "SMESH_MesherHelper::GetNodeUV(); Vertex " << vertexID - << " not in face " << GetMeshDS()->ShapeToIndex( F ) ); + MESSAGE("GetNodeUV() Vertex "<< vertexID <<" not in face "<< GetMeshDS()->ShapeToIndex(F)); // get UV of a vertex closest to the node double dist = 1e100; gp_Pnt pn = XYZ( n ); @@ -1073,7 +1115,6 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge& E, } Quantity_Parameter U = projector->LowerDistanceParameter(); u = double( U ); - MESSAGE(" f " << f << " l " << l << " u " << u); curvPnt = curve->Value( u ); dist = nodePnt.Distance( curvPnt ); if ( distXYZ ) { @@ -1083,8 +1124,7 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge& E, } if ( dist > tol ) { - MESSAGE( "SMESH_MesherHelper::CheckNodeU(), invalid projection" ); - MESSAGE("distance " << dist << " " << tol ); + MESSAGE( "CheckNodeU(), invalid projection; distance " << dist << "; tol " << tol ); return false; } // store the fixed U on the edge @@ -1609,7 +1649,7 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1, // get type of shape for the new medium node int faceID = -1, edgeID = -1; - TopoDS_Edge E; double u [2]; + TopoDS_Edge E; double u [2] = {0.,0.}; TopoDS_Face F; gp_XY uv[2]; bool uvOK[2] = { true, true }; const bool useCurSubShape = ( !myShape.IsNull() && myShape.ShapeType() == TopAbs_EDGE ); @@ -2528,6 +2568,7 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2 } // get nodes on theBaseEdge sorted by param on edge and initialize theParam2ColumnMap with them + const SMDS_MeshNode* prevEndNodes[2] = { 0, 0 }; edge = theBaseSide.begin(); for ( int iE = 0; edge != theBaseSide.end(); ++edge, ++iE ) { @@ -2595,11 +2636,16 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2 const double prevPar = theParam2ColumnMap.empty() ? 0 : theParam2ColumnMap.rbegin()->first; for ( u_n = sortedBaseNN.begin(); u_n != sortedBaseNN.end(); u_n++ ) { + if ( u_n->second == prevEndNodes[0] || + u_n->second == prevEndNodes[1] ) + continue; double par = prevPar + coeff * ( u_n->first - f ); TParam2ColumnMap::iterator u2nn = theParam2ColumnMap.insert( theParam2ColumnMap.end(), make_pair( par, TNodeColumn())); u2nn->second.push_back( u_n->second ); } + prevEndNodes[0] = sortedBaseNN.begin()->second; + prevEndNodes[1] = sortedBaseNN.rbegin()->second; } if ( theParam2ColumnMap.size() < 2 ) return false; @@ -2890,7 +2936,7 @@ bool SMESH_MesherHelper::IsReversedSubMesh (const TopoDS_Face& theFace) TopoDS_Shape s0 = GetSubShapeByNode( nn[0], GetMeshDS() ); TopoDS_Shape s1 = GetSubShapeByNode( nn[1], GetMeshDS() ); TopoDS_Shape E = GetCommonAncestor( s0, s1, *myMesh, TopAbs_EDGE ); - if ( !E.IsNull() && !s0.IsSame( s1 )) + if ( !E.IsNull() && !s0.IsSame( s1 ) && E.Orientation() != TopAbs_INTERNAL ) { // is E seam edge? int nb = 0; @@ -2904,10 +2950,16 @@ bool SMESH_MesherHelper::IsReversedSubMesh (const TopoDS_Face& theFace) bool ok = true; double u0 = GetNodeU( TopoDS::Edge( E ), nn[0], nn[1], &ok ); double u1 = GetNodeU( TopoDS::Edge( E ), nn[1], nn[0], &ok ); - // check that the 2 nodes are connected with a segment (IPAL53055) - if ( SMESHDS_SubMesh* sm = GetMeshDS()->MeshElements( E )) - if ( sm->NbElements() > 0 && !GetMeshDS()->FindEdge( nn[0], nn[1] )) - ok = false; + if ( ok ) + { + // check that the 2 nodes are connected with a segment (IPAL53055) + ok = false; + const SMDS_MeshElement* seg; + if ( SMESHDS_SubMesh* sm = GetMeshDS()->MeshElements( E )) + if (( sm->NbElements() > 0 ) && + ( seg = GetMeshDS()->FindEdge( nn[0], nn[1] ))) + ok = sm->Contains( seg ); + } if ( ok ) { isReversed = ( u0 > u1 ); @@ -3049,8 +3101,6 @@ bool SMESH_MesherHelper::IsSubShape( const TopoDS_Shape& shape, if ( shape.IsSame( exp.Current() )) return true; } - SCRUTE((shape.IsNull())); - SCRUTE((mainShape.IsNull())); return false; } @@ -3358,11 +3408,16 @@ namespace { TopTools_ListIteratorOfListOfShape _ancIter; TopAbs_ShapeEnum _type; TopTools_MapOfShape _encountered; - TAncestorsIterator( const TopTools_ListOfShape& ancestors, TopAbs_ShapeEnum type) + TopTools_IndexedMapOfShape _allowed; + TAncestorsIterator( const TopTools_ListOfShape& ancestors, + TopAbs_ShapeEnum type, + const TopoDS_Shape* container/* = 0*/) : _ancIter( ancestors ), _type( type ) { + if ( container && !container->IsNull() ) + TopExp::MapShapes( *container, type, _allowed); if ( _ancIter.More() ) { - if ( _ancIter.Value().ShapeType() != _type ) next(); + if ( !isCurrentAllowed() ) next(); else _encountered.Add( _ancIter.Value() ); } } @@ -3375,25 +3430,32 @@ namespace { const TopoDS_Shape* s = _ancIter.More() ? & _ancIter.Value() : 0; if ( _ancIter.More() ) for ( _ancIter.Next(); _ancIter.More(); _ancIter.Next()) - if ( _ancIter.Value().ShapeType() == _type && _encountered.Add( _ancIter.Value() )) + if ( isCurrentAllowed() && _encountered.Add( _ancIter.Value() )) break; return s; } + bool isCurrentAllowed() + { + return (( _ancIter.Value().ShapeType() == _type ) && + ( _allowed.IsEmpty() || _allowed.Contains( _ancIter.Value() ))); + } }; } // namespace //======================================================================= /*! - * \brief Return iterator on ancestors of the given type + * \brief Return iterator on ancestors of the given type, included into a container shape */ //======================================================================= PShapeIteratorPtr SMESH_MesherHelper::GetAncestors(const TopoDS_Shape& shape, const SMESH_Mesh& mesh, - TopAbs_ShapeEnum ancestorType) + TopAbs_ShapeEnum ancestorType, + const TopoDS_Shape* container) { - return PShapeIteratorPtr( new TAncestorsIterator( mesh.GetAncestors(shape), ancestorType)); + return PShapeIteratorPtr + ( new TAncestorsIterator( mesh.GetAncestors(shape), ancestorType, container)); } //======================================================================= @@ -4591,7 +4653,7 @@ namespace { // Structures used by FixQuadraticElements() SMDS_ElemIteratorPtr faceIter( new TIterOnIter( faceIterVec )); // a seacher to check if a volume is close to a concave face - std::auto_ptr< SMESH_ElementSearcher > faceSearcher + SMESHUtils::Deleter< SMESH_ElementSearcher > faceSearcher ( SMESH_MeshAlgos::GetElementSearcher( *theHelper.GetMeshDS(), faceIter )); // classifier @@ -4693,7 +4755,7 @@ namespace { // Structures used by FixQuadraticElements() gp_Pnt pMedium = SMESH_TNodeXYZ( linkIt->second ); double hMedium = faceNorm * gp_Vec( pOnFace0, pMedium ).XYZ(); double hVol = faceNorm * gp_Vec( pOnFace0, pInSolid ).XYZ(); - isDistorted = ( Abs( hMedium ) > Abs( hVol * 0.5 )); + isDistorted = ( Abs( hMedium ) > Abs( hVol * 0.75 )); } } } @@ -4774,7 +4836,8 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError, } // fix nodes on geom faces #ifdef _DEBUG_ - int nbfaces = faces.Extent(); /*avoid "unused varianbles": */ nbfaces++, nbfaces--; + int nbfaces = nbSolids; + nbfaces = faces.Extent(); /*avoid "unused varianbles": */ nbfaces++, nbfaces--; #endif for ( TopTools_MapIteratorOfMapOfShape fIt( faces ); fIt.More(); fIt.Next() ) { MSG("FIX FACE " << nbfaces-- << " #" << GetMeshDS()->ShapeToIndex(fIt.Key())); @@ -5115,6 +5178,7 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError, "uv2: "<Move( move, /*sum=*/false, /*is2dFixed=*/true ); @@ -5133,7 +5197,6 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError, // ------------- TIDSortedElemSet biQuadQuas, biQuadTris, triQuadHexa; - const SMDS_MeshElement *biQuadQua, *triQuadHex; const bool toFixCentralNodes = ( myMesh->NbBiQuadQuadrangles() + myMesh->NbBiQuadTriangles() + myMesh->NbTriQuadraticHexas() ); @@ -5164,7 +5227,6 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError, // collect bi-quadratic elements if ( toFixCentralNodes ) { - biQuadQua = triQuadHex = 0; SMDS_ElemIteratorPtr eIt = pLink->_mediumNode->GetInverseElementIterator(); while ( eIt->more() ) { @@ -5323,4 +5385,24 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError, nCenterCoords.X(), nCenterCoords.Y(), nCenterCoords.Z()); } } +#ifdef _DEBUG_ + // avoid warning: defined but not used operator<<() + SMESH_Comment() << *links.begin() << *faces.begin(); +#endif } + +//================================================================================ +/*! + * \brief DEBUG + */ +//================================================================================ + +void SMESH_MesherHelper::WriteShape(const TopoDS_Shape& s) +{ + const char* name = "/tmp/shape.brep"; + BRepTools::Write( s, name ); +#ifdef _DEBUG_ + std::cout << name << std::endl; +#endif +} +