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