Version: 6.3.1
Data Structures | Public Types | Public Member Functions | Private Member Functions | Private Attributes

SMESH.Controls.ManifoldPart Class Reference

#include <SMESH_ControlsDef.hxx>

Inheritance diagram for SMESH.Controls.ManifoldPart:
Inheritance graph
[legend]

Data Structures

class  Link

Public Types

typedef std::set
< ManifoldPart::Link
TMapOfLink
typedef std::vector
< SMDS_MeshFace * > 
TVectorOfFacePtr
typedef std::vector
< ManifoldPart::Link
TVectorOfLink
typedef std::map
< SMDS_MeshFace *, int
TDataMapFacePtrInt
typedef std::map
< ManifoldPart::Link,
SMDS_MeshFace * > 
TDataMapOfLinkFacePtr

Public Member Functions

bool IsEqual (const ManifoldPart::Link &theLink1, const ManifoldPart::Link &theLink2)
 ManifoldPart ()
 ~ManifoldPart ()
virtual void SetMesh (const SMDS_Mesh *theMesh)
virtual bool IsSatisfy (long theElementId)
virtual SMDSAbs_ElementType GetType () const
void SetAngleTolerance (const double theAngToler)
double GetAngleTolerance () const
void SetIsOnlyManifold (const bool theIsOnly)
void SetStartElem (const long theStartElemId)

Private Member Functions

bool process ()
bool findConnected (const TDataMapFacePtrInt &theAllFacePtrInt, SMDS_MeshFace *theStartFace, TMapOfLink &theNonManifold, TColStd_MapOfInteger &theResFaces)
bool isInPlane (const SMDS_MeshFace *theFace1, const SMDS_MeshFace *theFace2)
void expandBoundary (TMapOfLink &theMapOfBoundary, TVectorOfLink &theSeqOfBoundary, TDataMapOfLinkFacePtr &theDMapLinkFacePtr, TMapOfLink &theNonManifold, SMDS_MeshFace *theNextFace) const
void getFacesByLink (const Link &theLink, TVectorOfFacePtr &theFaces) const

Private Attributes

const SMDS_MeshmyMesh
TColStd_MapOfInteger myMapIds
TColStd_MapOfInteger myMapBadGeomIds
TVectorOfFacePtr myAllFacePtr
TDataMapFacePtrInt myAllFacePtrIntDMap
double myAngToler
bool myIsOnlyManifold
long myStartElemId

Detailed Description

Definition at line 647 of file SMESH_ControlsDef.hxx.


Member Typedef Documentation

Definition at line 671 of file SMESH_ControlsDef.hxx.

Definition at line 672 of file SMESH_ControlsDef.hxx.

Definition at line 668 of file SMESH_ControlsDef.hxx.

Definition at line 669 of file SMESH_ControlsDef.hxx.

Definition at line 670 of file SMESH_ControlsDef.hxx.


Constructor & Destructor Documentation

ManifoldPart::ManifoldPart ( )
ManifoldPart::~ManifoldPart ( )

Definition at line 3125 of file SMESH_Controls.cxx.

References SMESH.Controls.ManifoldPart.myMesh.

{
  myMesh = 0;
}

Member Function Documentation

void ManifoldPart::expandBoundary ( ManifoldPart::TMapOfLink theMapOfBoundary,
ManifoldPart::TVectorOfLink theSeqOfBoundary,
ManifoldPart::TDataMapOfLinkFacePtr theDMapLinkFacePtr,
ManifoldPart::TMapOfLink theNonManifold,
SMDS_MeshFace theNextFace 
) const [private]

Definition at line 3347 of file SMESH_Controls.cxx.

References getLinks(), SMESH.Controls.ManifoldPart.Link.IsEqual(), and SMESH.Controls.ManifoldPart.myIsOnlyManifold.

Referenced by SMESH.Controls.ManifoldPart.findConnected().

{
  ManifoldPart::TVectorOfLink aLinks;
  getLinks( theNextFace, aLinks );
  int aNbLink = (int)aLinks.size();
  for ( int i = 0; i < aNbLink; i++ )
  {
    ManifoldPart::Link aLink = aLinks[ i ];
    if ( myIsOnlyManifold && (theNonManifold.find( aLink ) != theNonManifold.end()) )
      continue;
    if ( theMapOfBoundary.find( aLink ) != theMapOfBoundary.end() )
    {
      if ( myIsOnlyManifold )
      {
        // remove from boundary
        theMapOfBoundary.erase( aLink );
        ManifoldPart::TVectorOfLink::iterator pLink = theSeqOfBoundary.begin();
        for ( ; pLink != theSeqOfBoundary.end(); ++pLink )
        {
          ManifoldPart::Link aBoundLink = *pLink;
          if ( aBoundLink.IsEqual( aLink ) )
          {
            theSeqOfBoundary.erase( pLink );
            break;
          }
        }
      }
    }
    else
    {
      theMapOfBoundary.insert( aLink );
      theSeqOfBoundary.push_back( aLink );
      theDMapLinkFacePtr[ aLink ] = theNextFace;
    }
  }
}
bool ManifoldPart::findConnected ( const TDataMapFacePtrInt theAllFacePtrInt,
SMDS_MeshFace theStartFace,
ManifoldPart::TMapOfLink theNonManifold,
TColStd_MapOfInteger &  theResFaces 
) [private]

Definition at line 3238 of file SMESH_Controls.cxx.

References SMESH.Controls.ManifoldPart.expandBoundary(), SMESH.Controls.ManifoldPart.getFacesByLink(), SMDS_MeshElement.GetID(), SMESH.getNormale(), ex30_groupsOp.isDone, SMESH.Controls.ManifoldPart.isInPlane(), SMESH.Controls.ManifoldPart.myAllFacePtrIntDMap, SMESH.Controls.ManifoldPart.myIsOnlyManifold, and SMESH.Controls.ManifoldPart.myMapBadGeomIds.

Referenced by SMESH.Controls.ManifoldPart.process().

{
  theResFaces.Clear();
  if ( !theAllFacePtrInt.size() )
    return false;

  if ( getNormale( theStartFace ).SquareModulus() <= gp::Resolution() )
  {
    myMapBadGeomIds.Add( theStartFace->GetID() );
    return false;
  }

  ManifoldPart::TMapOfLink aMapOfBoundary, aMapToSkip;
  ManifoldPart::TVectorOfLink aSeqOfBoundary;
  theResFaces.Add( theStartFace->GetID() );
  ManifoldPart::TDataMapOfLinkFacePtr aDMapLinkFace;

  expandBoundary( aMapOfBoundary, aSeqOfBoundary,
                 aDMapLinkFace, theNonManifold, theStartFace );

  bool isDone = false;
  while ( !isDone && aMapOfBoundary.size() != 0 )
  {
    bool isToReset = false;
    ManifoldPart::TVectorOfLink::iterator pLink = aSeqOfBoundary.begin();
    for ( ; !isToReset && pLink != aSeqOfBoundary.end(); ++pLink )
    {
      ManifoldPart::Link aLink = *pLink;
      if ( aMapToSkip.find( aLink ) != aMapToSkip.end() )
        continue;
      // each link could be treated only once
      aMapToSkip.insert( aLink );

      ManifoldPart::TVectorOfFacePtr aFaces;
      // find next
      if ( myIsOnlyManifold &&
           (theNonManifold.find( aLink ) != theNonManifold.end()) )
        continue;
      else
      {
        getFacesByLink( aLink, aFaces );
        // filter the element to keep only indicated elements
        ManifoldPart::TVectorOfFacePtr aFiltered;
        ManifoldPart::TVectorOfFacePtr::iterator pFace = aFaces.begin();
        for ( ; pFace != aFaces.end(); ++pFace )
        {
          SMDS_MeshFace* aFace = *pFace;
          if ( myAllFacePtrIntDMap.find( aFace ) != myAllFacePtrIntDMap.end() )
            aFiltered.push_back( aFace );
        }
        aFaces = aFiltered;
        if ( aFaces.size() < 2 )  // no neihgbour faces
          continue;
        else if ( myIsOnlyManifold && aFaces.size() > 2 ) // non manifold case
        {
          theNonManifold.insert( aLink );
          continue;
        }
      }

      // compare normal with normals of neighbor element
      SMDS_MeshFace* aPrevFace = aDMapLinkFace[ aLink ];
      ManifoldPart::TVectorOfFacePtr::iterator pFace = aFaces.begin();
      for ( ; pFace != aFaces.end(); ++pFace )
      {
        SMDS_MeshFace* aNextFace = *pFace;
        if ( aPrevFace == aNextFace )
          continue;
        int anNextFaceID = aNextFace->GetID();
        if ( myIsOnlyManifold && theResFaces.Contains( anNextFaceID ) )
         // should not be with non manifold restriction. probably bad topology
          continue;
        // check if face was treated and skipped
        if ( myMapBadGeomIds.Contains( anNextFaceID ) ||
             !isInPlane( aPrevFace, aNextFace ) )
          continue;
        // add new element to connected and extend the boundaries.
        theResFaces.Add( anNextFaceID );
        expandBoundary( aMapOfBoundary, aSeqOfBoundary,
                        aDMapLinkFace, theNonManifold, aNextFace );
        isToReset = true;
      }
    }
    isDone = !isToReset;
  }

  return !theResFaces.IsEmpty();
}
double ManifoldPart::GetAngleTolerance ( ) const

Definition at line 3147 of file SMESH_Controls.cxx.

References SMESH.Controls.ManifoldPart.myAngToler.

{ return myAngToler; }
void ManifoldPart::getFacesByLink ( const Link theLink,
ManifoldPart::TVectorOfFacePtr theFaces 
) const [private]

Definition at line 3388 of file SMESH_Controls.cxx.

References SMDS_MeshElement.facesIterator(), SMESH.Controls.ManifoldPart.Link.myNode1, and SMESH.Controls.ManifoldPart.Link.myNode2.

Referenced by SMESH.Controls.ManifoldPart.findConnected().

{
  std::set<SMDS_MeshCell *> aSetOfFaces;
  // take all faces that shared first node
  SMDS_ElemIteratorPtr anItr = theLink.myNode1->facesIterator();
  for ( ; anItr->more(); )
  {
    SMDS_MeshFace* aFace = (SMDS_MeshFace*)anItr->next();
    if ( !aFace )
      continue;
    aSetOfFaces.insert( aFace );
  }
  // take all faces that shared second node
  anItr = theLink.myNode2->facesIterator();
  // find the common part of two sets
  for ( ; anItr->more(); )
  {
    SMDS_MeshFace* aFace = (SMDS_MeshFace*)anItr->next();
    if ( aSetOfFaces.count( aFace ) )
      theFaces.push_back( aFace );
  }
}
SMDSAbs_ElementType ManifoldPart::GetType ( ) const [virtual]

Implements SMESH.Controls.Predicate.

Definition at line 3136 of file SMESH_Controls.cxx.

References SMDSAbs_Face.

{ return SMDSAbs_Face; }
bool ManifoldPart::IsEqual ( const ManifoldPart::Link theLink1,
const ManifoldPart::Link theLink2 
)

Definition at line 3112 of file SMESH_Controls.cxx.

References SMESH.Controls.ManifoldPart.Link.IsEqual().

{
  return theLink1.IsEqual( theLink2 );
}
bool ManifoldPart::isInPlane ( const SMDS_MeshFace theFace1,
const SMDS_MeshFace theFace2 
) [private]

Definition at line 3330 of file SMESH_Controls.cxx.

References SMDS_MeshElement.GetID(), SMESH.getNormale(), SMESH.Controls.ManifoldPart.myAngToler, and SMESH.Controls.ManifoldPart.myMapBadGeomIds.

Referenced by SMESH.Controls.ManifoldPart.findConnected().

{
  gp_Dir aNorm1 = gp_Dir( getNormale( theFace1 ) );
  gp_XYZ aNorm2XYZ = getNormale( theFace2 );
  if ( aNorm2XYZ.SquareModulus() <= gp::Resolution() )
  {
    myMapBadGeomIds.Add( theFace2->GetID() );
    return false;
  }
  if ( aNorm1.IsParallel( gp_Dir( aNorm2XYZ ), myAngToler ) )
    return true;

  return false;
}
bool ManifoldPart::IsSatisfy ( long  theElementId) [virtual]

Implements SMESH.Controls.Predicate.

Definition at line 3139 of file SMESH_Controls.cxx.

References SMESH.Controls.ManifoldPart.myMapIds.

{
  return myMapIds.Contains( theElementId );
}
bool ManifoldPart::process ( ) [private]

Definition at line 3156 of file SMESH_Controls.cxx.

References SMDS_Mesh.facesIterator(), SMESH.Controls.ManifoldPart.findConnected(), SMDS_Mesh.FindElement(), SMDS_MeshElement.GetID(), SMESH.Controls.ManifoldPart.myAllFacePtr, SMESH.Controls.ManifoldPart.myAllFacePtrIntDMap, SMESH.Controls.ManifoldPart.myMapBadGeomIds, SMESH.Controls.ManifoldPart.myMapIds, SMESH.Controls.ManifoldPart.myMesh, and SMESH.Controls.ManifoldPart.myStartElemId.

Referenced by SMESH.Controls.ElementsOnSurface.process(), SMESH.Controls.ElementsOnSurface.SetMesh(), SMESH.Controls.ManifoldPart.SetMesh(), and SMESH.Controls.ElementsOnSurface.SetSurface().

{
  myMapIds.Clear();
  myMapBadGeomIds.Clear();

  myAllFacePtr.clear();
  myAllFacePtrIntDMap.clear();
  if ( !myMesh )
    return false;

  // collect all faces into own map
  SMDS_FaceIteratorPtr anFaceItr = myMesh->facesIterator();
  for (; anFaceItr->more(); )
  {
    SMDS_MeshFace* aFacePtr = (SMDS_MeshFace*)anFaceItr->next();
    myAllFacePtr.push_back( aFacePtr );
    myAllFacePtrIntDMap[aFacePtr] = myAllFacePtr.size()-1;
  }

  SMDS_MeshFace* aStartFace = (SMDS_MeshFace*)myMesh->FindElement( myStartElemId );
  if ( !aStartFace )
    return false;

  // the map of non manifold links and bad geometry
  TMapOfLink aMapOfNonManifold;
  TColStd_MapOfInteger aMapOfTreated;

  // begin cycle on faces from start index and run on vector till the end
  //  and from begin to start index to cover whole vector
  const int aStartIndx = myAllFacePtrIntDMap[aStartFace];
  bool isStartTreat = false;
  for ( int fi = aStartIndx; !isStartTreat || fi != aStartIndx ; fi++ )
  {
    if ( fi == aStartIndx )
      isStartTreat = true;
    // as result next time when fi will be equal to aStartIndx

    SMDS_MeshFace* aFacePtr = myAllFacePtr[ fi ];
    if ( aMapOfTreated.Contains( aFacePtr->GetID() ) )
      continue;

    aMapOfTreated.Add( aFacePtr->GetID() );
    TColStd_MapOfInteger aResFaces;
    if ( !findConnected( myAllFacePtrIntDMap, aFacePtr,
                         aMapOfNonManifold, aResFaces ) )
      continue;
    TColStd_MapIteratorOfMapOfInteger anItr( aResFaces );
    for ( ; anItr.More(); anItr.Next() )
    {
      int aFaceId = anItr.Key();
      aMapOfTreated.Add( aFaceId );
      myMapIds.Add( aFaceId );
    }

    if ( fi == ( myAllFacePtr.size() - 1 ) )
      fi = 0;
  } // end run on vector of faces
  return !myMapIds.IsEmpty();
}
void ManifoldPart::SetAngleTolerance ( const double  theAngToler)

Definition at line 3144 of file SMESH_Controls.cxx.

References SMESH.Controls.ManifoldPart.myAngToler.

{ myAngToler = theAngToler; }
void ManifoldPart::SetIsOnlyManifold ( const bool  theIsOnly)

Definition at line 3150 of file SMESH_Controls.cxx.

References SMESH.Controls.ManifoldPart.myIsOnlyManifold.

{ myIsOnlyManifold = theIsOnly; }
void ManifoldPart::SetMesh ( const SMDS_Mesh theMesh) [virtual]
void ManifoldPart::SetStartElem ( const long  theStartElemId)

Definition at line 3153 of file SMESH_Controls.cxx.

References SMESH.Controls.ManifoldPart.myStartElemId.

{ myStartElemId = theStartId; }

Field Documentation

Definition at line 707 of file SMESH_ControlsDef.hxx.

Referenced by SMESH.Controls.ManifoldPart.process().

TColStd_MapOfInteger SMESH.Controls.ManifoldPart.myMapBadGeomIds [private]
TColStd_MapOfInteger SMESH.Controls.ManifoldPart.myMapIds [private]
Copyright © 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
Copyright © 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS