示例#1
0
//----------------------------------------------------------------
// Function: to update the core Surface
//           for any movement  or Boolean operation of the body.
// Author: Jane Hu
//----------------------------------------------------------------
CubitStatus OCCSurface::update_OCC_entity( BRepBuilderAPI_Transform *aBRepTrsf,
                                         BRepAlgoAPI_BooleanOperation *op)
{
  assert(aBRepTrsf != NULL || op != NULL);

  TopoDS_Shape shape;
  if (aBRepTrsf)
    shape = aBRepTrsf->ModifiedShape(*get_TopoDS_Face());
  else
  {
    TopTools_ListOfShape shapes;
    shapes.Assign(op->Modified(*get_TopoDS_Face()));
    if(shapes.Extent() == 0)
         shapes.Assign(op->Generated(*get_TopoDS_Face()));
    if (shapes.Extent() == 1)
      shape = shapes.First();
    else if(shapes.Extent() > 1)
    {
      //update all attributes first.
      TopTools_ListIteratorOfListOfShape it;
      it.Initialize(shapes);
      for(; it.More(); it.Next())
      {
        shape = it.Value();
        OCCQueryEngine::instance()->copy_attributes(*get_TopoDS_Face(), shape);
      }
      shape = shapes.First();
    }
    else if(op->IsDeleted(*get_TopoDS_Face()))
      ;
    else
      return CUBIT_SUCCESS;
  }
 
  TopoDS_Face surface; 
  if(!shape.IsNull())
    surface = TopoDS::Face(shape);

  if (aBRepTrsf) 
  {
    //set the loops
    DLIList<OCCLoop *> loops;
    this->get_loops(loops);
    for (int i = 1; i <= loops.size(); i++)
    {
       OCCLoop *loop = loops.get_and_step();
       loop->update_OCC_entity(aBRepTrsf, op);
    }
    OCCQueryEngine::instance()->update_OCC_map(*myTopoDSFace, surface);
  }

  else if(op)
    update_OCC_entity(*myTopoDSFace, surface, op);

  return CUBIT_SUCCESS;
}
//=======================================================================
// function: IsExistingPaveBlock
// purpose:
//=======================================================================
Standard_Boolean NMTTools_PaveFiller::IsExistingPaveBlock(const BOPTools_PaveBlock& aPBNew,
                                                          const TopTools_ListOfShape& aLSE,
                                                          const Standard_Real aTolR3D)
{
  Standard_Boolean bFlag;
  Standard_Integer aNbSE, iC;
  Standard_Real aTolE, aTol;
  TopTools_ListIteratorOfListOfShape anIt;
  //
  bFlag=Standard_False;
  //
  aNbSE=aLSE.Extent();
  if (!aNbSE) {
    return bFlag;
  }
  //
  anIt.Initialize(aLSE);
  for (; anIt.More(); anIt.Next()) {
    const TopoDS_Edge& aE=TopoDS::Edge(anIt.Value());
    aTolE=BRep_Tool::Tolerance(aE);
    aTol=aTolR3D;
    if (aTolE>aTol) {
      aTol=aTolE;
    }
    iC=CheckIntermediatePoint(aPBNew, aE, aTol);
    if (!iC) {
      return !bFlag;
    }
  }
  return bFlag;
}
//=======================================================================
// function: FillImagesFaces1
// purpose:
//=======================================================================
void GEOMAlgo_Builder::FillImagesFaces1()
{
  Standard_Integer i, aNb, iSense, aNbLFx;
  TopoDS_Face aF, aFSp, aFSD;
  TopTools_ListOfShape aLFx;
  TopTools_ListIteratorOfListOfShape aIt;
  //
  const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
  //
  aNb=aDS.NumberOfShapesOfTheObject();
  for (i=1; i<=aNb; ++i) {
    const TopoDS_Shape& aS=aDS.Shape(i);
    if (aS.ShapeType()!=TopAbs_FACE) {
      continue;
    }
    //
    if (!mySplitFaces.HasImage(aS)) {
      continue;
    }
    //
    aF=*((TopoDS_Face*)&aS);
    //
    aLFx.Clear();
    const TopTools_ListOfShape& aLF=mySplitFaces.Image(aF);
    aIt.Initialize(aLF);
    for (; aIt.More(); aIt.Next()) {
      aFSp=*((TopoDS_Face*)(&aIt.Value()));
      if (!mySameDomainShapes.Contains(aFSp)) {
        aLFx.Append(aFSp);
      }
      else {
        const TopoDS_Shape& aSx=mySameDomainShapes.FindFromKey(aFSp);
        aFSD=*((TopoDS_Face*)(&aSx));
        iSense=GEOMAlgo_Tools3D::Sense(aFSp, aFSD);
        if (iSense<0) {
          aFSD.Reverse();
        }
        aLFx.Append(aFSD);
      }
    }
    //
    if (!myImages.HasImage(aF)) {
      aNbLFx=aLFx.Extent();
      if (aNbLFx==1) {
        const TopoDS_Shape& aFx=aLFx.First();
        if (aF.IsSame(aFx)) {
          continue;
        }
      }
      myImages.Bind(aF, aLFx);
    }
  }
}
示例#4
0
//=======================================================================
//function : IsInternalFace
//purpose  : 
//=======================================================================
  Standard_Boolean GEOMAlgo_Tools3D::IsInternalFace(const TopoDS_Face& theFace,
                                                    const TopoDS_Edge& theEdge,
                                                    const TopTools_ListOfShape& theLF,
                                                    IntTools_Context& theContext)
{
  Standard_Boolean bRet;
  Standard_Boolean aNbF;
  //
  bRet=Standard_False;
  //
  aNbF=theLF.Extent();
  if (aNbF==2) {
    const TopoDS_Face& aF1=TopoDS::Face(theLF.First());
    const TopoDS_Face& aF2=TopoDS::Face(theLF.Last());
    bRet=GEOMAlgo_Tools3D::IsInternalFace(theFace, theEdge, aF1, aF2, theContext);
    return bRet;
  }
  //
  else {
    NMTTools_ListOfCoupleOfShape aLCFF;
    NMTTools_ListIteratorOfListOfCoupleOfShape aIt;
    //
    FindFacePairs(theEdge, theLF, aLCFF);
    //
    aIt.Initialize(aLCFF);
    for (; aIt.More(); aIt.Next()) {
      const NMTTools_CoupleOfShape& aCSFF=aIt.Value();
      //
      const TopoDS_Face& aF1=TopoDS::Face(aCSFF.Shape1());
      const TopoDS_Face& aF2=TopoDS::Face(aCSFF.Shape2());
      bRet=GEOMAlgo_Tools3D::IsInternalFace(theFace, theEdge, aF1, aF2, theContext);
      if (bRet) {
        return bRet;
      }
    }
  }
  return bRet;
}
//=======================================================================
// 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: FillIn2DParts
// purpose:
//=======================================================================
void GEOMAlgo_Builder::FillIn2DParts()
{
  const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
  NMTTools_PaveFiller* pPF=myPaveFiller;
  NMTDS_InterfPool* pIP=pPF->IP();
  BOPTools_CArray1OfSSInterference& aFFs=pIP->SSInterferences();
  NMTTools_CommonBlockPool& aCBP=pPF->ChangeCommonBlockPool();
  //
  Standard_Integer  j, nSpIn, nSpSc, aNbCurves;
  Standard_Integer aNbS, nF, aNbCBP, n1, n2, aNbFFs, aNbSpIn;
  TopTools_MapOfShape  aMFence;
  TopTools_ListOfShape aLSpIn;
  TopoDS_Face aF;
  NMTTools_ListIteratorOfListOfCommonBlock aItCB;
  BOPTools_ListIteratorOfListOfPaveBlock aItPB;
  //
  myInParts.Clear();
  //
  aNbFFs=aFFs.Extent();
  aNbCBP=aCBP.Extent();
  //
  aNbS=aDS.NumberOfShapesOfTheObject();
  for (nF=1; nF<=aNbS; ++nF) {
    if (aDS.GetShapeType(nF)!=TopAbs_FACE) {
      continue;
    }
    //
    aF=TopoDS::Face(aDS.Shape(nF));
    //
    aMFence.Clear();
    aLSpIn.Clear();
    //
    // 1. In Parts
    BOPTools_ListOfPaveBlock aLPBIn;
    //
    pPF->RealSplitsInFace(nF, aLPBIn);
    //
    aItPB.Initialize(aLPBIn);
    for (; aItPB.More(); aItPB.Next()) {
      const BOPTools_PaveBlock& aPB1=aItPB.Value();
      nSpIn=aPB1.Edge();
      const TopoDS_Shape& aSpIn=aDS.Shape(nSpIn);
      aLSpIn.Append(aSpIn);
    }
    //
    // 2. Section Parts
    for (j=1; j<=aNbFFs; ++j) {
      BOPTools_SSInterference& aFF=aFFs(j);
      aFF.Indices(n1, n2);
      if (!(n1==nF || n2==nF)) {
        continue;
      }
      BOPTools_SequenceOfCurves& aSC=aFF.Curves();
      aNbCurves=aSC.Length();
      if (!aNbCurves) {
        continue;
      }
      //
      const BOPTools_Curve& aBC=aSC(1);
      const BOPTools_ListOfPaveBlock& aLPB=aBC.NewPaveBlocks();
      aItPB.Initialize(aLPB);
      for (; aItPB.More(); aItPB.Next()) {
        const BOPTools_PaveBlock& aPBSc=aItPB.Value();
        nSpSc=aPBSc.Edge();
        const TopoDS_Shape& aSpSc=aDS.Shape(nSpSc);
        if (aMFence.Add(aSpSc)){
          aLSpIn.Append(aSpSc);
        }
      }
    }
    aNbSpIn=aLSpIn.Extent();
    if (aNbSpIn) {
      myInParts.Add(aF, aLSpIn);
    }
  }//for (nF=1; nF<=aNbS; ++nF) {
}
示例#7
0
//=======================================================================
//function : SortShapes
//purpose  :
//=======================================================================
void GEOMUtils::SortShapes (TopTools_ListOfShape& SL,
                            const Standard_Boolean isOldSorting)
{
#ifdef STD_SORT_ALGO
  std::vector<TopoDS_Shape> aShapesVec;
  aShapesVec.reserve(SL.Extent());

  TopTools_ListIteratorOfListOfShape it (SL);
  for (; it.More(); it.Next()) {
    aShapesVec.push_back(it.Value());
  }
  SL.Clear();

  CompareShapes shComp (isOldSorting);
  std::stable_sort(aShapesVec.begin(), aShapesVec.end(), shComp);
  //std::sort(aShapesVec.begin(), aShapesVec.end(), shComp);

  std::vector<TopoDS_Shape>::const_iterator anIter = aShapesVec.begin();
  for (; anIter != aShapesVec.end(); ++anIter) {
    SL.Append(*anIter);
  }
#else
  // old implementation
  Standard_Integer MaxShapes = SL.Extent();
  TopTools_Array1OfShape  aShapes (1,MaxShapes);
  TColStd_Array1OfInteger OrderInd(1,MaxShapes);
  TColStd_Array1OfReal    MidXYZ  (1,MaxShapes); //X,Y,Z;
  TColStd_Array1OfReal    Length  (1,MaxShapes); //X,Y,Z;

  // Computing of CentreOfMass
  Standard_Integer Index;
  GProp_GProps GPr;
  gp_Pnt GPoint;
  TopTools_ListIteratorOfListOfShape it(SL);
  for (Index=1;  it.More();  Index++)
  {
    TopoDS_Shape S = it.Value();
    SL.Remove( it ); // == it.Next()
    aShapes(Index) = S;
    OrderInd.SetValue (Index, Index);
    if (S.ShapeType() == TopAbs_VERTEX) {
      GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
      Length.SetValue( Index, (Standard_Real) S.Orientation());
    }
    else {
      // BEGIN: fix for Mantis issue 0020842
      if (isOldSorting) {
        BRepGProp::LinearProperties (S, GPr);
      }
      else {
        if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) {
          BRepGProp::LinearProperties (S, GPr);
        }
        else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) {
          BRepGProp::SurfaceProperties(S, GPr);
        }
        else {
          BRepGProp::VolumeProperties(S, GPr);
        }
      }
      // END: fix for Mantis issue 0020842
      GPoint = GPr.CentreOfMass();
      Length.SetValue(Index, GPr.Mass());
    }
    MidXYZ.SetValue(Index, GPoint.X()*999.0 + GPoint.Y()*99.0 + GPoint.Z()*0.9);
    //cout << Index << " L: " << Length(Index) << "CG: " << MidXYZ(Index) << endl;
  }

  // Sorting
  Standard_Integer aTemp;
  Standard_Boolean exchange, Sort = Standard_True;
  Standard_Real    tol = Precision::Confusion();
  while (Sort)
  {
    Sort = Standard_False;
    for (Index=1; Index < MaxShapes; Index++)
    {
      exchange = Standard_False;
      Standard_Real dMidXYZ = MidXYZ(OrderInd(Index)) - MidXYZ(OrderInd(Index+1));
      Standard_Real dLength = Length(OrderInd(Index)) - Length(OrderInd(Index+1));
      if ( dMidXYZ >= tol ) {
//         cout << "MidXYZ: " << MidXYZ(OrderInd(Index))<< " > " <<MidXYZ(OrderInd(Index+1))
//              << " d: " << dMidXYZ << endl;
        exchange = Standard_True;
      }
      else if ( Abs(dMidXYZ) < tol && dLength >= tol ) {
//         cout << "Length: " << Length(OrderInd(Index))<< " > " <<Length(OrderInd(Index+1))
//              << " d: " << dLength << endl;
        exchange = Standard_True;
      }
      else if ( Abs(dMidXYZ) < tol && Abs(dLength) < tol &&
                aShapes(OrderInd(Index)).ShapeType() <= TopAbs_FACE) {
        // PAL17233
        // equal values possible on shapes such as two halves of a sphere and
        // a membrane inside the sphere
        Bnd_Box box1,box2;
        BRepBndLib::Add( aShapes( OrderInd(Index) ), box1 );
        if ( box1.IsVoid() ) continue;
        BRepBndLib::Add( aShapes( OrderInd(Index+1) ), box2 );
        Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent();
        if ( dSquareExtent >= tol ) {
//           cout << "SquareExtent: " << box1.SquareExtent()<<" > "<<box2.SquareExtent() << endl;
          exchange = Standard_True;
        }
        else if ( Abs(dSquareExtent) < tol ) {
          Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2;
          box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
          val1 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
          box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
          val2 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
          //exchange = val1 > val2;
          if ((val1 - val2) >= tol) {
            exchange = Standard_True;
          }
          //cout << "box: " << val1<<" > "<<val2 << endl;
        }
      }

      if (exchange)
      {
//         cout << "exchange " << Index << " & " << Index+1 << endl;
        aTemp = OrderInd(Index);
        OrderInd(Index) = OrderInd(Index+1);
        OrderInd(Index+1) = aTemp;
        Sort = Standard_True;
      }
    }
  }

  for (Index=1; Index <= MaxShapes; Index++)
    SL.Append( aShapes( OrderInd(Index) ));
#endif
}
示例#8
0
//----------------------------------------------------------------
// Function: TopoDS_Shape level function to update the core Surface
//           for any movement  or Boolean operation of the body.
// Author: Jane Hu
//----------------------------------------------------------------
CubitStatus OCCSurface::update_OCC_entity(TopoDS_Face& old_surface,
                                          TopoDS_Shape& new_surface,
                                          BRepBuilderAPI_MakeShape *op,
                                          TopoDS_Vertex* removed_vertex,
                                          LocOpe_SplitShape* sp) 
{
  //set the Wires
  TopTools_IndexedMapOfShape M, M2;
  TopoDS_Shape shape, shape2, shape_edge, shape_vertex;
  TopExp::MapShapes(old_surface, TopAbs_WIRE, M);

  TopTools_ListOfShape shapes;  
  BRepFilletAPI_MakeFillet2d* test_op = NULL;

  for (int ii=1; ii<=M.Extent(); ii++) 
  {
     TopoDS_Wire wire = TopoDS::Wire(M(ii));
     TopTools_ListOfShape shapes;
     if(op)
     {
       test_op = dynamic_cast<BRepFilletAPI_MakeFillet2d*>(op);
       if(!test_op)
         shapes.Assign(op->Modified(wire));
       if(shapes.Extent() == 0)
         shapes.Assign(op->Generated(wire));
       if(!new_surface.IsNull())
         TopExp::MapShapes(new_surface,TopAbs_WIRE, M2);
     }
     else if(sp)
       shapes.Assign(sp->DescendantShapes(wire));

     if (shapes.Extent() == 1)
     {
       shape = shapes.First();
       if(M2.Extent() == 1)
       {
         shape2 = TopoDS::Wire(M2(1));
         if(!shape.IsSame(shape2))
           shape = shape2;
       }
       else if(M2.Extent() > 1)
         shape.Nullify();
     }
     else if(shapes.Extent() > 1)
       shape.Nullify();
     else if(op->IsDeleted(wire) || shapes.Extent() == 0)
     {
       TopTools_IndexedMapOfShape M_new;
       TopExp::MapShapes(new_surface, TopAbs_WIRE, M_new);
       if (M_new.Extent()== 1)
         shape = M_new(1);
       else
         shape.Nullify();
     }
     else
     {
       shape = wire;
       continue;
     }

     //set curves
     BRepTools_WireExplorer Ex;
      
     for(Ex.Init(wire); Ex.More();Ex.Next())
     {
       TopoDS_Edge edge = Ex.Current();
       if(op && !test_op)
       {
         shapes.Assign(op->Modified(edge));
         if(shapes.Extent() == 0)
           shapes.Assign(op->Generated(edge));
       }
         
       else if(sp)
         shapes.Assign(sp->DescendantShapes(edge));

       if (shapes.Extent() == 1)
       {
        //in fillet creating mothod, one edge could generated a face, so check
        //it here.
         TopAbs_ShapeEnum type = shapes.First().TShape()->ShapeType(); 
         if(type != TopAbs_EDGE)
           shape_edge.Nullify();
         else
           shape_edge = shapes.First();
       }
       else if (shapes.Extent() > 1)
       {
         //update all attributes first.
         TopTools_ListIteratorOfListOfShape it;
         it.Initialize(shapes);
         for(; it.More(); it.Next())
         {
           shape_edge = it.Value();
           OCCQueryEngine::instance()->copy_attributes(edge, shape_edge);
         }
         shape_edge.Nullify();
       }
       else if (op->IsDeleted(edge))
         shape_edge.Nullify(); 
       else if (test_op)
       {
         if(!test_op->IsModified(edge))
           shape_edge = edge;
         else
           shape_edge = (test_op->Modified(edge)).First();
       } 
       else
         shape_edge = edge;

       //update vertex
       TopoDS_Vertex vertex = Ex.CurrentVertex();
       shapes.Clear();
       if(test_op)
         assert(removed_vertex != NULL);

       if(op && ! test_op )
         shapes.Assign(op->Modified(vertex));
       else if(sp)
         shapes.Assign(sp->DescendantShapes(vertex));

       if (shapes.Extent() == 1)
         shape_vertex = shapes.First();

       else if(shapes.Extent() > 1)
       {
         //update all attributes first.
         TopTools_ListIteratorOfListOfShape it;
         it.Initialize(shapes);
         for(; it.More(); it.Next())
         {
           shape_vertex = it.Value();
           OCCQueryEngine::instance()->copy_attributes(vertex, shape_vertex);
         }
         shape_vertex.Nullify() ;
       }
       else if(op->IsDeleted(vertex) || (test_op && vertex.IsSame( *removed_vertex)))
         shape_vertex.Nullify() ;
         
       else
         shape_vertex = vertex;
      
       if(!vertex.IsSame(shape_vertex) )
         OCCQueryEngine::instance()->update_OCC_map(vertex, shape_vertex);

       if (!edge.IsSame(shape_edge))
         OCCQueryEngine::instance()->update_OCC_map(edge, shape_edge);
     }
     if (!wire.IsSame(shape))
       OCCQueryEngine::instance()->update_OCC_map(wire, shape);
  }
  double dTOL = OCCQueryEngine::instance()->get_sme_resabs_tolerance();
  if (!old_surface.IsSame(new_surface))
  {
    TopAbs_ShapeEnum shapetype =  TopAbs_SHAPE;
    if(!new_surface.IsNull())
      shapetype = new_surface.TShape()->ShapeType();  
    if(shapetype == TopAbs_FACE || new_surface.IsNull())
      OCCQueryEngine::instance()->update_OCC_map(old_surface, new_surface);
    else 
    {
      TopTools_IndexedMapOfShape M;
      TopExp::MapShapes(new_surface, TopAbs_FACE, M);   
      TopoDS_Shape new_shape;
      if(M.Extent() == 1)
        new_shape = M(1);
      else if(M.Extent() > 1)
      {
        for(int i = 1; i <= M.Extent(); i++)
        {
          GProp_GProps myProps;
          BRepGProp::SurfaceProperties(old_surface, myProps);
          double orig_mass = myProps.Mass();
          gp_Pnt orig_pnt = myProps.CentreOfMass();
          BRepGProp::SurfaceProperties(M(i), myProps);
          double after_mass = myProps.Mass();
          gp_Pnt after_pnt = myProps.CentreOfMass();
          if(fabs(-after_mass + orig_mass) <= dTOL && 
             orig_pnt.IsEqual(after_pnt, dTOL))
          {
            new_shape = M(i);
            break;
          }
        }
      }
      OCCQueryEngine::instance()->update_OCC_map(old_surface, new_shape);
    }
  }
  return CUBIT_SUCCESS;
}
//=======================================================================
//function : FillIn3DParts
//purpose  :
//=======================================================================
  void GEOMAlgo_Builder::FillIn3DParts()
{
  myErrorStatus=0;
  //
  const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
  NMTTools_PaveFiller* pPF=myPaveFiller;
  const Handle(IntTools_Context)& aCtx= pPF->Context();
  //
  Standard_Boolean bIsIN, bHasImage;
  Standard_Integer aNbS, aNbSolids, i, j, aNbFaces, aNbFP, aNbFPx, aNbFIN, aNbLIF;
  TopAbs_ShapeEnum aType;
  TopAbs_State aState;
  TopTools_IndexedMapOfShape aMSolids, aMS, aMFaces, aMFIN;
  TopTools_MapOfShape aMFDone;
  TopTools_IndexedDataMapOfShapeListOfShape aMEF;
  TopTools_ListIteratorOfListOfShape aItS;
  TopoDS_Iterator aIt, aItF;
  BRep_Builder aBB;
  TopoDS_Solid aSolidSp;
  TopoDS_Face aFP;
  //
  myDraftSolids.Clear();
  //
  aNbS=aDS.NumberOfShapesOfTheObject();
  for (i=1; i<=aNbS; ++i) {
    const TopoDS_Shape& aS=aDS.Shape(i);
    //
    aType=aS.ShapeType();
    if (aType==TopAbs_SOLID) {
      // all solids from DS
      aMSolids.Add(aS);
    }
    else if (aType==TopAbs_FACE) {
      // all faces (originals from DS or theirs images)
      if (myImages.HasImage(aS)) {
        const TopTools_ListOfShape& aLS=myImages.Image(aS);
        aItS.Initialize(aLS);
        for (; aItS.More(); aItS.Next()) {
          const TopoDS_Shape& aFx=aItS.Value();
          //
          if (mySameDomainShapes.Contains(aFx)) {
            const TopoDS_Shape& aFSDx=mySameDomainShapes.FindFromKey(aFx);
            aMFaces.Add(aFSDx);
          }
          else {
            aMFaces.Add(aFx);
          }
        }
      }
      else {
        if (mySameDomainShapes.Contains(aS)) {
          const TopoDS_Shape& aFSDx=mySameDomainShapes.FindFromKey(aS);
          aMFaces.Add(aFSDx);
        }
        else {
          aMFaces.Add(aS);
        }
      }
    }
  }
  //
  aNbFaces=aMFaces.Extent();
  aNbSolids=aMSolids.Extent();
  //
  for (i=1; i<=aNbSolids; ++i) {
    const TopoDS_Solid& aSolid=TopoDS::Solid(aMSolids(i));
    aMFDone.Clear();
    aMFIN.Clear();
    aMEF.Clear();
    //
    aBB.MakeSolid(aSolidSp);
    //
    TopTools_ListOfShape aLIF;
    //
    BuildDraftSolid(aSolid, aSolidSp, aLIF);
    aNbLIF=aLIF.Extent();
    //
    // 1 all faces/edges from aSolid [ aMS ]
    bHasImage=Standard_False;
    aMS.Clear();
    aIt.Initialize(aSolid);
    for (; aIt.More(); aIt.Next()) {
      const TopoDS_Shape& aShell=aIt.Value();
      //
      if (myImages.HasImage(aShell)) {
        bHasImage=Standard_True;
        //
        const TopTools_ListOfShape& aLS=myImages.Image(aShell);
        aItS.Initialize(aLS);
        for (; aItS.More(); aItS.Next()) {
          const TopoDS_Shape& aSx=aItS.Value();
          aMS.Add(aSx);
          TopExp::MapShapes(aSx, TopAbs_FACE, aMS);
          TopExp::MapShapes(aSx, TopAbs_EDGE, aMS);
          TopExp::MapShapesAndAncestors(aSx, TopAbs_EDGE, TopAbs_FACE, aMEF);
        }
      }
      else {
        //aMS.Add(aShell);
        TopExp::MapShapes(aShell, TopAbs_FACE, aMS);
        //modified by NIZNHY-PKV Fri Dec 03 11:18:45 2010f
        TopExp::MapShapes(aShell, TopAbs_EDGE, aMS);
        //modified by NIZNHY-PKV Fri Dec 03 11:18:51 2010t
        TopExp::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aMEF);
      }
    }
    //
    // 2 all faces that are not from aSolid [ aLFP1 ]
    Standard_Integer aNbEFP;
    TopTools_IndexedDataMapOfShapeListOfShape aMEFP;
    TopTools_ListIteratorOfListOfShape aItFP, aItEx;
    TopTools_MapOfShape aMFence;
    TopTools_ListOfShape aLFP1, aLFP2, aLFP, aLCBF, aLFIN, aLEx;//*pLFP,
    //
    // for all non-solid faces build EF map [ aMEFP ]
    for (j=1; j<=aNbFaces; ++j) {
      const TopoDS_Shape& aFace=aMFaces(j);
      if (!aMS.Contains(aFace)) {
        TopExp::MapShapesAndAncestors(aFace, TopAbs_EDGE, TopAbs_FACE, aMEFP);
      }
    }
    //
    // among all faces from aMEFP select these that have same edges
    // with the solid (i.e aMEF). These faces will be treated first
    // to prevent the usage of 3D classifier.
    // The full list of faces to process is aLFP1.
    aNbEFP=aMEFP.Extent();
    for (j=1; j<=aNbEFP; ++j) {
      const TopoDS_Shape& aE=aMEFP.FindKey(j);
      //
      if (aMEF.Contains(aE)) { // !!
        const TopTools_ListOfShape& aLF=aMEFP(j);
        aItFP.Initialize(aLF);
        for (; aItFP.More(); aItFP.Next()) {
          const TopoDS_Shape& aF=aItFP.Value();
          if (aMFence.Add(aF)) {
            aLFP1.Append(aF);
          }
        }
      }
      else {
        aLEx.Append(aE);
      }
    }
    //
    aItEx.Initialize(aLEx);
    for (; aItEx.More(); aItEx.Next()) {
      const TopoDS_Shape& aE=aItEx.Value();
      const TopTools_ListOfShape& aLF=aMEFP.FindFromKey(aE);
      aItFP.Initialize(aLF);
      for (; aItFP.More(); aItFP.Next()) {
        const TopoDS_Shape& aF=aItFP.Value();
        if (aMFence.Add(aF)) {
          aLFP2.Append(aF);
        }
      }
    }
    aLFP1.Append(aLFP2);
    //==========
    //
    // 3 Process faces aLFP1
    aNbFP=aLFP1.Extent();
    aItFP.Initialize(aLFP1);
    for (; aItFP.More(); aItFP.Next()) {
      const TopoDS_Shape& aSP=aItFP.Value();
      if (!aMFDone.Add(aSP)) {
        continue;
      }

      //
      // first face to process
      aFP=TopoDS::Face(aSP);
      bIsIN= GEOMAlgo_Tools3D::IsInternalFace(aFP, aSolidSp, aMEF, 1.e-14, aCtx);
      aState=(bIsIN) ? TopAbs_IN : TopAbs_OUT;
      //
      // collect faces to process [ aFP is the first ]
      aLFP.Clear();
      aLFP.Append(aFP);
      aItS.Initialize(aLFP1);
      for (; aItS.More(); aItS.Next()) {
        const TopoDS_Shape& aSk=aItS.Value();
        if (!aMFDone.Contains(aSk)) {
          aLFP.Append(aSk);
        }
      }
      //
      // Connexity Block that spreads from aFP the Bound
      // or till the end of the block itself
      aLCBF.Clear();
      GEOMAlgo_Tools3D::MakeConnexityBlock(aLFP, aMS, aLCBF);
      //
      // fill states for the Connexity Block
      aItS.Initialize(aLCBF);
      for (; aItS.More(); aItS.Next()) {
        const TopoDS_Shape& aSx=aItS.Value();
        aMFDone.Add(aSx);
        if (aState==TopAbs_IN) {
          aMFIN.Add(aSx);
        }
      }
      //
      aNbFPx=aMFDone.Extent();
      if (aNbFPx==aNbFP) {
        break;
      }
    }//for (; aItFP.More(); aItFP.Next())
    //
    // faces Inside aSolid
    aLFIN.Clear();
    aNbFIN=aMFIN.Extent();
    if (aNbFIN || aNbLIF) {
      for (j=1; j<=aNbFIN; ++j) {
        const TopoDS_Shape& aFIN=aMFIN(j);
        aLFIN.Append(aFIN);
      }
      //
      aItS.Initialize(aLIF);
      for (; aItS.More(); aItS.Next()) {
        const TopoDS_Shape& aFIN=aItS.Value();
        aLFIN.Append(aFIN);
      }
      //
      myInParts.Add(aSolid, aLFIN);
    }
    if (aNbFIN || bHasImage) {
      myDraftSolids.Add(aSolid, aSolidSp);
    }
  }//for (i=1; i<=aNbSolids; ++i) { // next solid
}
示例#10
0
//=======================================================================
// function: MakeConnexityBlock.
// purpose: 
//=======================================================================
  void GEOMAlgo_Tools3D::MakeConnexityBlock (const TopTools_ListOfShape& theLFIn,
                                             const TopTools_IndexedMapOfShape& theMEAvoid,
                                             TopTools_ListOfShape& theLCB)
{
  Standard_Integer  aNbF, aNbAdd1;
  TopExp_Explorer aExp;
  TopTools_IndexedDataMapOfShapeListOfShape aMEF;
  TopTools_MapIteratorOfMapOfShape aItM, aItM1;
  TopTools_MapOfShape aMCB, aMAdd, aMAdd1;
  TopTools_ListIteratorOfListOfShape aIt;
  //
  // 1. aMEF
  aNbF=theLFIn.Extent();
  aIt.Initialize(theLFIn);
  for (; aIt.More(); aIt.Next()) {
    const TopoDS_Shape& aF=aIt.Value();      
    TopExp::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
  }
  //
  // 2. aMCB
  const TopoDS_Shape& aF1=theLFIn.First();
  aMAdd.Add(aF1);
  //
  while(1) {
    aMAdd1.Clear();
    aItM.Initialize(aMAdd);
    for (; aItM.More(); aItM.Next()) {
      const TopoDS_Shape& aF=aItM.Key();
      //
      //aMAdd1.Clear();
      aExp.Init(aF, TopAbs_EDGE);
      for (; aExp.More(); aExp.Next()) {
        const TopoDS_Shape& aE=aExp.Current();
        if (theMEAvoid.Contains(aE)){
          continue;
        }
        //
        const TopTools_ListOfShape& aLF=aMEF.FindFromKey(aE);
        aIt.Initialize(aLF);
        for (; aIt.More(); aIt.Next()) {
          const TopoDS_Shape& aFx=aIt.Value();
          if (aFx.IsSame(aF)) {
            continue;
          }
          if (aMCB.Contains(aFx)) {
            continue;
          }
          aMAdd1.Add(aFx);
        }
      }//for (; aExp.More(); aExp.Next()){
      aMCB.Add(aF);
    }// for (; aItM.More(); aItM.Next()) {
    //
    aNbAdd1=aMAdd1.Extent();
    if (!aNbAdd1) {
      break;
    }
    //
    aMAdd.Clear();
    aItM1.Initialize(aMAdd1);
    for (; aItM1.More(); aItM1.Next()) {
      const TopoDS_Shape& aFAdd=aItM1.Key();
      aMAdd.Add(aFAdd);
    }
    //
  }//while(1) {
  
  //
  aNbF=aMCB.Extent();
  aItM.Initialize(aMCB);
  for (; aItM.More(); aItM.Next()) {
    const TopoDS_Shape& aF=aItM.Key();
    theLCB.Append(aF);
  }
}
示例#11
0
//----------------------------------------------------------------
// Function: TopoDS_Shape level function to update the core Body
//           for any Boolean operation of the body.
// Author: Jane Hu
//----------------------------------------------------------------
CubitStatus OCCBody::update_OCC_entity(TopoDS_Shape& old_shape,
                                       TopoDS_Shape& new_shape,
                                       BRepBuilderAPI_MakeShape *op,
                                       LocOpe_SplitShape* sp)
{
  //set the Shells
  TopTools_IndexedMapOfShape M;
  TopExp::MapShapes(old_shape, TopAbs_SOLID, M);
  TopTools_IndexedMapOfShape M_new;
  TopExp::MapShapes(new_shape, TopAbs_SOLID, M_new);
  TopTools_ListOfShape shapes;
  TopoDS_Shape shape;

  CubitBoolean updated = CUBIT_FALSE;	
  if(!old_shape.IsNull() && old_shape.ShapeType() == TopAbs_COMPOUND && 
     !new_shape.IsNull() && new_shape.ShapeType() == TopAbs_COMPOUND &&
     !old_shape.IsSame(new_shape))
  {
    //By updating underling solids, shells etc., the old_shape will get changed.
    //trying to make sure the the number of each entity in the old and new 
    //shapes are the same, which means that nothing is delete, that we can 
    //update the map here. Otherwise, when deleting solids, it'll delete the
    //the old body and create new body. This is Ok for general boolean operation    //except imprint when booleans are called, usually the original body are
    // supposed to be kept. 
    updated = CUBIT_TRUE;
    OCCQueryEngine::instance()->update_OCC_map(old_shape, new_shape);
  }
 
  DLIList<int> new_solid_nums;
  DLIList<int> unfound_nums;
  for(int ii=1; ii<=M.Extent(); ii++)
  {
    TopoDS_Solid solid = TopoDS::Solid(M(ii));

    TopTools_ListOfShape shapes;
    if(op)
    {
      shapes.Assign(op->Modified(solid));
      if(shapes.Extent() == 0)
         shapes.Assign(op->Generated(solid));
    }
    else if(sp)
      shapes.Assign(sp->DescendantShapes(solid));

    if (shapes.Extent() == 1)
      shape = shapes.First();

    else if(shapes.Extent() > 1)
    {
      //update all attributes first.
      TopTools_ListIteratorOfListOfShape it;
      it.Initialize(shapes);
      for(; it.More(); it.Next())
      {
        shape = it.Value();
        OCCQueryEngine::instance()->copy_attributes(solid, shape);
      } 
      shape = shapes.First();
    }

    else if(op->IsDeleted(solid))
    {
       if (M_new.Extent()== 1 && ii == 1)
         shape = M_new(1);
       else if(M_new.Extent()== 1 && ii > 1)
         shape.Nullify();
       else if(M_new.Extent() > 1)
       {
         GProp_GProps myProps;
         BRepGProp::VolumeProperties(solid, myProps);
         double bf_mass = myProps.Mass();
         gp_Pnt old_center = myProps.CentreOfMass();
         CubitBoolean found = CUBIT_FALSE;
         for(int l = 1; l <= M_new.Extent(); l++)
         {
           BRepGProp::VolumeProperties(M_new(l), myProps);
           double af_mass = myProps.Mass();
           double dTol = OCCQueryEngine::instance()->get_sme_resabs_tolerance();
           if(fabs(bf_mass-af_mass) < dTol) //unchanged
           {
             gp_Pnt  new_center = myProps.CentreOfMass(); 
             if(new_center.IsEqual(old_center, dTol))
             {
               found = CUBIT_TRUE;
               shape = M_new(l);
               new_solid_nums.append(l);
               break;
             }
           }
         }
         if(!found)
         {
           unfound_nums.append(ii); 
           continue;
         }
       }
       else
         shape.Nullify();
    }
    else
    {
       shape = solid;
       continue;
    }

    if(shapes.Extent() > 0 || (op && op->IsDeleted(solid)))
      OCCLump::update_OCC_entity(solid, shape, op, sp);
  }

  if( unfound_nums.size() == 1 )
  {
    TopoDS_Solid solid = TopoDS::Solid(M(unfound_nums.get()));
    for(int kk = 1; kk <= M_new.Extent(); kk++)
    {
      if(!new_solid_nums.move_to(kk))
      {
        shape = M_new(kk);
        break;
      } 
    }
    OCCLump::update_OCC_entity(solid, shape, op, sp);
  }
  else if(unfound_nums.size() > 1)
  {
    shape.Nullify();
    for(int kk = 1; kk <=unfound_nums.size(); kk++)
    {
       TopoDS_Solid solid = TopoDS::Solid(M(unfound_nums.get_and_step()));
       OCCLump::update_OCC_entity(solid, shape, op, sp);
    }
  } 
  if(!old_shape.IsSame(new_shape) && !updated)
    OCCQueryEngine::instance()->update_OCC_map(old_shape, new_shape);
  return CUBIT_SUCCESS;
}
示例#12
0
//=======================================================================
//function : SelectEdge
//purpose  : Find the edge <NE> connected <CE> by the vertex <CV> in the list <LE>.
//           <NE> Is erased  of the list. If <CE> is too in the list <LE> 
//			 with the same orientation, it's erased of the list 
//=======================================================================
static Standard_Boolean  SelectEdge(const TopoDS_Face&    F,
				    const TopoDS_Edge&    CE,
				    const TopoDS_Vertex&  CV,
				    TopoDS_Edge&          NE,
				    TopTools_ListOfShape& LE)
{
  TopTools_ListIteratorOfListOfShape itl;
  NE.Nullify();
  for ( itl.Initialize(LE); itl.More(); itl.Next()) {
    if (itl.Value().IsEqual(CE)) {
      LE.Remove(itl);
      break;
    }
  }

  if (LE.Extent() > 1) {
    //--------------------------------------------------------------
    // Several possible edges.   
    // - Test the edges differents of CE 
    //--------------------------------------------------------------
    Standard_Real   cf, cl, f, l;
    TopoDS_Face FForward = F;
    Handle(Geom2d_Curve) Cc, C;
    FForward.Orientation(TopAbs_FORWARD);
			
    Cc = BRep_Tool::CurveOnSurface(CE,FForward,cf,cl);
    Standard_Real dist,distmin  = 100*BRep_Tool::Tolerance(CV);
    Standard_Real uc,u;
    if (CE.Orientation () == TopAbs_FORWARD) uc = cl;
    else                                     uc = cf;

    gp_Pnt2d P2,PV = Cc->Value(uc); 

    Standard_Real delta = FindDelta(LE,FForward);

    for ( itl.Initialize(LE); itl.More(); itl.Next()) {
      const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
      if (!E.IsSame(CE)) {
	C = BRep_Tool::CurveOnSurface(E,FForward,f,l);
	if (E.Orientation () == TopAbs_FORWARD) u = f;
	else                                    u = l;
	P2 = C->Value(u);
	dist = PV.Distance(P2);
	if (dist <= distmin){
	  distmin = dist;
	}
				
      }
    }

    Standard_Real anglemax = - PI;
    TopoDS_Edge   SelectedEdge;	
    for ( itl.Initialize(LE); itl.More(); itl.Next()) {
      const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
      if (!E.IsSame(CE)) {
	C = BRep_Tool::CurveOnSurface(E,FForward,f,l);
	if (E.Orientation () == TopAbs_FORWARD) u = f;
	else                                    u = l;
	P2 = C->Value(u);
	dist = PV.Distance(P2);
	if (dist <= distmin + (1./3)*delta){ 
	  gp_Pnt2d PC, P;
	  gp_Vec2d CTg1, CTg2, Tg1, Tg2;
	  Cc->D2(uc, PC, CTg1, CTg2);
	  C->D2(u, P, Tg1, Tg2);

	  Standard_Real angle;

	  if (CE.Orientation () == TopAbs_REVERSED && E.Orientation () == TopAbs_FORWARD) {
	    angle = CTg1.Angle(Tg1.Reversed());
	  }
	  else if (CE.Orientation () == TopAbs_FORWARD && E.Orientation () == TopAbs_REVERSED) {
	    angle = (CTg1.Reversed()).Angle(Tg1);
	  }
	  else if (CE.Orientation () == TopAbs_REVERSED && E.Orientation () == TopAbs_REVERSED) {
	    angle = CTg1.Angle(Tg1);
	  }
	  else if (CE.Orientation () == TopAbs_FORWARD && E.Orientation () == TopAbs_FORWARD) {
	    angle = (CTg1.Reversed()).Angle(Tg1.Reversed());
	  }
	  if (angle >= anglemax) {
	    anglemax = angle ;
	    SelectedEdge = E;	
	  }
	}
      }
    }
    for ( itl.Initialize(LE); itl.More(); itl.Next()) {
      const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
      if (E.IsEqual(SelectedEdge)) {
	NE = TopoDS::Edge(E);
	LE.Remove(itl);
	break;
      }
    }					
  }
  else if (LE.Extent() == 1) {
    NE = TopoDS::Edge(LE.First());
    LE.RemoveFirst();
  }
  else {
    return Standard_False;
  }
  return Standard_True;
}