1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-09-03 14:10:33 +03:00

Fix for issue #27665

This commit is contained in:
nbv
2016-07-11 16:09:45 +03:00
parent d6e98f99a7
commit 105d021c01
5 changed files with 238 additions and 51 deletions

View File

@@ -133,6 +133,8 @@ is
generic class GExtCC2d, CCache2d, ECC2d;
generic class GLocateExtCC2d, LCCache2d, ELCC2d, LocECC2d;
imported UBTFilterCCPoints;
-- Curve-Surface:
class ExtCS;

View File

@@ -28,7 +28,8 @@ uses POnCurv from Extrema,
Pnt from gp,
HArray1OfPnt from TColgp,
SequenceOfReal from TColStd,
ListOfTransient from TColStd
ListOfTransient from TColStd,
UBTFilterCCPoints from Extrema
raises InfiniteSolutions from StdFail,
@@ -138,12 +139,12 @@ is
Results(me: in out; AlgExt: ExtElC from Extrema;
Ut11, Ut12, Ut21, Ut22: Real)
is static protected;
is static;
Results(me: in out;AlgExt: ECC;
Ut11, Ut12, Ut21, Ut22: Real)
is static protected;
is static;
@@ -169,7 +170,8 @@ fields
mydist12: Real;
mydist21: Real;
mydist22: Real;
myFilter: UBTFilterCCPoints from Extrema;
end GExtCC;

View File

@@ -43,6 +43,95 @@
#include <Extrema_ExtPElC.hxx>
#include <Standard_NullObject.hxx>
#include <NCollection_UBTreeFiller.hxx>
#include <Bnd_Box.hxx>
#include <BndLib_Add3dCurve.hxx>
#include <TColgp_HArray1OfPnt.hxx>
typedef NCollection_UBTreeFiller<Handle(Extrema_CCache), Bnd_Box> UBTreeFiller;
typedef NCollection_UBTree<Handle(Extrema_CCache), Bnd_Box> UBTree;
class ComputeIntervExtrema : public UBTree::Selector
{
public:
/**
* Constructor
*/
ComputeIntervExtrema(const Handle(Extrema_CCache)& theCache, Extrema_ECCOfExtCC& theECC, Extrema_GExtCC *theExt, const Standard_Boolean theIsFirst, const Standard_Real U11, const Standard_Real U12, const Standard_Real U21, const Standard_Real U22) : myECC(theECC), myExt(theExt), myIsFirst(theIsFirst), myU11(U11), myU12(U12), myU21(U21), myU22(U22)
{
if(theIsFirst)
myECC.SetCurveCache (1, theCache);
else
myECC.SetCurveCache (2, theCache);
//Initialize BndBox
myBox.SetVoid();
Curve1& aC = *(Curve1*)(theCache->CurvePtr());
const Standard_Real aFPar = theCache->FirstParameter(),
aLPar = theCache->LastParameter();
BndLib_Add3dCurve::Add(aC, aFPar, aLPar, Precision::Confusion(), myBox);
myBox.Enlarge(Precision::Infinite());
};
/**
* Bounding box rejection - definition of virtual method.
*/
Standard_EXPORT virtual Standard_Boolean Reject(const Bnd_Box& theBox) const;
/**
* Redefined from the base class
*/
Standard_EXPORT virtual Standard_Boolean Accept(const Handle(Extrema_CCache)& theCache);
protected:
ComputeIntervExtrema& operator=(ComputeIntervExtrema&);
private:
Extrema_ECCOfExtCC& myECC;
Bnd_Box myBox;
Extrema_GExtCC *myExt;
const Standard_Boolean myIsFirst;
Standard_Real myU11;
Standard_Real myU12;
Standard_Real myU21;
Standard_Real myU22;
}; //end fo clMinimumDistanceSelector
Standard_Boolean ComputeIntervExtrema::Reject(const Bnd_Box& theBox) const
{
return (theBox.IsOut(myBox));
}
Standard_Boolean ComputeIntervExtrema::Accept(const Handle(Extrema_CCache)& theCache)
{
if(myIsFirst)
myECC.SetCurveCache (2, theCache);
else
myECC.SetCurveCache (1, theCache);
myECC.Perform();
myExt->Results(myECC, myU11, myU12, myU21, myU22);
if(!myECC.IsDone() || myECC.NbExt() == 0)
return Standard_True;
Standard_Real aMinDist = RealLast();
for(Standard_Integer i = 1; i <= myECC.NbExt(); i++)
{
aMinDist = Min(aMinDist, myECC.SquareDistance(i));
}
myBox.SetGap(sqrt(aMinDist));
return Standard_True;
}
//=======================================================================
//function : Extrema_GExtCC
//purpose :
@@ -395,18 +484,34 @@ void Extrema_GExtCC::Perform()
}
}
//2. process each cache from one list with each cache from the other
TColStd_ListIteratorOfListOfTransient anIt1 (myCacheLists[0]);
for (; anIt1.More(); anIt1.Next()) {
Handle(Extrema_CCache) aCache1 = Handle(Extrema_CCache)::DownCast (anIt1.Value());
myECC.SetCurveCache (1, aCache1);
TColStd_ListIteratorOfListOfTransient anIt2 (myCacheLists[1]);
for (; anIt2.More(); anIt2.Next()) {
Handle(Extrema_CCache) aCache2 = Handle(Extrema_CCache)::DownCast (anIt2.Value());
myECC.SetCurveCache (2, aCache2);
myECC.Perform();
Results(myECC, U11, U12, U21, U22);
}
Bnd_Box aBox;
const Standard_Integer aFInd = (myCacheLists[0].Extent() > myCacheLists[1].Extent()) ? 1 : 0;
const Standard_Integer aSInd = (myCacheLists[0].Extent() > myCacheLists[1].Extent()) ? 0 : 1;
Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator(5000);
UBTree aDeflTree (anAlloc);
UBTreeFiller aDeflTreeFiller(aDeflTree);
TColStd_ListIteratorOfListOfTransient anIt2 (myCacheLists[aSInd]);
for (; anIt2.More(); anIt2.Next())
{
aBox.SetVoid();
const Handle(Extrema_CCache)& aCache2 = Handle(Extrema_CCache)::DownCast (anIt2.Value());
BndLib_Add3dCurve::Add(*(Curve1*)myC[aSInd], aCache2->FirstParameter(), aCache2->LastParameter(), Precision::Confusion(), aBox);
aDeflTreeFiller.Add(aCache2, aBox);
}
//Shake TreeFiller
aDeflTreeFiller.Fill();
aDeflTreeFiller.Reset();
TColStd_ListIteratorOfListOfTransient anIt1 (myCacheLists[aFInd]);
for (; anIt1.More(); anIt1.Next())
{
const Handle(Extrema_CCache)& aCache1 = Handle(Extrema_CCache)::DownCast (anIt1.Value());
ComputeIntervExtrema aSel(aCache1, myECC, this, aFInd == 0, U11, U12, U21, U22);
myFilter.Reset(myTol);
aDeflTree.Select(aSel);
}
}
}
@@ -832,50 +937,58 @@ void Extrema_GExtCC::Results(const Extrema_ECC& AlgExt,
const Standard_Real Ut21,
const Standard_Real Ut22)
{
Standard_Integer i, j,NbExt;
Standard_Real Val, U, U2,Uj,U2j;
Extrema_POnCurv P1, P2,P1j,P2j;
Standard_Boolean IsExtrema;
Standard_Integer i, NbExt;
Standard_Real Val, U, U2;
Extrema_POnCurv P1, P2;
myDone = AlgExt.IsDone();
if (myDone) {
NbExt = AlgExt.NbExt();
for (i = 1; i <= NbExt; i++) {
// Size computed to have cell index inside of int32 value.
Extrema_CCPointsInspector anInspector(myTol);
for (i = 1; i <= NbExt; i++)
{
AlgExt.Points(i, P1, P2);
U = P1.Parameter();
U2 = P2.Parameter();
IsExtrema=Standard_True;
for (j=1;j<=mynbext;j++)
{ P1j=mypoints.Value(2*j-1);
P2j=mypoints.Value(2*j);
Uj=P1j.Parameter();
U2j=P2j.Parameter();
if ((Abs(Uj-U)<=myTol[0]) && (Abs(U2j-U2)<=myTol[1]))
IsExtrema=Standard_False;}
if (IsExtrema)
{
// Verification de la validite des parametres
if (Tool1::IsPeriodic(*((Curve1*)myC[0]))) {
U = ElCLib::InPeriod(U, Ut11, Ut11+Tool1::Period(*((Curve1*)myC[0])));
}
if (Tool2::IsPeriodic(*((Curve2*)myC[1]))) {
U2 = ElCLib::InPeriod(U2, Ut21, Ut21+Tool2::Period(*((Curve2*)myC[1])));
}
if ((U >= Ut11 - RealEpsilon()) &&
(U <= Ut12 + RealEpsilon()) &&
(U2 >= Ut21 - RealEpsilon()) &&
(U2 <= Ut22 + RealEpsilon()))
gp_XY aPnt2d(U, U2);
gp_XY aXYmin(U - myTol[0], U2 - myTol[1]);
gp_XY aXYmax(U + myTol[0], U2 + myTol[1]);
anInspector.ClearFind();
anInspector.SetCurrent(aPnt2d);
myFilter.Inspect(aXYmin, aXYmax, anInspector);
if (anInspector.isFind())
{
continue;
}
myFilter.Add(aPnt2d, aPnt2d);
// Verification de la validite des parametres
if (Tool1::IsPeriodic(*((Curve1*)myC[0]))) {
U = ElCLib::InPeriod(U, Ut11, Ut11+Tool1::Period(*((Curve1*)myC[0])));
}
if (Tool2::IsPeriodic(*((Curve2*)myC[1]))) {
U2 = ElCLib::InPeriod(U2, Ut21, Ut21+Tool2::Period(*((Curve2*)myC[1])));
}
if( (U >= Ut11 - RealEpsilon()) &&
(U <= Ut12 + RealEpsilon()) &&
(U2 >= Ut21 - RealEpsilon()) &&
(U2 <= Ut22 + RealEpsilon()))
{ mynbext++;
Val = AlgExt.SquareDistance(i);
mySqDist.Append(Val);
P1.SetValues(U, P1.Value());
P2.SetValues(U2, P2.Value());
mypoints.Append(P1);
mypoints.Append(P2);
}
Val = AlgExt.SquareDistance(i);
mySqDist.Append(Val);
P1.SetValues(U, P1.Value());
P2.SetValues(U2, P2.Value());
mypoints.Append(P1);
mypoints.Append(P2);
}
}
}
}
}

View File

@@ -0,0 +1,69 @@
// Created on: 2016-07-20
// Created by: OPEN CASCADE Support
// Copyright (c) 2005-2016 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and / or modify it
// under the terms of the GNU Lesser General Public version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _Extrema_UBTFilterCCPoints_HeaderFile
#define _Extrema_UBTFilterCCPoints_HeaderFile
#include <NCollection_CellFilter.hxx>
class Extrema_CCPointsInspector : public NCollection_CellFilter_InspectorXY
{
public:
typedef gp_XY Target;
//! Constructor; remembers the tolerance
Extrema_CCPointsInspector (const Standard_Real theTol[2])
{
myTol[0] = theTol[0];
myTol[1] = theTol[1];
myIsFind = Standard_False;
}
void ClearFind()
{
myIsFind = Standard_False;
}
Standard_Boolean isFind()
{
return myIsFind;
}
//! Set current point to search for coincidence
void SetCurrent (const gp_XY& theCurPnt)
{
myCurrent = theCurPnt;
}
//! Implementation of inspection method
NCollection_CellFilter_Action Inspect (const Target& theObject)
{
gp_XY aPt = myCurrent.Subtracted(theObject);
if((Abs(aPt.X()) < myTol[0]) && (Abs(aPt.Y()) < myTol[1]))
{
myIsFind = Standard_True;
}
return CellFilter_Keep;
}
private:
Standard_Real myTol[2];
gp_XY myCurrent;
Standard_Boolean myIsFind;
};
typedef NCollection_CellFilter<Extrema_CCPointsInspector> Extrema_UBTFilterCCPoints;
#endif //_Extrema_UBTFilterCCPoints_HeaderFile

View File

@@ -1 +1,2 @@
Extrema_HUBTreeOfSphere.hxx
Extrema_UBTFilterCCPoints.hxx