Exemplo n.º 1
0
//=======================================================================
//function :  CloseContour
//purpose  :
//=======================================================================
Standard_Boolean GEOMImpl_HealingDriver::CloseContour (GEOMImpl_IHealing* theHI,
                                                       const TopoDS_Shape& theOriginalShape,
                                                       TopoDS_Shape& theOutShape) const
{
  Standard_Boolean isByVertex = theHI->GetIsCommonVertex();
  Handle(TColStd_HArray1OfInteger) aWires = theHI->GetWires();

  ShHealOper_CloseContour aHealer (theOriginalShape);

  Standard_Boolean aResult = Standard_False;
  if ( aWires.IsNull() ) {
    if ( theOriginalShape.ShapeType() == TopAbs_WIRE )
      aResult = aHealer.Perform(TopoDS::Wire(theOriginalShape), isByVertex, !isByVertex);
  }
  else {
    TopTools_SequenceOfShape aShapesWires;
    TopTools_IndexedMapOfShape aShapes;
    TopExp::MapShapes(theOriginalShape, aShapes);
    for (int i = 1; i <= aWires->Length(); i++) {
      int indexOfWire = aWires->Value(i);
      TopoDS_Shape aWire = aShapes.FindKey(indexOfWire);
      aShapesWires.Append(aWire);
    }

    aResult = aHealer.Perform( aShapesWires, isByVertex, !isByVertex );
  }

  if (aResult)
    theOutShape = aHealer.GetResultShape();
  else
    raiseNotDoneExeption( aHealer.GetErrorStatus() );

  return aResult;
}
Exemplo n.º 2
0
//=======================================================================
//function :  RemoveHoles
//purpose  :
//=======================================================================
Standard_Boolean GEOMImpl_HealingDriver::RemoveHoles (GEOMImpl_IHealing* theHI,
                                                      const TopoDS_Shape& theOriginalShape,
                                                      TopoDS_Shape& theOutShape) const
{
  Handle(TColStd_HArray1OfInteger) aWires = theHI->GetWires();

  ShHealOper_FillHoles aHealer (theOriginalShape);

  Standard_Boolean aResult = Standard_False;
  if (aWires.IsNull()) { // remove all faces
    aResult = aHealer.Fill();
  } else {
    TopTools_SequenceOfShape aShapesWires;
    TopTools_IndexedMapOfShape aShapes;
    TopExp::MapShapes(theOriginalShape, aShapes);
    for (int i = 1; i <= aWires->Length(); i++) {
      int indexOfWire = aWires->Value(i);
      TopoDS_Shape aWire = aShapes.FindKey(indexOfWire);
      aShapesWires.Append(aWire);
    }

    aResult = aHealer.Fill(aShapesWires);
  }

  if (aResult)
    theOutShape = aHealer.GetResultShape();
  else
    raiseNotDoneExeption( aHealer.GetErrorStatus() );

  return aResult;
}
Exemplo n.º 3
0
Standard_Boolean ShHealOper_FillHoles::Fill()
{
  ShapeAnalysis_FreeBounds sab(myInitShape);
  TopoDS_Compound aCompClosed = sab.GetClosedWires();
  TopoDS_Compound aCompOpen = sab.GetOpenWires();
  TopTools_SequenceOfShape aFillWires;
  if(!aCompClosed.IsNull()) {
    TopoDS_Iterator aIt(aCompClosed);

    for( ; aIt.More(); aIt.Next()) 
      aFillWires.Append(aIt.Value());
  }
  if(!aCompOpen.IsNull()) {
    TopoDS_Iterator aIt(aCompOpen);
    for(  ; aIt.More(); aIt.Next()) 
      aFillWires.Append(aIt.Value());
  }
  
  TopExp_Explorer aExp(myInitShape,TopAbs_EDGE,TopAbs_FACE);
  
  for( ; aExp.More(); aExp.Next())
    aFillWires.Append(aExp.Current());

  return Fill(aFillWires);
}
Exemplo n.º 4
0
//=======================================================================
//function :  SupressFaces
//purpose  :
//=======================================================================
void SuppressFacesRec (const TopTools_SequenceOfShape& theShapesFaces,
                       const TopoDS_Shape&             theOriginalShape,
                       TopoDS_Shape&                   theOutShape)
{
  if ((theOriginalShape.ShapeType() != TopAbs_COMPOUND &&
       theOriginalShape.ShapeType() != TopAbs_COMPSOLID))
  {
    ShHealOper_RemoveFace aHealer (theOriginalShape);
    Standard_Boolean aResult = aHealer.Perform(theShapesFaces);

    if (aResult)
      theOutShape = aHealer.GetResultShape();
    else
      raiseNotDoneExeption(aHealer.GetErrorStatus());
  }
  else
  {
    BRep_Builder BB;
    TopoDS_Compound CC;
    BB.MakeCompound(CC);

    TopTools_MapOfShape mapShape;
    TopoDS_Iterator It (theOriginalShape, Standard_True, Standard_True);

    for (; It.More(); It.Next()) {
      TopoDS_Shape aShape_i = It.Value();
      if (mapShape.Add(aShape_i)) {
        // check, if current shape contains at least one of faces to be removed
        bool isFound = false;
        TopTools_IndexedMapOfShape aShapes_i;
        TopExp::MapShapes(aShape_i, aShapes_i);
        for (int i = 1; i <= theShapesFaces.Length() && !isFound; i++) {
          const TopoDS_Shape& aFace_i = theShapesFaces.Value(i);
          if (aShapes_i.Contains(aFace_i)) isFound = true;
        }
        if (isFound) {
          TopoDS_Shape anOutSh_i;
          SuppressFacesRec(theShapesFaces, aShape_i, anOutSh_i);
          if ( !anOutSh_i.IsNull() )
            BB.Add(CC, anOutSh_i);
        }
        else {
          // nothing to do
          BB.Add(CC, aShape_i);
        }
      }
    }
    theOutShape = CC;
  }
}
Exemplo n.º 5
0
Standard_Boolean ShHealOper_Sewing::sewing(const TopTools_SequenceOfShape& theSeqShapes)
{
  myDone = Standard_False;
  myErrorStatus = ShHealOper_NotError;
  if(myInitShape.IsNull()) {
    myErrorStatus = ShHealOper_InvalidParameters;
    return myDone;
  }
  //sewing shape
  Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
  aSewing->Load(myInitShape);
  aSewing->SetTolerance(myTolerance);
  aSewing->SetFaceMode(myFacesMode);
  aSewing->SetFloatingEdgesMode(myEdgesMode);
  aSewing->SetNonManifoldMode(myNonManifoldMode);
  Standard_Integer j =1;
  for( ; j <= theSeqShapes.Length();j++)
    aSewing->Add(theSeqShapes.Value(j));

  aSewing->Perform();
  const TopoDS_Shape aSewShape = aSewing->SewedShape();
  if(aSewShape.IsNull()) {
    myErrorStatus = ShHealOper_ErrorExecution;
    return myDone;
  }
  if(aSewShape.IsSame(myInitShape))
    return myDone;

  //analysis either sewing was made by changing number of shells
  myDone = isSewed(aSewShape);

  //keep modification of the subshapes in the Context.
  TopExp_Explorer aExp(myInitShape,TopAbs_FACE);
  for( ; aExp.More(); aExp.Next())
    myDone = (getModifications( aExp.Current(),aSewing) || myDone);

  TopoDS_Shape aTempShape = myContext->Apply(aSewShape);
  //obtained shells with fixed orientation for manifold and nonmanifold shells
  if(myFacesMode) 
    myDone = getShells(aTempShape) || myDone;

  //obtained manifold wires if sewing edges was performed.
  if(myEdgesMode) 
    myDone = getWires(aTempShape) || myDone;
  
  if(myDone)
    myResultShape = myContext->Apply(aTempShape);
    
  return myDone;
}
Exemplo n.º 6
0
Standard_Boolean ShHealOper_FillHoles::Fill(const TopTools_SequenceOfShape& theFillShapes)
{
  myDone = Standard_False;
  myErrorStatus = ShHealOper_NotError;
  if(myInitShape.IsNull()) {
    myErrorStatus = ShHealOper_InvalidParameters;
    return myDone;
  }
  if(!theFillShapes.Length()) {
    return myDone;
  }

  Handle(TopTools_HSequenceOfShape) aSeqWires = new TopTools_HSequenceOfShape;
  if(!prepareWires(theFillShapes,aSeqWires)) {
    myErrorStatus = ShHealOper_InvalidParameters;
    return myDone;
  }

  myResultShape = myInitShape;
  Standard_Integer i =1;
  for( ; i <= aSeqWires->Length(); i++) {
    TopoDS_Wire aWire = TopoDS::Wire(aSeqWires->Value(i));
    Handle(TColGeom2d_HArray1OfCurve) aCurves2d;
    Handle(TColStd_HArray1OfInteger) aOrders;
    Handle(TColStd_HArray1OfInteger) aSenses;
    Handle(Geom_Surface) aSurf = buildSurface(aWire,aCurves2d,aOrders,aSenses);
    if(aSurf.IsNull())
      myErrorStatus = ShHealOper_ErrorExecution;
    else 
      myDone = (addFace(aSurf,aWire,aCurves2d,aOrders,aSenses) || myDone);
  }
  if(myDone)
    myResultShape = myContext->Apply(myResultShape);
  return myDone;
}
Standard_Boolean ShHealOper_RemoveFace::Perform(const TopTools_SequenceOfShape& theRemoveFaces)
{
  myDone = Standard_False;
  myErrorStatus = ShHealOper_NotError;
  if(myInitShape.IsNull()) {
    myErrorStatus = ShHealOper_InvalidParameters;
    return myDone;
  }
  if(theRemoveFaces.IsEmpty())
    return Standard_False;
  myMapFaces.Clear();
  
  Standard_Integer i=1; 
  for( ; i <= theRemoveFaces.Length(); i++)
    myMapFaces.Add(theRemoveFaces.Value(i));
  
  myDone = removeFaces(myInitShape,myResultShape);
  return myDone;
}
CCPACSFuselageProfileGetPointAlgo::CCPACSFuselageProfileGetPointAlgo (const TopTools_SequenceOfShape& wireContainer)
{
    try {
        if (wireContainer.Length()!=1) {
            throw CTiglError("Error: CCPACSWingProfileGetPointAlgo: Number of wires is not equal 1", TIGL_ERROR);
        }
        wire = TopoDS::Wire(wireContainer(1));
    }
    catch(...) {
        throw CTiglError("Error: CCPACSFuselageProfileGetPointAlgo: Conversion of shape to wire failed", TIGL_ERROR);
    }
    wireLength = GetWireLength(wire);
}
Exemplo n.º 9
0
Standard_Boolean GEOMImpl_HealingDriver::SuppressFaces (GEOMImpl_IHealing* theHI,
                                                        const TopoDS_Shape& theOriginalShape,
                                                        TopoDS_Shape& theOutShape) const
{
  Handle(TColStd_HArray1OfInteger) aFaces = theHI->GetFaces();

  Standard_Boolean aResult = Standard_False;

  if (aFaces.IsNull()) {
    ShHealOper_RemoveFace aHealer (theOriginalShape);
    aResult = aHealer.Perform();

    if (aResult)
      theOutShape = aHealer.GetResultShape();
    else
      raiseNotDoneExeption(aHealer.GetErrorStatus());
  }
  else {
    TopTools_SequenceOfShape aShapesFaces;
    TopTools_IndexedMapOfShape aShapes;
    TopExp::MapShapes(theOriginalShape, aShapes);
    for (int i = 1; i <= aFaces->Length(); i++) {
      int indexOfFace = aFaces->Value(i);
      TopoDS_Shape aFace = aShapes.FindKey(indexOfFace);
      aShapesFaces.Append(aFace);
    }
    SuppressFacesRec(aShapesFaces, theOriginalShape, theOutShape);
    if ((theOriginalShape.ShapeType() == TopAbs_COMPOUND ||
         theOriginalShape.ShapeType() == TopAbs_COMPSOLID)) {
      TopoDS_Shape aSh = theOutShape;
      theOutShape = GEOMImpl_GlueDriver::GlueFaces(aSh, Precision::Confusion(), Standard_True);
    }
  }

  return Standard_True;
}
Exemplo n.º 10
0
//=======================================================================
//function : MergeEdges
//purpose  : auxilary
//=======================================================================
static Standard_Boolean MergeEdges(const TopTools_SequenceOfShape& SeqEdges,
                                   const TopoDS_Face& aFace,
                                   const Standard_Real Tol,
                                   TopoDS_Edge& anEdge)
{
  // make chain for union
  BRep_Builder B;
  ShapeAnalysis_Edge sae;
  TopoDS_Edge FirstE = TopoDS::Edge(SeqEdges.Value(1));
  TopoDS_Edge LastE = FirstE;
  TopoDS_Vertex VF = sae.FirstVertex(FirstE);
  TopoDS_Vertex VL = sae.LastVertex(LastE);
  TopTools_SequenceOfShape aChain;
  aChain.Append(FirstE);
  TColStd_MapOfInteger IndUsedEdges;
  IndUsedEdges.Add(1);
  Standard_Integer j;
  for(j=2; j<=SeqEdges.Length(); j++) {
    for(Standard_Integer k=2; k<=SeqEdges.Length(); k++) {
      if(IndUsedEdges.Contains(k)) continue;
      TopoDS_Edge edge = TopoDS::Edge(SeqEdges.Value(k));
      TopoDS_Vertex VF2 = sae.FirstVertex(edge);
      TopoDS_Vertex VL2 = sae.LastVertex(edge);
      if(sae.FirstVertex(edge).IsSame(VL)) {
        aChain.Append(edge);
        LastE = edge;
        VL = sae.LastVertex(LastE);
        IndUsedEdges.Add(k);
      }
      else if(sae.LastVertex(edge).IsSame(VF)) {
        aChain.Prepend(edge);
        FirstE = edge;
        VF = sae.FirstVertex(FirstE);
        IndUsedEdges.Add(k);
      }
    }
  }
  if(aChain.Length()<SeqEdges.Length()) {
    MESSAGE ("can not create correct chain...");
    return Standard_False;
  }
  // union edges in chain
  // first step: union lines and circles
  TopLoc_Location Loc;
  Standard_Real fp1,lp1,fp2,lp2;
  for(j=1; j<aChain.Length(); j++) {
    TopoDS_Edge edge1 = TopoDS::Edge(aChain.Value(j));
    Handle(Geom_Curve) c3d1 = BRep_Tool::Curve(edge1,Loc,fp1,lp1);
    if(c3d1.IsNull()) break;
    while(c3d1->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
      Handle(Geom_TrimmedCurve) tc =
        Handle(Geom_TrimmedCurve)::DownCast(c3d1);
      c3d1 = tc->BasisCurve();
    }
    TopoDS_Edge edge2 = TopoDS::Edge(aChain.Value(j+1));
    Handle(Geom_Curve) c3d2 = BRep_Tool::Curve(edge2,Loc,fp2,lp2);
    if(c3d2.IsNull()) break;
    while(c3d2->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
      Handle(Geom_TrimmedCurve) tc =
        Handle(Geom_TrimmedCurve)::DownCast(c3d2);
      c3d2 = tc->BasisCurve();
    }
    if( c3d1->IsKind(STANDARD_TYPE(Geom_Line)) && c3d2->IsKind(STANDARD_TYPE(Geom_Line)) ) {
      // union lines
      Handle(Geom_Line) L1 = Handle(Geom_Line)::DownCast(c3d1);
      Handle(Geom_Line) L2 = Handle(Geom_Line)::DownCast(c3d2);
      gp_Dir Dir1 = L1->Position().Direction();
      gp_Dir Dir2 = L2->Position().Direction();
      //if(!Dir1.IsEqual(Dir2,Precision::Angular())) { 
      //if(!Dir1.IsParallel(Dir2,Precision::Angular())) { 
      if(!Dir1.IsParallel(Dir2,Tol)) { 
        continue;
      }
      // can union lines => create new edge
      TopoDS_Vertex V1 = sae.FirstVertex(edge1);
      gp_Pnt PV1 = BRep_Tool::Pnt(V1);
      TopoDS_Vertex V2 = sae.LastVertex(edge2);
      gp_Pnt PV2 = BRep_Tool::Pnt(V2);
      gp_Vec Vec(PV1,PV2);
      Handle(Geom_Line) L = new Geom_Line(gp_Ax1(PV1,Vec));
      Standard_Real dist = PV1.Distance(PV2);
      Handle(Geom_TrimmedCurve) tc = new Geom_TrimmedCurve(L,0.0,dist);
      TopoDS_Edge E;
      B.MakeEdge (E,tc,Precision::Confusion());
      B.Add (E,V1);  B.Add (E,V2);
      B.UpdateVertex(V1, 0., E, 0.);
      B.UpdateVertex(V2, dist, E, 0.);
      //ShapeFix_Edge sfe;
      //sfe.FixAddPCurve(E,aFace,Standard_False);
      //sfe.FixSameParameter(E);
      aChain.Remove(j);
      aChain.SetValue(j,E);
      j--;
    }
    if( c3d1->IsKind(STANDARD_TYPE(Geom_Circle)) && c3d2->IsKind(STANDARD_TYPE(Geom_Circle)) ) {
      // union circles
      Handle(Geom_Circle) C1 = Handle(Geom_Circle)::DownCast(c3d1);
      Handle(Geom_Circle) C2 = Handle(Geom_Circle)::DownCast(c3d2);
      gp_Pnt P01 = C1->Location();
      gp_Pnt P02 = C2->Location();
      if (P01.Distance(P02) > Precision::Confusion()) continue;
      // can union circles => create new edge
      TopoDS_Vertex V1 = sae.FirstVertex(edge1);
      gp_Pnt PV1 = BRep_Tool::Pnt(V1);
      TopoDS_Vertex V2 = sae.LastVertex(edge2);
      gp_Pnt PV2 = BRep_Tool::Pnt(V2);
      TopoDS_Vertex VM = sae.LastVertex(edge1);
      gp_Pnt PVM = BRep_Tool::Pnt(VM);
      GC_MakeCircle MC (PV1,PVM,PV2);
      Handle(Geom_Circle) C = MC.Value();
      TopoDS_Edge E;
      if (!MC.IsDone() || C.IsNull()) {
        // jfa for Mantis issue 0020228
        if (PV1.Distance(PV2) > Precision::Confusion()) continue;
        // closed chain
        C = C1;
        B.MakeEdge (E,C,Precision::Confusion());
        B.Add(E,V1);
        B.Add(E,V2);
      }
      else {
        gp_Pnt P0 = C->Location();
        gp_Dir D1(gp_Vec(P0,PV1));
        gp_Dir D2(gp_Vec(P0,PV2));
        Standard_Real fpar = C->XAxis().Direction().Angle(D1);
        if(fabs(fpar)>Precision::Confusion()) {
          // check orientation
          gp_Dir ND =  C->XAxis().Direction().Crossed(D1);
          if(ND.IsOpposite(C->Axis().Direction(),Precision::Confusion())) {
            fpar = -fpar;
          }
        }
        Standard_Real lpar = C->XAxis().Direction().Angle(D2);
        if(fabs(lpar)>Precision::Confusion()) {
          // check orientation
          gp_Dir ND =  C->XAxis().Direction().Crossed(D2);
          if(ND.IsOpposite(C->Axis().Direction(),Precision::Confusion())) {
            lpar = -lpar;
          }
        }
        if(lpar<fpar) lpar += 2*M_PI;
        Handle(Geom_TrimmedCurve) tc = new Geom_TrimmedCurve(C,fpar,lpar);
        B.MakeEdge (E,tc,Precision::Confusion());
        B.Add(E,V1);
        B.Add(E,V2);
        B.UpdateVertex(V1, fpar, E, 0.);
        B.UpdateVertex(V2, lpar, E, 0.);
      }
      aChain.Remove(j);
      aChain.SetValue(j,E);
      j--;
    }
  }
  if (j < aChain.Length()) {
    MESSAGE ("null curve3d in edge...");
    return Standard_False;
  }
  if (aChain.Length() > 1) {
    // second step: union edges with various curves
    // skl for bug 0020052 from Mantis: perform such unions
    // only if curves are bspline or bezier
    bool NeedUnion = true;
    for(j=1; j<=aChain.Length(); j++) {
      TopoDS_Edge edge = TopoDS::Edge(aChain.Value(j));
      Handle(Geom_Curve) c3d = BRep_Tool::Curve(edge,Loc,fp1,lp1);
      if(c3d.IsNull()) continue;
      while(c3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
        Handle(Geom_TrimmedCurve) tc =
          Handle(Geom_TrimmedCurve)::DownCast(c3d);
        c3d = tc->BasisCurve();
      }
      if( ( c3d->IsKind(STANDARD_TYPE(Geom_BSplineCurve)) ||
            c3d->IsKind(STANDARD_TYPE(Geom_BezierCurve)) ) ) continue;
      NeedUnion = false;
      break;
    }
    if(NeedUnion) {
      MESSAGE ("can not make analitical union => make approximation");
      TopoDS_Wire W;
      B.MakeWire(W);
      for(j=1; j<=aChain.Length(); j++) {
        TopoDS_Edge edge = TopoDS::Edge(aChain.Value(j));
        B.Add(W,edge);
      }
      Handle(BRepAdaptor_HCompCurve) Adapt = new BRepAdaptor_HCompCurve(W);
      Approx_Curve3d Conv(Adapt,Tol,GeomAbs_C1,9,1000);
      Handle(Geom_BSplineCurve) bc = Conv.Curve();
      TopoDS_Edge E;
      B.MakeEdge (E,bc,Precision::Confusion());
      B.Add (E,VF);
      B.Add (E,VL);
      aChain.SetValue(1,E);
    }
    else {
      MESSAGE ("can not make approximation for such types of curves");
      return Standard_False;
    }
  }

  anEdge = TopoDS::Edge(aChain.Value(1));
  return Standard_True;
}
Exemplo n.º 11
0
TopoDS_Shape BlockFix_UnionEdges::Perform(const TopoDS_Shape& Shape,
                                          const Standard_Real Tol)
{
  myContext = new ShapeBuild_ReShape;
  myTolerance = Tol;
  TopoDS_Shape aResult = myContext->Apply(Shape);

  // processing each solid
  TopAbs_ShapeEnum aType = TopAbs_SOLID;
  TopExp_Explorer exps (Shape, aType);
  if (!exps.More()) {
    aType = TopAbs_SHELL;
    exps.Init(Shape, aType);
  }
  for (; exps.More(); exps.Next()) {
    //TopoDS_Solid aSolid = TopoDS::Solid(exps.Current());
    TopoDS_Shape aSolid = exps.Current();

    TopTools_IndexedMapOfShape ChangedFaces;

    // creating map of edge faces
    TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces;
    TopExp::MapShapesAndAncestors(aSolid, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces);

    Handle(ShapeBuild_ReShape) aContext = new ShapeBuild_ReShape;
    TopoDS_Shape aRes = aSolid;
    aRes = aContext->Apply(aSolid);

    // processing each face
    TopExp_Explorer exp;
    for (exp.Init(aRes, TopAbs_FACE); exp.More(); exp.Next()) {
      TopoDS_Face aFace =
        TopoDS::Face(aContext->Apply(exp.Current().Oriented(TopAbs_FORWARD)));
      TopTools_IndexedDataMapOfShapeListOfShape aMapFacesEdges;

      for (TopExp_Explorer expe(aFace,TopAbs_EDGE); expe.More(); expe.Next()) {
        TopoDS_Edge edge = TopoDS::Edge(expe.Current());
        if (!aMapEdgeFaces.Contains(edge)) continue;
        const TopTools_ListOfShape& aList = aMapEdgeFaces.FindFromKey(edge);
        TopTools_ListIteratorOfListOfShape anIter(aList);
        for ( ; anIter.More(); anIter.Next()) {
          TopoDS_Face face = TopoDS::Face(anIter.Value());
          TopoDS_Face face1 = TopoDS::Face(aContext->Apply(anIter.Value()));
          if (face1.IsSame(aFace)) continue;
          if (aMapFacesEdges.Contains(face)) {
            aMapFacesEdges.ChangeFromKey(face).Append(edge);
          }
          else {
            TopTools_ListOfShape ListEdges;
            ListEdges.Append(edge);
            aMapFacesEdges.Add(face,ListEdges);
          }
        }
      }

      for (Standard_Integer i=1; i<=aMapFacesEdges.Extent(); i++) {
        const TopTools_ListOfShape& ListEdges = aMapFacesEdges.FindFromIndex(i);
        TopTools_SequenceOfShape SeqEdges;
        TopTools_ListIteratorOfListOfShape anIter(ListEdges);
        for ( ; anIter.More(); anIter.Next()) {
          SeqEdges.Append(anIter.Value());
        }
        if (SeqEdges.Length()==1) continue;
        TopoDS_Edge E;
        if ( MergeEdges(SeqEdges,aFace,Tol,E) ) {
          // now we have only one edge - aChain.Value(1)
          // we have to replace old ListEdges with this new edge
          aContext->Replace(SeqEdges(1),E);
          for (Standard_Integer j=2; j<=SeqEdges.Length(); j++) {
            aContext->Remove(SeqEdges(j));
          }
          TopoDS_Face tmpF = TopoDS::Face(exp.Current());
          if ( !ChangedFaces.Contains(tmpF) )
            ChangedFaces.Add(tmpF);
          tmpF = TopoDS::Face(aMapFacesEdges.FindKey(i));
          if ( !ChangedFaces.Contains(tmpF) )
            ChangedFaces.Add(tmpF);
        }
      }

    } // end processing each face

    // fix changed faces and replace them in the local context
    for (Standard_Integer i=1; i<=ChangedFaces.Extent(); i++) {
      TopoDS_Face aFace = TopoDS::Face(aContext->Apply(ChangedFaces.FindKey(i)));
      Handle(ShapeFix_Face) sff = new ShapeFix_Face(aFace);
      sff->SetContext(myContext);
      sff->SetPrecision(myTolerance);
      sff->SetMinTolerance(myTolerance);
      sff->SetMaxTolerance(Max(1.,myTolerance*1000.));
      sff->Perform();
      aContext->Replace(aFace,sff->Face());
    }

    if (ChangedFaces.Extent() > 0) {
      // fix changed shell and replace it in the local context
      TopoDS_Shape aRes1 = aContext->Apply(aRes);
      TopExp_Explorer expsh;
      for (expsh.Init(aRes1, TopAbs_SHELL); expsh.More(); expsh.Next()) {
        TopoDS_Shell aShell = TopoDS::Shell(expsh.Current());
        Handle(ShapeFix_Shell) sfsh = new ShapeFix_Shell;
        sfsh->FixFaceOrientation(aShell);
        aContext->Replace(aShell,sfsh->Shell());
      }
      TopoDS_Shape aRes2 = aContext->Apply(aRes1);
      // put new solid into global context
      myContext->Replace(aSolid,aRes2);
    }

  } // end processing each solid

  aResult = myContext->Apply(Shape);
  return aResult;
}
Exemplo n.º 12
0
//=======================================================================
//function : GlueEdgesWithPCurves
//purpose  : Glues the pcurves of the sequence of edges
//           and glues their 3d curves
//=======================================================================
static TopoDS_Edge GlueEdgesWithPCurves(const TopTools_SequenceOfShape& aChain,
                                        const TopoDS_Vertex& FirstVertex,
                                        const TopoDS_Vertex& LastVertex)
{
  Standard_Integer i, j;

  TopoDS_Edge FirstEdge = TopoDS::Edge(aChain(1));
  //TColGeom2d_SequenceOfCurve PCurveSeq;
  TColGeom_SequenceOfSurface SurfSeq;
  //TopTools_SequenceOfShape LocSeq;
  
  BRep_ListIteratorOfListOfCurveRepresentation itr( (Handle(BRep_TEdge)::DownCast(FirstEdge.TShape()))->Curves() );
  for (; itr.More(); itr.Next())
  {
    Handle(BRep_CurveRepresentation) CurveRep = itr.Value();
    if (CurveRep->IsCurveOnSurface())
    {
      //PCurveSeq.Append(CurveRep->PCurve());
      SurfSeq.Append(CurveRep->Surface());
      /*
      TopoDS_Shape aLocShape;
      aLocShape.Location(CurveRep->Location());
      LocSeq.Append(aLocShape);
      */
    }
  }

  Standard_Real fpar, lpar;
  BRep_Tool::Range(FirstEdge, fpar, lpar);
  TopoDS_Edge PrevEdge = FirstEdge;
  TopoDS_Vertex CV;
  Standard_Real MaxTol = 0.;
  
  TopoDS_Edge ResEdge;
  BRep_Builder BB;

  Standard_Integer nb_curve = aChain.Length();   //number of curves
  TColGeom_Array1OfBSplineCurve tab_c3d(0,nb_curve-1);                    //array of the curves
  TColStd_Array1OfReal tabtolvertex(0,nb_curve-1); //(0,nb_curve-2);  //array of the tolerances
    
  TopoDS_Vertex PrevVertex = FirstVertex;
  for (i = 1; i <= nb_curve; i++)
  {
    TopoDS_Edge anEdge = TopoDS::Edge(aChain(i));
    TopoDS_Vertex VF, VL;
    TopExp::Vertices(anEdge, VF, VL);
    Standard_Boolean ToReverse = (!VF.IsSame(PrevVertex));
    
    Standard_Real Tol1 = BRep_Tool::Tolerance(VF);
    Standard_Real Tol2 = BRep_Tool::Tolerance(VL);
    if (Tol1 > MaxTol)
      MaxTol = Tol1;
    if (Tol2 > MaxTol)
      MaxTol = Tol2;
    
    if (i > 1)
    {
      TopExp::CommonVertex(PrevEdge, anEdge, CV);
      Standard_Real Tol = BRep_Tool::Tolerance(CV);
      tabtolvertex(i-2) = Tol;
    }
    
    Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
    Handle(Geom_TrimmedCurve) aTrCurve = new Geom_TrimmedCurve(aCurve, fpar, lpar);
    tab_c3d(i-1) = GeomConvert::CurveToBSplineCurve(aTrCurve);
    GeomConvert::C0BSplineToC1BSplineCurve(tab_c3d(i-1), Precision::Confusion());
    if (ToReverse)
      tab_c3d(i-1)->Reverse();
    PrevVertex = (ToReverse)? VF : VL;
    PrevEdge = anEdge;
  }
  Handle(TColGeom_HArray1OfBSplineCurve)  concatcurve;     //array of the concatenated curves
  Handle(TColStd_HArray1OfInteger)        ArrayOfIndices;  //array of the remining Vertex
  GeomConvert::ConcatC1(tab_c3d,
                        tabtolvertex,
                        ArrayOfIndices,
                        concatcurve,
                        Standard_False,
                        Precision::Confusion());   //C1 concatenation
  
  if (concatcurve->Length() > 1)
  {
    GeomConvert_CompCurveToBSplineCurve Concat(concatcurve->Value(concatcurve->Lower()));
    
    for (i = concatcurve->Lower()+1; i <= concatcurve->Upper(); i++)
      Concat.Add( concatcurve->Value(i), MaxTol, Standard_True );
    
    concatcurve->SetValue(concatcurve->Lower(), Concat.BSplineCurve());
  }
  Handle(Geom_BSplineCurve) ResCurve = concatcurve->Value(concatcurve->Lower());
  
  TColGeom2d_SequenceOfBoundedCurve ResPCurves;
  TopLoc_Location aLoc;
  for (j = 1; j <= SurfSeq.Length(); j++)
  {
    TColGeom2d_Array1OfBSplineCurve tab_c2d(0,nb_curve-1); //array of the pcurves
    
    PrevVertex = FirstVertex;
    PrevEdge = FirstEdge;
    //TopLoc_Location theLoc = LocSeq(j).Location();
    for (i = 1; i <= nb_curve; i++)
    {
      TopoDS_Edge anEdge = TopoDS::Edge(aChain(i));
      TopoDS_Vertex VF, VL;
      TopExp::Vertices(anEdge, VF, VL);
      Standard_Boolean ToReverse = (!VF.IsSame(PrevVertex));

      /*
      Handle(Geom2d_Curve) aPCurve =
        BRep_Tool::CurveOnSurface(anEdge, SurfSeq(j), anEdge.Location()*theLoc, fpar, lpar);
      */
      Handle(Geom2d_Curve) aPCurve =
        BRep_Tool::CurveOnSurface(anEdge, SurfSeq(j), aLoc, fpar, lpar);
      Handle(Geom2d_TrimmedCurve) aTrPCurve = new Geom2d_TrimmedCurve(aPCurve, fpar, lpar);
      tab_c2d(i-1) = Geom2dConvert::CurveToBSplineCurve(aTrPCurve);
      Geom2dConvert::C0BSplineToC1BSplineCurve(tab_c2d(i-1), Precision::Confusion());
      if (ToReverse)
        tab_c2d(i-1)->Reverse();
      PrevVertex = (ToReverse)? VF : VL;
      PrevEdge = anEdge;
    }
    Handle(TColGeom2d_HArray1OfBSplineCurve)  concatc2d;     //array of the concatenated curves
    Handle(TColStd_HArray1OfInteger)        ArrayOfInd2d;  //array of the remining Vertex
    Geom2dConvert::ConcatC1(tab_c2d,
                            tabtolvertex,
                            ArrayOfInd2d,
                            concatc2d,
                            Standard_False,
                            Precision::Confusion());   //C1 concatenation
    
    if (concatc2d->Length() > 1)
    {
      Geom2dConvert_CompCurveToBSplineCurve Concat2d(concatc2d->Value(concatc2d->Lower()));
      
      for (i = concatc2d->Lower()+1; i <= concatc2d->Upper(); i++)
        Concat2d.Add( concatc2d->Value(i), MaxTol, Standard_True );
      
      concatc2d->SetValue(concatc2d->Lower(), Concat2d.BSplineCurve());
    }
    Handle(Geom2d_BSplineCurve) aResPCurve = concatc2d->Value(concatc2d->Lower());
    ResPCurves.Append(aResPCurve);
  }
  
  ResEdge = BRepLib_MakeEdge(ResCurve,
                             FirstVertex, LastVertex,
                             ResCurve->FirstParameter(), ResCurve->LastParameter());
  BB.SameRange(ResEdge, Standard_False);
  BB.SameParameter(ResEdge, Standard_False);
  for (j = 1; j <= ResPCurves.Length(); j++)
  {
    BB.UpdateEdge(ResEdge, ResPCurves(j), SurfSeq(j), aLoc, MaxTol);
    BB.Range(ResEdge, SurfSeq(j), aLoc, ResPCurves(j)->FirstParameter(), ResPCurves(j)->LastParameter());
  }

  BRepLib::SameParameter(ResEdge, MaxTol, Standard_True);
  
  return ResEdge;
}
Standard_Boolean ShHealOper_RemoveFace::isReplace(const TopoDS_Shape& theShape, 
                                                  TopoDS_Shape& theNewShape)
{
  
  Standard_Boolean isChange = Standard_False;
  TopTools_SequenceOfShape aSeqShapes;
  if(theShape.ShapeType() == TopAbs_COMPOUND || theShape.ShapeType() == TopAbs_COMPSOLID ||
     theShape.ShapeType() == TopAbs_SOLID) {
    TopoDS_Iterator aEs(theShape);
    for( ; aEs.More(); aEs.Next()) {
      TopoDS_Shape aNewShell = aEs.Value();
      if(aNewShell.ShapeType()!= TopAbs_SHELL) {
        aSeqShapes.Append(aNewShell);
        continue;
      }
      TopoDS_Shape as = getResultShell(TopoDS::Shell(aNewShell));
      isChange = (as.IsNull() || (as.ShapeType() == TopAbs_FACE));
      if(!as.IsNull()) {
        aSeqShapes.Append(as);
      }
    }
  }
  else if(theShape.ShapeType() == TopAbs_SHELL) {
    TopoDS_Shape aSh = getResultShell(TopoDS::Shell(theShape));
    isChange = (aSh.IsNull() || (aSh.ShapeType() == TopAbs_FACE));
    if(!aSh.IsNull())
      aSeqShapes.Append(aSh);
  }
  else aSeqShapes.Append(theShape);

  if(aSeqShapes.IsEmpty())
    return Standard_True;

  if(isChange) {
    if(aSeqShapes.Length() == 1)
      theNewShape = aSeqShapes.Value(1);
    else if (aSeqShapes.Length() > 1) {
      TopoDS_Compound aComp1;
      BRep_Builder aBB;
      aBB.MakeCompound(aComp1);
      Standard_Integer kk =1;
      for( ; kk <=  aSeqShapes.Length(); kk++)
        aBB.Add(aComp1,aSeqShapes.Value(kk));
      if(aSeqShapes.Length())
        theNewShape = aComp1;
    }
  }
  else
    theNewShape = theShape;
  return isChange;
}
Exemplo n.º 14
0
//=======================================================================
// function: Path
// purpose: 
//=======================================================================
  void Path (const GeomAdaptor_Surface& aGAS,
	     const TopoDS_Face& myFace,
	     const TopoDS_Vertex& aVa,
	     const TopoDS_Edge& aEOuta,
	     BOP_EdgeInfo& anEdgeInfo,
	     TopTools_SequenceOfShape& aLS,
	     TopTools_SequenceOfShape& aVertVa,
	     TColgp_SequenceOfPnt2d& aCoordVa,
	     BOPTColStd_ListOfListOfShape& myShapes,
	     BOP_IndexedDataMapOfVertexListEdgeInfo& mySmartMap)
			       
{
  Standard_Integer i,j, aNb, aNbj;
  Standard_Real aTol, anAngleIn, anAngleOut, anAngle, aMinAngle;
  Standard_Real aTol2D, aTol2D2;
  Standard_Real aTol2, aD2;//, aTolUVb, aTolVVb;  
  Standard_Boolean anIsSameV2d, anIsSameV, anIsFound, anIsOut, anIsNotPassed;
  BOP_ListIteratorOfListOfEdgeInfo anIt;
  TopoDS_Vertex aVb;
  TopoDS_Edge aEOutb;
  //
  aTol=1.e-7;
  //
  // append block
  //
  // Do not escape through edge from which you enter 
  aNb=aLS.Length();
  if (aNb==1) {
    const TopoDS_Shape& anEPrev=aLS(aNb);
    if (anEPrev.IsSame(aEOuta)) {
      return;
    }
  }
  //
  //
  anEdgeInfo.SetPassed(Standard_True);
  aLS.Append(aEOuta);
  aVertVa.Append(aVa);
  
  TopoDS_Vertex pVa=aVa;
  pVa.Orientation(TopAbs_FORWARD);
  gp_Pnt2d aPa=Coord2d(pVa, aEOuta, myFace);
  aCoordVa.Append(aPa);
  
  GetNextVertex (pVa, aEOuta, aVb);

  gp_Pnt2d aPb=Coord2d(aVb, aEOuta, myFace);

  //const BOP_ListOfEdgeInfo& aLEInfoVb=mySmartMap.FindFromKey(aVb);
  //
  aTol=2.*Tolerance2D(aVb, aGAS);
  aTol2=10.*aTol*aTol;
  //
  aNb=aLS.Length();
  if (aNb>0) {
    //
    TopTools_ListOfShape aBuf;
    //
    for (i=aNb; i>0; i--) {
      const TopoDS_Shape& aVPrev=aVertVa(i);
      const gp_Pnt2d& aPaPrev=aCoordVa(i);
      const TopoDS_Shape& aEPrev=aLS(i);

      aBuf.Append(aEPrev);

      anIsSameV=aVPrev.IsSame(aVb);
      anIsSameV2d=Standard_False;

      if (anIsSameV) {
	anIsSameV2d = Standard_True;
	//
	aD2=aPaPrev.SquareDistance(aPb);
	anIsSameV2d =aD2<aTol2;
      }//if (anIsSameV) {
      //
      if (anIsSameV && anIsSameV2d) {
	myShapes.Append(aBuf);
	//
	TopTools_SequenceOfShape aLSt, aVertVat;
	TColgp_SequenceOfPnt2d aCoordVat;
	//
	aNbj=i-1;
	if (aNbj<1) {
	  //
	  aLS.Clear();
	  aVertVa.Clear();
	  aCoordVa.Clear();
	  //
	  return;
	}

	aVb=TopoDS::Vertex(aVertVa(i));

	for (j=1; j<=aNbj; j++) {
	  aLSt.Append(aLS(j));
	  aVertVat.Append(aVertVa(j));
	  aCoordVat.Append(aCoordVa(j));
	}
	//
	aLS.Clear();
	aVertVa.Clear();
	aCoordVa.Clear();

	aLS=aLSt;
	aVertVa=aVertVat;
	aCoordVa=aCoordVat;
	//
	break;
      }
    }
  }
  //
  aTol2D=2.*Tolerance2D(aVb, aGAS);
  aTol2D2=100.*aTol2D*aTol2D;
  //
  // anAngleIn in Vb from edge aEOuta
  const BOP_ListOfEdgeInfo& aLEInfo=mySmartMap.FindFromKey(aVb);
  //
  anAngleIn=AngleIn(aEOuta, aLEInfo);
  //
  // aEOutb
  BOP_EdgeInfo *pEdgeInfo=NULL;

  aMinAngle=100.;
  anIsFound=Standard_False;

  Standard_Integer aCurIndexE = 0;

  anIt.Initialize(aLEInfo);
  for (; anIt.More(); anIt.Next()) {
    BOP_EdgeInfo& anEI=anIt.Value();
    const TopoDS_Edge& aE=anEI.Edge();
    anIsOut=!anEI.IsIn();
    anIsNotPassed=!anEI.Passed();
    
    if (anIsOut && anIsNotPassed) {
      aCurIndexE++;
      //
      // Is there one way to go out of the vertex 
      // we have to use it only.
      Standard_Integer iCnt;
      iCnt=NbWaysOut (aLEInfo);
      //
      if (!iCnt) {
	// no way to go . (Error)
	return ;
      }
      //
      if (iCnt==1) {
	// the one and only way to go out .
	pEdgeInfo=&anEI;
	anIsFound=Standard_True;
	break;
      }
      //
      // Look for minimal angle and make the choice.
      gp_Pnt2d aP2Dx;
      //
      aP2Dx=Coord2dVf(aE, myFace);
      //
      aD2=aP2Dx.SquareDistance(aPb);
      if (aD2 > aTol2D2){
	continue;
      }
      //
      //
      anAngleOut=anEI.Angle();
      //
      anAngle=ClockWiseAngle(anAngleIn, anAngleOut);
      if (anAngle < aMinAngle) {
	aMinAngle=anAngle;
	pEdgeInfo=&anEI;
	anIsFound=Standard_True;
      }
    }
  } // for (; anIt.More(); anIt.Next()) 
  //
  if (!anIsFound) {
    // no way to go . (Error)
    return;
  }
  
  aEOutb=pEdgeInfo->Edge();
  //
  Path (aGAS, myFace, aVb, aEOutb, *pEdgeInfo, aLS, 
	aVertVa, aCoordVa, myShapes, mySmartMap);
}
void Tesselate_Presentation::tesselateShape(const TopoDS_Shape& aShape)
{
//  setResultTitle("Tesselate shape");
  TCollection_AsciiString aText = (
    "/////////////////////////////////////////////////////////////////" EOL
    "// Tesselate shape." EOL
    "/////////////////////////////////////////////////////////////////" EOL EOL
    ) ;

  Standard_Real aDeflection = DATA[myIndex][0];
  Standard_Integer aNumOfFace = (Standard_Integer)DATA[myIndex][1];
  Standard_Integer aNumOfEdge = (Standard_Integer)DATA[myIndex][2];

  aText +=
    "Standard_Real aDeflection;" EOL
    "// aDeflection = ... ;" EOL EOL

    "// removes all the triangulations of the faces ," EOL
    "//and all the polygons on the triangulations of the edges:" EOL
    "BRepTools::Clean(aShape);" EOL EOL

    "// adds a triangulation of the shape aShape with the deflection aDeflection:" EOL
    "BRepMesh::Mesh(aShape,aDeflection);" EOL EOL

    "TopExp_Explorer aExpFace,aExpEdge;" EOL
    "for(aExpFace.Init(aShape,TopAbs_FACE);aExpFace.More();aExpFace.Next())" EOL
    "{  " EOL
    "  TopoDS_Face aFace = TopoDS::Face(aExpFace.Current());" EOL
    "  TopLoc_Location aLocation;" EOL EOL
    
    "  // takes the triangulation of the face aFace:" EOL
    "  Handle_Poly_Triangulation aTr = BRep_Tool::Triangulation(aFace,aLocation);" EOL EOL
    
    "  if(!aTr.IsNull()) // if this triangulation is not NULL" EOL
    "  { " EOL
    "    // takes the array of nodes for this triangulation:" EOL
    "    const TColgp_Array1OfPnt& aNodes = aTr->Nodes();" EOL
    "    // takes the array of triangles for this triangulation:" EOL
    "    const Poly_Array1OfTriangle& triangles = aTr->Triangles();" EOL EOL
    
    "    // create array of node points in absolute coordinate system" EOL
    "    TColgp_Array1OfPnt aPoints(1, aNodes.Length());" EOL
    "    for( Standard_Integer i = 1; i < aNodes.Length()+1; i++)" EOL
    "      aPoints(i) = aNodes(i).Transformed(aLocation);" EOL EOL

    "    // Takes the node points of each triangle of this triangulation." EOL
    "    // takes a number of triangles:" EOL
    "    Standard_Integer nnn = aTr->NbTriangles();" EOL
    "    Standard_Integer nt,n1,n2,n3;" EOL
    "    for( nt = 1 ; nt < nnn+1 ; nt++)" EOL
    "    {" EOL
    "      // takes the node indices of each triangle in n1,n2,n3:" EOL
    "      triangles(nt).Get(n1,n2,n3);" EOL
    "      // takes the node points:" EOL
    "      gp_Pnt aPnt1 = aPoints(n1);" EOL
    "      gp_Pnt aPnt2 = aPoints(n2);" EOL
    "      gp_Pnt aPnt3 = aPoints(n3);" EOL
    "    } " EOL EOL
    
    "    // Takes the polygon associated to an edge." EOL
    "    aExpEdge.Init(aFace,TopAbs_EDGE);" EOL
    "    TopoDS_Edge aEdge;" EOL
    "    // for example,working with the first edge:" EOL
    "    if(aExpEdge.More())" EOL
    "      aEdge = TopoDS::Edge(aExpEdge.Current());" EOL EOL
    
    "    if(!aEdge.IsNull()) // if this edge is not NULL" EOL
    "    {" EOL
    "      // takes the polygon associated to the edge aEdge:" EOL
    "      Handle_Poly_PolygonOnTriangulation aPol = " EOL
    "        BRep_Tool::PolygonOnTriangulation(aEdge,aTr,aEdge.Location());" EOL EOL
    
    "      if(!aPol.IsNull()) // if this polygon is not NULL" EOL
    "        // takes the array of nodes for this polygon" EOL
    "        // (indexes in the array of nodes for triangulation of theFace):" EOL
    "        const TColStd_Array1OfInteger& aNodesOfPol = aPol->Nodes();" EOL
    "    }" EOL
    "  }" EOL
    "}" EOL EOL
    
    "//==================================================" EOL EOL
    
      ;
   aText += "  Result with deflection = ";
   aText += TCollection_AsciiString(aDeflection);
   aText += " :" EOL;

   GetDocument()->PocessTextInDialog("Compute the triangulation on a shape", aText);
//   setResultText(aText.ToCString());  

//==========================================================================

  BRepTools::Clean(aShape);
  BRepMesh::Mesh(aShape,aDeflection);

  BRep_Builder aBuilder,aBuild1,aBuild2;
  TopoDS_Compound aCompound,aComp1,aComp2;
  aBuilder.MakeCompound(aCompound);
  aBuild1.MakeCompound(aComp1);
  aBuild2.MakeCompound(aComp2);

  TopTools_SequenceOfShape aVertices;
  Standard_Integer aCount = 0;
  Standard_Integer aNumOfNodes = 0;
  Standard_Integer aNumOfTriangles = 0;
  
  Handle_AIS_InteractiveObject aShowEdge,aShowFace,aShowShape;
  
  TopExp_Explorer aExpFace,aExpEdge;

  for(aExpFace.Init(aShape,TopAbs_FACE);aExpFace.More();aExpFace.Next())
  {  
    aCount++;
  
    TopoDS_Face aFace = TopoDS::Face(aExpFace.Current());
    TopLoc_Location aLocation;

    Handle_Poly_Triangulation aTr = BRep_Tool::Triangulation(aFace,aLocation);

    if(!aTr.IsNull())
    { 
      const TColgp_Array1OfPnt& aNodes = aTr->Nodes();
      aNumOfNodes += aTr->NbNodes();
      Standard_Integer aLower = aNodes.Lower();
      Standard_Integer anUpper = aNodes.Upper();
      const Poly_Array1OfTriangle& triangles = aTr->Triangles();
      aNumOfTriangles += aTr->NbTriangles();

      if(aCount == aNumOfFace)
      {
        Standard_Integer aNbOfNodesOfFace = aTr->NbNodes();
        Standard_Integer aNbOfTrianglesOfFace = aTr->NbTriangles();
        aExpEdge.Init(aFace,TopAbs_EDGE);

        TopoDS_Edge aEdge;

        for( Standard_Integer i = 0; aExpEdge.More() && i < aNumOfEdge ; aExpEdge.Next(), i++)
          aEdge = TopoDS::Edge(aExpEdge.Current());

        if(!aEdge.IsNull())
        {
          Handle_Poly_PolygonOnTriangulation aPol = 
            BRep_Tool::PolygonOnTriangulation(aEdge,aTr,aEdge.Location());

          if(!aPol.IsNull())
          {
            const TColStd_Array1OfInteger& aNodesOfPol = aPol->Nodes();
            Standard_Integer aNbOfNodesOfEdge = aPol->NbNodes();

            aText += "Number of nodes of the edge = ";
            aText += TCollection_AsciiString(aNbOfNodesOfEdge) + EOL;
            aText += "Number of nodes of the face = ";
            aText += TCollection_AsciiString(aNbOfNodesOfFace) + EOL;
            aText += "Number of triangles of the face = ";
            aText += TCollection_AsciiString(aNbOfTrianglesOfFace) + EOL;
			GetDocument()->PocessTextInDialog("Compute the triangulation on a shape", aText);
//            setResultText(aText.ToCString());  

            Standard_Integer aLower = aNodesOfPol.Lower(), anUpper = aNodesOfPol.Upper();
            for( int i = aLower; i < anUpper ; i++)
            {
              gp_Pnt aPnt1 = aNodes(aNodesOfPol(i)).Transformed(aLocation);
              gp_Pnt aPnt2 = aNodes(aNodesOfPol(i+1)).Transformed(aLocation);
              TopoDS_Vertex aVertex1 = BRepBuilderAPI_MakeVertex (aPnt1);
              TopoDS_Vertex aVertex2 = BRepBuilderAPI_MakeVertex (aPnt2);

              if(!aVertex1.IsNull() && !aVertex2.IsNull() && // if vertices are "alive"
                !BRep_Tool::Pnt(aVertex1).IsEqual(
                BRep_Tool::Pnt(aVertex2),Precision::Confusion())) // if they are different
              {
                aEdge = BRepBuilderAPI_MakeEdge (aVertex1,aVertex2);
                aBuild2.Add(aComp2,aVertex1);
                if(!aEdge.IsNull())
                  aBuild2.Add(aComp2,aEdge);
                if(i == anUpper-1)
                  aBuild2.Add(aComp2,aVertex2);
              }
            }
      
            getAISContext()->EraseAll();
            aShowShape = drawShape(aShape);
            if(WAIT_A_SECOND) return;
            aShowEdge = drawShape(aComp2,Quantity_NOC_GREEN);
            getAISContext()->Erase(aShowShape);
            if(WAIT_A_SECOND) return;
          }
        }
      }
    

      TopTools_DataMapOfIntegerShape aEdges;
      TopTools_SequenceOfShape aVertices;

      for( Standard_Integer i = 1; i < aNodes.Length()+1; i++)
      {
        gp_Pnt aPnt = aNodes(i).Transformed(aLocation);
        TopoDS_Vertex aVertex = BRepBuilderAPI_MakeVertex(aPnt);

        if(!aVertex.IsNull())
        {
          aBuilder.Add(aCompound,aVertex);
          if(aCount == aNumOfFace ) 
            aBuild1.Add(aComp1,aVertex);
          aVertices.Append(aVertex);
        }
      }

      Standard_Integer nnn = aTr->NbTriangles();
      Standard_Integer nt,n1,n2,n3;

      for( nt = 1 ; nt < nnn+1 ; nt++)
      {     
        triangles(nt).Get(n1,n2,n3);

        Standard_Integer key[3];
        
        TopoDS_Vertex aV1,aV2;
        key[0] = _key(n1, n2);
        if(!aEdges.IsBound(key[0]))
        {
          aV1 = TopoDS::Vertex(aVertices(n1));
          aV2 = TopoDS::Vertex(aVertices(n2));
          if(!aV1.IsNull() && !aV2.IsNull() &&
            !BRep_Tool::Pnt(aV1).IsEqual(BRep_Tool::Pnt(aV2),Precision::Confusion()))
          {
            TopoDS_Edge aEdge = BRepBuilderAPI_MakeEdge (aV1,aV2);  
            if(!aEdge.IsNull())
            {
              aEdges.Bind(key[0], aEdge);
              aBuilder.Add(aCompound,aEdges(key[0]));
              if(aCount == aNumOfFace)
                aBuild1.Add(aComp1,aEdges(key[0]));
            } 
          }
        }
        
        key[1] = _key(n2,n3);
        if(!aEdges.IsBound(key[1])) 
        { 
          aV1 = TopoDS::Vertex(aVertices(n2));
          aV2 = TopoDS::Vertex(aVertices(n3));
          if(!aV1.IsNull() && !aV2.IsNull() &&
            !BRep_Tool::Pnt(aV1).IsEqual(BRep_Tool::Pnt(aV2),Precision::Confusion()))
          {
            TopoDS_Edge aEdge = BRepBuilderAPI_MakeEdge (aV1,aV2);  
            if(!aEdge.IsNull())
            {
              aEdges.Bind(key[1],aEdge);
              aBuilder.Add(aCompound,aEdges(key[1]));
              if(aCount == aNumOfFace) 
                aBuild1.Add(aComp1,aEdges(key[1]));
            } 
          } 
        } 
 
        key[2] = _key(n3,n1);
        if(!aEdges.IsBound(key[2])) 
        { 
          aV1 = TopoDS::Vertex(aVertices(n3));
          aV2 = TopoDS::Vertex(aVertices(n1));
          if(!aV1.IsNull() && !aV2.IsNull() &&
            !BRep_Tool::Pnt(aV1).IsEqual(BRep_Tool::Pnt(aV2),Precision::Confusion()))
          { 
            TopoDS_Edge aEdge = BRepBuilderAPI_MakeEdge (aV1,aV2);  
            if(!aEdge.IsNull())
            { 
              aEdges.Bind(key[2],aEdge);
              aBuilder.Add(aCompound,aEdges(key[2]));
              if(aCount == aNumOfFace) 
                aBuild1.Add(aComp1,aEdges(key[2]));
            } 
          } 
        } 
      } 
      
      if(aCount == aNumOfFace)
      {
        aShowFace = drawShape(aComp1,Quantity_NOC_GREEN);
        getAISContext()->Erase(aShowEdge);
      }
    }
    else
    {
      aText += "Can't compute a triangulation on face ";
      aText += TCollection_AsciiString(aCount) + EOL;
	  GetDocument()->PocessTextInDialog("Compute the triangulation on a shape", aText);
//      setResultText(aText.ToCString());
    }
  }
  
  aText += "Number of nodes of the shape = ";
  aText += TCollection_AsciiString(aNumOfNodes) + EOL;
  aText += "Number of triangles of the shape = ";
  aText += TCollection_AsciiString(aNumOfTriangles) + EOL EOL;
  GetDocument()->PocessTextInDialog("Compute the triangulation on a shape", aText);
//  setResultText(aText.ToCString());

  if(WAIT_A_SECOND) return;
  drawShape(aCompound,Quantity_NOC_GREEN);
  getAISContext()->Erase(aShowFace);
  
}
bool StdMeshers_Hexa_3D::Evaluate(SMESH_Mesh & aMesh,
                                  const TopoDS_Shape & aShape,
                                  MapShapeNbElems& aResMap)
{
  vector < SMESH_subMesh * >meshFaces;
  TopTools_SequenceOfShape aFaces;
  for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
    aFaces.Append(exp.Current());
    SMESH_subMesh *aSubMesh = aMesh.GetSubMeshContaining(exp.Current());
    ASSERT(aSubMesh);
    meshFaces.push_back(aSubMesh);
  }
  if (meshFaces.size() != 6) {
    //return error(COMPERR_BAD_SHAPE, TComm(meshFaces.size())<<" instead of 6 faces in a block");
    static StdMeshers_CompositeHexa_3D compositeHexa(-10, 0, aMesh.GetGen());
    return compositeHexa.Evaluate(aMesh, aShape, aResMap);
  }
  
  int i = 0;
  for(; i<6; i++) {
    //TopoDS_Shape aFace = meshFaces[i]->GetSubShape();
    TopoDS_Shape aFace = aFaces.Value(i+1);
    SMESH_Algo *algo = _gen->GetAlgo(aMesh, aFace);
    if( !algo ) {
      std::vector<int> aResVec(SMDSEntity_Last);
      for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
      SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
      aResMap.insert(std::make_pair(sm,aResVec));
      SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
      smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
      return false;
    }
    string algoName = algo->GetName();
    bool isAllQuad = false;
    if (algoName == "Quadrangle_2D") {
      MapShapeNbElemsItr anIt = aResMap.find(meshFaces[i]);
      if( anIt == aResMap.end() ) continue;
      std::vector<int> aVec = (*anIt).second;
      int nbtri = Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]);
      if( nbtri == 0 )
        isAllQuad = true;
    }
    if ( ! isAllQuad ) {
      return EvaluatePentahedralMesh(aMesh, aShape, aResMap);
    }
  }
  
  // find number of 1d elems for 1 face
  int nb1d = 0;
  TopTools_MapOfShape Edges1;
  bool IsQuadratic = false;
  bool IsFirst = true;
  for (TopExp_Explorer exp(aFaces.Value(1), TopAbs_EDGE); exp.More(); exp.Next()) {
    Edges1.Add(exp.Current());
    SMESH_subMesh *sm = aMesh.GetSubMesh(exp.Current());
    if( sm ) {
      MapShapeNbElemsItr anIt = aResMap.find(sm);
      if( anIt == aResMap.end() ) continue;
      std::vector<int> aVec = (*anIt).second;
      nb1d += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]);
      if(IsFirst) {
        IsQuadratic = (aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge]);
        IsFirst = false;
      }
    }
  }
  // find face opposite to 1 face
  int OppNum = 0;
  for(i=2; i<=6; i++) {
    bool IsOpposite = true;
    for(TopExp_Explorer exp(aFaces.Value(i), TopAbs_EDGE); exp.More(); exp.Next()) {
      if( Edges1.Contains(exp.Current()) ) {
        IsOpposite = false;
        break;
      }
    }
    if(IsOpposite) {
      OppNum = i;
      break;
    }
  }
  // find number of 2d elems on side faces
  int nb2d = 0;
  for(i=2; i<=6; i++) {
    if( i == OppNum ) continue;
    MapShapeNbElemsItr anIt = aResMap.find( meshFaces[i-1] );
    if( anIt == aResMap.end() ) continue;
    std::vector<int> aVec = (*anIt).second;
    nb2d += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]);
  }
  
  MapShapeNbElemsItr anIt = aResMap.find( meshFaces[0] );
  std::vector<int> aVec = (*anIt).second;
  int nb2d_face0 = Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]);
  int nb0d_face0 = aVec[SMDSEntity_Node];

  std::vector<int> aResVec(SMDSEntity_Last);
  for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
  if(IsQuadratic) {
    aResVec[SMDSEntity_Quad_Hexa] = nb2d_face0 * ( nb2d/nb1d );
    int nb1d_face0_int = ( nb2d_face0*4 - nb1d ) / 2;
    aResVec[SMDSEntity_Node] = nb0d_face0 * ( 2*nb2d/nb1d - 1 ) - nb1d_face0_int * nb2d/nb1d;
  }
  else {
    aResVec[SMDSEntity_Node] = nb0d_face0 * ( nb2d/nb1d - 1 );
    aResVec[SMDSEntity_Hexa] = nb2d_face0 * ( nb2d/nb1d );
  }
  SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
  aResMap.insert(std::make_pair(sm,aResVec));

  return true;
}