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