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