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