X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_FaceSide.cxx;h=36f0680cc4267e48bd301fc4ff4df772709f3011;hb=9645435524d6601ce3d0da6d226d9c11991d864e;hp=dc436d74fcc81b02102b408237ae31821982b506;hpb=8fa039a796957b302d86d90b22afc0a998573f83;p=modules%2Fsmesh.git diff --git a/src/StdMeshers/StdMeshers_FaceSide.cxx b/src/StdMeshers/StdMeshers_FaceSide.cxx index dc436d74f..36f0680cc 100644 --- a/src/StdMeshers/StdMeshers_FaceSide.cxx +++ b/src/StdMeshers/StdMeshers_FaceSide.cxx @@ -1,26 +1,25 @@ -// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// 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. +// 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. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_FaceSide.hxx // Created : Wed Jan 31 18:41:25 2007 // Author : Edward AGAPOV (eap) @@ -40,9 +39,10 @@ #include #include -#include #include #include +#include +#include #include #include #include @@ -50,9 +50,6 @@ #include #include -#include -#include - #include #include "utilities.h" @@ -65,14 +62,16 @@ */ //================================================================================ -StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace, - const TopoDS_Edge& theEdge, - SMESH_Mesh* theMesh, - const bool theIsForward, - const bool theIgnoreMediumNodes) +StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace, + const TopoDS_Edge& theEdge, + SMESH_Mesh* theMesh, + const bool theIsForward, + const bool theIgnoreMediumNodes, + SMESH_ProxyMesh::Ptr theProxyMesh) { list edges(1,theEdge); - *this = StdMeshers_FaceSide( theFace, edges, theMesh, theIsForward, theIgnoreMediumNodes ); + *this = StdMeshers_FaceSide( theFace, edges, theMesh, theIsForward, + theIgnoreMediumNodes, theProxyMesh ); } //================================================================================ @@ -83,41 +82,45 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace, */ //================================================================================ -StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace, - list& theEdges, - SMESH_Mesh* theMesh, - const bool theIsForward, - const bool theIgnoreMediumNodes) +StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace, + list& theEdges, + SMESH_Mesh* theMesh, + const bool theIsForward, + const bool theIgnoreMediumNodes, + SMESH_ProxyMesh::Ptr theProxyMesh) { int nbEdges = theEdges.size(); - myEdge.resize( nbEdges ); - myC2d.resize( nbEdges ); + myEdge.resize ( nbEdges ); + myEdgeID.resize ( nbEdges ); + myC2d.resize ( nbEdges ); myC3dAdaptor.resize( nbEdges ); - myFirst.resize( nbEdges ); - myLast.resize( nbEdges ); - myNormPar.resize( nbEdges ); + myFirst.resize ( nbEdges ); + myLast.resize ( nbEdges ); + myNormPar.resize ( nbEdges ); myEdgeLength.resize( nbEdges ); - myIsUniform.resize( nbEdges, true ); - myLength = 0; - myNbPonits = myNbSegments = 0; - myMesh = theMesh; + myIsUniform.resize ( nbEdges, true ); + myLength = 0; + myNbPonits = myNbSegments = 0; + myProxyMesh = theProxyMesh; myMissingVertexNodes = false; - myIgnoreMediumNodes = theIgnoreMediumNodes; - myDefaultPnt2d = gp_Pnt2d( 1e+100, 1e+100 ); + myIgnoreMediumNodes = theIgnoreMediumNodes; + myDefaultPnt2d = gp_Pnt2d( 1e+100, 1e+100 ); + if ( !myProxyMesh ) myProxyMesh.reset( new SMESH_ProxyMesh( *theMesh )); if ( nbEdges == 0 ) return; - SMESHDS_Mesh* meshDS = theMesh->GetMeshDS(); + SMESHDS_Mesh* meshDS = myProxyMesh->GetMeshDS(); int nbDegen = 0; list::iterator edge = theEdges.begin(); TopoDS_Iterator vExp; for ( int index = 0; edge != theEdges.end(); ++index, ++edge ) { - int i = theIsForward ? index : nbEdges - index - 1; + int i = theIsForward ? index : nbEdges-index-1; myEdgeLength[i] = SMESH_Algo::EdgeLength( *edge ); if ( myEdgeLength[i] < DBL_MIN ) nbDegen++; myLength += myEdgeLength[i]; myEdge[i] = *edge; + myEdgeID[i] = meshDS->ShapeToIndex( *edge ); if ( !theIsForward ) myEdge[i].Reverse(); if ( theFace.IsNull() ) @@ -127,7 +130,7 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace, if ( myEdge[i].Orientation() == TopAbs_REVERSED ) std::swap( myFirst[i], myLast[i] ); - if ( SMESHDS_SubMesh* sm = meshDS->MeshElements( *edge )) { + if ( const SMESHDS_SubMesh* sm = myProxyMesh->GetSubMesh( *edge )) { int nbN = sm->NbNodes(); if ( theIgnoreMediumNodes ) { SMDS_ElemIteratorPtr elemIt = sm->GetElements(); @@ -137,6 +140,7 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace, myNbPonits += nbN; myNbSegments += sm->NbElements(); } + // TopExp::FirstVertex() and TopExp::LastVertex() return NULL from INTERNAL edge vExp.Initialize( *edge ); if ( vExp.Value().Orientation() == TopAbs_REVERSED ) vExp.Next(); @@ -145,10 +149,12 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace, else myMissingVertexNodes = true; - // check if edge has non-uniform parametrization (issue 0020705) + // check if the edge has a non-uniform parametrization (issue 0020705) if ( !myC2d[i].IsNull() && myEdgeLength[i] > DBL_MIN) { - Geom2dAdaptor_Curve A2dC( myC2d[i] ); + Geom2dAdaptor_Curve A2dC( myC2d[i], + std::min( myFirst[i], myLast[i] ), + std::max( myFirst[i], myLast[i] )); double p2 = myFirst[i]+(myLast[i]-myFirst[i])/2., p4 = myFirst[i]+(myLast[i]-myFirst[i])/4.; double d2 = GCPnts_AbscissaPoint::Length( A2dC, myFirst[i], p2 ); double d4 = GCPnts_AbscissaPoint::Length( A2dC, myFirst[i], p4 ); @@ -162,7 +168,12 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace, myC3dAdaptor[i].Load( C3d, fp,lp ); } } - } + // reverse a proxy submesh + if ( !theIsForward ) + reverseProxySubmesh( myEdge[i] ); + + } // loop on edges + vExp.Initialize( theEdges.back() ); if ( vExp.Value().Orientation() != TopAbs_REVERSED ) vExp.Next(); if ( vExp.More() ) @@ -202,8 +213,8 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const SMDS_MeshNode* theNode, const StdMeshers_FaceSide* theSide) { myC2d.resize(1); - myLength = 0; - myMesh = theSide->GetMesh(); + myLength = 0; + myProxyMesh = theSide->myProxyMesh; myDefaultPnt2d = thePnt2d; myPoints = theSide->GetUVPtStruct(); @@ -231,82 +242,102 @@ const vector& StdMeshers_FaceSide::GetUVPtStruct(bool isXConst, if ( NbEdges() == 0 ) return myPoints; - SMESHDS_Mesh* meshDS = myMesh->GetMeshDS(); - SMESH_MesherHelper helper(*myMesh); + SMESHDS_Mesh* meshDS = myProxyMesh->GetMeshDS(); + SMESH_MesherHelper helper(*myProxyMesh->GetMesh()); bool paramOK; + double eps = 1e-100; // sort nodes of all edges putting them into a map map< double, const SMDS_MeshNode*> u2node; - //int nbOnDegen = 0; - for ( int i = 0; i < myEdge.size(); ++i ) + vector< const SMESH_ProxyMesh::SubMesh* > proxySubMesh( myEdge.size()); + int nbProxyNodes = 0; + for ( size_t iE = 0; iE < myEdge.size(); ++iE ) { + proxySubMesh[iE] = myProxyMesh->GetProxySubMesh( myEdge[iE] ); + if ( proxySubMesh[iE] ) + { + if ( proxySubMesh[iE]->GetUVPtStructVec().empty() ) { + proxySubMesh[iE] = 0; + } + else { + nbProxyNodes += proxySubMesh[iE]->GetUVPtStructVec().size() - 1; + if ( iE+1 == myEdge.size() ) + ++nbProxyNodes; + continue; + } + } // Put 1st vertex node of a current edge TopoDS_Vertex VV[2]; // TopExp::FirstVertex() returns NULL for INTERNAL edge - for ( TopoDS_Iterator vIt(myEdge[i]); vIt.More(); vIt.Next() ) - VV[ VV[0].IsNull() ? 0 : 1 ] = TopoDS::Vertex(vIt.Value()); - if ( VV[0].Orientation() == TopAbs_REVERSED ) std::swap ( VV[0], VV[1] ); + VV[0] = SMESH_MesherHelper::IthVertex( 0, myEdge[iE]); + VV[1] = SMESH_MesherHelper::IthVertex( 1, myEdge[iE]); const SMDS_MeshNode* node = SMESH_Algo::VertexNode( VV[0], meshDS ); - double prevNormPar = ( i == 0 ? 0 : myNormPar[ i-1 ]); // normalized param - if ( node ) { // internal nodes may be missing - u2node.insert( make_pair( prevNormPar, node )); + double prevNormPar = ( iE == 0 ? 0 : myNormPar[ iE-1 ]); // normalized param + if ( node ) { // nodes on internal vertices may be missing + u2node.insert( u2node.end(), make_pair( prevNormPar, node )); } - else if ( i == 0 ) { + else if ( iE == 0 ) { MESSAGE(" NO NODE on VERTEX" ); return myPoints; } // Put internal nodes - SMESHDS_SubMesh* sm = meshDS->MeshElements( myEdge[i] ); - if ( !sm ) continue; - vector< pair< double, const SMDS_MeshNode*> > u2nodeVec; - u2nodeVec.reserve( sm->NbNodes() ); - SMDS_NodeIteratorPtr nItr = sm->GetNodes(); - double paramSize = myLast[i] - myFirst[i]; - double r = myNormPar[i] - prevNormPar; - if ( !myIsUniform[i] ) - while ( nItr->more() ) - { - const SMDS_MeshNode* node = nItr->next(); - if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge )) - continue; - double u = helper.GetNodeU( myEdge[i], node, 0, ¶mOK ); - double aLenU = GCPnts_AbscissaPoint::Length - ( const_cast( myC3dAdaptor[i]), myFirst[i], u ); - if ( myEdgeLength[i] < aLenU ) // nonregression test "3D_mesh_NETGEN/G6" + if ( const SMESHDS_SubMesh* sm = myProxyMesh->GetSubMesh( myEdge[iE] )) + { + vector< pair< double, const SMDS_MeshNode*> > u2nodeVec; + u2nodeVec.reserve( sm->NbNodes() ); + SMDS_NodeIteratorPtr nItr = sm->GetNodes(); + double paramSize = myLast[iE] - myFirst[iE]; + double r = myNormPar[iE] - prevNormPar; + helper.SetSubShape( myEdge[iE] ); + helper.ToFixNodeParameters( true ); + if ( !myIsUniform[iE] ) + while ( nItr->more() ) { - u2nodeVec.clear(); - break; + const SMDS_MeshNode* node = nItr->next(); + if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge )) + continue; + double u = helper.GetNodeU( myEdge[iE], node, 0, ¶mOK ); + double aLenU = GCPnts_AbscissaPoint::Length + ( const_cast( myC3dAdaptor[iE]), myFirst[iE], u ); + if ( myEdgeLength[iE] < aLenU ) // nonregression test "3D_mesh_NETGEN/G6" + { + u2nodeVec.clear(); + break; + } + double normPar = prevNormPar + r*aLenU/myEdgeLength[iE]; + u2nodeVec.push_back( make_pair( normPar, node )); } - double normPar = prevNormPar + r*aLenU/myEdgeLength[i]; - u2nodeVec.push_back( make_pair( normPar, node )); - } - nItr = sm->GetNodes(); - if ( u2nodeVec.empty() ) - while ( nItr->more() ) - { - const SMDS_MeshNode* node = nItr->next(); - if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge )) - continue; - double u = helper.GetNodeU( myEdge[i], node, 0, ¶mOK ); - - // paramSize is signed so orientation is taken into account - double normPar = prevNormPar + r * ( u - myFirst[i] ) / paramSize; - u2nodeVec.push_back( make_pair( normPar, node )); - } - u2node.insert( u2nodeVec.begin(), u2nodeVec.end() ); + nItr = sm->GetNodes(); + if ( u2nodeVec.empty() ) + while ( nItr->more() ) + { + const SMDS_MeshNode* node = nItr->next(); + if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge )) + continue; + double u = helper.GetNodeU( myEdge[iE], node, 0, ¶mOK ); + + // paramSize is signed so orientation is taken into account + double normPar = prevNormPar + r * ( u - myFirst[iE] ) / paramSize; + u2nodeVec.push_back( make_pair( normPar, node )); + } + for ( size_t j = 0; j < u2nodeVec.size(); ++j ) + u2node.insert( u2node.end(), u2nodeVec[j] ); + } // Put 2nd vertex node for a last edge - if ( i+1 == myEdge.size() ) { + if ( iE+1 == myEdge.size() ) { node = SMESH_Algo::VertexNode( VV[1], meshDS ); if ( !node ) { MESSAGE(" NO NODE on VERTEX" ); return myPoints; } - u2node.insert( make_pair( 1., node )); + u2node.insert( u2node.end(), make_pair( 1., node )); } - } - if ( u2node.size() != myNbPonits ) { + } // loop on myEdge's + + if ( u2node.size() + nbProxyNodes != myNbPonits ) + { MESSAGE("Wrong node parameters on edges, u2node.size():" <& StdMeshers_FaceSide::GetUVPtStruct(bool isXConst, // fill array of UVPtStruct - vector* points = const_cast*>( &myPoints ); - points->resize( myNbPonits ); + UVPtStructVec& points = const_cast< UVPtStructVec& >( myPoints ); + points.resize( myNbPonits ); - int EdgeIndex = 0; - double prevNormPar = 0, paramSize = myNormPar[ EdgeIndex ]; + int iPt = 0; + double prevNormPar = 0, paramSize = myNormPar[ 0 ]; map< double, const SMDS_MeshNode*>::iterator u_node = u2node.begin(); - for (int i = 0 ; u_node != u2node.end(); ++u_node, ++i ) { - UVPtStruct & uvPt = (*points)[i]; - uvPt.node = u_node->second; - uvPt.x = uvPt.y = uvPt.normParam = u_node->first; - if ( isXConst ) uvPt.x = constValue; - else uvPt.y = constValue; - if ( myNormPar[ EdgeIndex ] < uvPt.normParam ) { - prevNormPar = myNormPar[ EdgeIndex ]; - ++EdgeIndex; -#ifdef _DEBUG_ - if ( EdgeIndex >= myEdge.size() ) { - dump("DEBUG"); - MESSAGE ( "WRONg EdgeIndex " << 1+EdgeIndex - << " myNormPar.size()="<MeshElements( myEdge[i] )) + { + SMDS_NodeIteratorPtr nItr = sm->GetNodes(); + double paramSize = myLast[i] - myFirst[i]; + double r = myNormPar[i] - prevNormPar; + helper.SetSubShape( myEdge[i] ); + helper.ToFixNodeParameters( true ); + while ( nItr->more() ) + { + const SMDS_MeshNode* node = nItr->next(); + if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge )) + continue; + double u = helper.GetNodeU( myEdge[i], node, 0, ¶mOK ); + + // paramSize is signed so orientation is taken into account + double normPar = prevNormPar + r * ( u - myFirst[i] ) / paramSize; + u2node.insert( u2node.end(), make_pair( normPar, node )); + } + } + + // Put 2nd vertex node for a last edge + if ( i+1 == myEdge.size() ) { + node = SMESH_Algo::VertexNode( VV[1], meshDS ); + if ( !node ) { + return resultNodes; + } + u2node.insert( u2node.end(), make_pair( 1., node )); + } + } + + // Fill the result vector + + if ( u2node.size() == myNbPonits ) + { + resultNodes.reserve( u2node.size() ); + map< double, const SMDS_MeshNode*>::iterator u2n = u2node.begin(); + for ( ; u2n != u2node.end(); ++u2n ) + resultNodes.push_back( u2n->second ); + } + } + else + { + resultNodes.resize( myPoints.size() ); + for ( size_t i = 0; i < myPoints.size(); ++i ) + resultNodes[i] = myPoints[i].node; + } + + return resultNodes; +} //================================================================================ /*! @@ -444,6 +584,7 @@ void StdMeshers_FaceSide::Reverse() } if ( nbEdges > 1 ) { reverse( myEdge ); + reverse( myEdgeID ); reverse( myC2d ); reverse( myC3dAdaptor ); reverse( myFirst ); @@ -457,6 +598,31 @@ void StdMeshers_FaceSide::Reverse() myNormPar[nbEdges-1]=1.; myPoints.clear(); myFalsePoints.clear(); + for ( size_t i = 0; i < myEdge.size(); ++i ) + reverseProxySubmesh( myEdge[i] ); + } +} + +//================================================================================ +/*! + * \brief Reverse UVPtStructVec if a proxy sub-mesh of E + */ +//================================================================================ + +void StdMeshers_FaceSide::reverseProxySubmesh( const TopoDS_Edge& E ) +{ + if ( !myProxyMesh ) return; + if ( const SMESH_ProxyMesh::SubMesh* sm = myProxyMesh->GetProxySubMesh( E )) + { + UVPtStructVec& edgeUVPtStruct = (UVPtStructVec& ) sm->GetUVPtStructVec(); + for ( size_t i = 0; i < edgeUVPtStruct.size(); ++i ) + { + UVPtStruct & uvPt = edgeUVPtStruct[i]; + uvPt.normParam = 1 - uvPt.normParam; + uvPt.x = 1 - uvPt.x; + uvPt.y = 1 - uvPt.y; + } + reverse( edgeUVPtStruct ); } } @@ -531,14 +697,15 @@ BRepAdaptor_CompCurve* StdMeshers_FaceSide::GetCurve3d() const if ( myEdge.empty() ) return 0; -// if ( myEdge.size() == 1 ) -// return new BRepAdaptor_Curve( myEdge[0] ); - TopoDS_Wire aWire; BRep_Builder aBuilder; aBuilder.MakeWire(aWire); for ( int i=0; i edges, internalEdges; @@ -629,14 +797,16 @@ TSideVector StdMeshers_FaceSide::GetFaceWires(const TopoDS_Face& theFace, } StdMeshers_FaceSide* wire = new StdMeshers_FaceSide( theFace, wireEdges, &theMesh, - /*isForward=*/true, theIgnoreMediumNodes); + /*isForward=*/true, theIgnoreMediumNodes, + theProxyMesh ); wires[ iW ] = StdMeshers_FaceSidePtr( wire ); from = to; } while ( !internalEdges.empty() ) { StdMeshers_FaceSide* wire = new StdMeshers_FaceSide( theFace, internalEdges.back(), &theMesh, - /*isForward=*/true, theIgnoreMediumNodes); + /*isForward=*/true, theIgnoreMediumNodes, + theProxyMesh ); wires.push_back( StdMeshers_FaceSidePtr( wire )); internalEdges.pop_back(); }