//=======================================================================
// function: SplitIndex
// purpose:
//=======================================================================
Standard_Integer NMTTools_PaveFiller::SplitIndex
  (const BOPTools_PaveBlock& aPBx) const
{
  Standard_Integer anOriginalEdge, anEdgeIndex=0;

  anOriginalEdge=aPBx.OriginalEdge();

  const BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(anOriginalEdge));
  //
  BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPB);
  for (; anIt.More(); anIt.Next()) {
    BOPTools_PaveBlock& aPB=anIt.Value();
    if (aPB.IsEqual(aPBx)) {
      anEdgeIndex=aPB.Edge();
      return anEdgeIndex;
    }
  }
  return anEdgeIndex;
}
//=======================================================================
// function: PreparePaveBlocks
// purpose: 
//=======================================================================
  void NMTTools_CheckerSI::PreparePaveBlocks(const Standard_Integer nE)
{
  myIsDone=Standard_False;
  //
  // char buf[32]={"SR"};
  Standard_Boolean bIsValid;
  Standard_Integer nV1, nV2, iErr;
  Standard_Real aT1, aT2;
  TopoDS_Edge aE;
  TopoDS_Vertex aV1, aV2;
  //
  BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(nE));
  // Edge 
  aE=TopoDS::Edge(myDS->Shape(nE));
  if (BRep_Tool::Degenerated(aE)) {
    myIsDone=Standard_True;
    return;
  }
  //
  BOPTools_PaveSet& aPS=myPavePool(myDS->RefEdge(nE));
  
  BOPTools_PaveBlockIterator aPBIt(nE, aPS);
  for (; aPBIt.More(); aPBIt.Next()) {
    BOPTools_PaveBlock& aPB=aPBIt.Value();
    const IntTools_Range& aRange=aPB.Range();
    //
    const BOPTools_Pave& aPave1=aPB.Pave1();
    nV1=aPave1.Index();
    aV1=TopoDS::Vertex(myDS->Shape(nV1));
    aT1=aPave1.Param();
    //
    const BOPTools_Pave& aPave2=aPB.Pave2();
    nV2=aPave2.Index();
    aV2=TopoDS::Vertex(myDS->Shape(nV2)); 
    aT2=aPave2.Param();
    //
    bIsValid=Standard_True;
    if (nV1==nV2) {
      bIsValid=IsValid(aE, aV1, aT1, aT2);
      if (!bIsValid) {
	//printf(" pb SR: nV    nE: %d  nV1:( %d %15.10lf ) nV2:( %d %15.10lf )\n", nE, nV1, aT1, nV2, aT2);
	myStopStatus=1;
      }
    }
    //
    IntTools_ShrunkRange aSR (aE, aV1, aV2, aRange, myContext);
    iErr=aSR.ErrorStatus();
    if (!aSR.IsDone()) {
      //printf(" pb SR: Done  nE: %d  nV1:( %d %15.10lf ) nV2:( %d %15.10lf )\n", nE, nV1, aT1, nV2, aT2);
      aSR.SetShrunkRange(aRange);
      //throw BOPTColStd_Failure(buf) ;
    }
    else if (iErr!=6) {
      CorrectShrunkRanges (0, aPave1, aSR);
      CorrectShrunkRanges (1, aPave2, aSR);
    }
    aPB.SetShrunkRange(aSR);
    aLPB.Append(aPB);
  } //for (; aPBIt.More(); aPBIt.Next()) 
  myIsDone=Standard_True;
}
//=======================================================================
// function: MakeSplitEdges
// purpose:
//=======================================================================
void NMTTools_PaveFiller::MakeSplitEdges()
{
  myIsDone=Standard_False;
  //
  Standard_Boolean bIsNewVertex1, bIsNewVertex2;
  Standard_Integer i, aNbS, nV1, nV2, aNbPaveBlocks, aNewShapeIndex;
  Standard_Real    t1, t2;
  TopAbs_Orientation anOri;
  TopoDS_Edge aE, aESplit;
  TopoDS_Vertex aV1, aV2;
  //
  aNbS=myDS->NumberOfShapesOfTheObject();
  for (i=1; i<=aNbS; ++i) {
    if (myDS->GetShapeType(i) != TopAbs_EDGE)
      continue;
    //
    // Original Edge
    aE=TopoDS::Edge(myDS->Shape(i));
    if (BRep_Tool::Degenerated(aE)){
      continue;
    }
    //
    anOri=aE.Orientation();
    aE.Orientation(TopAbs_FORWARD);
    //
    // Making Split Edges
    //
    // Split Set for the Original Edge i
    BOPTools_ListOfPaveBlock& aSplitEdges=mySplitShapesPool(myDS->RefEdge(i));
    BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSplitEdges);
    //
    aNbPaveBlocks=aSplitEdges.Extent();

    for (; aPBIt.More(); aPBIt.Next()) {
      BOPTools_PaveBlock& aPB=aPBIt.Value();
      // aPave1
      const BOPTools_Pave& aPave1=aPB.Pave1();
      nV1=aPave1.Index();
      t1=aPave1.Param();
      aV1=TopoDS::Vertex(myDS->GetShape(nV1));
      aV1.Orientation(TopAbs_FORWARD);
      // aPave2
      const BOPTools_Pave& aPave2=aPB.Pave2();
      nV2=aPave2.Index();
      t2=aPave2.Param();
      aV2=TopoDS::Vertex(myDS->GetShape(nV2));
      aV2.Orientation(TopAbs_REVERSED);
      //xx
      if (aNbPaveBlocks==1) {
        bIsNewVertex1=myDS->IsNewShape (nV1);
        bIsNewVertex2=myDS->IsNewShape (nV2);
        if (!bIsNewVertex1 && !bIsNewVertex2) {
          aPB.SetEdge(i);
          continue;
        }
      }
      //xx
      BOPTools_Tools::MakeSplitEdge(aE, aV1, t1, aV2, t2, aESplit);
      //
      // Add Split Part of the Original Edge to the DS
      BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;

      anASSeq.SetNewSuccessor(nV1);
      anASSeq.SetNewOrientation(aV1.Orientation());

      anASSeq.SetNewSuccessor(nV2);
      anASSeq.SetNewOrientation(aV2.Orientation());
      //
      if (anOri==TopAbs_INTERNAL) {
        anASSeq.SetNewAncestor(i);
        aESplit.Orientation(anOri);
      }
      //
      myDS->InsertShapeAndAncestorsSuccessors(aESplit, anASSeq);
      aNewShapeIndex=myDS->NumberOfInsertedShapes();
      myDS->SetState(aNewShapeIndex, BooleanOperations_UNKNOWN);
      //
      // Fill Split Set for the Original Edge
      aPB.SetEdge(aNewShapeIndex);
      //
    }
  }
  myIsDone=Standard_True;
}
//=======================================================================
// function: UpdatePaveBlocks
// purpose:
//=======================================================================
void NMTTools_PaveFiller::UpdatePaveBlocks()
{
  myIsDone=Standard_False;
  //
  Standard_Integer i, aNbFFs, nF1, nF2, aNbF, nF, iRankF, nE, nV1, nV2, aNbPB;
  Standard_Real aT1, aT2;
  TColStd_IndexedMapOfInteger aMF, aME;
  TopExp_Explorer aExp;
  TopoDS_Vertex aV1, aV2;
  TopoDS_Edge aE;
  BOPTools_Pave aPave1, aPave2;
  BOPTools_PaveBlock aPB;
  //
  BOPTools_CArray1OfSSInterference& aFFs=myIP->SSInterferences();
  //
  aNbFFs=aFFs.Extent();
  for (i=1; i<=aNbFFs; ++i) {
    BOPTools_SSInterference& aFFi=aFFs(i);
    aFFi.Indices(nF1, nF2);
    aMF.Add(nF1);
    aMF.Add(nF2);
  }
  //
  aNbF=aMF.Extent();
  for(i=1; i<=aNbF; ++i) {
    nF=aMF(i);
    iRankF=myDS->Rank(nF);
    const TopoDS_Shape aF=myDS->Shape(nF);//mpv
    aExp.Init(aF, TopAbs_EDGE);
    for(; aExp.More();  aExp.Next()) {
      aE=TopoDS::Edge(aExp.Current());
      //
      if (BRep_Tool::Degenerated(aE)) {
        continue;
      }
      //
      nE=myDS->ShapeIndex(aE, iRankF);
      //
      if (aME.Contains(nE)) {
        continue;
      }
      aME.Add(nE);
      //
      BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(nE));
      aNbPB=aLPB.Extent();
      if (aNbPB) {
        continue;
      }
      TopExp::Vertices(aE, aV1, aV2);
      //
      nV1=myDS->ShapeIndex(aV1, iRankF);
      aT1=BRep_Tool::Parameter(aV1, aE);
      aPave1.SetIndex(nV1);
      aPave1.SetParam(aT1);
      //
      nV2=myDS->ShapeIndex(aV2, iRankF);
      aT2=BRep_Tool::Parameter(aV2, aE);
      aPave2.SetIndex(nV2);
      aPave2.SetParam(aT2);
      //
      aPB.SetEdge(nE);
      aPB.SetOriginalEdge(nE);
      aPB.SetPave1(aPave1);
      aPB.SetPave2(aPave2);
      //
      aLPB.Append(aPB);
    }
  }
}
//=======================================================================
// function: UpdateCommonBlocks
// purpose:
//=======================================================================
void NMTTools_PaveFiller::UpdateCommonBlocks()
{
  myIsDone=Standard_False;
  //
  Standard_Integer nE, aNbS,  nSp, nEx, nSpx;
  NMTTools_ListIteratorOfListOfCommonBlock aCBIt;
  BOPTools_ListIteratorOfListOfPaveBlock aPBIt;
  //
  aNbS=myDS->NumberOfShapesOfTheObject();
  //
  for (nE=1; nE<=aNbS; ++nE) {
    if (myDS->GetShapeType(nE)!=TopAbs_EDGE){
      continue;
    }
    if (BRep_Tool::Degenerated(TopoDS::Edge(myDS->Shape(nE)))){
      continue;
    }
    //
    NMTTools_ListOfCommonBlock& aLCB=myCommonBlockPool(myDS->RefEdge(nE));
    /*BOPTools_ListOfPaveBlock& aLPB=*/mySplitShapesPool  (myDS->RefEdge(nE));
    //
    aCBIt.Initialize(aLCB);
    for (; aCBIt.More(); aCBIt.Next()) {
      NMTTools_CommonBlock& aCB=aCBIt.ChangeValue();
      //
      // Among all PBs of aCB the first PB will be one
      // that have max tolerance value
      {
        Standard_Real aTolEx, aTolExMax;
        BOPTools_ListOfPaveBlock *pLPB, aLPBx;
        //
        aTolExMax=-1.;
        pLPB=(BOPTools_ListOfPaveBlock *)&aCB.PaveBlocks();
        aPBIt.Initialize(*pLPB);
        for (; aPBIt.More(); aPBIt.Next()) {
          const BOPTools_PaveBlock& aPBx=aPBIt.Value();
          nEx=aPBx.OriginalEdge();
          const TopoDS_Edge& aEx=TopoDS::Edge(myDS->Shape(nEx));
          aTolEx=BRep_Tool::Tolerance(aEx);
          if (aTolEx>aTolExMax) {
            aTolExMax=aTolEx;
            aLPBx.Prepend(aPBx);
          }
          else{
            aLPBx.Append(aPBx);
          }
        }
        //
        pLPB->Clear();
        *pLPB=aLPBx;
      }
      //
      BOPTools_PaveBlock& aPB=aCB.PaveBlock1(nE);
      nSp=SplitIndex(aPB);
      aPB.SetEdge(nSp);
      //
      const BOPTools_ListOfPaveBlock& aCBLPB=aCB.PaveBlocks();
      aPBIt.Initialize(aCBLPB);
      for (; aPBIt.More(); aPBIt.Next()) {
        BOPTools_PaveBlock& aPBx=aPBIt.Value();
        nEx=aPBx.OriginalEdge();
        if (nEx==nE) {
          continue;
        }
        //
        nSpx=SplitIndex(aPBx);
        aPBx.SetEdge(nSpx);
      }
      //
    }
  }
}
//=======================================================================
// function: UpdateCommonBlocks
// purpose:
//=======================================================================
void NMTTools_PaveFiller::UpdateCommonBlocks(const Standard_Integer)
{
  Standard_Integer nE, aNbS,  nEx, nEMax, j, aNbPoints, aNbLCB, nF;
  Standard_Real aTolEx, aTolExMax, aTSRMax[2], aTx[2], aTmp;
  TColStd_ListIteratorOfListOfInteger aItLI;
  gp_Pnt aPMax[2];
  TopoDS_Edge aEMax;
  BOPTools_ListIteratorOfListOfPaveBlock aItLPB, aItLPBS;
  NMTTools_ListIteratorOfListOfCommonBlock aItLCB;
  NMTTools_MapOfPaveBlock aMPB;
  //
  myIsDone=Standard_False;
  //
  aNbS=myDS->NumberOfShapesOfTheObject();
  for (nE=1; nE<=aNbS; ++nE) {
    if (myDS->GetShapeType(nE)!=TopAbs_EDGE){
      continue;
    }
    //
    const TopoDS_Edge& aE=*((TopoDS_Edge*)&myDS->Shape(nE));
    if (BRep_Tool::Degenerated(aE)){
      continue;
    }
    //
    NMTTools_ListOfCommonBlock& aLCB=myCommonBlockPool(myDS->RefEdge(nE));
    //modified by NIZNHY-PKV Thu Jan 19 09:03:19 2012f
    aNbLCB=aLCB.Extent();
    if (!aNbLCB) {
      continue;
    }
    // 0
    NMTTools_ListOfCommonBlock aLCBx;
    //
    aItLCB.Initialize(aLCB);
    for (; aItLCB.More(); aItLCB.Next()) {
      NMTTools_CommonBlock aCBx;
      //
      NMTTools_CommonBlock& aCB=aItLCB.ChangeValue();
      const BOPTools_ListOfPaveBlock &aLPB=aCB.PaveBlocks();
      aItLPB.Initialize(aLPB);
      for (; aItLPB.More(); aItLPB.Next()) {
        const BOPTools_PaveBlock& aPBx=aItLPB.Value();
        nEx=aPBx.OriginalEdge();
        BOPTools_ListOfPaveBlock& aLPBS=mySplitShapesPool(myDS->RefEdge(nEx));
        aItLPBS.Initialize(aLPBS);
        for (; aItLPBS.More(); aItLPBS.Next()) {
          const BOPTools_PaveBlock& aPBSx=aItLPBS.Value();
          if (aPBSx.IsEqual(aPBx)) {
            aCBx.AddPaveBlock(aPBSx);
            break;
          }
        }// for (; aItLPBS.More(); aItLPBS.Next()) {
      }// for (; aItLPB.More(); aItLPB.Next()) {
      //
      const TColStd_ListOfInteger& aLI=aCB.Faces();
      aItLI.Initialize(aLI);
      for (; aItLI.More(); aItLI.Next()) {
        nF=aItLI.Value();
        aCBx.AddFace(nF);
      }
      //
      aLCBx.Append(aCBx);
    }//for (; aItLCB.More(); aItLCB.Next()) {
    //
    aLCB.Clear();
    //
    aItLCB.Initialize(aLCBx);
    for (; aItLCB.More(); aItLCB.Next()) {
      NMTTools_CommonBlock& aCBx=aItLCB.ChangeValue();
      aLCB.Append(aCBx);
    }
    //modified by NIZNHY-PKV Thu Jan 19 09:03:30 2012t
    // 1
    aItLCB.Initialize(aLCB);
    for (; aItLCB.More(); aItLCB.Next()) {
      NMTTools_CommonBlock& aCB=aItLCB.ChangeValue();
      //
      BOPTools_PaveBlock aPBMax;
      aTolExMax=-1.;
      const BOPTools_ListOfPaveBlock &aLPB=aCB.PaveBlocks();
      aItLPB.Initialize(aLPB);
      for (; aItLPB.More(); aItLPB.Next()) {
        const BOPTools_PaveBlock& aPBx=aItLPB.Value();
        nEx=aPBx.OriginalEdge();
        const TopoDS_Edge& aEx=*((TopoDS_Edge*)&myDS->Shape(nEx));
        aTolEx=BRep_Tool::Tolerance(aEx);
        if (aTolEx>aTolExMax) {
          aTolExMax=aTolEx;
          aEMax=aEx;
          aPBMax=aPBx;
        }
      }
      //
      // 2
      if (aMPB.Contains(aPBMax)) {
        continue;
      }
      aMPB.Add(aPBMax);
      //
      nEMax=aPBMax.OriginalEdge();
      const IntTools_ShrunkRange& aISRMax=aPBMax.ShrunkRange();
      const IntTools_Range& aSRMax=aISRMax.ShrunkRange();
      const Bnd_Box& aBoxMax=aISRMax.BndBox();
      aSRMax.Range(aTSRMax[0], aTSRMax[1]);
      for (j=0; j<2; ++j) {
        BOPTools_Tools::PointOnEdge(aEMax, aTSRMax[j], aPMax[j]);
      }
      //
      // 3
      aItLPB.Initialize(aLPB);
      for (; aItLPB.More(); aItLPB.Next()) {
        const BOPTools_PaveBlock& aPBx=aItLPB.Value();
        nEx=aPBx.OriginalEdge();
        if (nEx==nEMax) {
          continue;
        }
        //
        const TopoDS_Edge& aEx=*((TopoDS_Edge*)&myDS->Shape(nEx));
        GeomAPI_ProjectPointOnCurve& aPPCx=myContext->ProjPC(aEx);
        //
        for (j=0; j<2; ++j) {
          aPPCx.Perform(aPMax[j]);
          aNbPoints=aPPCx.NbPoints();
          if (!aNbPoints) {
            break;
          }
          aTx[j]=aPPCx.LowerDistanceParameter();
        }
        if (!aNbPoints) {
          // correction the range is impossible due to
          // a projection problem
          continue;
        }
        //
        if (aTx[0]>aTx[1]){
          aTmp=aTx[0];
          aTx[0]=aTx[1];
          aTx[1]=aTmp;
        }
        //
        // 4 Correction
        // 4.1 aPBx
        {
          const IntTools_ShrunkRange& aISRx=aPBx.ShrunkRange();
          IntTools_Range *pSRx=(IntTools_Range *)(&aISRx.ShrunkRange());
          Bnd_Box *pBoxx=(Bnd_Box *)(&aISRx.BndBox());
          //
          pSRx->SetFirst(aTx[0]);
          pSRx->SetLast(aTx[1]);
          *pBoxx=aBoxMax;
        }
        //
        // 4.2 aPBSx
        BOPTools_ListOfPaveBlock& aLPBSx=mySplitShapesPool(myDS->RefEdge(nEx));
        aItLPBS.Initialize(aLPBSx);
        for (; aItLPBS.More(); aItLPBS.Next()) {
          const BOPTools_PaveBlock& aPBSx=aItLPBS.Value();
          if (!aPBSx.IsEqual(aPBx)) {
            continue;
          }
          //
          const IntTools_ShrunkRange& aISRx=aPBSx.ShrunkRange();
          IntTools_Range *pSRx=(IntTools_Range *)(&aISRx.ShrunkRange());
          Bnd_Box *pBoxx=(Bnd_Box *)(&aISRx.BndBox());
          //
          pSRx->SetFirst(aTx[0]);
          pSRx->SetLast(aTx[1]);
          *pBoxx=aBoxMax;
        }
        //
        //
      }//for (; aItLPB.More(); aItLPB.Next()) {
    }//for (; aItLCB.More(); aItLCB.Next()) {
  }//for (nE=1; nE<=aNbS; ++nE) {
}
//
//=======================================================================
// function: PerformEF
// purpose: 
//=======================================================================
  void NMTTools_PaveFiller::PerformEF() 
{
  Standard_Boolean bJustAdd;
  Standard_Integer n1, n2, anIndexIn, nE, nF, aNbEFs, aBlockLength;
  Standard_Integer aDiscretize;
  Standard_Real aTolE, aTolF, aDeflection;
  BooleanOperations_IndexedDataMapOfShapeInteger aMapVI;
  BOPTools_IDMapOfPaveBlockIMapOfInteger aMapCB;
  BOPTools_IMapOfPaveBlock aIMPBx;
  //
  myIsDone=Standard_False;
  aDeflection=0.01;
  aDiscretize=35;
  //
  BOPTools_CArray1OfESInterference& aEFs=myIP->ESInterferences();
  //
  myDSIt->Initialize(TopAbs_EDGE, TopAbs_FACE);
  //
  // BlockLength correction
  aNbEFs=myDSIt->BlockLength();
  aBlockLength=aEFs.BlockLength();
  if (aNbEFs > aBlockLength) {
    aEFs.SetBlockLength(aNbEFs);
  }
  //
  for (; myDSIt->More(); myDSIt->Next()) {
    myDSIt->Current(n1, n2, bJustAdd);
    //
    if(bJustAdd) {
      continue;
    }
    //
    anIndexIn = 0;
    //
    nE=n1; 
    nF=n2;
    if (myDS->GetShapeType(n2)==TopAbs_EDGE) {
      nE=n2; 
      nF=n1;
    }
    //
    // all Common Blocks for face nF
    NMTTools_ListOfCommonBlock aLCBF;
    CommonBlocksFace(nF, aLCBF);
    NMTTools_CommonBlockAPI aCBAPIF(aLCBF);
    //
    // Edge
    const TopoDS_Edge aE=TopoDS::Edge(myDS->Shape(nE));
    if (BRep_Tool::Degenerated(aE)){
      continue;
    }
    //
    // Face
    const TopoDS_Face aF=TopoDS::Face(myDS->Shape(nF));
    //
    TopTools_IndexedMapOfShape aME;
    TopExp::MapShapes(aF, TopAbs_EDGE, aME);
    if (aME.Contains(aE)) {
      continue;
    }
    //
    aTolF=BRep_Tool::Tolerance(aF);
    aTolE=BRep_Tool::Tolerance(aE);
    
    const Bnd_Box& aBBF=myDS->GetBoundingBox(nF); 
    //
    // Process each PaveBlock on edge nE
    BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(nE));
    //
    BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPB);
    for (; anIt.More(); anIt.Next()) {
      BOPTools_PaveBlock& aPB=anIt.Value();
      if (aCBAPIF.IsCommonBlock(aPB)) {
	continue;
      }
      //
      const IntTools_ShrunkRange& aShrunkRange=aPB.ShrunkRange();
      const IntTools_Range& aSR =aShrunkRange.ShrunkRange();
      const Bnd_Box& aBBE=aShrunkRange.BndBox();
      //
      if (aBBF.IsOut (aBBE)) {
	continue;
      }
      // 
      // EF
      IntTools_EdgeFace aEF;
      aEF.SetEdge (aE);
      aEF.SetFace (aF);
      aEF.SetTolE (aTolE);
      aEF.SetTolF (aTolF);
      aEF.SetDiscretize (aDiscretize);
      aEF.SetDeflection (aDeflection);
      // 
      aEF.SetContext((IntTools_PContext)&myContext);
      // 
      IntTools_Range anewSR = aSR;
      // 
      // Correction of the Shrunk Range 
      BOPTools_Tools::CorrectRange(aE, aF, aSR, anewSR);
      aEF.SetRange (anewSR);
      //
      aEF.Perform();
      //
      if (aEF.IsDone()) {
	Standard_Boolean bCoinsideFlag;
	Standard_Integer i, aNbCPrts;
	TopAbs_ShapeEnum aType;
	//
	const IntTools_SequenceOfCommonPrts& aCPrts=aEF.CommonParts();
	//
	aNbCPrts=aCPrts.Length();
	for (i=1; i<=aNbCPrts; ++i) {
	  anIndexIn=0;
	  //
	  const IntTools_CommonPrt& aCPart=aCPrts(i);
	  aType=aCPart.Type();
	  //
	  switch (aType) {
	    //
	    case TopAbs_VERTEX:  {
	      Standard_Boolean bIsOnPave1, bIsOnPave2;
	      Standard_Integer nVF;
	      Standard_Real aT, aTolToDecide; 
	      TopoDS_Vertex aNewVertex;
	      //
	      const IntTools_Range& aR=aCPart.Range1();
	      //
	      // New Vertex
	      VertexParameter(aCPart, aT);
	      BOPTools_Tools::MakeNewVertex(aE, aT, aF, aNewVertex);
	      //
	      //decide to add pave or not
	      aTolToDecide=5.e-8;
	      bIsOnPave1=IsOnPave(anewSR.First(), aR, aTolToDecide); 
	      bIsOnPave2=IsOnPave(anewSR.Last() , aR, aTolToDecide); 
	      //
	      if (!bIsOnPave1 && !bIsOnPave2) {
		nVF=CheckFacePaves(aNewVertex, nF);
		if (!nVF) {
		  // really new vertex
		  // Add Interference to the Pool
		  BOPTools_ESInterference anInterf (nE, nF, aCPart);
		  anIndexIn=aEFs.Append(anInterf);
		  anInterf.SetNewShape(0);
		  //
		  aMapVI.Add(aNewVertex, anIndexIn);
		  aIMPBx.Add(aPB);
		  //
		  myIP->Add(nE, nF, Standard_True, NMTDS_TI_EF);
		  //
		}// if (!nVF)
	      }// if (!bIsOnPave1 && !bIsOnPave2) 
	      //
	      //modified by NIZNHY-PKV Fri Apr 18 10:55:38 2008f
	      else {
		const BOPTools_Pave& aPave=(bIsOnPave1)? aPB.Pave1() : aPB.Pave2();
		nVF=aPave.Index();
		const TopoDS_Vertex& aVF=TopoDS::Vertex(myDS->Shape(nVF));
		BOPTools_Tools::UpdateVertex (aVF, aNewVertex);
	      }
	      //modified by NIZNHY-PKV Fri Apr 18 10:55:40 2008t
	      //
	    }// case TopAbs_VERTEX:
	      break;
	    //
	    case TopAbs_EDGE: {
	      bCoinsideFlag=BOPTools_Tools::IsBlockInOnFace(aPB, aF, myContext);
	      if (!bCoinsideFlag) {
		break;
	      }
	      //
	      // Fill aMapCB
	      if (aMapCB.Contains(aPB)) {
		TColStd_IndexedMapOfInteger& aMapF=aMapCB.ChangeFromKey(aPB);
		aMapF.Add(nF);
	      }
	      else {
		TColStd_IndexedMapOfInteger aMapF;
		aMapF.Add(nF);
		aMapCB.Add(aPB, aMapF);
	      }
	      //
	      aIMPBx.Add(aPB);
	      myIP->Add(nE, nF, Standard_True, NMTDS_TI_EF);
	    }// case TopAbs_EDGE:
	      break;

	    default:
	      break;
	  } // switch (aType) 
	} // for (i=1; i<=aNbCPrts; i++) 
      } //if (aEF.IsDone())
    } // for (; anIt.More(); anIt.Next()) 
  }// for (; myDSIt.More(); myDSIt.Next()) 
  //
  // Treat New vertices
  EFNewVertices(aMapVI);
  //
  // Add draft Common Blocks of EF type 
  EFCommonBlocks(aMapCB);
  //
  // Collect all CB we suspected to split by new vertices
  NMTTools_ListOfCommonBlock aLCBx;
  {
    Standard_Integer i, aNbPBx, nEx;
    BOPTools_IMapOfPaveBlock aMx;
    //
    aNbPBx=aIMPBx.Extent();
    for (i=1; i<=aNbPBx; ++i) {
      const BOPTools_PaveBlock& aPBx=aIMPBx(i);
      nEx=aPBx.OriginalEdge();
      NMTTools_ListOfCommonBlock& aLCB=myCommonBlockPool(myDS->RefEdge(nEx));
      if (aLCB.Extent()) {
	NMTTools_CommonBlockAPI aCBAPIx(aLCB);
	if (aCBAPIx.IsCommonBlock(aPBx)) {
	  NMTTools_CommonBlock& aCBx=aCBAPIx.CommonBlock(aPBx);
	  const BOPTools_PaveBlock& aPB1=aCBx.PaveBlock1();
	  if (!aMx.Contains(aPB1)){
	    aMx.Add(aPB1);
	    aLCBx.Append(aCBx);
	  }
	}
      }
    }
  }
  //
  // Split the common blocks above
  if (aLCBx.Extent()) {
    ReplaceCommonBlocks(aLCBx);
  }
  //
  myIsDone=Standard_True;
}