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