0023952: Improving thread-safety of intersections, approximations and other modeling...
[occt.git] / src / IntPatch / IntPatch_HInterTool.cxx
1 // Created on: 1995-07-02
2 // Created by: Laurent BUCHARD
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 #include <IntPatch_HInterTool.ixx>
23
24 #include <Extrema_EPCOfExtPC2d.hxx>
25 #include <Extrema_POnCurv2d.hxx>
26
27 #include <GeomAbs_SurfaceType.hxx>
28 #include <Standard_OutOfRange.hxx>
29
30 #include <Handle_Geom_BezierSurface.hxx>
31 #include <Handle_Geom_BSplineSurface.hxx>
32 #include <Handle_Geom2d_BezierCurve.hxx>
33 #include <Handle_Geom2d_BSplineCurve.hxx>
34
35 #include <Geom_BezierSurface.hxx>
36 #include <Geom_BSplineSurface.hxx>
37 #include <Geom2d_BezierCurve.hxx>
38 #include <Geom2d_BSplineCurve.hxx>
39
40 IntPatch_HInterTool::IntPatch_HInterTool() :
41     uinf (0.), vinf (0.), usup (0.), vsup (0.)
42 {
43 }
44
45 Standard_Integer IntPatch_HInterTool::NbSamplesV (const Handle(Adaptor3d_HSurface)& S,
46                                                   const Standard_Real, const Standard_Real)
47 {
48   switch (S->GetType())
49   {
50     case GeomAbs_Plane: return 2;
51     case GeomAbs_BezierSurface: return (3 + S->NbVPoles());
52     case GeomAbs_BSplineSurface: 
53     {
54       Standard_Integer nbs = S->NbVKnots();
55       nbs *= S->VDegree();
56       if (!S->IsVRational()) nbs *= 2;
57       if (nbs < 4) nbs = 4;
58           return nbs;
59     }
60     break;
61     case GeomAbs_Cylinder:
62     case GeomAbs_Cone:
63     case GeomAbs_Sphere:
64     case GeomAbs_Torus:
65     case GeomAbs_SurfaceOfRevolution:
66     case GeomAbs_SurfaceOfExtrusion: return 15;
67   }
68   return 10;
69 }
70
71 Standard_Integer IntPatch_HInterTool::NbSamplesU (const Handle(Adaptor3d_HSurface)& S,
72                                                   const Standard_Real, const Standard_Real)
73 {
74   switch (S->GetType())
75   {
76     case GeomAbs_Plane: return 2;
77     case GeomAbs_BezierSurface: return (3 + S->NbUPoles());
78     case GeomAbs_BSplineSurface:
79     {
80       Standard_Integer nbs = S->NbUKnots();
81       nbs *= S->UDegree();
82       if (!S->IsURational()) nbs *= 2;
83       if (nbs < 4) nbs = 4;
84       return nbs;
85         }
86     case GeomAbs_Torus: return 20;
87     //case GeomAbs_Cylinder:
88     //case GeomAbs_Cone:
89     //case GeomAbs_Sphere:
90     //case GeomAbs_SurfaceOfRevolution:
91     //case GeomAbs_SurfaceOfExtrusion: return 10;
92   }
93   return 10;
94 }
95
96 Standard_Integer IntPatch_HInterTool::NbSamplePoints (const Handle(Adaptor3d_HSurface)& S)
97 {
98   uinf = S->FirstUParameter();
99   usup = S->LastUParameter();
100   vinf = S->FirstVParameter();
101   vsup = S->LastVParameter();
102
103   if (usup < uinf) {
104     Standard_Real temp = uinf;
105     uinf = usup;
106     usup = temp;
107     }
108     if (vsup < vinf) {
109     Standard_Real temp = vinf;
110     vinf = vsup;
111     vsup = temp;
112   }
113   if (uinf == RealFirst() && usup == RealLast()) {
114     uinf = -1.e5;
115     usup =  1.e5;
116   }
117   else if (uinf == RealFirst()) {
118     uinf = usup - 2.e5;
119   }
120   else if (usup == RealLast()) {
121     usup = uinf + 2.e5;
122   }
123   
124   if (vinf == RealFirst() && vsup == RealLast()) {
125     vinf = -1.e5;
126     vsup =  1.e5;
127   }
128   else if (vinf == RealFirst()) {
129     vinf = vsup - 2.e5;
130   }
131   else if (vsup == RealLast()) {
132     vsup = vinf + 2.e5;
133   }
134   const Standard_Integer m = (1+NbSamplesU(S,uinf,usup)/2) * (1+NbSamplesV(S,vinf,vsup)/2);
135   return(m);
136 }
137
138 void IntPatch_HInterTool::SamplePoint (const Handle(Adaptor3d_HSurface)& S,
139                                        const Standard_Integer Index,
140                                        Standard_Real& U,
141                                        Standard_Real& V ) const
142 {
143   Standard_Integer nbIntU = 1+NbSamplesU(S,uinf,usup);
144   nbIntU>>=1;
145   Standard_Integer nbIntV = 1+NbSamplesV(S,vinf,vsup);     
146   nbIntV>>=1;
147   
148   if(nbIntU * nbIntV >5) {
149     
150     Standard_Integer NV = (Index-1) / nbIntU;
151     Standard_Integer NU = (Index-1) - NV * nbIntU;
152     Standard_Real du = ((usup-uinf)/((Standard_Real)(nbIntU+1)));
153     Standard_Real dv = ((vsup-vinf)/((Standard_Real)(nbIntV+1)));
154     
155     Standard_Integer perturb=(NU+NV) & 3;
156
157     //-- petite perturbation pou eviter les pbs de symetrie avec Les recherches de points int. 
158
159     switch(perturb) { 
160     case 1: dv*=1.001;  dv*=0.999; break;
161     case 2: du*=1.001;  dv*=1.001; break;
162     case 3: du*=0.999;             break;
163     default: break;
164     }
165     
166     U = uinf + du*(Standard_Real)(NU+1);
167     V = vinf + dv*(Standard_Real)(NV+1);
168     return;
169   }
170   
171   
172   switch (Index) {
173   case 1:
174     U = 0.76*uinf + 0.24*usup;
175     V = 0.74*vinf + 0.26*vsup;
176     break;
177   case 2:
178     U = 0.73*uinf + 0.27*usup;
179     V = 0.24*vinf + 0.76*vsup;
180     break;
181   case 3:
182     U = 0.25*uinf + 0.75*usup;
183     V = 0.76*vinf + 0.24*vsup;
184     break;
185   case 4:
186     U = 0.26*uinf + 0.74*usup;
187     V = 0.25*vinf + 0.75*vsup;
188     break;
189   default:
190     U = 0.51*uinf+0.49*usup; 
191     V = 0.49*vinf+0.51*vsup;
192   }
193 }
194
195
196 Standard_Integer IntPatch_HInterTool::NbSamplesOnArc (const Handle(Adaptor2d_HCurve2d)& A)
197 {
198   GeomAbs_CurveType CurveType  = A->GetType();
199
200 //  Standard_Real nbsOnC = 5;
201   Standard_Integer nbsOnC = 5;
202   switch(CurveType) { 
203   case GeomAbs_Line:
204     nbsOnC = 2;
205     break;
206   case GeomAbs_Circle:
207   case GeomAbs_Ellipse:
208   case GeomAbs_Hyperbola:
209   case GeomAbs_Parabola:
210     nbsOnC = 10;
211     break;
212   case GeomAbs_BezierCurve:
213     nbsOnC = A->NbPoles();
214     break;
215   case GeomAbs_BSplineCurve: { 
216     //-- Handle_Geom2d_BSplineCurve& BSC=A->BSpline();
217     nbsOnC = 2 + A->NbKnots() * A->Degree();
218     break;
219   }
220   default:
221     nbsOnC = 10;
222   } 
223   return(nbsOnC);
224 }
225
226 void IntPatch_HInterTool::Bounds(const Handle(Adaptor2d_HCurve2d)& A,
227                                  Standard_Real& Ufirst,
228                                  Standard_Real& Ulast)
229 {
230   Ufirst = A->FirstParameter();
231   Ulast  = A->LastParameter();
232 }
233
234 Standard_Boolean IntPatch_HInterTool::Project (const Handle(Adaptor2d_HCurve2d)& C,
235                                                const gp_Pnt2d& P,
236                                                Standard_Real& Paramproj,
237                                                gp_Pnt2d& Ptproj)
238 {
239   Standard_Real epsX = 1.e-8;
240   Standard_Integer Nbu = 20;
241   Standard_Real Tol = 1.e-5;
242   Standard_Real Dist2;
243
244   Extrema_EPCOfExtPC2d extrema(P,C->Curve2d(),Nbu,epsX,Tol);
245   if (!extrema.IsDone()) {
246     return Standard_False;
247   }
248   Standard_Integer Nbext = extrema.NbExt();
249   if (Nbext == 0) {
250     return Standard_False;
251   }
252   Standard_Integer indexmin = 1;
253   Dist2 = extrema.SquareDistance(1);
254   for (Standard_Integer i=2; i<=Nbext; i++) {
255     if (extrema.SquareDistance(i) < Dist2) {
256       indexmin = i;
257       Dist2 = extrema.SquareDistance(i);
258     }
259   }
260   Paramproj = extrema.Point(indexmin).Parameter();
261   Ptproj = extrema.Point(indexmin).Value();
262   return Standard_True;
263 }
264
265 Standard_Real IntPatch_HInterTool::Tolerance (const Handle(Adaptor3d_HVertex)& V,
266                                               const Handle(Adaptor2d_HCurve2d)& C)
267 {
268   return V->Resolution(C);
269 }
270
271 Standard_Real IntPatch_HInterTool::Parameter (const Handle(Adaptor3d_HVertex)& V,
272                                               const Handle(Adaptor2d_HCurve2d)& C)
273 {
274   return V->Parameter(C);
275 }
276
277 Standard_Boolean IntPatch_HInterTool::HasBeenSeen(const Handle(Adaptor2d_HCurve2d)&)
278 {
279   return Standard_False;
280 }
281
282 Standard_Integer IntPatch_HInterTool::NbPoints(const Handle(Adaptor2d_HCurve2d)&)
283 {
284   return 0;
285 }
286
287 void IntPatch_HInterTool::Value(const Handle(Adaptor2d_HCurve2d)&,
288                                 const Standard_Integer,
289                                 gp_Pnt&,
290                                 Standard_Real&,
291                                 Standard_Real&)
292 {
293   Standard_OutOfRange::Raise();
294 }
295
296 Standard_Boolean IntPatch_HInterTool::IsVertex(const Handle(Adaptor2d_HCurve2d)&,
297                                                const Standard_Integer)
298 {
299   return Standard_False;
300 }
301
302 void IntPatch_HInterTool::Vertex(const Handle(Adaptor2d_HCurve2d)&,
303                                  const Standard_Integer,
304                                  Handle(Adaptor3d_HVertex)&)
305 {
306   Standard_OutOfRange::Raise();
307 }
308
309 Standard_Integer IntPatch_HInterTool::NbSegments(const Handle(Adaptor2d_HCurve2d)&)
310 {
311   return 0;
312 }
313
314 Standard_Boolean IntPatch_HInterTool::HasFirstPoint (const Handle(Adaptor2d_HCurve2d)&,
315                                                      const Standard_Integer,
316                                                      Standard_Integer&)
317 {
318   Standard_OutOfRange::Raise();
319   return Standard_False;
320 }
321
322 Standard_Boolean IntPatch_HInterTool::HasLastPoint (const Handle(Adaptor2d_HCurve2d)&,
323                                                     const Standard_Integer,
324                                                     Standard_Integer&)
325 {
326   Standard_OutOfRange::Raise();
327   return Standard_False;
328 }
329
330 Standard_Boolean IntPatch_HInterTool::IsAllSolution (const Handle(Adaptor2d_HCurve2d)&)
331 {
332   return Standard_False;
333 }