-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2010 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
//
// 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
#include "SMESH_Hypothesis.hxx"
#include "SMESH_IndexedDataMapOfShapeIndexedMapOfShape.hxx"
#include "SMESH_Mesh.hxx"
-#include "SMESH_MeshEditor.hxx"
+#include "SMESH_MesherHelper.hxx"
#include "SMESH_subMesh.hxx"
#include "SMESH_subMeshEventListener.hxx"
#include "SMDS_EdgePosition.hxx"
#define RETURN_BAD_RESULT(msg) { MESSAGE(")-: Error: " << msg); return false; }
-#define SHOW_VERTEX(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 << msg << (v).TShape().operator->()<<" ( " <<p.X()<<", "<<p.Y()<<", "<<p.Z()<<" )"<<endl;}\
+#define CONT_BAD_RESULT(msg) { MESSAGE(")-: Error: " << msg); continue; }
+#define SHOW_VERTEX(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<<msg<<" "<<(v).TShape().operator->()<<" ( "<<p.X()<<", "<<p.Y()<<", "<<p.Z()<<" )"<<endl;}\
// else {\
-// cout << msg << " "; TopAbs::Print(v.ShapeType(),cout) <<" "<<(v).TShape().operator->()<<endl;}\
+// cout << msg << " "; TopAbs::Print((v).ShapeType(),cout) <<" "<<(v).TShape().operator->()<<endl;}\
// }
#define SHOW_LIST(msg,l) \
// { \
SMESH_Mesh* theMesh2,
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.
+ // 2) Accosiate same shapes with different location (partners).
+ // 3) If vertex association is given, perform accosiation according to shape type:
+ // switch ( ShapeType ) {
+ // case TopAbs_EDGE:
+ // case ...:
+ // }
+ // else try to accosiate in different ways:
+ // a) accosiate shapes by propagation and other simple cases
+ // switch ( ShapeType ) {
+ // case TopAbs_EDGE:
+ // case ...:
+ // }
+ // b) find association of a couple of vertices and recall self.
+ //
+
+ // =================================================================================
+ // Is it the case of associating a group member -> another group? (PAL16202, 16203)
+ // =================================================================================
if ( theShape1.ShapeType() != theShape2.ShapeType() ) {
- // is it the case of a group member -> another group? (PAL16202, 16203)
TopoDS_Shape group1, group2;
if ( theShape1.ShapeType() == TopAbs_COMPOUND ) {
group1 = theShape1;
}
bool bidirect = ( !theShape1.IsSame( theShape2 ));
+
+ // ============
+ // Is partner?
+ // ============
+ bool partner = theShape1.IsPartner( theShape2 );
+ TopTools_DataMapIteratorOfDataMapOfShapeShape vvIt( theMap );
+ for ( ; partner && vvIt.More(); vvIt.Next() )
+ partner = vvIt.Key().IsPartner( vvIt.Value() );
+
+ if ( partner ) // Same shape with different location
+ {
+ // recursively associate all subshapes of theShape1 and theShape2
+ typedef list< pair< TopoDS_Shape, TopoDS_Shape > > TShapePairsList;
+ TShapePairsList shapesQueue( 1, make_pair( theShape1, theShape2 ));
+ TShapePairsList::iterator s1_s2 = shapesQueue.begin();
+ for ( ; s1_s2 != shapesQueue.end(); ++s1_s2 )
+ {
+ InsertAssociation( s1_s2->first, s1_s2->second, theMap, bidirect);
+ TopoDS_Iterator s1It( s1_s2->first), s2It( s1_s2->second );
+ for ( ; s1It.More(); s1It.Next(), s2It.Next() )
+ shapesQueue.push_back( make_pair( s1It.Value(), s2It.Value() ));
+ }
+ return true;
+ }
+
if ( !theMap.IsEmpty() )
{
//======================================================================
pair<int,TopoDS_Edge> 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
}
}
if ( !propag_edges.empty() ) // propagation found
*/
//================================================================================
-int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1,
- TopoDS_Vertex VV1[2],
- const TopoDS_Face& face2,
- TopoDS_Vertex VV2[2],
+int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1,
+ TopoDS_Vertex VV1[2],
+ const TopoDS_Face& face2,
+ TopoDS_Vertex VV2[2],
list< TopoDS_Edge > & edges1,
list< TopoDS_Edge > & edges2)
{
- edges1.clear();
- edges2.clear();
-
list< int > nbVInW1, nbVInW2;
- if ( SMESH_Block::GetOrderedEdges( face1, VV1[0], edges1, nbVInW1) !=
- SMESH_Block::GetOrderedEdges( face2, VV2[0], edges2, nbVInW2) )
- RETURN_BAD_RESULT("Different number of wires in faces ");
+ for ( int outer_wire_algo = 0; outer_wire_algo < 2; ++outer_wire_algo )
+ {
+ edges1.clear();
+ edges2.clear();
- if ( nbVInW1.front() != nbVInW2.front() )
- RETURN_BAD_RESULT("Different number of edges in faces: " <<
+ if ( SMESH_Block::GetOrderedEdges( face1, VV1[0], edges1, nbVInW1, outer_wire_algo) !=
+ SMESH_Block::GetOrderedEdges( face2, VV2[0], edges2, nbVInW2, outer_wire_algo) )
+ CONT_BAD_RESULT("Different number of wires in faces ");
+
+ if ( nbVInW1.front() != nbVInW2.front() )
+ CONT_BAD_RESULT("Different number of edges in faces: " <<
nbVInW1.front() << " != " << nbVInW2.front());
- // Define if we need to reverse one of wires to make edges in lists match each other
-
- bool reverse = false;
-
- list< TopoDS_Edge >::iterator eBackIt;
- if ( !VV1[1].IsSame( TopExp::LastVertex( edges1.front(), true ))) {
- reverse = true;
- eBackIt = --edges1.end();
- // check if the second vertex belongs to the first or last edge in the wire
- if ( !VV1[1].IsSame( TopExp::FirstVertex( *eBackIt, true ))) {
- bool KO = true; // belongs to none
- if ( nbVInW1.size() > 1 ) { // several wires
- eBackIt = edges1.begin();
- for ( int i = 1; i < nbVInW1.front(); ++i ) ++eBackIt;
- KO = !VV1[1].IsSame( TopExp::FirstVertex( *eBackIt, true ));
+ // Define if we need to reverse one of wires to make edges in lists match each other
+
+ bool reverse = false;
+
+ list< TopoDS_Edge >::iterator edgeIt;
+ if ( !VV1[1].IsSame( TopExp::LastVertex( edges1.front(), true ))) {
+ reverse = true;
+ edgeIt = --edges1.end();
+ // 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
+ edgeIt = edges1.begin();
+ for ( int i = 1; i < nbVInW1.front(); ++i ) ++edgeIt;
+ KO = !VV1[1].IsSame( TopExp::FirstVertex( *edgeIt, true ));
+ }
+ if ( KO )
+ CONT_BAD_RESULT("GetOrderedEdges() failed");
}
- if ( KO )
- RETURN_BAD_RESULT("GetOrderedEdges() failed");
}
- }
- eBackIt = --edges2.end();
- if ( !VV2[1].IsSame( TopExp::LastVertex( edges2.front(), true ))) {
- reverse = !reverse;
- // check if the second vertex belongs to the first or last edge in the wire
- if ( !VV2[1].IsSame( TopExp::FirstVertex( *eBackIt, true ))) {
- bool KO = true; // belongs to none
- if ( nbVInW2.size() > 1 ) { // several wires
- eBackIt = edges2.begin();
- for ( int i = 1; i < nbVInW2.front(); ++i ) ++eBackIt;
- KO = !VV2[1].IsSame( TopExp::FirstVertex( *eBackIt, true ));
+ edgeIt = --edges2.end();
+ if ( !VV2[1].IsSame( TopExp::LastVertex( edges2.front(), true ))) {
+ reverse = !reverse;
+ // 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
+ edgeIt = edges2.begin();
+ for ( int i = 1; i < nbVInW2.front(); ++i ) ++edgeIt;
+ KO = !VV2[1].IsSame( TopExp::FirstVertex( *edgeIt, true ));
+ }
+ if ( KO )
+ CONT_BAD_RESULT("GetOrderedEdges() failed");
}
- if ( KO )
- RETURN_BAD_RESULT("GetOrderedEdges() failed");
}
- }
- if ( reverse )
- {
- Reverse( edges2 , nbVInW2.front());
- if (( VV1[1].IsSame( TopExp::LastVertex( edges1.front(), true ))) !=
- ( VV2[1].IsSame( TopExp::LastVertex( edges2.front(), true ))))
- RETURN_BAD_RESULT("GetOrderedEdges() failed");
+ if ( reverse )
+ {
+ Reverse( edges2 , nbVInW2.front());
+ if (( VV1[1].IsSame( TopExp::LastVertex( edges1.front(), true ))) !=
+ ( VV2[1].IsSame( TopExp::LastVertex( edges2.front(), true ))))
+ CONT_BAD_RESULT("GetOrderedEdges() failed");
+ }
}
return nbVInW2.front();
}
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
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
notInSet.insert( f2 );
for ( int i = 0; i < nbNodes; ++i ) {
const SMDS_MeshNode* n1 = faceToKeep->GetNode( i );
- const SMDS_MeshNode* n2 = faceToKeep->GetNode( i+1 );
+ const SMDS_MeshNode* n2 = faceToKeep->GetNode( i+1 % nbNodes );
f1 = SMESH_MeshEditor::FindFaceInSet( n1, n2, inSet, notInSet );
if ( f1 )
elems.insert( f1 );
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
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