X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_ProjectionUtils.cxx;h=c6347d53a7b0087e6c3a936540e62676bcdd0731;hb=e182c4b35455fd7e29ce02717480529a557ea27a;hp=50365eb7f79a19d885ae32995a24641061ec7286;hpb=c9d6ead3f53eee7910e100e6037ca30bc900e0fe;p=modules%2Fsmesh.git diff --git a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx index 50365eb7f..c6347d53a 100644 --- a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx +++ b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2011 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 : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_ProjectionUtils.cxx // Created : Fri Oct 27 10:24:28 2006 @@ -34,7 +35,6 @@ #include "SMESH_Block.hxx" #include "SMESH_Gen.hxx" #include "SMESH_Hypothesis.hxx" -#include "SMESH_IndexedDataMapOfShapeIndexedMapOfShape.hxx" #include "SMESH_Mesh.hxx" #include "SMESH_MesherHelper.hxx" #include "SMESH_subMesh.hxx" @@ -43,6 +43,7 @@ #include "utilities.h" +#include #include #include #include @@ -52,6 +53,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -60,22 +64,22 @@ #include #include #include -#include -#include + +#include using namespace std; #define RETURN_BAD_RESULT(msg) { MESSAGE(")-: Error: " << msg); return false; } #define CONT_BAD_RESULT(msg) { MESSAGE(")-: Error: " << msg); continue; } -#define SHOW_VERTEX(v,msg) \ +#define SHOW_SHAPE(v,msg) \ // { \ // if ( (v).IsNull() ) cout << msg << " NULL SHAPE" << endl; \ // else if ((v).ShapeType() == TopAbs_VERTEX) {\ // gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( (v) ));\ -// cout<()<<" ( "<()<ShapeToIndex(S), theMeshDS[1]->ShapeToIndex(S) ); + return long(S.TShape().operator->()); + } + //================================================================================ /*! * \brief Write shape for debug purposes @@ -115,31 +127,24 @@ namespace { */ //================================================================================ - void Reverse( list< TopoDS_Edge > & edges, const int nbEdges ) + void Reverse( list< TopoDS_Edge > & edges, const int nbEdges, const int firstEdge=0) { SHOW_LIST("BEFORE REVERSE", edges); list< TopoDS_Edge >::iterator eIt = edges.begin(); - if ( edges.size() == nbEdges ) - { - edges.reverse(); - } - else // reverse only the given nb of edges + std::advance( eIt, firstEdge ); + list< TopoDS_Edge >::iterator eBackIt = eIt; + for ( int i = 0; i < nbEdges; ++i, ++eBackIt ) + eBackIt->Reverse(); // reverse edge + // reverse list + --eBackIt; + while ( eIt != eBackIt ) { - // look for the last edge to be reversed - list< TopoDS_Edge >::iterator eBackIt = edges.begin(); - for ( int i = 1; i < nbEdges; ++i ) - ++eBackIt; - // reverse - while ( eIt != eBackIt ) { - std::swap( *eIt, *eBackIt ); - SHOW_LIST("# AFTER SWAP", edges) + std::swap( *eIt, *eBackIt ); + SHOW_LIST("# AFTER SWAP", edges) if ( (++eIt) != eBackIt ) --eBackIt; - } } - for ( eIt = edges.begin(); eIt != edges.end(); ++eIt ) - eIt->Reverse(); SHOW_LIST("ATFER REVERSE", edges) } @@ -350,6 +355,26 @@ namespace { return true; } + //================================================================================ + /*! + * \brief Return true if uv position of the vIndex-th vertex of edge on face is close + * enough to given uv + */ + //================================================================================ + + bool sameVertexUV( const TopoDS_Edge& edge, + const TopoDS_Face& face, + const int& vIndex, + const gp_Pnt2d& uv, + const double& tol2d ) + { + TopoDS_Vertex VV[2]; + TopExp::Vertices( edge, VV[0], VV[1], true); + gp_Pnt2d v1UV = BRep_Tool::Parameters( VV[vIndex], face); + double dist2d = v1UV.Distance( uv ); + return dist2d < tol2d; + } + } // namespace //======================================================================= @@ -380,7 +405,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the // case TopAbs_EDGE: // case ...: // } - // else try to accosiate in different ways: + // 4) else try to accosiate in different ways: // a) accosiate shapes by propagation and other simple cases // switch ( ShapeType ) { // case TopAbs_EDGE: @@ -389,8 +414,11 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the // b) find association of a couple of vertices and recall self. // + theMeshDS[0] = theMesh1->GetMeshDS(); // debug + theMeshDS[1] = theMesh2->GetMeshDS(); + // ================================================================================= - // Is it the case of associating a group member -> another group? (PAL16202, 16203) + // 1) Is it the case of associating a group member -> another group? (PAL16202, 16203) // ================================================================================= if ( theShape1.ShapeType() != theShape2.ShapeType() ) { TopoDS_Shape group1, group2; @@ -411,7 +439,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the bool bidirect = ( !theShape1.IsSame( theShape2 )); // ============ - // Is partner? + // 2) Is partner? // ============ bool partner = theShape1.IsPartner( theShape2 ); TopTools_DataMapIteratorOfDataMapOfShapeShape vvIt( theMap ); @@ -437,7 +465,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the if ( !theMap.IsEmpty() ) { //====================================================================== - // HAS initial vertex association + // 3) HAS initial vertex association //====================================================================== switch ( theShape1.ShapeType() ) { // ---------------------------------------------------------------------- @@ -447,6 +475,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the RETURN_BAD_RESULT("Wrong map extent " << theMap.Extent() ); TopoDS_Edge edge1 = TopoDS::Edge( theShape1 ); TopoDS_Edge edge2 = TopoDS::Edge( theShape2 ); + if ( edge1.Orientation() >= TopAbs_INTERNAL ) edge1.Orientation( TopAbs_FORWARD ); + if ( edge2.Orientation() >= TopAbs_INTERNAL ) edge2.Orientation( TopAbs_FORWARD ); TopoDS_Vertex VV1[2], VV2[2]; TopExp::Vertices( edge1, VV1[0], VV1[1] ); TopExp::Vertices( edge2, VV2[0], VV2[1] ); @@ -462,6 +492,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the // ---------------------------------------------------------------------- TopoDS_Face face1 = TopoDS::Face( theShape1 ); TopoDS_Face face2 = TopoDS::Face( theShape2 ); + if ( face1.Orientation() >= TopAbs_INTERNAL ) face1.Orientation( TopAbs_FORWARD ); + if ( face2.Orientation() >= TopAbs_INTERNAL ) face2.Orientation( TopAbs_FORWARD ); TopoDS_Vertex VV1[2], VV2[2]; // find a not closed edge of face1 both vertices of which are associated @@ -509,6 +541,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the TopExp_Explorer exp ( theShape1, TopAbs_EDGE ); for ( ; VV2[ 1 ].IsNull() && exp.More(); exp.Next() ) { edge1 = TopoDS::Edge( exp.Current() ); + if ( edge1.Orientation() >= TopAbs_INTERNAL ) edge1.Orientation( TopAbs_FORWARD ); TopExp::Vertices( edge1 , VV1[0], VV1[1] ); if ( theMap.IsBound( VV1[0] )) { VV2[ 0 ] = TopoDS::Vertex( theMap( VV1[0] )); @@ -672,7 +705,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the if ( !initAssocOK ) { // for shell association there must be an edge with both vertices bound TopoDS_Vertex v1, v2; - TopExp::Vertices( TopoDS::Edge( it1.Value()), v1, v2 ); + TopExp::Vertices( TopoDS::Edge( it1.Value().Oriented(TopAbs_FORWARD)), v1, v2 ); initAssocOK = ( theMap.IsBound( v1 ) && theMap.IsBound( v2 )); } } @@ -875,7 +908,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the } // end case of available initial vertex association //====================================================================== - // NO INITIAL VERTEX ASSOCIATION + // 4) NO INITIAL VERTEX ASSOCIATION //====================================================================== switch ( theShape1.ShapeType() ) { @@ -903,7 +936,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the return true; // done } } - if ( IsClosedEdge( edge1 ) && IsClosedEdge( edge2 )) + if ( SMESH_MesherHelper::IsClosedEdge( edge1 ) && + SMESH_MesherHelper::IsClosedEdge( edge2 )) { // TODO: find out a proper orientation (is it possible?) InsertAssociation( edge1, edge2, theMap, bidirect); // insert with a proper orientation @@ -921,6 +955,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the { TopoDS_Face face1 = TopoDS::Face(theShape1); TopoDS_Face face2 = TopoDS::Face(theShape2); + if ( face1.Orientation() >= TopAbs_INTERNAL ) face1.Orientation( TopAbs_FORWARD ); + if ( face2.Orientation() >= TopAbs_INTERNAL ) face2.Orientation( TopAbs_FORWARD ); TopoDS_Edge edge1, edge2; // get outer edge of theShape1 edge1 = TopoDS::Edge( OuterShape( face1, TopAbs_EDGE )); @@ -943,13 +979,14 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the list< TopoDS_Edge > edges1, edges2; int nbE = FindFaceAssociation( face1, VV1, face2, VV2, edges1, edges2 ); if ( !nbE ) RETURN_BAD_RESULT("FindFaceAssociation() failed"); - if ( nbE == 2 ) // only 2 edges + // take care of proper association of propagated edges + bool same1 = edge1.IsSame( edges1.front() ); + bool same2 = edge2.IsSame( edges2.front() ); + if ( same1 != same2 ) { - // take care of proper association of propagated edges - bool same1 = edge1.IsSame( edges1.front() ); - bool same2 = edge2.IsSame( edges2.front() ); - if ( same1 != same2 ) - Reverse(edges2, nbE); + Reverse(edges2, nbE); + if ( nbE != 2 ) // 2 degen edges of 4 (issue 0021144) + edges2.splice( edges2.end(), edges2, edges2.begin()); } // store association list< TopoDS_Edge >::iterator eIt1 = edges1.begin(); @@ -1047,6 +1084,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the TopTools_IndexedMapOfShape vMap1, vMap2; TopExp::MapShapes( theShape1, TopAbs_VERTEX, vMap1 ); TopExp::MapShapes( theShape2, TopAbs_VERTEX, vMap2 ); + TopoDS_Vertex VV1[2], VV2[2]; if ( vMap1.Extent() != vMap2.Extent() ) RETURN_BAD_RESULT("Different nb of vertices"); @@ -1060,6 +1098,32 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the return FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap); } + // Try to associate by common vertices of an edge + for ( int i = 1; i <= vMap1.Extent(); ++i ) + { + const TopoDS_Shape& v1 = vMap1(i); + if ( vMap2.Contains( v1 )) + { + // find an egde sharing v1 and sharing at the same time another common vertex + PShapeIteratorPtr edgeIt = SMESH_MesherHelper::GetAncestors( v1, *theMesh1, TopAbs_EDGE); + bool edgeFound = false; + while ( edgeIt->more() && !edgeFound ) + { + TopoDS_Edge edge = TopoDS::Edge( edgeIt->next()->Oriented(TopAbs_FORWARD)); + TopExp::Vertices(edge, VV1[0], VV1[1]); + if ( !VV1[0].IsSame( VV1[1] )) + edgeFound = ( vMap2.Contains( VV1[ v1.IsSame(VV1[0]) ? 1:0])); + } + if ( edgeFound ) + { + InsertAssociation( VV1[0], VV1[0], theMap, bidirect ); + InsertAssociation( VV1[1], VV1[1], theMap, bidirect ); + if (FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap )) + return true; + } + } + } + // Find transformation to make the shapes be of similar size at same location Bnd_Box box[2]; @@ -1081,7 +1145,6 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the // Find 2 closest vertices - TopoDS_Vertex VV1[2], VV2[2]; // get 2 linked vertices of shape 1 not belonging to an inner wire of a face TopoDS_Shape edge = theShape1; TopExp_Explorer expF( theShape1, TopAbs_FACE ), expE; @@ -1090,7 +1153,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the edge.Nullify(); TopoDS_Shape wire = OuterShape( TopoDS::Face( expF.Current() ), TopAbs_WIRE ); for ( expE.Init( wire, TopAbs_EDGE ); edge.IsNull() && expE.More(); expE.Next() ) - if ( !IsClosedEdge( TopoDS::Edge( expE.Current() ))) + if ( !SMESH_MesherHelper::IsClosedEdge( TopoDS::Edge( expE.Current() ))) edge = expE.Current(); if ( !edge.IsNull() ) break; @@ -1098,13 +1161,13 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the } else if (edge.ShapeType() != TopAbs_EDGE) { // no faces edge.Nullify(); for ( expE.Init( theShape1, TopAbs_EDGE ); edge.IsNull() && expE.More(); expE.Next() ) - if ( !IsClosedEdge( TopoDS::Edge( expE.Current() ))) + if ( !SMESH_MesherHelper::IsClosedEdge( TopoDS::Edge( expE.Current() ))) edge = expE.Current(); } if ( edge.IsNull() || edge.ShapeType() != TopAbs_EDGE ) RETURN_BAD_RESULT("Edge not found"); - TopExp::Vertices( TopoDS::Edge( edge ), VV1[0], VV1[1]); + TopExp::Vertices( TopoDS::Edge( edge.Oriented(TopAbs_FORWARD)), VV1[0], VV1[1]); if ( VV1[0].IsSame( VV1[1] )) RETURN_BAD_RESULT("Only closed edges"); @@ -1160,19 +1223,23 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, list< TopoDS_Edge > & edges1, list< TopoDS_Edge > & edges2) { - list< int > nbVInW1, nbVInW2; - for ( int outer_wire_algo = 0; outer_wire_algo < 2; ++outer_wire_algo ) + bool OK = false; + list< int > nbEInW1, nbEInW2; + int i_ok_wire_algo = -1; + for ( int outer_wire_algo = 0; outer_wire_algo < 2 && !OK; ++outer_wire_algo ) { edges1.clear(); edges2.clear(); - if ( SMESH_Block::GetOrderedEdges( face1, VV1[0], edges1, nbVInW1, outer_wire_algo) != - SMESH_Block::GetOrderedEdges( face2, VV2[0], edges2, nbVInW2, outer_wire_algo) ) + if ( SMESH_Block::GetOrderedEdges( face1, VV1[0], edges1, nbEInW1, outer_wire_algo) != + SMESH_Block::GetOrderedEdges( face2, VV2[0], edges2, nbEInW2, outer_wire_algo) ) CONT_BAD_RESULT("Different number of wires in faces "); - if ( nbVInW1.front() != nbVInW2.front() ) + if ( nbEInW1 != nbEInW2 ) CONT_BAD_RESULT("Different number of edges in faces: " << - nbVInW1.front() << " != " << nbVInW2.front()); + nbEInW1.front() << " != " << nbEInW2.front()); + + i_ok_wire_algo = outer_wire_algo; // Define if we need to reverse one of wires to make edges in lists match each other @@ -1185,9 +1252,9 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, // check if the second vertex belongs to the first or last edge in the wire if ( !VV1[1].IsSame( TopExp::FirstVertex( *edgeIt, true ))) { bool KO = true; // belongs to none - if ( nbVInW1.size() > 1 ) { // several wires + if ( nbEInW1.size() > 1 ) { // several wires edgeIt = edges1.begin(); - for ( int i = 1; i < nbVInW1.front(); ++i ) ++edgeIt; + std::advance( edgeIt, nbEInW1.front()-1 ); KO = !VV1[1].IsSame( TopExp::FirstVertex( *edgeIt, true )); } if ( KO ) @@ -1200,9 +1267,9 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, // check if the second vertex belongs to the first or last edge in the wire if ( !VV2[1].IsSame( TopExp::FirstVertex( *edgeIt, true ))) { bool KO = true; // belongs to none - if ( nbVInW2.size() > 1 ) { // several wires + if ( nbEInW2.size() > 1 ) { // several wires edgeIt = edges2.begin(); - for ( int i = 1; i < nbVInW2.front(); ++i ) ++edgeIt; + std::advance( edgeIt, nbEInW2.front()-1 ); KO = !VV2[1].IsSame( TopExp::FirstVertex( *edgeIt, true )); } if ( KO ) @@ -1211,13 +1278,84 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, } if ( reverse ) { - Reverse( edges2 , nbVInW2.front()); + Reverse( edges2 , nbEInW2.front()); if (( VV1[1].IsSame( TopExp::LastVertex( edges1.front(), true ))) != ( VV2[1].IsSame( TopExp::LastVertex( edges2.front(), true )))) CONT_BAD_RESULT("GetOrderedEdges() failed"); } + OK = true; + + } // loop algos getting an outer wire + + // Try to orient all (if !OK) or only internal wires (issue 0020996) by UV similarity + if (( !OK || nbEInW1.size() > 1 ) && i_ok_wire_algo > -1 ) + { + // Check that Vec(VV1[0],VV1[1]) in 2D on face1 is the same + // as Vec(VV2[0],VV2[1]) on face2 + double vTol = BRep_Tool::Tolerance( VV1[0] ); + BRepAdaptor_Surface surface1( face1, false ); + double vTolUV = + surface1.UResolution( vTol ) + surface1.VResolution( vTol ); // let's be tolerant + gp_Pnt2d v0f1UV = BRep_Tool::Parameters( VV1[0], face1 ); + gp_Pnt2d v0f2UV = BRep_Tool::Parameters( VV2[0], face2 ); + gp_Pnt2d v1f1UV = BRep_Tool::Parameters( VV1[1], face1 ); + gp_Pnt2d v1f2UV = BRep_Tool::Parameters( VV2[1], face2 ); + gp_Vec2d v01f1Vec( v0f1UV, v1f1UV ); + gp_Vec2d v01f2Vec( v0f2UV, v1f2UV ); + if ( Abs( v01f1Vec.X()-v01f2Vec.X()) < vTolUV && + Abs( v01f1Vec.Y()-v01f2Vec.Y()) < vTolUV ) + { + if ( !OK /*i_ok_wire_algo != 1*/ ) + { + edges1.clear(); + edges2.clear(); + SMESH_Block::GetOrderedEdges( face1, VV1[0], edges1, nbEInW1, i_ok_wire_algo); + SMESH_Block::GetOrderedEdges( face2, VV2[0], edges2, nbEInW2, i_ok_wire_algo); + } + gp_XY dUV = v0f2UV.XY() - v0f1UV.XY(); // UV shift between 2 faces + // skip edges of the outer wire (if the outer wire is OK) + list< int >::iterator nbEInW = nbEInW1.begin(); + list< TopoDS_Edge >::iterator edge1Beg = edges1.begin(), edge2Beg = edges2.begin(); + if ( OK ) + { + for ( int i = 0; i < *nbEInW; ++i ) + ++edge1Beg, ++edge2Beg; + ++nbEInW; + } + for ( ; nbEInW != nbEInW1.end(); ++nbEInW ) // loop on wires + { + // reach an end of edges of a current wire + list< TopoDS_Edge >::iterator edge1End = edge1Beg, edge2End = edge2Beg; + for ( int i = 0; i < *nbEInW; ++i ) + ++edge1End, ++edge2End; + // rotate edges2 untill coincident with edges1 in 2D + v0f1UV = BRep_Tool::Parameters( TopExp::FirstVertex(*edge1Beg,true), face1 ); + v1f1UV = BRep_Tool::Parameters( TopExp::LastVertex (*edge1Beg,true), face1 ); + v0f1UV.ChangeCoord() += dUV; + v1f1UV.ChangeCoord() += dUV; + int i = *nbEInW; + while ( --i > 0 && !sameVertexUV( *edge2Beg, face2, 0, v0f1UV, vTolUV )) + edges2.splice( edge2End, edges2, edge2Beg++ ); // move edge2Beg to place before edge2End + if ( sameVertexUV( *edge2Beg, face2, 0, v0f1UV, vTolUV )) + { + if ( nbEInW == nbEInW1.begin() ) + OK = true; // OK is for the first wire + // reverse edges2 if needed + if ( !sameVertexUV( *edge2Beg, face2, 1, v1f1UV, vTolUV )) + { + Reverse( edges2 , *nbEInW, distance( edges2.begin(),edge2Beg )); + // set correct edge2End + edge2End = edges2.begin(); + std::advance( edge2End, std::accumulate( nbEInW1.begin(), nbEInW, *nbEInW)); + } + } + // prepare to the next wire loop + edge1Beg = edge1End, edge2Beg = edge2End; + } + } } - return nbVInW2.front(); + + return OK ? nbEInW1.front() : 0; } //======================================================================= @@ -1270,8 +1408,8 @@ bool StdMeshers_ProjectionUtils::InsertAssociation( const TopoDS_Shape& theShape const bool theBidirectional) { if ( !theShape1.IsNull() && !theShape2.IsNull() ) { - SHOW_VERTEX(theShape1,"Assoc "); - SHOW_VERTEX(theShape2," to "); + SHOW_SHAPE(theShape1,"Assoc "); + SHOW_SHAPE(theShape2," to "); bool isNew = ( theAssociationMap.Bind( theShape1, theShape2 )); if ( theBidirectional ) theAssociationMap.Bind( theShape2, theShape1 ); @@ -1283,44 +1421,6 @@ bool StdMeshers_ProjectionUtils::InsertAssociation( const TopoDS_Shape& theShape return false; } -//======================================================================= -//function : IsSubShape -//purpose : -//======================================================================= - -bool StdMeshers_ProjectionUtils::IsSubShape( const TopoDS_Shape& shape, - SMESH_Mesh* aMesh ) -{ - if ( shape.IsNull() || !aMesh ) - return false; - return - aMesh->GetMeshDS()->ShapeToIndex( shape ) || - // PAL16202 - shape.ShapeType() == TopAbs_COMPOUND && aMesh->GetMeshDS()->IsGroupOfSubShapes( shape ); -} - -//======================================================================= -//function : IsSubShape -//purpose : -//======================================================================= - -bool StdMeshers_ProjectionUtils::IsSubShape( const TopoDS_Shape& shape, - const TopoDS_Shape& mainShape ) -{ - if ( !shape.IsNull() && !mainShape.IsNull() ) - { - for ( TopExp_Explorer exp( mainShape, shape.ShapeType()); - exp.More(); - exp.Next() ) - if ( shape.IsSame( exp.Current() )) - return true; - } - SCRUTE((shape.IsNull())); - SCRUTE((mainShape.IsNull())); - return false; -} - - //======================================================================= /*! * \brief Finds an edge by its vertices in a main shape of the mesh @@ -1406,7 +1506,7 @@ StdMeshers_ProjectionUtils::GetPropagationEdge( SMESH_Mesh* aMesh, const TopoDS_Edge& theEdge, const TopoDS_Edge& fromEdge) { - SMESH_IndexedMapOfShape aChain; + TopTools_IndexedMapOfShape aChain; int step = 0; // List of edges, added to chain on the previous cycle pass @@ -1536,7 +1636,7 @@ FindMatchingNodesOnFaces( const TopoDS_Face& face1, if ( !assocMap.IsBound( e2 )) RETURN_BAD_RESULT("Association not found for edge " << meshDS2->ShapeToIndex( e2 )); TopoDS_Edge e1 = TopoDS::Edge( assocMap( e2 )); - if ( !IsSubShape( e1, face1 )) + if ( !helper1.IsSubShape( e1, face1 )) RETURN_BAD_RESULT("Wrong association, edge " << meshDS1->ShapeToIndex( e1 ) << " isn't a subshape of face " << meshDS1->ShapeToIndex( face1 )); // check that there are nodes on edges @@ -1594,7 +1694,7 @@ FindMatchingNodesOnFaces( const TopoDS_Face& face1, if ( hasNodesOnEdge ) { int nbNodeToGet = 1; - if ( IsClosedEdge( edge1 ) || IsClosedEdge( edge2 ) ) + if ( helper1.IsClosedEdge( edge1 ) || helper2.IsClosedEdge( edge2 ) ) nbNodeToGet = 2; for ( int is2 = 0; is2 < 2; ++is2 ) { @@ -1682,7 +1782,7 @@ FindMatchingNodesOnFaces( const TopoDS_Face& face1, const SMDS_MeshElement* f = ( iF ? f2 : f1 ); for ( int i = 0; !notSeamNode[ iF ] && i < f->NbNodes(); ++i ) { const SMDS_MeshNode* node = f->GetNode( i ); - if ( !helper->IsSeamShape( node->GetPosition()->GetShapeId() )) + if ( !helper->IsSeamShape( node->getshapeId() )) notSeamNode[ iF ] = node; } } @@ -1750,7 +1850,7 @@ FindMatchingNodesOnFaces( const TopoDS_Face& face1, while ( nIt->more() ) { const SMDS_MeshNode* node = nIt->next(); const SMDS_EdgePosition* pos = - static_cast(node->GetPosition().get()); + static_cast(node->GetPosition()); pos2nodes.insert( make_pair( pos->GetUParameter(), node )); } if ( pos2nodes.size() != edgeSM->NbNodes() ) @@ -1802,19 +1902,6 @@ FindMatchingNodesOnFaces( const TopoDS_Face& face1, return true; } -//================================================================================ -/*! - * \brief Check if the first and last vertices of an edge are the same - * \param anEdge - the edge to check - * \retval bool - true if same - */ -//================================================================================ - -bool StdMeshers_ProjectionUtils::IsClosedEdge( const TopoDS_Edge& anEdge ) -{ - return TopExp::FirstVertex( anEdge ).IsSame( TopExp::LastVertex( anEdge )); -} - //================================================================================ /*! * \brief Return any subshape of a face belonging to the outer wire @@ -1853,7 +1940,7 @@ bool StdMeshers_ProjectionUtils::MakeComputed(SMESH_subMesh * sm, const int iter SMESH_Mesh* mesh = sm->GetFather(); SMESH_Gen* gen = mesh->GetGen(); - SMESH_Algo* algo = gen->GetAlgo( *mesh, sm->GetSubShape() ); + SMESH_Algo* algo = sm->GetAlgo(); if ( !algo ) { if ( sm->GetSubShape().ShapeType() != TopAbs_COMPOUND ) @@ -1993,9 +2080,7 @@ namespace { // delete current source listener subMesh->DeleteEventListener( GetSrcSubMeshListener() ); // let algo set a new one - SMESH_Gen* gen = subMesh->GetFather()->GetGen(); - if ( SMESH_Algo* algo = gen->GetAlgo( *subMesh->GetFather(), - subMesh->GetSubShape() )) + if ( SMESH_Algo* algo = subMesh->GetAlgo() ) algo->SetEventListener( subMesh ); } } @@ -2036,7 +2121,7 @@ void StdMeshers_ProjectionUtils::SetEventListener(SMESH_subMesh* subMesh, SMESH_Mesh* srcMesh) { // Set listener that resets an event listener on source submesh when - // "ProjectionSource*D" hypothesis is modified + // "ProjectionSource*D" hypothesis is modified since source shape can be changed subMesh->SetEventListener( GetHypModifWaiter(),0,subMesh); // Set an event listener to submesh of the source shape @@ -2056,13 +2141,16 @@ void StdMeshers_ProjectionUtils::SetEventListener(SMESH_subMesh* subMesh, for (; it.More(); it.Next()) { SMESH_subMesh* srcSM = srcMesh->GetSubMesh( it.Current() ); - SMESH_subMeshEventListenerData* data = - srcSM->GetEventListenerData(GetSrcSubMeshListener()); - if ( data ) - data->mySubMeshes.push_back( subMesh ); - else - data = SMESH_subMeshEventListenerData::MakeData( subMesh ); - subMesh->SetEventListener ( GetSrcSubMeshListener(), data, srcSM ); + if ( srcSM != subMesh ) + { + SMESH_subMeshEventListenerData* data = + srcSM->GetEventListenerData(GetSrcSubMeshListener()); + if ( data ) + data->mySubMeshes.push_back( subMesh ); + else + data = SMESH_subMeshEventListenerData::MakeData( subMesh ); + subMesh->SetEventListener ( GetSrcSubMeshListener(), data, srcSM ); + } } } else