From: eap Date: Tue, 7 Mar 2017 18:35:05 +0000 (+0300) Subject: IPAL54027: Projection algo is very long on a face with many edges X-Git-Tag: V8_3_0a2~5 X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=commitdiff_plain;h=55290963c776b86cb15aea30629389d503c1d3b9 IPAL54027: Projection algo is very long on a face with many edges --- diff --git a/src/SMESH/SMESH_MesherHelper.cxx b/src/SMESH/SMESH_MesherHelper.cxx index ce4e90cc4..e03128dc8 100644 --- a/src/SMESH/SMESH_MesherHelper.cxx +++ b/src/SMESH/SMESH_MesherHelper.cxx @@ -139,9 +139,9 @@ SMESHDS_Mesh* SMESH_MesherHelper::GetMeshDS() const //======================================================================= //function : IsQuadraticSubMesh -//purpose : Check submesh for given shape: if all elements on this shape +//purpose : Check sub-meshes of a given shape: if all elements on sub-shapes // are quadratic, quadratic elements will be created. -// Also fill myTLinkNodeMap +// Fill myTLinkNodeMap //======================================================================= bool SMESH_MesherHelper::IsQuadraticSubMesh(const TopoDS_Shape& aSh) @@ -149,7 +149,6 @@ bool SMESH_MesherHelper::IsQuadraticSubMesh(const TopoDS_Shape& aSh) SMESHDS_Mesh* meshDS = GetMeshDS(); // we can create quadratic elements only if all elements // created on sub-shapes of given shape are quadratic - // also we have to fill myTLinkNodeMap myCreateQuadratic = true; mySeamShapeIds.clear(); myDegenShapeIds.clear(); @@ -162,9 +161,6 @@ bool SMESH_MesherHelper::IsQuadraticSubMesh(const TopoDS_Shape& aSh) } SMDSAbs_ElementType elemType( subType==TopAbs_FACE ? SMDSAbs_Face : SMDSAbs_Edge ); - - //int nbOldLinks = myTLinkNodeMap.size(); - if ( !myMesh->HasShapeToMesh() ) { if (( myCreateQuadratic = myMesh->NbFaces( ORDER_QUADRATIC ))) @@ -373,6 +369,27 @@ void SMESH_MesherHelper::SetSubShape(const TopoDS_Shape& aSh) } } +//======================================================================= +/*! + * \brief Copy shape information from another helper. Used to improve performance + * since SetSubShape() can be time consuming if there are many edges + */ +//======================================================================= + +void SMESH_MesherHelper::CopySubShapeInfo(const SMESH_MesherHelper& other) +{ + this->myShape = other.myShape; + this->myShapeID = other.myShapeID; + this->myDegenShapeIds = other.myDegenShapeIds; + this->mySeamShapeIds = other.mySeamShapeIds; + this->myPar1[0] = other.myPar1[0]; + this->myPar1[1] = other.myPar1[1]; + this->myPar2[0] = other.myPar2[0]; + this->myPar2[1] = other.myPar2[1]; + this->myParIndex = other.myParIndex; + this->myFace2Surface = other.myFace2Surface; +} + //======================================================================= //function : ShapeToIndex //purpose : Convert a shape to its index in the SMESHDS_Mesh @@ -2825,8 +2842,9 @@ bool SMESH_MesherHelper::IsStructured( SMESH_subMesh* faceSM ) //purpose : Return true if 2D mesh on FACE is ditorted //======================================================================= -bool SMESH_MesherHelper::IsDistorted2D( SMESH_subMesh* faceSM, - bool checkUV) +bool SMESH_MesherHelper::IsDistorted2D( SMESH_subMesh* faceSM, + bool checkUV, + SMESH_MesherHelper* faceHelper) { if ( !faceSM || faceSM->GetSubShape().ShapeType() != TopAbs_FACE ) return false; @@ -2834,12 +2852,26 @@ bool SMESH_MesherHelper::IsDistorted2D( SMESH_subMesh* faceSM, bool haveBadFaces = false; SMESH_MesherHelper helper( *faceSM->GetFather() ); + if ( faceHelper ) + helper.CopySubShapeInfo( *faceHelper ); helper.SetSubShape( faceSM->GetSubShape() ); const TopoDS_Face& F = TopoDS::Face( faceSM->GetSubShape() ); SMESHDS_SubMesh* smDS = helper.GetMeshDS()->MeshElements( F ); if ( !smDS || smDS->NbElements() == 0 ) return false; + bool subIdsValid = true; // shape ID of nodes is OK + if ( helper.HasSeam() ) + { + // check if nodes are bound to seam edges + SMESH_subMeshIteratorPtr smIt = faceSM->getDependsOnIterator(/*includeSelf=*/false); + while ( smIt->more() && subIdsValid ) + { + SMESH_subMesh* sm = smIt->next(); + if ( helper.IsSeamShape( sm->GetId() ) && sm->IsEmpty() ) + subIdsValid = false; + } + } SMDS_ElemIteratorPtr faceIt = smDS->GetElements(); double prevArea = 0; vector< const SMDS_MeshNode* > nodes; @@ -2864,12 +2896,20 @@ bool SMESH_MesherHelper::IsDistorted2D( SMESH_subMesh* faceSM, if ( isOnDegen ) continue; } - // prepare to getting UVs + // prepare for getting UVs const SMDS_MeshNode* inFaceNode = 0; if ( helper.HasSeam() ) { for ( size_t i = 0; ( i < nodes.size() && !inFaceNode ); ++i ) if ( !helper.IsSeamShape( nodes[ i ]->getshapeId() )) + { inFaceNode = nodes[ i ]; + if ( !subIdsValid ) + { + gp_XY uv = helper.GetNodeUV( F, inFaceNode ); + if ( helper.IsOnSeam( uv )) + inFaceNode = NULL; + } + } if ( !inFaceNode ) continue; } @@ -2878,6 +2918,14 @@ bool SMESH_MesherHelper::IsDistorted2D( SMESH_subMesh* faceSM, for ( size_t i = 0; i < nodes.size(); ++i ) uv[ i ] = helper.GetNodeUV( F, nodes[ i ], inFaceNode, toCheckUV ); + if ( !subIdsValid ) // fix uv on seam + { + gp_XY uvInFace = helper.GetNodeUV( F, inFaceNode ); + for ( size_t i = 0; i < uv.size(); ++i ) + if ( helper.IsOnSeam( uv[i] )) + uv[i] = helper.getUVOnSeam( uv[i], uvInFace ).XY(); + } + // compare orientation of triangles double faceArea = 0; for ( int iT = 0, nbT = nodes.size()-2; iT < nbT; ++iT ) @@ -3087,7 +3135,7 @@ TopAbs_Orientation SMESH_MesherHelper::GetSubShapeOri(const TopoDS_Shape& shape, //======================================================================= //function : IsSubShape -//purpose : +//purpose : //======================================================================= bool SMESH_MesherHelper::IsSubShape( const TopoDS_Shape& shape, @@ -3395,6 +3443,25 @@ double SMESH_MesherHelper::GetOtherParam(const double param) const return fabs(param-myPar1[i]) < fabs(param-myPar2[i]) ? myPar2[i] : myPar1[i]; } +//======================================================================= +//function : IsOnSeam +//purpose : Check if UV is on seam. Return 0 if not, 1 for U seam, 2 for V seam +//======================================================================= + +int SMESH_MesherHelper::IsOnSeam(const gp_XY& uv) const +{ + for ( int i = U_periodic; i <= V_periodic ; ++i ) + if ( myParIndex & i ) + { + double p = uv.Coord( i ); + double tol = ( myPar2[i-1] - myPar1[i-1] ) / 100.; + if ( Abs( p - myPar1[i-1] ) < tol || + Abs( p - myPar2[i-1] ) < tol ) + return i; + } + return 0; +} + namespace { //======================================================================= diff --git a/src/SMESH/SMESH_MesherHelper.hxx b/src/SMESH/SMESH_MesherHelper.hxx index 7e60e6d25..cf3506fea 100644 --- a/src/SMESH/SMESH_MesherHelper.hxx +++ b/src/SMESH/SMESH_MesherHelper.hxx @@ -122,7 +122,9 @@ class SMESH_EXPORT SMESH_MesherHelper /*! * \brief Return true if 2D mesh on FACE is distored */ - static bool IsDistorted2D( SMESH_subMesh* faceSM, bool checkUV=false ); + static bool IsDistorted2D( SMESH_subMesh* faceSM, + bool checkUV = false, + SMESH_MesherHelper* faceHelper = NULL); /*! * \brief Returns true if given node is medium @@ -318,6 +320,12 @@ public: * \brief Return the shape set by IsQuadraticSubMesh() or SetSubShape() */ const TopoDS_Shape& GetSubShape() const { return myShape; } + /*! + * \brief Copy shape information from another helper to improve performance + * since SetSubShape() can be time consuming if there are many edges + */ + void CopySubShapeInfo(const SMESH_MesherHelper& other); + /*! * \brief Convert a shape to its index in the SMESHDS_Mesh @@ -611,6 +619,10 @@ public: * \brief Return an alternative parameter for a node on seam */ double GetOtherParam(const double param) const; + /*! + * \brief Check if UV is on seam. Return 0 if not, 1 for U seam, 2 for V seam + */ + int IsOnSeam(const gp_XY& uv) const; /*! * \brief Return existing or create new medium nodes between given ones @@ -693,6 +705,7 @@ public: static void WriteShape(const TopoDS_Shape& s); + protected: /*! @@ -709,6 +722,7 @@ public: double getFaceMaxTol( const TopoDS_Shape& face ) const; + private: // forbidden copy constructor diff --git a/src/StdMeshers/StdMeshers_FaceSide.cxx b/src/StdMeshers/StdMeshers_FaceSide.cxx index 3f1ce2d6b..9f5929e36 100644 --- a/src/StdMeshers/StdMeshers_FaceSide.cxx +++ b/src/StdMeshers/StdMeshers_FaceSide.cxx @@ -63,7 +63,7 @@ using namespace std; * \brief Constructor of a side of one edge * \param theFace - the face * \param theEdge - the edge - */ + */ //================================================================================ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace, @@ -71,11 +71,15 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace, SMESH_Mesh* theMesh, const bool theIsForward, const bool theIgnoreMediumNodes, + SMESH_MesherHelper* theFaceHelper, SMESH_ProxyMesh::Ptr theProxyMesh) { std::list edges(1,theEdge); - *this = StdMeshers_FaceSide( theFace, edges, theMesh, theIsForward, - theIgnoreMediumNodes, theProxyMesh ); + StdMeshers_FaceSide tmp( theFace, edges, theMesh, theIsForward, + theIgnoreMediumNodes, theFaceHelper, theProxyMesh ); + *this = tmp; + + tmp.myHelper = NULL; } //================================================================================ @@ -89,6 +93,7 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace, SMESH_Mesh* theMesh, const bool theIsForward, const bool theIgnoreMediumNodes, + SMESH_MesherHelper* theFaceHelper, SMESH_ProxyMesh::Ptr theProxyMesh) { int nbEdges = theEdges.size(); @@ -108,7 +113,13 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace, myMissingVertexNodes = false; myIgnoreMediumNodes = theIgnoreMediumNodes; myDefaultPnt2d = gp_Pnt2d( 1e+100, 1e+100 ); + myHelper = NULL; if ( !myProxyMesh ) myProxyMesh.reset( new SMESH_ProxyMesh( *theMesh )); + if ( theFaceHelper && theFaceHelper->GetSubShape() == myFace ) + { + myHelper = new SMESH_MesherHelper( * myProxyMesh->GetMesh() ); + myHelper->CopySubShapeInfo( *theFaceHelper ); + } if ( nbEdges == 0 ) return; SMESHDS_Mesh* meshDS = myProxyMesh->GetMeshDS(); @@ -203,6 +214,7 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const StdMeshers_FaceSide* theSide, myLast.push_back ( theULast ); myNormPar.push_back ( 1. ); myIsUniform.push_back( true ); + myHelper = NULL; myLength = 0; myProxyMesh = theSide->myProxyMesh; myDefaultPnt2d = *thePnt2d1; @@ -260,6 +272,7 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(UVPtStructVec& theSideNodes, } myFace = theFace; + myHelper = NULL; myPoints = theSideNodes; myNbPonits = myPoints.size(); myNbSegments = myNbPonits + 1; @@ -312,6 +325,17 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(UVPtStructVec& theSideNodes, myEdgeLength.resize( 1, myLength ); } +//================================================================================ +/*! + * \brief Destructor + */ +//================================================================================ + +StdMeshers_FaceSide::~StdMeshers_FaceSide() +{ + delete myHelper; myHelper = NULL; +} + //================================================================================ /* * Return info on nodes on the side @@ -326,12 +350,12 @@ const std::vector& StdMeshers_FaceSide::GetUVPtStruct(bool isXCons if ( NbEdges() == 0 ) return myPoints; StdMeshers_FaceSide* me = const_cast< StdMeshers_FaceSide* >( this ); - SMESH_MesherHelper eHelper( *myProxyMesh->GetMesh() ); - SMESH_MesherHelper fHelper( *myProxyMesh->GetMesh() ); - fHelper.SetSubShape( myFace ); bool paramOK = true; double eps = 1e-100; + SMESH_MesherHelper eHelper( *myProxyMesh->GetMesh() ); + SMESH_MesherHelper& fHelper = *FaceHelper(); + // sort nodes of all edges by putting them into a map map< double, const SMDS_MeshNode*> u2node; @@ -618,9 +642,8 @@ std::vector StdMeshers_FaceSide::GetOrderedNodes(int theEd if ( NbEdges() == 0 ) return resultNodes; //SMESHDS_Mesh* meshDS = myProxyMesh->GetMeshDS(); - SMESH_MesherHelper eHelper( *myProxyMesh->GetMesh() ); - SMESH_MesherHelper fHelper( *myProxyMesh->GetMesh() ); - fHelper.SetSubShape( myFace ); + SMESH_MesherHelper eHelper( *myProxyMesh->GetMesh() ); + SMESH_MesherHelper& fHelper = * FaceHelper(); bool paramOK = true; // Sort nodes of all edges putting them into a map @@ -1014,8 +1037,7 @@ int StdMeshers_FaceSide::NbPoints(const bool update) const } } - SMESH_MesherHelper helper( *myProxyMesh->GetMesh() ); - helper.SetSubShape( myFace ); + SMESH_MesherHelper* helper = FaceHelper(); std::set< const SMDS_MeshNode* > vNodes; const int nbV = NbEdges() + !IsClosed(); @@ -1023,8 +1045,8 @@ int StdMeshers_FaceSide::NbPoints(const bool update) const if ( const SMDS_MeshNode* n = VertexNode( i )) { if ( !vNodes.insert( n ).second && - ( helper.IsRealSeam ( n->getshapeId() ) || - helper.IsDegenShape( n->getshapeId() ))) + ( helper->IsRealSeam ( n->getshapeId() ) || + helper->IsDegenShape( n->getshapeId() ))) me->myNbPonits++; } else @@ -1241,9 +1263,14 @@ TSideVector StdMeshers_FaceSide::GetFaceWires(const TopoDS_Face& theFace, SMESH_Mesh & theMesh, const bool theIgnoreMediumNodes, TError & theError, + SMESH_MesherHelper* theFaceHelper, SMESH_ProxyMesh::Ptr theProxyMesh, const bool theCheckVertexNodes) { + SMESH_MesherHelper helper( theMesh ); + if ( theFaceHelper && theFaceHelper->GetSubShape() == theFace ) + helper.CopySubShapeInfo( *theFaceHelper ); + list< TopoDS_Edge > edges, internalEdges; list< int > nbEdgesInWires; int nbWires = SMESH_Block::GetOrderedEdges (theFace, edges, nbEdgesInWires); @@ -1287,7 +1314,7 @@ TSideVector StdMeshers_FaceSide::GetFaceWires(const TopoDS_Face& theFace, StdMeshers_FaceSide* wire = new StdMeshers_FaceSide( theFace, wireEdges, &theMesh, /*isForward=*/true, theIgnoreMediumNodes, - theProxyMesh ); + &helper, theProxyMesh ); wires[ iW ] = StdMeshers_FaceSidePtr( wire ); from = to; } @@ -1295,7 +1322,7 @@ TSideVector StdMeshers_FaceSide::GetFaceWires(const TopoDS_Face& theFace, { StdMeshers_FaceSide* wire = new StdMeshers_FaceSide( theFace, internalEdges.back(), &theMesh, /*isForward=*/true, theIgnoreMediumNodes, - theProxyMesh ); + &helper, theProxyMesh ); wires.push_back( StdMeshers_FaceSidePtr( wire )); internalEdges.pop_back(); } @@ -1351,3 +1378,20 @@ bool StdMeshers_FaceSide::IsClosed() const { return myEdge.empty() ? false : FirstVertex().IsSame( LastVertex() ); } + +//================================================================================ +/*! + * \brief Return a helper initialized with the FACE + */ +//================================================================================ + +SMESH_MesherHelper* StdMeshers_FaceSide::FaceHelper() const +{ + StdMeshers_FaceSide* me = const_cast< StdMeshers_FaceSide* >( this ); + if ( !myHelper && myProxyMesh ) + { + me->myHelper = new SMESH_MesherHelper( *myProxyMesh->GetMesh() ); + me->myHelper->SetSubShape( myFace ); + } + return me->myHelper; +} diff --git a/src/StdMeshers/StdMeshers_FaceSide.hxx b/src/StdMeshers/StdMeshers_FaceSide.hxx index 37e025f82..6759f50a9 100644 --- a/src/StdMeshers/StdMeshers_FaceSide.hxx +++ b/src/StdMeshers/StdMeshers_FaceSide.hxx @@ -43,13 +43,14 @@ #include #include -class SMDS_MeshNode; -class SMESH_Mesh; class Adaptor2d_Curve2d; class Adaptor3d_Curve; class BRepAdaptor_CompCurve; -struct SMESH_ComputeError; +class SMDS_MeshNode; +class SMESH_Mesh; +class SMESH_MesherHelper; class StdMeshers_FaceSide; +struct SMESH_ComputeError; typedef boost::shared_ptr< SMESH_ComputeError > TError; typedef boost::shared_ptr< StdMeshers_FaceSide > StdMeshers_FaceSidePtr; @@ -65,6 +66,9 @@ typedef std::vector< StdMeshers_FaceSidePtr > TSideVector; class STDMESHERS_EXPORT StdMeshers_FaceSide { public: + + enum { ALL_EDGES = -1, LAST_EDGE = -1 }; //!< constants + /*! * \brief Wrap one edge */ @@ -73,6 +77,7 @@ public: SMESH_Mesh* theMesh, const bool theIsForward, const bool theIgnoreMediumNodes, + SMESH_MesherHelper* theFaceHelper = NULL, SMESH_ProxyMesh::Ptr theProxyMesh = SMESH_ProxyMesh::Ptr()); /*! * \brief Wrap several edges. Edges must be properly ordered and oriented. @@ -82,6 +87,7 @@ public: SMESH_Mesh* theMesh, const bool theIsForward, const bool theIgnoreMediumNodes, + SMESH_MesherHelper* theFaceHelper = NULL, SMESH_ProxyMesh::Ptr theProxyMesh = SMESH_ProxyMesh::Ptr()); /*! * \brief Simulate a side from a vertex using data from other FaceSide @@ -89,10 +95,10 @@ public: StdMeshers_FaceSide(const StdMeshers_FaceSide* theSide, const SMDS_MeshNode* theNode, const gp_Pnt2d* thePnt2d1, - const gp_Pnt2d* thePnt2d2=NULL, - const Handle(Geom2d_Curve)& theC2d=NULL, - const double theUFirst=0., - const double theULast=1.); + const gp_Pnt2d* thePnt2d2 = NULL, + const Handle(Geom2d_Curve)& theC2d = NULL, + const double theUFirst = 0., + const double theULast = 1.); /*! * \brief Create a side from an UVPtStructVec */ @@ -101,32 +107,36 @@ public: const TopoDS_Edge& theEdge = TopoDS_Edge(), SMESH_Mesh* theMesh = 0); + ~StdMeshers_FaceSide(); + // static "consrtuctors" static StdMeshers_FaceSidePtr New(const TopoDS_Face& Face, const TopoDS_Edge& Edge, SMESH_Mesh* Mesh, const bool IsForward, const bool IgnoreMediumNodes, + SMESH_MesherHelper* FaceHelper = NULL, SMESH_ProxyMesh::Ptr ProxyMesh = SMESH_ProxyMesh::Ptr()) { return StdMeshers_FaceSidePtr - ( new StdMeshers_FaceSide( Face,Edge,Mesh,IsForward,IgnoreMediumNodes,ProxyMesh )); + ( new StdMeshers_FaceSide( Face,Edge,Mesh,IsForward,IgnoreMediumNodes,FaceHelper,ProxyMesh )); } static StdMeshers_FaceSidePtr New (const TopoDS_Face& Face, std::list& Edges, SMESH_Mesh* Mesh, const bool IsForward, const bool IgnoreMediumNodes, + SMESH_MesherHelper* FaceHelper = NULL, SMESH_ProxyMesh::Ptr ProxyMesh = SMESH_ProxyMesh::Ptr()) { return StdMeshers_FaceSidePtr - ( new StdMeshers_FaceSide( Face,Edges,Mesh,IsForward,IgnoreMediumNodes,ProxyMesh )); + ( new StdMeshers_FaceSide( Face,Edges,Mesh,IsForward,IgnoreMediumNodes,FaceHelper,ProxyMesh )); } static StdMeshers_FaceSidePtr New (const StdMeshers_FaceSide* Side, const SMDS_MeshNode* Node, const gp_Pnt2d* Pnt2d1, - const gp_Pnt2d* Pnt2d2=NULL, - const Handle(Geom2d_Curve)& C2d=NULL, - const double UFirst=0., - const double ULast=1.) + const gp_Pnt2d* Pnt2d2 = NULL, + const Handle(Geom2d_Curve)& C2d = NULL, + const double UFirst = 0., + const double ULast = 1.) { return StdMeshers_FaceSidePtr ( new StdMeshers_FaceSide( Side,Node,Pnt2d1,Pnt2d2,C2d,UFirst,ULast )); } @@ -143,8 +153,9 @@ public: SMESH_Mesh & theMesh, const bool theIgnoreMediumNodes, TError & theError, + SMESH_MesherHelper* theFaceHelper = NULL, SMESH_ProxyMesh::Ptr theProxyMesh = SMESH_ProxyMesh::Ptr(), - const bool theCheckVertexNodes=true); + const bool theCheckVertexNodes = true); /*! * \brief Change orientation of side geometry */ @@ -183,7 +194,7 @@ public: * Missing nodes are allowed only on internal vertices. * For a closed side, the 1st point repeats at end */ - const UVPtStructVec& GetUVPtStruct(bool isXConst =0, double constValue =0) const; + const UVPtStructVec& GetUVPtStruct( bool isXConst = 0, double constValue = 0 ) const; /*! * \brief Simulates detailed data on nodes * \param isXConst - true if normalized parameter X is constant @@ -194,10 +205,10 @@ public: double constValue = 0) const; /*! * \brief Return nodes in the order they encounter while walking along - * the while side or a specified EDGE. - * For a closed side, the 1st point repeats at end + * the while side or a specified EDGE. For a closed side, the 1st point repeats at end. + * \param iE - index of the EDGE. Default is "all EDGEs". */ - std::vector GetOrderedNodes(int iE=-1) const; + std::vector GetOrderedNodes( int iE = ALL_EDGES ) const; /*! * \brief Return nodes of the i-th EDGE. @@ -262,7 +273,7 @@ public: /*! * \brief Return last vertex of the i-th edge (count starts from zero) */ - TopoDS_Vertex LastVertex(int i=-1) const; + TopoDS_Vertex LastVertex(int i = LAST_EDGE) const; /*! * \brief Return \c true if the chain of EDGEs is closed */ @@ -276,8 +287,6 @@ public: */ inline int EdgeIndex( double U ) const; - //virtual gp_Pnt Value(double U) const; - void dump(const char* msg=0) const; /*! @@ -314,6 +323,10 @@ public: * \brief Return orientation of i-th wrapped edge (count starts from zero) */ inline bool IsReversed(int i) const; + /*! + * \brief Return a helper initialized with the FACE + */ + SMESH_MesherHelper* FaceHelper() const; protected: @@ -335,6 +348,7 @@ protected: SMESH_ProxyMesh::Ptr myProxyMesh; bool myMissingVertexNodes, myIgnoreMediumNodes; gp_Pnt2d myDefaultPnt2d; + SMESH_MesherHelper* myHelper; }; diff --git a/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx b/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx index de7de3b32..972d4b12c 100644 --- a/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx +++ b/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx @@ -203,7 +203,7 @@ bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh // get all edges of a face TError problem; TWireVector wires = - StdMeshers_FaceSide::GetFaceWires( F, aMesh, skipMediumNodes, problem, proxyMesh ); + StdMeshers_FaceSide::GetFaceWires( F, aMesh, skipMediumNodes, problem, _helper, proxyMesh ); int nbWires = wires.size(); if ( problem && !problem->IsOK() ) return error( problem ); if ( nbWires == 0 ) return error( "Problem in StdMeshers_FaceSide::GetFaceWires()"); diff --git a/src/StdMeshers/StdMeshers_PolygonPerFace_2D.cxx b/src/StdMeshers/StdMeshers_PolygonPerFace_2D.cxx index 5f3a21e8a..78c4d62e5 100644 --- a/src/StdMeshers/StdMeshers_PolygonPerFace_2D.cxx +++ b/src/StdMeshers/StdMeshers_PolygonPerFace_2D.cxx @@ -87,10 +87,10 @@ bool StdMeshers_PolygonPerFace_2D::Compute(SMESH_Mesh& theMesh, if ( !proxyMesh ) return false; - TError erorr; + TError err; TSideVector wires = StdMeshers_FaceSide::GetFaceWires(face, theMesh, /*skipMediumNodes=*/_quadraticMesh, - erorr, proxyMesh, + err, &helper, proxyMesh, /*checkVertexNodes=*/false); if ( wires.size() != 1 ) return error( COMPERR_BAD_SHAPE, SMESH_Comment("One wire required, not ") << wires.size() ); diff --git a/src/StdMeshers/StdMeshers_Prism_3D.cxx b/src/StdMeshers/StdMeshers_Prism_3D.cxx index 538cbdddf..a7dae0283 100644 --- a/src/StdMeshers/StdMeshers_Prism_3D.cxx +++ b/src/StdMeshers/StdMeshers_Prism_3D.cxx @@ -3258,9 +3258,11 @@ bool StdMeshers_Prism_3D::initPrism(Prism_3D::TPrismTopo& thePrism, "Non-quadrilateral faces are not opposite")); // check that the found top and bottom FACEs are opposite + TopTools_IndexedMapOfShape topEdgesMap( thePrism.myBottomEdges.size() ); + TopExp::MapShapes( thePrism.myTop, topEdgesMap ); list< TopoDS_Edge >::iterator edge = thePrism.myBottomEdges.begin(); for ( ; edge != thePrism.myBottomEdges.end(); ++edge ) - if ( myHelper->IsSubShape( *edge, thePrism.myTop )) + if ( topEdgesMap.Contains( *edge )) return toSM( error (notQuadGeomSubMesh.empty() ? COMPERR_BAD_INPUT_MESH : COMPERR_BAD_SHAPE, "Non-quadrilateral faces are not opposite")); diff --git a/src/StdMeshers/StdMeshers_Projection_1D2D.cxx b/src/StdMeshers/StdMeshers_Projection_1D2D.cxx index d0966d7b8..c0e53ceeb 100644 --- a/src/StdMeshers/StdMeshers_Projection_1D2D.cxx +++ b/src/StdMeshers/StdMeshers_Projection_1D2D.cxx @@ -160,8 +160,8 @@ bool StdMeshers_Projection_1D2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape } TopoDS_Face F = TopoDS::Face( theShape ); TError err; - TSideVector wires = StdMeshers_FaceSide::GetFaceWires( F, theMesh, - /*ignoreMediumNodes=*/false, err); + TSideVector wires = StdMeshers_FaceSide::GetFaceWires( F, theMesh, /*ignoreMediumNodes=*/false, + err, &helper); if ( err && !err->IsOK() ) return error( err ); diff --git a/src/StdMeshers/StdMeshers_Projection_2D.cxx b/src/StdMeshers/StdMeshers_Projection_2D.cxx index 9c1169199..eeb20f009 100644 --- a/src/StdMeshers/StdMeshers_Projection_2D.cxx +++ b/src/StdMeshers/StdMeshers_Projection_2D.cxx @@ -426,6 +426,7 @@ namespace { const TopoDS_Face& srcFace, SMESH_Mesh * tgtMesh, SMESH_Mesh * srcMesh, + SMESH_MesherHelper* tgtHelper, const TAssocTool::TShapeShapeMap& shape2ShapeMap, TSideVector& srcWires, TSideVector& tgtWires, @@ -436,7 +437,7 @@ namespace { // get ordered src EDGEs TError err; - srcWires = StdMeshers_FaceSide::GetFaceWires( srcFace, *srcMesh,/*skipMediumNodes=*/0, err); + srcWires = StdMeshers_FaceSide::GetFaceWires( srcFace, *srcMesh,/*skipMediumNodes=*/0, err ); if (( err && !err->IsOK() ) || ( srcWires.empty() )) return err; @@ -445,8 +446,6 @@ namespace { << tgtMesh->GetMeshDS()->ShapeToIndex( tgtFace ) << " <- " << srcMesh->GetMeshDS()->ShapeToIndex( srcFace ) << endl; #endif - SMESH_MesherHelper srcHelper( *srcMesh ); - srcHelper.SetSubShape( srcFace ); // make corresponding sequence of tgt EDGEs tgtWires.resize( srcWires.size() ); @@ -493,7 +492,8 @@ namespace { tgtWires[ iW ].reset( new StdMeshers_FaceSide( tgtFace, tgtEdges, tgtMesh, /*theIsForward = */ true, - /*theIgnoreMediumNodes = */false)); + /*theIgnoreMediumNodes = */false, + tgtHelper )); StdMeshers_FaceSidePtr tgtWire = tgtWires[ iW ]; // Fill map of src to tgt nodes with nodes on edges @@ -517,9 +517,11 @@ namespace { else { const bool skipMedium = true, isFwd = true; - StdMeshers_FaceSide srcEdge( srcFace, srcWire->Edge(iE), srcMesh, isFwd, skipMedium); - StdMeshers_FaceSide tgtEdge( tgtFace, tgtWire->Edge(iE), tgtMesh, isFwd, skipMedium); - + StdMeshers_FaceSide srcEdge( srcFace, srcWire->Edge(iE), + srcMesh, isFwd, skipMedium, srcWires[0]->FaceHelper() ); + StdMeshers_FaceSide tgtEdge( tgtFace, tgtWire->Edge(iE), + tgtMesh, isFwd, skipMedium, tgtHelper); + vector< const SMDS_MeshNode* > srcNodes = srcEdge.GetOrderedNodes(); vector< const SMDS_MeshNode* > tgtNodes = tgtEdge.GetOrderedNodes(); @@ -566,11 +568,11 @@ namespace { TAssocTool::TNodeNodeMap& src2tgtNodes, const bool is1DComputed) { - SMESH_Mesh * tgtMesh = tgtWires[0]->GetMesh(); - SMESH_Mesh * srcMesh = srcWires[0]->GetMesh(); - SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS(); - SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS(); - SMESH_MesherHelper helper( *tgtMesh ); + SMESH_Mesh * tgtMesh = tgtWires[0]->GetMesh(); + SMESH_Mesh * srcMesh = srcWires[0]->GetMesh(); + SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS(); + SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS(); + SMESH_MesherHelper* helper = tgtWires[0]->FaceHelper(); const double tol = 1.e-7 * srcMeshDS->getMaxDim(); @@ -647,7 +649,7 @@ namespace { 0.123 * ( srcSurf.FirstVParameter() + srcSurf.LastVParameter() )); gp_Pnt tgtTrsfP = trsf.Transform( srcP ); TopLoc_Location loc; - GeomAPI_ProjectPointOnSurf& proj = helper.GetProjector( tgtFace, loc, 0.1*tol ); + GeomAPI_ProjectPointOnSurf& proj = helper->GetProjector( tgtFace, loc, 0.1*tol ); if ( !loc.IsIdentity() ) tgtTrsfP.Transform( loc.Transformation().Inverted() ); proj.Perform( tgtTrsfP ); @@ -662,16 +664,14 @@ namespace { // Make new faces // prepare the helper to adding quadratic elements if necessary - //helper.SetSubShape( tgtFace ); - helper.IsQuadraticSubMesh( tgtFace ); + helper->IsQuadraticSubMesh( tgtFace ); SMESHDS_SubMesh* srcSubDS = srcMeshDS->MeshElements( srcFace ); if ( !is1DComputed && srcSubDS->NbElements() ) - helper.SetIsQuadratic( srcSubDS->GetElements()->next()->IsQuadratic() ); + helper->SetIsQuadratic( srcSubDS->GetElements()->next()->IsQuadratic() ); - SMESH_MesherHelper srcHelper( *srcMesh ); - srcHelper.SetSubShape( srcFace ); - SMESH_MesherHelper edgeHelper( *tgtMesh ); + SMESH_MesherHelper* srcHelper = srcWires[0]->FaceHelper(); + SMESH_MesherHelper edgeHelper( *tgtMesh ); edgeHelper.ToFixNodeParameters( true ); const SMDS_MeshNode* nullNode = 0; @@ -690,7 +690,7 @@ namespace { const SMDS_MeshElement* elem = elemIt->next(); const int nbN = elem->NbCornerNodes(); tgtNodes.resize( nbN ); - helper.SetElementsOnShape( false ); + helper->SetElementsOnShape( false ); for ( int i = 0; i < nbN; ++i ) // loop on nodes of the source element { const SMDS_MeshNode* srcNode = elem->GetNode(i); @@ -699,21 +699,21 @@ namespace { { // create a new node gp_Pnt tgtP = trsf.Transform( SMESH_TNodeXYZ( srcNode )); - SMDS_MeshNode* n = helper.AddNode( tgtP.X(), tgtP.Y(), tgtP.Z() ); + SMDS_MeshNode* n = helper->AddNode( tgtP.X(), tgtP.Y(), tgtP.Z() ); srcN_tgtN->second = n; switch ( srcNode->GetPosition()->GetTypeOfPosition() ) { case SMDS_TOP_FACE: { - gp_Pnt2d srcUV = srcHelper.GetNodeUV( srcFace, srcNode ); - tgtMeshDS->SetNodeOnFace( n, helper.GetSubShapeID(), srcUV.X(), srcUV.Y() ); + gp_Pnt2d srcUV = srcHelper->GetNodeUV( srcFace, srcNode ); + tgtMeshDS->SetNodeOnFace( n, helper->GetSubShapeID(), srcUV.X(), srcUV.Y() ); break; } case SMDS_TOP_EDGE: { const TopoDS_Edge& srcE = TopoDS::Edge( srcMeshDS->IndexToShape( srcNode->getshapeId())); const TopoDS_Edge& tgtE = TopoDS::Edge( shape2ShapeMap( srcE, /*isSrc=*/true )); - double srcU = srcHelper.GetNodeU( srcE, srcNode ); + double srcU = srcHelper->GetNodeU( srcE, srcNode ); tgtMeshDS->SetNodeOnEdge( n, tgtE, srcU ); if ( !tgtFace.IsPartner( srcFace )) { @@ -749,14 +749,14 @@ namespace { tgtNodes[i] = srcN_tgtN->second; } // create a new face - helper.SetElementsOnShape( true ); + helper->SetElementsOnShape( true ); switch ( nbN ) { - case 3: helper.AddFace(tgtNodes[0], tgtNodes[tri1], tgtNodes[tri2]); break; - case 4: helper.AddFace(tgtNodes[0], tgtNodes[quad1], tgtNodes[2], tgtNodes[quad3]); break; + case 3: helper->AddFace(tgtNodes[0], tgtNodes[tri1], tgtNodes[tri2]); break; + case 4: helper->AddFace(tgtNodes[0], tgtNodes[quad1], tgtNodes[2], tgtNodes[quad3]); break; default: if ( isReverse ) std::reverse( tgtNodes.begin(), tgtNodes.end() ); - helper.AddPolygonalFace( tgtNodes ); + helper->AddPolygonalFace( tgtNodes ); } } @@ -764,7 +764,7 @@ namespace { if ( !tgtFace.IsPartner( srcFace ) ) { - helper.ToFixNodeParameters( true ); + helper->ToFixNodeParameters( true ); int nbOkPos = 0; const double tol2d = 1e-12; @@ -777,8 +777,8 @@ namespace { case SMDS_TOP_FACE: { if ( nbOkPos > 10 ) break; - gp_XY uv = helper.GetNodeUV( tgtFace, n ), uvBis = uv; - if (( helper.CheckNodeUV( tgtFace, n, uv, tol )) && + gp_XY uv = helper->GetNodeUV( tgtFace, n ), uvBis = uv; + if (( helper->CheckNodeUV( tgtFace, n, uv, tol )) && (( uv - uvBis ).SquareModulus() < tol2d )) ++nbOkPos; else @@ -898,18 +898,16 @@ namespace { SMESHDS_SubMesh* srcSubDS = srcMesh->GetMeshDS()->MeshElements( srcFace ); - SMESH_MesherHelper helper( *tgtMesh ); - helper.SetSubShape( tgtFace ); + SMESH_MesherHelper* helper = tgtWires[0]->FaceHelper(); if ( is1DComputed ) - helper.IsQuadraticSubMesh( tgtFace ); + helper->IsQuadraticSubMesh( tgtFace ); else - helper.SetIsQuadratic( srcSubDS->GetElements()->next()->IsQuadratic() ); - helper.SetElementsOnShape( true ); + helper->SetIsQuadratic( srcSubDS->GetElements()->next()->IsQuadratic() ); + helper->SetElementsOnShape( true ); Handle(Geom_Surface) tgtSurface = BRep_Tool::Surface( tgtFace ); SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS(); - SMESH_MesherHelper srcHelper( *srcMesh ); - srcHelper.SetSubShape( srcFace ); + SMESH_MesherHelper* srcHelper = srcWires[0]->FaceHelper(); const SMDS_MeshNode* nullNode = 0; TAssocTool::TNodeNodeMap::iterator srcN_tgtN; @@ -920,7 +918,7 @@ namespace { while ( elemIt->more() ) // loop on all mesh faces on srcFace { const SMDS_MeshElement* elem = elemIt->next(); - const int nbN = elem->NbCornerNodes(); + const int nbN = elem->NbCornerNodes(); tgtNodes.resize( nbN ); for ( int i = 0; i < nbN; ++i ) // loop on nodes of the source element { @@ -929,27 +927,27 @@ namespace { if ( srcN_tgtN->second == nullNode ) { // create a new node - gp_Pnt2d srcUV = srcHelper.GetNodeUV( srcFace, srcNode, - elem->GetNode( helper.WrapIndex(i+1,nbN)), &uvOK); + gp_Pnt2d srcUV = srcHelper->GetNodeUV( srcFace, srcNode, + elem->GetNode( helper->WrapIndex(i+1,nbN)), &uvOK); gp_Pnt2d tgtUV = trsf.Transform( srcUV ); gp_Pnt tgtP = tgtSurface->Value( tgtUV.X(), tgtUV.Y() ); SMDS_MeshNode* n = tgtMeshDS->AddNode( tgtP.X(), tgtP.Y(), tgtP.Z() ); switch ( srcNode->GetPosition()->GetTypeOfPosition() ) { case SMDS_TOP_FACE: { - tgtMeshDS->SetNodeOnFace( n, helper.GetSubShapeID(), tgtUV.X(), tgtUV.Y() ); + tgtMeshDS->SetNodeOnFace( n, helper->GetSubShapeID(), tgtUV.X(), tgtUV.Y() ); break; } case SMDS_TOP_EDGE: { - TopoDS_Shape srcEdge = srcHelper.GetSubShapeByNode( srcNode, srcHelper.GetMeshDS() ); + TopoDS_Shape srcEdge = srcHelper->GetSubShapeByNode( srcNode, srcHelper->GetMeshDS() ); TopoDS_Edge tgtEdge = TopoDS::Edge( shape2ShapeMap( srcEdge, /*isSrc=*/true )); double U = Precision::Infinite(); - helper.CheckNodeU( tgtEdge, n, U, Precision::PConfusion()); + helper->CheckNodeU( tgtEdge, n, U, Precision::PConfusion()); tgtMeshDS->SetNodeOnEdge( n, TopoDS::Edge( tgtEdge ), U ); break; } case SMDS_TOP_VERTEX: { - TopoDS_Shape srcV = srcHelper.GetSubShapeByNode( srcNode, srcHelper.GetMeshDS() ); + TopoDS_Shape srcV = srcHelper->GetSubShapeByNode( srcNode, srcHelper->GetMeshDS() ); TopoDS_Shape tgtV = shape2ShapeMap( srcV, /*isSrc=*/true ); tgtMeshDS->SetNodeOnVertex( n, TopoDS::Vertex( tgtV )); break; @@ -963,8 +961,8 @@ namespace { // create a new face (with reversed orientation) switch ( nbN ) { - case 3: helper.AddFace(tgtNodes[0], tgtNodes[2], tgtNodes[1]); break; - case 4: helper.AddFace(tgtNodes[0], tgtNodes[3], tgtNodes[2], tgtNodes[1]); break; + case 3: helper->AddFace(tgtNodes[0], tgtNodes[2], tgtNodes[1]); break; + case 4: helper->AddFace(tgtNodes[0], tgtNodes[3], tgtNodes[2], tgtNodes[1]); break; } } // loop on all mesh faces on srcFace @@ -1082,8 +1080,7 @@ namespace { // // as all XY are computed, create tgt nodes and faces - // SMESH_MesherHelper helper( *tgtMesh ); - // helper.SetSubShape( tgtFace ); + // SMESH_MesherHelper helper = *tgtWires[0]->FaceHelper(); // if ( is1DComputed ) // helper.IsQuadraticSubMesh( tgtFace ); // else @@ -1091,8 +1088,7 @@ namespace { // helper.SetElementsOnShape( true ); // Handle(Geom_Surface) tgtSurface = BRep_Tool::Surface( tgtFace ); - // SMESH_MesherHelper srcHelper( *srcMesh ); - // srcHelper.SetSubShape( srcFace ); + // SMESH_MesherHelper srcHelper = *srcWires[0]->FaceHelper(); // vector< const SMDS_MeshNode* > tgtNodes; // gp_XY uv; @@ -1541,7 +1537,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& // get ordered src and tgt EDGEs TSideVector srcWires, tgtWires; bool is1DComputed = false; // if any tgt EDGE is meshed - TError err = getWires( tgtFace, srcFace, tgtMesh, srcMesh, + TError err = getWires( tgtFace, srcFace, tgtMesh, srcMesh, &helper, shape2ShapeMap, srcWires, tgtWires, _src2tgtNodes, is1DComputed ); if ( err && !err->IsOK() ) return error( err ); @@ -1935,7 +1931,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& // boundary, also bad face can be created if EDGEs already discretized // --> fix bad faces by smoothing // ---------------------------------------------------------------- - if ( helper.IsDistorted2D( tgtSubMesh, /*checkUV=*/false )) + if ( helper.IsDistorted2D( tgtSubMesh, /*checkUV=*/false, &helper )) { morph( helper, tgtFace, srcFace, tgtWires, srcWires, _src2tgtNodes ); diff --git a/src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.cxx b/src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.cxx index c7df8a3f7..a4d3ffbdd 100644 --- a/src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.cxx +++ b/src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.cxx @@ -1384,10 +1384,13 @@ namespace const SMESH_MAT2d::MedialAxis& theMA, TMAPar2NPoints & thePointsOnE ) { + SMESH_Mesh* mesh = theHelper.GetMesh(); + SMESHDS_Mesh* meshDS = theHelper.GetMeshDS(); + list< TopoDS_Edge > ee1( theSinuFace._sinuSide [0].begin(), theSinuFace._sinuSide [0].end() ); list< TopoDS_Edge > ee2( theSinuFace._sinuSide [1].begin(), theSinuFace._sinuSide [1].end() ); - StdMeshers_FaceSide sideOut( theSinuFace.Face(), ee1, theHelper.GetMesh(), true, true ); - StdMeshers_FaceSide sideIn ( theSinuFace.Face(), ee2, theHelper.GetMesh(), true, true ); + StdMeshers_FaceSide sideOut( theSinuFace.Face(), ee1, mesh, true, true, &theHelper ); + StdMeshers_FaceSide sideIn ( theSinuFace.Face(), ee2, mesh, true, true, &theHelper ); const UVPtStructVec& uvsOut = sideOut.GetUVPtStruct(); const UVPtStructVec& uvsIn = sideIn.GetUVPtStruct(); // if ( uvs1.size() != uvs2.size() ) @@ -1396,7 +1399,6 @@ namespace const SMESH_MAT2d::Branch& branch = *theMA.getBranch(0); SMESH_MAT2d::BoundaryPoint bp[2]; SMESH_MAT2d::BranchPoint brp; - SMESHDS_Mesh* meshDS = theHelper.GetMeshDS(); map< double, const SMDS_MeshNode* > nodeParams; // params of existing nodes map< double, const SMDS_MeshNode* >::iterator u2n; @@ -1510,7 +1512,8 @@ namespace for ( int i = 0; i < 4; ++i ) { theFace._quad->side[i] = StdMeshers_FaceSide::New( face, side[i], mesh, i < QUAD_TOP_SIDE, - /*skipMediumNodes=*/true, proxyMesh ); + /*skipMediumNodes=*/true, + &theHelper, proxyMesh ); } if ( theFace.IsRing() ) @@ -1892,7 +1895,7 @@ namespace continue; StdMeshers_FaceSide side( face, theSinuEdges[i], mesh, - /*isFwd=*/true, /*skipMediumNodes=*/true ); + /*isFwd=*/true, /*skipMediumNodes=*/true, &theHelper ); vector nodes = side.GetOrderedNodes(); for ( size_t in = 1; in < nodes.size(); ++in ) { diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx index 8f909f214..ef472e49a 100644 --- a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx @@ -230,7 +230,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, myNeedSmooth = false; myCheckOri = false; - FaceQuadStruct::Ptr quad = CheckNbEdges( aMesh, F, /*considerMesh=*/true ); + FaceQuadStruct::Ptr quad = CheckNbEdges( aMesh, F, /*considerMesh=*/true, myHelper ); if (!quad) return false; myQuadList.clear(); @@ -1052,7 +1052,8 @@ static bool twoEdgesMeatAtVertex(const TopoDS_Edge& e1, FaceQuadStruct::Ptr StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, - const bool considerMesh) + const bool considerMesh, + SMESH_MesherHelper* aFaceHelper) { if ( !myQuadList.empty() && myQuadList.front()->face.IsSame( aShape )) return myQuadList.front(); @@ -1071,6 +1072,7 @@ FaceQuadStruct::Ptr StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & } // find corner vertices of the quad + myHelper = ( aFaceHelper && aFaceHelper->GetSubShape() == aShape ) ? aFaceHelper : NULL; vector corners; int nbDegenEdges, nbSides = getCorners( F, aMesh, edges, corners, nbDegenEdges, considerMesh ); if ( nbSides == 0 ) @@ -1096,7 +1098,7 @@ FaceQuadStruct::Ptr StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & sideEdges.push_back( *edgeIt++ ); if ( !sideEdges.empty() ) quad->side.push_back( StdMeshers_FaceSide::New(F, sideEdges, &aMesh, iSide < QUAD_TOP_SIDE, - ignoreMediumNodes, myProxyMesh)); + ignoreMediumNodes, myHelper, myProxyMesh)); else --iSide; } @@ -1150,7 +1152,7 @@ FaceQuadStruct::Ptr StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & { quad->side.push_back ( StdMeshers_FaceSide::New( F, sideEdges, &aMesh, iSide < QUAD_TOP_SIDE, - ignoreMediumNodes, myProxyMesh )); + ignoreMediumNodes, myHelper, myProxyMesh )); ++iSide; } if ( quad->side.size() == 4 ) @@ -4110,7 +4112,7 @@ bool StdMeshers_Quadrangle_2D::check() { TError err; TSideVector wireVec = - StdMeshers_FaceSide::GetFaceWires( geomFace, *myHelper->GetMesh(), true, err ); + StdMeshers_FaceSide::GetFaceWires( geomFace, *myHelper->GetMesh(), true, err, myHelper ); StdMeshers_FaceSidePtr wire = wireVec[0]; // find a right angle VERTEX @@ -4251,7 +4253,10 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face& theFace, theNbDegenEdges = 0; SMESH_MesherHelper helper( theMesh ); - StdMeshers_FaceSide faceSide( theFace, theWire, &theMesh, /*isFwd=*/true, /*skipMedium=*/true); + if ( myHelper ) + helper.CopySubShapeInfo( *myHelper ); + StdMeshers_FaceSide faceSide( theFace, theWire, &theMesh, + /*isFwd=*/true, /*skipMedium=*/true, &helper ); // sort theVertices by angle multimap vertexByAngle; diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx index fd40f12d2..a1938bde9 100644 --- a/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx @@ -155,7 +155,8 @@ class STDMESHERS_EXPORT StdMeshers_Quadrangle_2D: public SMESH_2D_Algo FaceQuadStruct::Ptr CheckNbEdges(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, - const bool considerMesh=false); + const bool considerMesh = false, + SMESH_MesherHelper* aFaceHelper = 0); static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll); diff --git a/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx b/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx index ec3c297fc..dc573828e 100644 --- a/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx +++ b/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx @@ -208,7 +208,8 @@ namespace SMESH_Mesh* aMesh, StdMeshers_FaceSidePtr& aCircSide, StdMeshers_FaceSidePtr& aLinSide1, - StdMeshers_FaceSidePtr& aLinSide2) + StdMeshers_FaceSidePtr& aLinSide2, + SMESH_MesherHelper* helper) { const TopoDS_Face& face = TopoDS::Face( aShape ); aCircSide.reset(); aLinSide1.reset(); aLinSide2.reset(); @@ -259,7 +260,7 @@ namespace StdMeshers_FaceSidePtr side; if ( aMesh ) side = StdMeshers_FaceSide::New( face, sideEdges, aMesh, - /*isFwd=*/true, /*skipMedium=*/ true ); + /*isFwd=*/true, /*skipMedium=*/ true, helper ); sides.push_back( side ); } @@ -357,7 +358,7 @@ namespace edges.push_back( aCircSide->Edge( iE % aCircSide->NbEdges() )); aCircSide = StdMeshers_FaceSide::New( face, edges, aMesh, - /*isFwd=*/true, /*skipMedium=*/ true ); + /*isFwd=*/true, /*skipMedium=*/ true, helper ); } } @@ -773,8 +774,11 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh, StdMeshers_Quadrangle_2D::myCheckOri = false; StdMeshers_Quadrangle_2D::myQuadList.clear(); + myHelper->SetSubShape( aShape ); + myHelper->SetElementsOnShape( true ); + StdMeshers_FaceSidePtr circSide, linSide1, linSide2; - int nbSides = analyseFace( aShape, &aMesh, circSide, linSide1, linSide2 ); + int nbSides = analyseFace( aShape, &aMesh, circSide, linSide1, linSide2, myHelper ); if( nbSides > 3 || nbSides < 1 ) return error("The face must be a full ellipse or a part of ellipse (i.e. the number " "of edges is less or equal to 3 and one of them is an ellipse curve)"); @@ -797,7 +801,6 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh, Handle(Geom_Surface) S = BRep_Tool::Surface(F); myHelper->IsQuadraticSubMesh( aShape ); - myHelper->SetElementsOnShape( true ); vector< double > layerPositions; // [0,1] @@ -811,7 +814,7 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh, TopoDS_Edge linEdge = makeEdgeToCenter( circSide, F, circNode ); StdMeshers_FaceSidePtr tmpSide = - StdMeshers_FaceSide::New( F, linEdge, &aMesh, /*isFrw=*/true, /*skipMedium=*/true ); + StdMeshers_FaceSide::New( F, linEdge, &aMesh, /*isFrw=*/true, /*skipMedium=*/true, myHelper ); if ( !computeLayerPositions( tmpSide, layerPositions )) return false; @@ -855,7 +858,7 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh, isVIn0Shared = vIn0.IsSame( circSide->FirstVertex( iE )); linSide1 = StdMeshers_FaceSide::New( F, edges, &aMesh, - /*isFrw=*/isVIn0Shared, /*skipMedium=*/true ); + /*isFrw=*/isVIn0Shared, /*skipMedium=*/true, myHelper ); int nbMeshedEdges; if ( !computeLayerPositions( linSide1, layerPositions, &nbMeshedEdges )) @@ -1105,7 +1108,7 @@ bool StdMeshers_RadialQuadrangle_1D2D::Evaluate(SMESH_Mesh& aMesh, TNodeDistributor* algo1d = TNodeDistributor::GetDistributor(aMesh); StdMeshers_FaceSidePtr circSide, linSide1, linSide2; - int nbSides = analyseFace( aShape, &aMesh, circSide, linSide1, linSide2 ); + int nbSides = analyseFace( aShape, &aMesh, circSide, linSide1, linSide2, myHelper ); if( nbSides > 3 || nbSides < 1 ) return false; @@ -1123,7 +1126,7 @@ bool StdMeshers_RadialQuadrangle_1D2D::Evaluate(SMESH_Mesh& aMesh, TopoDS_Edge linEdge = makeEdgeToCenter( circSide, F, circNode ); StdMeshers_FaceSidePtr tmpSide = - StdMeshers_FaceSide::New( F, linEdge, &aMesh, /*isFrw=*/true, /*skipMedium=*/true ); + StdMeshers_FaceSide::New( F, linEdge, &aMesh, /*isFrw=*/true, /*skipMedium=*/true, myHelper ); if ( !computeLayerPositions( tmpSide, layerPositions )) return false; @@ -1220,7 +1223,7 @@ bool StdMeshers_RadialQuadrangle_1D2D::IsApplicable( const TopoDS_Shape & aShape for (TopExp_Explorer exp( aShape, TopAbs_FACE ); exp.More(); exp.Next(), ++nbFoundFaces ) { StdMeshers_FaceSidePtr circSide, linSide1, linSide2; - int nbSides = analyseFace( exp.Current(), NULL, circSide, linSide1, linSide2 ); + int nbSides = analyseFace( exp.Current(), NULL, circSide, linSide1, linSide2, NULL ); bool ok = ( 0 < nbSides && nbSides <= 3 && isCornerInsideCircle( circSide, linSide1, linSide2 )); if( toCheckAll && !ok ) return false; diff --git a/src/StdMeshers/StdMeshers_ViscousLayers2D.cxx b/src/StdMeshers/StdMeshers_ViscousLayers2D.cxx index af66439b6..ecd62abc2 100644 --- a/src/StdMeshers/StdMeshers_ViscousLayers2D.cxx +++ b/src/StdMeshers/StdMeshers_ViscousLayers2D.cxx @@ -585,7 +585,7 @@ StdMeshers_ViscousLayers2D::CheckHypothesis(SMESH_Mesh& VISCOUS_2D::_ViscousBuilder2D builder( theMesh, face, hyps, hypShapes ); builder._faceSideVec = StdMeshers_FaceSide::GetFaceWires( face, theMesh, true, error, - SMESH_ProxyMesh::Ptr(), + NULL, SMESH_ProxyMesh::Ptr(), /*theCheckVertexNodes=*/false); if ( error->IsOK() && !builder.findEdgesWithLayers()) { @@ -686,7 +686,7 @@ bool _ViscousBuilder2D::error(const string& text ) SMESH_ProxyMesh::Ptr _ViscousBuilder2D::Compute() { - _faceSideVec = StdMeshers_FaceSide::GetFaceWires( _face, *_mesh, true, _error); + _faceSideVec = StdMeshers_FaceSide::GetFaceWires( _face, *_mesh, true, _error, &_helper ); if ( !_error->IsOK() ) return _proxyMesh;