//=======================================================================
// function:EFNewVertices
// purpose: 
//=======================================================================
  void NMTTools_PaveFiller::EFNewVertices 
    (const TopoDS_Vertex& aNewVertex,
     const BooleanOperations_IndexedDataMapOfShapeInteger& aMapVI) 
{
  Standard_Integer i, aNewShape, nE, nF;
  Standard_Real aT;
  BOPTools_Pave aPave;
  BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
  //
  BOPTools_CArray1OfESInterference& aEFs=myIP->ESInterferences();
  //
  // Insert New Vertex in DS;
  myDS->InsertShapeAndAncestorsSuccessors(aNewVertex, anASSeq);
  aNewShape=myDS->NumberOfInsertedShapes();
  myDS->SetState (aNewShape, BooleanOperations_ON);
  //
  // Insert New Vertex in EFInterference
  i=aMapVI.FindFromKey(aNewVertex);
  BOPTools_ESInterference& aEFInterf= aEFs(i);
  aEFInterf.SetNewShape(aNewShape);
  // Extract interference info
  aEFInterf.Indices(nE, nF);
  if (myDS->GetShapeType(nF)==TopAbs_EDGE) {
    nE=nF;
  }
  const IntTools_CommonPrt& aCPart=aEFInterf.CommonPrt();
  VertexParameter(aCPart, aT);
  //
  // Pave for edge nE
  aPave.SetInterference(i);
  aPave.SetType (BooleanOperations_EdgeSurface);
  aPave.SetIndex(aNewShape);
  aPave.SetParam(aT);
  // Append the Pave to the myPavePoolNew
  BOPTools_PaveSet& aPaveSet=myPavePoolNew(myDS->RefEdge(nE));
  aPaveSet.Append(aPave);
  //
}
//=======================================================================
// function: FillInternalVertices
// purpose:
//=======================================================================
void GEOMAlgo_Builder::FillInternalVertices()
{
  const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
  NMTTools_PaveFiller* pPF=myPaveFiller;
  NMTDS_InterfPool* pIP=pPF->IP();
  const Handle(IntTools_Context)& aCtx= pPF->Context();
  //
  BOPTools_CArray1OfVSInterference& aVFs=pIP->VSInterferences();
  BOPTools_CArray1OfESInterference& aEFs=pIP->ESInterferences();
  const NMTTools_IndexedDataMapOfIndexedMapOfInteger& aMAV=pPF->AloneVertices();
  //
  Standard_Boolean bHasImage;
  Standard_Integer i, j, nF, aNbS, nV, nVSD, n1, n2, iFlag;
  Standard_Integer aNbVFs, aNbAVF, aNbEFs, aNbVC, aNbE, aNbV;
  Standard_Real aU1, aU2, aTol;
  NMTTools_IndexedDataMapOfIndexedMapOfInteger aMFMV;
  TopTools_MapOfShape aMFence;
  TopTools_ListIteratorOfListOfShape aIt, aItV;
  BRep_Builder aBB;
  //
  // 1. Collect face-vertex candidates [aMFMV]
  //
  // 1.1. VFs
  aNbVFs=aVFs.Extent();
  for (i=1; i<=aNbVFs; ++i) {
    const BOPTools_VSInterference& aVS=aVFs(i);
    aVS.Indices(n1, n2);
    nF=n2;
    nV=n1;
    if (aDS.Shape(n1).ShapeType()==TopAbs_FACE) {
      nF=n1;
      nV=n2;
    }
    nVSD=pPF->FindSDVertex(nV);
    if (nVSD) {
      nV=nVSD;
    }
    //
    UpdateCandidates(nF, nV, aMFMV);
  }
  //
  // 1.2 EFs
  aNbEFs=aEFs.Extent();
  for (i=1; i<=aNbEFs; ++i) {
    const BOPTools_ESInterference& aEF=aEFs(i);
    aEF.Indices(n1, n2);
    nV=aEF.NewShape();
    if (!nV) {
      continue;
    }
    const TopoDS_Shape& aSnew=aDS.Shape(nV);
    if (aSnew.ShapeType()!=TopAbs_VERTEX) {
      continue;
    }
    //
    nF=(aDS.Shape(n1).ShapeType()==TopAbs_FACE) ? n1 : n2;
    nVSD=pPF->FindSDVertex(nV);
    if (nVSD) {
      nV=nVSD;
    }
    UpdateCandidates(nF, nV, aMFMV);
  }
  //
  aNbS=aDS.NumberOfShapesOfTheObject();
  for (nF=1; nF<=aNbS; ++nF) {
    const TopoDS_Shape& aF=aDS.Shape(nF);
    //
    if (aF.ShapeType()!=TopAbs_FACE) {
      continue;
    }
    if (!aMFence.Add(aF)) {
      continue;
    }
    //
    const TopoDS_Face& aFF=TopoDS::Face(aF);
    aTol=BRep_Tool::Tolerance(aFF);
    //
    // 1.3 FFs
    if (aMAV.Contains(nF)) {
      const TColStd_IndexedMapOfInteger& aMAVF=aMAV.FindFromKey(nF);
      aNbAVF=aMAVF.Extent();
      for (j=1; j<=aNbAVF; ++j) {
        nV=aMAVF(j);
        nVSD=pPF->FindSDVertex(nV);
        if (nVSD) {
          nV=nVSD;
        }
        //
        UpdateCandidates(nF, nV, aMFMV);
      }
    }
    //
    // 1.4 Internal vertices of the face nF
    BooleanOperations_OnceExplorer aExp(aDS);
    aExp.Init(nF, TopAbs_VERTEX);
    for (; aExp.More(); aExp.Next()) {
      nV=aExp.Current();
      const TopoDS_Shape& aV=aDS.Shape(nV);
      if (aV.Orientation()==TopAbs_INTERNAL) {
        nVSD=pPF->FindSDVertex(nV);
        if (nVSD) {
          nV=nVSD;
        }
        //
        UpdateCandidates(nF, nV, aMFMV);
      }
    }
    //
    // 2. Process face nF
    if (!aMFMV.Contains(nF)) {
      continue;
    }
    //
    const TColStd_IndexedMapOfInteger& aMVC=aMFMV.FindFromKey(nF);
    aNbVC=aMVC.Extent();
    if (!aNbVC) {
      continue;
    }
    //
    // 2.1 Refine candidates
    TopTools_IndexedDataMapOfShapeListOfShape aMVE;
    TopTools_ListOfShape aLV;
    //
    bHasImage=myImages.HasImage(aF);
    if (bHasImage) {
      const TopTools_ListOfShape& aLFx=myImages.Image(aF);
      aIt.Initialize(aLFx);
      for (; aIt.More(); aIt.Next()) {
        const TopoDS_Shape& aFx=aIt.Value();
        TopExp::MapShapesAndAncestors(aFx, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
      }
    }
    else {
      Standard_Boolean bFaceToProcess;
      //
      TopExp::MapShapesAndAncestors(aF, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
      bFaceToProcess=Standard_False;
      for (j=1; j<=aNbVC; ++j) {
        nV=aMVC(j);
        const TopoDS_Shape& aV=aDS.Shape(nV);
        if (!aMVE.Contains(aV)) {
          bFaceToProcess=!bFaceToProcess;
          break;
        }
      }
      if (!bFaceToProcess) {
        continue;
      }
    }// else
    //
    for (j=1; j<=aNbVC; ++j) {
      nV=aMVC(j);
      const TopoDS_Shape& aV=aDS.Shape(nV);
      if (aMVE.Contains(aV)) {
        const TopTools_ListOfShape& aLE=aMVE.FindFromKey(aV);
        aNbE=aLE.Extent();
        if (aNbE) {
          continue;
        }
      }
      aLV.Append(aV);
    }
    //
    aNbV=aLV.Extent();
    if (aNbV) {
      //  3. Try to put vertices into the face(s)
      aItV.Initialize(aLV);
      for (; aItV.More(); aItV.Next()) {
        TopoDS_Vertex aV=TopoDS::Vertex(aItV.Value());
        aV.Orientation(TopAbs_INTERNAL);
        //
        bHasImage=myImages.HasImage(aF);
        if (bHasImage) {
          const TopTools_ListOfShape& aLFx=myImages.Image(aF);
          aIt.Initialize(aLFx);
          for (; aIt.More(); aIt.Next()) {
            TopoDS_Face aFx=TopoDS::Face(aIt.Value());
            // update classifier
            IntTools_FClass2d& aClsf=aCtx->FClass2d(aFx);
            aClsf.Init(aFx, aTol);
            //
            iFlag=aCtx->ComputeVS (aV, aFx, aU1, aU2);
            if (!iFlag) {
              aBB.Add(aFx, aV);
              break;
            }
          }
        }
        else {
          const TopoDS_Face& aFx=TopoDS::Face(aF);
          // update classifier
          IntTools_FClass2d& aClsf=aCtx->FClass2d(aFx);
          aClsf.Init(aFx, aTol);
          //
          iFlag=aCtx->ComputeVS (aV, aFx, aU1, aU2);
          if (!iFlag) {
            TopoDS_Face aFz;
            //
            GEOMAlgo_Tools3D::CopyFace(aFx, aFz);
            aBB.Add(aFz, aV);
            myImages.Bind(aF, aFz);
          }
        }
      }// for (; aItV.More(); aItV.Next()) {
    }// if (aNbV) {
  }// for (nF=1; nF<=aNb; ++nF) {
}
//=======================================================================
// function:EFNewVertices
// purpose: 
//=======================================================================
  void NMTTools_PaveFiller::EFNewVertices 
    (const BooleanOperations_IndexedDataMapOfShapeInteger& aMapVI) 
{
  Standard_Integer i, j, aNb, aNewShape, aFlag, iX, aNbVV, aNbSimple;
  Standard_Integer aWhat, aWith, nE, nF, nV, aNbIEF, aNbEdges, iTmp;
  Standard_Real aT;
  TopoDS_Compound aCompound;
  TopoDS_Vertex aNewVertex;
  BRep_Builder aBB;
  BOPTools_Pave aPave;
  NMTTools_IndexedDataMapOfIndexedMapOfInteger aMNVE, aMNVIEF;
  BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
  TopTools_IndexedMapOfShape aMNVComplex, aMNVSimple;
  //
  aNb=aMapVI.Extent();
  if (!aNb) { // no new vertices, no new problems 
    return;
  }
  //
  BOPTools_CArray1OfESInterference& aEFs=myIP->ESInterferences();
  //
  // 0.
  if (aNb==1) {
    aNewVertex=TopoDS::Vertex(aMapVI.FindKey(1));
    EFNewVertices(aNewVertex, aMapVI);
    return;
  }
  //
  // 1. Make compound from new vertices
  aBB.MakeCompound(aCompound);
  for (i=1; i<=aNb; ++i) {
    const TopoDS_Shape& aV=aMapVI.FindKey(i);
    aBB.Add(aCompound, aV);
  }
  //
  // 2. VV intersection between these vertices 
  //       using the auxiliary Filler
  NMTTools_PaveFiller tPF;
  //
  tPF.SetCompositeShape(aCompound);
  //
  tPF.Init();
  tPF.PerformVV();
  //
  NMTDS_ShapesDataStructure& tDS=*(tPF.DS());
  NMTDS_InterfPool& tInterfPool=*(tPF.IP());
  BOPTools_CArray1OfVVInterference& aVVInterfs=tInterfPool.VVInterferences();
  //
  // 3. Separate Comlex and Simple new vertices
  aNbVV=aVVInterfs.Extent();
   for (i=1; i<=aNbVV; ++i) {
    const BOPTools_VVInterference& aVV=aVVInterfs(i);
    aVV.Indices(aWhat, aWith);
    const TopoDS_Shape& aV1=tDS.Shape(aWhat);
    const TopoDS_Shape& aV2=tDS.Shape(aWith);
    aMNVComplex.Add(aV1);
    aMNVComplex.Add(aV2);
  }
  //
  for (i=1; i<=aNb; ++i) {
    const TopoDS_Shape& aV=aMapVI.FindKey(i);
    if (!aMNVComplex.Contains(aV)) {
      aMNVSimple.Add(aV);
    }
  }
  //
  // 4. Treat Simple new Vertices
  aNbSimple=aMNVSimple.Extent();
  for (i=1; i<=aNbSimple; ++i) {
    const TopoDS_Vertex& aV=TopoDS::Vertex(aMNVSimple(i));
    EFNewVertices(aV, aMapVI);
  }
  //
  // 3. Fill Maps : NewVertex-edges (aMNVE) 
  //                NewVertex-interferences (aMNVIEE)
  aNb=aVVInterfs.Extent();
  for (i=1; i<=aNb; ++i) {
    const BOPTools_VVInterference& aVV=aVVInterfs(i);
    aNewShape=aVV.NewShape();
    if (!aNewShape) {
      continue;
    }
    //
    if (!aMNVE.Contains(aNewShape)) {
      TColStd_IndexedMapOfInteger aMx;
      aMNVE.Add(aNewShape, aMx);
    }
    if (!aMNVIEF.Contains(aNewShape)) {
      TColStd_IndexedMapOfInteger aMx;
      aMNVIEF.Add(aNewShape, aMx);
    }
    //
    TColStd_IndexedMapOfInteger& aME=aMNVE.ChangeFromKey(aNewShape);
    TColStd_IndexedMapOfInteger& aMIEF=aMNVIEF.ChangeFromKey(aNewShape);
    //
    aVV.Indices(aWhat, aWith);
    //aWhat
    const TopoDS_Shape& aV1=tDS.Shape(aWhat);
    iX=aMapVI.FindFromKey(aV1);
    const BOPTools_ESInterference& aEF1=aEFs(iX);
    aEF1.Indices(nE, nF);
    //
    if (myDS->GetShapeType(nF)==TopAbs_EDGE) {
      iTmp=nE;
      nE=nF;
      nF=iTmp;
    }
    aME.Add(nE);
    aMIEF.Add(iX);
    //aWith
    const TopoDS_Shape& aV2=tDS.Shape(aWith);
    iX=aMapVI.FindFromKey(aV2);
    const BOPTools_ESInterference& aEF2=aEFs(iX);
    aEF2.Indices(nE, nF);
    //
    if (myDS->GetShapeType(nF)==TopAbs_EDGE) {
      iTmp=nE;
      nE=nF;
      nF=iTmp;
    }
    aME.Add(nE);
    aMIEF.Add(iX);
  }// for (i=1; i<=aNb; ++i) {
  //
  // 4. Process new vertices
  aNb=aMNVE.Extent();
  for (i=1; i<=aNb; ++i) { // xx
    //
    //  new Vertex
    nV=aMNVE.FindKey(i);
    aNewVertex=TopoDS::Vertex(tDS.Shape(nV));
    //
    // Insert New Vertex in DS;
    myDS->InsertShapeAndAncestorsSuccessors(aNewVertex, anASSeq);
    aNewShape=myDS->NumberOfInsertedShapes();
    myDS->SetState (aNewShape, BooleanOperations_ON);
    //
    // Update index of NewShape in EF interferences
    const TColStd_IndexedMapOfInteger& aMIEF=aMNVIEF.FindFromKey(nV);
    aNbIEF=aMIEF.Extent();
    for (j=1; j<=aNbIEF; ++j) {
      iX=aMIEF(j);
      BOPTools_ESInterference& aEF=aEFs(iX);
      aEF.SetNewShape(aNewShape);
    }
    // 
    // Update Paves on all edges 
    const TColStd_IndexedMapOfInteger& aME=aMNVE(i);
    aNbEdges=aME.Extent();
    for (j=1; j<=aNbEdges; ++j) {
      nE=aME(j);
      const TopoDS_Edge aE=TopoDS::Edge(myDS->Shape(nE));//mpv
      //
      aFlag=myContext.ComputeVE (aNewVertex, aE, aT);
      //
      if (!aFlag) {
	aPave.SetInterference(-1);
	aPave.SetType (BooleanOperations_EdgeSurface);
	aPave.SetIndex(aNewShape);
	aPave.SetParam(aT);
	//
	BOPTools_PaveSet& aPaveSet=myPavePoolNew(myDS->RefEdge(nE));
	aPaveSet.Append(aPave);
      }
    }
  }
}