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_MeshVolumeElement () 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 intGetFaceNodesIndices (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 intGetFaceNodesIndices (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_MeshElementmyVolume
const SMDS_VtkVolumemyPolyedre
bool myVolForward
int myNbFaces
int myVolumeNbNodes
const SMDS_MeshNode ** myVolumeNodes
std::vector< intmyPolyIndices
bool myExternalFaces
int myCurFace
int myFaceNbNodes
intmyFaceNodeIndices
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