0027067: Avoid use of virtual methods for implementation of destructors in legacy...
[occt.git] / src / BRepLib / BRepLib.cxx
1 // Created on: 1993-12-15
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 //pmn 26/09/97 Add parameters of approximation in BuildCurve3d
18 //  Modified by skv - Thu Jun  3 12:39:19 2004 OCC5898
19
20 #include <Adaptor3d_CurveOnSurface.hxx>
21 #include <AdvApprox_ApproxAFunction.hxx>
22 #include <AppParCurves_MultiBSpCurve.hxx>
23 #include <AppParCurves_MultiCurve.hxx>
24 #include <Approx_CurvilinearParameter.hxx>
25 #include <Approx_SameParameter.hxx>
26 #include <Bnd_Box.hxx>
27 #include <BRep_Builder.hxx>
28 #include <BRep_CurveRepresentation.hxx>
29 #include <BRep_GCurve.hxx>
30 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
31 #include <BRep_ListOfCurveRepresentation.hxx>
32 #include <BRep_TEdge.hxx>
33 #include <BRep_TFace.hxx>
34 #include <BRep_Tool.hxx>
35 #include <BRep_TVertex.hxx>
36 #include <BRepAdaptor_HCurve.hxx>
37 #include <BRepAdaptor_HCurve2d.hxx>
38 #include <BRepAdaptor_HSurface.hxx>
39 #include <BRepAdaptor_Surface.hxx>
40 #include <BRepBndLib.hxx>
41 #include <BRepClass3d_SolidClassifier.hxx>
42 #include <BRepLib.hxx>
43 #include <BSplCLib.hxx>
44 #include <ElSLib.hxx>
45 #include <Extrema_LocateExtPC.hxx>
46 #include <GCPnts_QuasiUniformDeflection.hxx>
47 #include <Geom2d_BSplineCurve.hxx>
48 #include <Geom2d_Curve.hxx>
49 #include <Geom2d_TrimmedCurve.hxx>
50 #include <Geom2dAdaptor.hxx>
51 #include <Geom2dAdaptor_Curve.hxx>
52 #include <Geom2dAdaptor_HCurve.hxx>
53 #include <Geom2dConvert.hxx>
54 #include <Geom_BSplineCurve.hxx>
55 #include <Geom_BSplineSurface.hxx>
56 #include <Geom_Curve.hxx>
57 #include <Geom_Plane.hxx>
58 #include <Geom_RectangularTrimmedSurface.hxx>
59 #include <Geom_Surface.hxx>
60 #include <Geom_TrimmedCurve.hxx>
61 #include <GeomAdaptor_Curve.hxx>
62 #include <GeomAdaptor_HCurve.hxx>
63 #include <GeomAdaptor_HSurface.hxx>
64 #include <GeomAdaptor_Surface.hxx>
65 #include <GeomLib.hxx>
66 #include <GeomLProp_SLProps.hxx>
67 #include <gp.hxx>
68 #include <gp_Ax2.hxx>
69 #include <gp_Pln.hxx>
70 #include <Poly_PolygonOnTriangulation.hxx>
71 #include <Poly_Triangulation.hxx>
72 #include <Precision.hxx>
73 #include <ProjLib_ProjectedCurve.hxx>
74 #include <Standard_Real.hxx>
75 #include <TColgp_Array1OfPnt.hxx>
76 #include <TColgp_Array1OfPnt2d.hxx>
77 #include <TColStd_Array1OfReal.hxx>
78 #include <TColStd_MapOfTransient.hxx>
79 #include <TopExp.hxx>
80 #include <TopExp_Explorer.hxx>
81 #include <TopoDS.hxx>
82 #include <TopoDS_Edge.hxx>
83 #include <TopoDS_Face.hxx>
84 #include <TopoDS_Shape.hxx>
85 #include <TopoDS_Solid.hxx>
86 #include <TopoDS_Vertex.hxx>
87 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
88 #include <TopTools_ListIteratorOfListOfShape.hxx>
89 #include <TopTools_MapOfShape.hxx>
90 #include <TShort_HArray1OfShortReal.hxx>
91
92 // TODO - not thread-safe static variables
93 static Standard_Real thePrecision = Precision::Confusion();     
94 static Handle(Geom_Plane) thePlane;
95
96 //=======================================================================
97 //function : Precision
98 //purpose  : 
99 //=======================================================================
100
101 void BRepLib::Precision(const Standard_Real P)
102 {
103   thePrecision = P;
104 }
105
106 //=======================================================================
107 //function : Precision
108 //purpose  : 
109 //=======================================================================
110
111 Standard_Real  BRepLib::Precision()
112 {
113   return thePrecision;
114 }
115
116 //=======================================================================
117 //function : Plane
118 //purpose  : 
119 //=======================================================================
120
121 void  BRepLib::Plane(const Handle(Geom_Plane)& P)
122 {
123   thePlane = P;
124 }
125
126
127 //=======================================================================
128 //function : Plane
129 //purpose  : 
130 //=======================================================================
131
132 const Handle(Geom_Plane)&  BRepLib::Plane()
133 {
134   if (thePlane.IsNull()) thePlane = new Geom_Plane(gp::XOY());
135   return thePlane;
136 }
137 //=======================================================================
138 //function : CheckSameRange
139 //purpose  : 
140 //=======================================================================
141
142 Standard_Boolean  BRepLib::CheckSameRange(const TopoDS_Edge& AnEdge,
143   const Standard_Real Tolerance) 
144 {
145   Standard_Boolean  IsSameRange = Standard_True,
146     first_time_in = Standard_True ;
147
148   BRep_ListIteratorOfListOfCurveRepresentation an_Iterator
149     ((*((Handle(BRep_TEdge)*)&AnEdge.TShape()))->ChangeCurves());
150
151   Standard_Real first, last;
152   Standard_Real current_first =0., current_last =0. ;
153   Handle(BRep_GCurve) geometric_representation_ptr ;
154
155   while (IsSameRange && an_Iterator.More()) {
156     geometric_representation_ptr =
157       Handle(BRep_GCurve)::DownCast(an_Iterator.Value());
158     if (!geometric_representation_ptr.IsNull()) {
159
160       first = geometric_representation_ptr->First();
161       last =  geometric_representation_ptr->Last();
162       if (first_time_in ) {
163         current_first = first ;
164         current_last = last   ;
165         first_time_in = Standard_False ;
166       }
167       else {
168         IsSameRange = (Abs(current_first - first) <= Tolerance) 
169           && (Abs(current_last -last) <= Tolerance ) ;
170       }
171     }
172     an_Iterator.Next() ;
173   }
174   return IsSameRange ;
175 }
176
177 //=======================================================================
178 //function : SameRange
179 //purpose  : 
180 //=======================================================================
181
182 void BRepLib::SameRange(const TopoDS_Edge& AnEdge,
183   const Standard_Real Tolerance) 
184 {
185   BRep_ListIteratorOfListOfCurveRepresentation an_Iterator
186     ((*((Handle(BRep_TEdge)*)&AnEdge.TShape()))->ChangeCurves());
187
188   Handle(Geom2d_Curve) Curve2dPtr, Curve2dPtr2, NewCurve2dPtr, NewCurve2dPtr2;
189   TopLoc_Location LocalLoc ;
190
191   Standard_Boolean first_time_in = Standard_True,
192     has_curve,
193     has_closed_curve ;
194   Handle(BRep_GCurve) geometric_representation_ptr ;
195   Standard_Real first,
196     current_first,
197     last,
198     current_last ;
199
200   const Handle(Geom_Curve) C = BRep_Tool::Curve(AnEdge,
201     LocalLoc,
202     current_first,
203     current_last);
204   if (!C.IsNull()) {
205     first_time_in = Standard_False ;
206   }
207
208   while (an_Iterator.More()) {
209     geometric_representation_ptr =
210       Handle(BRep_GCurve)::DownCast(an_Iterator.Value());
211     if (! geometric_representation_ptr.IsNull()) {
212       has_closed_curve =
213         has_curve = Standard_False ;
214       first = geometric_representation_ptr->First();
215       last =  geometric_representation_ptr->Last();
216       if (geometric_representation_ptr->IsCurveOnSurface()) {
217         Curve2dPtr = geometric_representation_ptr->PCurve() ; 
218         has_curve = Standard_True ;
219       }
220       if (geometric_representation_ptr->IsCurveOnClosedSurface()) {
221         Curve2dPtr2 = geometric_representation_ptr->PCurve2() ;
222         has_closed_curve = Standard_True ;
223       }
224       if (has_curve || has_closed_curve) {
225         if (first_time_in) {
226           current_first = first ;
227           current_last = last ;
228           first_time_in = Standard_False ;
229         }
230
231         if (Abs(first - current_first) > Precision::Confusion() ||
232           Abs(last - current_last) > Precision::Confusion() )
233         {
234           if (has_curve)
235           {
236             GeomLib::SameRange(Tolerance,
237               Curve2dPtr,
238               geometric_representation_ptr->First(),
239               geometric_representation_ptr->Last(),
240               current_first,
241               current_last,
242               NewCurve2dPtr);
243             geometric_representation_ptr->PCurve(NewCurve2dPtr) ;
244           }
245           if (has_closed_curve)
246           {
247             GeomLib::SameRange(Tolerance,
248               Curve2dPtr2,
249               geometric_representation_ptr->First(),
250               geometric_representation_ptr->Last(),
251               current_first,
252               current_last,
253               NewCurve2dPtr2);
254             geometric_representation_ptr->PCurve2(NewCurve2dPtr2) ;
255           }
256         }
257       }
258     }
259     an_Iterator.Next() ;
260   }
261   BRep_Builder B;
262   B.Range(TopoDS::Edge(AnEdge),
263     current_first,
264     current_last) ;
265
266   B.SameRange(AnEdge,
267     Standard_True) ;
268 }
269
270 //=======================================================================
271 //function : EvaluateMaxSegment
272 //purpose  : return MaxSegment to pass in approximation, if MaxSegment==0 provided
273 //=======================================================================
274
275 static Standard_Integer evaluateMaxSegment(const Standard_Integer aMaxSegment,
276   const Adaptor3d_CurveOnSurface& aCurveOnSurface)
277 {
278   if (aMaxSegment != 0) return aMaxSegment;
279
280   Handle(Adaptor3d_HSurface) aSurf   = aCurveOnSurface.GetSurface();
281   Handle(Adaptor2d_HCurve2d) aCurv2d = aCurveOnSurface.GetCurve();
282
283   Standard_Real aNbSKnots = 0, aNbC2dKnots = 0;
284
285   if (aSurf->GetType() == GeomAbs_BSplineSurface) {
286     Handle(Geom_BSplineSurface) aBSpline = aSurf->BSpline();
287     aNbSKnots = Max(aBSpline->NbUKnots(), aBSpline->NbVKnots());
288   }
289   if (aCurv2d->GetType() == GeomAbs_BSplineCurve) {
290     aNbC2dKnots = aCurv2d->NbKnots();
291   }
292   Standard_Integer aReturn = (Standard_Integer) (  30 + Max(aNbSKnots, aNbC2dKnots) ) ;
293   return aReturn;
294 }
295
296 //=======================================================================
297 //function : BuildCurve3d
298 //purpose  : 
299 //=======================================================================
300
301 Standard_Boolean  BRepLib::BuildCurve3d(const TopoDS_Edge& AnEdge,
302   const Standard_Real Tolerance,
303   const GeomAbs_Shape Continuity,
304   const Standard_Integer MaxDegree,
305   const Standard_Integer MaxSegment)
306 {
307   Standard_Integer //ErrorCode,
308     //                   ReturnCode = 0,
309     ii,
310     //                   num_knots,
311     jj;
312
313   TopLoc_Location LocalLoc,L[2],LC;
314   Standard_Real f,l,fc,lc, first[2], last[2],
315     tolerance,
316     max_deviation,
317     average_deviation ;
318   Handle(Geom2d_Curve) Curve2dPtr, Curve2dArray[2]  ;
319   Handle(Geom_Surface) SurfacePtr, SurfaceArray[2]  ;
320
321   Standard_Integer not_done ;
322   // if the edge has a 3d curve returns true
323
324
325   const Handle(Geom_Curve) C = BRep_Tool::Curve(AnEdge,LocalLoc,f,l);
326   if (!C.IsNull()) 
327     return Standard_True;
328   //
329   // this should not exists but UpdateEdge makes funny things 
330   // if the edge is not same range 
331   //
332   if (! CheckSameRange(AnEdge,
333     Precision::Confusion())) {
334       SameRange(AnEdge,
335         Tolerance) ;
336   }
337
338
339
340   // search a curve on a plane
341   Handle(Geom_Surface) S;
342   Handle(Geom2d_Curve) PC;
343   Standard_Integer i = 0;
344   Handle(Geom_Plane) P;
345   not_done = 1 ;
346
347   while (not_done) {
348     i++;
349     BRep_Tool::CurveOnSurface(AnEdge,PC,S,LocalLoc,f,l,i);
350     Handle(Geom_RectangularTrimmedSurface) RT = 
351       Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
352     if ( RT.IsNull()) {
353       P = Handle(Geom_Plane)::DownCast(S);
354     }
355     else {
356       P = Handle(Geom_Plane)::DownCast(RT->BasisSurface());
357     }
358     not_done = ! (S.IsNull() || !P.IsNull()) ;
359   }
360   if (! P.IsNull()) {
361     // compute the 3d curve
362     gp_Ax2 axes = P->Position().Ax2();
363     Handle(Geom_Curve) C3d = GeomLib::To3d(axes,PC);
364     if (C3d.IsNull())
365       return Standard_False;
366     // update the edge
367     Standard_Real First, Last;
368
369     BRep_Builder B;
370     B.UpdateEdge(AnEdge,C3d,LocalLoc,0.0e0);
371     BRep_Tool::Range(AnEdge, S, LC, First, Last);
372     B.Range(AnEdge, First, Last); //Do not forget 3D range.(PRO6412)
373   }
374   else {
375     //
376     // compute the 3d curve using existing surface
377     //
378     fc = f ;
379     lc = l ;
380     if (!BRep_Tool::Degenerated(AnEdge)) {
381       jj = 0 ;
382       for (ii = 0 ; ii < 3 ; ii++ ) {
383         BRep_Tool::CurveOnSurface(TopoDS::Edge(AnEdge),
384           Curve2dPtr,
385           SurfacePtr,
386           LocalLoc,
387           fc,
388           lc,
389           ii) ;
390
391         if (!Curve2dPtr.IsNull() && jj < 2){
392           Curve2dArray[jj] = Curve2dPtr ;
393           SurfaceArray[jj] = SurfacePtr ;
394           L[jj] = LocalLoc ;
395           first[jj] = fc ;
396           last[jj] = lc ;
397           jj += 1 ;
398         }
399       }
400       f = first[0] ;
401       l = last[0] ;
402       Curve2dPtr = Curve2dArray[0] ;
403       SurfacePtr = SurfaceArray[0] ;
404
405       Geom2dAdaptor_Curve     AnAdaptor3dCurve2d (Curve2dPtr, f, l) ;
406       GeomAdaptor_Surface     AnAdaptor3dSurface (SurfacePtr) ;
407       Handle(Geom2dAdaptor_HCurve) AnAdaptor3dCurve2dPtr =
408         new Geom2dAdaptor_HCurve(AnAdaptor3dCurve2d) ;
409       Handle(GeomAdaptor_HSurface) AnAdaptor3dSurfacePtr =
410         new GeomAdaptor_HSurface (AnAdaptor3dSurface) ;
411       Adaptor3d_CurveOnSurface  CurveOnSurface( AnAdaptor3dCurve2dPtr,
412         AnAdaptor3dSurfacePtr) ;
413
414       Handle(Geom_Curve) NewCurvePtr ;
415
416       GeomLib::BuildCurve3d(Tolerance,
417         CurveOnSurface,
418         f,
419         l,
420         NewCurvePtr,
421         max_deviation,
422         average_deviation,
423         Continuity,
424         MaxDegree,
425         evaluateMaxSegment(MaxSegment,CurveOnSurface)) ;
426       BRep_Builder B;   
427       tolerance = BRep_Tool::Tolerance(AnEdge) ;
428       //Patch
429       //max_deviation = Max(tolerance, max_deviation) ;
430       max_deviation = Max( tolerance, Tolerance );
431       if (NewCurvePtr.IsNull())
432         return Standard_False;
433       B.UpdateEdge(TopoDS::Edge(AnEdge),
434         NewCurvePtr,
435         L[0],
436         max_deviation) ;
437       if (jj == 1 ) {
438         //
439         // if there is only one curve on surface attached to the edge
440         // than it can be qualified sameparameter
441         //
442         B.SameParameter(TopoDS::Edge(AnEdge),
443           Standard_True) ;
444       }
445     }
446     else {
447       return Standard_False ;
448     }
449
450   }         
451   return Standard_True;
452 }
453 //=======================================================================
454 //function : BuildCurves3d
455 //purpose  : 
456 //=======================================================================
457
458 Standard_Boolean  BRepLib::BuildCurves3d(const TopoDS_Shape& S) 
459
460 {
461   return BRepLib::BuildCurves3d(S,
462     1.0e-5) ;
463 }
464
465 //=======================================================================
466 //function : BuildCurves3d
467 //purpose  : 
468 //=======================================================================
469
470 Standard_Boolean  BRepLib::BuildCurves3d(const TopoDS_Shape& S,
471   const Standard_Real Tolerance,
472   const GeomAbs_Shape Continuity,
473   const Standard_Integer MaxDegree,
474   const Standard_Integer MaxSegment)
475 {
476   Standard_Boolean boolean_value,
477     ok = Standard_True;
478   TopTools_MapOfShape a_counter ;
479   TopExp_Explorer ex(S,TopAbs_EDGE);
480
481   while (ex.More()) {
482     if (a_counter.Add(ex.Current())) {
483       boolean_value = 
484         BuildCurve3d(TopoDS::Edge(ex.Current()),
485         Tolerance, Continuity,
486         MaxDegree, MaxSegment);
487       ok = ok && boolean_value ;
488     }
489     ex.Next();
490   }
491   return ok;
492 }
493 //=======================================================================
494 //function : UpdateEdgeTolerance
495 //purpose  : 
496 //=======================================================================
497
498 Standard_Boolean  BRepLib::UpdateEdgeTol(const TopoDS_Edge& AnEdge,
499   const Standard_Real MinToleranceRequested,
500   const Standard_Real MaxToleranceToCheck)
501 {
502
503   Standard_Integer curve_on_surface_index,
504     curve_index,
505     not_done,
506     has_closed_curve,
507     has_curve,
508     jj,
509     ii,
510     geom_reference_curve_flag = 0,
511     max_sampling_points = 90,
512     min_sampling_points = 30 ;
513
514   Standard_Real factor = 100.0e0,
515     //     sampling_array[2],
516     safe_factor = 1.4e0,
517     current_last,
518     current_first,
519     max_distance,
520     coded_edge_tolerance,
521     edge_tolerance = 0.0e0 ;
522   Handle(TColStd_HArray1OfReal) parameters_ptr ;
523   Handle(BRep_GCurve) geometric_representation_ptr ;
524
525   if (BRep_Tool::Degenerated(AnEdge)) return Standard_False ;
526   coded_edge_tolerance = BRep_Tool::Tolerance(AnEdge) ;
527   if (coded_edge_tolerance > MaxToleranceToCheck) return Standard_False ;
528
529   const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&AnEdge.TShape());
530   BRep_ListOfCurveRepresentation& list_curve_rep = TE->ChangeCurves() ;
531   BRep_ListIteratorOfListOfCurveRepresentation an_iterator(list_curve_rep),
532     second_iterator(list_curve_rep) ;
533   Handle(Geom2d_Curve) curve2d_ptr, new_curve2d_ptr;
534   Handle(Geom_Surface) surface_ptr ;
535   TopLoc_Location local_location ;
536   GCPnts_QuasiUniformDeflection  a_sampler ;
537   GeomAdaptor_Curve  geom_reference_curve ;
538   Adaptor3d_CurveOnSurface  curve_on_surface_reference ; 
539   Handle(Geom_Curve) C = BRep_Tool::Curve(AnEdge,
540     local_location,
541     current_first,
542     current_last);
543   curve_on_surface_index = -1 ;
544   if (!C.IsNull()) {
545     if (! local_location.IsIdentity()) {
546       C = Handle(Geom_Curve)::
547         DownCast(C-> Transformed(local_location.Transformation()) ) ;
548     }
549     geom_reference_curve.Load(C) ;
550     geom_reference_curve_flag = 1 ;
551     a_sampler.Initialize(geom_reference_curve,
552       MinToleranceRequested * factor,
553       current_first,
554       current_last) ;
555   }
556   else {
557     not_done = 1 ;
558     curve_on_surface_index = 0 ;  
559
560     while (not_done && an_iterator.More()) {
561       geometric_representation_ptr =
562         Handle(BRep_GCurve)::DownCast(second_iterator.Value());
563       if (!geometric_representation_ptr.IsNull() 
564         && geometric_representation_ptr->IsCurveOnSurface()) {
565           curve2d_ptr = geometric_representation_ptr->PCurve() ;
566           local_location = geometric_representation_ptr->Location() ;
567           current_first = geometric_representation_ptr->First();
568           //first = geometric_representation_ptr->First();
569           current_last =  geometric_representation_ptr->Last();
570           // must be inverted 
571           //
572           if (! local_location.IsIdentity() ) {
573             surface_ptr = Handle(Geom_Surface)::
574               DownCast( geometric_representation_ptr->Surface()->
575               Transformed(local_location.Transformation()) ) ;
576           }
577           else {
578             surface_ptr = 
579               geometric_representation_ptr->Surface() ;
580           }
581           not_done = 0 ;
582       }
583       curve_on_surface_index += 1 ;
584     }
585     Geom2dAdaptor_Curve     AnAdaptor3dCurve2d (curve2d_ptr) ;
586     GeomAdaptor_Surface     AnAdaptor3dSurface (surface_ptr) ;
587     Handle(Geom2dAdaptor_HCurve) AnAdaptor3dCurve2dPtr =
588       new Geom2dAdaptor_HCurve(AnAdaptor3dCurve2d) ;
589     Handle(GeomAdaptor_HSurface) AnAdaptor3dSurfacePtr =
590       new GeomAdaptor_HSurface (AnAdaptor3dSurface) ;
591     curve_on_surface_reference.Load (AnAdaptor3dCurve2dPtr, AnAdaptor3dSurfacePtr);
592     a_sampler.Initialize(curve_on_surface_reference,
593       MinToleranceRequested * factor,
594       current_first,
595       current_last) ;
596   }
597   TColStd_Array1OfReal   sampling_parameters(1,a_sampler.NbPoints()) ;
598   for (ii = 1 ; ii <= a_sampler.NbPoints() ; ii++) {
599     sampling_parameters(ii) = a_sampler.Parameter(ii) ;
600   }
601   if (a_sampler.NbPoints() < min_sampling_points) {
602     GeomLib::DensifyArray1OfReal(min_sampling_points,
603       sampling_parameters,
604       parameters_ptr) ;
605   }
606   else if (a_sampler.NbPoints() > max_sampling_points) {
607     GeomLib::RemovePointsFromArray(max_sampling_points,
608       sampling_parameters,
609       parameters_ptr) ; 
610   }
611   else {
612     jj = 1 ;
613     parameters_ptr =
614       new TColStd_HArray1OfReal(1,sampling_parameters.Length()) ;
615     for (ii = sampling_parameters.Lower() ; ii <= sampling_parameters.Upper() ; ii++) {
616       parameters_ptr->ChangeArray1()(jj) =
617         sampling_parameters(ii) ;
618       jj +=1 ;
619     }
620   }
621
622   curve_index = 0 ;
623
624   while (second_iterator.More()) {
625     geometric_representation_ptr =
626       Handle(BRep_GCurve)::DownCast(second_iterator.Value());
627     if (! geometric_representation_ptr.IsNull() && 
628       curve_index != curve_on_surface_index) {
629         has_closed_curve =
630           has_curve = Standard_False ;
631         //      first = geometric_representation_ptr->First();
632         //      last =  geometric_representation_ptr->Last();
633         local_location = geometric_representation_ptr->Location() ;
634         if (geometric_representation_ptr->IsCurveOnSurface()) {
635           curve2d_ptr = geometric_representation_ptr->PCurve() ; 
636           has_curve = Standard_True ;
637         }
638         if (geometric_representation_ptr->IsCurveOnClosedSurface()) {
639           curve2d_ptr = geometric_representation_ptr->PCurve2() ;
640           has_closed_curve = Standard_True ;
641         }
642
643         if (has_curve ||
644           has_closed_curve) {
645             if (! local_location.IsIdentity() ) {
646               surface_ptr = Handle(Geom_Surface)::
647                 DownCast( geometric_representation_ptr->Surface()->
648                 Transformed(local_location.Transformation()) ) ;
649             }
650             else {
651               surface_ptr = 
652                 geometric_representation_ptr->Surface() ;
653             }
654             Geom2dAdaptor_Curve     an_adaptor_curve2d (curve2d_ptr) ;
655             GeomAdaptor_Surface     an_adaptor_surface(surface_ptr) ;
656             Handle(Geom2dAdaptor_HCurve) an_adaptor_curve2d_ptr =
657               new Geom2dAdaptor_HCurve(an_adaptor_curve2d) ;
658             Handle(GeomAdaptor_HSurface) an_adaptor_surface_ptr =
659               new GeomAdaptor_HSurface (an_adaptor_surface) ;
660             Adaptor3d_CurveOnSurface a_curve_on_surface(an_adaptor_curve2d_ptr,
661               an_adaptor_surface_ptr) ;
662
663             if (BRep_Tool::SameParameter(AnEdge)) {
664
665               GeomLib::EvalMaxParametricDistance(a_curve_on_surface,
666                 geom_reference_curve,
667                 MinToleranceRequested,
668                 parameters_ptr->Array1(),
669                 max_distance) ;
670             }
671             else if (geom_reference_curve_flag) {
672               GeomLib::EvalMaxDistanceAlongParameter(a_curve_on_surface,
673                 geom_reference_curve,
674                 MinToleranceRequested,
675                 parameters_ptr->Array1(),
676                 max_distance) ;
677             }
678             else {
679
680               GeomLib::EvalMaxDistanceAlongParameter(a_curve_on_surface,
681                 curve_on_surface_reference,
682                 MinToleranceRequested,
683                 parameters_ptr->Array1(),
684                 max_distance) ;
685             }
686             max_distance *= safe_factor ;
687             edge_tolerance = Max(max_distance, edge_tolerance) ;
688         }
689
690
691     }
692     curve_index += 1 ;
693     second_iterator.Next() ; 
694   }
695
696   TE->Tolerance(edge_tolerance);
697   return Standard_True ;
698
699 }
700 //=======================================================================
701 //function : UpdateEdgeTolerance
702 //purpose  : 
703 //=======================================================================
704
705 Standard_Boolean BRepLib::UpdateEdgeTolerance(const TopoDS_Shape& S,
706   const Standard_Real MinToleranceRequested,
707   const Standard_Real MaxToleranceToCheck) 
708 {
709   TopExp_Explorer ex(S,TopAbs_EDGE);
710   TopTools_MapOfShape  a_counter ;
711
712   Standard_Boolean     return_status = Standard_False,
713     local_flag ;
714
715   while (ex.More()) {
716     if (a_counter.Add(ex.Current())) {
717       local_flag =
718         BRepLib::UpdateEdgeTol(TopoDS::Edge(ex.Current()),
719         MinToleranceRequested,
720         MaxToleranceToCheck) ;
721       if (local_flag && ! return_status) {
722         return_status = Standard_True ;
723       }
724     }
725     ex.Next();
726   }
727   return return_status ;
728 }
729
730 //=======================================================================
731 //function : SetEdgeTol
732 //purpose  : 
733 //=======================================================================
734
735 static void SetEdgeTol(const TopoDS_Edge& E,
736   const TopoDS_Face& F)
737 {
738   TopLoc_Location L;
739   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,L);
740   TopLoc_Location l = L.Predivided(E.Location());
741
742   const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape());
743   BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->ChangeCurves());
744
745   while (itcr.More()) {
746     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
747     if(cr->IsCurveOnSurface(S,l)) return;
748     itcr.Next();
749   }
750
751   Handle(Geom_Plane) GP;
752   Handle(Geom_RectangularTrimmedSurface) GRTS;
753   GRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
754   if(!GRTS.IsNull())
755     GP = Handle(Geom_Plane)::DownCast(GRTS->BasisSurface());
756   else
757     GP = Handle(Geom_Plane)::DownCast(S);
758
759   Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve();
760   Handle(GeomAdaptor_HSurface) HS = new GeomAdaptor_HSurface();
761
762   TopLoc_Location LC;
763   Standard_Real First, Last;
764   GeomAdaptor_Curve& GAC = HC->ChangeCurve();
765   GAC.Load(BRep_Tool::Curve(E,LC,First,Last));
766   LC = L.Predivided(LC);
767
768   if (!LC.IsIdentity()) {
769     GP = Handle(Geom_Plane)::DownCast(
770       GP->Transformed(LC.Transformation()));
771   }
772   GeomAdaptor_Surface& GAS = HS->ChangeSurface();
773   GAS.Load(GP);
774
775   ProjLib_ProjectedCurve Proj(HS,HC);
776   Handle(Geom2d_Curve) pc = Geom2dAdaptor::MakeCurve(Proj);
777
778   gp_Pln pln = GAS.Plane();
779   Standard_Real d2 = 0.;
780   Standard_Integer nn = 23;
781   Standard_Real unsurnn = 1./nn;
782   for(Standard_Integer i = 0; i <= nn; i++){
783     Standard_Real t = unsurnn*i;
784     Standard_Real u = First*(1.-t) + Last*t;
785     gp_Pnt Pc3d = HC->Value(u);
786     gp_Pnt2d p2d = pc->Value(u);
787     gp_Pnt Pcons = ElSLib::Value(p2d.X(),p2d.Y(),pln);
788     Standard_Real eps = Max(Pc3d.XYZ().SquareModulus(), Pcons.XYZ().SquareModulus());
789     eps = Epsilon(eps);
790     Standard_Real temp = Pc3d.SquareDistance(Pcons);
791     if(temp <= eps)
792     {
793       temp = 0.;
794     }
795     if(temp > d2) d2 = temp;
796   }
797   d2 = 1.5*sqrt(d2);
798   TE->UpdateTolerance(d2);
799 }
800
801 //=======================================================================
802 //function : SameParameter
803 //purpose  : 
804 //=======================================================================
805 void  BRepLib::SameParameter(const TopoDS_Shape& S,
806   const Standard_Real Tolerance,
807   const Standard_Boolean forced) 
808 {
809   TopExp_Explorer ex(S,TopAbs_EDGE);
810   TopTools_MapOfShape  Done;
811   BRep_Builder brB;
812
813   while (ex.More()) {
814     if (Done.Add(ex.Current())) {
815       if (forced) {
816         brB.SameRange(TopoDS::Edge(ex.Current()), Standard_False);
817         brB.SameParameter(TopoDS::Edge(ex.Current()), Standard_False);
818       }
819       BRepLib::SameParameter(TopoDS::Edge(ex.Current()),Tolerance);
820     }
821     ex.Next();
822   }
823
824   Done.Clear();
825   BRepAdaptor_Surface BS;
826   for(ex.Init(S,TopAbs_FACE); ex.More(); ex.Next()){
827     const TopoDS_Face& curface = TopoDS::Face(ex.Current());
828     if(!Done.Add(curface)) continue;
829     BS.Initialize(curface);
830     if(BS.GetType() != GeomAbs_Plane) continue;
831     TopExp_Explorer ex2;
832     for(ex2.Init(curface,TopAbs_EDGE); ex2.More(); ex2.Next()){
833       const TopoDS_Edge& E = TopoDS::Edge(ex2.Current());
834       SetEdgeTol(E,curface);
835     }
836   }
837   BRepLib::UpdateTolerances(S);
838 }
839
840 //================================================================
841 //function : SameParameter
842 //WARNING  : New spec DUB LBO 9/9/97.
843 //  Recode in the edge the best tolerance found, 
844 //  for vertex extremities it is required to find something else
845 //================================================================
846 static Standard_Boolean EvalTol(const Handle(Geom2d_Curve)& pc,
847   const Handle(Geom_Surface)& s,
848   const GeomAdaptor_Curve&    gac,
849   const Standard_Real         tol,
850   Standard_Real&              tolbail)
851 {
852   Standard_Integer ok = 0;
853   Standard_Real f = gac.FirstParameter();
854   Standard_Real l = gac.LastParameter();
855   Extrema_LocateExtPC Projector;
856   Projector.Initialize(gac,f,l,tol);
857   Standard_Real u,v;
858   gp_Pnt p;
859   tolbail = tol;
860   for(Standard_Integer i = 1; i <= 5; i++){
861     Standard_Real t = i/6.;
862     t = (1.-t) * f + t * l;
863     pc->Value(t).Coord(u,v);
864     p = s->Value(u,v);
865     Projector.Perform(p,t);
866     if (Projector.IsDone()) {
867       Standard_Real dist2 = Projector.SquareDistance();
868       if(dist2 > tolbail * tolbail) tolbail = sqrt (dist2);
869       ok++;
870     }
871   }
872   return (ok > 2);
873 }
874
875 static Standard_Real ComputeTol(const Handle(Adaptor3d_HCurve)& c3d,
876   const Handle(Adaptor2d_HCurve2d)& c2d,
877   const Handle(Adaptor3d_HSurface)& surf,
878   const Standard_Integer        nbp)
879
880 {
881
882   TColStd_Array1OfReal dist(1,nbp+10);
883   dist.Init(-1.);
884
885   Adaptor3d_CurveOnSurface  cons(c2d,surf);
886   Standard_Real d2 = 0.;
887   Standard_Real first = c3d->FirstParameter();
888   Standard_Real last  = c3d->LastParameter();
889   Standard_Integer i = 0;
890   for(i = 0; i <= nbp; i++){
891     const Standard_Real t = IntToReal(i)/IntToReal(nbp);
892     const Standard_Real u = first*(1.-t) + last*t;
893     gp_Pnt Pc3d = c3d->Value(u);
894     gp_Pnt Pcons = cons.Value(u);
895     if (Precision::IsInfinite(Pcons.X()) ||
896       Precision::IsInfinite(Pcons.Y()) ||
897       Precision::IsInfinite(Pcons.Z())) {
898         d2=Precision::Infinite();
899         break;
900     }
901     Standard_Real temp = Pc3d.SquareDistance(Pcons);
902
903
904     dist(i+1) = temp;
905
906
907     if(temp > d2) d2 = temp;
908   }
909
910
911   Standard_Boolean ana = Standard_False;
912   Standard_Real D2 = 0;
913   Standard_Integer N1 = 0;
914   Standard_Integer N2 = 0;
915   Standard_Integer N3 = 0;
916
917   for( i = 1; i<= nbp+10; i++)
918     if( dist(i) > 0 ) {
919       if( dist(i) < 1.0 ) N1++;
920       else N2++;
921     }
922
923     if( N1 > N2 && N2 != 0 ) N3 = 100*N2/(N1+N2);
924     if( N3 < 10 && N3 != 0 ) {
925       ana = Standard_True;
926       for( i = 1; i<= nbp+10; i++)
927         if( dist(i) > 0 && dist(i) < 1.0 )
928           if( dist(i) > D2 ) D2 = dist(i);
929     }
930
931     //d2 = 1.5*sqrt(d2);
932     d2 = (!ana) ? 1.5*sqrt(d2) : 1.5*sqrt(D2);
933     if(d2<1.e-7) d2 = 1.e-7;
934
935     return d2;
936 }
937
938 void BRepLib::SameParameter(const TopoDS_Edge&  AnEdge,
939   const Standard_Real Tolerance)
940 {
941   if (BRep_Tool::SameParameter(AnEdge)) return;
942
943   const Standard_Integer NCONTROL = 22;
944
945   Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve();
946   Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve();
947   Handle(GeomAdaptor_HSurface) HS = new GeomAdaptor_HSurface();
948   GeomAdaptor_Curve& GAC = HC->ChangeCurve();
949   Geom2dAdaptor_Curve& GAC2d = HC2d->ChangeCurve2d();
950   GeomAdaptor_Surface& GAS = HS->ChangeSurface();
951   Standard_Real f3d =0.,l3d =0.;
952   TopLoc_Location L3d;
953   Handle(Geom_Curve) C3d;
954
955   const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &AnEdge.TShape());
956   BRep_ListOfCurveRepresentation& CList = TE->ChangeCurves();
957   BRep_ListIteratorOfListOfCurveRepresentation It(CList);
958
959   Standard_Boolean NotDone = Standard_True;
960
961   while (NotDone && It.More()) {
962     Handle(BRep_GCurve) GCurve = Handle(BRep_GCurve)::DownCast(It.Value());
963     if (!GCurve.IsNull() && GCurve->IsCurve3D()) {
964       C3d = GCurve->Curve3D() ;
965       f3d = GCurve->First();
966       l3d = GCurve->Last();
967       L3d = GCurve->Location() ;
968       NotDone = Standard_False;
969     } 
970     It.Next() ;
971   }
972
973   if(C3d.IsNull()) return;
974
975   // modified by NIZHNY-OCC486  Tue Aug 27 17:15:13 2002 :
976   Standard_Boolean m_TrimmedPeriodical = Standard_False;
977   Handle(Standard_Type) TheType = C3d->DynamicType();
978   if( TheType == STANDARD_TYPE(Geom_TrimmedCurve))
979   {
980     Handle(Geom_Curve) gtC (Handle(Geom_TrimmedCurve)::DownCast (C3d)->BasisCurve());
981     m_TrimmedPeriodical = gtC->IsPeriodic();
982   }
983   // modified by NIZHNY-OCC486  Tue Aug 27 17:15:17 2002 .
984
985   BRep_Builder B;
986   if(!C3d->IsPeriodic()) {
987     Standard_Real Udeb = C3d->FirstParameter();
988     Standard_Real Ufin = C3d->LastParameter();
989     // modified by NIZHNY-OCC486  Tue Aug 27 17:17:14 2002 :
990     //if (Udeb > f3d) f3d = Udeb;
991     //if (l3d > Ufin) l3d = Ufin;
992     if(!m_TrimmedPeriodical)
993     {
994       if (Udeb > f3d) f3d = Udeb;
995       if (l3d > Ufin) l3d = Ufin;
996     }
997     // modified by NIZHNY-OCC486  Tue Aug 27 17:17:55 2002 .
998   }
999   if(!L3d.IsIdentity()){
1000     C3d = Handle(Geom_Curve)::DownCast(C3d->Transformed(L3d.Transformation()));
1001   }
1002   GAC.Load(C3d,f3d,l3d);
1003
1004   Standard_Boolean IsSameP = 1;
1005   Standard_Real maxdist = 0.;
1006
1007   //  Modified by skv - Thu Jun  3 12:39:19 2004 OCC5898 Begin
1008   Standard_Real anEdgeTol = BRep_Tool::Tolerance(AnEdge);
1009   //  Modified by skv - Thu Jun  3 12:39:20 2004 OCC5898 End
1010   Standard_Boolean SameRange = BRep_Tool::SameRange(AnEdge);
1011   Standard_Boolean YaPCu = Standard_False;
1012   It.Initialize(CList);
1013
1014   while (It.More()) {
1015     Standard_Boolean isANA = Standard_False;
1016     Standard_Boolean isBSP = Standard_False;
1017     Handle(BRep_GCurve) GCurve = Handle(BRep_GCurve)::DownCast(It.Value());
1018     Handle(Geom2d_Curve) PC[2];
1019     Handle(Geom_Surface) S;
1020     if (!GCurve.IsNull() && GCurve->IsCurveOnSurface()) {
1021       YaPCu = Standard_True;
1022       PC[0] = GCurve->PCurve();
1023       TopLoc_Location PCLoc = GCurve->Location();
1024       S = GCurve->Surface();
1025       if (!PCLoc.IsIdentity() ) {
1026         S = Handle(Geom_Surface)::DownCast(S->Transformed(PCLoc.Transformation()));
1027       }
1028
1029       GAS.Load(S);
1030       if (GCurve->IsCurveOnClosedSurface()) {
1031         PC[1] = GCurve->PCurve2();
1032       }
1033
1034       // Eval tol2d to compute SameRange
1035       Standard_Real UResol = Max(GAS.UResolution(Tolerance), Precision::PConfusion());
1036       Standard_Real VResol = Max(GAS.VResolution(Tolerance), Precision::PConfusion());
1037       Standard_Real Tol2d  = Min(UResol, VResol);
1038       for(Standard_Integer i = 0; i < 2; i++){
1039         Handle(Geom2d_Curve) curPC = PC[i];
1040         Standard_Boolean updatepc = 0;
1041         if(curPC.IsNull()) break;
1042         if(!SameRange){
1043           GeomLib::SameRange(Tol2d,
1044             PC[i],GCurve->First(),GCurve->Last(),
1045             f3d,l3d,curPC);
1046
1047           updatepc = (curPC != PC[i]);
1048
1049         }
1050         Standard_Boolean goodpc = 1;
1051         GAC2d.Load(curPC,f3d,l3d);
1052
1053         Standard_Real error = ComputeTol(HC, HC2d, HS, NCONTROL);
1054
1055         if(GAC2d.GetType() == GeomAbs_BSplineCurve && 
1056           GAC2d.Continuity() == GeomAbs_C0) {
1057             Handle(Geom2d_BSplineCurve) bs2d = GAC2d.BSpline();
1058             Handle(Geom2d_BSplineCurve) bs2dsov = bs2d;
1059             Standard_Real fC0 = bs2d->FirstParameter(), lC0 = bs2d->LastParameter();
1060             Standard_Boolean repar = Standard_True;
1061             gp_Pnt2d OriginPoint;
1062             bs2d->D0(fC0, OriginPoint);
1063             Geom2dConvert::C0BSplineToC1BSplineCurve(bs2d, Tol2d);
1064             isBSP = Standard_True; 
1065
1066             if(bs2d->IsPeriodic()) { // -------- IFV, Jan 2000
1067               gp_Pnt2d NewOriginPoint;
1068               bs2d->D0(bs2d->FirstParameter(), NewOriginPoint);
1069               if(Abs(OriginPoint.X() - NewOriginPoint.X()) > Precision::PConfusion() ||
1070                 Abs(OriginPoint.Y() - NewOriginPoint.Y()) > Precision::PConfusion()    ) {
1071
1072                   TColStd_Array1OfReal Knotbs2d (1, bs2d->NbKnots());
1073                   bs2d->Knots(Knotbs2d);
1074
1075                   for(Standard_Integer Index = 1; Index <= bs2d->NbKnots(); Index++) {
1076                     bs2d->D0(Knotbs2d(Index), NewOriginPoint);
1077                     if(Abs(OriginPoint.X() - NewOriginPoint.X()) > Precision::PConfusion() ||
1078                       Abs(OriginPoint.Y() - NewOriginPoint.Y()) > Precision::PConfusion()    ) continue;
1079
1080                     bs2d->SetOrigin(Index);
1081                     break;
1082                   }
1083               }
1084             }
1085
1086             if(bs2d->Continuity() == GeomAbs_C0) {
1087               Standard_Real tolbail;
1088               if(EvalTol(curPC,S,GAC,Tolerance,tolbail)){
1089                 bs2d = bs2dsov;
1090                 Standard_Real UResbail = GAS.UResolution(tolbail);
1091                 Standard_Real VResbail = GAS.VResolution(tolbail);
1092                 Standard_Real Tol2dbail  = Min(UResbail,VResbail);
1093                 bs2d->D0(bs2d->FirstParameter(), OriginPoint); 
1094
1095                 Standard_Integer nbp = bs2d->NbPoles();
1096                 TColgp_Array1OfPnt2d poles(1,nbp);
1097                 bs2d->Poles(poles);
1098                 gp_Pnt2d p = poles(1), p1;
1099                 Standard_Real d = Precision::Infinite();
1100                 for(Standard_Integer ip = 2; ip <= nbp; ip++) {
1101                   p1 = poles(ip);
1102                   d = Min(d,p.SquareDistance(p1));
1103                   p = p1;
1104                 }
1105                 d = sqrt(d)*.1;
1106
1107                 Tol2dbail = Max(Min(Tol2dbail,d),Tol2d);
1108
1109                 Geom2dConvert::C0BSplineToC1BSplineCurve(bs2d,Tol2dbail);
1110
1111                 if(bs2d->IsPeriodic()) { // -------- IFV, Jan 2000
1112                   gp_Pnt2d NewOriginPoint;
1113                   bs2d->D0(bs2d->FirstParameter(), NewOriginPoint);
1114                   if(Abs(OriginPoint.X() - NewOriginPoint.X()) > Precision::PConfusion() ||
1115                     Abs(OriginPoint.Y() - NewOriginPoint.Y()) > Precision::PConfusion()    ) {
1116
1117                       TColStd_Array1OfReal Knotbs2d (1, bs2d->NbKnots());
1118                       bs2d->Knots(Knotbs2d);
1119
1120                       for(Standard_Integer Index = 1; Index <= bs2d->NbKnots(); Index++) {
1121                         bs2d->D0(Knotbs2d(Index), NewOriginPoint);
1122                         if(Abs(OriginPoint.X() - NewOriginPoint.X()) > Precision::PConfusion() ||
1123                           Abs(OriginPoint.Y() - NewOriginPoint.Y()) > Precision::PConfusion()    ) continue;
1124
1125                         bs2d->SetOrigin(Index);
1126                         break;
1127                       }
1128                   }
1129                 }
1130
1131
1132                 if(bs2d->Continuity() == GeomAbs_C0) {
1133                   goodpc = 1;
1134                   bs2d = bs2dsov;
1135                   repar = Standard_False;
1136                 }
1137               }
1138               else goodpc = 0;
1139             }
1140
1141             if(goodpc){
1142               if(repar) {
1143                 Standard_Integer NbKnots = bs2d->NbKnots();
1144                 TColStd_Array1OfReal Knots(1,NbKnots);
1145                 bs2d->Knots(Knots);
1146                 //          BSplCLib::Reparametrize(f3d,l3d,Knots);
1147                 BSplCLib::Reparametrize(fC0,lC0,Knots);
1148                 bs2d->SetKnots(Knots);
1149                 GAC2d.Load(bs2d,f3d,l3d);
1150                 curPC = bs2d;
1151                 Standard_Boolean updatepcsov = updatepc;
1152                 updatepc = Standard_True;
1153
1154                 Standard_Real error1 = ComputeTol(HC, HC2d, HS, NCONTROL);
1155                 if(error1 > error) {
1156                   bs2d = bs2dsov;
1157                   GAC2d.Load(bs2d,f3d,l3d);
1158                   curPC = bs2d;
1159                   updatepc = updatepcsov;
1160                   isANA = Standard_True;
1161                 }
1162                 else {
1163                   error = error1;
1164                 }
1165               }
1166
1167               //check, if new BSpline "good" or not --------- IFV, Jan of 2000
1168               GeomAbs_Shape cont = bs2d->Continuity();
1169               Standard_Boolean IsBad = Standard_False;
1170
1171               if(cont > GeomAbs_C0 && error > Max(1.e-3,Tolerance)) {
1172                 Standard_Integer NbKnots = bs2d->NbKnots();
1173                 TColStd_Array1OfReal Knots(1,NbKnots);
1174                 bs2d->Knots(Knots);
1175                 Standard_Real critratio = 10.; 
1176                 Standard_Real dtprev = Knots(2) - Knots(1), dtratio = 1.;
1177                 Standard_Real dtmin = dtprev;
1178                 Standard_Real dtcur;
1179                 for(Standard_Integer j = 2; j < NbKnots; j++) {
1180                   dtcur = Knots(j+1) - Knots(j);
1181                   dtmin = Min(dtmin, dtcur);
1182
1183                   if(IsBad) continue;
1184
1185                   if(dtcur > dtprev) dtratio = dtcur/dtprev;
1186                   else dtratio = dtprev/dtcur;
1187                   if(dtratio > critratio) {IsBad = Standard_True;}
1188                   dtprev = dtcur;
1189
1190                 }
1191                 if(IsBad) {
1192                   // To avoid failures in Approx_CurvilinearParameter 
1193                   bs2d->Resolution(Max(1.e-3,Tolerance), dtcur);
1194                   if(dtmin < dtcur) IsBad = Standard_False;
1195                 }
1196               }
1197
1198
1199               if(IsBad ) { //if BSpline "bad", try to reparametrize it
1200                 // by its curve length
1201
1202                 //            GeomAbs_Shape cont = bs2d->Continuity();
1203                 if(cont > GeomAbs_C2) cont = GeomAbs_C2;
1204                 Standard_Integer maxdeg = bs2d->Degree();
1205                 if(maxdeg == 1) maxdeg = 14;
1206                 Approx_CurvilinearParameter AppCurPar(HC2d, HS, Max(1.e-3,Tolerance),
1207                   cont, maxdeg, 10);
1208                 if(AppCurPar.IsDone() || AppCurPar.HasResult()) {
1209                   bs2d = AppCurPar.Curve2d1();
1210                   GAC2d.Load(bs2d,f3d,l3d);
1211                   curPC = bs2d;
1212
1213                   if(Abs(bs2d->FirstParameter() - fC0) > Tol2d ||
1214                     Abs(bs2d->LastParameter() - lC0) > Tol2d    ) {
1215                       Standard_Integer NbKnots = bs2d->NbKnots();
1216                       TColStd_Array1OfReal Knots(1,NbKnots);
1217                       bs2d->Knots(Knots);
1218                       //                  BSplCLib::Reparametrize(f3d,l3d,Knots);
1219                       BSplCLib::Reparametrize(fC0,lC0,Knots);
1220                       bs2d->SetKnots(Knots);
1221                       GAC2d.Load(bs2d,f3d,l3d);
1222                       curPC = bs2d;
1223
1224                   }
1225                 }
1226               }
1227
1228
1229             }
1230         }
1231
1232
1233         if(goodpc){
1234           //      Approx_SameParameter SameP(HC,HC2d,HS,Tolerance);
1235           Standard_Real aTol = (isANA && isBSP) ? 1.e-7 : Tolerance;
1236           const Handle(Adaptor3d_HCurve)& aHCurv = HC; // to avoid ambiguity
1237           const Handle(Adaptor2d_HCurve2d)& aHCurv2d = HC2d; // to avoid ambiguity
1238           Approx_SameParameter SameP(aHCurv,aHCurv2d,HS,aTol);
1239
1240           if (SameP.IsSameParameter()) {
1241             maxdist = Max(maxdist,SameP.TolReached());
1242             if(updatepc){
1243               if (i == 0) GCurve->PCurve(curPC);
1244               else GCurve->PCurve2(curPC);
1245             }
1246           }
1247           else if (SameP.IsDone()) {
1248             Standard_Real tolreached = SameP.TolReached();
1249             if(tolreached < error) {
1250               curPC = SameP.Curve2d();
1251               updatepc = Standard_True;
1252               maxdist = Max(maxdist,tolreached);
1253             }
1254             else {
1255               maxdist = Max(maxdist, error);
1256             }
1257             if(updatepc){
1258               if (i == 0) GCurve->PCurve(curPC);
1259               else GCurve->PCurve2(curPC);
1260             }
1261           }
1262           else
1263           {
1264             //Approx_SameParameter has failed.
1265             //Consequently, the situation might be,
1266             //when 3D and 2D-curve do not have same-range.
1267             GeomLib::SameRange( Tol2d, PC[i], 
1268                                 GCurve->First(), GCurve->Last(),
1269                                 f3d,l3d,curPC);
1270
1271             if (i == 0) GCurve->PCurve(curPC);
1272             else GCurve->PCurve2(curPC);
1273
1274             IsSameP = 0;
1275           }
1276
1277         }
1278         else IsSameP = 0;
1279
1280         //  Modified by skv - Thu Jun  3 12:39:19 2004 OCC5898 Begin
1281         if (!IsSameP) {
1282           if (anEdgeTol > error) {
1283             maxdist = Max(maxdist, anEdgeTol);
1284             IsSameP = Standard_True;
1285           }
1286         }
1287         //  Modified by skv - Thu Jun  3 12:39:20 2004 OCC5898 End
1288       }
1289     }
1290     It.Next() ;
1291   }
1292   B.Range(AnEdge,f3d,l3d);
1293   B.SameRange(AnEdge,Standard_True);
1294   if ( IsSameP) {
1295     // Reduce eventually the tolerance of the edge, as
1296     // all its representations are processed (except for some associated
1297     // to planes and not stored in the edge !) 
1298     // The same cannot be done with vertices that cannot be enlarged 
1299     // or left as is.
1300     if (YaPCu) {
1301       // Avoid setting too small tolerances.
1302       maxdist = Max(maxdist,Precision::Confusion());
1303       TopoDS_Vertex V1,V2;
1304       TopExp::Vertices(AnEdge,V1,V2);
1305       if (!V1.IsNull())
1306         B.UpdateVertex(V1,maxdist);
1307       if (!V2.IsNull())
1308         B.UpdateVertex(V2,maxdist);
1309       TE->Modified(Standard_True);
1310       TE->Tolerance(maxdist);
1311     }
1312     B.SameParameter(AnEdge,Standard_True);
1313   }
1314 }
1315
1316 //=======================================================================
1317 //function : UpdateTolerances
1318 //purpose  : 
1319 //=======================================================================
1320 void  BRepLib::UpdateTolerances(const TopoDS_Shape& aShape,
1321   const Standard_Boolean verifyTolerance) 
1322 {
1323
1324   // Harmonize tolerances
1325   // with rule Tolerance(VERTEX)>=Tolerance(EDGE)>=Tolerance(FACE)
1326   BRep_Builder B;
1327   Standard_Real tol=0;
1328   if (verifyTolerance) {
1329     // Set tolerance to its minimum value
1330     Handle(Geom_Surface) S;
1331     TopLoc_Location l;
1332     TopExp_Explorer ex;
1333     Bnd_Box aB;
1334     Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, dMax;
1335     for (ex.Init(aShape, TopAbs_FACE); ex.More(); ex.Next()) {
1336       const TopoDS_Face& curf=TopoDS::Face(ex.Current());
1337       S = BRep_Tool::Surface(curf, l);
1338       if (!S.IsNull()) {
1339         aB.SetVoid();
1340         BRepBndLib::Add(curf,aB);
1341         if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1342           S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
1343         }
1344         GeomAdaptor_Surface AS(S);
1345         switch (AS.GetType()) {
1346         case GeomAbs_Plane: 
1347         case GeomAbs_Cylinder: 
1348         case GeomAbs_Cone: 
1349           {
1350             tol=Precision::Confusion();
1351             break;
1352           }
1353         case GeomAbs_Sphere: 
1354         case GeomAbs_Torus: 
1355           {
1356             tol=Precision::Confusion()*2;
1357             break;
1358           }
1359         default:
1360           tol=Precision::Confusion()*4;
1361         }
1362         if (!aB.IsWhole()) {
1363           aB.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
1364           dMax=1.;
1365           if (!aB.IsOpenXmin() && !aB.IsOpenXmax()) dMax=aXmax-aXmin;
1366           if (!aB.IsOpenYmin() && !aB.IsOpenYmax()) aYmin=aYmax-aYmin;
1367           if (!aB.IsOpenZmin() && !aB.IsOpenZmax()) aZmin=aZmax-aZmin;
1368           if (aYmin>dMax) dMax=aYmin;
1369           if (aZmin>dMax) dMax=aZmin;
1370           tol=tol*dMax;
1371           // Do not process tolerances > 1.
1372           if (tol>1.) tol=0.99;
1373         }
1374         const Handle(BRep_TFace)& Tf = *((Handle(BRep_TFace)*)&curf.TShape());
1375         Tf->Tolerance(tol);
1376       }
1377     }
1378   }
1379
1380   //Process edges
1381   TopTools_IndexedDataMapOfShapeListOfShape parents;
1382   TopExp::MapShapesAndAncestors(aShape, TopAbs_EDGE, TopAbs_FACE, parents);
1383   TopTools_ListIteratorOfListOfShape lConx;
1384   Standard_Integer iCur;
1385   for (iCur=1; iCur<=parents.Extent(); iCur++) {
1386     tol=0;
1387     for (lConx.Initialize(parents(iCur)); lConx.More(); lConx.Next()) {
1388       tol=Max(tol, BRep_Tool::Tolerance(TopoDS::Face(lConx.Value())));
1389     }
1390     // Update can only increase tolerance, so if the edge has a greater
1391     //  tolerance than its faces it is not concerned
1392     B.UpdateEdge(TopoDS::Edge(parents.FindKey(iCur)), tol);
1393   }
1394
1395   //Vertices are processed
1396   parents.Clear();
1397   TopExp::MapShapesAndAncestors(aShape, TopAbs_VERTEX, TopAbs_EDGE, parents);
1398   TColStd_MapOfTransient Initialized;
1399   TopTools_MapOfShape Done;
1400   Standard_Integer nbV = parents.Extent();
1401   for (iCur=1; iCur<=nbV; iCur++) {
1402     tol=0;
1403     Done.Clear();
1404     const TopoDS_Vertex& V = TopoDS::Vertex(parents.FindKey(iCur));
1405     Bnd_Box box;
1406     box.Add(BRep_Tool::Pnt(V));
1407     gp_Pnt p3d;
1408     for (lConx.Initialize(parents(iCur)); lConx.More(); lConx.Next()) {
1409       const TopoDS_Edge& E = TopoDS::Edge(lConx.Value());
1410       if(!Done.Add(E)) continue;
1411       tol=Max(tol, BRep_Tool::Tolerance(E));
1412       if(!BRep_Tool::SameRange(E)) continue;
1413       Standard_Real par = BRep_Tool::Parameter(V,E);
1414       Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape());
1415       BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
1416       const TopLoc_Location& Eloc = E.Location();
1417       while (itcr.More()) {
1418         // For each CurveRepresentation, check the provided parameter
1419         const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
1420         const TopLoc_Location& loc = cr->Location();
1421         TopLoc_Location L = (Eloc * loc);
1422         if (cr->IsCurve3D()) {
1423           const Handle(Geom_Curve)& C = cr->Curve3D();
1424           if (!C.IsNull()) { // edge non degenerated
1425             p3d = C->Value(par);
1426             p3d.Transform(L.Transformation());
1427             box.Add(p3d);
1428           }
1429         }
1430         else if (cr->IsCurveOnSurface()) {
1431           const Handle(Geom_Surface)& Su = cr->Surface();
1432           const Handle(Geom2d_Curve)& PC = cr->PCurve();
1433           Handle(Geom2d_Curve) PC2;
1434           if (cr->IsCurveOnClosedSurface()) {
1435             PC2 = cr->PCurve2();
1436           }
1437           gp_Pnt2d p2d = PC->Value(par);
1438           p3d = Su->Value(p2d.X(),p2d.Y());
1439           p3d.Transform(L.Transformation());
1440           box.Add(p3d);
1441           if (!PC2.IsNull()) {
1442             p2d = PC2->Value(par);
1443             p3d = Su->Value(p2d.X(),p2d.Y());
1444             p3d.Transform(L.Transformation());
1445             box.Add(p3d);
1446           }
1447         }
1448         itcr.Next();
1449       }
1450     }
1451     Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
1452     box.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
1453     aXmax -= aXmin; aYmax -= aYmin; aZmax -= aZmin;
1454     tol = Max(tol,sqrt(aXmax*aXmax+aYmax*aYmax+aZmax*aZmax));
1455     tol += 2.*Epsilon(tol);
1456     if (verifyTolerance) {
1457       // ASet minimum value of the tolerance 
1458       // Attention to sharing of the vertex by other shapes
1459       const Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*)&V.TShape());
1460       if (Initialized.Add(TV)) 
1461         TV->Tolerance(tol);
1462       else 
1463         B.UpdateVertex(V, tol);
1464     }
1465     else {
1466       // Update can only increase tolerance, so if the edge has a greater
1467       //  tolerance than its faces it is not concerned
1468       B.UpdateVertex(V, tol);
1469     }
1470   }
1471 }
1472
1473 //=======================================================================
1474 //function : UpdateInnerTolerances
1475 //purpose  : 
1476 //=======================================================================
1477 void  BRepLib::UpdateInnerTolerances(const TopoDS_Shape& aShape)
1478 {
1479   TopTools_IndexedDataMapOfShapeListOfShape EFmap;
1480   TopExp::MapShapesAndAncestors(aShape, TopAbs_EDGE, TopAbs_FACE, EFmap);
1481   BRep_Builder BB;
1482   for (Standard_Integer i = 1; i <= EFmap.Extent(); i++)
1483   {
1484     TopoDS_Edge anEdge = TopoDS::Edge(EFmap.FindKey(i));
1485     TopoDS_Vertex V1, V2;
1486     TopExp::Vertices(anEdge, V1, V2);
1487     Standard_Real fpar, lpar;
1488     BRep_Tool::Range(anEdge, fpar, lpar);
1489     Standard_Real TolEdge = BRep_Tool::Tolerance(anEdge);
1490     gp_Pnt Pnt1, Pnt2;
1491     Handle(BRepAdaptor_HCurve) anHCurve = new BRepAdaptor_HCurve();
1492     anHCurve->ChangeCurve().Initialize(anEdge);
1493     if (!V1.IsNull())
1494       Pnt1 = BRep_Tool::Pnt(V1);
1495     if (!V2.IsNull())
1496       Pnt2 = BRep_Tool::Pnt(V2);
1497     
1498     if (!BRep_Tool::Degenerated(anEdge) &&
1499         EFmap(i).Extent() > 0)
1500     {
1501       NCollection_Sequence<Handle(Adaptor3d_HCurve)> theRep;
1502       theRep.Append(anHCurve);
1503       TopTools_ListIteratorOfListOfShape itl(EFmap(i));
1504       for (; itl.More(); itl.Next())
1505       {
1506         const TopoDS_Face& aFace = TopoDS::Face(itl.Value());
1507         Handle(BRepAdaptor_HCurve) anHCurvOnSurf = new BRepAdaptor_HCurve();
1508         anHCurvOnSurf->ChangeCurve().Initialize(anEdge, aFace);
1509         theRep.Append(anHCurvOnSurf);
1510       }
1511       
1512       const Standard_Integer NbSamples = (BRep_Tool::SameParameter(anEdge))? 23 : 2;
1513       Standard_Real delta = (lpar - fpar)/(NbSamples-1);
1514       Standard_Real MaxDist = 0.;
1515       for (Standard_Integer j = 2; j <= theRep.Length(); j++)
1516       {
1517         for (Standard_Integer k = 0; k <= NbSamples; k++)
1518         {
1519           Standard_Real ParamOnCenter = (k == NbSamples)? lpar :
1520             fpar + k*delta;
1521           gp_Pnt Center = theRep(1)->Value(ParamOnCenter);
1522           Standard_Real ParamOnCurve = (BRep_Tool::SameParameter(anEdge))? ParamOnCenter
1523             : ((k == 0)? theRep(j)->FirstParameter() : theRep(j)->LastParameter());
1524           gp_Pnt aPoint = theRep(j)->Value(ParamOnCurve);
1525           Standard_Real aDist = Center.Distance(aPoint);
1526           //aDist *= 1.1;
1527           aDist += 2.*Epsilon(aDist);
1528           if (aDist > MaxDist)
1529             MaxDist = aDist;
1530
1531           //Update tolerances of vertices
1532           if (k == 0 && !V1.IsNull())
1533           {
1534             Standard_Real aDist1 = Pnt1.Distance(aPoint);
1535             aDist1 += 2.*Epsilon(aDist1);
1536             BB.UpdateVertex(V1, aDist1);
1537           }
1538           if (k == NbSamples && !V2.IsNull())
1539           {
1540             Standard_Real aDist2 = Pnt2.Distance(aPoint);
1541             aDist2 += 2.*Epsilon(aDist2);
1542             BB.UpdateVertex(V2, aDist2);
1543           }
1544         }
1545       }
1546       BB.UpdateEdge(anEdge, MaxDist);
1547     }
1548     TolEdge = BRep_Tool::Tolerance(anEdge);
1549     if (!V1.IsNull())
1550     {
1551       gp_Pnt End1 = anHCurve->Value(fpar);
1552       Standard_Real dist1 = Pnt1.Distance(End1);
1553       dist1 += 2.*Epsilon(dist1);
1554       BB.UpdateVertex(V1, Max(dist1, TolEdge));
1555     }
1556     if (!V2.IsNull())
1557     {
1558       gp_Pnt End2 = anHCurve->Value(lpar);
1559       Standard_Real dist2 = Pnt2.Distance(End2);
1560       dist2 += 2.*Epsilon(dist2);
1561       BB.UpdateVertex(V2, Max(dist2, TolEdge));
1562     }
1563   }
1564 }
1565
1566 //=======================================================================
1567 //function : OrientClosedSolid
1568 //purpose  : 
1569 //=======================================================================
1570 Standard_Boolean BRepLib::OrientClosedSolid(TopoDS_Solid& solid) 
1571 {
1572   // Set material inside the solid
1573   BRepClass3d_SolidClassifier where(solid);
1574   where.PerformInfinitePoint(Precision::Confusion());
1575   if (where.State()==TopAbs_IN) {
1576     solid.Reverse();
1577   }
1578   else if (where.State()==TopAbs_ON || where.State()==TopAbs_UNKNOWN) 
1579     return Standard_False;
1580
1581   return Standard_True;
1582 }
1583
1584 //=======================================================================
1585 //function : tgtfaces
1586 //purpose  : check the angle at the border between two squares.
1587 //           Two shares should have a shared front edge.
1588 //=======================================================================
1589
1590 static Standard_Boolean tgtfaces(const TopoDS_Edge& Ed,
1591   const TopoDS_Face& F1,
1592   const TopoDS_Face& F2,
1593   const Standard_Real ta,
1594   const Standard_Boolean couture)
1595 {
1596   // Check if pcurves exist on both faces of edge
1597   Standard_Real aFirst,aLast;
1598   Handle(Geom2d_Curve) aCurve;
1599   aCurve = BRep_Tool::CurveOnSurface(Ed,F1,aFirst,aLast);
1600   if(aCurve.IsNull())
1601     return Standard_False;
1602   aCurve = BRep_Tool::CurveOnSurface(Ed,F2,aFirst,aLast);
1603   if(aCurve.IsNull())
1604     return Standard_False;
1605
1606   Standard_Real u;
1607   TopoDS_Edge E = Ed;
1608   BRepAdaptor_Surface aBAS1(F1,Standard_False);
1609   BRepAdaptor_Surface aBAS2(F2,Standard_False);
1610   Handle(BRepAdaptor_HSurface) HS1 = new BRepAdaptor_HSurface(aBAS1);
1611   Handle(BRepAdaptor_HSurface) HS2;
1612   if(couture) HS2 = HS1;
1613   else HS2 = new BRepAdaptor_HSurface(aBAS2);
1614
1615   E.Orientation(TopAbs_FORWARD);
1616   Handle(BRepAdaptor_HCurve2d) HC2d1 = new BRepAdaptor_HCurve2d();
1617   HC2d1->ChangeCurve2d().Initialize(E,F1);
1618   if(couture) E.Orientation(TopAbs_REVERSED);
1619   Handle(BRepAdaptor_HCurve2d) HC2d2 = new BRepAdaptor_HCurve2d();
1620   HC2d2->ChangeCurve2d().Initialize(E,F2);
1621   Adaptor3d_CurveOnSurface C1(HC2d1,HS1);
1622   Adaptor3d_CurveOnSurface C2(HC2d2,HS2);
1623
1624   Standard_Boolean rev1 = (F1.Orientation() == TopAbs_REVERSED);
1625   Standard_Boolean rev2 = (F2.Orientation() == TopAbs_REVERSED);
1626   Standard_Real f,l,eps, angmax = -M_PI;
1627   Standard_Real ang =0.;
1628   BRep_Tool::Range(E,f,l);
1629   Extrema_LocateExtPC ext;
1630   Standard_Boolean IsInitialized = Standard_False;
1631
1632   eps = (l - f)/100.;
1633   f += eps; // to avoid calculations on  
1634   l -= eps; // points of pointed squares.
1635   gp_Pnt2d p;
1636   gp_Pnt pp1,pp2;//,PP;
1637   gp_Vec du,dv;
1638   gp_Vec d1,d2;
1639   Standard_Real uu, vv, norm;
1640
1641   Standard_Integer i;
1642   Standard_Boolean Nok;
1643   for(i = 0; (i<= 20) && (angmax<=ta) ; i++){
1644     // First suppose that this is sameParameter
1645     Nok = Standard_True;
1646     u = f + (l-f)*i/20;
1647     HC2d1->D0(u,p);
1648     HS1->D1(p.X(),p.Y(),pp1,du,dv);
1649     d1 = (du.Crossed(dv));
1650     norm = d1.Magnitude(); 
1651     if (norm > 1.e-12) d1 /= norm;
1652     else Nok=Standard_False;
1653     if(rev1) d1.Reverse();
1654
1655     HC2d2->D0(u,p);
1656     HS2->D1(p.X(), p.Y(), pp2, du, dv);
1657     d2 = (du.Crossed(dv));
1658     norm = d2.Magnitude();
1659     if (norm> 1.e-12) d2 /= norm;
1660     else Nok=Standard_False;
1661     if(rev2) d2.Reverse();
1662     if (Nok) ang = d1.Angle(d2);
1663
1664     if (Nok &&(ang > ta)) { // Refine by projection
1665       if (! IsInitialized ) {
1666         ext.Initialize(C2,f,l,Precision::PConfusion());
1667         IsInitialized = Standard_True;
1668       }      
1669       ext.Perform(pp1,u);
1670       if(ext.IsDone() && ext.IsMin()){
1671         Extrema_POnCurv poc = ext.Point();
1672         Standard_Real v = poc.Parameter();
1673
1674         HC2d2->D0(v,p);
1675         p.Coord(uu,vv);
1676         HS2->D1(p.X(), p.Y(), pp2, du, dv);
1677         d2 = (du.Crossed(dv));
1678         norm = d2.Magnitude();
1679         if (norm> 1.e-12) d2 /= norm;
1680         else Nok = Standard_False;
1681         if(rev2) d2.Reverse();
1682         if (Nok) ang = d1.Angle(d2);
1683       }
1684     }
1685     if(ang >= angmax) angmax = ang;
1686   }     
1687
1688   return (angmax<=ta);
1689
1690 }
1691
1692
1693 //=======================================================================
1694 // function : EncodeRegularity
1695 // purpose  : code the regularities on all edges of the shape, boundary of 
1696 //            two faces that do not have it.
1697 //=======================================================================
1698
1699 void BRepLib::EncodeRegularity(const TopoDS_Shape& S,
1700   const Standard_Real TolAng)
1701 {
1702   BRep_Builder B;
1703   TopTools_IndexedDataMapOfShapeListOfShape M;
1704   TopExp::MapShapesAndAncestors(S,TopAbs_EDGE,TopAbs_FACE,M);
1705   TopTools_ListIteratorOfListOfShape It;
1706   TopExp_Explorer Ex;
1707   TopoDS_Face F1,F2;
1708   Standard_Boolean found, couture;
1709   for(Standard_Integer i = 1; i <= M.Extent(); i++){
1710     TopoDS_Edge E = TopoDS::Edge(M.FindKey(i));
1711     found = Standard_False; couture = Standard_False;
1712     F1.Nullify();
1713     for(It.Initialize(M.FindFromIndex(i));It.More() && !found;It.Next()){
1714       if(F1.IsNull()) { F1 = TopoDS::Face(It.Value()); }
1715       else {
1716         if(!F1.IsSame(TopoDS::Face(It.Value()))){
1717           found = Standard_True;
1718           F2 = TopoDS::Face(It.Value());
1719         }
1720       }
1721     }
1722     if (!found && !F1.IsNull()){//is it a sewing edge?
1723       TopAbs_Orientation orE = E.Orientation();
1724       TopoDS_Edge curE;
1725       for(Ex.Init(F1,TopAbs_EDGE);Ex.More() && !found;Ex.Next()){
1726         curE= TopoDS::Edge(Ex.Current());
1727         if(E.IsSame(curE) && orE != curE.Orientation()) {
1728           found = Standard_True;
1729           couture = Standard_True;
1730           F2 = F1;
1731         }
1732       }
1733     }
1734     if(found){
1735       if(BRep_Tool::Continuity(E,F1,F2)<=GeomAbs_C0){
1736
1737         try {
1738           if(tgtfaces(E, F1, F2, TolAng, couture)){
1739             B.Continuity(E,F1,F2,GeomAbs_G1);
1740           }
1741         }
1742         catch(Standard_Failure)
1743         {
1744         }
1745       }
1746     }
1747   }
1748 }
1749
1750 //=======================================================================
1751 // function : EncodeRegularity
1752 // purpose  : code the regularity between 2 faces on an edge 
1753 //=======================================================================
1754
1755 void BRepLib::EncodeRegularity(TopoDS_Edge& E,
1756   const TopoDS_Face& F1,
1757   const TopoDS_Face& F2,
1758   const Standard_Real TolAng)
1759 {
1760   BRep_Builder B;
1761   if(BRep_Tool::Continuity(E,F1,F2)<=GeomAbs_C0){
1762     try {
1763       if( tgtfaces(E, F1, F2, TolAng, F1.IsEqual(F2))) {
1764         B.Continuity(E,F1,F2,GeomAbs_G1);
1765       }
1766     }
1767     catch(Standard_Failure)
1768     {
1769     }
1770   }
1771 }
1772
1773 //=======================================================================
1774 // function : EnsureNormalConsistency
1775 // purpose  : Corrects the normals in Poly_Triangulation of faces.
1776 //              Returns TRUE if any correction is done.
1777 //=======================================================================
1778 Standard_Boolean BRepLib::
1779             EnsureNormalConsistency(const TopoDS_Shape& theShape,
1780                                     const Standard_Real theAngTol,
1781                                     const Standard_Boolean theForceComputeNormals)
1782 {
1783   const Standard_Real aThresDot = cos(theAngTol);
1784
1785   Standard_Boolean aRetVal = Standard_False, isNormalsFound = Standard_False;
1786
1787   // compute normals if they are absent
1788   TopExp_Explorer anExpFace(theShape,TopAbs_FACE);
1789   for (; anExpFace.More(); anExpFace.Next())
1790   {
1791     const TopoDS_Face& aFace = TopoDS::Face(anExpFace.Current());
1792     const Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
1793     if(aSurf.IsNull())
1794       continue;
1795     TopLoc_Location aLoc;
1796     const Handle(Poly_Triangulation)& aPT = BRep_Tool::Triangulation(aFace, aLoc);
1797     if(aPT.IsNull())
1798       continue;
1799     if (!theForceComputeNormals && aPT->HasNormals())
1800     {
1801       isNormalsFound = Standard_True;
1802       continue;
1803     }
1804
1805     GeomLProp_SLProps aSLP(aSurf, 2, Precision::Confusion());
1806     const Standard_Integer anArrDim = 3*aPT->NbNodes();
1807     Handle(TShort_HArray1OfShortReal) aNormArr = new TShort_HArray1OfShortReal(1, anArrDim);
1808     Standard_Integer anNormInd = aNormArr->Lower();
1809     for(Standard_Integer i = aPT->UVNodes().Lower(); i <= aPT->UVNodes().Upper(); i++)
1810     {
1811       const gp_Pnt2d &aP2d = aPT->UVNodes().Value(i);
1812       aSLP.SetParameters(aP2d.X(), aP2d.Y());
1813
1814       gp_XYZ aNorm(0.,0.,0.);
1815       if(!aSLP.IsNormalDefined())
1816       {
1817 #ifdef OCCT_DEBUG
1818         cout << "BRepLib::EnsureNormalConsistency(): Cannot find normal!" << endl;
1819 #endif
1820       }
1821       else
1822       {
1823         aNorm = aSLP.Normal().XYZ();
1824         if (aFace.Orientation() == TopAbs_REVERSED)
1825           aNorm.Reverse();
1826       }
1827       aNormArr->ChangeValue(anNormInd++) = static_cast<Standard_ShortReal>(aNorm.X());
1828       aNormArr->ChangeValue(anNormInd++) = static_cast<Standard_ShortReal>(aNorm.Y());
1829       aNormArr->ChangeValue(anNormInd++) = static_cast<Standard_ShortReal>(aNorm.Z());
1830     }
1831
1832     aRetVal = Standard_True;
1833     isNormalsFound = Standard_True;
1834     aPT->SetNormals(aNormArr);
1835   }
1836
1837   if(!isNormalsFound)
1838   {
1839     return aRetVal;
1840   }
1841
1842   // loop by edges
1843   TopTools_IndexedDataMapOfShapeListOfShape aMapEF;
1844   TopExp::MapShapesAndAncestors(theShape,TopAbs_EDGE,TopAbs_FACE,aMapEF);
1845   for(Standard_Integer anInd = 1; anInd <= aMapEF.Extent(); anInd++)
1846   {
1847     const TopoDS_Edge& anEdg = TopoDS::Edge(aMapEF.FindKey(anInd));
1848     const TopTools_ListOfShape& anEdgList = aMapEF.FindFromIndex(anInd);
1849     if (anEdgList.Extent() != 2)
1850       continue;
1851     TopTools_ListIteratorOfListOfShape anItF(anEdgList);
1852     const TopoDS_Face aFace1 = TopoDS::Face(anItF.Value());
1853     anItF.Next();
1854     const TopoDS_Face aFace2 = TopoDS::Face(anItF.Value());
1855     TopLoc_Location aLoc1, aLoc2;
1856     const Handle(Poly_Triangulation)& aPT1 = BRep_Tool::Triangulation(aFace1, aLoc1);
1857     const Handle(Poly_Triangulation)& aPT2 = BRep_Tool::Triangulation(aFace2, aLoc2);
1858
1859     if(aPT1.IsNull() || aPT2.IsNull())
1860       continue;
1861
1862     if(!aPT1->HasNormals() || !aPT2->HasNormals())
1863       continue;
1864
1865     const Handle(Poly_PolygonOnTriangulation)& aPTEF1 = 
1866                                 BRep_Tool::PolygonOnTriangulation(anEdg, aPT1, aLoc1);
1867     const Handle(Poly_PolygonOnTriangulation)& aPTEF2 = 
1868                                 BRep_Tool::PolygonOnTriangulation(anEdg, aPT2, aLoc2);
1869
1870     TShort_Array1OfShortReal& aNormArr1 = aPT1->ChangeNormals();
1871     TShort_Array1OfShortReal& aNormArr2 = aPT2->ChangeNormals();
1872
1873     for(Standard_Integer anEdgNode = aPTEF1->Nodes().Lower();
1874                          anEdgNode <= aPTEF1->Nodes().Upper(); anEdgNode++)
1875     {
1876       //Number of node
1877       const Standard_Integer aFNodF1 = aPTEF1->Nodes().Value(anEdgNode);
1878       const Standard_Integer aFNodF2 = aPTEF2->Nodes().Value(anEdgNode);
1879
1880       const Standard_Integer aFNorm1FirstIndex = aNormArr1.Lower() + 3*
1881                                                     (aFNodF1 - aPT1->Nodes().Lower());
1882       const Standard_Integer aFNorm2FirstIndex = aNormArr2.Lower() + 3*
1883                                                     (aFNodF2 - aPT2->Nodes().Lower());
1884
1885       gp_XYZ aNorm1(aNormArr1.Value(aFNorm1FirstIndex),
1886                     aNormArr1.Value(aFNorm1FirstIndex+1),
1887                     aNormArr1.Value(aFNorm1FirstIndex+2));
1888       gp_XYZ aNorm2(aNormArr2.Value(aFNorm2FirstIndex),
1889                     aNormArr2.Value(aFNorm2FirstIndex+1),
1890                     aNormArr2.Value(aFNorm2FirstIndex+2));
1891       const Standard_Real aDot = aNorm1 * aNorm2;
1892
1893       if(aDot > aThresDot)
1894       {
1895         gp_XYZ aNewNorm = (aNorm1 + aNorm2).Normalized();
1896         aNormArr1.ChangeValue(aFNorm1FirstIndex) =
1897           aNormArr2.ChangeValue(aFNorm2FirstIndex) =
1898           static_cast<Standard_ShortReal>(aNewNorm.X());
1899         aNormArr1.ChangeValue(aFNorm1FirstIndex+1) =
1900           aNormArr2.ChangeValue(aFNorm2FirstIndex+1) =
1901           static_cast<Standard_ShortReal>(aNewNorm.Y());
1902         aNormArr1.ChangeValue(aFNorm1FirstIndex+2) =
1903           aNormArr2.ChangeValue(aFNorm2FirstIndex+2) =
1904           static_cast<Standard_ShortReal>(aNewNorm.Z());
1905         aRetVal = Standard_True;
1906       }
1907     }
1908   }
1909
1910   return aRetVal;
1911 }
1912
1913 //=======================================================================
1914 //function : SortFaces
1915 //purpose  : 
1916 //=======================================================================
1917
1918 void  BRepLib::SortFaces (const TopoDS_Shape& Sh,
1919   TopTools_ListOfShape& LF)
1920 {
1921   LF.Clear();
1922   TopTools_ListOfShape LTri,LPlan,LCyl,LCon,LSphere,LTor,LOther;
1923   TopExp_Explorer exp(Sh,TopAbs_FACE);
1924   TopLoc_Location l;
1925   Handle(Geom_Surface) S;
1926
1927   for (; exp.More(); exp.Next()) {
1928     const TopoDS_Face&   F = TopoDS::Face(exp.Current());
1929     S = BRep_Tool::Surface(F, l);
1930     if (!S.IsNull()) {
1931       if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1932         S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
1933       }
1934       GeomAdaptor_Surface AS(S);
1935       switch (AS.GetType()) {
1936       case GeomAbs_Plane: 
1937         {
1938           LPlan.Append(F);
1939           break;
1940         }
1941       case GeomAbs_Cylinder: 
1942         {
1943           LCyl.Append(F);
1944           break;
1945         }
1946       case GeomAbs_Cone: 
1947         {
1948           LCon.Append(F);
1949           break;
1950         }
1951       case GeomAbs_Sphere: 
1952         {
1953           LSphere.Append(F);
1954           break;
1955         }
1956       case GeomAbs_Torus: 
1957         {
1958           LTor.Append(F);
1959           break;
1960         }
1961       default:
1962         LOther.Append(F);
1963       }
1964     }
1965     else LTri.Append(F);
1966   }
1967   LF.Append(LPlan); LF.Append(LCyl  ); LF.Append(LCon); LF.Append(LSphere);
1968   LF.Append(LTor ); LF.Append(LOther); LF.Append(LTri); 
1969 }
1970
1971 //=======================================================================
1972 //function : ReverseSortFaces
1973 //purpose  : 
1974 //=======================================================================
1975
1976 void  BRepLib::ReverseSortFaces (const TopoDS_Shape& Sh,
1977   TopTools_ListOfShape& LF)
1978 {
1979   LF.Clear();
1980   TopTools_ListOfShape LTri,LPlan,LCyl,LCon,LSphere,LTor,LOther;
1981   TopExp_Explorer exp(Sh,TopAbs_FACE);
1982   TopLoc_Location l;
1983   Handle(Geom_Surface) S;
1984
1985   for (; exp.More(); exp.Next()) {
1986     const TopoDS_Face&   F = TopoDS::Face(exp.Current());
1987     S = BRep_Tool::Surface(F, l);
1988     if (!S.IsNull()) {
1989       if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1990         S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
1991       }
1992       GeomAdaptor_Surface AS(S);
1993       switch (AS.GetType()) {
1994       case GeomAbs_Plane: 
1995         {
1996           LPlan.Append(F);
1997           break;
1998         }
1999       case GeomAbs_Cylinder: 
2000         {
2001           LCyl.Append(F);
2002           break;
2003         }
2004       case GeomAbs_Cone: 
2005         {
2006           LCon.Append(F);
2007           break;
2008         }
2009       case GeomAbs_Sphere: 
2010         {
2011           LSphere.Append(F);
2012           break;
2013         }
2014       case GeomAbs_Torus: 
2015         {
2016           LTor.Append(F);
2017           break;
2018         }
2019       default:
2020         LOther.Append(F);
2021       }
2022     }
2023     else LTri.Append(F);
2024   }
2025   LF.Append(LTri); LF.Append(LOther); LF.Append(LTor ); LF.Append(LSphere);
2026   LF.Append(LCon); LF.Append(LCyl  ); LF.Append(LPlan);
2027
2028 }
2029