519bc4d75964d7b930be84b8b61838040db02a56
[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 typedef Handle(Geom_BSplineSurface)     Handle(BSplineSurface);
25 typedef TColStd_Array1OfInteger      Array1OfInteger;
26 typedef TColStd_HArray1OfInteger HArray1OfInteger;
27
28
29
30
31 GeomConvert_BSplineSurfaceKnotSplitting::
32 GeomConvert_BSplineSurfaceKnotSplitting (
33
34 const Handle(BSplineSurface)& BasisSurface, 
35 const Standard_Integer        UContinuityRange,
36 const Standard_Integer        VContinuityRange
37
38 ) {
39
40
41   if (UContinuityRange < 0 || VContinuityRange < 0) { 
42     Standard_RangeError::Raise(); 
43   }
44
45   Standard_Integer FirstUIndex = BasisSurface->FirstUKnotIndex ();
46   Standard_Integer LastUIndex  = BasisSurface->LastUKnotIndex  ();
47   Standard_Integer FirstVIndex = BasisSurface->FirstVKnotIndex ();
48   Standard_Integer LastVIndex  = BasisSurface->LastVKnotIndex  ();
49   Standard_Integer UDegree     = BasisSurface->UDegree ();
50   Standard_Integer VDegree     = BasisSurface->VDegree ();
51   Standard_Integer i;
52
53
54
55   if (UContinuityRange == 0) {
56     usplitIndexes = new HArray1OfInteger (1, 2);
57     usplitIndexes->SetValue (1, FirstUIndex);
58     usplitIndexes->SetValue (2, LastUIndex);
59   }
60   else {
61     Standard_Integer NbUKnots = BasisSurface->NbUKnots();
62     Array1OfInteger UMults (1, NbUKnots);
63     BasisSurface->UMultiplicities (UMults);
64     Standard_Integer Mmax = BSplCLib::MaxKnotMult (UMults, FirstUIndex, LastUIndex);
65     if (UDegree - Mmax >= UContinuityRange) {
66       usplitIndexes = new HArray1OfInteger (1, 2);
67       usplitIndexes->SetValue (1, FirstUIndex);
68       usplitIndexes->SetValue (2, LastUIndex);
69     }
70     else {
71       Array1OfInteger USplit (1, LastUIndex - FirstUIndex + 1);
72       Standard_Integer NbUSplit = 1;
73       Standard_Integer UIndex = FirstUIndex;
74       USplit (NbUSplit) = UIndex;
75       UIndex++;
76       NbUSplit++;
77       while (UIndex < LastUIndex) {
78         if (UDegree - UMults(UIndex) < UContinuityRange) {
79           USplit (NbUSplit) = UIndex;
80           NbUSplit++;
81         }
82         UIndex++;
83       }
84       USplit (NbUSplit) = UIndex;
85       usplitIndexes = new HArray1OfInteger (1, NbUSplit);
86       for (i = 1; i <= NbUSplit; i++) {
87         usplitIndexes->SetValue (i, USplit (i));
88       }
89     }
90   }
91
92
93
94   if (VContinuityRange == 0) {
95     vsplitIndexes = new HArray1OfInteger (1, 2);
96     vsplitIndexes->SetValue (1, FirstVIndex);
97     vsplitIndexes->SetValue (2, LastVIndex);
98   }
99   else {
100     Standard_Integer NbVKnots = BasisSurface->NbVKnots();
101     Array1OfInteger VMults (1, NbVKnots);
102     BasisSurface->VMultiplicities (VMults);
103     Standard_Integer Mmax = BSplCLib::MaxKnotMult (VMults, FirstVIndex, LastVIndex);
104     if (VDegree - Mmax >= VContinuityRange) {
105       usplitIndexes = new HArray1OfInteger (1, 2);
106       usplitIndexes->SetValue (1, FirstVIndex);
107       usplitIndexes->SetValue (2, LastVIndex);
108     }
109     else {
110       Array1OfInteger VSplit (1, LastVIndex - FirstVIndex + 1);
111       Standard_Integer NbVSplit  = 1;
112       Standard_Integer VIndex    = FirstVIndex;
113       VSplit (NbVSplit) = VIndex;
114       VIndex++;
115       NbVSplit++;
116       while (VIndex < LastVIndex) {
117         if (VDegree - VMults (VIndex) < VContinuityRange) {
118           VSplit (NbVSplit) = VIndex;
119           NbVSplit++;
120         }
121         VIndex++;
122       }
123       VSplit (NbVSplit) = VIndex;
124       vsplitIndexes = new HArray1OfInteger (1, NbVSplit);
125       for (i = 1; i <= NbVSplit; i++) {
126         vsplitIndexes->SetValue (i, VSplit (i));
127       }
128     }
129   }
130 }
131
132
133
134 Standard_Integer GeomConvert_BSplineSurfaceKnotSplitting::NbUSplits () const {
135    return usplitIndexes->Length();
136 }
137
138
139 Standard_Integer GeomConvert_BSplineSurfaceKnotSplitting::NbVSplits () const {
140    return vsplitIndexes->Length();
141 }
142
143
144 Standard_Integer GeomConvert_BSplineSurfaceKnotSplitting::USplitValue (
145
146 const Standard_Integer UIndex
147
148 ) const {
149
150   Standard_RangeError_Raise_if (
151                       UIndex < 1 || UIndex > usplitIndexes->Length(), " ");
152   return usplitIndexes->Value (UIndex);
153 }
154
155
156
157 Standard_Integer GeomConvert_BSplineSurfaceKnotSplitting::VSplitValue (
158
159 const Standard_Integer VIndex
160
161 ) const {
162
163   Standard_RangeError_Raise_if (
164                       VIndex < 1 || VIndex > vsplitIndexes->Length(), " ");
165   return vsplitIndexes->Value (VIndex);
166 }
167
168
169 void GeomConvert_BSplineSurfaceKnotSplitting::Splitting (
170
171 Array1OfInteger& USplit, 
172 Array1OfInteger& VSplit
173
174 ) const {
175   Standard_Integer i ;
176   for ( i = 1; i <= usplitIndexes->Length(); i++){
177     USplit (i) = usplitIndexes->Value (i);
178   }
179   for (i = 1; i <= vsplitIndexes->Length(); i++){
180     VSplit (i) = vsplitIndexes->Value (i);
181   }
182 }