0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / BlendFunc / BlendFunc_ConstThroatInv.cxx
1 // Created by: Julia GERASIMOVA
2 // Copyright (c) 2015 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
16 #include <Adaptor2d_HCurve2d.hxx>
17 #include <Adaptor3d_HCurve.hxx>
18 #include <Adaptor3d_HSurface.hxx>
19 #include <BlendFunc.hxx>
20 #include <BlendFunc_ConstThroatInv.hxx>
21 #include <math_Matrix.hxx>
22 #include <Precision.hxx>
23
24 //=======================================================================
25 //function : BlendFunc_ConstThroatInv
26 //purpose  : 
27 //=======================================================================
28
29 BlendFunc_ConstThroatInv::BlendFunc_ConstThroatInv(const Handle(Adaptor3d_HSurface)& S1,
30                                                    const Handle(Adaptor3d_HSurface)& S2,
31                                                    const Handle(Adaptor3d_HCurve)&   C)
32   : BlendFunc_GenChamfInv(S1,S2,C)
33 {
34 }
35
36
37 //=======================================================================
38 //function : Set
39 //purpose  : 
40 //=======================================================================
41
42 void BlendFunc_ConstThroatInv::Set(const Standard_Real    theThroat,
43                                    const Standard_Real,
44                                    const Standard_Integer Choix)
45 {
46   //Standard_Real dis1,dis2;
47
48   Throat = theThroat;
49
50   choix = Choix;
51   switch (choix) {
52   case 1:
53   case 2:
54     {
55       sign1 = -1;
56       sign2 = -1;
57     }
58     break;
59   case 3:
60   case 4:
61     {
62       sign1 = 1;
63       sign2 = -1;
64     }
65     break;
66   case 5:
67   case 6:
68     {
69       sign1 = 1;
70       sign2 = 1;
71     }
72     break;
73   case 7:
74   case 8:
75     {
76       sign1 = -1;
77       sign2 = 1;
78     }
79     break;
80   default:
81     sign1 = -1;
82     sign2 = -1;
83   }
84 }
85
86 //=======================================================================
87 //function : IsSolution
88 //purpose  : 
89 //=======================================================================
90
91 Standard_Boolean BlendFunc_ConstThroatInv::IsSolution(const math_Vector& Sol, const Standard_Real Tol)
92 {
93   math_Vector valsol(1,4);
94   Value(Sol, valsol);
95
96   if (Abs(valsol(1)) <= Tol &&
97       Abs(valsol(2)) <= Tol &&
98       Abs(valsol(3)) <= Tol*Tol &&
99       Abs(valsol(4)) <= Tol*Tol)
100     return Standard_True;
101
102   return Standard_False;
103 }
104
105 //=======================================================================
106 //function : Value
107 //purpose  : 
108 //=======================================================================
109
110 Standard_Boolean BlendFunc_ConstThroatInv::Value(const math_Vector& X, math_Vector& F)
111 {
112   gp_Pnt2d p2d;
113   gp_Vec2d v2d;
114   csurf->D1(X(1),p2d,v2d);  
115   param = X(2);
116   curv->D2(param,ptgui,d1gui,d2gui);
117   normtg = d1gui.Magnitude();
118   nplan  = d1gui.Normalized();
119   theD = - (nplan.XYZ().Dot(ptgui.XYZ()));
120
121   math_Vector XX(1,4);
122
123   if(first){
124     XX(1) = p2d.X(); XX(2) = p2d.Y();
125     XX(3) = X(3); XX(4) = X(4);
126   }
127
128   else{
129     XX(1) = X(3); XX(2) = X(4);
130     XX(3) = p2d.X(); XX(4) = p2d.Y();
131   }
132   
133   surf1->D0( XX(1), XX(2), pts1 );
134   surf2->D0( XX(3), XX(4), pts2 );
135   
136   F(1) = nplan.XYZ().Dot(pts1.XYZ()) + theD;
137   F(2) = nplan.XYZ().Dot(pts2.XYZ()) + theD;
138
139   const gp_Pnt ptmid((pts1.XYZ() + pts2.XYZ())/2);
140   const gp_Vec vmid(ptgui, ptmid);
141   
142   F(3) = vmid.SquareMagnitude() - Throat*Throat;
143
144   const gp_Vec vref1(ptgui, pts1);
145   const gp_Vec vref2(ptgui, pts2);
146
147   F(4) = vref1.SquareMagnitude() - vref2.SquareMagnitude();
148   
149   return Standard_True;
150 }
151
152 //=======================================================================
153 //function : Derivatives
154 //purpose  : 
155 //=======================================================================
156
157 Standard_Boolean BlendFunc_ConstThroatInv::Derivatives(const math_Vector& X, math_Matrix& D)
158 {
159   //Standard_Integer i, j;
160   gp_Pnt2d p2d;
161   gp_Vec2d v2d; //, df1, df2;
162   //gp_Pnt pts, ptgui;
163   gp_Vec dnplan, temp, temp1, temp2, tempmid; //, d1u, d1v, nplan;
164   math_Vector XX(1,4); //x1(1,2), x2(1,2);
165   //math_Matrix d1(1,2,1,2), d2(1,2,1,2);
166
167   csurf->D1(X(1), p2d, v2d);  
168   //corde1.SetParam(X(2));
169   //corde2.SetParam(X(2));
170   param = X(2);
171   curv->D2(param,ptgui,d1gui,d2gui);
172   normtg = d1gui.Magnitude();
173   nplan  = d1gui.Normalized();
174   theD = - (nplan.XYZ().Dot(ptgui.XYZ()));
175
176   dnplan.SetLinearForm(1./normtg,d2gui,
177                        -1./normtg*(nplan.Dot(d2gui)),nplan); 
178   
179   temp1.SetXYZ(pts1.XYZ() - ptgui.XYZ());
180   temp2.SetXYZ(pts2.XYZ() - ptgui.XYZ());
181   tempmid.SetXYZ((pts1.XYZ() + pts2.XYZ())/2 - ptgui.XYZ());
182   
183   //x1(1) = p2d.X(); x1(2) = p2d.Y();
184   //x2(1) = X(3); x2(2) = X(4);
185   if (first)
186   {
187     XX(1) = p2d.X(); XX(2) = p2d.Y();
188     XX(3) = X(3); XX(4) = X(4);
189   }
190   else
191   {
192     XX(1) = X(3); XX(2) = X(4);
193     XX(3) = p2d.X(); XX(4) = p2d.Y();
194   }
195
196   surf1->D1(XX(1), XX(2), pts1, d1u1, d1v1);
197   surf2->D1(XX(3), XX(4), pts2, d1u2, d1v2);
198   
199   if( first ){
200     // p2d = pts est sur surf1
201     //ptgui = corde1.PointOnGuide();
202     //nplan = corde1.NPlan();
203     temp.SetLinearForm(v2d.X(),d1u1, v2d.Y(),d1v1);
204
205     D(1,1) = nplan.Dot(temp);
206     D(2,1) = 0.;
207     D(3,1) = gp_Vec(ptgui,pts1).Dot(temp);
208     D(4,1) = 2*(gp_Vec(ptgui,pts1).Dot(temp));
209
210     D(1,3) = 0.;
211     D(1,4) = 0.;
212     D(2,3) = nplan.Dot(d1u2);
213     D(2,4) = nplan.Dot(d1v2);
214     D(3,3) = gp_Vec((pts1.XYZ() + pts2.XYZ())/2 - ptgui.XYZ()).Dot(d1u2);
215     D(3,4) = gp_Vec((pts1.XYZ() + pts2.XYZ())/2 - ptgui.XYZ()).Dot(d1v2);
216     D(4,3) = -2.*gp_Vec(ptgui,pts2).Dot(d1u2);
217     D(4,4) = -2.*gp_Vec(ptgui,pts2).Dot(d1v2);
218     
219     //surf1->D1(x1(1),x1(2),pts,d1u,d1v);
220   }   
221   else{
222     //  p2d = pts est sur surf2
223     //ptgui = corde2.PointOnGuide();
224     //nplan = corde2.NPlan();
225     temp.SetLinearForm(v2d.X(),d1u2, v2d.Y(),d1v2);
226
227     D(1,1) = 0.;
228     D(2,1) = nplan.Dot(temp);
229     D(3,1) = gp_Vec(ptgui,pts2).Dot(temp);
230     D(4,1) = -2*(gp_Vec(ptgui,pts2).Dot(temp));
231
232     D(1,3) = nplan.Dot(d1u1);
233     D(1,4) = nplan.Dot(d1v1);
234     D(2,3) = 0.;
235     D(2,4) = 0.;
236     D(3,3) = gp_Vec((pts1.XYZ() + pts2.XYZ())/2 - ptgui.XYZ()).Dot(d1u1);
237     D(3,4) = gp_Vec((pts1.XYZ() + pts2.XYZ())/2 - ptgui.XYZ()).Dot(d1v1);
238     D(4,3) = 2.*gp_Vec(ptgui,pts1).Dot(d1u1);
239     D(4,4) = 2.*gp_Vec(ptgui,pts1).Dot(d1v1);
240     
241     //surf2->D1(x1(1),x1(2),pts,d1u,d1v);
242   }
243
244   D(1,2) = dnplan.Dot(temp1) - nplan.Dot(d1gui);
245   D(2,2) = dnplan.Dot(temp2) - nplan.Dot(d1gui);
246   D(3,2) = -2.*d1gui.Dot(tempmid);
247   D(4,2) = 2.*d1gui.Dot(temp1) - 2.*d1gui.Dot(temp2);
248
249   return Standard_True;
250