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

SMDS_VolumeTool Class Reference

#include <SMDS_VolumeTool.hxx>

Public Types

enum  VolumeType {
  UNKNOWN = -1, TETRA = 0, PYRAM, PENTA,
  HEXA, QUAD_TETRA, QUAD_PYRAM, QUAD_PENTA,
  QUAD_HEXA, POLYHEDA
}

Public Member Functions

 SMDS_VolumeTool ()
 ~SMDS_VolumeTool ()
 SMDS_VolumeTool (const SMDS_MeshElement *theVolume)
bool Set (const SMDS_MeshElement *theVolume)
const SMDS_MeshVolume * Element () const
int ID () const
VolumeType GetVolumeType () const
bool IsForward () const
void Inverse ()
const SMDS_MeshNode ** GetNodes ()
int NbNodes ()
double GetSize () const
bool GetBaryCenter (double &X, double &Y, double &Z) const
bool IsOut (double X, double Y, double Z, double tol)
 Classify a point.
bool IsLinked (const SMDS_MeshNode *theNode1, const SMDS_MeshNode *theNode2, const bool theIgnoreMediumNodes=false) const
bool IsLinked (const int theNode1Index, const int theNode2Index, bool theIgnoreMediumNodes=false) const
int GetNodeIndex (const SMDS_MeshNode *theNode) const
int GetAllExistingEdges (std::vector< const SMDS_MeshElement * > &edges) const
 Fill vector with boundary edges existing in the mesh.
void SetExternalNormal ()
int NbFaces () const
int NbFaceNodes (int faceIndex)
const int * GetFaceNodesIndices (int faceIndex)
const SMDS_MeshNode ** GetFaceNodes (int faceIndex)
bool GetFaceNodes (int faceIndex, std::set< const SMDS_MeshNode * > &theFaceNodes)
bool IsFaceExternal (int faceIndex)
bool IsFreeFace (int faceIndex, const SMDS_MeshElement **otherVol=0)
 check that only one volume is build on the face nodes
bool GetFaceNormal (int faceIndex, double &X, double &Y, double &Z)
bool GetFaceBaryCenter (int faceIndex, double &X, double &Y, double &Z)
 Return barycenter of a face.
double GetFaceArea (int faceIndex)
int GetOppFaceIndex (int faceIndex) const
int GetFaceIndex (const std::set< const SMDS_MeshNode * > &theFaceNodes)
int GetAllExistingFaces (std::vector< const SMDS_MeshElement * > &faces)
 Fill vector with boundary faces existing in the mesh.

Static Public Member Functions

static VolumeType GetType (int nbNodes)
static int NbFaces (VolumeType type)
static const int * GetFaceNodesIndices (VolumeType type, int faceIndex, bool external)
static int NbFaceNodes (VolumeType type, int faceIndex)
static int NbCornerNodes (VolumeType type)
 Useful to know nb of corner nodes of a quadratic volume.

Private Member Functions

bool setFace (int faceIndex)

Private Attributes

const SMDS_MeshElement * myVolume
const SMDS_VtkVolume * myPolyedre
bool myVolForward
int myNbFaces
int myVolumeNbNodes
const SMDS_MeshNode ** myVolumeNodes
std::vector< int > myPolyIndices
bool myExternalFaces
int myCurFace
int myFaceNbNodes
int * myFaceNodeIndices
const SMDS_MeshNode ** myFaceNodes

Detailed Description

Definition at line 50 of file SMDS_VolumeTool.hxx.


Member Enumeration Documentation

Enumerator:
UNKNOWN 
TETRA 
PYRAM 
PENTA 
HEXA 
QUAD_TETRA 
QUAD_PYRAM 
QUAD_PENTA 
QUAD_HEXA 
POLYHEDA 

Definition at line 54 of file SMDS_VolumeTool.hxx.


Constructor & Destructor Documentation

SMDS_VolumeTool::SMDS_VolumeTool ( )

Definition at line 408 of file SMDS_VolumeTool.cxx.

     : myVolume( 0 ),
       myPolyedre( 0 ),
       myVolForward( true ),
       myNbFaces( 0 ),
       myVolumeNbNodes( 0 ),
       myVolumeNodes( NULL ),
       myExternalFaces( false ),
       myFaceNbNodes( 0 ),
       myCurFace( -1 ),
       myFaceNodeIndices( NULL ),
       myFaceNodes( NULL )
{
  //MESSAGE("******************************************************** SMDS_VolumeToo");
}
SMDS_VolumeTool::~SMDS_VolumeTool ( )

Definition at line 451 of file SMDS_VolumeTool.cxx.

References myFaceNodeIndices, myFaceNodes, and myVolumeNodes.

{
  if ( myVolumeNodes != NULL ) delete [] myVolumeNodes;
  if ( myFaceNodes != NULL   ) delete [] myFaceNodes;

  myFaceNodeIndices = NULL;
  myVolumeNodes = myFaceNodes = NULL;
}
SMDS_VolumeTool::SMDS_VolumeTool ( const SMDS_MeshElement *  theVolume)

Definition at line 429 of file SMDS_VolumeTool.cxx.

References Set().

     : myVolume( 0 ),
       myPolyedre( 0 ),
       myVolForward( true ),
       myNbFaces( 0 ),
       myVolumeNbNodes( 0 ),
       myVolumeNodes( NULL ),
       myExternalFaces( false ),
       myFaceNbNodes( 0 ),
       myCurFace( -1 ),
       myFaceNodeIndices( NULL ),
       myFaceNodes( NULL )
{
  //MESSAGE("******************************************************** SMDS_VolumeToo");
  Set( theVolume );
}

Member Function Documentation

const SMDS_MeshVolume * SMDS_VolumeTool::Element ( ) const

Definition at line 1760 of file SMDS_VolumeTool.cxx.

References myVolume.

{
  return static_cast<const SMDS_MeshVolume*>( myVolume );
}
int SMDS_VolumeTool::GetAllExistingEdges ( std::vector< const SMDS_MeshElement * > &  edges) const

Fill vector with boundary edges existing in the mesh.

Parameters:
edges- vector of found edges
Return values:
int- nb of found faces

Definition at line 1341 of file SMDS_VolumeTool.cxx.

References SMESH_test.edge, SMDS_Mesh.FindEdge(), IsLinked(), myVolumeNbNodes, and myVolumeNodes.

Referenced by _MySubIterator._MySubIterator().

{
  edges.clear();
  edges.reserve( myVolumeNbNodes * 2 );
  for ( int i = 0; i < myVolumeNbNodes; ++i ) {
    for ( int j = i + 1; j < myVolumeNbNodes; ++j ) {
      if ( IsLinked( i, j )) {
        const SMDS_MeshElement* edge =
          SMDS_Mesh::FindEdge( myVolumeNodes[i], myVolumeNodes[j] );
        if ( edge )
          edges.push_back( edge );
      }
    }
  }
  return edges.size();
}
int SMDS_VolumeTool::GetAllExistingFaces ( std::vector< const SMDS_MeshElement * > &  faces)

Fill vector with boundary faces existing in the mesh.

Parameters:
faces- vector of found nodes
Return values:
int- nb of found faces

Definition at line 1307 of file SMDS_VolumeTool.cxx.

References PAL_MESH_043_3D.face, SMDS_Mesh.FindFace(), GetFaceNodes(), NbFaceNodes(), NbFaces(), and SMESH_AdvancedEditor.nodes.

Referenced by _MySubIterator._MySubIterator().

{
  faces.clear();
  faces.reserve( NbFaces() );
  for ( int iF = 0; iF < NbFaces(); ++iF ) {
    const SMDS_MeshFace* face = 0;
    const SMDS_MeshNode** nodes = GetFaceNodes( iF );
    switch ( NbFaceNodes( iF )) {
    case 3:
      face = SMDS_Mesh::FindFace( nodes[0], nodes[1], nodes[2] ); break;
    case 4:
      face = SMDS_Mesh::FindFace( nodes[0], nodes[1], nodes[2], nodes[3] ); break;
    case 6:
      face = SMDS_Mesh::FindFace( nodes[0], nodes[1], nodes[2],
                                  nodes[3], nodes[4], nodes[5]); break;
    case 8:
      face = SMDS_Mesh::FindFace( nodes[0], nodes[1], nodes[2], nodes[3],
                                  nodes[4], nodes[5], nodes[6], nodes[7]); break;
    }
    if ( face )
      faces.push_back( face );
  }
  return faces.size();
}
bool SMDS_VolumeTool::GetBaryCenter ( double &  X,
double &  Y,
double &  Z 
) const

Definition at line 829 of file SMDS_VolumeTool.cxx.

References myVolume, myVolumeNbNodes, myVolumeNodes, SMDS_MeshNode.X(), SMDS_MeshNode.Y(), and SMDS_MeshNode.Z().

Referenced by SMESH_Mesh_i.BaryCenter(), GetSize(), IsFaceExternal(), IsFreeFace(), and SMESH_MeshEditor.SplitVolumesIntoTetra().

{
  X = Y = Z = 0.;
  if ( !myVolume )
    return false;

  for ( int i = 0; i < myVolumeNbNodes; i++ ) {
    X += myVolumeNodes[ i ]->X();
    Y += myVolumeNodes[ i ]->Y();
    Z += myVolumeNodes[ i ]->Z();
  }
  X /= myVolumeNbNodes;
  Y /= myVolumeNbNodes;
  Z /= myVolumeNbNodes;

  return true;
}
double SMDS_VolumeTool::GetFaceArea ( int  faceIndex)

Definition at line 1059 of file SMDS_VolumeTool.cxx.

References SMDS_MeshElement.IsPoly(), MESSAGE, myFaceNbNodes, myFaceNodes, myVolume, PAL_MESH_041_mesh.p1, PAL_MESH_041_mesh.p2, PAL_MESH_041_mesh.p3, PAL_MESH_043_2D.p4, and setFace().

{
  if (myVolume->IsPoly()) {
    MESSAGE("Warning: attempt to obtain area of a face of polyhedral volume");
    return 0;
  }

  if ( !setFace( faceIndex ))
    return 0;

  XYZ p1 ( myFaceNodes[0] );
  XYZ p2 ( myFaceNodes[1] );
  XYZ p3 ( myFaceNodes[2] );
  XYZ aVec12( p2 - p1 );
  XYZ aVec13( p3 - p1 );
  double area = aVec12.Crossed( aVec13 ).Magnitude() * 0.5;

  if ( myFaceNbNodes == 4 ) {
    XYZ p4 ( myFaceNodes[3] );
    XYZ aVec14( p4 - p1 );
    area += aVec14.Crossed( aVec13 ).Magnitude() * 0.5;
  }
  return area;
}
bool SMDS_VolumeTool::GetFaceBaryCenter ( int  faceIndex,
double &  X,
double &  Y,
double &  Z 
)

Return barycenter of a face.

Definition at line 1039 of file SMDS_VolumeTool.cxx.

References myFaceNbNodes, myFaceNodes, setFace(), SMDS_MeshNode.X(), SMDS_MeshNode.Y(), and SMDS_MeshNode.Z().

Referenced by SMESH_MeshEditor.SplitVolumesIntoTetra().

{
  if ( !setFace( faceIndex ))
    return false;

  X = Y = Z = 0.0;
  for ( int i = 0; i < myFaceNbNodes; ++i )
  {
    X += myFaceNodes[i]->X() / myFaceNbNodes;
    Y += myFaceNodes[i]->Y() / myFaceNbNodes;
    Z += myFaceNodes[i]->Z() / myFaceNbNodes;
  }
  return true;
}
int SMDS_VolumeTool::GetFaceIndex ( const std::set< const SMDS_MeshNode * > &  theFaceNodes)

Definition at line 1486 of file SMDS_VolumeTool.cxx.

References GetFaceNodes(), myNbFaces, NbFaceNodes(), and SMESH_AdvancedEditor.nodes.

{
  for ( int iFace = 0; iFace < myNbFaces; iFace++ ) {
    const SMDS_MeshNode** nodes = GetFaceNodes( iFace );
    int nbFaceNodes = NbFaceNodes( iFace );
    set<const SMDS_MeshNode*> nodeSet;
    for ( int iNode = 0; iNode < nbFaceNodes; iNode++ )
      nodeSet.insert( nodes[ iNode ] );
    if ( theFaceNodes == nodeSet )
      return iFace;
  }
  return -1;
}
const SMDS_MeshNode ** SMDS_VolumeTool::GetFaceNodes ( int  faceIndex)
bool SMDS_VolumeTool::GetFaceNodes ( int  faceIndex,
std::set< const SMDS_MeshNode * > &  theFaceNodes 
)

Definition at line 939 of file SMDS_VolumeTool.cxx.

References myFaceNbNodes, myFaceNodes, and setFace().

{
  if ( !setFace( faceIndex ))
    return false;

  theFaceNodes.clear();
  int iNode, nbNode = myFaceNbNodes;
  for ( iNode = 0; iNode < nbNode; iNode++ )
    theFaceNodes.insert( myFaceNodes[ iNode ]);

  return true;
}
const int * SMDS_VolumeTool::GetFaceNodesIndices ( int  faceIndex)
const int * SMDS_VolumeTool::GetFaceNodesIndices ( VolumeType  type,
int  faceIndex,
bool  external 
) [static]

Definition at line 1715 of file SMDS_VolumeTool.cxx.

References HEXA, Hexa_F, Hexa_FE, PENTA, Penta_F, Penta_FE, PYRAM, Pyramid_F, QUAD_HEXA, QUAD_PENTA, QUAD_PYRAM, QUAD_TETRA, QuadHexa_F, QuadHexa_FE, QuadPenta_F, QuadPenta_FE, QuadPyram_F, QuadTetra_F, TETRA, and Tetra_F.

{
  switch ( type ) {
  case TETRA: return Tetra_F[ faceIndex ];
  case PYRAM: return Pyramid_F[ faceIndex ];
  case PENTA: return external ? Penta_FE[ faceIndex ] : Penta_F[ faceIndex ];
  case HEXA:  return external ? Hexa_FE[ faceIndex ] : Hexa_F[ faceIndex ];
  case QUAD_TETRA: return QuadTetra_F[ faceIndex ];
  case QUAD_PYRAM: return QuadPyram_F[ faceIndex ];
  case QUAD_PENTA: return external ? QuadPenta_FE[ faceIndex ] : QuadPenta_F[ faceIndex ];
  case QUAD_HEXA:  return external ? QuadHexa_FE[ faceIndex ] : QuadHexa_F[ faceIndex ];
  default:;
  }
  return 0;
}
bool SMDS_VolumeTool::GetFaceNormal ( int  faceIndex,
double &  X,
double &  Y,
double &  Z 
)

Definition at line 1000 of file SMDS_VolumeTool.cxx.

References myFaceNbNodes, myFaceNodes, PAL_MESH_041_mesh.p1, PAL_MESH_041_mesh.p2, PAL_MESH_041_mesh.p3, PAL_MESH_043_2D.p4, setFace(), and ex21_lamp.size.

Referenced by StdMeshers_HexaFromSkin_3D.Compute(), IsFaceExternal(), IsFreeFace(), IsOut(), and Set().

{
  if ( !setFace( faceIndex ))
    return false;

  XYZ p1 ( myFaceNodes[0] );
  XYZ p2 ( myFaceNodes[1] );
  XYZ p3 ( myFaceNodes[2] );
  XYZ aVec12( p2 - p1 );
  XYZ aVec13( p3 - p1 );
  XYZ cross = aVec12.Crossed( aVec13 );

  //if ( myFaceNbNodes == 4 ) {
  if ( myFaceNbNodes >3 ) {
    XYZ p4 ( myFaceNodes[3] );
    XYZ aVec14( p4 - p1 );
    XYZ cross2 = aVec13.Crossed( aVec14 );
    cross.x += cross2.x;
    cross.y += cross2.y;
    cross.z += cross2.z;    
  }

  double size = cross.Magnitude();
  if ( size <= DBL_MIN )
    return false;

  X = cross.x / size;
  Y = cross.y / size;
  Z = cross.z / size;

  return true;
}
int SMDS_VolumeTool::GetNodeIndex ( const SMDS_MeshNode *  theNode) const

Definition at line 1288 of file SMDS_VolumeTool.cxx.

References myVolume, myVolumeNbNodes, and myVolumeNodes.

{
  if ( myVolume ) {
    for ( int i = 0; i < myVolumeNbNodes; i++ ) {
      if ( myVolumeNodes[ i ] == theNode )
        return i;
    }
  }
  return -1;
}
const SMDS_MeshNode** SMDS_VolumeTool.GetNodes ( )
int SMDS_VolumeTool::GetOppFaceIndex ( int  faceIndex) const

Definition at line 1089 of file SMDS_VolumeTool.cxx.

References SMESH_test.ind, SMDS_MeshElement.IsPoly(), MESSAGE, myVolume, myVolumeNbNodes, and NbFaces().

{
  int ind = -1;
  if (myVolume->IsPoly()) {
    MESSAGE("Warning: attempt to obtain opposite face on polyhedral volume");
    return ind;
  }

  if ( faceIndex >= 0 && faceIndex < NbFaces() ) {
    switch ( myVolumeNbNodes ) {
    case 6:
      if ( faceIndex == 0 || faceIndex == 1 )
        ind = 1 - faceIndex;
        break;
    case 8:
      ind = faceIndex + ( faceIndex % 2 ? -1 : 1 );
      break;
    default:;
    }
  }
  return ind;
}
double SMDS_VolumeTool::GetSize ( ) const

cout <<"++++ " << Vn << " nodes " <<myFaceNodes[ 0 ]->GetID() << " " <<myFaceNodes[ n-1 ]->GetID() << " " <<myFaceNodes[ n ]->GetID() << " < " << V << endl;

Definition at line 688 of file SMDS_VolumeTool.cxx.

References SMDS_Mesh._meshList, SMDS_Mesh.AddNode(), GetBaryCenter(), SMDS_MeshElement.getMeshId(), getTetraVolume(), GetVolumeType(), SMESH_test.ind, IsFaceExternal(), SMDS_MeshElement.IsPoly(), PAL_MESH_041_mesh.mesh, myFaceNbNodes, myFaceNodes, myPolyedre, myVolume, myVolumeNodes, SMESH_AdvancedEditor.n1, SMESH_AdvancedEditor.n2, NbFaces(), and SMDS_Mesh.RemoveNode().

Referenced by SMESH.Controls.Volume.GetValue().

{
  double V = 0.;
  if ( !myVolume )
    return 0.;

  if ( myVolume->IsPoly() )
  {
    if ( !myPolyedre )
      return 0.;

    SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myPolyedre->getMeshId()];
    // split a polyhedron into tetrahedrons

    SMDS_VolumeTool* me = const_cast< SMDS_VolumeTool* > ( this );
    XYZ baryCenter;
    me->GetBaryCenter(baryCenter.x, baryCenter.y, baryCenter.z);
    SMDS_MeshNode *bcNode = mesh->AddNode( baryCenter.x, baryCenter.y, baryCenter.z );

    for ( int f = 0; f < NbFaces(); ++f )
    {
      bool externalFace = me->IsFaceExternal( f ); // it calls setFace()
      for ( int n = 2; n < myFaceNbNodes; ++n )
      {
        double Vn = getTetraVolume( myFaceNodes[ 0 ],
                                    myFaceNodes[ n-1 ],
                                    myFaceNodes[ n ],
                                    bcNode );
        V += externalFace ? -Vn : Vn;
      }
    }
    mesh->RemoveNode(bcNode);
  }
  else 
  {
    const static int ind[] = {
      0, 1, 3, 6, 11, 19, 32, 46, 66};
    const static int vtab[][4] = {
      // tetrahedron
      { 0, 1, 2, 3 },
      // pyramid
      { 0, 1, 3, 4 },
      { 1, 2, 3, 4 },
      // pentahedron
      { 0, 1, 2, 3 },
      { 1, 5, 3, 4 },
      { 1, 5, 2, 3 },
      // hexahedron
      { 1, 4, 3, 0 },
      { 4, 1, 6, 5 },
      { 1, 3, 6, 2 },
      { 4, 6, 3, 7 },
      { 1, 4, 6, 3 },

      // quadratic tetrahedron
      { 0, 4, 6, 7 },
      { 1, 5, 4, 8 },
      { 2, 6, 5, 9 },
      { 7, 8, 9, 3 },
      { 4, 6, 7, 9 },
      { 4, 5, 6, 9 },
      { 4, 7, 8, 9 },
      { 4, 5, 9, 8 },

      // quadratic pyramid
      { 0, 5, 8, 9 },
      { 1, 5,10, 6 },
      { 2, 6,11, 7 },
      { 3, 7,12, 8 },
      { 4, 9,11,10 },
      { 4, 9,12,11 },
      { 10, 5, 9, 8 },
      { 10, 8, 9,12 },
      { 10, 8,12, 7 },
      { 10, 7,12,11 },
      { 10, 7,11, 6 },
      { 10, 5, 8, 6 },
      { 10, 6, 8, 7 },

      // quadratic pentahedron
      { 12, 0, 8, 6 },
      { 12, 8, 7, 6 },
      { 12, 8, 2, 7 },
      { 12, 6, 7, 1 },
      { 12, 1, 7,13 },
      { 12, 7, 2,13 },
      { 12, 2,14,13 },

      { 12, 3, 9,11 },
      { 12,11, 9,10 },
      { 12,11,10, 5 },
      { 12, 9, 4,10 },
      { 12,14, 5,10 },
      { 12,14,10, 4 },
      { 12,14, 4,13 },

      // quadratic hexahedron
      { 16, 0,11, 8 },
      { 16,11, 9, 8 },
      { 16, 8, 9, 1 },
      { 16,11, 3,10 },
      { 16,11,10, 9 },
      { 16,10, 2, 9 },
      { 16, 3,19, 2 },
      { 16, 2,19,18 },
      { 16, 2,18,17 },
      { 16, 2,17, 1 },

      { 16, 4,12,15 },
      { 16,12, 5,13 },
      { 16,12,13,15 },
      { 16,13, 6,14 },
      { 16,13,14,15 },
      { 16,14, 7,15 },
      { 16, 6, 5,17 },
      { 16,18, 6,17 },
      { 16,18, 7, 6 },
      { 16,18,19, 7 },

    };

    int type = GetVolumeType();
    int n1 = ind[type];
    int n2 = ind[type+1];

    for (int i = n1; i <  n2; i++) {
      V -= getTetraVolume( myVolumeNodes[ vtab[i][0] ],
                           myVolumeNodes[ vtab[i][1] ],
                           myVolumeNodes[ vtab[i][2] ],
                           myVolumeNodes[ vtab[i][3] ]);
    }
  }
  return V;
}
SMDS_VolumeTool::VolumeType SMDS_VolumeTool::GetType ( int  nbNodes) [static]

Definition at line 1647 of file SMDS_VolumeTool.cxx.

References HEXA, PENTA, PYRAM, QUAD_HEXA, QUAD_PENTA, QUAD_PYRAM, QUAD_TETRA, TETRA, and UNKNOWN.

Referenced by StdMeshers_Projection_3D.Compute(), and SMESH_Pattern.getFacesDefinition().

{
  switch ( nbNodes ) {
  case 4: return TETRA;
  case 5: return PYRAM;
  case 6: return PENTA;
  case 8: return HEXA;
  case 10: return QUAD_TETRA;
  case 13: return QUAD_PYRAM;
  case 15: return QUAD_PENTA;
  case 20: return QUAD_HEXA;
  default:return UNKNOWN;
  }
}
SMDS_VolumeTool::VolumeType SMDS_VolumeTool::GetVolumeType ( ) const

Definition at line 617 of file SMDS_VolumeTool.cxx.

References HEXA, myPolyedre, myVolume, myVolumeNbNodes, PENTA, POLYHEDA, PYRAM, QUAD_HEXA, QUAD_PENTA, QUAD_PYRAM, QUAD_TETRA, TETRA, and UNKNOWN.

Referenced by GetSize(), and SMESHGUI_WhatIsDlg.SelectionIntoArgument().

{
  if ( myPolyedre )
    return POLYHEDA;

  if ( myVolume ) {
//    static const VolumeType types[] = {
//      TETRA,     // myVolumeNbNodes = 4
//      PYRAM,     // myVolumeNbNodes = 5
//      PENTA,     // myVolumeNbNodes = 6
//      UNKNOWN,   // myVolumeNbNodes = 7
//      HEXA       // myVolumeNbNodes = 8
//    };
//    return types[ myVolumeNbNodes - 4 ];
    switch(myVolumeNbNodes) {
    case 4: return TETRA; break;
    case 5: return PYRAM; break;
    case 6: return PENTA; break;
    case 8: return HEXA; break;
    case 10: return QUAD_TETRA; break;
    case 13: return QUAD_PYRAM; break;
    case 15: return QUAD_PENTA; break;
    case 20: return QUAD_HEXA; break;
    default: break;
    }
  }

  return UNKNOWN;
}
int SMDS_VolumeTool::ID ( ) const

Definition at line 1770 of file SMDS_VolumeTool.cxx.

References SMDS_MeshElement.GetID(), and myVolume.

Referenced by SMESH_MeshEditor.makeWalls().

{
  return myVolume ? myVolume->GetID() : 0;
}
void SMDS_VolumeTool::Inverse ( )

Definition at line 552 of file SMDS_VolumeTool.cxx.

References SMDS_MeshElement.IsPoly(), MESSAGE, myCurFace, myVolForward, myVolume, myVolumeNbNodes, myVolumeNodes, and SWAP_NODES.

{
  if ( !myVolume ) return;

  if (myVolume->IsPoly()) {
    MESSAGE("Warning: attempt to inverse polyhedral volume");
    return;
  }

  myVolForward = !myVolForward;
  myCurFace = -1;

  // inverse top and bottom faces
  switch ( myVolumeNbNodes ) {
  case 4:
    SWAP_NODES( myVolumeNodes, 1, 2 );
    break;
  case 5:
    SWAP_NODES( myVolumeNodes, 1, 3 );
    break;
  case 6:
    SWAP_NODES( myVolumeNodes, 1, 2 );
    SWAP_NODES( myVolumeNodes, 4, 5 );
    break;
  case 8:
    SWAP_NODES( myVolumeNodes, 1, 3 );
    SWAP_NODES( myVolumeNodes, 5, 7 );
    break;

  case 10:
    SWAP_NODES( myVolumeNodes, 1, 2 );
    SWAP_NODES( myVolumeNodes, 4, 6 );
    SWAP_NODES( myVolumeNodes, 8, 9 );
    break;
  case 13:
    SWAP_NODES( myVolumeNodes, 1, 3 );
    SWAP_NODES( myVolumeNodes, 5, 8 );
    SWAP_NODES( myVolumeNodes, 6, 7 );
    SWAP_NODES( myVolumeNodes, 10, 12 );
    break;
  case 15:
    SWAP_NODES( myVolumeNodes, 1, 2 );
    SWAP_NODES( myVolumeNodes, 4, 5 );
    SWAP_NODES( myVolumeNodes, 6, 8 );
    SWAP_NODES( myVolumeNodes, 9, 11 );
    SWAP_NODES( myVolumeNodes, 13, 14 );
    break;
  case 20:
    SWAP_NODES( myVolumeNodes, 1, 3 );
    SWAP_NODES( myVolumeNodes, 5, 7 );
    SWAP_NODES( myVolumeNodes, 8, 11 );
    SWAP_NODES( myVolumeNodes, 9, 10 );
    SWAP_NODES( myVolumeNodes, 12, 15 );
    SWAP_NODES( myVolumeNodes, 13, 14 );
    SWAP_NODES( myVolumeNodes, 17, 19 );
    break;
  default:;
  }
}
bool SMDS_VolumeTool::IsFaceExternal ( int  faceIndex)

Definition at line 958 of file SMDS_VolumeTool.cxx.

References GetBaryCenter(), SMDS_VtkVolume.GetFaceNode(), GetFaceNormal(), SMDS_MeshElement.IsPoly(), myExternalFaces, myPolyedre, myVolForward, myVolume, myVolumeNbNodes, and SMESH_fixation.p0.

Referenced by GetSize(), IsFreeFace(), IsOut(), setFace(), and SMESH_MeshEditor.SplitVolumesIntoTetra().

{
  if ( myExternalFaces || !myVolume )
    return true;

  if (myVolume->IsPoly()) {
    XYZ aNormal, baryCenter, p0 (myPolyedre->GetFaceNode(faceIndex + 1, 1));
    GetFaceNormal(faceIndex, aNormal.x, aNormal.y, aNormal.z);
    GetBaryCenter(baryCenter.x, baryCenter.y, baryCenter.z);
    XYZ insideVec (baryCenter - p0);
    if (insideVec.Dot(aNormal) > 0)
      return false;
    return true;
  }

  switch ( myVolumeNbNodes ) {
  case 4:
  case 5:
  case 10:
  case 13:
    // only the bottom of a reversed tetrahedron can be internal
    return ( myVolForward || faceIndex != 0 );
  case 6:
  case 15:
    // in a forward pentahedron, the top is internal, in a reversed one - bottom
    return ( myVolForward ? faceIndex != 1 : faceIndex != 0 );
  case 8:
  case 20: {
    // in a forward hexahedron, even face normal is external, odd - internal
    bool odd = faceIndex % 2;
    return ( myVolForward ? !odd : odd );
  }
  default:;
  }
  return false;
}
bool SMDS_VolumeTool.IsForward ( ) const
bool SMDS_VolumeTool::IsFreeFace ( int  faceIndex,
const SMDS_MeshElement **  otherVol = 0 
)

check that only one volume is build on the face nodes

If a face is shared by one of <ignoreVolumes>, it is considered free

Definition at line 1366 of file SMDS_VolumeTool.cxx.

References GetBaryCenter(), GetFaceNodes(), GetFaceNormal(), SMDS_MeshNode.GetInverseElementIterator(), IsFaceExternal(), myFaceNbNodes, myVolume, SMESH_AdvancedEditor.nodes, SMESH_fixation.p0, setFace(), and SMDSAbs_Volume.

Referenced by DriverSTL_W_SMDS_Mesh.findVolumeTriangles(), SMESH.Controls.OverConstrainedVolume.IsSatisfy(), SMESH.Controls.BareBorderVolume.IsSatisfy(), SMESH.SMESH_MeshEditor.Make2DMeshFrom3D(), and SMESH_MeshEditor.makeWalls().

{
  const bool isFree = true;

  if (!setFace( faceIndex ))
    return !isFree;

  const SMDS_MeshNode** nodes = GetFaceNodes( faceIndex );
  const int nbFaceNodes = myFaceNbNodes;

  // evaluate nb of face nodes shared by other volume
  int maxNbShared = -1;
  typedef map< const SMDS_MeshElement*, int > TElemIntMap;
  TElemIntMap volNbShared;
  TElemIntMap::iterator vNbIt;
  for ( int iNode = 0; iNode < nbFaceNodes; iNode++ ) {
    const SMDS_MeshNode* n = nodes[ iNode ];
    SMDS_ElemIteratorPtr eIt = n->GetInverseElementIterator( SMDSAbs_Volume );
    while ( eIt->more() ) {
      const SMDS_MeshElement* elem = eIt->next();
      if ( elem != myVolume ) {
        vNbIt = volNbShared.insert( make_pair( elem, 0 )).first;
        (*vNbIt).second++;
        if ( vNbIt->second > maxNbShared )
          maxNbShared = vNbIt->second;
      }
    }
  }
  if ( maxNbShared < 3 )
    return isFree; // is free

  // find volumes laying on the opposite side of the face
  // and sharing all nodes
  XYZ intNormal; // internal normal
  GetFaceNormal( faceIndex, intNormal.x, intNormal.y, intNormal.z );
  if ( IsFaceExternal( faceIndex ))
    intNormal = XYZ( -intNormal.x, -intNormal.y, -intNormal.z );
  XYZ p0 ( nodes[0] ), baryCenter;
  for ( vNbIt = volNbShared.begin(); vNbIt != volNbShared.end();  ) {
    const int& nbShared = (*vNbIt).second;
    if ( nbShared >= 3 ) {
      SMDS_VolumeTool volume( (*vNbIt).first );
      volume.GetBaryCenter( baryCenter.x, baryCenter.y, baryCenter.z );
      XYZ intNormal2( baryCenter - p0 );
      if ( intNormal.Dot( intNormal2 ) < 0 ) {
        // opposite side
        if ( nbShared >= nbFaceNodes )
        {
          // a volume shares the whole facet
          if ( otherVol ) *otherVol = vNbIt->first;
          return !isFree; 
        }
        ++vNbIt;
        continue;
      }
    }
    // remove a volume from volNbShared map
    volNbShared.erase( vNbIt++ );
  }

  // here volNbShared contains only volumes laying on the opposite side of
  // the face and sharing 3 or more but not all face nodes with myVolume
  if ( volNbShared.size() < 2 ) {
    return isFree; // is free
  }

  // check if the whole area of a face is shared
  for ( int iNode = 0; iNode < nbFaceNodes; iNode++ )
  {
    const SMDS_MeshNode* n = nodes[ iNode ];
    // check if n is shared by one of volumes of volNbShared
    bool isShared = false;
    SMDS_ElemIteratorPtr eIt = n->GetInverseElementIterator( SMDSAbs_Volume );
    while ( eIt->more() && !isShared )
      isShared = volNbShared.count( eIt->next() );
    if ( !isShared )
      return isFree;
  }
  if ( otherVol ) *otherVol = volNbShared.begin()->first;
  return !isFree;

//   if ( !myVolume->IsPoly() )
//   {
//     bool isShared[] = { false, false, false, false }; // 4 triangle parts of a quadrangle
//     for ( vNbIt = volNbShared.begin(); vNbIt != volNbShared.end(); vNbIt++ ) {
//       SMDS_VolumeTool volume( (*vNbIt).first );
//       bool prevLinkShared = false;
//       int nbSharedLinks = 0;
//       for ( int iNode = 0; iNode < nbFaceNodes; iNode++ ) {
//         bool linkShared = volume.IsLinked( nodes[ iNode ], nodes[ iNode + 1] );
//         if ( linkShared )
//           nbSharedLinks++;
//         if ( linkShared && prevLinkShared &&
//              volume.IsLinked( nodes[ iNode - 1 ], nodes[ iNode + 1] ))
//           isShared[ iNode ] = true;
//         prevLinkShared = linkShared;
//       }
//       if ( nbSharedLinks == nbFaceNodes )
//         return !free; // is not free
//       if ( nbFaceNodes == 4 ) {
//         // check traingle parts 1 & 3
//         if ( isShared[1] && isShared[3] )
//           return !free; // is not free
//         // check triangle parts 0 & 2;
//         // 0 part could not be checked in the loop; check it here
//         if ( isShared[2] && prevLinkShared &&
//              volume.IsLinked( nodes[ 0 ], nodes[ 1 ] ) &&
//              volume.IsLinked( nodes[ 1 ], nodes[ 3 ] ) )
//           return !free; // is not free
//       }
//     }
//   }
//  return free;
}
bool SMDS_VolumeTool::IsLinked ( const int  theNode1Index,
const int  theNode2Index,
bool  theIgnoreMediumNodes = false 
) const

Definition at line 1170 of file SMDS_VolumeTool.cxx.

References SMDS_MeshElement.GetEntityType(), IsLinked(), SMDS_MeshElement.IsPoly(), SMDS_MeshElement.IsQuadratic(), myVolume, myVolumeNbNodes, myVolumeNodes, SMDS_MeshElement.NbCornerNodes(), SMDSEntity_Hexa, SMDSEntity_Penta, SMDSEntity_Pyramid, SMDSEntity_Quad_Hexa, SMDSEntity_Quad_Penta, SMDSEntity_Quad_Pyramid, SMDSEntity_Quad_Tetra, and SMDSEntity_Tetra.

{
  if ( myVolume->IsPoly() ) {
    return IsLinked(myVolumeNodes[theNode1Index], myVolumeNodes[theNode2Index]);
  }

  int minInd = min( theNode1Index, theNode2Index );
  int maxInd = max( theNode1Index, theNode2Index );

  if ( minInd < 0 || maxInd > myVolumeNbNodes - 1 || maxInd == minInd )
    return false;

  SMDSAbs_EntityType type = myVolume->GetEntityType();
  if ( myVolume->IsQuadratic() )
  {
    int firstMediumInd = myVolume->NbCornerNodes();
    if ( minInd >= firstMediumInd )
      return false; // medium nodes are not linked
    if ( maxInd < firstMediumInd ) // both nodes are corners
    {
      if ( theIgnoreMediumNodes )
        type = SMDSAbs_EntityType( int(type)-1 ); // check linkage of corner nodes
      else
        return false; // corner nodes are not linked directly in a quadratic cell
    }
  }

  switch ( type ) {
  case SMDSEntity_Tetra:
    return true;
  case SMDSEntity_Hexa:
    switch ( maxInd - minInd ) {
    case 1: return minInd != 3;
    case 3: return minInd == 0 || minInd == 4;
    case 4: return true;
    default:;
    }
    break;
  case SMDSEntity_Pyramid:
    if ( maxInd == 4 )
      return true;
    switch ( maxInd - minInd ) {
    case 1:
    case 3: return true;
    default:;
    }
    break;
  case SMDSEntity_Penta:
    switch ( maxInd - minInd ) {
    case 1: return minInd != 2;
    case 2: return minInd == 0 || minInd == 3;
    case 3: return true;
    default:;
    }
    break;
  case SMDSEntity_Quad_Tetra:
    {
      switch ( minInd ) {
      case 0: if( maxInd==4 ||  maxInd==6 ||  maxInd==7 ) return true;
      case 1: if( maxInd==4 ||  maxInd==5 ||  maxInd==8 ) return true;
      case 2: if( maxInd==5 ||  maxInd==6 ||  maxInd==9 ) return true;
      case 3: if( maxInd==7 ||  maxInd==8 ||  maxInd==9 ) return true;
      default:;
      }
      break;
    }
  case SMDSEntity_Quad_Hexa:
    {
      switch ( minInd ) {
      case 0: if( maxInd==8 ||  maxInd==11 ||  maxInd==16 ) return true;
      case 1: if( maxInd==8 ||  maxInd==9 ||  maxInd==17 ) return true;
      case 2: if( maxInd==9 ||  maxInd==10 ||  maxInd==18 ) return true;
      case 3: if( maxInd==10 ||  maxInd==11 ||  maxInd==19 ) return true;
      case 4: if( maxInd==12 ||  maxInd==15 ||  maxInd==16 ) return true;
      case 5: if( maxInd==12 ||  maxInd==13 ||  maxInd==17 ) return true;
      case 6: if( maxInd==13 ||  maxInd==14 ||  maxInd==18 ) return true;
      case 7: if( maxInd==14 ||  maxInd==15 ||  maxInd==19 ) return true;
      default:;
      }
      break;
    }
  case SMDSEntity_Quad_Pyramid:
    {
      switch ( minInd ) {
      case 0: if( maxInd==5 ||  maxInd==8 ||  maxInd==9 ) return true;
      case 1: if( maxInd==5 ||  maxInd==6 ||  maxInd==10 ) return true;
      case 2: if( maxInd==6 ||  maxInd==7 ||  maxInd==11 ) return true;
      case 3: if( maxInd==7 ||  maxInd==8 ||  maxInd==12 ) return true;
      case 4: if( maxInd==9 ||  maxInd==10 ||  maxInd==11 ||  maxInd==12 ) return true;
      default:;
      }
      break;
    }
  case SMDSEntity_Quad_Penta:
    {
      switch ( minInd ) {
      case 0: if( maxInd==6 ||  maxInd==8 ||  maxInd==12 ) return true;
      case 1: if( maxInd==6 ||  maxInd==7 ||  maxInd==13 ) return true;
      case 2: if( maxInd==7 ||  maxInd==8 ||  maxInd==14 ) return true;
      case 3: if( maxInd==9 ||  maxInd==11 ||  maxInd==12 ) return true;
      case 4: if( maxInd==9 ||  maxInd==10 ||  maxInd==13 ) return true;
      case 5: if( maxInd==10 ||  maxInd==11 ||  maxInd==14 ) return true;
      default:;
      }
      break;
    }
  default:;
  }
  return false;
}
bool SMDS_VolumeTool::IsLinked ( const SMDS_MeshNode *  theNode1,
const SMDS_MeshNode *  theNode2,
const bool  theIgnoreMediumNodes = false 
) const

Definition at line 1118 of file SMDS_VolumeTool.cxx.

References SMDS_VtkVolume.GetFaceNode(), SMESH_test.i1, SMESH_test.i2, SMDS_MeshElement.IsPoly(), MESSAGE, myNbFaces, myPolyedre, myVolume, myVolumeNbNodes, myVolumeNodes, and SMDS_VtkVolume.NbFaceNodes().

Referenced by GetAllExistingEdges(), SMESH_MeshEditor.GetLinkedNodes(), IsLinked(), SMESH_Block.LoadMeshBlock(), Set(), SMESH_MeshEditor.SewFreeBorder(), and SMESH_MeshEditor.UpdateVolumes().

{
  if ( !myVolume )
    return false;

  if (myVolume->IsPoly()) {
    if (!myPolyedre) {
      MESSAGE("Warning: bad volumic element");
      return false;
    }
    bool isLinked = false;
    int iface;
    for (iface = 1; iface <= myNbFaces && !isLinked; iface++) {
      int inode, nbFaceNodes = myPolyedre->NbFaceNodes(iface);

      for (inode = 1; inode <= nbFaceNodes && !isLinked; inode++) {
        const SMDS_MeshNode* curNode = myPolyedre->GetFaceNode(iface, inode);

        if (curNode == theNode1 || curNode == theNode2) {
          int inextnode = (inode == nbFaceNodes) ? 1 : inode + 1;
          const SMDS_MeshNode* nextNode = myPolyedre->GetFaceNode(iface, inextnode);

          if ((curNode == theNode1 && nextNode == theNode2) ||
              (curNode == theNode2 && nextNode == theNode1)) {
            isLinked = true;
          }
        }
      }
    }
    return isLinked;
  }

  // find nodes indices
  int i1 = -1, i2 = -1;
  for ( int i = 0; i < myVolumeNbNodes; i++ ) {
    if ( myVolumeNodes[ i ] == theNode1 )
      i1 = i;
    else if ( myVolumeNodes[ i ] == theNode2 )
      i2 = i;
  }
  return IsLinked( i1, i2 );
}
bool SMDS_VolumeTool::IsOut ( double  X,
double  Y,
double  Z,
double  tol 
)

Classify a point.

Parameters:
tol- thickness of faces

Definition at line 854 of file SMDS_VolumeTool.cxx.

References GetFaceNormal(), IsFaceExternal(), myFaceNodes, myNbFaces, and SMESH_AdvancedEditor.tol.

Referenced by SMESH_MeshEditor.isOut().

{
  // LIMITATION: for convex volumes only
  XYZ p( X,Y,Z );
  for ( int iF = 0; iF < myNbFaces; ++iF )
  {
    XYZ faceNormal;
    if ( !GetFaceNormal( iF, faceNormal.x, faceNormal.y, faceNormal.z ))
      continue;
    if ( !IsFaceExternal( iF ))
      faceNormal = XYZ() - faceNormal; // reverse

    XYZ face2p( p - XYZ( myFaceNodes[0] ));
    if ( face2p.Dot( faceNormal ) > tol )
      return true;
  }
  return false;
}
int SMDS_VolumeTool::NbCornerNodes ( VolumeType  type) [static]

Useful to know nb of corner nodes of a quadratic volume.

Parameters:
type- volume type
Return values:
int- nb of corner nodes

Definition at line 1690 of file SMDS_VolumeTool.cxx.

References HEXA, PENTA, PYRAM, QUAD_HEXA, QUAD_PENTA, QUAD_PYRAM, QUAD_TETRA, and TETRA.

Referenced by StdMeshers_Projection_3D.Compute().

{
  switch ( type ) {
  case TETRA     :
  case QUAD_TETRA: return 4;
  case PYRAM     :
  case QUAD_PYRAM: return 5;
  case PENTA     :
  case QUAD_PENTA: return 6;
  case HEXA      :
  case QUAD_HEXA : return 8;
  default:    return 0;
  }
  return 0;
}
int SMDS_VolumeTool::NbFaceNodes ( VolumeType  type,
int  faceIndex 
) [static]

Definition at line 1738 of file SMDS_VolumeTool.cxx.

References HEXA, Hexa_nbN, PENTA, Penta_nbN, PYRAM, Pyramid_nbN, QUAD_HEXA, QUAD_PENTA, QUAD_PYRAM, QUAD_TETRA, QuadHexa_nbN, QuadPenta_nbN, QuadPyram_nbN, QuadTetra_nbN, TETRA, and Tetra_nbN.

{
  switch ( type ) {
  case TETRA: return Tetra_nbN[ faceIndex ];
  case PYRAM: return Pyramid_nbN[ faceIndex ];
  case PENTA: return Penta_nbN[ faceIndex ];
  case HEXA:  return Hexa_nbN[ faceIndex ];
  case QUAD_TETRA: return QuadTetra_nbN[ faceIndex ];
  case QUAD_PYRAM: return QuadPyram_nbN[ faceIndex ];
  case QUAD_PENTA: return QuadPenta_nbN[ faceIndex ];
  case QUAD_HEXA:  return QuadHexa_nbN[ faceIndex ];
  default:;
  }
  return 0;
}
int SMDS_VolumeTool::NbFaceNodes ( int  faceIndex)
int SMDS_VolumeTool.NbFaces ( ) const
int SMDS_VolumeTool::NbFaces ( VolumeType  type) [static]

Definition at line 1667 of file SMDS_VolumeTool.cxx.

References HEXA, PENTA, PYRAM, QUAD_HEXA, QUAD_PENTA, QUAD_PYRAM, QUAD_TETRA, and TETRA.

{
  switch ( type ) {
  case TETRA     :
  case QUAD_TETRA: return 4;
  case PYRAM     :
  case QUAD_PYRAM: return 5;
  case PENTA     :
  case QUAD_PENTA: return 5;
  case HEXA      :
  case QUAD_HEXA : return 6;
  default:    return 0;
  }
}
int SMDS_VolumeTool.NbNodes ( )

Definition at line 89 of file SMDS_VolumeTool.hxx.

Referenced by SMESH_MesherHelper.AddTLinks(), and SMESH_Block.LoadMeshBlock().

{ return myVolumeNbNodes; }
bool SMDS_VolumeTool::Set ( const SMDS_MeshElement *  theVolume)

Definition at line 465 of file SMDS_VolumeTool.cxx.

References GetFaceNormal(), SMDS_MeshElement.GetType(), IsLinked(), SMDS_MeshElement.IsPoly(), MESSAGE, myCurFace, myExternalFaces, myFaceNbNodes, myFaceNodeIndices, myFaceNodes, myNbFaces, myPolyedre, myVolForward, myVolume, myVolumeNbNodes, myVolumeNodes, SMDS_MeshElement.NbCornerNodes(), SMDS_MeshElement.NbFaces(), SMDS_MeshElement.NbNodes(), SMDS_MeshElement.nodesIterator(), SMDSAbs_Volume, SMDS_MeshNode.X(), SMDS_MeshNode.Y(), and SMDS_MeshNode.Z().

Referenced by StdMeshers_Prism_3D.AddPrisms(), SMESH_Mesh_i.BaryCenter(), DriverSTL_W_SMDS_Mesh.findVolumeTriangles(), SMESH_MesherHelper.FixQuadraticElements(), SMESH.Controls.Volume.GetValue(), SMESH.Controls.OverConstrainedVolume.IsSatisfy(), SMESH.Controls.BareBorderVolume.IsSatisfy(), SMESH_Block.LoadMeshBlock(), SMESH_Pattern.makePolyElements(), StdMeshers_Penta_3D.MakeVolumeMesh(), SMESH_MeshEditor.makeWalls(), SMESH_MeshEditor.SewFreeBorder(), SMDS_VolumeTool(), and SMESH_MeshEditor.SplitVolumesIntoTetra().

{
  myVolume = 0;
  myPolyedre = 0;

  myVolForward = true;
  myNbFaces = 0;
  myVolumeNbNodes = 0;
  if (myVolumeNodes != NULL) {
    delete [] myVolumeNodes;
    myVolumeNodes = NULL;
  }

  myExternalFaces = false;
  myFaceNbNodes = 0;

  myCurFace = -1;
  myFaceNodeIndices = NULL;
  if (myFaceNodes != NULL) {
    delete [] myFaceNodes;
    myFaceNodes = NULL;
  }

  if ( theVolume && theVolume->GetType() == SMDSAbs_Volume )
  {
    myVolume = theVolume;

    myNbFaces = theVolume->NbFaces();
    myVolumeNbNodes = theVolume->NbNodes();

    // set volume nodes
    int iNode = 0;
    myVolumeNodes = new const SMDS_MeshNode* [myVolumeNbNodes];
    SMDS_ElemIteratorPtr nodeIt = myVolume->nodesIterator();
    while ( nodeIt->more() ) {
      myVolumeNodes[ iNode++ ] = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
    }

    if (myVolume->IsPoly()) {
      myPolyedre = dynamic_cast<const SMDS_VtkVolume*>( myVolume );
      if (!myPolyedre) {
        MESSAGE("Warning: bad volumic element");
        return false;
      }
    }
    else {
      switch ( myVolumeNbNodes ) {
      case 4:
      case 5:
      case 6:
      case 8:
      case 10:
      case 13:
      case 15:
      case 20: {
        // define volume orientation
        XYZ botNormal;
        GetFaceNormal( 0, botNormal.x, botNormal.y, botNormal.z );
        const SMDS_MeshNode* botNode = myVolumeNodes[ 0 ];
        int topNodeIndex = myVolume->NbCornerNodes() - 1;
        while ( !IsLinked( 0, topNodeIndex, /*ignoreMediumNodes=*/true )) --topNodeIndex;
        const SMDS_MeshNode* topNode = myVolumeNodes[ topNodeIndex ];
        XYZ upDir (topNode->X() - botNode->X(),
                   topNode->Y() - botNode->Y(),
                   topNode->Z() - botNode->Z() );
        myVolForward = ( botNormal.Dot( upDir ) < 0 );
        break;
      }
      default:
        break;
      }
    }
  }
  return ( myVolume != 0 );
}
void SMDS_VolumeTool::SetExternalNormal ( )
bool SMDS_VolumeTool::setFace ( int  faceIndex) [private]

Definition at line 1524 of file SMDS_VolumeTool.cxx.

References SMDS_VtkVolume.GetFaceNode(), Hexa_F, Hexa_FE, Hexa_nbN, Hexa_RE, IsFaceExternal(), SMDS_MeshElement.IsPoly(), MESSAGE, myCurFace, myExternalFaces, myFaceNbNodes, myFaceNodeIndices, myFaceNodes, myPolyedre, myVolForward, myVolume, myVolumeNbNodes, myVolumeNodes, SMDS_VtkVolume.NbFaceNodes(), NbFaces(), Penta_F, Penta_FE, Penta_nbN, Penta_R, Penta_RE, Pyramid_F, Pyramid_nbN, Pyramid_R, Pyramid_RE, QuadHexa_F, QuadHexa_FE, QuadHexa_nbN, QuadHexa_RE, QuadPenta_F, QuadPenta_FE, QuadPenta_nbN, QuadPenta_R, QuadPenta_RE, QuadPyram_F, QuadPyram_nbN, QuadPyram_R, QuadPyram_RE, QuadTetra_F, QuadTetra_nbN, QuadTetra_R, QuadTetra_RE, Tetra_F, Tetra_nbN, Tetra_R, and Tetra_RE.

Referenced by GetFaceArea(), GetFaceBaryCenter(), GetFaceNodes(), GetFaceNodesIndices(), GetFaceNormal(), IsFreeFace(), and NbFaceNodes().

{
  if ( !myVolume )
    return false;

  if ( myCurFace == faceIndex )
    return true;

  myCurFace = -1;

  if ( faceIndex < 0 || faceIndex >= NbFaces() )
    return false;

  if (myFaceNodes != NULL) {
    delete [] myFaceNodes;
    myFaceNodes = NULL;
  }

  if (myVolume->IsPoly()) {
    if (!myPolyedre) {
      MESSAGE("Warning: bad volumic element");
      return false;
    }

    // check orientation
    bool isGoodOri = true;
    if (myExternalFaces)
      isGoodOri = IsFaceExternal( faceIndex );

    // set face nodes
    int iNode;
    myFaceNbNodes = myPolyedre->NbFaceNodes(faceIndex + 1);
    myFaceNodes = new const SMDS_MeshNode* [myFaceNbNodes + 1];
    if (isGoodOri) {
      for ( iNode = 0; iNode < myFaceNbNodes; iNode++ )
        myFaceNodes[ iNode ] = myPolyedre->GetFaceNode(faceIndex + 1, iNode + 1);
    } else {
      for ( iNode = 0; iNode < myFaceNbNodes; iNode++ )
        myFaceNodes[ iNode ] = myPolyedre->GetFaceNode(faceIndex + 1, myFaceNbNodes - iNode);
    }
    myFaceNodes[ myFaceNbNodes ] = myFaceNodes[ 0 ]; // last = first

  }
  else {
    // choose face node indices
    switch ( myVolumeNbNodes ) {
    case 4:
      myFaceNbNodes = Tetra_nbN[ faceIndex ];
      if ( myExternalFaces )
        myFaceNodeIndices = myVolForward ? Tetra_F[ faceIndex ] : Tetra_RE[ faceIndex ];
      else
        myFaceNodeIndices = myVolForward ? Tetra_F[ faceIndex ] : Tetra_R[ faceIndex ];
      break;
    case 5:
      myFaceNbNodes = Pyramid_nbN[ faceIndex ];
      if ( myExternalFaces )
        myFaceNodeIndices = myVolForward ? Pyramid_F[ faceIndex ] : Pyramid_RE[ faceIndex ];
      else
        myFaceNodeIndices = myVolForward ? Pyramid_F[ faceIndex ] : Pyramid_R[ faceIndex ];
      break;
    case 6:
      myFaceNbNodes = Penta_nbN[ faceIndex ];
      if ( myExternalFaces )
        myFaceNodeIndices = myVolForward ? Penta_FE[ faceIndex ] : Penta_RE[ faceIndex ];
      else
        myFaceNodeIndices = myVolForward ? Penta_F[ faceIndex ] : Penta_R[ faceIndex ];
      break;
    case 8:
      myFaceNbNodes = Hexa_nbN[ faceIndex ];
      if ( myExternalFaces )
        myFaceNodeIndices = myVolForward ? Hexa_FE[ faceIndex ] : Hexa_RE[ faceIndex ];
      else
        myFaceNodeIndices = Hexa_F[ faceIndex ];
      break;
    case 10:
      myFaceNbNodes = QuadTetra_nbN[ faceIndex ];
      if ( myExternalFaces )
        myFaceNodeIndices = myVolForward ? QuadTetra_F[ faceIndex ] : QuadTetra_RE[ faceIndex ];
      else
        myFaceNodeIndices = myVolForward ? QuadTetra_F[ faceIndex ] : QuadTetra_R[ faceIndex ];
      break;
    case 13:
      myFaceNbNodes = QuadPyram_nbN[ faceIndex ];
      if ( myExternalFaces )
        myFaceNodeIndices = myVolForward ? QuadPyram_F[ faceIndex ] : QuadPyram_RE[ faceIndex ];
      else
        myFaceNodeIndices = myVolForward ? QuadPyram_F[ faceIndex ] : QuadPyram_R[ faceIndex ];
      break;
    case 15:
      myFaceNbNodes = QuadPenta_nbN[ faceIndex ];
      if ( myExternalFaces )
        myFaceNodeIndices = myVolForward ? QuadPenta_FE[ faceIndex ] : QuadPenta_RE[ faceIndex ];
      else
        myFaceNodeIndices = myVolForward ? QuadPenta_F[ faceIndex ] : QuadPenta_R[ faceIndex ];
      break;
    case 20:
      myFaceNbNodes = QuadHexa_nbN[ faceIndex ];
      if ( myExternalFaces )
        myFaceNodeIndices = myVolForward ? QuadHexa_FE[ faceIndex ] : QuadHexa_RE[ faceIndex ];
      else
        myFaceNodeIndices = QuadHexa_F[ faceIndex ];
      break;
    default:
      return false;
    }

    // set face nodes
    myFaceNodes = new const SMDS_MeshNode* [myFaceNbNodes + 1];
    for ( int iNode = 0; iNode < myFaceNbNodes; iNode++ )
      myFaceNodes[ iNode ] = myVolumeNodes[ myFaceNodeIndices[ iNode ]];
    myFaceNodes[ myFaceNbNodes ] = myFaceNodes[ 0 ];
  }

  myCurFace = faceIndex;

  return true;
}

Field Documentation

Definition at line 230 of file SMDS_VolumeTool.hxx.

Referenced by Inverse(), Set(), SetExternalNormal(), and setFace().

Definition at line 228 of file SMDS_VolumeTool.hxx.

Referenced by IsFaceExternal(), Set(), SetExternalNormal(), and setFace().

Definition at line 232 of file SMDS_VolumeTool.hxx.

Referenced by GetFaceNodesIndices(), Set(), setFace(), and ~SMDS_VolumeTool().

Definition at line 223 of file SMDS_VolumeTool.hxx.

Referenced by GetFaceIndex(), IsLinked(), IsOut(), and Set().

Definition at line 220 of file SMDS_VolumeTool.hxx.

Referenced by GetSize(), GetVolumeType(), IsFaceExternal(), IsLinked(), Set(), and setFace().

std::vector< int > SMDS_VolumeTool.myPolyIndices [private]

Definition at line 226 of file SMDS_VolumeTool.hxx.

Referenced by GetFaceNodesIndices().

Definition at line 222 of file SMDS_VolumeTool.hxx.

Referenced by Inverse(), IsFaceExternal(), Set(), and setFace().

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