0024428: Implementation of LGPL license
[occt.git] / src / ShapeAlgo / ShapeAlgo_AlgoContainer.cxx
1 // Created on: 2000-02-07
2 // Created by: data exchange team
3 // Copyright (c) 2000-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and / or modify it
8 // under the terms of the GNU Lesser General Public version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <ShapeAlgo_AlgoContainer.ixx>
17
18 #include <GeomInt_WLApprox.hxx>
19 #include <IntSurf_LineOn2S.hxx>
20 #include <IntSurf_PntOn2S.hxx>
21 #include <IntPatch_WLine.hxx>
22
23 #include <BRep_Builder.hxx>
24 #include <BRep_Tool.hxx>
25 #include <BRepBuilderAPI_MakeEdge.hxx>
26 #include <BRepBuilderAPI_MakeWire.hxx>
27 #include <TopoDS.hxx>
28 #include <TopoDS_Edge.hxx>
29 #include <TopoDS_Wire.hxx>
30 #include <TopoDS_Iterator.hxx>
31 #include <TopExp.hxx>
32
33 #include <Precision.hxx>
34
35 #include <TColStd_Array1OfReal.hxx>
36 #include <TColStd_Array1OfInteger.hxx>
37 #include <TColgp_Array1OfPnt.hxx>
38 #include <TColgp_Array1OfPnt2d.hxx>
39
40 #include <ShapeBuild_Edge.hxx>
41 #include <ShapeConstruct.hxx>
42 #include <ShapeCustom.hxx>
43 #include <ShapeCustom_Surface.hxx>
44 #include <ShapeAnalysis.hxx>
45 #include <ShapeAnalysis_Edge.hxx>
46 #include <ShapeFix.hxx>
47 #include <ShapeFix_Edge.hxx>
48 #include <ShapeUpgrade.hxx>
49 #include <ShapeUpgrade_ShapeDivideContinuity.hxx>
50 #include <ShapeExtend_WireData.hxx>
51 #include <ShapeExtend_WireData.hxx>
52 #include <TopExp.hxx>
53 #include <gp_Pnt.hxx>
54 #include <Precision.hxx>
55 #include <ShapeFix_Wire.hxx>
56 #include <BRepTools.hxx>
57
58 //=======================================================================
59 //function : ShapeAlgo_AlgoContainer
60 //purpose  : 
61 //=======================================================================
62
63 ShapeAlgo_AlgoContainer::ShapeAlgo_AlgoContainer()
64 {
65   myTC = new ShapeAlgo_ToolContainer;
66 }
67
68 //=======================================================================
69 //function : ConnectNextWire
70 //purpose  : 
71 //=======================================================================
72
73 Standard_Boolean ShapeAlgo_AlgoContainer::ConnectNextWire (const Handle(ShapeAnalysis_Wire)& saw,
74                                                            const Handle(ShapeExtend_WireData)& nextsewd,
75                                                            const Standard_Real maxtol,
76                                                            Standard_Real& distmin,
77                                                            Standard_Boolean& revsewd,
78                                                            Standard_Boolean& revnextsewd) const
79 {
80   distmin = 0;
81   revsewd = revnextsewd = Standard_False;
82   if (nextsewd->NbEdges() == 0) return Standard_True;
83   
84   Handle(ShapeExtend_WireData) sewd = saw->WireData();
85   //add edges into empty WireData
86   if(sewd->NbEdges() == 0) {
87     sewd->Add (nextsewd);
88     return Standard_True;
89   }
90   
91   Standard_Real tailhead, tailtail, headtail, headhead;
92   saw->CheckShapeConnect (tailhead, tailtail, headtail, headhead, nextsewd->Wire(), maxtol);
93   distmin = tailhead;
94   Standard_Real precision = saw->Precision();
95   
96   if ( tailhead > precision && tailtail > precision &&
97        ( saw->LastCheckStatus (ShapeExtend_DONE4) ||
98          saw->LastCheckStatus (ShapeExtend_DONE3) ) ) {
99     sewd->Reverse();
100     distmin = headhead;
101     revsewd = Standard_True;
102     if (saw->LastCheckStatus (ShapeExtend_DONE3)) {
103       nextsewd->Reverse();
104       revnextsewd = Standard_True;
105       distmin = headtail;
106     }
107   }
108   else if (!saw->LastCheckStatus (ShapeExtend_FAIL) && !saw->LastCheckStatus (ShapeExtend_DONE5)) {
109     nextsewd->Reverse();
110     revnextsewd = Standard_True;
111     distmin     = tailtail;
112   }
113   Standard_Boolean OK = !saw->LastCheckStatus (ShapeExtend_FAIL);
114   if (OK) sewd->Add (nextsewd);
115   return OK;
116 }
117
118 //=======================================================================
119 //function : ApproxBSplineCurve
120 //purpose  : 
121 //=======================================================================
122
123 void ShapeAlgo_AlgoContainer::ApproxBSplineCurve (const Handle(Geom_BSplineCurve)& bspline,
124                                                   TColGeom_SequenceOfCurve& seq) const
125 {
126   seq.Clear();
127   Handle(Geom_BSplineCurve)  res, modifCurve;
128   TColGeom_SequenceOfCurve SCurve;
129
130   // si la BSpline est de degre 1 , on approxime .
131   // on passe par le programme des intersections ou tout le travail
132   // est deja fait !!! ( il faut faire des paquets de 30 points
133   // maximum , travailler dans un espace 0,1 pour tenir la precision)
134   
135   if (bspline->Degree() != 1) {
136     seq.Append(bspline);
137     return;
138   }
139
140   // on detecte d`eventuelles cassures par la multiplicite des poles.
141   // Puis on approxime chaque "partie" de BSpline 
142
143   Standard_Integer NbKnots = bspline->NbKnots();
144   Standard_Integer NbPoles = bspline->NbPoles();
145   TColgp_Array1OfPnt      Poles(1,NbPoles);
146   TColStd_Array1OfReal    Weigs(1,NbPoles); Weigs.Init(1.);
147   TColStd_Array1OfReal    Knots(1,NbKnots);
148   TColStd_Array1OfInteger Mults(1,NbKnots); 
149
150   bspline->Poles(Poles);
151   if ( bspline->IsRational()) bspline->Weights(Weigs);
152   bspline->Knots(Knots);
153   bspline->Multiplicities(Mults);
154   Standard_Integer deg = bspline->Degree();
155   
156   Standard_Integer jpole = 1;
157   Standard_Integer j, PoleIndex, I1;
158   PoleIndex = 1;
159   I1 = 1;
160   for ( Standard_Integer ipole = 1; ipole < NbPoles; ipole++) {
161     if (Poles(ipole).IsEqual(Poles(ipole+1),Precision::Confusion())) {
162       if (jpole == 1) {
163         PoleIndex++;
164       }
165       else {
166         TColgp_Array1OfPnt      newPoles(1,jpole);
167         TColStd_Array1OfReal    newWeigs(1,jpole); Weigs.Init(1.);
168         Standard_Integer NbNew = jpole - deg + 1;
169         TColStd_Array1OfReal    newKnots(1,NbNew);
170         TColStd_Array1OfInteger newMults(1,NbNew);
171         for ( j = 1; j <= NbNew; j++) {
172           newKnots(j) = Knots(I1+j-1);
173           newMults(j) = Mults(I1+j-1);
174         }
175         newMults(1) = newMults(NbNew) = deg+1;
176         for ( j = 1; j <= jpole; j++) {
177           newWeigs(j) = Weigs(PoleIndex  );
178           newPoles(j) = Poles(PoleIndex++);
179         }
180         
181         Handle(Geom_BSplineCurve) newC = new Geom_BSplineCurve
182           (newPoles, newWeigs, newKnots, newMults, deg);
183         SCurve.Append(newC);
184         I1 = ipole+1;
185         jpole = 1;
186       }
187     }
188     else {
189       jpole++;
190     }
191   }  
192     
193
194   Handle(Geom_BSplineCurve) mycurve;
195   Standard_Integer nbcurves = SCurve.Length();
196   if (nbcurves == 0) {
197     nbcurves = 1;
198     SCurve.Append(bspline);
199   }
200                         
201   for (Standard_Integer itab = 1; itab <= nbcurves; itab++) { 
202     mycurve = Handle(Geom_BSplineCurve)::DownCast(SCurve.Value(itab));
203     jpole = mycurve->NbPoles();
204     if ( jpole > 2) {
205       TColgp_Array1OfPnt newP(1,jpole);      
206       mycurve->Poles(newP);
207       Handle(IntSurf_LineOn2S) R = new IntSurf_LineOn2S();
208       Standard_Real u1,v1,u2,v2;
209       u1 = v1 = 0.;
210       u2 = v2 = 1.;
211       for( j=1; j<=jpole; j++) {
212         IntSurf_PntOn2S POn2S;
213         POn2S.SetValue(newP(j),u1,v1,u2,v2);
214         R->Add(POn2S);
215       }
216       GeomInt_WLApprox theapp3d;
217       Standard_Real Tol = Precision::Approximation();
218       theapp3d.SetParameters(Tol, Tol, 4, 8, 0, Standard_True);
219       Handle(IntPatch_WLine) WL = new IntPatch_WLine(R, Standard_False);
220       Standard_Integer indicemin = 1;
221       Standard_Integer indicemax = jpole;
222       theapp3d.Perform(WL, Standard_True, Standard_False, 
223                        Standard_False, indicemin, indicemax);
224       if (!theapp3d.IsDone()) {
225         modifCurve = mycurve; 
226       }
227       else if (theapp3d.NbMultiCurves() != 1) {
228         modifCurve = mycurve;
229       }
230       else {
231         const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(1);
232         Standard_Integer nbpoles = mbspc.NbPoles();
233         TColgp_Array1OfPnt tpoles(1,nbpoles);
234         mbspc.Curve(1,tpoles);
235         modifCurve = new Geom_BSplineCurve(tpoles,
236                                            mbspc.Knots(),
237                                            mbspc.Multiplicities(),
238                                            mbspc.Degree());
239       }
240     }
241     else {
242       modifCurve = mycurve;
243     }
244     seq.Append(modifCurve);
245   }
246 }
247
248 //=======================================================================
249 //function : ApproxBSplineCurve
250 //purpose  : 
251 //=======================================================================
252
253 void ShapeAlgo_AlgoContainer::ApproxBSplineCurve (const Handle(Geom2d_BSplineCurve)& bspline,
254                                                   TColGeom2d_SequenceOfCurve& seq) const
255 {
256   seq.Clear();
257   Handle(Geom2d_BSplineCurve)  res, modifCurve;
258   TColGeom2d_SequenceOfCurve SCurve;
259
260   // si la BSpline est de degre 1 , on approxime .
261   // on passe par le programme des intersections ou tout le travail
262   // est deja fait !!! ( il faut faire des paquets de 30 points
263   // maximum , travailler dans un espace 0,1 pour tenir la precision
264   // puis reconstruire une BSpline somme des toutes les Bspline).
265
266   if (bspline->Degree() != 1) {
267     seq.Append(bspline);
268     return;
269   }
270
271   // on detecte d`eventuelles cassures par la multiplicite des poles.
272   // Puis on approxime chaque "partie" de BSpline et on reconstruit 
273   // une BSpline = somme des BSplines traitees 
274
275   Standard_Integer NbKnots = bspline->NbKnots();
276   Standard_Integer NbPoles = bspline->NbPoles();
277   TColgp_Array1OfPnt2d    Poles(1,NbPoles);
278   TColStd_Array1OfReal    Weigs(1,NbPoles); Weigs.Init(1.);
279   TColStd_Array1OfReal    Knots(1,NbKnots);
280   TColStd_Array1OfInteger Mults(1,NbKnots); 
281
282   bspline->Poles(Poles);
283   if ( bspline->IsRational()) bspline->Weights(Weigs);
284   bspline->Knots(Knots);
285   bspline->Multiplicities(Mults);
286   Standard_Integer deg = bspline->Degree();
287   
288   Standard_Integer jpole = 1;
289   Standard_Integer j, PoleIndex, I1;
290   PoleIndex = 1;
291   I1 = 1;
292   for ( Standard_Integer ipole = 1; ipole < NbPoles; ipole++) {
293     if (Poles(ipole).IsEqual(Poles(ipole+1),Precision::PConfusion())) {
294       if (jpole == 1) {
295         PoleIndex++;
296       }
297       else {
298         TColgp_Array1OfPnt2d    newPoles(1,jpole);
299         TColStd_Array1OfReal    newWeigs(1,jpole); Weigs.Init(1.);
300         Standard_Integer NbNew = jpole - deg + 1;
301         TColStd_Array1OfReal    newKnots(1,NbNew);
302         TColStd_Array1OfInteger newMults(1,NbNew);
303         for ( j = 1; j <= NbNew; j++) {
304           newKnots(j) = Knots(I1+j-1);
305           newMults(j) = Mults(I1+j-1);
306         }
307         newMults(1) = newMults(NbNew) = deg+1;
308         for ( j = 1; j <= jpole; j++) {
309           newWeigs(j) = Weigs(PoleIndex  );
310           newPoles(j) = Poles(PoleIndex++);
311         }
312         
313         Handle(Geom2d_BSplineCurve) newC = new Geom2d_BSplineCurve
314           (newPoles, newWeigs, newKnots, newMults, deg);
315         SCurve.Append(newC);
316         I1 = ipole+1;
317         jpole = 1;
318       }
319     }
320     else {
321       jpole++;
322     }
323   }  
324     
325
326   Handle(Geom2d_BSplineCurve) mycurve;
327   Standard_Integer nbcurves = SCurve.Length();
328   if (nbcurves == 0) {
329     nbcurves = 1;
330     SCurve.Append(bspline);
331   }
332   
333   for (Standard_Integer itab = 1; itab <= nbcurves; itab++) { 
334     mycurve = Handle(Geom2d_BSplineCurve)::DownCast(SCurve.Value(itab));
335     jpole = mycurve->NbPoles();
336     if ( jpole > 10) {
337       TColgp_Array1OfPnt P(1,jpole);      
338       TColgp_Array1OfPnt2d newP(1,jpole);      
339       mycurve->Poles(newP);
340       Handle(IntSurf_LineOn2S) R = new IntSurf_LineOn2S();
341       Standard_Real u2,v2;
342       u2 = v2 = 1.;
343       for( j=1; j<=jpole; j++) {
344         IntSurf_PntOn2S POn2S;
345         POn2S.SetValue(P(j),newP(j).X(),newP(j).Y(),u2,v2);
346         R->Add(POn2S);
347       }
348       GeomInt_WLApprox theapp3d;
349       Standard_Real Tol = Precision::PApproximation();
350       theapp3d.SetParameters(Tol, Tol, 4, 8, 0, Standard_True);
351       Handle(IntPatch_WLine) WL = new IntPatch_WLine(R, Standard_False);
352       Standard_Integer indicemin = 1;
353       Standard_Integer indicemax = jpole;
354       theapp3d.Perform(WL, Standard_False, Standard_True, 
355                        Standard_False, indicemin, indicemax);
356       if (!theapp3d.IsDone()) {
357         modifCurve = mycurve; 
358       }
359       else if (theapp3d.NbMultiCurves() != 1) {
360         modifCurve = mycurve;
361       }
362       else {
363         const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(1);
364         Standard_Integer nbpoles = mbspc.NbPoles();
365         TColgp_Array1OfPnt2d tpoles(1,nbpoles);
366         mbspc.Curve(1,tpoles);
367         for( j=1; j<=jpole; j++) {      
368         }
369         modifCurve = new Geom2d_BSplineCurve(tpoles,
370                                              mbspc.Knots(),
371                                              mbspc.Multiplicities(),
372                                              mbspc.Degree());
373       }
374     }
375     else {
376       modifCurve = mycurve;
377     }
378     seq.Append(modifCurve);
379   }
380 }
381
382 //=======================================================================
383 //function : C0ShapeToC1Shape
384 //purpose  : 
385 //=======================================================================
386
387  TopoDS_Shape ShapeAlgo_AlgoContainer::C0ShapeToC1Shape (const TopoDS_Shape& shape,
388                                                             const Standard_Real tol) const
389 {
390   ShapeUpgrade_ShapeDivideContinuity sdc(shape);
391   sdc.SetTolerance(tol);
392   sdc.SetBoundaryCriterion(GeomAbs_C1);
393   sdc.SetSurfaceCriterion(GeomAbs_C1);
394   sdc.Perform();
395   return sdc.Result();
396 }
397
398 //=======================================================================
399 //function : ConvertSurfaceToBSpline
400 //purpose  : 
401 //=======================================================================
402
403  Handle(Geom_BSplineSurface) ShapeAlgo_AlgoContainer::ConvertSurfaceToBSpline(const Handle(Geom_Surface)& surf,
404                                                                                  const Standard_Real UF,
405                                                                                  const Standard_Real UL,
406                                                                                  const Standard_Real VF,
407                                                                                  const Standard_Real VL) const
408 {
409   return ShapeConstruct::ConvertSurfaceToBSpline(surf, UF, UL, VF, VL,
410                                                     Precision::Confusion(), GeomAbs_C1, 100,
411                                                     Geom_BSplineSurface::MaxDegree());
412 }
413
414 //=======================================================================
415 //function : HomoWires
416 //purpose  : 
417 //=======================================================================
418
419  Standard_Boolean ShapeAlgo_AlgoContainer::HomoWires(const TopoDS_Wire& wireIn1,
420                                                         const TopoDS_Wire& wireIn2,
421                                                         TopoDS_Wire& wireOut1,
422                                                         TopoDS_Wire& wireOut2,
423                                                         const Standard_Boolean) const
424 {
425   //Standard_Boolean res = Standard_False; //szv#4:S4163:12Mar99 not needed
426   TopoDS_Iterator  Cook,      Perry;
427   TopoDS_Edge      edge1,     edge2;
428   TopLoc_Location  loc1,      loc2;
429 //  BRepBuilderAPI_MakeWire makeWire1, makeWire2;
430   ShapeExtend_WireData makeWire1, makeWire2;
431   Standard_Boolean iterCook,  iterPerry;
432   Standard_Integer nEdges1,   nEdges2;
433   Standard_Real    length1,   length2;
434   Standard_Real    first1,    first2;
435   Standard_Real    last1,     last2;
436   Standard_Real    delta1,    delta2;
437
438   Handle (Geom_Curve) crv1;
439   Handle (Geom_Curve) crv2;
440
441   //Standard_Boolean notEnd  = Standard_True; //szv#4:S4163:12Mar99 unused
442   Standard_Integer nbCreatedEdges = 0;
443   // gka
444   //TopoDS_Vertex v11,v12,v21,v22
445   Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire();
446   sfw->Load(wireIn1);
447   sfw->FixReorder();
448   TopoDS_Wire wireIn11 = sfw->Wire() ;
449   sfw->Load(wireIn2);
450   sfw->FixReorder();
451   TopoDS_Wire wireIn22 = sfw->Wire() ;
452   
453   iterCook = iterPerry = Standard_True;
454   length1  = length2   = 0.;
455   nEdges1  = nEdges2   = 0;
456   for (Cook.Initialize(wireIn11); Cook.More(); Cook.Next()) {
457     nEdges1++;
458     edge1    = TopoDS::Edge(Cook.Value());
459     crv1     = BRep_Tool::Curve(edge1, loc1, first1, last1);
460     length1 += last1 - first1;
461   }
462   for (Perry.Initialize(wireIn22); Perry.More(); Perry.Next()) {
463     nEdges2++;
464     edge2    = TopoDS::Edge(Perry.Value());
465     crv2     = BRep_Tool::Curve(edge2, loc2, first2, last2);
466     length2 += last2 - first2;
467   }
468   Standard_Real epsilon = Precision::PConfusion() * (length1 + length2);
469   if (nEdges1 == 1 && nEdges2 == 1){
470     wireOut1 = wireIn11;
471     wireOut2 = wireIn22;
472     return Standard_True; //szv#4:S4163:12Mar99 `res=` not needed
473   }
474
475   if (length1 < epsilon) { 
476     Cook.Initialize(wireIn11);
477     for (Perry.Initialize(wireIn22); Perry.More(); Perry.Next()) {
478       edge1  = TopoDS::Edge(Cook.Value());
479       makeWire1.Add(edge1);
480     }
481     wireOut1 = makeWire1.Wire();
482     wireOut2 = wireIn22;
483     return Standard_True; //szv#4:S4163:12Mar99 `res=` not needed
484   }
485   if (length2 < epsilon) {
486     Perry.Initialize(wireIn22);
487     for (Cook.Initialize(wireIn11); Cook.More(); Cook.Next()) {
488       edge2 = TopoDS::Edge(Perry.Value());
489       makeWire2.Add(edge2);
490     }
491     wireOut1 = wireIn11;
492     wireOut2 = makeWire2.Wire();
493     return Standard_True; //szv#4:S4163:12Mar99 `res=` not needed
494   }
495
496
497   Standard_Real ratio = length2 / length1;
498
499   Cook.Initialize(wireIn11);
500   Perry.Initialize(wireIn22);
501   edge1  = TopoDS::Edge(Cook.Value());
502   edge2  = TopoDS::Edge(Perry.Value());
503   // essai mjm du 22/05/97 
504   Standard_Boolean IsToReverse1 = Standard_False;
505   Standard_Boolean IsToReverse2 = Standard_False;
506   if (edge1.Orientation() == TopAbs_REVERSED)
507     IsToReverse1 = Standard_True;
508   if (edge2.Orientation() == TopAbs_REVERSED)
509     IsToReverse2 = Standard_True;
510   crv1   = BRep_Tool::Curve(edge1, loc1, first1, last1);
511   crv2   = BRep_Tool::Curve(edge2, loc2, first2, last2);
512   delta1 = last1 - first1;
513   delta2 = last2 - first2;
514   while (nbCreatedEdges < (nEdges1 + nEdges2-1)) {  /*just a security. */
515
516     if ((delta1*ratio - delta2) > epsilon) {
517       BRepBuilderAPI_MakeEdge makeEdge1;
518       if(!IsToReverse1) {
519         makeEdge1.Init(crv1, first1, first1 + delta2/ratio);
520         first1+= delta2/ratio;
521       }
522       else {                                               // gka BUC60685
523         makeEdge1.Init(crv1, last1 - delta2/ratio , last1);
524         last1 -= delta2/ratio;
525       }
526       BRepBuilderAPI_MakeEdge makeEdge2(crv2, first2, last2);
527       edge1 = makeEdge1.Edge();
528       edge2 = makeEdge2.Edge();
529 // essai mjm du 22/05/97
530       iterCook  = Standard_False;
531       //first1   += delta2/ratio;
532       delta1    = last1 - first1;
533       iterPerry = Standard_True;
534       nbCreatedEdges++;
535     }
536     else if (Abs(delta1*ratio - delta2) <= epsilon) {
537       BRepBuilderAPI_MakeEdge makeEdge1(crv1, first1, last1);
538       BRepBuilderAPI_MakeEdge makeEdge2(crv2, first2, last2);
539       edge1 = makeEdge1.Edge();
540       edge2 = makeEdge2.Edge();
541       iterCook  = Standard_True;
542       iterPerry = Standard_True;
543       nbCreatedEdges += 2;
544     }
545     else /*((delta1*ratio - delta2) < -epsilon)*/ {
546       BRepBuilderAPI_MakeEdge makeEdge1(crv1, first1, last1);
547       edge1 = makeEdge1.Edge();
548       BRepBuilderAPI_MakeEdge makeEdge2;
549       if(!IsToReverse2) {
550         makeEdge2.Init(crv2, first2, first2 + delta1*ratio);
551         first2   += delta1*ratio;
552       }
553       else {                                              // gka BUC60685
554         makeEdge2.Init(crv2, last2 - delta1*ratio, last2);
555         last2 -= delta1*ratio;
556       }
557       edge1 = makeEdge1.Edge();
558       edge2 = makeEdge2.Edge();
559       iterCook  = Standard_True;
560       iterPerry = Standard_False;
561       //first2   += delta1*ratio;
562       delta2    = last2 - first2;
563       nbCreatedEdges++;
564     }
565     edge1.Move(loc1);
566     edge2.Move(loc2);
567     if ( IsToReverse1) edge1.Reverse();
568     if ( IsToReverse2) edge2.Reverse();
569     makeWire1.Add(edge1);
570     makeWire2.Add(edge2);
571
572     if (iterCook && iterPerry) {
573       TopoDS_Iterator Copernic = Cook;
574       if (Copernic.More())
575           Copernic.Next();
576       if (!Copernic.More()) {
577           wireOut1 = makeWire1.Wire();
578           wireOut2 = makeWire2.Wire();
579         return Standard_True; //szv#4:S4163:12Mar99 `res=` not needed
580       }
581     }
582     if (iterCook) {
583       Cook.Next();
584       edge1  = TopoDS::Edge(Cook.Value());
585       if (edge1.Orientation() == TopAbs_REVERSED)
586         IsToReverse1 = Standard_True;
587       else IsToReverse1 = Standard_False;
588       crv1   = BRep_Tool::Curve(edge1, loc1, first1, last1);
589       delta1 = last1 - first1;
590     }
591     if (iterPerry) {
592       Perry.Next();
593       edge2  = TopoDS::Edge(Perry.Value());
594       if (edge2.Orientation() == TopAbs_REVERSED)
595         IsToReverse2 = Standard_True;
596       else IsToReverse2 = Standard_False;
597       crv2   = BRep_Tool::Curve(edge2, loc2, first2, last2);
598       delta2 = last2 - first2;
599     }
600
601   }
602   return Standard_False; //szv#4:S4163:12Mar99 `res=` not needed
603 }
604
605 //=======================================================================
606 //function : C0BSplineToSequenceOfC1BSplineCurve
607 //purpose  : 
608 //=======================================================================
609
610  Standard_Boolean ShapeAlgo_AlgoContainer::C0BSplineToSequenceOfC1BSplineCurve(const Handle(Geom_BSplineCurve)& BS,
611                                                                                Handle(TColGeom_HSequenceOfBoundedCurve)& seqBS) const 
612 {
613   return ShapeUpgrade::C0BSplineToSequenceOfC1BSplineCurve (BS, seqBS);
614 }
615
616 //=======================================================================
617 //function : C0BSplineToSequenceOfC1BSplineCurve
618 //purpose  : 
619 //=======================================================================
620
621  Standard_Boolean ShapeAlgo_AlgoContainer::C0BSplineToSequenceOfC1BSplineCurve(const Handle(Geom2d_BSplineCurve)& BS,
622                                                                                Handle(TColGeom2d_HSequenceOfBoundedCurve)& seqBS) const
623 {
624   return ShapeUpgrade::C0BSplineToSequenceOfC1BSplineCurve (BS, seqBS);
625 }
626
627 //=======================================================================
628 //function : OuterWire
629 //purpose  : 
630 //=======================================================================
631
632 TopoDS_Wire ShapeAlgo_AlgoContainer::OuterWire(const TopoDS_Face& face) const
633 {
634   return ShapeAnalysis::OuterWire(face);
635 }
636
637 //=======================================================================
638 //function : ConvertToPeriodic
639 //purpose  : 
640 //=======================================================================
641
642  Handle(Geom_Surface) ShapeAlgo_AlgoContainer::ConvertToPeriodic (const Handle(Geom_Surface)& surf) const
643 {
644   ShapeCustom_Surface scs (surf);
645   return scs.ConvertToPeriodic (Standard_False);
646 }
647
648 //=======================================================================
649 //function : GetFaceUVBounds
650 //purpose  : 
651 //=======================================================================
652
653  void ShapeAlgo_AlgoContainer::GetFaceUVBounds (const TopoDS_Face& F,
654                                                 Standard_Real& Umin,
655                                                 Standard_Real& Umax,
656                                                 Standard_Real& Vmin,
657                                                 Standard_Real& Vmax) const
658 {
659   ShapeAnalysis::GetFaceUVBounds (F, Umin, Umax, Vmin, Vmax);
660 }
661
662 //=======================================================================
663 //function : ConvertCurveToBSpline
664 //purpose  : 
665 //=======================================================================
666
667 Handle(Geom_BSplineCurve) ShapeAlgo_AlgoContainer::ConvertCurveToBSpline(const Handle(Geom_Curve)& C3D,
668                                                                          const Standard_Real First,
669                                                                          const Standard_Real Last,
670                                                                          const Standard_Real Tol3d,
671                                                                          const GeomAbs_Shape Continuity, 
672                                                                          const Standard_Integer MaxSegments,
673                                                                          const Standard_Integer MaxDegree) const
674 {
675   return  ShapeConstruct::ConvertCurveToBSpline(C3D, First, Last, Tol3d, Continuity,  MaxSegments, MaxDegree);
676 }