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