Back to index

salome-smesh  6.5.0
Classes | Defines | Typedefs | Functions
SMESH_MeshEditor.cxx File Reference
#include "SMESH_MeshEditor.hxx"
#include "SMDS_FaceOfNodes.hxx"
#include "SMDS_VolumeTool.hxx"
#include "SMDS_EdgePosition.hxx"
#include "SMDS_FacePosition.hxx"
#include "SMDS_SpacePosition.hxx"
#include "SMDS_MeshGroup.hxx"
#include "SMDS_LinearEdge.hxx"
#include "SMDS_Downward.hxx"
#include "SMDS_SetIterator.hxx"
#include "SMESHDS_Group.hxx"
#include "SMESHDS_Mesh.hxx"
#include "SMESH_Algo.hxx"
#include "SMESH_ControlsDef.hxx"
#include "SMESH_Group.hxx"
#include "SMESH_MesherHelper.hxx"
#include "SMESH_OctreeNode.hxx"
#include "SMESH_subMesh.hxx"
#include <Basics_OCCTVersion.hxx>
#include "utilities.h"
#include <BRepAdaptor_Surface.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepClass3d_SolidClassifier.hxx>
#include <BRep_Tool.hxx>
#include <ElCLib.hxx>
#include <Extrema_GenExtPS.hxx>
#include <Extrema_POnCurv.hxx>
#include <Extrema_POnSurf.hxx>
#include <GC_MakeSegment.hxx>
#include <Geom2d_Curve.hxx>
#include <GeomAPI_ExtremaCurveCurve.hxx>
#include <GeomAdaptor_Surface.hxx>
#include <Geom_Curve.hxx>
#include <Geom_Line.hxx>
#include <Geom_Surface.hxx>
#include <IntAna_IntConicQuad.hxx>
#include <IntAna_Quadric.hxx>
#include <Precision.hxx>
#include <TColStd_ListOfInteger.hxx>
#include <TopAbs_State.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopTools_SequenceOfShape.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
#include <gp.hxx>
#include <gp_Ax1.hxx>
#include <gp_Dir.hxx>
#include <gp_Lin.hxx>
#include <gp_Pln.hxx>
#include <gp_Trsf.hxx>
#include <gp_Vec.hxx>
#include <gp_XY.hxx>
#include <gp_XYZ.hxx>
#include <cmath>
#include <map>
#include <set>
#include <numeric>
#include <limits>
#include <algorithm>
#include <sstream>

Go to the source code of this file.

Classes

class  LinkID_Gen
struct  SMESH_NodeSearcherImpl
 Implementation of search for the node closest to point. More...
struct  SMESH_ElementSearcherImpl
 Implementation of search for the elements by point and of classification of point in 2D mesh. More...
struct  SMESH_ElementSearcherImpl::TInters
 < data of intersection of the line and the mesh face (used in GetPointState()) More...
struct  SMESH_ElementSearcherImpl::TFaceLink
 < link and faces sharing it (used in findOuterBoundary()) More...
class  SortableElement

Defines

#define cast2Node(elem)   static_cast<const SMDS_MeshNode*>( elem )
#define ControlFreeBorder   SMESH::Controls::FreeEdges::IsFreeEdge

Typedefs

typedef map< const
SMDS_MeshElement *, list
< const SMDS_MeshNode * > > 
TElemOfNodeListMap
typedef map< const
SMDS_MeshElement *, list
< const SMDS_MeshElement * > > 
TElemOfElemListMap
typedef SMDS_SetIterator
< SMDS_pElement,
TIDSortedElemSet::const_iterator > 
TSetIterator

Functions

static void ShiftNodesQuadTria (const SMDS_MeshNode *aNodes[])
static int nbEdgeConnectivity (const SMDS_MeshNode *theNode)
static bool GetNodesFromTwoTria (const SMDS_MeshElement *theTria1, const SMDS_MeshElement *theTria2, const SMDS_MeshNode *N1[], const SMDS_MeshNode *N2[])
static bool findTriangles (const SMDS_MeshNode *theNode1, const SMDS_MeshNode *theNode2, const SMDS_MeshElement *&theTria1, const SMDS_MeshElement *&theTria2)
bool getQuadrangleNodes (const SMDS_MeshNode *theQuadNodes[], const SMDS_MeshNode *theNode1, const SMDS_MeshNode *theNode2, const SMDS_MeshElement *tr1, const SMDS_MeshElement *tr2)
static double getBadRate (const SMDS_MeshElement *theElem, SMESH::Controls::NumericalFunctorPtr &theCrit)
double getAngle (const SMDS_MeshElement *tr1, const SMDS_MeshElement *tr2, const SMDS_MeshNode *n1, const SMDS_MeshNode *n2)
void laplacianSmooth (const SMDS_MeshNode *theNode, const Handle(Geom_Surface)&theSurface, map< const SMDS_MeshNode *, gp_XY * > &theUVMap)
void centroidalSmooth (const SMDS_MeshNode *theNode, const Handle(Geom_Surface)&theSurface, map< const SMDS_MeshNode *, gp_XY * > &theUVMap)
static bool getClosestUV (Extrema_GenExtPS &projector, const gp_Pnt &point, gp_XY &result)
static bool isReverse (const SMDS_MeshElement *face, const vector< const SMDS_MeshNode * > &prevNodes, const vector< const SMDS_MeshNode * > &nextNodes, const int iNotSame)
ostream & operator<< (ostream &out, const SMESH_ElementSearcherImpl::TInters &i)
static const SMDS_MeshElement * findAdjacentFace (const SMDS_MeshNode *n1, const SMDS_MeshNode *n2, const SMDS_MeshElement *elem)

Define Documentation

#define cast2Node (   elem)    static_cast<const SMDS_MeshNode*>( elem )

Definition at line 100 of file SMESH_MeshEditor.cxx.

#define ControlFreeBorder   SMESH::Controls::FreeEdges::IsFreeEdge

Definition at line 7943 of file SMESH_MeshEditor.cxx.


Typedef Documentation

typedef map<const SMDS_MeshElement*, list<const SMDS_MeshElement*> > TElemOfElemListMap

Definition at line 106 of file SMESH_MeshEditor.cxx.

typedef map<const SMDS_MeshElement*, list<const SMDS_MeshNode*> > TElemOfNodeListMap

Definition at line 105 of file SMESH_MeshEditor.cxx.

typedef SMDS_SetIterator< SMDS_pElement, TIDSortedElemSet::const_iterator> TSetIterator

Definition at line 108 of file SMESH_MeshEditor.cxx.


Function Documentation

void centroidalSmooth ( const SMDS_MeshNode *  theNode,
const Handle(Geom_Surface)&  theSurface,
map< const SMDS_MeshNode *, gp_XY * > &  theUVMap 
)

Definition at line 2849 of file SMESH_MeshEditor.cxx.

{
  gp_XYZ aNewXYZ(0.,0.,0.);
  SMESH::Controls::Area anAreaFunc;
  double totalArea = 0.;
  int nbElems = 0;

  // compute new XYZ

  SMDS_ElemIteratorPtr elemIt = theNode->GetInverseElementIterator(SMDSAbs_Face);
  while ( elemIt->more() )
  {
    const SMDS_MeshElement* elem = elemIt->next();
    nbElems++;

    gp_XYZ elemCenter(0.,0.,0.);
    SMESH::Controls::TSequenceOfXYZ aNodePoints;
    SMDS_ElemIteratorPtr itN = elem->nodesIterator();
    int nn = elem->NbNodes();
    if(elem->IsQuadratic()) nn = nn/2;
    int i=0;
    //while ( itN->more() ) {
    while ( i<nn ) {
      const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>( itN->next() );
      i++;
      gp_XYZ aP( aNode->X(), aNode->Y(), aNode->Z() );
      aNodePoints.push_back( aP );
      if ( !theSurface.IsNull() ) { // smooth in 2D
        ASSERT( theUVMap.find( aNode ) != theUVMap.end() );
        gp_XY* uv = theUVMap[ aNode ];
        aP.SetCoord( uv->X(), uv->Y(), 0. );
      }
      elemCenter += aP;
    }
    double elemArea = anAreaFunc.GetValue( aNodePoints );
    totalArea += elemArea;
    elemCenter /= nn;
    aNewXYZ += elemCenter * elemArea;
  }
  aNewXYZ /= totalArea;
  if ( !theSurface.IsNull() ) {
    theUVMap[ theNode ]->SetCoord( aNewXYZ.X(), aNewXYZ.Y() );
    aNewXYZ = theSurface->Value( aNewXYZ.X(), aNewXYZ.Y() ).XYZ();
  }

  // move node

  const_cast< SMDS_MeshNode* >( theNode )->setXYZ(aNewXYZ.X(),aNewXYZ.Y(),aNewXYZ.Z());
}

Here is the caller graph for this function:

static const SMDS_MeshElement* findAdjacentFace ( const SMDS_MeshNode *  n1,
const SMDS_MeshNode *  n2,
const SMDS_MeshElement *  elem 
) [static]

Definition at line 7928 of file SMESH_MeshEditor.cxx.

{
  TIDSortedElemSet elemSet, avoidSet;
  if ( elem )
    avoidSet.insert ( elem );
  return SMESH_MeshEditor::FindFaceInSet( n1, n2, elemSet, avoidSet );
}
static bool findTriangles ( const SMDS_MeshNode *  theNode1,
const SMDS_MeshNode *  theNode2,
const SMDS_MeshElement *&  theTria1,
const SMDS_MeshElement *&  theTria2 
) [static]

Definition at line 696 of file SMESH_MeshEditor.cxx.

{
  if ( !theNode1 || !theNode2 ) return false;

  theTria1 = theTria2 = 0;

  set< const SMDS_MeshElement* > emap;
  SMDS_ElemIteratorPtr it = theNode1->GetInverseElementIterator(SMDSAbs_Face);
  while (it->more()) {
    const SMDS_MeshElement* elem = it->next();
    if ( elem->NbNodes() == 3 )
      emap.insert( elem );
  }
  it = theNode2->GetInverseElementIterator(SMDSAbs_Face);
  while (it->more()) {
    const SMDS_MeshElement* elem = it->next();
    if ( emap.find( elem ) != emap.end() ) {
      if ( theTria1 ) {
        // theTria1 must be element with minimum ID
        if( theTria1->GetID() < elem->GetID() ) {
          theTria2 = elem;
        }
        else {
          theTria2 = theTria1;
          theTria1 = elem;
        }
        break;
      }
      else {
        theTria1 = elem;
      }
    }
  }
  return ( theTria1 && theTria2 );
}

Here is the caller graph for this function:

double getAngle ( const SMDS_MeshElement *  tr1,
const SMDS_MeshElement *  tr2,
const SMDS_MeshNode *  n1,
const SMDS_MeshNode *  n2 
)

Definition at line 2067 of file SMESH_MeshEditor.cxx.

{
  double angle = 2. * M_PI; // bad angle

  // get normals
  SMESH::Controls::TSequenceOfXYZ P1, P2;
  if ( !SMESH::Controls::NumericalFunctor::GetPoints( tr1, P1 ) ||
       !SMESH::Controls::NumericalFunctor::GetPoints( tr2, P2 ))
    return angle;
  gp_Vec N1,N2;
  if(!tr1->IsQuadratic())
    N1 = gp_Vec( P1(2) - P1(1) ) ^ gp_Vec( P1(3) - P1(1) );
  else
    N1 = gp_Vec( P1(3) - P1(1) ) ^ gp_Vec( P1(5) - P1(1) );
  if ( N1.SquareMagnitude() <= gp::Resolution() )
    return angle;
  if(!tr2->IsQuadratic())
    N2 = gp_Vec( P2(2) - P2(1) ) ^ gp_Vec( P2(3) - P2(1) );
  else
    N2 = gp_Vec( P2(3) - P2(1) ) ^ gp_Vec( P2(5) - P2(1) );
  if ( N2.SquareMagnitude() <= gp::Resolution() )
    return angle;

  // find the first diagonal node n1 in the triangles:
  // take in account a diagonal link orientation
  const SMDS_MeshElement *nFirst[2], *tr[] = { tr1, tr2 };
  for ( int t = 0; t < 2; t++ ) {
    SMDS_ElemIteratorPtr it = tr[ t ]->nodesIterator();
    int i = 0, iDiag = -1;
    while ( it->more()) {
      const SMDS_MeshElement *n = it->next();
      if ( n == n1 || n == n2 ) {
        if ( iDiag < 0)
          iDiag = i;
        else {
          if ( i - iDiag == 1 )
            nFirst[ t ] = ( n == n1 ? n2 : n1 );
          else
            nFirst[ t ] = n;
          break;
        }
      }
      i++;
    }
  }
  if ( nFirst[ 0 ] == nFirst[ 1 ] )
    N2.Reverse();

  angle = N1.Angle( N2 );
  //SCRUTE( angle );
  return angle;
}

Here is the caller graph for this function:

static double getBadRate ( const SMDS_MeshElement *  theElem,
SMESH::Controls::NumericalFunctorPtr theCrit 
) [static]

Definition at line 1059 of file SMESH_MeshEditor.cxx.

{
  SMESH::Controls::TSequenceOfXYZ P;
  if ( !theElem || !theCrit->GetPoints( theElem, P ))
    return 1e100;
  return theCrit->GetBadRate( theCrit->GetValue( P ), theElem->NbNodes() );
  //return theCrit->GetBadRate( theCrit->GetValue( theElem->GetID() ), theElem->NbNodes() );
}

Here is the caller graph for this function:

static bool getClosestUV ( Extrema_GenExtPS &  projector,
const gp_Pnt &  point,
gp_XY &  result 
) [static]

Definition at line 2906 of file SMESH_MeshEditor.cxx.

{
  projector.Perform( point );
  if ( projector.IsDone() ) {
    double u, v, minVal = DBL_MAX;
    for ( int i = projector.NbExt(); i > 0; i-- )
#if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
      if ( projector.SquareDistance( i ) < minVal ) {
        minVal = projector.SquareDistance( i );
#else
      if ( projector.Value( i ) < minVal ) {
        minVal = projector.Value( i );
#endif
        projector.Point( i ).Parameter( u, v );
      }
    result.SetCoord( u, v );
    return true;
  }
  return false;
}

Here is the caller graph for this function:

static bool GetNodesFromTwoTria ( const SMDS_MeshElement *  theTria1,
const SMDS_MeshElement *  theTria2,
const SMDS_MeshNode *  N1[],
const SMDS_MeshNode *  N2[] 
) [static]

Definition at line 513 of file SMESH_MeshEditor.cxx.

{
  SMDS_ElemIteratorPtr it = theTria1->nodesIterator();
  int i=0;
  while(i<6) {
    N1[i] = static_cast<const SMDS_MeshNode*>( it->next() );
    i++;
  }
  if(it->more()) return false;
  it = theTria2->nodesIterator();
  i=0;
  while(i<6) {
    N2[i] = static_cast<const SMDS_MeshNode*>( it->next() );
    i++;
  }
  if(it->more()) return false;

  int sames[3] = {-1,-1,-1};
  int nbsames = 0;
  int j;
  for(i=0; i<3; i++) {
    for(j=0; j<3; j++) {
      if(N1[i]==N2[j]) {
        sames[i] = j;
        nbsames++;
        break;
      }
    }
  }
  if(nbsames!=2) return false;
  if(sames[0]>-1) {
    ShiftNodesQuadTria(N1);
    if(sames[1]>-1) {
      ShiftNodesQuadTria(N1);
    }
  }
  i = sames[0] + sames[1] + sames[2];
  for(; i<2; i++) {
    ShiftNodesQuadTria(N2);
  }
  // now we receive following N1 and N2 (using numeration as above image)
  // tria1 : (1 2 4 5 9 7)  and  tria2 : (3 4 2 8 9 6)
  // i.e. first nodes from both arrays determ new diagonal
  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool getQuadrangleNodes ( const SMDS_MeshNode *  theQuadNodes[],
const SMDS_MeshNode *  theNode1,
const SMDS_MeshNode *  theNode2,
const SMDS_MeshElement *  tr1,
const SMDS_MeshElement *  tr2 
)

Definition at line 814 of file SMESH_MeshEditor.cxx.

{
  if( tr1->NbNodes() != tr2->NbNodes() )
    return false;
  // find the 4-th node to insert into tr1
  const SMDS_MeshNode* n4 = 0;
  SMDS_ElemIteratorPtr it = tr2->nodesIterator();
  int i=0;
  while ( !n4 && i<3 ) {
    const SMDS_MeshNode * n = cast2Node( it->next() );
    i++;
    bool isDiag = ( n == theNode1 || n == theNode2 );
    if ( !isDiag )
      n4 = n;
  }
  // Make an array of nodes to be in a quadrangle
  int iNode = 0, iFirstDiag = -1;
  it = tr1->nodesIterator();
  i=0;
  while ( i<3 ) {
    const SMDS_MeshNode * n = cast2Node( it->next() );
    i++;
    bool isDiag = ( n == theNode1 || n == theNode2 );
    if ( isDiag ) {
      if ( iFirstDiag < 0 )
        iFirstDiag = iNode;
      else if ( iNode - iFirstDiag == 1 )
        theQuadNodes[ iNode++ ] = n4; // insert the 4-th node between diagonal nodes
    }
    else if ( n == n4 ) {
      return false; // tr1 and tr2 should not have all the same nodes
    }
    theQuadNodes[ iNode++ ] = n;
  }
  if ( iNode == 3 ) // diagonal nodes have 0 and 2 indices
    theQuadNodes[ iNode ] = n4;

  return true;
}

Here is the caller graph for this function:

static bool isReverse ( const SMDS_MeshElement *  face,
const vector< const SMDS_MeshNode * > &  prevNodes,
const vector< const SMDS_MeshNode * > &  nextNodes,
const int  iNotSame 
) [static]

Definition at line 3450 of file SMESH_MeshEditor.cxx.

{

  SMESH_TNodeXYZ pP = prevNodes[ iNotSame ];
  SMESH_TNodeXYZ pN = nextNodes[ iNotSame ];
  gp_XYZ extrDir( pN - pP ), faceNorm;
  SMESH_Algo::FaceNormal( face, faceNorm, /*normalized=*/false );

  return faceNorm * extrDir < 0.0;
}
void laplacianSmooth ( const SMDS_MeshNode *  theNode,
const Handle(Geom_Surface)&  theSurface,
map< const SMDS_MeshNode *, gp_XY * > &  theUVMap 
)

Definition at line 2794 of file SMESH_MeshEditor.cxx.

{
  // find surrounding nodes

  TIDSortedElemSet nodeSet;
  SMESH_MeshEditor::GetLinkedNodes( theNode, nodeSet, SMDSAbs_Face );

  // compute new coodrs

  double coord[] = { 0., 0., 0. };
  TIDSortedElemSet::iterator nodeSetIt = nodeSet.begin();
  for ( ; nodeSetIt != nodeSet.end(); nodeSetIt++ ) {
    const SMDS_MeshNode* node = cast2Node(*nodeSetIt);
    if ( theSurface.IsNull() ) { // smooth in 3D
      coord[0] += node->X();
      coord[1] += node->Y();
      coord[2] += node->Z();
    }
    else { // smooth in 2D
      ASSERT( theUVMap.find( node ) != theUVMap.end() );
      gp_XY* uv = theUVMap[ node ];
      coord[0] += uv->X();
      coord[1] += uv->Y();
    }
  }
  int nbNodes = nodeSet.size();
  if ( !nbNodes )
    return;
  coord[0] /= nbNodes;
  coord[1] /= nbNodes;

  if ( !theSurface.IsNull() ) {
    ASSERT( theUVMap.find( theNode ) != theUVMap.end() );
    theUVMap[ theNode ]->SetCoord( coord[0], coord[1] );
    gp_Pnt p3d = theSurface->Value( coord[0], coord[1] );
    coord[0] = p3d.X();
    coord[1] = p3d.Y();
    coord[2] = p3d.Z();
  }
  else
    coord[2] /= nbNodes;

  // move node

  const_cast< SMDS_MeshNode* >( theNode )->setXYZ(coord[0],coord[1],coord[2]);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int nbEdgeConnectivity ( const SMDS_MeshNode *  theNode) [static]

Definition at line 495 of file SMESH_MeshEditor.cxx.

{
  SMDS_ElemIteratorPtr elemIt = theNode->GetInverseElementIterator();
  int nb=0;
  while(elemIt->more()) {
    elemIt->next();
    nb++;
  }
  return nb;
}
ostream& operator<< ( ostream &  out,
const SMESH_ElementSearcherImpl::TInters i 
)

Definition at line 6297 of file SMESH_MeshEditor.cxx.

{
  return out << "TInters(face=" << ( i._face ? i._face->GetID() : 0)
             << ", _coincides="<<i._coincides << ")";
}
static void ShiftNodesQuadTria ( const SMDS_MeshNode *  aNodes[]) [static]

Definition at line 476 of file SMESH_MeshEditor.cxx.

{
  const SMDS_MeshNode* nd1 = aNodes[0];
  aNodes[0] = aNodes[1];
  aNodes[1] = aNodes[2];
  aNodes[2] = nd1;
  const SMDS_MeshNode* nd2 = aNodes[3];
  aNodes[3] = aNodes[4];
  aNodes[4] = aNodes[5];
  aNodes[5] = nd2;
}

Here is the caller graph for this function: