1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0029807: [Regression to 7.0.0] Impossible to cut cone from prism

The algorithm has been improved for the cases when the intersection line goes through the cone apex.

<!break>

1. All special points are put to the ALine forcefully (if they are true intersection point). Currently this step has not been implemented yet.

2. Now the tolerance of IntPatch_Point (put into ALine) is computed in order to cover the distance between it and the correspond ALine.

3. Test cases have been created.

4. Procedure of trimming IntAna_Curve has been improved.

5. Criterion when the discriminant of IntAna_Curve can be considered to be equal to 0 has been improved.

6. Methods IntAna_Curve::FindParameter(...) (and IntPatch_ALine::FindParameter(...)) currently returns list of all parameters corresponding the given point (IntAna_Curve can be self-interfered curve). Before the fix, this method always returned only one (randomly chosen) parameter.

7. Interfaces of the following methods have been changed: IntAna_Curve::FindParameter(...), IntPatch_ALine::FindParameter(...), IntPatch_ALine::ChangeVertex(...), IntPatch_SpecialPoints::AddPointOnUorVIso(...), IntPatch_SpecialPoints::AddSingularPole(...), IntPatch_WLineTool::ExtendTwoWLines().

8. Following methods have been added: IntAna_Quadric::SpecialPoints(...), IntPatch_ALineToWLine::GetSectionRadius(...), IntPatch_SpecialPoints::ProcessSphere(...), IntPatch_SpecialPoints::ProcessCone(...), IntPatch_SpecialPoints::GetTangentToIntLineForCone(...).

------------------
1) tests/boolean/volumemaker/C5
   tests/boolean/volumemaker/C6
   tests/boolean/volumemaker/E7

They are real IMPROVEMENTS. In the FIX (in compare with MASTER), section result between pairs of faces f2&f6 (C5), f3&f7 (C6) and f1&f5 (E7) is closed. Separated test cases have been created in order to focus on the problem with section. Bug #28503 has been fixed.

Correction in test cases.
This commit is contained in:
nbv
2018-05-25 11:05:58 +03:00
committed by bugmaster
parent d9d3107d8d
commit 3306fdd954
81 changed files with 3490 additions and 1091 deletions

View File

@@ -41,7 +41,8 @@ enum IntPatchWT_WLsConnectionType
{
IntPatchWT_NotConnected,
IntPatchWT_Singular,
IntPatchWT_EachOther
IntPatchWT_Common,
IntPatchWT_ReqExtend
};
//=======================================================================
@@ -849,17 +850,23 @@ static IntPatchWT_WLsConnectionType
const Standard_Real* const theArrPeriods)
{
const Standard_Real aSqToler = theToler3D*theToler3D;
IntPatchWT_WLsConnectionType aRetVal = IntPatchWT_NotConnected;
if(theVec3.SquareMagnitude() <= aSqToler)
{
return IntPatchWT_NotConnected;
if ((theVec1.Angle(theVec2) > IntPatch_WLineTool::myMaxConcatAngle))
{
return aRetVal;
}
else
{
aRetVal = IntPatchWT_Common;
}
}
if((theVec1.Angle(theVec2) > IntPatch_WLineTool::myMaxConcatAngle) ||
(theVec1.Angle(theVec3) > IntPatch_WLineTool::myMaxConcatAngle) ||
(theVec2.Angle(theVec3) > IntPatch_WLineTool::myMaxConcatAngle))
else if((theVec1.Angle(theVec2) > IntPatch_WLineTool::myMaxConcatAngle) ||
(theVec1.Angle(theVec3) > IntPatch_WLineTool::myMaxConcatAngle) ||
(theVec2.Angle(theVec3) > IntPatch_WLineTool::myMaxConcatAngle))
{
return IntPatchWT_NotConnected;
return aRetVal;
}
const gp_Pnt aPmid(0.5*(thePtWL1.Value().XYZ()+thePtWL2.Value().XYZ()));
@@ -973,7 +980,12 @@ static IntPatchWT_WLsConnectionType
return IntPatchWT_Singular;
}
return IntPatchWT_EachOther;
if (aRetVal == IntPatchWT_Common)
{
return IntPatchWT_Common;
}
return IntPatchWT_ReqExtend;
}
//=======================================================================
@@ -984,12 +996,47 @@ static IntPatchWT_WLsConnectionType
Standard_Boolean CheckArgumentsToJoin(const Handle(Adaptor3d_HSurface)& theS1,
const Handle(Adaptor3d_HSurface)& theS2,
const IntSurf_PntOn2S& thePnt,
const gp_Pnt& theP1,
const gp_Pnt& theP2,
const gp_Pnt& theP3,
const Standard_Real theMinRad)
{
const Standard_Real aRad =
IntPatch_PointLine::CurvatureRadiusOfIntersLine(theS1, theS2, thePnt);
const Standard_Real aRad =
IntPatch_PointLine::CurvatureRadiusOfIntersLine(theS1, theS2, thePnt);
return (aRad > theMinRad);
if (aRad > theMinRad)
{
return Standard_True;
}
else if (aRad > 0.0)
{
return Standard_False;
}
// Curvature radius cannot be computed.
// Check smoothness of polygon.
// theP2
// *
// |
// |
// * o *
// theP1 O theP3
//Joining is enabled if two conditions are satisfied together:
// 1. Angle (theP1, theP2, theP3) is quite big;
// 2. Modulus of perpendicular (O->theP2) to the segment (theP1->theP3)
// is less than 0.01*<modulus of this segment>.
const gp_Vec aV12f(theP1, theP2), aV12l(theP2, theP3);
if (aV12f.Angle(aV12l) > IntPatch_WLineTool::myMaxConcatAngle)
return Standard_False;
const gp_Vec aV13(theP1, theP3);
const Standard_Real aSq13 = aV13.SquareMagnitude();
return (aV12f.CrossSquareMagnitude(aV13) < 1.0e-4*aSq13*aSq13);
}
//=======================================================================
@@ -1482,18 +1529,14 @@ void IntPatch_WLineTool::JoinWLines(IntPatch_SequenceOfLine& theSlin,
const Standard_Real aSqMinFDist = Min(aSqDistF, aSqDistL);
if (aSqMinFDist < Precision::SquareConfusion())
{
if (CheckArgumentsToJoin(theS1, theS2, aPntFWL1, aMinRad))
const Standard_Boolean isFM = (aSqDistF < aSqDistL);
const IntSurf_PntOn2S& aPt1 = aWLine1->Point(2);
const IntSurf_PntOn2S& aPt2 = isFM ? aWLine2->Point(2) :
aWLine2->Point(aNbPntsWL2 - 1);
if (!IsSeamOrBound(aPt1, aPt2, aPntFWL1,
anArrPeriods, anArrFBonds, anArrLBonds))
{
const Standard_Boolean isFM = (aSqDistF < aSqDistL);
const IntSurf_PntOn2S& aPt1 = aWLine1->Point(2);
const IntSurf_PntOn2S& aPt2 = isFM ? aWLine2->Point(2) :
aWLine2->Point(aNbPntsWL2 - 1);
if (!IsSeamOrBound(aPt1, aPt2, aPntFWL1,
anArrPeriods, anArrFBonds, anArrLBonds))
{
isFirstConnected = Standard_True;
}
isFirstConnected = Standard_True;
}
}
@@ -1503,18 +1546,14 @@ void IntPatch_WLineTool::JoinWLines(IntPatch_SequenceOfLine& theSlin,
const Standard_Real aSqMinLDist = Min(aSqDistF, aSqDistL);
if (aSqMinLDist < Precision::SquareConfusion())
{
if (CheckArgumentsToJoin(theS1, theS2, aPntLWL1, aMinRad))
const Standard_Boolean isFM = (aSqDistF < aSqDistL);
const IntSurf_PntOn2S& aPt1 = aWLine1->Point(aNbPntsWL1 - 1);
const IntSurf_PntOn2S& aPt2 = isFM ? aWLine2->Point(2) :
aWLine2->Point(aNbPntsWL2 - 1);
if (!IsSeamOrBound(aPt1, aPt2, aPntLWL1,
anArrPeriods, anArrFBonds, anArrLBonds))
{
const Standard_Boolean isFM = (aSqDistF < aSqDistL);
const IntSurf_PntOn2S& aPt1 = aWLine1->Point(aNbPntsWL1 - 1);
const IntSurf_PntOn2S& aPt2 = isFM ? aWLine2->Point(2) :
aWLine2->Point(aNbPntsWL2 - 1);
if (!IsSeamOrBound(aPt1, aPt2, aPntLWL1,
anArrPeriods, anArrFBonds, anArrLBonds))
{
isLastConnected = Standard_True;
}
isLastConnected = Standard_True;
}
}
@@ -1549,15 +1588,29 @@ void IntPatch_WLineTool::JoinWLines(IntPatch_SequenceOfLine& theSlin,
const Standard_Integer anIndexWL2 = isFirstConnected ? aListFC.First() : aListLC.First();
Handle(IntPatch_WLine) aWLine2(Handle(IntPatch_WLine)::DownCast(theSlin.Value(anIndexWL2)));
const Standard_Integer aNbPntsWL2 = aWLine2->NbPnts();
const IntSurf_PntOn2S& aPntFWL2 = aWLine2->Point(1);
aWLine1->ClearVertexes();
const IntSurf_PntOn2S& aPntLWL2 = aWLine2->Point(aNbPntsWL2);
if (isFirstConnected)
{
if (aPntFWL1.IsSame(aPntFWL2, Precision::Confusion()))
const Standard_Real aSqDistF = aPntFWL1.Value().SquareDistance(aPntFWL2.Value());
const Standard_Real aSqDistL = aPntFWL1.Value().SquareDistance(aPntLWL2.Value());
const Standard_Boolean isFM = (aSqDistF < aSqDistL);
const IntSurf_PntOn2S& aPt1 = aWLine1->Point(2);
const IntSurf_PntOn2S& aPt2 = isFM ? aWLine2->Point(2) :
aWLine2->Point(aNbPntsWL2 - 1);
if (!CheckArgumentsToJoin(theS1, theS2, aPntFWL1, aPt1.Value(),
aPntFWL1.Value(), aPt2.Value(), aMinRad))
{
continue;
}
aWLine1->ClearVertexes();
if (isFM)
{
//First-First-connection
for (Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++)
@@ -1578,10 +1631,26 @@ void IntPatch_WLineTool::JoinWLines(IntPatch_SequenceOfLine& theSlin,
}
else //if (isLastConnected)
{
if (aPntLWL1.IsSame(aPntFWL2, Precision::Confusion()))
const Standard_Real aSqDistF = aPntLWL1.Value().SquareDistance(aPntFWL2.Value());
const Standard_Real aSqDistL = aPntLWL1.Value().SquareDistance(aPntLWL2.Value());
const Standard_Boolean isFM = (aSqDistF < aSqDistL);
const IntSurf_PntOn2S& aPt1 = aWLine1->Point(aNbPntsWL1 - 1);
const IntSurf_PntOn2S& aPt2 = isFM ? aWLine2->Point(2) :
aWLine2->Point(aNbPntsWL2 - 1);
if (!CheckArgumentsToJoin(theS1, theS2, aPntLWL1, aPt1.Value(),
aPntFWL1.Value(), aPt2.Value(), aMinRad))
{
continue;
}
aWLine1->ClearVertexes();
if (isFM)
{
//Last-First connection
for(Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++)
for (Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++)
{
const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
aWLine1->Curve()->Add(aPt);
@@ -1609,13 +1678,15 @@ void IntPatch_WLineTool::JoinWLines(IntPatch_SequenceOfLine& theSlin,
//purpose : Performs extending theWLine1 and theWLine2 through their
// respecting end point.
//=======================================================================
void IntPatch_WLineTool::ExtendTwoWLines(IntPatch_SequenceOfLine& theSlin,
const Handle(Adaptor3d_HSurface)& theS1,
const Handle(Adaptor3d_HSurface)& theS2,
const Standard_Real theToler3D,
const Standard_Real* const theArrPeriods,
const Bnd_Box2d& theBoxS1,
const Bnd_Box2d& theBoxS2)
void IntPatch_WLineTool::
ExtendTwoWLines(IntPatch_SequenceOfLine& theSlin,
const Handle(Adaptor3d_HSurface)& theS1,
const Handle(Adaptor3d_HSurface)& theS2,
const Standard_Real theToler3D,
const Standard_Real* const theArrPeriods,
const Bnd_Box2d& theBoxS1,
const Bnd_Box2d& theBoxS2,
const NCollection_List<gp_Pnt>& theListOfCriticalPoints)
{
if(theSlin.Length() < 2)
return;
@@ -1677,6 +1748,46 @@ void IntPatch_WLineTool::ExtendTwoWLines(IntPatch_SequenceOfLine& theSlin,
{
aCheckResult |= IntPatchWT_DisLastFirst | IntPatchWT_DisLastLast;
}
if (!theListOfCriticalPoints.IsEmpty())
{
for (NCollection_List<gp_Pnt>::Iterator anItr(theListOfCriticalPoints);
anItr.More(); anItr.Next())
{
const gp_Pnt &aPt = anItr.Value();
if (!(aCheckResult & (IntPatchWT_DisFirstFirst | IntPatchWT_DisFirstLast)))
{
if (aPt.SquareDistance(aPntFWL1.Value()) < Precision::Confusion())
{
aCheckResult |= IntPatchWT_DisFirstFirst | IntPatchWT_DisFirstLast;
}
}
if (!(aCheckResult & (IntPatchWT_DisLastFirst | IntPatchWT_DisLastLast)))
{
if (aPt.SquareDistance(aPntLWL1.Value()) < Precision::Confusion())
{
aCheckResult |= IntPatchWT_DisLastFirst | IntPatchWT_DisLastLast;
}
}
if (!(aCheckResult & (IntPatchWT_DisFirstFirst | IntPatchWT_DisLastFirst)))
{
if (aPt.SquareDistance(aPntFWL2.Value()) < Precision::Confusion())
{
aCheckResult |= IntPatchWT_DisFirstFirst | IntPatchWT_DisLastFirst;
}
}
if (!(aCheckResult & (IntPatchWT_DisFirstLast | IntPatchWT_DisLastLast)))
{
if (aPt.SquareDistance(aPntLWL2.Value()) < Precision::Confusion())
{
aCheckResult |= IntPatchWT_DisFirstLast | IntPatchWT_DisLastLast;
}
}
}
}
}
if(aCheckResult == (IntPatchWT_DisFirstFirst | IntPatchWT_DisFirstLast |