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