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 | |
33 | IntStart_SearchInside::IntStart_SearchInside (): done(Standard_False) |
34 | {} |
35 | |
36 | IntStart_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 | |
50 | void 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 | |
230 | void 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 | } |