0023706: Cannot project point on curve
[occt.git] / src / GeometryTest / GeometryTest_APICommands.cxx
CommitLineData
b311480e 1// Created on: 1995-01-17
2// Created by: Remi LEQUETTE
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
7fd59977 21
22
23#include <Geom_Curve.hxx>
24#include <Geom_Surface.hxx>
25#include <Draw.hxx>
26#include <Draw_Interpretor.hxx>
27#include <DrawTrSurf.hxx>
28#include <Draw_Appli.hxx>
29#include <GeometryTest.hxx>
30#include <GeomAPI_ProjectPointOnCurve.hxx>
31#include <GeomAPI_ProjectPointOnSurf.hxx>
32#include <GeomAPI_ExtremaCurveCurve.hxx>
33#include <GeomAPI_ExtremaCurveSurface.hxx>
34#include <GeomAPI_ExtremaSurfaceSurface.hxx>
35#include <GeomAPI_PointsToBSpline.hxx>
36#include <GeomAPI_PointsToBSplineSurface.hxx>
37#include <Geom_Line.hxx>
38#include <Geom_TrimmedCurve.hxx>
39#include <Draw_Segment3D.hxx>
40#include <Draw_Marker3D.hxx>
41#include <Draw_Color.hxx>
42#include <Draw_MarkerShape.hxx>
43#include <TColgp_Array1OfPnt.hxx>
44#include <TColgp_Array2OfPnt.hxx>
45#include <TColStd_Array2OfReal.hxx>
46#include <Precision.hxx>
47#include <stdio.h>
48#ifdef WNT
49Standard_IMPORT Draw_Viewer dout;
50#endif
51
52//=======================================================================
53//function : proj
54//purpose :
55//=======================================================================
56
57static Standard_Integer proj (Draw_Interpretor& di, Standard_Integer n, const char** a)
569aff1e 58 {
32ca7a51 59 if ( n < 5)
60 {
569aff1e 61 cout << " Use proj curve/surf x y z [extrema algo: g(grad)/t(tree)]" << endl;
62 return 1;
32ca7a51 63 }
7fd59977 64
91322f44 65 gp_Pnt P(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4]));
7fd59977 66
67 char name[100];
68
69 Handle(Geom_Curve) GC = DrawTrSurf::GetCurve(a[1]);
70 Handle(Geom_Surface) GS;
569aff1e 71 Extrema_ExtAlgo aProjAlgo = Extrema_ExtAlgo_Grad;
32ca7a51 72
569aff1e 73 if (n == 6 && a[5][0] == 't')
74 aProjAlgo = Extrema_ExtAlgo_Tree;
7fd59977 75
32ca7a51 76 if (GC.IsNull())
77 {
7fd59977 78 GS = DrawTrSurf::GetSurface(a[1]);
32ca7a51 79
7fd59977 80 if (GS.IsNull())
81 return 1;
32ca7a51 82
7fd59977 83 Standard_Real U1, U2, V1, V2;
84 GS->Bounds(U1,U2,V1,V2);
85
569aff1e 86 GeomAPI_ProjectPointOnSurf proj(P,GS,U1,U2,V1,V2,aProjAlgo);
32ca7a51 87
7fd59977 88 Standard_Real UU,VV;
32ca7a51 89 for ( Standard_Integer i = 1; i <= proj.NbPoints(); i++)
90 {
7fd59977 91 gp_Pnt P1 = proj.Point(i);
32ca7a51 92 if ( P.Distance(P1) > Precision::Confusion())
93 {
94 Handle(Geom_Line) L = new Geom_Line(P,gp_Vec(P,P1));
95 Handle(Geom_TrimmedCurve) CT =
96 new Geom_TrimmedCurve(L, 0., P.Distance(P1));
91322f44 97 Sprintf(name,"%s%d","ext_",i);
32ca7a51 98 char* temp = name; // portage WNT
99 DrawTrSurf::Set(temp, CT);
100 di << name << " ";
101 }
102 else
103 {
91322f44 104 Sprintf(name,"%s%d","ext_",i);
32ca7a51 105 di << name << " ";
106 char* temp = name; // portage WNT
107 DrawTrSurf::Set(temp, P1);
108 proj.Parameters(i,UU,VV);
109 di << " Le point est sur la surface." << "\n";
110 di << " Ses parametres sont: UU = " << UU << "\n";
111 di << " VV = " << VV << "\n";
112 }
7fd59977 113 }
114 }
32ca7a51 115 else
116 {
7fd59977 117 GeomAPI_ProjectPointOnCurve proj(P,GC,GC->FirstParameter(),
32ca7a51 118 GC->LastParameter());
119
120 if(proj.NbPoints() == 0)
121 {
122 cout << "No project point was found." << endl;
123 return 0;
124 }
125
126 for ( Standard_Integer i = 1; i <= proj.NbPoints(); i++)
127 {
7fd59977 128 gp_Pnt P1 = proj.Point(i);
129 Standard_Real UU = proj.Parameter(i);
130 di << " parameter " << i << " = " << UU << "\n";
32ca7a51 131 if ( P.Distance(P1) > Precision::Confusion())
132 {
133 Handle(Geom_Line) L = new Geom_Line(P,gp_Vec(P,P1));
134 Handle(Geom_TrimmedCurve) CT =
135 new Geom_TrimmedCurve(L, 0., P.Distance(P1));
91322f44 136 Sprintf(name,"%s%d","ext_",i);
32ca7a51 137 char* temp = name; // portage WNT
138 DrawTrSurf::Set(temp, CT);
139 di << name << " ";
140 }
141 else
142 {
91322f44 143 Sprintf(name,"%s%d","ext_",i);
32ca7a51 144 char* temp = name; // portage WNT
145 DrawTrSurf::Set(temp, P1);
146 di << name << " ";
147 UU = proj.Parameter(i);
148 di << " Le point est sur la courbe." << "\n";
149 di << " Son parametre est U = " << UU << "\n";
150 }
7fd59977 151 }
152 }
32ca7a51 153
7fd59977 154 return 0;
155}
156
157//=======================================================================
158//function : appro
159//purpose :
160//=======================================================================
161
162static Standard_Integer appro(Draw_Interpretor& di, Standard_Integer n, const char** a)
163{
164 if ( n<3) return 1;
165
166 Handle(Geom_Curve) GC;
91322f44 167 Standard_Integer Nb = Draw::Atoi(a[2]);
7fd59977 168
169 TColgp_Array1OfPnt Points(1, Nb);
170
171 Handle(Draw_Marker3D) mark;
172
173 if ( n == 4) {
174 GC = DrawTrSurf::GetCurve(a[3]);
175 if ( GC.IsNull())
176 return 1;
177
178 Standard_Real U, U1, U2;
179 U1 = GC->FirstParameter();
180 U2 = GC->LastParameter();
181 Standard_Real Delta = ( U2 - U1) / (Nb-1);
182 for ( Standard_Integer i = 1 ; i <= Nb; i++) {
183 U = U1 + (i-1) * Delta;
184 Points(i) = GC->Value(U);
185 mark = new Draw_Marker3D( Points(i), Draw_X, Draw_vert);
186 dout << mark;
187 }
188 }
189 else {
190 Standard_Integer id,XX,YY,b;
191 dout.Select(id,XX,YY,b);
192 Standard_Real zoom = dout.Zoom(id);
193
194 Points(1) = gp_Pnt( ((Standard_Real)XX)/zoom,
195 ((Standard_Real)YY)/zoom,
196 0.);
197
198 mark = new Draw_Marker3D( Points(1), Draw_X, Draw_vert);
199
200 dout << mark;
201
202 for (Standard_Integer i = 2; i<=Nb; i++) {
203 dout.Select(id,XX,YY,b);
204 Points(i) = gp_Pnt( ((Standard_Real)XX)/zoom,
205 ((Standard_Real)YY)/zoom,
206 0.);
207 mark = new Draw_Marker3D( Points(i), Draw_X, Draw_vert);
208 dout << mark;
209 }
210 }
211 dout.Flush();
212 Standard_Integer Dmin = 3;
213 Standard_Integer Dmax = 8;
214 Standard_Real Tol3d = 1.e-3;
215
216 Handle(Geom_BSplineCurve) TheCurve;
217 GeomAPI_PointsToBSpline aPointToBSpline(Points,Dmin,Dmax,GeomAbs_C2,Tol3d);
218 TheCurve = aPointToBSpline.Curve();
219
220
221 DrawTrSurf::Set(a[1], TheCurve);
222 di << a[1];
223
224 return 0;
225
226}
227
228
229//=======================================================================
230//function : grilapp
231//purpose :
232//=======================================================================
233
234static Standard_Integer grilapp(Draw_Interpretor& di, Standard_Integer n, const char** a)
235{
236 if ( n < 12) return 1;
237
238 Standard_Integer i,j;
91322f44 239 Standard_Integer Nu = Draw::Atoi(a[2]);
240 Standard_Integer Nv = Draw::Atoi(a[3]);
7fd59977 241 TColStd_Array2OfReal ZPoints (1, Nu, 1, Nv);
242
91322f44 243 Standard_Real X0 = Draw::Atof(a[4]);
244 Standard_Real dX = Draw::Atof(a[5]);
245 Standard_Real Y0 = Draw::Atof(a[6]);
246 Standard_Real dY = Draw::Atof(a[7]);
7fd59977 247
248 Standard_Integer Count = 8;
249 for ( j = 1; j <= Nv; j++) {
250 for ( i = 1; i <= Nu; i++) {
251 if ( Count > n) return 1;
91322f44 252 ZPoints(i,j) = Draw::Atof(a[Count]);
7fd59977 253 Count++;
254 }
255 }
256
257 Handle(Geom_BSplineSurface) S
258 = GeomAPI_PointsToBSplineSurface(ZPoints,X0,dX,Y0,dY);
259 DrawTrSurf::Set(a[1],S);
260
261 di << a[1];
262
263 return 0;
264}
265
266//=======================================================================
267//function : surfapp
268//purpose :
269//=======================================================================
270
271static Standard_Integer surfapp(Draw_Interpretor& di, Standard_Integer n, const char** a)
272{
273 if ( n < 5 ) return 1;
274
275 Standard_Integer i,j;
91322f44 276 Standard_Integer Nu = Draw::Atoi(a[2]);
277 Standard_Integer Nv = Draw::Atoi(a[3]);
7fd59977 278 TColgp_Array2OfPnt Points (1, Nu, 1, Nv);
279
280 if ( n == 5) {
281 Handle(Geom_Surface) Surf = DrawTrSurf::GetSurface(a[4]);
282 if ( Surf.IsNull()) return 1;
283
284 Standard_Real U, V, U1, V1, U2, V2;
285 Surf->Bounds( U1, U2, V1, V2);
286 for ( j = 1; j <= Nv; j++) {
287 V = V1 + (j-1) * (V2-V1) / (Nv-1);
288 for ( i = 1; i <= Nu; i++) {
289 U = U1 + (i-1) * (U2-U1) / (Nu-1);
290 Points(i,j) = Surf->Value(U,V);
291 }
292 }
293 }
294 else if ( n >= 16) {
295 Standard_Integer Count = 4;
296 for ( j = 1; j <= Nv; j++) {
297 for ( i = 1; i <= Nu; i++) {
298 if ( Count > n) return 1;
91322f44 299 Points(i,j) = gp_Pnt(Draw::Atof(a[Count]),Draw::Atof(a[Count+1]),Draw::Atof(a[Count+2]));
7fd59977 300 Count += 3;
301 }
302 }
303 }
304 char name[100];
305 Standard_Integer Count = 1;
306 for ( j = 1; j <= Nv; j++) {
307 for ( i = 1; i <= Nu; i++) {
91322f44 308 Sprintf(name,"point_%d",Count++);
7fd59977 309 char* temp = name; // portage WNT
310 DrawTrSurf::Set(temp,Points(i,j));
311 }
312 }
313
314 Handle(Geom_BSplineSurface) S = GeomAPI_PointsToBSplineSurface(Points);
315 DrawTrSurf::Set(a[1],S);
316 di << a[1];
317
318 return 0;
319}
320
321
322//=======================================================================
323//function : extrema
324//purpose :
325//=======================================================================
326
327static Standard_Integer extrema(Draw_Interpretor& di, Standard_Integer n, const char** a)
328{
329 if ( n<3) return 1;
330
331 Handle(Geom_Curve) GC1, GC2;
332 Handle(Geom_Surface) GS1, GS2;
333
334 Standard_Boolean C1 = Standard_False;
335 Standard_Boolean C2 = Standard_False;
336 Standard_Boolean S1 = Standard_False;
337 Standard_Boolean S2 = Standard_False;
338
339 Standard_Real U1f,U1l,U2f,U2l,V1f,V1l,V2f,V2l;
340
341 GC1 = DrawTrSurf::GetCurve(a[1]);
342 if ( GC1.IsNull()) {
343 GS1 = DrawTrSurf::GetSurface(a[1]);
344 if ( GS1.IsNull())
345 return 1;
346 S1 = Standard_True;
347 GS1->Bounds(U1f,U1l,V1f,V1l);
348 }
349 else {
350 C1 = Standard_True;
351 U1f = GC1->FirstParameter();
352 U1l = GC1->LastParameter();
353 }
354
355 GC2 = DrawTrSurf::GetCurve(a[2]);
356 if ( GC2.IsNull()) {
357 GS2 = DrawTrSurf::GetSurface(a[2]);
358 if ( GS2.IsNull())
359 return 1;
360 S2 = Standard_True;
361 GS2->Bounds(U2f,U2l,V2f,V2l);
362 }
363 else {
364 C2 = Standard_True;
365 U2f = GC2->FirstParameter();
366 U2l = GC2->LastParameter();
367 }
368
369 char name[100];
32ca7a51 370 if ( C1 && C2)
371 {
7fd59977 372 GeomAPI_ExtremaCurveCurve Ex(GC1,GC2,U1f,U1l,U2f,U2l);
32ca7a51 373
374 if(!Ex.Extrema().IsParallel())
375 {
376 const Standard_Integer aNExtr = Ex.NbExtrema();
377 if(aNExtr == 0)
378 {
379 di << "No solutions!\n";
380 }
381 else
382 {
383 for ( Standard_Integer i = 1; i <= aNExtr; i++)
384 {
385 gp_Pnt P1,P2;
386 Ex.Points(i,P1,P2);
387 Standard_Real U1,V1;
388 Ex.Parameters(i,U1,V1);
389 if (P1.Distance(P2) < 1.e-16)
390 {
391 di << "Extrema " << i << " is point : " << P1.X() << " " << P1.Y() << " " << P1.Z() << "\n";
392 continue;
393 }
394
395 Handle(Geom_Line) L = new Geom_Line(P1,gp_Vec(P1,P2));
396 Handle(Geom_TrimmedCurve) CT =
397 new Geom_TrimmedCurve(L, 0., P1.Distance(P2));
398#ifdef DEB
399 Sprintf(name,"%s%d (U=%f; V=%f)","ext_",i,U1,V1);
400#else
401 Sprintf(name,"%s%d","ext_",i);
402#endif
403 char* temp = name; // portage WNT
404 DrawTrSurf::Set(temp, CT);
405 di << name << " ";
406 }
407 }
7fd59977 408 }
32ca7a51 409 else
410 {
7fd59977 411 di << "Infinite number of extremas, distance = " << Ex.LowerDistance() << "\n";
32ca7a51 412 }
7fd59977 413 }
32ca7a51 414 else if ( C1 & S2)
415 {
7fd59977 416 GeomAPI_ExtremaCurveSurface Ex(GC1,GS2,U1f,U1l,U2f,U2l,V2f,V2l);
32ca7a51 417
418 const Standard_Integer aNExtr = Ex.NbExtrema();
419 if(aNExtr == 0)
420 {
421 di << "No solutions!\n";
422 }
423 else
424 {
425 for ( Standard_Integer i = 1; i <= aNExtr; i++)
426 {
427 gp_Pnt P1,P2;
428 Ex.Points(i,P1,P2);
429 if (P1.Distance(P2) < 1.e-16) continue;
430 Handle(Geom_Line) L = new Geom_Line(P1,gp_Vec(P1,P2));
431 Handle(Geom_TrimmedCurve) CT =
432 new Geom_TrimmedCurve(L, 0., P1.Distance(P2));
433 Sprintf(name,"%s%d","ext_",i);
434 char* temp = name; // portage WNT
435 DrawTrSurf::Set(temp, CT);
436 di << name << " ";
437 }
438 }
7fd59977 439 }
32ca7a51 440 else if ( S1 & C2)
441 {
7fd59977 442 GeomAPI_ExtremaCurveSurface Ex(GC2,GS1,U2f,U2l,U1f,U1l,V1f,V1l);
32ca7a51 443
444 const Standard_Integer aNExtr = Ex.NbExtrema();
445 if(aNExtr == 0)
446 {
447 di << "No solutions!\n";
448 }
449 else
450 {
451 for ( Standard_Integer i = 1; i <= aNExtr; i++)
452 {
453 gp_Pnt P1,P2;
454 Ex.Points(i,P1,P2);
455 if (P1.Distance(P2) < 1.e-16) continue;
456 Handle(Geom_Line) L = new Geom_Line(P1,gp_Vec(P1,P2));
457 Handle(Geom_TrimmedCurve) CT =
458 new Geom_TrimmedCurve(L, 0., P1.Distance(P2));
459 Sprintf(name,"%s%d","ext_",i);
460 char* temp = name; // portage WNT
461 DrawTrSurf::Set(temp, CT);
462 di << name << " ";
463 }
464 }
7fd59977 465 }
32ca7a51 466 else if ( S1 & S2)
467 {
7fd59977 468 GeomAPI_ExtremaSurfaceSurface Ex(GS1,GS2,U1f,U1l,V1f,V1l,U2f,U2l,V2f,V2l);
32ca7a51 469
470 const Standard_Integer aNExtr = Ex.NbExtrema();
471 if(aNExtr == 0)
472 {
473 di << "No solutions!\n";
474 }
475 else
476 {
477 for ( Standard_Integer i = 1; i <= aNExtr; i++)
478 {
479 gp_Pnt P1,P2;
480 Ex.Points(i,P1,P2);
481 if (P1.Distance(P2) < 1.e-16)
482 continue;
483
484 Handle(Geom_Line) L = new Geom_Line(P1,gp_Vec(P1,P2));
485 Handle(Geom_TrimmedCurve) CT =
486 new Geom_TrimmedCurve(L, 0., P1.Distance(P2));
487 Sprintf(name,"%s%d","ext_",i);
488 char* temp = name; // portage WNT
489 DrawTrSurf::Set(temp, CT);
490 di << name << " ";
491 }
492 }
7fd59977 493 }
7fd59977 494
495 return 0;
32ca7a51 496 }
7fd59977 497
498//=======================================================================
499//function : totalextcc
500//purpose :
501//=======================================================================
502
503static Standard_Integer totalextcc(Draw_Interpretor& di, Standard_Integer n, const char** a)
504{
505 if ( n<3) return 1;
506
507 Handle(Geom_Curve) GC1, GC2;
508
509
510 Standard_Real U1f,U1l,U2f,U2l;
511
512 GC1 = DrawTrSurf::GetCurve(a[1]);
513 if ( GC1.IsNull()) {
514 return 1;
515 }
516 else {
517 U1f = GC1->FirstParameter();
518 U1l = GC1->LastParameter();
519 }
520
521 GC2 = DrawTrSurf::GetCurve(a[2]);
522 if ( GC2.IsNull()) {
523 return 1;
524 }
525 else {
526 U2f = GC2->FirstParameter();
527 U2l = GC2->LastParameter();
528 }
529
530 char name[100];
531 GeomAPI_ExtremaCurveCurve Ex(GC1,GC2,U1f,U1l,U2f,U2l);
532 gp_Pnt P1,P2;
533 if(Ex.TotalNearestPoints(P1,P2)) {
534 if (P1.Distance(P2) < 1.e-16) {
535 di << "Extrema is point : " << P1.X() << " " << P1.Y() << " " << P1.Z() << "\n";
536 }
537 else {
538 di << "Extrema is segment of line" << "\n";
539 Handle(Geom_Line) L = new Geom_Line(P1,gp_Vec(P1,P2));
540 Handle(Geom_TrimmedCurve) CT =
541 new Geom_TrimmedCurve(L, 0., P1.Distance(P2));
91322f44 542 Sprintf(name,"%s%d","ext_",1);
7fd59977 543 char* temp = name; // portage WNT
544 DrawTrSurf::Set(temp, CT);
545 di << name << " ";
546 }
547
548 Standard_Real u1, u2;
549 Ex.TotalLowerDistanceParameters(u1, u2);
550
551 di << "Parameters on curves : " << u1 << " " << u2 << "\n";
552
553 }
554 else {
555 di << "Curves are infinite and parallel" << "\n";
556 }
557
558 di << "Minimal distance : " << Ex.TotalLowerDistance() << "\n";
559
560 return 0;
561
562}
563
564
565void GeometryTest::APICommands(Draw_Interpretor& theCommands)
566{
567 static Standard_Boolean done = Standard_False;
568 if (done) return;
569
570 done = Standard_True;
571 const char* g;
572
573 g = "GEOMETRY curves and surfaces analysis";
574
569aff1e 575 theCommands.Add("proj", "proj curve/surf x y z [extrema algo: g(grad)/t(tree)]",__FILE__, proj);
7fd59977 576
577 g = "GEOMETRY approximations";
578
579 theCommands.Add("appro", "appro result nbpoint [curve]",__FILE__, appro);
580 theCommands.Add("surfapp","surfapp result nbupoint nbvpoint x y z ....",
581 __FILE__,
582 surfapp);
583 theCommands.Add("grilapp",
584 "grilapp result nbupoint nbvpoint X0 dX Y0 dY z11 z12 .. z1nu .... ",
585 __FILE__,grilapp);
586
587 g = "GEOMETRY curves and surfaces analysis";
588
589 theCommands.Add("extrema", "extrema curve/surface curve/surface",__FILE__,extrema);
590 theCommands.Add("totalextcc", "totalextcc curve curve",__FILE__,totalextcc);
591}