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 #include <Adaptor3d_Curve.hxx>
16 #include <Adaptor3d_Surface.hxx>
17 #include <Blend_Point.hxx>
18 #include <BlendFunc.hxx>
19 #include <BlendFunc_ConstThroat.hxx>
20 #include <ElCLib.hxx>
21 #include <gp_Lin.hxx>
22 #include <gp_Pnt.hxx>
23 #include <gp_Vec.hxx>
24 #include <gp_Vec2d.hxx>
25 #include <math_Matrix.hxx>
26 #include <math_Gauss.hxx>
27 #include <Precision.hxx>
28 #include <Standard_NotImplemented.hxx>
29 
30 #define Eps 1.e-15
31 
32 
33 //=======================================================================
34 //function : BlendFunc_ConstThroat
35 //purpose  :
36 //=======================================================================
37 
BlendFunc_ConstThroat(const Handle (Adaptor3d_Surface)& S1,const Handle (Adaptor3d_Surface)& S2,const Handle (Adaptor3d_Curve)& C)38 BlendFunc_ConstThroat::BlendFunc_ConstThroat(const Handle(Adaptor3d_Surface)& S1,
39                                              const Handle(Adaptor3d_Surface)& S2,
40                                              const Handle(Adaptor3d_Curve)& C)
41 : BlendFunc_GenChamfer(S1,S2,C),
42   istangent(Standard_False),
43   param(0.0),
44   Throat(0.0),
45   normtg(0.0),
46   theD(0.0)
47 {
48 }
49 
50 //=======================================================================
51 //function : Set
52 //purpose  :
53 //=======================================================================
54 
Set(const Standard_Real aThroat,const Standard_Real,const Standard_Integer Choix)55 void BlendFunc_ConstThroat::Set(const Standard_Real aThroat,
56                                 const Standard_Real,
57                                 const Standard_Integer Choix)
58 {
59   Throat = aThroat;
60   choix = Choix;
61 }
62 
63 //=======================================================================
64 //function : Set
65 //purpose  :
66 //=======================================================================
67 
Set(const Standard_Real Param)68 void BlendFunc_ConstThroat::Set(const Standard_Real Param)
69 {
70   param = Param;
71   curv->D2(param,ptgui,d1gui,d2gui);
72   normtg = d1gui.Magnitude();
73   nplan  = d1gui.Normalized();
74   theD = - (nplan.XYZ().Dot(ptgui.XYZ()));
75 }
76 
77 //=======================================================================
78 //function : IsSolution
79 //purpose  :
80 //=======================================================================
81 
IsSolution(const math_Vector & Sol,const Standard_Real Tol)82 Standard_Boolean BlendFunc_ConstThroat::IsSolution(const math_Vector& Sol, const Standard_Real Tol)
83 {
84   math_Vector secmember(1,4), valsol(1,4);
85   math_Matrix gradsol(1,4,1,4);
86 
87   Value(Sol, valsol);
88   Derivatives(Sol, gradsol);
89 
90   tol = Tol;
91 
92   gp_Vec dnplan, temp1, temp2, tempmid;
93 
94   if (Abs(valsol(1)) <= Tol &&
95       Abs(valsol(2)) <= Tol &&
96       Abs(valsol(3)) <= Tol*Tol &&
97       Abs(valsol(4)) <= Tol*Tol)
98   {
99     dnplan.SetLinearForm(1./normtg,d2gui,
100 			 -1./normtg*(nplan.Dot(d2gui)),nplan);
101 
102     temp1.SetXYZ(pts1.XYZ() - ptgui.XYZ());
103     temp2.SetXYZ(pts2.XYZ() - ptgui.XYZ());
104     tempmid.SetXYZ((pts1.XYZ() + pts2.XYZ())/2 - ptgui.XYZ());
105     surf1->D1(Sol(1),Sol(2),pts1,d1u1,d1v1);
106     surf2->D1(Sol(3),Sol(4),pts2,d1u2,d1v2);
107 
108     secmember(1) = nplan.Dot(d1gui) - dnplan.Dot(temp1);
109     secmember(2) = nplan.Dot(d1gui) - dnplan.Dot(temp2);
110     secmember(3) = 2.*d1gui.Dot(tempmid);
111     secmember(4) = 2.*d1gui.Dot(temp2) - 2.*d1gui.Dot(temp1);
112 
113     math_Gauss Resol(gradsol);
114     if (Resol.IsDone()) {
115       Resol.Solve(secmember);
116       tg1.SetLinearForm(secmember(1),d1u1,secmember(2),d1v1);
117       tg2.SetLinearForm(secmember(3),d1u2,secmember(4),d1v2);
118       tg12d.SetCoord(secmember(1),secmember(2));
119       tg22d.SetCoord(secmember(3),secmember(4));
120       istangent = Standard_False;
121     }
122     else {
123       istangent = Standard_True;
124     }
125 
126     distmin = Min(distmin, pts1.Distance(pts2));
127 
128     return Standard_True;
129   }
130 
131   return Standard_False;
132 }
133 
134 //=======================================================================
135 //function : Value
136 //purpose  :
137 //=======================================================================
138 
Value(const math_Vector & X,math_Vector & F)139 Standard_Boolean BlendFunc_ConstThroat::Value(const math_Vector& X, math_Vector& F)
140 {
141   surf1->D0( X(1), X(2), pts1 );
142   surf2->D0( X(3), X(4), pts2 );
143 
144   F(1) = nplan.XYZ().Dot(pts1.XYZ()) + theD;
145   F(2) = nplan.XYZ().Dot(pts2.XYZ()) + theD;
146 
147   const gp_Pnt ptmid((pts1.XYZ() + pts2.XYZ())/2);
148   const gp_Vec vmid(ptgui, ptmid);
149 
150   F(3) = vmid.SquareMagnitude() - Throat*Throat;
151 
152   const gp_Vec vref1(ptgui, pts1);
153   const gp_Vec vref2(ptgui, pts2);
154 
155   F(4) = vref1.SquareMagnitude() - vref2.SquareMagnitude();
156 
157   return Standard_True;
158 }
159 
160 //=======================================================================
161 //function : Derivatives
162 //purpose  :
163 //=======================================================================
164 
Derivatives(const math_Vector & X,math_Matrix & D)165 Standard_Boolean BlendFunc_ConstThroat::Derivatives(const math_Vector& X, math_Matrix& D)
166 {
167   surf1->D1( X(1), X(2), pts1, d1u1, d1v1);
168   surf2->D1( X(3), X(4), pts2, d1u2, d1v2);
169 
170   D(1,1) = nplan.Dot(d1u1);
171   D(1,2) = nplan.Dot(d1v1);
172   D(1,3) = 0.;
173   D(1,4) = 0.;
174   D(2,1) = 0.;
175   D(2,2) = 0.;
176   D(2,3) = nplan.Dot(d1u2);
177   D(2,4) = nplan.Dot(d1v2);
178   D(3,1) = gp_Vec((pts1.XYZ() + pts2.XYZ())/2 - ptgui.XYZ()).Dot(d1u1);
179   D(3,2) = gp_Vec((pts1.XYZ() + pts2.XYZ())/2 - ptgui.XYZ()).Dot(d1v1);
180   D(3,3) = gp_Vec((pts1.XYZ() + pts2.XYZ())/2 - ptgui.XYZ()).Dot(d1u2);
181   D(3,4) = gp_Vec((pts1.XYZ() + pts2.XYZ())/2 - ptgui.XYZ()).Dot(d1v2);
182   D(4,1) = 2.*gp_Vec(ptgui,pts1).Dot(d1u1);
183   D(4,2) = 2.*gp_Vec(ptgui,pts1).Dot(d1v1);
184   D(4,3) = -2.*gp_Vec(ptgui,pts2).Dot(d1u2);
185   D(4,4) = -2.*gp_Vec(ptgui,pts2).Dot(d1v2);
186 
187   return Standard_True;
188 }
189 
190 //=======================================================================
191 //function : PointOnS1
192 //purpose  :
193 //=======================================================================
194 
PointOnS1() const195 const gp_Pnt& BlendFunc_ConstThroat::PointOnS1 () const
196 {
197   return pts1;
198 }
199 
200 
201 //=======================================================================
202 //function : PointOnS2
203 //purpose  :
204 //=======================================================================
205 
PointOnS2() const206 const gp_Pnt& BlendFunc_ConstThroat::PointOnS2 () const
207 {
208   return pts2;
209 }
210 
211 
212 //=======================================================================
213 //function : IsTangencyPoint
214 //purpose  :
215 //=======================================================================
216 
IsTangencyPoint() const217 Standard_Boolean BlendFunc_ConstThroat::IsTangencyPoint () const
218 {
219   return istangent;
220 }
221 
222 
223 //=======================================================================
224 //function : TangentOnS1
225 //purpose  :
226 //=======================================================================
227 
TangentOnS1() const228 const gp_Vec& BlendFunc_ConstThroat::TangentOnS1 () const
229 {
230   if (istangent)
231     throw Standard_DomainError("BlendFunc_ConstThroat::TangentOnS1");
232   return tg1;
233 }
234 
235 
236 //=======================================================================
237 //function : TangentOnS2
238 //purpose  :
239 //=======================================================================
240 
TangentOnS2() const241 const gp_Vec& BlendFunc_ConstThroat::TangentOnS2 () const
242 {
243   if (istangent)
244     throw Standard_DomainError("BlendFunc_ConstThroat::TangentOnS2");
245   return tg2;
246 }
247 
248 
249 //=======================================================================
250 //function : Tangent2dOnS1
251 //purpose  :
252 //=======================================================================
253 
Tangent2dOnS1() const254 const gp_Vec2d& BlendFunc_ConstThroat::Tangent2dOnS1 () const
255 {
256   if (istangent)
257     throw Standard_DomainError("BlendFunc_ConstThroat::Tangent2dOnS1");
258   return tg12d;
259 }
260 
261 
262 //=======================================================================
263 //function : Tangent2dOnS2
264 //purpose  :
265 //=======================================================================
266 
Tangent2dOnS2() const267 const gp_Vec2d& BlendFunc_ConstThroat::Tangent2dOnS2 () const
268 {
269   if (istangent)
270     throw Standard_DomainError("BlendFunc_ConstThroat::Tangent2dOnS2");
271   return tg22d;
272 }
273 
274 
275 //=======================================================================
276 //function : Tangent
277 //purpose  :
278 //=======================================================================
279 
Tangent(const Standard_Real U1,const Standard_Real V1,const Standard_Real U2,const Standard_Real V2,gp_Vec & TgF,gp_Vec & TgL,gp_Vec & NmF,gp_Vec & NmL) const280 void BlendFunc_ConstThroat::Tangent(const Standard_Real U1,
281                                     const Standard_Real V1,
282                                     const Standard_Real U2,
283                                     const Standard_Real V2,
284                                     gp_Vec& TgF,
285                                     gp_Vec& TgL,
286                                     gp_Vec& NmF,
287                                     gp_Vec& NmL) const
288 {
289   gp_Pnt pt;
290   gp_Vec d1u,d1v;
291   Standard_Boolean revF = Standard_False;
292   Standard_Boolean revL = Standard_False;
293 
294   surf1->D1(U1,V1,pt,d1u,d1v);
295   NmF = d1u.Crossed(d1v);
296 
297   surf2->D1(U2,V2,pt,d1u,d1v);
298   NmL = d1u.Crossed(d1v);
299 
300   TgF = (nplan.Crossed(NmF)).Normalized();
301   TgL = (nplan.Crossed(NmL)).Normalized();
302 
303   if( (choix == 2)||(choix == 5) ){
304     revF = Standard_True;
305     revL = Standard_True;
306   }
307   if( (choix == 4)||(choix == 7) )
308     revL = Standard_True;
309   if( (choix == 3)||(choix == 8) )
310     revF = Standard_True;
311 
312   if( revF )
313     TgF.Reverse();
314   if( revL )
315     TgL.Reverse();
316 }
317 
318 //=======================================================================
319 //function : GetSectionSize
320 //purpose  :
321 //=======================================================================
GetSectionSize() const322 Standard_Real BlendFunc_ConstThroat::GetSectionSize() const
323 {
324   throw Standard_NotImplemented("BlendFunc_ConstThroat::GetSectionSize()");
325 }
326