0031035: Coding - uninitialized class fields reported by Visual Studio Code Analysis
[occt.git] / src / ShapeUpgrade / ShapeUpgrade_SplitSurfaceContinuity.cxx
1 // Created on: 1999-04-14
2 // Created by: Roman LYGIN
3 // Copyright (c) 1999-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
18 #include <Geom_BSplineSurface.hxx>
19 #include <Geom_OffsetSurface.hxx>
20 #include <Geom_RectangularTrimmedSurface.hxx>
21 #include <Geom_SurfaceOfLinearExtrusion.hxx>
22 #include <Geom_SurfaceOfRevolution.hxx>
23 #include <Geom_SweptSurface.hxx>
24 #include <gp_Ax1.hxx>
25 #include <Precision.hxx>
26 #include <ShapeExtend.hxx>
27 #include <ShapeUpgrade.hxx>
28 #include <ShapeUpgrade_SplitCurve3dContinuity.hxx>
29 #include <ShapeUpgrade_SplitSurfaceContinuity.hxx>
30 #include <Standard_Type.hxx>
31 #include <TColGeom_HArray1OfCurve.hxx>
32 #include <TColGeom_HArray2OfSurface.hxx>
33 #include <TColStd_HArray1OfInteger.hxx>
34 #include <TColStd_HSequenceOfReal.hxx>
35
36 IMPLEMENT_STANDARD_RTTIEXT(ShapeUpgrade_SplitSurfaceContinuity,ShapeUpgrade_SplitSurface)
37
38 //======================================================================
39 //function : ShapeUpgrade_SplitSurface
40 //purpose  : 
41 //=======================================================================
42 ShapeUpgrade_SplitSurfaceContinuity::ShapeUpgrade_SplitSurfaceContinuity()
43 : myCont(0)
44 {
45   myCriterion = GeomAbs_C1;
46   myTolerance = Precision::Confusion();
47   
48 }
49
50 //=======================================================================
51 //function : SetCrierion
52 //purpose  : 
53 //=======================================================================
54
55  void ShapeUpgrade_SplitSurfaceContinuity::SetCriterion(const GeomAbs_Shape Criterion)
56 {
57   myCriterion = Criterion;
58   switch (myCriterion) {
59     default         :
60     case GeomAbs_C1 : myCont = 1; break;
61     case GeomAbs_C2 : myCont = 2; break;
62     case GeomAbs_C3 : myCont = 3; break;
63     case GeomAbs_CN : myCont = 4; break;
64   }
65 }
66
67 //=======================================================================
68 //function : SetTolerance
69 //purpose  : 
70 //=======================================================================
71
72  void ShapeUpgrade_SplitSurfaceContinuity::SetTolerance(const Standard_Real Tol)
73 {
74   myTolerance = Tol;
75 }
76
77 //=======================================================================
78 //function : Build
79 //purpose  : 
80 //=======================================================================
81
82  void ShapeUpgrade_SplitSurfaceContinuity::Compute(const Standard_Boolean Segment) 
83 {
84   if(!Segment) {
85     Standard_Real UF,UL,VF,VL;
86     mySurface->Bounds(UF,UL,VF,VL);
87     if(!Precision::IsInfinite(UF)) myUSplitValues->SetValue(1,UF);
88     if(!Precision::IsInfinite(UL)) myUSplitValues->SetValue(myUSplitValues->Length(),UL);
89     if(!Precision::IsInfinite(VF)) myVSplitValues->SetValue(1,VF);
90     if(!Precision::IsInfinite(VL)) myVSplitValues->SetValue(myVSplitValues->Length(),VL);
91   }
92   
93   Standard_Real UFirst = myUSplitValues->Value(1);
94   Standard_Real ULast  = myUSplitValues->Value(myUSplitValues->Length());
95   Standard_Real VFirst = myVSplitValues->Value(1);
96   Standard_Real VLast  = myVSplitValues->Value(myVSplitValues->Length());
97   Standard_Real precision = Precision::Confusion();
98 //  if (ShapeUpgrade::Debug()) std::cout << "SplitSurfaceContinuity::Build" << std::endl;
99   if(mySurface->Continuity() < myCriterion) 
100     myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE2);
101   if (myUSplitValues->Length() >2 || myVSplitValues->Length() >2 )
102     myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
103   
104   if (mySurface->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {      
105     Handle(Geom_SurfaceOfRevolution) Surface = Handle(Geom_SurfaceOfRevolution)::DownCast(mySurface);
106     if(Surface->Continuity() >=  myCriterion && myUSplitValues->Length() ==2 && myVSplitValues->Length() ==2 ) {
107       return;
108     }
109     Handle(Geom_Curve) BasCurve = Surface->BasisCurve(); 
110     ShapeUpgrade_SplitCurve3dContinuity spc;
111     spc.Init(BasCurve,VFirst,VLast);
112     spc.SetCriterion(myCriterion);
113     spc.SetTolerance(myTolerance);
114     spc.SetSplitValues(myVSplitValues);
115     spc.Compute();
116     myVSplitValues->Clear();
117     myVSplitValues->ChangeSequence() = spc.SplitValues()->Sequence();
118     if ( spc.Status ( ShapeExtend_DONE1 ) )
119       myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
120     if ( spc.Status ( ShapeExtend_DONE2 ) )
121       myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
122     if ( spc.Status ( ShapeExtend_DONE3 ) )
123       myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 );
124     return;
125   }   
126   if (mySurface->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) {
127     Handle(Geom_SurfaceOfLinearExtrusion) Surface = Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(mySurface);
128    if(Surface->Continuity() >=  myCriterion && myUSplitValues->Length() ==2 && myVSplitValues->Length() == 2) {
129       return;
130     }
131     Handle(Geom_Curve) BasCurve = Surface->BasisCurve();
132     ShapeUpgrade_SplitCurve3dContinuity spc;
133     spc.Init(BasCurve,UFirst,ULast);
134     spc.SetCriterion(myCriterion);
135     spc.SetTolerance(myTolerance);
136     spc.SetSplitValues(myUSplitValues);
137     spc.Compute(); 
138     myUSplitValues->Clear();
139     myUSplitValues->ChangeSequence() = spc.SplitValues()->Sequence();
140     if ( spc.Status ( ShapeExtend_DONE1 ) )
141       myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
142     if ( spc.Status ( ShapeExtend_DONE2 ) )
143       myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
144     if ( spc.Status ( ShapeExtend_DONE3 ) ) {
145       myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 );
146       Handle(Geom_Curve) aNewBascurve = spc.GetCurve();
147       Surface->SetBasisCurve(aNewBascurve);
148     }
149     return;
150   }
151   
152   if (mySurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
153     Handle(Geom_RectangularTrimmedSurface) tmp = Handle(Geom_RectangularTrimmedSurface)::DownCast (mySurface);
154     if(tmp->Continuity() >=  myCriterion && myUSplitValues->Length() ==2 && myVSplitValues->Length() == 2) {
155       return;
156     }
157     Standard_Real U1,U2,V1,V2;
158     tmp->Bounds(U1,U2,V1,V2);
159     Handle(Geom_Surface) theSurf = tmp->BasisSurface();
160     ShapeUpgrade_SplitSurfaceContinuity sps;
161     sps.Init(theSurf,Max(U1,UFirst),Min(U2,ULast),Max(V1,VFirst),Min(V2,VLast));
162     sps.SetUSplitValues(myUSplitValues);
163     sps.SetVSplitValues(myVSplitValues);
164     sps.SetTolerance(myTolerance);
165     sps.SetCriterion(myCriterion);
166     sps.Compute(Standard_True);
167     myUSplitValues->Clear();
168     myUSplitValues->ChangeSequence() = sps.USplitValues()->Sequence();
169     myVSplitValues->Clear();
170     myVSplitValues->ChangeSequence() = sps.VSplitValues()->Sequence();
171     myStatus |= sps.myStatus;
172     return;
173   }
174   else if (mySurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
175     GeomAbs_Shape BasCriterion;
176     switch (myCriterion) {
177       default         :
178       case GeomAbs_C1 : BasCriterion = GeomAbs_C2; break;
179       case GeomAbs_C2 : BasCriterion = GeomAbs_C3; break;
180       case GeomAbs_C3 : //if (ShapeUpgrade::Debug()) std::cout<<". this criterion is not suitable for a Offset Surface"<<std::endl;
181 #ifdef OCCT_DEBUG
182                         std::cout << "Warning: ShapeUpgrade_SplitSurfaceContinuity: criterion C3 for Offset surface" << std::endl; 
183 #endif
184       case GeomAbs_CN : BasCriterion = GeomAbs_CN; break;
185       
186     }
187     Handle(Geom_OffsetSurface) tmp = Handle(Geom_OffsetSurface)::DownCast (mySurface);
188     Handle(Geom_Surface) theSurf = tmp->BasisSurface();
189     if(theSurf->Continuity() >=  BasCriterion && myUSplitValues->Length() ==2 && myVSplitValues->Length() == 2) {
190       return;
191     }
192     ShapeUpgrade_SplitSurfaceContinuity sps;
193     sps.Init(theSurf,UFirst,ULast,VFirst,VLast);
194     sps.SetUSplitValues(myUSplitValues);
195     sps.SetVSplitValues(myVSplitValues);
196     sps.SetTolerance(myTolerance);
197     sps.SetCriterion(BasCriterion);
198     sps.Compute(Standard_True);
199     myUSplitValues->Clear();
200     myUSplitValues->ChangeSequence() = sps.USplitValues()->Sequence();
201     myVSplitValues->Clear();
202     myVSplitValues->ChangeSequence() = sps.VSplitValues()->Sequence();
203     myStatus |= sps.myStatus;
204     return;
205   }
206   
207   Handle(Geom_BSplineSurface) MyBSpline;
208   if(mySurface->IsKind(STANDARD_TYPE(Geom_BSplineSurface)))
209     MyBSpline = Handle(Geom_BSplineSurface)::DownCast(mySurface->Copy());
210   if (MyBSpline.IsNull()) {
211 //    if (ShapeUpgrade::Debug()) std::cout<<".  Surface is not a Bspline"<<std::endl;
212     return;
213   } 
214   if(mySurface->Continuity() >= myCriterion) {
215     return;
216   }
217   
218   // it is a BSplineSurface
219   Standard_Integer UDeg=MyBSpline->UDegree();
220   Standard_Integer VDeg=MyBSpline->VDegree();
221   Standard_Integer NbUKnots= MyBSpline->NbUKnots(); 
222   Standard_Integer UFirstInd =MyBSpline->FirstUKnotIndex()+1,
223   ULastInd = MyBSpline->LastUKnotIndex()-1,
224   VFirstInd =MyBSpline->FirstVKnotIndex()+1,
225   VLastInd = MyBSpline->LastVKnotIndex()-1;
226   Standard_Integer NbVKnots= MyBSpline->NbVKnots();
227   
228 //  if (ShapeUpgrade::Debug()) std::cout<<". NbUKnots="<<NbUKnots<<std::endl;
229   if (NbUKnots>2) {
230     // Only the internal knots are checked.
231     Standard_Integer iknot= UFirstInd;
232     for(Standard_Integer j =2; j <= myUSplitValues->Length(); j++) {
233       ULast =  myUSplitValues->Value(j);
234       
235       for (; iknot <= ULastInd; iknot++) {
236         Standard_Real valknot = MyBSpline->UKnot(iknot);
237         if(valknot <= UFirst + precision) continue;
238           if( valknot >= ULast - precision) break;
239         Standard_Integer Continuity=UDeg-MyBSpline->UMultiplicity(iknot);
240         if (Continuity < myCont) { 
241           // At this knot, the Surface is C0; try to remove Knot.
242           Standard_Integer newMultiplicity=UDeg - myCont;
243           Standard_Boolean corrected = Standard_False;
244           if ( newMultiplicity >= 0 )
245             corrected=MyBSpline->RemoveUKnot(iknot, newMultiplicity, myTolerance);
246           if (corrected && newMultiplicity > 0) {
247                 Continuity=UDeg-MyBSpline->UMultiplicity(iknot);
248                 corrected = (Continuity >= myCont);
249                 }
250           if (corrected) {
251             // at this knot, the continuity is now C1. Nothing else to do.
252 //          if (ShapeUpgrade::Debug()) std::cout<<". Correction at UKnot "<<iknot<<std::endl;
253             // PTV 15.05.2002 decrease iknot and ULastIndex values if knot removed
254             if (newMultiplicity ==0) { iknot--; ULastInd--; }
255             myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 );
256           }
257           else {
258             // impossible to force C1 within the tolerance: 
259             // this knot will be a splitting value.
260             Standard_Real u=MyBSpline->UKnot(iknot);
261             myUSplitValues->InsertBefore(j++,u);
262             myNbResultingRow++;
263 //          if (ShapeUpgrade::Debug()) std::cout<<". Splitting at Knot "<<iknot<<std::endl;
264           }
265         }
266       }
267       UFirst = ULast;
268     }
269   }
270 //  if (ShapeUpgrade::Debug()) std::cout<<". NbVKnots="<<NbVKnots<<std::endl;
271   if (NbVKnots>2) {
272     // Only the internal knots are checked.
273     Standard_Integer iknot=VFirstInd;
274     for(Standard_Integer j1 =2; j1 <= myVSplitValues->Length(); j1++) {
275       VLast =  myVSplitValues->Value(j1);
276       for (; iknot <= VLastInd; iknot++) {
277         Standard_Real valknot = MyBSpline->VKnot(iknot);
278         if(valknot <= VFirst + precision) continue;
279         if( valknot >= VLast - precision) break;
280         Standard_Integer Continuity=VDeg-MyBSpline->VMultiplicity(iknot);
281         if (Continuity < myCont) { 
282           // At this knot, the Surface is C0; try to remove Knot.
283           Standard_Integer newMultiplicity=VDeg - myCont;
284           Standard_Boolean corrected = Standard_False;
285           if( newMultiplicity >= 0 )
286             corrected=MyBSpline->RemoveVKnot(iknot, newMultiplicity, myTolerance);
287           if (corrected && newMultiplicity > 0) {
288                 Continuity=VDeg-MyBSpline->VMultiplicity(iknot);
289                 corrected = (Continuity >= myCont);
290           }
291           if (corrected ) {
292             // at this knot, the continuity is now Criterion. Nothing else to do.
293 //          if (ShapeUpgrade::Debug()) std::cout<<". Correction at VKnot "<<iknot<<std::endl;
294             // PTV 15.05.2002 decrease iknot and ULastIndex values if knot removed
295             if (newMultiplicity ==0) { iknot--; VLastInd--; }
296             myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 );
297           }
298           else {
299             // this knot will be a splitting value.
300             Standard_Real v=MyBSpline->VKnot(iknot);
301             myVSplitValues->InsertBefore(j1++,v);
302             myNbResultingCol++;
303 //          if (ShapeUpgrade::Debug()) std::cout<<". Splitting at Knot "<<iknot<<std::endl;
304           }
305         }
306       }
307       VFirst = VLast;
308     }
309   }
310   if ( Status ( ShapeExtend_DONE3 ) ) {
311     mySurface = MyBSpline;
312   }
313
314   if (myUSplitValues->Length() >2 || myVSplitValues->Length() >2 )
315     myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
316 }
317
318
319
320