de69b55a276c85fd1999901ef4e9071ed56c6f79
[occt.git] / src / BlendFunc / BlendFunc_Chamfer.cxx
1 // Created on: 1996-06-05
2 // Created by: Stagiaire Xuan Trang PHAMPHU
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21
22 // Modified : 20/08/96 PMN Ajout des methodes (Nb)Intervals et IsRationnal
23 // Modified : 30/12/96 PMN Ajout GetMinimalWeight, GetSectionSize;
24
25 #include <BlendFunc_Chamfer.ixx>
26
27 #include <BlendFunc.hxx>
28 #include <ElCLib.hxx>
29 #include <Precision.hxx>
30 #include <Standard_NotImplemented.hxx>
31 #ifdef DEB
32 static Standard_Boolean putsderivatives = 0;
33 #endif
34
35 //=======================================================================
36 //function : BlendFunc_Chamfer
37 //purpose  : 
38 //=======================================================================
39
40 BlendFunc_Chamfer::BlendFunc_Chamfer(const Handle(Adaptor3d_HSurface)& S1,
41                                      const Handle(Adaptor3d_HSurface)& S2,
42                                      const Handle(Adaptor3d_HCurve)&   CG) :
43     surf1(S1),surf2(S2),
44         curv(CG),
45         distmin(RealLast()),
46         corde1(S1,CG),corde2(S2,CG)
47 {
48 }
49
50 //=======================================================================
51 //function : NbEquations
52 //purpose  : 
53 //=======================================================================
54
55 Standard_Integer BlendFunc_Chamfer::NbEquations () const
56 {
57   return 4;
58 }
59
60
61 //=======================================================================
62 //function : Set
63 //purpose  : 
64 //=======================================================================
65
66 void BlendFunc_Chamfer::Set(const Standard_Real Dist1, const Standard_Real Dist2,
67                             const Standard_Integer Choix)
68 {
69   corde1.SetDist(Dist1);
70   corde2.SetDist(Dist2);
71   choix = Choix;
72 }
73
74 //=======================================================================
75 //function : Set
76 //purpose  : 
77 //=======================================================================
78
79 void BlendFunc_Chamfer::Set(const Standard_Real Param)
80 {
81   corde1.SetParam(Param);
82   corde2.SetParam(Param);
83 }
84
85 //=======================================================================
86 //function : Set
87 //purpose  : 
88 //=======================================================================
89
90 void BlendFunc_Chamfer::Set(const Standard_Real First, const Standard_Real Last)
91 {
92 //  corde1.SetParam(First, Last);
93 //  corde2.SetParam(First, Last);
94 }
95
96 //=======================================================================
97 //function : GetTolerance
98 //purpose  : 
99 //=======================================================================
100
101 void BlendFunc_Chamfer::GetTolerance(math_Vector& Tolerance, const Standard_Real Tol) const
102 {
103   Tolerance(1) = surf1->UResolution(Tol);
104   Tolerance(2) = surf1->VResolution(Tol);
105   Tolerance(3) = surf2->UResolution(Tol);
106   Tolerance(4) = surf2->VResolution(Tol);
107 }
108
109 //=======================================================================
110 //function : GetBounds
111 //purpose  : 
112 //=======================================================================
113
114 void BlendFunc_Chamfer::GetBounds(math_Vector& InfBound, math_Vector& SupBound) const
115 {
116   InfBound(1) = surf1->FirstUParameter();
117   InfBound(2) = surf1->FirstVParameter();
118   InfBound(3) = surf2->FirstUParameter();
119   InfBound(4) = surf2->FirstVParameter();
120   SupBound(1) = surf1->LastUParameter();
121   SupBound(2) = surf1->LastVParameter();
122   SupBound(3) = surf2->LastUParameter();
123   SupBound(4) = surf2->LastVParameter();
124
125   for(Standard_Integer i = 1; i <= 4; i++){
126     if(!Precision::IsInfinite(InfBound(i)) &&
127        !Precision::IsInfinite(SupBound(i))) {
128       const Standard_Real range = (SupBound(i) - InfBound(i));
129       InfBound(i) -= range;
130       SupBound(i) += range;
131     }
132   }
133 }
134
135 //=======================================================================
136 //function : IsSolution
137 //purpose  : 
138 //=======================================================================
139
140 Standard_Boolean BlendFunc_Chamfer::IsSolution(const math_Vector& Sol, const Standard_Real Tol)
141 {
142   math_Vector Sol1(1,2), Sol2(1,2);
143
144   Sol1(1) = Sol(1);
145   Sol1(2) = Sol(2);
146   Sol2(1) = Sol(3); 
147   Sol2(2) = Sol(4); 
148   
149   Standard_Boolean issol = corde1.IsSolution(Sol1,Tol);
150   issol = issol && corde2.IsSolution(Sol2,Tol);
151   tol = Tol;
152   if (issol) 
153     distmin = Min (distmin, corde1.PointOnS().Distance(corde2.PointOnS()));
154
155   return issol;
156 }
157
158 //=======================================================================
159 //function : GetMinimalDistance
160 //purpose  : 
161 //=======================================================================
162
163 Standard_Real BlendFunc_Chamfer::GetMinimalDistance() const
164 {
165   return distmin;
166 }
167
168 //=======================================================================
169 //function : Value
170 //purpose  : 
171 //=======================================================================
172
173 Standard_Boolean BlendFunc_Chamfer::Value(const math_Vector& X, math_Vector& F)
174 {
175   math_Vector x(1,2), f(1,2);
176
177   x(1) = X(1); x(2) = X(2);
178   corde1.Value(x,f);
179   F(1) = f(1); F(2) = f(2);
180
181   x(1) = X(3); x(2) = X(4);
182   corde2.Value(x,f);
183   F(3) = f(1); F(4) = f(2);
184
185   return Standard_True;
186 }
187
188
189 //=======================================================================
190 //function : Derivatives
191 //purpose  : 
192 //=======================================================================
193
194 Standard_Boolean BlendFunc_Chamfer::Derivatives(const math_Vector& X, math_Matrix& D)
195 {
196   Standard_Integer i,j;
197   math_Vector x(1,2);
198   math_Matrix d(1,2,1,2);
199
200   x(1) = X(1); x(2) = X(2);
201   corde1.Derivatives(x,d);
202   for( i=1; i<3; i++ ){
203     for( j=1; j<3; j++ ){
204       D(i,j) = d(i,j);
205       D(i,j+2) = 0.;
206     }
207   }   
208
209   x(1) = X(3); x(2) = X(4);
210   corde2.Derivatives(x,d);
211   for( i=1; i<3; i++ ){
212     for( j=1; j<3; j++ ){
213       D(i+2,j+2) = d(i,j);
214       D(i+2,j) = 0.;
215     }
216   }   
217
218   return Standard_True;
219 }
220
221 //=======================================================================
222 //function : Values
223 //purpose  : 
224 //=======================================================================
225
226 Standard_Boolean BlendFunc_Chamfer::Values(const math_Vector& X, math_Vector& F, math_Matrix& D)
227 {
228   Standard_Boolean val = Value(X,F);
229   return (val && Derivatives(X,D));
230 }
231
232 //=======================================================================
233 //function : PointOnS1
234 //purpose  : 
235 //=======================================================================
236
237 const gp_Pnt& BlendFunc_Chamfer::PointOnS1 () const
238 {
239   return corde1.PointOnS();
240 }
241   
242 //=======================================================================
243 //function : PointOnS2
244 //purpose  : 
245 //=======================================================================
246
247 const gp_Pnt& BlendFunc_Chamfer::PointOnS2 () const
248 {
249   return corde2.PointOnS();
250 }
251
252
253 //=======================================================================
254 //function : IsTangencyPoint
255 //purpose  : 
256 //=======================================================================
257
258 Standard_Boolean BlendFunc_Chamfer::IsTangencyPoint () const
259 {
260   return corde1.IsTangencyPoint() && corde2.IsTangencyPoint();
261 }
262
263 //=======================================================================
264 //function : TangentOnS1
265 //purpose  : 
266 //=======================================================================
267
268 const gp_Vec& BlendFunc_Chamfer::TangentOnS1 () const
269 {
270   return corde1.TangentOnS();
271 }
272
273 //=======================================================================
274 //function : TangentOnS2
275 //purpose  : 
276 //=======================================================================
277
278 const gp_Vec& BlendFunc_Chamfer::TangentOnS2 () const
279 {
280   return corde2.TangentOnS();
281 }
282
283 //=======================================================================
284 //function : Tangent2dOnS1
285 //purpose  : 
286 //=======================================================================
287
288 const gp_Vec2d& BlendFunc_Chamfer::Tangent2dOnS1 () const
289 {
290   return corde1.Tangent2dOnS();
291 }
292
293 //=======================================================================
294 //function : Tangent2dOnS2
295 //purpose  : 
296 //=======================================================================
297
298 const gp_Vec2d& BlendFunc_Chamfer::Tangent2dOnS2 () const
299 {
300   return corde2.Tangent2dOnS();
301 }
302
303 //=======================================================================
304 //function : Tangent
305 //purpose  : TgF,NmF et TgL,NmL les tangentes et normales respectives
306 //           aux surfaces S1 et S2 
307 //=======================================================================
308
309 void BlendFunc_Chamfer::Tangent(const Standard_Real U1,
310                                 const Standard_Real V1,
311                                 const Standard_Real U2,
312                                 const Standard_Real V2,
313                                 gp_Vec& TgF,
314                                 gp_Vec& TgL,
315                                 gp_Vec& NmF,
316                                 gp_Vec& NmL) const
317 {
318   gp_Pnt pt1,pt2,ptgui;
319   gp_Vec d1u1,d1v1,d1u2,d1v2;
320   gp_Vec nplan;
321   Standard_Boolean revF = Standard_False;
322   Standard_Boolean revL = Standard_False;
323
324   ptgui = corde1.PointOnGuide();
325   nplan = corde1.NPlan();
326   surf1->D1(U1,V1,pt1,d1u1,d1v1);
327   NmF = d1u1.Crossed(d1v1);
328
329   surf2->D1(U2,V2,pt2,d1u2,d1v2);
330   NmL = d1u2.Crossed(d1v2);
331
332   TgF = (nplan.Crossed(NmF)).Normalized();
333   TgL = (nplan.Crossed(NmL)).Normalized();
334
335   if( (choix == 2)||(choix == 5) ){
336     revF = Standard_True;
337     revL = Standard_True;
338   }
339   if( (choix == 4)||(choix == 7) )
340     revL = Standard_True;
341   if( (choix == 3)||(choix == 8) )
342     revF = Standard_True;
343
344   if( revF )
345     TgF.Reverse();
346   if( revL )
347     TgL.Reverse();
348 }
349
350 //=======================================================================
351 //function : Section
352 //purpose  : 
353 //=======================================================================
354
355 void BlendFunc_Chamfer::Section(const Standard_Real Param,
356                                 const Standard_Real U1,
357                                 const Standard_Real V1,
358                                 const Standard_Real U2,
359                                 const Standard_Real V2,
360                                 Standard_Real& Pdeb,
361                                 Standard_Real& Pfin,
362                                 gp_Lin& C)
363 {
364   const gp_Pnt pts1 = surf1->Value(U1,V1);
365   const gp_Pnt pts2 = surf2->Value(U2,V2);
366   const gp_Dir dir( gp_Vec(pts1,pts2) );
367
368   C.SetLocation(pts1);
369   C.SetDirection(dir);
370
371   Pdeb = 0.;
372   Pfin = ElCLib::Parameter(C,pts2);
373 }  
374
375 //=======================================================================
376 //function : IsRational
377 //purpose  : 
378 //=======================================================================
379
380 Standard_Boolean BlendFunc_Chamfer::IsRational() const
381 {
382   return Standard_False;
383 }
384
385 //=======================================================================
386 //function : GetSectionSize
387 //purpose  : Non implementee (non necessaire car non rationel)
388 //=======================================================================
389 Standard_Real BlendFunc_Chamfer::GetSectionSize() const 
390 {
391   Standard_NotImplemented::Raise("BlendFunc_Chamfer::GetSectionSize()");
392   return 0;
393 }
394
395 //=======================================================================
396 //function : GetMinimalWeight
397 //purpose  : 
398 //=======================================================================
399 void BlendFunc_Chamfer::GetMinimalWeight(TColStd_Array1OfReal& Weights) const 
400 {
401   Weights.Init(1);
402 }
403
404
405 //=======================================================================
406 //function : NbIntervals
407 //purpose  : 
408 //=======================================================================
409
410 Standard_Integer BlendFunc_Chamfer::NbIntervals (const GeomAbs_Shape S) const
411 {
412   return  curv->NbIntervals(BlendFunc::NextShape(S));
413 }
414
415
416 //=======================================================================
417 //function : Intervals
418 //purpose  : 
419 //=======================================================================
420
421 void BlendFunc_Chamfer::Intervals (TColStd_Array1OfReal& T, const GeomAbs_Shape S) const
422 {
423   curv->Intervals(T, BlendFunc::NextShape(S)); 
424 }
425
426 //=======================================================================
427 //function : GetShape
428 //purpose  : 
429 //=======================================================================
430
431 void BlendFunc_Chamfer::GetShape (Standard_Integer& NbPoles,
432                                   Standard_Integer& NbKnots,
433                                   Standard_Integer& Degree,
434                                   Standard_Integer& NbPoles2d)
435 {
436   NbPoles = 2;
437   NbPoles2d = 2;
438   NbKnots = 2;
439   Degree = 1;  
440 }
441   
442 //=======================================================================
443 //function : GetTolerance
444 //purpose  : Determine les Tolerance a utiliser dans les approximations.
445 //=======================================================================
446 void BlendFunc_Chamfer::GetTolerance(const Standard_Real BoundTol, 
447                                      const Standard_Real SurfTol, 
448                                      const Standard_Real AngleTol, 
449                                      math_Vector& Tol3d, 
450                                      math_Vector& Tol1D) const
451 {
452   Tol3d.Init(BoundTol);
453 }
454
455 //=======================================================================
456 //function : Knots
457 //purpose  : 
458 //=======================================================================
459
460 void BlendFunc_Chamfer::Knots(TColStd_Array1OfReal& TKnots)
461 {
462   TKnots(1) = 0.;
463   TKnots(2) = 1.;
464 }
465
466
467 //=======================================================================
468 //function : Mults
469 //purpose  : 
470 //=======================================================================
471
472 void BlendFunc_Chamfer::Mults(TColStd_Array1OfInteger& TMults)
473 {
474   TMults(1) = 2;
475   TMults(2) = 2;
476 }
477
478 //=======================================================================
479 //function : Section
480 //purpose  : 
481 //=======================================================================
482
483 Standard_Boolean BlendFunc_Chamfer::Section
484   (const Blend_Point& P,
485    TColgp_Array1OfPnt& Poles,
486    TColgp_Array1OfVec& DPoles,
487    TColgp_Array1OfVec& D2Poles,
488    TColgp_Array1OfPnt2d& Poles2d,
489    TColgp_Array1OfVec2d& DPoles2d,
490    TColgp_Array1OfVec2d& D2Poles2d,
491    TColStd_Array1OfReal& Weights,
492    TColStd_Array1OfReal& DWeights,
493    TColStd_Array1OfReal& D2Weights)
494 {
495    return Standard_False;
496 }
497
498 //=======================================================================
499 //function : Section
500 //purpose  : 
501 //=======================================================================
502
503 Standard_Boolean BlendFunc_Chamfer::Section
504   (const Blend_Point& P,
505    TColgp_Array1OfPnt& Poles,
506    TColgp_Array1OfVec& DPoles,
507    TColgp_Array1OfPnt2d& Poles2d,
508    TColgp_Array1OfVec2d& DPoles2d,
509    TColStd_Array1OfReal& Weights,
510    TColStd_Array1OfReal& DWeights)
511 {
512   math_Vector sol(1,4),valsol(1,4),secmember(1,4);
513   math_Matrix gradsol(1,4,1,4);
514
515   Standard_Real prm = P.Parameter();
516   Standard_Integer low = Poles.Lower();
517   Standard_Integer upp = Poles.Upper();
518   Standard_Boolean istgt;
519
520   P.ParametersOnS1(sol(1),sol(2));
521   P.ParametersOnS2(sol(3),sol(4));
522
523   Set(prm);
524   
525   Values(sol,valsol,gradsol);
526   IsSolution(sol,tol); 
527
528   istgt = IsTangencyPoint();
529
530   Poles2d(Poles2d.Lower()).SetCoord(sol(1),sol(2));
531   Poles2d(Poles2d.Upper()).SetCoord(sol(3),sol(4));
532   if (!istgt) {
533   DPoles2d(Poles2d.Lower()).SetCoord(Tangent2dOnS1().X(),
534                                      Tangent2dOnS1().Y());
535   DPoles2d(Poles2d.Upper()).SetCoord(Tangent2dOnS2().X(),
536                                      Tangent2dOnS2().Y());
537   }
538   Poles(low) = PointOnS1();
539   Poles(upp) = PointOnS2();
540   Weights(low) = 1.0;
541   Weights(upp) = 1.0;
542   if (!istgt) {
543     DPoles(low) = TangentOnS1();
544     DPoles(upp) = TangentOnS2();
545     DWeights(low) = 0.0;
546     DWeights(upp) = 0.0;  
547   }
548
549   return (!istgt);
550 }
551
552 //=======================================================================
553 //function : Section
554 //purpose  : 
555 //=======================================================================
556
557 void BlendFunc_Chamfer::Section(const Blend_Point& P,
558                                 TColgp_Array1OfPnt& Poles,
559                                 TColgp_Array1OfPnt2d& Poles2d,
560                                 TColStd_Array1OfReal& Weights)
561 {
562   Standard_Real u1,v1,u2,v2,prm = P.Parameter();
563   Standard_Integer low = Poles.Lower();
564   Standard_Integer upp = Poles.Upper();
565   math_Vector X(1,4), F(1,4);
566
567   P.ParametersOnS1(u1,v1);
568   P.ParametersOnS2(u2,v2);
569   X(1)=u1;
570   X(2)=v1;
571   X(3)=u2;
572   X(4)=v2;
573   Poles2d(Poles2d.Lower()).SetCoord(u1,v1);
574   Poles2d(Poles2d.Upper()).SetCoord(u2,v2);
575
576   Set(prm);
577   Value(X,F);
578   Poles(low) = PointOnS1();
579   Poles(upp) = PointOnS2();
580   Weights(low) = 1.0;
581   Weights(upp) = 1.0;
582 }
583
584 void BlendFunc_Chamfer::Resolution(const Standard_Integer IC2d, const Standard_Real Tol,
585                                    Standard_Real& TolU, Standard_Real& TolV) const
586 {
587   if(IC2d == 1){
588     TolU = surf1->UResolution(Tol);
589     TolV = surf1->VResolution(Tol);
590   }
591   else {
592     TolU = surf2->UResolution(Tol);
593     TolV = surf2->VResolution(Tol);
594   }
595 }