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