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