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