0030932: Modeling Algorithms - Invalid result on 2d curve on surface approximation
[occt.git] / src / GeomProjLib / GeomProjLib.cxx
CommitLineData
b311480e 1// Created on: 1994-09-21
2// Created by: Bruno DUMORTIER
3// Copyright (c) 1994-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
17// Modified by skv - Wed Aug 11 17:26:03 2004 OCC6272
18
7fd59977 19#include <Approx_CurveOnSurface.hxx>
42cf5bc1 20#include <Geom2d_BezierCurve.hxx>
21#include <Geom2d_BSplineCurve.hxx>
7fd59977 22#include <Geom2d_Circle.hxx>
42cf5bc1 23#include <Geom2d_Curve.hxx>
7fd59977 24#include <Geom2d_Ellipse.hxx>
7fd59977 25#include <Geom2d_Hyperbola.hxx>
42cf5bc1 26#include <Geom2d_Line.hxx>
27#include <Geom2d_Parabola.hxx>
7fd59977 28#include <Geom2d_TrimmedCurve.hxx>
42cf5bc1 29#include <Geom_BezierCurve.hxx>
30#include <Geom_BSplineCurve.hxx>
31#include <Geom_Circle.hxx>
32#include <Geom_Curve.hxx>
33#include <Geom_Ellipse.hxx>
34#include <Geom_Hyperbola.hxx>
35#include <Geom_Line.hxx>
36#include <Geom_Parabola.hxx>
37#include <Geom_Plane.hxx>
38#include <Geom_Surface.hxx>
39#include <Geom_TrimmedCurve.hxx>
40#include <GeomAdaptor_Curve.hxx>
41#include <GeomAdaptor_HCurve.hxx>
42#include <GeomAdaptor_HSurface.hxx>
43#include <GeomAdaptor_Surface.hxx>
44#include <GeomProjLib.hxx>
45#include <gp_Dir.hxx>
7fd59977 46#include <gp_Pln.hxx>
7fd59977 47#include <Precision.hxx>
42cf5bc1 48#include <ProjLib_CompProjectedCurve.hxx>
49#include <ProjLib_ProjectedCurve.hxx>
50#include <ProjLib_ProjectOnPlane.hxx>
51#include <ProjLib_ProjectOnSurface.hxx>
7fd59977 52#include <TColgp_Array1OfPnt.hxx>
53#include <TColgp_Array1OfPnt2d.hxx>
42cf5bc1 54#include <TColStd_Array1OfInteger.hxx>
55#include <TColStd_Array1OfReal.hxx>
7fd59977 56
42cf5bc1 57#include <stdio.h>
7fd59977 58#ifdef DRAW
59#include <DrawTrSurf.hxx>
7fd59977 60static Standard_Boolean Affich = Standard_False;
61static Standard_Integer NBPROJ = 1;
62#endif
63
64
65//=======================================================================
66//function : Curve2d
67//purpose :
68//=======================================================================
69
70Handle(Geom2d_Curve) GeomProjLib::Curve2d(const Handle(Geom_Curve)& C,
71 const Standard_Real First,
72 const Standard_Real Last,
73 const Handle(Geom_Surface)& S,
74 const Standard_Real UDeb,
75 const Standard_Real UFin,
76 const Standard_Real VDeb,
77 const Standard_Real VFin,
78 Standard_Real& Tolerance)
79{
80#ifdef DRAW
81 if ( Affich) {
1896126e 82 char name[256];
91322f44 83 Sprintf(name,"PROJCURV_%d",NBPROJ);
7fd59977 84 DrawTrSurf::Set(name,C);
91322f44 85 Sprintf(name,"PROJSURF_%d",NBPROJ);
7fd59977 86 DrawTrSurf::Set(name,S);
87 NBPROJ++;
88 }
89#endif
90
91 Tolerance = Max(Precision::PConfusion(),Tolerance);
92
93 GeomAdaptor_Curve AC(C,First,Last);
94 GeomAdaptor_Surface AS(S,
95 UDeb,
96 UFin,
97 VDeb,
98 VFin);
99
100 Handle(GeomAdaptor_HSurface) HS = new GeomAdaptor_HSurface(AS);
101 Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve(AC);
102
103 ProjLib_ProjectedCurve Proj(HS,HC,Tolerance);
104
105 Handle(Geom2d_Curve) G2dC;
106
107 switch ( Proj.GetType()) {
108
109 case GeomAbs_Line:
110 G2dC = new Geom2d_Line(Proj.Line());
111 break;
112
113 case GeomAbs_Circle:
114 G2dC = new Geom2d_Circle(Proj.Circle());
115 break;
116
117 case GeomAbs_Ellipse:
118 G2dC = new Geom2d_Ellipse(Proj.Ellipse());
119 break;
120
121 case GeomAbs_Parabola:
122 G2dC = new Geom2d_Parabola(Proj.Parabola());
123 break;
124
125 case GeomAbs_Hyperbola:
126 G2dC = new Geom2d_Hyperbola(Proj.Hyperbola());
127 break;
128
129 case GeomAbs_BezierCurve:
130 G2dC = Proj.Bezier();
131 break;
132
133 case GeomAbs_BSplineCurve:
134 G2dC = Proj.BSpline();
135 break;
136
137 default:
138 return G2dC;
139
140 }
141
142 if(G2dC.IsNull()) {
143 Tolerance = Proj.GetTolerance();
144 return G2dC;
145 }
146
147 if ( C->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)) ) {
148 Handle(Geom_TrimmedCurve) CTrim = Handle(Geom_TrimmedCurve)::DownCast(C);
149 Standard_Real U1 = CTrim->FirstParameter();
150 Standard_Real U2 = CTrim->LastParameter();
eb7404bf 151 if (!G2dC->IsPeriodic())
152 {
153 U1 = Max(U1, G2dC->FirstParameter());
154 U2 = Min(U2, G2dC->LastParameter());
155 }
7fd59977 156 G2dC = new Geom2d_TrimmedCurve( G2dC, U1, U2);
157 }
158
159#ifdef DRAW
160 if ( Affich) {
161 static Standard_CString aprojcurv = "projcurv" ;
162 DrawTrSurf::Set(aprojcurv,G2dC);
163 }
164#endif
165 Tolerance = Proj.GetTolerance();
166 return G2dC;
167}
168
169//=======================================================================
170//function : Curve2d
171//purpose :
172//=======================================================================
173
174Handle(Geom2d_Curve) GeomProjLib::Curve2d(const Handle(Geom_Curve)& C,
175 const Standard_Real First,
176 const Standard_Real Last,
177 const Handle(Geom_Surface)& S,
178 Standard_Real& Tolerance)
179{
180 Standard_Real UFirst,
181 ULast,
182 VFirst,
183 VLast ;
184
185 S->Bounds(UFirst,
186 ULast,
187 VFirst,
188 VLast) ;
189 return Curve2d(C,
190 First,
191 Last,
192 S,
193 UFirst,
194 ULast,
195 VFirst,
196 VLast,
197 Tolerance) ;
198}
199// Modified by skv - Wed Aug 11 17:26:03 2004 OCC6272 Begin
200// Add not implemented method.
201//=======================================================================
202//function : Curve2d
203//purpose :
204//=======================================================================
205
206Handle(Geom2d_Curve) GeomProjLib::Curve2d( const Handle(Geom_Curve)& C,
207 const Handle(Geom_Surface)& S,
208 const Standard_Real UDeb,
209 const Standard_Real UFin,
210 const Standard_Real VDeb,
211 const Standard_Real VFin)
212{
213 Standard_Real First = C->FirstParameter();
214 Standard_Real Last = C->LastParameter();
215 Standard_Real Tol = Precision::PConfusion();
216 return GeomProjLib::Curve2d(C,First,Last,S,UDeb,UFin,VDeb,VFin,Tol);
217}
218// Modified by skv - Wed Aug 11 17:26:03 2004 OCC6272 End
219
220//=======================================================================
221//function : Curve2d
222//purpose :
223//=======================================================================
224
225Handle(Geom2d_Curve) GeomProjLib::Curve2d( const Handle(Geom_Curve)& C,
226 const Handle(Geom_Surface)& S,
227 const Standard_Real UDeb,
228 const Standard_Real UFin,
229 const Standard_Real VDeb,
230 const Standard_Real VFin,
231 Standard_Real& Tolerance)
232{
233 Standard_Real First = C->FirstParameter();
234 Standard_Real Last = C->LastParameter();
235 return GeomProjLib::Curve2d(C,First,Last,S,UDeb,UFin,VDeb,VFin,Tolerance);
236}
237
238
239//=======================================================================
240//function : Curve2d
241//purpose :
242//=======================================================================
243
244Handle(Geom2d_Curve) GeomProjLib::Curve2d( const Handle(Geom_Curve)& C,
245 const Handle(Geom_Surface)& S)
246{
247 Standard_Real First = C->FirstParameter();
248 Standard_Real Last = C->LastParameter();
249 Standard_Real Tol = Precision::PConfusion();
250 return GeomProjLib::Curve2d(C,First,Last,S,Tol);
251}
252
253
254//=======================================================================
255//function : Curve2d
256//purpose :
257//=======================================================================
258
259Handle(Geom2d_Curve) GeomProjLib::Curve2d( const Handle(Geom_Curve)& C,
260 const Standard_Real First,
261 const Standard_Real Last,
262 const Handle(Geom_Surface)& S)
263{
264 Standard_Real Tol = Precision::PConfusion();
265 return GeomProjLib::Curve2d(C,First,Last,S,Tol);
266}
267
268
269//=======================================================================
270//function : Project
271//purpose :
272//=======================================================================
273
274Handle(Geom_Curve) GeomProjLib::Project( const Handle(Geom_Curve)& C,
275 const Handle(Geom_Surface)& S)
276{
277 GeomAdaptor_Curve AC(C);
278 GeomAdaptor_Surface AS(S);
279
280 Handle(Geom_Curve) GC;
281
282 if ( AS.GetType() == GeomAbs_Plane) {
283 ProjLib_ProjectOnPlane Proj( AS.Plane().Position());
284 Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve(AC);
285 Proj.Load(HC,Precision::PApproximation());
286
287 switch ( Proj.GetType()) {
288 case GeomAbs_Line:
289 GC = new Geom_Line(Proj.Line());
290 break;
291
292 case GeomAbs_Circle:
293 GC = new Geom_Circle(Proj.Circle());
294 break;
295
296 case GeomAbs_Ellipse:
297 GC = new Geom_Ellipse(Proj.Ellipse());
298 break;
299
300 case GeomAbs_Parabola:
301 GC = new Geom_Parabola(Proj.Parabola());
302 break;
303
304 case GeomAbs_Hyperbola:
305 GC = new Geom_Hyperbola(Proj.Hyperbola());
306 break;
307
308 case GeomAbs_BezierCurve:
309 GC = Proj.Bezier();
310 break;
311
312 case GeomAbs_BSplineCurve:
313 GC = Proj.BSpline();
314 break;
315
316 default:
317 return GC;
318
319 }
320
321 if ( C->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
322 Handle(Geom_TrimmedCurve) CTrim = Handle(Geom_TrimmedCurve)::DownCast(C);
323 Standard_Real U1 = CTrim->FirstParameter();
324 Standard_Real U2 = CTrim->LastParameter();
325 GC = new Geom_TrimmedCurve( GC, U1, U2);
326 }
327
328 }
329 else {
330 Handle(GeomAdaptor_HSurface) HS = new GeomAdaptor_HSurface(AS);
331 Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve(AC);
332// Standard_Real Tol = Precision::Approximation();
333// Standard_Real TolU = Precision::PApproximation();
334// Standard_Real TolV = Precision::PApproximation();
335 Standard_Real Tol = 0.0001;
336 Standard_Real TolU = Pow(Tol, 2./3);
337 Standard_Real TolV = Pow(Tol, 2./3);
338 ProjLib_CompProjectedCurve Proj(HS,HC,TolU,TolV,-1.);
339
7fd59977 340 Standard_Real f,l;
341 Proj.Bounds(1,f,l);
342 Handle(Adaptor2d_HCurve2d) HC2d = Proj.Trim(f,l,TolU);
f04de133 343 Approx_CurveOnSurface Approx(HC2d, HS, f, l, Tol);
344 Approx.Perform(16, 14, GeomAbs_C2, Standard_True);
7fd59977 345
346 // ici, on a toujours un type BSpline.
347 if (Approx.IsDone() && Approx.HasResult())
348 GC = Approx.Curve3d();
349 }
350
351 return GC;
352}
353
354//=======================================================================
355//function : ProjectOnPlane
356//purpose :
357//=======================================================================
358
359Handle(Geom_Curve) GeomProjLib::ProjectOnPlane
360(const Handle(Geom_Curve)& Curve,
361 const Handle(Geom_Plane)& Plane,
362 const gp_Dir& Dir,
363 const Standard_Boolean KeepParametrization)
364{
365 GeomAdaptor_Curve AC(Curve);
366 Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve(AC);
367
368 ProjLib_ProjectOnPlane Proj(Plane->Position(), Dir);
369 Proj.Load(HC,Precision::Approximation(), KeepParametrization);
370
371 Handle(Geom_Curve) GC;
372
373 switch ( Proj.GetType()) {
374 case GeomAbs_Line:
375 GC = new Geom_Line(Proj.Line());
376 break;
377
378 case GeomAbs_Circle:
379 GC = new Geom_Circle(Proj.Circle());
380 break;
381
382 case GeomAbs_Ellipse:
383 GC = new Geom_Ellipse(Proj.Ellipse());
384 break;
385
386 case GeomAbs_Parabola:
387 GC = new Geom_Parabola(Proj.Parabola());
388 break;
389
390 case GeomAbs_Hyperbola:
391 GC = new Geom_Hyperbola(Proj.Hyperbola());
392 break;
393
394 case GeomAbs_BezierCurve:
395 GC = Proj.Bezier();
396 break;
397
398 case GeomAbs_BSplineCurve:
399 GC = Proj.BSpline();
400 break;
401 default:
402 return GC;
403
404 }
405
406 if ( Curve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)) ) {
407 Handle(Geom_TrimmedCurve) CTrim
408 = Handle(Geom_TrimmedCurve)::DownCast(Curve);
409 GC = new Geom_TrimmedCurve( GC, Proj.FirstParameter(),
410 Proj.LastParameter());
411 }
412
413 return GC;
414
415}
416
417