X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_ProjectionUtils.cxx;h=730f78c62c4c628caa715a63c0ff3bc82f7a5c05;hp=76785fad0e64139375d4bbb51da17ac0f2eeb8a4;hb=5d68554076bbca0e1e95fb0db215a6c2b84b6c54;hpb=1067ffa6e7e5c394e3a1b17219d8b355a57607cd diff --git a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx index 76785fad0..730f78c62 100644 --- a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx +++ b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 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 @@ -31,15 +31,17 @@ #include "StdMeshers_ProjectionSource2D.hxx" #include "StdMeshers_ProjectionSource3D.hxx" +#include "SMDS_EdgePosition.hxx" #include "SMESH_Algo.hxx" #include "SMESH_Block.hxx" #include "SMESH_Gen.hxx" +#include "SMESH_HypoFilter.hxx" #include "SMESH_Hypothesis.hxx" #include "SMESH_Mesh.hxx" #include "SMESH_MesherHelper.hxx" #include "SMESH_subMesh.hxx" #include "SMESH_subMeshEventListener.hxx" -#include "SMDS_EdgePosition.hxx" +#include "SMESH_MeshAlgos.hxx" #include "utilities.h" @@ -215,13 +217,12 @@ namespace { list subMeshes = tgtMesh1->GetGroupSubMeshesContaining(tgtShape); list::iterator sm = subMeshes.begin(); int type, last = TopAbs_SHAPE; - StdMeshers_ProjectionUtils util; for ( ; sm != subMeshes.end(); ++sm ) { const TopoDS_Shape & group = (*sm)->GetSubShape(); // check if group is similar to srcGroup for ( type = srcGroup.ShapeType(); type < last; ++type) - if ( util.Count( srcGroup, (TopAbs_ShapeEnum)type, 0) != - util.Count( group, (TopAbs_ShapeEnum)type, 0)) + if ( SMESH_MesherHelper::Count( srcGroup, (TopAbs_ShapeEnum)type, 0) != + SMESH_MesherHelper::Count( group, (TopAbs_ShapeEnum)type, 0)) break; if ( type == last ) return group; @@ -285,7 +286,7 @@ namespace { // get edges of the face TopoDS_Edge edgeGr1, edgeGr2, verticEdge2; list< TopoDS_Edge > edges; list< int > nbEdgesInWire; - SMESH_Block::GetOrderedEdges( face, v1, edges, nbEdgesInWire); + SMESH_Block::GetOrderedEdges( face, edges, nbEdgesInWire, v1); if ( nbEdgesInWire.front() != 4 ) return _StoreBadShape( face ); list< TopoDS_Edge >::iterator edge = edges.begin(); @@ -418,15 +419,15 @@ namespace { } // namespace //======================================================================= -/*! - * \brief Looks for association of all sub-shapes of two shapes - * \param theShape1 - target shape - * \param theMesh1 - mesh built on shape 1 - * \param theShape2 - source shape - * \param theMesh2 - mesh built on shape 2 - * \param theAssociation - association map to be filled that may - * contain association of one or two pairs of vertices - * \retval bool - true if association found +/* + * Looks for association of all sub-shapes of two shapes + * \param theShape1 - target shape + * \param theMesh1 - mesh built on shape 1 + * \param theShape2 - source shape + * \param theMesh2 - mesh built on shape 2 + * \param theAssociation - association map to be filled that may + * contain association of one or two pairs of vertices + * \retval bool - true if association found */ //======================================================================= @@ -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() ) @@ -713,7 +716,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the // Maybe groups contain only one member TopoDS_Iterator it1( theShape1 ), it2( theShape2 ); TopAbs_ShapeEnum memberType = it1.Value().ShapeType(); - int nbMembers = Count( theShape1, memberType, true ); + int nbMembers = SMESH_MesherHelper::Count( theShape1, memberType, true ); if ( nbMembers == 0 ) return true; if ( nbMembers == 1 ) { return FindSubShapeAssociation( it1.Value(), theMesh1, it2.Value(), theMesh2, theMap ); @@ -762,7 +765,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the if ( groupEdges[ is2ndGroup ].Contains( f.Current() )) if ( ++nbGroupEdges > 1 ) break; - bool add = (nbGroupEdges > 1 || Count( face, TopAbs_EDGE, true ) == 1 ); + bool add = (nbGroupEdges > 1 || + SMESH_MesherHelper::Count( face, TopAbs_EDGE, true ) == 1 ); if ( !add ) { add = true; for ( TopExp_Explorer v( face, TopAbs_VERTEX ); add && v.More(); v.Next()) @@ -779,8 +783,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the } // Associate shells // - int nbFaces1 = Count( shell1, TopAbs_FACE, 0 ); - int nbFaces2 = Count( shell2, TopAbs_FACE, 0 ); + int nbFaces1 = SMESH_MesherHelper:: Count( shell1, TopAbs_FACE, 0 ); + int nbFaces2 = SMESH_MesherHelper:: Count( shell2, TopAbs_FACE, 0 ); if ( nbFaces1 != nbFaces2 ) RETURN_BAD_RESULT("Different nb of faces found for shells"); if ( nbFaces1 > 0 ) { @@ -997,20 +1001,29 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the 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 )); - // find out if any edge of face2 is a propagation edge of outer edge1 - map propag_edges; // use map to find the closest propagation edge - for ( TopExp_Explorer exp( face2, TopAbs_EDGE ); exp.More(); exp.Next() ) { - edge2 = TopoDS::Edge( exp.Current() ); - pair step_edge = GetPropagationEdge( theMesh1, edge2, edge1 ); - if ( !step_edge.second.IsNull() ) { // propagation found - propag_edges.insert( step_edge ); - if ( step_edge.first == 1 ) break; // most close found + TopoDS_Shape wire = OuterShape( face1, TopAbs_WIRE ); + //edge1 = TopoDS::Edge( OuterShape( face1, TopAbs_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() ); + // find out if any edge of face2 is a propagation edge of outer edge1 + for ( TopExp_Explorer exp( face2, TopAbs_EDGE ); exp.More(); exp.Next() ) { + edge2 = TopoDS::Edge( exp.Current() ); + pair step_edge = GetPropagationEdge( theMesh1, edge2, edge1 ); + if ( !step_edge.second.IsNull() ) { // propagation found + propag_edges.insert( make_pair( step_edge.first, + ( make_pair( edge1, step_edge.second )))); + if ( step_edge.first == 1 ) break; // most close found + } } + if ( !propag_edges.empty() && propag_edges.begin()->first == 1 ) break; } 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 ); @@ -1118,7 +1131,11 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the TopoDS_Vertex VV1[2], VV2[2]; if ( vMap1.Extent() != vMap2.Extent() ) - RETURN_BAD_RESULT("Different nb of vertices"); + { + if ( SMESH_MesherHelper:: Count( theShape1, TopAbs_EDGE, /*ignoreSame=*/false ) != + SMESH_MesherHelper:: Count( theShape2, TopAbs_EDGE, /*ignoreSame=*/false )) + RETURN_BAD_RESULT("Different nb of vertices"); + } if ( vMap1.Extent() == 1 ) { InsertAssociation( vMap1(1), vMap2(1), theMap ); @@ -1158,10 +1175,10 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the // Find transformation to make the shapes be of similar size at same location Bnd_Box box[2]; - for ( int i = 1; i <= vMap1.Extent(); ++i ) { + for ( int i = 1; i <= vMap1.Extent(); ++i ) box[ 0 ].Add( BRep_Tool::Pnt ( TopoDS::Vertex( vMap1( i )))); + for ( int i = 1; i <= vMap2.Extent(); ++i ) box[ 1 ].Add( BRep_Tool::Pnt ( TopoDS::Vertex( vMap2( i )))); - } gp_Pnt gc[2]; // box center double x0,y0,z0, x1,y1,z1; @@ -1253,15 +1270,15 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the } //================================================================================ -/*! - * \brief Find association of edges of faces - * \param face1 - face 1 - * \param VV1 - vertices of face 1 - * \param face2 - face 2 - * \param VV2 - vertices of face 2 associated with ones of face 1 - * \param edges1 - out list of edges of face 1 - * \param edges2 - out list of edges of face 2 - * \retval int - nb of edges in an outer wire in a success case, else zero +/* + * Find association of edges of faces + * \param face1 - face 1 + * \param VV1 - vertices of face 1 + * \param face2 - face 2 + * \param VV2 - vertices of face 2 associated with ones of face 1 + * \param edges1 - out list of edges of face 1 + * \param edges2 - out list of edges of face 2 + * \retval int - nb of edges in an outer wire in a success case, else zero */ //================================================================================ @@ -1281,8 +1298,8 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, edges1.clear(); edges2.clear(); - if ( SMESH_Block::GetOrderedEdges( face1, VV1[0], edges1, nbEInW1, outer_wire_algo) != - SMESH_Block::GetOrderedEdges( face2, VV2[0], edges2, nbEInW2, outer_wire_algo) ) + if ( SMESH_Block::GetOrderedEdges( face1, edges1, nbEInW1, VV1[0], outer_wire_algo) != + SMESH_Block::GetOrderedEdges( face2, edges2, nbEInW2, VV2[0], outer_wire_algo) ) CONT_BAD_RESULT("Different number of wires in faces "); if ( nbEInW1 != nbEInW2 && outer_wire_algo == 0 && @@ -1315,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 @@ -1364,8 +1387,8 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, { 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); + SMESH_Block::GetOrderedEdges( face1, edges1, nbEInW1, VV1[0], i_ok_wire_algo); + SMESH_Block::GetOrderedEdges( face2, edges2, nbEInW2, VV2[0], i_ok_wire_algo); } gp_XY dUV = v0f2UV.XY() - v0f1UV.XY(); // UV shift between 2 faces // @@ -1490,12 +1513,12 @@ void StdMeshers_ProjectionUtils::InitVertexAssociation( const SMESH_Hypothesis* } //======================================================================= -/*! - * \brief Inserts association theShape1 <-> theShape2 to TShapeShapeMap - * \param theShape1 - target shape - * \param theShape2 - source shape - * \param theAssociationMap - association map - * \retval bool - true if there was no association for these shapes before +/* + * Inserts association theShape1 <-> theShape2 to TShapeShapeMap + * \param theShape1 - target shape + * \param theShape2 - source shape + * \param theAssociationMap - association map + * \retval bool - true if there was no association for these shapes before */ //======================================================================= @@ -1516,12 +1539,12 @@ bool StdMeshers_ProjectionUtils::InsertAssociation( const TopoDS_Shape& theShape } //======================================================================= -/*! - * \brief Finds an edge by its vertices in a main shape of the mesh - * \param aMesh - the mesh - * \param V1 - vertex 1 - * \param V2 - vertex 2 - * \retval TopoDS_Edge - found edge +/* + * Finds an edge by its vertices in a main shape of the mesh + * \param aMesh - the mesh + * \param V1 - vertex 1 + * \param V2 - vertex 2 + * \retval TopoDS_Edge - found edge */ //======================================================================= @@ -1544,12 +1567,12 @@ TopoDS_Edge StdMeshers_ProjectionUtils::GetEdgeByVertices( SMESH_Mesh* } //================================================================================ -/*! - * \brief Return another face sharing an edge - * \param edgeToFaces - data map of descendants to ancestors - * \param edge - edge - * \param face - face - * \retval TopoDS_Face - found face +/* + * Return another face sharing an edge + * \param edgeToFaces - data map of descendants to ancestors + * \param edge - edge + * \param face - face + * \retval TopoDS_Face - found face */ //================================================================================ @@ -1570,8 +1593,8 @@ TopoDS_Face StdMeshers_ProjectionUtils::GetNextFace( const TAncestorMap& edgeToF } //================================================================================ -/*! - * \brief Return other vertex of an edge +/* + * Return other vertex of an edge */ //================================================================================ @@ -1586,12 +1609,12 @@ TopoDS_Vertex StdMeshers_ProjectionUtils::GetNextVertex(const TopoDS_Edge& edg } //================================================================================ -/*! - * \brief Return a propagation edge - * \param aMesh - mesh - * \param theEdge - edge to find by propagation - * \param fromEdge - start edge for propagation - * \retval pair - propagation step and found edge +/* + * Return a propagation edge + * \param aMesh - mesh + * \param theEdge - edge to find by propagation + * \param fromEdge - start edge for propagation + * \retval pair - propagation step and found edge */ //================================================================================ @@ -1670,16 +1693,16 @@ StdMeshers_ProjectionUtils::GetPropagationEdge( SMESH_Mesh* aMesh, } //================================================================================ - /*! - * \brief Find corresponding nodes on two faces - * \param face1 - the first face - * \param mesh1 - mesh containing elements on the first face - * \param face2 - the second face - * \param mesh2 - mesh containing elements on the second face - * \param assocMap - map associating sub-shapes of the faces - * \param node1To2Map - map containing found matching nodes - * \retval bool - is a success - */ +/* + * Find corresponding nodes on two faces + * \param face1 - the first face + * \param mesh1 - mesh containing elements on the first face + * \param face2 - the second face + * \param mesh2 - mesh containing elements on the second face + * \param assocMap - map associating sub-shapes of the faces + * \param node1To2Map - map containing found matching nodes + * \retval bool - is a success + */ //================================================================================ bool StdMeshers_ProjectionUtils:: @@ -1692,7 +1715,7 @@ FindMatchingNodesOnFaces( const TopoDS_Face& face1, { SMESHDS_Mesh* meshDS1 = mesh1->GetMeshDS(); SMESHDS_Mesh* meshDS2 = mesh2->GetMeshDS(); - + SMESH_MesherHelper helper1( *mesh1 ); SMESH_MesherHelper helper2( *mesh2 ); @@ -1862,12 +1885,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 @@ -1910,7 +1933,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 ); } @@ -1986,23 +2009,23 @@ FindMatchingNodesOnFaces( const TopoDS_Face& face1, node1To2Map.insert( make_pair( vNode1, vNode2 )); } -// don't know why this condition is usually true :( -// if ( node1To2Map.size() * quadFactor < SM1->NbNodes() ) -// MESSAGE("FindMatchingNodes() found too few node pairs starting from nodes (" -// << vNode1->GetID() << " - " << eNode1[0]->GetID() << ") (" -// << vNode2->GetID() << " - " << eNode2[0]->GetID() << "):" -// << node1To2Map.size() * quadFactor << " < " << SM1->NbNodes()); - + // don't know why this condition is usually true :( + // if ( node1To2Map.size() * quadFactor < SM1->NbNodes() ) + // MESSAGE("FindMatchingNodes() found too few node pairs starting from nodes (" + // << vNode1->GetID() << " - " << eNode1[0]->GetID() << ") (" + // << vNode2->GetID() << " - " << eNode2[0]->GetID() << "):" + // << node1To2Map.size() * quadFactor << " < " << SM1->NbNodes()); + return true; } //================================================================================ - /*! - * \brief Return any sub-shape of a face belonging to the outer wire - * \param face - the face - * \param type - type of sub-shape to return - * \retval TopoDS_Shape - the found sub-shape - */ +/* + * Return any sub-shape of a face belonging to the outer wire + * \param face - the face + * \param type - type of sub-shape to return + * \retval TopoDS_Shape - the found sub-shape + */ //================================================================================ TopoDS_Shape StdMeshers_ProjectionUtils::OuterShape( const TopoDS_Face& face, @@ -2015,12 +2038,12 @@ TopoDS_Shape StdMeshers_ProjectionUtils::OuterShape( const TopoDS_Face& face, } //================================================================================ - /*! - * \brief Check that submesh is computed and try to compute it if is not - * \param sm - submesh to compute - * \param iterationNb - int used to stop infinite recursive call - * \retval bool - true if computed - */ +/* + * 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 + */ //================================================================================ bool StdMeshers_ProjectionUtils::MakeComputed(SMESH_subMesh * sm, const int iterationNb) @@ -2032,30 +2055,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; @@ -2082,50 +2140,60 @@ 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; } + //================================================================================ -/*! - * \brief Count nb of sub-shapes - * \param shape - the shape - * \param type - the type of sub-shapes to count - * \retval int - the calculated number +/* + * Returns an error message to show in case if MakeComputed( sm ) fails. */ //================================================================================ -int StdMeshers_ProjectionUtils::Count(const TopoDS_Shape& shape, - const TopAbs_ShapeEnum type, - const bool ignoreSame) +std::string StdMeshers_ProjectionUtils::SourceNotComputedError( SMESH_subMesh * sm, + SMESH_Algo* projAlgo ) { - if ( ignoreSame ) { - TopTools_IndexedMapOfShape map; - TopExp::MapShapes( shape, type, map ); - return map.Extent(); - } - else { - int nb = 0; - for ( TopExp_Explorer exp( shape, type ); exp.More(); exp.Next() ) - ++nb; - return nb; + const char usualMessage [] = "Source mesh not computed"; + if ( !projAlgo ) + return usualMessage; + if ( !sm || sm->GetAlgoState() != SMESH_subMesh::NO_ALGO ) + return usualMessage; // algo is OK, anything else is KO. + + // Try to find a type of all-dimentional algorithm that would compute the + // given sub-mesh if it could be launched before projection + const TopoDS_Shape shape = sm->GetSubShape(); + const int shapeDim = SMESH_Gen::GetShapeDim( shape ); + + for ( int dimIncrement = 1; shapeDim + dimIncrement < 4; ++dimIncrement ) + { + SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() ); + filter.And( filter.HasDim( shapeDim + dimIncrement )); + + SMESH_Algo* algo = (SMESH_Algo*) sm->GetFather()->GetHypothesis( shape, filter, true ); + if ( algo && !algo->NeedDiscreteBoundary() ) + return SMESH_Comment("\"") + << algo->GetFeatures()._label << "\"" + << " can't be used to compute the source mesh for \"" + << projAlgo->GetFeatures()._label << "\" in this case"; } + return usualMessage; } //================================================================================ -/*! - * \brief Return a boundary EDGE of edgeContainer +/* + * Return a boundary EDGE (or all boundary EDGEs) of edgeContainer */ //================================================================================ @@ -2211,11 +2279,11 @@ namespace { // Definition of event listeners } //================================================================================ -/*! - * \brief Set event listeners to submesh with projection algo - * \param subMesh - submesh with projection algo - * \param srcShape - source shape - * \param srcMesh - source mesh +/* + * Set event listeners to submesh with projection algo + * \param subMesh - submesh with projection algo + * \param srcShape - source shape + * \param srcMesh - source mesh */ //================================================================================ @@ -2223,7 +2291,7 @@ void StdMeshers_ProjectionUtils::SetEventListener(SMESH_subMesh* subMesh, TopoDS_Shape srcShape, SMESH_Mesh* srcMesh) { - // Set listener that resets an event listener on source submesh when + // Set the listener that resets an event listener on source submesh when // "ProjectionSource*D" hypothesis is modified since source shape can be changed subMesh->SetEventListener( GetHypModifWaiter(),0,subMesh);