1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-16 10:08:36 +03:00

0024203: Command "sameparameter" in DRAW on attached edge set tolerance equal to 116.

Main problem:
Algorithm of locale extrema, which is called by "sameparameter" command, cannot find extrema because extremal point is far from initial point. Therefore, reparametrization of edge's curve (for same-parameter) cannot be made properly.

Solve:
Using of global extrema (see Approx_SameParameter.cxx).

As the given edge contains two 2d-curves and the second from them is problem, for select needed curve, an interface of "mk2dcurve" DRAW-command is changed. Now there can be used an index of curve (by default, index = 1, as earlier), see help for more detail information.

Test "heal advanced Z3":
Now checkshape finds only two invalid subshapes. Earlier, it found four subshapes. I think it is not regression. Therefore, test case was changed.

Tolerance reducing.

test
This commit is contained in:
nbv 2014-01-20 14:56:15 +04:00 committed by bugmaster
parent 091232bae7
commit a86d3ec04b
6 changed files with 1321 additions and 1179 deletions

View File

@ -26,14 +26,12 @@
#include <GeomAdaptor_HCurve.hxx> #include <GeomAdaptor_HCurve.hxx>
#include <GeomAdaptor_Surface.hxx> #include <GeomAdaptor_Surface.hxx>
#include <GeomAdaptor_HSurface.hxx> #include <GeomAdaptor_HSurface.hxx>
//#include <GCPnts_UniformDeflection.hxx>
#include <GCPnts_QuasiUniformDeflection.hxx> #include <GCPnts_QuasiUniformDeflection.hxx>
#include <Extrema_LocateExtPC.hxx> #include <Extrema_LocateExtPC.hxx>
#include <AdvApprox_ApproxAFunction.hxx> #include <AdvApprox_ApproxAFunction.hxx>
#include <GeomLib_MakeCurvefromApprox.hxx> #include <GeomLib_MakeCurvefromApprox.hxx>
#include <Precision.hxx> #include <Precision.hxx>
#include <Extrema_ExtPC.hxx>
#define MAX_ARRAY_SIZE 1000 // IFV, Jan 2000
#ifdef DEB #ifdef DEB
#ifdef DRAW #ifdef DRAW
@ -50,32 +48,32 @@ static Standard_Integer NbCurve = 0;
static void ProjectPointOnCurve(const Standard_Real InitValue, static void ProjectPointOnCurve(const Standard_Real InitValue,
const gp_Pnt APoint, const gp_Pnt APoint,
const Standard_Real Tolerance, const Standard_Real Tolerance,
const Standard_Integer NumIteration, const Standard_Integer NumIteration,
const Adaptor3d_Curve& Curve, const Adaptor3d_Curve& Curve,
Standard_Boolean& Status, Standard_Boolean& Status,
Standard_Real& Result) Standard_Real& Result)
{ {
Standard_Integer num_iter = 0, Standard_Integer num_iter = 0,
not_done = 1, not_done = 1,
ii ; ii ;
gp_Pnt a_point ; gp_Pnt a_point ;
gp_Vec vector, gp_Vec vector,
d1, d1,
d2 ; d2 ;
Standard_Real func, Standard_Real func,
func_derivative, func_derivative,
param = InitValue ; param = InitValue ;
Status = Standard_False ; Status = Standard_False ;
Standard_Real Toler = 1.0e-12; Standard_Real Toler = 1.0e-12;
do { do {
num_iter += 1 ; num_iter += 1 ;
Curve.D2(param, Curve.D2(param,
a_point, a_point,
d1, d1,
d2) ; d2) ;
for (ii = 1 ; ii <= 3 ; ii++) { for (ii = 1 ; ii <= 3 ; ii++) {
vector.SetCoord(ii, APoint.Coord(ii) - a_point.Coord(ii)) ; vector.SetCoord(ii, APoint.Coord(ii) - a_point.Coord(ii)) ;
} }
@ -87,14 +85,14 @@ static void ProjectPointOnCurve(const Standard_Real InitValue,
Status = Standard_True ; Status = Standard_True ;
} }
else else
{ // fixing a bug PRO18577 : avoid divizion by zero { // fixing a bug PRO18577 : avoid divizion by zero
if( Abs(func_derivative) > Toler ) { if( Abs(func_derivative) > Toler ) {
param -= func / func_derivative ; param -= func / func_derivative ;
}
param = Max(param,Curve.FirstParameter()) ;
param = Min(param,Curve.LastParameter()) ;
Status = Standard_True ;
} }
param = Max(param,Curve.FirstParameter()) ;
param = Min(param,Curve.LastParameter()) ;
//Status = Standard_True ;
}
} }
while (not_done && num_iter <= NumIteration) ; while (not_done && num_iter <= NumIteration) ;
Result = param ; Result = param ;
@ -109,31 +107,31 @@ static void ProjectPointOnCurve(const Standard_Real InitValue,
class Approx_SameParameter_Evaluator : public AdvApprox_EvaluatorFunction class Approx_SameParameter_Evaluator : public AdvApprox_EvaluatorFunction
{ {
public: public:
Approx_SameParameter_Evaluator (const TColStd_Array1OfReal& theFlatKnots, Approx_SameParameter_Evaluator (const TColStd_Array1OfReal& theFlatKnots,
const TColStd_Array1OfReal& thePoles, const TColStd_Array1OfReal& thePoles,
const Handle(Adaptor2d_HCurve2d)& theHCurve2d) const Handle(Adaptor2d_HCurve2d)& theHCurve2d)
: FlatKnots(theFlatKnots), Poles(thePoles), HCurve2d(theHCurve2d) {} : FlatKnots(theFlatKnots), Poles(thePoles), HCurve2d(theHCurve2d) {}
virtual void Evaluate (Standard_Integer *Dimension, virtual void Evaluate (Standard_Integer *Dimension,
Standard_Real StartEnd[2], Standard_Real StartEnd[2],
Standard_Real *Parameter, Standard_Real *Parameter,
Standard_Integer *DerivativeRequest, Standard_Integer *DerivativeRequest,
Standard_Real *Result, // [Dimension] Standard_Real *Result, // [Dimension]
Standard_Integer *ErrorCode); Standard_Integer *ErrorCode);
private: private:
const TColStd_Array1OfReal& FlatKnots; const TColStd_Array1OfReal& FlatKnots;
const TColStd_Array1OfReal& Poles; const TColStd_Array1OfReal& Poles;
Handle(Adaptor2d_HCurve2d) HCurve2d; Handle(Adaptor2d_HCurve2d) HCurve2d;
}; };
void Approx_SameParameter_Evaluator::Evaluate (Standard_Integer *,/*Dimension*/ void Approx_SameParameter_Evaluator::Evaluate (Standard_Integer *,/*Dimension*/
Standard_Real /*StartEnd*/[2], Standard_Real /*StartEnd*/[2],
Standard_Real *Parameter, Standard_Real *Parameter,
Standard_Integer *DerivativeRequest, Standard_Integer *DerivativeRequest,
Standard_Real *Result, Standard_Real *Result,
Standard_Integer *ReturnCode) Standard_Integer *ReturnCode)
{ {
gp_Pnt2d Point ; gp_Pnt2d Point ;
gp_Vec2d Vector ; gp_Vec2d Vector ;
@ -146,14 +144,14 @@ void Approx_SameParameter_Evaluator::Evaluate (Standard_Integer *,/*Dimension*/
// evaluate the 1D bspline that represents the change in parameterization // evaluate the 1D bspline that represents the change in parameterization
// //
BSplCLib::Eval(*Parameter, BSplCLib::Eval(*Parameter,
Standard_False, Standard_False,
*DerivativeRequest, *DerivativeRequest,
extrap_mode[0], extrap_mode[0],
3, 3,
FlatKnots, FlatKnots,
1, 1,
PolesArray[0], PolesArray[0],
eval_result[0]) ; eval_result[0]) ;
if (*DerivativeRequest == 0){ if (*DerivativeRequest == 0){
@ -169,24 +167,22 @@ void Approx_SameParameter_Evaluator::Evaluate (Standard_Integer *,/*Dimension*/
} }
static Standard_Real ComputeTolReached(const Handle(Adaptor3d_HCurve)& c3d, static Standard_Real ComputeTolReached(const Handle(Adaptor3d_HCurve)& c3d,
const Adaptor3d_CurveOnSurface& cons, const Adaptor3d_CurveOnSurface& cons,
const Standard_Integer nbp) const Standard_Integer nbp)
{ {
Standard_Real d2 = 0.; Standard_Real d2 = 0.;
Standard_Integer nn = nbp; const Standard_Real first = c3d->FirstParameter();
Standard_Real unsurnn = 1./nn; const Standard_Real last = c3d->LastParameter();
Standard_Real first = c3d->FirstParameter(); for(Standard_Integer i = 0; i <= nbp; i++){
Standard_Real last = c3d->LastParameter(); Standard_Real t = IntToReal(i)/IntToReal(nbp);
for(Standard_Integer i = 0; i <= nn; i++){
Standard_Real t = unsurnn*i;
Standard_Real u = first*(1.-t) + last*t; Standard_Real u = first*(1.-t) + last*t;
gp_Pnt Pc3d = c3d->Value(u); gp_Pnt Pc3d = c3d->Value(u);
gp_Pnt Pcons = cons.Value(u); gp_Pnt Pcons = cons.Value(u);
if (Precision::IsInfinite(Pcons.X()) || if (Precision::IsInfinite(Pcons.X()) ||
Precision::IsInfinite(Pcons.Y()) || Precision::IsInfinite(Pcons.Y()) ||
Precision::IsInfinite(Pcons.Z())) { Precision::IsInfinite(Pcons.Z())) {
d2=Precision::Infinite(); d2=Precision::Infinite();
break; break;
} }
Standard_Real temp = Pc3d.SquareDistance(Pcons); Standard_Real temp = Pc3d.SquareDistance(Pcons);
if(temp > d2) d2 = temp; if(temp > d2) d2 = temp;
@ -197,15 +193,15 @@ static Standard_Real ComputeTolReached(const Handle(Adaptor3d_HCurve)& c3d,
} }
static Standard_Boolean Check(const TColStd_Array1OfReal& FlatKnots, static Standard_Boolean Check(const TColStd_Array1OfReal& FlatKnots,
const TColStd_Array1OfReal& Poles, const TColStd_Array1OfReal& Poles,
const Standard_Integer nbp, const Standard_Integer nbp,
const TColStd_Array1OfReal& pc3d, const TColStd_Array1OfReal& pc3d,
// const TColStd_Array1OfReal& pcons, // const TColStd_Array1OfReal& pcons,
const TColStd_Array1OfReal& , const TColStd_Array1OfReal& ,
const Handle(Adaptor3d_HCurve)& c3d, const Handle(Adaptor3d_HCurve)& c3d,
const Adaptor3d_CurveOnSurface& cons, const Adaptor3d_CurveOnSurface& cons,
Standard_Real& tol, Standard_Real& tol,
const Standard_Real oldtol) const Standard_Real oldtol)
{ {
Standard_Real d = tol; Standard_Real d = tol;
Standard_Integer extrap_mode[2] ; Standard_Integer extrap_mode[2] ;
@ -226,7 +222,7 @@ static Standard_Boolean Check(const TColStd_Array1OfReal& FlatKnots,
gp_Pnt Pc3d = c3d->Value(tc3d); gp_Pnt Pc3d = c3d->Value(tc3d);
Standard_Real tcons; Standard_Real tcons;
BSplCLib::Eval(tc3d,Standard_False,0,extrap_mode[0], BSplCLib::Eval(tc3d,Standard_False,0,extrap_mode[0],
3,FlatKnots,1, (Standard_Real&)Poles(1),tcons); 3,FlatKnots,1, (Standard_Real&)Poles(1),tcons);
gp_Pnt Pcons = cons.Value(tcons); gp_Pnt Pcons = cons.Value(tcons);
Standard_Real temp = Pc3d.SquareDistance(Pcons); Standard_Real temp = Pc3d.SquareDistance(Pcons);
if(temp >= dglis) dglis = temp; if(temp >= dglis) dglis = temp;
@ -246,7 +242,7 @@ static Standard_Boolean Check(const TColStd_Array1OfReal& FlatKnots,
gp_Pnt Pc3d = c3d->Value(tc3d); gp_Pnt Pc3d = c3d->Value(tc3d);
Standard_Real tcons; Standard_Real tcons;
BSplCLib::Eval(tc3d,Standard_False,0,extrap_mode[0], BSplCLib::Eval(tc3d,Standard_False,0,extrap_mode[0],
3,FlatKnots,1, (Standard_Real&)Poles(1),tcons); 3,FlatKnots,1, (Standard_Real&)Poles(1),tcons);
gp_Pnt Pcons = cons.Value(tcons); gp_Pnt Pcons = cons.Value(tcons);
Standard_Real temp = Pc3d.SquareDistance(Pcons); Standard_Real temp = Pc3d.SquareDistance(Pcons);
if(temp >= dglis) dglis = temp; if(temp >= dglis) dglis = temp;
@ -261,25 +257,25 @@ static Standard_Boolean Check(const TColStd_Array1OfReal& FlatKnots,
Standard_Real d2 = 0.; Standard_Real d2 = 0.;
Standard_Integer nn = 2*nbp; Standard_Integer nn = 2*nbp;
Standard_Real unsurnn = 1./nn; Standard_Real unsurnn = 1./nn;
// Modified by skv - Wed Jun 2 11:49:59 2004 OCC5898 Begin // Modified by skv - Wed Jun 2 11:49:59 2004 OCC5898 Begin
// Correction of the interval of valid values. This condition has no sensible // Correction of the interval of valid values. This condition has no sensible
// grounds. But it is better then the old one (which is commented out) because // grounds. But it is better then the old one (which is commented out) because
// it fixes the bug OCC5898. To develop more or less sensible criterion it is // it fixes the bug OCC5898. To develop more or less sensible criterion it is
// necessary to deeply investigate this problem which is not possible in frames // necessary to deeply investigate this problem which is not possible in frames
// of debugging. // of debugging.
// Standard_Real firstborne= 2*pc3d(1)-pc3d(nbp); // Standard_Real firstborne= 2*pc3d(1)-pc3d(nbp);
// Standard_Real lastborne= 2*pc3d(nbp)-pc3d(1); // Standard_Real lastborne= 2*pc3d(nbp)-pc3d(1);
Standard_Real firstborne= 3.*pc3d(1) - 2.*pc3d(nbp); Standard_Real firstborne= 3.*pc3d(1) - 2.*pc3d(nbp);
Standard_Real lastborne = 3.*pc3d(nbp) - 2.*pc3d(1); Standard_Real lastborne = 3.*pc3d(nbp) - 2.*pc3d(1);
// Modified by skv - Wed Jun 2 11:50:03 2004 OCC5898 End // Modified by skv - Wed Jun 2 11:50:03 2004 OCC5898 End
for(i = 0; i <= nn; i++){ for(i = 0; i <= nn; i++){
Standard_Real t = unsurnn*i; Standard_Real t = unsurnn*i;
Standard_Real tc3d = pc3d(1)*(1.-t) + pc3d(nbp)*t; Standard_Real tc3d = pc3d(1)*(1.-t) + pc3d(nbp)*t;
gp_Pnt Pc3d = c3d->Value(tc3d); gp_Pnt Pc3d = c3d->Value(tc3d);
Standard_Real tcons; Standard_Real tcons;
BSplCLib::Eval(tc3d,Standard_False,0,extrap_mode[0], BSplCLib::Eval(tc3d,Standard_False,0,extrap_mode[0],
3,FlatKnots,1, (Standard_Real&)Poles(1),tcons); 3,FlatKnots,1, (Standard_Real&)Poles(1),tcons);
if (tcons < firstborne || tcons > lastborne) { if (tcons < firstborne || tcons > lastborne) {
tol=Precision::Infinite(); tol=Precision::Infinite();
return Standard_False; return Standard_False;
@ -303,10 +299,10 @@ static Standard_Boolean Check(const TColStd_Array1OfReal& FlatKnots,
//======================================================================= //=======================================================================
Approx_SameParameter::Approx_SameParameter(const Handle(Geom_Curve)& C3D, Approx_SameParameter::Approx_SameParameter(const Handle(Geom_Curve)& C3D,
const Handle(Geom2d_Curve)& C2D, const Handle(Geom2d_Curve)& C2D,
const Handle(Geom_Surface)& S, const Handle(Geom_Surface)& S,
const Standard_Real Tol): const Standard_Real Tol):
mySameParameter(Standard_True), myDone(Standard_False) mySameParameter(Standard_True), myDone(Standard_False)
{ {
myHCurve2d = new Geom2dAdaptor_HCurve(C2D); myHCurve2d = new Geom2dAdaptor_HCurve(C2D);
myC3d = new GeomAdaptor_HCurve(C3D); myC3d = new GeomAdaptor_HCurve(C3D);
@ -321,10 +317,10 @@ Approx_SameParameter::Approx_SameParameter(const Handle(Geom_Curve)& C3D,
//======================================================================= //=======================================================================
Approx_SameParameter::Approx_SameParameter(const Handle(Adaptor3d_HCurve)& C3D, Approx_SameParameter::Approx_SameParameter(const Handle(Adaptor3d_HCurve)& C3D,
const Handle(Geom2d_Curve)& C2D, const Handle(Geom2d_Curve)& C2D,
const Handle(Adaptor3d_HSurface)& S, const Handle(Adaptor3d_HSurface)& S,
const Standard_Real Tol): const Standard_Real Tol):
mySameParameter(Standard_True), myDone(Standard_False) mySameParameter(Standard_True), myDone(Standard_False)
{ {
myC3d = C3D; myC3d = C3D;
mySurf = S; mySurf = S;
@ -339,10 +335,10 @@ Approx_SameParameter::Approx_SameParameter(const Handle(Adaptor3d_HCurve)& C3D
//======================================================================= //=======================================================================
Approx_SameParameter::Approx_SameParameter(const Handle(Adaptor3d_HCurve)& C3D, Approx_SameParameter::Approx_SameParameter(const Handle(Adaptor3d_HCurve)& C3D,
const Handle(Adaptor2d_HCurve2d)& C2D, const Handle(Adaptor2d_HCurve2d)& C2D,
const Handle(Adaptor3d_HSurface)& S, const Handle(Adaptor3d_HSurface)& S,
const Standard_Real Tol): const Standard_Real Tol):
mySameParameter(Standard_True), myDone(Standard_False) mySameParameter(Standard_True), myDone(Standard_False)
{ {
myC3d = C3D; myC3d = C3D;
mySurf = S; mySurf = S;
@ -355,9 +351,12 @@ Approx_SameParameter::Approx_SameParameter(const Handle(Adaptor3d_HCurve)& C3D
//function : Build //function : Build
//purpose : //purpose :
//======================================================================= //=======================================================================
void Approx_SameParameter::Build(const Standard_Real Tolerance) void Approx_SameParameter::Build(const Standard_Real Tolerance)
{ {
const Standard_Real anErrorMAX = 1.0e15;
const Standard_Integer aMaxArraySize = 1000;
const Standard_Integer NCONTROL = 22;
Standard_Integer ii ; Standard_Integer ii ;
Adaptor3d_CurveOnSurface CurveOnSurface(myHCurve2d,mySurf); Adaptor3d_CurveOnSurface CurveOnSurface(myHCurve2d,mySurf);
Standard_Real fcons = CurveOnSurface.FirstParameter(); Standard_Real fcons = CurveOnSurface.FirstParameter();
@ -412,7 +411,6 @@ void Approx_SameParameter::Build(const Standard_Real Tolerance)
//Take a multiple of the sample pof CheckShape, //Take a multiple of the sample pof CheckShape,
//at least the control points will be correct. No comment!!! //at least the control points will be correct. No comment!!!
Standard_Integer NCONTROL = 22;
#ifdef DEB #ifdef DEB
Standard_Integer nbcoups = 0; Standard_Integer nbcoups = 0;
#endif #endif
@ -429,8 +427,8 @@ void Approx_SameParameter::Build(const Standard_Real Tolerance)
Standard_Real wcons = fcons; Standard_Real wcons = fcons;
Standard_Real wc3d = fc3d; Standard_Real wc3d = fc3d;
Standard_Real qpcons[MAX_ARRAY_SIZE], qnewpcons[MAX_ARRAY_SIZE], Standard_Real qpcons[aMaxArraySize], qnewpcons[aMaxArraySize],
qpc3d[MAX_ARRAY_SIZE], qnewpc3d[MAX_ARRAY_SIZE]; qpc3d[aMaxArraySize], qnewpc3d[aMaxArraySize];
Standard_Real * pcons = qpcons; Standard_Real * newpcons = qnewpcons; Standard_Real * pcons = qpcons; Standard_Real * newpcons = qnewpcons;
Standard_Real * pc3d = qpc3d; Standard_Real * newpc3d = qnewpc3d; Standard_Real * pc3d = qpc3d; Standard_Real * newpc3d = qnewpc3d;
@ -445,46 +443,46 @@ void Approx_SameParameter::Build(const Standard_Real Tolerance)
Standard_Integer New_NCONTROL = NCONTROL; Standard_Integer New_NCONTROL = NCONTROL;
if(Continuity < GeomAbs_C1) { if(Continuity < GeomAbs_C1) {
Standard_Integer NbInt = myHCurve2d->NbIntervals(GeomAbs_C1) + 1; Standard_Integer NbInt = myHCurve2d->NbIntervals(GeomAbs_C1) + 1;
TColStd_Array1OfReal Param_de_decoupeC1 (1, NbInt); TColStd_Array1OfReal Param_de_decoupeC1 (1, NbInt);
myHCurve2d->Intervals(Param_de_decoupeC1, GeomAbs_C1); myHCurve2d->Intervals(Param_de_decoupeC1, GeomAbs_C1);
TColStd_SequenceOfReal new_par; TColStd_SequenceOfReal new_par;
Standard_Integer inter = 1; Standard_Integer inter = 1;
ii =1; ii =1;
new_par.Append(fcons); new_par.Append(fcons);
while(Param_de_decoupeC1(inter) <= fcons + deltamin) inter++; while(Param_de_decoupeC1(inter) <= fcons + deltamin) inter++;
while(Param_de_decoupeC1(NbInt) >= lcons - deltamin) NbInt--; while(Param_de_decoupeC1(NbInt) >= lcons - deltamin) NbInt--;
while(inter <= NbInt || ii < NCONTROL) { while(inter <= NbInt || ii < NCONTROL) {
if(Param_de_decoupeC1(inter) < pcons[ii]) { if(Param_de_decoupeC1(inter) < pcons[ii]) {
new_par.Append(Param_de_decoupeC1(inter)); new_par.Append(Param_de_decoupeC1(inter));
if((pcons[ii] - Param_de_decoupeC1(inter)) <= deltamin) { if((pcons[ii] - Param_de_decoupeC1(inter)) <= deltamin) {
ii++; ii++;
if(ii > NCONTROL) {ii = NCONTROL;} if(ii > NCONTROL) {ii = NCONTROL;}
} }
inter++; inter++;
} }
else { else {
if((Param_de_decoupeC1(inter) - pcons[ii]) > deltamin) { if((Param_de_decoupeC1(inter) - pcons[ii]) > deltamin) {
new_par.Append(pcons[ii]); new_par.Append(pcons[ii]);
} }
ii++; ii++;
} }
} }
new_par.Append(lcons); new_par.Append(lcons);
New_NCONTROL = new_par.Length() - 1; New_NCONTROL = new_par.Length() - 1;
//simple protection if New_NCONTROL > allocated elements in array //simple protection if New_NCONTROL > allocated elements in array
if (New_NCONTROL > MAX_ARRAY_SIZE) { if (New_NCONTROL > aMaxArraySize) {
mySameParameter = Standard_False; mySameParameter = Standard_False;
return; return;
} }
for(ii = 1; ii <= New_NCONTROL; ii++){ for(ii = 1; ii <= New_NCONTROL; ii++){
pcons[ii] = pc3d[ii] = new_par.Value(ii + 1); pcons[ii] = pc3d[ii] = new_par.Value(ii + 1);
} }
pc3d[New_NCONTROL] = lc3d; pc3d[New_NCONTROL] = lc3d;
} }
Extrema_LocateExtPC Projector; Extrema_LocateExtPC Projector;
@ -512,29 +510,67 @@ void Approx_SameParameter::Build(const Standard_Real Tolerance)
projok = mySameParameter = Standard_False; projok = mySameParameter = Standard_False;
Projector.Perform(Pcons, initp); Projector.Perform(Pcons, initp);
if (Projector.IsDone()) { if (Projector.IsDone()) {
curp = Projector.Point().Parameter(); curp = Projector.Point().Parameter();
Standard_Real dist_2 = Projector.SquareDistance(); Standard_Real dist_2 = Projector.SquareDistance();
if(dist_2 > besttol2) besttol2 = dist_2; if(dist_2 > besttol2) besttol2 = dist_2;
projok = 1; projok = 1;
} }
else { else
ProjectPointOnCurve(initp,Pcons,Tol,30,myC3d->Curve(),projok,curp); {
ProjectPointOnCurve(initp,Pcons,Tol,30,myC3d->Curve(),projok,curp);
} }
if(projok){
if(curp > previousp + deltamin && curp < bornesup){ if(projok)
initp = previousp = pc3d[count] = curp; {
pcons[count] = pcons[ii]; if(curp > previousp + deltamin && curp < bornesup){
count++; initp = previousp = pc3d[count] = curp;
} pcons[count] = pcons[ii];
count++;
}
} }
else { else
{
Extrema_ExtPC PR(Pcons,myC3d->Curve(),fc3d,lc3d,Tol);
if(PR.IsDone())
{
const Standard_Integer aNbExt = PR.NbExt();
if(aNbExt > 0)
{
Standard_Integer anIndMin = 0;
Standard_Real aDistMin = RealLast();
for(Standard_Integer i = 1; i <= aNbExt; i++)
{
const gp_Pnt &aP = PR.Point(i).Value();
Standard_Real aDist2 = aP.SquareDistance(Pcons);
if(aDist2 < aDistMin)
{
aDistMin = aDist2;
anIndMin = i;
}
}
curp = PR.Point(anIndMin).Parameter();
if(curp > previousp + deltamin && curp < bornesup)
{
initp = previousp = pc3d[count] = curp;
pcons[count] = pcons[ii];
count++;
projok = Standard_True;
}
}
}
}
if(!projok)
{
//Projector
#ifdef DEB #ifdef DEB
// JAG // JAG
cout << "Projection not done" << endl; cout << "Projection not done" << endl;
#endif #endif
} }
} }
} }
if(mySameParameter){ if(mySameParameter){
myTolReached = 1.5*sqrt(dmax2); myTolReached = 1.5*sqrt(dmax2);
return; return;
@ -572,7 +608,10 @@ void Approx_SameParameter::Build(const Standard_Real Tolerance)
} }
#endif #endif
while(!interpolok){ Standard_Boolean hasCountChanged = Standard_False;
while(!interpolok)
{
// The tables and their limits for the interpolation. // The tables and their limits for the interpolation.
Standard_Integer num_knots = count + 7; Standard_Integer num_knots = count + 7;
Standard_Integer num_poles = count + 3; Standard_Integer num_poles = count + 3;
@ -603,58 +642,58 @@ void Approx_SameParameter::Build(const Standard_Real Tolerance)
} }
Standard_Integer inversion_problem; Standard_Integer inversion_problem;
BSplCLib::Interpolate(3,FlatKnots,InterpolationParameters,ContactOrder, BSplCLib::Interpolate(3,FlatKnots,InterpolationParameters,ContactOrder,
1,Poles(1),inversion_problem); 1,Poles(1),inversion_problem);
if(inversion_problem) { if(inversion_problem) {
Standard_ConstructionError::Raise(); Standard_ConstructionError::Raise();
} }
//------------------------------------------- //-------------------------------------------
#ifdef DEB #ifdef DEB
if (AffichFw) { if (AffichFw) {
nbcoups ++; nbcoups ++;
char Name[17]; char Name[17];
Name[0] = '\0'; Name[0] = '\0';
Standard_Integer nnn = 100; Standard_Integer nnn = 100;
TColgp_Array1OfPnt2d DEBP2d (0,nnn); TColgp_Array1OfPnt2d DEBP2d (0,nnn);
TColStd_Array1OfInteger DEBMults(0,nnn); TColStd_Array1OfInteger DEBMults(0,nnn);
DEBMults.Init(1); DEBMults(0) = 2; DEBMults(nnn) = 2; DEBMults.Init(1); DEBMults(0) = 2; DEBMults(nnn) = 2;
TColStd_Array1OfReal DEBKnots(0,nnn); TColStd_Array1OfReal DEBKnots(0,nnn);
Standard_Real du = (lc3d - fc3d) / nnn; Standard_Real du = (lc3d - fc3d) / nnn;
Standard_Real u3d = fc3d; Standard_Real u3d = fc3d;
Standard_Integer extrap_mode[2] ; Standard_Integer extrap_mode[2] ;
extrap_mode[0] = extrap_mode[1] = 3; extrap_mode[0] = extrap_mode[1] = 3;
Standard_Real eval_result[2] ; Standard_Real eval_result[2] ;
Standard_Integer DerivativeRequest = 0; Standard_Integer DerivativeRequest = 0;
Standard_Real *PolesArray = Standard_Real *PolesArray =
(Standard_Real *) &Poles(Poles.Lower()) ; (Standard_Real *) &Poles(Poles.Lower()) ;
for (Standard_Integer DEBi = 0; DEBi <= nnn; DEBi++) { for (Standard_Integer DEBi = 0; DEBi <= nnn; DEBi++) {
DEBKnots(DEBi) = DEBi; DEBKnots(DEBi) = DEBi;
BSplCLib::Eval(u3d, BSplCLib::Eval(u3d,
Standard_False, Standard_False,
DerivativeRequest, DerivativeRequest,
extrap_mode[0], extrap_mode[0],
3, 3,
FlatKnots, FlatKnots,
1, 1,
PolesArray[0], PolesArray[0],
eval_result[0]) ; eval_result[0]) ;
DEBP2d (DEBi) = gp_Pnt2d(u3d,eval_result[0]); DEBP2d (DEBi) = gp_Pnt2d(u3d,eval_result[0]);
u3d += du; u3d += du;
} }
Handle(Geom2d_BSplineCurve) DEBBS = Handle(Geom2d_BSplineCurve) DEBBS =
new Geom2d_BSplineCurve(DEBP2d,DEBKnots,DEBMults,1); new Geom2d_BSplineCurve(DEBP2d,DEBKnots,DEBMults,1);
Sprintf(Name,"DEBC2d_%d_%d",NbCurve,nbcoups ); Sprintf(Name,"DEBC2d_%d_%d",NbCurve,nbcoups );
#ifdef DRAW #ifdef DRAW
DrawTrSurf::Set(Name,DEBBS); DrawTrSurf::Set(Name,DEBBS);
#endif #endif
} }
#endif #endif
//------------------------------------------- //-------------------------------------------
//------------------------------------------- //-------------------------------------------
// Test if par2d(par3d) is monotonous function or not ----- IFV, Jan 2000 // Test if par2d(par3d) is monotonous function or not ----- IFV, Jan 2000
// and try to insert new point to improve BSpline interpolation // and try to insert new point to improve BSpline interpolation
@ -672,39 +711,39 @@ void Approx_SameParameter::Build(const Standard_Real Tolerance)
newpc3d[newcount] = pc3d[ii]; newpc3d[newcount] = pc3d[ii];
newcount++; newcount++;
if(count - ii + newcount == MAX_ARRAY_SIZE) continue; if(count - ii + newcount == aMaxArraySize) continue;
BSplCLib::Eval(.5*(pc3d[ii]+pc3d[ii+1]), Standard_False, DerivativeRequest, BSplCLib::Eval(.5*(pc3d[ii]+pc3d[ii+1]), Standard_False, DerivativeRequest,
extrap_mode[0], 3, FlatKnots, 1, PolesArray[0], eval_result[0]); extrap_mode[0], 3, FlatKnots, 1, PolesArray[0], eval_result[0]);
if(eval_result[0] < pcons[ii] || eval_result[0] > pcons[ii+1]) { if(eval_result[0] < pcons[ii] || eval_result[0] > pcons[ii+1]) {
Standard_Real ucons = 0.5*(pcons[ii]+pcons[ii+1]); Standard_Real ucons = 0.5*(pcons[ii]+pcons[ii+1]);
Standard_Real uc3d = 0.5*(pc3d[ii]+pc3d[ii+1]); Standard_Real uc3d = 0.5*(pc3d[ii]+pc3d[ii+1]);
CurveOnSurface.D0(ucons,Pcons); CurveOnSurface.D0(ucons,Pcons);
Projector.Perform(Pcons, uc3d); Projector.Perform(Pcons, uc3d);
if (Projector.IsDone()) { if (Projector.IsDone()) {
curp = Projector.Point().Parameter(); curp = Projector.Point().Parameter();
Standard_Real dist_2 = Projector.SquareDistance(); Standard_Real dist_2 = Projector.SquareDistance();
if(dist_2 > besttol2) besttol2 = dist_2; if(dist_2 > besttol2) besttol2 = dist_2;
projok = 1; projok = 1;
} }
else { else {
ProjectPointOnCurve(uc3d,Pcons,Tol,30,myC3d->Curve(),projok,curp); ProjectPointOnCurve(uc3d,Pcons,Tol,30,myC3d->Curve(),projok,curp);
} }
if(projok){ if(projok){
if(curp > pc3d[ii] + deltamin && curp < pc3d[ii+1] - deltamin){ if(curp > pc3d[ii] + deltamin && curp < pc3d[ii+1] - deltamin){
newpc3d[newcount] = curp; newpc3d[newcount] = curp;
newpcons[newcount] = ucons; newpcons[newcount] = ucons;
newcount ++; newcount ++;
} }
} }
else { else {
#ifdef DEB #ifdef DEB
// JAG // JAG
cout << "Projection not done" << endl; cout << "Projection not done" << endl;
#endif #endif
} }
} }
} }
@ -719,14 +758,14 @@ void Approx_SameParameter::Build(const Standard_Real Tolerance)
pcons = newpcons; pcons = newpcons;
newpcons = temp; newpcons = temp;
if((count != newcount) && newcount < MAX_ARRAY_SIZE) { count = newcount; continue;} if((count != newcount) && newcount < aMaxArraySize) { count = newcount; continue;}
count = newcount; count = newcount;
Standard_Real algtol = sqrt(besttol2); Standard_Real algtol = sqrt(besttol2);
interpolok = Check (FlatKnots, Poles, count+1, Paramc3d, Paramcons, interpolok = Check (FlatKnots, Poles, count+1, Paramc3d, Paramcons,
myC3d, CurveOnSurface, algtol, tolsov); myC3d, CurveOnSurface, algtol, tolsov);
if (Precision::IsInfinite(algtol)) { if (Precision::IsInfinite(algtol)) {
mySameParameter = Standard_False; mySameParameter = Standard_False;
@ -738,15 +777,15 @@ void Approx_SameParameter::Build(const Standard_Real Tolerance)
tolsov = algtol; tolsov = algtol;
interpolok = (interpolok || count >= MAX_ARRAY_SIZE); interpolok = (interpolok || count >= aMaxArraySize);
if(interpolok) { if(interpolok) {
Standard_Real besttol = sqrt(besttol2); Standard_Real besttol = sqrt(besttol2);
#ifdef DEB #ifdef DEB
if (Voir) { if (Voir) {
if(algtol > besttol){ if(algtol > besttol){
cout<<"SameParameter : Tol can't be reached before approx"<<endl; cout<<"SameParameter : Tol can't be reached before approx"<<endl;
} }
} }
#endif #endif
Handle(TColStd_HArray1OfReal) tol1d,tol2d,tol3d; Handle(TColStd_HArray1OfReal) tol1d,tol2d,tol3d;
@ -756,58 +795,85 @@ void Approx_SameParameter::Build(const Standard_Real Tolerance)
Approx_SameParameter_Evaluator ev (FlatKnots, Poles, myHCurve2d); Approx_SameParameter_Evaluator ev (FlatKnots, Poles, myHCurve2d);
AdvApprox_ApproxAFunction anApproximator(2,0,0,tol1d,tol2d,tol3d,fc3d,lc3d, AdvApprox_ApproxAFunction anApproximator(2,0,0,tol1d,tol2d,tol3d,fc3d,lc3d,
Continuity,11,40,ev); Continuity,11,40,ev);
if (anApproximator.IsDone() || anApproximator.HasResult()) { if (anApproximator.IsDone() || anApproximator.HasResult()) {
GeomLib_MakeCurvefromApprox aCurveBuilder(anApproximator) ; Adaptor3d_CurveOnSurface ACS = CurveOnSurface;
myCurve2d = aCurveBuilder.Curve2dFromTwo1d(1,2) ; GeomLib_MakeCurvefromApprox aCurveBuilder(anApproximator) ;
myHCurve2d = new Geom2dAdaptor_HCurve(myCurve2d); Handle(Geom2d_BSplineCurve) aC2d = aCurveBuilder.Curve2dFromTwo1d(1,2) ;
CurveOnSurface.Load(myHCurve2d); Handle(Adaptor2d_HCurve2d) aHCurve2d = new Geom2dAdaptor_HCurve(aC2d);
myTolReached = ComputeTolReached(myC3d,CurveOnSurface,NCONTROL); CurveOnSurface.Load(aHCurve2d);
myDone = Standard_True;
myTolReached = ComputeTolReached(myC3d,CurveOnSurface,NCONTROL);
if(myTolReached > anErrorMAX)
{
//This tolerance is too big. Probably, we will not can get
//edge with sameparameter in this case.
myDone = Standard_False;
return;
}
if( (myTolReached < 250.0*besttol) ||
(count >= aMaxArraySize-2) ||
!hasCountChanged) //if count does not change after adding new point
//(else we can have circularity)
{
myCurve2d = aC2d;
myHCurve2d = new Geom2dAdaptor_HCurve(myCurve2d);
myDone = Standard_True;
}
else
{
interpolok = Standard_False;
CurveOnSurface = ACS;
}
} }
} }
else {
if(!interpolok)
{
#ifdef DEB #ifdef DEB
if (Voir) if (Voir)
cout<<"SameParameter : Not enough points, enrich"<<endl; cout<<"SameParameter : Not enough points, enrich"<<endl;
#endif #endif
Standard_Integer newcount = 0; newcount = 0;
for(Standard_Integer n = 0; n < count; n++){ for(Standard_Integer n = 0; n < count; n++){
newpc3d[newcount] = pc3d[n]; newpc3d[newcount] = pc3d[n];
newpcons[newcount] = pcons[n]; newpcons[newcount] = pcons[n];
newcount ++; newcount ++;
if(count - n + newcount == MAX_ARRAY_SIZE) continue; if(count - n + newcount == aMaxArraySize) continue;
Standard_Real ucons = 0.5*(pcons[n]+pcons[n+1]); Standard_Real ucons = 0.5*(pcons[n]+pcons[n+1]);
Standard_Real uc3d = 0.5*(pc3d[n]+pc3d[n+1]); Standard_Real uc3d = 0.5*(pc3d[n]+pc3d[n+1]);
CurveOnSurface.D0(ucons,Pcons); CurveOnSurface.D0(ucons,Pcons);
Projector.Perform(Pcons, uc3d); Projector.Perform(Pcons, uc3d);
if (Projector.IsDone()) { if (Projector.IsDone()) {
curp = Projector.Point().Parameter(); curp = Projector.Point().Parameter();
Standard_Real dist_2 = Projector.SquareDistance(); Standard_Real dist_2 = Projector.SquareDistance();
if(dist_2 > besttol2) besttol2 = dist_2; if(dist_2 > besttol2) besttol2 = dist_2;
projok = 1; projok = 1;
} }
else { else {
ProjectPointOnCurve(uc3d,Pcons,Tol,30,myC3d->Curve(),projok,curp); ProjectPointOnCurve(uc3d,Pcons,Tol,30,myC3d->Curve(),projok,curp);
} }
if(projok){ if(projok){
if(curp > pc3d[n] + deltamin && curp < pc3d[n+1] - deltamin){ if(curp > pc3d[n] + deltamin && curp < pc3d[n+1] - deltamin){
newpc3d[newcount] = curp; newpc3d[newcount] = curp;
newpcons[newcount] = ucons; newpcons[newcount] = ucons;
newcount ++; newcount ++;
} }
} }
else { else {
#ifdef DEB #ifdef DEB
// JAG // JAG
cout << "Projection not done" << endl; cout << "Projection not done" << endl;
#endif #endif
} }
} }
newpc3d[newcount] = pc3d[count]; newpc3d[newcount] = pc3d[count];
newpcons[newcount] = pcons[count]; newpcons[newcount] = pcons[count];
@ -818,7 +884,16 @@ void Approx_SameParameter::Build(const Standard_Real Tolerance)
tempx = pcons; tempx = pcons;
pcons = newpcons; pcons = newpcons;
newpcons = tempx; newpcons = tempx;
count = newcount;
if(count != newcount)
{
count = newcount;
hasCountChanged = Standard_True;
}
else
{
hasCountChanged = Standard_False;
}
} }
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -379,7 +379,10 @@ static Standard_Integer mk2dcurve(Draw_Interpretor& di,
if (na < 3) return 1; if (na < 3) return 1;
TopoDS_Shape S; TopoDS_Shape S;
S = DBRep::Get(a[2],TopAbs_EDGE); if (S.IsNull()) return 1; S = DBRep::Get(a[2],TopAbs_EDGE);
if (S.IsNull())
return 1;
TopoDS_Edge E = TopoDS::Edge(S); TopoDS_Edge E = TopoDS::Edge(S);
TopLoc_Location L; TopLoc_Location L;
@ -387,20 +390,38 @@ static Standard_Integer mk2dcurve(Draw_Interpretor& di,
Handle(Geom2d_Curve) C; Handle(Geom2d_Curve) C;
Handle(Geom_Surface) Surf; Handle(Geom_Surface) Surf;
Standard_Boolean hasFace = Standard_False;
if ( na == 3 ) { if ( na == 3 ) {
// get the first PCurve connected to edge E // get the first PCurve connected to edge E
BRep_Tool::CurveOnSurface(E,C,Surf,L,f,l); BRep_Tool::CurveOnSurface(E,C,Surf,L,f,l);
} }
else if ( na == 4 ) { else if ( na == 4 )
S = DBRep::Get(a[3],TopAbs_FACE); if (S.IsNull()) return 1; {
TopoDS_Face F = TopoDS::Face(S); S = DBRep::Get(a[3],TopAbs_FACE);
C = BRep_Tool::CurveOnSurface(E,F,f,l); if (S.IsNull())
{
Standard_Integer ind = Draw::Atoi(a[3]);
BRep_Tool::CurveOnSurface(E,C,Surf,L,f,l,ind);
}
else
{
hasFace = Standard_True;
TopoDS_Face F = TopoDS::Face(S);
C = BRep_Tool::CurveOnSurface(E,F,f,l);
}
} }
if (C.IsNull()) { if (C.IsNull()) {
//cout << a[2] << " has no 2d curve"; if (na == 4) cout << " on " << a[3]; //cout << a[2] << " has no 2d curve"; if (na == 4) cout << " on " << a[3];
//cout << endl; //cout << endl;
di << a[2] << " has no 2d curve"; if (na == 4) di << " on " << a[3]; di << a[2] << " has no 2d curve";
if (hasFace)
{
di << " on " << a[3];
}
di << "\n"; di << "\n";
return 1; return 1;
} }
@ -1805,7 +1826,7 @@ void BRepTest::CurveCommands(Draw_Interpretor& theCommands)
mkcurve,g); mkcurve,g);
theCommands.Add("mk2dcurve", theCommands.Add("mk2dcurve",
"mk2dcurve curve edge [face]",__FILE__, "mk2dcurve curve edge [face OR index]",__FILE__,
mk2dcurve,g); mk2dcurve,g);
theCommands.Add("mkpoint", theCommands.Add("mkpoint",

View File

@ -45,9 +45,9 @@ Extrema_GLocateExtPC::Extrema_GLocateExtPC() { }
//======================================================================= //=======================================================================
Extrema_GLocateExtPC::Extrema_GLocateExtPC (const ThePoint& P, Extrema_GLocateExtPC::Extrema_GLocateExtPC (const ThePoint& P,
const TheCurve& C, const TheCurve& C,
const Standard_Real U0, const Standard_Real U0,
const Standard_Real TolF) const Standard_Real TolF)
{ {
Initialize(C, TheCurveTool::FirstParameter(C), TheCurveTool::LastParameter(C), TolF); Initialize(C, TheCurveTool::FirstParameter(C), TheCurveTool::LastParameter(C), TolF);
Perform(P, U0); Perform(P, U0);
@ -59,11 +59,11 @@ Extrema_GLocateExtPC::Extrema_GLocateExtPC (const ThePoint& P,
//======================================================================= //=======================================================================
Extrema_GLocateExtPC::Extrema_GLocateExtPC (const ThePoint& P, Extrema_GLocateExtPC::Extrema_GLocateExtPC (const ThePoint& P,
const TheCurve& C, const TheCurve& C,
const Standard_Real U0, const Standard_Real U0,
const Standard_Real Umin, const Standard_Real Umin,
const Standard_Real Usup, const Standard_Real Usup,
const Standard_Real TolF) const Standard_Real TolF)
{ {
Initialize(C, Umin, Usup, TolF); Initialize(C, Umin, Usup, TolF);
Perform(P, U0); Perform(P, U0);
@ -77,9 +77,9 @@ Extrema_GLocateExtPC::Extrema_GLocateExtPC (const ThePoint& P,
//======================================================================= //=======================================================================
void Extrema_GLocateExtPC::Initialize(const TheCurve& C, void Extrema_GLocateExtPC::Initialize(const TheCurve& C,
const Standard_Real Umin, const Standard_Real Umin,
const Standard_Real Usup, const Standard_Real Usup,
const Standard_Real TolF) const Standard_Real TolF)
{ {
myC = (Standard_Address)&C; myC = (Standard_Address)&C;
mytol = TolF; mytol = TolF;
@ -88,9 +88,9 @@ void Extrema_GLocateExtPC::Initialize(const TheCurve& C,
type = TheCurveTool::GetType(C); type = TheCurveTool::GetType(C);
Standard_Real tolu = TheCurveTool::Resolution(C, Precision::Confusion()); Standard_Real tolu = TheCurveTool::Resolution(C, Precision::Confusion());
if ((type == GeomAbs_BSplineCurve) || if ((type == GeomAbs_BSplineCurve) ||
(type == GeomAbs_BezierCurve) || (type == GeomAbs_BezierCurve) ||
(type == GeomAbs_OtherCurve)) { (type == GeomAbs_OtherCurve)) {
myLocExtPC.Initialize(C, Umin, Usup, tolu); myLocExtPC.Initialize(C, Umin, Usup, tolu);
} }
else { else {
myExtremPC.Initialize(C, Umin, Usup, tolu); myExtremPC.Initialize(C, Umin, Usup, tolu);
@ -106,29 +106,31 @@ void Extrema_GLocateExtPC::Initialize(const TheCurve& C,
//======================================================================= //=======================================================================
void Extrema_GLocateExtPC::Perform(const ThePoint& P, void Extrema_GLocateExtPC::Perform(const ThePoint& P,
const Standard_Real U0) const Standard_Real U0)
{ {
Standard_Integer i, i1, i2, inter; Standard_Integer i, i1, i2, inter;
Standard_Real Par, valU, valU2 = RealLast(), Standard_Real Par, valU, valU2 = RealLast(),
local_u0 ; local_u0 ;
Standard_Real myintuinf=0, myintusup=0; Standard_Real myintuinf=0, myintusup=0;
local_u0 = U0 ; local_u0 = U0 ;
switch(type) { switch(type)
case GeomAbs_OtherCurve: {
case GeomAbs_BSplineCurve: { case GeomAbs_OtherCurve:
case GeomAbs_BSplineCurve:
{
// La recherche de l extremum est faite intervalle continu C2 par // La recherche de l extremum est faite intervalle continu C2 par
// intervalle continu C2 de la courbe // intervalle continu C2 de la courbe
Standard_Integer n = TheCurveTool::NbIntervals(*((TheCurve*)myC), GeomAbs_C2); Standard_Integer n = TheCurveTool::NbIntervals(*((TheCurve*)myC), GeomAbs_C2);
TColStd_Array1OfReal theInter(1, n+1); TColStd_Array1OfReal theInter(1, n+1);
TheCurveTool::Intervals(*((TheCurve*)myC), theInter, GeomAbs_C2); TheCurveTool::Intervals(*((TheCurve*)myC), theInter, GeomAbs_C2);
// //
// be gentle with the caller // be gentle with the caller
// //
if (local_u0 < myumin) { if (local_u0 < myumin) {
local_u0 = myumin ; local_u0 = myumin ;
} }
else if (local_u0 > myusup) { else if (local_u0 > myusup) {
local_u0 = myusup ; local_u0 = myusup ;
} }
// Recherche de l intervalle ou se trouve U0 // Recherche de l intervalle ou se trouve U0
Standard_Boolean found = Standard_False; Standard_Boolean found = Standard_False;
@ -140,120 +142,144 @@ void Extrema_GLocateExtPC::Perform(const ThePoint& P,
// pas, mais il n'y avait aucune raison de sortir en "return") // pas, mais il n'y avait aucune raison de sortir en "return")
myintuinf = Max(theInter(inter), myumin); myintuinf = Max(theInter(inter), myumin);
myintusup = Min(theInter(inter+1), myusup); myintusup = Min(theInter(inter+1), myusup);
if ((local_u0 >= myintuinf) && (local_u0 < myintusup)) found = Standard_True; if ((local_u0 >= myintuinf) && (local_u0 < myintusup)) found = Standard_True;
inter++; inter++;
} }
if( found ) inter--; //IFV 16.06.00 - inter is increased after found! if( found ) inter--; //IFV 16.06.00 - inter is increased after found!
// Essai sur l intervalle trouve // Essai sur l intervalle trouve
myLocExtPC.Initialize((*((TheCurve*)myC)), myintuinf, myLocExtPC.Initialize((*((TheCurve*)myC)), myintuinf,
myintusup, mytol); myintusup, mytol);
myLocExtPC.Perform(P, local_u0); myLocExtPC.Perform(P, local_u0);
myDone = myLocExtPC.IsDone(); myDone = myLocExtPC.IsDone();
if (myDone) { if (myDone) {
mypp = myLocExtPC.Point(); mypp = myLocExtPC.Point();
myismin = myLocExtPC.IsMin(); myismin = myLocExtPC.IsMin();
mydist2 = myLocExtPC.SquareDistance(); mydist2 = myLocExtPC.SquareDistance();
} }
else { else {
Standard_Integer k = 1; Standard_Integer k = 1;
// Essai sur les intervalles alentours: // Essai sur les intervalles alentours:
i1 = inter; i1 = inter;
i2 = inter; i2 = inter;
Standard_Real s1inf, s2inf, s1sup, s2sup; Standard_Real s1inf, s2inf, s1sup, s2sup;
ThePoint P1; ThePoint P1;
TheVector V1; TheVector V1;
TheCurveTool::D1(*((TheCurve*)myC), myintuinf, P1, V1); TheCurveTool::D1(*((TheCurve*)myC), myintuinf, P1, V1);
s2inf = (TheVector(P, P1)*V1); s2inf = (TheVector(P, P1)*V1);
TheCurveTool::D1(*((TheCurve*)myC), myintusup, P1, V1); TheCurveTool::D1(*((TheCurve*)myC), myintusup, P1, V1);
s1sup = (TheVector(P, P1)*V1); s1sup = (TheVector(P, P1)*V1);
while (!myDone && (i2 > 0) && (i1 <= n)) { while (!myDone && (i2 > 0) && (i1 <= n))
i1 = inter + k; {
i2 = inter - k; i1 = inter + k;
if (i1 <= n) { i2 = inter - k;
myintuinf = Max(theInter(i1), myumin); if (i1 <= n)
myintusup = Min(theInter(i1+1), myusup); {
if (myintuinf < myintusup) { myintuinf = Max(theInter(i1), myumin);
TheCurveTool::D1(*((TheCurve*)myC), myintuinf, P1, V1); myintusup = Min(theInter(i1+1), myusup);
s2sup = (TheVector(P, P1)*V1); if (myintuinf < myintusup)
if (s1sup*s2sup <= RealEpsilon()) { {
// extremum: TheCurveTool::D1(*((TheCurve*)myC), myintuinf, P1, V1);
myDone = Standard_True; s2sup = (TheVector(P, P1)*V1);
mypp.SetValues(myintuinf, P1); if (s1sup*s2sup <= RealEpsilon())
myismin = (s1sup <= 0.0); {
mydist2 = P.SquareDistance(P1); // extremum:
break; myDone = Standard_True;
} mypp.SetValues(myintuinf, P1);
TheCurveTool::D1(*((TheCurve*)myC), myintusup, P1, V1); myismin = (s1sup <= 0.0);
s1sup = (TheVector(P, P1)*V1); mydist2 = P.SquareDistance(P1);
myLocExtPC.Initialize((*((TheCurve*)myC)), myintuinf, break;
myintusup, mytol); }
myLocExtPC.Perform(P, (myintuinf + myintusup)*0.5);
myDone = myLocExtPC.IsDone(); TheCurveTool::D1(*((TheCurve*)myC), myintusup, P1, V1);
if (myDone) { s1sup = (TheVector(P, P1)*V1);
mypp = myLocExtPC.Point(); myLocExtPC.Initialize((*((TheCurve*)myC)), myintuinf,
myismin = myLocExtPC.IsMin(); myintusup, mytol);
mydist2 = myLocExtPC.SquareDistance(); myLocExtPC.Perform(P, (myintuinf + myintusup)*0.5);
break; myDone = myLocExtPC.IsDone();
} if (myDone) {
} mypp = myLocExtPC.Point();
} myismin = myLocExtPC.IsMin();
if (i2 > 0) { mydist2 = myLocExtPC.SquareDistance();
myintuinf = Max(theInter(i2), myumin); break;
myintusup = Min(theInter(i2+1), myusup); }
if (myintuinf < myintusup) { }
TheCurveTool::D1(*((TheCurve*)myC), myintusup, P1, V1); }
s1inf = (TheVector(P, P1)*V1);
if (s1inf*s2inf <= RealEpsilon()) { if (i2 > 0)
// extremum: {
myDone = Standard_True; myintuinf = Max(theInter(i2), myumin);
mypp.SetValues(myintusup, P1); myintusup = Min(theInter(i2+1), myusup);
myismin = (s1inf <= 0.0); if (myintuinf < myintusup)
mydist2 = P.SquareDistance(P1); {
break; TheCurveTool::D1(*((TheCurve*)myC), myintusup, P1, V1);
} s1inf = (TheVector(P, P1)*V1);
TheCurveTool::D1(*((TheCurve*)myC), myintuinf, P1, V1); if (s1inf*s2inf <= RealEpsilon())
s2inf = (TheVector(P, P1)*V1); {
myLocExtPC.Initialize((*((TheCurve*)myC)), myintuinf, // extremum:
myintusup, mytol); myDone = Standard_True;
myLocExtPC.Perform(P, (myintuinf+myintusup)*0.5 ); mypp.SetValues(myintusup, P1);
myDone = myLocExtPC.IsDone(); myismin = (s1inf <= 0.0);
if (myDone) { mydist2 = P.SquareDistance(P1);
mypp = myLocExtPC.Point(); break;
myismin = myLocExtPC.IsMin(); }
mydist2 = myLocExtPC.SquareDistance();
break; TheCurveTool::D1(*((TheCurve*)myC), myintuinf, P1, V1);
} s2inf = (TheVector(P, P1)*V1);
} myLocExtPC.Initialize((*((TheCurve*)myC)), myintuinf,
} myintusup, mytol);
k++; myLocExtPC.Perform(P, (myintuinf+myintusup)*0.5 );
} myDone = myLocExtPC.IsDone();
if (myDone)
{
mypp = myLocExtPC.Point();
myismin = myLocExtPC.IsMin();
mydist2 = myLocExtPC.SquareDistance();
break;
}
}
}
k++;
}
} }
} }
break;
case GeomAbs_BezierCurve: { break;
case GeomAbs_BezierCurve:
{
myLocExtPC.Perform(P, U0); myLocExtPC.Perform(P, U0);
myDone = myLocExtPC.IsDone(); myDone = myLocExtPC.IsDone();
} }
break;
default:{ break;
default:
{
myExtremPC.Perform(P); myExtremPC.Perform(P);
numberext = 0; numberext = 0;
if (myExtremPC.IsDone()) { if (myExtremPC.IsDone())
for (i = 1; i <= myExtremPC.NbExt(); i++) { {
Par = myExtremPC.Point(i).Parameter(); for (i = 1; i <= myExtremPC.NbExt(); i++)
valU = Abs(Par - U0); {
if (valU <= valU2) { Par = myExtremPC.Point(i).Parameter();
valU2 = valU; valU = Abs(Par - U0);
numberext = i; if (valU <= valU2)
myDone = Standard_True; {
} valU2 = valU;
} numberext = i;
myDone = Standard_True;
}
}
} }
if (numberext == 0) myDone = Standard_False;
if (numberext == 0)
myDone = Standard_False;
break; break;
} }
} }

View File

@ -0,0 +1,25 @@
puts "============"
puts "OCC24203"
puts "============"
puts ""
#######################################################################
## Command "sameparameter" in DRAW on attached edge set tolerance equal to 116.
#######################################################################
pload DATAEXCHANGEKERNEL
restore [locate_data_file bug24203_notspedge.brep] e1
sameparameter e1
regexp {Tolerance +MAX=([-0-9.+eE]+)} [tolerance e1] full MaxTol_1
puts "MaxTolerance = $MaxTol_1"
set MaxTol 0.20
if { $MaxTol_1 > $MaxTol } {
puts "Faulty OCC24203"
} else {
puts "OCC24203 OK"
}

View File

@ -1,5 +1,5 @@
if {[string compare $command "SplitAngle"] == 0 } { if {[string compare $command "SplitAngle"] == 0 } {
puts "TODO OCC23127 ALL: Faulty shapes in variables faulty_1 to faulty_4 " puts "TODO OCC23127 ALL: Faulty shapes in variables faulty_1 to faulty_ "
} }
restore [locate_data_file METABO9.brep] a restore [locate_data_file METABO9.brep] a