X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_FaceSide.cxx;h=d1d20245d4858158eaccc04221b357aefba97717;hp=7719b4f6e799628d4678b0d3d5f9110e835e3ced;hb=7084b4f9799cf4a0145ba86ab8b653de8f2d2bdb;hpb=0635c9fc80f67d1e5dc0e94ec85f487286a92070 diff --git a/src/StdMeshers/StdMeshers_FaceSide.cxx b/src/StdMeshers/StdMeshers_FaceSide.cxx index 7719b4f6e..d1d20245d 100644 --- a/src/StdMeshers/StdMeshers_FaceSide.cxx +++ b/src/StdMeshers/StdMeshers_FaceSide.cxx @@ -1,25 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2015 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, 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 -// 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) @@ -31,24 +31,28 @@ #include "SMDS_MeshNode.hxx" #include "SMESHDS_Mesh.hxx" #include "SMESHDS_SubMesh.hxx" -//#include "SMESH_Algo.hxx" +#include "SMESH_Algo.hxx" #include "SMESH_Mesh.hxx" -#include "SMESH_MeshEditor.hxx" +#include "SMESH_MesherHelper.hxx" #include "SMESH_ComputeError.hxx" #include "SMESH_Block.hxx" #include #include -#include #include #include +#include +#include +#include #include #include +#include #include #include #include #include +#include #include "utilities.h" @@ -60,55 +64,63 @@ */ //================================================================================ -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 ); } //================================================================================ /*! * \brief Constructor of a side of several edges - * \param theFace - the face - * \param theEdge - the edge */ //================================================================================ -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 ); - myFirst.resize( nbEdges ); - myLast.resize( nbEdges ); - myNormPar.resize( nbEdges ); - myLength = 0; - myNbPonits = myNbSegments = 0; - myMesh = theMesh; + myEdge.resize ( nbEdges ); + myEdgeID.resize ( nbEdges ); + myC2d.resize ( nbEdges ); + myC3dAdaptor.resize( nbEdges ); + myFirst.resize ( nbEdges ); + myLast.resize ( nbEdges ); + myNormPar.resize ( nbEdges ); + myEdgeLength.resize( nbEdges ); + myIsUniform.resize ( nbEdges, true ); + myFace = theFace; + myLength = 0; + myNbPonits = myNbSegments = 0; + myProxyMesh = theProxyMesh; myMissingVertexNodes = false; - myIgnoreMediumNodes = theIgnoreMediumNodes; + 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(); - vector len( nbEdges ); + SMESHDS_Mesh* meshDS = myProxyMesh->GetMeshDS(); int nbDegen = 0; list::iterator edge = theEdges.begin(); for ( int index = 0; edge != theEdges.end(); ++index, ++edge ) { - int i = theIsForward ? index : nbEdges - index - 1; - len[i] = SMESH_Algo::EdgeLength( *edge ); - if ( len[i] < DBL_MIN ) nbDegen++; - myLength += len[i]; - myEdge[i] = *edge; + 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() ) @@ -118,25 +130,38 @@ 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 )) { - int nbN = sm->NbNodes(); - if ( theIgnoreMediumNodes ) { - SMDS_ElemIteratorPtr elemIt = sm->GetElements(); - if ( elemIt->more() && elemIt->next()->IsQuadratic() ) - nbN -= sm->NbElements(); + // check if the edge has a non-uniform parametrization (issue 0020705) + if ( !myC2d[i].IsNull() ) + { + if ( myEdgeLength[i] > DBL_MIN ) + { + 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.; + double 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 ); + //cout<<"len = "<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 2nd vertex node for a last edge - if ( i+1 == myEdge.size() ) { - node = SMESH_Algo::VertexNode( VLast, meshDS ); - if ( !node ) { - MESSAGE(" NO NODE on VERTEX" ); - return myPoints; + // Add 1st vertex node of a current edge + const SMDS_MeshNode* node = VertexNode( iE ); + const double prevNormPar = ( iE == 0 ? 0 : myNormPar[ iE-1 ]); // normalized param + if ( node ) // nodes on internal vertices may be missing + { + if ( vertexNodes.insert( node ).second || + fHelper.IsRealSeam( node->getshapeId() )) + u2node.insert( u2node.end(), make_pair( prevNormPar, node )); + } + else if ( iE == 0 ) + { + if ( nodes.empty() ) { + for ( ++iE; iE < myEdge.size(); ++iE ) + if (( node = VertexNode( iE ))) { + u2node.insert( make_pair( prevNormPar, node )); + break; + } + --iE; } - u2node.insert( make_pair( 1., node )); + if ( !node ) + return myPoints; + vertexNodes.insert( node ); } - // put internal nodes - SMESHDS_SubMesh* sm = meshDS->MeshElements( myEdge[i] ); - if ( !sm ) continue; - SMDS_NodeIteratorPtr nItr = sm->GetNodes(); - double paramSize = myLast[i] - myFirst[i], r = myNormPar[i] - prevNormPar; - while ( nItr->more() ) { - const SMDS_MeshNode* node = nItr->next(); - if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge )) - continue; - const SMDS_EdgePosition* epos = - static_cast(node->GetPosition().get()); - double u = epos->GetUParameter(); - // paramSize is signed so orientation is taken into account - double normPar = prevNormPar + r * ( u - myFirst[i] ) / paramSize; -#ifdef _DEBUG_ - if ( normPar > 1 || normPar < 0) { - dump("DEBUG"); - MESSAGE ( "WRONG normPar: "<second; + else + { + node = VertexNode( iE ); + while ( !node && iE > 0 ) + node = VertexNode( --iE ); + if ( !node ) + return myPoints; } + if ( u2node.rbegin()->second == node ) + u2node.erase( --u2node.end() ); + u2node.insert( u2node.end(), make_pair( 1., node )); } - if ( u2node.size() != myNbPonits ) { + + if ( u2node.size() + nbProxyNodes != myNbPonits && + u2node.size() + nbProxyNodes != NbPoints( /*update=*/true )) + { 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 = me->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()="<IsSame( wireEdges.front() )) { + theError = TError + ( new SMESH_ComputeError(COMPERR_BAD_INPUT_MESH,"No nodes on vertices")); + return TSideVector(0); + } + } } - // find out side orientation, which is important if there are several wires (PAL19080) - bool isForward = true; - if ( nbWires > 1 ) { - TopExp_Explorer e( theFace, TopAbs_EDGE ); - while ( ! e.Current().IsSame( wireEdges.back() )) - e.Next(); - isForward = ( e.Current().Orientation() == wireEdges.back().Orientation() ); + else if ( *nbE > 1 ) // Issue 0020676 (Face_pb_netgen.brep) - several internal edges in a wire + { + internalEdges.splice( internalEdges.end(), wireEdges, ++wireEdges.begin(), wireEdges.end()); } StdMeshers_FaceSide* wire = new StdMeshers_FaceSide( theFace, wireEdges, &theMesh, - isForward, 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, + theProxyMesh ); + wires.push_back( StdMeshers_FaceSidePtr( wire )); + internalEdges.pop_back(); + } return wires; } +//================================================================================ +/*! + * \brief Return 1st vertex of the i-the edge + */ +//================================================================================ + +TopoDS_Vertex StdMeshers_FaceSide::FirstVertex(int i) const +{ + TopoDS_Vertex v; + if ( i < NbEdges() ) + { + v = myEdge[i].Orientation() <= TopAbs_REVERSED ? // FORWARD || REVERSED + TopExp::FirstVertex( myEdge[i], 1 ) : + TopoDS::Vertex( TopoDS_Iterator( myEdge[i] ).Value() ); + } + return v; +} + +//================================================================================ +/*! + * \brief Return last vertex of the i-the edge + */ +//================================================================================ + +TopoDS_Vertex StdMeshers_FaceSide::LastVertex(int i) const +{ + TopoDS_Vertex v; + if ( i < NbEdges() ) + { + const TopoDS_Edge& edge = i<0 ? myEdge[ NbEdges() + i ] : myEdge[i]; + if ( edge.Orientation() <= TopAbs_REVERSED ) // FORWARD || REVERSED + v = TopExp::LastVertex( edge, 1 ); + else + for ( TopoDS_Iterator vIt( edge ); vIt.More(); vIt.Next() ) + v = TopoDS::Vertex( vIt.Value() ); + } + return v; +} + +//================================================================================ +/*! + * \brief Return \c true if the chain of EDGEs is closed + */ +//================================================================================ + +bool StdMeshers_FaceSide::IsClosed() const +{ + return myEdge.empty() ? false : FirstVertex().IsSame( LastVertex() ); +}