Logo Search packages:      
Sourcecode: opencascade version File versions  Download package

BOPTools_Tools3D_1.cxx

// File:    BOPTools_Tools3D_1.cxx
// Created: Mon Jun 18 09:51:53 2001
// Author:  Peter KURNEV
//          <pkv@irinox>

#include <BOPTools_Tools3D.ixx>
#include <math.h>

#include <gp.hxx>
#include <gp_Cylinder.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Vec2d.hxx>
#include <gp_Dir2d.hxx>

#include <gp_Dir.hxx>
#include <gp_Vec.hxx>

#include <Geom2d_Curve.hxx>
#include <Geom_Curve.hxx>
#include <Geom_Surface.hxx>

#include <GeomAdaptor_Surface.hxx>
#include <GeomAPI_ProjectPointOnSurf.hxx>

#include <BRepTools.hxx>
#include <BRepClass3d_SolidClassifier.hxx>

#include <BRep_Tool.hxx>
#include <BRepAdaptor_Surface.hxx>

#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopTools_ListOfShape.hxx>

#include <BOPTools_Tools2D.hxx>


//=======================================================================
//function : GetApproxNormalToFaceOnEdge
//purpose  : 
//=======================================================================
00043   void BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (const TopoDS_Edge& aE,
                                          const TopoDS_Face& aF,
                                          const Standard_Real aT,
                                          gp_Pnt& aPNear,
                                          gp_Dir& aDNF)
{
  Standard_Real aFirst, aLast;
  Handle(Geom2d_Curve) aC2D= BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast);
  
  if (aC2D.IsNull()) {
    return;
  }
  //gp_Pnt aPNear;
  gp_Pnt2d aPx2DNear;
  BOPTools_Tools3D::PointNearEdge (aE, aF, aT, aPx2DNear, aPNear);
  
  Handle(Geom_Surface) aS=BRep_Tool::Surface(aF);
  
  BOPTools_Tools3D::GetNormalToSurface (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF);
  
  if (aF.Orientation()==TopAbs_REVERSED){
    aDNF.Reverse();
  }
}
//=======================================================================
//function : PointNearEdge
//purpose  : 
//=======================================================================
00071   void BOPTools_Tools3D::PointNearEdge (const TopoDS_Edge& aE,
                              const TopoDS_Face& aF,
                              const Standard_Real aT, 
                              const Standard_Real aDt2D, 
                              gp_Pnt2d& aPx2DNear,
                              gp_Pnt& aPxNear)
{
  Standard_Real aFirst, aLast, aETol, aFTol, transVal;
  GeomAbs_SurfaceType aTS;
  Handle(Geom2d_Curve) aC2D;
  Handle(Geom_Surface) aS;
  //
  aC2D= BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast);
  if (aC2D.IsNull()) {
    aPx2DNear.SetCoord (99., 99);
    return;
  }
  //
  aS=BRep_Tool::Surface(aF);
  //
  gp_Pnt2d aPx2D;
  gp_Vec2d aVx2D;
  aC2D->D1 (aT, aPx2D, aVx2D);
  gp_Dir2d aDx2D(aVx2D);
  
  gp_Dir2d aDP;
  aDP.SetCoord (-aDx2D.Y(), aDx2D.X());
  
  if (aE.Orientation()==TopAbs_REVERSED){
    aDP.Reverse();
  }

  if (aF.Orientation()==TopAbs_REVERSED) {
    aDP.Reverse();
  }
  //
  aETol = BRep_Tool::Tolerance(aE);
  aFTol = BRep_Tool::Tolerance(aF);
  //modified by NIZNHY-PKV Fri Mar 28 15:09:30 2008f
  // pkv NPAL19220
  GeomAdaptor_Surface aGAS(aS);
  aTS=aGAS.GetType();
  if (aTS==GeomAbs_BSplineSurface) {
    if (aETol > 1.e-5) {
      aFTol=aETol;
    }
  }
  //modified by NIZNHY-PKV Fri Mar 28 15:09:43 2008t
  if( aETol > 1.e-5 && aFTol > 1.e-5 ) {
    //modified by NIZNHY-PKV Fri Mar 28 15:09:52 2008f
    //GeomAdaptor_Surface aGAS(aS);
    //aTS=aGAS.GetType();
    //modified by NIZNHY-PKV Fri Mar 28 15:10:01 2008t
    //pkv/103/D7
    if(aTS!=GeomAbs_Sphere) {
      gp_Vec2d transVec( aDP );
      transVal = aDt2D + aETol + aFTol;
      if (aTS==GeomAbs_Cylinder) {// pkv/909/F8
      Standard_Real aR, dT;
      //
      gp_Cylinder aCyl=aGAS.Cylinder();
      aR=aCyl.Radius();
      dT=1.-transVal/aR;
      dT=acos(dT);
      transVal=dT;
      }
      //
      transVec.Multiply(transVal);
      //
      aPx2DNear = aPx2D.Translated( transVec );
    }
    else {
      aPx2DNear.SetCoord (aPx2D.X()+aDt2D*aDP.X(), aPx2D.Y()+aDt2D*aDP.Y());
    }
  }
  else {
    aPx2DNear.SetCoord (aPx2D.X()+aDt2D*aDP.X(), aPx2D.Y()+aDt2D*aDP.Y());
  }
  //
  aS->D0(aPx2DNear.X(), aPx2DNear.Y(), aPxNear);
}

//=======================================================================
//function : PointNearEdge
//purpose  : 
//=======================================================================
00157   void BOPTools_Tools3D::PointNearEdge (const TopoDS_Edge& aE,
                              const TopoDS_Face& aF,
                              const Standard_Real aT, 
                              gp_Pnt2d& aPx2DNear,
                              gp_Pnt& aPxNear)
{
  Standard_Real dt2D=BOPTools_Tools3D::MinStepIn2d();//~1.e-5;
  //
  BOPTools_Tools3D::PointNearEdge (aE, aF, aT, dt2D, aPx2DNear, aPxNear);
}

//=======================================================================
// function: PointNearEdge
// purpose: 
//=======================================================================
00172   void  BOPTools_Tools3D::PointNearEdge (const TopoDS_Edge& aE,
                               const TopoDS_Face& aF, 
                               gp_Pnt2d& aPInFace2D, 
                               gp_Pnt& aPInFace)
                          
{
  Standard_Real aT, aT1, aT2;
  //
  // 1. 
  BRep_Tool::Range(aE, aT1, aT2);
  aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
  //
  // 2. a Point inside Face near aPOnEdge aPInFace;
  TopoDS_Face aFF=aF;
  TopoDS_Edge aERight;
  aFF.Orientation(TopAbs_FORWARD);
  BOPTools_Tools3D::OrientEdgeOnFace (aE, aFF, aERight);
  
  BOPTools_Tools3D::PointNearEdge (aERight, aFF, aT, aPInFace2D, aPInFace);
}


//=======================================================================
//function : PointToCompare
//purpose  : 
//=======================================================================
00198   void BOPTools_Tools3D::PointToCompare (const gp_Pnt& aP1,
                               const gp_Pnt& aP2,
                               const TopoDS_Face& aF,
                               gp_Pnt& aPF,
                               IntTools_Context& aContext)
{
  Standard_Boolean bFlag;
  Standard_Real aD, aTolF,  U, V;

  Handle(Geom_Surface) aS=BRep_Tool::Surface(aF);

  aTolF=BRep_Tool::Tolerance(aF);
  //
  GeomAPI_ProjectPointOnSurf& aProjector=aContext.ProjPS(aF);
  //
  aProjector.Perform(aP1);
  //
  bFlag=aProjector.IsDone();
  
  if (bFlag) {
    aD=aProjector.LowerDistance();
    if (aD<aTolF) {
      aProjector.LowerDistanceParameters (U, V);
      aS->D0(U, V, aPF);
      return;
    }
  }
  //
  aProjector.Perform(aP2);
  //
  bFlag=aProjector.IsDone();

  if (bFlag) {
    aD=aProjector.LowerDistance();
    if (aD<aTolF) {
      aProjector.LowerDistanceParameters (U, V);
      aS->D0(U, V, aPF);
      return;
    }
  }

  aPF=aP1;
}

//=======================================================================
//function : GetPlane
//purpose  : 
//=======================================================================
00246   void BOPTools_Tools3D::GetPlane (const TopoDS_Edge& aSpEF1,
                           const TopoDS_Edge& aEF1,
                           const TopoDS_Face& aF1,
                           const TopoDS_Face& aF2,
                           TopAbs_State& aStPF,
                           IntTools_Context& aContext)
{
  Standard_Real aT1, aT2, aT, aTolF2, aDt2D;
  gp_Pnt2d aPx2DNear;
  gp_Pnt aPxNear, aPxF2;
  gp_Dir aDNF2;

  Handle(Geom_Curve)aC3D =BRep_Tool::Curve(aSpEF1, aT1, aT2);
  aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);

  Handle(Geom2d_Curve) aC2D= BRep_Tool::CurveOnSurface (aEF1, aF1, aT1, aT2);

  aStPF=TopAbs_OUT;
  //
  aDt2D=BOPTools_Tools3D::MinStepIn2d();//~1.e-5;
  aTolF2=BRep_Tool::Tolerance(aF2);
  //
  {
    GeomAbs_SurfaceType aType1;
    
    Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
    GeomAdaptor_Surface aGASF1(aS1);
    aType1=aGASF1.GetType();
    
    if (aType1==GeomAbs_Cylinder) {
      Standard_Real aCT, aDt2Dx, aPC=0.99;
      
      aCT=1.-aGASF1.UResolution(aTolF2);
      aDt2Dx=aPC*acos(aCT);
      if (aDt2Dx>aDt2D) {
      aDt2D=aDt2Dx;
      }
    }
  }
  //
  BOPTools_Tools3D::PointNearEdge (aEF1, aF1, aT, aDt2D, aPx2DNear, aPxNear);
  //

  //-- EJG
  Standard_Boolean isIn = aContext.IsPointInFace(aF1,aPx2DNear);
  if( !isIn ) {
    Standard_Real aEF1Tol = BRep_Tool::Tolerance(aEF1);
    Standard_Real aF1Tol = BRep_Tool::Tolerance(aF1);
    if( aEF1Tol > 1.e-5 || ( aF1Tol > 1.e-5 || aTolF2 > 1.e-5 ) ) {
      gp_Pnt2d aP2DOnC; 
      aC2D->D0(aT, aP2DOnC);
      gp_Vec2d aP2Dir( aPx2DNear, aP2DOnC );
      Standard_Real transVal = aP2Dir.Magnitude();
      gp_Vec2d aP2DirN = aP2Dir.Normalized();
      if( aF1Tol > 1.e-5 && aTolF2 > 1.e-5 ) {
      transVal = 2.*transVal +aEF1Tol + aF1Tol + aTolF2;
      }
      else {
      transVal *= 2.;
      }
      aPx2DNear.Translate( (transVal*aP2DirN) );
      Handle(Geom_Surface) aS1 = BRep_Tool::Surface(aF1);
      aS1->D0(aPx2DNear.X(), aPx2DNear.Y(), aPxNear);

    }
  }
  //-- EJG

  Standard_Boolean bFlag;
  Standard_Real aD, U, V;
  //
  GeomAPI_ProjectPointOnSurf& aProjector=aContext.ProjPS(aF2);
  //
  Handle(Geom_Surface) aS2=BRep_Tool::Surface(aF2);
  //
  aProjector.Perform(aPxNear);
  //
  bFlag=aProjector.IsDone();
  
  if (!bFlag) {
    return;
  }
  //
  aD=aProjector.LowerDistance();
  if (aD<aTolF2) {
    // aPxF2, aDNF2, aPlnF2
    aProjector.LowerDistanceParameters (U, V);
    aS2->D0(U, V, aPxF2);
    
    BOPTools_Tools3D::GetNormalToSurface (aS2, U, V, aDNF2);
  
    if (aF2.Orientation()==TopAbs_REVERSED){
      aDNF2.Reverse();
    }

    gp_Pln aPlnF2(aPxF2, aDNF2);
    //
    aD=BOPTools_Tools3D::SignDistance(aPxNear, aPlnF2);
    
    if (aD<=0.) {
      aStPF=TopAbs_IN;
    }
  }
}

//=======================================================================
//function : GetPointState
//purpose  : 
//=======================================================================
00355   void BOPTools_Tools3D::GetPointState (const TopoDS_Edge& aSpEF2,
                              const TopoDS_Edge& aEF2,
                              const TopoDS_Face& aF2adj,
                              const TopoDS_Face& aF1,
                              TopAbs_State& aStPF)
{
  Standard_Real aT1, aT2, aT, aTolEF2;
  gp_Dir aDNF1;
  gp_Pnt2d aPxOnF1, aPxOnF2;
  //
  TopoDS_Face aF2adjF=aF2adj;
  aF2adjF.Orientation(TopAbs_FORWARD);
  //
  aTolEF2=BRep_Tool::Tolerance(aEF2);
  //
  aStPF=TopAbs_OUT;
  //
  Handle(Geom_Curve)aC3D =BRep_Tool::Curve(aSpEF2, aT1, aT2);
  aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
  //
  // 2D-curves of aSpEF2 for aF1, aF2adj
  Handle(Geom2d_Curve) aC2DF1= BRep_Tool::CurveOnSurface (aSpEF2, aF1, aT1, aT2);
  aC2DF1->D0(aT, aPxOnF1);

  Handle(Geom2d_Curve) aC2DF2= BRep_Tool::CurveOnSurface (aSpEF2, aF2adjF, aT1, aT2);
  aC2DF2->D0(aT, aPxOnF2);
  //
  // Surfaces
  Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
  Handle(Geom_Surface) aS2=BRep_Tool::Surface(aF2adjF);
  
  //
  // Step aDt2D 
  Standard_Real aDt2D, aDt2dMin, aURes, aVRes;
  //
  GeomAdaptor_Surface aGASF2adjF(aS2);
  //
  aURes=aGASF2adjF.UResolution(aTolEF2);
  aVRes=aGASF2adjF.VResolution(aTolEF2);
  aDt2D=(aURes>aVRes) ? aURes : aVRes;
  //
  aDt2dMin=BOPTools_Tools3D::MinStepIn2d();
  //
  if (aDt2D < aDt2dMin) {
    aDt2D=aDt2dMin;
  }
  //
  // Point aPxNear on aF2adjF that is Near Edge aEF2Right at parameter aT
  gp_Pnt2d aPx2DNear;
  gp_Pnt aPxNear;
  TopoDS_Edge aEF2Right;
  //
  BOPTools_Tools3D::OrientEdgeOnFace (aEF2, aF2adjF, aEF2Right);
  //
  BOPTools_Tools3D::PointNearEdge (aEF2Right, aF2adjF, aT, aDt2D, aPx2DNear, aPxNear);
  //
  // Normal to the face aF1 at the point aPxOnF1
  BOPTools_Tools3D::GetNormalToSurface (aS1, aPxOnF1.X(), aPxOnF1.Y(), aDNF1);
  if (aF1.Orientation()==TopAbs_REVERSED){
    aDNF1.Reverse();
  }
  //
  // Plane to compare aPlnF1
  gp_Pnt aPxF1, aPxF2;
  //
  aS1->D0(aPxOnF1.X(), aPxOnF1.Y(), aPxF1);
  //
  gp_Pln aPlnF1(aPxF1, aDNF1);
  //
  // Correction on shifting vector aVx
  {
    Standard_Real aX, aY, aZ;
    //
    aS2->D0(aPxOnF2.X(), aPxOnF2.Y(), aPxF2);
    gp_Vec aVx(aPxF2, aPxF1);
    //
    aX=aPxNear.X()+aVx.X();
    aY=aPxNear.Y()+aVx.Y();
    aZ=aPxNear.Z()+aVx.Z();
    //
    aPxNear.SetCoord(aX, aY, aZ);
  }
  //
  // Signed Distance between aPxNear, aPlnF1
  Standard_Real aD;
  aD=BOPTools_Tools3D::SignDistance(aPxNear, aPlnF1);
  if (aD<=0.) {
    aStPF=TopAbs_IN;
  }
}

//=======================================================================
//function : OrientEdgeOnFace
//purpose  : 
//=======================================================================
00450   void BOPTools_Tools3D::OrientEdgeOnFace (const TopoDS_Edge& aE,
                                 const TopoDS_Face& aF,
                                 TopoDS_Edge& aERight)
{
  if (BRep_Tool::IsClosed(aE, aF)) {
    aERight=aE;
    aERight.Orientation(aE.Orientation());

    Standard_Integer iFoundCount = 0;
    TopoDS_Edge anEdge = aE;
    TopExp_Explorer anExp(aF, TopAbs_EDGE);

    for (; anExp.More(); anExp.Next()) {
      const TopoDS_Shape& aSS=anExp.Current();
      
      if (aSS.IsSame(aE)) {
      anEdge = TopoDS::Edge(aSS);
      iFoundCount++;
      }
    }
    
    if(iFoundCount == 1) {
      aERight = anEdge;
    }
    return;
  }
  
  TopExp_Explorer anExp(aF, TopAbs_EDGE);
  for (; anExp.More(); anExp.Next()) {
    const TopoDS_Shape& aSS=anExp.Current();
    if (aSS.IsSame(aE)) {
      aERight=aE;
      aERight.Orientation(aSS.Orientation());
      return;
    }
  }
  aERight=aE;
  aERight.Orientation(aE.Orientation());
}
//=======================================================================
//function : OrientTouchEdgeOnF1
//purpose  : 
//=======================================================================
00493   TopAbs_Orientation BOPTools_Tools3D::OrientTouchEdgeOnF1 (const TopoDS_Edge& aSpEF2,
                                              const TopoDS_Edge& aEF2,
                                              const TopoDS_Face& aF2adj,
                                              const TopoDS_Face& aF1)
{
  Standard_Real aT1, aT2, aT;
  //
  Handle(Geom_Curve)aC3D =BRep_Tool::Curve(aSpEF2, aT1, aT2);
  //
  // point on edge aEF2 inside range of aSpEF2:
  gp_Pnt aPx;
  aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
  aC3D->D0(aT, aPx);
  //
  // Normal to aF1
  gp_Dir aDNF1;
  Handle(Geom2d_Curve) aC2DF1= BRep_Tool::CurveOnSurface (aSpEF2, aF1, aT1, aT2);
  gp_Pnt2d aPxOnF1;
  aC2DF1->D0(aT, aPxOnF1);

  Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
  BOPTools_Tools3D::GetNormalToSurface (aS1, aPxOnF1.X(), aPxOnF1.Y(), aDNF1);
  
  if (aF1.Orientation()==TopAbs_REVERSED){
    aDNF1.Reverse();
  }
  //
  // Point  aPxNear that is ON F2adj and near Px
  gp_Pnt2d aPx2DNear;
  gp_Pnt aPxNear;
  
  Handle(Geom2d_Curve) aC2D= BRep_Tool::CurveOnSurface (aEF2, aF2adj, aT1, aT2);
  
  TopoDS_Face aF2adjF=aF2adj;
  aF2adjF.Orientation(TopAbs_FORWARD);
  TopoDS_Edge aEF2Right;
  BOPTools_Tools3D::OrientEdgeOnFace (aEF2, aF2adjF, aEF2Right);
  BOPTools_Tools3D::PointNearEdge (aEF2Right, aF2adjF, aT, aPx2DNear, aPxNear);
  //
  // Normal to aF2adj
  gp_Dir aDNF2;
  Handle(Geom_Surface) aS2=BRep_Tool::Surface(aF2adj);
  BOPTools_Tools3D::GetNormalToSurface (aS2, aPx2DNear.X(), aPx2DNear.Y(), aDNF2);
  
  if (aF2adj.Orientation()==TopAbs_REVERSED){
    aDNF2.Reverse();
  }
  //
  // vector product
  gp_Dir aDTN=aDNF1^aDNF2;
  // Tangent for split
  gp_Vec aTE;
  BOPTools_Tools2D::TangentOnEdge(aT, aSpEF2, aTE);
  gp_Dir aDTE(aTE); 
  
  Standard_Real aScPr;
  aScPr=aDTN*aDTE;
  
  TopAbs_Orientation anOr;
  anOr=TopAbs_FORWARD;
  if (aScPr<0.) {
    anOr=TopAbs_REVERSED;
  }
  return anOr;
}

//=======================================================================
// function: GetSeams
// purpose: 
//=======================================================================
00563   void BOPTools_Tools3D::GetSeams (const TopoDS_Face& aF,
                           TopoDS_Edge& aSim1,
                           TopoDS_Edge& aSim2)
{
  TopTools_ListOfShape aLS;
  TopExp_Explorer anExpEdges (aF, TopAbs_EDGE);
  for (; anExpEdges.More(); anExpEdges.Next()) {
    const TopoDS_Edge& aE= TopoDS::Edge(anExpEdges.Current());
    if (BRep_Tool::IsClosed(aE, aF)) {
      aLS.Append(aE);
    }
  }
  aSim1=TopoDS::Edge(aLS.First());
  aSim2=TopoDS::Edge(aLS.Last ());
}

//=======================================================================
// function: GetSeam
// purpose: 
//=======================================================================
00583   void BOPTools_Tools3D::GetSeam (const TopoDS_Face& aF,
                          const TopoDS_Edge& aSim1,
                          TopoDS_Edge& aSim2)
{
  TopExp_Explorer anExpEdges (aF, TopAbs_EDGE);
  for (; anExpEdges.More(); anExpEdges.Next()) {
    const TopoDS_Edge& aE= TopoDS::Edge(anExpEdges.Current());
    if (BRep_Tool::IsClosed(aE, aF)) {
      if (aE.IsSame(aSim1)) {
      if (aE!=aSim1) {
        aSim2=aE;
        return;
      }
      }
    }
  }
}

//=======================================================================
//function : MinStepIn2d
//purpose  : 
//=======================================================================
00605   Standard_Real BOPTools_Tools3D::MinStepIn2d()
{
  Standard_Real dt=1.e-5;
  return dt;
} 


#include <TopTools_IndexedMapOfShape.hxx>
#include <TopoDS_Iterator.hxx>
#include <BRep_TVertex.hxx>
#include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
#include <BRep_PointRepresentation.hxx>
#include <BRep_TEdge.hxx>
#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
#include <BRep_CurveRepresentation.hxx>
#include <BRep_TFace.hxx>
#include <Poly_Triangulation.hxx>
#include <BRep_Builder.hxx>

static 
  Standard_Boolean HasGeometry(const TopoDS_Shape& aS);

static
  void Add(const TopoDS_Shape& aS,
         TopTools_IndexedMapOfShape& myShapes, 
         Standard_Boolean& bHasGeometry);

//=======================================================================
//function : IsEmptyShape
//purpose  : 
//=======================================================================
00636   Standard_Boolean BOPTools_Tools3D::IsEmptyShape(const TopoDS_Shape& aS)
{
  Standard_Boolean bHasGeometry=Standard_False;
  //
  TopTools_IndexedMapOfShape myShapes;
  //
  Add(aS, myShapes, bHasGeometry);

  return !bHasGeometry;
}
//=======================================================================
//function : Add
//purpose  : 
//=======================================================================
void Add(const TopoDS_Shape& aS,
       TopTools_IndexedMapOfShape& myShapes, 
       Standard_Boolean& bHasGeometry)
{
  Standard_Integer anIndex; 
  //
  if (bHasGeometry) {
    return;
  }
  //
  if (aS.IsNull()) {
    return;
  }
  //
  TopoDS_Shape aSx = aS;
  //
  anIndex=myShapes.FindIndex(aSx);
  if (!anIndex) {
    bHasGeometry=HasGeometry (aSx);
    if (bHasGeometry) {
      return;
    }
    //
    TopoDS_Iterator anIt(aSx, Standard_False, Standard_False);
    for(; anIt.More(); anIt.Next()) {
      const TopoDS_Shape& aSy=anIt.Value();
      Add(aSy, myShapes, bHasGeometry);
      //
      if (bHasGeometry) {
      return;
      }
      //
      myShapes.Add(aSx);
    }
  }
}
//=======================================================================
//function : HasGeometry
//purpose  : 
//=======================================================================
  Standard_Boolean HasGeometry(const TopoDS_Shape& aS)
{
  Standard_Boolean bHasGeometry=Standard_True;
  TopAbs_ShapeEnum aType= aS.ShapeType();

  if (aType == TopAbs_VERTEX) {
    
    Handle(BRep_TVertex) TV = Handle(BRep_TVertex)::DownCast(aS.TShape());
    BRep_ListIteratorOfListOfPointRepresentation itrp(TV->Points());
    
    while (itrp.More()) {
      const Handle(BRep_PointRepresentation)& PR = itrp.Value();

      if (PR->IsPointOnCurve()) {
        return bHasGeometry;
      }

      else if (PR->IsPointOnCurveOnSurface()) {
      return bHasGeometry;
      }

      else if (PR->IsPointOnSurface()) {
        return bHasGeometry;
      }
      itrp.Next();
    }
  }

  //
  else if (aType == TopAbs_EDGE) {
    Handle(BRep_TEdge) TE = Handle(BRep_TEdge)::DownCast(aS.TShape());
    BRep_ListIteratorOfListOfCurveRepresentation itrc(TE->Curves());

    while (itrc.More()) {
      const Handle(BRep_CurveRepresentation)& CR = itrc.Value();
      if (CR->IsCurve3D()) {
        if (!CR->Curve3D().IsNull()) {
          return bHasGeometry;
        }
      }
      else if (CR->IsCurveOnSurface()) {
      return bHasGeometry;
      }
      else if (CR->IsRegularity()) {
        return bHasGeometry;
      }
      else if (!CR->Polygon3D().IsNull()) {
      return bHasGeometry;
      }
      else if (CR->IsPolygonOnTriangulation()) {
      return bHasGeometry;
      }
      else if (CR->IsPolygonOnSurface()) {
      return bHasGeometry;
      }
      itrc.Next();
    }
  }
  //
  else if (aType == TopAbs_FACE) {
    Handle(BRep_TFace) TF = Handle(BRep_TFace)::DownCast(aS.TShape());
    if (!TF->Surface().IsNull())  {
      return bHasGeometry;
    }
    Handle(Poly_Triangulation) Tr = TF->Triangulation();
    if (!Tr.IsNull()) {
      return bHasGeometry;
    }
  }
  
  return !bHasGeometry;
}

//=======================================================================
// function: InvertShape
// purpose: 
//=======================================================================
00767   void BOPTools_Tools3D::InvertShape(const TopoDS_Shape& aS,
                             TopoDS_Shape& aSInvert)
{
  BRep_Builder aBB;
  
  aSInvert=aS.EmptyCopied();
  
  TopoDS_Iterator anIt(aS);

  while (anIt.More()) {
    aBB.Add(aSInvert, anIt.Value().Reversed());
    anIt.Next();
  }
}

//=======================================================================
// function: GetStatePartIN2D
// purpose: 
//=======================================================================
00786   TopAbs_State  BOPTools_Tools3D::GetStatePartIN2D(const TopoDS_Edge& aSp,
                                       const TopoDS_Edge& aEF1,
                                       const TopoDS_Face& aF1,
                                       const TopoDS_Face& aF2,
                                       IntTools_Context& aContext)
{
  gp_Dir aDBF1, aDNF2;
  TopAbs_State aStPF;

  BOPTools_Tools3D::GetBiNormal (aSp, aF1, aDBF1);
  BOPTools_Tools3D::GetNormalToFaceOnEdge (aSp, aF2, aDNF2);

  Standard_Real aTolScPr, aScPr;

  aTolScPr=1.e-7;
  aScPr=aDBF1*aDNF2;

  //XX 909/G2
  BRepAdaptor_Surface aBAS1, aBAS2;
  GeomAbs_SurfaceType aType1, aType2;

  aBAS1.Initialize (aF1, Standard_False);
  aBAS2.Initialize (aF2, Standard_False);
  aType1=aBAS1.GetType();
  aType2=aBAS2.GetType();
  
  if (aType1==GeomAbs_BSplineSurface
      ||
      aType2==GeomAbs_BSplineSurface) {
    //aTolScPr=1.e-5;
    aTolScPr=5.5e-5;
  }
  //XX

  if (fabs(aScPr) < aTolScPr) {
    
    
    BOPTools_Tools3D::GetPlane(aSp, aEF1, aF1, aF2, aStPF, aContext);
    aScPr=1.; // >0.
    if (aStPF==TopAbs_IN) {
      aScPr=-1.; // <0.
    }
  }

  aStPF=TopAbs_OUT;
  if (aScPr<0.) {
    aStPF=TopAbs_IN;
  }
  return aStPF;
}

// ===========================================================================================
// function: CheckSameDomainFaceInside
// purpose: Check if distance between several points of theFace1 and
//          theFace2 
// ===========================================================================================
Standard_Boolean BOPTools_Tools3D::CheckSameDomainFaceInside(const TopoDS_Face& theFace1,
                                               const TopoDS_Face& theFace2,
                                               IntTools_Context&  theContext) 
{
  Standard_Real umin = 0., umax = 0., vmin = 0., vmax = 0.;
  BRepTools::UVBounds(theFace1, umin, umax, vmin, vmax);
  Handle(Geom_Surface) aSurface = BRep_Tool::Surface(theFace1);

  Standard_Real aTolerance = BRep_Tool::Tolerance(theFace1);
  aTolerance += BRep_Tool::Tolerance(theFace2);

  Standard_Integer nbpoints = 5;
  Standard_Real adeltau = (umax - umin) / (nbpoints + 1);
  Standard_Real adeltav = (vmax - vmin) / (nbpoints + 1);
  Standard_Real U = umin + adeltau;
  Standard_Boolean bFoundON = Standard_False;
  GeomAPI_ProjectPointOnSurf& aProjector = theContext.ProjPS(theFace2);

  for(Standard_Integer i = 1; i <= nbpoints; i++, U+=adeltau) {
    Standard_Real V = vmin + adeltav;

    for(Standard_Integer j = 1; j <= nbpoints; j++, V+=adeltav) {
      gp_Pnt2d aPoint(U,V);

      if(theContext.IsPointInFace(theFace1, aPoint)) {
      gp_Pnt aP3d = aSurface->Value(U, V);
      aProjector.Perform(aP3d);

      if(aProjector.IsDone()) {
        Standard_Real U2 = 0., V2 = 0.;
        aProjector.LowerDistanceParameters(U2, V2);

        aPoint = gp_Pnt2d(U2, V2);

        if(aProjector.LowerDistance() > aTolerance)
           return Standard_False;
        else if(theContext.IsPointInFace(theFace2, aPoint))
          bFoundON = Standard_True;
      }
      }
    }
  }

  return bFoundON;
}

// ===========================================================================================
// function: ComputeFaceState
// purpose: 
// ===========================================================================================
Standard_Boolean BOPTools_Tools3D::ComputeFaceState(const TopoDS_Face&  theFace,
                                        const TopoDS_Solid& theRef,
                                        IntTools_Context&   theContext,
                                        TopAbs_State&       theState) 
{
  TopAbs_State aState = TopAbs_ON;

  Standard_Real umin = 0., umax = 0., vmin = 0., vmax = 0.;
  BRepTools::UVBounds(theFace, umin, umax, vmin, vmax);
  Handle(Geom_Surface) aSurface = BRep_Tool::Surface(theFace);
  Standard_Real aTolerance = BRep_Tool::Tolerance(theFace);

  Standard_Integer nbpoints = 5;
  Standard_Real adeltau = (umax - umin) / (nbpoints + 1);
  Standard_Real adeltav = (vmax - vmin) / (nbpoints + 1);
  Standard_Real U = umin + adeltau;
  Standard_Boolean bFoundValidPoint = Standard_False;
  Standard_Boolean bFoundInFacePoint = Standard_False;
  BRepClass3d_SolidClassifier& aSolidClassifier = theContext.SolidClassifier(theRef);
  Standard_Integer i = 0, j = 0;

  for(i = 1; !bFoundValidPoint && (i <= nbpoints); i++, U+=adeltau) {
    Standard_Real V = vmin + adeltav;

    for(j = 1; !bFoundValidPoint && (j <= nbpoints); j++, V+=adeltav) {
      gp_Pnt2d aPoint(U,V);

      if(theContext.IsPointInFace(theFace, aPoint)) {
      bFoundInFacePoint = Standard_True;
      gp_Pnt aP3d = aSurface->Value(U, V);

      aSolidClassifier.Perform(aP3d, aTolerance);
      aState = aSolidClassifier.State();

      if(aState != TopAbs_ON) {
        
        if(!aSolidClassifier.Rejected()) {
          TopoDS_Face aFace2 = aSolidClassifier.Face();

          if(!aFace2.IsNull()) {
            if(BOPTools_Tools3D::CheckSameDomainFaceInside(theFace, aFace2, theContext))
            aState = TopAbs_ON;
            else {
            break;
            }
          }
        }
      }
      }
    }
  }

  if(!bFoundInFacePoint) {
    U = (umin + umax) * 0.5;
    nbpoints /= 2;

    for(i = 1; !bFoundValidPoint && (i <= nbpoints); i++, U+=adeltau) {
      Standard_Real V = (vmin + vmax) * 0.5;

      for(j = 1; !bFoundValidPoint && (j <= nbpoints); j++, V+=adeltav) {
      gp_Pnt2d aPoint(U,V);

      if(theContext.IsPointInOnFace(theFace, aPoint)) {
        bFoundInFacePoint = Standard_True;
        gp_Pnt aP3d = aSurface->Value(U, V);
    
        aSolidClassifier.Perform(aP3d, aTolerance);
        aState = aSolidClassifier.State();

        if(aState != TopAbs_ON) {

          if(!aSolidClassifier.Rejected()) {
            TopoDS_Face aFace2 = aSolidClassifier.Face();

            if(!aFace2.IsNull()) {
            GeomAPI_ProjectPointOnSurf& aProjector = theContext.ProjPS(aFace2);
            aProjector.Perform(aP3d);

            if(aProjector.IsDone()) {
              Standard_Real U2 = 0., V2 = 0.;
              aProjector.LowerDistanceParameters(U2, V2);
              gp_Pnt2d aPoint2(U2, V2);

              if(aProjector.LowerDistance() < aTolerance) {
                if(theContext.IsPointInFace(aFace2, aPoint2)) 
                  aState = TopAbs_ON;
              }
            }
            bFoundValidPoint = Standard_True;
            break;
            }
          }
          else {
            bFoundInFacePoint = Standard_False;
          }
        }
      }
      }
    }
  }

  if(!bFoundInFacePoint)
    return Standard_False;

  theState = aState;

  return Standard_True;
}

Generated by  Doxygen 1.6.0   Back to index