973c2be1 |
1 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
2 | // |
973c2be1 |
3 | // This file is part of Open CASCADE Technology software library. |
b311480e |
4 | // |
d5f74e42 |
5 | // This library is free software; you can redistribute it and/or modify it under |
6 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
7 | // by the Free Software Foundation, with special exception defined in the file |
8 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
9 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
10 | // |
973c2be1 |
11 | // Alternatively, this file may be used under the terms of Open CASCADE |
12 | // commercial license or contractual agreement. |
b311480e |
13 | |
42cf5bc1 |
14 | |
15 | #include <BSplSLib.hxx> |
16 | #include <Convert_GridPolynomialToPoles.hxx> |
7fd59977 |
17 | #include <Geom_BezierSurface.hxx> |
42cf5bc1 |
18 | #include <Geom_BSplineSurface.hxx> |
19 | #include <Geom_OsculatingSurface.hxx> |
20 | #include <Geom_Surface.hxx> |
21 | #include <PLib.hxx> |
22 | #include <Precision.hxx> |
23 | #include <TColgp_Array1OfPnt.hxx> |
7fd59977 |
24 | #include <TColgp_Array2OfPnt.hxx> |
42cf5bc1 |
25 | #include <TColgp_Array2OfVec.hxx> |
7fd59977 |
26 | #include <TColgp_HArray2OfPnt.hxx> |
7fd59977 |
27 | #include <TColStd_Array1OfInteger.hxx> |
42cf5bc1 |
28 | #include <TColStd_Array1OfReal.hxx> |
7fd59977 |
29 | #include <TColStd_HArray1OfInteger.hxx> |
42cf5bc1 |
30 | #include <TColStd_HArray1OfReal.hxx> |
31 | #include <TColStd_HArray2OfInteger.hxx> |
7fd59977 |
32 | |
92efcf78 |
33 | IMPLEMENT_STANDARD_RTTIEXT(Geom_OsculatingSurface,MMgt_TShared) |
34 | |
7fd59977 |
35 | //======================================================================= |
36 | //function : Geom_OffsetOsculatingSurface |
37 | //purpose : |
38 | //======================================================================= |
7fd59977 |
39 | Geom_OsculatingSurface::Geom_OsculatingSurface() |
3d58dc49 |
40 | : myAlong(1,4) |
7fd59977 |
41 | { |
6b84c3f7 |
42 | myAlong.Init(Standard_False); |
7fd59977 |
43 | } |
44 | //======================================================================= |
45 | //function : Geom_OffsetOsculatingSurface |
46 | //purpose : |
47 | //======================================================================= |
48 | |
49 | Geom_OsculatingSurface::Geom_OsculatingSurface(const Handle(Geom_Surface)& BS, |
3d58dc49 |
50 | const Standard_Real Tol) |
51 | : myAlong(1,4) |
7fd59977 |
52 | { |
53 | Init(BS,Tol); |
54 | } |
55 | |
56 | //======================================================================= |
57 | //function : Init |
58 | //purpose : |
59 | //======================================================================= |
60 | |
61 | void Geom_OsculatingSurface::Init(const Handle(Geom_Surface)& BS, |
3d58dc49 |
62 | const Standard_Real Tol) |
7fd59977 |
63 | { |
64 | ClearOsculFlags(); |
65 | myTol=Tol; |
c15398ab |
66 | Standard_Real TolMin=0.;//consider all singularities below Tol, not just above 1.e-12 (id23943) |
7fd59977 |
67 | Standard_Boolean OsculSurf = Standard_True; |
68 | myBasisSurf = Handle(Geom_Surface)::DownCast(BS->Copy()); |
69 | myOsculSurf1 = new Geom_HSequenceOfBSplineSurface(); |
70 | myOsculSurf2 = new Geom_HSequenceOfBSplineSurface(); |
71 | if ((BS->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) || |
3d58dc49 |
72 | (BS->IsKind(STANDARD_TYPE(Geom_BezierSurface)))) |
73 | { |
74 | Standard_Real U1=0,U2=0,V1=0,V2=0; |
75 | |
76 | Standard_Integer i = 1; |
77 | BS->Bounds(U1,U2,V1,V2); |
78 | myAlong.SetValue(1,IsQPunctual(BS,V1,GeomAbs_IsoV,TolMin,Tol)); |
79 | myAlong.SetValue(2,IsQPunctual(BS,V2,GeomAbs_IsoV,TolMin,Tol)); |
80 | myAlong.SetValue(3,IsQPunctual(BS,U1,GeomAbs_IsoU,TolMin,Tol)); |
81 | myAlong.SetValue(4,IsQPunctual(BS,U2,GeomAbs_IsoU,TolMin,Tol)); |
0797d9d3 |
82 | #ifdef OCCT_DEBUG |
3d58dc49 |
83 | cout<<myAlong(1)<<endl<<myAlong(2)<<endl<<myAlong(3)<<endl<<myAlong(4)<<endl; |
7fd59977 |
84 | #endif |
3d58dc49 |
85 | if (myAlong(1) || myAlong(2) || myAlong(3) || myAlong(4)) |
86 | { |
87 | Handle(Geom_BSplineSurface) InitSurf, L,S; |
88 | if (BS->IsKind(STANDARD_TYPE(Geom_BezierSurface))) |
89 | { |
90 | Handle(Geom_BezierSurface) BzS = Handle(Geom_BezierSurface)::DownCast(BS); |
91 | TColgp_Array2OfPnt P(1,BzS->NbUPoles(),1,BzS->NbVPoles()); |
92 | TColStd_Array1OfReal UKnots(1,2); |
93 | TColStd_Array1OfReal VKnots(1,2); |
94 | TColStd_Array1OfInteger UMults(1,2); |
95 | TColStd_Array1OfInteger VMults(1,2); |
96 | for (i=1;i<=2;i++) |
97 | { |
98 | UKnots.SetValue(i,(i-1)); |
99 | VKnots.SetValue(i,(i-1)); |
100 | UMults.SetValue(i,BzS->UDegree()+1); |
101 | VMults.SetValue(i,BzS->VDegree()+1); |
102 | } |
103 | BzS->Poles(P); |
104 | InitSurf = new Geom_BSplineSurface(P,UKnots,VKnots, |
105 | UMults,VMults, |
106 | BzS->UDegree(), |
107 | BzS->VDegree(), |
108 | BzS->IsUPeriodic(), |
109 | BzS->IsVPeriodic()); |
110 | } |
111 | else |
112 | { |
113 | InitSurf = Handle(Geom_BSplineSurface)::DownCast(myBasisSurf); |
114 | } |
0797d9d3 |
115 | #ifdef OCCT_DEBUG |
3d58dc49 |
116 | cout<<"UDEG: "<<InitSurf->UDegree()<<endl; |
117 | cout<<"VDEG: "<<InitSurf->VDegree()<<endl; |
7fd59977 |
118 | #endif |
3d58dc49 |
119 | |
120 | if(IsAlongU() && IsAlongV()) ClearOsculFlags(); |
121 | // Standard_ConstructionError_Raise_if((IsAlongU() && IsAlongV()),"Geom_OsculatingSurface"); |
122 | if ((IsAlongU() && InitSurf->VDegree()>1) || |
123 | (IsAlongV() && InitSurf->UDegree()>1)) |
124 | { |
125 | myKdeg = new TColStd_HSequenceOfInteger(); |
126 | Standard_Integer k=0; |
127 | Standard_Boolean IsQPunc; |
128 | Standard_Integer UKnot,VKnot; |
129 | if (myAlong(1) || myAlong(2)) |
130 | { |
131 | for (i=1;i<InitSurf->NbUKnots();i++) |
132 | { |
133 | if (myAlong(1)) |
134 | { |
135 | S = InitSurf; k=0; IsQPunc=Standard_True; |
136 | UKnot=i; |
137 | VKnot=1; |
138 | while(IsQPunc) |
139 | { |
140 | OsculSurf = BuildOsculatingSurface(V1,UKnot,VKnot,S,L); |
141 | if(!OsculSurf) break; |
142 | k++; |
0797d9d3 |
143 | #ifdef OCCT_DEBUG |
3d58dc49 |
144 | cout<<"1.k = "<<k<<endl; |
7fd59977 |
145 | #endif |
3d58dc49 |
146 | IsQPunc=IsQPunctual(L,V1,GeomAbs_IsoV,0.,Tol); |
147 | UKnot=1; |
148 | VKnot=1; |
149 | S=L; |
150 | |
151 | } |
152 | if (OsculSurf) |
153 | myOsculSurf1->Append(L); |
154 | else |
155 | ClearOsculFlags(); //myAlong.SetValue(1,Standard_False); |
156 | if (myAlong(2) && OsculSurf) |
157 | { |
158 | S = InitSurf; k=0; IsQPunc=Standard_True; |
159 | UKnot=i; |
160 | VKnot=InitSurf->NbVKnots()-1; |
161 | |
162 | while(IsQPunc) |
163 | { |
164 | OsculSurf = BuildOsculatingSurface(V2,UKnot,VKnot,S,L); |
165 | if(!OsculSurf) break; |
166 | k++; |
0797d9d3 |
167 | #ifdef OCCT_DEBUG |
3d58dc49 |
168 | cout<<"2.k = "<<k<<endl; |
7fd59977 |
169 | #endif |
3d58dc49 |
170 | IsQPunc=IsQPunctual(L,V2,GeomAbs_IsoV,0.,Tol); |
171 | UKnot=1; |
172 | VKnot=1; |
173 | S=L; |
174 | } |
175 | if(OsculSurf) |
176 | { |
177 | myOsculSurf2->Append(L); |
178 | myKdeg->Append(k); |
179 | } |
180 | } |
181 | } |
182 | else |
183 | //if (myAlong(2)) |
184 | { |
185 | S = InitSurf; k=0; IsQPunc=Standard_True; |
186 | UKnot=i; |
187 | VKnot=InitSurf->NbVKnots()-1; |
188 | while(IsQPunc) |
189 | { |
190 | OsculSurf = BuildOsculatingSurface(V2,UKnot,VKnot,S,L); |
191 | if(!OsculSurf) break; |
192 | k++; |
0797d9d3 |
193 | #ifdef OCCT_DEBUG |
3d58dc49 |
194 | cout<<"2.k = "<<k<<endl; |
7fd59977 |
195 | #endif |
3d58dc49 |
196 | IsQPunc=IsQPunctual(L,V2,GeomAbs_IsoV,0.,Tol); |
197 | UKnot=1; |
198 | VKnot=1; |
199 | S=L; |
200 | |
201 | } |
202 | if(OsculSurf) |
203 | { |
204 | myOsculSurf2->Append(L); |
205 | myKdeg->Append(k); |
206 | } |
207 | else |
208 | ClearOsculFlags(); //myAlong.SetValue(2,Standard_False); |
209 | } |
210 | } |
211 | } |
212 | if (myAlong(3) || myAlong(4)) |
213 | { |
214 | for (i=1;i<InitSurf->NbVKnots();i++) |
215 | { |
216 | if (myAlong(3)) |
217 | { |
218 | S = InitSurf; k=0; IsQPunc=Standard_True; |
219 | UKnot=1; |
220 | VKnot=i; |
221 | while(IsQPunc) |
222 | { |
223 | OsculSurf = BuildOsculatingSurface(U1,UKnot,VKnot,S,L); |
224 | if(!OsculSurf) break; |
225 | k++; |
0797d9d3 |
226 | #ifdef OCCT_DEBUG |
3d58dc49 |
227 | cout<<"1.k = "<<k<<endl; |
7fd59977 |
228 | #endif |
3d58dc49 |
229 | IsQPunc=IsQPunctual(L,U1,GeomAbs_IsoU,0.,Tol); |
230 | UKnot=1; |
231 | VKnot=1; |
232 | S=L; |
233 | } |
234 | if(OsculSurf) |
235 | myOsculSurf1->Append(L); |
236 | else |
237 | ClearOsculFlags(); //myAlong.SetValue(3,Standard_False); |
238 | if (myAlong(4) && OsculSurf ) |
239 | { |
240 | S = InitSurf; k=0; IsQPunc=Standard_True; |
241 | UKnot=InitSurf->NbUKnots()-1; |
242 | VKnot=i; |
243 | while(IsQPunc) |
244 | { |
245 | OsculSurf = BuildOsculatingSurface(U2,UKnot,VKnot,S,L); |
246 | if(!OsculSurf) break; |
247 | k++; |
0797d9d3 |
248 | #ifdef OCCT_DEBUG |
3d58dc49 |
249 | cout<<"2.k = "<<k<<endl; |
7fd59977 |
250 | #endif |
3d58dc49 |
251 | IsQPunc=IsQPunctual(L,U2,GeomAbs_IsoU,0.,Tol); |
252 | UKnot=1; |
253 | VKnot=1; |
254 | S=L; |
255 | } |
256 | if(OsculSurf) |
257 | { |
258 | myOsculSurf2->Append(L); |
259 | myKdeg->Append(k); |
260 | } |
261 | } |
262 | } |
263 | else |
264 | { |
265 | S = InitSurf; k=0; IsQPunc=Standard_True; |
266 | UKnot=InitSurf->NbUKnots()-1; |
267 | VKnot=i; |
268 | while(IsQPunc) |
269 | { |
270 | OsculSurf = BuildOsculatingSurface(U2,UKnot,VKnot,S,L); |
271 | if(!OsculSurf) break; |
272 | k++; |
0797d9d3 |
273 | #ifdef OCCT_DEBUG |
3d58dc49 |
274 | cout<<"2.k = "<<k<<endl; |
7fd59977 |
275 | #endif |
3d58dc49 |
276 | IsQPunc=IsQPunctual(L,U2,GeomAbs_IsoU,0.,Tol); |
277 | UKnot=1; |
278 | VKnot=1; |
279 | S=L; |
280 | } |
281 | if(OsculSurf) |
282 | { |
283 | myOsculSurf2->Append(L); |
284 | myKdeg->Append(k); |
285 | } |
286 | else |
287 | ClearOsculFlags(); //myAlong.SetValue(4,Standard_False); |
288 | } |
289 | } |
290 | } |
291 | } |
292 | else |
293 | { |
294 | ClearOsculFlags(); |
295 | } |
7fd59977 |
296 | } |
3d58dc49 |
297 | } |
7fd59977 |
298 | else |
299 | ClearOsculFlags(); |
300 | } |
301 | |
302 | //======================================================================= |
303 | //function : BasisSurface |
304 | //purpose : |
305 | //======================================================================= |
306 | |
3d58dc49 |
307 | Handle(Geom_Surface) Geom_OsculatingSurface::BasisSurface() const |
7fd59977 |
308 | { |
309 | return myBasisSurf; |
310 | } |
311 | |
312 | //======================================================================= |
313 | //function : Tolerance |
314 | //purpose : |
315 | //======================================================================= |
316 | |
317 | Standard_Real Geom_OsculatingSurface::Tolerance() const |
318 | { |
319 | return myTol; |
320 | } |
321 | |
322 | //======================================================================= |
323 | //function : UOscSurf |
324 | //purpose : |
325 | //======================================================================= |
326 | |
327 | Standard_Boolean Geom_OsculatingSurface::UOscSurf |
3d58dc49 |
328 | (const Standard_Real U, |
329 | const Standard_Real V, |
330 | Standard_Boolean& t, |
331 | Handle(Geom_BSplineSurface)& L) const |
7fd59977 |
332 | { |
333 | Standard_Boolean along = Standard_False; |
334 | if (myAlong(1) || myAlong(2)) |
335 | { |
336 | Standard_Integer NU = 1, NV = 1; |
337 | Standard_Real u1,u2,v1,v2; |
338 | t = Standard_False; |
339 | myBasisSurf->Bounds(u1,u2,v1,v2); |
340 | Standard_Integer NbUK,NbVK; |
341 | Standard_Boolean isToSkipSecond = Standard_False; |
342 | if (myBasisSurf->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) |
343 | { |
344 | Handle(Geom_BSplineSurface) BSur = |
c5f3a425 |
345 | Handle(Geom_BSplineSurface)::DownCast (myBasisSurf); |
7fd59977 |
346 | NbUK = BSur->NbUKnots(); |
347 | NbVK = BSur->NbVKnots(); |
348 | TColStd_Array1OfReal UKnots(1,NbUK); |
349 | TColStd_Array1OfReal VKnots(1,NbVK); |
350 | BSur->UKnots(UKnots); |
351 | BSur->VKnots(VKnots); |
352 | BSplCLib::Hunt(UKnots,U,NU); |
353 | BSplCLib::Hunt(VKnots,V,NV); |
354 | if (NU < 1) NU=1; |
355 | if (NU >= NbUK) NU=NbUK-1; |
356 | if (NbVK==2 && NV==1) |
3d58dc49 |
357 | // Need to find the closest end |
358 | if (VKnots(NbVK)-V > V-VKnots(1)) |
359 | isToSkipSecond = Standard_True; |
7fd59977 |
360 | } |
361 | else {NU = 1; NV = 1 ; NbVK = 2 ;} |
362 | |
363 | if (myAlong(1) && NV == 1) |
364 | { |
365 | L = *((Handle(Geom_BSplineSurface)*)& myOsculSurf1->Value(NU)); |
366 | along = Standard_True; |
367 | } |
368 | if (myAlong(2) && (NV == NbVK-1) && !isToSkipSecond) |
369 | { |
370 | // t means that derivative vector of osculating surface is opposite |
371 | // to the original. This happens when (v-t)^k is negative, i.e. |
372 | // difference between degrees (k) is odd and t is the last parameter |
373 | if (myKdeg->Value(NU)%2) t = Standard_True; |
374 | L = *((Handle(Geom_BSplineSurface)*)& myOsculSurf2->Value(NU)); |
375 | along = Standard_True; |
376 | } |
377 | } |
378 | return along; |
379 | } |
380 | |
381 | //======================================================================= |
382 | //function : VOscSurf |
383 | //purpose : |
384 | //======================================================================= |
385 | |
386 | Standard_Boolean Geom_OsculatingSurface::VOscSurf |
3d58dc49 |
387 | (const Standard_Real U, |
388 | const Standard_Real V, |
389 | Standard_Boolean& t, |
390 | Handle(Geom_BSplineSurface)& L) const |
7fd59977 |
391 | { |
392 | Standard_Boolean along = Standard_False; |
393 | if (myAlong(3) || myAlong(4)) |
394 | { |
395 | Standard_Integer NU = 1, NV = 1; |
396 | Standard_Real u1,u2,v1,v2; |
397 | t = Standard_False; |
398 | myBasisSurf->Bounds(u1,u2,v1,v2); |
399 | Standard_Integer NbUK,NbVK; |
400 | Standard_Boolean isToSkipSecond = Standard_False; |
401 | if (myBasisSurf->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) |
402 | { |
403 | Handle(Geom_BSplineSurface) BSur = |
c5f3a425 |
404 | Handle(Geom_BSplineSurface)::DownCast (myBasisSurf); |
7fd59977 |
405 | NbUK = BSur->NbUKnots(); |
406 | NbVK = BSur->NbVKnots(); |
407 | TColStd_Array1OfReal UKnots(1,NbUK); |
408 | TColStd_Array1OfReal VKnots(1,NbVK); |
409 | BSur->UKnots(UKnots); |
410 | BSur->VKnots(VKnots); |
411 | BSplCLib::Hunt(UKnots,U,NU); |
412 | BSplCLib::Hunt(VKnots,V,NV); |
413 | if (NV < 1) NV=1; |
414 | if (NV >= NbVK) NV=NbVK-1; |
415 | if (NbUK==2 && NU==1) |
3d58dc49 |
416 | // Need to find the closest end |
417 | if (UKnots(NbUK)-U > U-UKnots(1)) |
418 | isToSkipSecond = Standard_True; |
7fd59977 |
419 | } |
420 | else {NU = 1; NV = 1 ; NbUK = 2;} |
421 | |
422 | if (myAlong(3) && NU == 1) |
423 | { |
424 | L = *((Handle(Geom_BSplineSurface)*)& myOsculSurf1->Value(NV)); |
425 | along = Standard_True; |
426 | } |
427 | if (myAlong(4) && (NU == NbUK-1) && !isToSkipSecond) |
428 | { |
429 | if (myKdeg->Value(NV)%2) t = Standard_True; |
430 | L = *((Handle(Geom_BSplineSurface)*)& myOsculSurf2->Value(NV)); |
431 | along = Standard_True; |
432 | } |
433 | } |
434 | return along; |
435 | } |
436 | |
437 | //======================================================================= |
438 | //function : BuildOsculatingSurface |
439 | //purpose : |
440 | //======================================================================= |
441 | |
442 | Standard_Boolean Geom_OsculatingSurface::BuildOsculatingSurface |
3d58dc49 |
443 | (const Standard_Real Param, |
444 | const Standard_Integer SUKnot, |
445 | const Standard_Integer SVKnot, |
446 | const Handle(Geom_BSplineSurface)& BS, |
447 | Handle(Geom_BSplineSurface)& BSpl) const |
7fd59977 |
448 | { |
449 | Standard_Integer i, j; |
450 | Standard_Boolean OsculSurf=Standard_True; |
0797d9d3 |
451 | #ifdef OCCT_DEBUG |
7fd59977 |
452 | cout<<"t = "<<Param<<endl; |
453 | cout<<"======================================"<<endl<<endl; |
454 | #endif |
455 | |
3d58dc49 |
456 | // for cache |
7fd59977 |
457 | Standard_Integer MinDegree, |
3d58dc49 |
458 | MaxDegree ; |
7fd59977 |
459 | Standard_Real udeg, vdeg; |
460 | udeg = BS->UDegree(); |
461 | vdeg = BS->VDegree(); |
462 | if( (IsAlongU() && vdeg <=1) || (IsAlongV() && udeg <=1)) |
463 | { |
0797d9d3 |
464 | #ifdef OCCT_DEBUG |
3d58dc49 |
465 | cout<<" surface osculatrice nulle "<<endl; |
7fd59977 |
466 | #endif |
3d58dc49 |
467 | //Standard_ConstructionError::Raise("Geom_OsculatingSurface"); |
468 | OsculSurf=Standard_False; |
7fd59977 |
469 | } |
470 | else |
471 | { |
3d58dc49 |
472 | MinDegree = (Standard_Integer ) Min(udeg,vdeg) ; |
473 | MaxDegree = (Standard_Integer ) Max(udeg,vdeg) ; |
474 | |
475 | TColgp_Array2OfPnt cachepoles(1, MaxDegree + 1, 1, MinDegree + 1); |
476 | // end for cache |
477 | |
478 | // for polynomial grid |
479 | Standard_Integer MaxUDegree, MaxVDegree; |
480 | Standard_Integer UContinuity, VContinuity; |
481 | |
482 | Handle(TColStd_HArray2OfInteger) NumCoeffPerSurface = |
483 | new TColStd_HArray2OfInteger(1, 1, 1, 2); |
484 | Handle(TColStd_HArray1OfReal) PolynomialUIntervals = |
485 | new TColStd_HArray1OfReal(1, 2); |
486 | Handle(TColStd_HArray1OfReal) PolynomialVIntervals = |
487 | new TColStd_HArray1OfReal(1, 2); |
488 | Handle(TColStd_HArray1OfReal) TrueUIntervals = |
489 | new TColStd_HArray1OfReal(1, 2); |
490 | Handle(TColStd_HArray1OfReal) TrueVIntervals = |
491 | new TColStd_HArray1OfReal(1, 2); |
492 | MaxUDegree = (Standard_Integer ) udeg; |
493 | MaxVDegree = (Standard_Integer ) vdeg; |
494 | |
495 | for (i=1;i<=2;i++) |
496 | { |
497 | PolynomialUIntervals->ChangeValue(i) = i-1; |
498 | PolynomialVIntervals->ChangeValue(i) = i-1; |
499 | TrueUIntervals->ChangeValue(i) = BS->UKnot(SUKnot+i-1); |
500 | TrueVIntervals->ChangeValue(i) = BS->VKnot(SVKnot+i-1); |
501 | } |
7fd59977 |
502 | |
503 | |
3d58dc49 |
504 | Standard_Integer OscUNumCoeff=0, OscVNumCoeff=0; |
505 | if (IsAlongU()) |
506 | { |
0797d9d3 |
507 | #ifdef OCCT_DEBUG |
3d58dc49 |
508 | cout<<">>>>>>>>>>> AlongU"<<endl; |
7fd59977 |
509 | #endif |
3d58dc49 |
510 | OscUNumCoeff = (Standard_Integer ) udeg + 1; |
511 | OscVNumCoeff = (Standard_Integer ) vdeg; |
512 | } |
513 | if (IsAlongV()) |
514 | { |
0797d9d3 |
515 | #ifdef OCCT_DEBUG |
3d58dc49 |
516 | cout<<">>>>>>>>>>> AlongV"<<endl; |
7fd59977 |
517 | #endif |
3d58dc49 |
518 | OscUNumCoeff = (Standard_Integer ) udeg; |
519 | OscVNumCoeff = (Standard_Integer ) vdeg + 1; |
520 | } |
521 | NumCoeffPerSurface->ChangeValue(1,1) = OscUNumCoeff; |
522 | NumCoeffPerSurface->ChangeValue(1,2) = OscVNumCoeff; |
523 | Standard_Integer nbc = NumCoeffPerSurface->Value(1,1)*NumCoeffPerSurface->Value(1,2)*3; |
524 | // |
525 | if(nbc == 0) |
526 | { |
527 | return Standard_False; |
528 | } |
529 | // |
530 | Handle(TColStd_HArray1OfReal) Coefficients = new TColStd_HArray1OfReal(1, nbc); |
531 | // end for polynomial grid |
532 | |
533 | // building the cache |
534 | Standard_Integer ULocalIndex, VLocalIndex; |
535 | Standard_Real ucacheparameter, vcacheparameter,uspanlength, vspanlength; |
536 | TColgp_Array2OfPnt NewPoles(1, BS->NbUPoles(), 1, BS->NbVPoles()); |
537 | |
538 | Standard_Integer aUfKnotsLength = BS->NbUPoles() + BS->UDegree() + 1; |
539 | Standard_Integer aVfKnotsLength = BS->NbVPoles() + BS->VDegree() + 1; |
540 | |
541 | if(BS->IsUPeriodic()) |
542 | { |
543 | TColStd_Array1OfInteger aMults(1, BS->NbUKnots()); |
544 | BS->UMultiplicities(aMults); |
545 | aUfKnotsLength = BSplCLib::KnotSequenceLength(aMults, BS->UDegree(), Standard_True); |
546 | } |
547 | |
548 | if(BS->IsVPeriodic()) |
549 | { |
550 | TColStd_Array1OfInteger aMults(1, BS->NbVKnots()); |
551 | BS->VMultiplicities(aMults); |
552 | aVfKnotsLength = BSplCLib::KnotSequenceLength(aMults, BS->VDegree(), Standard_True); |
553 | } |
554 | |
555 | TColStd_Array1OfReal UFlatKnots(1, aUfKnotsLength); |
556 | TColStd_Array1OfReal VFlatKnots(1, aVfKnotsLength); |
557 | BS->Poles(NewPoles); |
558 | BS->UKnotSequence(UFlatKnots); |
559 | BS->VKnotSequence(VFlatKnots); |
560 | |
561 | VLocalIndex = 0; |
562 | ULocalIndex = 0; |
563 | for(j = 1; j <= SVKnot; j++) VLocalIndex += BS->VMultiplicity(j); |
564 | for(i = 1; i <= SUKnot; i++) ULocalIndex += BS->UMultiplicity(i); |
565 | ucacheparameter = BS->UKnot(SUKnot); |
566 | vcacheparameter = BS->VKnot(SVKnot); |
567 | vspanlength = BS->VKnot(SVKnot + 1) - BS->VKnot(SVKnot); |
568 | uspanlength = BS->UKnot(SUKnot + 1) - BS->UKnot(SUKnot); |
569 | |
570 | // On se ramene toujours a un parametrage tel que localement ce soit l'iso |
571 | // u=0 ou v=0 qui soit degeneree |
572 | |
573 | Standard_Boolean IsVNegative = Param > vcacheparameter + vspanlength/2; |
574 | Standard_Boolean IsUNegative = Param > ucacheparameter + uspanlength/2; |
575 | |
576 | if (IsAlongU() && (Param > vcacheparameter + vspanlength/2)) |
577 | vcacheparameter = vcacheparameter + vspanlength; |
578 | if (IsAlongV() && (Param > ucacheparameter + uspanlength/2)) |
579 | ucacheparameter = ucacheparameter + uspanlength; |
580 | |
581 | BSplSLib::BuildCache(ucacheparameter, |
582 | vcacheparameter, |
583 | uspanlength, |
584 | vspanlength, |
585 | BS->IsUPeriodic(), |
586 | BS->IsVPeriodic(), |
587 | BS->UDegree(), |
588 | BS->VDegree(), |
589 | ULocalIndex, |
590 | VLocalIndex, |
591 | UFlatKnots, |
592 | VFlatKnots, |
593 | NewPoles, |
594 | BSplSLib::NoWeights(), |
595 | cachepoles, |
596 | BSplSLib::NoWeights()); |
597 | Standard_Integer m, n, index; |
598 | TColgp_Array2OfPnt OscCoeff(1,OscUNumCoeff , 1, OscVNumCoeff); |
599 | |
600 | if (IsAlongU()) |
601 | { |
602 | if (udeg > vdeg) |
603 | { |
604 | for(n = 1; n <= udeg + 1; n++) |
605 | for(m = 1; m <= vdeg; m++) |
606 | OscCoeff(n,m) = cachepoles(n,m+1) ; |
607 | } |
608 | else |
609 | { |
610 | for(n = 1; n <= udeg + 1; n++) |
611 | for(m = 1; m <= vdeg; m++) |
612 | OscCoeff(n,m) = cachepoles(m+1,n) ; |
7fd59977 |
613 | } |
3d58dc49 |
614 | if (IsVNegative) PLib::VTrimming(-1,0,OscCoeff,PLib::NoWeights2()); |
615 | |
616 | index=1; |
617 | for(n = 1; n <= udeg + 1; n++) |
618 | for(m = 1; m <= vdeg; m++) |
619 | { |
620 | Coefficients->ChangeValue(index++) = OscCoeff(n,m).X(); |
621 | Coefficients->ChangeValue(index++) = OscCoeff(n,m).Y(); |
622 | Coefficients->ChangeValue(index++) = OscCoeff(n,m).Z(); |
623 | } |
624 | } |
625 | |
626 | if (IsAlongV()) |
627 | { |
628 | if (udeg > vdeg) |
629 | { |
630 | for(n = 1; n <= udeg; n++) |
631 | for(m = 1; m <= vdeg + 1; m++) |
632 | OscCoeff(n,m) = cachepoles(n+1,m); |
633 | } |
634 | else |
635 | { |
636 | for(n = 1; n <= udeg; n++) |
637 | for(m = 1; m <= vdeg + 1; m++) |
638 | OscCoeff(n,m) = cachepoles(m,n+1); |
639 | } |
640 | if (IsUNegative) PLib::UTrimming(-1,0,OscCoeff,PLib::NoWeights2()); |
641 | index=1; |
642 | for(n = 1; n <= udeg; n++) |
643 | for(m = 1; m <= vdeg + 1; m++) |
644 | { |
645 | Coefficients->ChangeValue(index++) = OscCoeff(n,m).X(); |
646 | Coefficients->ChangeValue(index++) = OscCoeff(n,m).Y(); |
647 | Coefficients->ChangeValue(index++) = OscCoeff(n,m).Z(); |
648 | } |
649 | } |
650 | |
651 | if (IsAlongU()) MaxVDegree--; |
652 | if (IsAlongV()) MaxUDegree--; |
653 | UContinuity = - 1; |
654 | VContinuity = - 1; |
655 | |
656 | Convert_GridPolynomialToPoles Data(1,1, |
657 | UContinuity, |
658 | VContinuity, |
659 | MaxUDegree, |
660 | MaxVDegree, |
661 | NumCoeffPerSurface, |
662 | Coefficients, |
663 | PolynomialUIntervals, |
664 | PolynomialVIntervals, |
665 | TrueUIntervals, |
666 | TrueVIntervals); |
667 | |
668 | // Handle(Geom_BSplineSurface) BSpl = |
669 | BSpl =new Geom_BSplineSurface(Data.Poles()->Array2(), |
670 | Data.UKnots()->Array1(), |
671 | Data.VKnots()->Array1(), |
672 | Data.UMultiplicities()->Array1(), |
673 | Data.VMultiplicities()->Array1(), |
674 | Data.UDegree(), |
675 | Data.VDegree(), |
676 | 0, 0); |
0797d9d3 |
677 | #ifdef OCCT_DEBUG |
3d58dc49 |
678 | cout<<"^====================================^"<<endl<<endl; |
7fd59977 |
679 | #endif |
680 | |
3d58dc49 |
681 | // L=BSpl; |
682 | } |
7fd59977 |
683 | return OsculSurf; |
684 | } |
685 | |
686 | //======================================================================= |
687 | //function : IsQPunctual |
688 | //purpose : |
689 | //======================================================================= |
690 | |
691 | Standard_Boolean Geom_OsculatingSurface::IsQPunctual |
3d58dc49 |
692 | (const Handle(Geom_Surface)& S, |
693 | const Standard_Real Param, |
694 | const GeomAbs_IsoType IT, |
695 | const Standard_Real TolMin, |
696 | const Standard_Real TolMax) const |
7fd59977 |
697 | { |
3d58dc49 |
698 | Standard_Real U1=0,U2=0,V1=0,V2=0,T; |
699 | Standard_Boolean Along = Standard_True; |
700 | S->Bounds(U1,U2,V1,V2); |
701 | gp_Vec D1U,D1V; |
702 | gp_Pnt P; |
703 | Standard_Real Step,D1NormMax; |
704 | if (IT == GeomAbs_IsoV) |
705 | { |
706 | Step = (U2 - U1)/10; |
707 | D1NormMax=0.; |
708 | for (T=U1;T<=U2;T=T+Step) |
7fd59977 |
709 | { |
3d58dc49 |
710 | S->D1(T,Param,P,D1U,D1V); |
711 | D1NormMax=Max(D1NormMax,D1U.Magnitude()); |
712 | } |
7fd59977 |
713 | |
0797d9d3 |
714 | #ifdef OCCT_DEBUG |
3d58dc49 |
715 | cout << " D1NormMax = " << D1NormMax << endl; |
7fd59977 |
716 | #endif |
3d58dc49 |
717 | if (D1NormMax >TolMax || D1NormMax < TolMin ) |
718 | Along = Standard_False; |
719 | } |
720 | else |
721 | { |
722 | Step = (V2 - V1)/10; |
723 | D1NormMax=0.; |
724 | for (T=V1;T<=V2;T=T+Step) |
7fd59977 |
725 | { |
3d58dc49 |
726 | S->D1(Param,T,P,D1U,D1V); |
727 | D1NormMax=Max(D1NormMax,D1V.Magnitude()); |
728 | } |
0797d9d3 |
729 | #ifdef OCCT_DEBUG |
3d58dc49 |
730 | cout << " D1NormMax = " << D1NormMax << endl; |
7fd59977 |
731 | #endif |
3d58dc49 |
732 | if (D1NormMax >TolMax || D1NormMax < TolMin ) |
733 | Along = Standard_False; |
7fd59977 |
734 | |
735 | |
3d58dc49 |
736 | } |
737 | return Along; |
7fd59977 |
738 | } |
739 | |
740 | //======================================================================= |
741 | //function : HasOscSurf |
742 | //purpose : |
743 | //======================================================================= |
744 | |
3d58dc49 |
745 | Standard_Boolean Geom_OsculatingSurface::HasOscSurf() const |
7fd59977 |
746 | { |
747 | return (myAlong(1) || myAlong(2) || myAlong(3) || myAlong(4)); |
748 | } |
749 | |
750 | //======================================================================= |
751 | //function : IsAlongU |
752 | //purpose : |
753 | //======================================================================= |
754 | |
755 | Standard_Boolean Geom_OsculatingSurface::IsAlongU() const |
756 | { |
757 | return (myAlong(1) || myAlong(2)); |
758 | } |
759 | //======================================================================= |
760 | //function : IsAlongV |
761 | //purpose : |
762 | //======================================================================= |
763 | |
764 | Standard_Boolean Geom_OsculatingSurface::IsAlongV() const |
765 | { |
766 | return (myAlong(3) || myAlong(4)); |
767 | } |
768 | |
769 | |
770 | //======================================================================= |
771 | //function : IsGetSeqOfL1 |
772 | //purpose : |
773 | //======================================================================= |
774 | |
775 | const Geom_SequenceOfBSplineSurface& Geom_OsculatingSurface::GetSeqOfL1() const |
776 | { |
777 | return myOsculSurf1->Sequence(); |
778 | } |
779 | //======================================================================= |
780 | //function : IsGetSeqOfL2 |
781 | //purpose : |
782 | //======================================================================= |
783 | |
784 | const Geom_SequenceOfBSplineSurface& Geom_OsculatingSurface::GetSeqOfL2() const |
785 | { |
786 | return myOsculSurf2->Sequence(); |
787 | } |
788 | //======================================================================= |
789 | //function : ClearOsculFlags |
790 | //purpose : |
791 | //======================================================================= |
792 | |
793 | void Geom_OsculatingSurface::ClearOsculFlags() |
794 | { |
3d58dc49 |
795 | myAlong.SetValue(1,Standard_False); |
796 | myAlong.SetValue(2,Standard_False); |
797 | myAlong.SetValue(3,Standard_False); |
798 | myAlong.SetValue(4,Standard_False); |
7fd59977 |
799 | |
800 | } |
801 | |
802 | |
803 | |