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

void LocOpe_SplitDrafts::Perform ( const TopoDS_Face F,
const TopoDS_Wire W,
const gp_Dir Extractg,
const gp_Pln NPlg,
const Standard_Real  Angleg,
const gp_Dir Extractd,
const gp_Pln NPld,
const Standard_Real  Angled,
const Standard_Boolean  ModifyLeft = Standard_True,
const Standard_Boolean  ModifyRight = Standard_True 
)

Splits the face <F> of the former given shape with
the wire <W>. The wire is assumed to lie on the
face. Puts a draft angle on both parts of the
wire. <Extractg>, <Nplg>, <Angleg> define the
arguments for the left part of the wire.
<Extractd>, <Npld>, <Angled> define the arguments
for the right part of the wire. The draft angle is
measured with the direction <Extract>. <Npl>
defines the neutral plane (points belonging to the
neutral plane are not modified). <Angle> is the
value of the draft angle. If <ModifyLeft> is set
to <Standard_False>, no draft angle is applied to
the left part of the wire. If <ModifyRight> is set
to <Standard_False>,no draft angle is applied to
the right part of the wire.


Definition at line 119 of file LocOpe_SplitDrafts.cxx.

References TopoDS_Builder::Add(), LocOpe_SplitShape::Add(), BRepTools_Substitution::Build(), Precision::Confusion(), BRepTools_Substitution::Copy(), TopExp_Explorer::Current(), BRep_Tool::Curve(), LocOpe_SplitShape::DescendantShapes(), TopoDS_Shape::EmptyCopied(), GeomAdaptor_Curve::FirstParameter(), GeomFill_Pipe::GenerateParticularCase(), GeomFill_Pipe::Init(), TopExp_Explorer::Init(), BRepTools_Substitution::IsCopied(), TopoDS_Shape::IsNull(), TopoDS_Shape::IsSame(), GeomAdaptor_Curve::LastParameter(), GeomAdaptor_Curve::Load(), GeomAdaptor_Surface::Load(), gp_Ax1::Location(), BRep_Builder::MakeEdge(), BRep_Builder::MakeFace(), BRep_Builder::MakeVertex(), TopoDS_Builder::MakeWire(), TopExp::MapShapesAndAncestors(), TopExp_Explorer::More(), TopExp_Explorer::Next(), TopoDS_Shape::Nullify(), TopoDS_Shape::Orientation(), TopoDS_Shape::Oriented(), BRep_Tool::Parameter(), Precision::PConfusion(), GeomFill_Pipe::Perform(), IntCurveSurface_IntersectionPoint::Pnt(), BRep_Tool::Pnt(), TopExp_Explorer::ReInit(), TopoDS_Shape::ShapeType(), gp_Pnt::SquareDistance(), BRepTools_Substitution::Substitute(), BRep_Tool::Surface(), GeomFill_Pipe::Surface(), BRep_Tool::Tolerance(), TopLoc_Location::Transformation(), gp_Lin::Translate(), BRep_Builder::UpdateEdge(), BRep_Builder::UpdateVertex(), TopExp::Vertices(), and IntCurveSurface_IntersectionPoint::W().

Referenced by Perform().

{
  Standard_Integer j ;

  myResult.Nullify();
  myMap.Clear();
  if (myShape.IsNull() || F.IsNull() || W.IsNull()) {
    Standard_NullObject::Raise();
  }    

  if (!ModLeft && !ModRight) {
    Standard_ConstructionError::Raise();
  }

#ifdef DEB
  TopAbs_Orientation OriF;
#else
  TopAbs_Orientation OriF = TopAbs_FORWARD;
#endif
  Standard_Boolean FinS = Standard_False;
  TopExp_Explorer exp,exp2;
  for (exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next()) {
    const TopoDS_Shape& fac = exp.Current();
    TopTools_ListOfShape thelist;
    myMap.Bind(fac, thelist);
    if (fac.IsSame(F)) {
      OriF = fac.Orientation();
      FinS = Standard_True;
    }
  }

  if (!FinS) {
    cout << "LocOpe_SplitDrafts:!Fins Standard_ConstructionError::Raise()" << endl;
    Standard_ConstructionError::Raise();
  }    

  gp_Pln NewPlg,NewPld;
  gp_Ax1 NormalFg,NormalFd;
  TopoDS_Shape aLocalFace = F.Oriented(OriF);

  if (!NewPlane(TopoDS::Face(aLocalFace),
            Extrg,NPlg,Angleg,NewPlg,NormalFg,ModLeft) ||
      !NewPlane(TopoDS::Face(aLocalFace),
            Extrd,NPld,Angled,NewPld,NormalFd,ModRight)) {
    //  if (!NewPlane(TopoDS::Face(F.Oriented(OriF)),
    //            Extrg,NPlg,Angleg,NewPlg,NormalFg,ModLeft) ||
//      !NewPlane(TopoDS::Face(F.Oriented(OriF)),
    //            Extrd,NPld,Angled,NewPld,NormalFd,ModRight)) {
    return;
  }


  TopTools_ListIteratorOfListOfShape itl;
  BRep_Builder B;

  Handle(Geom_Surface) NewSg = new Geom_Plane(NewPlg);
  Handle(Geom_Surface) NewSd = new Geom_Plane(NewPld);
  Handle(Geom_Line) theLinePipe = new Geom_Line(NormalFg); // ou NormalFd
  GeomInt_IntSS i2s(NewSg,NewSd,Precision::Confusion());

  TopTools_MapOfShape theMap;
  Handle(GeomAdaptor_HCurve) HAC = new GeomAdaptor_HCurve;
  GeomAdaptor_Curve AC;
  Handle(GeomAdaptor_HSurface) HAS = new GeomAdaptor_HSurface;
  GeomAdaptor_Surface AS;
  IntCurveSurface_HInter intcs;

  TopoDS_Wire theW = W;
  if (i2s.IsDone() && i2s.NbLines() > 0) {
    // on split le wire" << endl;

    GeomFill_Pipe thePipe;
    thePipe.GenerateParticularCase(Standard_True);
    thePipe.Init(theLinePipe,i2s.Line(1));
    thePipe.Perform(Standard_True);

    Handle(Geom_Surface) Spl = thePipe.Surface();
    AS.Load(Spl);
    HAS->Set(AS);
    
    LocOpe_SplitShape splw(W);

    for (exp.Init(W,TopAbs_EDGE); exp.More(); exp.Next()) {
      const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
      if (theMap.Add(edg)) {
      TopLoc_Location Loc;
      Standard_Real f,l;
      Handle(Geom_Curve) C = BRep_Tool::Curve(edg,f,l);
      AC.Load(C);
      HAC->Set(AC);
      intcs.Perform(HAC,HAS);
      if (!intcs.IsDone()) {
        continue; // voir ce qu`on peut faire de mieux
      }

      if (intcs.NbSegments() >= 2) {
        continue; // Not yet implemented...and probably never"
      }

      if (intcs.NbSegments() == 1) {
        const IntCurveSurface_IntersectionPoint& P1 = 
          intcs.Segment(1).FirstPoint();
        const IntCurveSurface_IntersectionPoint& P2 = 
          intcs.Segment(1).SecondPoint();
        const gp_Pnt& pf = P1.Pnt();
        const gp_Pnt& pl = P2.Pnt();
        TopoDS_Vertex Vf,Vl;
        TopExp::Vertices(edg,Vf,Vl);
        gp_Pnt Pf = BRep_Tool::Pnt(Vf);
        gp_Pnt Pl = BRep_Tool::Pnt(Vl);
        Standard_Real Tolf = BRep_Tool::Tolerance(Vf);
        Standard_Real Toll = BRep_Tool::Tolerance(Vl);
        Tolf *= Tolf;
        Toll *= Toll;

        Standard_Real dff = pf.SquareDistance(Pf);
        Standard_Real dfl = pf.SquareDistance(Pl);
        Standard_Real dlf = pl.SquareDistance(Pf);
        Standard_Real dll = pl.SquareDistance(Pl);

        if ((dff <= Tolf && dll <= Toll) ||
            (dlf <= Tolf && dfl <= Toll)) {
          continue;
        }
        else {
          // on segmente edg en pf et pl
          TopoDS_Vertex Vnewf,Vnewl;
          B.MakeVertex(Vnewf,pf,Precision::Confusion());
          B.MakeVertex(Vnewl,pl,Precision::Confusion());
          if (P1.W() >= f && P1.W() <= l &&
            P2.W() >= f && P2.W() <= l) {
            splw.Add(Vnewf,P1.W(),edg);
            splw.Add(Vnewl,P2.W(),edg);
          }
          else {
            continue;
          }
        }
      }
      else if (intcs.NbPoints() != 0) {
        TopoDS_Vertex Vf,Vl;
        TopExp::Vertices(edg,Vf,Vl);
        gp_Pnt Pf = BRep_Tool::Pnt(Vf);
        gp_Pnt Pl = BRep_Tool::Pnt(Vl);
        Standard_Real Tolf = BRep_Tool::Tolerance(Vf);
        Standard_Real Toll = BRep_Tool::Tolerance(Vl);
        Tolf *= Tolf;
        Toll *= Toll;

        for (Standard_Integer i = 1; i <= intcs.NbPoints(); i++) {
          const IntCurveSurface_IntersectionPoint& Pi = intcs.Point(i);
          const gp_Pnt& pi = Pi.Pnt();
          Standard_Real dif = pi.SquareDistance(Pf);
          Standard_Real dil = pi.SquareDistance(Pl);
          if (dif <= Tolf) {
          }
          else if (dil <= Toll) {
          }
          else {
            if (Pi.W() >= f && Pi.W() <= l) {
            TopoDS_Vertex Vnew;
            B.MakeVertex(Vnew,pi,Precision::Confusion());
            splw.Add(Vnew,Pi.W(),edg);
            }
          }
        }
      }
      }
    }

    const TopTools_ListOfShape& lres = splw.DescendantShapes(W);
    if (lres.Extent() != 1) {
      return;
    }

    if (!W.IsSame(lres.First())) {
      theW.Nullify();
      theW = TopoDS::Wire(lres.First());
    }

    for (exp.ReInit(); exp.More(); exp.Next()) {
      if (!myMap.IsBound(exp.Current())) {
        TopTools_ListOfShape thelist1;
      myMap.Bind(exp.Current(), thelist1);
      for (itl.Initialize(splw.DescendantShapes(exp.Current())); 
           itl.More(); itl.Next()) {
        myMap(exp.Current()).Append(itl.Value());
      }
      for (exp2.Init(exp.Current(),TopAbs_VERTEX);exp2.More();exp2.Next()) {
        if (!myMap.IsBound(exp2.Current())) {
            TopTools_ListOfShape thelist2;
          myMap.Bind(exp2.Current(), thelist2);
          myMap(exp2.Current()).Append(exp2.Current());
        }
      }
      }
    }
  }
  else {
    for (exp.Init(W,TopAbs_EDGE); exp.More(); exp.Next()) {
      if (!myMap.IsBound(exp.Current())) {
        TopTools_ListOfShape thelist3;
      myMap.Bind(exp.Current(), thelist3);
      myMap(exp.Current()).Append(exp.Current());
      for (exp2.Init(exp.Current(),TopAbs_VERTEX);exp2.More();exp2.Next()) {
        if (!myMap.IsBound(exp2.Current())) {
          TopTools_ListOfShape thelist4;
          myMap.Bind(exp2.Current(), thelist4);
          myMap(exp2.Current()).Append(exp2.Current());
        }
      }
      }
    }
  }

  // On split la face par le wire
  
  Handle(LocOpe_WiresOnShape) WonS = new LocOpe_WiresOnShape(myShape);
  LocOpe_Spliter Spls(myShape);
  WonS->Bind(theW,F);

// JAG Le code suivant marchera apres integration de thick0
//  LocOpe_FindEdges fined(W,F);
//  for (fined.InitIterator(); fined.More(); fined.Next()) {
//    WonS->Bind(fined.EdgeFrom(),fined.EdgeTo());
//  }

  Spls.Perform(WonS);
  if (!Spls.IsDone()) {
    return;
  }

  TopoDS_Shape Res = Spls.ResultingShape();
  const TopTools_ListOfShape& theLeft = Spls.DirectLeft();

  // Descendants
  for (exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next()) {
    const TopoDS_Shape& fac = exp.Current();
    for (itl.Initialize(Spls.DescendantShapes(fac)); itl.More(); itl.Next()) {
      myMap(fac).Append(itl.Value());
    }
  }

  TopTools_DataMapOfShapeShape MapW;
  for (exp.Init(theW,TopAbs_EDGE); exp.More(); exp.Next()) {
    if (!MapW.IsBound(exp.Current())) {
      MapW.Bind(exp.Current(),TopoDS_Shape());
      for (exp2.Init(exp.Current(),TopAbs_VERTEX); exp2.More(); exp2.Next()) {
      if (!MapW.IsBound(exp2.Current())) {
        MapW.Bind(exp2.Current(),TopoDS_Shape());
      }

      }
    }
  }
  


  TopTools_IndexedDataMapOfShapeListOfShape theMapEF;
  TopExp::MapShapesAndAncestors(Res,TopAbs_EDGE,TopAbs_FACE,theMapEF);

  // On stocke les geometries potentiellement generees par les edges
  TopTools_IndexedDataMapOfShapeShape MapEV; // genere
  TopTools_DataMapOfShapeListOfShape MapSg,MapSd; // image a gauche et a droite

  Standard_Integer Nbedges,index;
  for (itl.Initialize(myMap(F)); itl.More(); itl.Next()) {
    const TopoDS_Shape& fac = TopoDS::Face(itl.Value());
    for (exp.Init(fac,TopAbs_EDGE); exp.More(); exp.Next()) {
      const TopoDS_Shape& edg = exp.Current();
      if (MapEV.FindIndex(edg) != 0) {
      continue;
      }
      if (MapW.IsBound(edg)) { // edge du wire initial
      TopLoc_Location Loc;
      Standard_Real f,l;
      Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(edg),Loc,f,l);
      if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
        C = Handle(Geom_TrimmedCurve)::DownCast(C)->BasisCurve();
      }
      C = Handle(Geom_Curve)::
        DownCast(C->Transformed(Loc.Transformation()));

      GeomFill_Pipe thePipe;
      thePipe.GenerateParticularCase(Standard_True);
      thePipe.Init(theLinePipe,C);
      thePipe.Perform(Standard_True);

      Handle(Geom_Surface) thePS = thePipe.Surface();
      if (thePS->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
        thePS = Handle(Geom_RectangularTrimmedSurface)::DownCast(thePS)
          ->BasisSurface();
      }

      TopoDS_Face NewFace;
      B.MakeFace(NewFace,thePS,Precision::Confusion());
      MapEV.Add(edg,NewFace);
      }
      else { // on recupere la face.
      index = theMapEF.FindIndex(edg);
      if (theMapEF(index).Extent() != 2) {
        return; // NotDone
      }
      TopoDS_Face theFace;
      if (theMapEF(index).First().IsSame(fac)) {
        MapEV.Add(edg,theMapEF(index).Last());
      }
      else {
        MapEV.Add(edg,theMapEF(index).First());
      }
      }
    }
  }


  TopTools_DataMapOfShapeShape MapSonS;

  Nbedges = MapEV.Extent();
  for (index = 1; index <= Nbedges; index++) {
    for (exp.Init(MapEV.FindKey(index),TopAbs_VERTEX); 
       exp.More(); exp.Next()) {
      const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
      if (MapEV.FindIndex(vtx)!= 0) {
      continue;
      }

      // Localisation du vertex :
      //    - entre 2 edges d`origine : on recupere l`edge qui n`est 
      //                                pas dans F
      //    - entre 2 edges du wire   : droite
      //    - mixte                   : intersection de surfaces
      for ( j = 1; j<=Nbedges; j++) {
      if (j == index) {
        continue;
      }
      for (exp2.Init(MapEV.FindKey(j),TopAbs_VERTEX);
           exp2.More(); exp2.Next()) {
        const TopoDS_Shape& vtx2 = exp2.Current();
        if (vtx2.IsSame(vtx)) {
          break;
        }
      }
      if (exp2.More()) {
        break;
      }
      }
      Standard_Integer Choice = 0;
      const TopoDS_Shape& edg1 = MapEV.FindKey(index);
      TopoDS_Shape edg2;
      if (j <= Nbedges) {
      edg2 = MapEV.FindKey(j);
      }
      else {
      edg2 = edg1;
      }
      if (MapW.IsBound(edg1)) {
      if (j>Nbedges) { // doit correspondre a edge ferme
        Choice = 2; // droite
      }
      else if (MapW.IsBound(MapEV.FindKey(j))) {
        Choice = 2; // droite
      }
      else {
        Choice = 3; // mixte
      }
      }
      else {
      if (j>Nbedges) { // doit correspondre a edge ferme
        Choice = 1; // edge a retrouver
      }
      else if (!MapW.IsBound(MapEV.FindKey(j))) {
        Choice = 1; // edge a retrouver
      }
      else {
        Choice = 3; // mixte
      }
      }
      Handle(Geom_Curve) Newc;
      Handle(Geom2d_Curve) newCs1,newCs2;
      Standard_Real knownp=0;
      TopoDS_Edge Ebind;
      switch (Choice) {
      case 1:
      {
        for (exp2.Init(Res,TopAbs_EDGE); exp2.More(); exp2.Next()) {
          if (exp2.Current().IsSame(edg1) || exp2.Current().IsSame(edg2)) {
            continue;
          }
//        for (TopExp_Explorer exp3(exp2.Current().Oriented(TopAbs_FORWARD),
            TopExp_Explorer exp3(exp2.Current().Oriented(TopAbs_FORWARD),
                              TopAbs_VERTEX) ;
          for ( ; exp3.More(); exp3.Next())  {
            if (exp3.Current().IsSame(vtx)) {
            break;
            }
          }
          if (exp3.More()) {
            break;
          }
        }
        if (exp2.More()) {
          Standard_Real f,l;
          TopLoc_Location Loc;
          Newc = BRep_Tool::Curve(TopoDS::Edge(exp2.Current()),Loc,f,l);
          Newc = Handle(Geom_Curve)::DownCast
            (Newc->Transformed(Loc.Transformation()));
          Ebind = TopoDS::Edge(exp2.Current());
          knownp = BRep_Tool::Parameter(vtx,Ebind);
        }
        else { // droite ??? il vaudrait mieux sortir
          return;

//        gp_Lin theLine(NormalFg);
//        theLine.Translate(NormalF.Location(),BRep_Tool::Pnt(vtx));
//        Newc = new Geom_Line(theLine);
//        knownp = 0.;
        }
      }
      break;
      case 2:
      {
        gp_Lin theLine(NormalFg);
        theLine.Translate(NormalFg.Location(),BRep_Tool::Pnt(vtx));
        Newc = new Geom_Line(theLine);
        knownp = 0.;
      }
      break;
      case 3:
      {
        const TopoDS_Face& F1 = TopoDS::Face(MapEV.FindFromKey(edg1));
        const TopoDS_Face& F2 = TopoDS::Face(MapEV.FindFromKey(edg2));
        Handle(Geom_Surface) S1 = BRep_Tool::Surface(F1);
        Handle(Geom_Surface) S2 = BRep_Tool::Surface(F2);
        Standard_Boolean AppS1 = Standard_False;
        Standard_Boolean AppS2 = Standard_False;
        if (S1->DynamicType() != STANDARD_TYPE(Geom_Plane)) {
          AppS1 = Standard_True;
        }
        if (S2->DynamicType() != STANDARD_TYPE(Geom_Plane)) {
          AppS2 = Standard_True;
        }
        i2s.Perform(S1,S2,Precision::Confusion(),Standard_True,AppS1,AppS2);
        if (!i2s.IsDone() || i2s.NbLines() <= 0) {
          return;
        }
      
        Standard_Real pmin=0, Dist, DistMin, GlobMin = RealLast();
        GeomAdaptor_Curve TheCurve;

        Standard_Integer i,imin,k;
        gp_Pnt pv = BRep_Tool::Pnt(vtx);
        imin = 0;
        for (i=1; i<= i2s.NbLines(); i++) {
          TheCurve.Load(i2s.Line(i));
          Extrema_ExtPC myExtPC(pv,TheCurve);

          if (myExtPC.IsDone()) {
            gp_Pnt p1b,p2b;
            Standard_Real thepmin = TheCurve.FirstParameter();
            myExtPC.TrimmedDistances(DistMin,Dist,p1b,p2b);
            if (Dist < DistMin) {
            thepmin = TheCurve.LastParameter();
            }
            for (k=1; k<=myExtPC.NbExt(); k++) {
            Dist = myExtPC.Value(k);
            if (Dist < DistMin) {
              DistMin = Dist;
              thepmin = myExtPC.Point(k).Parameter();
            }
            }
            
            if (DistMin  < GlobMin) {
            GlobMin = DistMin;
            pmin = thepmin;
            imin = i;
            }
          }
        }
        if (imin == 0) {
          return;
        }
        
        Newc = i2s.Line(imin);
        knownp = pmin;
        if (AppS1) {
          newCs1 = i2s.LineOnS1(imin);
        }
        if (AppS2) {
          newCs2 = i2s.LineOnS2(imin);
        }
      }
      break;
      }


      // Determination des vertex par intersection sur Plg ou/et Pld

      AC.Load(Newc);
      HAC->Set(AC);
      Standard_Integer nbfois = 2;
      TopoDS_Vertex vtx1,vtx2;
      Standard_Real p1=0,p2=0;
      Standard_Boolean IsLeft=Standard_False;
      if (Choice == 1) { 
      // edge retrouve : on ne fait qu`une seule intersection
      // il faut utiliser Plg ou Pld

      Standard_Integer indedgf = theMapEF.FindIndex(edg1);
      for (itl.Initialize(theMapEF(indedgf)); itl.More(); itl.Next()) {
        if (Contains(myMap(F),itl.Value())) {
          if (Contains(theLeft,itl.Value())) {
            AS.Load(NewSg);
            IsLeft = Standard_True;
          }
          else {
            AS.Load(NewSd);
            IsLeft = Standard_False;
          }
          
          nbfois = 1;
          vtx2 = vtx;
          p2 = knownp;
          break;
        }
      }
      if (!itl.More()) {
        cout << "LocOpe_SplitDrafts: betite probleme "<< endl;
        return;
      }

      }
      else {
      AS.Load(NewSg);
      }

      for (Standard_Integer it = 1; it<=nbfois; it++) {
      if (it == 2) {
        AS.Load(NewSd);
      }
      HAS->Set(AS);

      intcs.Perform(HAC,HAS);
      if (!intcs.IsDone()) {
        return; // voir ce qu`on peut faire de mieux
      }
      Standard_Integer imin = 1;
      Standard_Real delta = Abs(knownp - intcs.Point(1).W());
      for (Standard_Integer i = 2;  i<= intcs.NbPoints(); i++) {
        Standard_Real newdelta =  Abs(knownp - intcs.Point(i).W());
        if (newdelta < delta) {
          imin = i;
          delta = newdelta;
        }
      }
      if (it == 1) {
        B.MakeVertex(vtx1,intcs.Point(imin).Pnt(),Precision::Confusion());
        p1 = intcs.Point(imin).W();
        knownp = p1;
      }
      else {
        B.MakeVertex(vtx2,intcs.Point(imin).Pnt(),Precision::Confusion());
        p2 = intcs.Point(imin).W();
      }
      }
      if (Abs(p1-p2) > Precision::PConfusion()) {
      TopoDS_Edge NewEdge;
      B.MakeEdge(NewEdge,Newc,Precision::Confusion());
      if (p1 < p2) {
        B.Add(NewEdge,vtx1.Oriented(TopAbs_FORWARD));
        B.Add(NewEdge,vtx2.Oriented(TopAbs_REVERSED));
      }
      else {
        B.Add(NewEdge,vtx1.Oriented(TopAbs_REVERSED));
        B.Add(NewEdge,vtx2.Oriented(TopAbs_FORWARD));
      }
      B.UpdateVertex(vtx1,p1,NewEdge,Precision::Confusion());
      B.UpdateVertex(vtx2,p2,NewEdge,Precision::Confusion());
      if (!newCs1.IsNull()) {
        B.UpdateEdge(NewEdge,newCs1,
                   TopoDS::Face(MapEV.FindFromKey(edg1)),
                   Precision::Confusion());
      }

      if (!newCs2.IsNull()) {
        B.UpdateEdge(NewEdge,newCs2,
                   TopoDS::Face(MapEV.FindFromKey(edg2)),
                   Precision::Confusion());
      }

      
      MapEV.Add(vtx,NewEdge);

      if (Choice == 1) {
        TopoDS_Shape aLocalEdge = Ebind.EmptyCopied();
        TopoDS_Edge NE = TopoDS::Edge(aLocalEdge);
//      TopoDS_Edge NE = TopoDS::Edge(Ebind.EmptyCopied());
        for (exp2.Init(Ebind,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
          const TopoDS_Vertex& thevtx = TopoDS::Vertex(exp2.Current());
          if (thevtx.IsSame(vtx)) {
            B.Add(NE,vtx1.Oriented(thevtx.Orientation()));
            B.UpdateVertex(vtx1,p1,NE,Precision::Confusion());
          }
          else {
            B.Add(NE,thevtx);
            Standard_Real theprm = BRep_Tool::Parameter(thevtx,Ebind);
            B.UpdateVertex(thevtx,theprm,NE,BRep_Tool::Tolerance(thevtx));
          }
        }
        MapSonS.Bind(Ebind,NE.Oriented(TopAbs_FORWARD));
        if (IsLeft) {
            TopTools_ListOfShape thelist5;
          MapSg.Bind(vtx, thelist5);
          MapSg(vtx).Append(vtx1);
        }
        else {
            TopTools_ListOfShape thelist6;
          MapSd.Bind(vtx, thelist6);
          MapSd(vtx).Append(vtx1);
        }
      }
      else {
          TopTools_ListOfShape thelist7, thelist8;
        MapSg.Bind(vtx, thelist7);
        MapSd.Bind(vtx, thelist8);
        MapSg(vtx).Append(vtx1);
        MapSd(vtx).Append(vtx2);
      }
      }
      else {
      MapEV.Add(vtx,vtx2); // on peut avoir vtx2 = vtx si choix == 1
      if (Choice == 1) {
        if (IsLeft) {
            TopTools_ListOfShape thelist9;
          MapSg.Bind(vtx, thelist9);
          MapSg(vtx).Append(vtx);
        }
        else {
            TopTools_ListOfShape thelist10;
          MapSd.Bind(vtx, thelist10);
          MapSd(vtx).Append(vtx);
        }
      }
      else {
          TopTools_ListOfShape thelist11, thelist12;
        MapSg.Bind(vtx, thelist11);
        MapSd.Bind(vtx, thelist12);
        MapSg(vtx).Append(vtx2);
        MapSd(vtx).Append(vtx2);
      }
      }
    }
  }


  theMap.Clear();
  for (exp.Init(theW,TopAbs_EDGE); exp.More(); exp.Next()) {
    const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
    if (!theMap.Add(edg)) { // precaution sans doute inutile...
      continue;
    }
    Standard_Integer indedg = MapEV.FindIndex(edg);
    TopoDS_Face& GenF = TopoDS::Face(MapEV(indedg));
    TopTools_ListOfShape thelist13, thelist14;
    MapSg.Bind(edg, thelist13);  // genere a gauche
    MapSd.Bind(edg, thelist14);  // genere a droite
    TopoDS_Vertex Vf,Vl;
    TopoDS_Shape aLocalEdge = edg.Oriented(TopAbs_FORWARD);
    TopExp::Vertices(TopoDS::Edge(aLocalEdge),Vf,Vl);
//    TopExp::Vertices(TopoDS::Edge(edg.Oriented(TopAbs_FORWARD)),Vf,Vl);
    TopoDS_Shape Gvf = MapEV.FindFromKey(Vf); 
    TopoDS_Shape Gvl = MapEV.FindFromKey(Vl); 

/* Le code suivant est OK. On essaie de l`ameliorer

    if (Gvf.ShapeType() == TopAbs_VERTEX &&
      Gvl.ShapeType() == TopAbs_VERTEX) {
      // en fait on doit pouvoir avoir 1 face a 2 cotes...
      if (Gvf.IsSame(Vf)) {
      MapW(edg) = edg;
      MapSg(edg).Append(edg.Oriented(TopAbs_FORWARD));
      MapSd(edg).Append(edg.Oriented(TopAbs_FORWARD));
      }
      else {
      TopoDS_Edge NewEdg = NewEdge(edg,
                             GenF,NewSg,
                             TopoDS::Vertex(Gvf),
                             TopoDS::Vertex(Gvl));
      if (NewEdg.IsNull()) {
        return;
      }
      MapW(edg) = NewEdg;
      MapSg(edg).Append(NewEdg);
      MapSd(edg).Append(NewEdg);
      }
    }
    else if (Gvf.ShapeType() == TopAbs_VERTEX  ||
           Gvl.ShapeType() == TopAbs_VERTEX) {      // face triangulaire
      TopoDS_Vertex Vfd,Vld,Vfg,Vlg;
      if (Gvf.ShapeType() == TopAbs_VERTEX) {
      Vfg = TopoDS::Vertex(Gvf);
      Vfd = Vfg;
      Vlg = TopoDS::Vertex(MapSg(Vl).First());
      Vld = TopoDS::Vertex(MapSd(Vl).First());
      }
      else {
      Vlg = TopoDS::Vertex(Gvl);
      Vld = Vlg;
      Vfg = TopoDS::Vertex(MapSg(Vf).First());
      Vfd = TopoDS::Vertex(MapSd(Vf).First());
      }

      TopoDS_Edge NewEdgg = NewEdge(edg,GenF,NewSg,Vfg,Vlg);
      if (NewEdgg.IsNull()) {
      return;
      }

      TopoDS_Edge NewEdgd = NewEdge(edg,GenF,NewSd,Vfd,Vld);
      if (NewEdgg.IsNull()) {
      return;
      }
      MapSg(edg).Append(NewEdgg);
      MapSd(edg).Append(NewEdgd);

      TopTools_ListOfShape theedges;
      theedges.Append(NewEdgg);
      theedges.Append(NewEdgd);
      if (Gvf.ShapeType() == TopAbs_EDGE) {
      theedges.Append(Gvf);
      }
      else {//if (Gvl.ShapeType() == TopAbs_EDGE) {
      theedges.Append(Gvl);
      }
      MakeFace(GenF,theedges);
      MapW(edg) = GenF;
    }
    else {
      // une face a 4 cotes
      TopoDS_Vertex Vfd,Vld,Vfg,Vlg;

      Vfg = TopoDS::Vertex(MapSg(Vf).First());
      Vfd = TopoDS::Vertex(MapSd(Vf).First());
      Vlg = TopoDS::Vertex(MapSg(Vl).First());
      Vld = TopoDS::Vertex(MapSd(Vl).First());
      
      TopoDS_Vertex VVf1,VVl1,VVf2,VVl2;
      TopExp::Vertices(TopoDS::Edge(Gvf.Oriented(TopAbs_FORWARD)),VVf1,VVl1);
      TopExp::Vertices(TopoDS::Edge(Gvl.Oriented(TopAbs_FORWARD)),VVf2,VVl2);

      TopoDS_Edge NewEdgg = NewEdge(edg,GenF,NewSg,Vfg,Vlg);
      if (NewEdgg.IsNull()) {
      return;
      }
      
      TopoDS_Edge NewEdgd = NewEdge(edg,GenF,NewSd,Vfd,Vld);
      if (NewEdgd.IsNull()) {
      return;
      }

      if ((VVf1.IsSame(Vfg) && VVf2.IsSame(Vlg)) ||
        (VVf1.IsSame(Vfd) && VVf2.IsSame(Vld))) {
      // 4 cotes
      MapSg(edg).Append(NewEdgg);
      MapSd(edg).Append(NewEdgd);
      
      TopTools_ListOfShape theedges;
      theedges.Append(NewEdgg);
      theedges.Append(NewEdgd);
      theedges.Append(Gvf);
      theedges.Append(Gvl);
      
      MakeFace(GenF,theedges);
      MapW(edg) = GenF;
      }
      else {
#ifdef DEB
      cout << "Pb d'analyse" << endl;
#endif
      return;
      }
    }
*/
    // nouveau code

    TopoDS_Vertex Vfd,Vld,Vfg,Vlg;
    if (Gvf.ShapeType() == TopAbs_VERTEX) {
      Vfg = TopoDS::Vertex(Gvf);
      Vfd = Vfg;
    }
    else {
      Vfg = TopoDS::Vertex(MapSg(Vf).First());
      Vfd = TopoDS::Vertex(MapSd(Vf).First());
    }
    if (Gvl.ShapeType() == TopAbs_VERTEX) {
      Vlg = TopoDS::Vertex(Gvl);
      Vld = Vlg;
    }
    else {
      Vlg = TopoDS::Vertex(MapSg(Vl).First());
      Vld = TopoDS::Vertex(MapSd(Vl).First());
    }

    TopoDS_Edge NewEdgg = NewEdge(edg,GenF,NewSg,Vfg,Vlg);
    if (NewEdgg.IsNull()) {
      return;
    }
    
    TopoDS_Edge NewEdgd = NewEdge(edg,GenF,NewSd,Vfd,Vld);
    if (NewEdgg.IsNull()) {
      return;
    }

    Standard_Boolean isedg = Standard_False;
    if (Gvf.ShapeType() == TopAbs_VERTEX &&
      Gvl.ShapeType() == TopAbs_VERTEX) {
      // edg ou face a 2 cotes

      // Comparaison NewEdgg et NewEdgd
      Standard_Real fg,lg,fd,ld;
      Handle(Geom_Curve) Cg = BRep_Tool::Curve(NewEdgg,fg,lg);
      Handle(Geom_Curve) Cd = BRep_Tool::Curve(NewEdgd,fd,ld);
      Standard_Real prmg = (fg+lg)/2.;
      Standard_Real prmd = (fd+ld)/2.;
      gp_Pnt pg = Cg->Value(prmg);
      gp_Pnt pd = Cd->Value(prmd);
      Standard_Real Tol = Max(BRep_Tool::Tolerance(NewEdgg),
                        BRep_Tool::Tolerance(NewEdgg));
      if (pg.SquareDistance(pd) <= Tol*Tol) {
      isedg = Standard_True;
      // raffinement pour essayer de partager l`edge de depart...
      Standard_Boolean modified = Standard_True;
      if (Gvf.IsSame(Vf) && Gvl.IsSame(Vl)) {
        // Comparaison avec l`edge de depart
        Cd = BRep_Tool::Curve(edg,fd,ld);
        prmd = (fd+ld)/2.;
        pd = Cd->Value(prmd);
        Tol = Max(BRep_Tool::Tolerance(NewEdgg),
                BRep_Tool::Tolerance(edg));
        if (pg.SquareDistance(pd) <= Tol*Tol) {
          modified = Standard_False;
        }
      }

      if (!modified) {
        MapW(edg) = edg;
        MapSg(edg).Append(edg);
        MapSd(edg).Append(edg);
      }
      else {
        MapW(edg) = NewEdgg;
        MapSg(edg).Append(NewEdgg);
        MapSd(edg).Append(NewEdgg);
      }
      }
    }

    if (!isedg) {
      // face a 2 ou 3 ou 4 cotes
      MapSg(edg).Append(NewEdgg);
      MapSd(edg).Append(NewEdgd);
      
      TopTools_ListOfShape theedges;
      theedges.Append(NewEdgg);
      theedges.Append(NewEdgd);
      if (Gvf.ShapeType() == TopAbs_EDGE) {
      theedges.Append(Gvf);
      }
      if (Gvl.ShapeType() == TopAbs_EDGE) {
      theedges.Append(Gvl);
      }
      MakeFace(GenF,theedges);
      MapW(edg) = GenF;
    }

  }


  TopTools_MapOfShape mapedgadded;
  TopTools_ListOfShape thefaces;

  for (itl.Initialize(myMap(F)); itl.More(); itl.Next()) {
    const TopoDS_Face& fac = TopoDS::Face(itl.Value());
    theMap.Clear();
    TopoDS_Face DrftFace; // elle est FORWARD
    Standard_Boolean IsLeft;
    if (Contains(theLeft,fac)) {
      B.MakeFace(DrftFace,NewSg,BRep_Tool::Tolerance(fac));
      IsLeft = Standard_True;
    }
    else {
      B.MakeFace(DrftFace,NewSd,BRep_Tool::Tolerance(fac));
      IsLeft = Standard_False;
    }
    
    TopExp_Explorer exp3;
    for (exp3.Init(fac.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
       exp3.More(); exp3.Next()) {
      const TopoDS_Shape& wir = exp3.Current();
      TopoDS_Wire NewWireOnF;
      B.MakeWire(NewWireOnF);
      for (exp.Init(wir.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
         exp.More(); exp.Next()) {
      const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
      if (!theMap.Add(edg)) { // precaution sans doute inutile...
        continue;
      }
      if (MapW.IsBound(edg)) { // edge du wire d`origine
        TopTools_ListIteratorOfListOfShape itld;
        TopAbs_Orientation ored = edg.Orientation();
        if (IsLeft) {
          itld.Initialize(MapSg(edg));
        }
        else {
          itld.Initialize(MapSd(edg));
        }
        for (; itld.More(); itld.Next()) {
          if (itld.Value().Orientation() == TopAbs_REVERSED) {
            ored = TopAbs::Reverse(ored);
          }
          TopoDS_Shape aLocalEdge = itld.Value().Oriented(ored);
          B.Add(NewWireOnF,TopoDS::Edge(aLocalEdge));
//        B.Add(NewWireOnF,TopoDS::Edge(itld.Value().Oriented(ored)));
        }
      }
      else {
        Handle(Geom_Surface) NewS;
        if (IsLeft) {
          NewS = NewSg;
        }
        else {
          NewS = NewSd;
        }
        Standard_Integer indedg = MapEV.FindIndex(edg);
        const TopoDS_Face& GenF = TopoDS::Face(MapEV(indedg));
        TopoDS_Vertex Vf,Vl;
        TopoDS_Shape aLocalEdge = edg.Oriented(TopAbs_FORWARD);
        TopExp::Vertices(TopoDS::Edge(aLocalEdge),Vf,Vl);
//      TopExp::Vertices(TopoDS::Edge(edg.Oriented(TopAbs_FORWARD)),Vf,Vl);
        TopoDS_Shape Gvf = MapEV.FindFromKey(Vf); 
        TopoDS_Shape Gvl = MapEV.FindFromKey(Vl); 
        if (Gvf.ShapeType() == TopAbs_VERTEX &&
            Gvl.ShapeType() == TopAbs_VERTEX) {
          if (!Gvf.IsSame(Vf) || !Gvl.IsSame(Vl)) {
            TopoDS_Edge NewEdg = NewEdge(edg,GenF,NewS,
                                 TopoDS::Vertex(Gvf),
                                 TopoDS::Vertex(Gvl));
            if (NewEdg.IsNull()) {
            return;
            }

            MapSonS.Bind(edg,NewEdg);

            if (NewEdg.Orientation() == TopAbs_REVERSED) {
            NewEdg.Orientation(TopAbs::Reverse(edg.Orientation()));
            }
            else {
            NewEdg.Orientation(edg.Orientation());
            }           
            B.Add(NewWireOnF,NewEdg);
          }
          else { // Frozen???
            B.Add(NewWireOnF,edg);
          }
        }
        else {
          TopoDS_Vertex Vff,Vll;
          if (Gvf.ShapeType() == TopAbs_VERTEX) {
            Vff = TopoDS::Vertex(Gvf);
          }
          else {
            if (IsLeft) {
            Vff = TopoDS::Vertex(MapSg(Vf).First());
            }
            else {
            Vff = TopoDS::Vertex(MapSd(Vf).First());
            }
          }
          if (Gvl.ShapeType() == TopAbs_VERTEX) {
            Vll = TopoDS::Vertex(Gvl);
          }
          else {
            if (IsLeft) {
            Vll = TopoDS::Vertex(MapSg(Vl).First());
            }
            else {
            Vll = TopoDS::Vertex(MapSd(Vl).First());
            }
          }
          
          TopoDS_Edge NewEdg = NewEdge(edg,GenF,NewS,Vff,Vll);
          if (NewEdg.IsNull()) {
            return;
          }

          if (!MapW.IsBound(Vf) && !MapW.IsBound(Vl)) {
            MapSonS.Bind(edg,NewEdg);
          }
//        else if (MapW.IsBound(Vf) && MapW.IsBound(Vl)) {
            

//        }
          else {
            if (MapW.IsBound(Vf)) {
            if (Gvf.ShapeType() != TopAbs_EDGE || 
                mapedgadded.Contains(Gvf)) {
              MapSonS.Bind(edg,NewEdg);
            }
            else {
              TopoDS_Wire NewWir;
              B.MakeWire(NewWir);
              B.Add(NewWir,NewEdg);

              TopoDS_Vertex Vf2,Vl2;
              TopExp::Vertices(TopoDS::Edge(Gvf),Vf2,Vl2);
#ifdef DEB
              TopAbs_Orientation ornw =
#endif
                                            NewEdg.Orientation();

              // ici bug orientation : voir tspdrft6

//            if ((ornw == TopAbs_FORWARD && Vl2.IsSame(Vff)) ||
//                (ornw == TopAbs_REVERSED && Vl2.IsSame(Vll))) {
              if (Vl2.IsSame(Vff)) {
                B.Add(NewWir,Gvf.Oriented(TopAbs_FORWARD));
              }
              else {
                B.Add(NewWir,Gvf.Oriented(TopAbs_REVERSED));
              }
              mapedgadded.Add(Gvf);
              MapSonS.Bind(edg,NewWir); // NewWire est FORWARD
            }
            }
            else {
            if (Gvl.ShapeType() != TopAbs_EDGE ||
                mapedgadded.Contains(Gvl)) {
              MapSonS.Bind(edg,NewEdg);
            }
            else {
              TopoDS_Wire NewWir;
              B.MakeWire(NewWir);
              B.Add(NewWir,NewEdg);

              TopoDS_Vertex Vf2,Vl2;
              TopExp::Vertices(TopoDS::Edge(Gvl),Vf2,Vl2);
#ifdef DEB
              TopAbs_Orientation ornw =
#endif
                                            NewEdg.Orientation();

              // ici bug orientation : voir tspdrft6

//            if ((ornw == TopAbs_FORWARD && Vl2.IsSame(Vff)) ||
//                (ornw == TopAbs_REVERSED && Vl2.IsSame(Vll))) {
              if (Vf2.IsSame(Vll)) {
                B.Add(NewWir,Gvl.Oriented(TopAbs_FORWARD));
              }
              else {
                B.Add(NewWir,Gvl.Oriented(TopAbs_REVERSED));
              }
              mapedgadded.Add(Gvl);
              MapSonS.Bind(edg,NewWir); // NewWire est FORWARD
            }
            }
          }
          if (NewEdg.Orientation() == TopAbs_REVERSED) {
            NewEdg.Orientation(TopAbs::Reverse(edg.Orientation()));
          }
          else {
            NewEdg.Orientation(edg.Orientation());
          }       
          B.Add(NewWireOnF,NewEdg);
        }
      }
      }
      B.Add(DrftFace,NewWireOnF.Oriented(wir.Orientation()));
    }
    thefaces.Append(DrftFace);
  }

  BRepTools_Substitution theSubs;
  TopTools_DataMapIteratorOfDataMapOfShapeShape itdmss;
  for (itdmss.Initialize(MapSonS);
       itdmss.More(); itdmss.Next()) {
    TopTools_ListOfShape lsubs;
    for (exp.Init(itdmss.Value(),TopAbs_EDGE); exp.More(); exp.Next()) {
      lsubs.Append(exp.Current());
    }
    theSubs.Substitute(itdmss.Key(),lsubs);
  }

  // on reconstruit les faces
  for (exp.Init(Res,TopAbs_FACE); exp.More(); exp.Next()) {
    if (Contains(myMap(F),exp.Current())) {
      continue;
    }
    theSubs.Build(exp.Current());
  }

  // Stockage des descendants
//  for (TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdmsls(myMap);
  TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdmsls(myMap) ;
  for ( ; itdmsls.More(); itdmsls.Next()) {
    if (itdmsls.Key().ShapeType() == TopAbs_EDGE) {
      TopTools_ListOfShape thedesc;
      theMap.Clear();
      for (itl.Initialize(itdmsls.Value());itl.More(); itl.Next()) {
      if (theMap.Add(MapW(itl.Value()))) {
        thedesc.Append(MapW(itl.Value()));
      }
      }
      myMap(itdmsls.Key()) = thedesc;
    }
    else if (itdmsls.Key().IsSame(F)) {
      myMap(F).Clear();
      for (itl.Initialize(thefaces); itl.More(); itl.Next()) {
      myMap(F).Append(itl.Value());
      }
    }
    else {
      TopTools_ListOfShape thedesc;
      theMap.Clear();
      for (itl.Initialize(itdmsls.Value());itl.More(); itl.Next()) {
      if (theSubs.IsCopied(itl.Value())) {
        if (theSubs.Copy(itl.Value()).Extent() != 1) {
#ifdef DEB
          cout << "Invalid number of descendant" << endl;
#endif
          return;
        }
        else {
          if (theMap.Add(theSubs.Copy(itl.Value()).First())) {
            thedesc.Append(theSubs.Copy(itl.Value()).First());
          }
        }
      }
      else if (theMap.Add(itl.Value())) {
        thedesc.Append(itl.Value());
      }
      }
      myMap(itdmsls.Key()) = thedesc;
    }
  }

  theMap.Clear();
  thefaces.Clear();
  for (itdmsls.Initialize(myMap);itdmsls.More(); itdmsls.Next()) {
    for (itl.Initialize(itdmsls.Value());itl.More(); itl.Next()) {
      if (itl.Value().ShapeType() == TopAbs_FACE &&
        theMap.Add(itl.Value())) {
      thefaces.Append(itl.Value());
      }
    }
  }
  LocOpe_BuildShape BS(thefaces);
  myResult = BS.Shape();
}


Generated by  Doxygen 1.6.0   Back to index