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