0024023: Revamp the OCCT Handle -- general
[occt.git] / src / GeomConvert / GeomConvert_BSplineSurfaceKnotSplitting.cxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 //Jean-Claude Vauthier 28 Novembre 1991
16 //Passage sur C1 Aout 1992
17
18
19 #include <GeomConvert_BSplineSurfaceKnotSplitting.ixx>
20
21 #include <Standard_RangeError.hxx>
22
23 #include <BSplCLib.hxx>
24
25 typedef TColStd_Array1OfInteger      Array1OfInteger;
26 typedef TColStd_HArray1OfInteger HArray1OfInteger;
27
28 GeomConvert_BSplineSurfaceKnotSplitting::
29 GeomConvert_BSplineSurfaceKnotSplitting (
30
31 const Handle(Geom_BSplineSurface)& BasisSurface, 
32 const Standard_Integer        UContinuityRange,
33 const Standard_Integer        VContinuityRange
34
35 ) {
36
37
38   if (UContinuityRange < 0 || VContinuityRange < 0) { 
39     Standard_RangeError::Raise(); 
40   }
41
42   Standard_Integer FirstUIndex = BasisSurface->FirstUKnotIndex ();
43   Standard_Integer LastUIndex  = BasisSurface->LastUKnotIndex  ();
44   Standard_Integer FirstVIndex = BasisSurface->FirstVKnotIndex ();
45   Standard_Integer LastVIndex  = BasisSurface->LastVKnotIndex  ();
46   Standard_Integer UDegree     = BasisSurface->UDegree ();
47   Standard_Integer VDegree     = BasisSurface->VDegree ();
48   Standard_Integer i;
49
50
51
52   if (UContinuityRange == 0) {
53     usplitIndexes = new HArray1OfInteger (1, 2);
54     usplitIndexes->SetValue (1, FirstUIndex);
55     usplitIndexes->SetValue (2, LastUIndex);
56   }
57   else {
58     Standard_Integer NbUKnots = BasisSurface->NbUKnots();
59     Array1OfInteger UMults (1, NbUKnots);
60     BasisSurface->UMultiplicities (UMults);
61     Standard_Integer Mmax = BSplCLib::MaxKnotMult (UMults, FirstUIndex, LastUIndex);
62     if (UDegree - Mmax >= UContinuityRange) {
63       usplitIndexes = new HArray1OfInteger (1, 2);
64       usplitIndexes->SetValue (1, FirstUIndex);
65       usplitIndexes->SetValue (2, LastUIndex);
66     }
67     else {
68       Array1OfInteger USplit (1, LastUIndex - FirstUIndex + 1);
69       Standard_Integer NbUSplit = 1;
70       Standard_Integer UIndex = FirstUIndex;
71       USplit (NbUSplit) = UIndex;
72       UIndex++;
73       NbUSplit++;
74       while (UIndex < LastUIndex) {
75         if (UDegree - UMults(UIndex) < UContinuityRange) {
76           USplit (NbUSplit) = UIndex;
77           NbUSplit++;
78         }
79         UIndex++;
80       }
81       USplit (NbUSplit) = UIndex;
82       usplitIndexes = new HArray1OfInteger (1, NbUSplit);
83       for (i = 1; i <= NbUSplit; i++) {
84         usplitIndexes->SetValue (i, USplit (i));
85       }
86     }
87   }
88
89
90
91   if (VContinuityRange == 0) {
92     vsplitIndexes = new HArray1OfInteger (1, 2);
93     vsplitIndexes->SetValue (1, FirstVIndex);
94     vsplitIndexes->SetValue (2, LastVIndex);
95   }
96   else {
97     Standard_Integer NbVKnots = BasisSurface->NbVKnots();
98     Array1OfInteger VMults (1, NbVKnots);
99     BasisSurface->VMultiplicities (VMults);
100     Standard_Integer Mmax = BSplCLib::MaxKnotMult (VMults, FirstVIndex, LastVIndex);
101     if (VDegree - Mmax >= VContinuityRange) {
102       usplitIndexes = new HArray1OfInteger (1, 2);
103       usplitIndexes->SetValue (1, FirstVIndex);
104       usplitIndexes->SetValue (2, LastVIndex);
105     }
106     else {
107       Array1OfInteger VSplit (1, LastVIndex - FirstVIndex + 1);
108       Standard_Integer NbVSplit  = 1;
109       Standard_Integer VIndex    = FirstVIndex;
110       VSplit (NbVSplit) = VIndex;
111       VIndex++;
112       NbVSplit++;
113       while (VIndex < LastVIndex) {
114         if (VDegree - VMults (VIndex) < VContinuityRange) {
115           VSplit (NbVSplit) = VIndex;
116           NbVSplit++;
117         }
118         VIndex++;
119       }
120       VSplit (NbVSplit) = VIndex;
121       vsplitIndexes = new HArray1OfInteger (1, NbVSplit);
122       for (i = 1; i <= NbVSplit; i++) {
123         vsplitIndexes->SetValue (i, VSplit (i));
124       }
125     }
126   }
127 }
128
129
130
131 Standard_Integer GeomConvert_BSplineSurfaceKnotSplitting::NbUSplits () const {
132    return usplitIndexes->Length();
133 }
134
135
136 Standard_Integer GeomConvert_BSplineSurfaceKnotSplitting::NbVSplits () const {
137    return vsplitIndexes->Length();
138 }
139
140
141 Standard_Integer GeomConvert_BSplineSurfaceKnotSplitting::USplitValue (
142
143 const Standard_Integer UIndex
144
145 ) const {
146
147   Standard_RangeError_Raise_if (
148                       UIndex < 1 || UIndex > usplitIndexes->Length(), " ");
149   return usplitIndexes->Value (UIndex);
150 }
151
152
153
154 Standard_Integer GeomConvert_BSplineSurfaceKnotSplitting::VSplitValue (
155
156 const Standard_Integer VIndex
157
158 ) const {
159
160   Standard_RangeError_Raise_if (
161                       VIndex < 1 || VIndex > vsplitIndexes->Length(), " ");
162   return vsplitIndexes->Value (VIndex);
163 }
164
165
166 void GeomConvert_BSplineSurfaceKnotSplitting::Splitting (
167
168 Array1OfInteger& USplit, 
169 Array1OfInteger& VSplit
170
171 ) const {
172   Standard_Integer i ;
173   for ( i = 1; i <= usplitIndexes->Length(); i++){
174     USplit (i) = usplitIndexes->Value (i);
175   }
176   for (i = 1; i <= vsplitIndexes->Length(); i++){
177     VSplit (i) = vsplitIndexes->Value (i);
178   }
179 }