0026936: Drawbacks of inlining in new type system in OCCT 7.0 -- automatic
[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   Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &F.TShape());
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   Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &F.TShape());
101   TopLoc_Location L = F.Location() * TF->Location();
102   Handle(Geom_Surface) S = TF->Surface();
103
104   if(S.IsNull()) return S;
105
106   Handle(Geom_Geometry) S1;
107   if (!L.IsIdentity()) {
108     S1 = S->Copy();
109     S = Handle(Geom_Surface)::DownCast (S1);
110     S->Transform(L.Transformation());
111   }
112   return S;
113 }
114
115 //=======================================================================
116 //function : Triangulation
117 //purpose  : Returns  the Triangulation of  the  face. It  is a
118 //           null handle if there is no triangulation.
119 //=======================================================================
120
121 const Handle(Poly_Triangulation)&
122 BRep_Tool::Triangulation(const TopoDS_Face& F,
123                          TopLoc_Location&   L)
124 {
125   L = F.Location();
126   return (*((Handle(BRep_TFace)*)&F.TShape()))->Triangulation();
127 }
128
129 //=======================================================================
130 //function : Tolerance
131 //purpose  : Returns the tolerance of the face.
132 //=======================================================================
133
134 Standard_Real  BRep_Tool::Tolerance(const TopoDS_Face& F)
135 {
136   Standard_Real p = (*((Handle(BRep_TFace)*)&F.TShape()))->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   return (*((Handle(BRep_TFace)*) &F.TShape()))->NaturalRestriction();
150 }
151
152 //=======================================================================
153 //function : Curve
154 //purpose  : Returns the 3D curve  of the edge.  May be  a Null
155 //           handle. Returns in <L> the location for the curve.
156 //           In <First> and <Last> the parameter range.
157 //=======================================================================
158
159 static const Handle(Geom_Curve) nullCurve;
160
161 const Handle(Geom_Curve)&  BRep_Tool::Curve(const TopoDS_Edge& E,
162                                             TopLoc_Location& L,
163                                             Standard_Real& First,
164                                             Standard_Real& Last)
165 {
166   // find the representation
167   BRep_ListIteratorOfListOfCurveRepresentation itcr
168     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
169
170   while (itcr.More()) {
171     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
172     if (cr->IsCurve3D()) {
173       Handle(BRep_Curve3D) GC (Handle(BRep_Curve3D)::DownCast (cr));
174       L = E.Location() * GC->Location();
175       GC->Range(First,Last);
176       return GC->Curve3D();
177     }
178     itcr.Next();
179   }
180   L.Identity();
181   return nullCurve;
182 }
183
184 //=======================================================================
185 //function : Curve
186 //purpose  : Returns the 3D curve  of the edge. May be a Null handle.
187 //           In <First> and <Last> the parameter range.
188 //           It can be a copy if there is a Location.
189 //=======================================================================
190
191 Handle(Geom_Curve)  BRep_Tool::Curve(const TopoDS_Edge& E,
192                                      Standard_Real& First,
193                                      Standard_Real& Last)
194 {
195   TopLoc_Location L;
196   Handle(Geom_Curve) C = Curve(E,L,First,Last);
197   if ( !C.IsNull() ) {
198     Handle(Geom_Geometry) C1;
199     if ( !L.IsIdentity() ) {
200       C1 = C->Copy();
201       C = Handle(Geom_Curve)::DownCast (C1);
202       C->Transform(L.Transformation());
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   BRep_ListIteratorOfListOfCurveRepresentation itcr
218     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
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   BRep_ListIteratorOfListOfCurveRepresentation itcr
247     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
248
249   while (itcr.More()) {
250     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
251     if (cr->IsPolygon3D()) {
252       Handle(BRep_Polygon3D) GC (Handle(BRep_Polygon3D)::DownCast (cr));
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   BRep_ListIteratorOfListOfCurveRepresentation itcr
309     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
310
311   while (itcr.More()) {
312     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
313     if (cr->IsCurveOnSurface(S,loc)) {
314       Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (cr));
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   BRep_ListIteratorOfListOfCurveRepresentation itcr
405     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
406
407   while (itcr.More()) {
408     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
409     if (cr->IsCurveOnSurface()) {
410       Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (cr));
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   BRep_ListIteratorOfListOfCurveRepresentation itcr
443     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
444
445   while (itcr.More()) {
446     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
447     if (cr->IsCurveOnSurface()) {
448       Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (cr));
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) 
507      BRep_Tool::PolygonOnSurface(const TopoDS_Edge& E, 
508                                  const Handle(Geom_Surface)& S,
509                                  const TopLoc_Location& L)
510 {
511   TopLoc_Location l = L.Predivided(E.Location());
512   Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED);
513
514   // find the representation
515   BRep_ListIteratorOfListOfCurveRepresentation itcr
516     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
517
518   while (itcr.More()) {
519     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
520     if (cr->IsPolygonOnSurface(S,l)) {
521       if (cr->IsPolygonOnClosedSurface() && Eisreversed )
522         return cr->Polygon2();
523       else
524         return cr->Polygon();
525     }
526     itcr.Next();
527   }
528   
529   return nullPolygon2D;
530 }
531
532 //=======================================================================
533 //function : PolygonOnSurface
534 //purpose  : 
535 //=======================================================================
536
537 void BRep_Tool::PolygonOnSurface(const TopoDS_Edge&      E,
538                                  Handle(Poly_Polygon2D)& P,
539                                  Handle(Geom_Surface)&   S,
540                                  TopLoc_Location&        L)
541 {
542   // find the representation
543   BRep_ListIteratorOfListOfCurveRepresentation itcr
544     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
545
546   while (itcr.More()) {
547     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
548     if (cr->IsPolygonOnSurface()) {
549       Handle(BRep_PolygonOnSurface) PS (Handle(BRep_PolygonOnSurface)::DownCast (cr));
550       P = PS->Polygon();
551       S = PS->Surface();
552       L = E.Location() * PS->Location();
553       return;
554     }
555     itcr.Next();
556   }
557   
558   L = TopLoc_Location();
559   P = Handle(Poly_Polygon2D)();
560   S = Handle(Geom_Surface)();
561 }
562
563 //=======================================================================
564 //function : PolygonOnSurface
565 //purpose  : 
566 //=======================================================================
567
568 void BRep_Tool::PolygonOnSurface(const TopoDS_Edge&      E,
569                                  Handle(Poly_Polygon2D)& P,
570                                  Handle(Geom_Surface)&   S,
571                                  TopLoc_Location&        L,
572                                  const Standard_Integer  Index)
573 {
574   Standard_Integer i = 0;
575
576   // find the representation
577   BRep_ListIteratorOfListOfCurveRepresentation itcr
578     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
579
580   while (itcr.More()) {
581     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
582     if (cr->IsPolygonOnSurface()) {
583       Handle(BRep_PolygonOnSurface) PS (Handle(BRep_PolygonOnSurface)::DownCast (cr));
584       i++;
585       if (i > Index) break;
586       if (i == Index) {
587         P = PS->Polygon();
588         S = PS->Surface();
589         L = E.Location() * PS->Location();
590         return;
591       }
592     }
593     itcr.Next();
594   }
595   
596   L = TopLoc_Location();
597   P = Handle(Poly_Polygon2D)();
598   S = Handle(Geom_Surface)();
599 }
600
601 //=======================================================================
602 //function : PolygonOnTriangulation
603 //purpose  : Returns the polygon associated to the  edge in  the
604 //           parametric  space of  the  face.  Returns   a NULL
605 //           handle  if this polygon  does not exist.
606 //=======================================================================
607
608 static const Handle(Poly_PolygonOnTriangulation) nullArray;
609
610 const Handle(Poly_PolygonOnTriangulation)&
611 BRep_Tool::PolygonOnTriangulation(const TopoDS_Edge&                E, 
612                                   const Handle(Poly_Triangulation)& T,
613                                   const TopLoc_Location&            L)
614 {
615   TopLoc_Location l = L.Predivided(E.Location());
616   Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED);
617
618   // find the representation
619   BRep_ListIteratorOfListOfCurveRepresentation itcr
620     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
621
622   while (itcr.More()) {
623     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
624     if ( cr->IsPolygonOnTriangulation(T,l)) {
625       if ( cr->IsPolygonOnClosedTriangulation() && Eisreversed )
626         return cr->PolygonOnTriangulation2();
627       else
628         return cr->PolygonOnTriangulation();
629     }
630     itcr.Next();
631   }
632   
633   return nullArray;
634 }
635
636 //=======================================================================
637 //function : PolygonOnTriangulation
638 //purpose  : 
639 //=======================================================================
640
641 void 
642 BRep_Tool::PolygonOnTriangulation(const TopoDS_Edge&                   E,
643                                   Handle(Poly_PolygonOnTriangulation)& P,
644                                   Handle(Poly_Triangulation)&          T,
645                                   TopLoc_Location&                     L)
646 {
647   // find the representation
648   BRep_ListIteratorOfListOfCurveRepresentation itcr
649     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
650
651   while (itcr.More()) {
652     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
653     if (cr->IsPolygonOnTriangulation()) {
654       Handle(BRep_PolygonOnTriangulation) PT (Handle(BRep_PolygonOnTriangulation)::DownCast (cr));
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   BRep_ListIteratorOfListOfCurveRepresentation itcr
684     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
685
686   while (itcr.More()) {
687     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
688     if (cr->IsPolygonOnTriangulation()) {
689       Handle(BRep_PolygonOnTriangulation) PT (Handle(BRep_PolygonOnTriangulation)::DownCast (cr));
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   BRep_ListIteratorOfListOfCurveRepresentation itcr
745     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
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   BRep_ListIteratorOfListOfCurveRepresentation itcr
771     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
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   Standard_Real p = (*((Handle(BRep_TEdge)*)&E.TShape()))->Tolerance();
791   Standard_Real pMin = Precision::Confusion();
792   if (p > pMin) return p;
793   else          return pMin;
794 }
795
796 //=======================================================================
797 //function : SameParameter
798 //purpose  : Returns the SameParameter flag for the edge.
799 //=======================================================================
800
801 Standard_Boolean  BRep_Tool::SameParameter(const TopoDS_Edge& E)
802 {
803   return (*((Handle(BRep_TEdge)*)&E.TShape()))->SameParameter();
804 }
805
806 //=======================================================================
807 //function : SameRange
808 //purpose  : Returns the SameRange flag for the edge.
809 //=======================================================================
810
811 Standard_Boolean  BRep_Tool::SameRange(const TopoDS_Edge& E)
812 {
813   return (*((Handle(BRep_TEdge)*)&E.TShape()))->SameRange();
814 }
815
816 //=======================================================================
817 //function : Degenerated
818 //purpose  : Returns True  if the edge is degenerated.
819 //=======================================================================
820
821 Standard_Boolean  BRep_Tool::Degenerated(const TopoDS_Edge& E)
822 {
823   return (*((Handle(BRep_TEdge)*)&E.TShape()))->Degenerated();
824 }
825
826 //=======================================================================
827 //function : Range
828 //purpose  : 
829 //=======================================================================
830
831 void  BRep_Tool::Range(const TopoDS_Edge& E, 
832                        Standard_Real& First, 
833                        Standard_Real& Last)
834 {
835   //  set the range to all the representations
836   BRep_ListIteratorOfListOfCurveRepresentation itcr
837     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
838
839   while (itcr.More()) {
840     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
841     if (cr->IsCurve3D()) {
842       Handle(BRep_Curve3D) CR (Handle(BRep_Curve3D)::DownCast (cr));
843       if (!CR->Curve3D().IsNull()) {
844         First = CR->First(); 
845         Last = CR->Last();
846         break;
847       }
848     }
849     else if (cr->IsCurveOnSurface()) {
850       Handle(BRep_GCurve) CR (Handle(BRep_GCurve)::DownCast (cr));
851       First = CR->First(); 
852       Last = CR->Last();
853       break;
854     }
855     itcr.Next();
856   }
857 }
858
859 //=======================================================================
860 //function : Range
861 //purpose  : 
862 //=======================================================================
863
864 void  BRep_Tool::Range(const TopoDS_Edge& E, 
865                        const Handle(Geom_Surface)& S,
866                        const TopLoc_Location& L,
867                        Standard_Real& First, 
868                        Standard_Real& Last)
869 {
870   TopLoc_Location l = L.Predivided(E.Location());
871   
872   // find the representation
873   BRep_ListIteratorOfListOfCurveRepresentation itcr
874     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
875   
876   while (itcr.More()) {
877     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
878     if (cr->IsCurveOnSurface(S,l)) {
879       Handle(BRep_GCurve)::DownCast (cr)->Range(First,Last);
880       break;
881     }
882     itcr.Next();
883   }
884   if (!itcr.More()) {
885     Range(E,First,Last);
886   }
887   (*((Handle(BRep_TEdge)*)&E.TShape()))->Modified(Standard_True);
888  }
889
890 //=======================================================================
891 //function : Range
892 //purpose  : 
893 //=======================================================================
894
895 void  BRep_Tool::Range(const TopoDS_Edge& E, 
896                        const TopoDS_Face& F, 
897                        Standard_Real& First, 
898                        Standard_Real& Last)
899 {
900   TopLoc_Location L;
901   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,L);
902   Range(E,S,L,First,Last);
903 }
904
905 //=======================================================================
906 //function : UVPoints
907 //purpose  : 
908 //=======================================================================
909
910 void  BRep_Tool::UVPoints(const TopoDS_Edge& E, 
911                           const Handle(Geom_Surface)& S, 
912                           const TopLoc_Location& L, 
913                           gp_Pnt2d& PFirst, 
914                           gp_Pnt2d& PLast)
915 {
916   TopLoc_Location l = L.Predivided(E.Location());
917   Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED);
918
919   // find the representation
920   BRep_ListIteratorOfListOfCurveRepresentation itcr
921     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
922
923   while (itcr.More()) {
924     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
925     if (cr->IsCurveOnSurface(S,l)) {
926       if (cr->IsCurveOnClosedSurface() && Eisreversed)
927         Handle(BRep_CurveOnClosedSurface)::DownCast (cr)->UVPoints2(PFirst,PLast);
928       else
929         Handle(BRep_CurveOnSurface)::DownCast (cr)->UVPoints(PFirst,PLast);
930       return;
931     }
932     itcr.Next();
933   }
934
935   // for planar surface project the vertices
936   // modif 21-05-97 : for RectangularTrimmedSurface, project the vertices
937   Handle(Geom_Plane) GP;
938   Handle(Geom_RectangularTrimmedSurface) GRTS;
939   GRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
940   if(!GRTS.IsNull())
941     GP = Handle(Geom_Plane)::DownCast(GRTS->BasisSurface());
942   else
943     GP = Handle(Geom_Plane)::DownCast(S);
944   //fin modif du 21-05-97
945   if (!GP.IsNull()) {
946     // get the two vertices
947     TopoDS_Vertex Vf,Vl;
948     TopExp::Vertices(E,Vf,Vl);
949
950     TopLoc_Location Linverted = L.Inverted();
951     Vf.Move(Linverted);
952     Vl.Move(Linverted);
953     Standard_Real u,v;
954     gp_Pln pln = GP->Pln();
955
956     u=v=0.;
957     if (!Vf.IsNull()) {
958       gp_Pnt PF = BRep_Tool::Pnt(Vf);
959       ElSLib::Parameters(pln,PF,u,v);
960     }
961     PFirst.SetCoord(u,v);
962
963     u=v=0.;
964     if (!Vl.IsNull()) {
965       gp_Pnt PL = BRep_Tool::Pnt(Vl);
966       ElSLib::Parameters(pln,PL,u,v);
967     }
968     PLast.SetCoord(u,v);
969   }    
970 }
971
972 //=======================================================================
973 //function : UVPoints
974 //purpose  : 
975 //=======================================================================
976
977 void  BRep_Tool::UVPoints(const TopoDS_Edge& E,
978                           const TopoDS_Face& F, 
979                           gp_Pnt2d& PFirst, 
980                           gp_Pnt2d& PLast)
981 {
982   TopLoc_Location L;
983   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,L);
984   TopoDS_Edge aLocalEdge = E;
985   if (F.Orientation() == TopAbs_REVERSED) {
986     aLocalEdge.Reverse();
987 //    UVPoints(E,S,L,PFirst,PLast);
988   }
989 //    UVPoints(TopoDS::Edge(E.Reversed()),S,L,PFirst,PLast);
990 //  else
991 //    UVPoints(E,S,L,PFirst,PLast);
992   UVPoints(aLocalEdge,S,L,PFirst,PLast);
993 }
994
995 //=======================================================================
996 //function : SetUVPoints
997 //purpose  : 
998 //=======================================================================
999
1000 void  BRep_Tool::SetUVPoints(const TopoDS_Edge& E,
1001                              const Handle(Geom_Surface)& S,
1002                              const TopLoc_Location& L, 
1003                              const gp_Pnt2d& PFirst, 
1004                              const gp_Pnt2d& PLast)
1005 {
1006   TopLoc_Location l = L.Predivided(E.Location());
1007   Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED);
1008
1009   // find the representation
1010   BRep_ListIteratorOfListOfCurveRepresentation itcr
1011     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
1012
1013   while (itcr.More()) {
1014     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
1015     if (cr->IsCurveOnSurface(S,l)) {
1016       if (cr->IsCurveOnClosedSurface() && Eisreversed)
1017         Handle(BRep_CurveOnClosedSurface)::DownCast (cr)->
1018           SetUVPoints2(PFirst,PLast);
1019       else
1020         Handle(BRep_CurveOnSurface)::DownCast (cr)->
1021           SetUVPoints(PFirst,PLast);
1022     }
1023     itcr.Next();
1024   }
1025 }
1026
1027 //=======================================================================
1028 //function : SetUVPoints
1029 //purpose  : 
1030 //=======================================================================
1031
1032 void  BRep_Tool::SetUVPoints(const TopoDS_Edge& E,
1033                              const TopoDS_Face& F, 
1034                              const gp_Pnt2d& PFirst, 
1035                              const gp_Pnt2d& PLast)
1036 {
1037   TopLoc_Location L;
1038   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,L);
1039   TopoDS_Edge aLocalEdge = E;
1040   if (F.Orientation() == TopAbs_REVERSED) {
1041     aLocalEdge.Reverse();
1042 //    SetUVPoints(TopoDS::Edge(E.Reversed()),S,L,PFirst,PLast);
1043   }
1044 //  else
1045 //    SetUVPoints(E,S,L,PFirst,PLast);
1046   SetUVPoints(aLocalEdge,S,L,PFirst,PLast);
1047 }
1048
1049 //=======================================================================
1050 //function : HasContinuity
1051 //purpose  : Returns True if the edge is on the surfaces of the
1052 //           two faces.
1053 //=======================================================================
1054
1055 Standard_Boolean BRep_Tool::HasContinuity(const TopoDS_Edge& E, 
1056                                           const TopoDS_Face& F1, 
1057                                           const TopoDS_Face& F2)
1058 {
1059   TopLoc_Location l1,l2;
1060   const Handle(Geom_Surface)& S1 = BRep_Tool::Surface(F1,l1);
1061   const Handle(Geom_Surface)& S2 = BRep_Tool::Surface(F2,l2);
1062   return HasContinuity(E,S1,S2,l1,l2);
1063 }
1064
1065 //=======================================================================
1066 //function : Continuity
1067 //purpose  : Returns the continuity.
1068 //=======================================================================
1069
1070 GeomAbs_Shape  BRep_Tool::Continuity(const TopoDS_Edge& E, 
1071                                      const TopoDS_Face& F1, 
1072                                      const TopoDS_Face& F2)
1073 {
1074   TopLoc_Location l1,l2;
1075   const Handle(Geom_Surface)& S1 = BRep_Tool::Surface(F1,l1);
1076   const Handle(Geom_Surface)& S2 = BRep_Tool::Surface(F2,l2);
1077   return Continuity(E,S1,S2,l1,l2);
1078 }
1079
1080 //=======================================================================
1081 //function : HasContinuity
1082 //purpose  : Returns True if the edge is on the surfaces.
1083 //=======================================================================
1084
1085 Standard_Boolean BRep_Tool::HasContinuity(const TopoDS_Edge& E, 
1086                                           const Handle(Geom_Surface)& S1, 
1087                                           const Handle(Geom_Surface)& S2, 
1088                                           const TopLoc_Location& L1, 
1089                                           const TopLoc_Location& L2)
1090 {
1091   const TopLoc_Location& Eloc = E.Location();
1092   TopLoc_Location l1 = L1.Predivided(Eloc);
1093   TopLoc_Location l2 = L2.Predivided(Eloc);
1094
1095   // find the representation
1096   BRep_ListIteratorOfListOfCurveRepresentation itcr
1097     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
1098
1099   while (itcr.More()) {
1100     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
1101     if (cr->IsRegularity(S1,S2,l1,l2))
1102       return Standard_True;
1103     itcr.Next();
1104   }
1105   return Standard_False;
1106 }
1107
1108 //=======================================================================
1109 //function : Continuity
1110 //purpose  : Returns the continuity.
1111 //=======================================================================
1112
1113 GeomAbs_Shape  BRep_Tool::Continuity(const TopoDS_Edge& E, 
1114                                      const Handle(Geom_Surface)& S1, 
1115                                      const Handle(Geom_Surface)& S2, 
1116                                      const TopLoc_Location& L1, 
1117                                      const TopLoc_Location& L2)
1118 {
1119   TopLoc_Location l1 = L1.Predivided(E.Location());
1120   TopLoc_Location l2 = L2.Predivided(E.Location());
1121
1122   // find the representation
1123   BRep_ListIteratorOfListOfCurveRepresentation itcr
1124     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
1125
1126   while (itcr.More()) {
1127     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
1128     if (cr->IsRegularity(S1,S2,l1,l2))
1129       return cr->Continuity();
1130     itcr.Next();
1131   }
1132   return GeomAbs_C0;
1133 }
1134
1135 //=======================================================================
1136 //function : HasContinuity
1137 //purpose  : Returns True if the edge is on some two surfaces.
1138 //=======================================================================
1139
1140 Standard_Boolean BRep_Tool::HasContinuity(const TopoDS_Edge& E)
1141 {
1142   BRep_ListIteratorOfListOfCurveRepresentation itcr
1143     ((*((Handle(BRep_TEdge)*)&E.TShape()))->Curves());
1144
1145   for (; itcr.More(); itcr.Next())
1146   {
1147     const Handle(BRep_CurveRepresentation)& CR = itcr.Value();
1148     if (CR->IsRegularity())
1149       return Standard_True;
1150   }
1151   return Standard_False;
1152 }
1153
1154 //=======================================================================
1155 //function : Pnt
1156 //purpose  : Returns the 3d point.
1157 //=======================================================================
1158
1159 gp_Pnt  BRep_Tool::Pnt(const TopoDS_Vertex& V)
1160 {
1161   Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &V.TShape());
1162
1163   if (TV.IsNull())
1164   {
1165     Standard_NullObject::Raise("BRep_Tool:: TopoDS_Vertex hasn't gp_Pnt");
1166   }
1167
1168   gp_Pnt P = TV->Pnt();
1169   P.Transform(V.Location().Transformation());
1170   return P;
1171 }
1172
1173 //=======================================================================
1174 //function : Tolerance
1175 //purpose  : Returns the tolerance.
1176 //=======================================================================
1177
1178 Standard_Real  BRep_Tool::Tolerance(const TopoDS_Vertex& V)
1179 {
1180   Handle(BRep_TVertex)& aTVert = *((Handle(BRep_TVertex)*)&V.TShape());
1181
1182   if (aTVert.IsNull())
1183   {
1184     Standard_NullObject::Raise("BRep_Tool:: TopoDS_Vertex hasn't gp_Pnt");
1185   }
1186
1187   Standard_Real p = aTVert->Tolerance();
1188   Standard_Real pMin = Precision::Confusion();
1189   if (p > pMin) return p;
1190   else          return pMin;
1191 }
1192
1193 //=======================================================================
1194 //function : Parameter
1195 //purpose  : Returns the parameter of <V> on <E>.
1196 //=======================================================================
1197
1198 Standard_Real  BRep_Tool::Parameter(const TopoDS_Vertex& V, 
1199                                   const TopoDS_Edge& E)
1200 {
1201   
1202   // Search the vertex in the edge
1203
1204   Standard_Boolean rev = Standard_False;
1205   TopoDS_Shape VF;
1206   TopAbs_Orientation orient = TopAbs_INTERNAL;
1207
1208   TopoDS_Iterator itv(E.Oriented(TopAbs_FORWARD));
1209
1210   // if the edge has no vertices
1211   // and is degenerated use the vertex orientation
1212   // RLE, june 94
1213
1214   if (!itv.More() && Degenerated(E)) {
1215     orient = V.Orientation();
1216   }
1217
1218   while (itv.More()) {
1219     const TopoDS_Shape& Vcur = itv.Value();
1220     if (V.IsSame(Vcur)) {
1221       if (VF.IsNull()) {
1222         VF = Vcur;
1223       }
1224       else {
1225         rev = E.Orientation() == TopAbs_REVERSED;
1226         if (Vcur.Orientation() == V.Orientation()) {
1227           VF = Vcur;
1228         }
1229       }
1230     }
1231     itv.Next();
1232   }
1233   
1234   if (!VF.IsNull()) orient = VF.Orientation();
1235  
1236   Standard_Real f,l;
1237
1238   if (orient ==  TopAbs_FORWARD) {
1239     BRep_Tool::Range(E,f,l);
1240     return (rev) ? l : f;
1241   }
1242  
1243   else if (orient ==  TopAbs_REVERSED) {
1244     BRep_Tool::Range(E,f,l);
1245     return (rev) ? f : l;
1246    }
1247
1248   else {
1249     TopLoc_Location L;
1250     const Handle(Geom_Curve)& C = BRep_Tool::Curve(E,L,f,l);
1251     L = L.Predivided(V.Location());
1252     if (!C.IsNull() || Degenerated(E)) {
1253       BRep_ListIteratorOfListOfPointRepresentation itpr
1254         ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
1255
1256       while (itpr.More()) {
1257         const Handle(BRep_PointRepresentation)& pr = itpr.Value();
1258         if (pr->IsPointOnCurve(C,L)) {
1259           Standard_Real p = pr->Parameter();
1260           Standard_Real res = p;// SVV 4 nov 99 - to avoid warnings on Linux
1261           if (!C.IsNull()) {
1262             // Closed curves RLE 16 june 94
1263             if (Precision::IsNegativeInfinite(f)) return pr->Parameter();//p;
1264             if (Precision::IsPositiveInfinite(l)) return pr->Parameter();//p;
1265             gp_Pnt Pf = C->Value(f).Transformed(L.Transformation());
1266             gp_Pnt Pl = C->Value(l).Transformed(L.Transformation());
1267             Standard_Real tol = BRep_Tool::Tolerance(V);
1268             if (Pf.Distance(Pl) < tol) {
1269               if (Pf.Distance(BRep_Tool::Pnt(V)) < tol) {
1270                 if (V.Orientation() == TopAbs_FORWARD) res = f;//p = f;
1271                 else                                   res = l;//p = l;
1272               }
1273             }
1274           }
1275           return res;//p;
1276         }
1277         itpr.Next();
1278       }
1279     }
1280     else {
1281       // no 3d curve !!
1282       // let us try with the first pcurve
1283       Handle(Geom2d_Curve) PC;
1284       Handle(Geom_Surface) S;
1285       BRep_Tool::CurveOnSurface(E,PC,S,L,f,l);
1286       L = L.Predivided(V.Location()); 
1287       BRep_ListIteratorOfListOfPointRepresentation itpr
1288         ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
1289
1290       while (itpr.More()) {
1291         const Handle(BRep_PointRepresentation)& pr = itpr.Value();
1292         if (pr->IsPointOnCurveOnSurface(PC,S,L)) {
1293           Standard_Real p = pr->Parameter();
1294           // Closed curves RLE 16 june 94
1295           if (PC->IsClosed()) {
1296             if ((p == PC->FirstParameter()) || 
1297                 (p == PC->LastParameter())) {
1298               if (V.Orientation() == TopAbs_FORWARD) p = PC->FirstParameter();
1299               else                                   p = PC->LastParameter();
1300             }
1301           }
1302           return p;
1303         }
1304         itpr.Next();
1305       }
1306     }
1307   }
1308   
1309   Standard_NoSuchObject::Raise("BRep_Tool:: no parameter on edge");
1310   return 0;
1311 }
1312
1313 //=======================================================================
1314 //function : Parameter
1315 //purpose  : Returns the  parameters  of   the  vertex   on the
1316 //           pcurve of the edge on the face.
1317 //=======================================================================
1318
1319 Standard_Real BRep_Tool::Parameter(const TopoDS_Vertex& V, 
1320                                    const TopoDS_Edge& E, 
1321                                    const TopoDS_Face& F)
1322 {
1323   TopLoc_Location L;
1324   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,L);
1325   return BRep_Tool::Parameter(V,E,S,L);
1326 }
1327
1328 //=======================================================================
1329 //function : Parameter
1330 //purpose  : Returns the  parameters  of   the  vertex   on the
1331 //           pcurve of the edge on the surface.
1332 //=======================================================================
1333
1334 Standard_Real BRep_Tool::Parameter(const TopoDS_Vertex& V, 
1335                                    const TopoDS_Edge& E, 
1336                                    const Handle(Geom_Surface)& S,
1337                                    const TopLoc_Location& L)
1338 {
1339   // Search the vertex in the edge
1340
1341   Standard_Boolean rev = Standard_False;
1342   TopoDS_Shape VF;
1343   TopoDS_Iterator itv(E.Oriented(TopAbs_FORWARD));
1344
1345   while (itv.More()) {
1346     if (V.IsSame(itv.Value())) {
1347       if (VF.IsNull()) VF = itv.Value();
1348       else {
1349         rev = E.Orientation() == TopAbs_REVERSED;
1350         if (itv.Value().Orientation() == V.Orientation()) 
1351         VF = itv.Value();
1352       }
1353     }
1354     itv.Next();
1355   }
1356
1357  TopAbs_Orientation orient = TopAbs_INTERNAL;
1358   if (!VF.IsNull()) orient = VF.Orientation();
1359  
1360  Standard_Real f,l;
1361
1362  if (orient ==  TopAbs_FORWARD) {
1363    BRep_Tool::Range(E,S,L,f,l);
1364    return (rev) ? l : f;
1365  }
1366  
1367  else if (orient ==  TopAbs_REVERSED) {
1368    BRep_Tool::Range(E,S,L,f,l);
1369    return (rev) ? f : l;
1370  }
1371
1372  else {
1373    Handle(Geom2d_Curve) PC = BRep_Tool::CurveOnSurface(E,S,L,f,l);
1374    BRep_ListIteratorOfListOfPointRepresentation itpr
1375      ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
1376
1377    while (itpr.More()) {
1378      if (itpr.Value()->IsPointOnCurveOnSurface(PC,S,L))
1379        return itpr.Value()->Parameter();
1380      itpr.Next();
1381    }
1382  }
1383
1384  //----------------------------------------------------------
1385    
1386   TopLoc_Location L1;
1387   const Handle(Geom_Curve)& C = BRep_Tool::Curve(E,L1,f,l);
1388   L1 = L1.Predivided(V.Location());
1389   if (!C.IsNull() || Degenerated(E)) {
1390     BRep_ListIteratorOfListOfPointRepresentation itpr
1391       ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
1392
1393     while (itpr.More()) {
1394       const Handle(BRep_PointRepresentation)& pr = itpr.Value();
1395       if (pr->IsPointOnCurve(C,L1)) {
1396         Standard_Real p = pr->Parameter();
1397         Standard_Real res = p;
1398         if (!C.IsNull()) {
1399           // Closed curves RLE 16 june 94
1400           if (Precision::IsNegativeInfinite(f)) return res;
1401           if (Precision::IsPositiveInfinite(l)) return res;
1402           gp_Pnt Pf = C->Value(f).Transformed(L1.Transformation());
1403           gp_Pnt Pl = C->Value(l).Transformed(L1.Transformation());
1404           Standard_Real tol = BRep_Tool::Tolerance(V);
1405           if (Pf.Distance(Pl) < tol) {
1406             if (Pf.Distance(BRep_Tool::Pnt(V)) < tol) {
1407               if (V.Orientation() == TopAbs_FORWARD) res = f;
1408               else                                   res = l;
1409             }
1410           }
1411         }
1412         return res;
1413       }
1414       itpr.Next();
1415     }
1416   }
1417   
1418 //----------------------------------------------------------   
1419  
1420   Standard_NoSuchObject::Raise("BRep_Tool:: no parameter on edge");
1421   return 0;
1422 }
1423
1424 //=======================================================================
1425 //function : Parameters
1426 //purpose  : Returns the parameters of the vertex on the face.
1427 //=======================================================================
1428
1429 gp_Pnt2d  BRep_Tool::Parameters(const TopoDS_Vertex& V, 
1430                                 const TopoDS_Face& F)
1431 {
1432   TopLoc_Location L;
1433   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,L);
1434   L = L.Predivided(V.Location());
1435   BRep_ListIteratorOfListOfPointRepresentation itpr
1436     ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
1437   // It is checked if there is PointRepresentation (case non Manifold)
1438
1439   while (itpr.More()) {
1440     if (itpr.Value()->IsPointOnSurface(S,L)) {
1441       return gp_Pnt2d(itpr.Value()->Parameter(),
1442                       itpr.Value()->Parameter2());
1443     }
1444     itpr.Next();
1445   }
1446
1447  TopoDS_Vertex Vf,Vl;
1448  TopoDS_Edge E;
1449  // Otherwise the edges are searched (PMN 4/06/97) It is not possible to succeed 999/1000!
1450  // even if often there is a way to make more economically than above...
1451  TopExp_Explorer exp;
1452  for (exp.Init(F, TopAbs_EDGE); exp.More(); exp.Next()) { 
1453     E = TopoDS::Edge(exp.Current());  
1454     TopExp::Vertices(E, Vf, Vl);
1455     if ((V.IsSame(Vf)) || (V.IsSame(Vl))) {
1456       gp_Pnt2d Pf, Pl;
1457       UVPoints(E, F, Pf, Pl);
1458       if (V.IsSame(Vf)) return Pf;
1459       else              return Pl;//Ambiguity (natural) for degenerated edges.
1460     }
1461   }
1462   Standard_NoSuchObject::Raise("BRep_Tool:: no parameters on surface");
1463   return gp_Pnt2d(0,0);
1464 }
1465 //=======================================================================
1466 //function : IsClosed
1467 //purpose  : 
1468 //=======================================================================
1469 Standard_Boolean BRep_Tool::IsClosed (const TopoDS_Shape& theShape)
1470 {
1471   if (theShape.ShapeType() == TopAbs_SHELL)
1472   {
1473     NCollection_Map<TopoDS_Shape, TopTools_ShapeMapHasher> aMap (101, new NCollection_IncAllocator);
1474     TopExp_Explorer exp (theShape.Oriented(TopAbs_FORWARD), TopAbs_EDGE);
1475     Standard_Boolean hasBound = Standard_False;
1476     for (; exp.More(); exp.Next())
1477     {
1478       const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1479       if (BRep_Tool::Degenerated(E) || E.Orientation() == TopAbs_INTERNAL || E.Orientation() == TopAbs_EXTERNAL)
1480         continue;
1481       hasBound = Standard_True;
1482       if (!aMap.Add(E))
1483         aMap.Remove(E);
1484     }
1485     return hasBound && aMap.IsEmpty();
1486   }
1487   else if (theShape.ShapeType() == TopAbs_WIRE)
1488   {
1489     NCollection_Map<TopoDS_Shape, TopTools_ShapeMapHasher> aMap (101, new NCollection_IncAllocator);
1490     TopExp_Explorer exp (theShape.Oriented(TopAbs_FORWARD), TopAbs_VERTEX);
1491     Standard_Boolean hasBound = Standard_False;
1492     for (; exp.More(); exp.Next())
1493     {
1494       const TopoDS_Shape& V = exp.Current();
1495       if (V.Orientation() == TopAbs_INTERNAL || V.Orientation() == TopAbs_EXTERNAL)
1496         continue;
1497       hasBound = Standard_True;
1498       if (!aMap.Add(V))
1499         aMap.Remove(V);
1500     }
1501     return hasBound && aMap.IsEmpty();
1502   }
1503   else if (theShape.ShapeType() == TopAbs_EDGE)
1504   {
1505     TopoDS_Vertex aVFirst, aVLast;
1506     TopExp::Vertices(TopoDS::Edge(theShape), aVFirst, aVLast);
1507     return !aVFirst.IsNull() && aVFirst.IsSame(aVLast);
1508   }
1509   return theShape.Closed();
1510 }
1511
1512 //modified by NIZNHY-PKV Fri Oct 17 14:09:58 2008 f 
1513 //=======================================================================
1514 //function : IsPlane
1515 //purpose  : 
1516 //=======================================================================
1517 Standard_Boolean IsPlane(const Handle(Geom_Surface)& aS)
1518 {
1519   Standard_Boolean bRet;
1520   Handle(Geom_Plane) aGP;
1521   Handle(Geom_RectangularTrimmedSurface) aGRTS;
1522   Handle(Geom_OffsetSurface) aGOFS;
1523   //
1524   aGRTS=Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
1525   aGOFS=Handle(Geom_OffsetSurface)::DownCast(aS);
1526   //
1527   if(!aGOFS.IsNull()) {
1528     aGP=Handle(Geom_Plane)::DownCast(aGOFS->BasisSurface());
1529   }
1530   else if(!aGRTS.IsNull()) {
1531     aGP=Handle(Geom_Plane)::DownCast(aGRTS->BasisSurface());
1532   }
1533   else {
1534     aGP=Handle(Geom_Plane)::DownCast(aS);
1535   }
1536   //
1537   bRet=!aGP.IsNull();
1538   //
1539   return bRet;
1540 }
1541
1542 //=======================================================================
1543 //function : MaxTolerance
1544 //purpose  : 
1545 //=======================================================================
1546 Standard_Real BRep_Tool::MaxTolerance (const TopoDS_Shape& theShape,
1547                                        const TopAbs_ShapeEnum theSubShape)
1548 {
1549   Standard_Real aTol = 0.0;
1550
1551   // Explorer Shape-Subshape.
1552   TopExp_Explorer anExpSS(theShape, theSubShape);
1553   if (theSubShape == TopAbs_FACE)
1554   {
1555     for( ; anExpSS.More() ;  anExpSS.Next() )
1556     {
1557       const TopoDS_Shape& aCurrentSubShape = anExpSS.Current();
1558       aTol = Max(aTol, Tolerance(TopoDS::Face(aCurrentSubShape)));
1559     }
1560   }
1561   else if (theSubShape == TopAbs_EDGE)
1562   {
1563     for( ; anExpSS.More() ;  anExpSS.Next() )
1564     {
1565       const TopoDS_Shape& aCurrentSubShape = anExpSS.Current();
1566       aTol = Max(aTol, Tolerance(TopoDS::Edge(aCurrentSubShape)));
1567     }
1568   }
1569   else if (theSubShape == TopAbs_VERTEX)
1570   {
1571     for( ; anExpSS.More() ;  anExpSS.Next() )
1572     {
1573       const TopoDS_Shape& aCurrentSubShape = anExpSS.Current();
1574       aTol = Max(aTol, Tolerance(TopoDS::Vertex(aCurrentSubShape)));
1575     }
1576   }
1577
1578   return aTol;
1579 }