2d6094436bee1e142904658ba959894684aa7658
[occt.git] / src / BRepTools / BRepTools.cxx
1 // Created on: 1993-01-21
2 // Created by: Remi LEQUETTE
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and / or modify it
9 // under the terms of the GNU Lesser General Public version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <Standard_Stream.hxx>
18
19 #include <BRepTools.ixx>
20 #include <BRepTools_ShapeSet.hxx>
21 #include <BRep_Tool.hxx>
22 #include <TopExp.hxx>
23 #include <TopExp_Explorer.hxx>
24 #include <TopoDS.hxx>
25 #include <TopoDS_Iterator.hxx>
26 #include <BndLib_Add2dCurve.hxx>
27 #include <Geom2dAdaptor_Curve.hxx>
28 #include <Geom_Surface.hxx>
29 #include <Geom_Curve.hxx>
30 #include <Geom2d_Curve.hxx>
31 #include <BRepTools_MapOfVertexPnt2d.hxx>
32 #include <BRep_CurveRepresentation.hxx>
33 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
34 #include <BRep_TEdge.hxx>
35 #include <TColgp_SequenceOfPnt2d.hxx>
36 #include <TColStd_SequenceOfReal.hxx>
37 #include <TColGeom2d_SequenceOfCurve.hxx>
38 #include <TopTools_SequenceOfShape.hxx>
39 #include <Precision.hxx>
40
41 #include <Poly_Triangulation.hxx>
42 #include <Poly_PolygonOnTriangulation.hxx>
43 #include <TColStd_HArray1OfInteger.hxx>
44 #include <TColStd_MapOfTransient.hxx>
45
46 #include <gp_Lin2d.hxx>
47 #include <ElCLib.hxx>
48 #include <gp_Vec2d.hxx>
49 #include <Standard_ErrorHandler.hxx>
50 #include <Standard_Failure.hxx>
51
52 #include <errno.h>
53
54 //=======================================================================
55 //function : UVBounds
56 //purpose  : 
57 //=======================================================================
58
59 void  BRepTools::UVBounds(const TopoDS_Face& F, 
60                           Standard_Real& UMin, Standard_Real& UMax, 
61                           Standard_Real& VMin, Standard_Real& VMax)
62 {
63   Bnd_Box2d B;
64   AddUVBounds(F,B);
65   B.Get(UMin,VMin,UMax,VMax);
66 }
67
68 //=======================================================================
69 //function : UVBounds
70 //purpose  : 
71 //=======================================================================
72
73 void  BRepTools::UVBounds(const TopoDS_Face& F,
74                           const TopoDS_Wire& W, 
75                           Standard_Real& UMin, Standard_Real& UMax, 
76                           Standard_Real& VMin, Standard_Real& VMax)
77 {
78   Bnd_Box2d B;
79   AddUVBounds(F,W,B);
80   B.Get(UMin,VMin,UMax,VMax);
81 }
82
83
84 //=======================================================================
85 //function : UVBounds
86 //purpose  : 
87 //=======================================================================
88
89 void  BRepTools::UVBounds(const TopoDS_Face& F,
90                           const TopoDS_Edge& E, 
91                           Standard_Real& UMin, Standard_Real& UMax, 
92                           Standard_Real& VMin, Standard_Real& VMax)
93 {
94   Bnd_Box2d B;
95   AddUVBounds(F,E,B);
96   B.Get(UMin,VMin,UMax,VMax);
97 }
98
99 //=======================================================================
100 //function : AddUVBounds
101 //purpose  : 
102 //=======================================================================
103
104 void  BRepTools::AddUVBounds(const TopoDS_Face& FF, Bnd_Box2d& B)
105 {
106   TopoDS_Face F = FF;
107   F.Orientation(TopAbs_FORWARD);
108   TopExp_Explorer ex(F,TopAbs_EDGE);
109
110   // fill box for the given face
111   Bnd_Box2d aBox;
112   for (;ex.More();ex.Next()) {
113     BRepTools::AddUVBounds(F,TopoDS::Edge(ex.Current()),aBox);
114   }
115   
116   // if the box is empty (face without edges or without pcurves),
117   // get natural bounds
118   if (aBox.IsVoid()) {
119     Standard_Real UMin,UMax,VMin,VMax;
120     TopLoc_Location L;
121     BRep_Tool::Surface(F,L)->Bounds(UMin,UMax,VMin,VMax);
122     aBox.Update(UMin,VMin,UMax,VMax);
123   }
124   
125   // add face box to result
126   B.Add ( aBox );
127 }
128
129
130 //=======================================================================
131 //function : AddUVBounds
132 //purpose  : 
133 //=======================================================================
134
135 void  BRepTools::AddUVBounds(const TopoDS_Face& F, 
136                              const TopoDS_Wire& W, 
137                              Bnd_Box2d& B)
138 {
139   TopExp_Explorer ex;
140   for (ex.Init(W,TopAbs_EDGE);ex.More();ex.Next()) {
141     BRepTools::AddUVBounds(F,TopoDS::Edge(ex.Current()),B);
142     }
143 }
144
145
146 //=======================================================================
147 //function : AddUVBounds
148 //purpose  : 
149 //=======================================================================
150
151 void  BRepTools::AddUVBounds(const TopoDS_Face& F, 
152                              const TopoDS_Edge& E,
153                              Bnd_Box2d& B)
154 {
155   Standard_Real pf,pl;
156   Bnd_Box2d Baux; 
157   const Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,pf,pl);
158   if (C.IsNull()) return;
159   if (pl < pf) { // Petit Blindage
160     Standard_Real aux;
161     aux = pf; pf = pl; pl = aux;
162   }
163   Geom2dAdaptor_Curve PC(C,pf,pl);
164   if (Precision::IsNegativeInfinite(pf) ||
165       Precision::IsPositiveInfinite(pf)) {
166     Geom2dAdaptor_Curve GC(PC);
167     BndLib_Add2dCurve::Add(GC,0.,B);
168     }
169   else {
170
171     // just compute points to get a close box.
172     TopLoc_Location L;
173     Standard_Real Umin,Umax,Vmin,Vmax;
174     const Handle(Geom_Surface)& Surf=BRep_Tool::Surface(F,L);
175     Surf->Bounds(Umin,Umax,Vmin,Vmax);
176     gp_Pnt2d Pa,Pb,Pc;
177
178
179     Standard_Real i, nbp = 20;
180     if (PC.GetType() == GeomAbs_Line) nbp = 2;
181     Standard_Real step = (pl - pf) / nbp;
182     gp_Pnt2d P;
183     PC.D0(pf,P);
184     Baux.Add(P);
185
186     Standard_Real du=0.0;
187     Standard_Real dv=0.0;
188
189     Pc=P;
190     for (i = 1; i < nbp; i++) {
191       pf += step;
192       PC.D0(pf,P);
193       Baux.Add(P);
194       if(i==1) { Pb=Pc; Pc=P; } 
195       else { 
196         //-- Calcul de la fleche 
197         Pa=Pb; Pb=Pc; Pc=P;     
198         gp_Vec2d PaPc(Pa,Pc);
199 //      gp_Lin2d L2d(Pa,PaPc);
200 //      Standard_Real up = ElCLib::Parameter(L2d,Pb);
201 //      gp_Pnt2d PProj   = ElCLib::Value(up,L2d);
202         gp_Pnt2d PProj(Pa.Coord()+(PaPc.XY()/2.));
203         Standard_Real ddu=Abs(Pb.X()-PProj.X());
204         Standard_Real ddv=Abs(Pb.Y()-PProj.Y());
205         if(ddv>dv) dv=ddv;
206         if(ddu>du) du=ddu;
207       }
208     }
209     PC.D0(pl,P);
210     Baux.Add(P);
211
212     //-- cout<<" du="<<du<<"   dv="<<dv<<endl;
213     Standard_Real u0,u1,v0,v1;
214     Baux.Get(u0,v0,u1,v1);
215     du*=1.5;
216     dv*=1.5;
217     u0-=du; v0-=dv; u1+=du; v1+=dv;
218     if(Surf->IsUPeriodic()) { } 
219     else { 
220       if(u0<=Umin) {  u0=Umin; } 
221       if(u1>=Umax) {  u1=Umax; } 
222     }
223     if(Surf->IsVPeriodic()) { } 
224     else { 
225       if(v0<=Vmin) {  v0=Vmin; } 
226       if(v1>=Vmax) {  v1=Vmax; }
227     }
228     P.SetCoord(u0,v0) ; Baux.Add(P);
229     P.SetCoord(u1,v1) ; Baux.Add(P);
230
231     Bnd_Box2d FinalBox;
232     Standard_Real aXmin, aYmin, aXmax, aYmax;
233     Baux.Get(aXmin, aYmin, aXmax, aYmax);
234     Standard_Real Tol2d = Precision::PConfusion();
235     if (Abs(aXmin - Umin) <= Tol2d)
236       aXmin = Umin;
237     if (Abs(aYmin - Vmin) <= Tol2d)
238       aYmin = Vmin;
239     if (Abs(aXmax - Umax) <= Tol2d)
240       aXmax = Umax;
241     if (Abs(aYmax - Vmax) <= Tol2d)
242       aYmax = Vmax;
243     FinalBox.Update(aXmin, aYmin, aXmax, aYmax);
244     
245     B.Add(FinalBox);
246   }
247 }
248
249 //=======================================================================
250 //function : Update
251 //purpose  : 
252 //=======================================================================
253
254 void BRepTools::Update(const TopoDS_Vertex&)
255 {
256 }
257
258 //=======================================================================
259 //function : Update
260 //purpose  : 
261 //=======================================================================
262
263 void BRepTools::Update(const TopoDS_Edge&)
264 {
265 }
266
267 //=======================================================================
268 //function : Update
269 //purpose  : 
270 //=======================================================================
271
272 void BRepTools::Update(const TopoDS_Wire&)
273 {
274 }
275
276 //=======================================================================
277 //function : Update
278 //purpose  : 
279 //=======================================================================
280
281 void BRepTools::Update(const TopoDS_Face& F)
282 {
283   if (!F.Checked()) {
284     UpdateFaceUVPoints(F);
285     F.TShape()->Checked(Standard_True);
286   }
287 }
288
289 //=======================================================================
290 //function : Update
291 //purpose  : 
292 //=======================================================================
293
294 void BRepTools::Update(const TopoDS_Shell& S)
295 {
296   TopExp_Explorer ex(S,TopAbs_FACE);
297   while (ex.More()) {
298     Update(TopoDS::Face(ex.Current()));
299     ex.Next();
300   }
301 }
302
303 //=======================================================================
304 //function : Update
305 //purpose  : 
306 //=======================================================================
307
308 void BRepTools::Update(const TopoDS_Solid& S)
309 {
310   TopExp_Explorer ex(S,TopAbs_FACE);
311   while (ex.More()) {
312     Update(TopoDS::Face(ex.Current()));
313     ex.Next();
314   }
315 }
316
317 //=======================================================================
318 //function : Update
319 //purpose  : 
320 //=======================================================================
321
322 void BRepTools::Update(const TopoDS_CompSolid& CS)
323 {
324   TopExp_Explorer ex(CS,TopAbs_FACE);
325   while (ex.More()) {
326     Update(TopoDS::Face(ex.Current()));
327     ex.Next();
328   }
329 }
330
331 //=======================================================================
332 //function : Update
333 //purpose  : 
334 //=======================================================================
335
336 void BRepTools::Update(const TopoDS_Compound& C)
337 {
338   TopExp_Explorer ex(C,TopAbs_FACE);
339   while (ex.More()) {
340     Update(TopoDS::Face(ex.Current()));
341     ex.Next();
342   }
343 }
344
345 //=======================================================================
346 //function : Update
347 //purpose  : 
348 //=======================================================================
349
350 void BRepTools::Update(const TopoDS_Shape& S)
351 {
352   switch (S.ShapeType()) {
353
354   case TopAbs_VERTEX :
355     Update(TopoDS::Vertex(S));
356     break;
357
358   case TopAbs_EDGE :
359     Update(TopoDS::Edge(S));
360     break;
361
362   case TopAbs_WIRE :
363     Update(TopoDS::Wire(S));
364     break;
365
366   case TopAbs_FACE :
367     Update(TopoDS::Face(S));
368     break;
369
370   case TopAbs_SHELL :
371     Update(TopoDS::Shell(S));
372     break;
373
374   case TopAbs_SOLID :
375     Update(TopoDS::Solid(S));
376     break;
377
378   case TopAbs_COMPSOLID :
379     Update(TopoDS::CompSolid(S));
380     break;
381
382   case TopAbs_COMPOUND :
383     Update(TopoDS::Compound(S));
384     break;
385
386   default:
387     break;
388
389   }
390 }
391
392
393 //=======================================================================
394 //function : UpdateFaceUVPoints
395 //purpose  : reset the UV points of a  Face
396 //=======================================================================
397
398 void  BRepTools::UpdateFaceUVPoints(const TopoDS_Face& F)
399 {
400   // Recompute for each edge the two UV points in order to have the same
401   // UV point on connected edges.
402
403   // First edge loop, store the vertices in a Map with their 2d points
404
405   BRepTools_MapOfVertexPnt2d theVertices;
406   TopoDS_Iterator expE,expV;
407   TopoDS_Iterator EdgeIt,VertIt;
408   TColStd_SequenceOfReal aFSeq, aLSeq;
409   TColGeom2d_SequenceOfCurve aCSeq;
410   TopTools_SequenceOfShape aShSeq;
411   gp_Pnt2d P;
412   Standard_Integer i;
413   // a 3d tolerance for UV !!
414   Standard_Real tolerance = BRep_Tool::Tolerance(F);
415   TColgp_SequenceOfPnt2d emptySequence;
416   
417   for (expE.Initialize(F); expE.More(); expE.Next()) {
418     if(expE.Value().ShapeType() != TopAbs_WIRE)
419       continue;
420     
421     EdgeIt.Initialize(expE.Value());
422     for( ; EdgeIt.More(); EdgeIt.Next())
423     {
424       const TopoDS_Edge& E = TopoDS::Edge(EdgeIt.Value());
425       Standard_Real f,l;
426       Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,f,l);
427
428       aFSeq.Append(f);
429       aLSeq.Append(l);
430       aCSeq.Append(C);
431       aShSeq.Append(E);
432
433       if (C.IsNull()) continue;
434
435       for (expV.Initialize(E.Oriented(TopAbs_FORWARD)); 
436            expV.More(); expV.Next()) {
437         
438         const TopoDS_Vertex& V = TopoDS::Vertex(expV.Value());
439         
440         TopAbs_Orientation Vori = V.Orientation();
441         if ( Vori == TopAbs_INTERNAL ) {
442           continue;
443         }
444         
445         Standard_Real p = BRep_Tool::Parameter(V,E,F);
446         C->D0(p,P);
447         if (!theVertices.IsBound(V)) 
448           theVertices.Bind(V,emptySequence);
449         TColgp_SequenceOfPnt2d& S = theVertices(V);
450         for (i = 1; i <= S.Length(); i++) {
451           if (P.Distance(S(i)) < tolerance) break;
452         }
453         if (i > S.Length())
454           S.Append(P);
455       }
456     }
457   }
458  
459   // second edge loop, update the edges 2d points
460   TopoDS_Vertex Vf,Vl;
461   gp_Pnt2d Pf,Pl;
462
463   for(Standard_Integer j = 1; j <= aShSeq.Length(); j++)
464   {
465     const TopoDS_Edge& E = TopoDS::Edge(aShSeq.Value(j));
466     const Handle(Geom2d_Curve)& C = aCSeq.Value(j);
467     if (C.IsNull()) continue;
468     
469     TopExp::Vertices(E,Vf,Vl);
470     if (Vf.IsNull()) {
471       Pf.SetCoord(RealLast(),RealLast());
472     }
473     else {
474       if ( Vf.Orientation() == TopAbs_INTERNAL ) {
475         continue;
476       }
477       const TColgp_SequenceOfPnt2d& seqf = theVertices(Vf);
478       if (seqf.Length() == 1) 
479         Pf = seqf(1);
480       else {
481         C->D0(aFSeq.Value(j),Pf);
482         for (i = 1; i <= seqf.Length(); i++) {
483           if (Pf.Distance(seqf(i)) <= tolerance) {
484             Pf = seqf(i);
485             break;
486           }
487         }
488       }
489     }
490     if (Vl.IsNull()) {
491       Pl.SetCoord(RealLast(),RealLast());
492     }
493     else {
494       if ( Vl.Orientation() == TopAbs_INTERNAL ) {
495         continue;
496       }
497       const TColgp_SequenceOfPnt2d& seql = theVertices(Vl);
498       if (seql.Length() == 1) 
499         Pl = seql(1);
500       else {
501         C->D0(aLSeq.Value(j),Pl);
502         for (i = 1; i <= seql.Length(); i++) {
503           if (Pl.Distance(seql(i)) <= tolerance) {
504             Pl = seql(i);
505             break;
506           }
507         }
508       }
509     }
510
511     // set the correct points
512     BRep_Tool::SetUVPoints(E,F,Pf,Pl);
513   }
514 }
515
516
517
518 //=======================================================================
519 //function : Compare
520 //purpose  : 
521 //=======================================================================
522
523 Standard_Boolean BRepTools::Compare(const TopoDS_Vertex& V1,
524                                     const TopoDS_Vertex& V2)
525 {
526   if (V1.IsSame(V2)) return Standard_True;
527   gp_Pnt p1 = BRep_Tool::Pnt(V1);
528   gp_Pnt p2 = BRep_Tool::Pnt(V2);
529   Standard_Real l = p1.Distance(p2);
530   if (l <= BRep_Tool::Tolerance(V1)) return Standard_True;
531   if (l <= BRep_Tool::Tolerance(V2)) return Standard_True;
532   return Standard_False;
533 }
534
535 //=======================================================================
536 //function : Compare
537 //purpose  : 
538 //=======================================================================
539
540 Standard_Boolean BRepTools::Compare(const TopoDS_Edge& E1,
541                                     const TopoDS_Edge& E2)
542 {
543   if (E1.IsSame(E2)) return Standard_True;
544   return Standard_False;
545 }
546
547 //=======================================================================
548 //function : OuterWire
549 //purpose  : 
550 //=======================================================================
551
552 TopoDS_Wire  BRepTools::OuterWire(const TopoDS_Face& F)
553 {
554   TopoDS_Wire Wres;
555   TopExp_Explorer expw (F,TopAbs_WIRE);
556
557   if (expw.More()) {
558     Wres = TopoDS::Wire(expw.Current());
559     expw.Next();
560     if (expw.More()) {
561       Standard_Real UMin, UMax, VMin, VMax;
562       Standard_Real umin, umax, vmin, vmax;
563       BRepTools::UVBounds(F,Wres,UMin,UMax,VMin,VMax);
564         while (expw.More()) {
565           const TopoDS_Wire& W = TopoDS::Wire(expw.Current());
566           BRepTools::UVBounds(F,W,umin, umax, vmin, vmax);
567           if ((umin <= UMin) &&
568               (umax >= UMax) &&
569               (vmin <= VMin) &&
570               (vmax >= VMax)) {
571             Wres = W;
572             UMin = umin;
573             UMax = umax;
574             VMin = vmin;
575             VMax = vmax;
576           }
577           expw.Next();
578         }
579     }
580   }
581   return Wres;
582 }
583
584 //=======================================================================
585 //function : Map3DEdges
586 //purpose  : 
587 //=======================================================================
588
589 void  BRepTools::Map3DEdges(const TopoDS_Shape& S, 
590                             TopTools_IndexedMapOfShape& M)
591 {
592   TopExp_Explorer Ex;
593   for (Ex.Init(S,TopAbs_EDGE); Ex.More(); Ex.Next()) {
594     if (!BRep_Tool::Degenerated(TopoDS::Edge(Ex.Current())))
595       M.Add(Ex.Current());
596   }
597 }
598
599 //=======================================================================
600 //function : Dump
601 //purpose  : 
602 //=======================================================================
603
604 void  BRepTools::Dump(const TopoDS_Shape& Sh, Standard_OStream& S)
605 {
606   BRepTools_ShapeSet SS;
607   SS.Add(Sh);
608   SS.Dump(Sh,S);
609   SS.Dump(S);
610 }
611
612 #ifdef DEB
613 //=======================================================================
614 //function : BRepTools_Write 
615 //purpose  : 
616 //=======================================================================
617 void BRepTools_Write (const TopoDS_Shape& S,
618                       const Standard_CString File)
619 {
620   BRepTools::Write (S,File);  
621 }
622 #endif
623
624 //=======================================================================
625 //function : Write
626 //purpose  : 
627 //=======================================================================
628
629 void  BRepTools::Write(const TopoDS_Shape& Sh, Standard_OStream& S,
630                        const Handle(Message_ProgressIndicator)& PR)
631 {
632   BRepTools_ShapeSet SS;
633   SS.SetProgress(PR);
634   SS.Add(Sh);
635   SS.Write(S);
636   SS.Write(Sh,S);
637 }
638
639
640 //=======================================================================
641 //function : Read
642 //purpose  : 
643 //=======================================================================
644
645 void  BRepTools::Read(TopoDS_Shape& Sh, 
646                       istream& S, 
647                       const BRep_Builder& B,
648                       const Handle(Message_ProgressIndicator)& PR)
649 {
650   BRepTools_ShapeSet SS(B);
651   SS.SetProgress(PR);
652   SS.Read(S);
653   SS.Read(Sh,S);
654 }
655
656 //=======================================================================
657 //function : Write
658 //purpose  : 
659 //=======================================================================
660
661 Standard_Boolean  BRepTools::Write(const TopoDS_Shape& Sh, 
662                                    const Standard_CString File,
663                                    const Handle(Message_ProgressIndicator)& PR)
664 {
665   ofstream os;
666   //  if (!fic.open(File,output)) return Standard_False;
667   os.open(File, ios::out);
668   if (!os.rdbuf()->is_open()) return Standard_False;
669
670   Standard_Boolean isGood = (os.good() && !os.eof());
671   if(!isGood)
672     return isGood;
673   
674   BRepTools_ShapeSet SS;
675   SS.SetProgress(PR);
676   SS.Add(Sh);
677   
678   os << "DBRep_DrawableShape\n";  // for easy Draw read
679   SS.Write(os);
680   isGood = os.good();
681   if(isGood )
682     SS.Write(Sh,os);
683   os.flush();
684   isGood = os.good();
685
686   errno = 0;
687   os.close();
688   isGood = os.good() && isGood && !errno;
689
690   return isGood;
691 }
692
693 //=======================================================================
694 //function : Read
695 //purpose  : 
696 //=======================================================================
697
698 Standard_Boolean BRepTools::Read(TopoDS_Shape& Sh, 
699                                  const Standard_CString File,
700                                  const BRep_Builder& B,
701                                  const Handle(Message_ProgressIndicator)& PR)
702 {
703   filebuf fic;
704   istream in(&fic);
705   if (!fic.open(File, ios::in)) return Standard_False;
706
707   BRepTools_ShapeSet SS(B);
708   SS.SetProgress(PR);
709   SS.Read(in);
710   if(!SS.NbShapes()) return Standard_False;
711   SS.Read(Sh,in);
712   return Standard_True;
713 }
714
715
716 //=======================================================================
717 //function : Clean
718 //purpose  : 
719 //=======================================================================
720
721 void BRepTools::Clean(const TopoDS_Shape& S)
722 {
723   BRep_Builder B;
724   TopExp_Explorer ex;
725   Handle(Poly_Triangulation) TNULL, T;
726   Handle(Poly_PolygonOnTriangulation) PolyNULL, Poly;
727
728   if (!S.IsNull()) {
729     TopLoc_Location L;
730     for (ex.Init(S,TopAbs_FACE);ex.More();ex.Next()) {
731       const TopoDS_Face& F = TopoDS::Face(ex.Current());
732       B.UpdateFace(F, TNULL);
733     }
734     for (ex.Init(S, TopAbs_EDGE); ex.More(); ex.Next()) {
735       const TopoDS_Edge& E = TopoDS::Edge(ex.Current());
736 // agv 21.09.01 : Inefficient management of Locations -> improve performance
737 //    do {
738 //      BRep_Tool::PolygonOnTriangulation(E, Poly, T, L);
739 //      B.UpdateEdge(E, PolyNULL, T, L);
740 //    } while(!Poly.IsNull());
741 //
742       Handle(BRep_CurveRepresentation) cr;
743       const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
744       BRep_ListOfCurveRepresentation& lcr = TE -> ChangeCurves();
745       BRep_ListIteratorOfListOfCurveRepresentation itcr(lcr);
746
747       // find and remove all representations
748       while (itcr.More()) {
749         cr = itcr.Value();
750         if (cr->IsPolygonOnTriangulation())
751           lcr.Remove(itcr);
752         else
753           itcr.Next();
754       }
755       TE->Modified(Standard_True);
756 // agv : fin
757     }
758   }
759 }
760
761 //=======================================================================
762 //function : RemoveUnusedPCurves
763 //purpose  : 
764 //=======================================================================
765
766 void BRepTools::RemoveUnusedPCurves(const TopoDS_Shape& S)
767 {
768   TColStd_MapOfTransient UsedSurfaces;
769   
770   TopExp_Explorer Explo(S, TopAbs_FACE);
771   for (; Explo.More(); Explo.Next())
772   {
773     TopoDS_Face aFace = TopoDS::Face(Explo.Current());
774     TopLoc_Location aLoc;
775     Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace, aLoc);
776     UsedSurfaces.Add(aSurf);
777   }
778
779   TopTools_IndexedMapOfShape Emap;
780   TopExp::MapShapes(S, TopAbs_EDGE, Emap);
781
782   Standard_Integer i;
783   for (i = 1; i <= Emap.Extent(); i++)
784   {
785     const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &Emap(i).TShape());
786     BRep_ListOfCurveRepresentation& lcr = TE -> ChangeCurves();
787     BRep_ListIteratorOfListOfCurveRepresentation itrep(lcr );
788     while (itrep.More())
789     {
790       Standard_Boolean ToRemove = Standard_False;
791       
792       Handle(BRep_CurveRepresentation) CurveRep = itrep.Value();
793       if (CurveRep->IsCurveOnSurface())
794       {
795         Handle(Geom_Surface) aSurface = CurveRep->Surface();
796         if (!UsedSurfaces.Contains(aSurface))
797           ToRemove = Standard_True;
798       }
799       else if (CurveRep->IsRegularity())
800       {
801         Handle(Geom_Surface) Surf1 = CurveRep->Surface();
802         Handle(Geom_Surface) Surf2 = CurveRep->Surface2();
803         ToRemove = (!UsedSurfaces.Contains(Surf1) || !UsedSurfaces.Contains(Surf2));
804       }
805       
806       if (ToRemove)
807         lcr.Remove(itrep);
808       else
809         itrep.Next();
810     }
811   }
812 }
813
814 //=======================================================================
815 //function : Triangulation
816 //purpose  : 
817 //=======================================================================
818
819 Standard_Boolean  BRepTools::Triangulation(const TopoDS_Shape&    S,
820                                            const Standard_Real    deflec)
821 {
822   TopExp_Explorer exf, exe;
823   TopLoc_Location l;
824   Handle(Poly_Triangulation) T;
825   Handle(Poly_PolygonOnTriangulation) Poly;
826
827   for (exf.Init(S, TopAbs_FACE); exf.More(); exf.Next()) {
828     const TopoDS_Face& F = TopoDS::Face(exf.Current());
829     T = BRep_Tool::Triangulation(F, l);
830     if (T.IsNull() || (T->Deflection() > deflec))
831       return Standard_False;
832     for (exe.Init(F, TopAbs_EDGE); exe.More(); exe.Next()) {
833       const TopoDS_Edge& E = TopoDS::Edge(exe.Current());
834       Poly = BRep_Tool::PolygonOnTriangulation(E, T, l);
835       if (Poly.IsNull()) return Standard_False;
836     }
837   }
838   return Standard_True;
839 }
840
841
842 //=======================================================================
843 //function : IsReallyClosed
844 //purpose  : 
845 //=======================================================================
846
847 Standard_Boolean BRepTools::IsReallyClosed(const TopoDS_Edge& E,
848                                            const TopoDS_Face& F)
849 {
850   if (!BRep_Tool::IsClosed(E,F)) {
851     return Standard_False;
852   }
853   Standard_Integer nbocc = 0;
854   TopExp_Explorer exp;
855   for (exp.Init(F,TopAbs_EDGE);exp.More();exp.Next()) {
856     if (exp.Current().IsSame(E)) {
857       nbocc++;
858     }
859   }
860   return nbocc == 2;
861 }
862
863
864