Version: 6.3.1
Public Types | Public Member Functions | Static Public Member Functions | Protected Member Functions | Private Types | Private Member Functions | Private Attributes

SMESH_MesherHelper Class Reference

It helps meshers to add elements. More...

#include <SMESH_MesherHelper.hxx>

Public Types

enum  MType { LINEAR, QUADRATIC, COMP }
 

Check mesh without geometry for: if all elements on this shape are quadratic, quadratic elements will be created.

More...

Public Member Functions

 SMESH_MesherHelper (SMESH_Mesh &theMesh)
 Constructor.
SMESH_MeshGetMesh () const
SMESHDS_MeshGetMeshDS () const
bool IsQuadraticSubMesh (const TopoDS_Shape &theShape)
 Check submesh for given shape: if all elements on this shape are quadratic, quadratic elements will be created.
void SetIsQuadratic (const bool theBuildQuadratic)
 Set order of elements to create without calling IsQuadraticSubMesh()
bool GetIsQuadratic () const
 Return myCreateQuadratic flag.
void FixQuadraticElements (bool volumeOnly=true)
 Move medium nodes of faces and volumes to fix distorted elements.
void SetElementsOnShape (bool toSet)
 To set created elements on the shape set by IsQuadraticSubMesh() or the next methods.
void SetSubShape (const int subShapeID)
 Set shape to make elements on without calling IsQuadraticSubMesh()
void SetSubShape (const TopoDS_Shape &subShape)
 ==SMESHDS_Mesh::ShapeToIndex(shape)
int GetSubShapeID () const
 Return ID of the shape set by IsQuadraticSubMesh() or SetSubShape()
const TopoDS_Shape & GetSubShape () const
 Return the shape set by IsQuadraticSubMesh() or SetSubShape()
SMDS_MeshNodeAddNode (double x, double y, double z, int ID=0)
 Creates a node.
SMDS_MeshEdgeAddEdge (const SMDS_MeshNode *n1, const SMDS_MeshNode *n2, const int id=0, const bool force3d=true)
 Creates quadratic or linear edge.
SMDS_MeshFaceAddFace (const SMDS_MeshNode *n1, const SMDS_MeshNode *n2, const SMDS_MeshNode *n3, const int id=0, const bool force3d=false)
 Creates quadratic or linear triangle.
SMDS_MeshFaceAddFace (const SMDS_MeshNode *n1, const SMDS_MeshNode *n2, const SMDS_MeshNode *n3, const SMDS_MeshNode *n4, const int id=0, const bool force3d=false)
 Creates quadratic or linear quadrangle.
SMDS_MeshFaceAddPolygonalFace (const std::vector< const SMDS_MeshNode * > &nodes, const int id=0, const bool force3d=false)
 Creates polygon, with additional nodes in quadratic mesh.
SMDS_MeshVolumeAddVolume (const SMDS_MeshNode *n1, const SMDS_MeshNode *n2, const SMDS_MeshNode *n3, const SMDS_MeshNode *n4, const int id=0, const bool force3d=true)
 Creates quadratic or linear tetrahedron.
SMDS_MeshVolumeAddVolume (const SMDS_MeshNode *n1, const SMDS_MeshNode *n2, const SMDS_MeshNode *n3, const SMDS_MeshNode *n4, const SMDS_MeshNode *n5, const int id=0, const bool force3d=true)
 Creates quadratic or linear pyramid.
SMDS_MeshVolumeAddVolume (const SMDS_MeshNode *n1, const SMDS_MeshNode *n2, const SMDS_MeshNode *n3, const SMDS_MeshNode *n4, const SMDS_MeshNode *n5, const SMDS_MeshNode *n6, const int id=0, const bool force3d=true)
 Creates quadratic or linear pentahedron.
SMDS_MeshVolumeAddVolume (const SMDS_MeshNode *n1, const SMDS_MeshNode *n2, const SMDS_MeshNode *n3, const SMDS_MeshNode *n4, const SMDS_MeshNode *n5, const SMDS_MeshNode *n6, const SMDS_MeshNode *n7, const SMDS_MeshNode *n8, const int id=0, bool force3d=true)
 Creates quadratic or linear hexahedron.
SMDS_MeshVolumeAddPolyhedralVolume (const std::vector< const SMDS_MeshNode * > &nodes, const std::vector< int > &quantities, const int ID=0, const bool force3d=true)
 Creates polyhedron.
double GetNodeU (const TopoDS_Edge &theEdge, const SMDS_MeshNode *theNode, const SMDS_MeshNode *inEdgeNode=0, bool *check=0)
 Return U of the given node on the edge.
gp_XY GetNodeUV (const TopoDS_Face &F, const SMDS_MeshNode *n, const SMDS_MeshNode *inFaceNode=0, bool *check=0) const
 Return node UV on face.
bool CheckNodeUV (const TopoDS_Face &F, const SMDS_MeshNode *n, gp_XY &uv, const double tol, const bool force=false, double distXYZ[4]=0) const
 Check and fix node UV on a face.
bool CheckNodeU (const TopoDS_Edge &E, const SMDS_MeshNode *n, double &u, const double tol, const bool force=false, double distXYZ[4]=0) const
 Check and fix node U on an edge.
bool GetNodeUVneedInFaceNode (const TopoDS_Face &F=TopoDS_Face()) const
 Check if inFaceNode argument is necessary for call GetNodeUV(F,..)
GeomAPI_ProjectPointOnSurf & GetProjector (const TopoDS_Face &F, TopLoc_Location &loc, double tol=0) const
 Return projector intitialized by given face without location, which is returned.
bool IsDegenShape (const int subShape) const
 Check if shape is a degenerated edge or it's vertex.
bool HasDegeneratedEdges () const
 Check if the shape set through IsQuadraticSubMesh() or SetSubShape() has a degenerated edges.
bool IsSeamShape (const int subShape) const
 Check if shape is a seam edge or it's vertex.
bool IsSeamShape (const TopoDS_Shape &subShape) const
 Check if shape is a seam edge or it's vertex.
bool IsRealSeam (const int subShape) const
 Return true if an edge or a vertex encounters twice in face wire.
bool IsRealSeam (const TopoDS_Shape &subShape) const
 Return true if an edge or a vertex encounters twice in face wire.
bool HasSeam () const
 Check if the shape set through IsQuadraticSubMesh() or SetSubShape() has a seam edge.
int GetPeriodicIndex () const
 Return index of periodic parametric direction of a closed face.
double GetOtherParam (const double param) const
 Return an alternative parameter for a node on seam.
const SMDS_MeshNodeGetMediumNode (const SMDS_MeshNode *n1, const SMDS_MeshNode *n2, const bool force3d)
 Return existing or create new medium nodes between given ones.
void AddTLinkNode (const SMDS_MeshNode *n1, const SMDS_MeshNode *n2, const SMDS_MeshNode *n12)
 Add a link in my data structure.
void AddTLinkNodeMap (const TLinkNodeMap &aMap)
 Add many links in my data structure.
void AddTLinks (const SMDS_MeshEdge *edge)
 Add quadratic links of edge to own data structure.
void AddTLinks (const SMDS_MeshFace *face)
 Add quadratic links of face to own data structure.
void AddTLinks (const SMDS_MeshVolume *vol)
 Add quadratic links of volume to own data structure.
const TLinkNodeMapGetTLinkNodeMap () const
 Returns myTLinkNodeMap.
MType IsQuadraticMesh ()
virtual ~SMESH_MesherHelper ()

Static Public Member Functions

static bool IsMedium (const SMDS_MeshNode *node, const SMDSAbs_ElementType typeToCheck=SMDSAbs_All)
 Returns true if given node is medium.
static bool LoadNodeColumns (TParam2ColumnMap &theParam2ColumnMap, const TopoDS_Face &theFace, const TopoDS_Edge &theBaseEdge, SMESHDS_Mesh *theMesh, SMESH_ProxyMesh *theProxyMesh=0)
 Load nodes bound to face into a map of node columns.
static TopoDS_Shape GetSubShapeByNode (const SMDS_MeshNode *node, const SMESHDS_Mesh *meshDS)
 Return support shape of a node.
static int WrapIndex (const int ind, const int nbNodes)
 Return a valid node index, fixing the given one if necessary.
static int NbAncestors (const TopoDS_Shape &shape, const SMESH_Mesh &mesh, TopAbs_ShapeEnum ancestorType=TopAbs_SHAPE)
 Return number of unique ancestors of the shape.
static PShapeIteratorPtr GetAncestors (const TopoDS_Shape &shape, const SMESH_Mesh &mesh, TopAbs_ShapeEnum ancestorType)
 Return iterator on ancestors of the given type.
static TopAbs_Orientation GetSubShapeOri (const TopoDS_Shape &shape, const TopoDS_Shape &subShape)
 Return orientation of sub-shape in the main shape.
static bool IsSubShape (const TopoDS_Shape &shape, const TopoDS_Shape &mainShape)
static bool IsSubShape (const TopoDS_Shape &shape, SMESH_Mesh *aMesh)
static double MaxTolerance (const TopoDS_Shape &shape)
 Return maximal tolerance of shape.
static bool IsClosedEdge (const TopoDS_Edge &anEdge)
 Check if the first and last vertices of an edge are the same.
static TopoDS_Vertex IthVertex (const bool is2nd, TopoDS_Edge anEdge, const bool CumOri=true)
 Wrapper over TopExp.FirstVertex() and TopExp.LastVertex() fixing them in the case of INTERNAL edge.
static gp_XY GetMiddleUV (const Handle(Geom_Surface)&surface, const gp_XY &uv1, const gp_XY &uv2)
 Return middle UV taking in account surface period.
static gp_XY applyIn2D (const Handle(Geom_Surface)&surface, const gp_XY &uv1, const gp_XY &uv2, xyFunPtr fun, const bool resultInPeriod=true)
 Perform given operation on two 2d points in parameric space of given surface.

Protected Member Functions

gp_Pnt2d GetUVOnSeam (const gp_Pnt2d &uv1, const gp_Pnt2d &uv2) const
 Select UV on either of 2 pcurves of a seam edge, closest to the given UV.
const SMDS_MeshNodegetMediumNodeOnComposedWire (const SMDS_MeshNode *n1, const SMDS_MeshNode *n2, bool force3d)
 Makes a medium node if nodes reside different edges.

Private Types

typedef std::map< int,
GeomAPI_ProjectPointOnSurf * > 
TID2ProjectorOnSurf
typedef std::map< int,
GeomAPI_ProjectPointOnCurve * > 
TID2ProjectorOnCurve

Private Member Functions

 SMESH_MesherHelper (const SMESH_MesherHelper &theOther)
bool toCheckPosOnShape (int shapeID) const
 Return true if position of nodes on the shape hasn't yet been checked or the positions proved to be invalid.
void setPosOnShapeValidity (int shapeID, bool ok) const
 Set validity of positions of nodes on the shape.

Private Attributes

TLinkNodeMap myTLinkNodeMap
std::set< intmyDegenShapeIds
std::set< intmySeamShapeIds
double myPar1 [2]
double myPar2 [2]
int myParIndex
TID2ProjectorOnSurf myFace2Projector
TID2ProjectorOnCurve myEdge2Projector
TopoDS_Shape myShape
SMESH_MeshmyMesh
int myShapeID
bool myCreateQuadratic
bool mySetElemOnShape
std::map< int, boolmyNodePosShapesValidity

Detailed Description

It helps meshers to add elements.

It allow meshers not to care about creation of medium nodes when filling a quadratic mesh. Helper does it itself. It defines degree of elements to create when IsQuadraticSubMesh() is called.

Definition at line 70 of file SMESH_MesherHelper.hxx.


Member Typedef Documentation

typedef std::map< int, GeomAPI_ProjectPointOnCurve* > SMESH_MesherHelper.TID2ProjectorOnCurve [private]

Definition at line 507 of file SMESH_MesherHelper.hxx.

typedef std::map< int, GeomAPI_ProjectPointOnSurf* > SMESH_MesherHelper.TID2ProjectorOnSurf [private]

Definition at line 505 of file SMESH_MesherHelper.hxx.


Member Enumeration Documentation

Check mesh without geometry for: if all elements on this shape are quadratic, quadratic elements will be created.

Used then generated 3D mesh without geometry.

Enumerator:
LINEAR 
QUADRATIC 
COMP 

Definition at line 474 of file SMESH_MesherHelper.hxx.


Constructor & Destructor Documentation

SMESH_MesherHelper::SMESH_MesherHelper ( SMESH_Mesh theMesh)

Constructor.

Definition at line 80 of file SMESH_MesherHelper.cxx.

References myMesh, myPar1, myPar2, and mySetElemOnShape.

  : myParIndex(0), myMesh(&theMesh), myShapeID(0), myCreateQuadratic(false)
{
  myPar1[0] = myPar2[0] = myPar1[1] = myPar2[1] = 0;
  mySetElemOnShape = ( ! myMesh->HasShapeToMesh() );
}
SMESH_MesherHelper::~SMESH_MesherHelper ( ) [virtual]

Definition at line 92 of file SMESH_MesherHelper.cxx.

References myEdge2Projector, and myFace2Projector.

{
  {
    TID2ProjectorOnSurf::iterator i_proj = myFace2Projector.begin();
    for ( ; i_proj != myFace2Projector.end(); ++i_proj )
      delete i_proj->second;
  }
  {
    TID2ProjectorOnCurve::iterator i_proj = myEdge2Projector.begin();
    for ( ; i_proj != myEdge2Projector.end(); ++i_proj )
      delete i_proj->second;
  }
}
SMESH_MesherHelper.SMESH_MesherHelper ( const SMESH_MesherHelper theOther) [private]

Definition at line 495 of file SMESH_MesherHelper.hxx.

{};

Member Function Documentation

SMDS_MeshEdge * SMESH_MesherHelper::AddEdge ( const SMDS_MeshNode n1,
const SMDS_MeshNode n2,
const int  id = 0,
const bool  force3d = true 
)

Creates quadratic or linear edge.

Definition at line 1158 of file SMESH_MesherHelper.cxx.

References SMESHDS_Mesh.AddEdge(), SMESHDS_Mesh.AddEdgeWithID(), SMESH_test.edge, GetMediumNode(), GetMeshDS(), myCreateQuadratic, mySetElemOnShape, myShapeID, and SMESHDS_Mesh.SetMeshElementOnShape().

Referenced by SMESH_MeshEditor.convertElemToQuadratic(), and SMESH_MeshEditor.ConvertToQuadratic().

{
  SMESHDS_Mesh * meshDS = GetMeshDS();
  
  SMDS_MeshEdge* edge = 0;
  if (myCreateQuadratic) {
    const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
    if(id)
      edge = meshDS->AddEdgeWithID(n1, n2, n12, id);
    else
      edge = meshDS->AddEdge(n1, n2, n12);
  }
  else {
    if(id)
      edge = meshDS->AddEdgeWithID(n1, n2, id);
    else
      edge = meshDS->AddEdge(n1, n2);
  }

  if ( mySetElemOnShape && myShapeID > 0 )
    meshDS->SetMeshElementOnShape( edge, myShapeID );

  return edge;
}
SMDS_MeshFace * SMESH_MesherHelper::AddFace ( const SMDS_MeshNode n1,
const SMDS_MeshNode n2,
const SMDS_MeshNode n3,
const int  id = 0,
const bool  force3d = false 
)

Creates quadratic or linear triangle.

Definition at line 1191 of file SMESH_MesherHelper.cxx.

References SMESHDS_Mesh.AddFace(), SMESHDS_Mesh.AddFaceWithID(), GetMediumNode(), GetMeshDS(), myCreateQuadratic, mySetElemOnShape, myShapeID, and SMESHDS_Mesh.SetMeshElementOnShape().

Referenced by AddFace(), SMESH_MeshEditor.convertElemToQuadratic(), SMESH_MeshEditor.ConvertToQuadratic(), StdMeshers_Penta_3D.MakeMeshOnFxy1(), and SMESH_MeshEditor.SplitVolumesIntoTetra().

{
  SMESHDS_Mesh * meshDS = GetMeshDS();
  SMDS_MeshFace* elem = 0;

  if( n1==n2 || n2==n3 || n3==n1 )
    return elem;

  if(!myCreateQuadratic) {
    if(id)
      elem = meshDS->AddFaceWithID(n1, n2, n3, id);
    else
      elem = meshDS->AddFace(n1, n2, n3);
  }
  else {
    const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
    const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
    const SMDS_MeshNode* n31 = GetMediumNode(n3,n1,force3d);

    if(id)
      elem = meshDS->AddFaceWithID(n1, n2, n3, n12, n23, n31, id);
    else
      elem = meshDS->AddFace(n1, n2, n3, n12, n23, n31);
  }
  if ( mySetElemOnShape && myShapeID > 0 )
    meshDS->SetMeshElementOnShape( elem, myShapeID );

  return elem;
}
SMDS_MeshFace * SMESH_MesherHelper::AddFace ( const SMDS_MeshNode n1,
const SMDS_MeshNode n2,
const SMDS_MeshNode n3,
const SMDS_MeshNode n4,
const int  id = 0,
const bool  force3d = false 
)

Creates quadratic or linear quadrangle.

Definition at line 1230 of file SMESH_MesherHelper.cxx.

References SMESHDS_Mesh.AddFace(), AddFace(), SMESHDS_Mesh.AddFaceWithID(), GetMediumNode(), GetMeshDS(), myCreateQuadratic, mySetElemOnShape, myShapeID, and SMESHDS_Mesh.SetMeshElementOnShape().

{
  SMESHDS_Mesh * meshDS = GetMeshDS();
  SMDS_MeshFace* elem = 0;

  if( n1==n2 ) {
    return AddFace(n1,n3,n4,id,force3d);
  }
  if( n1==n3 ) {
    return AddFace(n1,n2,n4,id,force3d);
  }
  if( n1==n4 ) {
    return AddFace(n1,n2,n3,id,force3d);
  }
  if( n2==n3 ) {
    return AddFace(n1,n2,n4,id,force3d);
  }
  if( n2==n4 ) {
    return AddFace(n1,n2,n3,id,force3d);
  }
  if( n3==n4 ) {
    return AddFace(n1,n2,n3,id,force3d);
  }

  if(!myCreateQuadratic) {
    if(id)
      elem = meshDS->AddFaceWithID(n1, n2, n3, n4, id);
    else
      elem = meshDS->AddFace(n1, n2, n3, n4);
  }
  else {
    const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
    const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
    const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,force3d);
    const SMDS_MeshNode* n41 = GetMediumNode(n4,n1,force3d);

    if(id)
      elem = meshDS->AddFaceWithID(n1, n2, n3, n4, n12, n23, n34, n41, id);
    else
      elem = meshDS->AddFace(n1, n2, n3, n4, n12, n23, n34, n41);
  }
  if ( mySetElemOnShape && myShapeID > 0 )
    meshDS->SetMeshElementOnShape( elem, myShapeID );

  return elem;
}
SMDS_MeshNode * SMESH_MesherHelper::AddNode ( double  x,
double  y,
double  z,
int  ID = 0 
)

Creates a node.

Definition at line 1132 of file SMESH_MesherHelper.cxx.

References SMESHDS_Mesh.AddNode(), SMESHDS_Mesh.AddNodeWithID(), GetMeshDS(), mySetElemOnShape, myShape, myShapeID, ex29_refine.node(), SMESHDS_Mesh.SetNodeInVolume(), SMESHDS_Mesh.SetNodeOnEdge(), SMESHDS_Mesh.SetNodeOnFace(), and SMESHDS_Mesh.SetNodeOnVertex().

Referenced by StdMeshers_QuadToTriaAdaptor.Compute(), StdMeshers_HexaFromSkin_3D.Compute(), StdMeshers_Hexa_3D.Compute(), StdMeshers_CompositeHexa_3D.Compute(), getMediumNodeOnComposedWire(), VISCOUS._ViscousBuilder.makeLayer(), VISCOUS._ViscousBuilder.refine(), and SMESH_MeshEditor.SplitVolumesIntoTetra().

{
  SMESHDS_Mesh * meshDS = GetMeshDS();
  SMDS_MeshNode* node = 0;
  if ( ID )
    node = meshDS->AddNodeWithID( x, y, z, ID );
  else
    node = meshDS->AddNode( x, y, z );
  if ( mySetElemOnShape && myShapeID > 0 ) {
    switch ( myShape.ShapeType() ) {
    case TopAbs_SOLID:  meshDS->SetNodeInVolume( node, myShapeID); break;
    case TopAbs_SHELL:  meshDS->SetNodeInVolume( node, myShapeID); break;
    case TopAbs_FACE:   meshDS->SetNodeOnFace(   node, myShapeID); break;
    case TopAbs_EDGE:   meshDS->SetNodeOnEdge(   node, myShapeID); break;
    case TopAbs_VERTEX: meshDS->SetNodeOnVertex( node, myShapeID); break;
    default: ;
    }
  }
  return node;
}
SMDS_MeshFace * SMESH_MesherHelper::AddPolygonalFace ( const std::vector< const SMDS_MeshNode * > &  nodes,
const int  id = 0,
const bool  force3d = false 
)

Creates polygon, with additional nodes in quadratic mesh.

Definition at line 1287 of file SMESH_MesherHelper.cxx.

References SMESHDS_Mesh.AddPolygonalFace(), SMESHDS_Mesh.AddPolygonalFaceWithID(), GetMediumNode(), GetMeshDS(), myCreateQuadratic, mySetElemOnShape, myShapeID, SMESH_AdvancedEditor.n1, SMESH_AdvancedEditor.n2, and SMESHDS_Mesh.SetMeshElementOnShape().

Referenced by SMESH_MeshEditor.convertElemToQuadratic(), and SMESH_MeshEditor.ConvertToQuadratic().

{
  SMESHDS_Mesh * meshDS = GetMeshDS();
  SMDS_MeshFace* elem = 0;

  if(!myCreateQuadratic) {
    if(id)
      elem = meshDS->AddPolygonalFaceWithID(nodes, id);
    else
      elem = meshDS->AddPolygonalFace(nodes);
  }
  else {
    vector<const SMDS_MeshNode*> newNodes;
    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* n12 = GetMediumNode(n1,n2,force3d);
      newNodes.push_back( n1 );
      newNodes.push_back( n12 );
    }
    if(id)
      elem = meshDS->AddPolygonalFaceWithID(newNodes, id);
    else
      elem = meshDS->AddPolygonalFace(newNodes);
  }
  if ( mySetElemOnShape && myShapeID > 0 )
    meshDS->SetMeshElementOnShape( elem, myShapeID );

  return elem;
}
SMDS_MeshVolume * SMESH_MesherHelper::AddPolyhedralVolume ( const std::vector< const SMDS_MeshNode * > &  nodes,
const std::vector< int > &  quantities,
const int  ID = 0,
const bool  force3d = true 
)

Creates polyhedron.

In quadratic mesh, adds medium nodes

Definition at line 1517 of file SMESH_MesherHelper.cxx.

References SMESHDS_Mesh.AddPolyhedralVolume(), SMESHDS_Mesh.AddPolyhedralVolumeWithID(), GetMediumNode(), GetMeshDS(), myCreateQuadratic, mySetElemOnShape, myShapeID, SMESH_AdvancedEditor.n1, SMESH_AdvancedEditor.n2, and SMESHDS_Mesh.SetMeshElementOnShape().

Referenced by SMESH_MeshEditor.convertElemToQuadratic(), and SMESH_MeshEditor.ConvertToQuadratic().

{
  SMESHDS_Mesh * meshDS = GetMeshDS();
  SMDS_MeshVolume* elem = 0;
  if(!myCreateQuadratic)
  {
    if(id)
      elem = meshDS->AddPolyhedralVolumeWithID(nodes, quantities, id);
    else
      elem = meshDS->AddPolyhedralVolume(nodes, quantities);
  }
  else
  {
    vector<const SMDS_MeshNode*> newNodes;
    vector<int> newQuantities;
    for ( int iFace=0, iN=0; iFace < quantities.size(); ++iFace)
    {
      int nbNodesInFace = quantities[iFace];
      newQuantities.push_back(0);
      for ( int i = 0; i < nbNodesInFace; ++i )
      {
        const SMDS_MeshNode* n1 = nodes[ iN + i ];
        newNodes.push_back( n1 );
        newQuantities.back()++;
        
        const SMDS_MeshNode* n2 = nodes[ iN + ( i+1==nbNodesInFace ? 0 : i+1 )];
//         if ( n1->GetPosition()->GetTypeOfPosition() != SMDS_TOP_3DSPACE &&
//              n2->GetPosition()->GetTypeOfPosition() != SMDS_TOP_3DSPACE )
        {
          const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
          newNodes.push_back( n12 );
          newQuantities.back()++;
        }
      }
      iN += nbNodesInFace;
    }
    if(id)
      elem = meshDS->AddPolyhedralVolumeWithID( newNodes, newQuantities, id );
    else
      elem = meshDS->AddPolyhedralVolume( newNodes, newQuantities );
  }
  if ( mySetElemOnShape && myShapeID > 0 )
    meshDS->SetMeshElementOnShape( elem, myShapeID );

  return elem;
}
void SMESH_MesherHelper::AddTLinkNode ( const SMDS_MeshNode n1,
const SMDS_MeshNode n2,
const SMDS_MeshNode n12 
)

Add a link in my data structure.

Definition at line 332 of file SMESH_MesherHelper.cxx.

References myTLinkNodeMap.

Referenced by AddTLinks(), IsQuadraticSubMesh(), and SMESH_MeshEditor.SplitVolumesIntoTetra().

{
  // add new record to map
  SMESH_TLink link( n1, n2 );
  myTLinkNodeMap.insert( make_pair(link,n12));
}
void SMESH_MesherHelper.AddTLinkNodeMap ( const TLinkNodeMap aMap)

Add many links in my data structure.

Definition at line 457 of file SMESH_MesherHelper.hxx.

    { myTLinkNodeMap.insert(aMap.begin(), aMap.end()); }
void SMESH_MesherHelper::AddTLinks ( const SMDS_MeshEdge edge)

Add quadratic links of edge to own data structure.

Definition at line 347 of file SMESH_MesherHelper.cxx.

References AddTLinkNode(), SMDS_MeshElement.GetNode(), and SMDS_MeshElement.IsQuadratic().

Referenced by SMESH_MeshEditor.ConvertToQuadratic(), and IsQuadraticSubMesh().

{
  if ( edge->IsQuadratic() )
    AddTLinkNode(edge->GetNode(0), edge->GetNode(1), edge->GetNode(2));
}
void SMESH_MesherHelper::AddTLinks ( const SMDS_MeshFace face)

Add quadratic links of face to own data structure.

Definition at line 359 of file SMESH_MesherHelper.cxx.

References AddTLinkNode(), SMDS_MeshElement.GetNode(), SMDS_MeshElement.IsPoly(), and SMDS_MeshElement.NbNodes().

{
  if ( !f->IsPoly() )
    switch ( f->NbNodes() ) {
    case 6:
      AddTLinkNode(f->GetNode(0),f->GetNode(1),f->GetNode(3));
      AddTLinkNode(f->GetNode(1),f->GetNode(2),f->GetNode(4));
      AddTLinkNode(f->GetNode(2),f->GetNode(0),f->GetNode(5)); break;
    case 8:
      AddTLinkNode(f->GetNode(0),f->GetNode(1),f->GetNode(4));
      AddTLinkNode(f->GetNode(1),f->GetNode(2),f->GetNode(5));
      AddTLinkNode(f->GetNode(2),f->GetNode(3),f->GetNode(6));
      AddTLinkNode(f->GetNode(3),f->GetNode(0),f->GetNode(7));
    default:;
    }
}
void SMESH_MesherHelper::AddTLinks ( const SMDS_MeshVolume vol)

Add quadratic links of volume to own data structure.

Definition at line 382 of file SMESH_MesherHelper.cxx.

References AddTLinkNode(), SMDS_VolumeTool.GetFaceNodesIndices(), SMDS_VolumeTool.GetNodes(), SMDS_MeshElement.IsQuadratic(), SMDS_VolumeTool.NbFaceNodes(), SMDS_VolumeTool.NbFaces(), SMDS_VolumeTool.NbNodes(), and SMESH_AdvancedEditor.nodes.

{
  if ( volume->IsQuadratic() )
  {
    SMDS_VolumeTool vTool( volume );
    const SMDS_MeshNode** nodes = vTool.GetNodes();
    set<int> addedLinks;
    for ( int iF = 1; iF < vTool.NbFaces(); ++iF )
    {
      const int nbN = vTool.NbFaceNodes( iF );
      const int* iNodes = vTool.GetFaceNodesIndices( iF );
      for ( int i = 0; i < nbN; )
      {
        int iN1  = iNodes[i++];
        int iN12 = iNodes[i++];
        int iN2  = iNodes[i++];
        if ( iN1 > iN2 ) std::swap( iN1, iN2 );
        int linkID = iN1 * vTool.NbNodes() + iN2;
        pair< set<int>::iterator, bool > it_isNew = addedLinks.insert( linkID );
        if ( it_isNew.second )
          AddTLinkNode( nodes[iN1], nodes[iN2], nodes[iN12] );
        else
          addedLinks.erase( it_isNew.first ); // each link encounters only twice
      }
    }
  }
}
SMDS_MeshVolume * SMESH_MesherHelper::AddVolume ( const SMDS_MeshNode n1,
const SMDS_MeshNode n2,
const SMDS_MeshNode n3,
const SMDS_MeshNode n4,
const SMDS_MeshNode n5,
const SMDS_MeshNode n6,
const SMDS_MeshNode n7,
const SMDS_MeshNode n8,
const int  id = 0,
bool  force3d = true 
)

Creates quadratic or linear hexahedron.

Definition at line 1461 of file SMESH_MesherHelper.cxx.

References SMESHDS_Mesh.AddVolume(), SMESHDS_Mesh.AddVolumeWithID(), GetMediumNode(), GetMeshDS(), myCreateQuadratic, mySetElemOnShape, myShapeID, and SMESHDS_Mesh.SetMeshElementOnShape().

{
  SMESHDS_Mesh * meshDS = GetMeshDS();
  SMDS_MeshVolume* elem = 0;
  if(!myCreateQuadratic) {
    if(id)
      elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, id);
    else
      elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6, n7, n8);
  }
  else {
    const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
    const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
    const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,force3d);
    const SMDS_MeshNode* n41 = GetMediumNode(n4,n1,force3d);

    const SMDS_MeshNode* n56 = GetMediumNode(n5,n6,force3d);
    const SMDS_MeshNode* n67 = GetMediumNode(n6,n7,force3d);
    const SMDS_MeshNode* n78 = GetMediumNode(n7,n8,force3d);
    const SMDS_MeshNode* n85 = GetMediumNode(n8,n5,force3d);

    const SMDS_MeshNode* n15 = GetMediumNode(n1,n5,force3d);
    const SMDS_MeshNode* n26 = GetMediumNode(n2,n6,force3d);
    const SMDS_MeshNode* n37 = GetMediumNode(n3,n7,force3d);
    const SMDS_MeshNode* n48 = GetMediumNode(n4,n8,force3d);

    if(id)
      elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8,
                                     n12, n23, n34, n41, n56, n67,
                                     n78, n85, n15, n26, n37, n48, id);
    else
      elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6, n7, n8,
                               n12, n23, n34, n41, n56, n67,
                               n78, n85, n15, n26, n37, n48);
  }
  if ( mySetElemOnShape && myShapeID > 0 )
    meshDS->SetMeshElementOnShape( elem, myShapeID );

  return elem;
}
SMDS_MeshVolume * SMESH_MesherHelper::AddVolume ( const SMDS_MeshNode n1,
const SMDS_MeshNode n2,
const SMDS_MeshNode n3,
const SMDS_MeshNode n4,
const int  id = 0,
const bool  force3d = true 
)

Creates quadratic or linear tetrahedron.

Definition at line 1374 of file SMESH_MesherHelper.cxx.

References SMESHDS_Mesh.AddVolume(), SMESHDS_Mesh.AddVolumeWithID(), GetMediumNode(), GetMeshDS(), myCreateQuadratic, mySetElemOnShape, myShapeID, and SMESHDS_Mesh.SetMeshElementOnShape().

Referenced by StdMeshers_Prism_3D.AddPrisms(), StdMeshers_QuadToTriaAdaptor.Compute(), StdMeshers_Projection_3D.Compute(), StdMeshers_HexaFromSkin_3D.Compute(), StdMeshers_Hexa_3D.Compute(), StdMeshers_CompositeHexa_3D.Compute(), SMESH_MeshEditor.convertElemToQuadratic(), SMESH_MeshEditor.ConvertToQuadratic(), StdMeshers_Penta_3D.MakeVolumeMesh(), VISCOUS._ViscousBuilder.refine(), and SMESH_MeshEditor.SplitVolumesIntoTetra().

{
  SMESHDS_Mesh * meshDS = GetMeshDS();
  SMDS_MeshVolume* elem = 0;
  if(!myCreateQuadratic) {
    if(id)
      elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, id);
    else
      elem = meshDS->AddVolume(n1, n2, n3, n4);
  }
  else {
    const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
    const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
    const SMDS_MeshNode* n31 = GetMediumNode(n3,n1,force3d);

    const SMDS_MeshNode* n14 = GetMediumNode(n1,n4,force3d);
    const SMDS_MeshNode* n24 = GetMediumNode(n2,n4,force3d);
    const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,force3d);

    if(id)
      elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n12, n23, n31, n14, n24, n34, id);
    else
      elem = meshDS->AddVolume(n1, n2, n3, n4, n12, n23, n31, n14, n24, n34);
  }
  if ( mySetElemOnShape && myShapeID > 0 )
    meshDS->SetMeshElementOnShape( elem, myShapeID );

  return elem;
}
SMDS_MeshVolume * SMESH_MesherHelper::AddVolume ( const SMDS_MeshNode n1,
const SMDS_MeshNode n2,
const SMDS_MeshNode n3,
const SMDS_MeshNode n4,
const SMDS_MeshNode n5,
const int  id = 0,
const bool  force3d = true 
)

Creates quadratic or linear pyramid.

Definition at line 1414 of file SMESH_MesherHelper.cxx.

References SMESHDS_Mesh.AddVolume(), SMESHDS_Mesh.AddVolumeWithID(), GetMediumNode(), GetMeshDS(), myCreateQuadratic, mySetElemOnShape, myShapeID, and SMESHDS_Mesh.SetMeshElementOnShape().

{
  SMDS_MeshVolume* elem = 0;
  if(!myCreateQuadratic) {
    if(id)
      elem = GetMeshDS()->AddVolumeWithID(n1, n2, n3, n4, n5, id);
    else
      elem = GetMeshDS()->AddVolume(n1, n2, n3, n4, n5);
  }
  else {
    const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
    const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
    const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,force3d);
    const SMDS_MeshNode* n41 = GetMediumNode(n4,n1,force3d);

    const SMDS_MeshNode* n15 = GetMediumNode(n1,n5,force3d);
    const SMDS_MeshNode* n25 = GetMediumNode(n2,n5,force3d);
    const SMDS_MeshNode* n35 = GetMediumNode(n3,n5,force3d);
    const SMDS_MeshNode* n45 = GetMediumNode(n4,n5,force3d);

    if(id)
      elem = GetMeshDS()->AddVolumeWithID ( n1,  n2,  n3,  n4,  n5,
                                            n12, n23, n34, n41,
                                            n15, n25, n35, n45,
                                            id);
    else
      elem = GetMeshDS()->AddVolume( n1,  n2,  n3,  n4,  n5,
                                     n12, n23, n34, n41,
                                     n15, n25, n35, n45);
  }
  if ( mySetElemOnShape && myShapeID > 0 )
    GetMeshDS()->SetMeshElementOnShape( elem, myShapeID );

  return elem;
}
SMDS_MeshVolume * SMESH_MesherHelper::AddVolume ( const SMDS_MeshNode n1,
const SMDS_MeshNode n2,
const SMDS_MeshNode n3,
const SMDS_MeshNode n4,
const SMDS_MeshNode n5,
const SMDS_MeshNode n6,
const int  id = 0,
const bool  force3d = true 
)

Creates quadratic or linear pentahedron.

Definition at line 1326 of file SMESH_MesherHelper.cxx.

References SMESHDS_Mesh.AddVolume(), SMESHDS_Mesh.AddVolumeWithID(), GetMediumNode(), GetMeshDS(), myCreateQuadratic, mySetElemOnShape, myShapeID, and SMESHDS_Mesh.SetMeshElementOnShape().

{
  SMESHDS_Mesh * meshDS = GetMeshDS();
  SMDS_MeshVolume* elem = 0;
  if(!myCreateQuadratic) {
    if(id)
      elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, id);
    else
      elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6);
  }
  else {
    const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
    const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
    const SMDS_MeshNode* n31 = GetMediumNode(n3,n1,force3d);

    const SMDS_MeshNode* n45 = GetMediumNode(n4,n5,force3d);
    const SMDS_MeshNode* n56 = GetMediumNode(n5,n6,force3d);
    const SMDS_MeshNode* n64 = GetMediumNode(n6,n4,force3d);

    const SMDS_MeshNode* n14 = GetMediumNode(n1,n4,force3d);
    const SMDS_MeshNode* n25 = GetMediumNode(n2,n5,force3d);
    const SMDS_MeshNode* n36 = GetMediumNode(n3,n6,force3d);

    if(id)
      elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, 
                                     n12, n23, n31, n45, n56, n64, n14, n25, n36, id);
    else
      elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6,
                               n12, n23, n31, n45, n56, n64, n14, n25, n36);
  }
  if ( mySetElemOnShape && myShapeID > 0 )
    meshDS->SetMeshElementOnShape( elem, myShapeID );

  return elem;
}
gp_XY SMESH_MesherHelper::applyIn2D ( const Handle(Geom_Surface)&  surface,
const gp_XY &  uv1,
const gp_XY &  uv2,
xyFunPtr  fun,
const bool  resultInPeriod = true 
) [static]

Perform given operation on two 2d points in parameric space of given surface.

It takes into account period of the surface. Use gp_XY_FunPtr macro to easily define pointer to function of gp_XY class.

Definition at line 696 of file SMESH_MesherHelper.cxx.

References SMESH_AdvancedEditor.res.

Referenced by FixQuadraticElements(), and GetMiddleUV().

{
  Standard_Boolean isUPeriodic = surface.IsNull() ? false : surface->IsUPeriodic();
  Standard_Boolean isVPeriodic = surface.IsNull() ? false : surface->IsVPeriodic();
  if ( !isUPeriodic && !isVPeriodic )
    return fun(uv1,uv2);

  // move uv2 not far than half-period from uv1
  double u2 = 
    uv2.X()+(isUPeriodic ? ShapeAnalysis::AdjustByPeriod(uv2.X(),uv1.X(),surface->UPeriod()) :0);
  double v2 = 
    uv2.Y()+(isVPeriodic ? ShapeAnalysis::AdjustByPeriod(uv2.Y(),uv1.Y(),surface->VPeriod()) :0);

  // execute operation
  gp_XY res = fun( uv1, gp_XY(u2,v2) );

  // move result within period
  if ( resultInPeriod )
  {
    Standard_Real UF,UL,VF,VL;
    surface->Bounds(UF,UL,VF,VL);
    if ( isUPeriodic )
      res.SetX( res.X() + ShapeAnalysis::AdjustToPeriod(res.X(),UF,UL));
    if ( isVPeriodic )
      res.SetY( res.Y() + ShapeAnalysis::AdjustToPeriod(res.Y(),VF,VL));
  }

  return res;
}
bool SMESH_MesherHelper::CheckNodeU ( const TopoDS_Edge &  E,
const SMDS_MeshNode n,
double &  u,
const double  tol,
const bool  force = false,
double  distXYZ[4] = 0 
) const

Check and fix node U on an edge.

Parameters:
force- check even if checks of other nodes on this edge passed OK
distXYZ- returns result distance and point coordinates
Return values:
bool- false if U is bad and could not be fixed

Definition at line 801 of file SMESH_MesherHelper.cxx.

References SMDS_MeshElement.GetID(), GetMeshDS(), SMDS_MeshElement.getshapeId(), Handle(), Max(), MESSAGE, myEdge2Projector, myShape, myShapeID, setPosOnShapeValidity(), SMESHDS_Mesh.ShapeToIndex(), and toCheckPosOnShape().

Referenced by GetMediumNode(), getMediumNodeOnComposedWire(), GetNodeU(), and VISCOUS._LayerEdge.SetNewLength().

{
  int shapeID = n->getshapeId();
  if ( force || toCheckPosOnShape( shapeID ))
  {
    TopLoc_Location loc; double f,l;
    Handle(Geom_Curve) curve = BRep_Tool::Curve( E,loc,f,l );
    if ( curve.IsNull() ) // degenerated edge
    {
      if ( u+tol < f || u-tol > l )
      {
        double r = Max( 0.5, 1 - tol*n->GetID()); // to get a unique u on edge
        u =  f*r + l*(1-r);
      }
    }
    else
    {
      gp_Pnt nodePnt = SMESH_TNodeXYZ( n );
      if ( !loc.IsIdentity() ) nodePnt.Transform( loc.Transformation().Inverted() );
      gp_Pnt curvPnt = curve->Value( u );
      double dist = nodePnt.Distance( curvPnt );
      if ( distXYZ ) {
        curvPnt.Transform( loc );
        distXYZ[0] = dist;
        distXYZ[1] = curvPnt.X(); distXYZ[2] = curvPnt.Y(); distXYZ[3]=curvPnt.Z();
      }
      if ( dist > tol )
      {
        setPosOnShapeValidity( shapeID, false );
        // u incorrect, project the node to the curve
        int edgeID = GetMeshDS()->ShapeToIndex( E );
        TID2ProjectorOnCurve& i2proj = const_cast< TID2ProjectorOnCurve&>( myEdge2Projector );
        TID2ProjectorOnCurve::iterator i_proj =
          i2proj.insert( make_pair( edgeID, (GeomAPI_ProjectPointOnCurve*) 0 )).first;
        if ( !i_proj->second  )
        {
          i_proj->second = new GeomAPI_ProjectPointOnCurve();
          i_proj->second->Init( curve, f, l );
        }
        GeomAPI_ProjectPointOnCurve* projector = i_proj->second;
        projector->Perform( nodePnt );
        if ( projector->NbPoints() < 1 )
        {
          MESSAGE( "SMESH_MesherHelper::CheckNodeU() failed to project" );
          return false;
        }
        Quantity_Parameter U = projector->LowerDistanceParameter();
        u = double( U );
        curvPnt = curve->Value( u );
        dist = nodePnt.Distance( curvPnt );
        if ( distXYZ ) {
          curvPnt.Transform( loc );
          distXYZ[0] = dist;
          distXYZ[1] = curvPnt.X(); distXYZ[2] = curvPnt.Y(); distXYZ[3]=curvPnt.Z();
        }
        if ( dist > tol )
        {
          MESSAGE( "SMESH_MesherHelper::CheckNodeU(), invalid projection" );
          MESSAGE("distance " << dist << " " << tol );
          return false;
        }
        // store the fixed U on the edge
        if ( myShape.IsSame(E) && shapeID == myShapeID )
          const_cast<SMDS_MeshNode*>(n)->SetPosition
            ( SMDS_PositionPtr( new SMDS_EdgePosition( U )));
      }
      else if ( fabs( u ) > numeric_limits<double>::min() )
      {
        setPosOnShapeValidity( shapeID, true );
      }
      if (( u < f-tol || u > l+tol ) && force )
      {
        // node is on vertex but is set on periodic but trimmed edge (issue 0020890)
        try
        {
          // do not use IsPeriodic() as Geom_TrimmedCurve::IsPeriodic () returns false
          double period = curve->Period();
          u = ( u < f ) ? u + period : u - period;
        }
        catch (Standard_Failure& exc)
        {
          return false;
        }
      }
    }
  }
  return true;
}
bool SMESH_MesherHelper::CheckNodeUV ( const TopoDS_Face &  F,
const SMDS_MeshNode n,
gp_XY &  uv,
const double  tol,
const bool  force = false,
double  distXYZ[4] = 0 
) const

Check and fix node UV on a face.

Parameters:
force- check even if checks of other nodes on this face passed OK
distXYZ- returns result distance and point coordinates
Return values:
bool- false if UV is bad and could not be fixed

Definition at line 595 of file SMESH_MesherHelper.cxx.

References GetProjector(), SMDS_MeshElement.getshapeId(), Handle(), MESSAGE, myShape, myShapeID, setPosOnShapeValidity(), and toCheckPosOnShape().

Referenced by GetMediumNode(), GetNodeUV(), VISCOUS._LayerEdge.SetNewLength(), and VISCOUS._LayerEdge.SmoothOnEdge().

{
  int shapeID = n->getshapeId();
  bool infinit = ( Precision::IsInfinite( uv.X() ) || Precision::IsInfinite( uv.Y() ));
  if ( force || toCheckPosOnShape( shapeID ) || infinit )
  {
    // check that uv is correct
    TopLoc_Location loc;
    Handle(Geom_Surface) surface = BRep_Tool::Surface( F,loc );
    gp_Pnt nodePnt = XYZ( n ), surfPnt(0,0,0);
    double dist = 0;
    if ( !loc.IsIdentity() ) nodePnt.Transform( loc.Transformation().Inverted() );
    if ( infinit ||
         (dist = nodePnt.Distance( surfPnt = surface->Value( uv.X(), uv.Y() ))) > tol )
    {
      setPosOnShapeValidity( shapeID, false );
      if ( !infinit && distXYZ ) {
        surfPnt.Transform( loc );
        distXYZ[0] = dist;
        distXYZ[1] = surfPnt.X(); distXYZ[2] = surfPnt.Y(); distXYZ[3]=surfPnt.Z();
      }
      // uv incorrect, project the node to surface
      GeomAPI_ProjectPointOnSurf& projector = GetProjector( F, loc, tol );
      projector.Perform( nodePnt );
      if ( !projector.IsDone() || projector.NbPoints() < 1 )
      {
        MESSAGE( "SMESH_MesherHelper::CheckNodeUV() failed to project" );
        return false;
      }
      Quantity_Parameter U,V;
      projector.LowerDistanceParameters(U,V);
      uv.SetCoord( U,V );
      surfPnt = surface->Value( U, V );
      dist = nodePnt.Distance( surfPnt );
      if ( distXYZ ) {
        surfPnt.Transform( loc );
        distXYZ[0] = dist;
        distXYZ[1] = surfPnt.X(); distXYZ[2] = surfPnt.Y(); distXYZ[3]=surfPnt.Z();
      }
      if ( dist > tol )
      {
        MESSAGE( "SMESH_MesherHelper::CheckNodeUV(), invalid projection" );
        return false;
      }
      // store the fixed UV on the face
      if ( myShape.IsSame(F) && shapeID == myShapeID )
        const_cast<SMDS_MeshNode*>(n)->SetPosition
          ( SMDS_PositionPtr( new SMDS_FacePosition( U, V )));
    }
    else if ( uv.Modulus() > numeric_limits<double>::min() )
    {
      setPosOnShapeValidity( shapeID, true );
    }
  }
  return true;
}
void SMESH_MesherHelper::FixQuadraticElements ( bool  volumeOnly = true)

Move medium nodes of faces and volumes to fix distorted elements.

Parameters:
volumeOnly- fix nodes on geom faces or not if the shape is solid
volumeOnly- to fix nodes on faces or not, if the shape is solid

Issue 0020307: EDF 992 SMESH : Linea/Quadratic with Medium Node on Geometry

Definition at line 2856 of file SMESH_MesherHelper.cxx.

References SMESH_TNodeXYZ._node, applyIn2D(), ex24_cylinder.base, ex10_grid4geometry.dir, PAL_MESH_043_3D.face, ex21_lamp.faces, SMDS_Mesh.FindFace(), FixQuadraticElements(), SMDS_MeshElement.GetEntityType(), SMDS_VolumeTool.GetFaceNodes(), SMDS_MeshNode.GetInverseElementIterator(), GetMeshDS(), GetMiddleUV(), SMDS_MeshElement.GetNode(), GetNodeUV(), SMDS_MeshNode.GetPosition(), GetSubShapeByNode(), SMDS_Position.GetTypeOfPosition(), Handle(), SMDS_MeshElement.IsQuadratic(), SMESHDS_Mesh.MoveNode(), MSG, MSGBEG, myMesh, myShape, myShapeID, SMESH_AdvancedEditor.n2, SMDS_MeshElement.NbCornerNodes(), SMDS_VolumeTool.NbFaceNodes(), SMDS_VolumeTool.NbFaces(), SMDS_MeshElement.NbNodes(), SMESH_AdvancedEditor.res, SMDS_VolumeTool.Set(), SetSubShape(), SMDS_TOP_3DSPACE, SMDS_TOP_EDGE, SMDS_TOP_FACE, SMDSAbs_All, SMDSAbs_Face, SMDSAbs_Volume, SMDSEntity_Quad_Pyramid, SMESH_test4.submesh, SMESH_demo_hexa2_upd.vol, SMDS_MeshNode.X(), and ex13_hole1partial.x.

Referenced by SMESH_MeshEditor.ConvertToQuadratic(), and FixQuadraticElements().

{
  // setenv NO_FixQuadraticElements to know if FixQuadraticElements() is guilty of bad conversion
  if ( getenv("NO_FixQuadraticElements") )
    return;

  // 0. Apply algorithm to solids or geom faces
  // ----------------------------------------------
  if ( myShape.IsNull() ) {
    if ( !myMesh->HasShapeToMesh() ) return;
    SetSubShape( myMesh->GetShapeToMesh() );

#ifdef _DEBUG_
    int nbSolids = 0;
    TopTools_IndexedMapOfShape solids;
    TopExp::MapShapes(myShape,TopAbs_SOLID,solids);
    nbSolids = solids.Extent();
#endif
    TopTools_MapOfShape faces; // faces not in solid or in not meshed solid
    for ( TopExp_Explorer f(myShape,TopAbs_FACE,TopAbs_SOLID); f.More(); f.Next() ) {
      faces.Add( f.Current() ); // not in solid
    }
    for ( TopExp_Explorer s(myShape,TopAbs_SOLID); s.More(); s.Next() ) {
      if ( myMesh->GetSubMesh( s.Current() )->IsEmpty() ) { // get faces of solid
        for ( TopExp_Explorer f( s.Current(), TopAbs_FACE); f.More(); f.Next() )
          faces.Add( f.Current() ); // in not meshed solid
      }
      else { // fix nodes in the solid and its faces
#ifdef _DEBUG_
        MSG("FIX SOLID " << nbSolids-- << " #" << GetMeshDS()->ShapeToIndex(s.Current()));
#endif
        SMESH_MesherHelper h(*myMesh);
        h.SetSubShape( s.Current() );
        h.FixQuadraticElements(false);
      }
    }
    // fix nodes on geom faces
#ifdef _DEBUG_
    int nbfaces = faces.Extent(); /*avoid "unused varianbles": */ nbfaces++, nbfaces--; 
#endif
    for ( TopTools_MapIteratorOfMapOfShape fIt( faces ); fIt.More(); fIt.Next() ) {
      MSG("FIX FACE " << nbfaces-- << " #" << GetMeshDS()->ShapeToIndex(fIt.Key()));
      SMESH_MesherHelper h(*myMesh);
      h.SetSubShape( fIt.Key() );
      h.FixQuadraticElements(true);
    }
    //perf_print_all_meters(1);
    return;
  }

  // 1. Find out type of elements and get iterator on them
  // ---------------------------------------------------

  SMDS_ElemIteratorPtr elemIt;
  SMDSAbs_ElementType elemType = SMDSAbs_All;

  SMESH_subMesh* submesh = myMesh->GetSubMeshContaining( myShapeID );
  if ( !submesh )
    return;
  if ( SMESHDS_SubMesh* smDS = submesh->GetSubMeshDS() ) {
    elemIt = smDS->GetElements();
    if ( elemIt->more() ) {
      elemType = elemIt->next()->GetType();
      elemIt = smDS->GetElements();
    }
  }
  if ( !elemIt || !elemIt->more() || elemType < SMDSAbs_Face )
    return;

  // 2. Fill in auxiliary data structures
  // ----------------------------------

  set< QLink > links;
  set< QFace > faces;
  set< QLink >::iterator pLink;
  set< QFace >::iterator pFace;

  bool isCurved = false;
  //bool hasRectFaces = false;
  //set<int> nbElemNodeSet;
  SMDS_VolumeTool volTool;

  TIDSortedNodeSet apexOfPyramid;
  const int apexIndex = 4;

  if ( elemType == SMDSAbs_Volume )
  {
    while ( elemIt->more() ) // loop on volumes
    {
      const SMDS_MeshElement* vol = elemIt->next();
      if ( !vol->IsQuadratic() || !volTool.Set( vol ))
        return;
      for ( int iF = 0; iF < volTool.NbFaces(); ++iF ) // loop on faces of volume
      {
        int nbN = volTool.NbFaceNodes( iF );
        //nbElemNodeSet.insert( nbN );
        const SMDS_MeshNode** faceNodes = volTool.GetFaceNodes( iF );
        vector< const QLink* > faceLinks( nbN/2 );
        for ( int iN = 0; iN < nbN; iN += 2 ) // loop on links of a face
        {
          // store QLink
          QLink link( faceNodes[iN], faceNodes[iN+2], faceNodes[iN+1] );
          pLink = links.insert( link ).first;
          faceLinks[ iN/2 ] = & *pLink;
          if ( !isCurved )
            isCurved = !link.IsStraight();
          if ( link.MediumPos() == SMDS_TOP_3DSPACE && !link.IsStraight() )
            return; // already fixed
        }
        // store QFace
        pFace = faces.insert( QFace( faceLinks )).first;
        if ( pFace->NbVolumes() == 0 )
          pFace->AddSelfToLinks();
        pFace->SetVolume( vol );
//         hasRectFaces = hasRectFaces ||
//           ( volTool.GetVolumeType() == SMDS_VolumeTool::QUAD_HEXA ||
//             volTool.GetVolumeType() == SMDS_VolumeTool::QUAD_PENTA );
#ifdef _DEBUG_
        if ( nbN == 6 )
          pFace->_face = GetMeshDS()->FindFace(faceNodes[0],faceNodes[2],faceNodes[4]);
        else
          pFace->_face = GetMeshDS()->FindFace(faceNodes[0],faceNodes[2],
                                               faceNodes[4],faceNodes[6] );
#endif
      }
      // collect pyramid apexes for further correction
      if ( vol->NbCornerNodes() == 5 )
        apexOfPyramid.insert( vol->GetNode( apexIndex ));
    }
    set< QLink >::iterator pLink = links.begin();
    for ( ; pLink != links.end(); ++pLink )
      pLink->SetContinuesFaces();
  }
  else
  {
    while ( elemIt->more() ) // loop on faces
    {
      const SMDS_MeshElement* face = elemIt->next();
      if ( !face->IsQuadratic() )
        continue;
      //nbElemNodeSet.insert( face->NbNodes() );
      int nbN = face->NbNodes()/2;
      vector< const QLink* > faceLinks( nbN );
      for ( int iN = 0; iN < nbN; ++iN ) // loop on links of a face
      {
        // store QLink
        QLink link( face->GetNode(iN), face->GetNode((iN+1)%nbN), face->GetNode(iN+nbN) );
        pLink = links.insert( link ).first;
        faceLinks[ iN ] = & *pLink;
        if ( !isCurved )
          isCurved = !link.IsStraight();
      }
      // store QFace
      pFace = faces.insert( QFace( faceLinks )).first;
      pFace->AddSelfToLinks();
      //hasRectFaces = ( hasRectFaces || nbN == 4 );
    }
  }
  if ( !isCurved )
    return; // no curved edges of faces

  // 3. Compute displacement of medium nodes
  // ---------------------------------------

  // two loops on QFaces: the first is to treat boundary links, the second is for internal ones
  TopLoc_Location loc;
  // not treat boundary of volumic submesh
  int isInside = ( elemType == SMDSAbs_Volume && volumeOnly ) ? 1 : 0;
  for ( ; isInside < 2; ++isInside ) {
    MSG( "--------------- LOOP (inside=" << isInside << ") ------------------");
    SMDS_TypeOfPosition pos = isInside ? SMDS_TOP_3DSPACE : SMDS_TOP_FACE;
    SMDS_TypeOfPosition bndPos = isInside ? SMDS_TOP_FACE : SMDS_TOP_EDGE;

    for ( pFace = faces.begin(); pFace != faces.end(); ++pFace ) {
      if ( bool(isInside) == pFace->IsBoundary() )
        continue;
      for ( int dir = 0; dir < 2; ++dir ) // 2 directions of propagation from the quadrangle
      {
        MSG( "CHAIN");
        // make chain of links connected via continues faces
        int error = ERR_OK;
        TChain rawChain;
        if ( !pFace->GetLinkChain( dir, rawChain, pos, error) && error ==ERR_UNKNOWN ) continue;
        rawChain.reverse();
        if ( !pFace->GetLinkChain( dir+2, rawChain, pos, error ) && error ==ERR_UNKNOWN ) continue;

        vector< TChain > chains;
        if ( error == ERR_OK ) { // chain contains continues rectangles
          chains.resize(1);
          chains[0].splice( chains[0].begin(), rawChain );
        }
        else if ( error == ERR_TRI ) {  // chain contains continues triangles
          TSplitTriaResult res = splitTrianglesIntoChains( rawChain, chains, pos );
          if ( res != _OK ) { // not quadrangles split into triangles
            fixTriaNearBoundary( rawChain, *this );
            break;
          }
        }
        else if ( error == ERR_PRISM ) { // quadrangle side faces of prisms
          fixPrism( rawChain );
          break;
        }
        else {
          continue;
        }
        for ( int iC = 0; iC < chains.size(); ++iC )
        {
          TChain& chain = chains[iC];
          if ( chain.empty() ) continue;
          if ( chain.front().IsStraight() && chain.back().IsStraight() ) {
            MSG("3D straight - ignore");
            continue;
          }
          if ( chain.front()->MediumPos() > bndPos ||
               chain.back() ->MediumPos() > bndPos ) {
            MSG("Internal chain - ignore");
            continue;
          }
          // mesure chain length and compute link position along the chain
          double chainLen = 0;
          vector< double > linkPos;
          MSGBEG( "Link medium nodes: ");
          TChain::iterator link0 = chain.begin(), link1 = chain.begin(), link2;
          for ( ++link1; link1 != chain.end(); ++link1, ++link0 ) {
            MSGBEG( (*link0)->_mediumNode->GetID() << "-" <<(*link1)->_mediumNode->GetID()<<" ");
            double len = ((*link0)->MiddlePnt() - (*link1)->MiddlePnt()).Modulus();
            while ( len < numeric_limits<double>::min() ) { // remove degenerated link
              link1 = chain.erase( link1 );
              if ( link1 == chain.end() )
                break;
              len = ((*link0)->MiddlePnt() - (*link1)->MiddlePnt()).Modulus();
            }
            chainLen += len;
            linkPos.push_back( chainLen );
          }
          MSG("");
          if ( linkPos.size() < 2 )
            continue;

          gp_Vec move0 = chain.front()->_nodeMove;
          gp_Vec move1 = chain.back ()->_nodeMove;

          TopoDS_Face face;
          bool checkUV = true;
          if ( !isInside )
          {
            // compute node displacement of end links of chain in parametric space of face
            TChainLink& linkOnFace = *(++chain.begin());
            const SMDS_MeshNode* nodeOnFace = linkOnFace->_mediumNode;
            TopoDS_Shape f = GetSubShapeByNode( nodeOnFace, GetMeshDS() );
            if ( !f.IsNull() && f.ShapeType() == TopAbs_FACE )
            {
              face = TopoDS::Face( f );
              Handle(Geom_Surface) surf = BRep_Tool::Surface(face,loc);
              bool isStraight[2];
              for ( int is1 = 0; is1 < 2; ++is1 ) // move0 or move1
              {
                TChainLink& link = is1 ? chain.back() : chain.front();
                gp_XY uvm = GetNodeUV( face, link->_mediumNode, nodeOnFace, &checkUV);
                gp_XY uv1 = GetNodeUV( face, link->node1(), nodeOnFace, &checkUV);
                gp_XY uv2 = GetNodeUV( face, link->node2(), nodeOnFace, &checkUV);
                gp_XY uv12 = GetMiddleUV( surf, uv1, uv2);
                // uvMove = uvm - uv12
                gp_XY uvMove = applyIn2D(surf, uvm, uv12, gp_XY_Subtracted, /*inPeriod=*/false);
                ( is1 ? move1 : move0 ).SetCoord( uvMove.X(), uvMove.Y(), 0 );
                if ( !is1 ) // correct nodeOnFace for move1 (issue 0020919)
                  nodeOnFace = (*(++chain.rbegin()))->_mediumNode;
                isStraight[is1] = isStraightLink( (uv2-uv1).SquareModulus(),
                                                  10 * uvMove.SquareModulus());
              }
              if ( isStraight[0] && isStraight[1] ) {
                MSG("2D straight - ignore");
                continue; // straight - no need to move nodes of internal links
              }

              // check if a chain is already fixed
              gp_XY uvm = GetNodeUV( face, linkOnFace->_mediumNode, 0, &checkUV);
              gp_XY uv1 = GetNodeUV( face, linkOnFace->node1(), nodeOnFace, &checkUV);
              gp_XY uv2 = GetNodeUV( face, linkOnFace->node2(), nodeOnFace, &checkUV);
              gp_XY uv12 = GetMiddleUV( surf, uv1, uv2);
              if (( uvm - uv12 ).SquareModulus() > 1e-10 )
              {
                MSG("Already fixed - ignore");
                continue;
              }
            }
          }
          gp_Trsf trsf;
          if ( isInside || face.IsNull() )
          {
            // compute node displacement of end links in their local coord systems
            {
              TChainLink& ln0 = chain.front(), ln1 = *(++chain.begin());
              trsf.SetTransformation( gp_Ax3( gp::Origin(), ln0.Normal(),
                                              gp_Vec( ln0->MiddlePnt(), ln1->MiddlePnt() )));
              move0.Transform(trsf);
            }
            {
              TChainLink& ln0 = *(++chain.rbegin()), ln1 = chain.back();
              trsf.SetTransformation( gp_Ax3( gp::Origin(), ln1.Normal(),
                                              gp_Vec( ln0->MiddlePnt(), ln1->MiddlePnt() )));
              move1.Transform(trsf);
            }
          }
          // compute displacement of medium nodes
          link2 = chain.begin();
          link0 = link2++;
          link1 = link2++;
          for ( int i = 0; link2 != chain.end(); ++link0, ++link1, ++link2, ++i )
          {
            double r = linkPos[i] / chainLen;
            // displacement in local coord system
            gp_Vec move = (1. - r) * move0 + r * move1;
            if ( isInside || face.IsNull()) {
              // transform to global
              gp_Vec x01( (*link0)->MiddlePnt(), (*link1)->MiddlePnt() );
              gp_Vec x12( (*link1)->MiddlePnt(), (*link2)->MiddlePnt() );
              gp_Vec x = x01.Normalized() + x12.Normalized();
              trsf.SetTransformation( gp_Ax3( gp::Origin(), link1->Normal(), x), gp_Ax3() );
              move.Transform(trsf);
            }
            else {
              // compute 3D displacement by 2D one
              Handle(Geom_Surface) s = BRep_Tool::Surface(face,loc);
              gp_XY oldUV   = GetNodeUV( face, (*link1)->_mediumNode, 0, &checkUV);
              gp_XY newUV   = applyIn2D( s, oldUV, gp_XY( move.X(),move.Y()), gp_XY_Added);
              gp_Pnt newPnt = s->Value( newUV.X(), newUV.Y());
              move = gp_Vec( XYZ((*link1)->_mediumNode), newPnt.Transformed(loc) );
#ifdef _DEBUG_
              if ( (XYZ((*link1)->node1()) - XYZ((*link1)->node2())).SquareModulus() <
                   move.SquareMagnitude())
              {
                gp_XY uv0 = GetNodeUV( face, (*link0)->_mediumNode, 0, &checkUV);
                gp_XY uv2 = GetNodeUV( face, (*link2)->_mediumNode, 0, &checkUV);
                MSG( "TOO LONG MOVE \t" <<
                     "uv0: "<<uv0.X()<<", "<<uv0.Y()<<" \t" <<
                     "uv2: "<<uv2.X()<<", "<<uv2.Y()<<" \t" <<
                     "uvOld: "<<oldUV.X()<<", "<<oldUV.Y()<<" \t" <<
                     "newUV: "<<newUV.X()<<", "<<newUV.Y()<<" \t");
              }
#endif
            }
            (*link1)->Move( move );
            MSG( "Move " << (*link1)->_mediumNode->GetID() << " following "
                 << chain.front()->_mediumNode->GetID() <<"-"
                 << chain.back ()->_mediumNode->GetID() <<
                 " by " << move.Magnitude());
          }
        } // loop on chains of links
      } // loop on 2 directions of propagation from quadrangle
    } // loop on faces
  }

  // 4. Move nodes
  // -------------

//   vector<const SMDS_MeshElement*> vols( 100 );
//   vector<double>                  volSize( 100 );
//   int nbVols;
//   bool ok;
  for ( pLink = links.begin(); pLink != links.end(); ++pLink ) {
    if ( pLink->IsMoved() ) {
      gp_Pnt p = pLink->MiddlePnt() + pLink->Move();
      GetMeshDS()->MoveNode( pLink->_mediumNode, p.X(), p.Y(), p.Z());
      //
//       gp_Pnt pNew = pLink->MiddlePnt() + pLink->Move();
//       if ( pLink->MediumPos() != SMDS_TOP_3DSPACE )
//       {
//         // avoid making distorted volumes near boundary
//         SMDS_ElemIteratorPtr volIt =
//           (*pLink)._mediumNode->GetInverseElementIterator( SMDSAbs_Volume );
//         for ( nbVols = 0; volIt->more() && volTool.Set( volIt->next() ); ++nbVols )
//         {
//           vols   [ nbVols ] = volTool.Element();
//           volSize[ nbVols ] = volTool.GetSize();
//         }
//         gp_Pnt pOld = pLink->MediumPnt();
//         const_cast<SMDS_MeshNode*>( pLink->_mediumNode )->setXYZ( pNew.X(), pNew.Y(), pNew.Z() );
//         ok = true;
//         while ( nbVols-- && ok )
//         {
//           volTool.Set( vols[ nbVols ]);
//           ok = ( volSize[ nbVols ] * volTool.GetSize() > 1e-20 ); 
//         }
//         if ( !ok )
//         {
//           const_cast<SMDS_MeshNode*>( pLink->_mediumNode )->setXYZ( pOld.X(), pOld.Y(), pOld.Z() );
//           MSG( "Do NOT move \t" << pLink->_mediumNode->GetID()
//                << " because of distortion of volume " << vols[ nbVols+1 ]->GetID());
//           continue;
//         }
//       }
//       GetMeshDS()->MoveNode( pLink->_mediumNode, pNew.X(), pNew.Y(), pNew.Z() );
    }
  }

  //return;

  // issue 0020982
  // Move the apex of pyramid together with the most curved link

  TIDSortedNodeSet::iterator apexIt = apexOfPyramid.begin();
  for ( ; apexIt != apexOfPyramid.end(); ++apexIt )
  {
    SMESH_TNodeXYZ apex = *apexIt;

    gp_Vec maxMove( 0,0,0 );
    double maxMoveSize2 = 0;

    // shift of node index to get medium nodes between the base nodes
    const int base2MediumShift = 5;

    // find maximal movement of medium node
    SMDS_ElemIteratorPtr volIt = apex._node->GetInverseElementIterator( SMDSAbs_Volume );
    vector< const SMDS_MeshElement* > pyramids;
    while ( volIt->more() )
    {
      const SMDS_MeshElement* pyram = volIt->next();
      if ( pyram->GetEntityType() != SMDSEntity_Quad_Pyramid ) continue;
      pyramids.push_back( pyram );

      for ( int iBase = 0; iBase < apexIndex; ++iBase )
      {
        SMESH_TNodeXYZ medium = pyram->GetNode( iBase + base2MediumShift );
        if ( medium._node->GetPosition()->GetTypeOfPosition() != SMDS_TOP_3DSPACE )
        {
          SMESH_TNodeXYZ n1 = pyram->GetNode( iBase );
          SMESH_TNodeXYZ n2 = pyram->GetNode( ( iBase+1 ) % 4 );
          gp_Pnt middle = 0.5 * ( n1 + n2 );
          gp_Vec move( middle, medium );
          double moveSize2 = move.SquareMagnitude();
          if ( moveSize2 > maxMoveSize2 )
            maxMove = move, maxMoveSize2 = moveSize2;
        }
      }
    }

    // move the apex
    if ( maxMoveSize2 > 1e-20 )
    {
      apex += maxMove.XYZ();
      GetMeshDS()->MoveNode( apex._node, apex.X(), apex.Y(), apex.Z());

      // move medium nodes neighboring the apex to the middle
      const int base2MediumShift_2 = 9;
      for ( unsigned i = 0; i < pyramids.size(); ++i )
        for ( int iBase = 0; iBase < apexIndex; ++iBase )
        {
          SMESH_TNodeXYZ         base = pyramids[i]->GetNode( iBase );
          const SMDS_MeshNode* medium = pyramids[i]->GetNode( iBase + base2MediumShift_2 );
          gp_XYZ middle = 0.5 * ( apex + base );
          GetMeshDS()->MoveNode( medium, middle.X(), middle.Y(), middle.Z());
        }
    }
  }
}
PShapeIteratorPtr SMESH_MesherHelper::GetAncestors ( const TopoDS_Shape &  shape,
const SMESH_Mesh mesh,
TopAbs_ShapeEnum  ancestorType 
) [static]

Return iterator on ancestors of the given type.

Definition at line 1478 of file SMESH_Mesh.cxx.

Referenced by VISCOUS._ViscousBuilder.addBoundaryElements(), VISCOUS._ViscousBuilder.findFacesWithLayers(), StdMeshers_ProjectionUtils.FindSubShapeAssociation(), and VISCOUS._ViscousBuilder.updateNormals().

{
  if ( _mapAncestors.Contains( theS ) )
    return _mapAncestors.FindFromKey( theS );

  static TopTools_ListOfShape emptyList;
  return emptyList;
}
bool SMESH_MesherHelper.GetIsQuadratic ( ) const

Return myCreateQuadratic flag.

Definition at line 176 of file SMESH_MesherHelper.hxx.

{ return myCreateQuadratic; }
const SMDS_MeshNode * SMESH_MesherHelper::GetMediumNode ( const SMDS_MeshNode n1,
const SMDS_MeshNode n2,
const bool  force3d 
)

Return existing or create new medium nodes between given ones.

Parameters:
force3d- true means node creation at the middle between the two given nodes, else node position is found on its supporting geometrical shape, if any.

Definition at line 900 of file SMESH_MesherHelper.cxx.

References SMESHDS_Mesh.AddNode(), CheckNodeU(), CheckNodeUV(), getMediumNodeOnComposedWire(), GetMeshDS(), GetMiddleUV(), GetNodeU(), GetNodeUV(), SMDS_MeshNode.GetPosition(), SMDS_MeshElement.getshapeId(), SMDS_Position.GetTypeOfPosition(), Handle(), SMESHDS_Mesh.IndexToShape(), IsDegenShape(), IsSeamShape(), myParIndex, myShape, myShapeID, myTLinkNodeMap, SMESHDS_Mesh.SetNodeInVolume(), SMESHDS_Mesh.SetNodeOnEdge(), SMESHDS_Mesh.SetNodeOnFace(), SMDS_TOP_EDGE, SMDS_TOP_FACE, SMDS_MeshNode.X(), ex13_hole1partial.x, SMDS_MeshNode.Y(), ex13_hole1partial.y, and SMDS_MeshNode.Z().

Referenced by AddEdge(), AddFace(), AddPolygonalFace(), AddPolyhedralVolume(), and AddVolume().

{
  // Find existing node

  SMESH_TLink link(n1,n2);
  ItTLinkNode itLN = myTLinkNodeMap.find( link );
  if ( itLN != myTLinkNodeMap.end() ) {
    return (*itLN).second;
  }

  // Create medium node

  SMDS_MeshNode* n12;
  SMESHDS_Mesh* meshDS = GetMeshDS();

  if ( IsSeamShape( n1->getshapeId() ))
    // to get a correct UV of a node on seam, the second node must have checked UV
    std::swap( n1, n2 );

  // 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();
    }

    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( myShape.IsNull() )
      F = TopoDS::Face(meshDS->IndexToShape(faceID));
    else {
      F = TopoDS::Face(myShape);
      faceID = myShapeID;
    }
    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)
  {
    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;
    }
    u[0] = GetNodeU(E,n1,n2, force3d ? 0 : &uvOK[0]);
    u[1] = GetNodeU(E,n2,n1, force3d ? 0 : &uvOK[1]);
  }
  if(!force3d)
  {
    // 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 ( IsDegenShape( n1->getshapeId() )) {
          if ( myParIndex & U_periodic ) uv[0].SetCoord( 1, uv[1].Coord( 1 ));
          else                           uv[0].SetCoord( 2, uv[1].Coord( 2 ));
        }
        else if ( IsDegenShape( n2->getshapeId() )) {
          if ( myParIndex & U_periodic ) uv[1].SetCoord( 1, uv[0].Coord( 1 ));
          else                           uv[1].SetCoord( 2, uv[0].Coord( 2 ));
        }

        TopLoc_Location loc;
        Handle(Geom_Surface) S = BRep_Tool::Surface(F,loc);
        gp_XY UV = GetMiddleUV( S, uv[0], uv[1] );
        gp_Pnt P = S->Value( UV.X(), UV.Y() ).Transformed(loc);
        n12 = meshDS->AddNode(P.X(), P.Y(), P.Z());
        meshDS->SetNodeOnFace(n12, faceID, UV.X(), UV.Y());
        myTLinkNodeMap.insert(make_pair(link,n12));
        return n12;
      }
    }
    else if ( !E.IsNull() )
    {
      double f,l;
      Handle(Geom_Curve) C = BRep_Tool::Curve(E, f, l);
      if(!C.IsNull())
      {
        Standard_Boolean isPeriodic = C->IsPeriodic();
        double U;
        if(isPeriodic) {
          Standard_Real Period = C->Period();
          Standard_Real p = u[1]+ShapeAnalysis::AdjustByPeriod(u[1],u[0],Period);
          Standard_Real pmid = (u[0]+p)/2.;
          U = pmid+ShapeAnalysis::AdjustToPeriod(pmid,C->FirstParameter(),C->LastParameter());
        }
        else
          U = (u[0]+u[1])/2.;

        gp_Pnt P = C->Value( U );
        n12 = meshDS->AddNode(P.X(), P.Y(), P.Z());
        meshDS->SetNodeOnEdge(n12, edgeID, U);
        myTLinkNodeMap.insert(make_pair(link,n12));
        return n12;
      }
    }
  }

  // 3d variant
  double x = ( n1->X() + n2->X() )/2.;
  double y = ( n1->Y() + n2->Y() )/2.;
  double z = ( n1->Z() + n2->Z() )/2.;
  n12 = meshDS->AddNode(x,y,z);

  if ( !F.IsNull() )
  {
    gp_XY UV = ( uv[0] + uv[1] ) / 2.;
    CheckNodeUV( F, n12, UV, 2*BRep_Tool::Tolerance( F ), /*force=*/true);
    meshDS->SetNodeOnFace(n12, faceID, UV.X(), UV.Y() );
  }
  else if ( !E.IsNull() )
  {
    double U = ( u[0] + u[1] ) / 2.;
    CheckNodeU( E, n12, U, 2*BRep_Tool::Tolerance( E ), /*force=*/true);
    meshDS->SetNodeOnEdge(n12, edgeID, U);
  }
  else if ( myShapeID > 0 )
  {
    meshDS->SetNodeInVolume(n12, myShapeID);
  }

  myTLinkNodeMap.insert( make_pair( link, n12 ));
  return n12;
}
const SMDS_MeshNode * SMESH_MesherHelper::getMediumNodeOnComposedWire ( const SMDS_MeshNode n1,
const SMDS_MeshNode n2,
bool  force3d 
) [protected]

Makes a medium node if nodes reside different edges.

Definition at line 1061 of file SMESH_MesherHelper.cxx.

References AddNode(), CheckNodeU(), SMESH_test.edge, GetMeshDS(), GetNodeU(), GetSubShapeByNode(), Handle(), SMESHDS_Mesh.MoveNode(), myTLinkNodeMap, SMESH_AdvancedEditor.n1, SMESHDS_Mesh.SetNodeOnEdge(), SMESH_fixation.shape, SMESH_AdvancedEditor.tol, and SMDS_MeshNode.X().

Referenced by GetMediumNode().

{
  gp_Pnt middle = 0.5 * XYZ(n1) + 0.5 * XYZ(n2);
  SMDS_MeshNode* n12 = AddNode( middle.X(), middle.Y(), middle.Z() );

  // To find position on edge and 3D position for n12,
  // project <middle> to 2 edges and select projection most close to <middle>

  double u = 0, distMiddleProj = Precision::Infinite(), distXYZ[4];
  int iOkEdge = 0;
  TopoDS_Edge edges[2];
  for ( int is2nd = 0; is2nd < 2; ++is2nd )
  {
    // get an edge
    const SMDS_MeshNode* n = is2nd ? n2 : n1;
    TopoDS_Shape shape = GetSubShapeByNode( n, GetMeshDS() );
    if ( shape.IsNull() || shape.ShapeType() != TopAbs_EDGE )
      continue;

    // project to get U of projection and distance from middle to projection
    TopoDS_Edge edge = edges[ is2nd ] = TopoDS::Edge( shape );
    double node2MiddleDist = middle.Distance( XYZ(n) );
    double foundU = GetNodeU( edge, n );
    CheckNodeU( edge, n12, foundU, 2*BRep_Tool::Tolerance(edge), /*force=*/true, distXYZ );
    if ( distXYZ[0] < node2MiddleDist )
    {
      distMiddleProj = distXYZ[0];
      u = foundU;
      iOkEdge = is2nd;
    }
  }
  if ( Precision::IsInfinite( distMiddleProj ))
  {
    // both projections failed; set n12 on the edge of n1 with U of a common vertex
    TopoDS_Vertex vCommon;
    if ( TopExp::CommonVertex( edges[0], edges[1], vCommon ))
      u = BRep_Tool::Parameter( vCommon, edges[0] );
    else
    {
      double f,l, u0 = GetNodeU( edges[0], n1 );
      BRep_Tool::Range( edges[0],f,l );
      u = ( fabs(u0-f) < fabs(u0-l) ) ? f : l;
    }
    iOkEdge = 0;
    distMiddleProj = 0;
  }

  // move n12 to position of a successfull projection
  double tol = BRep_Tool::Tolerance(edges[ iOkEdge ]);
  if ( !force3d && distMiddleProj > 2*tol )
  {
    TopLoc_Location loc; double f,l;
    Handle(Geom_Curve) curve = BRep_Tool::Curve( edges[iOkEdge],loc,f,l );
    gp_Pnt p = curve->Value( u );
    GetMeshDS()->MoveNode( n12, p.X(), p.Y(), p.Z() );
  }

  GetMeshDS()->SetNodeOnEdge(n12, edges[iOkEdge], u);

  myTLinkNodeMap.insert( make_pair( SMESH_TLink(n1,n2), n12 ));

  return n12;
}
SMESH_Mesh* SMESH_MesherHelper.GetMesh ( ) const

Definition at line 159 of file SMESH_MesherHelper.hxx.

Referenced by StdMeshers_PrismAsBlock.TSideFace.GetEdge().

{ return myMesh; }
SMESHDS_Mesh* SMESH_MesherHelper.GetMeshDS ( ) const
gp_XY SMESH_MesherHelper::GetMiddleUV ( const Handle(Geom_Surface)&  surface,
const gp_XY &  uv1,
const gp_XY &  uv2 
) [static]

Return middle UV taking in account surface period.

Definition at line 734 of file SMESH_MesherHelper.cxx.

References applyIn2D(), SMESH.DownCast(), and Handle().

Referenced by FixQuadraticElements(), and GetMediumNode().

{
  // NOTE:
  // the proper place of getting basic surface seems to be in applyIn2D()
  // but we put it here to decrease a risk of regressions just before releasing a version
  Handle(Geom_Surface) surf = surface;
  while ( !surf.IsNull() && surf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface )))
    surf = Handle(Geom_RectangularTrimmedSurface)::DownCast( surf )->BasisSurface();

  return applyIn2D( surf, p1, p2, & AverageUV );
}
double SMESH_MesherHelper::GetNodeU ( const TopoDS_Edge &  theEdge,
const SMDS_MeshNode theNode,
const SMDS_MeshNode inEdgeNode = 0,
bool check = 0 
)

Return U of the given node on the edge.

Definition at line 753 of file SMESH_MesherHelper.cxx.

References CheckNodeU(), GetMeshDS(), SMDS_MeshNode.GetPosition(), SMDS_MeshElement.getshapeId(), SMDS_Position.GetTypeOfPosition(), SMDS_EdgePosition.GetUParameter(), SMESHDS_Mesh.IndexToShape(), SMESHDS_Mesh.ShapeToIndex(), SMDS_TOP_EDGE, SMDS_TOP_VERTEX, and SMESH_AdvancedEditor.tol.

Referenced by VISCOUS._Shrinker1D.AddEdge(), VISCOUS._Shrinker1D.Compute(), StdMeshers_Hexa_3D.Compute(), VISCOUS._LayerEdge.Copy(), StdMeshers_ProjectionUtils.FindMatchingNodesOnFaces(), GetMediumNode(), getMediumNodeOnComposedWire(), StdMeshers_FaceSide.GetUVPtStruct(), VISCOUS._ViscousBuilder.prepareEdgeToShrink(), VISCOUS._ViscousBuilder.refine(), VISCOUS._ViscousBuilder.setEdgeData(), VISCOUS._LayerEdge.SetNewLength2d(), and StdMeshers_PrismAsBlock.TSideFace.Value().

{
  double param = 0;
  const SMDS_PositionPtr pos = n->GetPosition();
  if ( pos->GetTypeOfPosition()==SMDS_TOP_EDGE )
  {
    const SMDS_EdgePosition* epos = static_cast<const SMDS_EdgePosition*>( pos );
    param =  epos->GetUParameter();
  }
  else if( pos->GetTypeOfPosition() == SMDS_TOP_VERTEX )
  {
    if ( inEdgeNode && TopExp::FirstVertex( E ).IsSame( TopExp::LastVertex( E ))) // issue 0020128
    {
      Standard_Real f,l;
      BRep_Tool::Range( E, f,l );
      double uInEdge = GetNodeU( E, inEdgeNode );
      param = ( fabs( uInEdge - f ) < fabs( l - uInEdge )) ? f : l;
    }
    else
    {
      SMESHDS_Mesh * meshDS = GetMeshDS();
      int vertexID = n->getshapeId();
      const TopoDS_Vertex& V = TopoDS::Vertex(meshDS->IndexToShape(vertexID));
      param =  BRep_Tool::Parameter( V, E );
    }
  }
  if ( check )
  {
    double tol = BRep_Tool::Tolerance( E );
    double f,l;  BRep_Tool::Range( E, f,l );
    bool force = ( param < f-tol || param > l+tol );
    if ( !force && pos->GetTypeOfPosition()==SMDS_TOP_EDGE )
      force = ( GetMeshDS()->ShapeToIndex( E ) != n->getshapeId() );

    *check = CheckNodeU( E, n, param, 2*tol, force );
  }
  return param;
}
gp_XY SMESH_MesherHelper::GetNodeUV ( const TopoDS_Face &  F,
const SMDS_MeshNode n,
const SMDS_MeshNode inFaceNode = 0,
bool check = 0 
) const

Return node UV on face.

Parameters:
inFaceNode- a node of element being created located inside a face

Definition at line 468 of file SMESH_MesherHelper.cxx.

References CheckNodeUV(), SMESH_test.edge, GetMeshDS(), SMDS_MeshNode.GetPosition(), SMDS_MeshElement.getshapeId(), SMDS_Position.GetTypeOfPosition(), SMDS_EdgePosition.GetUParameter(), SMDS_FacePosition.GetUParameter(), GetUVOnSeam(), SMDS_FacePosition.GetVParameter(), Handle(), IsSeamShape(), MaxTolerance(), MESSAGE, myMesh, SMDS_TOP_EDGE, SMDS_TOP_FACE, and SMDS_TOP_VERTEX.

Referenced by SMESH_Pattern.Apply(), VISCOUS._LayerEdge.Copy(), StdMeshers_ProjectionUtils.FindMatchingNodesOnFaces(), FixQuadraticElements(), GetMediumNode(), VISCOUS._Simplex.IsForward(), StdMeshers_Penta_3D.MakeNodes(), VISCOUS._ViscousBuilder.prepareEdgeToShrink(), SMESH_MeshEditor.QuadToTri(), VISCOUS._ViscousBuilder.refine(), VISCOUS._ViscousBuilder.setEdgeData(), VISCOUS._LayerEdge.SetNewLength2d(), VISCOUS._ViscousBuilder.shrink(), VISCOUS._SmoothNode.Smooth(), VISCOUS._ViscousBuilder.smoothAnalyticEdge(), and StdMeshers_PrismAsBlock.TSideFace.Value().

{
  gp_Pnt2d uv( Precision::Infinite(), Precision::Infinite() );
  const SMDS_PositionPtr Pos = n->GetPosition();
  bool uvOK = false;
  if(Pos->GetTypeOfPosition()==SMDS_TOP_FACE)
  {
    // node has position on face
    const SMDS_FacePosition* fpos =
      static_cast<const SMDS_FacePosition*>(n->GetPosition());
    uv.SetCoord(fpos->GetUParameter(),fpos->GetVParameter());
    if ( check )
      uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 10*MaxTolerance( F ));
  }
  else if(Pos->GetTypeOfPosition()==SMDS_TOP_EDGE)
  {
    // node has position on edge => it is needed to find
    // corresponding edge from face, get pcurve for this
    // edge and retrieve value from this pcurve
    const SMDS_EdgePosition* epos =
      static_cast<const SMDS_EdgePosition*>(n->GetPosition());
    int edgeID = n->getshapeId();
    TopoDS_Edge E = TopoDS::Edge(GetMeshDS()->IndexToShape(edgeID));
    double f, l, u = epos->GetUParameter();
    Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
    bool validU = ( f < u && u < l );
    if ( validU )
      uv = C2d->Value( u );
    else
      uv.SetCoord( Precision::Infinite(),0.);
    if ( check || !validU )
      uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 10*MaxTolerance( F ),/*force=*/ !validU );

    // for a node on a seam edge select one of UVs on 2 pcurves
    if ( n2 && IsSeamShape( edgeID ) )
    {
      uv = GetUVOnSeam( uv, GetNodeUV( F, n2, 0, check ));
    }
    else
    { // adjust uv to period
      TopLoc_Location loc;
      Handle(Geom_Surface) S = BRep_Tool::Surface(F,loc);
      Standard_Boolean isUPeriodic = S->IsUPeriodic();
      Standard_Boolean isVPeriodic = S->IsVPeriodic();
      if ( isUPeriodic || isVPeriodic ) {
        Standard_Real UF,UL,VF,VL;
        S->Bounds(UF,UL,VF,VL);
        if(isUPeriodic)
          uv.SetX( uv.X() + ShapeAnalysis::AdjustToPeriod(uv.X(),UF,UL));
        if(isVPeriodic)
          uv.SetY( uv.Y() + ShapeAnalysis::AdjustToPeriod(uv.Y(),VF,VL));
      }
    }
  }
  else if(Pos->GetTypeOfPosition()==SMDS_TOP_VERTEX)
  {
    if ( int vertexID = n->getshapeId() ) {
      const TopoDS_Vertex& V = TopoDS::Vertex(GetMeshDS()->IndexToShape(vertexID));
      try {
        uv = BRep_Tool::Parameters( V, F );
        uvOK = true;
      }
      catch (Standard_Failure& exc) {
      }
      if ( !uvOK ) {
        for ( TopExp_Explorer vert(F,TopAbs_VERTEX); !uvOK && vert.More(); vert.Next() )
          uvOK = ( V == vert.Current() );
        if ( !uvOK ) {
#ifdef _DEBUG_
          MESSAGE ( "SMESH_MesherHelper::GetNodeUV(); Vertex " << vertexID
               << " not in face " << GetMeshDS()->ShapeToIndex( F ) );
#endif
          // get UV of a vertex closest to the node
          double dist = 1e100;
          gp_Pnt pn = XYZ( n );
          for ( TopExp_Explorer vert(F,TopAbs_VERTEX); !uvOK && vert.More(); vert.Next() ) {
            TopoDS_Vertex curV = TopoDS::Vertex( vert.Current() );
            gp_Pnt p = BRep_Tool::Pnt( curV );
            double curDist = p.SquareDistance( pn );
            if ( curDist < dist ) {
              dist = curDist;
              uv = BRep_Tool::Parameters( curV, F );
              uvOK = ( dist < DBL_MIN );
            }
          }
        }
        else {
          uvOK = false;
          TopTools_ListIteratorOfListOfShape it( myMesh->GetAncestors( V ));
          for ( ; it.More(); it.Next() ) {
            if ( it.Value().ShapeType() == TopAbs_EDGE ) {
              const TopoDS_Edge & edge = TopoDS::Edge( it.Value() );
              double f,l;
              Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edge, F, f, l);
              if ( !C2d.IsNull() ) {
                double u = ( V == TopExp::FirstVertex( edge ) ) ?  f : l;
                uv = C2d->Value( u );
                uvOK = true;
                break;
              }
            }
          }
        }
      }
      if ( n2 && IsSeamShape( vertexID ) )
        uv = GetUVOnSeam( uv, GetNodeUV( F, n2, 0 ));
    }
  }
  else
  {
    uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 10*MaxTolerance( F ));
  }

  if ( check )
    *check = uvOK;

  return uv.XY();
}
bool SMESH_MesherHelper::GetNodeUVneedInFaceNode ( const TopoDS_Face &  F = TopoDS_Face()) const

Check if inFaceNode argument is necessary for call GetNodeUV(F,..)

Return values:
bool- return true if the face is periodic

If F is Null, answer about subshape set through IsQuadraticSubMesh() or SetSubShape()

Definition at line 285 of file SMESH_MesherHelper.cxx.

References Handle(), mySeamShapeIds, and myShape.

Referenced by SMESH_Pattern.Apply(), and SMESH_MeshEditor.QuadToTri().

{
  if ( F.IsNull() ) return !mySeamShapeIds.empty();

  if ( !F.IsNull() && !myShape.IsNull() && myShape.IsSame( F ))
    return !mySeamShapeIds.empty();

  TopLoc_Location loc;
  Handle(Geom_Surface) aSurface = BRep_Tool::Surface( F,loc );
  if ( !aSurface.IsNull() )
    return ( aSurface->IsUPeriodic() || aSurface->IsVPeriodic() );

  return false;
}
double SMESH_MesherHelper::GetOtherParam ( const double  param) const

Return an alternative parameter for a node on seam.

Definition at line 1834 of file SMESH_MesherHelper.cxx.

References myPar1, myPar2, and myParIndex.

{
  int i = myParIndex & U_periodic ? 0 : 1;
  return fabs(param-myPar1[i]) < fabs(param-myPar2[i]) ? myPar2[i] : myPar1[i];
}
int SMESH_MesherHelper.GetPeriodicIndex ( ) const

Return index of periodic parametric direction of a closed face.

Return values:
int- 1 for U, 2 for V direction

Definition at line 433 of file SMESH_MesherHelper.hxx.

{ return myParIndex; }
GeomAPI_ProjectPointOnSurf & SMESH_MesherHelper::GetProjector ( const TopoDS_Face &  F,
TopLoc_Location &  loc,
double  tol = 0 
) const

Return projector intitialized by given face without location, which is returned.

Definition at line 662 of file SMESH_MesherHelper.cxx.

References GetMeshDS(), Handle(), myFace2Projector, and SMESHDS_Mesh.ShapeToIndex().

Referenced by CheckNodeUV().

{
  Handle(Geom_Surface) surface = BRep_Tool::Surface( F,loc );
  int faceID = GetMeshDS()->ShapeToIndex( F );
  TID2ProjectorOnSurf& i2proj = const_cast< TID2ProjectorOnSurf&>( myFace2Projector );
  TID2ProjectorOnSurf::iterator i_proj = i2proj.find( faceID );
  if ( i_proj == i2proj.end() )
  {
    if ( tol == 0 ) tol = BRep_Tool::Tolerance( F );
    double U1, U2, V1, V2;
    surface->Bounds(U1, U2, V1, V2);
    GeomAPI_ProjectPointOnSurf* proj = new GeomAPI_ProjectPointOnSurf();
    proj->Init( surface, U1, U2, V1, V2, tol );
    i_proj = i2proj.insert( make_pair( faceID, proj )).first;
  }
  return *( i_proj->second );
}
const TopoDS_Shape& SMESH_MesherHelper.GetSubShape ( ) const
TopoDS_Shape SMESH_MesherHelper::GetSubShapeByNode ( const SMDS_MeshNode node,
const SMESHDS_Mesh meshDS 
) [static]
int SMESH_MesherHelper.GetSubShapeID ( ) const

Return ID of the shape set by IsQuadraticSubMesh() or SetSubShape()

Return values:
int- shape index in SMESHDS

Definition at line 200 of file SMESH_MesherHelper.hxx.

Referenced by StdMeshers_Prism_3D.AddPrisms(), StdMeshers_Projection_3D.Compute(), SMESH_MeshEditor.QuadToTri(), and VISCOUS._ViscousBuilder.refine().

{ return myShapeID; }
TopAbs_Orientation SMESH_MesherHelper::GetSubShapeOri ( const TopoDS_Shape &  shape,
const TopoDS_Shape &  subShape 
) [static]

Return orientation of sub-shape in the main shape.

Definition at line 1684 of file SMESH_MesherHelper.cxx.

Referenced by VISCOUS._ViscousBuilder.addBoundaryElements(), StdMeshers_Hexa_3D.Compute(), and VISCOUS._ViscousBuilder.setEdgeData().

{
  TopAbs_Orientation ori = TopAbs_Orientation(-1);
  if ( !shape.IsNull() && !subShape.IsNull() )
  {
    TopExp_Explorer e( shape, subShape.ShapeType() );
    if ( shape.Orientation() >= TopAbs_INTERNAL ) // TopAbs_INTERNAL or TopAbs_EXTERNAL
      e.Init( shape.Oriented(TopAbs_FORWARD), subShape.ShapeType() );
    for ( ; e.More(); e.Next())
      if ( subShape.IsSame( e.Current() ))
        break;
    if ( e.More() )
      ori = e.Current().Orientation();
  }
  return ori;
}
const TLinkNodeMap& SMESH_MesherHelper.GetTLinkNodeMap ( ) const

Returns myTLinkNodeMap.

Definition at line 467 of file SMESH_MesherHelper.hxx.

{ return myTLinkNodeMap; }
gp_Pnt2d SMESH_MesherHelper::GetUVOnSeam ( const gp_Pnt2d &  uv1,
const gp_Pnt2d &  uv2 
) const [protected]

Select UV on either of 2 pcurves of a seam edge, closest to the given UV.

Parameters:
uv1- UV on the seam
uv2- UV within a face
Return values:
gp_Pnt2d- selected UV

Definition at line 440 of file SMESH_MesherHelper.cxx.

References Abs(), myPar1, myPar2, myParIndex, PAL_MESH_041_mesh.p1, and PAL_MESH_041_mesh.p2.

Referenced by GetNodeUV().

{
  gp_Pnt2d result = uv1;
  for ( int i = U_periodic; i <= V_periodic ; ++i )
  {
    if ( myParIndex & i )
    {
      double p1 = uv1.Coord( i );
      double dp1 = Abs( p1-myPar1[i-1]), dp2 = Abs( p1-myPar2[i-1]);
      if ( myParIndex == i ||
           dp1 < ( myPar2[i-1] - myPar2[i-1] ) / 100. ||
           dp2 < ( myPar2[i-1] - myPar2[i-1] ) / 100. )
      {
        double p2 = uv2.Coord( i );
        double p1Alt = ( dp1 < dp2 ) ? myPar2[i-1] : myPar1[i-1];
        if ( Abs( p2 - p1 ) > Abs( p2 - p1Alt ))
          result.SetCoord( i, p1Alt );
      }
    }
  }
  return result;
}
bool SMESH_MesherHelper.HasDegeneratedEdges ( ) const

Check if the shape set through IsQuadraticSubMesh() or SetSubShape() has a degenerated edges.

Return values:
bool- true if it has

Definition at line 389 of file SMESH_MesherHelper.hxx.

{ return !myDegenShapeIds.empty(); }
bool SMESH_MesherHelper.HasSeam ( ) const

Check if the shape set through IsQuadraticSubMesh() or SetSubShape() has a seam edge.

Return values:
bool- true if it has

Definition at line 428 of file SMESH_MesherHelper.hxx.

Referenced by StdMeshers_ProjectionUtils.FindMatchingNodesOnFaces().

{ return !mySeamShapeIds.empty(); }
bool SMESH_MesherHelper::IsClosedEdge ( const TopoDS_Edge &  anEdge) [static]

Check if the first and last vertices of an edge are the same.

Parameters:
anEdge- the edge to check
Return values:
bool- true if same

Definition at line 1766 of file SMESH_MesherHelper.cxx.

Referenced by StdMeshers_ProjectionUtils.FindMatchingNodesOnFaces(), StdMeshers_ProjectionUtils.FindSubShapeAssociation(), and StdMeshers_PrismAsBlock.IsForwardEdge().

{
  if ( anEdge.Orientation() >= TopAbs_INTERNAL )
    return IsClosedEdge( TopoDS::Edge( anEdge.Oriented( TopAbs_FORWARD )));
  return TopExp::FirstVertex( anEdge ).IsSame( TopExp::LastVertex( anEdge ));
}
bool SMESH_MesherHelper.IsDegenShape ( const int  subShape) const

Check if shape is a degenerated edge or it's vertex.

Parameters:
subShape- edge or vertex index in SMESHDS
Return values:
bool- true if subShape is a degenerated shape

It works only if IsQuadraticSubMesh() or SetSubShape() has been called

Definition at line 382 of file SMESH_MesherHelper.hxx.

Referenced by GetMediumNode().

  { return myDegenShapeIds.find( subShape ) != myDegenShapeIds.end(); }
bool SMESH_MesherHelper::IsMedium ( const SMDS_MeshNode node,
const SMDSAbs_ElementType  typeToCheck = SMDSAbs_All 
) [static]

Returns true if given node is medium.

Parameters:
n- node to check
typeToCheck- type of elements containing the node to ask about node status
Return values:
bool- check result

Definition at line 428 of file SMESH_MeshEditor.cxx.

References SMDS_MeshNode.GetInverseElementIterator(), and SMDS_MeshElement.IsMediumNode().

Referenced by StdMeshers_Penta_3D.FindNodeOnShape(), fixCommonVertexUV(), SMESH_Mesh_i.IsMediumNodeOfAnyElem(), StdMeshers_Penta_3D.LoadIJNodes(), StdMeshers_Penta_3D.MakeMeshOnFxy1(), and StdMeshers_Penta_3D.MakeNodes().

{
  bool isMedium = false;
  SMDS_ElemIteratorPtr it = node->GetInverseElementIterator(typeToCheck);
  while (it->more() && !isMedium ) {
    const SMDS_MeshElement* elem = it->next();
    isMedium = elem->IsMediumNode(node);
  }
  return isMedium;
}
SMESH_MesherHelper::MType SMESH_MesherHelper::IsQuadraticMesh ( )

Definition at line 1802 of file SMESH_MesherHelper.cxx.

References COMP, LINEAR, myMesh, ORDER_LINEAR, ORDER_QUADRATIC, and QUADRATIC.

{
  int NbAllEdgsAndFaces=0;
  int NbQuadFacesAndEdgs=0;
  int NbFacesAndEdges=0;
  //All faces and edges
  NbAllEdgsAndFaces = myMesh->NbEdges() + myMesh->NbFaces();
  
  //Quadratic faces and edges
  NbQuadFacesAndEdgs = myMesh->NbEdges(ORDER_QUADRATIC) + myMesh->NbFaces(ORDER_QUADRATIC);

  //Linear faces and edges
  NbFacesAndEdges = myMesh->NbEdges(ORDER_LINEAR) + myMesh->NbFaces(ORDER_LINEAR);
  
  if (NbAllEdgsAndFaces == NbQuadFacesAndEdgs) {
    //Quadratic mesh
    return SMESH_MesherHelper::QUADRATIC;
  }
  else if (NbAllEdgsAndFaces == NbFacesAndEdges) {
    //Linear mesh
    return SMESH_MesherHelper::LINEAR;
  }
  else
    //Mesh with both type of elements
    return SMESH_MesherHelper::COMP;
}
bool SMESH_MesherHelper::IsQuadraticSubMesh ( const TopoDS_Shape &  theShape)

Check submesh for given shape: if all elements on this shape are quadratic, quadratic elements will be created.

Also fill myTLinkNodeMap

Definition at line 113 of file SMESH_MesherHelper.cxx.

References AddTLinkNode(), AddTLinks(), SMDS_Mesh.facesIterator(), GetMeshDS(), SMDS_MeshElement.GetNode(), SMDS_MeshElement.GetType(), SMDS_MeshElement.IsQuadratic(), SMESHDS_Mesh.MeshElements(), myCreateQuadratic, myDegenShapeIds, myMesh, mySeamShapeIds, myTLinkNodeMap, SMDS_MeshElement.NbNodes(), ORDER_QUADRATIC, SetSubShape(), SMDSAbs_Edge, and SMDSAbs_Face.

Referenced by StdMeshers_QuadToTriaAdaptor.Compute(), StdMeshers_Quadrangle_2D.Compute(), StdMeshers_Projection_3D.Compute(), StdMeshers_Penta_3D.Compute(), StdMeshers_Hexa_3D.Compute(), StdMeshers_CompositeHexa_3D.Compute(), StdMeshers_Penta_3D.Evaluate(), and StdMeshers_CompositeHexa_3D.Evaluate().

{
  SMESHDS_Mesh* meshDS = GetMeshDS();
  // we can create quadratic elements only if all elements
  // created on subshapes of given shape are quadratic
  // also we have to fill myTLinkNodeMap
  myCreateQuadratic = true;
  mySeamShapeIds.clear();
  myDegenShapeIds.clear();
  TopAbs_ShapeEnum subType( aSh.ShapeType()==TopAbs_FACE ? TopAbs_EDGE : TopAbs_FACE );
  SMDSAbs_ElementType elemType( subType==TopAbs_FACE ? SMDSAbs_Face : SMDSAbs_Edge );

  int nbOldLinks = myTLinkNodeMap.size();

  if ( !myMesh->HasShapeToMesh() )
  {
    if (( myCreateQuadratic = myMesh->NbFaces( ORDER_QUADRATIC )))
    {
      SMDS_FaceIteratorPtr fIt = meshDS->facesIterator();
      while ( fIt->more() )
        AddTLinks( static_cast< const SMDS_MeshFace* >( fIt->next() ));
    }
  }
  else
  {
    TopExp_Explorer exp( aSh, subType );
    TopTools_MapOfShape checkedSubShapes;
    for (; exp.More() && myCreateQuadratic; exp.Next()) {
      if ( !checkedSubShapes.Add( exp.Current() ))
        continue; // needed if aSh is compound of solids
      if ( SMESHDS_SubMesh * subMesh = meshDS->MeshElements( exp.Current() )) {
        if ( SMDS_ElemIteratorPtr it = subMesh->GetElements() ) {
          while(it->more()) {
            const SMDS_MeshElement* e = it->next();
            if ( e->GetType() != elemType || !e->IsQuadratic() ) {
              myCreateQuadratic = false;
              break;
            }
            else {
              // fill TLinkNodeMap
              switch ( e->NbNodes() ) {
              case 3:
                AddTLinkNode(e->GetNode(0),e->GetNode(1),e->GetNode(2)); break;
              case 6:
                AddTLinkNode(e->GetNode(0),e->GetNode(1),e->GetNode(3));
                AddTLinkNode(e->GetNode(1),e->GetNode(2),e->GetNode(4));
                AddTLinkNode(e->GetNode(2),e->GetNode(0),e->GetNode(5)); break;
              case 8:
                AddTLinkNode(e->GetNode(0),e->GetNode(1),e->GetNode(4));
                AddTLinkNode(e->GetNode(1),e->GetNode(2),e->GetNode(5));
                AddTLinkNode(e->GetNode(2),e->GetNode(3),e->GetNode(6));
                AddTLinkNode(e->GetNode(3),e->GetNode(0),e->GetNode(7));
                break;
              default:
                myCreateQuadratic = false;
                break;
              }
            }
          }
        }
      }
    }
  }

  if ( nbOldLinks == myTLinkNodeMap.size() )
    myCreateQuadratic = false;

  if(!myCreateQuadratic) {
    myTLinkNodeMap.clear();
  }
  SetSubShape( aSh );

  return myCreateQuadratic;
}
bool SMESH_MesherHelper.IsRealSeam ( const TopoDS_Shape &  subShape) const

Return true if an edge or a vertex encounters twice in face wire.

Parameters:
subShape- edge or vertex

Definition at line 421 of file SMESH_MesherHelper.hxx.

References IsRealSeam().

Referenced by IsRealSeam().

  { return IsRealSeam( GetMeshDS()->ShapeToIndex( subShape)); }
bool SMESH_MesherHelper.IsRealSeam ( const int  subShape) const

Return true if an edge or a vertex encounters twice in face wire.

Parameters:
subShape- Id of edge or vertex

Definition at line 415 of file SMESH_MesherHelper.hxx.

Referenced by StdMeshers_ProjectionUtils.FindMatchingNodesOnFaces().

  { return mySeamShapeIds.find( -subShape ) != mySeamShapeIds.end(); }
bool SMESH_MesherHelper.IsSeamShape ( const int  subShape) const

Check if shape is a seam edge or it's vertex.

Parameters:
subShape- edge or vertex index in SMESHDS
Return values:
bool- true if subShape is a seam shape

It works only if IsQuadraticSubMesh() or SetSubShape() has been called. Seam shape has two 2D alternative represenations on the face

Definition at line 399 of file SMESH_MesherHelper.hxx.

Referenced by SMESH_Pattern.Apply(), StdMeshers_ProjectionUtils.FindMatchingNodesOnFaces(), GetMediumNode(), GetNodeUV(), and SetSubShape().

  { return mySeamShapeIds.find( subShape ) != mySeamShapeIds.end(); }
bool SMESH_MesherHelper.IsSeamShape ( const TopoDS_Shape &  subShape) const

Check if shape is a seam edge or it's vertex.

Parameters:
subShape- edge or vertex
Return values:
bool- true if subShape is a seam shape

It works only if IsQuadraticSubMesh() or SetSubShape() has been called. Seam shape has two 2D alternative represenations on the face

Definition at line 409 of file SMESH_MesherHelper.hxx.

References IsSeamShape().

Referenced by IsSeamShape().

  { return IsSeamShape( GetMeshDS()->ShapeToIndex( subShape )); }
bool SMESH_MesherHelper::IsSubShape ( const TopoDS_Shape &  shape,
const TopoDS_Shape &  mainShape 
) [static]

Definition at line 1707 of file SMESH_MesherHelper.cxx.

Referenced by VISCOUS._ViscousBuilder.addBoundaryElements(), StdMeshers_Projection_3D.CheckHypothesis(), StdMeshers_Projection_3D.Compute(), VISCOUS._ViscousBuilder.findFacesWithLayers(), StdMeshers_ProjectionUtils.FindMatchingNodesOnFaces(), VISCOUS._ViscousBuilder.findNeiborsOnEdge(), StdMeshers_PrismAsBlock.Init(), SMESH_HypoFilter.IsMoreLocalThanPredicate.IsOk(), and VISCOUS._ViscousBuilder.updateNormals().

{
  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;
}
bool SMESH_MesherHelper::IsSubShape ( const TopoDS_Shape &  shape,
SMESH_Mesh aMesh 
) [static]

Definition at line 1728 of file SMESH_MesherHelper.cxx.

{
  if ( shape.IsNull() || !aMesh )
    return false;
  return
    aMesh->GetMeshDS()->ShapeToIndex( shape ) ||
    // PAL16202
    (shape.ShapeType() == TopAbs_COMPOUND && aMesh->GetMeshDS()->IsGroupOfSubShapes( shape ));
}
TopoDS_Vertex SMESH_MesherHelper::IthVertex ( const bool  is2nd,
TopoDS_Edge  anEdge,
const bool  CumOri = true 
) [static]

Wrapper over TopExp.FirstVertex() and TopExp.LastVertex() fixing them in the case of INTERNAL edge.

Definition at line 1780 of file SMESH_MesherHelper.cxx.

Referenced by StdMeshers_FaceSide.GetUVPtStruct().

{
  if ( anEdge.Orientation() >= TopAbs_INTERNAL )
    anEdge.Orientation( TopAbs_FORWARD );

  const TopAbs_Orientation tgtOri = is2nd ? TopAbs_REVERSED : TopAbs_FORWARD;
  TopoDS_Iterator vIt( anEdge, CumOri );
  while ( vIt.More() && vIt.Value().Orientation() != tgtOri )
    vIt.Next();

  return ( vIt.More() ? TopoDS::Vertex(vIt.Value()) : TopoDS_Vertex() );
}
bool SMESH_MesherHelper::LoadNodeColumns ( TParam2ColumnMap theParam2ColumnMap,
const TopoDS_Face &  theFace,
const TopoDS_Edge &  theBaseEdge,
SMESHDS_Mesh theMesh,
SMESH_ProxyMesh theProxyMesh = 0 
) [static]

Load nodes bound to face into a map of node columns.

Parameters:
theParam2ColumnMap- map of node columns to fill
theFace- the face on which nodes are searched for
theBaseEdge- the edge nodes of which are columns' bases
theMesh- the mesh containing nodes
Return values:
bool- false if something is wrong

The key of the map is a normalized parameter of each base node on theBaseEdge. This method works in supposition that nodes on the face forms a rectangular grid and elements can be quardrangles or triangles

Definition at line 1572 of file SMESH_MesherHelper.cxx.

References SMESHDS_SubMesh.Contains(), PAL_MESH_043_3D.face, SMESH_MeshEditor.FindFaceInSet(), SMESHDS_SubMesh.GetElements(), SMESH_ProxyMesh.GetProxyNode(), SMESH_Algo.GetSortedNodesOnEdge(), SMESH_ProxyMesh.GetSubMesh(), SMESH_test.i1, SMESH_test.i2, SMESH_ProxyMesh.IsTemporary(), SMESHDS_Mesh.MeshElements(), SMESH_AdvancedEditor.n1, SMESH_AdvancedEditor.n2, and SMESHDS_SubMesh.NbElements().

Referenced by StdMeshers_Hexa_3D.Compute().

{
  const SMESHDS_SubMesh* faceSubMesh = 0;
  if ( theProxyMesh )
  {
    faceSubMesh = theProxyMesh->GetSubMesh( theFace );
    if ( !faceSubMesh ||
         faceSubMesh->NbElements() == 0 ||
         theProxyMesh->IsTemporary( faceSubMesh->GetElements()->next() ))
    {
      // can use a proxy sub-mesh with not temporary elements only
      faceSubMesh = 0;
      theProxyMesh = 0;
    }
  }
  if ( !faceSubMesh )
    faceSubMesh = theMesh->MeshElements( theFace );
  if ( !faceSubMesh || faceSubMesh->NbElements() == 0 )
    return false;

  // get nodes on theBaseEdge sorted by param on edge and initialize theParam2ColumnMap with them

  map< double, const SMDS_MeshNode*> sortedBaseNodes;
  if ( !SMESH_Algo::GetSortedNodesOnEdge( theMesh, theBaseEdge,/*noMedium=*/true, sortedBaseNodes)
       || sortedBaseNodes.size() < 2 )
    return false;

  int nbRows = faceSubMesh->NbElements() / ( sortedBaseNodes.size()-1 ) + 1;
  map< double, const SMDS_MeshNode*>::iterator u_n = sortedBaseNodes.begin();
  double f = u_n->first, range = sortedBaseNodes.rbegin()->first - f;
  for ( ; u_n != sortedBaseNodes.end(); u_n++ )
  {
    double par = ( u_n->first - f ) / range;
    vector<const SMDS_MeshNode*>& nCol = theParam2ColumnMap[ par ];
    nCol.resize( nbRows );
    nCol[0] = u_n->second;
  }
  TParam2ColumnMap::iterator par_nVec_2, par_nVec_1 = theParam2ColumnMap.begin();
  if ( theProxyMesh )
  {
    for ( ; par_nVec_1 != theParam2ColumnMap.end(); ++par_nVec_1 )
    {
      const SMDS_MeshNode* & n = par_nVec_1->second[0];
      n = theProxyMesh->GetProxyNode( n );
    }
  }

  // fill theParam2ColumnMap column by column by passing from nodes on
  // theBaseEdge up via mesh faces on theFace

  par_nVec_2 = theParam2ColumnMap.begin();
  par_nVec_1 = par_nVec_2++;
  TIDSortedElemSet emptySet, avoidSet;
  for ( ; par_nVec_2 != theParam2ColumnMap.end(); ++par_nVec_1, ++par_nVec_2 )
  {
    vector<const SMDS_MeshNode*>& nCol1 = par_nVec_1->second;
    vector<const SMDS_MeshNode*>& nCol2 = par_nVec_2->second;

    int i1, i2, iRow = 0;
    const SMDS_MeshNode *n1 = nCol1[0], *n2 = nCol2[0];
    // find face sharing node n1 and n2 and belonging to faceSubMesh
    while ( const SMDS_MeshElement* face =
            SMESH_MeshEditor::FindFaceInSet( n1, n2, emptySet, avoidSet, &i1, &i2))
    {
      if ( faceSubMesh->Contains( face ))
      {
        int nbNodes = face->IsQuadratic() ? face->NbNodes()/2 : face->NbNodes();
        if ( nbNodes != 4 )
          return false;
        n1 = face->GetNode( (i2+2) % 4 ); // opposite corner of quadrangle face
        n2 = face->GetNode( (i1+2) % 4 );
        if ( ++iRow >= nbRows )
          return false;
        nCol1[ iRow ] = n1;
        nCol2[ iRow ] = n2;
        avoidSet.clear();
      }
      avoidSet.insert( face );
    }
    if ( iRow + 1 < nbRows ) // compact if necessary
      nCol1.resize( iRow + 1 ), nCol2.resize( iRow + 1 );
  }
  return theParam2ColumnMap.size() > 1 && theParam2ColumnMap.begin()->second.size() > 1;
}
double SMESH_MesherHelper::MaxTolerance ( const TopoDS_Shape &  shape) [static]

Return maximal tolerance of shape.

Definition at line 1744 of file SMESH_MesherHelper.cxx.

References Max(), and SMESH_AdvancedEditor.tol.

Referenced by GetNodeUV().

{
  double tol = Precision::Confusion();
  TopExp_Explorer exp;
  for ( exp.Init( shape, TopAbs_FACE ); exp.More(); exp.Next() )
    tol = Max( tol, BRep_Tool::Tolerance( TopoDS::Face( exp.Current())));
  for ( exp.Init( shape, TopAbs_EDGE ); exp.More(); exp.Next() )
    tol = Max( tol, BRep_Tool::Tolerance( TopoDS::Edge( exp.Current())));
  for ( exp.Init( shape, TopAbs_VERTEX ); exp.More(); exp.Next() )
    tol = Max( tol, BRep_Tool::Tolerance( TopoDS::Vertex( exp.Current())));

  return tol;
}
int SMESH_MesherHelper::NbAncestors ( const TopoDS_Shape &  shape,
const SMESH_Mesh mesh,
TopAbs_ShapeEnum  ancestorType = TopAbs_SHAPE 
) [static]

Return number of unique ancestors of the shape.

Definition at line 1666 of file SMESH_MesherHelper.cxx.

Referenced by StdMeshers_QuadToTriaAdaptor.Compute(), and VISCOUS._ViscousBuilder.findFacesWithLayers().

{
  TopTools_MapOfShape ancestors;
  TopTools_ListIteratorOfListOfShape ansIt( mesh.GetAncestors(shape) );
  for ( ; ansIt.More(); ansIt.Next() ) {
    if ( ancestorType == TopAbs_SHAPE || ansIt.Value().ShapeType() == ancestorType )
      ancestors.Add( ansIt.Value() );
  }
  return ancestors.Extent();
}
void SMESH_MesherHelper.SetElementsOnShape ( bool  toSet)

To set created elements on the shape set by IsQuadraticSubMesh() or the next methods.

By defaul elements are set on the shape if a mesh has no shape to be meshed

Definition at line 189 of file SMESH_MesherHelper.hxx.

Referenced by StdMeshers_QuadToTriaAdaptor.Compute(), StdMeshers_Hexa_3D.Compute(), StdMeshers_CompositeHexa_3D.Compute(), SMESH_subMesh.ComputeStateEngine(), VISCOUS._ViscousBuilder.makeLayer(), VISCOUS._ViscousBuilder.refine(), and SMESH_MeshEditor.SplitVolumesIntoTetra().

{ mySetElemOnShape = toSet; }
void SMESH_MesherHelper.SetIsQuadratic ( const bool  theBuildQuadratic)

Set order of elements to create without calling IsQuadraticSubMesh()

Definition at line 171 of file SMESH_MesherHelper.hxx.

Referenced by SMESH_MeshEditor.ConvertToQuadratic(), and SMESH_MeshEditor.SplitVolumesIntoTetra().

  { myCreateQuadratic = theBuildQuadratic; }
void SMESH_MesherHelper::setPosOnShapeValidity ( int  shapeID,
bool  ok 
) const [private]

Set validity of positions of nodes on the shape.

Once set, validity is not changed

Definition at line 430 of file SMESH_MesherHelper.cxx.

Referenced by CheckNodeU(), and CheckNodeUV().

{
  ((SMESH_MesherHelper*)this)->myNodePosShapesValidity.insert( make_pair( shapeID, ok));
}
void SMESH_MesherHelper::SetSubShape ( const int  subShapeID)
void SMESH_MesherHelper::SetSubShape ( const TopoDS_Shape &  subShape)

==SMESHDS_Mesh::ShapeToIndex(shape)

Definition at line 208 of file SMESH_MesherHelper.cxx.

References Abs(), SMESH_test.edge, PAL_MESH_043_3D.face, GetMeshDS(), Handle(), IsSeamShape(), myDegenShapeIds, myPar1, myPar2, myParIndex, mySeamShapeIds, myShape, myShapeID, and SMESHDS_Mesh.ShapeToIndex().

{
  if ( myShape.IsSame( aSh ))
    return;

  myShape = aSh;
  mySeamShapeIds.clear();
  myDegenShapeIds.clear();

  if ( myShape.IsNull() ) {
    myShapeID  = 0;
    return;
  }
  SMESHDS_Mesh* meshDS = GetMeshDS();
  myShapeID = meshDS->ShapeToIndex(aSh);
  myParIndex = 0;

  // treatment of periodic faces
  for ( TopExp_Explorer eF( aSh, TopAbs_FACE ); eF.More(); eF.Next() )
  {
    const TopoDS_Face& face = TopoDS::Face( eF.Current() );
    TopLoc_Location loc;
    Handle(Geom_Surface) surface = BRep_Tool::Surface( face, loc );

    if ( surface->IsUPeriodic() || surface->IsVPeriodic() )
    {
      //while ( surface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface )))
      //surface = Handle(Geom_RectangularTrimmedSurface)::DownCast( surface )->BasisSurface();
      GeomAdaptor_Surface surf( surface );

      for (TopExp_Explorer exp( face, TopAbs_EDGE ); exp.More(); exp.Next())
      {
        // look for a seam edge
        const TopoDS_Edge& edge = TopoDS::Edge( exp.Current() );
        if ( BRep_Tool::IsClosed( edge, face )) {
          // initialize myPar1, myPar2 and myParIndex
          gp_Pnt2d uv1, uv2;
          BRep_Tool::UVPoints( edge, face, uv1, uv2 );
          if ( Abs( uv1.Coord(1) - uv2.Coord(1) ) < Abs( uv1.Coord(2) - uv2.Coord(2) ))
          {
            myParIndex |= U_periodic;
            myPar1[0] = surf.FirstUParameter();
            myPar2[0] = surf.LastUParameter();
          }
          else {
            myParIndex |= V_periodic;
            myPar1[1] = surf.FirstVParameter();
            myPar2[1] = surf.LastVParameter();
          }
          // store seam shape indices, negative if shape encounters twice
          int edgeID = meshDS->ShapeToIndex( edge );
          mySeamShapeIds.insert( IsSeamShape( edgeID ) ? -edgeID : edgeID );
          for ( TopExp_Explorer v( edge, TopAbs_VERTEX ); v.More(); v.Next() ) {
            int vertexID = meshDS->ShapeToIndex( v.Current() );
            mySeamShapeIds.insert( IsSeamShape( vertexID ) ? -vertexID : vertexID );
          }
        }

        // look for a degenerated edge
        if ( BRep_Tool::Degenerated( edge )) {
          myDegenShapeIds.insert( meshDS->ShapeToIndex( edge ));
          for ( TopExp_Explorer v( edge, TopAbs_VERTEX ); v.More(); v.Next() )
            myDegenShapeIds.insert( meshDS->ShapeToIndex( v.Current() ));
        }
      }
    }
  }
}
bool SMESH_MesherHelper::toCheckPosOnShape ( int  shapeID) const [private]

Return true if position of nodes on the shape hasn't yet been checked or the positions proved to be invalid.

Definition at line 417 of file SMESH_MesherHelper.cxx.

References myNodePosShapesValidity.

Referenced by CheckNodeU(), and CheckNodeUV().

{
  map< int,bool >::const_iterator id_ok = myNodePosShapesValidity.find( shapeID );
  return ( id_ok == myNodePosShapesValidity.end() || !id_ok->second );
}
static int SMESH_MesherHelper.WrapIndex ( const int  ind,
const int  nbNodes 
) [static]

Return a valid node index, fixing the given one if necessary.

Parameters:
ind- node index
nbNodes- total nb of nodes
Return values:
int- valid node index

Definition at line 117 of file SMESH_MesherHelper.hxx.

References SMESH_test.ind.

Referenced by SMESH_MeshEditor.GetLinkedNodes(), VISCOUS._ViscousBuilder.getSimplices(), and VISCOUS._ViscousBuilder.limitStepSize().

                                                         {
    if ( ind < 0 ) return nbNodes + ind % nbNodes;
    if ( ind >= nbNodes ) return ind % nbNodes;
    return ind;
  }

Field Documentation

std::set< int > SMESH_MesherHelper.myDegenShapeIds [private]

Definition at line 500 of file SMESH_MesherHelper.hxx.

Referenced by IsQuadraticSubMesh(), and SetSubShape().

Definition at line 508 of file SMESH_MesherHelper.hxx.

Referenced by CheckNodeU(), and ~SMESH_MesherHelper().

Definition at line 506 of file SMESH_MesherHelper.hxx.

Referenced by GetProjector(), and ~SMESH_MesherHelper().

Definition at line 518 of file SMESH_MesherHelper.hxx.

Referenced by toCheckPosOnShape().

double SMESH_MesherHelper.myPar1[2] [private]
double SMESH_MesherHelper.myPar2[2] [private]

Definition at line 503 of file SMESH_MesherHelper.hxx.

Referenced by GetMediumNode(), GetOtherParam(), GetUVOnSeam(), and SetSubShape().

std::set< int > SMESH_MesherHelper.mySeamShapeIds [private]
TopoDS_Shape SMESH_MesherHelper.myShape [private]
Copyright © 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
Copyright © 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS