bcfa81a5ff0c28e17adcd2087b66828833819a3a
[occt.git] / src / IntImp / IntImp_Int2S.gxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 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 #ifndef OCCT_DEBUG
16 #define No_Standard_RangeError
17 #define No_Standard_OutOfRange
18 #endif
19
20
21 #include <IntImp_ComputeTangence.hxx>
22 #include <math_FunctionSetRoot.hxx>
23 #include <math_Vector.hxx>
24 #include <IntImp_ConstIsoparametric.hxx>
25 #include <Standard_ConstructionError.hxx>
26 #include <Precision.hxx>
27
28
29 //Standard_IMPORT extern IntImp_ConstIsoparametric   *ChoixRef;
30
31 IntImp_Int2S::IntImp_Int2S(const ThePSurface& surf1,
32                            const ThePSurface& surf2,
33                            const Standard_Real TolTangency ) :
34 done(Standard_True),
35 empty(Standard_True),
36 myZerParFunc(surf1,surf2),
37 tol(TolTangency*TolTangency)
38 {
39   ua0 = ThePSurfaceTool::FirstUParameter(surf1); //-- ThePSurfaceTool::UIntervalFirst(surf1);
40   va0 = ThePSurfaceTool::FirstVParameter(surf1); //-- ThePSurfaceTool::VIntervalFirst(surf1);
41   ua1 = ThePSurfaceTool::LastUParameter(surf1);  //-- ThePSurfaceTool::UIntervalLast(surf1);
42   va1 = ThePSurfaceTool::LastVParameter(surf1);  //-- ThePSurfaceTool::VIntervalLast(surf1);
43
44   ub0 = ThePSurfaceTool::FirstUParameter(surf2); //-- ThePSurfaceTool::UIntervalFirst(surf2);
45   vb0 = ThePSurfaceTool::FirstVParameter(surf2); //-- ThePSurfaceTool::VIntervalFirst(surf2);
46   ub1 = ThePSurfaceTool::LastUParameter(surf2);  //-- ThePSurfaceTool::UIntervalLast(surf2);
47   vb1 = ThePSurfaceTool::LastVParameter(surf2);  //-- ThePSurfaceTool::VIntervalLast(surf2);
48
49   ures1 = ThePSurfaceTool::UResolution(surf1,Precision::Confusion());
50   vres1 = ThePSurfaceTool::VResolution(surf1,Precision::Confusion());
51
52   ures2 = ThePSurfaceTool::UResolution(surf2,Precision::Confusion());
53   vres2 = ThePSurfaceTool::VResolution(surf2,Precision::Confusion());
54 }
55
56
57 IntImp_Int2S::IntImp_Int2S(const TColStd_Array1OfReal& Param,
58                            const ThePSurface& surf1,
59                            const ThePSurface& surf2,
60                            const Standard_Real TolTangency ) :
61 done(Standard_True),
62 empty(Standard_True),
63 myZerParFunc(surf1,surf2),
64 tol(TolTangency*TolTangency)
65 {
66   math_FunctionSetRoot Rsnld(myZerParFunc,15);    //-- Modif lbr 18 MAI ?????????????
67   ua0 = ThePSurfaceTool::FirstUParameter(surf1); //-- ThePSurfaceTool::UIntervalFirst(surf1);
68   va0 = ThePSurfaceTool::FirstVParameter(surf1); //-- ThePSurfaceTool::VIntervalFirst(surf1);
69   ua1 = ThePSurfaceTool::LastUParameter(surf1);  //-- ThePSurfaceTool::UIntervalLast(surf1);
70   va1 = ThePSurfaceTool::LastVParameter(surf1);  //-- ThePSurfaceTool::VIntervalLast(surf1);
71
72   ub0 = ThePSurfaceTool::FirstUParameter(surf2); //-- ThePSurfaceTool::UIntervalFirst(surf2);
73   vb0 = ThePSurfaceTool::FirstVParameter(surf2); //-- ThePSurfaceTool::VIntervalFirst(surf2);
74   ub1 = ThePSurfaceTool::LastUParameter(surf2);  //-- ThePSurfaceTool::UIntervalLast(surf2);
75   vb1 = ThePSurfaceTool::LastVParameter(surf2);  //-- ThePSurfaceTool::VIntervalLast(surf2);
76
77   ures1 = ThePSurfaceTool::UResolution(surf1,Precision::Confusion());
78   vres1 = ThePSurfaceTool::VResolution(surf1,Precision::Confusion());
79
80   ures2 = ThePSurfaceTool::UResolution(surf2,Precision::Confusion());
81   vres2 = ThePSurfaceTool::VResolution(surf2,Precision::Confusion());
82   Perform(Param,Rsnld);
83
84
85 IntImp_ConstIsoparametric IntImp_Int2S:: Perform(const TColStd_Array1OfReal& Param,
86                                                  math_FunctionSetRoot& Rsnld,
87                                                  const IntImp_ConstIsoparametric ChoixIso) 
88 {
89   Standard_Real BornInfBuf[3], BornSupBuf[3], ToleranceBuf[3], UVapBuf[3];
90   Standard_Real UvresBuf[4];
91   math_Vector BornInf (BornInfBuf, 1, 3), BornSup (BornSupBuf, 1, 3),
92               Tolerance (ToleranceBuf, 1, 3), UVap (UVapBuf, 1, 3);
93   TColStd_Array1OfReal Uvres (UvresBuf[0], 1, 4);
94
95   IntImp_ConstIsoparametric BestChoix;
96
97   myZerParFunc.ComputeParameters(ChoixIso,Param,UVap,BornInf,BornSup,Tolerance);
98   Rsnld.SetTolerance(Tolerance);
99   Rsnld.Perform(myZerParFunc,UVap,BornInf,BornSup);
100   BestChoix = ChoixIso;
101   if (Rsnld.IsDone()) {
102     if (Abs(myZerParFunc.Root()) <= tol) { //distance des 2 points
103       // dans la tolerance
104       Rsnld.Root(UVap);
105       empty = Standard_False;
106       tangent = myZerParFunc.IsTangent(UVap,Uvres,BestChoix);
107       pint.SetValue(myZerParFunc.Point(),Uvres(1),Uvres(2),Uvres(3),Uvres(4));
108       if (!tangent) {
109         d3d  = myZerParFunc.Direction();
110         d2d1 = myZerParFunc.DirectionOnS1();
111         d2d2 = myZerParFunc.DirectionOnS2();
112       }
113     }
114     else {
115       empty = Standard_True;
116     }
117   }
118   else { 
119     empty = Standard_True;
120   }
121   return BestChoix;
122 }
123
124 IntImp_ConstIsoparametric IntImp_Int2S:: Perform(const TColStd_Array1OfReal& Param,
125                                                  math_FunctionSetRoot& Rsnld)
126 {
127   gp_Vec DPUV[4];
128   gp_Pnt P1,P2;
129   Standard_Real Epsuv[4];
130   Standard_Real DuvBuf[4];
131   TColStd_Array1OfReal Duv (DuvBuf[0], 1, 4);
132   Standard_Real UVd[4],UVf[4];
133   IntImp_ConstIsoparametric ChoixIso[4];
134   IntImp_ConstIsoparametric BestChoix=ChoixRef[0];
135   const ThePSurface& Caro1 = myZerParFunc.AuxillarSurface1();
136   const ThePSurface& Caro2 = myZerParFunc.AuxillarSurface2();
137
138   ThePSurfaceTool::D1(Caro1, Param(1),Param(2),P1,DPUV[0],DPUV[1]);
139   ThePSurfaceTool::D1(Caro2, Param(3),Param(4),P2,DPUV[2],DPUV[3]);
140
141   Epsuv[0] = ThePSurfaceTool::UResolution(Caro1,Precision::Confusion());
142   Epsuv[1] = ThePSurfaceTool::VResolution(Caro1,Precision::Confusion());
143
144   Epsuv[2] = ThePSurfaceTool::UResolution(Caro2,Precision::Confusion());
145   Epsuv[3] = ThePSurfaceTool::VResolution(Caro2,Precision::Confusion());
146
147   for (Standard_Integer j=0;j<=3;j++)
148     UVd[j] = Param(j+1);
149
150   empty = Standard_True;
151
152   Standard_Boolean Tangent = IntImp_ComputeTangence(DPUV,Epsuv,UVd,ChoixIso);
153   if (Tangent)
154     return BestChoix;
155
156   Standard_Integer i=0;
157   IntImp_ConstIsoparametric CurrentChoix = BestChoix;   //-- Modif 17 Mai 93 
158
159   while (empty &&  i<= 3)
160   {
161     CurrentChoix = Perform(Param,Rsnld,ChoixIso[i]);
162     if(!empty) { 
163       BestChoix = CurrentChoix; 
164     }
165     i++;
166   }
167   if (!empty) { // verifier que l on ne deborde pas les frontieres
168     pint.Parameters(Duv(1),Duv(2),Duv(3),Duv(4));
169
170     UVd[0] = ua0; //-- ThePSurfaceTool::UIntervalFirst(Caro1);
171     UVd[1] = va0; //-- ThePSurfaceTool::VIntervalFirst(Caro1);
172     UVf[0] = ua1; //-- ThePSurfaceTool::UIntervalLast(Caro1);
173     UVf[1] = va1; //-- ThePSurfaceTool::VIntervalLast(Caro1);
174
175     UVd[2] = ub0; //-- ThePSurfaceTool::UIntervalFirst(Caro2);
176     UVd[3] = vb0; //-- ubThePSurfaceTool::VIntervalFirst(Caro2);
177     UVf[2] = ub1; //-- ThePSurfaceTool::UIntervalLast(Caro2);
178     UVf[3] = vb1; //-- ThePSurfaceTool::VIntervalLast(Caro2);
179
180     Standard_Integer Nc,Iiso;
181     if (Duv(1) <= UVd[0]-Epsuv[0]) {
182       Duv(1) = UVd[0];
183       Nc =0;
184       Iiso=0;
185     }
186     else if (Duv(1) >= UVf[0]+ Epsuv[0]) {
187       Duv(1) = UVf[0];
188       Nc =0;
189       Iiso=0; 
190     }
191     else if (Duv(2) <= UVd[1] -Epsuv[1]) {
192       Duv(2) = UVd[1];
193       Nc =0;
194       Iiso=1; 
195     }
196     else if (Duv(2) >= UVf[1]+Epsuv[1]) {
197       Duv(2) = UVf[1];
198       Nc =0;
199       Iiso=1; 
200     }
201     else if (Duv(3) <= UVd[2]-Epsuv[2]) {
202       Duv(3) = UVd[2];
203       Nc =2;
204       Iiso = 2;
205     }
206     else if (Duv(3) >= UVf[2]+Epsuv[2]) {
207       Duv(3) = UVf[2];
208       Nc =2;
209       Iiso = 2;
210     }
211     else if (Duv(4) <= UVd[3]-Epsuv[3]) {
212       Duv(4) = UVd[3];
213       Nc =2;
214       Iiso = 3;
215     }
216     else if (Duv(4) >= UVf[3]+Epsuv[3]) {
217       Duv(4) = UVf[3];
218       Nc =2;
219       Iiso =3;
220     }
221     else return BestChoix; // on a gagne
222     empty = Standard_True;
223     BestChoix = ChoixRef[Iiso]; //en attendant
224     BestChoix = Perform(Duv,Rsnld,BestChoix);
225     if (!empty) { // verification si l on ne deborde pas sur le carreau 
226       // reciproque
227       Nc =3-Nc;
228       if (Duv(Nc) <= UVd[Nc-1]-Epsuv[Nc-1])
229         Duv(Nc)=UVd[Nc-1];
230       else if (Duv(Nc) >=UVf[Nc-1]+Epsuv[Nc-1])
231         Duv(Nc)=UVf[Nc-1];
232       else if (Duv(Nc+1) <= UVd[Nc])
233       {
234         Nc = Nc + 1;
235         Duv(Nc)=UVd[Nc-1];
236       }
237       else if (Duv(Nc+1) >=UVf[Nc])
238       {
239         Nc = Nc + 1;
240         Duv(Nc)=UVf[Nc-1];
241       } 
242       else
243         return BestChoix;
244       
245       empty = Standard_True;
246       
247       if(Nc == 4)
248         Nc = 0;
249       
250       BestChoix = ChoixRef[Nc]; //en attendant
251       BestChoix = Perform(Duv,Rsnld,BestChoix);
252     }
253   }
254   return BestChoix;   
255 }