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