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