-// 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
{
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();
//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()
//=======================================================================
return true;
}
+//=======================================================================
+//function : GetMediumPos
+//purpose : Return index and type of the shape (EDGE or FACE only) to
+// set a medium node on
+//=======================================================================
+
+std::pair<int, TopAbs_ShapeEnum> 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
// 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<int, TopAbs_ShapeEnum> 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 ));
for ( int i = 0; i < nodes.size(); ++i )
{
const SMDS_MeshNode* n1 = nodes[i];
- const SMDS_MeshNode* n2 = nodes[(i+1)/nodes.size()];
+ const SMDS_MeshNode* n2 = nodes[(i+1)%nodes.size()];
const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
newNodes.push_back( n1 );
newNodes.push_back( n12 );
double f, l;
BRep_Tool::Range( *edge, f, l );
if ( edge->Orientation() == 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++ )
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 <Perf_Meter.hxx>
//=======================================================================