0027021: TopExp::Vertices performance optimization
[occt.git] / src / BRep / BRep_Tool.cxx
1 // Created on: 1993-07-07
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 under
9 // the terms of the GNU Lesser General Public License 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
18 #include <BRep_Curve3D.hxx>
19 #include <BRep_CurveOnClosedSurface.hxx>
20 #include <BRep_CurveOnSurface.hxx>
21 #include <BRep_CurveRepresentation.hxx>
22 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
23 #include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
24 #include <BRep_PointRepresentation.hxx>
25 #include <BRep_Polygon3D.hxx>
26 #include <BRep_PolygonOnClosedSurface.hxx>
27 #include <BRep_PolygonOnClosedTriangulation.hxx>
28 #include <BRep_PolygonOnSurface.hxx>
29 #include <BRep_PolygonOnTriangulation.hxx>
30 #include <BRep_TEdge.hxx>
31 #include <BRep_TFace.hxx>
32 #include <BRep_Tool.hxx>
33 #include <BRep_TVertex.hxx>
34 #include <ElSLib.hxx>
35 #include <Geom2d_Curve.hxx>
36 #include <Geom2d_TrimmedCurve.hxx>
37 #include <Geom2dAdaptor.hxx>
38 #include <Geom_Curve.hxx>
39 #include <Geom_OffsetSurface.hxx>
40 #include <Geom_Plane.hxx>
41 #include <Geom_RectangularTrimmedSurface.hxx>
42 #include <Geom_Surface.hxx>
43 #include <Geom_TrimmedCurve.hxx>
44 #include <GeomAdaptor_HCurve.hxx>
45 #include <GeomAdaptor_HSurface.hxx>
46 #include <GeomProjLib.hxx>
47 #include <gp_Pnt.hxx>
48 #include <gp_Pnt2d.hxx>
49 #include <NCollection_IncAllocator.hxx>
50 #include <NCollection_Map.hxx>
51 #include <Poly_Polygon2D.hxx>
52 #include <Poly_Polygon3D.hxx>
53 #include <Poly_PolygonOnTriangulation.hxx>
54 #include <Poly_Triangulation.hxx>
55 #include <Precision.hxx>
56 #include <ProjLib_ProjectedCurve.hxx>
57 #include <Standard_NoSuchObject.hxx>
58 #include <Standard_NullObject.hxx>
59 #include <TopExp.hxx>
60 #include <TopExp_Explorer.hxx>
61 #include <TopLoc_Location.hxx>
62 #include <TopoDS.hxx>
63 #include <TopoDS_Edge.hxx>
64 #include <TopoDS_Face.hxx>
65 #include <TopoDS_Iterator.hxx>
66 #include <TopoDS_Shape.hxx>
67 #include <TopoDS_Vertex.hxx>
68 #include <TopoDS_Wire.hxx>
69 #include <TopTools_MapOfShape.hxx>
70 #include <TopTools_ShapeMapHasher.hxx>
71 #include <BRep_GCurve.hxx>
72
73 //modified by NIZNHY-PKV Fri Oct 17 14:13:29 2008f
74 static 
75   Standard_Boolean IsPlane(const Handle(Geom_Surface)& aS);
76 //modified by NIZNHY-PKV Fri Oct 17 14:13:33 2008t
77 //
78 //=======================================================================
79 //function : Surface
80 //purpose  : Returns the geometric surface of the face. Returns
81 //           in <L> the location for the surface.
82 //=======================================================================
83
84 const Handle(Geom_Surface)& BRep_Tool::Surface(const TopoDS_Face& F,
85                                                TopLoc_Location& L)
86 {
87   const BRep_TFace* TF = static_cast<const BRep_TFace*>(F.TShape().get());
88   L = F.Location() * TF->Location();
89   return TF->Surface();
90 }
91
92 //=======================================================================
93 //function : Surface
94 //purpose  : Returns the geometric  surface of the face. It can
95 //           be a copy if there is a Location.
96 //=======================================================================
97
98 Handle(Geom_Surface) BRep_Tool::Surface(const TopoDS_Face& F)
99 {
100   const BRep_TFace* TF = static_cast<const BRep_TFace*>(F.TShape().get());
101   const Handle(Geom_Surface)& S = TF->Surface();
102
103   if(S.IsNull()) return S;
104
105   TopLoc_Location L = F.Location() * TF->Location();
106   if (!L.IsIdentity()) {
107     Handle(Geom_Geometry) aCopy = S->Transformed(L.Transformation());
108     Geom_Surface* aGS = static_cast<Geom_Surface*>(aCopy.get());
109     return Handle(Geom_Surface)(aGS);
110   }
111   return S;
112 }
113
114 //=======================================================================
115 //function : Triangulation
116 //purpose  : Returns  the Triangulation of  the  face. It  is a
117 //           null handle if there is no triangulation.
118 //=======================================================================
119
120 const Handle(Poly_Triangulation)& BRep_Tool::Triangulation(const TopoDS_Face& F,
121                                                            TopLoc_Location&   L)
122 {
123   L = F.Location();
124   const BRep_TFace* TF = static_cast<const BRep_TFace*>(F.TShape().get());
125   return TF->Triangulation();
126 }
127
128 //=======================================================================
129 //function : Tolerance
130 //purpose  : Returns the tolerance of the face.
131 //=======================================================================
132
133 Standard_Real  BRep_Tool::Tolerance(const TopoDS_Face& F)
134 {
135   const BRep_TFace* TF = static_cast<const BRep_TFace*>(F.TShape().get());
136   Standard_Real p = TF->Tolerance();
137   Standard_Real pMin = Precision::Confusion();
138   if (p > pMin) return p;
139   else          return pMin;
140 }
141
142 //=======================================================================
143 //function : NaturalRestriction
144 //purpose  : Returns the  NaturalRestriction  flag of the  face.
145 //=======================================================================
146
147 Standard_Boolean  BRep_Tool::NaturalRestriction(const TopoDS_Face& F)
148 {
149   const BRep_TFace* TF = static_cast<const BRep_TFace*>(F.TShape().get());
150   return TF->NaturalRestriction();
151 }
152
153 //=======================================================================
154 //function : Curve
155 //purpose  : Returns the 3D curve  of the edge.  May be  a Null
156 //           handle. Returns in <L> the location for the curve.
157 //           In <First> and <Last> the parameter range.
158 //=======================================================================
159
160 static const Handle(Geom_Curve) nullCurve;
161
162 const Handle(Geom_Curve)&  BRep_Tool::Curve(const TopoDS_Edge& E,
163                                             TopLoc_Location& L,
164                                             Standard_Real& First,
165                                             Standard_Real& Last)
166 {
167   // find the representation
168   const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
169   BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves()); 
170
171   while (itcr.More()) {
172     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
173     if (cr->IsCurve3D()) {
174       const BRep_Curve3D* GC = static_cast<const BRep_Curve3D*>(cr.get());
175       L = E.Location() * GC->Location();
176       GC->Range(First,Last);
177       return GC->Curve3D();
178     }
179     itcr.Next();
180   }
181   L.Identity();
182   return nullCurve;
183 }
184
185 //=======================================================================
186 //function : Curve
187 //purpose  : Returns the 3D curve  of the edge. May be a Null handle.
188 //           In <First> and <Last> the parameter range.
189 //           It can be a copy if there is a Location.
190 //=======================================================================
191
192 Handle(Geom_Curve)  BRep_Tool::Curve(const TopoDS_Edge& E,
193                                      Standard_Real& First,
194                                      Standard_Real& Last)
195 {
196   TopLoc_Location L;
197   const Handle(Geom_Curve)& C = Curve(E,L,First,Last);
198   if ( !C.IsNull() ) {
199     if ( !L.IsIdentity() ) {
200       Handle(Geom_Geometry) aCopy = C->Transformed(L.Transformation());
201       Geom_Curve* aGC = static_cast<Geom_Curve*>(aCopy.get());
202       return Handle(Geom_Curve)(aGC);
203     }
204   }
205   return C;
206 }
207
208 //=======================================================================
209 //function : IsGeometric
210 //purpose  : Returns True if <E> is a 3d curve or a curve on
211 //           surface.
212 //=======================================================================
213
214 Standard_Boolean  BRep_Tool::IsGeometric(const TopoDS_Edge& E)
215 {
216   // find the representation
217   const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
218   BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
219
220   while (itcr.More()) {
221     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
222     if (cr->IsCurve3D()) {
223       Standard_Real first, last;
224       TopLoc_Location L;
225       const Handle(Geom_Curve)&  C = BRep_Tool::Curve(E, L, first, last);
226       if (!C.IsNull()) return Standard_True;
227     }
228     else if (cr->IsCurveOnSurface()) return Standard_True;
229     itcr.Next();
230   }
231   return Standard_False;
232 }
233
234 //=======================================================================
235 //function : Polygon3D
236 //purpose  : Returns the 3D polygon of the edge. May be   a Null
237 //           handle. Returns in <L> the location for the polygon.
238 //=======================================================================
239
240 static const Handle(Poly_Polygon3D) nullPolygon3D;
241
242 const Handle(Poly_Polygon3D)& BRep_Tool::Polygon3D(const TopoDS_Edge& E,
243                                                    TopLoc_Location&   L)
244 {
245   // find the representation
246   const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
247   BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
248
249   while (itcr.More()) {
250     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
251     if (cr->IsPolygon3D()) {
252       const BRep_Polygon3D* GC = static_cast<const BRep_Polygon3D*>(cr.get());
253       L = E.Location() * GC->Location();
254       return GC->Polygon3D();
255     }
256     itcr.Next();
257   }
258   L.Identity();
259   return nullPolygon3D;
260 }
261
262 //=======================================================================
263 //function : CurveOnSurface
264 //purpose  : Returns the curve  associated to the  edge in  the
265 //           parametric  space of  the  face.  Returns   a NULL
266 //           handle  if this curve  does not exist.  Returns in
267 //           <First> and <Last> the parameter range.
268 //=======================================================================
269
270 Handle(Geom2d_Curve) BRep_Tool::CurveOnSurface(const TopoDS_Edge& E, 
271                                                const TopoDS_Face& F,
272                                                Standard_Real& First,
273                                                Standard_Real& Last)
274 {
275   TopLoc_Location l;
276   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,l);
277   TopoDS_Edge aLocalEdge = E;
278   if (F.Orientation() == TopAbs_REVERSED) {
279     aLocalEdge.Reverse();
280 //    return CurveOnSurface(E,S,l,First,Last);
281   }
282 //    return CurveOnSurface(TopoDS::Edge(E.Reversed()),S,l,First,Last);
283 //  else
284 //    return CurveOnSurface(E,S,l,First,Last);
285   return CurveOnSurface(aLocalEdge,S,l,First,Last);
286 }
287
288 //=======================================================================
289 //function : CurveOnSurface
290 //purpose  : Returns the  curve associated to   the edge in the
291 //           parametric  space of the   surface. Returns a NULL
292 //           handle  if this curve does  not exist.  Returns in
293 //           <First> and <Last> the parameter range.
294 //=======================================================================
295
296 static const Handle(Geom2d_Curve) nullPCurve;
297
298 Handle(Geom2d_Curve) BRep_Tool::CurveOnSurface(const TopoDS_Edge& E, 
299                                                const Handle(Geom_Surface)& S,
300                                                const TopLoc_Location& L,
301                                                Standard_Real& First,
302                                                Standard_Real& Last)
303 {
304   TopLoc_Location loc = L.Predivided(E.Location());
305   Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED);
306
307   // find the representation
308   const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
309   BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
310
311   while (itcr.More()) {
312     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
313     if (cr->IsCurveOnSurface(S,loc)) {
314       const BRep_GCurve* GC = static_cast<const BRep_GCurve*>(cr.get());
315       GC->Range(First,Last);
316       if (GC->IsCurveOnClosedSurface() && Eisreversed)
317         return GC->PCurve2();
318       else
319         return GC->PCurve();
320     }
321     itcr.Next();
322   }
323
324   // for planar surface and 3d curve try a projection
325   // modif 21-05-97 : for RectangularTrimmedSurface, try a projection
326   Handle(Geom_Plane) GP;
327   Handle(Geom_RectangularTrimmedSurface) GRTS;
328   GRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
329   if(!GRTS.IsNull())
330     GP = Handle(Geom_Plane)::DownCast(GRTS->BasisSurface());
331   else
332     GP = Handle(Geom_Plane)::DownCast(S);
333   //fin modif du 21-05-97
334
335   if (!GP.IsNull())
336   {
337     Handle(GeomAdaptor_HCurve) HC;
338     Handle(GeomAdaptor_HSurface) HS;
339
340     HC = new GeomAdaptor_HCurve();
341     HS = new GeomAdaptor_HSurface();
342
343     TopLoc_Location aCurveLocation;
344
345     Standard_Real f, l;// for those who call with (u,u).
346     Handle(Geom_Curve) C3d = BRep_Tool::Curve(E, aCurveLocation, f, l);
347
348     if (C3d.IsNull())
349     {
350       return nullPCurve;
351     }
352
353     aCurveLocation = aCurveLocation.Predivided(L);
354     First = f; Last = l; //Range of edge must not be modified
355
356     if (!aCurveLocation.IsIdentity())
357     {
358       const gp_Trsf& T = aCurveLocation.Transformation();
359       Handle(Geom_Geometry) GC3d = C3d->Transformed(T);
360       C3d = Handle(Geom_Curve)::DownCast (GC3d);
361       f = C3d->TransformedParameter(f, T);
362       l = C3d->TransformedParameter(l, T);
363     }
364     GeomAdaptor_Surface& GAS = HS->ChangeSurface();
365     GAS.Load(GP);
366
367     Handle(Geom_Curve) ProjOnPlane = 
368       GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3d,f,l,Standard_True,Standard_False),
369                                   GP,
370                                   GP->Position().Direction(),
371                                   Standard_True);
372
373     GeomAdaptor_Curve& GAC = HC->ChangeCurve();
374     GAC.Load(ProjOnPlane);
375
376     ProjLib_ProjectedCurve Proj(HS,HC);
377     Handle(Geom2d_Curve) pc = Geom2dAdaptor::MakeCurve(Proj);
378
379     if (pc->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
380       Handle(Geom2d_TrimmedCurve) TC = 
381         Handle(Geom2d_TrimmedCurve)::DownCast (pc);
382       pc = TC->BasisCurve();
383     }
384
385     return pc;
386   }
387   
388   return nullPCurve;
389 }
390
391 //=======================================================================
392 //function : CurveOnSurface
393 //purpose  : 
394 //=======================================================================
395
396 void  BRep_Tool::CurveOnSurface(const TopoDS_Edge& E, 
397                                 Handle(Geom2d_Curve)& C, 
398                                 Handle(Geom_Surface)& S, 
399                                 TopLoc_Location& L,
400                                 Standard_Real& First,
401                                 Standard_Real& Last)
402 {
403   // find the representation
404   const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
405   BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
406
407   while (itcr.More()) {
408     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
409     if (cr->IsCurveOnSurface()) {
410       const BRep_GCurve* GC = static_cast<const BRep_GCurve*>(cr.get());
411       C = GC->PCurve();
412       S = GC->Surface();
413       L = E.Location() * GC->Location();
414       GC->Range(First,Last);
415       return;
416     }
417     itcr.Next();
418   }
419   
420   C = Handle(Geom2d_Curve)();
421   S = Handle(Geom_Surface)();
422   L = TopLoc_Location();
423 }
424
425 //=======================================================================
426 //function : CurveOnSurface
427 //purpose  : 
428 //=======================================================================
429
430 void  BRep_Tool::CurveOnSurface(const TopoDS_Edge& E, 
431                                 Handle(Geom2d_Curve)& C, 
432                                 Handle(Geom_Surface)& S, 
433                                 TopLoc_Location& L,
434                                 Standard_Real& First,
435                                 Standard_Real& Last,
436                                 const Standard_Integer Index)
437 {
438   Standard_Integer i = 0;
439   Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED);
440
441   // find the representation
442   const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
443   BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
444
445   while (itcr.More()) {
446     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
447     if (cr->IsCurveOnSurface()) {
448       const BRep_GCurve* GC = static_cast<const BRep_GCurve*>(cr.get());
449       i++;
450       if (i > Index) break;
451       if (i == Index) {
452         // JMB le 21 Mai 1999
453         // it is done as in the other CurveOnSurface methods, ie. take into account
454         // the orientation in case of cut edges (return PCurve2)
455         // otherwise there is a risk to loop curves or to not get the prover one.
456         if (GC->IsCurveOnClosedSurface() && Eisreversed)
457           C = GC->PCurve2();
458         else
459           C = GC->PCurve();
460         S = GC->Surface();
461         L = E.Location() * GC->Location();
462         GC->Range(First,Last);
463         return;
464       }
465     }
466     itcr.Next();
467   }
468   
469   C = Handle(Geom2d_Curve)();
470   S = Handle(Geom_Surface)();
471   L = TopLoc_Location();
472 }
473
474 //=======================================================================
475 //function : PolygonOnSurface
476 //purpose  : Returns the polygon associated to the  edge in  the
477 //           parametric  space of  the  face.  Returns   a NULL
478 //           handle  if this polygon  does not exist.
479 //=======================================================================
480
481 Handle(Poly_Polygon2D) BRep_Tool::PolygonOnSurface(const TopoDS_Edge& E, 
482                                                    const TopoDS_Face& F)
483 {
484   TopLoc_Location l;
485   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,l);
486   TopoDS_Edge aLocalEdge = E;
487   if (F.Orientation() == TopAbs_REVERSED) {
488     aLocalEdge.Reverse();
489 //    return PolygonOnSurface(E,S,l);
490   }
491   //    return PolygonOnSurface(TopoDS::Edge(E.Reversed()),S,l);
492 //  else
493 //    return PolygonOnSurface(E,S,l);
494   return PolygonOnSurface(aLocalEdge,S,l);
495 }
496
497 //=======================================================================
498 //function : PolygonOnSurface
499 //purpose  : Returns the polygon associated to the  edge in  the
500 //           parametric  space of  the surface. Returns   a NULL
501 //           handle  if this polygon  does not exist.
502 //=======================================================================
503
504 static const Handle(Poly_Polygon2D) nullPolygon2D;
505
506 Handle(Poly_Polygon2D) BRep_Tool::PolygonOnSurface(const TopoDS_Edge& E, 
507                                                    const Handle(Geom_Surface)& S,
508                                                    const TopLoc_Location& L)
509 {
510   TopLoc_Location l = L.Predivided(E.Location());
511   Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED);
512
513   // find the representation
514   const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
515   BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
516
517   while (itcr.More()) {
518     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
519     if (cr->IsPolygonOnSurface(S,l)) {
520       if (cr->IsPolygonOnClosedSurface() && Eisreversed )
521         return cr->Polygon2();
522       else
523         return cr->Polygon();
524     }
525     itcr.Next();
526   }
527   
528   return nullPolygon2D;
529 }
530
531 //=======================================================================
532 //function : PolygonOnSurface
533 //purpose  : 
534 //=======================================================================
535
536 void BRep_Tool::PolygonOnSurface(const TopoDS_Edge&      E,
537                                  Handle(Poly_Polygon2D)& P,
538                                  Handle(Geom_Surface)&   S,
539                                  TopLoc_Location&        L)
540 {
541   // find the representation
542   const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
543   BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
544
545   while (itcr.More()) {
546     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
547     if (cr->IsPolygonOnSurface()) {
548       const BRep_PolygonOnSurface* PS = static_cast<const BRep_PolygonOnSurface*>(cr.get());
549       P = PS->Polygon();
550       S = PS->Surface();
551       L = E.Location() * PS->Location();
552       return;
553     }
554     itcr.Next();
555   }
556   
557   L = TopLoc_Location();
558   P = Handle(Poly_Polygon2D)();
559   S = Handle(Geom_Surface)();
560 }
561
562 //=======================================================================
563 //function : PolygonOnSurface
564 //purpose  : 
565 //=======================================================================
566
567 void BRep_Tool::PolygonOnSurface(const TopoDS_Edge&      E,
568                                  Handle(Poly_Polygon2D)& P,
569                                  Handle(Geom_Surface)&   S,
570                                  TopLoc_Location&        L,
571                                  const Standard_Integer  Index)
572 {
573   Standard_Integer i = 0;
574
575   // find the representation
576   const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
577   BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
578
579   while (itcr.More()) {
580     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
581     if (cr->IsPolygonOnSurface()) {
582       const BRep_PolygonOnSurface* PS = static_cast<const BRep_PolygonOnSurface*>(cr.get());
583       i++;
584       if (i > Index) break;
585       if (i == Index) {
586         P = PS->Polygon();
587         S = PS->Surface();
588         L = E.Location() * PS->Location();
589         return;
590       }
591     }
592     itcr.Next();
593   }
594   
595   L = TopLoc_Location();
596   P = Handle(Poly_Polygon2D)();
597   S = Handle(Geom_Surface)();
598 }
599
600 //=======================================================================
601 //function : PolygonOnTriangulation
602 //purpose  : Returns the polygon associated to the  edge in  the
603 //           parametric  space of  the  face.  Returns   a NULL
604 //           handle  if this polygon  does not exist.
605 //=======================================================================
606
607 static const Handle(Poly_PolygonOnTriangulation) nullArray;
608
609 const Handle(Poly_PolygonOnTriangulation)&
610 BRep_Tool::PolygonOnTriangulation(const TopoDS_Edge&                E, 
611                                   const Handle(Poly_Triangulation)& T,
612                                   const TopLoc_Location&            L)
613 {
614   TopLoc_Location l = L.Predivided(E.Location());
615   Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED);
616
617   // find the representation
618   const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
619   BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
620
621   while (itcr.More()) {
622     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
623     if ( cr->IsPolygonOnTriangulation(T,l)) {
624       if ( cr->IsPolygonOnClosedTriangulation() && Eisreversed )
625         return cr->PolygonOnTriangulation2();
626       else
627         return cr->PolygonOnTriangulation();
628     }
629     itcr.Next();
630   }
631   
632   return nullArray;
633 }
634
635 //=======================================================================
636 //function : PolygonOnTriangulation
637 //purpose  : 
638 //=======================================================================
639
640 void 
641 BRep_Tool::PolygonOnTriangulation(const TopoDS_Edge&                   E,
642                                   Handle(Poly_PolygonOnTriangulation)& P,
643                                   Handle(Poly_Triangulation)&          T,
644                                   TopLoc_Location&                     L)
645 {
646   // find the representation
647   const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
648   BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
649
650   while (itcr.More()) {
651     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
652     if (cr->IsPolygonOnTriangulation()) {
653       const BRep_PolygonOnTriangulation* PT =
654         static_cast<const BRep_PolygonOnTriangulation*>(cr.get());
655       P = PT->PolygonOnTriangulation();
656       T = PT->Triangulation();
657       L = E.Location() * PT->Location();
658       return;
659     }
660     itcr.Next();
661   }
662   
663   L = TopLoc_Location();
664   P = Handle(Poly_PolygonOnTriangulation)();
665   T = Handle(Poly_Triangulation)();
666 }
667
668 //=======================================================================
669 //function : PolygonOnTriangulation
670 //purpose  : 
671 //=======================================================================
672
673 void 
674 BRep_Tool::PolygonOnTriangulation(const TopoDS_Edge&                   E,
675                                   Handle(Poly_PolygonOnTriangulation)& P,
676                                   Handle(Poly_Triangulation)&          T,
677                                   TopLoc_Location&                     L,
678                                   const Standard_Integer               Index)
679 {
680   Standard_Integer i = 0;
681
682   // find the representation
683   const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
684   BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
685
686   while (itcr.More()) {
687     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
688     if (cr->IsPolygonOnTriangulation()) {
689       const BRep_PolygonOnTriangulation* PT =
690         static_cast<const BRep_PolygonOnTriangulation*>(cr.get());
691       i++;
692       if (i > Index) break;
693       if (i == Index) {
694         T = PT->Triangulation();
695         P = PT->PolygonOnTriangulation();
696         L = E.Location() * PT->Location();
697         return;
698       }
699     }
700     itcr.Next();
701   }
702   
703   L = TopLoc_Location();
704   P = Handle(Poly_PolygonOnTriangulation)();
705   T = Handle(Poly_Triangulation)();
706 }
707
708 //=======================================================================
709 //function : IsClosed
710 //purpose  : Returns  True  if  <E>  has  two  PCurves  in  the
711 //           parametric space of <F>. i.e.  <F>  is on a closed
712 //           surface and <E> is on the closing curve.
713 //=======================================================================
714
715 Standard_Boolean BRep_Tool::IsClosed(const TopoDS_Edge& E, 
716                                      const TopoDS_Face& F)
717 {
718   TopLoc_Location l;
719   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,l);
720   if (IsClosed(E,S,l)) return Standard_True;
721   const Handle(Poly_Triangulation)& T = BRep_Tool::Triangulation(F,l);
722   return IsClosed(E, T, l);
723 }
724
725 //=======================================================================
726 //function : IsClosed
727 //purpose  : Returns  True  if  <E>  has  two  PCurves  in  the
728 //           parametric space  of <S>.  i.e.   <S>  is a closed
729 //           surface and <E> is on the closing curve.
730 //=======================================================================
731
732 Standard_Boolean BRep_Tool::IsClosed(const TopoDS_Edge& E,
733                                      const Handle(Geom_Surface)& S,
734                                      const TopLoc_Location& L)
735 {
736   //modified by NIZNHY-PKV Fri Oct 17 12:16:58 2008f
737   if (IsPlane(S)) {
738     return Standard_False;
739   }
740   //modified by NIZNHY-PKV Fri Oct 17 12:16:54 2008t
741   //
742   TopLoc_Location      l = L.Predivided(E.Location());
743
744   // find the representation
745   const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
746   BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
747
748   while (itcr.More()) {
749     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
750     if (cr->IsCurveOnSurface(S,l) &&
751         cr->IsCurveOnClosedSurface())
752       return Standard_True;
753     itcr.Next();
754   }
755   return Standard_False;
756 }
757
758 //=======================================================================
759 //function : IsClosed
760 //purpose  : Returns  True  if <E> has two arrays of indices in
761 //           the triangulation <T>.
762 //=======================================================================
763
764 Standard_Boolean BRep_Tool::IsClosed(const TopoDS_Edge&                E, 
765                                      const Handle(Poly_Triangulation)& T,
766                                      const TopLoc_Location& L)
767 {
768   TopLoc_Location l = L.Predivided(E.Location());
769
770   // find the representation
771   const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
772   BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
773
774   while (itcr.More()) {
775     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
776     if (cr->IsPolygonOnTriangulation(T,l) &&
777         cr->IsPolygonOnClosedTriangulation()) 
778       return Standard_True;
779     itcr.Next();
780   }
781   return Standard_False;
782 }
783
784 //=======================================================================
785 //function : Tolerance
786 //purpose  : Returns the tolerance for <E>.
787 //=======================================================================
788
789 Standard_Real  BRep_Tool::Tolerance(const TopoDS_Edge& E)
790 {
791   const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
792   Standard_Real p = TE->Tolerance();
793   Standard_Real pMin = Precision::Confusion();
794   if (p > pMin) return p;
795   else          return pMin;
796 }
797
798 //=======================================================================
799 //function : SameParameter
800 //purpose  : Returns the SameParameter flag for the edge.
801 //=======================================================================
802
803 Standard_Boolean  BRep_Tool::SameParameter(const TopoDS_Edge& E)
804 {
805   const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
806   return TE->SameParameter();
807 }
808
809 //=======================================================================
810 //function : SameRange
811 //purpose  : Returns the SameRange flag for the edge.
812 //=======================================================================
813
814 Standard_Boolean  BRep_Tool::SameRange(const TopoDS_Edge& E)
815 {
816   const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
817   return TE->SameRange();
818 }
819
820 //=======================================================================
821 //function : Degenerated
822 //purpose  : Returns True  if the edge is degenerated.
823 //=======================================================================
824
825 Standard_Boolean  BRep_Tool::Degenerated(const TopoDS_Edge& E)
826 {
827   const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
828   return TE->Degenerated();
829 }
830
831 //=======================================================================
832 //function : Range
833 //purpose  : 
834 //=======================================================================
835
836 void  BRep_Tool::Range(const TopoDS_Edge& E, 
837                        Standard_Real& First, 
838                        Standard_Real& Last)
839 {
840   //  set the range to all the representations
841   const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
842   BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
843
844   while (itcr.More()) {
845     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
846     if (cr->IsCurve3D()) {
847       const BRep_Curve3D* CR = static_cast<const BRep_Curve3D*>(cr.get());
848       if (!CR->Curve3D().IsNull()) {
849         First = CR->First(); 
850         Last = CR->Last();
851         break;
852       }
853     }
854     else if (cr->IsCurveOnSurface()) {
855       const BRep_GCurve* CR = static_cast<const BRep_GCurve*>(cr.get());
856       First = CR->First(); 
857       Last = CR->Last();
858       break;
859     }
860     itcr.Next();
861   }
862 }
863
864 //=======================================================================
865 //function : Range
866 //purpose  : 
867 //=======================================================================
868
869 void  BRep_Tool::Range(const TopoDS_Edge& E, 
870                        const Handle(Geom_Surface)& S,
871                        const TopLoc_Location& L,
872                        Standard_Real& First, 
873                        Standard_Real& Last)
874 {
875   TopLoc_Location l = L.Predivided(E.Location());
876   
877   // find the representation
878   const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
879   BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
880   
881   while (itcr.More()) {
882     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
883     if (cr->IsCurveOnSurface(S,l)) {
884       const BRep_CurveOnSurface* CR = static_cast<const BRep_CurveOnSurface*>(cr.get());
885       CR->Range(First,Last);
886       break;
887     }
888     itcr.Next();
889   }
890   if (!itcr.More()) {
891     Range(E,First,Last);
892   }
893   E.TShape()->Modified(Standard_True);
894  }
895
896 //=======================================================================
897 //function : Range
898 //purpose  : 
899 //=======================================================================
900
901 void  BRep_Tool::Range(const TopoDS_Edge& E, 
902                        const TopoDS_Face& F, 
903                        Standard_Real& First, 
904                        Standard_Real& Last)
905 {
906   TopLoc_Location L;
907   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,L);
908   Range(E,S,L,First,Last);
909 }
910
911 //=======================================================================
912 //function : UVPoints
913 //purpose  : 
914 //=======================================================================
915
916 void  BRep_Tool::UVPoints(const TopoDS_Edge& E, 
917                           const Handle(Geom_Surface)& S, 
918                           const TopLoc_Location& L, 
919                           gp_Pnt2d& PFirst, 
920                           gp_Pnt2d& PLast)
921 {
922   TopLoc_Location l = L.Predivided(E.Location());
923   Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED);
924
925   // find the representation
926   const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
927   BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
928
929   while (itcr.More()) {
930     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
931     if (cr->IsCurveOnSurface(S,l)) {
932       if (cr->IsCurveOnClosedSurface() && Eisreversed)
933       {
934         const BRep_CurveOnClosedSurface* CR =
935           static_cast<const BRep_CurveOnClosedSurface*>(cr.get());
936         CR->UVPoints2(PFirst, PLast);
937       }
938       else
939       {
940         const BRep_CurveOnSurface* CR =
941           static_cast<const BRep_CurveOnSurface*>(cr.get());
942         CR->UVPoints(PFirst, PLast);
943       }
944       return;
945     }
946     itcr.Next();
947   }
948
949   // for planar surface project the vertices
950   // modif 21-05-97 : for RectangularTrimmedSurface, project the vertices
951   Handle(Geom_Plane) GP;
952   Handle(Geom_RectangularTrimmedSurface) GRTS;
953   GRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
954   if(!GRTS.IsNull())
955     GP = Handle(Geom_Plane)::DownCast(GRTS->BasisSurface());
956   else
957     GP = Handle(Geom_Plane)::DownCast(S);
958   //fin modif du 21-05-97
959   if (!GP.IsNull()) {
960     // get the two vertices
961     TopoDS_Vertex Vf,Vl;
962     TopExp::Vertices(E,Vf,Vl);
963
964     TopLoc_Location Linverted = L.Inverted();
965     Vf.Move(Linverted);
966     Vl.Move(Linverted);
967     Standard_Real u,v;
968     gp_Pln pln = GP->Pln();
969
970     u=v=0.;
971     if (!Vf.IsNull()) {
972       gp_Pnt PF = BRep_Tool::Pnt(Vf);
973       ElSLib::Parameters(pln,PF,u,v);
974     }
975     PFirst.SetCoord(u,v);
976
977     u=v=0.;
978     if (!Vl.IsNull()) {
979       gp_Pnt PL = BRep_Tool::Pnt(Vl);
980       ElSLib::Parameters(pln,PL,u,v);
981     }
982     PLast.SetCoord(u,v);
983   }    
984 }
985
986 //=======================================================================
987 //function : UVPoints
988 //purpose  : 
989 //=======================================================================
990
991 void  BRep_Tool::UVPoints(const TopoDS_Edge& E,
992                           const TopoDS_Face& F, 
993                           gp_Pnt2d& PFirst, 
994                           gp_Pnt2d& PLast)
995 {
996   TopLoc_Location L;
997   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,L);
998   TopoDS_Edge aLocalEdge = E;
999   if (F.Orientation() == TopAbs_REVERSED) {
1000     aLocalEdge.Reverse();
1001 //    UVPoints(E,S,L,PFirst,PLast);
1002   }
1003 //    UVPoints(TopoDS::Edge(E.Reversed()),S,L,PFirst,PLast);
1004 //  else
1005 //    UVPoints(E,S,L,PFirst,PLast);
1006   UVPoints(aLocalEdge,S,L,PFirst,PLast);
1007 }
1008
1009 //=======================================================================
1010 //function : SetUVPoints
1011 //purpose  : 
1012 //=======================================================================
1013
1014 void  BRep_Tool::SetUVPoints(const TopoDS_Edge& E,
1015                              const Handle(Geom_Surface)& S,
1016                              const TopLoc_Location& L, 
1017                              const gp_Pnt2d& PFirst, 
1018                              const gp_Pnt2d& PLast)
1019 {
1020   TopLoc_Location l = L.Predivided(E.Location());
1021   Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED);
1022
1023   // find the representation
1024   const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
1025   BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
1026
1027   while (itcr.More()) {
1028     Handle(BRep_CurveRepresentation)& cr = itcr.Value();
1029     if (cr->IsCurveOnSurface(S,l)) {
1030       if (cr->IsCurveOnClosedSurface() && Eisreversed)
1031       {
1032         BRep_CurveOnClosedSurface* CS = static_cast<BRep_CurveOnClosedSurface*>(cr.get());
1033         CS->SetUVPoints2(PFirst, PLast);
1034       }
1035       else
1036       {
1037         BRep_CurveOnSurface* CS = static_cast<BRep_CurveOnSurface*>(cr.get());
1038         CS->SetUVPoints(PFirst, PLast);
1039       }
1040     }
1041     itcr.Next();
1042   }
1043 }
1044
1045 //=======================================================================
1046 //function : SetUVPoints
1047 //purpose  : 
1048 //=======================================================================
1049
1050 void  BRep_Tool::SetUVPoints(const TopoDS_Edge& E,
1051                              const TopoDS_Face& F, 
1052                              const gp_Pnt2d& PFirst, 
1053                              const gp_Pnt2d& PLast)
1054 {
1055   TopLoc_Location L;
1056   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,L);
1057   TopoDS_Edge aLocalEdge = E;
1058   if (F.Orientation() == TopAbs_REVERSED) {
1059     aLocalEdge.Reverse();
1060 //    SetUVPoints(TopoDS::Edge(E.Reversed()),S,L,PFirst,PLast);
1061   }
1062 //  else
1063 //    SetUVPoints(E,S,L,PFirst,PLast);
1064   SetUVPoints(aLocalEdge,S,L,PFirst,PLast);
1065 }
1066
1067 //=======================================================================
1068 //function : HasContinuity
1069 //purpose  : Returns True if the edge is on the surfaces of the
1070 //           two faces.
1071 //=======================================================================
1072
1073 Standard_Boolean BRep_Tool::HasContinuity(const TopoDS_Edge& E, 
1074                                           const TopoDS_Face& F1, 
1075                                           const TopoDS_Face& F2)
1076 {
1077   TopLoc_Location l1,l2;
1078   const Handle(Geom_Surface)& S1 = BRep_Tool::Surface(F1,l1);
1079   const Handle(Geom_Surface)& S2 = BRep_Tool::Surface(F2,l2);
1080   return HasContinuity(E,S1,S2,l1,l2);
1081 }
1082
1083 //=======================================================================
1084 //function : Continuity
1085 //purpose  : Returns the continuity.
1086 //=======================================================================
1087
1088 GeomAbs_Shape  BRep_Tool::Continuity(const TopoDS_Edge& E, 
1089                                      const TopoDS_Face& F1, 
1090                                      const TopoDS_Face& F2)
1091 {
1092   TopLoc_Location l1,l2;
1093   const Handle(Geom_Surface)& S1 = BRep_Tool::Surface(F1,l1);
1094   const Handle(Geom_Surface)& S2 = BRep_Tool::Surface(F2,l2);
1095   return Continuity(E,S1,S2,l1,l2);
1096 }
1097
1098 //=======================================================================
1099 //function : HasContinuity
1100 //purpose  : Returns True if the edge is on the surfaces.
1101 //=======================================================================
1102
1103 Standard_Boolean BRep_Tool::HasContinuity(const TopoDS_Edge& E, 
1104                                           const Handle(Geom_Surface)& S1, 
1105                                           const Handle(Geom_Surface)& S2, 
1106                                           const TopLoc_Location& L1, 
1107                                           const TopLoc_Location& L2)
1108 {
1109   const TopLoc_Location& Eloc = E.Location();
1110   TopLoc_Location l1 = L1.Predivided(Eloc);
1111   TopLoc_Location l2 = L2.Predivided(Eloc);
1112
1113   // find the representation
1114   const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
1115   BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
1116
1117   while (itcr.More()) {
1118     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
1119     if (cr->IsRegularity(S1,S2,l1,l2))
1120       return Standard_True;
1121     itcr.Next();
1122   }
1123   return Standard_False;
1124 }
1125
1126 //=======================================================================
1127 //function : Continuity
1128 //purpose  : Returns the continuity.
1129 //=======================================================================
1130
1131 GeomAbs_Shape  BRep_Tool::Continuity(const TopoDS_Edge& E, 
1132                                      const Handle(Geom_Surface)& S1, 
1133                                      const Handle(Geom_Surface)& S2, 
1134                                      const TopLoc_Location& L1, 
1135                                      const TopLoc_Location& L2)
1136 {
1137   TopLoc_Location l1 = L1.Predivided(E.Location());
1138   TopLoc_Location l2 = L2.Predivided(E.Location());
1139
1140   // find the representation
1141   BRep_ListIteratorOfListOfCurveRepresentation itcr
1142     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
1143
1144   while (itcr.More()) {
1145     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
1146     if (cr->IsRegularity(S1,S2,l1,l2))
1147       return cr->Continuity();
1148     itcr.Next();
1149   }
1150   return GeomAbs_C0;
1151 }
1152
1153 //=======================================================================
1154 //function : HasContinuity
1155 //purpose  : Returns True if the edge is on some two surfaces.
1156 //=======================================================================
1157
1158 Standard_Boolean BRep_Tool::HasContinuity(const TopoDS_Edge& E)
1159 {
1160   const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
1161   BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
1162
1163   for (; itcr.More(); itcr.Next())
1164   {
1165     const Handle(BRep_CurveRepresentation)& CR = itcr.Value();
1166     if (CR->IsRegularity())
1167       return Standard_True;
1168   }
1169   return Standard_False;
1170 }
1171
1172 //=======================================================================
1173 //function : Pnt
1174 //purpose  : Returns the 3d point.
1175 //=======================================================================
1176
1177 gp_Pnt  BRep_Tool::Pnt(const TopoDS_Vertex& V)
1178 {
1179   const BRep_TVertex* TV = static_cast<const BRep_TVertex*>(V.TShape().get());
1180   
1181   if (TV == 0)
1182   {
1183     Standard_NullObject::Raise("BRep_Tool:: TopoDS_Vertex hasn't gp_Pnt");
1184   }
1185
1186   const gp_Pnt& P = TV->Pnt();
1187   if (V.Location().IsIdentity())
1188   {
1189     return P;
1190   }
1191
1192   return P.Transformed(V.Location().Transformation());
1193 }
1194
1195 //=======================================================================
1196 //function : Tolerance
1197 //purpose  : Returns the tolerance.
1198 //=======================================================================
1199
1200 Standard_Real  BRep_Tool::Tolerance(const TopoDS_Vertex& V)
1201 {
1202   const BRep_TVertex* aTVert = static_cast<const BRep_TVertex*>(V.TShape().get());
1203
1204   if (aTVert == 0)
1205   {
1206     Standard_NullObject::Raise("BRep_Tool:: TopoDS_Vertex hasn't gp_Pnt");
1207   }
1208
1209   Standard_Real p = aTVert->Tolerance();
1210   Standard_Real pMin = Precision::Confusion();
1211   if (p > pMin) return p;
1212   else          return pMin;
1213 }
1214
1215 //=======================================================================
1216 //function : Parameter
1217 //purpose  : Returns the parameter of <V> on <E>.
1218 //=======================================================================
1219
1220 Standard_Real  BRep_Tool::Parameter(const TopoDS_Vertex& V, 
1221                                     const TopoDS_Edge& E)
1222 {
1223   
1224   // Search the vertex in the edge
1225
1226   Standard_Boolean rev = Standard_False;
1227   TopoDS_Shape VF;
1228   TopAbs_Orientation orient = TopAbs_INTERNAL;
1229
1230   TopoDS_Iterator itv(E.Oriented(TopAbs_FORWARD));
1231
1232   // if the edge has no vertices
1233   // and is degenerated use the vertex orientation
1234   // RLE, june 94
1235
1236   if (!itv.More() && Degenerated(E)) {
1237     orient = V.Orientation();
1238   }
1239
1240   while (itv.More()) {
1241     const TopoDS_Shape& Vcur = itv.Value();
1242     if (V.IsSame(Vcur)) {
1243       if (VF.IsNull()) {
1244         VF = Vcur;
1245       }
1246       else {
1247         rev = E.Orientation() == TopAbs_REVERSED;
1248         if (Vcur.Orientation() == V.Orientation()) {
1249           VF = Vcur;
1250         }
1251       }
1252     }
1253     itv.Next();
1254   }
1255   
1256   if (!VF.IsNull()) orient = VF.Orientation();
1257  
1258   Standard_Real f,l;
1259
1260   if (orient ==  TopAbs_FORWARD) {
1261     BRep_Tool::Range(E,f,l);
1262     return (rev) ? l : f;
1263   }
1264  
1265   else if (orient ==  TopAbs_REVERSED) {
1266     BRep_Tool::Range(E,f,l);
1267     return (rev) ? f : l;
1268    }
1269
1270   else {
1271     TopLoc_Location L;
1272     const Handle(Geom_Curve)& C = BRep_Tool::Curve(E,L,f,l);
1273     L = L.Predivided(V.Location());
1274     if (!C.IsNull() || Degenerated(E)) {
1275       const BRep_TVertex* TV = static_cast<const BRep_TVertex*>(V.TShape().get());
1276       BRep_ListIteratorOfListOfPointRepresentation itpr(TV->Points());
1277
1278       while (itpr.More()) {
1279         const Handle(BRep_PointRepresentation)& pr = itpr.Value();
1280         if (pr->IsPointOnCurve(C,L)) {
1281           Standard_Real p = pr->Parameter();
1282           Standard_Real res = p;// SVV 4 nov 99 - to avoid warnings on Linux
1283           if (!C.IsNull()) {
1284             // Closed curves RLE 16 june 94
1285             if (Precision::IsNegativeInfinite(f)) return pr->Parameter();//p;
1286             if (Precision::IsPositiveInfinite(l)) return pr->Parameter();//p;
1287             gp_Pnt Pf = C->Value(f).Transformed(L.Transformation());
1288             gp_Pnt Pl = C->Value(l).Transformed(L.Transformation());
1289             Standard_Real tol = BRep_Tool::Tolerance(V);
1290             if (Pf.Distance(Pl) < tol) {
1291               if (Pf.Distance(BRep_Tool::Pnt(V)) < tol) {
1292                 if (V.Orientation() == TopAbs_FORWARD) res = f;//p = f;
1293                 else                                   res = l;//p = l;
1294               }
1295             }
1296           }
1297           return res;//p;
1298         }
1299         itpr.Next();
1300       }
1301     }
1302     else {
1303       // no 3d curve !!
1304       // let us try with the first pcurve
1305       Handle(Geom2d_Curve) PC;
1306       Handle(Geom_Surface) S;
1307       BRep_Tool::CurveOnSurface(E,PC,S,L,f,l);
1308       L = L.Predivided(V.Location());
1309       const BRep_TVertex* TV = static_cast<const BRep_TVertex*>(V.TShape().get());
1310       BRep_ListIteratorOfListOfPointRepresentation itpr(TV->Points());
1311
1312       while (itpr.More()) {
1313         const Handle(BRep_PointRepresentation)& pr = itpr.Value();
1314         if (pr->IsPointOnCurveOnSurface(PC,S,L)) {
1315           Standard_Real p = pr->Parameter();
1316           // Closed curves RLE 16 june 94
1317           if (PC->IsClosed()) {
1318             if ((p == PC->FirstParameter()) || 
1319                 (p == PC->LastParameter())) {
1320               if (V.Orientation() == TopAbs_FORWARD) p = PC->FirstParameter();
1321               else                                   p = PC->LastParameter();
1322             }
1323           }
1324           return p;
1325         }
1326         itpr.Next();
1327       }
1328     }
1329   }
1330   
1331   Standard_NoSuchObject::Raise("BRep_Tool:: no parameter on edge");
1332   return 0;
1333 }
1334
1335 //=======================================================================
1336 //function : Parameter
1337 //purpose  : Returns the  parameters  of   the  vertex   on the
1338 //           pcurve of the edge on the face.
1339 //=======================================================================
1340
1341 Standard_Real BRep_Tool::Parameter(const TopoDS_Vertex& V, 
1342                                    const TopoDS_Edge& E, 
1343                                    const TopoDS_Face& F)
1344 {
1345   TopLoc_Location L;
1346   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,L);
1347   return BRep_Tool::Parameter(V,E,S,L);
1348 }
1349
1350 //=======================================================================
1351 //function : Parameter
1352 //purpose  : Returns the  parameters  of   the  vertex   on the
1353 //           pcurve of the edge on the surface.
1354 //=======================================================================
1355
1356 Standard_Real BRep_Tool::Parameter(const TopoDS_Vertex& V, 
1357                                    const TopoDS_Edge& E, 
1358                                    const Handle(Geom_Surface)& S,
1359                                    const TopLoc_Location& L)
1360 {
1361   // Search the vertex in the edge
1362
1363   Standard_Boolean rev = Standard_False;
1364   TopoDS_Shape VF;
1365   TopoDS_Iterator itv(E.Oriented(TopAbs_FORWARD));
1366
1367   while (itv.More()) {
1368     if (V.IsSame(itv.Value())) {
1369       if (VF.IsNull()) VF = itv.Value();
1370       else {
1371         rev = E.Orientation() == TopAbs_REVERSED;
1372         if (itv.Value().Orientation() == V.Orientation()) 
1373         VF = itv.Value();
1374       }
1375     }
1376     itv.Next();
1377   }
1378
1379  TopAbs_Orientation orient = TopAbs_INTERNAL;
1380   if (!VF.IsNull()) orient = VF.Orientation();
1381  
1382  Standard_Real f,l;
1383
1384  if (orient ==  TopAbs_FORWARD) {
1385    BRep_Tool::Range(E,S,L,f,l);
1386    return (rev) ? l : f;
1387  }
1388  
1389  else if (orient ==  TopAbs_REVERSED) {
1390    BRep_Tool::Range(E,S,L,f,l);
1391    return (rev) ? f : l;
1392  }
1393
1394  else {
1395    Handle(Geom2d_Curve) PC = BRep_Tool::CurveOnSurface(E,S,L,f,l);
1396    const BRep_TVertex* TV = static_cast<const BRep_TVertex*>(V.TShape().get());
1397    BRep_ListIteratorOfListOfPointRepresentation itpr(TV->Points());
1398
1399    while (itpr.More()) {
1400      if (itpr.Value()->IsPointOnCurveOnSurface(PC,S,L))
1401        return itpr.Value()->Parameter();
1402      itpr.Next();
1403    }
1404  }
1405
1406  //----------------------------------------------------------
1407    
1408   TopLoc_Location L1;
1409   const Handle(Geom_Curve)& C = BRep_Tool::Curve(E,L1,f,l);
1410   L1 = L1.Predivided(V.Location());
1411   if (!C.IsNull() || Degenerated(E)) {
1412     const BRep_TVertex* TV = static_cast<const BRep_TVertex*>(V.TShape().get());
1413     BRep_ListIteratorOfListOfPointRepresentation itpr(TV->Points());
1414
1415     while (itpr.More()) {
1416       const Handle(BRep_PointRepresentation)& pr = itpr.Value();
1417       if (pr->IsPointOnCurve(C,L1)) {
1418         Standard_Real p = pr->Parameter();
1419         Standard_Real res = p;
1420         if (!C.IsNull()) {
1421           // Closed curves RLE 16 june 94
1422           if (Precision::IsNegativeInfinite(f)) return res;
1423           if (Precision::IsPositiveInfinite(l)) return res;
1424           gp_Pnt Pf = C->Value(f).Transformed(L1.Transformation());
1425           gp_Pnt Pl = C->Value(l).Transformed(L1.Transformation());
1426           Standard_Real tol = BRep_Tool::Tolerance(V);
1427           if (Pf.Distance(Pl) < tol) {
1428             if (Pf.Distance(BRep_Tool::Pnt(V)) < tol) {
1429               if (V.Orientation() == TopAbs_FORWARD) res = f;
1430               else                                   res = l;
1431             }
1432           }
1433         }
1434         return res;
1435       }
1436       itpr.Next();
1437     }
1438   }
1439   
1440 //----------------------------------------------------------   
1441  
1442   Standard_NoSuchObject::Raise("BRep_Tool:: no parameter on edge");
1443   return 0;
1444 }
1445
1446 //=======================================================================
1447 //function : Parameters
1448 //purpose  : Returns the parameters of the vertex on the face.
1449 //=======================================================================
1450
1451 gp_Pnt2d  BRep_Tool::Parameters(const TopoDS_Vertex& V, 
1452                                 const TopoDS_Face& F)
1453 {
1454   TopLoc_Location L;
1455   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,L);
1456   L = L.Predivided(V.Location());
1457   const BRep_TVertex* TV = static_cast<const BRep_TVertex*>(V.TShape().get());
1458   BRep_ListIteratorOfListOfPointRepresentation itpr(TV->Points());
1459   
1460   // It is checked if there is PointRepresentation (case non Manifold)
1461   while (itpr.More()) {
1462     if (itpr.Value()->IsPointOnSurface(S,L)) {
1463       return gp_Pnt2d(itpr.Value()->Parameter(),
1464                       itpr.Value()->Parameter2());
1465     }
1466     itpr.Next();
1467   }
1468
1469  TopoDS_Vertex Vf,Vl;
1470  TopoDS_Edge E;
1471  // Otherwise the edges are searched (PMN 4/06/97) It is not possible to succeed 999/1000!
1472  // even if often there is a way to make more economically than above...
1473  TopExp_Explorer exp;
1474  for (exp.Init(F, TopAbs_EDGE); exp.More(); exp.Next()) { 
1475     E = TopoDS::Edge(exp.Current());  
1476     TopExp::Vertices(E, Vf, Vl);
1477     if ((V.IsSame(Vf)) || (V.IsSame(Vl))) {
1478       gp_Pnt2d Pf, Pl;
1479       UVPoints(E, F, Pf, Pl);
1480       if (V.IsSame(Vf)) return Pf;
1481       else              return Pl;//Ambiguity (natural) for degenerated edges.
1482     }
1483   }
1484   Standard_NoSuchObject::Raise("BRep_Tool:: no parameters on surface");
1485   return gp_Pnt2d(0,0);
1486 }
1487 //=======================================================================
1488 //function : IsClosed
1489 //purpose  : 
1490 //=======================================================================
1491 Standard_Boolean BRep_Tool::IsClosed (const TopoDS_Shape& theShape)
1492 {
1493   if (theShape.ShapeType() == TopAbs_SHELL)
1494   {
1495     NCollection_Map<TopoDS_Shape, TopTools_ShapeMapHasher> aMap (101, new NCollection_IncAllocator);
1496     TopExp_Explorer exp (theShape.Oriented(TopAbs_FORWARD), TopAbs_EDGE);
1497     Standard_Boolean hasBound = Standard_False;
1498     for (; exp.More(); exp.Next())
1499     {
1500       const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1501       if (BRep_Tool::Degenerated(E) || E.Orientation() == TopAbs_INTERNAL || E.Orientation() == TopAbs_EXTERNAL)
1502         continue;
1503       hasBound = Standard_True;
1504       if (!aMap.Add(E))
1505         aMap.Remove(E);
1506     }
1507     return hasBound && aMap.IsEmpty();
1508   }
1509   else if (theShape.ShapeType() == TopAbs_WIRE)
1510   {
1511     NCollection_Map<TopoDS_Shape, TopTools_ShapeMapHasher> aMap (101, new NCollection_IncAllocator);
1512     TopExp_Explorer exp (theShape.Oriented(TopAbs_FORWARD), TopAbs_VERTEX);
1513     Standard_Boolean hasBound = Standard_False;
1514     for (; exp.More(); exp.Next())
1515     {
1516       const TopoDS_Shape& V = exp.Current();
1517       if (V.Orientation() == TopAbs_INTERNAL || V.Orientation() == TopAbs_EXTERNAL)
1518         continue;
1519       hasBound = Standard_True;
1520       if (!aMap.Add(V))
1521         aMap.Remove(V);
1522     }
1523     return hasBound && aMap.IsEmpty();
1524   }
1525   else if (theShape.ShapeType() == TopAbs_EDGE)
1526   {
1527     TopoDS_Vertex aVFirst, aVLast;
1528     TopExp::Vertices(TopoDS::Edge(theShape), aVFirst, aVLast);
1529     return !aVFirst.IsNull() && aVFirst.IsSame(aVLast);
1530   }
1531   return theShape.Closed();
1532 }
1533
1534 //modified by NIZNHY-PKV Fri Oct 17 14:09:58 2008 f 
1535 //=======================================================================
1536 //function : IsPlane
1537 //purpose  : 
1538 //=======================================================================
1539 Standard_Boolean IsPlane(const Handle(Geom_Surface)& aS)
1540 {
1541   Standard_Boolean bRet;
1542   Handle(Geom_Plane) aGP;
1543   Handle(Geom_RectangularTrimmedSurface) aGRTS;
1544   Handle(Geom_OffsetSurface) aGOFS;
1545   //
1546   aGRTS=Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
1547   aGOFS=Handle(Geom_OffsetSurface)::DownCast(aS);
1548   //
1549   if(!aGOFS.IsNull()) {
1550     aGP=Handle(Geom_Plane)::DownCast(aGOFS->BasisSurface());
1551   }
1552   else if(!aGRTS.IsNull()) {
1553     aGP=Handle(Geom_Plane)::DownCast(aGRTS->BasisSurface());
1554   }
1555   else {
1556     aGP=Handle(Geom_Plane)::DownCast(aS);
1557   }
1558   //
1559   bRet=!aGP.IsNull();
1560   //
1561   return bRet;
1562 }
1563
1564 //=======================================================================
1565 //function : MaxTolerance
1566 //purpose  : 
1567 //=======================================================================
1568 Standard_Real BRep_Tool::MaxTolerance (const TopoDS_Shape& theShape,
1569                                        const TopAbs_ShapeEnum theSubShape)
1570 {
1571   Standard_Real aTol = 0.0;
1572
1573   // Explorer Shape-Subshape.
1574   TopExp_Explorer anExpSS(theShape, theSubShape);
1575   if (theSubShape == TopAbs_FACE)
1576   {
1577     for( ; anExpSS.More() ;  anExpSS.Next() )
1578     {
1579       const TopoDS_Shape& aCurrentSubShape = anExpSS.Current();
1580       aTol = Max(aTol, Tolerance(TopoDS::Face(aCurrentSubShape)));
1581     }
1582   }
1583   else if (theSubShape == TopAbs_EDGE)
1584   {
1585     for( ; anExpSS.More() ;  anExpSS.Next() )
1586     {
1587       const TopoDS_Shape& aCurrentSubShape = anExpSS.Current();
1588       aTol = Max(aTol, Tolerance(TopoDS::Edge(aCurrentSubShape)));
1589     }
1590   }
1591   else if (theSubShape == TopAbs_VERTEX)
1592   {
1593     for( ; anExpSS.More() ;  anExpSS.Next() )
1594     {
1595       const TopoDS_Shape& aCurrentSubShape = anExpSS.Current();
1596       aTol = Max(aTol, Tolerance(TopoDS::Vertex(aCurrentSubShape)));
1597     }
1598   }
1599
1600   return aTol;
1601 }