0022922: Clean up warnings on uninitialized / unused variables
[occt.git] / src / GeomFill / GeomFill_Frenet.cxx
CommitLineData
7fd59977 1// File: GeomFill_Frenet.cxx
2// Created: Thu Jan 22 09:12:54 1998
3// Author: Philippe MANGIN/Roman BORISOV
4// <pmn@sgi29>
5
6#include <GeomFill_Frenet.ixx>
7#include <GeomAbs_CurveType.hxx>
8#include <Adaptor3d_HCurve.hxx>
9#include <Precision.hxx>
10#include <GeomLib.hxx>
11#include <GeomFill_SnglrFunc.hxx>
12#include <Extrema_ExtPC.hxx>
13#include <TColStd_HArray1OfBoolean.hxx>
14#include <SortTools_QuickSortOfReal.hxx>
15#include <TCollection_CompareOfReal.hxx>
16#include <TColgp_SequenceOfPnt2d.hxx>
17
18#define NullTol 1.e-10
19#define MaxSingular 1.e-5
20
21//=======================================================================
22//function : FDeriv
23//purpose : computes (F/|F|)'
24//=======================================================================
25static gp_Vec FDeriv(const gp_Vec& F, const gp_Vec& DF)
26{
27 Standard_Real Norma = F.Magnitude();
28 gp_Vec Result = (DF - F*(F*DF)/(Norma*Norma))/Norma;
29 return Result;
30}
31
32
33//=======================================================================
34//function : DDeriv
35//purpose : computes (F/|F|)''
36//=======================================================================
37static gp_Vec DDeriv(const gp_Vec& F, const gp_Vec& DF, const gp_Vec& D2F)
38{
39 Standard_Real Norma = F.Magnitude();
40 gp_Vec Result = (D2F - 2*DF*(F*DF)/(Norma*Norma))/Norma -
41 F*((DF.SquareMagnitude() + F*D2F
42 - 3*(F*DF)*(F*DF)/(Norma*Norma))/(Norma*Norma*Norma));
43 return Result;
44}
45
46//=======================================================================
47//function : GeomFill_Frenet
48//purpose :
49//=======================================================================
50
51GeomFill_Frenet::GeomFill_Frenet()
52{
53}
54
55
56//=======================================================================
57//function : Copy
58//purpose :
59//=======================================================================
60
61Handle(GeomFill_TrihedronLaw) GeomFill_Frenet::Copy() const
62{
63 Handle(GeomFill_Frenet) copy = new (GeomFill_Frenet)();
64 if (!myCurve.IsNull()) copy->SetCurve(myCurve);
65 return copy;
66}
67
68//=======================================================================
69//function : SetCurve
70//purpose :
71//=======================================================================
72
73 void GeomFill_Frenet::SetCurve(const Handle(Adaptor3d_HCurve)& C)
74{
75 GeomFill_TrihedronLaw::SetCurve(C);
76 if (! C.IsNull()) {
77 GeomAbs_CurveType type;
78 type = C->GetType();
79 switch (type) {
80 case GeomAbs_Circle:
81 case GeomAbs_Ellipse:
82 case GeomAbs_Hyperbola:
83 case GeomAbs_Parabola:
84 case GeomAbs_Line:
85 {
86 // No probleme
87 isSngl = Standard_False;
88 }
89 default :
90 {
91 // We have to search singulaties
92 Init();
93 }
94 }
95 }
96}
97
98//=======================================================================
99//function : Init
100//purpose :
101//=======================================================================
102
103 void GeomFill_Frenet::Init()
104{
105 Standard_Integer i, j;
106 GeomFill_SnglrFunc Func(myCurve);
107 Standard_Real TolF = 1.0e-10, Tol = 10*TolF, Tol2 = Tol * Tol,
108 PTol = Precision::PConfusion();
109
110// We want to determine if the curve has linear segments
111 Standard_Integer NbIntC2 = myCurve->NbIntervals(GeomAbs_C2);
112 Handle(TColStd_HArray1OfReal) myC2Disc =
113 new TColStd_HArray1OfReal(1, NbIntC2 + 1);
114 Handle(TColStd_HArray1OfBoolean) IsLin =
115 new TColStd_HArray1OfBoolean(1, NbIntC2);
116 Handle(TColStd_HArray1OfBoolean) IsConst =
117 new TColStd_HArray1OfBoolean(1, NbIntC2);
118 TColStd_Array1OfReal AveFunc(1, NbIntC2);
119 myCurve->Intervals(myC2Disc->ChangeArray1(), GeomAbs_C2);
120 Standard_Integer NbControl = 10;
121 Standard_Real Step, Average = 0, modulus;
122 gp_Pnt C, C1;
123 for(i = 1; i <= NbIntC2; i++) {
124 Step = (myC2Disc->Value(i+1) - myC2Disc->Value(i))/NbControl;
125 IsLin->ChangeValue(i) = Standard_True;
126 IsConst->ChangeValue(i) = Standard_True;
127 for(j = 1; j <= NbControl; j++) {
128 Func.D0(myC2Disc->Value(i) + (j-1)*Step, C);
129 if(j == 1) C1 = C;
130 modulus = C.XYZ().Modulus();
131 if(modulus > Tol) {
132 IsLin->ChangeValue(i) = Standard_False;
133 }
134 Average += modulus;
135
136 if(IsConst->Value(i)) {
137 if(Abs(C.X() - C1.X()) > Tol ||
138 Abs(C.Y() - C1.Y()) > Tol ||
139 Abs(C.Z() - C1.Z()) > Tol) {
140 IsConst->ChangeValue(i) = Standard_False;
141 }
142 }
143
144 }
145 AveFunc(i) = Average/NbControl;
146 }
147
148// Here we are looking for singularities
149 TColStd_SequenceOfReal * SeqArray = new TColStd_SequenceOfReal[ NbIntC2 ];
150 TColStd_SequenceOfReal SnglSeq;
151// Standard_Real Value2, preValue=1.e200, t;
152 Standard_Real Value2, t;
153 Extrema_ExtPC Ext;
154 gp_Pnt Origin(0, 0, 0);
155
156 for(i = 1; i <= NbIntC2; i++) {
157 if (!IsLin->Value(i) && !IsConst->Value(i))
158 {
159 Func.SetRatio(1./AveFunc(i)); // Normalization
160 Ext.Initialize(Func, myC2Disc->Value(i), myC2Disc->Value(i+1), TolF);
161 Ext.Perform(Origin);
162 if(Ext.IsDone() && Ext.NbExt() != 0)
163 {
164 for(j = 1; j <= Ext.NbExt(); j++)
165 {
166 Value2 = Ext.SquareDistance(j);
167 if(Value2 < Tol2)
168 {
169 t = Ext.Point(j).Parameter();
170 SeqArray[i-1].Append(t);
171 }
172 }
173 }
174 // sorting
175 if(SeqArray[i-1].Length() != 0) {
176 TColStd_Array1OfReal anArray( 1, SeqArray[i-1].Length() );
177 for (j = 1; j <= anArray.Length(); j++)
178 anArray(j) = SeqArray[i-1](j);
179 TCollection_CompareOfReal Compar;
180 SortTools_QuickSortOfReal::Sort( anArray, Compar);
181 for (j = 1; j <= anArray.Length(); j++)
182 SeqArray[i-1](j) = anArray(j);
183 }
184 }
185 }
186 //Filling SnglSeq by first sets of roots
187 for(i = 0; i < NbIntC2; i++)
188 for (j = 1; j <= SeqArray[i].Length(); j++)
189 SnglSeq.Append( SeqArray[i](j) );
190
191 //Extrema works bad, need to pass second time
192 for(i = 0; i < NbIntC2; i++)
193 if (! SeqArray[i].IsEmpty())
194 {
195 SeqArray[i].Prepend( myC2Disc->Value(i+1) );
196 SeqArray[i].Append( myC2Disc->Value(i+2) );
197 Func.SetRatio(1./AveFunc(i+1)); // Normalization
198 for (j = 1; j < SeqArray[i].Length(); j++)
199 if (SeqArray[i](j+1) - SeqArray[i](j) > PTol)
200 {
201 Ext.Initialize(Func, SeqArray[i](j), SeqArray[i](j+1), TolF);
202 Ext.Perform(Origin);
203 if(Ext.IsDone())
204 {
205 for(Standard_Integer k = 1; k <= Ext.NbExt(); k++)
206 {
207 Value2 = Ext.SquareDistance(k);
208 if(Value2 < Tol2)
209 {
210 t = Ext.Point(k).Parameter();
211 if (t-SeqArray[i](j) > PTol && SeqArray[i](j+1)-t > PTol)
212 SnglSeq.Append(t);
213 }
214 }
215 }
216 }
217 }
218
219 delete [] SeqArray;
220
221 if(SnglSeq.Length() > 0) {
222 // sorting
223 TColStd_Array1OfReal anArray( 1, SnglSeq.Length() );
224 for (i = 1; i <= SnglSeq.Length(); i++)
225 anArray(i) = SnglSeq(i);
226 TCollection_CompareOfReal Compar;
227 SortTools_QuickSortOfReal::Sort( anArray, Compar );
228 for (i = 1; i <= SnglSeq.Length(); i++)
229 SnglSeq(i) = anArray(i);
230
231 // discard repeating elements
232 Standard_Boolean found = Standard_True;
233 j = 1;
234 while (found)
235 {
236 found = Standard_False;
237 for (i = j; i < SnglSeq.Length(); i++)
238 if (SnglSeq(i+1) - SnglSeq(i) <= PTol)
239 {
240 SnglSeq.Remove(i+1);
241 j = i;
242 found = Standard_True;
243 break;
244 }
245 }
246
247 mySngl = new TColStd_HArray1OfReal(1, SnglSeq.Length());
248 for(i = 1; i <= mySngl->Length(); i++)
249 mySngl->ChangeValue(i) = SnglSeq(i);
250
251// computation of length of singular interval
252 mySnglLen = new TColStd_HArray1OfReal(1, mySngl->Length());
253 gp_Vec SnglDer, SnglDer2;
254 Standard_Real norm;
255 for(i = 1; i <= mySngl->Length(); i++) {
256 Func.D2(mySngl->Value(i), C, SnglDer, SnglDer2);
257 if ((norm = SnglDer.Magnitude()) > gp::Resolution())
258 mySnglLen->ChangeValue(i) = Min(NullTol/norm, MaxSingular);
259 else if ((norm = SnglDer2.Magnitude()) > gp::Resolution())
260 mySnglLen->ChangeValue(i) = Min(Sqrt(2*NullTol/norm), MaxSingular);
261 else mySnglLen->ChangeValue(i) = MaxSingular;
262 }
263#if DEB
264 for(i = 1; i <= mySngl->Length(); i++) {
265 cout<<"Sngl("<<i<<") = "<<mySngl->Value(i)<<" Length = "<<mySnglLen->Value(i)<<endl;
266 }
267#endif
268 if(mySngl->Length() > 1) {
269// we have to merge singular points that have common parts of singular intervals
270 TColgp_SequenceOfPnt2d tmpSeq;
271 tmpSeq.Append(gp_Pnt2d(mySngl->Value(1), mySnglLen->Value(1)));
272 Standard_Real U11, U12, U21, U22;
273 for(i = 2; i<= mySngl->Length(); i++) {
274 U12 = tmpSeq.Last().X() + tmpSeq.Last().Y();
275 U21 = mySngl->Value(i) - mySnglLen->Value(i);
276 if(U12 >= U21) {
277 U11 = tmpSeq.Last().X() - tmpSeq.Last().Y();
278 U22 = mySngl->Value(i) + mySnglLen->Value(i);
279 tmpSeq.ChangeValue(tmpSeq.Length()) = gp_Pnt2d((U11 + U22)/2, (U22 - U11)/2);
280 }
281 else tmpSeq.Append(gp_Pnt2d(mySngl->Value(i), mySnglLen->Value(i)));
282 }
283 mySngl = new TColStd_HArray1OfReal(1, tmpSeq.Length());
284 mySnglLen = new TColStd_HArray1OfReal(1, tmpSeq.Length());
285 for(i = 1; i <= mySngl->Length(); i++) {
286 mySngl->ChangeValue(i) = tmpSeq(i).X();
287 mySnglLen->ChangeValue(i) = tmpSeq(i).Y();
288 }
289 }
290#if DEB
291 cout<<"After merging"<<endl;
292 for(i = 1; i <= mySngl->Length(); i++) {
293 cout<<"Sngl("<<i<<") = "<<mySngl->Value(i)<<" Length = "<<mySnglLen->Value(i)<<endl;
294 }
295#endif
296 isSngl = Standard_True;
297 }
298 else isSngl = Standard_False;
299}
300
301//=======================================================================
302//function : D0
303//purpose :
304//=======================================================================
305
306 Standard_Boolean GeomFill_Frenet::D0(const Standard_Real Param,
307 gp_Vec& Tangent,
308 gp_Vec& Normal,
309 gp_Vec& BiNormal)
310{
311 Standard_Real norm;
312 Standard_Integer Index;
313 if(IsSingular(Param, Index))
314 if (SingularD0(Param, Index, Tangent, Normal, BiNormal))
315 return Standard_True;
316
317 myTrimmed->D2(Param, P, Tangent, BiNormal);
318 Tangent.Normalize();
319 BiNormal = Tangent.Crossed(BiNormal);
320 norm = BiNormal.Magnitude();
321 if (norm <= gp::Resolution()) {
322 gp_Ax2 Axe (gp_Pnt(0,0,0), Tangent);
323 BiNormal.SetXYZ(Axe.YDirection().XYZ());
324 }
325 else BiNormal.Normalize();
326
327 Normal = BiNormal;
328 Normal.Cross(Tangent);
329
330 return Standard_True;
331}
332
333//=======================================================================
334//function : D1
335//purpose :
336//=======================================================================
337
338 Standard_Boolean GeomFill_Frenet::D1(const Standard_Real Param,
339 gp_Vec& Tangent,
340 gp_Vec& DTangent,
341 gp_Vec& Normal,
342 gp_Vec& DNormal,
343 gp_Vec& BiNormal,
344 gp_Vec& DBiNormal)
345{
346 Standard_Integer Index;
347 if(IsSingular(Param, Index))
348 if (SingularD1(Param, Index, Tangent, DTangent, Normal, DNormal, BiNormal, DBiNormal))
349 return Standard_True;
350
351// Standard_Real Norma;
352 gp_Vec DC1, DC2, DC3;
353 myTrimmed->D3(Param, P, DC1, DC2, DC3);
354 Tangent = DC1.Normalized();
355
356 //if (DC2.Magnitude() <= NullTol || Tangent.Crossed(DC2).Magnitude() <= NullTol) {
357 if (Tangent.Crossed(DC2).Magnitude() <= gp::Resolution()) {
358 gp_Ax2 Axe (gp_Pnt(0,0,0), Tangent);
359 Normal.SetXYZ(Axe.XDirection().XYZ());
360 BiNormal.SetXYZ(Axe.YDirection().XYZ());
361 DTangent.SetCoord(0,0,0);
362 DNormal.SetCoord(0,0,0);
363 DBiNormal.SetCoord(0,0,0);
364 return Standard_True;
365 }
366 else
367 BiNormal = Tangent.Crossed(DC2).Normalized();
368
369 Normal = BiNormal.Crossed(Tangent);
370
371 DTangent = FDeriv(DC1, DC2);
372
373 gp_Vec instead_DC1, instead_DC2;
374 instead_DC1 = Tangent.Crossed(DC2);
375 instead_DC2 = DTangent.Crossed(DC2) + Tangent.Crossed(DC3);
376 DBiNormal = FDeriv(instead_DC1, instead_DC2);
377
378 DNormal = DBiNormal.Crossed(Tangent) + BiNormal.Crossed(DTangent);
379 return Standard_True;
380}
381
382//=======================================================================
383//function : D2
384//purpose :
385//=======================================================================
386
387 Standard_Boolean GeomFill_Frenet::D2(const Standard_Real Param,
388 gp_Vec& Tangent,
389 gp_Vec& DTangent,
390 gp_Vec& D2Tangent,
391 gp_Vec& Normal,
392 gp_Vec& DNormal,
393 gp_Vec& D2Normal,
394 gp_Vec& BiNormal,
395 gp_Vec& DBiNormal,
396 gp_Vec& D2BiNormal)
397{
398 Standard_Integer Index;
399 if(IsSingular(Param, Index))
400 if(SingularD2(Param, Index, Tangent, DTangent, D2Tangent,
401 Normal, DNormal, D2Normal,
402 BiNormal, DBiNormal, D2BiNormal))
403 return Standard_True;
404
405// Standard_Real Norma;
406 gp_Vec DC1, DC2, DC3, DC4;
407 myTrimmed->D3(Param, P, DC1, DC2, DC3);
408 DC4 = myTrimmed->DN(Param, 4);
409
410 Tangent = DC1.Normalized();
411
412 //if (DC2.Magnitude() <= NullTol || Tangent.Crossed(DC2).Magnitude() <= NullTol) {
413 if (Tangent.Crossed(DC2).Magnitude() <= gp::Resolution()) {
414 gp_Ax2 Axe (gp_Pnt(0,0,0), Tangent);
415 Normal.SetXYZ(Axe.XDirection().XYZ());
416 BiNormal.SetXYZ(Axe.YDirection().XYZ());
417 DTangent.SetCoord(0,0,0);
418 DNormal.SetCoord(0,0,0);
419 DBiNormal.SetCoord(0,0,0);
420 D2Tangent.SetCoord(0,0,0);
421 D2Normal.SetCoord(0,0,0);
422 D2BiNormal.SetCoord(0,0,0);
423 return Standard_True;
424 }
425 else
426 BiNormal = Tangent.Crossed(DC2).Normalized();
427
428 Normal = BiNormal.Crossed(Tangent);
429
430 DTangent = FDeriv(DC1, DC2);
431 D2Tangent = DDeriv(DC1, DC2, DC3);
432
433 gp_Vec instead_DC1, instead_DC2, instead_DC3;
434 instead_DC1 = Tangent.Crossed(DC2);
435 instead_DC2 = DTangent.Crossed(DC2) + Tangent.Crossed(DC3);
436 instead_DC3 = D2Tangent.Crossed(DC2) + 2*DTangent.Crossed(DC3) + Tangent.Crossed(DC4);
437 DBiNormal = FDeriv(instead_DC1, instead_DC2);
438 D2BiNormal = DDeriv(instead_DC1, instead_DC2, instead_DC3);
439
440 DNormal = DBiNormal.Crossed(Tangent) + BiNormal.Crossed(DTangent);
441
442 D2Normal = D2BiNormal.Crossed(Tangent) + 2*DBiNormal.Crossed(DTangent) + BiNormal.Crossed(D2Tangent);
443
444 return Standard_True;
445}
446
447//=======================================================================
448//function : NbIntervals
449//purpose :
450//=======================================================================
451
452 Standard_Integer GeomFill_Frenet::NbIntervals(const GeomAbs_Shape S) const
453{
454 GeomAbs_Shape tmpS = GeomAbs_C0;
455 Standard_Integer NbTrimmed;
456 switch (S) {
457 case GeomAbs_C0: tmpS = GeomAbs_C2; break;
458 case GeomAbs_C1: tmpS = GeomAbs_C3; break;
459 case GeomAbs_C2:
460 case GeomAbs_C3:
461 case GeomAbs_CN: tmpS = GeomAbs_CN; break;
462 default: Standard_OutOfRange::Raise();
463 }
464
465 NbTrimmed = myCurve->NbIntervals(tmpS);
466
467 if (!isSngl) return NbTrimmed;
468
469 TColStd_Array1OfReal TrimInt(1, NbTrimmed + 1);
470 myCurve->Intervals(TrimInt, tmpS);
471
472 TColStd_SequenceOfReal Fusion;
473 GeomLib::FuseIntervals(TrimInt, mySngl->Array1(), Fusion);
474
475 return Fusion.Length() - 1;
476}
477
478//=======================================================================
479//function : Intervals
480//purpose :
481//=======================================================================
482
483 void GeomFill_Frenet::Intervals(TColStd_Array1OfReal& T,
484 const GeomAbs_Shape S) const
485{
486 GeomAbs_Shape tmpS = GeomAbs_C0;
487 Standard_Integer NbTrimmed;
488 switch (S) {
489 case GeomAbs_C0: tmpS = GeomAbs_C2; break;
490 case GeomAbs_C1: tmpS = GeomAbs_C3; break;
491 case GeomAbs_C2:
492 case GeomAbs_C3:
493 case GeomAbs_CN: tmpS = GeomAbs_CN; break;
494 default: Standard_OutOfRange::Raise();
495 }
496
497 if (!isSngl) {
498 myCurve->Intervals(T, tmpS);
499 return;
500 }
501
502 NbTrimmed = myCurve->NbIntervals(tmpS);
503 TColStd_Array1OfReal TrimInt(1, NbTrimmed + 1);
504 myCurve->Intervals(TrimInt, tmpS);
505
506 TColStd_SequenceOfReal Fusion;
507 GeomLib::FuseIntervals(TrimInt, mySngl->Array1(), Fusion);
508
509 for (Standard_Integer i = 1; i <= Fusion.Length(); i++)
510 T.ChangeValue(i) = Fusion.Value(i);
511}
512
513 void GeomFill_Frenet::GetAverageLaw(gp_Vec& ATangent,
514 gp_Vec& ANormal,
515 gp_Vec& ABiNormal)
516{
517 Standard_Integer Num = 20; //order of digitalization
518 gp_Vec T, N, BN;
519 ATangent = gp_Vec(0, 0, 0);
520 ANormal = gp_Vec(0, 0, 0);
521 ABiNormal = gp_Vec(0, 0, 0);
522 Standard_Real Step = (myTrimmed->LastParameter() -
523 myTrimmed->FirstParameter()) / Num;
524 Standard_Real Param;
525 for (Standard_Integer i = 0; i <= Num; i++) {
526 Param = myTrimmed->FirstParameter() + i*Step;
527 if (Param > myTrimmed->LastParameter()) Param = myTrimmed->LastParameter();
528 D0(Param, T, N, BN);
529 ATangent += T;
530 ANormal += N;
531 ABiNormal += BN;
532 }
533 ATangent /= Num + 1;
534 ANormal /= Num + 1;
535
536 ATangent.Normalize();
537 ABiNormal = ATangent.Crossed(ANormal).Normalized();
538 ANormal = ABiNormal.Crossed(ATangent);
539}
540
541//=======================================================================
542//function : IsConstant
543//purpose :
544//=======================================================================
545
546 Standard_Boolean GeomFill_Frenet::IsConstant() const
547{
548 return (myCurve->GetType() == GeomAbs_Line);
549}
550
551//=======================================================================
552//function : IsOnlyBy3dCurve
553//purpose :
554//=======================================================================
555
556 Standard_Boolean GeomFill_Frenet::IsOnlyBy3dCurve() const
557{
558 return Standard_True;
559}
560
561//=======================================================================
562//function : IsSingular
563//purpose :
564//=======================================================================
565
566Standard_Boolean GeomFill_Frenet::IsSingular(const Standard_Real U, Standard_Integer& Index) const
567{
568 Standard_Integer i;
569 if(!isSngl) return Standard_False;
570 for(i = 1; i <= mySngl->Length(); i++) {
571 if (Abs(U - mySngl->Value(i)) < mySnglLen->Value(i)) {
572 Index = i;
573 return Standard_True;
574 }
575 }
576 return Standard_False;
577}
578
579//=======================================================================
580//function : DoSingular
581//purpose :
582//=======================================================================
583
584Standard_Boolean GeomFill_Frenet::DoSingular(const Standard_Real U,
585 const Standard_Integer Index,
586 gp_Vec& Tangent,
587 gp_Vec& BiNormal,
588 Standard_Integer& n,
589 Standard_Integer& k,
590 Standard_Integer& TFlag,
591 Standard_Integer& BNFlag)
592{
593 Standard_Integer i, MaxN = 20;
594 Standard_Real h;
595 h = 2*mySnglLen->Value(Index);
596
597 Standard_Real A, B;
598 gp_Vec T, N, BN;
599 TFlag = 1;
600 BNFlag = 1;
601 GetInterval(A, B);
602 if (U >= (A + B)/2) h = -h;
603 for(i = 1; i <= MaxN; i++) {
604 Tangent = myTrimmed->DN(U, i);
605 if(Tangent.Magnitude() > Precision::Confusion()) break;
606 }
607 if (i > MaxN) return Standard_False;
608 Tangent.Normalize();
609 n = i;
610
611 i++;
612 for(; i <= MaxN; i++) {
613 BiNormal = Tangent.Crossed(myTrimmed->DN(U, i));
614 Standard_Real magn = BiNormal.Magnitude();
615 if (magn > Precision::Confusion())
616 {
617 //modified by jgv, 12.08.03 for OCC605 ////
618 gp_Vec NextBiNormal = Tangent.Crossed(myTrimmed->DN(U, i+1));
619 if (NextBiNormal.Magnitude() > magn)
620 {
621 i++;
622 BiNormal = NextBiNormal;
623 }
624 ///////////////////////////////////////////
625 break;
626 }
627 }
628 if (i > MaxN) return Standard_False;
629 BiNormal.Normalize();
630 k = i;
631
632 D0(U + h, T, N, BN);
633
c6541a0c
D
634 if(Tangent.Angle(T) > M_PI/2) TFlag = -1;
635 if(BiNormal.Angle(BN) > M_PI/2) BNFlag = -1;
7fd59977 636
637 return Standard_True;
638}
639
640 Standard_Boolean GeomFill_Frenet::SingularD0(const Standard_Real Param,
641 const Standard_Integer Index,
642 gp_Vec& Tangent,
643 gp_Vec& Normal,
644 gp_Vec& BiNormal)
645{
646 Standard_Integer n, k, TFlag, BNFlag;
647 if(!DoSingular(Param, Index, Tangent, BiNormal,
648 n, k, TFlag, BNFlag)) return Standard_False;
649 Tangent *= TFlag;
650 BiNormal *= BNFlag;
651 Normal = BiNormal;
652 Normal.Cross(Tangent);
653
654 return Standard_True;
655}
656
657 Standard_Boolean GeomFill_Frenet::SingularD1(const Standard_Real Param,
658 const Standard_Integer Index,
659 gp_Vec& Tangent,gp_Vec& DTangent,
660 gp_Vec& Normal,gp_Vec& DNormal,
661 gp_Vec& BiNormal,gp_Vec& DBiNormal)
662{
663 Standard_Integer n, k, TFlag, BNFlag;
664 if(!DoSingular(Param, Index, Tangent, BiNormal, n, k, TFlag, BNFlag)) return Standard_False;
665
666 gp_Vec F, DF, Dtmp;
667 F = myTrimmed->DN(Param, n);
668 DF = myTrimmed->DN(Param, n+1);
669 DTangent = FDeriv(F, DF);
670
671 Dtmp = myTrimmed->DN(Param, k);
672 F = Tangent.Crossed(Dtmp);
673 DF = DTangent.Crossed(Dtmp) + Tangent.Crossed(myTrimmed->DN(Param, k+1));
674 DBiNormal = FDeriv(F, DF);
675
676 if(TFlag < 0) {
677 Tangent = -Tangent;
678 DTangent = -DTangent;
679 }
680
681 if(BNFlag < 0) {
682 BiNormal = -BiNormal;
683 DBiNormal = -DBiNormal;
684 }
685
686 Normal = BiNormal.Crossed(Tangent);
687 DNormal = DBiNormal.Crossed(Tangent) + BiNormal.Crossed(DTangent);
688
689 return Standard_True;
690}
691
692 Standard_Boolean GeomFill_Frenet::SingularD2(const Standard_Real Param,
693 const Standard_Integer Index,
694 gp_Vec& Tangent,
695 gp_Vec& DTangent,
696 gp_Vec& D2Tangent,
697 gp_Vec& Normal,
698 gp_Vec& DNormal,
699 gp_Vec& D2Normal,
700 gp_Vec& BiNormal,
701 gp_Vec& DBiNormal,
702 gp_Vec& D2BiNormal)
703{
704 Standard_Integer n, k, TFlag, BNFlag;
705 if(!DoSingular(Param, Index, Tangent, BiNormal, n, k, TFlag, BNFlag))
706 return Standard_False;
707
708 gp_Vec F, DF, D2F, Dtmp1, Dtmp2;
709 F = myTrimmed->DN(Param, n);
710 DF = myTrimmed->DN(Param, n+1);
711 D2F = myTrimmed->DN(Param, n+2);
712 DTangent = FDeriv(F, DF);
713 D2Tangent = DDeriv(F, DF, D2F);
714
715 Dtmp1 = myTrimmed->DN(Param, k);
716 Dtmp2 = myTrimmed->DN(Param, k+1);
717 F = Tangent.Crossed(Dtmp1);
718 DF = DTangent.Crossed(Dtmp1) + Tangent.Crossed(Dtmp2);
719 D2F = D2Tangent.Crossed(Dtmp1) + 2*DTangent.Crossed(Dtmp2) +
720 Tangent.Crossed(myTrimmed->DN(Param, k+2));
721 DBiNormal = FDeriv(F, DF);
722 D2BiNormal = DDeriv(F, DF, D2F);
723
724 if(TFlag < 0) {
725 Tangent = -Tangent;
726 DTangent = -DTangent;
727 D2Tangent = -D2Tangent;
728 }
729
730 if(BNFlag < 0) {
731 BiNormal = -BiNormal;
732 DBiNormal = -DBiNormal;
733 D2BiNormal = -D2BiNormal;
734 }
735
736 Normal = BiNormal.Crossed(Tangent);
737 DNormal = DBiNormal.Crossed(Tangent) + BiNormal.Crossed(DTangent);
738 D2Normal = D2BiNormal.Crossed(Tangent) + 2*DBiNormal.Crossed(DTangent) + BiNormal.Crossed(D2Tangent);
739
740 return Standard_True;
741}