1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-06-05 11:24:17 +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 abv
parent 8db1c1c0d9
commit 4401e4e8ff
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
@ -93,7 +91,7 @@ static void ProjectPointOnCurve(const Standard_Real InitValue,
} }
param = Max(param,Curve.FirstParameter()) ; param = Max(param,Curve.FirstParameter()) ;
param = Min(param,Curve.LastParameter()) ; param = Min(param,Curve.LastParameter()) ;
Status = Standard_True ; //Status = Standard_True ;
} }
} }
while (not_done && num_iter <= NumIteration) ; while (not_done && num_iter <= NumIteration) ;
@ -109,7 +107,7 @@ 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)
@ -122,7 +120,7 @@ class Approx_SameParameter_Evaluator : public AdvApprox_EvaluatorFunction
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;
@ -173,12 +171,10 @@ static Standard_Real ComputeTolReached(const Handle(Adaptor3d_HCurve)& c3d,
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);
@ -200,7 +196,7 @@ 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,
@ -261,18 +257,18 @@ 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;
@ -306,7 +302,7 @@ 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);
@ -324,7 +320,7 @@ 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;
@ -342,7 +338,7 @@ 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;
@ -476,7 +474,7 @@ void Approx_SameParameter::Build(const Standard_Real Tolerance)
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;
} }
@ -517,17 +515,54 @@ void Approx_SameParameter::Build(const Standard_Real Tolerance)
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(projok)
{
if(curp > previousp + deltamin && curp < bornesup){ if(curp > previousp + deltamin && curp < bornesup){
initp = previousp = pc3d[count] = curp; initp = previousp = pc3d[count] = curp;
pcons[count] = pcons[ii]; pcons[count] = pcons[ii];
count++; 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;
@ -535,6 +570,7 @@ void Approx_SameParameter::Build(const Standard_Real Tolerance)
} }
} }
} }
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;
@ -652,9 +691,9 @@ void Approx_SameParameter::Build(const Standard_Real Tolerance)
#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,7 +711,7 @@ 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]);
@ -719,7 +758,7 @@ 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;
@ -738,7 +777,7 @@ 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);
@ -759,27 +798,54 @@ void Approx_SameParameter::Build(const Standard_Real Tolerance)
Continuity,11,40,ev); Continuity,11,40,ev);
if (anApproximator.IsDone() || anApproximator.HasResult()) { if (anApproximator.IsDone() || anApproximator.HasResult()) {
Adaptor3d_CurveOnSurface ACS = CurveOnSurface;
GeomLib_MakeCurvefromApprox aCurveBuilder(anApproximator) ; GeomLib_MakeCurvefromApprox aCurveBuilder(anApproximator) ;
myCurve2d = aCurveBuilder.Curve2dFromTwo1d(1,2) ; Handle(Geom2d_BSplineCurve) aC2d = aCurveBuilder.Curve2dFromTwo1d(1,2) ;
myHCurve2d = new Geom2dAdaptor_HCurve(myCurve2d); Handle(Adaptor2d_HCurve2d) aHCurve2d = new Geom2dAdaptor_HCurve(aC2d);
CurveOnSurface.Load(myHCurve2d); CurveOnSurface.Load(aHCurve2d);
myTolReached = ComputeTolReached(myC3d,CurveOnSurface,NCONTROL); 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; 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]);
@ -818,7 +884,16 @@ void Approx_SameParameter::Build(const Standard_Real Tolerance)
tempx = pcons; tempx = pcons;
pcons = newpcons; pcons = newpcons;
newpcons = tempx; newpcons = tempx;
if(count != newcount)
{
count = newcount; count = newcount;
hasCountChanged = Standard_True;
}
else
{
hasCountChanged = Standard_False;
}
} }
} }
} }

View File

@ -299,9 +299,9 @@ Standard_Boolean BRepLib::BuildCurve3d(const TopoDS_Edge& AnEdge,
const Standard_Integer MaxSegment) const Standard_Integer MaxSegment)
{ {
Standard_Integer //ErrorCode, Standard_Integer //ErrorCode,
// ReturnCode = 0, // ReturnCode = 0,
ii, ii,
// num_knots, // num_knots,
jj; jj;
TopLoc_Location LocalLoc,L[2],LC; TopLoc_Location LocalLoc,L[2],LC;
@ -319,10 +319,10 @@ Standard_Boolean BRepLib::BuildCurve3d(const TopoDS_Edge& AnEdge,
const Handle(Geom_Curve) C = BRep_Tool::Curve(AnEdge,LocalLoc,f,l); const Handle(Geom_Curve) C = BRep_Tool::Curve(AnEdge,LocalLoc,f,l);
if (!C.IsNull()) if (!C.IsNull())
return Standard_True; return Standard_True;
// //
// this should not exists but UpdateEdge makes funny things // this should not exists but UpdateEdge makes funny things
// if the edge is not same range // if the edge is not same range
// //
if (! CheckSameRange(AnEdge, if (! CheckSameRange(AnEdge,
Precision::Confusion())) { Precision::Confusion())) {
SameRange(AnEdge, SameRange(AnEdge,
@ -439,10 +439,10 @@ Standard_Boolean BRepLib::BuildCurve3d(const TopoDS_Edge& AnEdge,
TopoDS_Edge E = AnEdge ; TopoDS_Edge E = AnEdge ;
E.Closed(is_closed) ; E.Closed(is_closed) ;
if (jj == 1 ) { if (jj == 1 ) {
// //
// if there is only one curve on surface attached to the edge // if there is only one curve on surface attached to the edge
// than it can be qualified sameparameter // than it can be qualified sameparameter
// //
B.SameParameter(TopoDS::Edge(AnEdge), B.SameParameter(TopoDS::Edge(AnEdge),
Standard_True) ; Standard_True) ;
} }
@ -502,7 +502,7 @@ Standard_Boolean BRepLib::BuildCurves3d(const TopoDS_Shape& S,
Standard_Boolean BRepLib::UpdateEdgeTol(const TopoDS_Edge& AnEdge, Standard_Boolean BRepLib::UpdateEdgeTol(const TopoDS_Edge& AnEdge,
const Standard_Real MinToleranceRequested, const Standard_Real MinToleranceRequested,
const Standard_Real MaxToleranceToCheck) const Standard_Real MaxToleranceToCheck)
{ {
Standard_Integer curve_on_surface_index, Standard_Integer curve_on_surface_index,
curve_index, curve_index,
@ -633,8 +633,8 @@ Standard_Boolean BRepLib::UpdateEdgeTol(const TopoDS_Edge& AnEdge,
curve_index != curve_on_surface_index) { curve_index != curve_on_surface_index) {
has_closed_curve = has_closed_curve =
has_curve = Standard_False ; has_curve = Standard_False ;
// first = geometric_representation_ptr->First(); // first = geometric_representation_ptr->First();
// last = geometric_representation_ptr->Last(); // last = geometric_representation_ptr->Last();
local_location = geometric_representation_ptr->Location() ; local_location = geometric_representation_ptr->Location() ;
if (geometric_representation_ptr->IsCurveOnSurface()) { if (geometric_representation_ptr->IsCurveOnSurface()) {
curve2d_ptr = geometric_representation_ptr->PCurve() ; curve2d_ptr = geometric_representation_ptr->PCurve() ;
@ -701,7 +701,7 @@ Standard_Boolean BRepLib::UpdateEdgeTol(const TopoDS_Edge& AnEdge,
TE->Tolerance(edge_tolerance); TE->Tolerance(edge_tolerance);
return Standard_True ; return Standard_True ;
} }
//======================================================================= //=======================================================================
//function : UpdateEdgeTolerance //function : UpdateEdgeTolerance
//purpose : //purpose :
@ -881,17 +881,14 @@ static Standard_Real ComputeTol(const Handle(Adaptor3d_HCurve)& c3d,
TColStd_Array1OfReal dist(1,nbp+10); TColStd_Array1OfReal dist(1,nbp+10);
dist.Init(-1.); dist.Init(-1.);
Adaptor3d_CurveOnSurface cons(c2d,surf); Adaptor3d_CurveOnSurface cons(c2d,surf);
Standard_Real d2 = 0.; Standard_Real d2 = 0.;
Standard_Integer nn = nbp;
Standard_Real unsurnn = 1./nn;
Standard_Real first = c3d->FirstParameter(); Standard_Real first = c3d->FirstParameter();
Standard_Real last = c3d->LastParameter(); Standard_Real last = c3d->LastParameter();
Standard_Integer i = 0; Standard_Integer i = 0;
for(i = 0; i <= nn; i++){ for(i = 0; i <= nbp; i++){
Standard_Real t = unsurnn*i; const Standard_Real t = IntToReal(i)/IntToReal(nbp);
Standard_Real u = first*(1.-t) + last*t; const 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()) ||
@ -937,8 +934,6 @@ static Standard_Real ComputeTol(const Handle(Adaptor3d_HCurve)& c3d,
return d2; return d2;
} }
void BRepLib::SameParameter(const TopoDS_Edge& AnEdge, void BRepLib::SameParameter(const TopoDS_Edge& AnEdge,
const Standard_Real Tolerance) const Standard_Real Tolerance)
{ {
@ -1008,9 +1003,9 @@ void BRepLib::SameParameter(const TopoDS_Edge& AnEdge,
Standard_Boolean IsSameP = 1; Standard_Boolean IsSameP = 1;
Standard_Real maxdist = 0.; Standard_Real maxdist = 0.;
// Modified by skv - Thu Jun 3 12:39:19 2004 OCC5898 Begin // Modified by skv - Thu Jun 3 12:39:19 2004 OCC5898 Begin
Standard_Real anEdgeTol = BRep_Tool::Tolerance(AnEdge); Standard_Real anEdgeTol = BRep_Tool::Tolerance(AnEdge);
// Modified by skv - Thu Jun 3 12:39:20 2004 OCC5898 End // Modified by skv - Thu Jun 3 12:39:20 2004 OCC5898 End
Standard_Boolean SameRange = BRep_Tool::SameRange(AnEdge); Standard_Boolean SameRange = BRep_Tool::SameRange(AnEdge);
Standard_Boolean YaPCu = Standard_False; Standard_Boolean YaPCu = Standard_False;
It.Initialize(CList); It.Initialize(CList);
@ -1029,6 +1024,7 @@ void BRepLib::SameParameter(const TopoDS_Edge& AnEdge,
if (!PCLoc.IsIdentity() ) { if (!PCLoc.IsIdentity() ) {
S = Handle(Geom_Surface)::DownCast(S->Transformed(PCLoc.Transformation())); S = Handle(Geom_Surface)::DownCast(S->Transformed(PCLoc.Transformation()));
} }
GAS.Load(S); GAS.Load(S);
if (GCurve->IsCurveOnClosedSurface()) { if (GCurve->IsCurveOnClosedSurface()) {
PC[1] = GCurve->PCurve2(); PC[1] = GCurve->PCurve2();
@ -1202,7 +1198,7 @@ void BRepLib::SameParameter(const TopoDS_Edge& AnEdge,
if(IsBad ) { //if BSpline "bad", try to reparametrize it if(IsBad ) { //if BSpline "bad", try to reparametrize it
// by its curve length // by its curve length
// GeomAbs_Shape cont = bs2d->Continuity(); // GeomAbs_Shape cont = bs2d->Continuity();
if(cont > GeomAbs_C2) cont = GeomAbs_C2; if(cont > GeomAbs_C2) cont = GeomAbs_C2;
Standard_Integer maxdeg = bs2d->Degree(); Standard_Integer maxdeg = bs2d->Degree();
if(maxdeg == 1) maxdeg = 14; if(maxdeg == 1) maxdeg = 14;
@ -1218,7 +1214,7 @@ void BRepLib::SameParameter(const TopoDS_Edge& AnEdge,
Standard_Integer NbKnots = bs2d->NbKnots(); Standard_Integer NbKnots = bs2d->NbKnots();
TColStd_Array1OfReal Knots(1,NbKnots); TColStd_Array1OfReal Knots(1,NbKnots);
bs2d->Knots(Knots); bs2d->Knots(Knots);
// BSplCLib::Reparametrize(f3d,l3d,Knots); // BSplCLib::Reparametrize(f3d,l3d,Knots);
BSplCLib::Reparametrize(fC0,lC0,Knots); BSplCLib::Reparametrize(fC0,lC0,Knots);
bs2d->SetKnots(Knots); bs2d->SetKnots(Knots);
GAC2d.Load(bs2d,f3d,l3d); GAC2d.Load(bs2d,f3d,l3d);
@ -1234,7 +1230,7 @@ void BRepLib::SameParameter(const TopoDS_Edge& AnEdge,
if(goodpc){ if(goodpc){
// Approx_SameParameter SameP(HC,HC2d,HS,Tolerance); // Approx_SameParameter SameP(HC,HC2d,HS,Tolerance);
Standard_Real aTol = (isANA && isBSP) ? 1.e-7 : Tolerance; Standard_Real aTol = (isANA && isBSP) ? 1.e-7 : Tolerance;
Approx_SameParameter SameP(HC,HC2d,HS,aTol); Approx_SameParameter SameP(HC,HC2d,HS,aTol);
@ -1265,14 +1261,14 @@ void BRepLib::SameParameter(const TopoDS_Edge& AnEdge,
} }
else IsSameP = 0; else IsSameP = 0;
// Modified by skv - Thu Jun 3 12:39:19 2004 OCC5898 Begin // Modified by skv - Thu Jun 3 12:39:19 2004 OCC5898 Begin
if (!IsSameP) { if (!IsSameP) {
if (anEdgeTol > error) { if (anEdgeTol > error) {
maxdist = Max(maxdist, anEdgeTol); maxdist = Max(maxdist, anEdgeTol);
IsSameP = Standard_True; IsSameP = Standard_True;
} }
} }
// Modified by skv - Thu Jun 3 12:39:20 2004 OCC5898 End // Modified by skv - Thu Jun 3 12:39:20 2004 OCC5898 End
} }
} }
It.Next() ; It.Next() ;
@ -1309,8 +1305,8 @@ void BRepLib::UpdateTolerances(const TopoDS_Shape& aShape,
const Standard_Boolean verifyTolerance) const Standard_Boolean verifyTolerance)
{ {
// Harmonize tolerances // Harmonize tolerances
// with rule Tolerance(VERTEX)>=Tolerance(EDGE)>=Tolerance(FACE) // with rule Tolerance(VERTEX)>=Tolerance(EDGE)>=Tolerance(FACE)
BRep_Builder B; BRep_Builder B;
Standard_Real tol=0; Standard_Real tol=0;
if (verifyTolerance) { if (verifyTolerance) {
@ -1464,7 +1460,7 @@ void BRepLib::UpdateTolerances(const TopoDS_Shape& aShape,
//======================================================================= //=======================================================================
Standard_Boolean BRepLib::OrientClosedSolid(TopoDS_Solid& solid) Standard_Boolean BRepLib::OrientClosedSolid(TopoDS_Solid& solid)
{ {
// Set material inside the solid // Set material inside the solid
BRepClass3d_SolidClassifier where(solid); BRepClass3d_SolidClassifier where(solid);
where.PerformInfinitePoint(Precision::Confusion()); where.PerformInfinitePoint(Precision::Confusion());
if (where.State()==TopAbs_IN) { if (where.State()==TopAbs_IN) {
@ -1772,4 +1768,3 @@ void BRepLib::ReverseSortFaces (const TopoDS_Shape& Sh,
} }

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; {
S = DBRep::Get(a[3],TopAbs_FACE);
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); TopoDS_Face F = TopoDS::Face(S);
C = BRep_Tool::CurveOnSurface(E,F,f,l); 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

@ -113,17 +113,19 @@ void Extrema_GLocateExtPC::Perform(const ThePoint& P,
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_OtherCurve:
case GeomAbs_BSplineCurve: { 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 ;
} }
@ -170,16 +172,20 @@ void Extrema_GLocateExtPC::Perform(const ThePoint& P,
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; i1 = inter + k;
i2 = inter - k; i2 = inter - k;
if (i1 <= n) { if (i1 <= n)
{
myintuinf = Max(theInter(i1), myumin); myintuinf = Max(theInter(i1), myumin);
myintusup = Min(theInter(i1+1), myusup); myintusup = Min(theInter(i1+1), myusup);
if (myintuinf < myintusup) { if (myintuinf < myintusup)
{
TheCurveTool::D1(*((TheCurve*)myC), myintuinf, P1, V1); TheCurveTool::D1(*((TheCurve*)myC), myintuinf, P1, V1);
s2sup = (TheVector(P, P1)*V1); s2sup = (TheVector(P, P1)*V1);
if (s1sup*s2sup <= RealEpsilon()) { if (s1sup*s2sup <= RealEpsilon())
{
// extremum: // extremum:
myDone = Standard_True; myDone = Standard_True;
mypp.SetValues(myintuinf, P1); mypp.SetValues(myintuinf, P1);
@ -187,6 +193,7 @@ void Extrema_GLocateExtPC::Perform(const ThePoint& P,
mydist2 = P.SquareDistance(P1); mydist2 = P.SquareDistance(P1);
break; break;
} }
TheCurveTool::D1(*((TheCurve*)myC), myintusup, P1, V1); TheCurveTool::D1(*((TheCurve*)myC), myintusup, P1, V1);
s1sup = (TheVector(P, P1)*V1); s1sup = (TheVector(P, P1)*V1);
myLocExtPC.Initialize((*((TheCurve*)myC)), myintuinf, myLocExtPC.Initialize((*((TheCurve*)myC)), myintuinf,
@ -201,13 +208,17 @@ void Extrema_GLocateExtPC::Perform(const ThePoint& P,
} }
} }
} }
if (i2 > 0) {
if (i2 > 0)
{
myintuinf = Max(theInter(i2), myumin); myintuinf = Max(theInter(i2), myumin);
myintusup = Min(theInter(i2+1), myusup); myintusup = Min(theInter(i2+1), myusup);
if (myintuinf < myintusup) { if (myintuinf < myintusup)
{
TheCurveTool::D1(*((TheCurve*)myC), myintusup, P1, V1); TheCurveTool::D1(*((TheCurve*)myC), myintusup, P1, V1);
s1inf = (TheVector(P, P1)*V1); s1inf = (TheVector(P, P1)*V1);
if (s1inf*s2inf <= RealEpsilon()) { if (s1inf*s2inf <= RealEpsilon())
{
// extremum: // extremum:
myDone = Standard_True; myDone = Standard_True;
mypp.SetValues(myintusup, P1); mypp.SetValues(myintusup, P1);
@ -215,13 +226,16 @@ void Extrema_GLocateExtPC::Perform(const ThePoint& P,
mydist2 = P.SquareDistance(P1); mydist2 = P.SquareDistance(P1);
break; break;
} }
TheCurveTool::D1(*((TheCurve*)myC), myintuinf, P1, V1); TheCurveTool::D1(*((TheCurve*)myC), myintuinf, P1, V1);
s2inf = (TheVector(P, P1)*V1); s2inf = (TheVector(P, P1)*V1);
myLocExtPC.Initialize((*((TheCurve*)myC)), myintuinf, myLocExtPC.Initialize((*((TheCurve*)myC)), myintuinf,
myintusup, mytol); myintusup, mytol);
myLocExtPC.Perform(P, (myintuinf+myintusup)*0.5 ); myLocExtPC.Perform(P, (myintuinf+myintusup)*0.5 );
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();
@ -229,31 +243,43 @@ void Extrema_GLocateExtPC::Perform(const ThePoint& P,
} }
} }
} }
k++; k++;
} }
} }
} }
break; break;
case GeomAbs_BezierCurve: {
case GeomAbs_BezierCurve:
{
myLocExtPC.Perform(P, U0); myLocExtPC.Perform(P, U0);
myDone = myLocExtPC.IsDone(); myDone = myLocExtPC.IsDone();
} }
break; break;
default:{ default:
{
myExtremPC.Perform(P); myExtremPC.Perform(P);
numberext = 0; numberext = 0;
if (myExtremPC.IsDone()) { if (myExtremPC.IsDone())
for (i = 1; i <= myExtremPC.NbExt(); i++) { {
for (i = 1; i <= myExtremPC.NbExt(); i++)
{
Par = myExtremPC.Point(i).Parameter(); Par = myExtremPC.Point(i).Parameter();
valU = Abs(Par - U0); valU = Abs(Par - U0);
if (valU <= valU2) { if (valU <= valU2)
{
valU2 = valU; valU2 = valU;
numberext = i; numberext = i;
myDone = Standard_True; 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