mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-04 18:06:22 +03:00
1. Extrema algorithm calls Curve-surface intersector. This intersector returns flag about infinite solution (in spite of extrema's returning not-parallel status correctly - axes of considered cylinder and circle are not parallel). In this case, attempt of obtaining number of intersection points leads to exception. So, the fix adds check of infinite solution after the intersection algorithm. 2. The methods IsDone(), IsParallel(), NbExt(), SquareDistance() and Points() (of Extrema_* classes) have been corrected to make them consistent to the documentation. 3. Revision of some Extrema_* classes has been made in order to avoid places with uninitialized variables. 4. Currently Extrema does not store any points in case when the arguments are parallel. It stores the distance only. 5. Some cases on Extrema-algo have been moved from "fclasses"-group to "modalg"-group.
644 lines
17 KiB
C++
644 lines
17 KiB
C++
// Created on: 1995-01-17
|
|
// Created by: Remi LEQUETTE
|
|
// Copyright (c) 1995-1999 Matra Datavision
|
|
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
|
//
|
|
// This file is part of Open CASCADE Technology software library.
|
|
//
|
|
// This library is free software; you can redistribute it and/or modify it under
|
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
|
// by the Free Software Foundation, with special exception defined in the file
|
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
// distribution for complete text of the license and disclaimer of any warranty.
|
|
//
|
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
// commercial license or contractual agreement.
|
|
|
|
#include <Geom_BSplineCurve.hxx>
|
|
#include <Geom_BSplineSurface.hxx>
|
|
#include <Draw.hxx>
|
|
#include <Draw_Interpretor.hxx>
|
|
#include <DrawTrSurf.hxx>
|
|
#include <Draw_Appli.hxx>
|
|
#include <GeometryTest.hxx>
|
|
#include <GeomAPI_ProjectPointOnCurve.hxx>
|
|
#include <GeomAPI_ProjectPointOnSurf.hxx>
|
|
#include <Extrema_GenLocateExtPS.hxx>
|
|
#include <GeomAPI_ExtremaCurveCurve.hxx>
|
|
#include <GeomAPI_ExtremaCurveSurface.hxx>
|
|
#include <GeomAPI_ExtremaSurfaceSurface.hxx>
|
|
#include <GeomAPI_PointsToBSpline.hxx>
|
|
#include <GeomAPI_PointsToBSplineSurface.hxx>
|
|
#include <Geom_Line.hxx>
|
|
#include <Geom_TrimmedCurve.hxx>
|
|
#include <Draw_Segment3D.hxx>
|
|
#include <Draw_Marker3D.hxx>
|
|
#include <Draw_Color.hxx>
|
|
#include <Draw_MarkerShape.hxx>
|
|
#include <TColgp_Array1OfPnt.hxx>
|
|
#include <TColgp_Array2OfPnt.hxx>
|
|
#include <TColStd_Array2OfReal.hxx>
|
|
#include <Precision.hxx>
|
|
#include <stdio.h>
|
|
|
|
#ifdef _WIN32
|
|
Standard_IMPORT Draw_Viewer dout;
|
|
#endif
|
|
|
|
//=======================================================================
|
|
//function : proj
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
static void showProjSolution(Draw_Interpretor& di,
|
|
const Standard_Integer i,
|
|
const gp_Pnt& P, const gp_Pnt& P1,
|
|
const Standard_Real U, const Standard_Real V,
|
|
const Standard_Boolean isSurface)
|
|
{
|
|
char name[100];
|
|
Sprintf(name, "%s%d", "ext_", i);
|
|
di << name << " ";
|
|
char* temp = name; // portage WNT
|
|
if (P.Distance(P1) > Precision::Confusion())
|
|
{
|
|
Handle(Geom_Line) L = new Geom_Line(P, gp_Vec(P, P1));
|
|
Handle(Geom_TrimmedCurve) CT =
|
|
new Geom_TrimmedCurve(L, 0., P.Distance(P1));
|
|
DrawTrSurf::Set(temp, CT);
|
|
}
|
|
else
|
|
{
|
|
DrawTrSurf::Set(temp, P1);
|
|
if (isSurface)
|
|
di << " Point on surface ";
|
|
else
|
|
di << " Point on curve ";
|
|
}
|
|
if (isSurface)
|
|
di << " Parameters: " << U << " " << V << "\n";
|
|
else
|
|
di << " parameter " << i << " = " << U << "\n";
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : proj
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
static Standard_Integer proj (Draw_Interpretor& di, Standard_Integer n, const char** a)
|
|
{
|
|
if ( n < 5)
|
|
{
|
|
cout << " Use proj curve/surf x y z [{extrema algo: g(grad)/t(tree)}|{u v}]" << endl;
|
|
return 1;
|
|
}
|
|
|
|
gp_Pnt P(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4]));
|
|
|
|
Handle(Geom_Curve) GC = DrawTrSurf::GetCurve(a[1]);
|
|
Handle(Geom_Surface) GS;
|
|
Extrema_ExtAlgo aProjAlgo = Extrema_ExtAlgo_Grad;
|
|
|
|
if (n == 6 && a[5][0] == 't')
|
|
aProjAlgo = Extrema_ExtAlgo_Tree;
|
|
|
|
if (GC.IsNull())
|
|
{
|
|
GS = DrawTrSurf::GetSurface(a[1]);
|
|
|
|
if (GS.IsNull())
|
|
return 1;
|
|
|
|
if (n <= 6)
|
|
{
|
|
Standard_Real U1, U2, V1, V2;
|
|
GS->Bounds(U1,U2,V1,V2);
|
|
|
|
GeomAPI_ProjectPointOnSurf proj(P,GS,U1,U2,V1,V2,aProjAlgo);
|
|
if (!proj.IsDone())
|
|
{
|
|
di << "projection failed.";
|
|
return 0;
|
|
}
|
|
|
|
Standard_Real UU,VV;
|
|
for ( Standard_Integer i = 1; i <= proj.NbPoints(); i++)
|
|
{
|
|
gp_Pnt P1 = proj.Point(i);
|
|
proj.Parameters(i, UU, VV);
|
|
showProjSolution(di, i, P, P1, UU, VV, Standard_True);
|
|
}
|
|
}
|
|
else if (n == 7)
|
|
{
|
|
const gp_XY aP2d(Draw::Atof(a[5]), Draw::Atof(a[6]));
|
|
GeomAdaptor_Surface aGAS(GS);
|
|
Extrema_GenLocateExtPS aProjector(aGAS, Precision::PConfusion(), Precision::PConfusion());
|
|
aProjector.Perform(P, aP2d.X(), aP2d.Y());
|
|
if (!aProjector.IsDone())
|
|
{
|
|
di << "projection failed.";
|
|
return 0;
|
|
}
|
|
|
|
const Extrema_POnSurf& aP = aProjector.Point();
|
|
Standard_Real UU, VV;
|
|
aP.Parameter(UU, VV);
|
|
showProjSolution(di, 1, P, aP.Value(), UU, VV, Standard_True);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
GeomAPI_ProjectPointOnCurve proj(P,GC,GC->FirstParameter(),
|
|
GC->LastParameter());
|
|
|
|
if(proj.NbPoints() == 0)
|
|
{
|
|
cout << "No project point was found." << endl;
|
|
return 0;
|
|
}
|
|
|
|
for ( Standard_Integer i = 1; i <= proj.NbPoints(); i++)
|
|
{
|
|
gp_Pnt P1 = proj.Point(i);
|
|
Standard_Real UU = proj.Parameter(i);
|
|
showProjSolution(di, i, P, P1, UU, UU, Standard_False);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : appro
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
static Standard_Integer appro(Draw_Interpretor& di, Standard_Integer n, const char** a)
|
|
{
|
|
if ( n<3) return 1;
|
|
|
|
Handle(Geom_Curve) GC;
|
|
Standard_Integer Nb = Draw::Atoi(a[2]);
|
|
|
|
TColgp_Array1OfPnt Points(1, Nb);
|
|
|
|
Handle(Draw_Marker3D) mark;
|
|
|
|
if ( n == 4) {
|
|
GC = DrawTrSurf::GetCurve(a[3]);
|
|
if ( GC.IsNull())
|
|
return 1;
|
|
|
|
Standard_Real U, U1, U2;
|
|
U1 = GC->FirstParameter();
|
|
U2 = GC->LastParameter();
|
|
Standard_Real Delta = ( U2 - U1) / (Nb-1);
|
|
for ( Standard_Integer i = 1 ; i <= Nb; i++) {
|
|
U = U1 + (i-1) * Delta;
|
|
Points(i) = GC->Value(U);
|
|
mark = new Draw_Marker3D( Points(i), Draw_X, Draw_vert);
|
|
dout << mark;
|
|
}
|
|
}
|
|
else {
|
|
Standard_Integer id,XX,YY,b;
|
|
dout.Select(id,XX,YY,b);
|
|
Standard_Real zoom = dout.Zoom(id);
|
|
|
|
Points(1) = gp_Pnt( ((Standard_Real)XX)/zoom,
|
|
((Standard_Real)YY)/zoom,
|
|
0.);
|
|
|
|
mark = new Draw_Marker3D( Points(1), Draw_X, Draw_vert);
|
|
|
|
dout << mark;
|
|
|
|
for (Standard_Integer i = 2; i<=Nb; i++) {
|
|
dout.Select(id,XX,YY,b);
|
|
Points(i) = gp_Pnt( ((Standard_Real)XX)/zoom,
|
|
((Standard_Real)YY)/zoom,
|
|
0.);
|
|
mark = new Draw_Marker3D( Points(i), Draw_X, Draw_vert);
|
|
dout << mark;
|
|
}
|
|
}
|
|
dout.Flush();
|
|
Standard_Integer Dmin = 3;
|
|
Standard_Integer Dmax = 8;
|
|
Standard_Real Tol3d = 1.e-3;
|
|
|
|
Handle(Geom_BSplineCurve) TheCurve;
|
|
GeomAPI_PointsToBSpline aPointToBSpline(Points,Dmin,Dmax,GeomAbs_C2,Tol3d);
|
|
TheCurve = aPointToBSpline.Curve();
|
|
|
|
|
|
DrawTrSurf::Set(a[1], TheCurve);
|
|
di << a[1];
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : grilapp
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
static Standard_Integer grilapp(Draw_Interpretor& di, Standard_Integer n, const char** a)
|
|
{
|
|
if ( n < 12) return 1;
|
|
|
|
Standard_Integer i,j;
|
|
Standard_Integer Nu = Draw::Atoi(a[2]);
|
|
Standard_Integer Nv = Draw::Atoi(a[3]);
|
|
TColStd_Array2OfReal ZPoints (1, Nu, 1, Nv);
|
|
|
|
Standard_Real X0 = Draw::Atof(a[4]);
|
|
Standard_Real dX = Draw::Atof(a[5]);
|
|
Standard_Real Y0 = Draw::Atof(a[6]);
|
|
Standard_Real dY = Draw::Atof(a[7]);
|
|
|
|
Standard_Integer Count = 8;
|
|
for ( j = 1; j <= Nv; j++) {
|
|
for ( i = 1; i <= Nu; i++) {
|
|
if ( Count > n) return 1;
|
|
ZPoints(i,j) = Draw::Atof(a[Count]);
|
|
Count++;
|
|
}
|
|
}
|
|
|
|
Handle(Geom_BSplineSurface) S
|
|
= GeomAPI_PointsToBSplineSurface(ZPoints,X0,dX,Y0,dY);
|
|
DrawTrSurf::Set(a[1],S);
|
|
|
|
di << a[1];
|
|
|
|
return 0;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : surfapp
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
static Standard_Integer surfapp(Draw_Interpretor& di, Standard_Integer n, const char** a)
|
|
{
|
|
if ( n < 5 ) return 1;
|
|
|
|
Standard_Integer i,j;
|
|
Standard_Integer Nu = Draw::Atoi(a[2]);
|
|
Standard_Integer Nv = Draw::Atoi(a[3]);
|
|
TColgp_Array2OfPnt Points (1, Nu, 1, Nv);
|
|
|
|
if ( n == 5) {
|
|
Handle(Geom_Surface) Surf = DrawTrSurf::GetSurface(a[4]);
|
|
if ( Surf.IsNull()) return 1;
|
|
|
|
Standard_Real U, V, U1, V1, U2, V2;
|
|
Surf->Bounds( U1, U2, V1, V2);
|
|
for ( j = 1; j <= Nv; j++) {
|
|
V = V1 + (j-1) * (V2-V1) / (Nv-1);
|
|
for ( i = 1; i <= Nu; i++) {
|
|
U = U1 + (i-1) * (U2-U1) / (Nu-1);
|
|
Points(i,j) = Surf->Value(U,V);
|
|
}
|
|
}
|
|
}
|
|
else if ( n >= 16) {
|
|
Standard_Integer Count = 4;
|
|
for ( j = 1; j <= Nv; j++) {
|
|
for ( i = 1; i <= Nu; i++) {
|
|
if ( Count > n) return 1;
|
|
Points(i,j) = gp_Pnt(Draw::Atof(a[Count]),Draw::Atof(a[Count+1]),Draw::Atof(a[Count+2]));
|
|
Count += 3;
|
|
}
|
|
}
|
|
}
|
|
char name[100];
|
|
Standard_Integer Count = 1;
|
|
for ( j = 1; j <= Nv; j++) {
|
|
for ( i = 1; i <= Nu; i++) {
|
|
Sprintf(name,"point_%d",Count++);
|
|
char* temp = name; // portage WNT
|
|
DrawTrSurf::Set(temp,Points(i,j));
|
|
}
|
|
}
|
|
|
|
Handle(Geom_BSplineSurface) S = GeomAPI_PointsToBSplineSurface(Points);
|
|
DrawTrSurf::Set(a[1],S);
|
|
di << a[1];
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : extrema
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
static Standard_Integer extrema(Draw_Interpretor& di, Standard_Integer n, const char** a)
|
|
{
|
|
if (n < 3)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
Handle(Geom_Curve) GC1, GC2;
|
|
Handle(Geom_Surface) GS1, GS2;
|
|
|
|
Standard_Boolean isInfinitySolutions = Standard_False;
|
|
Standard_Real aMinDist = RealLast();
|
|
|
|
Standard_Real U1f, U1l, U2f, U2l, V1f = 0., V1l = 0., V2f = 0., V2l = 0.;
|
|
|
|
GC1 = DrawTrSurf::GetCurve(a[1]);
|
|
if ( GC1.IsNull()) {
|
|
GS1 = DrawTrSurf::GetSurface(a[1]);
|
|
if ( GS1.IsNull())
|
|
return 1;
|
|
|
|
GS1->Bounds(U1f,U1l,V1f,V1l);
|
|
}
|
|
else {
|
|
U1f = GC1->FirstParameter();
|
|
U1l = GC1->LastParameter();
|
|
}
|
|
|
|
GC2 = DrawTrSurf::GetCurve(a[2]);
|
|
if ( GC2.IsNull()) {
|
|
GS2 = DrawTrSurf::GetSurface(a[2]);
|
|
if ( GS2.IsNull())
|
|
return 1;
|
|
GS2->Bounds(U2f,U2l,V2f,V2l);
|
|
}
|
|
else {
|
|
U2f = GC2->FirstParameter();
|
|
U2l = GC2->LastParameter();
|
|
}
|
|
|
|
NCollection_Vector<gp_Pnt> aPnts1, aPnts2;
|
|
NCollection_Vector<Standard_Real> aPrms[4];
|
|
if (!GC1.IsNull() && !GC2.IsNull())
|
|
{
|
|
GeomAPI_ExtremaCurveCurve Ex(GC1, GC2, U1f, U1l, U2f, U2l);
|
|
|
|
// Since GeomAPI cannot provide access to flag directly.
|
|
isInfinitySolutions = Ex.Extrema().IsParallel();
|
|
if (isInfinitySolutions)
|
|
{
|
|
aMinDist = Ex.LowerDistance();
|
|
}
|
|
else
|
|
{
|
|
for (Standard_Integer aJ = 1; aJ <= Ex.NbExtrema(); ++aJ)
|
|
{
|
|
gp_Pnt aP1, aP2;
|
|
Ex.Points(aJ, aP1, aP2);
|
|
aPnts1.Append(aP1);
|
|
aPnts2.Append(aP2);
|
|
|
|
Standard_Real aU1, aU2;
|
|
Ex.Parameters(aJ, aU1, aU2);
|
|
aPrms[0].Append(aU1);
|
|
aPrms[2].Append(aU2);
|
|
}
|
|
}
|
|
}
|
|
else if (!GC1.IsNull() && !GS2.IsNull())
|
|
{
|
|
GeomAPI_ExtremaCurveSurface Ex(GC1, GS2, U1f, U1l, U2f, U2l, V2f, V2l);
|
|
|
|
isInfinitySolutions = Ex.Extrema().IsParallel();
|
|
if (isInfinitySolutions)
|
|
{
|
|
aMinDist = Ex.LowerDistance();
|
|
}
|
|
else
|
|
{
|
|
for (Standard_Integer aJ = 1; aJ <= Ex.NbExtrema(); ++aJ)
|
|
{
|
|
gp_Pnt aP1, aP2;
|
|
Ex.Points(aJ, aP1, aP2);
|
|
aPnts1.Append(aP1);
|
|
aPnts2.Append(aP2);
|
|
|
|
Standard_Real aU1, aU2, aV2;
|
|
Ex.Parameters(aJ, aU1, aU2, aV2);
|
|
aPrms[0].Append(aU1);
|
|
aPrms[2].Append(aU2);
|
|
aPrms[3].Append(aV2);
|
|
}
|
|
}
|
|
}
|
|
else if (!GS1.IsNull() && !GC2.IsNull())
|
|
{
|
|
GeomAPI_ExtremaCurveSurface Ex(GC2, GS1, U2f, U2l, U1f, U1l, V1f, V1l);
|
|
|
|
isInfinitySolutions = Ex.Extrema().IsParallel();
|
|
if (isInfinitySolutions)
|
|
{
|
|
aMinDist = Ex.LowerDistance();
|
|
}
|
|
else
|
|
{
|
|
for (Standard_Integer aJ = 1; aJ <= Ex.NbExtrema(); ++aJ)
|
|
{
|
|
gp_Pnt aP2, aP1;
|
|
Ex.Points(aJ, aP2, aP1);
|
|
aPnts1.Append(aP1);
|
|
aPnts2.Append(aP2);
|
|
|
|
Standard_Real aU1, aV1, aU2;
|
|
Ex.Parameters(aJ, aU2, aU1, aV1);
|
|
aPrms[0].Append(aU1);
|
|
aPrms[1].Append(aV1);
|
|
aPrms[2].Append(aU2);
|
|
}
|
|
}
|
|
}
|
|
else if (!GS1.IsNull() && !GS2.IsNull())
|
|
{
|
|
GeomAPI_ExtremaSurfaceSurface Ex(GS1, GS2, U1f, U1l, V1f, V1l, U2f, U2l, V2f, V2l);
|
|
// Since GeomAPI cannot provide access to flag directly.
|
|
isInfinitySolutions = Ex.Extrema().IsParallel();
|
|
if (isInfinitySolutions)
|
|
{
|
|
aMinDist = Ex.LowerDistance();
|
|
}
|
|
else
|
|
{
|
|
for (Standard_Integer aJ = 1; aJ <= Ex.NbExtrema(); ++aJ)
|
|
{
|
|
gp_Pnt aP1, aP2;
|
|
Ex.Points(aJ, aP1, aP2);
|
|
aPnts1.Append(aP1);
|
|
aPnts2.Append(aP2);
|
|
|
|
Standard_Real aU1, aV1, aU2, aV2;
|
|
Ex.Parameters(aJ, aU1, aV1, aU2, aV2);
|
|
aPrms[0].Append(aU1);
|
|
aPrms[1].Append(aV1);
|
|
aPrms[2].Append(aU2);
|
|
aPrms[3].Append(aV2);
|
|
}
|
|
}
|
|
}
|
|
|
|
char aName[100];
|
|
char* aName2 = aName; // portage WNT
|
|
|
|
// Output points.
|
|
const Standard_Integer aPntCount = aPnts1.Size();
|
|
if (aPntCount == 0 || isInfinitySolutions)
|
|
{
|
|
// Infinity solutions flag may be set with 0 number of
|
|
// solutions in analytic extrema Curve/Curve.
|
|
if (isInfinitySolutions)
|
|
di << "Infinite number of extremas, distance = " << aMinDist << "\n";
|
|
else
|
|
di << "No solutions!\n";
|
|
}
|
|
for (Standard_Integer aJ = 1; aJ <= aPntCount; aJ++)
|
|
{
|
|
gp_Pnt aP1 = aPnts1(aJ - 1), aP2 = aPnts2(aJ - 1);
|
|
|
|
if (aP1.Distance(aP2) < 1.e-16)
|
|
{
|
|
di << "Extrema " << aJ << " is point : " <<
|
|
aP1.X() << " " << aP1.Y() << " " << aP1.Z() << "\n";
|
|
continue;
|
|
}
|
|
|
|
Handle(Geom_Line) aL = new Geom_Line(aP1, gp_Vec(aP1, aP2));
|
|
Handle(Geom_TrimmedCurve) aCT =
|
|
new Geom_TrimmedCurve(aL, 0., aP1.Distance(aP2));
|
|
Sprintf(aName, "%s%d", "ext_", aJ);
|
|
DrawTrSurf::Set(aName2, aCT);
|
|
di << aName << " ";
|
|
}
|
|
|
|
if (n >= 4)
|
|
{
|
|
// Output points.
|
|
for (Standard_Integer aJ = 1; aJ <= aPntCount; aJ++)
|
|
{
|
|
gp_Pnt aP1 = aPnts1(aJ - 1), aP2 = aPnts2(aJ - 1);
|
|
Sprintf(aName, "%s%d%s", "ext_", aJ, "_2");
|
|
DrawTrSurf::Set(aName2, aP1);
|
|
di << aName << " ";
|
|
Sprintf(aName, "%s%d%s", "ext_", aJ, "_3");
|
|
DrawTrSurf::Set(aName2, aP2);
|
|
di << aName << " ";
|
|
}
|
|
|
|
// Output parameters.
|
|
for (Standard_Integer aJ = 0; aJ < 4; ++aJ)
|
|
{
|
|
for (Standard_Integer aPrmCount = aPrms[aJ].Size(), aK = 0;
|
|
aK < aPrmCount; ++aK)
|
|
{
|
|
Standard_Real aP = aPrms[aJ](aK);
|
|
Sprintf(aName, "%s%d%s%d", "prm_", aJ + 1, "_", aK + 1);
|
|
Draw::Set(aName2, aP);
|
|
di << aName << " ";
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : totalextcc
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
static Standard_Integer totalextcc(Draw_Interpretor& di, Standard_Integer n, const char** a)
|
|
{
|
|
if ( n<3) return 1;
|
|
|
|
Handle(Geom_Curve) GC1, GC2;
|
|
|
|
|
|
Standard_Real U1f,U1l,U2f,U2l;
|
|
|
|
GC1 = DrawTrSurf::GetCurve(a[1]);
|
|
if ( GC1.IsNull()) {
|
|
return 1;
|
|
}
|
|
else {
|
|
U1f = GC1->FirstParameter();
|
|
U1l = GC1->LastParameter();
|
|
}
|
|
|
|
GC2 = DrawTrSurf::GetCurve(a[2]);
|
|
if ( GC2.IsNull()) {
|
|
return 1;
|
|
}
|
|
else {
|
|
U2f = GC2->FirstParameter();
|
|
U2l = GC2->LastParameter();
|
|
}
|
|
|
|
char name[100];
|
|
GeomAPI_ExtremaCurveCurve Ex(GC1,GC2,U1f,U1l,U2f,U2l);
|
|
gp_Pnt P1,P2;
|
|
if(Ex.TotalNearestPoints(P1,P2)) {
|
|
if (P1.Distance(P2) < 1.e-16) {
|
|
di << "Extrema is point : " << P1.X() << " " << P1.Y() << " " << P1.Z() << "\n";
|
|
}
|
|
else {
|
|
di << "Extrema is segment of line\n";
|
|
Handle(Geom_Line) L = new Geom_Line(P1,gp_Vec(P1,P2));
|
|
Handle(Geom_TrimmedCurve) CT =
|
|
new Geom_TrimmedCurve(L, 0., P1.Distance(P2));
|
|
Sprintf(name,"%s%d","ext_",1);
|
|
char* temp = name; // portage WNT
|
|
DrawTrSurf::Set(temp, CT);
|
|
di << name << " ";
|
|
}
|
|
|
|
Standard_Real u1, u2;
|
|
Ex.TotalLowerDistanceParameters(u1, u2);
|
|
|
|
di << "Parameters on curves : " << u1 << " " << u2 << "\n";
|
|
|
|
}
|
|
else {
|
|
di << "Curves are infinite and parallel\n";
|
|
}
|
|
|
|
di << "Minimal distance : " << Ex.TotalLowerDistance() << "\n";
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
void GeometryTest::APICommands(Draw_Interpretor& theCommands)
|
|
{
|
|
static Standard_Boolean done = Standard_False;
|
|
if (done) return;
|
|
|
|
done = Standard_True;
|
|
|
|
theCommands.Add("proj", "proj curve/surf x y z [{extrema algo: g(grad)/t(tree)}|{u v}]\n"
|
|
"\t\tOptional parameters are relevant to surf only.\n"
|
|
"\t\tIf initial {u v} are given then local extrema is called",__FILE__, proj);
|
|
|
|
theCommands.Add("appro", "appro result nbpoint [curve]",__FILE__, appro);
|
|
theCommands.Add("surfapp","surfapp result nbupoint nbvpoint x y z ....",
|
|
__FILE__,
|
|
surfapp);
|
|
theCommands.Add("grilapp",
|
|
"grilapp result nbupoint nbvpoint X0 dX Y0 dY z11 z12 .. z1nu .... ",
|
|
__FILE__,grilapp);
|
|
|
|
theCommands.Add("extrema", "extrema curve/surface curve/surface [extended_output = 0|1]",__FILE__,extrema);
|
|
theCommands.Add("totalextcc", "totalextcc curve curve",__FILE__,totalextcc);
|
|
}
|