0024023: Revamp the OCCT Handle -- downcast (automatic)
[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)::DownCast (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       Handle(BRep_Curve3D) GC (Handle(BRep_Curve3D)::DownCast (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)::DownCast (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       Handle(BRep_Polygon3D) GC (Handle(BRep_Polygon3D)::DownCast (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       Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (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)::DownCast (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)::DownCast (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       Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (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       Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (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       Handle(BRep_PolygonOnSurface) PS (Handle(BRep_PolygonOnSurface)::DownCast (cr));
537       P = PS->Polygon();
538       S = PS->Surface();
539       L = E.Location() * PS->Location();
540       return;
541     }
542     itcr.Next();
543   }
544   
545   L = TopLoc_Location();
546   P = Handle(Poly_Polygon2D)();
547   S = Handle(Geom_Surface)();
548 }
549
550 //=======================================================================
551 //function : PolygonOnSurface
552 //purpose  : 
553 //=======================================================================
554
555 void BRep_Tool::PolygonOnSurface(const TopoDS_Edge&      E,
556                                  Handle(Poly_Polygon2D)& P,
557                                  Handle(Geom_Surface)&   S,
558                                  TopLoc_Location&        L,
559                                  const Standard_Integer  Index)
560 {
561   Standard_Integer i = 0;
562
563   // find the representation
564   BRep_ListIteratorOfListOfCurveRepresentation itcr
565     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
566
567   while (itcr.More()) {
568     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
569     if (cr->IsPolygonOnSurface()) {
570       Handle(BRep_PolygonOnSurface) PS (Handle(BRep_PolygonOnSurface)::DownCast (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       Handle(BRep_PolygonOnTriangulation) PT (Handle(BRep_PolygonOnTriangulation)::DownCast (cr));
642       P = PT->PolygonOnTriangulation();
643       T = PT->Triangulation();
644       L = E.Location() * PT->Location();
645       return;
646     }
647     itcr.Next();
648   }
649   
650   L = TopLoc_Location();
651   P = Handle(Poly_PolygonOnTriangulation)();
652   T = Handle(Poly_Triangulation)();
653 }
654
655 //=======================================================================
656 //function : PolygonOnTriangulation
657 //purpose  : 
658 //=======================================================================
659
660 void 
661 BRep_Tool::PolygonOnTriangulation(const TopoDS_Edge&                   E,
662                                   Handle(Poly_PolygonOnTriangulation)& P,
663                                   Handle(Poly_Triangulation)&          T,
664                                   TopLoc_Location&                     L,
665                                   const Standard_Integer               Index)
666 {
667   Standard_Integer i = 0;
668
669   // find the representation
670   BRep_ListIteratorOfListOfCurveRepresentation itcr
671     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
672
673   while (itcr.More()) {
674     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
675     if (cr->IsPolygonOnTriangulation()) {
676       Handle(BRep_PolygonOnTriangulation) PT (Handle(BRep_PolygonOnTriangulation)::DownCast (cr));
677       i++;
678       if (i > Index) break;
679       if (i == Index) {
680         T = PT->Triangulation();
681         P = PT->PolygonOnTriangulation();
682         L = E.Location() * PT->Location();
683         return;
684       }
685     }
686     itcr.Next();
687   }
688   
689   L = TopLoc_Location();
690   P = Handle(Poly_PolygonOnTriangulation)();
691   T = Handle(Poly_Triangulation)();
692 }
693
694 //=======================================================================
695 //function : IsClosed
696 //purpose  : Returns  True  if  <E>  has  two  PCurves  in  the
697 //           parametric space of <F>. i.e.  <F>  is on a closed
698 //           surface and <E> is on the closing curve.
699 //=======================================================================
700
701 Standard_Boolean BRep_Tool::IsClosed(const TopoDS_Edge& E, 
702                                      const TopoDS_Face& F)
703 {
704   TopLoc_Location l;
705   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,l);
706   if (IsClosed(E,S,l)) return Standard_True;
707   const Handle(Poly_Triangulation)& T = BRep_Tool::Triangulation(F,l);
708   return IsClosed(E, T, l);
709 }
710
711 //=======================================================================
712 //function : IsClosed
713 //purpose  : Returns  True  if  <E>  has  two  PCurves  in  the
714 //           parametric space  of <S>.  i.e.   <S>  is a closed
715 //           surface and <E> is on the closing curve.
716 //=======================================================================
717
718 Standard_Boolean BRep_Tool::IsClosed(const TopoDS_Edge& E,
719                                      const Handle(Geom_Surface)& S,
720                                      const TopLoc_Location& L)
721 {
722   //modified by NIZNHY-PKV Fri Oct 17 12:16:58 2008f
723   if (IsPlane(S)) {
724     return Standard_False;
725   }
726   //modified by NIZNHY-PKV Fri Oct 17 12:16:54 2008t
727   //
728   TopLoc_Location      l = L.Predivided(E.Location());
729
730   // find the representation
731   BRep_ListIteratorOfListOfCurveRepresentation itcr
732     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
733
734   while (itcr.More()) {
735     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
736     if (cr->IsCurveOnSurface(S,l) &&
737         cr->IsCurveOnClosedSurface())
738       return Standard_True;
739     itcr.Next();
740   }
741   return Standard_False;
742 }
743
744 //=======================================================================
745 //function : IsClosed
746 //purpose  : Returns  True  if <E> has two arrays of indices in
747 //           the triangulation <T>.
748 //=======================================================================
749
750 Standard_Boolean BRep_Tool::IsClosed(const TopoDS_Edge&                E, 
751                                      const Handle(Poly_Triangulation)& T,
752                                      const TopLoc_Location& L)
753 {
754   TopLoc_Location l = L.Predivided(E.Location());
755
756   // find the representation
757   BRep_ListIteratorOfListOfCurveRepresentation itcr
758     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
759
760   while (itcr.More()) {
761     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
762     if (cr->IsPolygonOnTriangulation(T,l) &&
763         cr->IsPolygonOnClosedTriangulation()) 
764       return Standard_True;
765     itcr.Next();
766   }
767   return Standard_False;
768 }
769
770 //=======================================================================
771 //function : Tolerance
772 //purpose  : Returns the tolerance for <E>.
773 //=======================================================================
774
775 Standard_Real  BRep_Tool::Tolerance(const TopoDS_Edge& E)
776 {
777   Standard_Real p = (*((Handle(BRep_TEdge)*)&E.TShape()))->Tolerance();
778   Standard_Real pMin = Precision::Confusion();
779   if (p > pMin) return p;
780   else          return pMin;
781 }
782
783 //=======================================================================
784 //function : SameParameter
785 //purpose  : Returns the SameParameter flag for the edge.
786 //=======================================================================
787
788 Standard_Boolean  BRep_Tool::SameParameter(const TopoDS_Edge& E)
789 {
790   return (*((Handle(BRep_TEdge)*)&E.TShape()))->SameParameter();
791 }
792
793 //=======================================================================
794 //function : SameRange
795 //purpose  : Returns the SameRange flag for the edge.
796 //=======================================================================
797
798 Standard_Boolean  BRep_Tool::SameRange(const TopoDS_Edge& E)
799 {
800   return (*((Handle(BRep_TEdge)*)&E.TShape()))->SameRange();
801 }
802
803 //=======================================================================
804 //function : Degenerated
805 //purpose  : Returns True  if the edge is degenerated.
806 //=======================================================================
807
808 Standard_Boolean  BRep_Tool::Degenerated(const TopoDS_Edge& E)
809 {
810   return (*((Handle(BRep_TEdge)*)&E.TShape()))->Degenerated();
811 }
812
813 //=======================================================================
814 //function : Range
815 //purpose  : 
816 //=======================================================================
817
818 void  BRep_Tool::Range(const TopoDS_Edge& E, 
819                        Standard_Real& First, 
820                        Standard_Real& Last)
821 {
822   //  set the range to all the representations
823   BRep_ListIteratorOfListOfCurveRepresentation itcr
824     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
825
826   while (itcr.More()) {
827     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
828     if (cr->IsCurve3D()) {
829       Handle(BRep_Curve3D) CR (Handle(BRep_Curve3D)::DownCast (cr));
830       if (!CR->Curve3D().IsNull()) {
831         First = CR->First(); 
832         Last = CR->Last();
833         break;
834       }
835     }
836     else if (cr->IsCurveOnSurface()) {
837       Handle(BRep_GCurve) CR (Handle(BRep_GCurve)::DownCast (cr));
838       First = CR->First(); 
839       Last = CR->Last();
840       break;
841     }
842     itcr.Next();
843   }
844 }
845
846 //=======================================================================
847 //function : Range
848 //purpose  : 
849 //=======================================================================
850
851 void  BRep_Tool::Range(const TopoDS_Edge& E, 
852                        const Handle(Geom_Surface)& S,
853                        const TopLoc_Location& L,
854                        Standard_Real& First, 
855                        Standard_Real& Last)
856 {
857   TopLoc_Location l = L.Predivided(E.Location());
858   
859   // find the representation
860   BRep_ListIteratorOfListOfCurveRepresentation itcr
861     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
862   
863   while (itcr.More()) {
864     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
865     if (cr->IsCurveOnSurface(S,l)) {
866       Handle(BRep_GCurve)::DownCast (cr)->Range(First,Last);
867       break;
868     }
869     itcr.Next();
870   }
871   if (!itcr.More()) {
872     Range(E,First,Last);
873   }
874   (*((Handle(BRep_TEdge)*)&E.TShape()))->Modified(Standard_True);
875  }
876
877 //=======================================================================
878 //function : Range
879 //purpose  : 
880 //=======================================================================
881
882 void  BRep_Tool::Range(const TopoDS_Edge& E, 
883                        const TopoDS_Face& F, 
884                        Standard_Real& First, 
885                        Standard_Real& Last)
886 {
887   TopLoc_Location L;
888   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,L);
889   Range(E,S,L,First,Last);
890 }
891
892 //=======================================================================
893 //function : UVPoints
894 //purpose  : 
895 //=======================================================================
896
897 void  BRep_Tool::UVPoints(const TopoDS_Edge& E, 
898                           const Handle(Geom_Surface)& S, 
899                           const TopLoc_Location& L, 
900                           gp_Pnt2d& PFirst, 
901                           gp_Pnt2d& PLast)
902 {
903   TopLoc_Location l = L.Predivided(E.Location());
904   Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED);
905
906   // find the representation
907   BRep_ListIteratorOfListOfCurveRepresentation itcr
908     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
909
910   while (itcr.More()) {
911     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
912     if (cr->IsCurveOnSurface(S,l)) {
913       if (cr->IsCurveOnClosedSurface() && Eisreversed)
914         Handle(BRep_CurveOnClosedSurface)::DownCast (cr)->UVPoints2(PFirst,PLast);
915       else
916         Handle(BRep_CurveOnSurface)::DownCast (cr)->UVPoints(PFirst,PLast);
917       return;
918     }
919     itcr.Next();
920   }
921
922   // for planar surface project the vertices
923   // modif 21-05-97 : for RectangularTrimmedSurface, project the vertices
924   Handle(Geom_Plane) GP;
925   Handle(Geom_RectangularTrimmedSurface) GRTS;
926   GRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
927   if(!GRTS.IsNull())
928     GP = Handle(Geom_Plane)::DownCast(GRTS->BasisSurface());
929   else
930     GP = Handle(Geom_Plane)::DownCast(S);
931   //fin modif du 21-05-97
932   if (!GP.IsNull()) {
933     // get the two vertices
934     TopoDS_Vertex Vf,Vl;
935     TopExp::Vertices(E,Vf,Vl);
936
937     TopLoc_Location Linverted = L.Inverted();
938     Vf.Move(Linverted);
939     Vl.Move(Linverted);
940     Standard_Real u,v;
941     gp_Pln pln = GP->Pln();
942
943     u=v=0.;
944     if (!Vf.IsNull()) {
945       gp_Pnt PF = BRep_Tool::Pnt(Vf);
946       ElSLib::Parameters(pln,PF,u,v);
947     }
948     PFirst.SetCoord(u,v);
949
950     u=v=0.;
951     if (!Vl.IsNull()) {
952       gp_Pnt PL = BRep_Tool::Pnt(Vl);
953       ElSLib::Parameters(pln,PL,u,v);
954     }
955     PLast.SetCoord(u,v);
956   }    
957 }
958
959 //=======================================================================
960 //function : UVPoints
961 //purpose  : 
962 //=======================================================================
963
964 void  BRep_Tool::UVPoints(const TopoDS_Edge& E,
965                           const TopoDS_Face& F, 
966                           gp_Pnt2d& PFirst, 
967                           gp_Pnt2d& PLast)
968 {
969   TopLoc_Location L;
970   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,L);
971   TopoDS_Edge aLocalEdge = E;
972   if (F.Orientation() == TopAbs_REVERSED) {
973     aLocalEdge.Reverse();
974 //    UVPoints(E,S,L,PFirst,PLast);
975   }
976 //    UVPoints(TopoDS::Edge(E.Reversed()),S,L,PFirst,PLast);
977 //  else
978 //    UVPoints(E,S,L,PFirst,PLast);
979   UVPoints(aLocalEdge,S,L,PFirst,PLast);
980 }
981
982 //=======================================================================
983 //function : SetUVPoints
984 //purpose  : 
985 //=======================================================================
986
987 void  BRep_Tool::SetUVPoints(const TopoDS_Edge& E,
988                              const Handle(Geom_Surface)& S,
989                              const TopLoc_Location& L, 
990                              const gp_Pnt2d& PFirst, 
991                              const gp_Pnt2d& PLast)
992 {
993   TopLoc_Location l = L.Predivided(E.Location());
994   Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED);
995
996   // find the representation
997   BRep_ListIteratorOfListOfCurveRepresentation itcr
998     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
999
1000   while (itcr.More()) {
1001     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
1002     if (cr->IsCurveOnSurface(S,l)) {
1003       if (cr->IsCurveOnClosedSurface() && Eisreversed)
1004         Handle(BRep_CurveOnClosedSurface)::DownCast (cr)->
1005           SetUVPoints2(PFirst,PLast);
1006       else
1007         Handle(BRep_CurveOnSurface)::DownCast (cr)->
1008           SetUVPoints(PFirst,PLast);
1009     }
1010     itcr.Next();
1011   }
1012 }
1013
1014 //=======================================================================
1015 //function : SetUVPoints
1016 //purpose  : 
1017 //=======================================================================
1018
1019 void  BRep_Tool::SetUVPoints(const TopoDS_Edge& E,
1020                              const TopoDS_Face& F, 
1021                              const gp_Pnt2d& PFirst, 
1022                              const gp_Pnt2d& PLast)
1023 {
1024   TopLoc_Location L;
1025   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,L);
1026   TopoDS_Edge aLocalEdge = E;
1027   if (F.Orientation() == TopAbs_REVERSED) {
1028     aLocalEdge.Reverse();
1029 //    SetUVPoints(TopoDS::Edge(E.Reversed()),S,L,PFirst,PLast);
1030   }
1031 //  else
1032 //    SetUVPoints(E,S,L,PFirst,PLast);
1033   SetUVPoints(aLocalEdge,S,L,PFirst,PLast);
1034 }
1035
1036 //=======================================================================
1037 //function : HasContinuity
1038 //purpose  : Returns True if the edge is on the surfaces of the
1039 //           two faces.
1040 //=======================================================================
1041
1042 Standard_Boolean BRep_Tool::HasContinuity(const TopoDS_Edge& E, 
1043                                           const TopoDS_Face& F1, 
1044                                           const TopoDS_Face& F2)
1045 {
1046   TopLoc_Location l1,l2;
1047   const Handle(Geom_Surface)& S1 = BRep_Tool::Surface(F1,l1);
1048   const Handle(Geom_Surface)& S2 = BRep_Tool::Surface(F2,l2);
1049   return HasContinuity(E,S1,S2,l1,l2);
1050 }
1051
1052 //=======================================================================
1053 //function : Continuity
1054 //purpose  : Returns the continuity.
1055 //=======================================================================
1056
1057 GeomAbs_Shape  BRep_Tool::Continuity(const TopoDS_Edge& E, 
1058                                      const TopoDS_Face& F1, 
1059                                      const TopoDS_Face& F2)
1060 {
1061   TopLoc_Location l1,l2;
1062   const Handle(Geom_Surface)& S1 = BRep_Tool::Surface(F1,l1);
1063   const Handle(Geom_Surface)& S2 = BRep_Tool::Surface(F2,l2);
1064   return Continuity(E,S1,S2,l1,l2);
1065 }
1066
1067 //=======================================================================
1068 //function : HasContinuity
1069 //purpose  : Returns True if the edge is on the surfaces.
1070 //=======================================================================
1071
1072 Standard_Boolean BRep_Tool::HasContinuity(const TopoDS_Edge& E, 
1073                                           const Handle(Geom_Surface)& S1, 
1074                                           const Handle(Geom_Surface)& S2, 
1075                                           const TopLoc_Location& L1, 
1076                                           const TopLoc_Location& L2)
1077 {
1078   const TopLoc_Location& Eloc = E.Location();
1079   TopLoc_Location l1 = L1.Predivided(Eloc);
1080   TopLoc_Location l2 = L2.Predivided(Eloc);
1081
1082   // find the representation
1083   BRep_ListIteratorOfListOfCurveRepresentation itcr
1084     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
1085
1086   while (itcr.More()) {
1087     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
1088     if (cr->IsRegularity(S1,S2,l1,l2))
1089       return Standard_True;
1090     itcr.Next();
1091   }
1092   return Standard_False;
1093 }
1094
1095 //=======================================================================
1096 //function : Continuity
1097 //purpose  : Returns the continuity.
1098 //=======================================================================
1099
1100 GeomAbs_Shape  BRep_Tool::Continuity(const TopoDS_Edge& E, 
1101                                      const Handle(Geom_Surface)& S1, 
1102                                      const Handle(Geom_Surface)& S2, 
1103                                      const TopLoc_Location& L1, 
1104                                      const TopLoc_Location& L2)
1105 {
1106   TopLoc_Location l1 = L1.Predivided(E.Location());
1107   TopLoc_Location l2 = L2.Predivided(E.Location());
1108
1109   // find the representation
1110   BRep_ListIteratorOfListOfCurveRepresentation itcr
1111     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
1112
1113   while (itcr.More()) {
1114     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
1115     if (cr->IsRegularity(S1,S2,l1,l2))
1116       return cr->Continuity();
1117     itcr.Next();
1118   }
1119   return GeomAbs_C0;
1120 }
1121
1122 //=======================================================================
1123 //function : HasContinuity
1124 //purpose  : Returns True if the edge is on some two surfaces.
1125 //=======================================================================
1126
1127 Standard_Boolean BRep_Tool::HasContinuity(const TopoDS_Edge& E)
1128 {
1129   BRep_ListIteratorOfListOfCurveRepresentation itcr
1130     ((*((Handle(BRep_TEdge)*)&E.TShape()))->Curves());
1131
1132   for (; itcr.More(); itcr.Next())
1133   {
1134     const Handle(BRep_CurveRepresentation)& CR = itcr.Value();
1135     if (CR->IsRegularity())
1136       return Standard_True;
1137   }
1138   return Standard_False;
1139 }
1140
1141 //=======================================================================
1142 //function : Pnt
1143 //purpose  : Returns the 3d point.
1144 //=======================================================================
1145
1146 gp_Pnt  BRep_Tool::Pnt(const TopoDS_Vertex& V)
1147 {
1148   Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &V.TShape());
1149
1150   if (TV.IsNull())
1151   {
1152     Standard_NullObject::Raise("BRep_Tool:: TopoDS_Vertex hasn't gp_Pnt");
1153   }
1154
1155   gp_Pnt P = TV->Pnt();
1156   P.Transform(V.Location().Transformation());
1157   return P;
1158 }
1159
1160 //=======================================================================
1161 //function : Tolerance
1162 //purpose  : Returns the tolerance.
1163 //=======================================================================
1164
1165 Standard_Real  BRep_Tool::Tolerance(const TopoDS_Vertex& V)
1166 {
1167   Handle(BRep_TVertex)& aTVert = *((Handle(BRep_TVertex)*)&V.TShape());
1168
1169   if (aTVert.IsNull())
1170   {
1171     Standard_NullObject::Raise("BRep_Tool:: TopoDS_Vertex hasn't gp_Pnt");
1172   }
1173
1174   Standard_Real p = aTVert->Tolerance();
1175   Standard_Real pMin = Precision::Confusion();
1176   if (p > pMin) return p;
1177   else          return pMin;
1178 }
1179
1180 //=======================================================================
1181 //function : Parameter
1182 //purpose  : Returns the parameter of <V> on <E>.
1183 //=======================================================================
1184
1185 Standard_Real  BRep_Tool::Parameter(const TopoDS_Vertex& V, 
1186                                   const TopoDS_Edge& E)
1187 {
1188   
1189   // Search the vertex in the edge
1190
1191   Standard_Boolean rev = Standard_False;
1192   TopoDS_Shape VF;
1193   TopAbs_Orientation orient = TopAbs_INTERNAL;
1194
1195   TopoDS_Iterator itv(E.Oriented(TopAbs_FORWARD));
1196
1197   // if the edge has no vertices
1198   // and is degenerated use the vertex orientation
1199   // RLE, june 94
1200
1201   if (!itv.More() && Degenerated(E)) {
1202     orient = V.Orientation();
1203   }
1204
1205   while (itv.More()) {
1206     const TopoDS_Shape& Vcur = itv.Value();
1207     if (V.IsSame(Vcur)) {
1208       if (VF.IsNull()) {
1209         VF = Vcur;
1210       }
1211       else {
1212         rev = E.Orientation() == TopAbs_REVERSED;
1213         if (Vcur.Orientation() == V.Orientation()) {
1214           VF = Vcur;
1215         }
1216       }
1217     }
1218     itv.Next();
1219   }
1220   
1221   if (!VF.IsNull()) orient = VF.Orientation();
1222  
1223   Standard_Real f,l;
1224
1225   if (orient ==  TopAbs_FORWARD) {
1226     BRep_Tool::Range(E,f,l);
1227     return (rev) ? l : f;
1228   }
1229  
1230   else if (orient ==  TopAbs_REVERSED) {
1231     BRep_Tool::Range(E,f,l);
1232     return (rev) ? f : l;
1233    }
1234
1235   else {
1236     TopLoc_Location L;
1237     const Handle(Geom_Curve)& C = BRep_Tool::Curve(E,L,f,l);
1238     L = L.Predivided(V.Location());
1239     if (!C.IsNull() || Degenerated(E)) {
1240       BRep_ListIteratorOfListOfPointRepresentation itpr
1241         ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
1242
1243       while (itpr.More()) {
1244         const Handle(BRep_PointRepresentation)& pr = itpr.Value();
1245         if (pr->IsPointOnCurve(C,L)) {
1246           Standard_Real p = pr->Parameter();
1247           Standard_Real res = p;// SVV 4 nov 99 - to avoid warnings on Linux
1248           if (!C.IsNull()) {
1249             // Closed curves RLE 16 june 94
1250             if (Precision::IsNegativeInfinite(f)) return pr->Parameter();//p;
1251             if (Precision::IsPositiveInfinite(l)) return pr->Parameter();//p;
1252             gp_Pnt Pf = C->Value(f).Transformed(L.Transformation());
1253             gp_Pnt Pl = C->Value(l).Transformed(L.Transformation());
1254             Standard_Real tol = BRep_Tool::Tolerance(V);
1255             if (Pf.Distance(Pl) < tol) {
1256               if (Pf.Distance(BRep_Tool::Pnt(V)) < tol) {
1257                 if (V.Orientation() == TopAbs_FORWARD) res = f;//p = f;
1258                 else                                   res = l;//p = l;
1259               }
1260             }
1261           }
1262           return res;//p;
1263         }
1264         itpr.Next();
1265       }
1266     }
1267     else {
1268       // no 3d curve !!
1269       // let us try with the first pcurve
1270       Handle(Geom2d_Curve) PC;
1271       Handle(Geom_Surface) S;
1272       BRep_Tool::CurveOnSurface(E,PC,S,L,f,l);
1273       L = L.Predivided(V.Location()); 
1274       BRep_ListIteratorOfListOfPointRepresentation itpr
1275         ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
1276
1277       while (itpr.More()) {
1278         const Handle(BRep_PointRepresentation)& pr = itpr.Value();
1279         if (pr->IsPointOnCurveOnSurface(PC,S,L)) {
1280           Standard_Real p = pr->Parameter();
1281           // Closed curves RLE 16 june 94
1282           if (PC->IsClosed()) {
1283             if ((p == PC->FirstParameter()) || 
1284                 (p == PC->LastParameter())) {
1285               if (V.Orientation() == TopAbs_FORWARD) p = PC->FirstParameter();
1286               else                                   p = PC->LastParameter();
1287             }
1288           }
1289           return p;
1290         }
1291         itpr.Next();
1292       }
1293     }
1294   }
1295   
1296   Standard_NoSuchObject::Raise("BRep_Tool:: no parameter on edge");
1297   return 0;
1298 }
1299
1300 //=======================================================================
1301 //function : Parameter
1302 //purpose  : Returns the  parameters  of   the  vertex   on the
1303 //           pcurve of the edge on the face.
1304 //=======================================================================
1305
1306 Standard_Real BRep_Tool::Parameter(const TopoDS_Vertex& V, 
1307                                    const TopoDS_Edge& E, 
1308                                    const TopoDS_Face& F)
1309 {
1310   TopLoc_Location L;
1311   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,L);
1312   return BRep_Tool::Parameter(V,E,S,L);
1313 }
1314
1315 //=======================================================================
1316 //function : Parameter
1317 //purpose  : Returns the  parameters  of   the  vertex   on the
1318 //           pcurve of the edge on the surface.
1319 //=======================================================================
1320
1321 Standard_Real BRep_Tool::Parameter(const TopoDS_Vertex& V, 
1322                                    const TopoDS_Edge& E, 
1323                                    const Handle(Geom_Surface)& S,
1324                                    const TopLoc_Location& L)
1325 {
1326   // Search the vertex in the edge
1327
1328   Standard_Boolean rev = Standard_False;
1329   TopoDS_Shape VF;
1330   TopoDS_Iterator itv(E.Oriented(TopAbs_FORWARD));
1331
1332   while (itv.More()) {
1333     if (V.IsSame(itv.Value())) {
1334       if (VF.IsNull()) VF = itv.Value();
1335       else {
1336         rev = E.Orientation() == TopAbs_REVERSED;
1337         if (itv.Value().Orientation() == V.Orientation()) 
1338         VF = itv.Value();
1339       }
1340     }
1341     itv.Next();
1342   }
1343
1344  TopAbs_Orientation orient = TopAbs_INTERNAL;
1345   if (!VF.IsNull()) orient = VF.Orientation();
1346  
1347  Standard_Real f,l;
1348
1349  if (orient ==  TopAbs_FORWARD) {
1350    BRep_Tool::Range(E,S,L,f,l);
1351    return (rev) ? l : f;
1352  }
1353  
1354  else if (orient ==  TopAbs_REVERSED) {
1355    BRep_Tool::Range(E,S,L,f,l);
1356    return (rev) ? f : l;
1357  }
1358
1359  else {
1360    Handle(Geom2d_Curve) PC = BRep_Tool::CurveOnSurface(E,S,L,f,l);
1361    BRep_ListIteratorOfListOfPointRepresentation itpr
1362      ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
1363
1364    while (itpr.More()) {
1365      if (itpr.Value()->IsPointOnCurveOnSurface(PC,S,L))
1366        return itpr.Value()->Parameter();
1367      itpr.Next();
1368    }
1369  }
1370
1371  //----------------------------------------------------------
1372    
1373   TopLoc_Location L1;
1374   const Handle(Geom_Curve)& C = BRep_Tool::Curve(E,L1,f,l);
1375   L1 = L1.Predivided(V.Location());
1376   if (!C.IsNull() || Degenerated(E)) {
1377     BRep_ListIteratorOfListOfPointRepresentation itpr
1378       ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
1379
1380     while (itpr.More()) {
1381       const Handle(BRep_PointRepresentation)& pr = itpr.Value();
1382       if (pr->IsPointOnCurve(C,L1)) {
1383         Standard_Real p = pr->Parameter();
1384         Standard_Real res = p;
1385         if (!C.IsNull()) {
1386           // Closed curves RLE 16 june 94
1387           if (Precision::IsNegativeInfinite(f)) return res;
1388           if (Precision::IsPositiveInfinite(l)) return res;
1389           gp_Pnt Pf = C->Value(f).Transformed(L1.Transformation());
1390           gp_Pnt Pl = C->Value(l).Transformed(L1.Transformation());
1391           Standard_Real tol = BRep_Tool::Tolerance(V);
1392           if (Pf.Distance(Pl) < tol) {
1393             if (Pf.Distance(BRep_Tool::Pnt(V)) < tol) {
1394               if (V.Orientation() == TopAbs_FORWARD) res = f;
1395               else                                   res = l;
1396             }
1397           }
1398         }
1399         return res;
1400       }
1401       itpr.Next();
1402     }
1403   }
1404   
1405 //----------------------------------------------------------   
1406  
1407   Standard_NoSuchObject::Raise("BRep_Tool:: no parameter on edge");
1408   return 0;
1409 }
1410
1411 //=======================================================================
1412 //function : Parameters
1413 //purpose  : Returns the parameters of the vertex on the face.
1414 //=======================================================================
1415
1416 gp_Pnt2d  BRep_Tool::Parameters(const TopoDS_Vertex& V, 
1417                                 const TopoDS_Face& F)
1418 {
1419   TopLoc_Location L;
1420   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,L);
1421   L = L.Predivided(V.Location());
1422   BRep_ListIteratorOfListOfPointRepresentation itpr
1423     ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
1424   // It is checked if there is PointRepresentation (case non Manifold)
1425
1426   while (itpr.More()) {
1427     if (itpr.Value()->IsPointOnSurface(S,L)) {
1428       return gp_Pnt2d(itpr.Value()->Parameter(),
1429                       itpr.Value()->Parameter2());
1430     }
1431     itpr.Next();
1432   }
1433
1434  TopoDS_Vertex Vf,Vl;
1435  TopoDS_Edge E;
1436  // Otherwise the edges are searched (PMN 4/06/97) It is not possible to succeed 999/1000!
1437  // even if often there is a way to make more economically than above...
1438  TopExp_Explorer exp;
1439  for (exp.Init(F, TopAbs_EDGE); exp.More(); exp.Next()) { 
1440     E = TopoDS::Edge(exp.Current());  
1441     TopExp::Vertices(E, Vf, Vl);
1442     if ((V.IsSame(Vf)) || (V.IsSame(Vl))) {
1443       gp_Pnt2d Pf, Pl;
1444       UVPoints(E, F, Pf, Pl);
1445       if (V.IsSame(Vf)) return Pf;
1446       else              return Pl;//Ambiguity (natural) for degenerated edges.
1447     }
1448   }
1449   Standard_NoSuchObject::Raise("BRep_Tool:: no parameters on surface");
1450   return gp_Pnt2d(0,0);
1451 }
1452 //=======================================================================
1453 //function : IsClosed
1454 //purpose  : 
1455 //=======================================================================
1456 Standard_Boolean BRep_Tool::IsClosed (const TopoDS_Shape& theShape)
1457 {
1458   if (theShape.ShapeType() == TopAbs_SHELL)
1459   {
1460     NCollection_Map<TopoDS_Shape, TopTools_ShapeMapHasher> aMap (101, new NCollection_IncAllocator);
1461     TopExp_Explorer exp (theShape.Oriented(TopAbs_FORWARD), TopAbs_EDGE);
1462     Standard_Boolean hasBound = Standard_False;
1463     for (; exp.More(); exp.Next())
1464     {
1465       const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1466       if (BRep_Tool::Degenerated(E) || E.Orientation() == TopAbs_INTERNAL || E.Orientation() == TopAbs_EXTERNAL)
1467         continue;
1468       hasBound = Standard_True;
1469       if (!aMap.Add(E))
1470         aMap.Remove(E);
1471     }
1472     return hasBound && aMap.IsEmpty();
1473   }
1474   else if (theShape.ShapeType() == TopAbs_WIRE)
1475   {
1476     NCollection_Map<TopoDS_Shape, TopTools_ShapeMapHasher> aMap (101, new NCollection_IncAllocator);
1477     TopExp_Explorer exp (theShape.Oriented(TopAbs_FORWARD), TopAbs_VERTEX);
1478     Standard_Boolean hasBound = Standard_False;
1479     for (; exp.More(); exp.Next())
1480     {
1481       const TopoDS_Shape& V = exp.Current();
1482       if (V.Orientation() == TopAbs_INTERNAL || V.Orientation() == TopAbs_EXTERNAL)
1483         continue;
1484       hasBound = Standard_True;
1485       if (!aMap.Add(V))
1486         aMap.Remove(V);
1487     }
1488     return hasBound && aMap.IsEmpty();
1489   }
1490   else if (theShape.ShapeType() == TopAbs_EDGE)
1491   {
1492     TopoDS_Vertex aVFirst, aVLast;
1493     TopExp::Vertices(TopoDS::Edge(theShape), aVFirst, aVLast);
1494     return !aVFirst.IsNull() && aVFirst.IsSame(aVLast);
1495   }
1496   return theShape.Closed();
1497 }
1498
1499 //modified by NIZNHY-PKV Fri Oct 17 14:09:58 2008 f 
1500 //=======================================================================
1501 //function : IsPlane
1502 //purpose  : 
1503 //=======================================================================
1504 Standard_Boolean IsPlane(const Handle(Geom_Surface)& aS)
1505 {
1506   Standard_Boolean bRet;
1507   Handle(Geom_Plane) aGP;
1508   Handle(Geom_RectangularTrimmedSurface) aGRTS;
1509   Handle(Geom_OffsetSurface) aGOFS;
1510   //
1511   aGRTS=Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
1512   aGOFS=Handle(Geom_OffsetSurface)::DownCast(aS);
1513   //
1514   if(!aGOFS.IsNull()) {
1515     aGP=Handle(Geom_Plane)::DownCast(aGOFS->BasisSurface());
1516   }
1517   else if(!aGRTS.IsNull()) {
1518     aGP=Handle(Geom_Plane)::DownCast(aGRTS->BasisSurface());
1519   }
1520   else {
1521     aGP=Handle(Geom_Plane)::DownCast(aS);
1522   }
1523   //
1524   bRet=!aGP.IsNull();
1525   //
1526   return bRet;
1527 }
1528