X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_ViscousLayers.cxx;h=a384191b2be9903701f64001acb577d3e5007b28;hp=eafdf22ef132433b1160be9fc79ffb6e3c07ce12;hb=2f529dcd2629679dadcca3047583bfcf28ca7b1a;hpb=264eeb2edd6977ccf2d2bd88cbb210353f63f7c9 diff --git a/src/StdMeshers/StdMeshers_ViscousLayers.cxx b/src/StdMeshers/StdMeshers_ViscousLayers.cxx index eafdf22ef..a384191b2 100644 --- a/src/StdMeshers/StdMeshers_ViscousLayers.cxx +++ b/src/StdMeshers/StdMeshers_ViscousLayers.cxx @@ -27,6 +27,7 @@ #include "SMDS_FaceOfNodes.hxx" #include "SMDS_FacePosition.hxx" #include "SMDS_MeshNode.hxx" +#include "SMDS_PolygonalFaceOfNodes.hxx" #include "SMDS_SetIterator.hxx" #include "SMESHDS_Group.hxx" #include "SMESHDS_Hypothesis.hxx" @@ -93,9 +94,10 @@ #include #include #include +#include #ifdef _DEBUG_ -#define __myDEBUG +//#define __myDEBUG //#define __NOT_INVALIDATE_BAD_SMOOTH //#define __NODES_AT_POS #endif @@ -114,7 +116,7 @@ namespace VISCOUS_3D enum UIndex { U_TGT = 1, U_SRC, LEN_TGT }; const double theMinSmoothCosin = 0.1; - const double theSmoothThickToElemSizeRatio = 0.3; + const double theSmoothThickToElemSizeRatio = 0.6; const double theMinSmoothTriaAngle = 30; const double theMinSmoothQuadAngle = 45; @@ -500,9 +502,12 @@ namespace VISCOUS_3D gp_Ax1 LastSegment(double& segLen, _EdgesOnShape& eos) const; gp_XY LastUV( const TopoDS_Face& F, _EdgesOnShape& eos, int which=-1 ) const; bool IsOnEdge() const { return _2neibors; } + bool IsOnFace() const { return ( _nodes[0]->GetPosition()->GetDim() == 2 ); } + int BaseShapeDim() const { return _nodes[0]->GetPosition()->GetDim(); } gp_XYZ Copy( _LayerEdge& other, _EdgesOnShape& eos, SMESH_MesherHelper& helper ); void SetCosin( double cosin ); void SetNormal( const gp_XYZ& n ) { _normal = n; } + void SetMaxLen( double l ) { _maxLen = l; } int NbSteps() const { return _pos.size() - 1; } // nb inlation steps bool IsNeiborOnEdge( const _LayerEdge* edge ) const; void SetSmooLen( double len ) { // set _len at which smoothing is needed @@ -657,7 +662,8 @@ namespace VISCOUS_3D vector< _EdgesOnShape* > _eosConcaVer; // edges at concave VERTEXes of a FACE vector< _EdgesOnShape* > _eosC1; // to smooth together several C1 continues shapes - vector< gp_XYZ > _faceNormals; // if _shape is FACE + typedef std::unordered_map< const SMDS_MeshElement*, gp_XYZ > TFace2NormMap; + TFace2NormMap _faceNormals; // if _shape is FACE vector< _EdgesOnShape* > _faceEOS; // to get _faceNormals of adjacent FACEs Handle(ShapeAnalysis_Surface) _offsetSurf; @@ -761,7 +767,7 @@ namespace VISCOUS_3D // Convex FACEs whose radius of curvature is less than the thickness of layers map< TGeomID, _ConvexFace > _convexFaces; - // shapes (EDGEs and VERTEXes) srink from which is forbidden due to collisions with + // shapes (EDGEs and VERTEXes) shrink from which is forbidden due to collisions with // the adjacent SOLID set< TGeomID > _noShrinkShapes; @@ -844,6 +850,8 @@ namespace VISCOUS_3D void Append( const gp_Pnt& center, _LayerEdge* ledge ) { + if ( ledge->Is( _LayerEdge::MULTI_NORMAL )) + return; if ( _curvaCenters.size() > 0 ) _segLength2.push_back( center.SquareDistance( _curvaCenters.back() )); _curvaCenters.push_back( center ); @@ -959,7 +967,7 @@ namespace VISCOUS_3D void limitMaxLenByCurvature( _SolidData& data, SMESH_MesherHelper& helper ); void limitMaxLenByCurvature( _LayerEdge* e1, _LayerEdge* e2, _EdgesOnShape& eos1, _EdgesOnShape& eos2, - SMESH_MesherHelper& helper ); + const bool isSmoothable ); bool updateNormals( _SolidData& data, SMESH_MesherHelper& helper, int stepNb, double stepSize ); bool updateNormalsOfConvexFaces( _SolidData& data, SMESH_MesherHelper& helper, @@ -1084,31 +1092,32 @@ namespace VISCOUS_3D return _eos._edges[ is2nd ? _eos._edges.size()-1 : 0 ]->_2neibors->_edges[ is2nd ]; } bool isAnalytic() const { return !_anaCurve.IsNull(); } + + void offPointsToPython() const; // debug }; //-------------------------------------------------------------------------------- /*! * \brief Class of temporary mesh face. * We can't use SMDS_FaceOfNodes since it's impossible to set it's ID which is - * needed because SMESH_ElementSearcher internaly uses set of elements sorted by ID + * needed because SMESH_ElementSearcher internally uses set of elements sorted by ID */ - struct _TmpMeshFace : public SMDS_MeshElement + struct _TmpMeshFace : public SMDS_PolygonalFaceOfNodes { - vector _nn; + const SMDS_MeshElement* _srcFace; + _TmpMeshFace( const vector& nodes, - int id, int faceID=-1, int idInFace=-1): - SMDS_MeshElement(id), _nn(nodes) { setShapeId(faceID); setIdInShape(idInFace); } - virtual const SMDS_MeshNode* GetNode(const int ind) const { return _nn[ind]; } - virtual SMDSAbs_ElementType GetType() const { return SMDSAbs_Face; } - virtual vtkIdType GetVtkType() const { return -1; } - virtual SMDSAbs_EntityType GetEntityType() const { return SMDSEntity_Last; } - virtual SMDSAbs_GeometryType GetGeomType() const - { return _nn.size() == 3 ? SMDSGeom_TRIANGLE : SMDSGeom_QUADRANGLE; } - virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType) const - { return SMDS_ElemIteratorPtr( new SMDS_NodeVectorElemIterator( _nn.begin(), _nn.end()));} + int ID, + int faceID=-1, + const SMDS_MeshElement* srcFace=0 ): + SMDS_PolygonalFaceOfNodes(nodes), _srcFace( srcFace ) { setID( ID ); setShapeID( faceID ); } + virtual SMDSAbs_EntityType GetEntityType() const + { return _srcFace ? _srcFace->GetEntityType() : SMDSEntity_Quadrangle; } + virtual SMDSAbs_GeometryType GetGeomType() const + { return _srcFace ? _srcFace->GetGeomType() : SMDSGeom_QUADRANGLE; } }; //-------------------------------------------------------------------------------- /*! - * \brief Class of temporary mesh face storing _LayerEdge it's based on + * \brief Class of temporary mesh quadrangle face storing _LayerEdge it's based on */ struct _TmpMeshFaceOnEdge : public _TmpMeshFace { @@ -1116,17 +1125,21 @@ namespace VISCOUS_3D _TmpMeshFaceOnEdge( _LayerEdge* le1, _LayerEdge* le2, int ID ): _TmpMeshFace( vector(4), ID ), _le1(le1), _le2(le2) { - _nn[0]=_le1->_nodes[0]; - _nn[1]=_le1->_nodes.back(); - _nn[2]=_le2->_nodes.back(); - _nn[3]=_le2->_nodes[0]; + myNodes[0]=_le1->_nodes[0]; + myNodes[1]=_le1->_nodes.back(); + myNodes[2]=_le2->_nodes.back(); + myNodes[3]=_le2->_nodes[0]; + } + const SMDS_MeshNode* n( size_t i ) const + { + return myNodes[ i ]; } gp_XYZ GetDir() const // return average direction of _LayerEdge's, normal to EDGE { - SMESH_TNodeXYZ p0s( _nn[0] ); - SMESH_TNodeXYZ p0t( _nn[1] ); - SMESH_TNodeXYZ p1t( _nn[2] ); - SMESH_TNodeXYZ p1s( _nn[3] ); + SMESH_TNodeXYZ p0s( myNodes[0] ); + SMESH_TNodeXYZ p0t( myNodes[1] ); + SMESH_TNodeXYZ p1t( myNodes[2] ); + SMESH_TNodeXYZ p1s( myNodes[3] ); gp_XYZ v0 = p0t - p0s; gp_XYZ v1 = p1t - p1s; gp_XYZ v01 = p1s - p0s; @@ -1137,10 +1150,10 @@ namespace VISCOUS_3D } gp_XYZ GetDir(_LayerEdge* le1, _LayerEdge* le2) // return average direction of _LayerEdge's { - _nn[0]=le1->_nodes[0]; - _nn[1]=le1->_nodes.back(); - _nn[2]=le2->_nodes.back(); - _nn[3]=le2->_nodes[0]; + myNodes[0]=le1->_nodes[0]; + myNodes[1]=le1->_nodes.back(); + myNodes[2]=le2->_nodes.back(); + myNodes[3]=le2->_nodes[0]; return GetDir(); } }; @@ -1603,8 +1616,8 @@ namespace VISCOUS_3D // look for two neighbor not in-FACE nodes of face for ( int i = 0; i < 2; ++i ) { - if ( nNext[i]->GetPosition()->GetDim() != 2 && - nNext[i]->GetID() < nodeOnEdge->GetID() ) + if (( nNext[i]->GetPosition()->GetDim() != 2 ) && + ( nodeOnEdge->GetPosition()->GetDim() == 0 || nNext[i]->GetID() < nodeOnEdge->GetID() )) { // look for an in-FACE node for ( int iN = 0; iN < nbN; ++iN ) @@ -2338,7 +2351,7 @@ bool _ViscousBuilder::findFacesWithLayers(const bool onlyWith) for ( TopoDS_Iterator vIt( edge ); vIt.More(); vIt.Next() ) { TGeomID vID = getMeshDS()->ShapeToIndex( vIt.Value() ); - bool noShrinkV = false; + bool noShrinkV = false, noShrinkIfAdjMeshed = false; if ( iSolid < _sdVec.size() ) { @@ -2348,7 +2361,8 @@ bool _ViscousBuilder::findFacesWithLayers(const bool onlyWith) i2S = _sdVec[i ]._shrinkShape2Shape.find( vID ); i2SAdj = _sdVec[iSolid]._shrinkShape2Shape.find( vID ); if ( i2SAdj == _sdVec[iSolid]._shrinkShape2Shape.end() ) - noShrinkV = ( i2S->second.ShapeType() == TopAbs_EDGE || isStructured ); + noShrinkV = (( isStructured ) || + ( noShrinkIfAdjMeshed = i2S->second.ShapeType() == TopAbs_EDGE )); else noShrinkV = ( ! i2S->second.IsSame( i2SAdj->second )); } @@ -2360,8 +2374,31 @@ bool _ViscousBuilder::findFacesWithLayers(const bool onlyWith) else { // the adjacent SOLID has NO layers at all - noShrinkV = ( isStructured || - _sdVec[i]._shrinkShape2Shape[ vID ].ShapeType() == TopAbs_EDGE ); + if ( isStructured ) + { + noShrinkV = true; + } + else + { + noShrinkV = noShrinkIfAdjMeshed = + ( _sdVec[i]._shrinkShape2Shape[ vID ].ShapeType() == TopAbs_EDGE ); + } + } + + if ( noShrinkV && noShrinkIfAdjMeshed ) + { + // noShrinkV if FACEs in the adjacent SOLID are meshed + PShapeIteratorPtr fIt = helper.GetAncestors( _sdVec[i]._shrinkShape2Shape[ vID ], + *_mesh, TopAbs_FACE, &solid ); + while ( fIt->more() ) + { + const TopoDS_Shape* f = fIt->next(); + if ( !f->IsSame( fWOL )) + { + noShrinkV = ! _mesh->GetSubMesh( *f )->IsEmpty(); + break; + } + } } if ( noShrinkV ) _sdVec[i]._noShrinkShapes.insert( vID ); @@ -2610,7 +2647,7 @@ bool _ViscousBuilder::makeLayer(_SolidData& data) // create a temporary face const SMDS_MeshElement* newFace = - new _TmpMeshFace( newNodes, --_tmpFaceID, face->getshapeId(), face->getIdInShape() ); + new _TmpMeshFace( newNodes, --_tmpFaceID, face->GetShapeID(), face ); proxySub->AddElement( newFace ); // compute inflation step size by min size of element on a convex surface @@ -2855,7 +2892,7 @@ void _ViscousBuilder::limitStepSizeByCurvature( _SolidData& data ) double curvature = Max( surfProp.MaxCurvature() * oriFactor, surfProp.MinCurvature() * oriFactor ); if ( curvature > minCurvature ) - ledge->_maxLen = Min( ledge->_maxLen, 1. / curvature ); + ledge->SetMaxLen( Min( ledge->_maxLen, 1. / curvature )); } } } @@ -2876,7 +2913,12 @@ void _ViscousBuilder::limitStepSizeByCurvature( _SolidData& data ) for ( size_t j = 0; j < ledge->_simplices.size(); ++j ) if ( ledge->_simplices[j]._nNext->GetPosition()->GetDim() < 2 ) { - convFace._simplexTestEdges.push_back( ledge ); + // do not select _LayerEdge's neighboring sharp EDGEs + bool sharpNbr = false; + for ( size_t iN = 0; iN < ledge->_neibors.size() && !sharpNbr; ++iN ) + sharpNbr = ( ledge->_neibors[iN]->_cosin > theMinSmoothCosin ); + if ( !sharpNbr ) + convFace._simplexTestEdges.push_back( ledge ); break; } } @@ -2926,22 +2968,11 @@ bool _ViscousBuilder::findShapesToSmooth( _SolidData& data ) // define allowed thickness computeGeomSize( data ); // compute data._geomSize and _LayerEdge::_maxLen - data._maxThickness = 0; - data._minThickness = 1e100; - list< const StdMeshers_ViscousLayers* >::iterator hyp = data._hyps.begin(); - for ( ; hyp != data._hyps.end(); ++hyp ) - { - data._maxThickness = Max( data._maxThickness, (*hyp)->GetTotalThickness() ); - data._minThickness = Min( data._minThickness, (*hyp)->GetTotalThickness() ); - } - //const double tgtThick = /*Min( 0.5 * data._geomSize, */data._maxThickness; // Find shapes needing smoothing; such a shape has _LayerEdge._normal on it's // boundary inclined to the shape at a sharp angle - //list< TGeomID > shapesToSmooth; TopTools_MapOfShape edgesOfSmooFaces; - SMESH_MesherHelper helper( *_mesh ); bool ok = true; @@ -2956,32 +2987,34 @@ bool _ViscousBuilder::findShapesToSmooth( _SolidData& data ) continue; double tgtThick = eos._hyp.GetTotalThickness(); - TopExp_Explorer eExp( edgesByGeom[iS]._shape, TopAbs_EDGE ); - for ( ; eExp.More() && !eos._toSmooth; eExp.Next() ) + SMESH_subMeshIteratorPtr subIt = eos._subMesh->getDependsOnIterator(/*includeSelf=*/false ); + while ( subIt->more() && !eos._toSmooth ) { - TGeomID iE = getMeshDS()->ShapeToIndex( eExp.Current() ); - vector<_LayerEdge*>& eE = edgesByGeom[ iE ]._edges; - if ( eE.empty() ) continue; + TGeomID iSub = subIt->next()->GetId(); + const vector<_LayerEdge*>& eSub = edgesByGeom[ iSub ]._edges; + if ( eSub.empty() ) continue; double faceSize; - for ( size_t i = 0; i < eE.size() && !eos._toSmooth; ++i ) - if ( eE[i]->_cosin > theMinSmoothCosin ) + for ( size_t i = 0; i < eSub.size() && !eos._toSmooth; ++i ) + if ( eSub[i]->_cosin > theMinSmoothCosin ) { - SMDS_ElemIteratorPtr fIt = eE[i]->_nodes[0]->GetInverseElementIterator(SMDSAbs_Face); + SMDS_ElemIteratorPtr fIt = eSub[i]->_nodes[0]->GetInverseElementIterator(SMDSAbs_Face); while ( fIt->more() && !eos._toSmooth ) { const SMDS_MeshElement* face = fIt->next(); if ( face->getshapeId() == eos._shapeID && - getDistFromEdge( face, eE[i]->_nodes[0], faceSize )) + getDistFromEdge( face, eSub[i]->_nodes[0], faceSize )) { - eos._toSmooth = needSmoothing( eE[i]->_cosin, tgtThick, faceSize ); + eos._toSmooth = needSmoothing( eSub[i]->_cosin, + tgtThick * eSub[i]->_lenFactor, + faceSize); } } } } if ( eos._toSmooth ) { - for ( eExp.ReInit(); eExp.More(); eExp.Next() ) + for ( TopExp_Explorer eExp( edgesByGeom[iS]._shape, TopAbs_EDGE ); eExp.More(); eExp.Next() ) edgesOfSmooFaces.Add( eExp.Current() ); data.PrepareEdgesToSmoothOnFace( &edgesByGeom[iS], /*substituteSrcNodes=*/false ); @@ -3025,8 +3058,8 @@ bool _ViscousBuilder::findShapesToSmooth( _SolidData& data ) if ( endSeg->getshapeId() == (int) iS ) { double segLen = - SMESH_TNodeXYZ( endSeg->GetNode(0) ).Distance( endSeg->GetNode(1 )); - eos._toSmooth = needSmoothing( cosinAbs, tgtThick, segLen ); + SMESH_TNodeXYZ( endSeg->GetNode( 0 )).Distance( endSeg->GetNode( 1 )); + eos._toSmooth = needSmoothing( cosinAbs, tgtThick * eV[0]->_lenFactor, segLen ); } } if ( eos._toSmooth ) @@ -3050,11 +3083,12 @@ bool _ViscousBuilder::findShapesToSmooth( _SolidData& data ) if ( !eos._hyp.ToSmooth() ) for ( size_t i = 0; i < eos._edges.size(); ++i ) - eos._edges[i]->SetCosin( 0 ); + //eos._edges[i]->SetCosin( 0 ); // keep _cosin to use in limitMaxLenByCurvature() + eos._edges[i]->_lenFactor = 1; } - // Fill _eosC1 to make that C1 FACEs and EGDEs between them to be smoothed as a whole + // Fill _eosC1 to make that C1 FACEs and EDGEs between them to be smoothed as a whole TopTools_MapOfShape c1VV; @@ -3114,19 +3148,21 @@ bool _ViscousBuilder::findShapesToSmooth( _SolidData& data ) { _EdgesOnShape* eof = data.GetShapeEdges( *face ); if ( !eof ) continue; // other solid - if ( !eos.HasC1( eoe )) - { - eos._eosC1.push_back( eoe ); - eoe->_toSmooth = false; - data.PrepareEdgesToSmoothOnFace( eoe, /*substituteSrcNodes=*/false ); - } - if ( eos._shapeID != eof->_shapeID && !eos.HasC1( eof )) + if ( eos._shapeID == eof->_shapeID ) continue; + if ( !eos.HasC1( eof )) { + // check the FACEs eos._eosC1.push_back( eof ); eof->_toSmooth = false; data.PrepareEdgesToSmoothOnFace( eof, /*substituteSrcNodes=*/false ); smQueue.push_back( eof->_subMesh ); } + if ( !eos.HasC1( eoe )) + { + eos._eosC1.push_back( eoe ); + eoe->_toSmooth = false; + data.PrepareEdgesToSmoothOnFace( eoe, /*substituteSrcNodes=*/false ); + } } } } @@ -3282,19 +3318,19 @@ void _ViscousBuilder::setShapeData( _EdgesOnShape& eos, if ( eos.ShapeType() == TopAbs_FACE ) // get normals to elements on a FACE { SMESHDS_SubMesh* smDS = sm->GetSubMeshDS(); - eos._faceNormals.resize( smDS->NbElements() ); + if ( !smDS ) return; + eos._faceNormals.reserve( smDS->NbElements() ); + double oriFactor = helper.IsReversedSubMesh( TopoDS::Face( eos._shape )) ? 1.: -1.; SMDS_ElemIteratorPtr eIt = smDS->GetElements(); - for ( int iF = 0; eIt->more(); ++iF ) + for ( ; eIt->more(); ) { const SMDS_MeshElement* face = eIt->next(); - if ( !SMESH_MeshAlgos::FaceNormal( face, eos._faceNormals[iF], /*normalized=*/true )) - eos._faceNormals[iF].SetCoord( 0,0,0 ); + gp_XYZ& norm = eos._faceNormals[face]; + if ( !SMESH_MeshAlgos::FaceNormal( face, norm, /*normalized=*/true )) + norm.SetCoord( 0,0,0 ); + norm *= oriFactor; } - - if ( !helper.IsReversedSubMesh( TopoDS::Face( eos._shape ))) - for ( size_t iF = 0; iF < eos._faceNormals.size(); ++iF ) - eos._faceNormals[iF].Reverse(); } else // find EOS of adjacent FACEs { @@ -3320,7 +3356,7 @@ void _ViscousBuilder::setShapeData( _EdgesOnShape& eos, bool _EdgesOnShape::GetNormal( const SMDS_MeshElement* face, gp_Vec& norm ) { bool ok = false; - const _EdgesOnShape* eos = 0; + _EdgesOnShape* eos = 0; if ( face->getshapeId() == _shapeID ) { @@ -3334,9 +3370,9 @@ bool _EdgesOnShape::GetNormal( const SMDS_MeshElement* face, gp_Vec& norm ) } if (( eos ) && - ( ok = ( face->getIdInShape() < (int) eos->_faceNormals.size() ))) + ( ok = ( eos->_faceNormals.count( face ) ))) { - norm = eos->_faceNormals[ face->getIdInShape() ]; + norm = eos->_faceNormals[ face ]; } else if ( !eos ) { @@ -3562,7 +3598,7 @@ bool _ViscousBuilder::setEdgeData(_LayerEdge& edge, getMeshDS()->RemoveFreeNode( edge._nodes.back(), 0, /*fromGroups=*/false ); edge._nodes.resize( 1 ); edge._normal.SetCoord( 0,0,0 ); - edge._maxLen = 0; + edge.SetMaxLen( 0 ); } // Set the rest data @@ -3574,7 +3610,7 @@ bool _ViscousBuilder::setEdgeData(_LayerEdge& edge, { const SMDS_MeshNode* tgtNode = edge._nodes.back(); if ( SMESHDS_SubMesh* sm = getMeshDS()->MeshElements( data._solid )) - sm->RemoveNode( tgtNode , /*isNodeDeleted=*/false ); + sm->RemoveNode( tgtNode ); // set initial position which is parameters on _sWOL in this case if ( eos.SWOLType() == TopAbs_EDGE ) @@ -3699,7 +3735,7 @@ gp_XYZ _ViscousBuilder::getFaceNormal(const SMDS_MeshNode* node, isOK = false; return p.XYZ(); } - Quantity_Parameter U,V; + Standard_Real U,V; projector.LowerDistanceParameters(U,V); uv.SetCoord( U,V ); } @@ -4110,6 +4146,8 @@ void _LayerEdge::SetDataByNeighbors( const SMDS_MeshNode* n1, { if ( eos.ShapeType() != TopAbs_EDGE ) return; + if ( _curvature && Is( SMOOTHED_C1 )) + return; gp_XYZ pos = SMESH_TNodeXYZ( _nodes[0] ); gp_XYZ vec1 = pos - SMESH_TNodeXYZ( n1 ); @@ -4276,7 +4314,7 @@ void _Simplex::SortSimplices(vector<_Simplex>& simplices) //================================================================================ /*! - * \brief DEBUG. Create groups contating temorary data of _LayerEdge's + * \brief DEBUG. Create groups containing temporary data of _LayerEdge's */ //================================================================================ @@ -4363,7 +4401,7 @@ void _ViscousBuilder::computeGeomSize( _SolidData& data ) _EdgesOnShape& eos = data._edgesOnShape[ iS ]; if ( eos._edges.empty() ) continue; - // get neighbor faces intersection with which should not be considered since + // get neighbor faces, intersection with which should not be considered since // collisions are avoided by means of smoothing set< TGeomID > neighborFaces; if ( eos._hyp.ToSmooth() ) @@ -4383,16 +4421,88 @@ void _ViscousBuilder::computeGeomSize( _SolidData& data ) for ( size_t i = 0; i < eos._edges.size(); ++i ) { if ( eos._edges[i]->Is( _LayerEdge::BLOCKED )) continue; - eos._edges[i]->_maxLen = thinkness; + eos._edges[i]->SetMaxLen( thinkness ); eos._edges[i]->FindIntersection( *searcher, intersecDist, data._epsilon, eos, &face ); if ( intersecDist > 0 && face ) { data._geomSize = Min( data._geomSize, intersecDist ); if ( !neighborFaces.count( face->getshapeId() )) - eos._edges[i]->_maxLen = Min( thinkness, intersecDist / ( face->GetID() < 0 ? 3. : 2. )); + eos[i]->SetMaxLen( Min( thinkness, intersecDist / ( face->GetID() < 0 ? 3. : 2. ))); } } } + + data._maxThickness = 0; + data._minThickness = 1e100; + list< const StdMeshers_ViscousLayers* >::iterator hyp = data._hyps.begin(); + for ( ; hyp != data._hyps.end(); ++hyp ) + { + data._maxThickness = Max( data._maxThickness, (*hyp)->GetTotalThickness() ); + data._minThickness = Min( data._minThickness, (*hyp)->GetTotalThickness() ); + } + + // Limit inflation step size by geometry size found by intersecting + // normals of _LayerEdge's with mesh faces + if ( data._stepSize > 0.3 * data._geomSize ) + limitStepSize( data, 0.3 * data._geomSize ); + + if ( data._stepSize > data._minThickness ) + limitStepSize( data, data._minThickness ); + + + // ------------------------------------------------------------------------- + // Detect _LayerEdge which can't intersect with opposite or neighbor layer, + // so no need in detecting intersection at each inflation step + // ------------------------------------------------------------------------- + + int nbSteps = data._maxThickness / data._stepSize; + if ( nbSteps < 3 || nbSteps * data._n2eMap.size() < 100000 ) + return; + + vector< const SMDS_MeshElement* > closeFaces; + int nbDetected = 0; + + for ( size_t iS = 0; iS < data._edgesOnShape.size(); ++iS ) + { + _EdgesOnShape& eos = data._edgesOnShape[ iS ]; + if ( eos._edges.empty() || eos.ShapeType() != TopAbs_FACE ) + continue; + + for ( size_t i = 0; i < eos.size(); ++i ) + { + SMESH_NodeXYZ p( eos[i]->_nodes[0] ); + double radius = data._maxThickness + 2 * eos[i]->_maxLen; + closeFaces.clear(); + searcher->GetElementsInSphere( p, radius, SMDSAbs_Face, closeFaces ); + + bool toIgnore = true; + for ( size_t iF = 0; iF < closeFaces.size() && toIgnore; ++iF ) + if ( !( toIgnore = ( closeFaces[ iF ]->getshapeId() == eos._shapeID || + data._ignoreFaceIds.count( closeFaces[ iF ]->getshapeId() )))) + { + // check if a _LayerEdge will inflate in a direction opposite to a direction + // toward a close face + bool allBehind = true; + for ( int iN = 0; iN < closeFaces[ iF ]->NbCornerNodes() && allBehind; ++iN ) + { + SMESH_NodeXYZ pi( closeFaces[ iF ]->GetNode( iN )); + allBehind = (( pi - p ) * eos[i]->_normal < 0.1 * data._stepSize ); + } + toIgnore = allBehind; + } + + + if ( toIgnore ) // no need to detect intersection + { + eos[i]->Set( _LayerEdge::INTERSECTED ); + ++nbDetected; + } + } + } + + debugMsg( "Nb LE to intersect " << data._n2eMap.size()-nbDetected << ", ignore " << nbDetected ); + + return; } //================================================================================ @@ -4405,14 +4515,7 @@ bool _ViscousBuilder::inflate(_SolidData& data) { SMESH_MesherHelper helper( *_mesh ); - // Limit inflation step size by geometry size found by itersecting - // normals of _LayerEdge's with mesh faces - if ( data._stepSize > 0.3 * data._geomSize ) - limitStepSize( data, 0.3 * data._geomSize ); - const double tgtThick = data._maxThickness; - if ( data._stepSize > data._minThickness ) - limitStepSize( data, data._minThickness ); if ( data._stepSize < 1. ) data._epsilon = data._stepSize * 1e-7; @@ -4530,6 +4633,7 @@ bool _ViscousBuilder::inflate(_SolidData& data) break; } #endif + // new step size limitStepSize( data, 0.25 * distToIntersection ); if ( data._stepSizeNodes[0] ) @@ -4762,7 +4866,7 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data, if ( nbBad == oldBadNb && nbBad > 0 && - step < stepLimit ) // smooth w/o chech of validity + step < stepLimit ) // smooth w/o check of validity { dumpFunctionEnd(); dumpFunction(SMESH_Comment("smoothWoCheck")<_nodes.size() < 2 ) continue; SMESH_TNodeXYZ tgtXYZ = edge->_nodes.back(); + //SMESH_TNodeXYZ prevXYZ = edge->_nodes[0]; gp_XYZ prevXYZ = edge->PrevCheckPos( &eos ); //const gp_XYZ& prevXYZ = edge->PrevPos(); for ( size_t j = 0; j < edge->_simplices.size(); ++j ) @@ -4890,6 +4995,7 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data, const SMDS_MeshElement* intFace = 0; const SMDS_MeshElement* closestFace = 0; _LayerEdge* le = 0; + bool is1stBlocked = true; // dbg for ( size_t iS = 0; iS < data._edgesOnShape.size(); ++iS ) { _EdgesOnShape& eos = data._edgesOnShape[ iS ]; @@ -4961,7 +5067,7 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data, continue; // ignore intersection with intFace of an adjacent FACE - if ( dist > 0 ) + if ( dist > 0.1 * eos._edges[i]->_len ) { bool toIgnore = false; if ( eos._toSmooth ) @@ -5000,17 +5106,19 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data, if ( toBlockInfaltion && dist < ( eos._edges[i]->_len * theThickToIntersection )) { + if ( is1stBlocked ) { is1stBlocked = false; // debug + dumpFunction(SMESH_Comment("blockIntersected") <Set( _LayerEdge::INTERSECTED ); // not to intersect eos._edges[i]->Block( data ); // not to inflate - if ( _EdgesOnShape* eof = data.GetShapeEdges( intFace->getshapeId() )) + //if ( _EdgesOnShape* eof = data.GetShapeEdges( intFace->getshapeId() )) { // block _LayerEdge's, on top of which intFace is if ( const _TmpMeshFace* f = dynamic_cast< const _TmpMeshFace*>( intFace )) { - const SMDS_MeshElement* srcFace = - eof->_subMesh->GetSubMeshDS()->GetElement( f->getIdInShape() ); - SMDS_ElemIteratorPtr nIt = srcFace->nodesIterator(); + const SMDS_MeshElement* srcFace = f->_srcFace; + SMDS_ElemIteratorPtr nIt = srcFace->nodesIterator(); while ( nIt->more() ) { const SMDS_MeshNode* srcNode = static_cast( nIt->next() ); @@ -5033,11 +5141,14 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data, } // loop on eos._edges } // loop on data._edgesOnShape + if ( !is1stBlocked ) + dumpFunctionEnd(); + if ( closestFace && le ) { #ifdef __myDEBUG SMDS_MeshElement::iterator nIt = closestFace->begin_nodes(); - cout << "Shortest distance: _LayerEdge nodes: tgt " << le->_nodes.back()->GetID() + cout << "#Shortest distance: _LayerEdge nodes: tgt " << le->_nodes.back()->GetID() << " src " << le->_nodes[0]->GetID()<< ", intersection with face (" << (*nIt++)->GetID()<<" "<< (*nIt++)->GetID()<<" "<< (*nIt++)->GetID() << ") distance = " << distToIntersection<< endl; @@ -5231,7 +5342,8 @@ void _ViscousBuilder::makeOffsetSurface( _EdgesOnShape& eos, SMESH_MesherHelper& try { - BRepOffsetAPI_MakeOffsetShape offsetMaker( eos._shape, -offset, Precision::Confusion() ); + BRepOffsetAPI_MakeOffsetShape offsetMaker; + offsetMaker.PerformByJoin( eos._shape, -offset, Precision::Confusion() ); if ( !offsetMaker.IsDone() ) return; TopExp_Explorer fExp( offsetMaker.Shape(), TopAbs_FACE ); @@ -5508,8 +5620,10 @@ void _Smoother1D::findEdgesToSmooth() { if ( !_eos[i]->Is( _LayerEdge::TO_SMOOTH )) { - if ( needSmoothing( _leOnV[0]._cosin, _eos[i]->_len, _curveLen * _leParams[i] ) || - isToSmooth( i )) + if ( needSmoothing( _leOnV[0]._cosin, + _eos[i]->_len * leOnV[0]->_lenFactor, _curveLen * _leParams[i] ) || + isToSmooth( i ) + ) _eos[i]->Set( _LayerEdge::TO_SMOOTH ); else break; @@ -5523,7 +5637,8 @@ void _Smoother1D::findEdgesToSmooth() { if ( !_eos[i]->Is( _LayerEdge::TO_SMOOTH )) { - if ( needSmoothing( _leOnV[1]._cosin, _eos[i]->_len, _curveLen * ( 1.-_leParams[i] )) || + if ( needSmoothing( _leOnV[1]._cosin, + _eos[i]->_len * leOnV[1]->_lenFactor, _curveLen * ( 1.-_leParams[i] )) || isToSmooth( i )) _eos[i]->Set( _LayerEdge::TO_SMOOTH ); else @@ -5654,26 +5769,47 @@ bool _Smoother1D::smoothAnalyticEdge( _SolidData& data, if ( iFrom >= iTo ) continue; _LayerEdge* e0 = _eos[iFrom]->_2neibors->_edges[0]; _LayerEdge* e1 = _eos[iTo-1]->_2neibors->_edges[1]; - gp_XY uv0 = ( e0 == eV0 ) ? uvV0 : e0->LastUV( F, _eos ); - gp_XY uv1 = ( e1 == eV1 ) ? uvV1 : e1->LastUV( F, _eos ); - double param0 = ( iFrom == 0 ) ? 0. : _leParams[ iFrom-1 ]; - double param1 = _leParams[ iTo ]; - const gp_XY rangeUV = uv1 - uv0; + gp_XY uv0 = ( e0 == eV0 ) ? uvV0 : e0->LastUV( F, _eos ); + gp_XY uv1 = ( e1 == eV1 ) ? uvV1 : e1->LastUV( F, _eos ); + double param0 = ( iFrom == 0 ) ? 0. : _leParams[ iFrom-1 ]; + double param1 = _leParams[ iTo ]; + gp_XY rangeUV = uv1 - uv0; for ( size_t i = iFrom; i < iTo; ++i ) { if ( _eos[i]->Is( _LayerEdge::BLOCKED )) continue; double param = ( _leParams[i] - param0 ) / ( param1 - param0 ); gp_XY newUV = uv0 + param * rangeUV; - _eos[i]->_pos.back().SetCoord( newUV.X(), newUV.Y(), 0 ); gp_Pnt newPos = surface->Value( newUV.X(), newUV.Y() ); SMDS_MeshNode* tgtNode = const_cast( _eos[i]->_nodes.back() ); tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() ); dumpMove( tgtNode ); - SMDS_FacePosition* pos = static_cast( tgtNode->GetPosition() ); + SMDS_FacePositionPtr pos = tgtNode->GetPosition(); pos->SetUParameter( newUV.X() ); pos->SetVParameter( newUV.Y() ); + + gp_XYZ newUV0( newUV.X(), newUV.Y(), 0 ); + + if ( !_eos[i]->Is( _LayerEdge::SMOOTHED )) + { + _eos[i]->Set( _LayerEdge::SMOOTHED ); // to check in refine() (IPAL54237) + if ( _eos[i]->_pos.size() > 2 ) + { + // modify previous positions to make _LayerEdge less sharply bent + vector& uvVec = _eos[i]->_pos; + const gp_XYZ uvShift = newUV0 - uvVec.back(); + const double len2 = ( uvVec.back() - uvVec[ 0 ] ).SquareModulus(); + int iPrev = uvVec.size() - 2; + while ( iPrev > 0 ) + { + double r = ( uvVec[ iPrev ] - uvVec[0] ).SquareModulus() / len2; + uvVec[ iPrev ] += uvShift * r; + --iPrev; + } + } + } + _eos[i]->_pos.back() = newUV0; } } } @@ -5761,9 +5897,11 @@ bool _Smoother1D::smoothAnalyticEdge( _SolidData& data, tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() ); dumpMove( tgtNode ); - SMDS_FacePosition* pos = static_cast( tgtNode->GetPosition() ); + SMDS_FacePositionPtr pos = tgtNode->GetPosition(); pos->SetUParameter( newUV.X() ); pos->SetVParameter( newUV.Y() ); + + _eos[i]->Set( _LayerEdge::SMOOTHED ); // to check in refine() (IPAL54237) } } return true; @@ -5836,16 +5974,19 @@ bool _Smoother1D::smoothComplexEdge( _SolidData& data, // project tgt nodes of extreme _LayerEdge's to the offset segments // ----------------------------------------------------------------- - if ( e[0]->Is( _LayerEdge::NORMAL_UPDATED )) _iSeg[0] = 0; - if ( e[1]->Is( _LayerEdge::NORMAL_UPDATED )) _iSeg[1] = _offPoints.size()-2; + const int updatedOrBlocked = _LayerEdge::NORMAL_UPDATED | _LayerEdge::BLOCKED; + if ( e[0]->Is( updatedOrBlocked )) _iSeg[0] = 0; + if ( e[1]->Is( updatedOrBlocked )) _iSeg[1] = _offPoints.size()-2; gp_Pnt pExtreme[2], pProj[2]; + bool isProjected[2]; for ( int is2nd = 0; is2nd < 2; ++is2nd ) { pExtreme[ is2nd ] = SMESH_TNodeXYZ( e[is2nd]->_nodes.back() ); int i = _iSeg[ is2nd ]; int di = is2nd ? -1 : +1; - bool projected = false; + bool & projected = isProjected[ is2nd ]; + projected = false; double uOnSeg, distMin = Precision::Infinite(), dist, distPrev = 0; int nbWorse = 0; do { @@ -5892,38 +6033,43 @@ bool _Smoother1D::smoothComplexEdge( _SolidData& data, gp_Vec vDiv0( pExtreme[0], pProj[0] ); gp_Vec vDiv1( pExtreme[1], pProj[1] ); double d0 = vDiv0.Magnitude(); - double d1 = vDiv1.Magnitude(); - if ( e[0]->_normal * vDiv0.XYZ() < 0 ) e[0]->_len += d0; - else e[0]->_len -= d0; - if ( e[1]->_normal * vDiv1.XYZ() < 0 ) e[1]->_len += d1; - else e[1]->_len -= d1; + double d1 = isProjected[1] ? vDiv1.Magnitude() : 0; + if ( e[0]->Is( _LayerEdge::BLOCKED )) { + if ( e[0]->_normal * vDiv0.XYZ() < 0 ) e[0]->_len += d0; + else e[0]->_len -= d0; + } + if ( e[1]->Is( _LayerEdge::BLOCKED )) { + if ( e[1]->_normal * vDiv1.XYZ() < 0 ) e[1]->_len += d1; + else e[1]->_len -= d1; + } // --------------------------------------------------------------------------------- // compute normalized length of the offset segments located between the projections // --------------------------------------------------------------------------------- + // temporary replace extreme _offPoints by pExtreme + gp_XYZ opXYZ[2] = { _offPoints[ _iSeg[0] ]._xyz, + _offPoints[ _iSeg[1]+1 ]._xyz }; + _offPoints[ _iSeg[0] ]._xyz = pExtreme[0].XYZ(); + _offPoints[ _iSeg[1]+ 1]._xyz = pExtreme[1].XYZ(); + size_t iSeg = 0, nbSeg = _iSeg[1] - _iSeg[0] + 1; vector< double > len( nbSeg + 1 ); len[ iSeg++ ] = 0; - len[ iSeg++ ] = pProj[ 0 ].Distance( _offPoints[ _iSeg[0]+1 ]._xyz )/* * e[0]->_lenFactor*/; + len[ iSeg++ ] = pProj[ 0 ].Distance( _offPoints[ _iSeg[0]+1 ]._xyz ); for ( size_t i = _iSeg[0]+1; i <= _iSeg[1]; ++i, ++iSeg ) { len[ iSeg ] = len[ iSeg-1 ] + _offPoints[i].Distance( _offPoints[i+1] ); } - len[ nbSeg ] -= pProj[ 1 ].Distance( _offPoints[ _iSeg[1]+1 ]._xyz )/* * e[1]->_lenFactor*/; + // if ( isProjected[ 1 ]) + // len[ nbSeg ] -= pProj[ 1 ].Distance( _offPoints[ _iSeg[1]+1 ]._xyz ); + // else + // len[ nbSeg ] += pExtreme[ 1 ].Distance( _offPoints[ _iSeg[1]+1 ]._xyz ); - // d0 *= e[0]->_lenFactor; - // d1 *= e[1]->_lenFactor; double fullLen = len.back() - d0 - d1; for ( iSeg = 0; iSeg < len.size(); ++iSeg ) len[iSeg] = ( len[iSeg] - d0 ) / fullLen; - // temporary replace extreme _offPoints by pExtreme - gp_XYZ op[2] = { _offPoints[ _iSeg[0] ]._xyz, - _offPoints[ _iSeg[1]+1 ]._xyz }; - _offPoints[ _iSeg[0] ]._xyz = pExtreme[0].XYZ(); - _offPoints[ _iSeg[1]+ 1]._xyz = pExtreme[1].XYZ(); - // ------------------------------------------------------------- // distribute tgt nodes of _LayerEdge's between the projections // ------------------------------------------------------------- @@ -5956,8 +6102,8 @@ bool _Smoother1D::smoothComplexEdge( _SolidData& data, dumpMove( tgtNode ); } - _offPoints[ _iSeg[0] ]._xyz = op[0]; - _offPoints[ _iSeg[1]+1 ]._xyz = op[1]; + _offPoints[ _iSeg[0] ]._xyz = opXYZ[0]; + _offPoints[ _iSeg[1]+1 ]._xyz = opXYZ[1]; return true; } @@ -6011,8 +6157,8 @@ void _Smoother1D::prepare(_SolidData& data) // divide E to have offset segments with low deflection BRepAdaptor_Curve c3dAdaptor( E ); - const double curDeflect = 0.1; //0.3; // 0.01; // Curvature deflection - const double angDeflect = 0.1; //0.2; // 0.09; // Angular deflection + const double curDeflect = 0.1; //0.01; // Curvature deflection == |p1p2]*sin(p1p2,p1pM) + const double angDeflect = 0.1; //0.09; // Angular deflection == sin(p1pM,pMp2) GCPnts_TangentialDeflection discret(c3dAdaptor, angDeflect, curDeflect); if ( discret.NbPoints() <= 2 ) { @@ -6022,14 +6168,39 @@ void _Smoother1D::prepare(_SolidData& data) const double u0 = c3dAdaptor.FirstParameter(); gp_Pnt p; gp_Vec tangent; - _offPoints.resize( discret.NbPoints() ); - for ( size_t i = 0; i < _offPoints.size(); i++ ) + if ( discret.NbPoints() >= (int) _eos.size() + 2 ) { - double u = discret.Parameter( i+1 ); - c3dAdaptor.D1( u, p, tangent ); - _offPoints[i]._xyz = p.XYZ(); - _offPoints[i]._edgeDir = tangent.XYZ(); - _offPoints[i]._param = GCPnts_AbscissaPoint::Length( c3dAdaptor, u0, u ) / _curveLen; + _offPoints.resize( discret.NbPoints() ); + for ( size_t i = 0; i < _offPoints.size(); i++ ) + { + double u = discret.Parameter( i+1 ); + c3dAdaptor.D1( u, p, tangent ); + _offPoints[i]._xyz = p.XYZ(); + _offPoints[i]._edgeDir = tangent.XYZ(); + _offPoints[i]._param = GCPnts_AbscissaPoint::Length( c3dAdaptor, u0, u ) / _curveLen; + } + } + else + { + std::vector< double > params( _eos.size() + 2 ); + + params[0] = data.GetHelper().GetNodeU( E, leOnV[0]->_nodes[0] ); + params.back() = data.GetHelper().GetNodeU( E, leOnV[1]->_nodes[0] ); + for ( size_t i = 0; i < _eos.size(); i++ ) + params[i+1] = data.GetHelper().GetNodeU( E, _eos[i]->_nodes[0] ); + + if ( params[1] > params[ _eos.size() ] ) + std::reverse( params.begin() + 1, params.end() - 1 ); + + _offPoints.resize( _eos.size() + 2 ); + for ( size_t i = 0; i < _offPoints.size(); i++ ) + { + const double u = params[i]; + c3dAdaptor.D1( u, p, tangent ); + _offPoints[i]._xyz = p.XYZ(); + _offPoints[i]._edgeDir = tangent.XYZ(); + _offPoints[i]._param = GCPnts_AbscissaPoint::Length( c3dAdaptor, u0, u ) / _curveLen; + } } // set _2edges @@ -6069,8 +6240,14 @@ void _Smoother1D::prepare(_SolidData& data) int iLBO = _offPoints.size() - 2; // last but one - _leOnV[ 0 ]._normal = getNormalNormal( leOnV[0]->_normal, _edgeDir[0] ); - _leOnV[ 1 ]._normal = getNormalNormal( leOnV[1]->_normal, _edgeDir[1] ); + if ( leOnV[ 0 ]->Is( _LayerEdge::MULTI_NORMAL )) + _leOnV[ 0 ]._normal = getNormalNormal( _eos._edges[1]->_normal, _edgeDir[0] ); + else + _leOnV[ 0 ]._normal = getNormalNormal( leOnV[0]->_normal, _edgeDir[0] ); + if ( leOnV[ 1 ]->Is( _LayerEdge::MULTI_NORMAL )) + _leOnV[ 1 ]._normal = getNormalNormal( _eos._edges.back()->_normal, _edgeDir[1] ); + else + _leOnV[ 1 ]._normal = getNormalNormal( leOnV[1]->_normal, _edgeDir[1] ); _leOnV[ 0 ]._len = 0; _leOnV[ 1 ]._len = 0; _leOnV[ 0 ]._lenFactor = _offPoints[1 ]._2edges._edges[1]->_lenFactor; @@ -6104,7 +6281,7 @@ void _Smoother1D::prepare(_SolidData& data) //================================================================================ /*! - * \brief set _normal of _leOnV[is2nd] to be normal to the EDGE + * \brief return _normal of _leOnV[is2nd] normal to the EDGE */ //================================================================================ @@ -6115,9 +6292,36 @@ gp_XYZ _Smoother1D::getNormalNormal( const gp_XYZ & normal, gp_XYZ norm = edgeDir ^ cross; double size = norm.Modulus(); + // if ( size == 0 ) // MULTI_NORMAL _LayerEdge + // return gp_XYZ( 1e-100, 1e-100, 1e-100 ); + return norm / size; } +//================================================================================ +/*! + * \brief Writes a script creating a mesh composed of _offPoints + */ +//================================================================================ + +void _Smoother1D::offPointsToPython() const +{ + const char* fname = "/tmp/offPoints.py"; + cout << "execfile('"<_edges.size(); ++i ) - { - eos->_edges[i]->SetSmooLen( Precision::Infinite() ); - } - SMESH_subMeshIteratorPtr smIt = eos->_subMesh->getDependsOnIterator(/*includeSelf=*/false); - while ( smIt->more() ) // loop on sub-shapes of the FACE - { - _EdgesOnShape* eoe = GetShapeEdges( smIt->next()->GetId() ); - if ( !eoe ) continue; - - vector<_LayerEdge*>& eE = eoe->_edges; - for ( size_t iE = 0; iE < eE.size(); ++iE ) // loop on _LayerEdge's on EDGE or VERTEX - { - if ( eE[iE]->_cosin <= theMinSmoothCosin ) - continue; + // for ( size_t i = 0; i < eos->_edges.size(); ++i ) + // { + // eos->_edges[i]->SetSmooLen( Precision::Infinite() ); + // } + // SMESH_subMeshIteratorPtr smIt = eos->_subMesh->getDependsOnIterator(/*includeSelf=*/false); + // while ( smIt->more() ) // loop on sub-shapes of the FACE + // { + // _EdgesOnShape* eoe = GetShapeEdges( smIt->next()->GetId() ); + // if ( !eoe ) continue; - SMDS_ElemIteratorPtr segIt = eE[iE]->_nodes[0]->GetInverseElementIterator(SMDSAbs_Edge); - while ( segIt->more() ) - { - const SMDS_MeshElement* seg = segIt->next(); - if ( !eos->_subMesh->DependsOn( seg->getshapeId() )) - continue; - if ( seg->GetNode(0) != eE[iE]->_nodes[0] ) - continue; // not to check a seg twice - for ( size_t iN = 0; iN < eE[iE]->_neibors.size(); ++iN ) - { - _LayerEdge* eN = eE[iE]->_neibors[iN]; - if ( eN->_nodes[0]->getshapeId() != eos->_shapeID ) - continue; - double dist = SMESH_MeshAlgos::GetDistance( seg, SMESH_TNodeXYZ( eN->_nodes[0] )); - double smooLen = getSmoothingThickness( eE[iE]->_cosin, dist ); - eN->SetSmooLen( Min( smooLen, eN->GetSmooLen() )); - eN->Set( _LayerEdge::NEAR_BOUNDARY ); - } - } - } - } + // vector<_LayerEdge*>& eE = eoe->_edges; + // for ( size_t iE = 0; iE < eE.size(); ++iE ) // loop on _LayerEdge's on EDGE or VERTEX + // { + // if ( eE[iE]->_cosin <= theMinSmoothCosin ) + // continue; + + // SMDS_ElemIteratorPtr segIt = eE[iE]->_nodes[0]->GetInverseElementIterator(SMDSAbs_Edge); + // while ( segIt->more() ) + // { + // const SMDS_MeshElement* seg = segIt->next(); + // if ( !eos->_subMesh->DependsOn( seg->getshapeId() )) + // continue; + // if ( seg->GetNode(0) != eE[iE]->_nodes[0] ) + // continue; // not to check a seg twice + // for ( size_t iN = 0; iN < eE[iE]->_neibors.size(); ++iN ) + // { + // _LayerEdge* eN = eE[iE]->_neibors[iN]; + // if ( eN->_nodes[0]->getshapeId() != eos->_shapeID ) + // continue; + // double dist = SMESH_MeshAlgos::GetDistance( seg, SMESH_TNodeXYZ( eN->_nodes[0] )); + // double smooLen = getSmoothingThickness( eE[iE]->_cosin, dist ); + // eN->SetSmooLen( Min( smooLen, eN->GetSmooLen() )); + // eN->Set( _LayerEdge::NEAR_BOUNDARY ); + // } + // } + // } + // } } // if ( eos->ShapeType() == TopAbs_FACE ) for ( size_t i = 0; i < eos->_edges.size(); ++i ) @@ -6299,11 +6503,12 @@ void _SolidData::PrepareEdgesToSmoothOnFace( _EdgesOnShape* eos, bool substitute avgLen /= edge->_simplices.size(); if (( edge->_curvature = _Curvature::New( avgNormProj, avgLen ))) { + edge->Set( _LayerEdge::SMOOTHED_C1 ); isCurved = true; - SMDS_FacePosition* fPos = dynamic_cast( edge->_nodes[0]->GetPosition() ); + SMDS_FacePositionPtr fPos = edge->_nodes[0]->GetPosition(); if ( !fPos ) for ( size_t iS = 0; iS < edge->_simplices.size() && !fPos; ++iS ) - fPos = dynamic_cast( edge->_simplices[iS]._nPrev->GetPosition() ); + fPos = edge->_simplices[iS]._nPrev->GetPosition(); if ( fPos ) edge->_curvature->_uv.SetCoord( fPos->GetUParameter(), fPos->GetVParameter() ); } @@ -6394,7 +6599,7 @@ void _ViscousBuilder::limitMaxLenByCurvature( _SolidData& data, SMESH_MesherHelp if ( eI->_nodes[0]->GetID() < eN->_nodes[0]->GetID() ) // treat this pair once { _EdgesOnShape* eosN = data.GetShapeEdges( eN ); - limitMaxLenByCurvature( eI, eN, eosI, *eosN, helper ); + limitMaxLenByCurvature( eI, eN, eosI, *eosN, eosI._hyp.ToSmooth() ); } } } @@ -6408,7 +6613,7 @@ void _ViscousBuilder::limitMaxLenByCurvature( _SolidData& data, SMESH_MesherHelp for ( size_t i = 1; i < eosI._edges.size(); ++i ) { _LayerEdge* eI = eosI._edges[i]; - limitMaxLenByCurvature( eI, e0, eosI, eosI, helper ); + limitMaxLenByCurvature( eI, e0, eosI, eosI, eosI._hyp.ToSmooth() ); e0 = eI; } } @@ -6421,12 +6626,17 @@ void _ViscousBuilder::limitMaxLenByCurvature( _SolidData& data, SMESH_MesherHelp */ //================================================================================ -void _ViscousBuilder::limitMaxLenByCurvature( _LayerEdge* e1, - _LayerEdge* e2, - _EdgesOnShape& eos1, - _EdgesOnShape& eos2, - SMESH_MesherHelper& helper ) +void _ViscousBuilder::limitMaxLenByCurvature( _LayerEdge* e1, + _LayerEdge* e2, + _EdgesOnShape& eos1, + _EdgesOnShape& eos2, + const bool isSmoothable ) { + if (( e1->_nodes[0]->GetPosition()->GetDim() != + e2->_nodes[0]->GetPosition()->GetDim() ) && + ( e1->_cosin < 0.75 )) + return; // angle > 90 deg at e1 + gp_XYZ plnNorm = e1->_normal ^ e2->_normal; double norSize = plnNorm.SquareModulus(); if ( norSize < std::numeric_limits::min() ) @@ -6446,9 +6656,10 @@ void _ViscousBuilder::limitMaxLenByCurvature( _LayerEdge* e1, double ovl = ( u1 * e1->_normal * dir12 - u2 * e2->_normal * dir12 ) / dir12.SquareModulus(); if ( ovl > theSmoothThickToElemSizeRatio ) - { - e1->_maxLen = Min( e1->_maxLen, 0.75 * u1 / e1->_lenFactor ); - e2->_maxLen = Min( e2->_maxLen, 0.75 * u2 / e2->_lenFactor ); + { + const double coef = 0.75; + e1->SetMaxLen( Min( e1->_maxLen, coef * u1 / e1->_lenFactor )); + e2->SetMaxLen( Min( e2->_maxLen, coef * u2 / e2->_lenFactor )); } } } @@ -6469,6 +6680,7 @@ void _ViscousBuilder::findCollisionEdges( _SolidData& data, SMESH_MesherHelper& _EdgesOnShape& eos = data._edgesOnShape[iS]; if ( eos._edges.empty() ) continue; if ( eos.ShapeType() != TopAbs_EDGE && eos.ShapeType() != TopAbs_VERTEX ) continue; + if ( !eos._sWOL.IsNull() ) continue; // PAL23566 for ( size_t i = 0; i < eos._edges.size(); ++i ) { @@ -6515,7 +6727,7 @@ void _ViscousBuilder::findCollisionEdges( _SolidData& data, SMESH_MesherHelper& src2->GetID() < edge->_nodes[0]->GetID() ) continue; // avoid using same segment twice - // a _LayerEdge containg tgt2 + // a _LayerEdge containing tgt2 _LayerEdge* neiborEdge = edge->_2neibors->_edges[j]; _TmpMeshFaceOnEdge* f = new _TmpMeshFaceOnEdge( edge, neiborEdge, --_tmpFaceID ); @@ -6594,9 +6806,9 @@ void _ViscousBuilder::findCollisionEdges( _SolidData& data, SMESH_MesherHelper& ( f->_le2->IsOnEdge() && f->_le2->_2neibors->include( edge ))) continue; } dist1 = dist2 = Precision::Infinite(); - if ( !edge->SegTriaInter( lastSegment, f->_nn[0], f->_nn[1], f->_nn[2], dist1, eps )) + if ( !edge->SegTriaInter( lastSegment, f->n(0), f->n(1), f->n(2), dist1, eps )) dist1 = Precision::Infinite(); - if ( !edge->SegTriaInter( lastSegment, f->_nn[3], f->_nn[2], f->_nn[0], dist2, eps )) + if ( !edge->SegTriaInter( lastSegment, f->n(3), f->n(2), f->n(0), dist2, eps )) dist2 = Precision::Infinite(); if (( dist1 > segLen ) && ( dist2 > segLen )) continue; @@ -6604,7 +6816,7 @@ void _ViscousBuilder::findCollisionEdges( _SolidData& data, SMESH_MesherHelper& if ( edge->IsOnEdge() ) { // skip perpendicular EDGEs - gp_Vec fSegDir = SMESH_TNodeXYZ( f->_nn[0] ) - SMESH_TNodeXYZ( f->_nn[3] ); + gp_Vec fSegDir = SMESH_TNodeXYZ( f->n(0) ) - SMESH_TNodeXYZ( f->n(3) ); bool isParallel = ( isLessAngle( eSegDir0, fSegDir, angle45 ) || isLessAngle( eSegDir1, fSegDir, angle45 ) || isLessAngle( eSegDir0, fSegDir.Reversed(), angle45 ) || @@ -6623,7 +6835,7 @@ void _ViscousBuilder::findCollisionEdges( _SolidData& data, SMESH_MesherHelper& // else // { // double shortLen = 0.75 * ( Min( dist1, dist2 ) / edge->_lenFactor ); - // edge->_maxLen = Min( shortLen, edge->_maxLen ); + // edge->SetMaxLen( Min( shortLen, edge->_maxLen )); // } } @@ -6834,8 +7046,8 @@ bool _ViscousBuilder::updateNormals( _SolidData& data, // compute new _normals for ( size_t i = 0; i < intEdgesDist.size(); ++i ) { - _LayerEdge* edge2 = intEdgesDist[i].first; - double distWgt = edge1->_len / intEdgesDist[i].second; + _LayerEdge* edge2 = intEdgesDist[i].first; + double distWgt = edge1->_len / intEdgesDist[i].second; // if ( edge1->Is( _LayerEdge::BLOCKED ) && // edge2->Is( _LayerEdge::BLOCKED )) continue; if ( edge2->Is( _LayerEdge::MARKED )) continue; @@ -6873,12 +7085,17 @@ bool _ViscousBuilder::updateNormals( _SolidData& data, e2neIt = edge2newEdge.insert( make_pair( edge1, zeroEdge )).first; e2neIt->second._normal += distWgt * newNormal; e2neIt->second._cosin = newCos; - e2neIt->second._maxLen = 0.7 * minIntDist / edge1->_lenFactor; + e2neIt->second.SetMaxLen( 0.7 * minIntDist / edge1->_lenFactor ); if ( iter > 0 && sgn1 * sgn2 < 0 && edge1->_cosin < 0 ) e2neIt->second._normal += dir2; + e2neIt = edge2newEdge.insert( make_pair( edge2, zeroEdge )).first; e2neIt->second._normal += distWgt * newNormal; - e2neIt->second._cosin = edge2->_cosin; + if ( Precision::IsInfinite( zeroEdge._maxLen )) + { + e2neIt->second._cosin = edge2->_cosin; + e2neIt->second.SetMaxLen( 1.3 * minIntDist / edge1->_lenFactor ); + } if ( iter > 0 && sgn1 * sgn2 < 0 && edge2->_cosin < 0 ) e2neIt->second._normal += dir1; } @@ -6895,9 +7112,10 @@ bool _ViscousBuilder::updateNormals( _SolidData& data, for ( e2neIt = edge2newEdge.begin(); e2neIt != edge2newEdge.end(); ++e2neIt ) { _LayerEdge* edge = e2neIt->first; - if ( edge->Is( _LayerEdge::BLOCKED )) continue; _LayerEdge& newEdge = e2neIt->second; _EdgesOnShape* eos = data.GetShapeEdges( edge ); + if ( edge->Is( _LayerEdge::BLOCKED && newEdge._maxLen > edge->_len )) + continue; // Check if a new _normal is OK: newEdge._normal.Normalize(); @@ -6906,7 +7124,7 @@ bool _ViscousBuilder::updateNormals( _SolidData& data, if ( newEdge._maxLen < edge->_len && iter > 0 ) // limit _maxLen { edge->InvalidateStep( stepNb + 1, *eos, /*restoreLength=*/true ); - edge->_maxLen = newEdge._maxLen; + edge->SetMaxLen( newEdge._maxLen ); edge->SetNewLength( newEdge._maxLen, *eos, helper ); } continue; // the new _normal is bad @@ -7804,7 +8022,7 @@ bool _LayerEdge::FindIntersection( SMESH_ElementSearcher& searcher, gp_XYZ _LayerEdge::PrevCheckPos( _EdgesOnShape* eos ) const { - size_t i = Is( NORMAL_UPDATED ) ? _pos.size()-2 : 0; + size_t i = Is( NORMAL_UPDATED ) && IsOnFace() ? _pos.size()-2 : 0; if ( !eos || eos->_sWOL.IsNull() ) return _pos[ i ]; @@ -8034,7 +8252,7 @@ void _LayerEdge::MoveNearConcaVer( const _EdgesOnShape* eov, prevPosV = surface.Value( prevPosV.X(), prevPosV.Y() ).XYZ(); } - SMDS_FacePosition* fPos; + SMDS_FacePositionPtr fPos; //double r = 1. - Min( 0.9, step / 10. ); for ( set< _LayerEdge* >::iterator e = edges.begin(); e != edges.end(); ++e ) { @@ -8048,7 +8266,7 @@ void _LayerEdge::MoveNearConcaVer( const _EdgesOnShape* eov, // set _curvature to make edgeF updated by putOnOffsetSurface() if ( !edgeF->_curvature ) - if (( fPos = dynamic_cast( edgeF->_nodes[0]->GetPosition() ))) + if (( fPos = edgeF->_nodes[0]->GetPosition() )) { edgeF->_curvature = new _Curvature; edgeF->_curvature->_r = 0; @@ -8523,7 +8741,7 @@ int _LayerEdge::Smooth(const int step, const bool isConcaveFace, bool findBest ) //================================================================================ /*! - * \brief Chooses a smoothing technic giving a position most close to an initial one. + * \brief Chooses a smoothing technique giving a position most close to an initial one. * For a correct result, _simplices must contain nodes lying on geometry. */ //================================================================================ @@ -8558,7 +8776,7 @@ void _LayerEdge::ChooseSmooFunction( const set< TGeomID >& concaveVertices, } } - // // this coice is done only if ( !concaveVertices.empty() ) for Grids/smesh/bugs_19/X1 + // // this choice is done only if ( !concaveVertices.empty() ) for Grids/smesh/bugs_19/X1 // // where the nodes are smoothed too far along a sphere thus creating // // inverted _simplices // double dist[theNbSmooFuns]; @@ -9269,7 +9487,7 @@ void _LayerEdge::SetNewLength( double len, _EdgesOnShape& eos, SMESH_MesherHelpe _pos.back().SetCoord( u, 0, 0 ); if ( _nodes.size() > 1 && uvOK ) { - SMDS_EdgePosition* pos = static_cast( n->GetPosition() ); + SMDS_EdgePositionPtr pos = n->GetPosition(); pos->SetUParameter( u ); } } @@ -9281,7 +9499,7 @@ void _LayerEdge::SetNewLength( double len, _EdgesOnShape& eos, SMESH_MesherHelpe _pos.back().SetCoord( uv.X(), uv.Y(), 0 ); if ( _nodes.size() > 1 && uvOK ) { - SMDS_FacePosition* pos = static_cast( n->GetPosition() ); + SMDS_FacePositionPtr pos = n->GetPosition(); pos->SetUParameter( uv.X() ); pos->SetVParameter( uv.Y() ); } @@ -9327,9 +9545,9 @@ void _LayerEdge::Block( _SolidData& data ) SMESH_Comment msg( "#BLOCK shape="); msg << data.GetShapeEdges( this )->_shapeID << ", nodes " << _nodes[0]->GetID() << ", " << _nodes.back()->GetID(); - dumpCmd( msg + " -- BEGIN") + dumpCmd( msg + " -- BEGIN"); - _maxLen = _len; + SetMaxLen( _len ); std::queue<_LayerEdge*> queue; queue.push( this ); @@ -9353,18 +9571,19 @@ void _LayerEdge::Block( _SolidData& data ) double newMaxLen = edge->_maxLen + 0.5 * Sqrt( minDist ); //if ( edge->_nodes[0]->getshapeId() == neibor->_nodes[0]->getshapeId() ) viscous_layers_00/A3 { - newMaxLen *= edge->_lenFactor / neibor->_lenFactor; + //newMaxLen *= edge->_lenFactor / neibor->_lenFactor; // newMaxLen *= Min( edge->_lenFactor / neibor->_lenFactor, // neibor->_lenFactor / edge->_lenFactor ); } if ( neibor->_maxLen > newMaxLen ) { - neibor->_maxLen = newMaxLen; + neibor->SetMaxLen( newMaxLen ); if ( neibor->_maxLen < neibor->_len ) { _EdgesOnShape* eos = data.GetShapeEdges( neibor ); + int lastStep = neibor->Is( BLOCKED ) ? 1 : 0; while ( neibor->_len > neibor->_maxLen && - neibor->NbSteps() > 1 ) + neibor->NbSteps() > lastStep ) neibor->InvalidateStep( neibor->NbSteps(), *eos, /*restoreLength=*/true ); neibor->SetNewLength( neibor->_maxLen, *eos, data.GetHelper() ); //neibor->Block( data ); @@ -9373,7 +9592,7 @@ void _LayerEdge::Block( _SolidData& data ) } } } - dumpCmd( msg + " -- END") + dumpCmd( msg + " -- END"); } //================================================================================ @@ -9396,7 +9615,7 @@ void _LayerEdge::InvalidateStep( size_t curStep, const _EdgesOnShape& eos, bool TopLoc_Location loc; if ( eos.SWOLType() == TopAbs_EDGE ) { - SMDS_EdgePosition* pos = static_cast( n->GetPosition() ); + SMDS_EdgePositionPtr pos = n->GetPosition(); pos->SetUParameter( nXYZ.X() ); double f,l; Handle(Geom_Curve) curve = BRep_Tool::Curve( TopoDS::Edge( eos._sWOL ), loc, f,l); @@ -9404,7 +9623,7 @@ void _LayerEdge::InvalidateStep( size_t curStep, const _EdgesOnShape& eos, bool } else { - SMDS_FacePosition* pos = static_cast( n->GetPosition() ); + SMDS_FacePositionPtr pos = n->GetPosition(); pos->SetUParameter( nXYZ.X() ); pos->SetVParameter( nXYZ.Y() ); Handle(Geom_Surface) surface = BRep_Tool::Surface( TopoDS::Face(eos._sWOL), loc ); @@ -9416,9 +9635,15 @@ void _LayerEdge::InvalidateStep( size_t curStep, const _EdgesOnShape& eos, bool if ( restoreLength ) { - _len -= ( nXYZ.XYZ() - curXYZ ).Modulus() / _lenFactor; + if ( NbSteps() == 0 ) + _len = 0.; + else if ( IsOnFace() && Is( MOVED )) + _len = ( nXYZ.XYZ() - SMESH_NodeXYZ( _nodes[0] )) * _normal; + else + _len -= ( nXYZ.XYZ() - curXYZ ).Modulus() / _lenFactor; } } + return; } //================================================================================ @@ -9454,10 +9679,23 @@ void _LayerEdge::SmoothPos( const vector< double >& segLen, const double tol ) int iSmoothed = GetSmoothedPos( tol ); if ( !iSmoothed ) return; - //if ( 1 || Is( DISTORTED )) + gp_XYZ normal = _normal; + if ( Is( NORMAL_UPDATED )) { - gp_XYZ normal = _normal; - if ( Is( NORMAL_UPDATED )) + double minDot = 1; + for ( size_t i = 0; i < _neibors.size(); ++i ) + { + if ( _neibors[i]->IsOnFace() ) + { + double dot = _normal * _neibors[i]->_normal; + if ( dot < minDot ) + { + normal = _neibors[i]->_normal; + minDot = dot; + } + } + } + if ( minDot == 1. ) for ( size_t i = 1; i < _pos.size(); ++i ) { normal = _pos[i] - _pos[0]; @@ -9468,42 +9706,29 @@ void _LayerEdge::SmoothPos( const vector< double >& segLen, const double tol ) break; } } - const double r = 0.2; - for ( int iter = 0; iter < 50; ++iter ) + } + const double r = 0.2; + for ( int iter = 0; iter < 50; ++iter ) + { + double minDot = 1; + for ( size_t i = Max( 1, iSmoothed-1-iter ); i < _pos.size()-1; ++i ) { - double minDot = 1; - for ( size_t i = Max( 1, iSmoothed-1-iter ); i < _pos.size()-1; ++i ) - { - gp_XYZ midPos = 0.5 * ( _pos[i-1] + _pos[i+1] ); - gp_XYZ newPos = ( 1-r ) * midPos + r * _pos[i]; - _pos[i] = newPos; - double midLen = 0.5 * ( segLen[i-1] + segLen[i+1] ); - double newLen = ( 1-r ) * midLen + r * segLen[i]; - const_cast< double& >( segLen[i] ) = newLen; - // check angle between normal and (_pos[i+1], _pos[i] ) - gp_XYZ posDir = _pos[i+1] - _pos[i]; - double size = posDir.SquareModulus(); - if ( size > RealSmall() ) - minDot = Min( minDot, ( normal * posDir ) * ( normal * posDir ) / size ); - } - if ( minDot > 0.5 * 0.5 ) - break; + gp_XYZ midPos = 0.5 * ( _pos[i-1] + _pos[i+1] ); + gp_XYZ newPos = ( 1-r ) * midPos + r * _pos[i]; + _pos[i] = newPos; + double midLen = 0.5 * ( segLen[i-1] + segLen[i+1] ); + double newLen = ( 1-r ) * midLen + r * segLen[i]; + const_cast< double& >( segLen[i] ) = newLen; + // check angle between normal and (_pos[i+1], _pos[i] ) + gp_XYZ posDir = _pos[i+1] - _pos[i]; + double size = posDir.SquareModulus(); + if ( size > RealSmall() ) + minDot = Min( minDot, ( normal * posDir ) * ( normal * posDir ) / size ); } + if ( minDot > 0.5 * 0.5 ) + break; } - // else - // { - // for ( size_t i = 1; i < _pos.size()-1; ++i ) - // { - // if ((int) i < iSmoothed && ( segLen[i] / segLen.back() < 0.5 )) - // continue; - - // double wgt = segLen[i] / segLen.back(); - // gp_XYZ normPos = _pos[0] + _normal * wgt * _len; - // gp_XYZ tgtPos = ( 1 - wgt ) * _pos[0] + wgt * _pos.back(); - // gp_XYZ newPos = ( 1 - wgt ) * normPos + wgt * tgtPos; - // _pos[i] = newPos; - // } - // } + return; } //================================================================================ @@ -9544,11 +9769,11 @@ std::string _LayerEdge::DumpFlags() const return dump; } + //================================================================================ /*! - case brief: - default: -*/ + * \brief Create layers of prisms + */ //================================================================================ bool _ViscousBuilder::refine(_SolidData& data) @@ -9603,11 +9828,8 @@ bool _ViscousBuilder::refine(_SolidData& data) surface = helper.GetSurface( geomFace ); // propagate _toSmooth back to _eosC1, which was unset in findShapesToSmooth() for ( size_t i = 0; i < eos._eosC1.size(); ++i ) - { eos._eosC1[ i ]->_toSmooth = true; - for ( size_t j = 0; j < eos._eosC1[i]->_edges.size(); ++j ) - eos._eosC1[i]->_edges[j]->Set( _LayerEdge::SMOOTHED_C1 ); - } + isTooConvexFace = false; if ( _ConvexFace* cf = data.GetConvexFace( eos._shapeID )) isTooConvexFace = cf->_isTooCurved; @@ -9710,8 +9932,20 @@ bool _ViscousBuilder::refine(_SolidData& data) } else if ( eos._isRegularSWOL ) // usual SWOL { - for ( size_t j = 1; j < edge._pos.size(); ++j ) - segLen[j] = segLen[j-1] + (edge._pos[j-1] - edge._pos[j] ).Modulus(); + if ( edge.Is( _LayerEdge::SMOOTHED )) + { + SMESH_NodeXYZ p0( edge._nodes[0] ); + for ( size_t j = 1; j < edge._pos.size(); ++j ) + { + gp_XYZ pj = surface->Value( edge._pos[j].X(), edge._pos[j].Y() ).XYZ(); + segLen[j] = ( pj - p0 ) * edge._normal; + } + } + else + { + for ( size_t j = 1; j < edge._pos.size(); ++j ) + segLen[j] = segLen[j-1] + (edge._pos[j-1] - edge._pos[j] ).Modulus(); + } } else if ( !surface.IsNull() ) // SWOL surface with singularities { @@ -9754,12 +9988,12 @@ bool _ViscousBuilder::refine(_SolidData& data) SMDS_PositionPtr lastPos = tgtNode->GetPosition(); if ( isOnEdge ) { - SMDS_EdgePosition* epos = static_cast( lastPos ); + SMDS_EdgePositionPtr epos = lastPos; epos->SetUParameter( otherTgtPos.X() ); } else { - SMDS_FacePosition* fpos = static_cast( lastPos ); + SMDS_FacePositionPtr fpos = lastPos; fpos->SetUParameter( otherTgtPos.X() ); fpos->SetVParameter( otherTgtPos.Y() ); } @@ -9848,7 +10082,7 @@ bool _ViscousBuilder::refine(_SolidData& data) u = helper.GetNodeU( geomEdge, node ); pos = curve->Value( u ).Transformed(loc); - SMDS_EdgePosition* epos = static_cast( node->GetPosition() ); + SMDS_EdgePositionPtr epos = node->GetPosition(); epos->SetUParameter( u ); } else @@ -9858,7 +10092,7 @@ bool _ViscousBuilder::refine(_SolidData& data) uv = helper.GetNodeUV( geomFace, node ); pos = surface->Value( uv ); - SMDS_FacePosition* fpos = static_cast( node->GetPosition() ); + SMDS_FacePositionPtr fpos = node->GetPosition(); fpos->SetUParameter( uv.X() ); fpos->SetVParameter( uv.Y() ); } @@ -10033,10 +10267,11 @@ bool _ViscousBuilder::refine(_SolidData& data) SMESH_ComputeErrorPtr& err = _mesh->GetSubMesh( data._solid )->GetComputeError(); if ( !err || err->IsOK() ) { - err.reset( new SMESH_ComputeError( COMPERR_WARNING, - "Bad quality volumes created" )); - err->myBadElements.insert( err->myBadElements.end(), - degenVols.begin(),degenVols.end() ); + SMESH_BadInputElements* badElems = + new SMESH_BadInputElements( getMeshDS(), COMPERR_WARNING, "Bad quality volumes created" ); + badElems->myBadElements.insert( badElems->myBadElements.end(), + degenVols.begin(),degenVols.end() ); + err.reset( badElems ); } } @@ -10102,7 +10337,7 @@ bool _ViscousBuilder::shrink(_SolidData& theData) vector< _EdgesOnShape* > subEOS; vector< _LayerEdge* > lEdges; - // loop on FACEs to srink mesh on + // loop on FACEs to shrink mesh on map< TGeomID, list< _SolidData* > >::iterator f2sd = f2sdMap.begin(); for ( ; f2sd != f2sdMap.end(); ++f2sd ) { @@ -10252,13 +10487,13 @@ bool _ViscousBuilder::shrink(_SolidData& theData) if ( eos.SWOLType() == TopAbs_EDGE ) { SMESH_subMesh* edgeSM = _mesh->GetSubMesh( eos._sWOL ); - _Shrinker1D& srinker = e2shrMap[ edgeSM->GetId() ]; - eShri1D.insert( & srinker ); - srinker.AddEdge( eos._edges[0], eos, helper ); + _Shrinker1D& shrinker = e2shrMap[ edgeSM->GetId() ]; + eShri1D.insert( & shrinker ); + shrinker.AddEdge( eos._edges[0], eos, helper ); VISCOUS_3D::ToClearSubWithMain( edgeSM, data._solid ); - // restore params of nodes on EGDE if the EDGE has been already - // srinked while srinking other FACE - srinker.RestoreParams(); + // restore params of nodes on EDGE if the EDGE has been already + // shrinked while shrinking other FACE + shrinker.RestoreParams(); } for ( size_t i = 0; i < eos._edges.size(); ++i ) { @@ -10449,14 +10684,14 @@ bool _ViscousBuilder::shrink(_SolidData& theData) edge->Is( _LayerEdge::SHRUNK )) continue; if ( subEOS[iS]->SWOLType() == TopAbs_FACE ) { - SMDS_FacePosition* pos = static_cast( tgtNode->GetPosition() ); + SMDS_FacePositionPtr pos = tgtNode->GetPosition(); pos->SetUParameter( edge->_pos[0].X() ); pos->SetVParameter( edge->_pos[0].Y() ); p = surface->Value( edge->_pos[0].X(), edge->_pos[0].Y() ); } else { - SMDS_EdgePosition* pos = static_cast( tgtNode->GetPosition() ); + SMDS_EdgePositionPtr pos = tgtNode->GetPosition(); pos->SetUParameter( edge->_pos[0].Coord( U_TGT )); p = BRepAdaptor_Curve( TopoDS::Edge( subEOS[iS]->_sWOL )).Value( pos->GetUParameter() ); } @@ -10605,7 +10840,7 @@ bool _ViscousBuilder::shrink(_SolidData& theData) if ( data2 ) VISCOUS_3D::ToClearSubWithMain( sm, data2->_solid ); - } // loop on FACES to srink mesh on + } // loop on FACES to shrink mesh on // Replace source nodes by target nodes in shrinked mesh edges @@ -10651,7 +10886,7 @@ bool _ViscousBuilder::prepareEdgeToShrink( _LayerEdge& edge, edge._pos[0].SetCoord( tgtUV.X(), tgtUV.Y(), 0 ); // set UV of source node to target node - SMDS_FacePosition* pos = static_cast( tgtNode->GetPosition() ); + SMDS_FacePositionPtr pos = tgtNode->GetPosition(); pos->SetUParameter( srcUV.X() ); pos->SetVParameter( srcUV.Y() ); } @@ -10701,7 +10936,7 @@ bool _ViscousBuilder::prepareEdgeToShrink( _LayerEdge& edge, edge._simplices[0]._nPrev = n2; // set U of source node to the target node - SMDS_EdgePosition* pos = static_cast( tgtNode->GetPosition() ); + SMDS_EdgePositionPtr pos = tgtNode->GetPosition(); pos->SetUParameter( uSrc ); } return true; @@ -10734,7 +10969,7 @@ void _ViscousBuilder::restoreNoShrink( _LayerEdge& edge ) const TopLoc_Location loc; Handle(Geom_Curve) curve = BRep_Tool::Curve( TopoDS::Edge( S ), loc, f, l ); if ( curve.IsNull() ) return; - SMDS_EdgePosition* ePos = static_cast( srcNode->GetPosition() ); + SMDS_EdgePositionPtr ePos = srcNode->GetPosition(); p = curve->Value( ePos->GetUParameter() ); break; } @@ -10752,7 +10987,7 @@ void _ViscousBuilder::restoreNoShrink( _LayerEdge& edge ) const //================================================================================ /*! - * \brief Try to fix triangles with high aspect ratio by swaping diagonals + * \brief Try to fix triangles with high aspect ratio by swapping diagonals */ //================================================================================ @@ -10960,7 +11195,7 @@ bool _LayerEdge::SetNewLength2d( Handle(Geom_Surface)& surface, { return true; } - SMDS_FacePosition* pos = static_cast( tgtNode->GetPosition() ); + SMDS_FacePositionPtr pos = tgtNode->GetPosition(); pos->SetUParameter( newUV.X() ); pos->SetVParameter( newUV.Y() ); @@ -10974,7 +11209,7 @@ bool _LayerEdge::SetNewLength2d( Handle(Geom_Surface)& surface, { const TopoDS_Edge& E = TopoDS::Edge( eos._sWOL ); const SMDS_MeshNode* n2 = _simplices[0]._nPrev; - SMDS_EdgePosition* tgtPos = static_cast( tgtNode->GetPosition() ); + SMDS_EdgePositionPtr tgtPos = tgtNode->GetPosition(); const double u2 = helper.GetNodeU( E, n2, tgtNode ); const double uSrc = _pos[0].Coord( U_SRC ); @@ -11094,7 +11329,7 @@ bool _SmoothNode::Smooth(int& nbBad, return false; } - SMDS_FacePosition* pos = static_cast( _node->GetPosition() ); + SMDS_FacePositionPtr pos = _node->GetPosition(); pos->SetUParameter( newPos.X() ); pos->SetVParameter( newPos.Y() ); @@ -11114,7 +11349,7 @@ bool _SmoothNode::Smooth(int& nbBad, //================================================================================ /*! - * \brief Computes new UV using angle based smoothing technic + * \brief Computes new UV using angle based smoothing technique */ //================================================================================ @@ -11321,7 +11556,7 @@ void _Shrinker1D::Compute(bool set3D, SMESH_MesherHelper& helper) if ( !discret.IsDone() ) return throw SALOME_Exception(LOCALIZED("GCPnts_AbscissaPoint failed")); double u = discret.Parameter(); - SMDS_EdgePosition* pos = static_cast( _nodes[i]->GetPosition() ); + SMDS_EdgePositionPtr pos = _nodes[i]->GetPosition(); pos->SetUParameter( u ); gp_Pnt p = C->Value( u ); const_cast< SMDS_MeshNode*>( _nodes[i] )->setXYZ( p.X(), p.Y(), p.Z() ); @@ -11339,7 +11574,7 @@ void _Shrinker1D::Compute(bool set3D, SMESH_MesherHelper& helper) { if ( !_nodes[i] ) continue; double u = f * ( 1-_normPar[i] ) + l * _normPar[i]; - SMDS_EdgePosition* pos = static_cast( _nodes[i]->GetPosition() ); + SMDS_EdgePositionPtr pos = _nodes[i]->GetPosition(); pos->SetUParameter( u ); } } @@ -11357,7 +11592,7 @@ void _Shrinker1D::RestoreParams() for ( size_t i = 0; i < _nodes.size(); ++i ) { if ( !_nodes[i] ) continue; - SMDS_EdgePosition* pos = static_cast( _nodes[i]->GetPosition() ); + SMDS_EdgePositionPtr pos = _nodes[i]->GetPosition(); pos->SetUParameter( _initU[i] ); } _done = false; @@ -11444,11 +11679,11 @@ bool _ViscousBuilder::addBoundaryElements(_SolidData& data) const SMDS_MeshNode* tgtN0 = ledges[0]->_nodes.back(); const SMDS_MeshNode* tgtN1 = ledges[1]->_nodes.back(); int nbSharedPyram = 0; - SMDS_ElemIteratorPtr vIt = tgtN0->GetInverseElementIterator(SMDSAbs_Volume); + SMDS_ElemIteratorPtr vIt = tgtN1->GetInverseElementIterator(SMDSAbs_Volume); while ( vIt->more() ) { const SMDS_MeshElement* v = vIt->next(); - nbSharedPyram += int( v->GetNodeIndex( tgtN1 ) >= 0 ); + nbSharedPyram += int( v->GetNodeIndex( tgtN0 ) >= 0 ); } if ( nbSharedPyram > 1 ) continue; // not free border of the pyramid