7fd59977 |
1 | //-- File IntStart_SearchInside.gxx |
2 | |
3 | #ifndef DEB |
4 | #define No_Standard_RangeError |
5 | #define No_Standard_OutOfRange |
6 | #endif |
7 | |
8 | |
9 | |
10 | #include <math_FunctionSetRoot.hxx> |
11 | #include <Precision.hxx> |
12 | #include <gp_Pnt2d.hxx> |
13 | |
14 | #include <TopAbs_State.hxx> |
15 | |
16 | IntStart_SearchInside::IntStart_SearchInside (): done(Standard_False) |
17 | {} |
18 | |
19 | IntStart_SearchInside::IntStart_SearchInside (TheFunction& Func, |
20 | const ThePSurface& PS, |
21 | const Handle(TheTopolTool)& T, |
22 | const Standard_Real Epsilon) { |
23 | |
24 | Perform(Func,PS,T,Epsilon); |
25 | } |
26 | |
27 | |
28 | //======================================================================= |
29 | //function : Perform |
30 | //purpose : Search all inside points |
31 | //======================================================================= |
32 | |
33 | void IntStart_SearchInside::Perform (TheFunction& Func, |
34 | const ThePSurface& PS, |
35 | const Handle(TheTopolTool)& T, |
36 | const Standard_Real Epsilon) { |
37 | |
38 | done = Standard_False; |
39 | list.Clear(); |
40 | static math_Vector Binf(1,2), Bsup(1,2), UVap(1,2),toler(1,2); |
41 | gp_Pnt psol; |
42 | Standard_Boolean testpnt; |
43 | Standard_Integer i,j,nbpt; |
44 | TopAbs_State situ; |
45 | Standard_Real umin,umax,vmin,vmax; |
46 | Binf(1) = umin = ThePSurfaceTool::FirstUParameter(PS); |
47 | Binf(2) = vmin = ThePSurfaceTool::FirstVParameter(PS); |
48 | Bsup(1) = umax = ThePSurfaceTool::LastUParameter(PS); |
49 | Bsup(2) = vmax = ThePSurfaceTool::LastVParameter(PS); |
50 | |
51 | Standard_Integer NbsampleU= T->NbSamplesU(); |
52 | Standard_Integer NbsampleV= T->NbSamplesV(); |
53 | Standard_Integer Nbsample = T->NbSamples(); |
54 | |
55 | Standard_Real du = Bsup(1)-Binf(1); |
56 | Standard_Real dv = Bsup(2)-Binf(2); |
57 | du/=(Standard_Real)NbsampleU*0.5; |
58 | dv/=(Standard_Real)NbsampleV*0.5; |
59 | |
60 | Standard_Real toler1 = toler(1) = ThePSurfaceTool::UResolution(PS,Precision::Confusion()); |
61 | Standard_Real toler2 = toler(2) = ThePSurfaceTool::VResolution(PS,Precision::Confusion()); |
62 | Standard_Real Maxtoler1toler2 = toler1; |
63 | if(toler2>Maxtoler1toler2) Maxtoler1toler2 = toler2; |
64 | |
65 | //-- lbr le 15 mai 97 |
66 | //-- on interdit aux points d'etre trop prets des restrictions |
67 | Maxtoler1toler2*=1000; |
68 | if(Maxtoler1toler2>du*0.001) Maxtoler1toler2=du*0.001; |
69 | if(Maxtoler1toler2>dv*0.001) Maxtoler1toler2=dv*0.001; |
70 | |
71 | |
72 | Func.Set(PS); |
73 | Standard_Real Tol = Func.Tolerance(); |
74 | |
75 | math_FunctionSetRoot Rsnld(Func,toler); |
76 | |
77 | Standard_Integer REJET_OK=0; |
78 | Standard_Integer REJET_KO=0; |
79 | |
80 | //-- lbr le 15 mai 97 |
81 | umin+=du*0.01; |
82 | vmin+=dv*0.01; |
83 | umax-=du*0.01; |
84 | vmax-=dv*0.01; |
85 | |
86 | //-- lbr le 30 octobre 97 : |
87 | //-- Si une surface vient tangenter 2 edges proche d un coin |
88 | //-- il faut faire attention qu un point de depart soit trouve au |
89 | //-- voisinage du coin. Car ds le cas contraire, le cheminement ne |
90 | //-- pourra pas passer au travers des frontieres : |
91 | //-- |
92 | //-- typiquement I est un cylindre (conge) |
93 | //-- |
94 | //-- PPPPPPPPPPPPPPPPPPPP*PPPPPPPPPPPPPPPP |
95 | //-- P I I |
96 | //-- P I I |
97 | //-- P I |
98 | //-- P # il faut trouver un point ici |
99 | //-- P I |
100 | //-- P I |
101 | //-- PI |
102 | //-- * I |
103 | //-- PI I |
104 | //-- P I I I I I I I I |
105 | //-- |
106 | |
107 | |
108 | for (i=1; i <= Nbsample+12; i++) { |
109 | gp_Pnt2d s2d; |
110 | gp_Pnt s3d; |
111 | Standard_Boolean nepastester=Standard_False; |
112 | if(i<=Nbsample) { |
113 | T->SamplePoint(i,s2d,s3d); |
114 | UVap(1)=s2d.X(); UVap(2)=s2d.Y(); |
115 | |
116 | Standard_Real u1,v1,u2,v2; |
117 | u1 = Binf(1) = Max(umin,UVap(1)-du); |
118 | v1 = Binf(2) = Max(vmin,UVap(2)-dv); |
119 | u2 = Bsup(1) = Min(umax,UVap(1)+du); |
120 | v2 = Bsup(2) = Min(vmax,UVap(2)+dv); |
121 | |
122 | |
123 | //-- gp_Pnt Pmilieu = ThePSurfaceTool::Value(PS,0.5*(u1+u2),0.5*(v1+v2)); |
124 | gp_Pnt Pextrm1 = ThePSurfaceTool::Value(PS,u1,v1); |
125 | gp_Pnt Pextrm2 = ThePSurfaceTool::Value(PS,u2,v2); |
126 | static math_Vector Valf(1,1); |
127 | Func.Value(UVap,Valf); |
128 | Standard_Real rvalf = Valf(1); |
129 | Standard_Real DistPP = Pextrm1.SquareDistance(Pextrm2); |
130 | if(rvalf*rvalf > 3.0*DistPP) { |
131 | REJET_OK++; |
132 | nepastester=Standard_True; |
133 | } |
134 | } |
135 | else { |
136 | if(i==Nbsample+1) { s2d.SetCoord(umin+du*0.02,vmin+dv*0.02); } |
137 | else if(i==Nbsample+2) { s2d.SetCoord(umax-du*0.02,vmin+dv*0.02); } |
138 | else if(i==Nbsample+3) { s2d.SetCoord(umin+du*0.02,vmax-dv*0.02); } |
139 | else if(i==Nbsample+4) { s2d.SetCoord(umax-du*0.02,vmax-dv*0.02); } |
140 | |
141 | else if(i==Nbsample+5) { s2d.SetCoord(umin+du*0.02,vmin+dv*0.02); } |
142 | else if(i==Nbsample+6) { s2d.SetCoord(umax-du*0.02,vmin+dv*0.02); } |
143 | else if(i==Nbsample+7) { s2d.SetCoord(umin+du*0.02,vmax-dv*0.02); } |
144 | else if(i==Nbsample+8) { s2d.SetCoord(umax-du*0.02,vmax-dv*0.02); } |
145 | |
146 | else if(i==Nbsample+9) { s2d.SetCoord(umin+du*0.005,vmin+dv*0.005); } |
147 | else if(i==Nbsample+10){ s2d.SetCoord(umax-du*0.005,vmin+dv*0.005); } |
148 | else if(i==Nbsample+11){ s2d.SetCoord(umin+du*0.005,vmax-dv*0.005); } |
149 | else { s2d.SetCoord(umax-du*0.005,vmax-dv*0.005); } |
150 | |
151 | UVap(1)=s2d.X(); UVap(2)=s2d.Y(); |
152 | |
153 | Binf(1) = Max(umin,UVap(1)-du); |
154 | Binf(2) = Max(vmin,UVap(2)-dv); |
155 | Bsup(1) = Min(umax,UVap(1)+du); |
156 | Bsup(2) = Min(vmax,UVap(2)+dv); |
157 | } |
158 | |
159 | |
160 | if(nepastester==Standard_False) { |
161 | REJET_KO++; |
162 | Rsnld.Perform(Func,UVap,Binf,Bsup); |
163 | if (Rsnld.IsDone()) { |
164 | if (Abs(Func.Root()) <= Tol) { |
165 | if (!Func.IsTangent()) { |
166 | psol = Func.Point(); |
167 | Rsnld.Root(UVap); |
168 | // On regarde si le point trouve est bien un nouveau point. |
169 | j = 1; |
170 | nbpt = list.Length(); |
171 | testpnt = (j <= nbpt); |
172 | |
173 | while (testpnt) { |
174 | const IntSurf_InteriorPoint& IPj = list(j); |
175 | const gp_Pnt& Pj = IPj.Value(); |
176 | if ( (Abs(Pj.X()-psol.X()) <= Epsilon) |
177 | && (Abs(Pj.Y()-psol.Y()) <= Epsilon) |
178 | && (Abs(Pj.Z()-psol.Z()) <= Epsilon) |
179 | && (Abs(UVap(1)-IPj.UParameter()) <= toler1) |
180 | && (Abs(UVap(2)-IPj.VParameter()) <= toler2) ) { |
181 | testpnt = Standard_False; |
182 | } |
183 | else { |
184 | j = j+1; |
185 | testpnt = (j <= nbpt); |
186 | } |
187 | } |
188 | if (j > nbpt) { |
189 | // situ = TheSITool::Classify(PS,UVap(1),UVap(2)); |
190 | situ = T->Classify(gp_Pnt2d(UVap(1),UVap(2)), |
191 | Maxtoler1toler2,Standard_False); //-- ,Standard_False pour ne pas recadrer on Periodic |
192 | if (situ == TopAbs_IN) { |
193 | list.Append(IntSurf_InteriorPoint(psol,UVap(1),UVap(2), |
194 | Func.Direction3d(), |
195 | Func.Direction2d())); |
196 | } |
197 | } |
198 | } |
199 | } |
200 | } |
201 | } |
202 | } |
203 | //-- 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()); |
204 | done = Standard_True; |
205 | } |
206 | |
207 | |
208 | //======================================================================= |
209 | //function : Perform |
210 | //purpose : Test the given inside point |
211 | //======================================================================= |
212 | |
213 | void IntStart_SearchInside::Perform (TheFunction& Func, |
214 | const ThePSurface& PS, |
215 | const Standard_Real UStart, |
216 | const Standard_Real VStart) |
217 | { |
218 | done = Standard_False; |
219 | list.Clear(); |
220 | math_Vector Binf(1,2), Bsup(1,2), toler(1,2); |
221 | |
222 | Binf(1) = ThePSurfaceTool::FirstUParameter(PS); |
223 | Binf(2) = ThePSurfaceTool::FirstVParameter(PS); |
224 | Bsup(1) = ThePSurfaceTool::LastUParameter(PS); |
225 | Bsup(2) = ThePSurfaceTool::LastVParameter(PS); |
226 | |
227 | toler(1) = ThePSurfaceTool::UResolution(PS,Precision::Confusion()); |
228 | toler(2) = ThePSurfaceTool::VResolution(PS,Precision::Confusion()); |
229 | |
230 | if (UStart-Binf(1) > -toler(1) && UStart-Bsup(1) < toler(1) && |
231 | VStart-Binf(2) > -toler(2) && VStart-Bsup(2) < toler(2)) { |
232 | |
233 | Func.Set(PS); |
234 | math_Vector UVap(1,2); |
235 | UVap(1)=UStart; UVap(2)=VStart; |
236 | |
237 | math_FunctionSetRoot Rsnld(Func,toler); |
238 | Rsnld.Perform(Func,UVap,Binf,Bsup); |
239 | if (Rsnld.IsDone()) { |
240 | Standard_Real tol = Func.Tolerance(); |
241 | Standard_Real valf = Func.Root(); |
242 | if (Abs(valf) <= tol && !Func.IsTangent()) { |
243 | const gp_Pnt& psol = Func.Point(); |
244 | Rsnld.Root(UVap); |
245 | IntSurf_InteriorPoint intp (psol,UVap(1),UVap(2), |
246 | Func.Direction3d(),Func.Direction2d()); |
247 | list.Append(intp); |
248 | } |
249 | } |
250 | } |
251 | |
252 | done = Standard_True; |
253 | } |