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