X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH%2FSMESH_MesherHelper.cxx;h=b0fd1351a89e21a14adeadee55e6f3d1ff56ee4f;hp=c8c149da6fbc27d2814248cc68505d2b2c0340be;hb=d4a710ce52f6e76786a7b3845e2f7975dc9a00b1;hpb=eaff026082ad84e0e699eb0a8fec91173711fe2c diff --git a/src/SMESH/SMESH_MesherHelper.cxx b/src/SMESH/SMESH_MesherHelper.cxx index c8c149da6..b0fd1351a 100644 --- a/src/SMESH/SMESH_MesherHelper.cxx +++ b/src/SMESH/SMESH_MesherHelper.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 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 @@ -114,7 +114,7 @@ bool SMESH_MesherHelper::IsQuadraticSubMesh(const TopoDS_Shape& aSh) { SMESHDS_Mesh* meshDS = GetMeshDS(); // we can create quadratic elements only if all elements - // created on subshapes of given shape are quadratic + // created on sub-shapes of given shape are quadratic // also we have to fill myTLinkNodeMap myCreateQuadratic = true; mySeamShapeIds.clear(); @@ -279,7 +279,7 @@ void SMESH_MesherHelper::SetSubShape(const TopoDS_Shape& aSh) //function : GetNodeUVneedInFaceNode //purpose : Check if inFaceNode argument is necessary for call GetNodeUV(F,..) // Return true if the face is periodic. -// If F is Null, answer about subshape set through IsQuadraticSubMesh() or +// If F is Null, answer about sub-shape set through IsQuadraticSubMesh() or // * SetSubShape() //======================================================================= @@ -893,6 +893,85 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge& E, return true; } +//======================================================================= +//function : GetMediumPos +//purpose : Return index and type of the shape (EDGE or FACE only) to +// set a medium node on +//======================================================================= + +std::pair SMESH_MesherHelper::GetMediumPos(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2) +{ + TopAbs_ShapeEnum shapeType = TopAbs_SHAPE; + int shapeID = -1; + TopoDS_Shape shape; + + if (( myShapeID == n1->getshapeId() || myShapeID == n2->getshapeId() ) && myShapeID > 0 ) + { + shapeType = myShape.ShapeType(); + shapeID = myShapeID; + } + else if ( n1->getshapeId() == n2->getshapeId() ) + { + shapeID = n2->getshapeId(); + shape = GetSubShapeByNode( n1, GetMeshDS() ); + } + else + { + const SMDS_TypeOfPosition Pos1 = n1->GetPosition()->GetTypeOfPosition(); + const SMDS_TypeOfPosition Pos2 = n2->GetPosition()->GetTypeOfPosition(); + + if ( Pos1 == SMDS_TOP_3DSPACE || Pos2 == SMDS_TOP_3DSPACE ) + { + } + else if ( Pos1 == SMDS_TOP_FACE || Pos2 == SMDS_TOP_FACE ) + { + if ( Pos1 != SMDS_TOP_FACE || Pos2 != SMDS_TOP_FACE ) + { + if ( Pos1 != SMDS_TOP_FACE ) std::swap( n1,n2 ); + TopoDS_Shape F = GetSubShapeByNode( n1, GetMeshDS() ); + TopoDS_Shape S = GetSubShapeByNode( n2, GetMeshDS() ); + if ( IsSubShape( S, F )) + { + shapeType = TopAbs_FACE; + shapeID = n1->getshapeId(); + } + } + } + else if ( Pos1 == SMDS_TOP_EDGE && Pos2 == SMDS_TOP_EDGE ) + { + TopoDS_Shape E1 = GetSubShapeByNode( n1, GetMeshDS() ); + TopoDS_Shape E2 = GetSubShapeByNode( n2, GetMeshDS() ); + shape = GetCommonAncestor( E1, E2, *myMesh, TopAbs_FACE ); + } + else if ( Pos1 == SMDS_TOP_VERTEX && Pos2 == SMDS_TOP_VERTEX ) + { + TopoDS_Shape V1 = GetSubShapeByNode( n1, GetMeshDS() ); + TopoDS_Shape V2 = GetSubShapeByNode( n2, GetMeshDS() ); + shape = GetCommonAncestor( V1, V2, *myMesh, TopAbs_EDGE ); + if ( shape.IsNull() ) shape = GetCommonAncestor( V1, V2, *myMesh, TopAbs_FACE ); + } + else // VERTEX and EDGE + { + if ( Pos1 != SMDS_TOP_VERTEX ) std::swap( n1,n2 ); + TopoDS_Shape V = GetSubShapeByNode( n1, GetMeshDS() ); + TopoDS_Shape E = GetSubShapeByNode( n2, GetMeshDS() ); + if ( IsSubShape( V, E )) + shape = E; + else + shape = GetCommonAncestor( V, E, *myMesh, TopAbs_FACE ); + } + } + + if ( !shape.IsNull() ) + { + if ( shapeID < 1 ) + shapeID = GetMeshDS()->ShapeToIndex( shape ); + shapeType = shape.ShapeType(); + } + return make_pair( shapeID, shapeType ); +} + //======================================================================= //function : GetMediumNode //purpose : Return existing or create new medium nodes between given ones @@ -921,65 +1000,42 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1, // get type of shape for the new medium node int faceID = -1, edgeID = -1; - const SMDS_PositionPtr Pos1 = n1->GetPosition(); - const SMDS_PositionPtr Pos2 = n2->GetPosition(); - TopoDS_Edge E; double u [2]; TopoDS_Face F; gp_XY uv[2]; bool uvOK[2] = { false, false }; - if( myShape.IsNull() ) - { - if( Pos1->GetTypeOfPosition()==SMDS_TOP_FACE ) { - faceID = n1->getshapeId(); - } - else if( Pos2->GetTypeOfPosition()==SMDS_TOP_FACE ) { - faceID = n2->getshapeId(); - } + pair pos = GetMediumPos( n1, n2 ); - if( Pos1->GetTypeOfPosition()==SMDS_TOP_EDGE ) { - edgeID = n1->getshapeId(); - } - if( Pos2->GetTypeOfPosition()==SMDS_TOP_EDGE ) { - edgeID = n2->getshapeId(); - } - } // get positions of the given nodes on shapes - TopAbs_ShapeEnum shapeType = myShape.IsNull() ? TopAbs_SHAPE : myShape.ShapeType(); - if ( faceID>0 || shapeType == TopAbs_FACE) + if ( pos.second == TopAbs_FACE ) { - if( myShape.IsNull() ) - F = TopoDS::Face(meshDS->IndexToShape(faceID)); - else { - F = TopoDS::Face(myShape); - faceID = myShapeID; - } + F = TopoDS::Face(meshDS->IndexToShape( faceID = pos.first )); uv[0] = GetNodeUV(F,n1,n2, force3d ? 0 : &uvOK[0]); uv[1] = GetNodeUV(F,n2,n1, force3d ? 0 : &uvOK[1]); } - else if (edgeID>0 || shapeType == TopAbs_EDGE) + else if ( pos.second == TopAbs_EDGE ) { + const SMDS_PositionPtr Pos1 = n1->GetPosition(); + const SMDS_PositionPtr Pos2 = n2->GetPosition(); if ( Pos1->GetTypeOfPosition()==SMDS_TOP_EDGE && Pos2->GetTypeOfPosition()==SMDS_TOP_EDGE && - n1->getshapeId() != n2->getshapeId() ) // issue 0021006 - return getMediumNodeOnComposedWire(n1,n2,force3d); - - if( myShape.IsNull() ) - E = TopoDS::Edge(meshDS->IndexToShape(edgeID)); - else { - E = TopoDS::Edge(myShape); - edgeID = myShapeID; + n1->getshapeId() != n2->getshapeId() ) + { + // issue 0021006 + return getMediumNodeOnComposedWire(n1,n2,force3d); } + E = TopoDS::Edge(meshDS->IndexToShape( edgeID = pos.first )); u[0] = GetNodeU(E,n1,n2, force3d ? 0 : &uvOK[0]); u[1] = GetNodeU(E,n2,n1, force3d ? 0 : &uvOK[1]); } - if(!force3d) + + if ( !force3d & uvOK[0] && uvOK[1] ) { // we try to create medium node using UV parameters of // nodes, else - medium between corresponding 3d points if( ! F.IsNull() ) { - if ( uvOK[0] && uvOK[1] ) + //if ( uvOK[0] && uvOK[1] ) { if ( IsDegenShape( n1->getshapeId() )) { if ( myParIndex & U_periodic ) uv[0].SetCoord( 1, uv[1].Coord( 1 )); @@ -1303,7 +1359,7 @@ SMDS_MeshFace* SMESH_MesherHelper::AddPolygonalFace (const vectorOrientation() == TopAbs_REVERSED ) std::swap( f, l ); - const double coeff = 1. / ( l - f ) / length[iE] / fullLen; + const double coeff = 1. / ( l - f ) * length[iE] / fullLen; const double prevPar = theParam2ColumnMap.empty() ? 0 : theParam2ColumnMap.rbegin()->first; map< double, const SMDS_MeshNode*>::iterator u_n = sortedBaseNodes.begin(); for ( ; u_n != sortedBaseNodes.end(); u_n++ ) @@ -1933,6 +1989,30 @@ PShapeIteratorPtr SMESH_MesherHelper::GetAncestors(const TopoDS_Shape& shape, return PShapeIteratorPtr( new TAncestorsIterator( mesh.GetAncestors(shape), ancestorType)); } +//======================================================================= +//function : GetCommonAncestor +//purpose : Find a common ancestors of two shapes of the given type +//======================================================================= + +TopoDS_Shape SMESH_MesherHelper::GetCommonAncestor(const TopoDS_Shape& shape1, + const TopoDS_Shape& shape2, + const SMESH_Mesh& mesh, + TopAbs_ShapeEnum ancestorType) +{ + TopoDS_Shape commonAnc; + if ( !shape1.IsNull() && !shape2.IsNull() ) + { + PShapeIteratorPtr ancIt = GetAncestors( shape1, mesh, ancestorType ); + while ( const TopoDS_Shape* anc = ancIt->next() ) + if ( IsSubShape( shape2, *anc )) + { + commonAnc = *anc; + break; + } + } + return commonAnc; +} + //#include //=======================================================================