X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_ProjectionUtils.cxx;h=ae6f38419e465580eafdaad0461a7a1eaa107224;hp=08136aa73352cfef83e3f6466a0a382761c43574;hb=b1f58b701eb4ec6fb4a14b070041f2c89e44723c;hpb=bd8f1aee7c78f7d2eb82bd4fec5e08c9e3d280ce diff --git a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx index 08136aa73..ae6f38419 100644 --- a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx +++ b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -6,7 +6,7 @@ // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either -// version 2.1 of the License. +// version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -41,6 +41,7 @@ #include "SMESH_MesherHelper.hxx" #include "SMESH_subMesh.hxx" #include "SMESH_subMeshEventListener.hxx" +#include "SMESH_MeshAlgos.hxx" #include "utilities.h" @@ -437,8 +438,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the TShapeShapeMap & theMap) { // Structure of this long function is following - // 1) Group->group projection: theShape1 is a group member, - // theShape2 is a group. We find a group theShape1 is in and recall self. + // 1) Group -> Group projection: theShape1 is a group member, + // theShape2 is another group. We find a group theShape1 is in and recall self. // 2) Accosiate same shapes with different location (partners). // 3) If vertex association is given, perform accosiation according to shape type: // switch ( ShapeType ) { @@ -621,7 +622,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the TopTools_ListIteratorOfListOfShape ancestIt1( edgeToFace1.FindFromKey( edge1 )); for ( ; F1.IsNull() && ancestIt1.More(); ancestIt1.Next() ) if ( ancestIt1.Value().ShapeType() == TopAbs_FACE ) - F1 = ancestIt1.Value().Oriented( TopAbs_FORWARD ); + F1 = ancestIt1.Value().Oriented //( TopAbs_FORWARD ); + ( SMESH_MesherHelper::GetSubShapeOri( theShape1, ancestIt1.Value() )); if ( F1.IsNull() ) RETURN_BAD_RESULT(" Face1 not found"); @@ -629,7 +631,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the TopTools_ListIteratorOfListOfShape ancestIt2( edgeToFace2.FindFromKey( edge2 )); for ( int i = 0; FF2[1].IsNull() && ancestIt2.More(); ancestIt2.Next() ) if ( ancestIt2.Value().ShapeType() == TopAbs_FACE ) - FF2[ i++ ] = ancestIt2.Value().Oriented( TopAbs_FORWARD ); + FF2[ i++ ] = ancestIt2.Value().Oriented // ( TopAbs_FORWARD ); + ( SMESH_MesherHelper::GetSubShapeOri( theShape2, ancestIt2.Value() )); // get oriented edge1 and edge2 from F1 and FF2[0] for ( exp.Init( F1, TopAbs_EDGE ); exp.More(); exp.Next() ) @@ -1000,7 +1003,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the // get outer edge of theShape1 TopoDS_Shape wire = OuterShape( face1, TopAbs_WIRE ); //edge1 = TopoDS::Edge( OuterShape( face1, TopAbs_EDGE )); - map propag_edges; // use map to find the closest propagation edge + // use map to find the closest propagation edge + map > propag_edges; for ( TopoDS_Iterator edgeIt( wire ); edgeIt.More(); edgeIt.Next() ) { edge1 = TopoDS::Edge( edgeIt.Value() ); @@ -1009,7 +1013,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the edge2 = TopoDS::Edge( exp.Current() ); pair step_edge = GetPropagationEdge( theMesh1, edge2, edge1 ); if ( !step_edge.second.IsNull() ) { // propagation found - propag_edges.insert( step_edge ); + propag_edges.insert( make_pair( step_edge.first, + ( make_pair( edge1, step_edge.second )))); if ( step_edge.first == 1 ) break; // most close found } } @@ -1017,7 +1022,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the } if ( !propag_edges.empty() ) // propagation found { - edge2 = propag_edges.begin()->second; + edge1 = propag_edges.begin()->second.first; + edge2 = propag_edges.begin()->second.second; TopoDS_Vertex VV1[2], VV2[2]; TopExp::Vertices( edge1, VV1[0], VV1[1], true ); TopExp::Vertices( edge2, VV2[0], VV2[1], true ); @@ -1326,9 +1332,15 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, CONT_BAD_RESULT("GetOrderedEdges() failed"); } } - edgeIt = --edges2.end(); if ( !VV2[1].IsSame( TopExp::LastVertex( edges2.front(), true ))) { reverse = !reverse; + edgeIt = --edges2.end(); + // move a degenerated edge from back to front + // http://www.salome-platform.org/forum/forum_11/173031193 + if ( TopExp::FirstVertex( *edgeIt ).IsSame( TopExp::LastVertex( *edgeIt ))) { + edges2.splice( edges2.begin(), edges2, edgeIt ); + edgeIt = --edges2.end(); + } // 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 @@ -1416,7 +1428,8 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, // move edge2Beg to place before edge2End edges2.splice( edge2End, edges2, edge2Beg++ ); - if ( sameVertexUV( *edge2Beg, face2, 0, v0f1UV, vTolUV )) + if ( edge2Beg != edges2.end() && + sameVertexUV( *edge2Beg, face2, 0, v0f1UV, vTolUV )) { if ( iW1 == 0 ) OK = true; // OK is for the first wire // reverse edges2 if needed @@ -1600,79 +1613,87 @@ TopoDS_Vertex StdMeshers_ProjectionUtils::GetNextVertex(const TopoDS_Edge& edg /* * Return a propagation edge * \param aMesh - mesh - * \param theEdge - edge to find by propagation + * \param anEdge - edge to find by propagation * \param fromEdge - start edge for propagation + * \param chain - return, if !NULL, a propagation chain passed till + * anEdge; if anEdge.IsNull() then a full propagation chain is returned; + * fromEdge is the 1st in the chain * \retval pair - propagation step and found edge */ //================================================================================ pair -StdMeshers_ProjectionUtils::GetPropagationEdge( SMESH_Mesh* aMesh, - const TopoDS_Edge& theEdge, - const TopoDS_Edge& fromEdge) +StdMeshers_ProjectionUtils::GetPropagationEdge( SMESH_Mesh* aMesh, + const TopoDS_Edge& anEdge, + const TopoDS_Edge& fromEdge, + TopTools_IndexedMapOfShape* chain) { - TopTools_IndexedMapOfShape aChain; + TopTools_IndexedMapOfShape locChain; + TopTools_IndexedMapOfShape& aChain = chain ? *chain : locChain; int step = 0; + //TopTools_IndexedMapOfShape checkedWires; + BRepTools_WireExplorer aWE; + TopoDS_Shape fourEdges[4]; + // List of edges, added to chain on the previous cycle pass TopTools_ListOfShape listPrevEdges; - listPrevEdges.Append(fromEdge); + listPrevEdges.Append( fromEdge ); + aChain.Add( fromEdge ); // Collect all edges pass by pass - while (listPrevEdges.Extent() > 0) { + while (listPrevEdges.Extent() > 0) + { step++; // List of edges, added to chain on this cycle pass TopTools_ListOfShape listCurEdges; // Find the next portion of edges TopTools_ListIteratorOfListOfShape itE (listPrevEdges); - for (; itE.More(); itE.Next()) { - TopoDS_Shape anE = itE.Value(); + for (; itE.More(); itE.Next()) + { + const TopoDS_Shape& anE = itE.Value(); // Iterate on faces, having edge TopTools_ListIteratorOfListOfShape itA (aMesh->GetAncestors(anE)); - for (; itA.More(); itA.Next()) { - TopoDS_Shape aW = itA.Value(); + for (; itA.More(); itA.Next()) + { + const TopoDS_Shape& aW = itA.Value(); // There are objects of different type among the ancestors of edge - if (aW.ShapeType() == TopAbs_WIRE) { - TopoDS_Shape anOppE; - - BRepTools_WireExplorer aWE (TopoDS::Wire(aW)); - Standard_Integer nb = 1, found = 0; - TopTools_Array1OfShape anEdges (1,4); - for (; aWE.More(); aWE.Next(), nb++) { - if (nb > 4) { - found = 0; + if ( aW.ShapeType() == TopAbs_WIRE /*&& checkedWires.Add( aW )*/) + { + Standard_Integer nb = 0, found = -1; + for ( aWE.Init( TopoDS::Wire( aW )); aWE.More(); aWE.Next() ) { + if (nb+1 > 4) { + found = -1; break; } - anEdges(nb) = aWE.Current(); - if (anEdges(nb).IsSame(anE)) found = nb; + fourEdges[ nb ] = aWE.Current(); + if ( aWE.Current().IsSame( anE )) found = nb; + nb++; } - - if (nb == 5 && found > 0) { + if (nb == 4 && found >= 0) { // Quadrangle face found, get an opposite edge - Standard_Integer opp = found + 2; - if (opp > 4) opp -= 4; - anOppE = anEdges(opp); + TopoDS_Shape& anOppE = fourEdges[( found + 2 ) % 4 ]; // add anOppE to aChain if ... - if (!aChain.Contains(anOppE)) { // ... anOppE is not in aChain + int prevChainSize = aChain.Extent(); + if ( aChain.Add(anOppE) > prevChainSize ) { // ... anOppE is not in aChain // Add found edge to the chain oriented so that to // have it co-directed with a forward MainEdge TopAbs_Orientation ori = anE.Orientation(); - if ( anEdges(opp).Orientation() == anEdges(found).Orientation() ) + if ( anOppE.Orientation() == fourEdges[found].Orientation() ) ori = TopAbs::Reverse( ori ); anOppE.Orientation( ori ); - if ( anOppE.IsSame( theEdge )) + if ( anOppE.IsSame( anEdge )) return make_pair( step, TopoDS::Edge( anOppE )); - aChain.Add(anOppE); listCurEdges.Append(anOppE); } - } // if (nb == 5 && found > 0) + } // if (nb == 4 && found >= 0) } // if (aF.ShapeType() == TopAbs_WIRE) - } // for (; itF.More(); itF.Next()) - } // for (; itE.More(); itE.Next()) + } // loop on ancestors of anE + } // loop on listPrevEdges listPrevEdges = listCurEdges; } // while (listPrevEdges.Extent() > 0) @@ -1873,12 +1894,12 @@ FindMatchingNodesOnFaces( const TopoDS_Face& face1, TIDSortedElemSet inSet, notInSet; const SMDS_MeshElement* f1 = - SMESH_MeshEditor::FindFaceInSet( vNode, eNode, inSet, notInSet ); + SMESH_MeshAlgos::FindFaceInSet( vNode, eNode, inSet, notInSet ); if ( !f1 ) RETURN_BAD_RESULT("The first face on seam not found"); notInSet.insert( f1 ); const SMDS_MeshElement* f2 = - SMESH_MeshEditor::FindFaceInSet( vNode, eNode, inSet, notInSet ); + SMESH_MeshAlgos::FindFaceInSet( vNode, eNode, inSet, notInSet ); if ( !f2 ) RETURN_BAD_RESULT("The second face on seam not found"); // select a face with less UV of vNode @@ -1921,7 +1942,7 @@ FindMatchingNodesOnFaces( const TopoDS_Face& face1, for ( int i = 0; i < nbNodes; ++i ) { const SMDS_MeshNode* n1 = faceToKeep->GetNode( i ); const SMDS_MeshNode* n2 = faceToKeep->GetNode(( i+1 ) % nbNodes ); - f1 = SMESH_MeshEditor::FindFaceInSet( n1, n2, inSet, notInSet ); + f1 = SMESH_MeshAlgos::FindFaceInSet( n1, n2, inSet, notInSet ); if ( f1 ) elems.insert( f1 ); } @@ -2027,8 +2048,8 @@ TopoDS_Shape StdMeshers_ProjectionUtils::OuterShape( const TopoDS_Face& face, //================================================================================ /* - * Check that submesh is computed and try to compute it if is not - * \param sm - submesh to compute + * Check that sub-mesh is computed and try to compute it if is not + * \param sm - sub-mesh to compute * \param iterationNb - int used to stop infinite recursive call * \retval bool - true if computed */ @@ -2043,30 +2064,65 @@ bool StdMeshers_ProjectionUtils::MakeComputed(SMESH_subMesh * sm, const int iter if ( sm->IsMeshComputed() ) return true; - SMESH_Mesh* mesh = sm->GetFather(); - SMESH_Gen* gen = mesh->GetGen(); - SMESH_Algo* algo = sm->GetAlgo(); + SMESH_Mesh* mesh = sm->GetFather(); + SMESH_Gen* gen = mesh->GetGen(); + SMESH_Algo* algo = sm->GetAlgo(); + TopoDS_Shape shape = sm->GetSubShape(); if ( !algo ) { - if ( sm->GetSubShape().ShapeType() != TopAbs_COMPOUND ) - RETURN_BAD_RESULT("No algo assigned to submesh " << sm->GetId()); - // group - bool computed = true; - for ( TopoDS_Iterator grMember( sm->GetSubShape() ); grMember.More(); grMember.Next()) - if ( SMESH_subMesh* grSub = mesh->GetSubMesh( grMember.Value() )) - if ( !MakeComputed( grSub, iterationNb + 1 )) - computed = false; - return computed; + if ( shape.ShapeType() != TopAbs_COMPOUND ) + { + // No algo assigned to a non-compound sub-mesh. + // Try to find an all-dimensional algo of an upper dimension + int dim = gen->GetShapeDim( shape ); + for ( ++dim; ( dim <= 3 && !algo ); ++dim ) + { + SMESH_HypoFilter hypoFilter( SMESH_HypoFilter::IsAlgo() ); + hypoFilter.And( SMESH_HypoFilter::HasDim( dim )); + list hyps; + list< TopoDS_Shape > assignedTo; + int nbAlgos = + mesh->GetHypotheses( shape, hypoFilter, hyps, true, &assignedTo ); + if ( nbAlgos > 1 ) // concurrent algos + { + list smList; // where an algo is assigned + list< TopoDS_Shape >::iterator shapeIt = assignedTo.begin(); + for ( ; shapeIt != assignedTo.end(); ++shapeIt ) + smList.push_back( mesh->GetSubMesh( *shapeIt )); + + mesh->SortByMeshOrder( smList ); + algo = smList.front()->GetAlgo(); + shape = smList.front()->GetSubShape(); + } + else if ( nbAlgos == 1 ) + { + algo = (SMESH_Algo*) hyps.front(); + shape = assignedTo.front(); + } + } + if ( !algo ) + return false; + } + else + { + // group + bool computed = true; + for ( TopoDS_Iterator grMember( shape ); grMember.More(); grMember.Next()) + if ( SMESH_subMesh* grSub = mesh->GetSubMesh( grMember.Value() )) + if ( !MakeComputed( grSub, iterationNb + 1 )) + computed = false; + return computed; + } } string algoType = algo->GetName(); if ( algoType.substr(0, 11) != "Projection_") - return gen->Compute( *mesh, sm->GetSubShape() ); + return gen->Compute( *mesh, shape, /*shapeOnly=*/true ); // try to compute source mesh const list & hyps = - algo->GetUsedHypothesis( *mesh, sm->GetSubShape() ); + algo->GetUsedHypothesis( *mesh, shape ); TopoDS_Shape srcShape; SMESH_Mesh* srcMesh = 0; @@ -2093,16 +2149,16 @@ bool StdMeshers_ProjectionUtils::MakeComputed(SMESH_subMesh * sm, const int iter } } if ( srcShape.IsNull() ) // no projection source defined - return gen->Compute( *mesh, sm->GetSubShape() ); + return gen->Compute( *mesh, shape, /*shapeOnly=*/true ); - if ( srcShape.IsSame( sm->GetSubShape() )) + if ( srcShape.IsSame( shape )) RETURN_BAD_RESULT("Projection from self"); if ( !srcMesh ) srcMesh = mesh; if ( MakeComputed( srcMesh->GetSubMesh( srcShape ), iterationNb + 1 ) && - gen->Compute( *mesh, sm->GetSubShape() )) + gen->Compute( *mesh, shape, /*shapeOnly=*/true )) return sm->IsMeshComputed(); return false;