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

BOPTools_PaveFiller_3.cxx

// File:    BOPTools_PaveFiller_3.cxx
// Created: Tue Mar 13 16:12:16 2001
// Author:  Peter KURNEV
//          <pkv@irinox>


#include <BOPTools_PaveFiller.ixx>

#include <Geom_Curve.hxx>

#include <gp_Pnt.hxx>
#include <TColStd_SequenceOfInteger.hxx>
#include <TColStd_SequenceOfReal.hxx>

#include <TColStd_MapOfInteger.hxx>
#include <TColStd_ListOfInteger.hxx>
#include <TColStd_IndexedMapOfInteger.hxx>
#include <TColStd_ListIteratorOfListOfInteger.hxx>
// modified by NIZHNY-MKK  Tue Oct 18 12:37:02 2005
#include <TColStd_MapIteratorOfMapOfInteger.hxx>

#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Vertex.hxx>

#include <BRep_Tool.hxx>
#include <BRep_Builder.hxx>

#include <BooleanOperations_ShapesDataStructure.hxx>
#include <BooleanOperations_OnceExplorer.hxx>
#include <BooleanOperations_AncestorsSeqAndSuccessorsSeq.hxx>

#include <IntTools_FaceFace.hxx>
#include <IntTools_SequenceOfCurves.hxx>
#include <IntTools_Curve.hxx>
#include <IntTools_Tools.hxx>
#include <IntTools_SequenceOfPntOn2Faces.hxx>
#include <IntTools_PntOn2Faces.hxx>
#include <IntTools_PntOnFace.hxx>

#include <BOPTools_IteratorOfCoupleOfShape.hxx>
#include <BOPTools_CArray1OfSSInterference.hxx>
#include <BOPTools_SSInterference.hxx>
#include <BOPTools_ListOfPaveBlock.hxx>
#include <BOPTools_PaveBlock.hxx>
#include <BOPTools_Pave.hxx>
#include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
#include <BOPTools_ListIteratorOfListOfPave.hxx>
#include <BOPTools_PaveBlockIterator.hxx>
#include <BOPTools_Tools.hxx>
#include <BOPTools_SequenceOfCurves.hxx>
#include <BOPTools_Curve.hxx>
#include <BOPTools_ListOfPave.hxx>
#include <BOPTools_PaveSet.hxx>
#include <BOPTools_CommonBlock.hxx>
#include <BOPTools_ListIteratorOfListOfCommonBlock.hxx>
#include <BOPTools_ListOfCommonBlock.hxx>

#include <BOPTools_InterferencePool.hxx>
#include <BOPTools_ListIteratorOfListOfInterference.hxx>
#include <BOPTools_InterferenceLine.hxx>
#include <BOPTools_ListOfInterference.hxx>
#include <BOPTools_Interference.hxx>
#include <BOPTools_CArray1OfInterferenceLine.hxx>

#include <Precision.hxx>
#include <BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger.hxx>

#include <TopExp_Explorer.hxx>
#include <Geom2d_Curve.hxx>
#include <Geom2dAPI_InterCurveCurve.hxx>
#include <IntRes2d_IntersectionPoint.hxx>
#include <BOPTools_ESInterference.hxx>
#include <BOPTools_VSInterference.hxx>
#include <BOPTools_VEInterference.hxx>
#include <BOPTools_VVInterference.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>

#include <BOPTools_EEInterference.hxx>
#include <IntTools_CommonPrt.hxx>
#include <BOPTools_ESInterference.hxx>
#include <BOPTools_ShapeShapeInterference.hxx>

// modified by NIZHNY-AMV  Tue Oct 18 12:37:02 2005
#include <IntSurf_ListOfPntOn2S.hxx>

#include <GeomAPI_ProjectPointOnSurf.hxx>
#include <IntSurf_PntOn2S.hxx>
#include <TopTools_MapOfShape.hxx>


static
  Standard_Boolean IsPaveBlock(const Standard_Integer nV1,
                         const Standard_Integer nV2, 
                         const BOPTools_ListOfPaveBlock& aLPBExisting);
static
  Standard_Boolean IsFound(const TColStd_IndexedMapOfInteger& aMapWhat,
                     const TColStd_IndexedMapOfInteger& aMapWith);
static
  void FMapWith(const Standard_Integer nF,
            BOPTools_InterferencePool* myIntrPool,
            TColStd_IndexedMapOfInteger& aMapWith);
static
  void FMapWhat(const Standard_Integer nF,
            BOPTools_InterferencePool* myIntrPool,
            TColStd_IndexedMapOfInteger& aMapWhat);

//wkar OCC334 f
static
  void UnUsedMap(BOPTools_SequenceOfCurves& aSCvs,
             const BOPTools_PaveSet& aPSF,
             TColStd_IndexedMapOfInteger& aMapUnUsed);
static
  Standard_Boolean VertexRangeTolerance(const Standard_Integer nV,
                              const Standard_Integer nF1,
                              const Standard_Integer nF2,
                              const BOPTools_InterferencePool& anIntrPool,
                              Standard_Real& aTolV);
static 
  void FaceAndEdgeMap(const Standard_Integer nF,
                  const BOPTools_InterferencePool& anIntrPool,
                  TColStd_IndexedMapOfInteger& aMEF);
static
  void ProcessAloneStickVertices(const Standard_Integer nF1,
                         const Standard_Integer nF2,
                         const BOPTools_PaveSet& aPSF,
                         BOPTools_SequenceOfCurves& aSCvs,
                         const BOPTools_InterferencePool& anIntrPool,
                         TColStd_SequenceOfInteger& aSeqVx,
                         TColStd_SequenceOfReal& aSeqTolVx);
 
//wkar OCC334 t

static
  Standard_Boolean IsPairFound(const Standard_Integer nF1,
                         const Standard_Integer nF2,
                         BOPTools_InterferencePool* myIntrPool,
                         BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& aMapWhat,
                         BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& aMapWith);

static Standard_Boolean CheckNewVertexAndUpdateData(const TopoDS_Vertex&              theVertex,
                                        const Standard_Real               theParamOnE,
                                        const TopoDS_Edge&                theEdge,
                                        const Standard_Real               theParamOnCurve,
                                        const Standard_Integer            theIndexF1,
                                        const Standard_Integer            theIndexF2,
                                        const Standard_Real               theTolerance,
                                        const BOPTools_PInterferencePool& theIntrPool,
                                        const BooleanOperations_PShapesDataStructure& theDS,
                                        IntTools_Context*                 theContext,
                                        const BOPTools_PaveSet&           theEdgePaveSet,
                                        const Standard_Boolean            bAddNewVertex,
                                        const Standard_Boolean            bAddOldVertex,
                                        BOPTools_Curve&                   theBC,
                                        BOPTools_Pave&                    thePaveToPut,
                                        Standard_Boolean&                 bAddNewVertexOut,
                                        Standard_Boolean&                 bAddOldVertexOut);

static void AddInterfForAdjacentFace(const Standard_Integer            theEdgeIndex,
                             const Standard_Integer            theIndexF1,
                             const Standard_Integer            theIndexF2,
                             BOPTools_PInterferencePool        theIntrPool,
                             const BooleanOperations_PShapesDataStructure& theDS);

static Standard_Boolean RejectPaveBlock(const IntTools_Curve& theC,
                                        const Standard_Real   theT1,
                                        const Standard_Real   theT2,
                                        const TopoDS_Vertex&  theV,
                                        Standard_Real&        theRT);

static Standard_Boolean ModifFFTol(const TopoDS_Face& theF1,
                                   const TopoDS_Face& theF2,
                                   Standard_Real&     theTF);

static Standard_Integer RejectBuildingEdge(const IntTools_Curve& theC,
                                           const TopoDS_Vertex&  theV1,
                                           const TopoDS_Vertex&  theV2,
                                           const Standard_Real   theT1,
                                           const Standard_Real   theT2,
                                           const TopTools_ListOfShape& theL,
                                           Standard_Real&        theTF);

//=======================================================================
// function: PerformFF
// purpose: 
//=======================================================================
00190   void BOPTools_PaveFiller::PerformFF() 
{
  myIsDone=Standard_False;
  Standard_Boolean bIsFound;
  Standard_Integer n1, n2, anIndexIn=0, nF1, nF2, aNbFFs, aBlockLength;
  BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger aMapWhat, aMapWith;
  //
  BOPTools_CArray1OfSSInterference& aFFs=myIntrPool->SSInterferences();
  //
  //  F/F Interferences  [BooleanOperations_SurfaceSurface]
  myDSIt.Initialize(TopAbs_FACE, TopAbs_FACE);
  //
  // BlockLength correction
  aNbFFs=ExpectedPoolLength();
  aBlockLength=aFFs.BlockLength();
  if (aNbFFs > aBlockLength) {
    aFFs.SetBlockLength(aNbFFs);
  }
  //
  for (; myDSIt.More(); myDSIt.Next()) {
    Standard_Boolean justaddinterference = Standard_True;
    myDSIt.Current(n1, n2, justaddinterference);

    if(justaddinterference) {
      if (!myIntrPool->IsComputed(n1, n2)) {

      if(n1 < n2) {
        nF1 = n1;
        nF2 = n2;
      }
      else {
        nF1 = n2;
        nF2 = n1;
      }
      //
      bIsFound=IsPairFound(nF1, nF2, myIntrPool, aMapWhat, aMapWith);
      //
      if (!bIsFound) {
        myIntrPool->AddInterference (nF1, nF2, BooleanOperations_SurfaceSurface, anIndexIn); 
      }
      else {
        IntTools_SequenceOfPntOn2Faces aPnts;
        IntTools_SequenceOfCurves aCvs;

        BOPTools_SSInterference anInterf (nF1, nF2, 1.e-07, 1.e-07, aCvs, aPnts);
        anIndexIn=aFFs.Append(anInterf);
        myIntrPool->AddInterference (nF1, nF2, BooleanOperations_SurfaceSurface, anIndexIn); 
      }
      }
      continue;
    }
    //
    if (myIntrPool->IsComputed(n1, n2)) {
      continue;
    }
    //
    nF1=n1; 
    nF2=n2; 
    if (nF1 > nF2) {
      Standard_Integer iTmp;
      iTmp=nF1;
      nF1=nF2;
      nF2=iTmp;
    }

//     const TopoDS_Face& aF1=TopoDS::Face(myDS->GetShape(nF1));
//     const TopoDS_Face& aF2=TopoDS::Face(myDS->GetShape(nF2));
    // modified by NIZHNY-MKK  Tue Oct 18 12:33:59 2005.BEGIN
    TopoDS_Face aF1=TopoDS::Face(myDS->GetShape(nF1));
    TopoDS_Face aF2=TopoDS::Face(myDS->GetShape(nF2));
    IntSurf_ListOfPntOn2S aListOfPnts;
    GeomAPI_ProjectPointOnSurf& aProj1 = myContext.ProjPS(aF1);
    GeomAPI_ProjectPointOnSurf& aProj2 = myContext.ProjPS(aF2);

    BOPTools_CArray1OfESInterference& aEFs=myIntrPool->ESInterferences();
    TColStd_MapOfInteger aMapEdgeIndex1, aMapEdgeIndex2;
    for(Standard_Integer fIt = 0; fIt < 2; fIt++) {
      Standard_Integer nF = (fIt == 0) ? nF1 : nF2;
      for(Standard_Integer sIt1 = 1; sIt1 <= myDS->NumberOfSuccessors(nF); sIt1++) {
      Standard_Integer nIndexS1 = myDS->GetSuccessor(nF, sIt1);
      if(myDS->GetShapeType(nIndexS1) == TopAbs_EDGE) {
        if(fIt == 0)
          aMapEdgeIndex1.Add(nIndexS1);
        else
          aMapEdgeIndex2.Add(nIndexS1);
      }
      else {
        for(Standard_Integer sIt2 = 1; sIt2 <= myDS->NumberOfSuccessors(nIndexS1); sIt2++) {
          Standard_Integer nIndexS2 = myDS->GetSuccessor(nIndexS1, sIt2);
          
          if(myDS->GetShapeType(nIndexS2) == TopAbs_EDGE) {
            if(fIt == 0)
            aMapEdgeIndex1.Add(nIndexS2);
            else
            aMapEdgeIndex2.Add(nIndexS2);
          }
        }
      }
      }
      
      TColStd_MapIteratorOfMapOfInteger anIt;
      if(fIt == 0)
      anIt.Initialize(aMapEdgeIndex1);
      else
      anIt.Initialize(aMapEdgeIndex2);

      Standard_Integer nFOpposite = (fIt == 0) ? nF2 : nF1;      

      for(; anIt.More(); anIt.Next()) {
      Standard_Integer nIndexE = anIt.Key();

      for(Standard_Integer interIt = 1; interIt <= aEFs.Length(); interIt++) {
        const BOPTools_ESInterference& aEF = aEFs(interIt);          

        if((aEF.Index1() == nIndexE) && (nFOpposite == aEF.Index2())) {
          IntTools_CommonPrt aCP = aEF.CommonPrt();

          if(aCP.Type() == TopAbs_VERTEX) {
            Standard_Real aPar = aCP.VertexParameter1();
            // compute points and add to the list
            Standard_Real f,l;
            Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(myDS->GetShape(nIndexE)), f,l);
            Handle(Geom2d_Curve) aPCurve;
            if(fIt == 0) {
            aPCurve = BRep_Tool::CurveOnSurface(TopoDS::Edge(myDS->GetShape(nIndexE)),
                                        aF1, f, l);
            }
            else {
            aPCurve = BRep_Tool::CurveOnSurface(TopoDS::Edge(myDS->GetShape(nIndexE)),
                                        aF2, f, l);
            }           
                                                       
            gp_Pnt aPoint;
            aCurve->D0(aPar, aPoint);
            Standard_Real U1,V1,U2,V2;
            IntSurf_PntOn2S aPnt;
            if(!aPCurve.IsNull()) {
            gp_Pnt2d aP2d = aPCurve->Value(aPar);
            if(fIt == 0) {
              aProj2.Perform(aPoint);
              if(aProj2.IsDone()) {
                aProj2.LowerDistanceParameters(U2,V2);
                aPnt.SetValue(aP2d.X(),aP2d.Y(),U2,V2);
                aListOfPnts.Append(aPnt); 
              }
            }
            else {
              aProj1.Perform(aPoint);
              if(aProj1.IsDone()) {
                aProj1.LowerDistanceParameters(U1,V1);
                aPnt.SetValue(U1,V1,aP2d.X(),aP2d.Y());
                aListOfPnts.Append(aPnt); 
              }
            }
            }              
            else {
            // modified by NIZHNY-AMV  Tue Oct 18 12:37:02 2005.BEGIN
            aProj1.Perform(aPoint);
            aProj2.Perform(aPoint);
            if(aProj1.IsDone() && aProj2.IsDone()){
              aProj1.LowerDistanceParameters(U1,V1);
              aProj2.LowerDistanceParameters(U2,V2);
              aPnt.SetValue(U1,V1,U2,V2);
              aListOfPnts.Append(aPnt);                
            }
            // modified by NIZHNY-AMV  Tue Oct 18 12:37:02 2005.END
            }
          }
        }
      }
      }
    }
    // modified by NIZHNY-MKK  Tue Oct 18 12:34:07 2005.END

    //
    // FF
    Standard_Boolean bToApproxC3d, bToApproxC2dOnS1, bToApproxC2dOnS2, bIsDone;
    Standard_Real anApproxTol, aTolR3D, aTolR2D;
    //
    bToApproxC3d     = mySectionAttribute.Approximation();
    bToApproxC2dOnS1 = mySectionAttribute.PCurveOnS1();
    bToApproxC2dOnS2 = mySectionAttribute.PCurveOnS2();
    //
    anApproxTol=1.e-7;

    IntTools_FaceFace aFF;
    aFF.SetParameters (bToApproxC3d, 
                   bToApproxC2dOnS1, 
                   bToApproxC2dOnS2,
                   anApproxTol);
    // modified by NIZHNY-AMV  Tue Oct 18 12:37:02 2005.BEGIN
    if (!aListOfPnts.IsEmpty())
      aFF.SetList(aListOfPnts);
    // modified by NIZHNY-AMV  Tue Oct 18 12:37:02 2005.END
    aFF.Perform(aF1, aF2);

    bIsDone=aFF.IsDone();

    if (bIsDone) {
      // Add Interference to the Pool
      aTolR3D=aFF.TolReached3d();
      aTolR2D=aFF.TolReached2d();
      if (aTolR3D < 1.e-7){
      aTolR3D=1.e-7;
      } 
      aFF.PrepareLines3D();
      //
      anIndexIn=0;
      Standard_Integer aNbCurves, aNbPoints;

      const IntTools_SequenceOfCurves& aCvs=aFF.Lines();
      aNbCurves=aCvs.Length();
      //
      const IntTools_SequenceOfPntOn2Faces& aPnts=aFF.Points();
      aNbPoints=aPnts.Length();
      
      if (!aNbCurves && !aNbPoints) {
      //
      bIsFound=IsPairFound(nF1, nF2, myIntrPool, aMapWhat, aMapWith);
      //
      if (!bIsFound) {
        myIntrPool->AddInterference (nF1, nF2, BooleanOperations_SurfaceSurface, anIndexIn); 
        continue;
      }
      }
      //
      BOPTools_SSInterference anInterf (nF1, nF2, aTolR3D, aTolR2D, aCvs, aPnts);
      anIndexIn=aFFs.Append(anInterf);
      
      myIntrPool->AddInterference (nF1, nF2, BooleanOperations_SurfaceSurface, anIndexIn);
    } //if (bIsDone)
    //
    else {
      anIndexIn=0;
      //
      bIsFound=IsPairFound(nF1, nF2, myIntrPool, aMapWhat, aMapWith);
      //
      if (!bIsFound) {
      myIntrPool->AddInterference (nF1, nF2, BooleanOperations_SurfaceSurface, anIndexIn); 
      }
      else {
      IntTools_SequenceOfPntOn2Faces aPnts;
      IntTools_SequenceOfCurves aCvs;
      
      BOPTools_SSInterference anInterf (nF1, nF2, 1.e-07, 1.e-07, aCvs, aPnts);
      anIndexIn=aFFs.Append(anInterf);
      myIntrPool->AddInterference (nF1, nF2, BooleanOperations_SurfaceSurface, anIndexIn);
      }
    }
  }// for (; myDSIt.More(); myDSIt.Next()) 
  myIsDone=Standard_True;
}
//=======================================================================
// function: MakeBlocks
// purpose: 
//=======================================================================
00446   void BOPTools_PaveFiller::MakeBlocks()
{
  Standard_Integer i, j, aNbCurves, aNbFFs, nF1, nF2, aBid=0, nV1, nV2;
  Standard_Real aTolR3D, aT1, aT2;
  Standard_Boolean bValid, bCoincide;

  BOPTools_CArray1OfSSInterference& aFFs=myIntrPool->SSInterferences();
  
  aNbFFs=aFFs.Extent();

  for (i=1; i<=aNbFFs; i++) {
    BOPTools_SSInterference& aFFi=aFFs(i);
    // 
    // Curves' tolerance
    aTolR3D=aFFi.TolR3D();
    //
    // Faces
    nF1=aFFi.Index1();
    nF2=aFFi.Index2();
    const TopoDS_Face& aF1=TopoDS::Face(myDS->GetShape(nF1));
    const TopoDS_Face& aF2=TopoDS::Face(myDS->GetShape(nF2));

    TColStd_MapOfInteger aMap;
    BOPTools_ListOfPaveBlock aLPB;
    SplitsInFace (aBid, nF1, nF2, aLPB);
    SplitsInFace (aBid, nF2, nF1, aLPB);
    SplitsOnFace (aBid, nF1, nF2, aLPB);
    
    BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPB);
    for (; anIt.More(); anIt.Next()) {
      const BOPTools_PaveBlock& aPB=anIt.Value();
      aFFi.AppendBlock(aPB);
      nV1=aPB.Pave1().Index();
      nV2=aPB.Pave2().Index();
      aMap.Add(nV1);
      aMap.Add(nV2);
    }
    // Put existing paves on curves
    //     BOPTools_PaveSet aPSF;
    //     PrepareSetForFace (nF1, nF2, aPSF);

    BOPTools_SequenceOfCurves& aSCvs = aFFi.Curves();
    aNbCurves=aSCvs.Length();

    // 
    // Pave Blocks On Curves
    // 
    Standard_Boolean bIsPaveBlock;
    Standard_Integer iCheckIntermediatePoint;
    // 
    for (j=1; j<=aNbCurves; j++) {
      BOPTools_Curve& aBC=aSCvs(j);
      const IntTools_Curve& aC= aBC.Curve();
      
      BOPTools_PaveSet& aPaveSet=aBC.Set();
      BOPTools_PaveBlockIterator aPBIter(0, aPaveSet);
      for (; aPBIter.More(); aPBIter.Next()) {
      BOPTools_PaveBlock& aPBNew=aPBIter.Value();
      aPBNew.SetCurve(aC);
      aPBNew.SetFace1(nF1);
      aPBNew.SetFace2(nF2);
      //
      nV1=aPBNew.Pave1().Index();
      nV2=aPBNew.Pave2().Index();
      
      if (aMap.Contains(nV1) && aMap.Contains(nV2)) {
        //
        const BOPTools_ListOfPaveBlock& aLPBExisting=aFFi.PaveBlocks();
        bIsPaveBlock=IsPaveBlock(nV1, nV2, aLPBExisting);
        //
        iCheckIntermediatePoint=1;
        if (bIsPaveBlock) {
          BOPTools_ListIteratorOfListOfPaveBlock anItLPB(aLPBExisting);
          
          for (; anItLPB.More(); anItLPB.Next()) {
            const BOPTools_PaveBlock& aPBR=anItLPB.Value();
            iCheckIntermediatePoint=
            CheckIntermediatePoint(aPBNew, aPBR, aTolR3D);
            if (!iCheckIntermediatePoint) {
            break;
            }
          }
          bIsPaveBlock=bIsPaveBlock && !iCheckIntermediatePoint;
        }
        //
        if (bIsPaveBlock) {
          continue;
        }
      }
      //
      else {
        iCheckIntermediatePoint=0;
      } 
      //
      aT1=aPBNew.Pave1().Param();
      aT2=aPBNew.Pave2().Param();
      // 
      if((nV1 == nV2) && (Abs(aT2 - aT1) < Precision::PConfusion())) {
          continue;
      }
      // 
      // Checking of validity in 2D
      //
      Standard_Real aTolerance = (aTolR3D < 1.e-3) ? 1.e-3 : aTolR3D;
      bValid=myContext.IsValidBlockForFaces(aT1, aT2, aC, aF1, aF2, aTolerance);
      //
      if (!bValid) {
        continue;
      }
      //
      // Checking the  paveblocks for coinsidence with aLPB
      bCoincide=CheckCoincidence (aPBNew, aFFi);
      //
      bCoincide=bCoincide && !iCheckIntermediatePoint;
      //
      if (bCoincide) {
        continue;
      }
      //
        // reject pave block (FF) v1==v2 for too small sect. edge
        TopoDS_Vertex aV1=TopoDS::Vertex(myDS->GetShape(nV1));
        TopoDS_Vertex aV2=TopoDS::Vertex(myDS->GetShape(nV2));
        Standard_Boolean rejectPaveBlock = Standard_False;
        if(aV1.IsSame(aV2)) {
          Standard_Real aRT = 1.e-7;
          rejectPaveBlock = RejectPaveBlock(aC,aT1,aT2,aV1,aRT);
          if(rejectPaveBlock) {
            if(aRT > 1.e-7) {
              BRep_Builder BB;
              BB.UpdateVertex( aV1, 2*aRT );
            }
            continue;
          }
        }
        // -&&
        //
      aBC.AppendNewBlock(aPBNew);
      }
    } // end of for (j=1; j<=aNbCurves; j++)
  }// end of for (i=1; i<=aNbFFs; i++)
}
//=======================================================================
// function: MakeAloneVertices
// purpose: 
//=======================================================================
00591   void BOPTools_PaveFiller::MakeAloneVertices()
{
  Standard_Integer i, j, k, aNbFFs, aNbCurves, nF1, nF2, nV, aNbAlone, aNbV;
  Standard_Boolean bFlag=Standard_False;

  BOPTools_ListIteratorOfListOfPave anIt;
  TColStd_IndexedMapOfInteger aMap;
  BOPTools_CArray1OfSSInterference& aFFs=myIntrPool->SSInterferences();
  
  aNbFFs=aFFs.Extent();
  for (i=1; i<=aNbFFs; i++) {
    BOPTools_SSInterference& aFFi=aFFs(i);

    const IntTools_SequenceOfPntOn2Faces& aSeqAlonePnts=aFFi.AlonePnts();
    aNbAlone=aSeqAlonePnts.Length();
    
    if (!aNbAlone) {
      continue;
    }

    nF1=aFFi.Index1();
    nF2=aFFi.Index2();

//     const TopoDS_Face& aF1=TopoDS::Face(myDS->Shape(nF1));
//     const TopoDS_Face& aF2=TopoDS::Face(myDS->Shape(nF2));
    TopoDS_Face aF1=TopoDS::Face(myDS->Shape(nF1));
    TopoDS_Face aF2=TopoDS::Face(myDS->Shape(nF2));
    // 
    // 1. fill aMap where all indices for (F/F) vertices are
    aMap.Clear();
    
    BOPTools_PaveSet aPSF;
    
    PrepareSetForFace (nF1, nF2, aPSF);
    const BOPTools_ListOfPave& aLPaves=aPSF.Set();
    anIt.Initialize(aLPaves);
    for (; anIt.More(); anIt.Next()) {
      const BOPTools_Pave& aPave=anIt.Value();
      nV=aPave.Index();
      aMap.Add(nV);
    }

    BOPTools_SequenceOfCurves& aSCvs=aFFi.Curves();
    aNbCurves=aSCvs.Length();
    for (j=1; j<=aNbCurves; j++) {
      BOPTools_Curve& aBC=aSCvs(j);
      const BOPTools_PaveSet& aCPSF=aBC.Set();
      const BOPTools_ListOfPave& aLPs=aCPSF.Set();
      anIt.Initialize(aLPs);
      for (; anIt.More(); anIt.Next()) {
      const BOPTools_Pave& aPv=anIt.Value();
      nV=aPv.Index();
      aMap.Add(nV);
      }
    }
    //
    // 2. check alone points on closure with aMap's vertices
    Standard_Integer iVV;
    Standard_Real aTolVAlone, aTolF1, aTolF2;
    TopoDS_Vertex aVAlone;
    BRep_Builder aBB;
    
    aTolF1=BRep_Tool::Tolerance(aF1);
    aTolF2=BRep_Tool::Tolerance(aF2);
    aTolVAlone=aTolF1+aTolF2;

    aNbV=aMap.Extent();
    for (j=1; j<=aNbAlone; ++j) {
      const IntTools_PntOn2Faces& aP2F=aSeqAlonePnts(j);
      const IntTools_PntOnFace& aPF1=aP2F.P1();
      const gp_Pnt& aPAlone=aPF1.Pnt();
      aBB.MakeVertex(aVAlone, aPAlone, aTolVAlone);
      //
      bFlag=Standard_True;
      //
      for (k=1; k<=aNbV; ++k) {
      nV=aMap(k);
      const TopoDS_Vertex& aV=TopoDS::Vertex(myDS->Shape(nV));
      
      iVV= IntTools_Tools::ComputeVV (aVAlone, aV);
      if (!iVV) {
        // It means that aVAlone and aV coinsided so 
        // we do not need to insert aVAlone into the DS
        bFlag=Standard_False;
        break;
      }
      
      }
      if (bFlag) {
      Standard_Boolean bVF;
      Standard_Integer aNewShape;
      //
      bVF=myContext.IsValidPointForFaces (aPAlone, aF1, aF2, 1.e-3);
      //
      if (bVF) {
        BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
        myDS->InsertShapeAndAncestorsSuccessors(aVAlone, anASSeq);
        aNewShape=myDS->NumberOfInsertedShapes();
        myDS->SetState (aNewShape, BooleanOperations_ON);
        //
        TColStd_ListOfInteger& anAloneVertices=aFFi.AloneVertices();
        anAloneVertices.Append(aNewShape);
      }
      }
    }
    
  }
}
//=======================================================================
// function: CheckCoincidence
// purpose: 
//=======================================================================
00703   Standard_Boolean BOPTools_PaveFiller::CheckCoincidence(const BOPTools_PaveBlock& aPB,
                                           const BOPTools_SSInterference& aFFi)
                                           
{
  Standard_Real aTolC, aTE, aT11, aT12;
  Standard_Integer nV11, nV12, nV21, nV22, iVV, iVE, nE2, iCount=0, iCountExt=1;
  Standard_Integer iV;

  aTolC=aFFi.TolR3D();
  // V11
  const BOPTools_Pave& aPave11=aPB.Pave1();
  nV11=aPave11.Index();
  const TopoDS_Vertex& aV11=TopoDS::Vertex(myDS->GetShape(nV11));
  aT11=aPave11.Param();
  // V12
  const BOPTools_Pave& aPave12=aPB.Pave2();
  nV12=aPave12.Index();
  const TopoDS_Vertex& aV12=TopoDS::Vertex(myDS->GetShape(nV12));
  aT12=aPave12.Param();
  //
  const BOPTools_ListOfPaveBlock& aLPB=aFFi.PaveBlocks();
  BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPB);
  for (; anIt.More(); anIt.Next()) {
    
    iCount=0;
    
    const BOPTools_PaveBlock& aPBR=anIt.Value();
    // V21
    const BOPTools_Pave& aPave21=aPBR.Pave1();
    nV21=aPave21.Index();
    const TopoDS_Vertex& aV21=TopoDS::Vertex(myDS->GetShape(nV21));
    // V22
    const BOPTools_Pave& aPave22=aPBR.Pave2();
    nV22=aPave22.Index();
    const TopoDS_Vertex& aV22=TopoDS::Vertex(myDS->GetShape(nV22));
    // E2
    nE2=aPBR.Edge();
    const TopoDS_Edge& aE2=TopoDS::Edge(myDS->GetShape(nE2));
    //
    // VV
    iV=0;
    iVV=IntTools_Tools::ComputeVV (aV11, aV21);
    if (!iVV) {
      iCount++;
      iV++;
      if (iCount>iCountExt) {
      break;
      }
    }
    
    iVV=IntTools_Tools::ComputeVV (aV11, aV22);
    if (!iVV) {
      iCount++;
      iV++;
      if (iCount>iCountExt) {
      break;
      }
    }

    // VE
    if (!iV) {
      iVE=myContext.ComputeVE (aV11, aE2, aTE);
      if (!iVE) {
      iCount++;
      if (iCount>iCountExt) {
        break;
      }
      }
    }
    //
    // VV
    iV=0;
    iVV=IntTools_Tools::ComputeVV (aV12, aV21);
    if (!iVV) {
      iCount++;
      iV++;
      if (iCount>iCountExt) {
      break;
      }
    }

    iVV=IntTools_Tools::ComputeVV (aV12, aV22);
    if (!iVV) {
      iCount++;
      iV++;
      if (iCount>iCountExt) {
      break;
      }
    }
    // VE
    if (!iV) {
      //
      iVE=myContext.ComputeVE (aV12, aE2, aTE);
      //
      if (!iVE) {
      iCount++;
      if (iCount>iCountExt) {
        break;
      }
      }
    }
    
  } // next aPBR
  return (iCount>iCountExt);
}
//=======================================================================
// function: CheckIntermediatePoint
// purpose: 
//=======================================================================
00812   Standard_Integer BOPTools_PaveFiller::CheckIntermediatePoint(const BOPTools_PaveBlock& aPB,
                                                 const BOPTools_PaveBlock& aPBR,
                                                 const Standard_Real aTolC)
                                           
{
  Standard_Real aT11, aT12, aTM, aTmp;
  Standard_Integer iVM, nE2;

  gp_Pnt aPM;
  BRep_Builder aBB;
  TopoDS_Vertex aVM;
  // 
  // Vertex
  const BOPTools_Pave& aPave11=aPB.Pave1();
  aT11=aPave11.Param();
  // 
  const BOPTools_Pave& aPave12=aPB.Pave2();
  aT12=aPave12.Param();
  //
  aTM=IntTools_Tools::IntermediatePoint (aT11, aT12);
  //
  const IntTools_Curve& aIC=aPB.Curve();
  aIC.D0(aTM, aPM);
  //
  aBB.MakeVertex (aVM, aPM, aTolC);
  //
  //Edge
  nE2=aPBR.Edge();
  const TopoDS_Edge& aE2=TopoDS::Edge(myDS->GetShape(nE2));
  // VE
  iVM=myContext.ComputeVE(aVM, aE2, aTmp); 
  //
  return iVM;
}
//=======================================================================
// function: PutBoundPaveOnCurve
// purpose: 
//=======================================================================
00850   void BOPTools_PaveFiller::PutBoundPaveOnCurve(BOPTools_Curve& aBC,
                                    BOPTools_SSInterference& aFFi)
{ 
  Standard_Boolean bHasBounds, bVF;
  

  const IntTools_Curve& aIC=aBC.Curve();
  bHasBounds=aIC.HasBounds ();
  
  if (!bHasBounds){
    return;
  }

  Standard_Integer nF1, nF2;
  Standard_Real aT1, aT2, aTolR3D;
  gp_Pnt aP1, aP2;
  //
  // Bounds
  aIC.Bounds (aT1, aT2, aP1, aP2);
  //
  // Faces
  nF1=aFFi.Index1();
  nF2=aFFi.Index2();
  //
  aTolR3D=aFFi.TolR3D();
  //
  TopoDS_Face aF1=TopoDS::Face(myDS->GetShape(nF1));
  TopoDS_Face aF2=TopoDS::Face(myDS->GetShape(nF2));
  //
  bVF=myContext.IsValidPointForFaces (aP1, aF1, aF2, aTolR3D);
  //
  if (bVF) {
    PutBoundPaveOnCurve (aP1, aT1, aBC, aFFi);
  }
  //
  bVF=myContext.IsValidPointForFaces (aP2, aF1, aF2, aTolR3D);
  //
  if (bVF) {
    PutBoundPaveOnCurve (aP2, aT2, aBC, aFFi);
  }
}
//=======================================================================
// function: PutBoundPaveOnCurve
// purpose: 
//=======================================================================
00895   void BOPTools_PaveFiller::PutBoundPaveOnCurve(const gp_Pnt& aP,
                                    const Standard_Real aT,
                                    BOPTools_Curve& aBC,
                                    BOPTools_SSInterference& aFFi)
{ 
  Standard_Boolean bFound1, bFound2;
  Standard_Integer nV;
  Standard_Real aTolV=aFFi.TolR3D();

  BOPTools_Pave aPave1, aPave2, aPave;
  BOPTools_PaveSet& aCPS=aBC.Set();
  BOPTools_PaveSet& aFFiPS=aFFi.NewPaveSet();
  const IntTools_Curve& aIC=aBC.Curve();

  bFound1=FindPave(aP, aTolV, aCPS  , aPave1);
  bFound2=FindPave(aP, aTolV, aFFiPS, aPave2);
  
  if (!bFound1 && !bFound2) {
    TopoDS_Vertex aNewVertex;
    BOPTools_Tools::MakeNewVertex(aP, aTolV, aNewVertex);
    //
    BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
    myDS->InsertShapeAndAncestorsSuccessors(aNewVertex, anASSeq);
    nV=myDS->NumberOfInsertedShapes();
    aPave.SetIndex(nV);
    aPave.SetParam(aT);

    aCPS.Append(aPave);
    aFFiPS.Append(aPave);
    //
    // Append Techno Vertex to the Curve
    TColStd_ListOfInteger& aTVs=aBC.TechnoVertices();
    aTVs.Append(nV);
  }
  
  if (bFound1 && !bFound2) {
    nV=aPave1.Index();
    aPave.SetIndex(nV);
    aPave.SetParam(aT);
    aFFiPS.Append(aPave);
    //
    const TopoDS_Vertex& aV=TopoDS::Vertex(myDS->Shape(nV));
    BOPTools_Tools::UpdateVertex (aIC, aT, aV);
  }
  
  if (!bFound1 && bFound2) {
    nV=aPave2.Index();
    aPave.SetIndex(nV);
    aPave.SetParam(aT);
    aCPS.Append(aPave);
    //
    const TopoDS_Vertex& aV=TopoDS::Vertex(myDS->Shape(nV));
    BOPTools_Tools::UpdateVertex (aIC, aT, aV);
  }
}

//=======================================================================
// function: PutBoundPaveOnCurveSpec
// purpose: 
//=======================================================================
00955   void BOPTools_PaveFiller::PutBoundPaveOnCurveSpec(BOPTools_Curve& aBC,
                                        BOPTools_SSInterference& aFFi)
{ 
  Standard_Boolean bHasBounds, bVF;
  

  const IntTools_Curve& aIC=aBC.Curve();
  bHasBounds=aIC.HasBounds ();
  
  if (!bHasBounds){
    return;
  }

  Standard_Integer nF1, nF2;
  Standard_Real aT1, aT2, aTolR3D;
  gp_Pnt aP1, aP2;
  //
  // Bounds
  aIC.Bounds (aT1, aT2, aP1, aP2);
  //
  // Faces
  nF1=aFFi.Index1();
  nF2=aFFi.Index2();
  //
  aTolR3D=aFFi.TolR3D();
  //
  TopoDS_Face aF1=TopoDS::Face(myDS->GetShape(nF1));
  TopoDS_Face aF2=TopoDS::Face(myDS->GetShape(nF2));
  //
  bVF=myContext.IsValidPointForFaces (aP1, aF1, aF2, aTolR3D);
  //
  if (bVF) {
    PutBoundPaveOnCurveSpec (aP1, aT1, aBC, aFFi);
  }
  //
  bVF=myContext.IsValidPointForFaces (aP2, aF1, aF2, aTolR3D);
  //
  if (bVF) {
    PutBoundPaveOnCurveSpec (aP2, aT2, aBC, aFFi);
  }
}
//=======================================================================
// function: PutBoundPaveOnCurveSpec
// purpose: 
//=======================================================================
01000   void BOPTools_PaveFiller::PutBoundPaveOnCurveSpec(const gp_Pnt& aP,
                                        const Standard_Real aT,
                                        BOPTools_Curve& aBC,
                                        BOPTools_SSInterference& aFFi)
{ 
  Standard_Boolean bFound1, bFound2;
  Standard_Integer nV;
  Standard_Real aTolV=aFFi.TolR3D();

  BOPTools_Pave aPave1, aPave2, aPave;
  BOPTools_PaveSet& aCPS=aBC.Set();
  BOPTools_PaveSet& aFFiPS=aFFi.NewPaveSet();
  const IntTools_Curve& aIC=aBC.Curve();

  bFound1=FindPave(aP, aTolV, aCPS  , aPave1);
  bFound2=FindPave(aP, aTolV, aFFiPS, aPave2);
  
  if (!bFound1 && !bFound2) {
    TopoDS_Vertex aNewVertex;
    BOPTools_Tools::MakeNewVertex(aP, aTolV, aNewVertex);
    //
    BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
    myDS->InsertShapeAndAncestorsSuccessors(aNewVertex, anASSeq);
    nV=myDS->NumberOfInsertedShapes();
    aPave.SetIndex(nV);
    aPave.SetParam(aT);

    aCPS.Append(aPave);
    aFFiPS.Append(aPave);
    //
    // Append Techno Vertex to the Curve
    TColStd_ListOfInteger& aTVs=aBC.TechnoVertices();
    aTVs.Append(nV);
    //
    //To check, if face boundary must be split by new vertex
    TopTools_MapOfShape aMap;
    Standard_Real aPar;
    Standard_Integer anErrStat;
    Standard_Integer aWhat, aWith, anIndexIn;
    BOPTools_CArray1OfVEInterference& aVEs=myIntrPool->VEInterferences();
    // Faces
    Standard_Integer nF1=aFFi.Index1();
    const TopoDS_Shape aF1 = myDS->GetShape(nF1);
    //
    Standard_Integer nF2=aFFi.Index2();
    const TopoDS_Shape aF2 = myDS->GetShape(nF2);
    //
    //
    Standard_Integer aRank = myDS->Rank(nF1);
    TopExp_Explorer anExp(aF1, TopAbs_EDGE);
    for(; anExp.More(); anExp.Next()) {

      const TopoDS_Shape& anE = anExp.Current();
      if (BRep_Tool::Degenerated(TopoDS::Edge(anE))){
      continue;
      }

      if(!aMap.Add(anE)) continue;

      anErrStat = 
      myContext.ComputeVE(aNewVertex, TopoDS::Edge(anE), aPar);
      if(anErrStat) continue;
      //
      Standard_Real aT1, aT2;
      gp_Pnt aP1, aP2;
      aIC.Bounds(aT1, aT2, aP1, aP2);
      //Check if any other point on curve belongs edge
      aT1 = 0.5*(aT1+aT2);
      aIC.D0(aT1, aP1);
      TopoDS_Vertex aNewVertex1;
      BOPTools_Tools::MakeNewVertex(aP1, aTolV, aNewVertex1);
      anErrStat = 
      myContext.ComputeVE(aNewVertex1, TopoDS::Edge(anE), aT1);
      if(!anErrStat) continue; //curve and edge seem to be coincide
      
      aWhat = nV;
      aWith = myDS->ShapeIndex(anE, aRank);
      BOPTools_VEInterference anInterf (aWhat, aWith, aPar);
      anIndexIn=aVEs.Append(anInterf);
      //
      // Add Pave to the Edge's myPavePool
      BOPTools_Pave aPave3(aWhat, aPar, BooleanOperations_VertexEdge);
      aPave3.SetInterference(anIndexIn);
      BOPTools_PaveSet& aPaveSet= myPavePool(myDS->RefEdge(aWith));
      aPaveSet.Append(aPave3);

      //
      // State for the Vertex in DS;
      myDS->SetState (aWhat, BooleanOperations_ON);
      // Insert Vertex in Interference Object
      BOPTools_VEInterference& aVE=aVEs(anIndexIn);
      aVE.SetNewShape(aWhat);

      PreparePaveBlocks(aWith);
      RecomputeCommonBlocks(aWith);
    }
    //
    aRank = myDS->Rank(nF2);
    anExp.Init(aF2, TopAbs_EDGE);
    for(; anExp.More(); anExp.Next()) {
      const TopoDS_Shape& anE = anExp.Current();
      if (BRep_Tool::Degenerated(TopoDS::Edge(anE))){
      continue;
      }

      if(!aMap.Add(anE)) continue;

      anErrStat = 
      myContext.ComputeVE(aNewVertex, TopoDS::Edge(anE), aPar);
      if(anErrStat) continue;
      //
      Standard_Real aT1, aT2;
      gp_Pnt aP1, aP2;
      aIC.Bounds(aT1, aT2, aP1, aP2);
      //Check if any other point on curve belongs edge
      aT1 = 0.5*(aT1+aT2);
      aIC.D0(aT1, aP1);
      TopoDS_Vertex aNewVertex1;
      BOPTools_Tools::MakeNewVertex(aP1, aTolV, aNewVertex1);
      anErrStat = 
      myContext.ComputeVE(aNewVertex1, TopoDS::Edge(anE), aT1);
      if(!anErrStat) continue; //curve and edge seem to be coincide
      
      aWhat = nV;
      aWith = myDS->ShapeIndex(anE, aRank);
      BOPTools_VEInterference anInterf (aWhat, aWith, aPar);
      anIndexIn=aVEs.Append(anInterf);
      //
      // Add Pave to the Edge's myPavePool
      BOPTools_Pave aPave3(aWhat, aPar, BooleanOperations_VertexEdge);
      aPave3.SetInterference(anIndexIn);
      BOPTools_PaveSet& aPaveSet= myPavePool(myDS->RefEdge(aWith));
      aPaveSet.Append(aPave3);

      //
      // State for the Vertex in DS;
      myDS->SetState (aWhat, BooleanOperations_ON);
      // Insert Vertex in Interference Object
      BOPTools_VEInterference& aVE=aVEs(anIndexIn);
      aVE.SetNewShape(aWhat);

      PreparePaveBlocks(aWith);
      RecomputeCommonBlocks(aWith);
    }
    //
  }
  
  if (bFound1 && !bFound2) {
    nV=aPave1.Index();
    aPave.SetIndex(nV);
    aPave.SetParam(aT);
    aFFiPS.Append(aPave);
    //
    const TopoDS_Vertex& aV=TopoDS::Vertex(myDS->Shape(nV));
    BOPTools_Tools::UpdateVertex (aIC, aT, aV);
  }
  
  if (!bFound1 && bFound2) {
    nV=aPave2.Index();
    aPave.SetIndex(nV);
    aPave.SetParam(aT);
    aCPS.Append(aPave);
    //
    const TopoDS_Vertex& aV=TopoDS::Vertex(myDS->Shape(nV));
    BOPTools_Tools::UpdateVertex (aIC, aT, aV);
  }
}
//=======================================================================
// function: FindPave
// purpose: 
//=======================================================================
01171   Standard_Boolean BOPTools_PaveFiller::FindPave(const gp_Pnt& aP,
                                     const Standard_Real aTolPV, 
                                     const BOPTools_PaveSet& aPS,
                                     BOPTools_Pave& aPave)
{
  Standard_Integer nV;
  Standard_Boolean bIsVertex=Standard_False;
 
  const BOPTools_ListOfPave& aLP=aPS.Set();
  BOPTools_ListIteratorOfListOfPave anIt(aLP);
  for (; anIt.More(); anIt.Next()) {
    const BOPTools_Pave& aPC=anIt.Value();
    nV=aPC.Index();
    const TopoDS_Vertex& aV=TopoDS::Vertex(myDS->GetShape(nV));
    bIsVertex=IntTools_Tools::IsVertex (aP, aTolPV, aV);
    if (bIsVertex) {
      aPave=aPC;
      return bIsVertex;
    }
  }
  return bIsVertex;
}
//=======================================================================
// function: MakeSectionEdges
// purpose: 
//=======================================================================
01197   void BOPTools_PaveFiller::MakeSectionEdges()
{
  Standard_Integer i, j, aNbCurves, aNbFFs, nF1, nF2, nV1, nV2, aNbPaveBlocks,
                   aNewShapeIndex ;
  Standard_Real    t1, t2;
  TopoDS_Edge aESect;
  TopoDS_Vertex aV1, aV2;
  BRep_Builder BB;

  Standard_Integer pbi = 0;


  BOPTools_CArray1OfSSInterference& aFFs=myIntrPool->SSInterferences();
  
  aNbFFs=aFFs.Extent();
  for (i=1; i<=aNbFFs; i++) {
    BOPTools_SSInterference& aFFi=aFFs(i);
    nF1=aFFi.Index1();
    nF2=aFFi.Index2();
    //
    Standard_Real aTF = 1.e-7;
    TopoDS_Face aF1=TopoDS::Face(myDS->GetShape(nF1));
    TopoDS_Face aF2=TopoDS::Face(myDS->GetShape(nF2));
    Standard_Boolean isModT = ModifFFTol(aF1,aF2,aTF);
    Standard_Real aTolFF = (isModT) ? Max(aTF,aFFi.TolR3D()) : aFFi.TolR3D();
    BOPTools_ListOfPaveBlock aFFPBL;
    TopTools_ListOfShape aFFSEL;
    //
    BOPTools_SequenceOfCurves& aSCvs=aFFi.Curves();
    aNbCurves=aSCvs.Length();
    for (j=1; j<=aNbCurves; j++) {
      BOPTools_Curve& aBC=aSCvs(j);
      const IntTools_Curve& aIC=aBC.Curve();
      //
      const BOPTools_ListOfPaveBlock& aSectEdges=aBC.NewPaveBlocks();
      aNbPaveBlocks=aSectEdges.Extent();
      BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSectEdges);
      pbi = 0;
      for (; aPBIt.More(); aPBIt.Next()) {
        pbi++;
      BOPTools_PaveBlock& aPB=aPBIt.Value();
      //
      // Pave1
      const BOPTools_Pave& aPave1=aPB.Pave1(); 
      nV1=aPave1.Index();
      t1=aPave1.Param();
      aV1=TopoDS::Vertex(myDS->GetShape(nV1));
      aV1.Orientation(TopAbs_FORWARD);
      //
      // Pave2
      const BOPTools_Pave& aPave2=aPB.Pave2();
      nV2=aPave2.Index();
      t2=aPave2.Param();
      aV2=TopoDS::Vertex(myDS->GetShape(nV2));
      aV2.Orientation(TopAbs_REVERSED);
      //
      // MakeSplitEdge
        //
        // reject building parallel sect. edge on the same pave block,
        //          if distance between created and this edges is too small
        if(IsPaveBlock(nV1,nV2,aFFPBL)) {
          Standard_Real diffTol = 1.e-7;
          Standard_Integer eI = RejectBuildingEdge(aIC,aV1,aV2,t1,t2,aFFSEL,diffTol);
          if(eI != 0) {
            Standard_Integer eIndex = 0;
            TopTools_ListIteratorOfListOfShape aSEIt(aFFSEL);
            for(; aSEIt.More(); aSEIt.Next()) {
              eIndex++;
              if(eIndex == eI) {
                const TopoDS_Edge & aE = TopoDS::Edge(aSEIt.Value());
                TopoDS_Edge& anEdge = (TopoDS_Edge &) aE;
                BOPTools_ListOfPaveBlock& aListPB = (BOPTools_ListOfPaveBlock&) aSectEdges;
                aListPB.Remove(aPBIt);
                BB.UpdateEdge( anEdge, 2*(aTolFF+diffTol) );
                BB.UpdateVertex( aV1, 2*(aTolFF+diffTol) );
                BB.UpdateVertex( aV2, 2*(aTolFF+diffTol) );
                break;
              }
            }
            if(aPBIt.More())
              continue;
            else
              break;
          }
        }
       
      if(fabs(t1-t2) <= 1.e-10) continue;
      BOPTools_Tools::MakeSectEdge (aIC, aV1, t1, aV2, t2, aESect);
      //
        BB.UpdateEdge( aESect, aTolFF );
      BB.UpdateVertex( aV1, aTolFF );
      BB.UpdateVertex( aV2, aTolFF );
      ///////////////////////////////////
      // Add Sect Part to the DS
      BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
      
      anASSeq.SetNewSuccessor(nV1);
      anASSeq.SetNewOrientation(aV1.Orientation());
      
      anASSeq.SetNewSuccessor(nV2);
      anASSeq.SetNewOrientation(aV2.Orientation());
      //
      myDS->InsertShapeAndAncestorsSuccessors(aESect, anASSeq);
      aNewShapeIndex=myDS->NumberOfInsertedShapes();
      //
      aPB.SetEdge(aNewShapeIndex);
      //
        aFFSEL.Append(aESect);
        aFFPBL.Append(aPB);
      }
    }
  }
  
}
//=======================================================================
// function: PutPaveOnCurve
// purpose: 
//=======================================================================
01315   void BOPTools_PaveFiller::PutPaveOnCurve(const BOPTools_PaveSet& aPaveSet,
                                 const Standard_Real aTolR3D,
                                 BOPTools_Curve& aBC)
{ 
  const BOPTools_ListOfPave& aLP=aPaveSet.Set();
  BOPTools_ListIteratorOfListOfPave anIt(aLP);
  for (; anIt.More(); anIt.Next()) {
    const BOPTools_Pave& aPave=anIt.Value();
    PutPaveOnCurve (aPave, aTolR3D, aBC);
  }
}
//=======================================================================
// function: PutPaveOnCurve
// purpose: 
//=======================================================================
01330   void BOPTools_PaveFiller::PutPaveOnCurve (const BOPTools_Pave& aPave,
                                  const Standard_Real aTolR3D,
                                  BOPTools_Curve& aBC)
{
  Standard_Integer nV;
  Standard_Boolean bIsVertexOnLine;
  Standard_Real aT, aTolVExt;
  

  nV=aPave.Index();
  const TopoDS_Vertex& aV=TopoDS::Vertex(myDS->Shape(nV));
  const IntTools_Curve& aC=aBC.Curve();
  Handle (Geom_Curve) aC3D= aC.Curve();
  //
  //modified by NIZNHY-PKV Tue Oct 19 11:11:40 2004 f
  aTolVExt=BRep_Tool::Tolerance(aV);
  ExtendedTolerance(nV, aTolVExt);
  bIsVertexOnLine=myContext.IsVertexOnLine(aV, aTolVExt, aC, aTolR3D, aT);
  //bIsVertexOnLine=myContext.IsVertexOnLine(aV, aC, aTolR3D, aT);
  //modified by NIZNHY-PKV Tue Oct 19 11:12:39 2004 t
  //
  if (bIsVertexOnLine) {
    BOPTools_Pave aPaveNew(nV, aT, BooleanOperations_SurfaceSurface);
    BOPTools_PaveSet& aPaveSet=aBC.Set();
    aPaveSet.Append(aPaveNew);
    //<-B
    BOPTools_Tools::UpdateVertex (aC, aT, aV);
  }
}
//
//modified by NIZNHY-PKV Tue Oct 19 11:36:34 2004 f
//=======================================================================
// function: ExtendedTolerance
// purpose: 
//=======================================================================
  Standard_Boolean BOPTools_PaveFiller::ExtendedTolerance(const Standard_Integer nV,
                                            Standard_Real& aTolVExt)
{
  Standard_Boolean bFound, bIsNewShape;
  Standard_Integer k, i, aNbLines, aNewShape;
  Standard_Real aT11, aT12, aD1, aD2, aD;
  TopoDS_Vertex aV;
  gp_Pnt aPV, aP11, aP12;
  //
  bFound=Standard_False;
  //
  bIsNewShape=myDS->IsNewShape(nV);
  if (!bIsNewShape) {
    return bFound;
  }
  //
  aV=TopoDS::Vertex(myDS->Shape(nV));
  aPV=BRep_Tool::Pnt(aV);
  //
  const BOPTools_InterferencePool& anInterferencePool=*myIntrPool;
  const BOPTools_CArray1OfEEInterference&  aEEInterfs=anInterferencePool.EEInterfs();
  const BOPTools_CArray1OfESInterference&  aESInterfs=anInterferencePool.ESInterfs();
  //
  for (k=0; k<2; ++k) {
    aNbLines=(!k) ? aEEInterfs.Extent() : aESInterfs.Extent();
    for (i=1; i<=aNbLines; ++i) {
      BOPTools_ShapeShapeInterference *pI=(!k) ? 
      (BOPTools_ShapeShapeInterference *)&aEEInterfs(i):
        (BOPTools_ShapeShapeInterference *)&aESInterfs(i);
      //
      aNewShape=pI->NewShape();
      if (aNewShape==nV) {
      const IntTools_CommonPrt& aCPart=(!k) ? 
        aEEInterfs(i).CommonPrt() : 
          aESInterfs(i).CommonPrt();
      //
      const TopoDS_Edge& aE1=aCPart.Edge1();
      aCPart.Range1(aT11, aT12);
      BOPTools_Tools::PointOnEdge(aE1, aT11, aP11);
      BOPTools_Tools::PointOnEdge(aE1, aT12, aP12);
      aD1=aPV.Distance(aP11);
      aD2=aPV.Distance(aP12);
      aD=(aD1>aD2)? aD1 : aD2;
      if (aD>aTolVExt) {
        aTolVExt=aD;
      }
      bFound=!bFound;
      return bFound;
      }
    }
  }
  //
  return bFound;
}
//modified by NIZNHY-PKV Tue Oct 19 11:36:40 2004 t
//
//=======================================================================
// function: PutPavesOnCurves
// purpose: 
//=======================================================================
  void BOPTools_PaveFiller::PutPavesOnCurves ()
{
  Standard_Integer i, j, aNbCurves, aNbFFs, nF1, nF2, nV;
  Standard_Real aTolR3D = 0.;

  BOPTools_CArray1OfSSInterference& aFFs=myIntrPool->SSInterferences();
  
  aNbFFs=aFFs.Extent();

  for (i=1; i<=aNbFFs; i++) {
    BOPTools_SSInterference& aFFi=aFFs(i);
    // 
    // Curves' tolerance
    aTolR3D=aFFi.TolR3D();
    //
    // Faces
    nF1=aFFi.Index1();
    nF2=aFFi.Index2();

    //
    // Put existing paves on curves
    BOPTools_PaveSet aPSF;
    PrepareSetForFace (nF1, nF2, aPSF);

    BOPTools_SequenceOfCurves& aSCvs=aFFi.Curves();
    aNbCurves=aSCvs.Length();
    for (j=1; j<=aNbCurves; j++) {
      BOPTools_Curve& aBC=aSCvs(j);
      // DEBUG
      const IntTools_Curve& aC=aBC.Curve();
      Handle (Geom_Curve) aC3D= aC.Curve();
      //
      PutPaveOnCurve (aPSF, aTolR3D, aBC);
    }

    //
    // Put bounding paves on curves
    //Check very specific case of cone-cone intersection (OCC13211)

    Standard_Boolean bIsSpecific = Standard_False;
    if(aNbCurves >= 4) {
      const TopoDS_Shape aF1 = myDS->GetShape(nF1);
      BRepAdaptor_Surface aS1(TopoDS::Face(aF1), Standard_False);
      GeomAbs_SurfaceType aSType = aS1.GetType();
      if(aSType == GeomAbs_Cone) {
      const TopoDS_Shape aF2 = myDS->GetShape(nF2);
      BRepAdaptor_Surface aS2(TopoDS::Face(aF2), Standard_False);
      aSType = aS2.GetType();
      if(aSType == GeomAbs_Cone) {
        bIsSpecific = Standard_True;
      }
      }
    }
    //
    if(bIsSpecific) {
      for (j=1; j<=aNbCurves; j++) {
      BOPTools_Curve& aBC=aSCvs(j);
      PutBoundPaveOnCurveSpec (aBC, aFFi);
      }
    }
    else {
      for (j=1; j<=aNbCurves; j++) {
      BOPTools_Curve& aBC=aSCvs(j);
      PutBoundPaveOnCurve (aBC, aFFi);
      }
    }
    //
    // xxx
    for (j=1; j<=aNbCurves; j++) {
      BOPTools_Curve& aBC=aSCvs(j);
      BOPTools_ListOfPave anOldList;
      anOldList = aBC.Set().Set();

//  Modified by skv - Mon Sep 26 14:58:30 2005 Begin
      if (aBC.NewPaveBlocks().IsEmpty())
      continue;
//  Modified by skv - Mon Sep 26 14:58:30 2005 End
      //
      
      BOPTools_CArray1OfESInterference& aESs = myIntrPool->ESInterferences();
      Standard_Integer k, fit;
      //
      // Among all aESs find those that are between nE1 from nF1(nE2 from nF2) and nF2(nF1)  
      for(k = 1; k <= aESs.Length(); k++) {
      BOPTools_ESInterference& aES = aESs(k);

      if(aES.Index1() == nF1 || aES.Index2() == nF2) {
        Standard_Integer nE = (aES.Index1() == nF1) ? aES.Index2() : aES.Index1();

        // check if it belongs to F1 or F2.begin
        Standard_Boolean edgefound = Standard_False;

        for(fit = 0; !edgefound && (fit < 2); fit++) {
          Standard_Integer nF = (fit == 0) ? nF1 : nF2;
          Standard_Integer sit1 = 0, sit2 = 0;

          for(sit1 = 1; !edgefound && (sit1 <= myDS->NumberOfSuccessors(nF)); sit1++) {
            Standard_Integer asuccessor = myDS->GetSuccessor(nF, sit1);

            for(sit2 = 1; sit2 <= myDS->NumberOfSuccessors(asuccessor); sit2++) {
            if(nE == myDS->GetSuccessor(asuccessor, sit2)) {
              edgefound = Standard_True;
              break;
            }
            }
          }
        }
        // check if it belongs to F1 or F2.end

        if(edgefound) {
          RestrictCurveIn2d (nE, nF1, nF2, aTolR3D, aBC);// ->
        }
      }
      }// for(k = 1; k <= aESs.Length(); k++) 

      for(fit = 1; fit <= 2; fit++) {
      Standard_Integer nF = (fit == 1) ? nF1 : nF2;
      Standard_Integer nFOpposite = (fit == 1) ? nF2 : nF1;
      TopExp_Explorer anExp(myDS->Shape(nF), TopAbs_EDGE);

      for(; anExp.More(); anExp.Next()) {
        Standard_Integer nE = myDS->ShapeIndex(anExp.Current(), fit);

        if(nE) {
          const BOPTools_ListOfInterference& aList =
            myIntrPool->InterferenceTable().Value(nE).GetOnType(BooleanOperations_EdgeSurface);
          BOPTools_ListIteratorOfListOfInterference anIt2(aList);
          Standard_Boolean bProcessed = Standard_False;

          for(; anIt2.More(); anIt2.Next()) {
            if(anIt2.Value().With() == nFOpposite) {
            if(!bProcessed) {
              RestrictCurveIn2d (nE, nF1, nF2, aTolR3D, aBC);
              bProcessed = Standard_True;
              break;
            }
            }
          }

          if(!myCommonBlockPool(myDS->RefEdge(nE)).IsEmpty() &&
             !bProcessed) {
            RestrictCurveIn2d (nE, nF1, nF2, aTolR3D, aBC);
          }
        }
      }
      }
      // end for(fit = 1...

      // put new paves on other curves.begin
      BOPTools_ListOfPave aListOfNewPave;
      BOPTools_ListIteratorOfListOfPave anIt1, anIt2;

      for(anIt1.Initialize(aBC.Set().Set()); anIt1.More(); anIt1.Next()) {
      Standard_Boolean bfound = Standard_False;
      for(anIt2.Initialize(anOldList); anIt2.More(); anIt2.Next()) {
        if(anIt1.Value().IsEqual(anIt2.Value())) {
          bfound = Standard_True;
          break;
        }
      }

      if(!bfound) {
        aListOfNewPave.Append(anIt1.Value());
      }
      }

      Standard_Integer m = 0, n = 0;
      for (m=1; m<=aNbFFs; m++) {
      BOPTools_SSInterference& aFFm = aFFs(m);
      // 
      // Curves' tolerance
      Standard_Real aTolR3D2 = aFFm.TolR3D();

      BOPTools_SequenceOfCurves& aSCvs2 = aFFm.Curves();
      Standard_Integer aNbCurves2 = aSCvs2.Length();

      for(n = 1; n <= aNbCurves2; n++) {
        if((n == j) && (m == i))
          continue;
        BOPTools_Curve& aBC2 = aSCvs2(n);

        for(anIt1.Initialize(aListOfNewPave); anIt1.More(); anIt1.Next()) {
          Standard_Boolean bfound = Standard_False;
          for(anIt2.Initialize(aBC2.Set().Set()); anIt2.More(); anIt2.Next()) {
            if(anIt1.Value().Index() == anIt2.Value().Index()) {
            bfound = Standard_True;
            break;
            }           
          }

          if(!bfound) {
            PutPaveOnCurve (anIt1.Value(), aTolR3D2, aBC2);
          }
        }
      }
      }
      // put new paves on other curves.end
    } // xxx for (j=1; j<=aNbCurves; j++)

    //wkar OCC334 f
    {
      Standard_Integer aNbVtx, jx;
      Standard_Real aTolVRange;
      TColStd_SequenceOfInteger aSeqVx;
      TColStd_SequenceOfReal    aSeqTolVx;
      //
      ProcessAloneStickVertices(nF1, nF2, aPSF, aSCvs, *myIntrPool, aSeqVx, aSeqTolVx);
      //
      aNbVtx=aSeqVx.Length();
      for (jx=1; jx<=aNbVtx; ++jx) {
      BOPTools_PaveSet aPSFx;
      BOPTools_Pave aPVx;

      nV=aSeqVx(jx);
      aTolVRange=aSeqTolVx(jx);
      
      aPVx.SetIndex(nV);
      aPSFx.Append(aPVx);

      for (j=1; j<=aNbCurves; j++) {
        BOPTools_Curve& aBC=aSCvs(j);
        // DEBUG
        const IntTools_Curve& aC=aBC.Curve();
        Handle (Geom_Curve) aC3D= aC.Curve();
        //
        PutPaveOnCurve (aPSFx, aTolVRange, aBC);
      }
      }
    }
    //wkar OCC334 t
  }
}
//=======================================================================
// function: PrepareSetForFace
// purpose: 
//=======================================================================
01661   void BOPTools_PaveFiller::PrepareSetForFace(const Standard_Integer nF1,
                                    const Standard_Integer nF2,
                                    BOPTools_PaveSet& aPaveSet)
{ 
  Standard_Integer i, aNbV, nV;
  TColStd_IndexedMapOfInteger aMV;
  //
  StickVertices(nF1, nF2, aMV);
  //
  aNbV=aMV.Extent();
  for (i=1; i<=aNbV; ++i) {
    nV=aMV(i);
    BOPTools_Pave aPV;
    aPV.SetIndex(nV);
    aPaveSet.Append(aPV);
  }
}
//=======================================================================
// function: IsPaveBlock
// purpose: 
//=======================================================================
Standard_Boolean IsPaveBlock(const Standard_Integer nV1,
                       const Standard_Integer nV2, 
                       const BOPTools_ListOfPaveBlock& aLPBExisting)
{
  Standard_Boolean bFlag=Standard_True;
  Standard_Integer nVE1, nVE2;

  BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPBExisting);
  for (; anIt.More(); anIt.Next()) {
    const BOPTools_PaveBlock& aPBR=anIt.Value();
    // 
    nVE1=aPBR.Pave1().Index();
    // 
    nVE2=aPBR.Pave2().Index();
    //
    if ((nVE1==nV1 && nVE2==nV2) || (nVE2==nV1 && nVE1==nV2)) {
      return bFlag;
    }
  }
   return !bFlag;
}

//=======================================================================
// function: FMapWhat
// purpose: 
//=======================================================================
  void FMapWhat(const Standard_Integer nF,
                BOPTools_InterferencePool* myIntrPool,
                TColStd_IndexedMapOfInteger& aMapWhat)
                
{
  Standard_Integer nE, nV;
 
  

  BooleanOperations_ShapesDataStructure* myDS=myIntrPool->DS();
  BooleanOperations_OnceExplorer aExp(*myDS);
  //
  //  What
  aMapWhat.Add(nF);
  aExp.Init(nF, TopAbs_VERTEX);
  for (; aExp.More(); aExp.Next()) {
    nV=aExp.Current();
    aMapWhat.Add(nV);
  }
  //
  aExp.Init(nF, TopAbs_EDGE);
  for (; aExp.More(); aExp.Next()) {
    nE=aExp.Current();
    aMapWhat.Add(nE);
  }
}

//=======================================================================
// function: FMapWith
// purpose: 
//=======================================================================
  void FMapWith(const Standard_Integer nF,
            BOPTools_InterferencePool* myIntrPool,
            TColStd_IndexedMapOfInteger& aMapWith)
{
  TColStd_IndexedMapOfInteger aMapWhat;
  
  FMapWhat(nF, myIntrPool, aMapWhat);
  //
  // With
  Standard_Integer i, aNb, anIndex, aWhat, aWith;
  BOPTools_ListIteratorOfListOfInterference anIt;
  
  const BOPTools_CArray1OfInterferenceLine& anArrIL= myIntrPool->InterferenceTable();

  aNb=aMapWhat.Extent();
  for (i=1; i<=aNb; i++) {
    aWhat=aMapWhat(i);
    
    const BOPTools_InterferenceLine& aWithLine=anArrIL(aWhat);
  
    const BOPTools_ListOfInterference& aLI=aWithLine.List();
    anIt.Initialize(aLI);
    for (; anIt.More(); anIt.Next()) {
      const BOPTools_Interference& anIntf=anIt.Value();
      anIndex=anIntf.Index();
      if (anIndex) {
      aWith=anIntf.With();
      aMapWith.Add(aWith);
      }
    }
  }
}

//=======================================================================
// function: IsFound
// purpose: 
//=======================================================================
Standard_Boolean IsFound(const TColStd_IndexedMapOfInteger& aMapWhat,
                   const TColStd_IndexedMapOfInteger& aMapWith)
{
  Standard_Boolean bFlag=Standard_False;
  Standard_Integer i, aNb, aWhat;

  aNb=aMapWhat.Extent();
  for (i=1; i<=aNb; i++) {
    aWhat=aMapWhat(i);
    if (aMapWith.Contains(aWhat)) {
      return !bFlag;
    }
  }
  return bFlag;
}


//wkar OCC334 f
#include <BOPTools_CArray1OfESInterference.hxx>
#include <BOPTools_CArray1OfEEInterference.hxx>
#include <BOPTools_ESInterference.hxx>
#include <BOPTools_EEInterference.hxx>
#include <IntTools_CommonPrt.hxx>
#include <gp_Pnt.hxx>
#include <Geom_Curve.hxx>
#include <GeomAbs_SurfaceType.hxx>
#include <Geom_Surface.hxx>
#include <GeomAdaptor_Surface.hxx>

//=======================================================================
// function: ProcessAloneStickVertices
// purpose: 
//=======================================================================
void ProcessAloneStickVertices(const Standard_Integer nF1,
                         const Standard_Integer nF2,
                         const BOPTools_PaveSet& aPSF,
                         BOPTools_SequenceOfCurves& aSCvs,
                         const BOPTools_InterferencePool& anIntrPool,
                         TColStd_SequenceOfInteger& aSeqVx,
                         TColStd_SequenceOfReal& aSeqTolVx)
{
  Standard_Boolean bFound;
  Standard_Integer aNbVtx, jx, nV;
  Standard_Real aTolVRange;
  TColStd_IndexedMapOfInteger aMapUnUsed;
  GeomAbs_SurfaceType aType1, aType2;
  //
  BooleanOperations_PShapesDataStructure pDS=anIntrPool.DS();
  //
  const TopoDS_Face& aF1= TopoDS::Face(pDS->Shape(nF1));
  const TopoDS_Face& aF2= TopoDS::Face(pDS->Shape(nF2));
  Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
  Handle(Geom_Surface) aS2=BRep_Tool::Surface(aF2);
  GeomAdaptor_Surface aGAS1(aS1);
  GeomAdaptor_Surface aGAS2(aS2);
  
  aType1=aGAS1.GetType();
  aType2=aGAS2.GetType();

  if((aType1==GeomAbs_Cylinder && aType2==GeomAbs_Cylinder) 
     ||
     (aType1==GeomAbs_Plane && aType2==GeomAbs_Plane)) {
    //
    UnUsedMap(aSCvs, aPSF, aMapUnUsed);
    // 
    aNbVtx=aMapUnUsed.Extent();
    for (jx=1; jx<=aNbVtx; ++jx) {
      nV=aMapUnUsed(jx);
      if (pDS->IsNewShape(nV)) {
      bFound=VertexRangeTolerance(nV, nF1, nF2, anIntrPool, aTolVRange);
      if (bFound) {
        aSeqVx.Append(nV);
        aSeqTolVx.Append(aTolVRange);
      }
      }
    }
  }
}
//=======================================================================
// function: UnUsedMap
// purpose: 
//=======================================================================
void UnUsedMap(BOPTools_SequenceOfCurves& aSCvs,
             const BOPTools_PaveSet& aPSF,
             TColStd_IndexedMapOfInteger& aMapUnUsed)
{
  //
  // What stick/non-stick vertices we used 
  TColStd_IndexedMapOfInteger aMapUsed, aMapMustBeUsed;
  Standard_Integer j, aNbCurves, aNbVtx, nV1;//, nV2;
  BOPTools_ListIteratorOfListOfPave anLPIt;

  aNbCurves=aSCvs.Length();
  for (j=1; j<=aNbCurves; ++j) {
    BOPTools_Curve& aBC=aSCvs(j);
    //const IntTools_Curve& aC= aBC.Curve();// Wng in Gcc 3.0
      
    const BOPTools_PaveSet& aPaveSet=aBC.Set();
    const BOPTools_ListOfPave& aLPAlreadyUsed=aPaveSet.Set();
    anLPIt.Initialize(aLPAlreadyUsed);
    for (; anLPIt.More(); anLPIt.Next()) {
      const BOPTools_Pave& aPave=anLPIt.Value();
      nV1=aPave.Index();
      aMapUsed.Add(nV1);
    }
  }
  // 
  // 2. Stick vertices that must be used
  const BOPTools_ListOfPave& aLPMustUsed=aPSF.Set();
  anLPIt.Initialize(aLPMustUsed);
  for (; anLPIt.More(); anLPIt.Next()) {
    const BOPTools_Pave& aPave=anLPIt.Value();
    nV1=aPave.Index();
    aMapMustBeUsed.Add(nV1);
  }
  //
  // 3.Unused Stick vertices .
  aNbVtx=aMapMustBeUsed.Extent();
  for (j=1; j<=aNbVtx; ++j) {
    nV1=aMapMustBeUsed(j);
    if (!aMapUsed.Contains(nV1)) {
      aMapUnUsed.Add(nV1);
    }
  }
  // 
}
//=======================================================================
// function: VertexRangeTolerance
// purpose: 
//=======================================================================
Standard_Boolean VertexRangeTolerance(const Standard_Integer nV,
                              const Standard_Integer nF1,
                              const Standard_Integer nF2,
                              const BOPTools_InterferencePool& anIntrPool,
                              Standard_Real& aTolV)
{
  Standard_Boolean bFound=Standard_False;
  Standard_Integer i, aNbEFs, iWhat, iWith, iNewShape ;
  TColStd_IndexedMapOfInteger aMEF;
  //
  BooleanOperations_PShapesDataStructure pDS=anIntrPool.DS();
  //
  const TopoDS_Vertex& aV=TopoDS::Vertex(pDS->Shape(nV));
  //
  FaceAndEdgeMap(nF1, anIntrPool, aMEF);
  FaceAndEdgeMap(nF2, anIntrPool, aMEF);
  //
  // EF Interferences
  const BOPTools_CArray1OfESInterference& aEFs=anIntrPool.ESInterfs();
  
  aNbEFs=aEFs.Extent();
  for (i=1; i<=aNbEFs; ++i) {
    const BOPTools_ESInterference& aEF=aEFs(i);
    iNewShape=aEF.NewShape();
    if (iNewShape==nV) {
      aEF.Indices(iWhat, iWith);
      if (aMEF.Contains(iWhat) && aMEF.Contains(iWith)) {
      //...
      Standard_Real aTolVWas, aD1, aD2, aDMax;
      gp_Pnt aP3DV, aP3DV1, aP3DV2;
      //
      const IntTools_CommonPrt& aCommonPrt=aEF.CommonPrt();
      //const TopoDS_Edge& aE1= aCommonPrt.Edge1();// Wng in Gcc 3.0
      
      aP3DV=BRep_Tool::Pnt(aV);
      aTolVWas=BRep_Tool::Tolerance(aV);
      
      aCommonPrt.BoundingPoints(aP3DV1, aP3DV2);
      aD1=aP3DV.Distance(aP3DV1);
      aD2=aP3DV.Distance(aP3DV2);
      
      aDMax=Max(aD1, aD2);

      aTolV=aTolVWas;
      if (aDMax>aTolVWas) {
        aTolV=aDMax;
      }
      return !bFound;
      }
    }
  }
  //
  // EE Interferences
  /*
  const BOPTools_CArray1OfEEInterference& aEEs=anIntrPool.EEInterfs();
  aNbEEs=aEEs.Extent();
  for (i=1; i<=aNbEEs; ++i) {
    const BOPTools_EEInterference& aEE=aEEs(i);
    iNewShape=aEE.NewShape();
    if (iNewShape==nV) {
      aEE.Indices(iWhat, iWith);
      if (aMEF.Contains(iWhat) && aMEF.Contains(iWith)) {
      //...
      aTolV=0.;
      return !bFound;
      }
    }
  }
  */
  //
  return bFound;
}

//=======================================================================
// function: FaceAndEdgeMap
// purpose: 
//=======================================================================
void FaceAndEdgeMap(const Standard_Integer nF,
                const BOPTools_InterferencePool& anIntrPool,
                TColStd_IndexedMapOfInteger& aMEF)
{
  Standard_Integer nEF;
  aMEF.Add(nF);
  BooleanOperations_PShapesDataStructure myDS=anIntrPool.DS();
  BooleanOperations_OnceExplorer aExp(*myDS);
  aExp.Init(nF, TopAbs_EDGE);
  for (; aExp.More(); aExp.Next()) {
    nEF=aExp.Current();
    aMEF.Add(nEF);
  }
}
//wkar OCC334 t

//=======================================================================
// function: IsPairFound
// purpose: 
//=======================================================================
Standard_Boolean IsPairFound(const Standard_Integer nF1,
                       const Standard_Integer nF2,
                       BOPTools_InterferencePool* myIntrPool,
                       BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& aMapWhat,
                       BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& aMapWith)
{
  Standard_Boolean bIsFound;
  //
  if (!aMapWhat.Contains(nF1)) {
    TColStd_IndexedMapOfInteger aMWhat;
    FMapWhat(nF1, myIntrPool, aMWhat);
    aMapWhat.Add(nF1, aMWhat);
  }
  //
  if (!aMapWith.Contains(nF2)) {
    TColStd_IndexedMapOfInteger aMWith;
    FMapWith(nF2, myIntrPool, aMWith);
    aMapWith.Add(nF2, aMWith);
  }
  //
  const TColStd_IndexedMapOfInteger& aMWht=aMapWhat.FindFromKey(nF1);
  const TColStd_IndexedMapOfInteger& aMWit=aMapWith.FindFromKey(nF2);
  //
  bIsFound=IsFound(aMWht, aMWit);
  //
  return bIsFound;
}

//=======================================================================
// function: RestrictCurveIn2d
// purpose:  Intersects 2d curve of edge nE and 2d curve of theBC.
//           Splits theBC by new vertex, also splits nE by new vertex.
//           If nE has same domain with another edge, the same domain 
//           edge is splitted too.
//=======================================================================
  void BOPTools_PaveFiller::RestrictCurveIn2d(const Standard_Integer nE,
                                    const Standard_Integer nF1,
                                    const Standard_Integer nF2,
                                    const Standard_Real    theTolerance,
                                    BOPTools_Curve&        theBC) 
{
  myPavePoolNew.Resize (myNbEdges);
  TopoDS_Shape atmpShape;
 
  BOPTools_CArray1OfESInterference& aESs = myIntrPool->ESInterferences();

  BOPTools_PaveSet& aPS = myPavePool(myDS->RefEdge(nE));
  Standard_Boolean bSearchInter = Standard_True;

  // 6841
  Standard_Integer pvVrtIndex = 0;
  //

  BOPTools_ListIteratorOfListOfPave anIt1(aPS.Set());
  BOPTools_ListIteratorOfListOfPave anIt2;

  for(; bSearchInter && anIt1.More(); anIt1.Next()) {

    for(anIt2.Initialize(theBC.Set().Set()); anIt2.More(); anIt2.Next()) {

      if(anIt1.Value().Index() == anIt2.Value().Index()) { // too hard condition for the algorithm
      // 6841
        pvVrtIndex = anIt1.Value().Index();
        //
      bSearchInter = Standard_False;
      break;
      }
    }
  }
  // -- 6841: test 2d intersection any way, but update vertex only
  if((!bSearchInter && pvVrtIndex != 0)) {
    Standard_Boolean OnFirst = (myDS->Rank(nE) == 1);
    TopoDS_Edge aE = TopoDS::Edge(myDS->Shape(nE));
    TopoDS_Face aF  = (OnFirst) ? TopoDS::Face(myDS->Shape(nF1)) : TopoDS::Face(myDS->Shape(nF2));
    Standard_Real pf2 = 0., pl2 = 0.;
    Handle(Geom_Curve)   aC2D3 = BRep_Tool::Curve(aE, pf2, pl2);
    Handle(Geom2d_Curve) aC2D2 = BRep_Tool::CurveOnSurface(aE, aF, pf2, pl2);
    Handle(Geom2d_Curve) aC1D2 = (OnFirst) ? theBC.Curve().FirstCurve2d() : theBC.Curve().SecondCurve2d();
    Handle(Geom_Curve)   aC1D3 = theBC.Curve().Curve();
    if((!aC2D3.IsNull() && !aC2D2.IsNull()) && (!aC1D2.IsNull() && !aC1D3.IsNull())) {
      Standard_Real pf1 = aC1D2->FirstParameter();
      Standard_Real pl1 = aC1D2->LastParameter();
      Geom2dAPI_InterCurveCurve aInt(aC1D2, aC2D2, Precision::PConfusion());
      if(aInt.NbPoints() > 0) {
        Standard_Integer jj = 1;
        for(; jj <= aInt.NbPoints(); jj++) {
          Standard_Real t1 = aInt.Intersector().Point(jj).ParamOnFirst();
          Standard_Real t2 = aInt.Intersector().Point(jj).ParamOnSecond();
          if((t1 >= pf1) && (t1 <= pl1) && (t2 >= pf2) && (t2 <= pl2)) {
//             gp_Pnt2d aP2d = aInt.Point(jj);
            gp_Pnt   aP3d = aC2D3->Value(t2);
            gp_Pnt   aP3d2 = aC1D3->Value(t1);
            TopoDS_Vertex & aVrt = (TopoDS_Vertex &) myDS->Shape(pvVrtIndex);
            gp_Pnt aVP = BRep_Tool::Pnt(aVrt);
            Standard_Real aVTol  = BRep_Tool::Tolerance(aVrt);
            Standard_Real aD1 = aP3d.Distance(aVP);
            Standard_Real aD2 = aP3d2.Distance(aVP);
            Standard_Real aFD1 = fabs(aVTol-aD1);
            Standard_Real aFD2 = fabs(aVTol-aD2);
            if(aD1 > aVTol || aD2 > aVTol) {
              if(Max(aFD1,aFD2) <= 1.e-2) {
                Standard_Real nTol = aVTol + 2. * Max(aFD1,aFD2) + 1.e-7;
                BRep_Builder bb;
                bb.UpdateVertex(aVrt, nTol);
              }
            }
          }
        }
      }
    }
  }
  //-- 6841

  if(bSearchInter) {
    // search intersection in 2d. begin
    BOPTools_ListOfPave aPavesOnCurve, aPavesOnEdge;
    Standard_Boolean bIsOnFirst = (myDS->Rank(nE) == 1);

    Handle(Geom2d_Curve) aC1 = (bIsOnFirst) ? theBC.Curve().FirstCurve2d() : theBC.Curve().SecondCurve2d();

    if(aC1.IsNull())
      return;
    Standard_Real f1 = aC1->FirstParameter();
    Standard_Real l1 = aC1->LastParameter();
    
    // f1 and l1 may not correspond 
    // to boundary parameters of 3d curve
    if(theBC.Curve().HasBounds()) {
      gp_Pnt tmpp1, tmpp2;
      theBC.Curve().Bounds(f1, l1, tmpp1, tmpp2);
    }

    atmpShape           = myDS->Shape(nE);
    TopoDS_Edge  anEdge = TopoDS::Edge(atmpShape);
    TopoDS_Shape aFace  = (bIsOnFirst) ? myDS->Shape(nF1) : myDS->Shape(nF2);
    Standard_Real f2=0., l2=0.;
    Handle(Geom2d_Curve) aC2 = BRep_Tool::CurveOnSurface(anEdge, TopoDS::Face(aFace), f2, l2);
    Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, f2, l2);

    if(aC2.IsNull() || aCurve.IsNull())
      return;

    Geom2dAPI_InterCurveCurve anIntersector(aC1, aC2, Precision::PConfusion());

    if(anIntersector.NbPoints() > 0) {
      Standard_Integer j = 0;

      for(j = 1; j <= anIntersector.NbPoints(); j++) {
      Standard_Real t1 = anIntersector.Intersector().Point(j).ParamOnFirst();
      Standard_Real t2 = anIntersector.Intersector().Point(j).ParamOnSecond();

      if((t1 >= f1) && (t1 <= l1) &&
         (t2 >= f2) && (t2 <= l2)) {
        gp_Pnt2d aP2dOnFace = anIntersector.Point(j);
        atmpShape  = (!bIsOnFirst) ? myDS->Shape(nF1) : myDS->Shape(nF2);
        TopoDS_Face anOtherFace = TopoDS::Face(atmpShape);
        gp_Pnt aP3d = aCurve->Value(t2);

        if(myContext.IsPointInOnFace(TopoDS::Face(aFace), aP2dOnFace) &&
           myContext.IsValidPointForFace(aP3d, anOtherFace, BRep_Tool::Tolerance(anEdge))) {
          BOPTools_Pave aPave1;
          aPave1.SetParam(t1);
          aPave1.SetIndex(-1);
          aPavesOnCurve.Append(aPave1);
          BOPTools_Pave aPave2;
          aPave2.SetParam(t2);
          aPave2.SetIndex(-1);
          aPavesOnEdge.Append(aPave2);
        }
      }
      }
    } // (anIntersector.NbPoints())
    // search intersection in 2d. end


    BOPTools_ListIteratorOfListOfPave aPaveIt1(aPavesOnCurve);
    BOPTools_ListIteratorOfListOfPave aPaveIt2(aPavesOnEdge);

    // test common blocks. begin
    Standard_Boolean bFaceCBFound = Standard_False;
    Standard_Boolean bEdgeCBFound = Standard_False;
    const BOPTools_ListOfCommonBlock& aLCBTest = myCommonBlockPool(myDS->RefEdge(nE));
    BOPTools_ListIteratorOfListOfCommonBlock aCBListIt(aLCBTest);
    Standard_Boolean bHasCBOnFace = Standard_False;
    Standard_Boolean bHasCBOnEdge = Standard_False;

    for(; aCBListIt.More(); aCBListIt.Next()) {
      if((aCBListIt.Value().Face() == nF1) ||
       (aCBListIt.Value().Face() == nF2)) {
      bHasCBOnFace = Standard_True;
      }

      if(aCBListIt.Value().Face() == 0) {
      bHasCBOnEdge = Standard_True;
      }
    }
    
    if(!bHasCBOnFace || !bHasCBOnEdge) {
      BOPTools_PaveSet aTestPaveSet;
      aTestPaveSet.ChangeSet() = aPS.Set();

      for(; aPaveIt2.More(); aPaveIt2.Next()) {
      aTestPaveSet.Append(aPaveIt2.Value());
      }
      BOPTools_PaveBlockIterator aPBIter(0, aTestPaveSet);

      for (; aPBIter.More(); aPBIter.Next()) {
      const BOPTools_PaveBlock& aPB = aPBIter.Value();
      Standard_Real aT1=aPB.Pave1().Param();
      Standard_Real aT2=aPB.Pave2().Param();
      gp_Pnt aPMid = aCurve->Value((aT1 + aT2) * 0.5);
      Standard_Integer nFOpposite = (bIsOnFirst) ? nF2 : nF1;
      TopoDS_Shape aOppFace = myDS->Shape(nFOpposite);

      if(!bHasCBOnFace && !bFaceCBFound &&
         myContext.IsValidPointForFace(aPMid, TopoDS::Face(aOppFace), 
                               BRep_Tool::Tolerance(anEdge) +
                               BRep_Tool::Tolerance(TopoDS::Face(aOppFace)))) {
        bFaceCBFound = Standard_True;
      }

      if(!bHasCBOnEdge && !bEdgeCBFound) {
        TopoDS_Vertex aVMid;
        BRep_Builder aBB;
        aBB.MakeVertex(aVMid, aPMid, BRep_Tool::Tolerance(anEdge));
        TopExp_Explorer anExpE(aOppFace, TopAbs_EDGE);

        for(; anExpE.More(); anExpE.Next()) {
          TopoDS_Shape aTmpEdge = anExpE.Current();
          Standard_Real aParameter = 0.;

          if(myContext.ComputeVE(aVMid, TopoDS::Edge(aTmpEdge), aParameter) == 0) {
            bEdgeCBFound = Standard_True;
            break;
          }
        }
      }
      }
      aPaveIt2.Initialize(aPavesOnEdge);
    }
    // test common blocks. end

    Standard_Boolean bChecknAddPaves = Standard_True;

    if(bEdgeCBFound) {
      bChecknAddPaves = Standard_False;
    }
    else {
      if(!bHasCBOnEdge) {
      bChecknAddPaves = !bFaceCBFound;
      }
    }

    if(bChecknAddPaves) {
      // add paves chaking if new pave is equal to existent. begin
      for(; aPaveIt1.More() && aPaveIt2.More(); aPaveIt1.Next(), aPaveIt2.Next()) {
      BOPTools_Pave& aPaveOnCurve = aPaveIt1.Value();
      BOPTools_Pave& aPaveOnEdge  = aPaveIt2.Value();

      gp_Pnt aP1 = theBC.Curve().Curve()->Value(aPaveOnCurve.Param());
      gp_Pnt aP2 = aCurve->Value(aPaveOnEdge.Param());

      Standard_Boolean bAddNewVertex = Standard_True;
      Standard_Boolean bAddOldVertex = Standard_False;
      Standard_Integer oldvertexindex = 0;

      for(anIt2.Initialize(theBC.Set().Set()); anIt2.More(); anIt2.Next()) {
        atmpShape = myDS->Shape(anIt2.Value().Index());
        TopoDS_Vertex aVertex = TopoDS::Vertex(atmpShape);
        gp_Pnt aPoint = BRep_Tool::Pnt(aVertex);
        Standard_Real aTolerance = theTolerance + BRep_Tool::Tolerance(aVertex);
        if((aPoint.Distance(aP1) < aTolerance) ||
           (aPoint.Distance(aP2) < aTolerance)) {
          bAddNewVertex = Standard_False;
          bAddOldVertex = Standard_True;
          oldvertexindex = anIt2.Value().Index(); 
          break;
        }
      }

      // treat equality with other vertices.begin
      if(bAddNewVertex || bAddOldVertex) {
        TopoDS_Vertex aNewVertex;
        BOPTools_Tools::MakeNewVertex(anEdge, aPaveOnEdge.Param(), 
                              TopoDS::Face(aFace),  aNewVertex);
        
        BOPTools_Pave aPaveToPut;
        Standard_Boolean bAddNewVertextmp = bAddNewVertex, bAddOldVertextmp = bAddOldVertex;

        if(!CheckNewVertexAndUpdateData(aNewVertex, aPaveOnEdge.Param(), anEdge, aPaveOnCurve.Param(), 
                                nF1, nF2, theTolerance, myIntrPool, myDS, &myContext, aPS, 
                                bAddNewVertextmp, bAddOldVertextmp, theBC, aPaveToPut, 
                                bAddNewVertex, bAddOldVertex)) {
          bAddNewVertex = Standard_False;
          bAddOldVertex = Standard_False;
        }
        else {
          if((aPaveToPut.Index() != 0) && (aPaveToPut.Param() != 0.) &&
             aPaveToPut.Interference() != 0) {
            PutPaveOnCurve(aPaveToPut, theTolerance, theBC);
          }
        }
        // end for(anIt1.Initialize...
      }
      // treat equality with other vertices.end
      
      if(bAddNewVertex || (bAddOldVertex && oldvertexindex)) {
        TopoDS_Vertex aNewVertex;

        Standard_Integer aNewShapeIndex = 0;
          
          // reject creation new vertex if there is a created one at a too small distance
          BOPTools_Tools::MakeNewVertex(anEdge,aPaveOnEdge.Param(),TopoDS::Face(aFace),aNewVertex);
          Standard_Real nvTol = BRep_Tool::Tolerance(aNewVertex);
          Standard_Integer chShNb = myDS->NumberOfInsertedShapes(), chShInd = 0;
          Standard_Boolean completeSearching = Standard_False;
          for(chShInd = 1; chShInd <= chShNb; chShInd++) {
            if(myDS->GetShapeType(chShInd) != TopAbs_VERTEX)
              continue;
            TopoDS_Vertex chV = TopoDS::Vertex(myDS->Shape(chShInd));
            Standard_Real distVV = BRep_Tool::Pnt(chV).Distance(BRep_Tool::Pnt(aNewVertex));
            if(distVV <= 1.e-5) {
              for(anIt1.Initialize(aPS.Set()); anIt1.More(); anIt1.Next()) {
                if(anIt1.Value().Index() == chShInd) {
                  Standard_Real dParam = fabs(aPaveOnEdge.Param()-anIt1.Value().Param());
                  if(dParam <= 1.e-7) {
                    bAddNewVertex = Standard_False;
                    bAddOldVertex = Standard_True;
                    oldvertexindex = anIt1.Value().Index();
                    nvTol += BRep_Tool::Tolerance(chV) + distVV;
                    completeSearching = Standard_True;
                    break;
                  }
                }
              }
            }
            if(completeSearching)
              break;
          }
          // -&&


        if(!bAddOldVertex) {
          BOPTools_Tools::MakeNewVertex(anEdge, aPaveOnEdge.Param(), 
                                TopoDS::Face(aFace),  aNewVertex);
          BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq; 
          myDS->InsertShapeAndAncestorsSuccessors(aNewVertex, anASSeq);
          aNewShapeIndex = myDS->NumberOfInsertedShapes();
        }
        else {
          aNewShapeIndex = oldvertexindex;
          aNewVertex = TopoDS::Vertex(myDS->Shape(aNewShapeIndex));
          BRep_Builder aBB;
          //
            aBB.UpdateVertex(aNewVertex, aPaveOnEdge.Param(), anEdge, nvTol);
        }

          BOPTools_ListIteratorOfListOfPave anItAll;
          Standard_Boolean samePFound = Standard_False;
          for(anItAll.Initialize(aPS.Set()); anItAll.More(); anItAll.Next()) {
            if(anItAll.Value().Index() == aNewShapeIndex) {
              BOPTools_Pave& aPV = anItAll.Value();
              aPV.SetParam(aPaveOnEdge.Param());
              samePFound = Standard_True; 
              break;
            }
          }
          if(samePFound)
            continue;


        myDS->SetState (aNewShapeIndex, BooleanOperations_ON);

        IntTools_CommonPrt aCPart;
        aCPart.SetEdge1(anEdge);
        aCPart.SetType(TopAbs_VERTEX);
        aCPart.SetRange1(IntTools_Range(aPaveOnEdge.Param(), aPaveOnEdge.Param()));
        aCPart.SetVertexParameter1(aPaveOnEdge.Param());

        Standard_Integer nFOpposite = (bIsOnFirst) ? nF2 : nF1;
        BOPTools_ESInterference anInterf (nE, nFOpposite, aCPart);
        Standard_Integer anIndexIn = aESs.Append(anInterf);
        myIntrPool->AddInterference (nE, nFOpposite, BooleanOperations_EdgeSurface, anIndexIn);

        BOPTools_ESInterference& aESInterf = aESs(anIndexIn);
        aESInterf.SetNewShape(aNewShapeIndex);

        // put pave on edge. begin 
        aPaveOnEdge.SetInterference(anIndexIn);
        aPaveOnEdge.SetType (BooleanOperations_EdgeSurface);
        aPaveOnEdge.SetIndex(aNewShapeIndex);

        BOPTools_PaveSet& aPaveSet1 = myPavePoolNew(myDS->RefEdge(nE));
        aPaveSet1.Append(aPaveOnEdge);
        // put pave on edge. end

        // put pave on curve. begin 
        aPaveOnCurve.SetIndex(aNewShapeIndex);
        aPaveOnCurve.SetType(BooleanOperations_SurfaceSurface);
        BOPTools_PaveSet& aPaveSet = theBC.Set();
        aPaveSet.Append(aPaveOnCurve);

        BOPTools_Tools::UpdateVertex (theBC.Curve(), aPaveOnCurve.Param(), aNewVertex);

        // put pave on curve. end

        BOPTools_ListOfCommonBlock& aLCB1 = myCommonBlockPool(myDS->RefEdge(nE));

        BOPTools_ListIteratorOfListOfCommonBlock  anIt(aLCB1);

        for(; anIt.More(); anIt.Next()) {
          BOPTools_CommonBlock& aCB = anIt.Value();

          if(aCB.Face()) {
            continue;
          }

          Standard_Integer anOppIndex = aCB.PaveBlock2().OriginalEdge();
          IntTools_Range aRange = aCB.PaveBlock2().Range();

          if(anOppIndex == nE) {
            anOppIndex = aCB.PaveBlock1().OriginalEdge();
            aRange = aCB.PaveBlock1().Range();
          }
          TopoDS_Edge anOppEdge = TopoDS::Edge(myDS->Shape(anOppIndex));
          Standard_Real aOppParameter = 0.;

          if(myContext.ComputeVE(aNewVertex, anOppEdge, aOppParameter) == 0) {
          
            if((aOppParameter > aRange.First()) && (aOppParameter < aRange.Last())) {
            // put pave on same domain edge. begin
            BRep_Builder aBB;
            aBB.UpdateVertex(aNewVertex, aOppParameter, anOppEdge, BRep_Tool::Tolerance(aNewVertex));
            BOPTools_Pave aPaveOpp;
            aPaveOpp.SetParam(aOppParameter);
            aPaveOpp.SetIndex(aNewShapeIndex);
            BOPTools_PaveSet& aPaveSetOpp = myPavePoolNew(myDS->RefEdge(anOppIndex));
            aPaveSetOpp.Append(aPaveOpp);
            // put pave on same domain edge. end
            }
          }
        }

          // add SS interference for adjacent face.begin
        if(aLCB1.IsEmpty()) {
          AddInterfForAdjacentFace(nE, nF1, nF2, myIntrPool, myDS);
        }
        // add SS interference for adjacent face.end

        RefinePavePool();
        myPavePoolNew.Resize(myNbEdges);
        //

        RecomputeCommonBlocks(nE);

      }
      } // end for(; aPaveIt1.More() && aPaveIt2.More()...
      // add paves chaking if new pave is equal to existent. end
    }
  } //(bSearchInter)
  myPavePoolNew.Destroy();
}
//=======================================================================
//function : RecomputeCommonBlocks
//purpose  : 
//=======================================================================
  void BOPTools_PaveFiller::RecomputeCommonBlocks(const Standard_Integer nE) 
{
  TopoDS_Shape atmpShape = myDS->Shape(nE);
  TopoDS_Edge  anEdge   = TopoDS::Edge(atmpShape);
  BOPTools_ListOfCommonBlock& aLCB1 = myCommonBlockPool(myDS->RefEdge(nE));

  BOPTools_ListOfCommonBlock anOldLCB;
  anOldLCB = aLCB1;
  aLCB1.Clear();
  BOPTools_ListOfCommonBlock aNewLCB1;
  Standard_Boolean bReverse = Standard_False;
  BOPTools_ListIteratorOfListOfCommonBlock  anIt(anOldLCB);

  for(; anIt.More(); anIt.Next()) {
    BOPTools_CommonBlock& anOldCB = anIt.Value();

    Standard_Integer anIndex = anOldCB.PaveBlock1().OriginalEdge();
    Standard_Integer anIndexOpp = anOldCB.PaveBlock2().OriginalEdge();
    IntTools_Range aCBRange = anOldCB.PaveBlock1().Range();

    if(anIndex != nE) {
      aCBRange = anOldCB.PaveBlock2().Range();
      anIndex = anOldCB.PaveBlock2().OriginalEdge();
      anIndexOpp = anOldCB.PaveBlock1().OriginalEdge();
      bReverse = Standard_True;
    }

    BOPTools_ListOfPaveBlock& aSplitEdges1 = mySplitShapesPool(myDS->RefEdge(nE));
    BOPTools_ListIteratorOfListOfPaveBlock aLPBIt1(aSplitEdges1);
    Standard_Boolean found = Standard_False;
    BOPTools_ListOfCommonBlock aNewListOfCommonBlock;

    for(; aLPBIt1.More(); aLPBIt1.Next()) {
      BOPTools_PaveBlock& aPBCurrent1 = aLPBIt1.Value();
      IntTools_Range aCurRange1 = aPBCurrent1.Range();

      if((aCurRange1.First() > aCBRange.First() && aCurRange1.First() < aCBRange.Last()) ||
       (aCurRange1.Last() > aCBRange.First() && aCurRange1.Last() < aCBRange.Last())) {
      BOPTools_CommonBlock aNewCB;

      if(!bReverse)
        aNewCB.SetPaveBlock1(aPBCurrent1);
      else
        aNewCB.SetPaveBlock2(aPBCurrent1);

      Standard_Boolean foundpaveblock2 = Standard_False;

      if(anOldCB.Face()) {
        foundpaveblock2 = Standard_True;
        aNewCB.SetFace(anOldCB.Face());
      }
      else {
        if(anIndexOpp <= 0)
          continue;
        BOPTools_ListIteratorOfListOfPaveBlock aLPBIt2(mySplitShapesPool(myDS->RefEdge(anIndexOpp)));

        for(; aLPBIt2.More(); aLPBIt2.Next()) {
          BOPTools_PaveBlock& aPBCurrent2 = aLPBIt2.Value();
          IntTools_Range aCurRange2 = aPBCurrent2.Range();

          if(((aPBCurrent1.Pave1().Index() == aPBCurrent2.Pave1().Index()) && 
            (aPBCurrent1.Pave2().Index() == aPBCurrent2.Pave2().Index())) ||
             ((aPBCurrent1.Pave1().Index() == aPBCurrent2.Pave2().Index()) && 
            (aPBCurrent1.Pave2().Index() == aPBCurrent2.Pave1().Index()))) {
            Standard_Real f = 0., l = 0.;
            Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, f, l);
            Standard_Real aMidPar = (aCurRange1.First() + aCurRange1.Last()) * 0.5;
            gp_Pnt aMidPnt = aCurve->Value(aMidPar);
            Standard_Real aProjPar = 0.;
            TopoDS_Vertex aTestpVertex;
            TopoDS_Edge aOppEdge = TopoDS::Edge(myDS->Shape(anIndexOpp));
            BRep_Builder aBB;
            aBB.MakeVertex(aTestpVertex, aMidPnt, BRep_Tool::Tolerance(anEdge));

            if(myContext.ComputeVE(aTestpVertex, aOppEdge, aProjPar) == 0) {
            if(aProjPar > aCurRange2.First() && aProjPar < aCurRange2.Last()) {
              if(!bReverse)
                aNewCB.SetPaveBlock2(aPBCurrent2);
              else
                aNewCB.SetPaveBlock1(aPBCurrent2);
              foundpaveblock2 = Standard_True;
              break;
            }
            }
          }
        }
      }

      if(foundpaveblock2) {
        found = Standard_True;
        aNewListOfCommonBlock.Append(aNewCB);
      }
      }
    }
    // end for(; aLPBIt1.More()...

    if(!found) {
      aNewLCB1.Append(anOldCB);
    }
    else {
      BOPTools_ListOfCommonBlock tmplst;
      tmplst = aNewListOfCommonBlock;
      aNewLCB1.Append(tmplst);

      if((anOldCB.Face() == 0) && (anIndexOpp > 0)) {
      tmplst = aNewListOfCommonBlock;
      BOPTools_ListOfCommonBlock& aLCB2 = myCommonBlockPool(myDS->RefEdge(anIndexOpp));

      BOPTools_ListIteratorOfListOfCommonBlock anItLCB2(aLCB2);

      for(; anItLCB2.More(); anItLCB2.Next()) {
        BOPTools_CommonBlock& anOldCB2 = anItLCB2.Value();

        if(anOldCB2.Face())
          continue;

        if(anOldCB.PaveBlock1().IsEqual(anOldCB2.PaveBlock1()) &&
           anOldCB.PaveBlock2().IsEqual(anOldCB2.PaveBlock2())) {
          aLCB2.Remove(anItLCB2);
          aLCB2.Append(tmplst);
          break;
        }
      }
      }
    }
  }
  // end for(; anIt.More()...
  aLCB1 = aNewLCB1;
}
//=======================================================================
//function : CheckNewVertexAndUpdateData
//purpose  : 
//=======================================================================
Standard_Boolean CheckNewVertexAndUpdateData(const TopoDS_Vertex&              theVertex,
                                   const Standard_Real               theParamOnE,
                                   const TopoDS_Edge&                theEdge,
                                   const Standard_Real               theParamOnCurve,
                                   const Standard_Integer            theIndexF1,
                                   const Standard_Integer            theIndexF2,
                                   const Standard_Real               theTolerance,
                                   const BOPTools_PInterferencePool& theIntrPool,
                                   const BooleanOperations_PShapesDataStructure& theDS,
                                   IntTools_Context*                 theContext,
                                   const BOPTools_PaveSet&           theEdgePaveSet,
                                   const Standard_Boolean            bAddNewVertex,
                                   const Standard_Boolean            bAddOldVertex,
                                   BOPTools_Curve&                   theBC,
                                   BOPTools_Pave&                    thePaveToPut,
                                   Standard_Boolean&                 bAddNewVertexOut,
                                   Standard_Boolean&                 bAddOldVertexOut) {

  thePaveToPut.SetParam(0.);
  thePaveToPut.SetIndex(0);
  thePaveToPut.SetInterference(0);

  bAddNewVertexOut = bAddNewVertex;
  bAddOldVertexOut = bAddOldVertex;
  TopoDS_Shape atmpShape;
  gp_Pnt aP1 = theBC.Curve().Curve()->Value(theParamOnCurve);
  Standard_Real f = 0., l = 0.;
  Handle(Geom_Curve) aCurve = BRep_Tool::Curve(theEdge, f, l);

  if(aCurve.IsNull())
    return Standard_False;
  gp_Pnt aP2 = aCurve->Value(theParamOnE);

  BOPTools_ListIteratorOfListOfPave anIt1, anIt2;

  for(anIt1.Initialize(theEdgePaveSet.Set()); anIt1.More(); anIt1.Next()) {
    atmpShape = theDS->Shape(anIt1.Value().Index());
    TopoDS_Vertex aVertex = TopoDS::Vertex(atmpShape);
    gp_Pnt aPoint = BRep_Tool::Pnt(aVertex);
    Standard_Real aTolerance = theTolerance + BRep_Tool::Tolerance(aVertex);
    aTolerance *= 4.;

    if((aPoint.Distance(aP1) < aTolerance) ||
       (aPoint.Distance(aP2) < aTolerance)) {
      IntTools_Range aRange(anIt1.Value().Param(), theParamOnE);
      TopoDS_Vertex aV1 = aVertex;
      TopoDS_Vertex aV2 = theVertex;

      if(anIt1.Value().Param() > theParamOnE) {
      aRange.SetFirst(theParamOnE);
      aRange.SetLast(anIt1.Value().Param());
      aV1 = theVertex;
      aV2 = aVertex;
      }
      gp_Pnt ptest1 = aCurve->Value(aRange.First());
      gp_Pnt ptest2 = aCurve->Value(aRange.Last());
      Standard_Boolean bUpdateVertex = Standard_True;

      if(ptest1.Distance(ptest2) > (BRep_Tool::Tolerance(aVertex) + BRep_Tool::Tolerance(theEdge))) {
      IntTools_ShrunkRange aSR (theEdge, aV1, aV2, aRange, *theContext);
      bUpdateVertex = !aSR.IsDone() || (aSR.ErrorStatus() != 0);
      }

      if(bUpdateVertex) {
      bAddNewVertexOut = Standard_False;
            
      if(bAddOldVertexOut) {
        bAddOldVertexOut = Standard_False;
        break;
      }
      BOPTools_Tools::UpdateVertex (theBC.Curve(), theParamOnCurve, aVertex);

      Standard_Boolean bPutPave = Standard_True;

      for(anIt2.Initialize(theBC.Set().Set()); anIt2.More(); anIt2.Next()) {
        if(anIt1.Value().Index() == anIt2.Value().Index()) {
          bPutPave = Standard_False;
          break;
        }
      }

      Standard_Integer nbbefore = theBC.Set().Set().Extent();

      if(bPutPave) {
        thePaveToPut = anIt1.Value();
      }

      if(anIt1.Value().Index() > theDS->NumberOfSourceShapes())
        break;

      Standard_Integer nbafter = theBC.Set().Set().Extent();

      if(nbbefore < nbafter) {
        // update interferences.begin
        Standard_Integer nF = theIndexF1;

        if(theDS->Rank(anIt1.Value().Index()) != theDS->Rank(theIndexF1)) {
          nF = theIndexF2;
        }
        atmpShape = theDS->Shape(nF);
        TopoDS_Face   aF = TopoDS::Face  (atmpShape);
        BOPTools_CArray1OfVSInterference& aVSs = theIntrPool->VSInterferences();
        Standard_Integer vsit = 0;
        Standard_Boolean interffound = Standard_False;

        for(vsit = 1; vsit <= aVSs.Length(); vsit++) {
          if((aVSs.Value(vsit).Index1() == anIt1.Value().Index()) &&
             (aVSs.Value(vsit).Index2() == nF)) {
            interffound = Standard_True;
            break;
          }
        }

        if(!interffound) {
          BOPTools_CArray1OfVEInterference& aVEs = theIntrPool->VEInterferences();

          for(vsit = 1; vsit <= aVEs.Length(); vsit++) {
            if((aVEs.Value(vsit).Index1() == anIt1.Value().Index())) {
            interffound = Standard_True;
            break;
            }
          }
        }

        if(!interffound) {
          BOPTools_CArray1OfVVInterference& aVVs = theIntrPool->VVInterferences();

          for(vsit = 1; vsit <= aVVs.Length(); vsit++) {
            if((aVVs.Value(vsit).Index1() == anIt1.Value().Index())) {
            interffound = Standard_True;
            break;
            }
          }
        }

        if(!interffound) {
          Standard_Real aU = 0., aV = 0.;
          Standard_Integer aFlag = theContext->ComputeVS (aVertex, aF, aU, aV);
          Standard_Integer anIndexIn = 0;

          if (!aFlag) {
            //
            // Add Interference to the Pool
            BOPTools_VSInterference anInterf (anIt1.Value().Index(), nF, aU, aV);
            anIndexIn=aVSs.Append(anInterf);
            //
            // SetState for Vertex in DS;
            theDS->SetState (anIt1.Value().Index(), BooleanOperations_ON);
            // Insert Vertex in Interference Object
            BOPTools_VSInterference& aVS = aVSs(anIndexIn);
            aVS.SetNewShape(anIt1.Value().Index());

            interffound = Standard_False;
            const BOPTools_ListOfInterference& aList1 =
            theIntrPool->InterferenceTable().Value(anIt1.Value().Index()).GetOnType(BooleanOperations_EdgeSurface);
            BOPTools_ListOfInterference& amodifList1 = *((BOPTools_ListOfInterference*)&aList1); // not very good approach
            BOPTools_ListIteratorOfListOfInterference anInterfIt(amodifList1);

            for(; anInterfIt.More(); anInterfIt.Next()) {
            if(anInterfIt.Value().With() == nF) {
              anInterfIt.Value().SetIndex(anIndexIn);
              interffound = Standard_True;
            }
            }
            const BOPTools_ListOfInterference& aList2 =
            theIntrPool->InterferenceTable().Value(nF).GetOnType(BooleanOperations_EdgeSurface);
            BOPTools_ListOfInterference& amodifList2 = *((BOPTools_ListOfInterference*)&aList2); // not very good approach
            anInterfIt.Initialize(amodifList2);

            for(; anInterfIt.More(); anInterfIt.Next()) {
            if(anInterfIt.Value().With() == anIt1.Value().Index()) {
              anInterfIt.Value().SetIndex(anIndexIn);
              interffound = Standard_True;
            }
            }
                  
            if(!interffound)
            theIntrPool->AddInterference(anIt1.Value().Index(), nF, BooleanOperations_VertexSurface, anIndexIn);
          }
        }
        // update interferences.end
      }
      break;
      }
    }
  }
  // end for(anIt1.Initialize...
  return Standard_True;
}
//=======================================================================
//function : AddInterfForAdjacentFace
//purpose  : 
//=======================================================================
void AddInterfForAdjacentFace(const Standard_Integer            theEdgeIndex,
                        const Standard_Integer            theIndexF1,
                        const Standard_Integer            theIndexF2,
                        BOPTools_PInterferencePool        theIntrPool,
                        const BooleanOperations_PShapesDataStructure& theDS) {
  Standard_Boolean bIsOnFirst = (theDS->Rank(theEdgeIndex) == 1);

  IntTools_SequenceOfPntOn2Faces aPnts;
  IntTools_SequenceOfCurves aCvs;
  Standard_Integer index1 = (bIsOnFirst) ? theIndexF1 : theIndexF2;
  Standard_Integer index2 = (bIsOnFirst) ? theIndexF2 : theIndexF1;
  Standard_Integer nbw = theDS->NumberOfAncestors(theEdgeIndex);
  Standard_Integer ancwit = 0, ancfit = 0;
  Standard_Boolean badjacentfound = Standard_False;

  for(ancwit = 1; (!badjacentfound) && (ancwit <= nbw); ancwit++) {
    Standard_Integer ancestor1 = theDS->GetAncestor(theEdgeIndex, ancwit);

    if(ancestor1 == index1)
      continue;

    if(theDS->GetShapeType(ancestor1) == TopAbs_WIRE) {
      Standard_Integer nbf = theDS->NumberOfAncestors(ancestor1);

      for(ancfit = 1; ancfit <= nbf; ancfit++) {
      Standard_Integer ancestor2 = theDS->GetAncestor(ancestor1, ancfit);

      if(ancestor2 != index1) {
        index1 = ancestor2;
        badjacentfound = Standard_True;
        break;
      }
      }
    }
  }

  if(index1 > index2) {
    Standard_Integer tmp = index1;
    index1 = index2;
    index2 = tmp;
  }
  Standard_Boolean bAddInterference = Standard_True;
  Standard_Integer ffit = 0;
  BOPTools_CArray1OfSSInterference& aFFs = theIntrPool->SSInterferences();

  for(ffit = 1; ffit <= aFFs.Extent(); ffit++) {
    BOPTools_SSInterference& aFFi3 = aFFs(ffit);

    if((index1 == aFFi3.Index1()) && (index2 == aFFi3.Index2())) {
      bAddInterference = Standard_False;
    }
  }

  if(bAddInterference) {
    BOPTools_SSInterference anInterfSS (index1, index2, 1.e-07, 1.e-07, aCvs, aPnts);
    Standard_Integer anIndexInSS = aFFs.Append(anInterfSS);
    theIntrPool->AddInterference (index1, index2, BooleanOperations_SurfaceSurface, anIndexInSS); 
  }
}

//=======================================================================
//function : RejectPaveBlock
//purpose  : 
//=======================================================================
Standard_Boolean RejectPaveBlock(const IntTools_Curve& theC,
                                 const Standard_Real   theT1,
                                 const Standard_Real   theT2,
                                 const TopoDS_Vertex&  theV,
                                 Standard_Real&        theRT)
{
  theRT = BRep_Tool::Tolerance(theV);
  Handle(Geom_Curve) aC = theC.Curve();
 
  Standard_Real pf = aC->FirstParameter();
  Standard_Real pl = aC->LastParameter();
  Standard_Real dp = fabs(pl-pf);
  Standard_Boolean isp = (aC->IsPeriodic() && fabs(aC->Period()-dp) <= 1.e-9);
  Standard_Real dt = fabs(theT2-theT1);
  isp = (isp || (aC->IsPeriodic() && fabs(aC->Period()-dt) <= 1.e-9));
  Standard_Boolean c3d = (aC->IsClosed() || isp);
  
  if(c3d)
    return Standard_False;

  Standard_Real p1 = Max(pf,theT1);
  Standard_Real p2 = Min(pl,theT2);
  if(p2 != p1) {
    if(p2 < p1) {
      Standard_Real tp = p1; p1 = p2; p2 = tp;
    }
    gp_Pnt pntf, pntl;
    aC->D0(p1,pntf);
    aC->D0(p2,pntl);
    Standard_Real d3d = pntf.Distance(pntl);
    if(d3d > theRT)
      theRT = d3d;
  }
  return Standard_True;
}

//=======================================================================
//function : ModifFFTol
//purpose  : 
//=======================================================================
Standard_Boolean ModifFFTol(const TopoDS_Face& theF1,
                            const TopoDS_Face& theF2,
                            Standard_Real&     theTF)
{
  Standard_Real t1 = BRep_Tool::Tolerance(theF1), t2 = BRep_Tool::Tolerance(theF2);
  theTF = 2* (t1 + t2);
  BRepAdaptor_Surface BAS1(theF1);
  BRepAdaptor_Surface BAS2(theF2);
  Standard_Boolean isAna1 = (BAS1.GetType() == GeomAbs_Plane ||
                             BAS1.GetType() == GeomAbs_Cylinder ||
                             BAS1.GetType() == GeomAbs_Cone ||
                             BAS1.GetType() == GeomAbs_Sphere);
  Standard_Boolean isAna2 = (BAS2.GetType() == GeomAbs_Plane ||
                             BAS2.GetType() == GeomAbs_Cylinder ||
                             BAS2.GetType() == GeomAbs_Cone ||
                             BAS2.GetType() == GeomAbs_Sphere);

  if(isAna1 && isAna2)
    return Standard_False;

  theTF = Max(theTF, 5.e-6);
  return Standard_True;
}


//=======================================================================
//function : RejectBuildingEdge
//purpose  : 
//=======================================================================
Standard_Integer RejectBuildingEdge(const IntTools_Curve& theC,
                                    const TopoDS_Vertex&  theV1,
                                    const TopoDS_Vertex&  theV2,
                                    const Standard_Real   theT1,
                                    const Standard_Real   theT2,
                                    const TopTools_ListOfShape& theL,
                                    Standard_Real&        theTF)
{
  theTF = 1.e-7;
  if(theL.Extent() == 0)
    return 0;

  Handle(Geom_Curve) aTCurve;
  Standard_Real aTT;
  
  Standard_Integer eIndex = 0;
  Standard_Boolean edgeFound = Standard_False;
  Handle(Geom_Curve) aCurve = theC.Curve();
  TopTools_ListIteratorOfListOfShape anIt(theL);
  for(; anIt.More(); anIt.Next()) {
    eIndex++;
    const TopoDS_Edge & aE = TopoDS::Edge(anIt.Value());
    if(aE.IsNull()) continue;
    TopExp_Explorer ee(aE,TopAbs_VERTEX);
    Standard_Boolean v1Found = Standard_False;
    Standard_Boolean v2Found = Standard_False;
    Standard_Real v1P = 0., v2P = 0;
    for(; ee.More(); ee.Next()) {
      const TopoDS_Vertex aV = TopoDS::Vertex(ee.Current());
      if(aV.IsNull()) continue;
      if(aV.IsEqual(theV1)) {
        v1Found = Standard_True;
        v1P = BRep_Tool::Parameter(aV,aE);
      }
      if(aV.IsEqual(theV2)) {
        v2Found = Standard_True;
        v2P = BRep_Tool::Parameter(aV,aE);
      }
    }
    Standard_Boolean sameParam = Standard_False;
    if(v1Found && v2Found) {
      if(fabs(theT1-v1P) <= 1.e-8 && fabs(theT2-v2P) <= 1.e-8)
        sameParam = Standard_True;
    }
    if(sameParam) {
      Standard_Real f,l;
      aTCurve = BRep_Tool::Curve(aE,f,l);
      aTT = BRep_Tool::Tolerance(aE);
      edgeFound = Standard_True;
    }
    if(edgeFound)
      break;
  }

  if(!edgeFound)
    return 0;

  gp_Pnt p1 = aTCurve->Value(theT1);
  gp_Pnt p2 = aCurve->Value(theT1);
  Standard_Real dpf = p1.Distance(p2);
  p1 = aTCurve->Value(theT2);
  p2 = aCurve->Value(theT2);
  Standard_Real dpl = p1.Distance(p2);
  Standard_Real dplf = fabs(dpl-dpf);
  Standard_Real dpp = Max(dpl,dpf);

  if(dplf > 1.e-7)
    return 0;

  Standard_Real maxD = Max(dpl,dpf);
  Standard_Boolean inTol = Standard_True;
  Standard_Real dp = fabs(theT2-theT1)/23.;
  Standard_Integer di = 0;
  for(di = 1; di <= 21; di++) {
    Standard_Real cp = theT1 + dp*((Standard_Real)di);
    p1 = aTCurve->Value(cp);
    p2 = aCurve->Value(cp);
    Standard_Real d12 = p1.Distance(p2);
    maxD = Max(maxD,d12);
    if(fabs(d12-dpp) > 1.e-7) {
      inTol = Standard_False;
      break;
    }
  }

  if(!inTol)
    return 0;

  theTF = maxD;
  return eIndex;
}

Generated by  Doxygen 1.6.0   Back to index