0029151: GCC 7.1 warnings "this statement may fall through" [-Wimplicit-fallthrough=]
[occt.git] / src / IGESConvGeom / IGESConvGeom.cxx
1 // Created on: 1994-09-01
2 // Created by: Christian CAILLET
3 // Copyright (c) 1994-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 // modif du 31/01/97 : mjm
18 // on commence par les SplineCurves.
19 // modif du 17/03/97 : mjm
20 // SplineSurfaces.
21 //%13 pdn 12.02.99: USA60293 avoid applying transformation twice
22
23 #include <BSplCLib.hxx>
24 #include <BSplSLib.hxx>
25 #include <Geom2d_BSplineCurve.hxx>
26 #include <Geom_BSplineCurve.hxx>
27 #include <Geom_BSplineSurface.hxx>
28 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
29 #include <gp_GTrsf.hxx>
30 #include <gp_Trsf.hxx>
31 #include <IGESConvGeom.hxx>
32 #include <IGESData_ToolLocation.hxx>
33 #include <IGESGeom_SplineCurve.hxx>
34 #include <IGESGeom_SplineSurface.hxx>
35 #include <PLib.hxx>
36 #include <TColgp_HArray1OfPnt.hxx>
37 #include <TColgp_HArray2OfPnt.hxx>
38 #include <TColStd_Array1OfInteger.hxx>
39 #include <TColStd_Array1OfReal.hxx>
40 #include <TColStd_HArray1OfReal.hxx>
41
42 //=======================================================================
43 //function : IGESConvGeom::SplineCurveFromIGES
44 //purpose  : 
45 //=======================================================================
46 Standard_Integer  IGESConvGeom::SplineCurveFromIGES
47   (const Handle(IGESGeom_SplineCurve)& st,
48    const Standard_Real /*epscoef*/,  const Standard_Real epsgeom,
49    Handle(Geom_BSplineCurve)& res)
50 {
51   Standard_Integer returned = 0;
52
53   // on recupere le degre
54   Standard_Integer degree = st->SplineType();
55   if (degree > 3) degree = 3;
56
57   // on recupere le nombre de segments.
58   Standard_Integer nbSegs  = st->NbSegments();  
59   if (nbSegs < 1) return 5;            // FAIL : no segment
60
61   Standard_Integer nbKnots = nbSegs+1;          
62
63   // Array of multiplicities.  
64   TColStd_Array1OfInteger multi(1, nbKnots); 
65   multi.Init(degree);
66   multi.SetValue(multi.Lower(), degree+1);
67   multi.SetValue(multi.Upper(), degree+1);
68
69   // Array of knots.  
70   TColStd_Array1OfReal knots(1, nbKnots);                 
71   TColStd_Array1OfReal delta(1, nbSegs);
72   Standard_Integer i; // svv Jan 10 2000 : porting on DEC
73   for (i = 1; i<= nbKnots; i++)
74     knots.SetValue(i, st->BreakPoint(i));
75
76   for (i = 1; i <= nbSegs; i++) 
77     delta.SetValue(i, st->BreakPoint(i+1) - st->BreakPoint(i));
78
79   TColgp_Array1OfPnt bspoles(1, nbSegs*degree+1);
80   Standard_Integer ibspole = bspoles.Lower()-1;              // Bspole Index.
81   // il faut reparametrer avant de passer dans PLib.
82   // on est entre[0, T(i+1)-T(i)] et on veut [0,1]
83
84   for (i = 1; i <= nbSegs; i++) {
85     Standard_Real AX,BX,CX,DX,AY,BY,CY,DY,AZ,BZ,CZ,DZ;
86     st->XCoordPolynomial(i, AX, BX, CX, DX);
87     st->YCoordPolynomial(i, AY, BY, CY, DY);
88     st->ZCoordPolynomial(i, AZ, BZ, CZ, DZ);
89     if (st->NbDimensions() == 2 ) BZ=0.,CZ=0.,DZ=0.; 
90     Standard_Real Di  = delta(i);
91     Standard_Real Di2 = delta(i)*delta(i);
92     Standard_Real Di3 = delta(i)*delta(i)*delta(i);
93
94     TColgp_Array1OfPnt coeff(0, degree);
95     switch (degree) {
96     case 3 :
97       coeff.SetValue(coeff.Lower()+3, gp_Pnt(DX*Di3, DY*Di3, DZ*Di3));
98         Standard_FALLTHROUGH
99     case 2 :
100       coeff.SetValue(coeff.Lower()+2, gp_Pnt(CX*Di2, CY*Di2, CZ*Di2));
101         Standard_FALLTHROUGH
102     case 1 :
103       coeff.SetValue(coeff.Lower()+1, gp_Pnt(BX*Di, BY*Di, BZ*Di));
104       coeff.SetValue(coeff.Lower()+0, gp_Pnt(AX, AY, AZ));
105       break;
106     default:
107       break;
108     }
109
110
111     TColgp_Array1OfPnt bzpoles(0, degree);
112     PLib::CoefficientsPoles(coeff,PLib::NoWeights(),bzpoles,PLib::NoWeights());
113
114     // C0 test.
115     // Not to check the first pole of the first segment.
116     if (ibspole > bspoles.Lower()) {  
117       Standard_Integer bzlow = bzpoles.Lower();
118       if (!(bspoles.Value(ibspole).IsEqual(bzpoles.Value(bzlow), epsgeom))) {
119         returned = 1;
120         // Medium point computing.
121         bspoles.SetValue (ibspole, 
122            gp_Pnt((bspoles.Value(ibspole).X() + bzpoles.Value(bzlow).X())/2.,
123                   (bspoles.Value(ibspole).Y() + bzpoles.Value(bzlow).Y())/2.,
124                   (bspoles.Value(ibspole).Z() + bzpoles.Value(bzlow).Z())/2.));
125       }
126     }
127     if (i == 1) bspoles.SetValue(++ibspole, bzpoles.Value(bzpoles.Lower()));
128
129     for (Standard_Integer j = bzpoles.Lower()+1; j <= bzpoles.Upper(); j++) 
130       bspoles.SetValue(++ibspole, bzpoles.Value(j));
131   }
132   if (ibspole != bspoles.Upper()) {   
133     // Just to be sure.
134     return 3;           // FAIL : Error during creation of control points
135   }
136
137   //  Building result taking into account transformation if any :
138   //  ===========================================================
139   
140   //%13 pdn 12.02.99 USA60293
141 //  if (st->HasTransf()) {
142 //    gp_Trsf trsf;
143 //    Standard_Real epsilon = 1.E-04;
144 //    if (IGESData_ToolLocation::ConvertLocation
145 //      (epsilon,st->CompoundLocation(),trsf)) { 
146 //      for (Standard_Integer i = bspoles.Lower(); i <= bspoles.Upper(); i++) 
147 //      bspoles.SetValue(i, bspoles.Value(i).Transformed(trsf));
148 //    }
149 //    else
150 //      AddFail(st, "Transformation : not a similarity");
151 //  }
152   res = new Geom_BSplineCurve (bspoles, knots, multi, degree);
153 //  GeomConvert_CompCurveToBSplineCurve CompCurve = 
154 //    GeomConvert_CompCurveToBSplineCurve(res);
155 //  res = CompCurve.BSplineCurve();
156   return returned;
157 }
158
159
160
161 //=======================================================================
162 //function : IGESConvGeom::IncreaseCurveContinuity
163 //purpose  : 
164 //=======================================================================
165 Standard_Integer IGESConvGeom::IncreaseCurveContinuity (const Handle(Geom_BSplineCurve)& res,
166                                                         const Standard_Real epsgeom,
167                                                         const Standard_Integer continuity)
168 {
169   if (continuity < 1) return continuity;
170   Standard_Boolean isC1 = Standard_True, isC2 = Standard_True;
171   Standard_Integer degree = res->Degree();
172
173   
174   Standard_Boolean isModified;
175   do {
176     isModified = Standard_False;
177     for (Standard_Integer i = res->FirstUKnotIndex()+1; i < res->LastUKnotIndex(); i++) 
178       if(degree - res->Multiplicity(i) < continuity) {
179         if (continuity >= 2) {
180           if (!res->RemoveKnot(i, degree-2, epsgeom)) {
181             isC2 = Standard_False;
182             Standard_Boolean locOK = res->RemoveKnot(i, degree-1, epsgeom);   // is C1 ?
183             isC1 &= locOK;
184             isModified |= locOK;
185           }
186           else
187             isModified = Standard_True;
188         }
189         else {
190           Standard_Boolean locOK = res->RemoveKnot(i, degree-1, epsgeom);   // is C1 ?
191           isC1 &= locOK;
192           isModified |= locOK;
193         }
194       }
195   }
196   while (isModified);
197     
198   if (!isC1) return 0;
199   if (continuity >= 2 && !isC2) return 1;
200   return continuity;
201 }
202
203 //=======================================================================
204 //function : IncreaseCurveContinuity
205 //purpose  : 
206 //=======================================================================
207
208 Standard_Integer IGESConvGeom::IncreaseCurveContinuity (const Handle(Geom2d_BSplineCurve)& res,
209                                                         const Standard_Real epsgeom,
210                                                         const Standard_Integer continuity)
211 {
212   if (continuity < 1) return continuity;
213   Standard_Boolean isC1 = Standard_True, isC2 = Standard_True;
214   Standard_Integer degree = res->Degree();
215
216   Standard_Boolean isModified;
217   do {
218     isModified = Standard_False;
219     for (Standard_Integer i = res->FirstUKnotIndex()+1; i < res->LastUKnotIndex(); i++) 
220       if(degree - res->Multiplicity(i) < continuity) {
221         if (continuity >= 2) {
222           if (!res->RemoveKnot(i, degree-2, epsgeom)) {
223             isC2 = Standard_False;
224             Standard_Boolean locOK = res->RemoveKnot(i, degree-1, epsgeom);   // is C1 ?
225             isC1 &= locOK;
226             isModified |= locOK;
227           }
228           else
229             isModified = Standard_True;
230         }
231         else {
232           Standard_Boolean locOK = res->RemoveKnot(i, degree-1, epsgeom);   // is C1 ?
233           isC1 &= locOK;
234           isModified |= locOK;
235         }
236       }
237   }
238   while (isModified);
239
240   if (!isC1) return 0;
241   if (continuity >= 2 && !isC2) return 1;
242   return continuity;
243 }
244
245
246 //=======================================================================
247 //function : IGESConvGeom::SplineSurfaceFromIGES
248 //purpose  : 
249 //=======================================================================
250 Standard_Integer  IGESConvGeom::SplineSurfaceFromIGES
251   (const Handle(IGESGeom_SplineSurface)& st,
252    const Standard_Real /*epscoef*/,  const Standard_Real epsgeom,
253    Handle(Geom_BSplineSurface)& res)
254 {
255   Standard_Integer returned = 0;
256   Standard_Integer degree = st->BoundaryType();
257   if (degree > 3) degree = 3;
258   Standard_Integer DegreeU = degree;
259   Standard_Integer DegreeV = degree;
260   
261   Standard_Integer  NbUSeg = st->NbUSegments();  
262   Standard_Integer  NbVSeg = st->NbVSegments();  
263   
264   if ((NbUSeg < 1) || (NbVSeg < 1)) return 5;
265   
266   //  Output BSpline knots & multiplicities arraies for U & V :
267   //  =========================================================
268
269   TColStd_Array1OfReal  UKnot(1,NbUSeg+1);
270   TColStd_Array1OfReal  VKnot(1,NbVSeg+1);
271   TColStd_Array1OfReal  deltaU(1,NbUSeg);
272   TColStd_Array1OfReal  deltaV(1,NbVSeg);
273
274   Standard_Integer i; // svv Jan 10 2000 : porting on DEC
275   for (i=1; i <= NbUSeg+1; i++)
276     UKnot.SetValue(i, st->UBreakPoint(i));
277
278   for (i=1; i <= NbUSeg; i++)
279     deltaU.SetValue(i, st->UBreakPoint(i+1)- st->UBreakPoint(i));
280
281   for (i=1; i <= NbVSeg+1; i++)
282     VKnot.SetValue(i, st->VBreakPoint(i));
283
284   for (i=1; i <= NbVSeg; i++) 
285     deltaV.SetValue(i, st->VBreakPoint(i+1)- st->VBreakPoint(i));
286
287   TColStd_Array1OfInteger  UMult(1,NbUSeg+1); UMult.Init(DegreeU);
288   UMult.SetValue(UMult.Lower(),DegreeU+1);
289   UMult.SetValue(UMult.Upper(),DegreeU+1);
290
291   TColStd_Array1OfInteger  VMult(1,NbVSeg+1); VMult.Init(DegreeV);
292   VMult.SetValue(VMult.Lower(),DegreeV+1);
293   VMult.SetValue(VMult.Upper(),DegreeV+1);
294       
295   
296   //  Poles computing
297   //  ===============
298   
299   Standard_Integer  NbUPoles  =  NbUSeg * DegreeU + 1;
300   Standard_Integer  NbVPoles  =  NbVSeg * DegreeV + 1;  
301   
302   TColgp_Array2OfPnt  BsPole(1, NbUPoles, 1, NbVPoles);
303
304   Standard_Integer  iBs, jBs, iBz, jBz;
305   Standard_Boolean  wasC0 = Standard_True;
306   
307   //  Patch (1,1)
308   //  ===========
309   Standard_Integer USeg, VSeg, j;
310   USeg = 1;
311   VSeg = 1;
312   
313   Handle(TColStd_HArray1OfReal) XPoly = st->XPolynomial(USeg, VSeg);
314   Handle(TColStd_HArray1OfReal) YPoly = st->YPolynomial(USeg, VSeg);
315   Handle(TColStd_HArray1OfReal) ZPoly = st->ZPolynomial(USeg, VSeg);
316   
317   TColgp_Array2OfPnt Coef(1, DegreeU+1, 1, DegreeV+1);
318   Standard_Real ParamU, ParamV;
319   ParamU = 1.;
320   for (i=1; i<=DegreeU+1; i++) {
321     ParamV = 1.;
322     for (j=1; j<=DegreeV+1; j++) {
323       Standard_Integer PolyIndex = i + 4*(j-1);
324       gp_Pnt aPoint(XPoly->Value(PolyIndex)*ParamU*ParamV, 
325                     YPoly->Value(PolyIndex)*ParamU*ParamV, 
326                     ZPoly->Value(PolyIndex)*ParamU*ParamV);
327       Coef.SetValue(i, j, aPoint);
328       ParamV = ParamV *deltaV(VSeg);
329     }
330     ParamU = ParamU * deltaU(USeg);
331   }  
332   TColgp_Array2OfPnt BzPole(1, DegreeU+1, 1, DegreeV+1);
333   PLib::CoefficientsPoles(Coef,PLib::NoWeights2(),BzPole,PLib::NoWeights2());
334   
335   iBs = BsPole.LowerRow();
336   jBs = BsPole.LowerCol();
337   
338   //  Making output BSpline poles array :
339   for (iBz=BzPole.LowerRow(); iBz<=BzPole.UpperRow(); iBz++) {
340     for (jBz=BzPole.LowerCol(); jBz<=BzPole.UpperCol(); jBz++)
341       BsPole.SetValue(iBs, jBs++, BzPole.Value(iBz,jBz));
342     jBs = BsPole.LowerCol();
343     iBs++;
344   }
345
346
347   //  Patches (1<USeg<NbUSeg, 1)
348   //  ==========================
349   
350   VSeg = 1;
351   for (USeg=2; USeg<=NbUSeg; USeg++) {
352     XPoly = st->XPolynomial(USeg, VSeg);
353     YPoly = st->YPolynomial(USeg, VSeg);
354     ZPoly = st->ZPolynomial(USeg, VSeg);
355     ParamU = 1.;
356     for (i=Coef.LowerRow(); i<=Coef.UpperRow(); i++) {
357       ParamV = 1.;
358       for (j=Coef.LowerCol(); j<=Coef.UpperCol(); j++) {
359         Standard_Integer PolyIndex = i + 4*(j-1);
360         gp_Pnt aPoint;
361         aPoint.SetCoord(XPoly->Value(PolyIndex)*ParamU*ParamV, 
362                         YPoly->Value(PolyIndex)*ParamU*ParamV, 
363                         ZPoly->Value(PolyIndex)*ParamU*ParamV);
364         Coef.SetValue(i, j, aPoint);
365         ParamV = ParamV *deltaV(VSeg);
366       }
367       ParamU = ParamU * deltaU(USeg);
368     }
369     PLib::CoefficientsPoles(Coef,PLib::NoWeights2(),BzPole,PLib::NoWeights2());
370
371     //  C0 check and correction for poles lying on isoparametrics U=0 & V=0
372     Standard_Integer  iBsPole = BsPole.LowerRow() + (USeg-1)*DegreeU;
373     Standard_Integer  jBsPole = BsPole.LowerCol();
374     iBz = BzPole.LowerRow();
375     for (jBz=BzPole.LowerCol(); jBz<=BzPole.UpperCol(); jBz++) {
376      if (!BzPole.Value(iBz,jBz).IsEqual(BsPole.Value(iBsPole,jBsPole), epsgeom)) {
377         wasC0=Standard_False;
378         gp_Pnt MidPoint;
379         Standard_Real  XCoord = 
380           0.5 * (BzPole.Value(iBz,jBz).X() + BsPole.Value(iBsPole,jBsPole).X());
381         Standard_Real  YCoord = 
382           0.5 * (BzPole.Value(iBz,jBz).Y() + BsPole.Value(iBsPole,jBsPole).Y());
383         Standard_Real  ZCoord = 
384           0.5 * (BzPole.Value(iBz,jBz).Z() + BsPole.Value(iBsPole,jBsPole).Z());
385         MidPoint.SetCoord(XCoord, YCoord, ZCoord);
386         BsPole.SetValue(iBsPole, jBsPole++, MidPoint);
387       }
388       else {
389         BsPole.SetValue(iBsPole, jBsPole++, BzPole.Value(iBz,jBz));
390       }
391     }
392     
393     //  Other poles (no check about C0) :
394     iBsPole++;
395     jBsPole = BsPole.LowerCol();
396     for (iBz=BzPole.LowerRow()+1; iBz<=BzPole.UpperRow(); iBz++) {
397       for (jBz=BzPole.LowerCol(); jBz<=BzPole.UpperCol(); jBz++)
398         BsPole.SetValue(iBsPole, jBsPole++, BzPole.Value(iBz,jBz));
399       iBsPole++;
400       jBsPole = BsPole.LowerCol();
401     }
402   }
403       
404       
405       
406   //  Patches (1, 1<VSeg<NbVSeg)
407   //  ==========================
408   
409   USeg = 1;
410   for (VSeg=2; VSeg <= NbVSeg; VSeg++) {
411     XPoly = st->XPolynomial(USeg, VSeg);
412     YPoly = st->YPolynomial(USeg, VSeg);
413     ZPoly = st->ZPolynomial(USeg, VSeg);
414     ParamU = 1.;
415     for (i=Coef.LowerRow(); i<=Coef.UpperRow(); i++) {
416       ParamV = 1.;
417       for (j=Coef.LowerCol(); j<=Coef.UpperCol(); j++) {
418         Standard_Integer PolyIndex = i + 4*(j-1);
419         gp_Pnt aPoint;
420         aPoint.SetCoord(XPoly->Value(PolyIndex)*ParamU*ParamV, 
421                         YPoly->Value(PolyIndex)*ParamU*ParamV, 
422                         ZPoly->Value(PolyIndex)*ParamU*ParamV);
423         Coef.SetValue(i, j, aPoint);
424         ParamV = ParamV *deltaV(VSeg);
425       }
426       ParamU = ParamU * deltaU(USeg);
427     }
428     PLib::CoefficientsPoles(Coef,PLib::NoWeights2(),BzPole,PLib::NoWeights2());
429
430     //  C0 check and correction for poles lying on isoparametrics U=0 & V=0
431     iBs = BsPole.LowerRow();
432     jBs = BsPole.LowerCol() + (VSeg-1)*DegreeV;
433     jBz = BzPole.LowerCol();
434     for (iBz=BzPole.LowerRow(); iBz<=BzPole.UpperRow(); iBz++) {
435       if (!BzPole.Value(iBz,jBz).IsEqual(BsPole.Value(iBs,jBs), epsgeom)) {
436         wasC0=Standard_False;
437         gp_Pnt MidPoint;
438         Standard_Real  XCoord = 0.5 * 
439           (BzPole.Value(iBz,jBz).X() + BsPole.Value(iBs,jBs).X());
440         Standard_Real  YCoord = 0.5 * 
441           (BzPole.Value(iBz,jBz).Y() + BsPole.Value(iBs,jBs).Y());
442         Standard_Real  ZCoord = 0.5 * 
443           (BzPole.Value(iBz,jBz).Z() + BsPole.Value(iBs,jBs).Z());
444         MidPoint.SetCoord(XCoord, YCoord, ZCoord);
445         BsPole.SetValue(iBs++, jBs, MidPoint);
446       }
447       else{
448         BsPole.SetValue(iBs++, jBs, BzPole.Value(iBz,jBz));
449       }
450     }
451
452     jBs++;
453     iBs = BsPole.LowerRow();
454     for (jBz=BzPole.LowerCol()+1; jBz<=BzPole.UpperCol(); jBz++) {
455       for (iBz=BzPole.LowerRow(); iBz<=BzPole.UpperRow(); iBz++) 
456         BsPole.SetValue(iBs++, jBs, BzPole.Value(iBz,jBz));
457       iBs = BsPole.LowerRow();
458       jBs++;
459     }
460   }
461   
462   
463   //  Patches (1<USeg<NbUSeg, 1<VSeg<NbVSeg)
464   //  ======================================  
465   
466   for (VSeg=2; VSeg <= NbVSeg; VSeg++) {
467     for (USeg=2; USeg <= NbUSeg; USeg++) {
468       XPoly = st->XPolynomial(USeg, VSeg);
469       YPoly = st->YPolynomial(USeg, VSeg);
470       ZPoly = st->ZPolynomial(USeg, VSeg);
471       ParamU = 1.;
472       for (i=Coef.LowerRow(); i<=Coef.UpperRow(); i++) {
473         ParamV = 1.;
474         for (j=Coef.LowerCol(); j<=Coef.UpperCol(); j++) {
475           Standard_Integer PolyIndex = i + 4*(j-1);
476           gp_Pnt aPoint;
477           aPoint.SetCoord(XPoly->Value(PolyIndex)*ParamU*ParamV, 
478                           YPoly->Value(PolyIndex)*ParamU*ParamV, 
479                           ZPoly->Value(PolyIndex)*ParamU*ParamV);
480           Coef.SetValue(i, j, aPoint);
481           ParamV = ParamV *deltaV(VSeg);          
482         }
483         ParamU = ParamU * deltaU(USeg);
484       }
485       PLib::CoefficientsPoles(Coef,PLib::NoWeights2(),BzPole,PLib::NoWeights2());
486
487       //  C0 check and correction for poles lying on isoparametrics U=0 & V=0
488       iBs = (USeg-1)*DegreeU + BsPole.LowerRow();
489       jBs = (VSeg-1)*DegreeV + BsPole.LowerCol();
490       jBz = BzPole.LowerCol();
491       for (iBz=BzPole.LowerRow(); iBz<=BzPole.UpperRow(); iBz++) {
492         if (!BzPole.Value(iBz,jBz).IsEqual(BsPole.Value(iBs,jBs), epsgeom)) {
493           wasC0=Standard_False;
494           gp_Pnt MidPoint;
495           Standard_Real  XCoord = 0.5 * 
496             (BzPole.Value(iBz,jBz).X() + BsPole.Value(iBs,jBs).X());
497           Standard_Real  YCoord = 0.5 * 
498             (BzPole.Value(iBz,jBz).Y() + BsPole.Value(iBs,jBs).Y());
499           Standard_Real  ZCoord = 0.5 * 
500             (BzPole.Value(iBz,jBz).Z() + BsPole.Value(iBs,jBs).Z());
501           MidPoint.SetCoord(XCoord, YCoord, ZCoord);
502           BsPole.SetValue(iBs++, jBs, MidPoint);
503         }
504         else
505           BsPole.SetValue(iBs++, jBs, BzPole.Value(iBz,jBz));
506       }
507       
508       iBs = (USeg-1)*DegreeU + BsPole.LowerRow();
509       iBz = BzPole.LowerRow();
510       for (jBz=BzPole.LowerCol(); jBz<=BzPole.UpperCol(); jBz++) {
511         //  C0 check and correction for poles lying on isoparametrics U=0 & V=0
512         if (!BzPole.Value(iBz,jBz).IsEqual(BsPole.Value(iBs,jBs), epsgeom)) {
513           wasC0=Standard_False;
514           gp_Pnt MidPoint;
515           Standard_Real  XCoord = 0.5 * 
516             (BzPole.Value(iBz,jBz).X() + BsPole.Value(iBs,jBs).X());
517           Standard_Real  YCoord = 0.5 * 
518             (BzPole.Value(iBz,jBz).Y() + BsPole.Value(iBs,jBs).Y());
519           Standard_Real  ZCoord = 0.5 * 
520             (BzPole.Value(iBz,jBz).Z() + BsPole.Value(iBs,jBs).Z());
521           MidPoint.SetCoord(XCoord, YCoord, ZCoord);
522           BsPole.SetValue(iBs, jBs++, MidPoint);
523         }
524         else 
525           BsPole.SetValue(iBs, jBs++, BzPole.Value(iBz,jBz));
526       }
527
528       iBs = BsPole.LowerRow() + (USeg-1)*DegreeU + 1;
529       jBs = BsPole.LowerCol() + (VSeg-1)*DegreeV + 1;
530       for (iBz=BzPole.LowerRow()+1; iBz<=BzPole.UpperRow(); iBz++) {
531         for (jBz=BzPole.LowerCol()+1; jBz<=BzPole.UpperCol(); jBz++)
532           BsPole.SetValue(iBs, jBs++, BzPole.Value(iBz,jBz));
533         jBs = BsPole.LowerCol() + (VSeg-1)*DegreeV + 1;
534         iBs++;
535       }
536     }
537   }
538
539   //  Building result taking into account transformation if any :
540   //  ===========================================================
541
542   if (st->HasTransf()) {
543     gp_GTrsf GSplTrsf(st->CompoundLocation());
544     gp_Trsf  SplTrsf;
545     Standard_Real epsilon = 1.E-04;
546     if (IGESData_ToolLocation::ConvertLocation(epsilon,GSplTrsf,SplTrsf)) 
547       for (iBs=BsPole.LowerRow(); iBs<=BsPole.UpperRow(); iBs++) 
548         for (jBs=BsPole.LowerCol(); jBs<=BsPole.UpperCol(); jBs++) 
549           BsPole.SetValue(iBs, jBs, BsPole.Value(iBs,jBs).Transformed(SplTrsf));
550 //    else
551 //      AddWarning(start, "Transformation skipped : Not a similarity");
552   }
553
554   res = new Geom_BSplineSurface
555     (BsPole, UKnot, VKnot, UMult, VMult, DegreeU, DegreeV);
556   if (wasC0) returned += 1;
557   return returned;
558 }
559
560
561 //=======================================================================
562 //function : IGESConvGeom::IncreaseSurfaceContinuity
563 //purpose  : 
564 //=======================================================================
565 Standard_Integer IGESConvGeom::IncreaseSurfaceContinuity  (const Handle(Geom_BSplineSurface)& res,
566                                                            const Standard_Real epsgeom,
567                                                            const Standard_Integer continuity)
568 {
569   if (continuity < 1) return continuity;
570   Standard_Boolean isC1 = Standard_True, isC2 = Standard_True;
571   Standard_Integer DegreeU = res->UDegree();
572   
573   Standard_Boolean isModified;
574   do {
575     isModified = Standard_False;
576     for (Standard_Integer i = res->FirstUKnotIndex()+1; i < res->LastUKnotIndex(); i++) 
577       if(DegreeU - res->UMultiplicity(i) < continuity) {
578         if (continuity >= 2) {
579           if (!res->RemoveUKnot(i, DegreeU-2, epsgeom)) {
580             isC2 = Standard_False;
581             Standard_Boolean locOK = res->RemoveUKnot(i, DegreeU-1, epsgeom);   // is C1 ?
582             isC1 &= locOK;
583             isModified |= locOK;
584           }
585           else
586             isModified = Standard_True;
587         }
588         else {
589           Standard_Boolean locOK = res->RemoveUKnot(i, DegreeU-1, epsgeom);   // is C1 ?
590           isC1 &= locOK;
591           isModified |= locOK;
592         }
593       }
594   }
595   while (isModified);
596   
597   Standard_Integer DegreeV = res->VDegree();
598   do {
599     isModified = Standard_False;
600     for (Standard_Integer i = res->FirstVKnotIndex()+1; i < res->LastVKnotIndex(); i++) 
601       if(DegreeV - res->VMultiplicity(i) < continuity) {
602         if (continuity >= 2) {
603           if (!res->RemoveVKnot(i, DegreeV-2, epsgeom)) {
604             isC2 = Standard_False;
605             Standard_Boolean locOK = res->RemoveVKnot(i, DegreeV-1, epsgeom);   // is C1 ?
606             isC1 &= locOK;
607             isModified |= locOK;
608           }
609           else
610             isModified = Standard_True;
611         }
612         else {
613           Standard_Boolean locOK = res->RemoveVKnot(i, DegreeV-1, epsgeom);   // is C1 ?
614           isC1 &= locOK;
615           isModified |= locOK;
616         }
617       }
618   }
619   while (isModified);
620     
621   /*
622   while (--i > j) {                                      // from 2 to NbKnots-1
623     if (continuity >= 2) {
624       if (!res->RemoveUKnot(i, DegreeU-2, epsgeom)) {    // is C2 ?
625         isC2 = Standard_False;
626         isC1 &= res->RemoveUKnot(i, DegreeU-1, epsgeom); // is C1 ?
627       }
628     }
629     else {
630       isC1 &= res->RemoveUKnot(i, DegreeU-1, epsgeom); // is C1 ?
631     }
632   }
633
634   i = res->LastVKnotIndex();   //knots.Upper();
635   j = res->FirstVKnotIndex();  //knots.Lower();
636   Standard_Integer DegreeV = res->VDegree();
637   while (--i > j) {                                      // from 2 to NbKnots-1
638     if (continuity >= 2) {
639       if (!res->RemoveVKnot(i, DegreeV-2, epsgeom)) {    // is C2 ?
640         isC2 = Standard_False;
641         isC1 &= res->RemoveVKnot(i, DegreeV-1, epsgeom); // is C1 ?
642       }
643     }
644     else {
645       isC1 &= res->RemoveVKnot(i, DegreeV-1, epsgeom); // is C1 ?
646     }
647   }*/
648   
649   
650   if (!isC1) return 0;
651   if (continuity >= 2 && !isC2) return 1;
652   return continuity;
653 }
654