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