0023944: Typo in ShapeCustom_RestrictionParameters leading to wrong approximation...
[occt.git] / src / IntStart / IntStart_SearchInside.gxx
CommitLineData
b311480e 1// Copyright (c) 1995-1999 Matra Datavision
2// Copyright (c) 1999-2012 OPEN CASCADE SAS
3//
4// The content of this file is subject to the Open CASCADE Technology Public
5// License Version 6.5 (the "License"). You may not use the content of this file
6// except in compliance with the License. Please obtain a copy of the License
7// at http://www.opencascade.org and read it completely before using this file.
8//
9// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11//
12// The Original Code and all software distributed under the License is
13// distributed on an "AS IS" basis, without warranty of any kind, and the
14// Initial Developer hereby disclaims all such warranties, including without
15// limitation, any warranties of merchantability, fitness for a particular
16// purpose or non-infringement. Please see the License for the specific terms
17// and conditions governing the rights and limitations under the License.
18
7fd59977 19
20#ifndef DEB
21#define No_Standard_RangeError
22#define No_Standard_OutOfRange
23#endif
24
25
26
27#include <math_FunctionSetRoot.hxx>
28#include <Precision.hxx>
29#include <gp_Pnt2d.hxx>
30
31#include <TopAbs_State.hxx>
32
33IntStart_SearchInside::IntStart_SearchInside (): done(Standard_False)
34{}
35
36IntStart_SearchInside::IntStart_SearchInside (TheFunction& Func,
37 const ThePSurface& PS,
38 const Handle(TheTopolTool)& T,
39 const Standard_Real Epsilon) {
40
41 Perform(Func,PS,T,Epsilon);
42}
43
44
45//=======================================================================
46//function : Perform
47//purpose : Search all inside points
48//=======================================================================
49
50void IntStart_SearchInside::Perform (TheFunction& Func,
51 const ThePSurface& PS,
52 const Handle(TheTopolTool)& T,
53 const Standard_Real Epsilon) {
54
55 done = Standard_False;
56 list.Clear();
57 static math_Vector Binf(1,2), Bsup(1,2), UVap(1,2),toler(1,2);
58 gp_Pnt psol;
59 Standard_Boolean testpnt;
60 Standard_Integer i,j,nbpt;
61 TopAbs_State situ;
62 Standard_Real umin,umax,vmin,vmax;
63 Binf(1) = umin = ThePSurfaceTool::FirstUParameter(PS);
64 Binf(2) = vmin = ThePSurfaceTool::FirstVParameter(PS);
65 Bsup(1) = umax = ThePSurfaceTool::LastUParameter(PS);
66 Bsup(2) = vmax = ThePSurfaceTool::LastVParameter(PS);
67
68 Standard_Integer NbsampleU= T->NbSamplesU();
69 Standard_Integer NbsampleV= T->NbSamplesV();
70 Standard_Integer Nbsample = T->NbSamples();
71
72 Standard_Real du = Bsup(1)-Binf(1);
73 Standard_Real dv = Bsup(2)-Binf(2);
74 du/=(Standard_Real)NbsampleU*0.5;
75 dv/=(Standard_Real)NbsampleV*0.5;
76
77 Standard_Real toler1 = toler(1) = ThePSurfaceTool::UResolution(PS,Precision::Confusion());
78 Standard_Real toler2 = toler(2) = ThePSurfaceTool::VResolution(PS,Precision::Confusion());
79 Standard_Real Maxtoler1toler2 = toler1;
80 if(toler2>Maxtoler1toler2) Maxtoler1toler2 = toler2;
81
82 //-- lbr le 15 mai 97
83 //-- on interdit aux points d'etre trop prets des restrictions
84 Maxtoler1toler2*=1000;
85 if(Maxtoler1toler2>du*0.001) Maxtoler1toler2=du*0.001;
86 if(Maxtoler1toler2>dv*0.001) Maxtoler1toler2=dv*0.001;
87
88
89 Func.Set(PS);
90 Standard_Real Tol = Func.Tolerance();
91
92 math_FunctionSetRoot Rsnld(Func,toler);
93
94 Standard_Integer REJET_OK=0;
95 Standard_Integer REJET_KO=0;
96
97 //-- lbr le 15 mai 97
98 umin+=du*0.01;
99 vmin+=dv*0.01;
100 umax-=du*0.01;
101 vmax-=dv*0.01;
102
103 //-- lbr le 30 octobre 97 :
104 //-- Si une surface vient tangenter 2 edges proche d un coin
105 //-- il faut faire attention qu un point de depart soit trouve au
106 //-- voisinage du coin. Car ds le cas contraire, le cheminement ne
107 //-- pourra pas passer au travers des frontieres :
108 //--
109 //-- typiquement I est un cylindre (conge)
110 //--
111 //-- PPPPPPPPPPPPPPPPPPPP*PPPPPPPPPPPPPPPP
112 //-- P I I
113 //-- P I I
114 //-- P I
115 //-- P # il faut trouver un point ici
116 //-- P I
117 //-- P I
118 //-- PI
119 //-- * I
120 //-- PI I
121 //-- P I I I I I I I I
122 //--
123
124
125 for (i=1; i <= Nbsample+12; i++) {
126 gp_Pnt2d s2d;
127 gp_Pnt s3d;
128 Standard_Boolean nepastester=Standard_False;
129 if(i<=Nbsample) {
130 T->SamplePoint(i,s2d,s3d);
131 UVap(1)=s2d.X(); UVap(2)=s2d.Y();
132
133 Standard_Real u1,v1,u2,v2;
134 u1 = Binf(1) = Max(umin,UVap(1)-du);
135 v1 = Binf(2) = Max(vmin,UVap(2)-dv);
136 u2 = Bsup(1) = Min(umax,UVap(1)+du);
137 v2 = Bsup(2) = Min(vmax,UVap(2)+dv);
138
139
140 //-- gp_Pnt Pmilieu = ThePSurfaceTool::Value(PS,0.5*(u1+u2),0.5*(v1+v2));
141 gp_Pnt Pextrm1 = ThePSurfaceTool::Value(PS,u1,v1);
142 gp_Pnt Pextrm2 = ThePSurfaceTool::Value(PS,u2,v2);
143 static math_Vector Valf(1,1);
144 Func.Value(UVap,Valf);
145 Standard_Real rvalf = Valf(1);
146 Standard_Real DistPP = Pextrm1.SquareDistance(Pextrm2);
147 if(rvalf*rvalf > 3.0*DistPP) {
148 REJET_OK++;
149 nepastester=Standard_True;
150 }
151 }
152 else {
153 if(i==Nbsample+1) { s2d.SetCoord(umin+du*0.02,vmin+dv*0.02); }
154 else if(i==Nbsample+2) { s2d.SetCoord(umax-du*0.02,vmin+dv*0.02); }
155 else if(i==Nbsample+3) { s2d.SetCoord(umin+du*0.02,vmax-dv*0.02); }
156 else if(i==Nbsample+4) { s2d.SetCoord(umax-du*0.02,vmax-dv*0.02); }
157
158 else if(i==Nbsample+5) { s2d.SetCoord(umin+du*0.02,vmin+dv*0.02); }
159 else if(i==Nbsample+6) { s2d.SetCoord(umax-du*0.02,vmin+dv*0.02); }
160 else if(i==Nbsample+7) { s2d.SetCoord(umin+du*0.02,vmax-dv*0.02); }
161 else if(i==Nbsample+8) { s2d.SetCoord(umax-du*0.02,vmax-dv*0.02); }
162
163 else if(i==Nbsample+9) { s2d.SetCoord(umin+du*0.005,vmin+dv*0.005); }
164 else if(i==Nbsample+10){ s2d.SetCoord(umax-du*0.005,vmin+dv*0.005); }
165 else if(i==Nbsample+11){ s2d.SetCoord(umin+du*0.005,vmax-dv*0.005); }
166 else { s2d.SetCoord(umax-du*0.005,vmax-dv*0.005); }
167
168 UVap(1)=s2d.X(); UVap(2)=s2d.Y();
169
170 Binf(1) = Max(umin,UVap(1)-du);
171 Binf(2) = Max(vmin,UVap(2)-dv);
172 Bsup(1) = Min(umax,UVap(1)+du);
173 Bsup(2) = Min(vmax,UVap(2)+dv);
174 }
175
176
177 if(nepastester==Standard_False) {
178 REJET_KO++;
179 Rsnld.Perform(Func,UVap,Binf,Bsup);
180 if (Rsnld.IsDone()) {
181 if (Abs(Func.Root()) <= Tol) {
182 if (!Func.IsTangent()) {
183 psol = Func.Point();
184 Rsnld.Root(UVap);
185 // On regarde si le point trouve est bien un nouveau point.
186 j = 1;
187 nbpt = list.Length();
188 testpnt = (j <= nbpt);
189
190 while (testpnt) {
191 const IntSurf_InteriorPoint& IPj = list(j);
192 const gp_Pnt& Pj = IPj.Value();
193 if ( (Abs(Pj.X()-psol.X()) <= Epsilon)
194 && (Abs(Pj.Y()-psol.Y()) <= Epsilon)
195 && (Abs(Pj.Z()-psol.Z()) <= Epsilon)
196 && (Abs(UVap(1)-IPj.UParameter()) <= toler1)
197 && (Abs(UVap(2)-IPj.VParameter()) <= toler2) ) {
198 testpnt = Standard_False;
199 }
200 else {
201 j = j+1;
202 testpnt = (j <= nbpt);
203 }
204 }
205 if (j > nbpt) {
206 // situ = TheSITool::Classify(PS,UVap(1),UVap(2));
207 situ = T->Classify(gp_Pnt2d(UVap(1),UVap(2)),
208 Maxtoler1toler2,Standard_False); //-- ,Standard_False pour ne pas recadrer on Periodic
209 if (situ == TopAbs_IN) {
210 list.Append(IntSurf_InteriorPoint(psol,UVap(1),UVap(2),
211 Func.Direction3d(),
212 Func.Direction2d()));
213 }
214 }
215 }
216 }
217 }
218 }
219 }
220 //-- printf("\n Total : %d Rejet : %d RatioPointCalc : %g nbpt =%d\n",REJET_OK+REJET_KO,REJET_OK,(double)(REJET_KO)/(double)(REJET_OK+REJET_KO),list.Length());
221 done = Standard_True;
222}
223
224
225//=======================================================================
226//function : Perform
227//purpose : Test the given inside point
228//=======================================================================
229
230void IntStart_SearchInside::Perform (TheFunction& Func,
231 const ThePSurface& PS,
232 const Standard_Real UStart,
233 const Standard_Real VStart)
234{
235 done = Standard_False;
236 list.Clear();
237 math_Vector Binf(1,2), Bsup(1,2), toler(1,2);
238
239 Binf(1) = ThePSurfaceTool::FirstUParameter(PS);
240 Binf(2) = ThePSurfaceTool::FirstVParameter(PS);
241 Bsup(1) = ThePSurfaceTool::LastUParameter(PS);
242 Bsup(2) = ThePSurfaceTool::LastVParameter(PS);
243
244 toler(1) = ThePSurfaceTool::UResolution(PS,Precision::Confusion());
245 toler(2) = ThePSurfaceTool::VResolution(PS,Precision::Confusion());
246
247 if (UStart-Binf(1) > -toler(1) && UStart-Bsup(1) < toler(1) &&
248 VStart-Binf(2) > -toler(2) && VStart-Bsup(2) < toler(2)) {
249
250 Func.Set(PS);
251 math_Vector UVap(1,2);
252 UVap(1)=UStart; UVap(2)=VStart;
253
254 math_FunctionSetRoot Rsnld(Func,toler);
255 Rsnld.Perform(Func,UVap,Binf,Bsup);
256 if (Rsnld.IsDone()) {
257 Standard_Real tol = Func.Tolerance();
258 Standard_Real valf = Func.Root();
259 if (Abs(valf) <= tol && !Func.IsTangent()) {
260 const gp_Pnt& psol = Func.Point();
261 Rsnld.Root(UVap);
262 IntSurf_InteriorPoint intp (psol,UVap(1),UVap(2),
263 Func.Direction3d(),Func.Direction2d());
264 list.Append(intp);
265 }
266 }
267 }
268
269 done = Standard_True;
270}