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