X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_FaceSide.cxx;h=c2596b4b6db521feefb7466ed7c2cbadd1ee138f;hp=37bc6c346792d2ccbb0e37dae0ed57c9e389019c;hb=ae32dcd34f98b91cdb4f5800063a394feb0df408;hpb=9a54694a0ab1e5cbc558a35c4606ceea4f7af2ef diff --git a/src/StdMeshers/StdMeshers_FaceSide.cxx b/src/StdMeshers/StdMeshers_FaceSide.cxx index 37bc6c346..c2596b4b6 100644 --- a/src/StdMeshers/StdMeshers_FaceSide.cxx +++ b/src/StdMeshers/StdMeshers_FaceSide.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2014 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 @@ -6,7 +6,7 @@ // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either -// version 2.1 of the License. +// version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -51,6 +51,7 @@ #include #include +#include #include "utilities.h" @@ -202,36 +203,123 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace, //================================================================================ /*! * \brief Constructor of a side for vertex using data from other FaceSide - * \param theVertex - the vertex - * \param theSide - the side + * \param theVertex - the vertex + * \param theSide - the side */ //================================================================================ -StdMeshers_FaceSide::StdMeshers_FaceSide(const SMDS_MeshNode* theNode, - const gp_Pnt2d thePnt2d, - const StdMeshers_FaceSide* theSide) +StdMeshers_FaceSide::StdMeshers_FaceSide(const StdMeshers_FaceSide* theSide, + const SMDS_MeshNode* theNode, + const gp_Pnt2d* thePnt2d1, + const gp_Pnt2d* thePnt2d2, + const Handle(Geom2d_Curve)& theC2d, + const double theUFirst, + const double theULast) { - myC2d.resize(1); + myC2d.push_back ( theC2d ); + myFirst.push_back ( theUFirst ); + myLast.push_back ( theULast ); + myNormPar.push_back ( 1. ); + myIsUniform.push_back( true ); + myEdgeID.push_back ( 0 ); myLength = 0; myProxyMesh = theSide->myProxyMesh; - myDefaultPnt2d = thePnt2d; - - myPoints = theSide->GetUVPtStruct(); - myNbPonits = myPoints.size(); - myNbSegments = theSide->myNbSegments; - std::vector::iterator it = myPoints.begin(); - for(; it!=myPoints.end(); it++) { - (*it).u = thePnt2d.X(); - (*it).v = thePnt2d.Y(); - (*it).y = 0.0; - (*it).node = theNode; + myDefaultPnt2d = *thePnt2d1; + myPoints = theSide->GetUVPtStruct(); + myNbPonits = myPoints.size(); + myNbSegments = theSide->myNbSegments; + if ( thePnt2d2 ) + for ( size_t i = 0; i < myPoints.size(); ++i ) + { + double r = i / ( myPoints.size() - 1. ); + myPoints[i].u = (1-r) * thePnt2d1->X() + r * thePnt2d2->X(); + myPoints[i].v = (1-r) * thePnt2d1->Y() + r * thePnt2d2->Y(); + myPoints[i].node = theNode; + } + else + for ( size_t i = 0; i < myPoints.size(); ++i ) + { + myPoints[i].u = thePnt2d1->X(); + myPoints[i].v = thePnt2d1->Y(); + myPoints[i].node = theNode; + } +} + +//================================================================================ +/* + * Create a side from an UVPtStructVec + */ +//================================================================================ + +StdMeshers_FaceSide::StdMeshers_FaceSide(UVPtStructVec& theSideNodes, + const TopoDS_Face& theFace) +{ + myEdge.resize( 1 ); + myEdgeID.resize( 1, -1 ); + myC2d.resize( 1 ); + myC3dAdaptor.resize( 1 ); + myFirst.resize( 1, 0. ); + myLast.resize( 1, 1. ); + myNormPar.resize( 1, 1. ); + myIsUniform.resize( 1, 1 ); + myMissingVertexNodes = myIgnoreMediumNodes = false; + myDefaultPnt2d.SetCoord( 1e100, 1e100 ); + + myPoints = theSideNodes; + myNbPonits = myPoints.size(); + myNbSegments = myNbPonits + 1; + + myLength = 0; + if ( !myPoints.empty() ) + { + myPoints[0].normParam = 0; + if ( myPoints[0].node && + myPoints.back().node && + myPoints[ myNbPonits/2 ].node ) + { + gp_Pnt pPrev = SMESH_TNodeXYZ( myPoints[0].node ); + for ( size_t i = 1; i < myPoints.size(); ++i ) + { + gp_Pnt p = SMESH_TNodeXYZ( myPoints[i].node ); + myLength += p.Distance( pPrev ); + myPoints[i].normParam = myLength; + pPrev = p; + } + } + else if ( !theFace.IsNull() ) + { + TopLoc_Location loc; + Handle(Geom_Surface) surf = BRep_Tool::Surface( theFace, loc ); + gp_Pnt pPrev = surf->Value( myPoints[0].u, myPoints[0].v ); + for ( size_t i = 1; i < myPoints.size(); ++i ) + { + gp_Pnt p = surf->Value( myPoints[i].u, myPoints[i].v ); + myLength += p.Distance( pPrev ); + myPoints[i].normParam = myLength; + pPrev = p; + } + } + else + { + gp_Pnt2d pPrev = myPoints[0].UV(); + for ( size_t i = 1; i < myPoints.size(); ++i ) + { + gp_Pnt2d p = myPoints[i].UV(); + myLength += p.Distance( pPrev ); + myPoints[i].normParam = myLength; + pPrev = p; + } + } + if ( myLength > std::numeric_limits::min() ) + for ( size_t i = 1; i < myPoints.size(); ++i ) + myPoints[i].normParam /= myLength; } + myEdgeLength.resize( 1, myLength ); } //================================================================================ -/*! - * \brief Return info on nodes on the side - * \retval UVPtStruct* - array of data structures +/* + * Return info on nodes on the side */ //================================================================================ @@ -358,13 +446,22 @@ const vector& StdMeshers_FaceSide::GetUVPtStruct(bool isXConst, { const UVPtStructVec& edgeUVPtStruct = proxySubMesh[iE]->GetUVPtStructVec(); std::copy( edgeUVPtStruct.begin(), edgeUVPtStruct.end(), & points[iPt] ); + // check orientation + double du1 = edgeUVPtStruct.back().param - edgeUVPtStruct[0].param; + double du2 = myLast[iE] - myFirst[iE]; + if ( du1 * du2 < 0 ) + { + std::reverse( & points[iPt], & points[iPt + edgeUVPtStruct.size()]); + for ( size_t i = 0; i < edgeUVPtStruct.size(); ++i ) + points[iPt+i].normParam = 1. - points[iPt+i].normParam; + } // update normalized params if ( myEdge.size() > 1 ) { for ( size_t i = 0; i < edgeUVPtStruct.size(); ++i, ++iPt ) { UVPtStruct & uvPt = points[iPt]; - uvPt.normParam = prevNormPar + uvPt.normParam * paramSize; - uvPt.x = uvPt.y = uvPt.normParam; + uvPt.normParam = prevNormPar + uvPt.normParam * paramSize; + uvPt.x = uvPt.y = uvPt.normParam; } --iPt; // to point to the 1st VERTEX of the next EDGE } @@ -579,7 +676,8 @@ void StdMeshers_FaceSide::Reverse() int nbEdges = myEdge.size(); for ( int i = nbEdges-1; i >= 0; --i ) { std::swap( myFirst[i], myLast[i] ); - myEdge[i].Reverse(); + if ( !myEdge[i].IsNull() ) + myEdge[i].Reverse(); if ( i > 0 ) // at the first loop 1. is overwritten myNormPar[i] = 1 - myNormPar[i-1]; } @@ -597,13 +695,37 @@ void StdMeshers_FaceSide::Reverse() if ( nbEdges > 0 ) { myNormPar[nbEdges-1]=1.; - myPoints.clear(); - myFalsePoints.clear(); - for ( size_t i = 0; i < myEdge.size(); ++i ) - reverseProxySubmesh( myEdge[i] ); + if ( !myEdge[0].IsNull() ) + { + for ( size_t i = 0; i < myEdge.size(); ++i ) + reverseProxySubmesh( myEdge[i] ); + myPoints.clear(); + myFalsePoints.clear(); + } + else + { + for ( size_t i = 0; i < myPoints.size(); ++i ) + { + UVPtStruct & uvPt = myPoints[i]; + uvPt.normParam = 1 - uvPt.normParam; + uvPt.x = 1 - uvPt.x; + uvPt.y = 1 - uvPt.y; + } + reverse( myPoints ); + + for ( size_t i = 0; i < myFalsePoints.size(); ++i ) + { + UVPtStruct & uvPt = myFalsePoints[i]; + uvPt.normParam = 1 - uvPt.normParam; + uvPt.x = 1 - uvPt.x; + uvPt.y = 1 - uvPt.y; + } + reverse( myFalsePoints ); + } } for ( size_t i = 0; i < myEdge.size(); ++i ) { + if ( myEdge[i].IsNull() ) continue; // for a side on points only double fp,lp; Handle(Geom_Curve) C3d = BRep_Tool::Curve(myEdge[i],fp,lp); if ( !C3d.IsNull() ) @@ -836,6 +958,18 @@ gp_Pnt2d StdMeshers_FaceSide::Value2d(double U) const return myC2d[ i ]->Value(par); } + else if ( !myPoints.empty() ) + { + int i = U * double( myPoints.size()-1 ); + while ( i > 0 && myPoints[ i ].normParam > U ) + --i; + while ( i+1 < myPoints.size() && myPoints[ i+1 ].normParam < U ) + ++i; + double r = (( U - myPoints[ i ].normParam ) / + ( myPoints[ i+1 ].normParam - myPoints[ i ].normParam )); + return ( myPoints[ i ].UV() * ( 1 - r ) + + myPoints[ i+1 ].UV() * r ); + } return myDefaultPnt2d; } @@ -878,7 +1012,8 @@ TSideVector StdMeshers_FaceSide::GetFaceWires(const TopoDS_Face& theFace, SMESH_Mesh & theMesh, const bool theIgnoreMediumNodes, TError & theError, - SMESH_ProxyMesh::Ptr theProxyMesh) + SMESH_ProxyMesh::Ptr theProxyMesh, + const bool theCheckVertexNodes) { list< TopoDS_Edge > edges, internalEdges; list< int > nbEdgesInWires; @@ -903,17 +1038,18 @@ TSideVector StdMeshers_FaceSide::GetFaceWires(const TopoDS_Face& theFace, // as StdMeshers_FaceSide::GetUVPtStruct() requires if ( wireEdges.front().Orientation() != TopAbs_INTERNAL ) // Issue 0020676 { - while ( !SMESH_Algo::VertexNode( TopExp::FirstVertex( wireEdges.front(), true), - theMesh.GetMeshDS())) - { - wireEdges.splice(wireEdges.end(), wireEdges, - wireEdges.begin(), ++wireEdges.begin()); - if ( from->IsSame( wireEdges.front() )) { - theError = TError - ( new SMESH_ComputeError(COMPERR_BAD_INPUT_MESH,"No nodes on vertices")); - return TSideVector(0); + if ( theCheckVertexNodes ) + while ( !SMESH_Algo::VertexNode( TopExp::FirstVertex( wireEdges.front(), true), + theMesh.GetMeshDS())) + { + wireEdges.splice(wireEdges.end(), wireEdges, + wireEdges.begin(), ++wireEdges.begin()); + if ( from->IsSame( wireEdges.front() )) { + theError = TError + ( new SMESH_ComputeError(COMPERR_BAD_INPUT_MESH,"No nodes on vertices")); + return TSideVector(0); + } } - } } else if ( *nbE > 1 ) // Issue 0020676 (Face_pb_netgen.brep) - several internal edges in a wire {