0024134: Wrong result of projection point on the face
[occt.git] / src / Extrema / Extrema_ExtSS.cxx
CommitLineData
b311480e 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
7fd59977 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
36Extrema_ExtSS::Extrema_ExtSS()
37{
38 myDone = Standard_False;
39}
40
41Extrema_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
58Extrema_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
77void 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
95void 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
234Standard_Boolean Extrema_ExtSS::IsDone() const
235{
236 return myDone;
237}
238
239Standard_Boolean Extrema_ExtSS::IsParallel() const
240{
241 return myIsPar;
242}
243
244
245Standard_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
254Standard_Integer Extrema_ExtSS::NbExt() const
255{
256 if(!myDone) StdFail_NotDone::Raise();
257 return mySqDist.Length();
258}
259
260
261
262void 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}