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