From: eap Date: Wed, 27 Apr 2005 05:59:30 +0000 (+0000) Subject: PAL8581. Add Is2D parameter to Smooth() X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=618529fa9f962f5246bd632a05bdde97146c6c1d;p=modules%2Fsmesh.git PAL8581. Add Is2D parameter to Smooth() --- diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index 3db54ff3f..7ea6d4c55 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -1461,7 +1462,8 @@ void SMESH_MeshEditor::Smooth (set & theElems, set & theFixedNodes, const SmoothMethod theSmoothMethod, const int theNbIterations, - double theTgtAspectRatio) + double theTgtAspectRatio, + const bool the2D) { MESSAGE((theSmoothMethod==LAPLACIAN ? "LAPLACIAN" : "CENTROIDAL") << "--::Smooth()"); @@ -1481,17 +1483,18 @@ void SMESH_MeshEditor::Smooth (set & theElems, // get all face ids theElems are on set< int > faceIdSet; set< const SMDS_MeshElement* >::iterator itElem; - for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { - int fId = FindShape( *itElem ); - // check that corresponding submesh exists and a shape is face - if (fId && - faceIdSet.find( fId ) == faceIdSet.end() && - aMesh->MeshElements( fId )) { - TopoDS_Shape F = aMesh->IndexToShape( fId ); - if ( !F.IsNull() && F.ShapeType() == TopAbs_FACE ) - faceIdSet.insert( fId ); + if ( the2D ) + for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { + int fId = FindShape( *itElem ); + // check that corresponding submesh exists and a shape is face + if (fId && + faceIdSet.find( fId ) == faceIdSet.end() && + aMesh->MeshElements( fId )) { + TopoDS_Shape F = aMesh->IndexToShape( fId ); + if ( !F.IsNull() && F.ShapeType() == TopAbs_FACE ) + faceIdSet.insert( fId ); + } } - } faceIdSet.insert( 0 ); // to smooth elements that are not on any TopoDS_Face // =============================================== @@ -1505,7 +1508,7 @@ void SMESH_MeshEditor::Smooth (set & theElems, Handle(Geom_Surface) surface; SMESHDS_SubMesh* faceSubMesh = 0; TopoDS_Face face; - double fToler2 = 0, vPeriod = 0., uPeriod = 0.; + double fToler2 = 0, vPeriod = 0., uPeriod = 0., f,l; double u1 = 0, u2 = 0, v1 = 0, v2 = 0; bool isUPeriodic = false, isVPeriodic = false; if ( *fId ) { @@ -1513,7 +1516,7 @@ void SMESH_MeshEditor::Smooth (set & theElems, surface = BRep_Tool::Surface( face ); faceSubMesh = aMesh->MeshElements( *fId ); fToler2 = BRep_Tool::Tolerance( face ); - fToler2 *= fToler2; + fToler2 *= fToler2 * 10.; isUPeriodic = surface->IsUPeriodic(); if ( isUPeriodic ) vPeriod = surface->UPeriod(); @@ -1529,7 +1532,7 @@ void SMESH_MeshEditor::Smooth (set & theElems, bool checkBoundaryNodes = false; set setMovableNodes; map< const SMDS_MeshNode*, gp_XY* > uvMap, uvMap2; - list< gp_XY > listUV; // uvs the 2 maps refer to + list< gp_XY > listUV; // uvs the 2 uvMaps refer to list< const SMDS_MeshElement* > elemsOnFace; Extrema_GenExtPS projector; @@ -1619,26 +1622,60 @@ void SMESH_MeshEditor::Smooth (set & theElems, { node = *n; gp_XY uv( 0, 0 ); - bool project = true; - gp_Pnt pNode ( node->X(), node->Y(), node->Z() ); const SMDS_PositionPtr& pos = node->GetPosition(); posType = pos.get() ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE; - if (faceSubMesh && posType == SMDS_TOP_FACE ) - { - // check if existing UV is OK + // get existing UV + switch ( posType ) { + case SMDS_TOP_FACE: { SMDS_FacePosition* fPos = ( SMDS_FacePosition* ) pos.get(); uv.SetCoord( fPos->GetUParameter(), fPos->GetVParameter() ); - gp_Pnt pSurf = surface->Value( uv.X(), uv.Y() ); - project = pSurf.SquareDistance( pNode ) > fToler2; + break; + } + case SMDS_TOP_EDGE: { + TopoDS_Shape S = aMesh->IndexToShape( pos->GetShapeId() ); + Handle(Geom2d_Curve) pcurve; + if ( !S.IsNull() && S.ShapeType() == TopAbs_EDGE ) + pcurve = BRep_Tool::CurveOnSurface( TopoDS::Edge( S ), face, f,l ); + if ( !pcurve.IsNull() ) { + double u = (( SMDS_EdgePosition* ) pos.get() )->GetUParameter(); + uv = pcurve->Value( u ).XY(); + } + break; } - if ( project ) { - if ( !getClosestUV( projector, pNode, uv )) + case SMDS_TOP_VERTEX: { + TopoDS_Shape S = aMesh->IndexToShape( pos->GetShapeId() ); + if ( !S.IsNull() && S.ShapeType() == TopAbs_VERTEX ) + uv = BRep_Tool::Parameters( TopoDS::Vertex( S ), face ).XY(); + break; + } + default:; + } + // check existing UV + bool project = true; + gp_Pnt pNode ( node->X(), node->Y(), node->Z() ); + double dist1 = DBL_MAX, dist2 = 0; + if ( posType != SMDS_TOP_3DSPACE ) { + dist1 = pNode.SquareDistance( surface->Value( uv.X(), uv.Y() )); + project = dist1 > fToler2; + } + if ( project ) { // compute new UV + gp_XY newUV; + if ( !getClosestUV( projector, pNode, newUV )) { MESSAGE("Node Projection Failed " << node); - if ( isUPeriodic ) - uv.SetX( ElCLib::InPeriod( uv.X(), u1, u2 )); - if ( isVPeriodic ) - uv.SetY( ElCLib::InPeriod( uv.Y(), v1, v2 )); + } + else { + if ( isUPeriodic ) + newUV.SetX( ElCLib::InPeriod( newUV.X(), u1, u2 )); + if ( isVPeriodic ) + newUV.SetY( ElCLib::InPeriod( newUV.Y(), v1, v2 )); + // check new UV + if ( posType != SMDS_TOP_3DSPACE ) + dist2 = pNode.SquareDistance( surface->Value( newUV.X(), newUV.Y() )); + if ( dist2 < dist1 ) + uv = newUV; + } } + // store UV in the map listUV.push_back( uv ); uvMap.insert( make_pair( node, &listUV.back() )); } diff --git a/src/SMESH/SMESH_MeshEditor.hxx b/src/SMESH/SMESH_MeshEditor.hxx index e9252e6a8..0bb91f730 100644 --- a/src/SMESH/SMESH_MeshEditor.hxx +++ b/src/SMESH/SMESH_MeshEditor.hxx @@ -98,13 +98,16 @@ class SMESH_MeshEditor { std::set & theFixedNodes, const SmoothMethod theSmoothMethod, const int theNbIterations, - double theTgtAspectRatio = 1.0); + double theTgtAspectRatio = 1.0, + const bool the2D = true); // Smooth theElements using theSmoothMethod during theNbIterations // or until a worst element has aspect ratio <= theTgtAspectRatio. // Aspect Ratio varies in range [1.0, inf]. // If theElements is empty, the whole mesh is smoothed. // theFixedNodes contains additionally fixed nodes. Nodes built // on edges and boundary nodes are always fixed. + // If the2D, smoothing is performed using UV parameters of nodes + // on geometrical faces void RotationSweep (std::set & theElements,