1 // Created on: 1995-01-17
2 // Created by: Remi LEQUETTE
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <Geom_BSplineCurve.hxx>
18 #include <Geom_BSplineSurface.hxx>
20 #include <Draw_Interpretor.hxx>
21 #include <DrawTrSurf.hxx>
22 #include <Draw_Appli.hxx>
23 #include <GeometryTest.hxx>
24 #include <GeomAPI_ProjectPointOnCurve.hxx>
25 #include <GeomAPI_ProjectPointOnSurf.hxx>
26 #include <Extrema_GenLocateExtPS.hxx>
27 #include <GeomAPI_ExtremaCurveCurve.hxx>
28 #include <GeomAPI_ExtremaCurveSurface.hxx>
29 #include <GeomAPI_ExtremaSurfaceSurface.hxx>
30 #include <GeomAPI_PointsToBSpline.hxx>
31 #include <GeomAPI_PointsToBSplineSurface.hxx>
32 #include <Geom_Line.hxx>
33 #include <Geom_TrimmedCurve.hxx>
34 #include <Draw_Segment3D.hxx>
35 #include <Draw_Marker3D.hxx>
36 #include <Draw_Color.hxx>
37 #include <Draw_MarkerShape.hxx>
38 #include <TColgp_Array1OfPnt.hxx>
39 #include <TColgp_Array2OfPnt.hxx>
40 #include <TColStd_Array2OfReal.hxx>
41 #include <Precision.hxx>
45 Standard_IMPORT Draw_Viewer dout;
48 //=======================================================================
51 //=======================================================================
53 static void showProjSolution(Draw_Interpretor& di,
54 const Standard_Integer i,
55 const gp_Pnt& P, const gp_Pnt& P1,
56 const Standard_Real U, const Standard_Real V,
57 const Standard_Boolean isSurface)
60 Sprintf(name, "%s%d", "ext_", i);
62 char* temp = name; // portage WNT
63 if (P.Distance(P1) > Precision::Confusion())
65 Handle(Geom_Line) L = new Geom_Line(P, gp_Vec(P, P1));
66 Handle(Geom_TrimmedCurve) CT =
67 new Geom_TrimmedCurve(L, 0., P.Distance(P1));
68 DrawTrSurf::Set(temp, CT);
72 DrawTrSurf::Set(temp, P1);
74 di << " Point on surface ";
76 di << " Point on curve ";
79 di << " Parameters: " << U << " " << V << "\n";
81 di << " parameter " << i << " = " << U << "\n";
84 //=======================================================================
87 //=======================================================================
89 static Standard_Integer proj (Draw_Interpretor& di, Standard_Integer n, const char** a)
93 cout << " Use proj curve/surf x y z [{extrema algo: g(grad)/t(tree)}|{u v}]" << endl;
97 gp_Pnt P(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4]));
99 Handle(Geom_Curve) GC = DrawTrSurf::GetCurve(a[1]);
100 Handle(Geom_Surface) GS;
101 Extrema_ExtAlgo aProjAlgo = Extrema_ExtAlgo_Grad;
103 if (n == 6 && a[5][0] == 't')
104 aProjAlgo = Extrema_ExtAlgo_Tree;
108 GS = DrawTrSurf::GetSurface(a[1]);
115 Standard_Real U1, U2, V1, V2;
116 GS->Bounds(U1,U2,V1,V2);
118 GeomAPI_ProjectPointOnSurf proj(P,GS,U1,U2,V1,V2,aProjAlgo);
121 di << "projection failed.";
126 for ( Standard_Integer i = 1; i <= proj.NbPoints(); i++)
128 gp_Pnt P1 = proj.Point(i);
129 proj.Parameters(i, UU, VV);
130 showProjSolution(di, i, P, P1, UU, VV, Standard_True);
135 const gp_XY aP2d(Draw::Atof(a[5]), Draw::Atof(a[6]));
136 GeomAdaptor_Surface aGAS(GS);
137 Extrema_GenLocateExtPS aProjector(aGAS, Precision::PConfusion(), Precision::PConfusion());
138 aProjector.Perform(P, aP2d.X(), aP2d.Y());
139 if (!aProjector.IsDone())
141 di << "projection failed.";
145 const Extrema_POnSurf& aP = aProjector.Point();
146 Standard_Real UU, VV;
147 aP.Parameter(UU, VV);
148 showProjSolution(di, 1, P, aP.Value(), UU, VV, Standard_True);
153 GeomAPI_ProjectPointOnCurve proj(P,GC,GC->FirstParameter(),
154 GC->LastParameter());
156 if(proj.NbPoints() == 0)
158 cout << "No project point was found." << endl;
162 for ( Standard_Integer i = 1; i <= proj.NbPoints(); i++)
164 gp_Pnt P1 = proj.Point(i);
165 Standard_Real UU = proj.Parameter(i);
166 showProjSolution(di, i, P, P1, UU, UU, Standard_False);
173 //=======================================================================
176 //=======================================================================
178 static Standard_Integer appro(Draw_Interpretor& di, Standard_Integer n, const char** a)
182 Handle(Geom_Curve) GC;
183 Standard_Integer Nb = Draw::Atoi(a[2]);
185 TColgp_Array1OfPnt Points(1, Nb);
187 Handle(Draw_Marker3D) mark;
190 GC = DrawTrSurf::GetCurve(a[3]);
194 Standard_Real U, U1, U2;
195 U1 = GC->FirstParameter();
196 U2 = GC->LastParameter();
197 Standard_Real Delta = ( U2 - U1) / (Nb-1);
198 for ( Standard_Integer i = 1 ; i <= Nb; i++) {
199 U = U1 + (i-1) * Delta;
200 Points(i) = GC->Value(U);
201 mark = new Draw_Marker3D( Points(i), Draw_X, Draw_vert);
206 Standard_Integer id,XX,YY,b;
207 dout.Select(id,XX,YY,b);
208 Standard_Real zoom = dout.Zoom(id);
210 Points(1) = gp_Pnt( ((Standard_Real)XX)/zoom,
211 ((Standard_Real)YY)/zoom,
214 mark = new Draw_Marker3D( Points(1), Draw_X, Draw_vert);
218 for (Standard_Integer i = 2; i<=Nb; i++) {
219 dout.Select(id,XX,YY,b);
220 Points(i) = gp_Pnt( ((Standard_Real)XX)/zoom,
221 ((Standard_Real)YY)/zoom,
223 mark = new Draw_Marker3D( Points(i), Draw_X, Draw_vert);
228 Standard_Integer Dmin = 3;
229 Standard_Integer Dmax = 8;
230 Standard_Real Tol3d = 1.e-3;
232 Handle(Geom_BSplineCurve) TheCurve;
233 GeomAPI_PointsToBSpline aPointToBSpline(Points,Dmin,Dmax,GeomAbs_C2,Tol3d);
234 TheCurve = aPointToBSpline.Curve();
237 DrawTrSurf::Set(a[1], TheCurve);
245 //=======================================================================
248 //=======================================================================
250 static Standard_Integer grilapp(Draw_Interpretor& di, Standard_Integer n, const char** a)
252 if ( n < 12) return 1;
254 Standard_Integer i,j;
255 Standard_Integer Nu = Draw::Atoi(a[2]);
256 Standard_Integer Nv = Draw::Atoi(a[3]);
257 TColStd_Array2OfReal ZPoints (1, Nu, 1, Nv);
259 Standard_Real X0 = Draw::Atof(a[4]);
260 Standard_Real dX = Draw::Atof(a[5]);
261 Standard_Real Y0 = Draw::Atof(a[6]);
262 Standard_Real dY = Draw::Atof(a[7]);
264 Standard_Integer Count = 8;
265 for ( j = 1; j <= Nv; j++) {
266 for ( i = 1; i <= Nu; i++) {
267 if ( Count > n) return 1;
268 ZPoints(i,j) = Draw::Atof(a[Count]);
273 Handle(Geom_BSplineSurface) S
274 = GeomAPI_PointsToBSplineSurface(ZPoints,X0,dX,Y0,dY);
275 DrawTrSurf::Set(a[1],S);
282 //=======================================================================
285 //=======================================================================
287 static Standard_Integer surfapp(Draw_Interpretor& di, Standard_Integer n, const char** a)
289 if ( n < 5 ) return 1;
291 Standard_Integer i,j;
292 Standard_Integer Nu = Draw::Atoi(a[2]);
293 Standard_Integer Nv = Draw::Atoi(a[3]);
294 TColgp_Array2OfPnt Points (1, Nu, 1, Nv);
297 Handle(Geom_Surface) Surf = DrawTrSurf::GetSurface(a[4]);
298 if ( Surf.IsNull()) return 1;
300 Standard_Real U, V, U1, V1, U2, V2;
301 Surf->Bounds( U1, U2, V1, V2);
302 for ( j = 1; j <= Nv; j++) {
303 V = V1 + (j-1) * (V2-V1) / (Nv-1);
304 for ( i = 1; i <= Nu; i++) {
305 U = U1 + (i-1) * (U2-U1) / (Nu-1);
306 Points(i,j) = Surf->Value(U,V);
311 Standard_Integer Count = 4;
312 for ( j = 1; j <= Nv; j++) {
313 for ( i = 1; i <= Nu; i++) {
314 if ( Count > n) return 1;
315 Points(i,j) = gp_Pnt(Draw::Atof(a[Count]),Draw::Atof(a[Count+1]),Draw::Atof(a[Count+2]));
321 Standard_Integer Count = 1;
322 for ( j = 1; j <= Nv; j++) {
323 for ( i = 1; i <= Nu; i++) {
324 Sprintf(name,"point_%d",Count++);
325 char* temp = name; // portage WNT
326 DrawTrSurf::Set(temp,Points(i,j));
330 Handle(Geom_BSplineSurface) S = GeomAPI_PointsToBSplineSurface(Points);
331 DrawTrSurf::Set(a[1],S);
338 //=======================================================================
341 //=======================================================================
343 static Standard_Integer extrema(Draw_Interpretor& di, Standard_Integer n, const char** a)
350 Handle(Geom_Curve) GC1, GC2;
351 Handle(Geom_Surface) GS1, GS2;
353 Standard_Boolean C1 = Standard_False;
354 Standard_Boolean C2 = Standard_False;
355 Standard_Boolean S1 = Standard_False;
356 Standard_Boolean S2 = Standard_False;
357 Standard_Boolean isInfinitySolutions = Standard_False;
358 Standard_Real aMinDist = RealLast();
360 Standard_Real U1f, U1l, U2f, U2l, V1f = 0., V1l = 0., V2f = 0., V2l = 0.;
362 GC1 = DrawTrSurf::GetCurve(a[1]);
364 GS1 = DrawTrSurf::GetSurface(a[1]);
368 GS1->Bounds(U1f,U1l,V1f,V1l);
372 U1f = GC1->FirstParameter();
373 U1l = GC1->LastParameter();
376 GC2 = DrawTrSurf::GetCurve(a[2]);
378 GS2 = DrawTrSurf::GetSurface(a[2]);
382 GS2->Bounds(U2f,U2l,V2f,V2l);
386 U2f = GC2->FirstParameter();
387 U2l = GC2->LastParameter();
390 NCollection_Vector<gp_Pnt> aPnts1, aPnts2;
391 NCollection_Vector<Standard_Real> aPrms[4];
394 GeomAPI_ExtremaCurveCurve Ex(GC1, GC2, U1f, U1l, U2f, U2l);
396 for (Standard_Integer aJ = 1; aJ <= Ex.NbExtrema(); ++aJ)
399 Ex.Points(aJ, aP1, aP2);
403 Standard_Real aU1, aU2;
404 Ex.Parameters(aJ, aU1, aU2);
405 aPrms[0].Append(aU1);
406 aPrms[2].Append(aU2);
408 // Since GeomAPI cannot provide access to flag directly.
409 isInfinitySolutions = Ex.Extrema().IsParallel();
410 if (isInfinitySolutions)
411 aMinDist = Ex.LowerDistance();
415 GeomAPI_ExtremaCurveSurface Ex(GC1, GS2, U1f, U1l, U2f, U2l, V2f, V2l);
416 for (Standard_Integer aJ = 1; aJ <= Ex.NbExtrema(); ++aJ)
419 Ex.Points(aJ, aP1, aP2);
423 Standard_Real aU1, aU2, aV2;
424 Ex.Parameters(aJ, aU1, aU2, aV2);
425 aPrms[0].Append(aU1);
426 aPrms[2].Append(aU2);
427 aPrms[3].Append(aV2);
429 isInfinitySolutions = Ex.Extrema().IsParallel();
430 if (isInfinitySolutions)
431 aMinDist = Ex.LowerDistance();
435 GeomAPI_ExtremaCurveSurface Ex(GC2, GS1, U2f, U2l, U1f, U1l, V1f, V1l);
436 for (Standard_Integer aJ = 1; aJ <= Ex.NbExtrema(); ++aJ)
439 Ex.Points(aJ, aP2, aP1);
443 Standard_Real aU1, aV1, aU2;
444 Ex.Parameters(aJ, aU2, aU1, aV1);
445 aPrms[0].Append(aU1);
446 aPrms[1].Append(aV1);
447 aPrms[2].Append(aU2);
449 isInfinitySolutions = Ex.Extrema().IsParallel();
450 if (isInfinitySolutions)
451 aMinDist = Ex.LowerDistance();
455 GeomAPI_ExtremaSurfaceSurface Ex(
456 GS1, GS2, U1f, U1l, V1f, V1l, U2f, U2l, V2f, V2l);
457 for (Standard_Integer aJ = 1; aJ <= Ex.NbExtrema(); ++aJ)
460 Ex.Points(aJ, aP1, aP2);
464 Standard_Real aU1, aV1, aU2, aV2;
465 Ex.Parameters(aJ, aU1, aV1, aU2, aV2);
466 aPrms[0].Append(aU1);
467 aPrms[1].Append(aV1);
468 aPrms[2].Append(aU2);
469 aPrms[3].Append(aV2);
474 char* aName2 = aName; // portage WNT
477 const Standard_Integer aPntCount = aPnts1.Size();
478 if (aPntCount == 0 || isInfinitySolutions)
480 // Infinity solutions flag may be set with 0 number of
481 // solutions in analytic extrema Curve/Curve.
482 if (isInfinitySolutions)
483 di << "Infinite number of extremas, distance = " << aMinDist << "\n";
485 di << "No solutions!\n";
487 for (Standard_Integer aJ = 1; aJ <= aPntCount; aJ++)
489 gp_Pnt aP1 = aPnts1(aJ - 1), aP2 = aPnts2(aJ - 1);
491 if (aP1.Distance(aP2) < 1.e-16)
493 di << "Extrema " << aJ << " is point : " <<
494 aP1.X() << " " << aP1.Y() << " " << aP1.Z() << "\n";
498 Handle(Geom_Line) aL = new Geom_Line(aP1, gp_Vec(aP1, aP2));
499 Handle(Geom_TrimmedCurve) aCT =
500 new Geom_TrimmedCurve(aL, 0., aP1.Distance(aP2));
501 Sprintf(aName, "%s%d", "ext_", aJ);
502 DrawTrSurf::Set(aName2, aCT);
509 for (Standard_Integer aJ = 1; aJ <= aPntCount; aJ++)
511 gp_Pnt aP1 = aPnts1(aJ - 1), aP2 = aPnts2(aJ - 1);
512 Sprintf(aName, "%s%d%s", "ext_", aJ, "_2");
513 DrawTrSurf::Set(aName2, aP1);
515 Sprintf(aName, "%s%d%s", "ext_", aJ, "_3");
516 DrawTrSurf::Set(aName2, aP2);
520 // Output parameters.
521 for (Standard_Integer aJ = 0; aJ < 4; ++aJ)
523 for (Standard_Integer aPrmCount = aPrms[aJ].Size(), aK = 0;
524 aK < aPrmCount; ++aK)
526 Standard_Real aP = aPrms[aJ](aK);
527 Sprintf(aName, "%s%d%s%d", "prm_", aJ + 1, "_", aK + 1);
528 Draw::Set(aName2, aP);
537 //=======================================================================
538 //function : totalextcc
540 //=======================================================================
542 static Standard_Integer totalextcc(Draw_Interpretor& di, Standard_Integer n, const char** a)
546 Handle(Geom_Curve) GC1, GC2;
549 Standard_Real U1f,U1l,U2f,U2l;
551 GC1 = DrawTrSurf::GetCurve(a[1]);
556 U1f = GC1->FirstParameter();
557 U1l = GC1->LastParameter();
560 GC2 = DrawTrSurf::GetCurve(a[2]);
565 U2f = GC2->FirstParameter();
566 U2l = GC2->LastParameter();
570 GeomAPI_ExtremaCurveCurve Ex(GC1,GC2,U1f,U1l,U2f,U2l);
572 if(Ex.TotalNearestPoints(P1,P2)) {
573 if (P1.Distance(P2) < 1.e-16) {
574 di << "Extrema is point : " << P1.X() << " " << P1.Y() << " " << P1.Z() << "\n";
577 di << "Extrema is segment of line\n";
578 Handle(Geom_Line) L = new Geom_Line(P1,gp_Vec(P1,P2));
579 Handle(Geom_TrimmedCurve) CT =
580 new Geom_TrimmedCurve(L, 0., P1.Distance(P2));
581 Sprintf(name,"%s%d","ext_",1);
582 char* temp = name; // portage WNT
583 DrawTrSurf::Set(temp, CT);
587 Standard_Real u1, u2;
588 Ex.TotalLowerDistanceParameters(u1, u2);
590 di << "Parameters on curves : " << u1 << " " << u2 << "\n";
594 di << "Curves are infinite and parallel\n";
597 di << "Minimal distance : " << Ex.TotalLowerDistance() << "\n";
604 void GeometryTest::APICommands(Draw_Interpretor& theCommands)
606 static Standard_Boolean done = Standard_False;
609 done = Standard_True;
611 theCommands.Add("proj", "proj curve/surf x y z [{extrema algo: g(grad)/t(tree)}|{u v}]\n"
612 "\t\tOptional parameters are relevant to surf only.\n"
613 "\t\tIf initial {u v} are given then local extrema is called",__FILE__, proj);
615 theCommands.Add("appro", "appro result nbpoint [curve]",__FILE__, appro);
616 theCommands.Add("surfapp","surfapp result nbupoint nbvpoint x y z ....",
619 theCommands.Add("grilapp",
620 "grilapp result nbupoint nbvpoint X0 dX Y0 dY z11 z12 .. z1nu .... ",
623 theCommands.Add("extrema", "extrema curve/surface curve/surface [extended_output = 0|1]",__FILE__,extrema);
624 theCommands.Add("totalextcc", "totalextcc curve curve",__FILE__,totalextcc);