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