27118a6c00dd4d76a215a3c8ac425ac91e58e0c2
[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 #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
1143   if (TV.IsNull())
1144   {
1145     Standard_NullObject::Raise("BRep_Tool:: TopoDS_Vertex hasn't gp_Pnt");
1146   }
1147
1148   gp_Pnt P = TV->Pnt();
1149   P.Transform(V.Location().Transformation());
1150   return P;
1151 }
1152
1153 //=======================================================================
1154 //function : Tolerance
1155 //purpose  : Returns the tolerance.
1156 //=======================================================================
1157
1158 Standard_Real  BRep_Tool::Tolerance(const TopoDS_Vertex& V)
1159 {
1160   Handle(BRep_TVertex)& aTVert = *((Handle(BRep_TVertex)*)&V.TShape());
1161
1162   if (aTVert.IsNull())
1163   {
1164     Standard_NullObject::Raise("BRep_Tool:: TopoDS_Vertex hasn't gp_Pnt");
1165   }
1166
1167   Standard_Real p = aTVert->Tolerance();
1168   Standard_Real pMin = Precision::Confusion();
1169   if (p > pMin) return p;
1170   else          return pMin;
1171 }
1172
1173 //=======================================================================
1174 //function : Parameter
1175 //purpose  : Returns the parameter of <V> on <E>.
1176 //=======================================================================
1177
1178 Standard_Real  BRep_Tool::Parameter(const TopoDS_Vertex& V, 
1179                                   const TopoDS_Edge& E)
1180 {
1181   
1182   // Search the vertex in the edge
1183
1184   Standard_Boolean rev = Standard_False;
1185   TopoDS_Shape VF;
1186   TopAbs_Orientation orient = TopAbs_INTERNAL;
1187
1188   TopoDS_Iterator itv(E.Oriented(TopAbs_FORWARD));
1189
1190   // if the edge has no vertices
1191   // and is degenerated use the vertex orientation
1192   // RLE, june 94
1193
1194   if (!itv.More() && Degenerated(E)) {
1195     orient = V.Orientation();
1196   }
1197
1198   while (itv.More()) {
1199     const TopoDS_Shape& Vcur = itv.Value();
1200     if (V.IsSame(Vcur)) {
1201       if (VF.IsNull()) {
1202         VF = Vcur;
1203       }
1204       else {
1205         rev = E.Orientation() == TopAbs_REVERSED;
1206         if (Vcur.Orientation() == V.Orientation()) {
1207           VF = Vcur;
1208         }
1209       }
1210     }
1211     itv.Next();
1212   }
1213   
1214   if (!VF.IsNull()) orient = VF.Orientation();
1215  
1216   Standard_Real f,l;
1217
1218   if (orient ==  TopAbs_FORWARD) {
1219     BRep_Tool::Range(E,f,l);
1220     return (rev) ? l : f;
1221   }
1222  
1223   else if (orient ==  TopAbs_REVERSED) {
1224     BRep_Tool::Range(E,f,l);
1225     return (rev) ? f : l;
1226    }
1227
1228   else {
1229     TopLoc_Location L;
1230     const Handle(Geom_Curve)& C = BRep_Tool::Curve(E,L,f,l);
1231     L = L.Predivided(V.Location());
1232     if (!C.IsNull() || Degenerated(E)) {
1233       BRep_ListIteratorOfListOfPointRepresentation itpr
1234         ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
1235
1236       while (itpr.More()) {
1237         const Handle(BRep_PointRepresentation)& pr = itpr.Value();
1238         if (pr->IsPointOnCurve(C,L)) {
1239           Standard_Real p = pr->Parameter();
1240           Standard_Real res = p;// SVV 4 nov 99 - to avoid warnings on Linux
1241           if (!C.IsNull()) {
1242             // Closed curves RLE 16 june 94
1243             if (Precision::IsNegativeInfinite(f)) return pr->Parameter();//p;
1244             if (Precision::IsPositiveInfinite(l)) return pr->Parameter();//p;
1245             gp_Pnt Pf = C->Value(f).Transformed(L.Transformation());
1246             gp_Pnt Pl = C->Value(l).Transformed(L.Transformation());
1247             Standard_Real tol = BRep_Tool::Tolerance(V);
1248             if (Pf.Distance(Pl) < tol) {
1249               if (Pf.Distance(BRep_Tool::Pnt(V)) < tol) {
1250                 if (V.Orientation() == TopAbs_FORWARD) res = f;//p = f;
1251                 else                                   res = l;//p = l;
1252               }
1253             }
1254           }
1255           return res;//p;
1256         }
1257         itpr.Next();
1258       }
1259     }
1260     else {
1261       // no 3d curve !!
1262       // let us try with the first pcurve
1263       Handle(Geom2d_Curve) PC;
1264       Handle(Geom_Surface) S;
1265       BRep_Tool::CurveOnSurface(E,PC,S,L,f,l);
1266       L = L.Predivided(V.Location()); 
1267       BRep_ListIteratorOfListOfPointRepresentation itpr
1268         ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
1269
1270       while (itpr.More()) {
1271         const Handle(BRep_PointRepresentation)& pr = itpr.Value();
1272         if (pr->IsPointOnCurveOnSurface(PC,S,L)) {
1273           Standard_Real p = pr->Parameter();
1274           // Closed curves RLE 16 june 94
1275           if (PC->IsClosed()) {
1276             if ((p == PC->FirstParameter()) || 
1277                 (p == PC->LastParameter())) {
1278               if (V.Orientation() == TopAbs_FORWARD) p = PC->FirstParameter();
1279               else                                   p = PC->LastParameter();
1280             }
1281           }
1282           return p;
1283         }
1284         itpr.Next();
1285       }
1286     }
1287   }
1288   
1289   Standard_NoSuchObject::Raise("BRep_Tool:: no parameter on edge");
1290   return 0;
1291 }
1292
1293 //=======================================================================
1294 //function : Parameter
1295 //purpose  : Returns the  parameters  of   the  vertex   on the
1296 //           pcurve of the edge on the face.
1297 //=======================================================================
1298
1299 Standard_Real BRep_Tool::Parameter(const TopoDS_Vertex& V, 
1300                                    const TopoDS_Edge& E, 
1301                                    const TopoDS_Face& F)
1302 {
1303   TopLoc_Location L;
1304   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,L);
1305   return BRep_Tool::Parameter(V,E,S,L);
1306 }
1307
1308 //=======================================================================
1309 //function : Parameter
1310 //purpose  : Returns the  parameters  of   the  vertex   on the
1311 //           pcurve of the edge on the surface.
1312 //=======================================================================
1313
1314 Standard_Real BRep_Tool::Parameter(const TopoDS_Vertex& V, 
1315                                    const TopoDS_Edge& E, 
1316                                    const Handle(Geom_Surface)& S,
1317                                    const TopLoc_Location& L)
1318 {
1319   // Search the vertex in the edge
1320
1321   Standard_Boolean rev = Standard_False;
1322   TopoDS_Shape VF;
1323   TopoDS_Iterator itv(E.Oriented(TopAbs_FORWARD));
1324
1325   while (itv.More()) {
1326     if (V.IsSame(itv.Value())) {
1327       if (VF.IsNull()) VF = itv.Value();
1328       else {
1329         rev = E.Orientation() == TopAbs_REVERSED;
1330         if (itv.Value().Orientation() == V.Orientation()) 
1331         VF = itv.Value();
1332       }
1333     }
1334     itv.Next();
1335   }
1336
1337  TopAbs_Orientation orient = TopAbs_INTERNAL;
1338   if (!VF.IsNull()) orient = VF.Orientation();
1339  
1340  Standard_Real f,l;
1341
1342  if (orient ==  TopAbs_FORWARD) {
1343    BRep_Tool::Range(E,S,L,f,l);
1344    return (rev) ? l : f;
1345  }
1346  
1347  else if (orient ==  TopAbs_REVERSED) {
1348    BRep_Tool::Range(E,S,L,f,l);
1349    return (rev) ? f : l;
1350  }
1351
1352  else {
1353    Handle(Geom2d_Curve) PC = BRep_Tool::CurveOnSurface(E,S,L,f,l);
1354    BRep_ListIteratorOfListOfPointRepresentation itpr
1355      ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
1356
1357    while (itpr.More()) {
1358      if (itpr.Value()->IsPointOnCurveOnSurface(PC,S,L))
1359        return itpr.Value()->Parameter();
1360      itpr.Next();
1361    }
1362  }
1363
1364  //----------------------------------------------------------
1365    
1366   TopLoc_Location L1;
1367   const Handle(Geom_Curve)& C = BRep_Tool::Curve(E,L1,f,l);
1368   L1 = L1.Predivided(V.Location());
1369   if (!C.IsNull() || Degenerated(E)) {
1370     BRep_ListIteratorOfListOfPointRepresentation itpr
1371       ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
1372
1373     while (itpr.More()) {
1374       const Handle(BRep_PointRepresentation)& pr = itpr.Value();
1375       if (pr->IsPointOnCurve(C,L1)) {
1376         Standard_Real p = pr->Parameter();
1377         Standard_Real res = p;
1378         if (!C.IsNull()) {
1379           // Closed curves RLE 16 june 94
1380           if (Precision::IsNegativeInfinite(f)) return res;
1381           if (Precision::IsPositiveInfinite(l)) return res;
1382           gp_Pnt Pf = C->Value(f).Transformed(L1.Transformation());
1383           gp_Pnt Pl = C->Value(l).Transformed(L1.Transformation());
1384           Standard_Real tol = BRep_Tool::Tolerance(V);
1385           if (Pf.Distance(Pl) < tol) {
1386             if (Pf.Distance(BRep_Tool::Pnt(V)) < tol) {
1387               if (V.Orientation() == TopAbs_FORWARD) res = f;
1388               else                                   res = l;
1389             }
1390           }
1391         }
1392         return res;
1393       }
1394       itpr.Next();
1395     }
1396   }
1397   
1398 //----------------------------------------------------------   
1399  
1400   Standard_NoSuchObject::Raise("BRep_Tool:: no parameter on edge");
1401   return 0;
1402 }
1403
1404 //=======================================================================
1405 //function : Parameters
1406 //purpose  : Returns the parameters of the vertex on the face.
1407 //=======================================================================
1408
1409 gp_Pnt2d  BRep_Tool::Parameters(const TopoDS_Vertex& V, 
1410                                 const TopoDS_Face& F)
1411 {
1412   TopLoc_Location L;
1413   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,L);
1414   L = L.Predivided(V.Location());
1415   BRep_ListIteratorOfListOfPointRepresentation itpr
1416     ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
1417   // It is checked if there is PointRepresentation (case non Manifold)
1418
1419   while (itpr.More()) {
1420     if (itpr.Value()->IsPointOnSurface(S,L)) {
1421       return gp_Pnt2d(itpr.Value()->Parameter(),
1422                       itpr.Value()->Parameter2());
1423     }
1424     itpr.Next();
1425   }
1426
1427  TopoDS_Vertex Vf,Vl;
1428  TopoDS_Edge E;
1429  // Otherwise the edges are searched (PMN 4/06/97) It is not possible to succeed 999/1000!
1430  // even if often there is a way to make more economically than above...
1431  TopExp_Explorer exp;
1432  for (exp.Init(F, TopAbs_EDGE); exp.More(); exp.Next()) { 
1433     E = TopoDS::Edge(exp.Current());  
1434     TopExp::Vertices(E, Vf, Vl);
1435     if ((V.IsSame(Vf)) || (V.IsSame(Vl))) {
1436       gp_Pnt2d Pf, Pl;
1437       UVPoints(E, F, Pf, Pl);
1438       if (V.IsSame(Vf)) return Pf;
1439       else              return Pl;//Ambiguity (natural) for degenerated edges.
1440     }
1441   }
1442   Standard_NoSuchObject::Raise("BRep_Tool:: no parameters on surface");
1443   return gp_Pnt2d(0,0);
1444 }
1445 //=======================================================================
1446 //function : IsClosed
1447 //purpose  : Returns <True>  if S if flaged Closed, if S is a
1448 //           Solid,Shell or Compound  returns <True> is S has no free boundaries.
1449 //=======================================================================
1450 Standard_Boolean BRep_Tool::IsClosed(const TopoDS_Shape& S)
1451 {
1452   if (S.ShapeType() == TopAbs_SHELL || S.ShapeType() == TopAbs_SOLID ||
1453       S.ShapeType() == TopAbs_COMPOUND) {
1454     TopTools_MapOfShape M;
1455     TopExp_Explorer exp;
1456     for (exp.Init(S,TopAbs_EDGE); exp.More(); exp.Next()) {
1457 //    for (TopExp_Explorer exp(S,TopAbs_EDGE); exp.More(); exp.Next()) {
1458       const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1459       if (BRep_Tool::Degenerated(E)) continue;
1460       if (!M.Add(E)) M.Remove(E);
1461     }
1462     if ( M.IsEmpty()) return 1;
1463   }
1464   return (S.Closed());
1465 }
1466
1467 //modified by NIZNHY-PKV Fri Oct 17 14:09:58 2008 f 
1468 //=======================================================================
1469 //function : IsPlane
1470 //purpose  : 
1471 //=======================================================================
1472 Standard_Boolean IsPlane(const Handle(Geom_Surface)& aS)
1473 {
1474   Standard_Boolean bRet;
1475   Handle(Geom_Plane) aGP;
1476   Handle(Geom_RectangularTrimmedSurface) aGRTS;
1477   Handle(Geom_OffsetSurface) aGOFS;
1478   //
1479   aGRTS=Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
1480   aGOFS=Handle(Geom_OffsetSurface)::DownCast(aS);
1481   //
1482   if(!aGOFS.IsNull()) {
1483     aGP=Handle(Geom_Plane)::DownCast(aGOFS->BasisSurface());
1484   }
1485   else if(!aGRTS.IsNull()) {
1486     aGP=Handle(Geom_Plane)::DownCast(aGRTS->BasisSurface());
1487   }
1488   else {
1489     aGP=Handle(Geom_Plane)::DownCast(aS);
1490   }
1491   //
1492   bRet=!aGP.IsNull();
1493   //
1494   return bRet;
1495 }