1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-29 14:00:49 +03:00

0024915: Wrong intersection curves between two cylinders

Existing method of Cylinder-Cylinder intersection computing is based on finding the analytic line (as a function of one argument) and converting one into the walking-line with set of equidistant (along the line parameter) points.

The main advantage of applied method is using adaptively computed step. Necessary step is computed into every point of the obtained walking-line. At that we receive final walking-line directly (without preliminary analytic line) and we determine moments more precisely, when it should be split (see IntPatch_ImpImpIntersection_4.gxx).

The main disadvantages is bad working this method for non-trimmed cylinders (with infinite bounds), because step value is depend on the boundaries values.

More over, new method always returns walking-line, while intersection result can be an analytic curve (lines, circle, ellipse). That is NO good. Therefore, analytic curve is computed by existing method.

In conclusion, in spite of covering almost all more often meeting cases, new method has limited application. Then we should use the existing old method.

Additionally, method MinMax() is added (see Standard_Real.hxx file). It uses into new algorithm.

Some test cases is changed according to their new behavior.

Test case for issue CR24915 is added.

Into GeometryTest_APICommands.cxx only tabulations were chaged.

"Extending" of isolines (see Geom2dHatch_Hatcher.cxx).

Small correction of test case for issue CR24915.
This commit is contained in:
nbv
2014-08-15 14:35:04 +04:00
committed by bugmaster
parent d15f387afa
commit ecc4f1489d
22 changed files with 2800 additions and 827 deletions

View File

@@ -951,8 +951,11 @@ void Geom2dHatch_Hatcher::ComputeDomains (const Standard_Integer IndH)
Hatching.IsDone (Standard_False) ;
if (!Hatching.TrimDone()) Trim (IndH) ;
if (Hatching.Status() != HatchGen_NoProblem) return ;
if (!Hatching.TrimDone())
Trim (IndH);
if (Hatching.Status() != HatchGen_NoProblem)
return;
Standard_Boolean Points = myKeepPoints ;
Standard_Boolean Segments = myKeepSegments ;
@@ -962,19 +965,23 @@ void Geom2dHatch_Hatcher::ComputeDomains (const Standard_Integer IndH)
Standard_Integer NbPnt = Hatching.NbPoints() ;
Standard_Integer IPnt =1;
if (NbPnt == 0) {
if(NbPnt == 0)
{
//-- cout << "The hatching # " << setw(3) << IndH << " has to be classified" << endl ;
Geom2dHatch_Classifier Classifier(myElements,Hatching.ClassificationPoint(),0.0000001);
if(Classifier.State() == TopAbs_IN) {
if(Classifier.State() == TopAbs_IN)
{
HatchGen_Domain domain ;
Hatching.AddDomain (domain) ;
}
Hatching.IsDone (Standard_True) ;
return ;
}
//for (Standard_Integer IPnt = 1 ; IPnt <= NbPnt ; IPnt++) {
for (IPnt = 1 ; IPnt <= NbPnt ; IPnt++) {
for (IPnt = 1 ; IPnt <= NbPnt ; IPnt++)
{
Standard_Boolean NoDomain = Hatching.NbDomains() == 0 ;
Standard_Boolean FirstPoint = IPnt == 1 ;
Standard_Boolean LastPoint = IPnt == NbPnt ;
@@ -1003,34 +1010,52 @@ void Geom2dHatch_Hatcher::ComputeDomains (const Standard_Integer IndH)
// Initialisations dues au premier point.
//-----------------------------------------------------------------------
if (FirstPoint) {
if (FirstPoint)
{
SavPnt = Standard_False ;
ISav = 0 ;
NbOpenedSegments = 0 ;
if (SegmentEnd && SegmentBegin) {
if (StateAfter == TopAbs_UNKNOWN) StateAfter = TopAbs_IN ;
if (StateBefore == TopAbs_UNKNOWN) StateBefore = TopAbs_IN ;
if (Segments) {
SavPnt = Standard_True ;
ISav = 0 ;
}
} else if (SegmentEnd) {
if (StateAfter == TopAbs_UNKNOWN) StateAfter = TopAbs_IN ;
if (Segments) {
SavPnt = Standard_True ;
ISav = 0 ;
}
} else if (SegmentBegin) {
if (StateBefore == TopAbs_UNKNOWN) StateBefore = TopAbs_IN ;
if (StateBefore == TopAbs_IN) {
SavPnt = Standard_True ;
ISav = 0 ;
}
} else {
if (StateBefore == TopAbs_IN) {
SavPnt = Standard_True ;
ISav = 0 ;
}
if (SegmentEnd && SegmentBegin)
{
if (StateAfter == TopAbs_UNKNOWN)
StateAfter = TopAbs_IN ;
if (StateBefore == TopAbs_UNKNOWN)
StateBefore = TopAbs_IN ;
if (Segments)
{
SavPnt = Standard_True ;
ISav = 0 ;
}
}
else if (SegmentEnd)
{
if (StateAfter == TopAbs_UNKNOWN)
StateAfter = TopAbs_IN ;
if (Segments)
{
SavPnt = Standard_True ;
ISav = 0 ;
}
}
else if (SegmentBegin)
{
if (StateBefore == TopAbs_UNKNOWN)
StateBefore = TopAbs_IN ;
if (StateBefore == TopAbs_IN)
{
SavPnt = Standard_True ;
ISav = 0 ;
}
}
else
{
if (StateBefore == TopAbs_IN)
{
SavPnt = Standard_True ;
ISav = 0 ;
}
}
}
@@ -1038,15 +1063,28 @@ void Geom2dHatch_Hatcher::ComputeDomains (const Standard_Integer IndH)
// Initialisations dues au dernier point.
//-----------------------------------------------------------------------
if (LastPoint) {
if (SegmentEnd && SegmentBegin) {
if (StateAfter == TopAbs_UNKNOWN) StateAfter = TopAbs_IN ;
if (StateBefore == TopAbs_UNKNOWN) StateBefore = TopAbs_IN ;
} else if (SegmentEnd) {
if (StateAfter == TopAbs_UNKNOWN) StateAfter = TopAbs_IN ;
} else if (SegmentBegin) {
if (StateBefore == TopAbs_UNKNOWN) StateBefore = TopAbs_IN ;
} else {
if (LastPoint)
{
if (SegmentEnd && SegmentBegin)
{
if (StateAfter == TopAbs_UNKNOWN)
StateAfter = TopAbs_IN ;
if (StateBefore == TopAbs_UNKNOWN)
StateBefore = TopAbs_IN ;
}
else if (SegmentEnd)
{
if (StateAfter == TopAbs_UNKNOWN)
StateAfter = TopAbs_IN ;
}
else if (SegmentBegin)
{
if (StateBefore == TopAbs_UNKNOWN)
StateBefore = TopAbs_IN ;
}
else
{
}
}
@@ -1056,337 +1094,461 @@ void Geom2dHatch_Hatcher::ComputeDomains (const Standard_Integer IndH)
Standard_Boolean ToAppend = Standard_False ;
if (SegmentEnd && SegmentBegin) {
if (SegmentEnd && SegmentBegin)
{
if (StateBefore != TopAbs_IN && StateAfter != TopAbs_IN)
{
Hatching.Status (HatchGen_IncompatibleStates) ;
return ;
}
if (StateBefore != TopAbs_IN && StateAfter != TopAbs_IN) {
Hatching.Status (HatchGen_IncompatibleStates) ;
return ;
}
if (Points) {
if (Segments) {
if (!SavPnt) {
if(NoDomain) {
Hatching.Status (HatchGen_IncoherentParity) ;
}
else {
Hatching.IsDone(Standard_True);
}
return ;
}
if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
domain.SetSecondPoint (CurPnt) ;
ToAppend = Standard_True ;
SavPnt = Standard_True ;
ISav = IPnt ;
} else {
Standard_Boolean isININ = (StateBefore == TopAbs_IN && StateAfter == TopAbs_IN);
if (SavPnt && !isININ) {
if(NoDomain) {
Hatching.Status (HatchGen_IncoherentParity) ;
}
else {
Hatching.IsDone(Standard_True);
}
return ;
}
domain.SetPoints (CurPnt, CurPnt) ;
ToAppend = Standard_True ;
SavPnt = Standard_False ;
ISav = 0 ;
}
}
} else if (SegmentEnd) {
if (Points)
{
if (Segments)
{
if (!SavPnt)
{
if(NoDomain)
{
Hatching.Status (HatchGen_IncoherentParity) ;
}
else
{
Hatching.IsDone(Standard_True);
}
return ;
}
if (Segments) {
if (StateAfter == TopAbs_OUT) {
if (!SavPnt) {
if(NoDomain) {
Hatching.Status (HatchGen_IncoherentParity) ;
}
else {
Hatching.IsDone(Standard_True);
}
return ;
}
if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
domain.SetSecondPoint (CurPnt) ;
ToAppend = Standard_True ;
} else {
if (Points) {
if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
domain.SetSecondPoint (CurPnt) ;
ToAppend = Standard_True ;
SavPnt = Standard_True ;
ISav = IPnt ;
}
}
} else {
if (StateAfter == TopAbs_IN) {
SavPnt = Standard_True ;
ISav = IPnt ;
}
if (ISav != 0)
domain.SetFirstPoint (Hatching.Point(ISav)) ;
domain.SetSecondPoint (CurPnt) ;
ToAppend = Standard_True ;
SavPnt = Standard_True ;
ISav = IPnt ;
}
else
{
Standard_Boolean isININ = (StateBefore == TopAbs_IN && StateAfter == TopAbs_IN);
if (SavPnt && !isININ)
{
if(NoDomain)
{
Hatching.Status (HatchGen_IncoherentParity) ;
}
else
{
Hatching.IsDone(Standard_True);
}
return ;
}
domain.SetPoints (CurPnt, CurPnt) ;
ToAppend = Standard_True ;
SavPnt = Standard_False ;
ISav = 0 ;
}
}
}
else if (SegmentEnd)
{
if (Segments)
{
if (StateAfter == TopAbs_OUT)
{
if (!SavPnt)
{
if(NoDomain)
{
Hatching.Status (HatchGen_IncoherentParity) ;
}
else
{
Hatching.IsDone(Standard_True);
}
return ;
}
if (ISav != 0)
domain.SetFirstPoint (Hatching.Point(ISav)) ;
domain.SetSecondPoint (CurPnt) ;
ToAppend = Standard_True ;
}
else
{
if (Points)
{
if (ISav != 0)
domain.SetFirstPoint (Hatching.Point(ISav)) ;
domain.SetSecondPoint (CurPnt) ;
ToAppend = Standard_True ;
SavPnt = Standard_True ;
ISav = IPnt ;
}
}
}
else
{
if (StateAfter == TopAbs_IN)
{
SavPnt = Standard_True ;
ISav = IPnt ;
}
}
NbOpenedSegments-- ;
} else if (SegmentBegin) {
}
else if (SegmentBegin)
{
if (Segments)
{
if (StateBefore == TopAbs_OUT)
{
SavPnt = Standard_True ;
ISav = IPnt ;
}
else
{
if (Points)
{
if (!SavPnt)
{
if(NoDomain)
{
Hatching.Status (HatchGen_IncoherentParity) ;
}
else
{
Hatching.IsDone(Standard_True);
}
if (Segments) {
if (StateBefore == TopAbs_OUT) {
SavPnt = Standard_True ;
ISav = IPnt ;
} else {
if (Points) {
if (!SavPnt) {
if(NoDomain) {
Hatching.Status (HatchGen_IncoherentParity) ;
}
else {
Hatching.IsDone(Standard_True);
}
return ;
}
if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
domain.SetSecondPoint (CurPnt) ;
ToAppend = Standard_True ;
SavPnt = Standard_True ;
ISav = IPnt ;
}
}
} else {
if (StateBefore == TopAbs_IN) {
if (!SavPnt) {
if(NoDomain) {
Hatching.Status (HatchGen_IncoherentParity) ;
}
else {
Hatching.IsDone(Standard_True);
}
return ;
}
if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
domain.SetSecondPoint (CurPnt) ;
ToAppend = Standard_True ;
// Modified by Sergey KHROMOV - Fri Jan 5 12:05:30 2001
// SavPnt = Standard_False ;
// ISav = 0 ;
SavPnt = Standard_True ;
ISav = IPnt ;
// Modified by Sergey KHROMOV - Fri Jan 5 12:05:31 2001
}
return ;
}
if (ISav != 0)
domain.SetFirstPoint (Hatching.Point(ISav)) ;
domain.SetSecondPoint (CurPnt) ;
ToAppend = Standard_True ;
SavPnt = Standard_True ;
ISav = IPnt ;
}
}
}
else
{
if (StateBefore == TopAbs_IN)
{
if (!SavPnt)
{
if(NoDomain)
{
Hatching.Status (HatchGen_IncoherentParity) ;
}
else
{
Hatching.IsDone(Standard_True);
}
return ;
}
if (ISav != 0)
domain.SetFirstPoint (Hatching.Point(ISav)) ;
domain.SetSecondPoint (CurPnt) ;
ToAppend = Standard_True ;
//Modified by Sergey KHROMOV - Fri Jan 5 12:05:30 2001
//SavPnt = Standard_False ;
//ISav = 0 ;
SavPnt = Standard_True ;
ISav = IPnt ;
//Modified by Sergey KHROMOV - Fri Jan 5 12:05:31 2001
}
}
NbOpenedSegments++ ;
} else {
}
else
{
//-- ???????????????????????????????????????????????????????????????????????????
//-- Solution provisoire (lbr le 11 Aout 97 )
//-- si On a 2 points dont des points OUT OUT ou IN IN qui delimitent une isos
//-- on transforme les transitions
if (StateBefore == TopAbs_OUT && StateAfter == TopAbs_OUT) {
if(NbPnt == 2) {
if(FirstPoint)
StateAfter = TopAbs_IN;
else
StateBefore = TopAbs_IN;
}
if (StateBefore == TopAbs_OUT && StateAfter == TopAbs_OUT)
{
if(NbPnt == 2)
{
if(FirstPoint)
StateAfter = TopAbs_IN;
else
StateBefore = TopAbs_IN;
}
}
//-- ???????????????????????????????????????????????????????????????????????????
if (StateBefore == TopAbs_OUT && StateAfter == TopAbs_OUT) {
if(StateBefore == TopAbs_OUT && StateAfter == TopAbs_OUT)
{
if (SavPnt)
{
if(NoDomain)
{
Hatching.Status (HatchGen_IncoherentParity) ;
}
else
{
Hatching.IsDone(Standard_True);
}
if (SavPnt) {
if(NoDomain) {
Hatching.Status (HatchGen_IncoherentParity) ;
}
else {
Hatching.IsDone(Standard_True);
}
return ;
}
if (Points) {
domain.SetPoints (CurPnt, CurPnt) ;
ToAppend = Standard_True ;
SavPnt = Standard_True ;
ISav = IPnt ;
}
} else if (StateBefore == TopAbs_OUT && StateAfter == TopAbs_IN ) {
SavPnt = Standard_True ;
ISav = IPnt ;
} else if (StateBefore == TopAbs_IN && StateAfter == TopAbs_OUT) {
if (!SavPnt) {
if(NoDomain) {
Hatching.Status (HatchGen_IncoherentParity) ;
}
else {
Hatching.IsDone(Standard_True);
}
return ;
}
if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
domain.SetSecondPoint (CurPnt) ;
ToAppend = Standard_True ;
SavPnt = Standard_False ;
ISav = 0 ;
} else if (StateBefore == TopAbs_IN && StateAfter == TopAbs_IN ) {
if (Points) {
if (NbOpenedSegments == 0) {
if (!SavPnt) {
if(NoDomain) {
Hatching.Status (HatchGen_IncoherentParity) ;
}
else {
Hatching.IsDone(Standard_True);
}
return ;
}
if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
domain.SetSecondPoint (CurPnt) ;
ToAppend = Standard_True ;
SavPnt = Standard_True ;
ISav = IPnt ;
} else {
if (Segments) {
if (!SavPnt) {
if(NoDomain) {
Hatching.Status (HatchGen_IncoherentParity) ;
}
else {
Hatching.IsDone(Standard_True);
}
return ;
}
if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
domain.SetSecondPoint (CurPnt) ;
ToAppend = Standard_True ;
SavPnt = Standard_True ;
ISav = IPnt ;
} else {
if (SavPnt) {
if(NoDomain) {
Hatching.Status (HatchGen_IncoherentParity) ;
}
else {
Hatching.IsDone(Standard_True);
}
return ;
}
domain.SetPoints (CurPnt, CurPnt) ;
ToAppend = Standard_True ;
SavPnt = Standard_False ;
ISav = 0 ;
}
}
}
} else {
Hatching.Status (HatchGen_IncompatibleStates) ;
return ;
return ;
}
if (Points)
{
domain.SetPoints (CurPnt, CurPnt) ;
ToAppend = Standard_True ;
SavPnt = Standard_True ;
ISav = IPnt ;
}
}
else if (StateBefore == TopAbs_OUT && StateAfter == TopAbs_IN )
{
SavPnt = Standard_True ;
ISav = IPnt ;
}
else if (StateBefore == TopAbs_IN && StateAfter == TopAbs_OUT)
{
if (!SavPnt)
{
if(NoDomain)
{
Hatching.Status (HatchGen_IncoherentParity) ;
}
else
{
Hatching.IsDone(Standard_True);
}
return ;
}
if (ISav != 0)
domain.SetFirstPoint (Hatching.Point(ISav));
domain.SetSecondPoint (CurPnt) ;
ToAppend = Standard_True ;
SavPnt = Standard_False ;
ISav = 0 ;
}
else if (StateBefore == TopAbs_IN && StateAfter == TopAbs_IN )
{
if (Points)
{
if (NbOpenedSegments == 0)
{
if (!SavPnt)
{
if(NoDomain)
{
Hatching.Status (HatchGen_IncoherentParity) ;
}
else
{
Hatching.IsDone(Standard_True);
}
//return;
continue;
}
if (ISav != 0)
domain.SetFirstPoint (Hatching.Point(ISav)) ;
domain.SetSecondPoint (CurPnt) ;
ToAppend = Standard_True ;
SavPnt = Standard_True ;
ISav = IPnt ;
}
else
{
if (Segments)
{
if (!SavPnt)
{
if(NoDomain)
{
Hatching.Status (HatchGen_IncoherentParity) ;
}
else
{
Hatching.IsDone(Standard_True);
}
return ;
}
if (ISav != 0)
domain.SetFirstPoint (Hatching.Point(ISav)) ;
domain.SetSecondPoint (CurPnt) ;
ToAppend = Standard_True ;
SavPnt = Standard_True ;
ISav = IPnt ;
}
else
{
if (SavPnt)
{
if(NoDomain)
{
Hatching.Status (HatchGen_IncoherentParity) ;
}
else
{
Hatching.IsDone(Standard_True);
}
return ;
}
domain.SetPoints (CurPnt, CurPnt) ;
ToAppend = Standard_True ;
SavPnt = Standard_False ;
ISav = 0 ;
}
}
}
}
else
{
Hatching.Status (HatchGen_IncompatibleStates) ;
return ;
}
}
//-----------------------------------------------------------------------
// Ajout du domaine.
//-----------------------------------------------------------------------
if (ToAppend) Hatching.AddDomain (domain) ;
if (ToAppend)
Hatching.AddDomain (domain) ;
//-----------------------------------------------------------------------
// Traitement lie au dernier point.
//-----------------------------------------------------------------------
if (LastPoint) {
if (LastPoint)
{
domain.SetPoints () ;
ToAppend = Standard_False ;
if (SegmentEnd && SegmentBegin) {
if (Segments) {
if (!SavPnt) {
if(NoDomain) {
Hatching.Status (HatchGen_IncoherentParity) ;
}
else {
Hatching.IsDone(Standard_True);
}
return ;
}
if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
ToAppend = Standard_True ;
}
} else if (SegmentEnd) {
if (SegmentEnd && SegmentBegin)
{
if (Segments)
{
if (!SavPnt)
{
if(NoDomain)
{
Hatching.Status (HatchGen_IncoherentParity) ;
}
else
{
Hatching.IsDone(Standard_True);
}
if (StateAfter == TopAbs_IN) {
if (!SavPnt) {
if(NoDomain) {
Hatching.Status (HatchGen_IncoherentParity) ;
}
else {
Hatching.IsDone(Standard_True);
}
return ;
}
if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
ToAppend = Standard_True ;
}
} else if (SegmentBegin) {
if (Segments) {
if (!SavPnt) {
if(NoDomain) {
Hatching.Status (HatchGen_IncoherentParity) ;
}
else {
Hatching.IsDone(Standard_True);
}
return ;
}
if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
ToAppend = Standard_True ;
}
return ;
}
} else {
if (StateAfter == TopAbs_IN) {
if (!SavPnt) {
if(NoDomain) {
Hatching.Status (HatchGen_IncoherentParity) ;
}
else {
Hatching.IsDone(Standard_True);
}
return ;
}
if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
ToAppend = Standard_True ;
}
if(ISav != 0)
domain.SetFirstPoint (Hatching.Point(ISav)) ;
ToAppend = Standard_True ;
}
}
if (ToAppend) Hatching.AddDomain (domain) ;
else if (SegmentEnd)
{
if (StateAfter == TopAbs_IN)
{
if (!SavPnt)
{
if(NoDomain)
{
Hatching.Status (HatchGen_IncoherentParity) ;
}
else
{
Hatching.IsDone(Standard_True);
}
return ;
}
if (ISav != 0)
domain.SetFirstPoint (Hatching.Point(ISav)) ;
ToAppend = Standard_True ;
}
}
else if (SegmentBegin)
{
if (Segments)
{
if (!SavPnt)
{
if(NoDomain)
{
Hatching.Status (HatchGen_IncoherentParity) ;
}
else
{
Hatching.IsDone(Standard_True);
}
return ;
}
if (ISav != 0)
domain.SetFirstPoint (Hatching.Point(ISav)) ;
ToAppend = Standard_True ;
}
}
else
{
if (StateAfter == TopAbs_IN)
{
if(!SavPnt)
{
if(NoDomain)
{
Hatching.Status (HatchGen_IncoherentParity) ;
}
else
{
Hatching.IsDone(Standard_True);
}
return ;
}
if (ISav != 0)
domain.SetFirstPoint (Hatching.Point(ISav)) ;
ToAppend = Standard_True ;
}
}
if (ToAppend)
Hatching.AddDomain (domain) ;
}
}
Hatching.IsDone(Standard_True) ;
}