0023404: Create SquareConfusion function in Precision package for speed and convenience
[occt.git] / src / Extrema / Extrema_ExtSS.cxx
1 // Created on: 1995-07-19
2 // Created by: Modelistation
3 // Copyright (c) 1995-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
23 #include <Extrema_ExtSS.ixx>
24
25 #include <StdFail_NotDone.hxx>
26 #include <Standard_NotImplemented.hxx>
27 #include <StdFail_InfiniteSolutions.hxx>
28 #include <Precision.hxx>
29 #include <GeomAbs_SurfaceType.hxx>
30 #include <gp_Pnt.hxx>
31 #include <gp_Pln.hxx>
32
33 #include <Extrema_GenExtSS.hxx>
34 #include <ElCLib.hxx>
35
36 Extrema_ExtSS::Extrema_ExtSS() 
37 {
38   myDone = Standard_False;
39 }
40
41 Extrema_ExtSS::Extrema_ExtSS(const Adaptor3d_Surface&     S1,
42                              const Adaptor3d_Surface&     S2,
43                              const Standard_Real    TolS1,
44                              const Standard_Real    TolS2)
45
46 {
47   Initialize(S2, S2.FirstUParameter(), 
48                  S2.LastUParameter(), 
49                  S2.FirstVParameter(), 
50                  S2.LastVParameter(), TolS2);
51
52   Perform(S1, S1.FirstUParameter(),
53           S1.LastUParameter(), 
54           S1.FirstVParameter(), 
55           S1.LastVParameter(), TolS1);
56 }
57
58 Extrema_ExtSS::Extrema_ExtSS(const Adaptor3d_Surface&   S1,
59                              const Adaptor3d_Surface&   S2,
60                              const Standard_Real  Uinf1,        
61                              const Standard_Real  Usup1,
62                              const Standard_Real  Vinf1,        
63                              const Standard_Real  Vsup1,
64                              const Standard_Real  Uinf2,        
65                              const Standard_Real  Usup2,
66                              const Standard_Real  Vinf2,        
67                              const Standard_Real  Vsup2,
68                              const Standard_Real  TolS1,
69                              const Standard_Real  TolS2)
70
71 {
72   Initialize(S2, Uinf2, Usup2, Vinf2, Vsup2, TolS2);
73   Perform(S1, Uinf1, Usup1, Vinf1, Vsup1, TolS1);
74 }
75
76
77 void Extrema_ExtSS::Initialize(const Adaptor3d_Surface&  S2,
78                                const Standard_Real Uinf2,       
79                                const Standard_Real Usup2,
80                                const Standard_Real Vinf2,       
81                                const Standard_Real Vsup2,
82                                const Standard_Real TolS2)
83 {
84   myS2 = (Adaptor3d_SurfacePtr)&S2;
85   myIsPar = Standard_False;
86   myuinf2  = Uinf2;
87   myusup2  = Usup2;
88   myvinf2  = Vinf2;
89   myvsup2  = Vsup2;
90   mytolS2  = TolS2;
91   myStype  = S2.GetType();
92 }
93
94                                 
95 void Extrema_ExtSS::Perform(const Adaptor3d_Surface&   S1,      
96                             const Standard_Real  Uinf1, 
97                             const Standard_Real  Usup1,
98                             const Standard_Real  Vinf1, 
99                             const Standard_Real  Vsup1,
100                             const Standard_Real  TolS1)
101 {
102   myuinf1  = Uinf1;
103   myusup1  = Usup1;
104   myvinf1  = Vinf1;
105   myvsup1  = Vsup1;
106   mytolS1 =  TolS1;
107   myPOnS1.Clear();
108   myPOnS2.Clear();
109   mySqDist.Clear();
110   Standard_Integer i;
111   GeomAbs_SurfaceType myS1type  = S1.GetType();
112   Standard_Integer NbU = 10, NbV = 10;
113   
114   switch(myS1type) {
115
116     case GeomAbs_Plane: 
117     {
118       
119       switch(myStype) {
120       case GeomAbs_Plane:
121         {
122           myExtElSS.Perform(S1.Plane(),myS2->Plane());
123         }
124         break;
125       default:
126         {
127           Extrema_GenExtSS Ext(S1, *myS2, NbU, NbV, mytolS1, mytolS2);
128           myDone = Ext.IsDone();
129           if (myDone) {
130             Standard_Integer NbExt = Ext.NbExt();
131             Standard_Real U1, V1,U2,V2;
132             Extrema_POnSurf PS1;
133             Extrema_POnSurf PS2;
134             for (i = 1; i <= NbExt; i++) {
135               PS1 = Ext.PointOnS1(i);
136               PS2 = Ext.PointOnS2(i);
137               PS1.Parameter(U1, V1);
138               PS2.Parameter(U2, V2);
139               if (S1.IsUPeriodic())
140                 U1 = ElCLib::InPeriod(U1, myuinf1, myuinf1+S1.UPeriod());
141               if (S1.IsVPeriodic())
142                 V1 = ElCLib::InPeriod(V1, myvinf1, myvinf1+S1.VPeriod());
143               if (myS2->IsUPeriodic())
144                 U2 = ElCLib::InPeriod(U2, myuinf2, myuinf2+myS2->UPeriod());
145               if (myS2->IsVPeriodic())
146                 V2 = ElCLib::InPeriod(V2, myvinf2, myvinf2+myS2->VPeriod());
147
148               if ((myuinf1-U1) <= mytolS1 && (U1-myusup1) <= mytolS1 &&
149                   (myvinf1-V1) <= mytolS1 && (V1-myvsup1) <= mytolS1 &&
150                   (myuinf2-U2) <= mytolS2 && (U2-myusup2) <= mytolS2 &&
151                   (myvinf2-V2) <= mytolS2 && (V2-myvsup2) <= mytolS2) {
152                 mySqDist.Append(Ext.SquareDistance(i));
153                 myPOnS1.Append(Extrema_POnSurf(U1, V1, PS1.Value()));
154                 myPOnS2.Append(Extrema_POnSurf(U2, V2, PS2.Value()));
155               }
156             }
157           }
158           return;
159           
160         }
161         break;
162       }
163       break;
164     }
165   default:
166     {
167       Extrema_GenExtSS Ext(S1, *myS2, NbU, NbV, mytolS1, mytolS2);
168       myDone = Ext.IsDone();
169       if (myDone) {
170         Standard_Integer NbExt = Ext.NbExt();
171         Standard_Real U1, V1,U2,V2;
172         Extrema_POnSurf PS1;
173         Extrema_POnSurf PS2;
174         for (i = 1; i <= NbExt; i++) {
175           PS1 = Ext.PointOnS1(i);
176           PS2 = Ext.PointOnS2(i);
177           PS1.Parameter(U1, V1);
178           PS2.Parameter(U2, V2);
179           if (S1.IsUPeriodic())
180             U1 = ElCLib::InPeriod(U1, myuinf1, myuinf1+S1.UPeriod());
181           if (S1.IsVPeriodic())
182             V1 = ElCLib::InPeriod(V1, myvinf1, myvinf1+S1.VPeriod());
183           if (myS2->IsUPeriodic())
184             U2 = ElCLib::InPeriod(U2, myuinf2, myuinf2+myS2->UPeriod());
185           if (myS2->IsVPeriodic())
186             V2 = ElCLib::InPeriod(V2, myvinf2, myvinf2+myS2->VPeriod());
187           
188           if ((myuinf1-U1) <= mytolS1 && (U1-myusup1) <= mytolS1 &&
189               (myvinf1-V1) <= mytolS1 && (V1-myvsup1) <= mytolS1 &&
190               (myuinf2-U2) <= mytolS2 && (U2-myusup2) <= mytolS2 &&
191               (myvinf2-V2) <= mytolS2 && (V2-myvsup2) <= mytolS2) {
192             mySqDist.Append(Ext.SquareDistance(i));
193             myPOnS1.Append(Extrema_POnSurf(U1, V1, PS1.Value()));
194             myPOnS2.Append(Extrema_POnSurf(U2, V2, PS2.Value()));
195           }
196         }
197       }
198       return;
199       
200     }
201     break;
202   }
203
204   myDone = myExtElSS.IsDone();
205   if (myDone) {
206     myIsPar = myExtElSS.IsParallel();
207     if (myIsPar) {
208       mySqDist.Append(myExtElSS.SquareDistance(1));
209     }
210     else {
211       Standard_Integer NbExt = myExtElSS.NbExt();
212       Standard_Real U1, V1, U2, V2;
213       Extrema_POnSurf PS1;
214       Extrema_POnSurf PS2;
215       for (i = 1; i <= NbExt; i++) {
216         myExtElSS.Points(i, PS1, PS2);
217         PS1.Parameter(U1, V1);
218         PS2.Parameter(U2, V2);
219         if ((myuinf1-U1) <= mytolS1 && (U1-myusup1) <= mytolS1 &&
220             (myvinf1-V1) <= mytolS1 && (V1-myvsup1) <= mytolS1 &&
221             (myuinf2-U2) <= mytolS2 && (U2-myusup2) <= mytolS2 &&
222             (myvinf2-V2) <= mytolS2 && (V2-myvsup2) <= mytolS2) {
223           mySqDist.Append(myExtElSS.SquareDistance(i));
224           myPOnS1.Append(PS1);
225           myPOnS2.Append(PS2);
226         }
227       }
228     }
229   }
230   
231 }
232
233
234 Standard_Boolean Extrema_ExtSS::IsDone() const
235 {
236   return myDone;
237 }
238
239 Standard_Boolean Extrema_ExtSS::IsParallel() const
240 {
241   return myIsPar;
242 }
243
244
245 Standard_Real Extrema_ExtSS::SquareDistance(const Standard_Integer N) const
246 {
247   if(!myDone) StdFail_NotDone::Raise();
248   if (myIsPar && N != 1) StdFail_InfiniteSolutions::Raise();
249   if ((N < 1) || (N > mySqDist.Length())) Standard_OutOfRange::Raise();
250   return mySqDist.Value(N);
251 }
252
253
254 Standard_Integer Extrema_ExtSS::NbExt() const
255 {
256   if(!myDone) StdFail_NotDone::Raise();
257   return mySqDist.Length();
258 }
259
260
261
262 void Extrema_ExtSS::Points(const Standard_Integer N,
263                            Extrema_POnSurf&       P1,
264                            Extrema_POnSurf&       P2) const
265 {
266   if(!myDone) StdFail_NotDone::Raise();
267   P1 = myPOnS1.Value(N);
268   P2 = myPOnS2.Value(N);
269 }