1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-03 17:56:21 +03:00

0024889: Geom2dAPI_InterCurveCurve produces result with parameter outside the curve limits

1. DRAW-command for testing was created (see QABugs_19.cxx)
2. Alignments were changed in other files.

Main Changes are into IntCurve_IntConicConic_1.cxx file (variable isOutOfRange was added).
If found intersection point is out of range, minimal distance between corresponding ends of interval is taken. If this distance is less than tolerance, this point replaces found intersection point. Otherwise, found intersection point is ignored.
Modified QA command OCC24889 and added test case bugs/modalg_5/bug24889
This commit is contained in:
nbv 2014-05-29 16:38:47 +04:00 committed by apn
parent dc244065a9
commit 8696d65d2c
4 changed files with 986 additions and 620 deletions

View File

@ -691,15 +691,16 @@ void IntCurve_IntConicConic::Perform(const gp_Circ2d& Circle1
gp_Circ2d Circle2=_Circle2;
IntRes2d_Domain DomainCirc2=_DomainCirc2;
Standard_Boolean IndirectCircles=Standard_False;
if(Circle1.IsDirect() != _Circle2.IsDirect()) {
if(Circle1.IsDirect() != _Circle2.IsDirect())
{
IndirectCircles=Standard_True;
Circle2=_Circle2.Reversed();
DomainCirc2.SetValues(_DomainCirc2.LastPoint(),
PIpPI-_DomainCirc2.LastParameter(),
_DomainCirc2.LastTolerance(),
_DomainCirc2.FirstPoint(),
PIpPI-_DomainCirc2.FirstParameter(),
_DomainCirc2.FirstTolerance());
PIpPI-_DomainCirc2.LastParameter(),
_DomainCirc2.LastTolerance(),
_DomainCirc2.FirstPoint(),
PIpPI-_DomainCirc2.FirstParameter(),
_DomainCirc2.FirstTolerance());
DomainCirc2.SetEquivalentParameters(0.0,PIpPI);
}
@ -720,21 +721,31 @@ void IntCurve_IntConicConic::Perform(const gp_Circ2d& Circle1
Standard_Real deltat = C1Domain.Bsup-C1Domain.Binf;
if(deltat>=PIpPI) { deltat=PIpPI-1e-14; }
while(C1Domain.Binf >= PIpPI) C1Domain.Binf-=PIpPI;
while(C1Domain.Binf < 0.0) C1Domain.Binf+=PIpPI;
while(C1Domain.Binf >= PIpPI)
C1Domain.Binf-=PIpPI;
while(C1Domain.Binf < 0.0)
C1Domain.Binf+=PIpPI;
C1Domain.Bsup=C1Domain.Binf+deltat;
PeriodicInterval C2Domain(DomainCirc2);
deltat = C2Domain.Bsup-C2Domain.Binf;
if(deltat>=PIpPI) { deltat=PIpPI-1e-14; }
if(deltat>=PIpPI)
{
deltat=PIpPI-1e-14;
}
while(C2Domain.Binf >= PIpPI)
C2Domain.Binf-=PIpPI;
while(C2Domain.Binf < 0.0)
C2Domain.Binf+=PIpPI;
while(C2Domain.Binf >= PIpPI) C2Domain.Binf-=PIpPI;
while(C2Domain.Binf < 0.0) C2Domain.Binf+=PIpPI;
C2Domain.Bsup=C2Domain.Binf+deltat;
Standard_Boolean IdentCircles=Standard_False;
if(nbsol>2) {
if(nbsol>2)
{
//-- Les 2 cercles sont confondus a Tol pres
C1_Int1.SetValues(0,PIpPI);
C1_Int2.SetNull();
@ -788,7 +799,8 @@ void IntCurve_IntConicConic::Perform(const gp_Circ2d& Circle1
//----------------------------------------------------------------------
//----------- Traitement du second intervalle Geometrique C1_Int2 ----
//----------------------------------------------------------------------
if(nbsol==2) {
if(nbsol==2)
{
C1DomainAndRes=C1Domain.FirstIntersection(C1_Int2);
ProjectOnC2AndIntersectWithC2Domain(Circle1,Circle2
@ -819,14 +831,17 @@ void IntCurve_IntConicConic::Perform(const gp_Circ2d& Circle1
Standard_Real Tol2=Tol+Tol; //---- Pour eviter de toujours retourner
//des segments
Standard_Integer i ;
if(Tol < (1e-10)) Tol2 = 1e-10;
for( i=0; i<NbSolTotal ; i++) {
if(((R1 * SolutionC1[i].Length()))<=Tol2
&& ((R2 * SolutionC2[i].Length()))<=Tol2) {
if(Tol < (1e-10))
Tol2 = 1e-10;
for( i=0; i<NbSolTotal ; i++)
{
if(((R1 * SolutionC1[i].Length()) <=Tol2) &&
((R2 * SolutionC2[i].Length())<=Tol2))
{
Standard_Real t=(SolutionC1[i].Binf+SolutionC1[i].Bsup)*0.5;
SolutionC1[i].Binf=SolutionC1[i].Bsup=t;
t=(SolutionC2[i].Binf+SolutionC2[i].Bsup)*0.5;
SolutionC2[i].Binf=SolutionC2[i].Bsup=t;
}
@ -842,21 +857,91 @@ void IntCurve_IntConicConic::Perform(const gp_Circ2d& Circle1
IntRes2d_Transition T1a,T1b,T2a,T2b;
IntRes2d_Position Pos1a,Pos1b,Pos2a,Pos2b;
Standard_Boolean Opposite=((Circle1.Location().SquareDistance(Circle2.Location()))
>(R1*R1+R2*R2))? Standard_True : Standard_False;
Standard_Boolean Opposite =
((Circle1.Location().SquareDistance(Circle2.Location())) > (R1*R1+R2*R2)) ?
Standard_True : Standard_False;
//if(Circle1.IsDirect()) { cout<<" C1 Direct"<<endl; } else { cout<<" C1 INDirect"<<endl; }
//if(Circle2.IsDirect()) { cout<<" C2 Direct"<<endl; } else { cout<<" C2 INDirect"<<endl; }
for(i=0; i<NbSolTotal; i++) {
for(i=0; i<NbSolTotal; i++)
{
Standard_Real C2inf=(Opposite)? SolutionC2[i].Bsup : SolutionC2[i].Binf;
Standard_Real C2sup=(Opposite)? SolutionC2[i].Binf : SolutionC2[i].Bsup;
Standard_Real C1tinf = SolutionC1[i].Binf, C2tinf = C2inf;
Standard_Real C1inf=NormalizeOnCircleDomain(C1tinf,DomainCirc1);
C2inf=NormalizeOnCircleDomain(C2tinf,DomainCirc2);
Standard_Real C1inf=NormalizeOnCircleDomain(SolutionC1[i].Binf,DomainCirc1);
C2inf=NormalizeOnCircleDomain(C2inf,DomainCirc2);
Standard_Boolean isOutOfRange = Standard_False;
if(C1inf < DomainCirc1.FirstParameter())
{
if(C1tinf < DomainCirc1.FirstParameter())
{
C1inf = DomainCirc1.FirstParameter();
isOutOfRange = Standard_True;
}
else
{
C1inf = C1tinf;
}
}
if(IndirectCircles) {
if(C1inf > DomainCirc1.LastParameter())
{
if(C1tinf > DomainCirc1.LastParameter())
{
C1inf = DomainCirc1.LastParameter();
isOutOfRange = Standard_True;
}
else
{
C1inf = C1tinf;
}
}
if(C2inf < DomainCirc2.FirstParameter())
{
if(C2tinf < DomainCirc2.FirstParameter())
{
C2inf = DomainCirc2.FirstParameter();
isOutOfRange = Standard_True;
}
else
{
C2inf = C2tinf;
}
}
if(C2inf > DomainCirc2.LastParameter())
{
if(C2tinf > DomainCirc2.LastParameter())
{
C2inf = DomainCirc2.LastParameter();
isOutOfRange = Standard_True;
}
else
{
C2inf = C2tinf;
}
}
if(isOutOfRange)
{
gp_Pnt2d aP1, aP2;
gp_Vec2d aV11, aV12;
gp_Vec2d aV21, aV22;
ElCLib::CircleD2(C1inf,Axis2C1,R1,aP1,aV11,aV12);
ElCLib::CircleD2(C2inf,Axis2C2,R2,aP2,aV21,aV22);
if(aP1.SquareDistance(aP2) > Tol2*Tol2)
{//there are not any solutions in given parametric range.
continue;
}
}
if(IndirectCircles)
{
ElCLib::CircleD2(C1inf,Axis2C1,R1,P1a,Tan1,Norm1);
ElCLib::CircleD2(C2inf,Axis2C2,R2,P2a,Tan2,Norm2);
Tan2.Reverse();
@ -868,47 +953,52 @@ void IntCurve_IntConicConic::Perform(const gp_Circ2d& Circle1
IntRes2d_IntersectionPoint NewPoint1(P1a,C1inf,PIpPI-C2inf,T1a,T2a,Standard_False);
if((SolutionC1[i].Length()>0.0 ) || (SolutionC2[i].Length() >0.0)) {
//-- On traite un intervalle non reduit a un point
Standard_Real C1sup=NormalizeOnCircleDomain(SolutionC1[i].Bsup,DomainCirc1);
if(C1sup<C1inf) C1sup+=PIpPI;
C2sup=NormalizeOnCircleDomain(C2sup,DomainCirc2);
ElCLib::CircleD2(C1sup,Axis2C1,R1,P1b,Tan1,Norm1);
ElCLib::CircleD2(C2sup,Axis2C2,R2,P2b,Tan2,Norm2);
Tan2.Reverse();
if((SolutionC1[i].Length()>0.0 ) || (SolutionC2[i].Length() >0.0))
{
//-- On traite un intervalle non reduit a un point
Standard_Real C1sup=NormalizeOnCircleDomain(SolutionC1[i].Bsup,DomainCirc1);
if(C1sup<C1inf) C1sup+=PIpPI;
C2sup=NormalizeOnCircleDomain(C2sup,DomainCirc2);
IntImpParGen::DeterminePosition(Pos1b,DomainCirc1,P1b,C1sup);
IntImpParGen::DeterminePosition(Pos2b,_DomainCirc2,P2b,PIpPI-C2sup);
Determine_Transition_LC(Pos1b,Tan1,Norm1,T1b , Pos2b,Tan2,Norm2,T2b, Tol);
//--------------------------------------------------
if(Opposite) {
if(nbsol!=3) {
if(C2inf<C2sup) C2inf+=PIpPI;
}
}
else {
if(nbsol!=3) {
if(C2sup<C2inf) C2sup+=PIpPI;
}
}
IntRes2d_IntersectionPoint NewPoint2(P1b,C1sup,PIpPI-C2sup,T1b,T2b,Standard_False);
IntRes2d_IntersectionSegment NewSeg(NewPoint1,NewPoint2,
(Opposite==Standard_True)? Standard_False : Standard_True,
Standard_False);
Append(NewSeg);
ElCLib::CircleD2(C1sup,Axis2C1,R1,P1b,Tan1,Norm1);
ElCLib::CircleD2(C2sup,Axis2C2,R2,P2b,Tan2,Norm2);
Tan2.Reverse();
IntImpParGen::DeterminePosition(Pos1b,DomainCirc1,P1b,C1sup);
IntImpParGen::DeterminePosition(Pos2b,_DomainCirc2,P2b,PIpPI-C2sup);
Determine_Transition_LC(Pos1b,Tan1,Norm1,T1b , Pos2b,Tan2,Norm2,T2b, Tol);
//--------------------------------------------------
if(Opposite)
{
if(nbsol!=3)
{
if(C2inf<C2sup)
C2inf+=PIpPI;
}
}
else
{
if(nbsol!=3)
{
if(C2sup<C2inf) C2sup+=PIpPI;
}
}
IntRes2d_IntersectionPoint NewPoint2(P1b,C1sup,PIpPI-C2sup,T1b,T2b,Standard_False);
IntRes2d_IntersectionSegment NewSeg(NewPoint1,NewPoint2,
(Opposite==Standard_True)? Standard_False : Standard_True,
Standard_False);
Append(NewSeg);
}
else {
Append(NewPoint1);
else
{
Append(NewPoint1);
}
}
else {
else
{
ElCLib::CircleD2(C1inf,Axis2C1,R1,P1a,Tan1,Norm1);
ElCLib::CircleD2(C2inf,Axis2C2,R2,P2a,Tan2,Norm2);
@ -919,39 +1009,46 @@ void IntCurve_IntConicConic::Perform(const gp_Circ2d& Circle1
IntRes2d_IntersectionPoint NewPoint1(P1a,C1inf,C2inf,T1a,T2a,Standard_False);
if((SolutionC1[i].Length()>0.0 ) || (SolutionC2[i].Length() >0.0)) {
//-- On traite un intervalle non reduit a un point
Standard_Real C1sup=NormalizeOnCircleDomain(SolutionC1[i].Bsup,DomainCirc1);
if(C1sup<C1inf) C1sup+=PIpPI;
C2sup=NormalizeOnCircleDomain(C2sup,DomainCirc2);
ElCLib::CircleD2(C1sup,Axis2C1,R1,P1b,Tan1,Norm1);
ElCLib::CircleD2(C2sup,Axis2C2,R2,P2b,Tan2,Norm2);
IntImpParGen::DeterminePosition(Pos1b,DomainCirc1,P1b,C1sup);
IntImpParGen::DeterminePosition(Pos2b,DomainCirc2,P2b,C2sup);
Determine_Transition_LC(Pos1b,Tan1,Norm1,T1b , Pos2b,Tan2,Norm2,T2b, Tol);
//--------------------------------------------------
if(Opposite) {
if(nbsol!=3) {
if(C2inf<C2sup) C2inf+=PIpPI;
}
}
else {
if(nbsol!=3) {
if(C2sup<C2inf) C2sup+=PIpPI;
}
}
IntRes2d_IntersectionPoint NewPoint2(P1b,C1sup,C2sup,T1b,T2b,Standard_False);
IntRes2d_IntersectionSegment NewSeg(NewPoint1,NewPoint2,Opposite,Standard_False);
Append(NewSeg);
if((SolutionC1[i].Length()>0.0 ) || (SolutionC2[i].Length() >0.0))
{
//-- On traite un intervalle non reduit a un point
Standard_Real C1sup=NormalizeOnCircleDomain(SolutionC1[i].Bsup,DomainCirc1);
if(C1sup<C1inf) C1sup+=PIpPI;
C2sup=NormalizeOnCircleDomain(C2sup,DomainCirc2);
ElCLib::CircleD2(C1sup,Axis2C1,R1,P1b,Tan1,Norm1);
ElCLib::CircleD2(C2sup,Axis2C2,R2,P2b,Tan2,Norm2);
IntImpParGen::DeterminePosition(Pos1b,DomainCirc1,P1b,C1sup);
IntImpParGen::DeterminePosition(Pos2b,DomainCirc2,P2b,C2sup);
Determine_Transition_LC(Pos1b,Tan1,Norm1,T1b , Pos2b,Tan2,Norm2,T2b, Tol);
//--------------------------------------------------
if(Opposite)
{
if(nbsol!=3)
{
if(C2inf<C2sup)
C2inf+=PIpPI;
}
}
else
{
if(nbsol!=3)
{
if(C2sup<C2inf)
C2sup+=PIpPI;
}
}
IntRes2d_IntersectionPoint NewPoint2(P1b,C1sup,C2sup,T1b,T2b,Standard_False);
IntRes2d_IntersectionSegment NewSeg(NewPoint1,NewPoint2,Opposite,Standard_False);
Append(NewSeg);
}
else {
Append(NewPoint1);
else
{
Append(NewPoint1);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -2268,6 +2268,59 @@ static Standard_Integer OCC24834 (Draw_Interpretor& di, Standard_Integer n, cons
return 0;
}
#include <Geom2dAPI_InterCurveCurve.hxx>
#include <IntRes2d_IntersectionPoint.hxx>
//=======================================================================
//function : OCC24889
//purpose :
//=======================================================================
static Standard_Integer OCC24889 (Draw_Interpretor& theDI,
Standard_Integer /*theNArg*/,
const char** /*theArgs*/)
{
// Curves
Handle( Geom2d_Circle ) aCircle1 = new Geom2d_Circle(
gp_Ax22d( gp_Pnt2d( 25, -25 ), gp_Dir2d( 1, 0 ), gp_Dir2d( -0, 1 ) ), 155 );
Handle( Geom2d_Circle ) aCircle2 = new Geom2d_Circle(
gp_Ax22d( gp_Pnt2d( 25, 25 ), gp_Dir2d( 1, 0 ), gp_Dir2d( -0, 1 ) ), 155 );
Handle( Geom2d_TrimmedCurve ) aTrim[2] = {
new Geom2d_TrimmedCurve( aCircle1, 1.57079632679490, 2.97959469729228 ),
new Geom2d_TrimmedCurve( aCircle2, 3.30359060633978, 4.71238898038469 )
};
DrawTrSurf::Set("c_1", aTrim[0]);
DrawTrSurf::Set("c_2", aTrim[1]);
// Intersection
const Standard_Real aTol = Precision::Confusion();
Geom2dAPI_InterCurveCurve aIntTool( aTrim[0], aTrim[1], aTol );
const IntRes2d_IntersectionPoint& aIntPnt =
aIntTool.Intersector().Point( 1 );
gp_Pnt2d aIntRes = aIntTool.Point( 1 );
Standard_Real aPar[2] = {
aIntPnt.ParamOnFirst(),
aIntPnt.ParamOnSecond()
};
//theDI.precision( 5 );
theDI << "Int point: X = " << aIntRes.X() << "; Y = " << aIntRes.Y() << "\n";
for (int i = 0; i < 2; ++i)
{
theDI << "Curve " << i << ": FirstParam = " << aTrim[i]->FirstParameter() <<
"; LastParam = " << aTrim[i]->LastParameter() <<
"; IntParameter = " << aPar[i] << "\n";
}
return 0;
}
void QABugs::Commands_19(Draw_Interpretor& theCommands) {
const char *group = "QABugs";
@ -2309,6 +2362,7 @@ void QABugs::Commands_19(Draw_Interpretor& theCommands) {
theCommands.Add ("OCC24565", "OCC24565 FileNameIGS FileNameSTOR", __FILE__, OCC24565, group);
theCommands.Add ("OCC24755", "OCC24755", __FILE__, OCC24755, group);
theCommands.Add ("OCC24834", "OCC24834", __FILE__, OCC24834, group);
theCommands.Add ("OCC24889", "OCC24889", __FILE__, OCC24889, group);
theCommands.Add ("OCC23951", "OCC23951", __FILE__, OCC23951, group);
theCommands.Add ("OCC24931", "OCC24931", __FILE__, OCC24931, group);
return;

View File

@ -0,0 +1,38 @@
puts "=========="
puts "OCC24889"
puts "=========="
puts ""
#####################################################################################
# Geom2dAPI_InterCurveCurve produces result with parameter outside the curve limits
#####################################################################################
pload QAcommands
set info [OCC24889]
regexp {Curve 0: +FirstParam += +([-0-9.+eE]+); +LastParam += +([-0-9.+eE]+); +IntParameter += +([-0-9.+eE]+)} $info full first1 last1 intp1
regexp {Curve 1: +FirstParam += +([-0-9.+eE]+); +LastParam += +([-0-9.+eE]+); +IntParameter += +([-0-9.+eE]+)} $info full first2 last2 intp2
if { $intp1 >= $first1 && $intp1 <= $last1 } {
puts "OK: IntParameter1 inside the curve limits"
} else {
puts "Error: IntParameter1 outside the curve limits"
}
if { $intp2 >= $first2 && $intp2 <= $last2 } {
puts "OK: IntParameter2 inside the curve limits"
} else {
puts "Error: IntParameter2 outside the curve limits"
}
2dcvalue c_1 $intp1 xx1 yy1
2dcvalue c_2 $intp2 xx2 yy2
dump xx1 yy1
dump xx2 yy2
set dist_val [dval (xx1-xx2)*(xx1-xx2)+(yy1-yy2)*(yy1-yy2)]
if { $dist_val < 1.0e-14 } {
puts "OK: point distance is good"
} else {
puts "Error: point distance is wrong"
}