Back to index

salome-smesh  6.5.0
Typedefs | Enumerations | Functions
StdMeshers_QuadToTriaAdaptor.cxx File Reference
#include "StdMeshers_QuadToTriaAdaptor.hxx"
#include "SMDS_SetIterator.hxx"
#include "SMESH_Algo.hxx"
#include "SMESH_MesherHelper.hxx"
#include <IntAna_IntConicQuad.hxx>
#include <IntAna_Quadric.hxx>
#include <TColgp_HArray1OfPnt.hxx>
#include <TColgp_HArray1OfVec.hxx>
#include <TColgp_HSequenceOfPnt.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <gp_Lin.hxx>
#include <gp_Pln.hxx>
#include <numeric>
#include <limits>

Go to the source code of this file.

Typedefs

typedef SMDS_StdIterator
< SMESH_TNodeXYZ,
SMDS_ElemIteratorPtr
TXyzIterator

Enumerations

enum  EQuadNature {
  NOT_QUAD, QUAD, DEGEN_QUAD, PYRAM_APEX = 4,
  TRIA_APEX = 0
}

Functions

static gp_Pnt FindBestPoint (const gp_Pnt &P1, const gp_Pnt &P2, const gp_Pnt &PC, const gp_Vec &V)
static bool HasIntersection3 (const gp_Pnt &P, const gp_Pnt &PC, gp_Pnt &Pint, const gp_Pnt &P1, const gp_Pnt &P2, const gp_Pnt &P3)
static bool HasIntersection (const gp_Pnt &P, const gp_Pnt &PC, gp_Pnt &Pint, Handle(TColgp_HSequenceOfPnt)&aContour)

Typedef Documentation

Definition at line 50 of file StdMeshers_QuadToTriaAdaptor.cxx.


Enumeration Type Documentation

Enumerator:
NOT_QUAD 
QUAD 
DEGEN_QUAD 
PYRAM_APEX 
TRIA_APEX 

Definition at line 47 of file StdMeshers_QuadToTriaAdaptor.cxx.


Function Documentation

static gp_Pnt FindBestPoint ( const gp_Pnt &  P1,
const gp_Pnt &  P2,
const gp_Pnt &  PC,
const gp_Vec &  V 
) [static]

Definition at line 389 of file StdMeshers_QuadToTriaAdaptor.cxx.

{
  gp_Pnt Pbest = PC;
  const double a = P1.Distance(P2);
  const double b = P1.Distance(PC);
  const double c = P2.Distance(PC);
  if( a < (b+c)/2 )
    return Pbest;
  else {
    // find shift along V in order a to became equal to (b+c)/2
    const double Vsize = V.Magnitude();
    if ( fabs( Vsize ) > std::numeric_limits<double>::min() )
    {
      const double shift = sqrt( a*a + (b*b-c*c)*(b*b-c*c)/16/a/a - (b*b+c*c)/2 );
      Pbest.ChangeCoord() += shift * V.XYZ() / Vsize;
    }
  }
  return Pbest;
}
static bool HasIntersection ( const gp_Pnt &  P,
const gp_Pnt &  PC,
gp_Pnt &  Pint,
Handle(TColgp_HSequenceOfPnt)&  aContour 
) [static]

Definition at line 492 of file StdMeshers_QuadToTriaAdaptor.cxx.

{
  if(aContour->Length()==3) {
    return HasIntersection3( P, PC, Pint, aContour->Value(1),
                             aContour->Value(2), aContour->Value(3) );
  }
  else {
    bool check = false;
    if( (aContour->Value(1).Distance(aContour->Value(2)) > 1.e-6) &&
        (aContour->Value(1).Distance(aContour->Value(3)) > 1.e-6) &&
        (aContour->Value(2).Distance(aContour->Value(3)) > 1.e-6) ) {
      check = HasIntersection3( P, PC, Pint, aContour->Value(1),
                                aContour->Value(2), aContour->Value(3) );
    }
    if(check) return true;
    if( (aContour->Value(1).Distance(aContour->Value(4)) > 1.e-6) &&
        (aContour->Value(1).Distance(aContour->Value(3)) > 1.e-6) &&
        (aContour->Value(4).Distance(aContour->Value(3)) > 1.e-6) ) {
      check = HasIntersection3( P, PC, Pint, aContour->Value(1),
                                aContour->Value(3), aContour->Value(4) );
    }
    if(check) return true;
  }

  return false;
}

Here is the call graph for this function:

static bool HasIntersection3 ( const gp_Pnt &  P,
const gp_Pnt &  PC,
gp_Pnt &  Pint,
const gp_Pnt &  P1,
const gp_Pnt &  P2,
const gp_Pnt &  P3 
) [static]

Definition at line 417 of file StdMeshers_QuadToTriaAdaptor.cxx.

{
  //cout<<"HasIntersection3"<<endl;
  //cout<<"  PC("<<PC.X()<<","<<PC.Y()<<","<<PC.Z()<<")"<<endl;
  //cout<<"  P("<<P.X()<<","<<P.Y()<<","<<P.Z()<<")"<<endl;
  //cout<<"  P1("<<P1.X()<<","<<P1.Y()<<","<<P1.Z()<<")"<<endl;
  //cout<<"  P2("<<P2.X()<<","<<P2.Y()<<","<<P2.Z()<<")"<<endl;
  //cout<<"  P3("<<P3.X()<<","<<P3.Y()<<","<<P3.Z()<<")"<<endl;
  gp_Vec VP1(P1,P2);
  gp_Vec VP2(P1,P3);
  IntAna_Quadric IAQ(gp_Pln(P1,VP1.Crossed(VP2)));
  IntAna_IntConicQuad IAICQ(gp_Lin(PC,gp_Dir(gp_Vec(PC,P))),IAQ);
  if(IAICQ.IsDone()) {
    if( IAICQ.IsInQuadric() )
      return false;
    if( IAICQ.NbPoints() == 1 ) {
      gp_Pnt PIn = IAICQ.Point(1);
      const double preci = 1.e-10 * P.Distance(PC);
      // check if this point is internal for segment [PC,P]
      bool IsExternal =
        ( (PC.X()-PIn.X())*(P.X()-PIn.X()) > preci ) ||
        ( (PC.Y()-PIn.Y())*(P.Y()-PIn.Y()) > preci ) ||
        ( (PC.Z()-PIn.Z())*(P.Z()-PIn.Z()) > preci );
      if(IsExternal) {
        return false;
      }
      // check if this point is internal for triangle (P1,P2,P3)
      gp_Vec V1(PIn,P1);
      gp_Vec V2(PIn,P2);
      gp_Vec V3(PIn,P3);
      if( V1.Magnitude()<preci ||
          V2.Magnitude()<preci ||
          V3.Magnitude()<preci ) {
        Pint = PIn;
        return true;
      }
      const double angularTol = 1e-6;
      gp_Vec VC1 = V1.Crossed(V2);
      gp_Vec VC2 = V2.Crossed(V3);
      gp_Vec VC3 = V3.Crossed(V1);
      if(VC1.Magnitude()<gp::Resolution()) {
        if(VC2.IsOpposite(VC3,angularTol)) {
          return false;
        }
      }
      else if(VC2.Magnitude()<gp::Resolution()) {
        if(VC1.IsOpposite(VC3,angularTol)) {
          return false;
        }
      }
      else if(VC3.Magnitude()<gp::Resolution()) {
        if(VC1.IsOpposite(VC2,angularTol)) {
          return false;
        }
      }
      else {
        if( VC1.IsOpposite(VC2,angularTol) || VC1.IsOpposite(VC3,angularTol) ||
            VC2.IsOpposite(VC3,angularTol) ) {
          return false;
        }
      }
      Pint = PIn;
      return true;
    }
  }

  return false;
}

Here is the caller graph for this function: