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

0028599: Replacement of old Boolean operations with new ones in BRepProj_Projection algorithm

The usage of *BRepAlgo_Section* has been replaced with the usage of *BRepAlgoAPI_Section* in *BRepProj_Projection* algorithm.

The TODO statements have been removed from the failing test case in the "prj" grid as they are working correctly now.

The following changes have been made to improve the performance *BRepAlgoAPI_Section*:
1. Revision of the *IntPolyh_Intersection* class to avoid repeated calculation of the deflection of the same triangulation.
2. Small revision of the Edge/Face intersection algorithm to perform Extrema computation on the whole intersection range of the edge instead of discrete ranges.
3. Implementation of the extrema computation for the Circle and Sphere.
4. Correct computation of the parameter of the point on the Circle.
This commit is contained in:
emv
2017-12-26 14:28:27 +03:00
committed by apn
parent 95f688263d
commit 03cca6f742
50 changed files with 2340 additions and 1978 deletions

View File

@@ -7,7 +7,6 @@ IntTools_BaseRangeSample.hxx
IntTools_BaseRangeSample.lxx
IntTools_BeanFaceIntersector.cxx
IntTools_BeanFaceIntersector.hxx
IntTools_BeanFaceIntersector.lxx
IntTools_CArray1.gxx
IntTools_CArray1.lxx
IntTools_CArray1OfInteger.hxx

View File

@@ -125,7 +125,6 @@ myVMinParameter(0.),
myVMaxParameter(0.),
myBeanTolerance(0.),
myFaceTolerance(0.),
myDeflection(0.01),
myIsDone(Standard_False)
{
myCriteria = Precision::Confusion();
@@ -147,7 +146,6 @@ IntTools_BeanFaceIntersector::IntTools_BeanFaceIntersector(const TopoDS_Edge& th
myVMaxParameter(0.),
myBeanTolerance(0.),
myFaceTolerance(0.),
myDeflection(0.01),
myIsDone(Standard_False)
{
Init(theEdge, theFace);
@@ -167,7 +165,6 @@ IntTools_BeanFaceIntersector::IntTools_BeanFaceIntersector(const BRepAdaptor_Cur
myUMaxParameter(0.),
myVMinParameter(0.),
myVMaxParameter(0.),
myDeflection(0.01),
myIsDone(Standard_False)
{
Init(theCurve, theSurface, theBeanTolerance, theFaceTolerance);
@@ -195,7 +192,6 @@ IntTools_BeanFaceIntersector::IntTools_BeanFaceIntersector(const BRepAdaptor_Cur
myVMaxParameter(theVMaxParameter),
myBeanTolerance(theBeanTolerance),
myFaceTolerance(theFaceTolerance),
myDeflection(0.01),
myIsDone(Standard_False)
{
myCurve = theCurve;
@@ -322,142 +318,93 @@ void IntTools_BeanFaceIntersector::SetSurfaceParameters(const Standard_Real theU
// function: Perform
// purpose:
// ==================================================================================
void IntTools_BeanFaceIntersector::Perform()
void IntTools_BeanFaceIntersector::Perform()
{
myIsDone = Standard_False;
myResults.Clear();
Standard_Integer bRet;
Standard_Integer aDiscretization = 30;
Standard_Real aRelativeDeflection = 0.01;
myDeflection = aRelativeDeflection;
//
if (myContext.IsNull()) {
if (myContext.IsNull())
{
myContext=new IntTools_Context;
}
//
if(myCurve.GetType()==GeomAbs_Line && mySurface.GetType()==GeomAbs_Plane) {
// Fast computation of Line/Plane case
if (myCurve.GetType() == GeomAbs_Line &&
mySurface.GetType() == GeomAbs_Plane)
{
ComputeLinePlane();
return;
}
if(myCurve.GetType()==GeomAbs_Line) {
aDiscretization = 3;
myDeflection = Precision::Confusion();
}
else {
if(myCurve.GetType()==GeomAbs_Circle) {
aDiscretization = 23;
Standard_Real R = myCurve.Circle().Radius();
myDeflection = aRelativeDeflection * R;
}
if(myCurve.GetType() == GeomAbs_Ellipse) {
aDiscretization = 23;
Standard_Real R = myCurve.Ellipse().MajorRadius();
myDeflection = 2 * aRelativeDeflection * R;
}
}
// modified by NIZHNY-MKK Wed Oct 19 12:15:21 2005
Standard_Boolean bLocalize = Standard_False;
if(((mySurface.GetType() == GeomAbs_BSplineSurface) &&
((mySurface.UDegree() > 2) || (mySurface.VDegree() > 2)) &&
//modified by NIZNHY-PKV Wed Feb 25 15:02:00 2009f
//((mySurface.NbUKnots() > 2) || (mySurface.NbVKnots() > 2))) ||
((mySurface.NbUKnots() > 2) && (mySurface.NbVKnots() > 2))) ||
//modified by NIZNHY-PKV Wed Feb 25 15:02:13 2009t
(mySurface.GetType() == GeomAbs_BezierSurface) ||
(mySurface.GetType() == GeomAbs_OtherSurface)) {
bLocalize = Standard_True;
// Fast check on coincidence for analytic cases
if (FastComputeAnalytic())
{
// no further computation is necessary
myIsDone = Standard_True;
return;
}
if(bLocalize) {
if(Precision::IsInfinite(myUMinParameter) ||
Precision::IsInfinite(myUMaxParameter) ||
Precision::IsInfinite(myVMinParameter) ||
Precision::IsInfinite(myVMaxParameter))
bLocalize = Standard_False;
}
Standard_Boolean bSuccessLocalize = Standard_False;
// Initialization of the range manager
myRangeManager.SetBoundaries(myFirstParameter, myLastParameter, 0);
if( bLocalize) {
myRangeManager.SetBoundaries(myFirstParameter, myLastParameter, 0);
Standard_Boolean coinside = TestComputeCoinside();
if(!coinside)
bSuccessLocalize = ComputeLocalized();
// Check coincidence
Standard_Boolean isCoincide = TestComputeCoinside();
if (isCoincide)
{
myResults.Append(IntTools_Range(myFirstParameter, myLastParameter));
myIsDone = Standard_True;
return;
}
if(!bLocalize || !bSuccessLocalize) {
// modified by NIZHNY-MKK Wed Oct 19 12:15:26 2005.END
// Perform intersection
IntTools_CArray1OfReal aParams;
if(IntTools::PrepareArgs(myCurve,
myLastParameter,
myFirstParameter,
aDiscretization,
aRelativeDeflection,
aParams)) {
return;
}
// try to find localized solution
Standard_Boolean bLocalize = (!Precision::IsInfinite(myUMinParameter) &&
!Precision::IsInfinite(myUMaxParameter) &&
!Precision::IsInfinite(myVMinParameter) &&
!Precision::IsInfinite(myVMaxParameter));
bLocalize = bLocalize && (mySurface.GetType() == GeomAbs_BezierSurface ||
mySurface.GetType() == GeomAbs_OtherSurface ||
(mySurface.GetType() == GeomAbs_BSplineSurface &&
(mySurface.UDegree() > 2 || mySurface.VDegree() > 2) &&
(mySurface.NbUKnots() > 2 && mySurface.NbVKnots() > 2)));
myRangeManager.SetRanges(aParams, 0);
Standard_Boolean isLocalized = bLocalize && ComputeLocalized();
if(myRangeManager.Length()==0) {
return;
}
//
bRet=FastComputeExactIntersection();
if(bRet == 1) {
IntTools_Range aRange(myFirstParameter, myLastParameter);
myResults.Append(aRange);
myIsDone = Standard_True;
return;
}
//modified by NIZHNY-EMV Fri Apr 20 09:38:08 2012
else if (bRet == 2) {
myIsDone = Standard_True;
return;
}
//modified by NIZHNY-EMV Fri Apr 20 09:38:10 2012
// Perform real intersection
if (!isLocalized)
{
ComputeAroundExactIntersection();
ComputeUsingExtremum();
// Standard_Boolean coinside = TestCoinside(myCurve,mySurface);
Standard_Boolean coinside = TestComputeCoinside();
// if(coinside) {
// myRangeManager.InsertRange(myFirstParameter, myLastParameter, 2);
// }
// else {
if(!coinside) {
ComputeAroundExactIntersection();
ComputeUsingExtremum();
ComputeNearRangeBoundaries();
}
ComputeNearRangeBoundaries();
}
myIsDone = Standard_True;
for(Standard_Integer i = 1; i <= myRangeManager.Length(); i++) {
// Treatment of the results
for (Standard_Integer i = 1; i <= myRangeManager.Length(); i++)
{
if (myRangeManager.Flag(i) != 2)
continue;
if(myRangeManager.Flag(i) == 2) {
IntTools_Range aRange = myRangeManager.Range(i);
if(myResults.Length() > 0) {
const IntTools_Range& aLastRange = myResults.Last();
if(Abs(aRange.First() - aLastRange.Last()) > Precision::PConfusion()) {
myResults.Append(aRange);
}
else {
myResults.ChangeValue(myResults.Length()).SetLast(aRange.Last());
}
}
else {
IntTools_Range aRange = myRangeManager.Range(i);
Standard_Integer iLastRange = myResults.Length();
if (iLastRange > 0)
{
IntTools_Range& aLastRange = myResults.ChangeValue(iLastRange);
if (Abs(aRange.First() - aLastRange.Last()) > Precision::PConfusion())
{
myResults.Append(aRange);
}
else
{
aLastRange.SetLast(aRange.Last());
}
}
else
myResults.Append(aRange);
}
}
@@ -721,238 +668,127 @@ void IntTools_BeanFaceIntersector::ComputeAroundExactIntersection()
// function: FastComputeExactIntersection
// purpose:
// ==================================================================================
Standard_Integer IntTools_BeanFaceIntersector::FastComputeExactIntersection()
Standard_Boolean IntTools_BeanFaceIntersector::FastComputeAnalytic()
{
Standard_Integer aresult;
GeomAbs_CurveType aCT;
GeomAbs_SurfaceType aST;
//
aresult = 0;
aCT=myCurve.GetType();
aST=mySurface.GetType();
//
if((aCT==GeomAbs_BezierCurve) ||
(aCT==GeomAbs_BSplineCurve) ||
(aCT==GeomAbs_OffsetCurve) ||
(aCT==GeomAbs_OtherCurve)) {
return aresult;
GeomAbs_CurveType aCT = myCurve.GetType();
if (aCT == GeomAbs_BezierCurve ||
aCT == GeomAbs_BSplineCurve ||
aCT == GeomAbs_OffsetCurve ||
aCT == GeomAbs_OtherCurve)
{
// not supported type
return Standard_False;
}
if(aST==GeomAbs_Plane) {
Standard_Boolean isCoincide = Standard_False;
Standard_Boolean hasIntersection = Standard_True;
GeomAbs_SurfaceType aST = mySurface.GetType();
// Plane - Circle/Ellipse/Hyperbola/Parabola
if (aST == GeomAbs_Plane)
{
gp_Pln surfPlane = mySurface.Plane();
if(aCT==GeomAbs_Line) {
if((surfPlane.Distance(myCurve.Value(myFirstParameter)) < myCriteria) &&
(surfPlane.Distance(myCurve.Value(myLastParameter)) < myCriteria)) {
aresult = 1;
gp_Dir aDir;
gp_Pnt aPLoc;
switch (aCT) {
case GeomAbs_Circle:
{
aDir = myCurve.Circle().Axis().Direction();
aPLoc = myCurve.Circle().Location();
break;
}
case GeomAbs_Ellipse:
{
aDir = myCurve.Ellipse().Axis().Direction();
aPLoc = myCurve.Ellipse().Location();
break;
}
case GeomAbs_Hyperbola:
{
aDir = myCurve.Hyperbola().Axis().Direction();
aPLoc = myCurve.Hyperbola().Location();
break;
}
case GeomAbs_Parabola:
{
aDir = myCurve.Parabola().Axis().Direction();
aPLoc = myCurve.Parabola().Location();
break;
}
default:
return Standard_False;
}
else { // else 1
gp_Dir aDir;
switch(aCT) {
case GeomAbs_Circle: {
aDir = myCurve.Circle().Axis().Direction();
break;
}
case GeomAbs_Ellipse: {
aDir = myCurve.Ellipse().Axis().Direction();
break;
}
case GeomAbs_Hyperbola: {
aDir = myCurve.Hyperbola().Axis().Direction();
break;
}
case GeomAbs_Parabola: {
aDir = myCurve.Parabola().Axis().Direction();
break;
}
default: {
return aresult;
}
}
//
Standard_Real anAngle = aDir.Angle(surfPlane.Axis().Direction());
if(anAngle < Precision::Angular()) {
Standard_Boolean insertRange = Standard_False;
switch(aCT) {
case GeomAbs_Circle: {
Standard_Real adist =
surfPlane.Distance(myCurve.Circle().Location()) +
myCurve.Circle().Radius() * Precision::Angular();
if(adist < myCriteria) {
insertRange = Standard_True;
}
break;
}
case GeomAbs_Ellipse: {
Standard_Real adist =
surfPlane.Distance(myCurve.Ellipse().Location()) +
myCurve.Ellipse().MajorRadius() * Precision::Angular();
if(adist < myCriteria) {
insertRange = Standard_True;
}
break;
}
case GeomAbs_Hyperbola:
case GeomAbs_Parabola: {
Standard_Real aMaxPar =
(Abs(myFirstParameter) > Abs(myLastParameter)) ?
Abs(myFirstParameter) : Abs(myLastParameter);
gp_Pnt aLoc = (aCT == GeomAbs_Parabola) ?
myCurve.Parabola().Location() :
myCurve.Hyperbola().Location();
Standard_Real adist = aLoc.Distance(myCurve.Value(aMaxPar));
adist = surfPlane.Distance(aLoc) + adist * Precision::Angular();
if(adist < myCriteria) {
insertRange = Standard_True;
}
break;
}
default: {
break;
}
}
//
if(insertRange) {
aresult = 1;
}
}//if(anAngle < Precision::Angular()) {
}//else { // else 1
}// if(aST==GeomAbs_Plane) {
if(aCT==GeomAbs_Circle) {
gp_Circ aCircle = myCurve.Circle();
Standard_Real anAngle = aDir.Angle(surfPlane.Axis().Direction());
if (anAngle > Precision::Angular())
return Standard_False;
if(aST==GeomAbs_Cylinder) {
gp_Cylinder aCylinder = mySurface.Cylinder();
gp_Dir aDir1(aCylinder.Axis().Direction());
gp_Dir aDir2(aCircle.Axis().Direction());
Standard_Real anAngle = aDir1.Angle(aDir2);
if(anAngle < Precision::Angular()) {
gp_Pnt aLoc = aCircle.Location();
gp_Lin anCylAxis(aCylinder.Axis());
Standard_Real alocdist = anCylAxis.Distance(aLoc);
Standard_Real adist = alocdist;
Standard_Real adiff = aCircle.Radius() - aCylinder.Radius();
adist += Abs(adiff);
if(adist < myCriteria) {
Standard_Real acylradius = aCylinder.Radius();
Standard_Real atmpvalue = aCircle.Radius() * sin(Precision::Angular());
Standard_Real aprojectedradius = atmpvalue;
aprojectedradius =
sqrt((aCircle.Radius() * aCircle.Radius())
- (aprojectedradius * aprojectedradius));
adiff = aprojectedradius - acylradius;
adist = alocdist + Abs(adiff);
if(adist < myCriteria) { // Abs is important function here
aresult = 1;
}
}
}
}// if(aST==GeomAbs_Cylinder)
hasIntersection = Standard_False;
if(aST==GeomAbs_Sphere) {
gp_Pln aCirclePln(aCircle.Location(), aCircle.Axis().Direction());
IntAna_QuadQuadGeo anInter(aCirclePln, mySurface.Sphere());
if(anInter.IsDone()) {
if(anInter.TypeInter() == IntAna_Circle) {
gp_Circ aCircleToCompare = anInter.Circle(1);
Standard_Real adist =
aCircleToCompare.Location().Distance(aCircle.Location());
Standard_Real adiff = aCircle.Radius() - aCircleToCompare.Radius();
adist += Abs(adiff);
if(adist < myCriteria) {
aresult = 1;
}
}
}
}// if(aST==GeomAbs_Sphere) {
}// if(aCT==GeomAbs_Circle) {
//
//modified by NIZNHY-PKV Thu Mar 01 11:54:04 2012f
if(aST==GeomAbs_Cylinder) {
Standard_Real aRC;
gp_Cylinder aCyl;
//
aCyl=mySurface.Cylinder();
aRC=aCyl.Radius();
const gp_Ax1& aAx1C=aCyl.Axis();
const gp_Dir& aDirC=aAx1C.Direction();
//
if(aCT==GeomAbs_Line) {
Standard_Real aCos, aAng2, aTolang2;
gp_Lin aLin;
//
aTolang2=1.e-16;
aLin=myCurve.Line();
const gp_Dir& aDirL=aLin.Direction();
//
aCos=aDirC.Dot(aDirL);
if(aCos >= 0.) {
aAng2 = 2.*(1. - aCos);
}
else {
aAng2 = 2.*(1. + aCos);
}
//
if(aAng2<=aTolang2) {// IsParallel = Standard_True;
Standard_Boolean bFlag = Standard_False;
Standard_Integer i;
Standard_Real aD;
gp_Pnt aPL[2];
gp_Lin aLC(aAx1C);
//
aPL[0]=myCurve.Value(myFirstParameter);
aPL[1]=myCurve.Value(myLastParameter);
//
for (i=0; i<2; ++i) {
aD=aLC.Distance(aPL[i]);
aD=fabs(aD-aRC);
bFlag=(aD > myCriteria);
if (bFlag) {
break;
}
}
if (!bFlag){
aresult = 1;
}
}
}//if(aCT==GeomAbs_Line) {
Standard_Real aDist = surfPlane.Distance(aPLoc);
isCoincide = aDist < myCriteria;
}
//modified by NIZNHY-PKV Thu Mar 01 11:54:06 2012t
//
if (aresult==1) {
//check intermediate point
Standard_Real aTm;
Standard_Boolean bValid;
//
const TopoDS_Face& aF = mySurface.Face();
aTm = IntTools_Tools::IntermediatePoint(myFirstParameter, myLastParameter);
const gp_Pnt& aPm = myCurve.Value(aTm);
//
bValid = myContext->IsValidPointForFace(aPm, aF, myCriteria);
if (bValid) {
IntTools_Range aRange(myFirstParameter, myLastParameter);
myRangeManager.InsertRange(aRange, 2);
} else {
aresult=2;
// Cylinder - Line/Circle
else if (aST == GeomAbs_Cylinder)
{
gp_Cylinder aCylinder = mySurface.Cylinder();
const gp_Ax1& aCylAxis = aCylinder.Axis();
const gp_Dir& aCylDir = aCylAxis.Direction();
Standard_Real aCylRadius = aCylinder.Radius();
if (aCT == GeomAbs_Line)
{
gp_Lin aLin = myCurve.Line();
if (!aLin.Direction().IsParallel(aCylDir, Precision::Angular()))
return Standard_False;
hasIntersection = Standard_False;
Standard_Real aDist = Abs(aLin.Distance(aCylAxis.Location()) - aCylRadius);
isCoincide = (aDist < myCriteria);
}
else if (aCT == GeomAbs_Circle)
{
gp_Circ aCircle = myCurve.Circle();
Standard_Real anAngle = aCylDir.Angle(aCircle.Axis().Direction());
if (anAngle > Precision::Angular())
return Standard_False;
Standard_Real aDistLoc = gp_Lin(aCylAxis).Distance(aCircle.Location());
Standard_Real aDist = aDistLoc + Abs(aCircle.Radius() - aCylRadius);
isCoincide = (aDist < myCriteria);
if (!isCoincide)
hasIntersection = (aDistLoc - (aCircle.Radius() + aCylRadius)) < myCriteria &&
(Abs(aCircle.Radius() - aCylRadius) - aDistLoc) < myCriteria;
}
}
//
return aresult;
// Sphere - Line
else if (aST == GeomAbs_Sphere)
{
gp_Sphere aSph = mySurface.Sphere();
gp_Pnt aSphLoc = aSph.Location();
if (aCT == GeomAbs_Line)
{
gp_Lin aLin = myCurve.Line();
Standard_Real aDist = aLin.Distance(aSphLoc) - aSph.Radius();
hasIntersection = aDist < myCriteria;
}
}
// Check intermediate point
if (isCoincide)
{
myResults.Append(IntTools_Range(myFirstParameter, myLastParameter));
}
return isCoincide || !hasIntersection;
}
// ==================================================================================
@@ -1057,10 +893,6 @@ void IntTools_BeanFaceIntersector::ComputeUsingExtremum()
myUMaxParameter,
myVMinParameter,
myVMaxParameter);
Bnd_Box FBox;
BndLib_AddSurface::Add(mySurface, 0., FBox);
FBox.Enlarge(myFaceTolerance);
for(Standard_Integer i = 1; i <= myRangeManager.Length(); i++) {
@@ -1073,24 +905,13 @@ void IntTools_BeanFaceIntersector::ComputeUsingExtremum()
if(anarg2 - anarg1 < Precision::PConfusion()) {
if(((i > 1) && (myRangeManager.Flag(i-1) == 2)) ||
((i < myRangeManager.Length()) && (myRangeManager.Flag(i+1) == 2))) {
myRangeManager.SetFlag(i, 1);
continue;
if (((i > 1) && (myRangeManager.Flag(i - 1) == 2)) ||
((i < myRangeManager.Length()) && (myRangeManager.Flag(i + 1) == 2))) {
myRangeManager.SetFlag(i, 1);
continue;
}
}
// check bounding boxes
Bnd_Box EBox;
EBox.Add(myCurve.Value(anarg1));
EBox.Add(myCurve.Value(anarg2));
EBox.Enlarge(myBeanTolerance + myDeflection);
if(EBox.IsOut(FBox)) {
myRangeManager.SetFlag(i, 1);
continue;
}
GeomAdaptor_Curve aGACurve(aCurve, anarg1, anarg2);
Extrema_ExtCS theExtCS(aGACurve, aGASurface, Tol, Tol);
myExtrema = theExtCS;

View File

@@ -120,7 +120,11 @@ public:
//! Launches the algorithm
Standard_EXPORT void Perform();
Standard_Boolean IsDone() const;
//! Returns Done/NotDone state of the algorithm.
Standard_Boolean IsDone() const
{
return myIsDone;
}
Standard_EXPORT const IntTools_SequenceOfRanges& Result() const;
@@ -142,7 +146,12 @@ private:
Standard_EXPORT void ComputeLinePlane();
Standard_EXPORT Standard_Integer FastComputeExactIntersection();
//! Fast check on coincidence of the edge with face for the cases when both shapes are
//! based on analytic geometries. The method also computes if the intersection
//! between shapes is possible.
//! The method returns TRUE if the computation was successful and further computation is unnecessary.
//! Otherwise it returns FALSE and computation continues.
Standard_EXPORT Standard_Boolean FastComputeAnalytic();
Standard_EXPORT void ComputeUsingExtremum();
@@ -179,19 +188,10 @@ private:
Extrema_ExtCS myExtrema;
GeomAPI_ProjectPointOnSurf myProjector;
IntTools_MarkedRangeSet myRangeManager;
Standard_Real myDeflection;
Handle(IntTools_Context) myContext;
IntTools_SequenceOfRanges myResults;
Standard_Boolean myIsDone;
};
#include <IntTools_BeanFaceIntersector.lxx>
#endif // _IntTools_BeanFaceIntersector_HeaderFile

View File

@@ -1,19 +0,0 @@
// Copyright (c) 1999-2014 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 License 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.
inline Standard_Boolean IntTools_BeanFaceIntersector::IsDone() const
{
return myIsDone;
}

View File

@@ -68,146 +68,11 @@ static
IntTools_EdgeFace::IntTools_EdgeFace()
{
myFuzzyValue = Precision::Confusion();
myDiscret = 30;
myEpsT =1e-12;
myDeflection=0.01;
myIsDone=Standard_False;
myErrorStatus=1;
myQuickCoincidenceCheck=Standard_False;
}
//=======================================================================
//function : SetContext
//purpose :
//=======================================================================
void IntTools_EdgeFace::SetContext(const Handle(IntTools_Context)& theContext)
{
myContext = theContext;
}
//=======================================================================
//function : Context
//purpose :
//=======================================================================
const Handle(IntTools_Context)& IntTools_EdgeFace::Context()const
{
return myContext;
}
//=======================================================================
//function : SetEdge
//purpose :
//=======================================================================
void IntTools_EdgeFace::SetEdge(const TopoDS_Edge& anEdge)
{
myEdge=anEdge;
}
//=======================================================================
//function : SetFace
//purpose :
//=======================================================================
void IntTools_EdgeFace::SetFace(const TopoDS_Face& aFace)
{
myFace=aFace;
}
//=======================================================================
//function : Edge
//purpose :
//=======================================================================
const TopoDS_Edge& IntTools_EdgeFace::Edge()const
{
return myEdge;
}
//=======================================================================
//function : Face
//purpose :
//=======================================================================
const TopoDS_Face& IntTools_EdgeFace::Face()const
{
return myFace;
}
//=======================================================================
//function : SetFuzzyValue
//purpose :
//=======================================================================
void IntTools_EdgeFace::SetFuzzyValue(const Standard_Real theFuzz)
{
myFuzzyValue = Max(theFuzz, Precision::Confusion());
}
//=======================================================================
//function : SetDiscretize
//purpose :
//=======================================================================
void IntTools_EdgeFace::SetDiscretize(const Standard_Integer aDiscret)
{
myDiscret=aDiscret;
}
//=======================================================================
//function : SetDeflection
//purpose :
//=======================================================================
void IntTools_EdgeFace::SetDeflection(const Standard_Real aDefl)
{
myDeflection=aDefl;
}
//=======================================================================
//function : SetEpsilonT
//purpose :
//=======================================================================
void IntTools_EdgeFace::SetEpsilonT(const Standard_Real anEpsT)
{
myEpsT=anEpsT;
}
//=======================================================================
//function : SetRange
//purpose :
//=======================================================================
void IntTools_EdgeFace::SetRange(const Standard_Real aFirst,
const Standard_Real aLast)
{
myRange.SetFirst (aFirst);
myRange.SetLast (aLast);
}
//=======================================================================
//function : SetRange
//purpose :
//=======================================================================
void IntTools_EdgeFace::SetRange(const IntTools_Range& aRange)
{
SetRange(aRange.First(), aRange.Last());
}
//=======================================================================
//function : IsDone
//purpose :
//=======================================================================
Standard_Boolean IntTools_EdgeFace::IsDone()const
{
return myIsDone;
}
//=======================================================================
//function : ErrorStatus
//purpose :
//=======================================================================
Standard_Integer IntTools_EdgeFace::ErrorStatus()const
{
return myErrorStatus;
}
//=======================================================================
//function : CommonParts
//purpose :
//=======================================================================
const IntTools_SequenceOfCommonPrts& IntTools_EdgeFace::CommonParts() const
{
return mySeqOfCommonPrts;
}
//=======================================================================
//function : Range
//purpose :
//=======================================================================
const IntTools_Range& IntTools_EdgeFace::Range() const
{
return myRange;
}
//=======================================================================
//function : IsCoincident
//purpose :
//=======================================================================
@@ -352,7 +217,7 @@ Standard_Real IntTools_EdgeFace::DistanceFunction
//
if (!bFlag) {
myErrorStatus=11;
myErrorStatus = 4;
return 99.;
}
@@ -597,11 +462,11 @@ Standard_Boolean IntTools_EdgeFace::CheckTouch
return theflag;
}
if (fabs (aTx-aTF) < myEpsT) {
if (fabs (aTx-aTF) < Precision::PConfusion()) {
return !theflag;
}
if (fabs (aTx-aTL) < myEpsT) {
if (fabs (aTx-aTL) < Precision::PConfusion()) {
return !theflag;
}
@@ -769,16 +634,6 @@ void IntTools_EdgeFace::Perform()
myIsDone=Standard_True;
}
//
// myErrorStatus
// 1 - the method Perform() is not invoked
// 2,3,4,5 -the method CheckData() fails
// 6 - PrepareArgs() problems
// 7 - No Projectable ranges
// 8,9 - PrepareArgs() problems occured inside projectable Ranges
// 11 - can't fill array aFunc(i) in PrepareArgsFuncArrays
//=======================================================================
//function : CheckTouch
//purpose :

View File

@@ -38,113 +38,148 @@ class gp_Pnt;
class BRepAdaptor_Surface;
class IntTools_CommonPrt;
//! The class provides Edge/Face algorithm to determine
//! common parts between edge and face in 3-d space.
//! Common parts can be : Vertices or Edges.
//! The class provides Edge/Face intersection algorithm to determine
//! common parts between edge and face in 3-d space.
//! Common parts between Edge and Face can be:
//! - Vertices - in case of intersection or touching;
//! - Edge - in case of full coincidence of the edge with the face.
class IntTools_EdgeFace
{
public:
DEFINE_STANDARD_ALLOC
public: //! @name Constructors
//! Empty Constructor
Standard_EXPORT IntTools_EdgeFace();
//! Initializes algorithm by the edge anEdge
Standard_EXPORT void SetEdge (const TopoDS_Edge& anEdge);
public: //! @name Setters/Getters
//! Initializes algorithm by the face aFace
Standard_EXPORT void SetFace (const TopoDS_Face& aFace);
//! Sets the edge for intersection
void SetEdge(const TopoDS_Edge& theEdge)
{
myEdge = theEdge;
}
//! Returns edge
Standard_EXPORT const TopoDS_Edge& Edge() const;
//! Returns the edge
const TopoDS_Edge& Edge() const
{
return myEdge;
}
//! Returns face
Standard_EXPORT const TopoDS_Face& Face() const;
//! Sets the face for intersection
void SetFace(const TopoDS_Face& theFace)
{
myFace = theFace;
}
//! Initializes algorithm by discretization value
Standard_EXPORT void SetDiscretize (const Standard_Integer aDiscret);
//! Returns the face
const TopoDS_Face& Face() const
{
return myFace;
}
//! Initializes algorithm by deflection value
Standard_EXPORT void SetDeflection (const Standard_Real aDeflection);
//! Initializes algorithm by parameter tolerance
Standard_EXPORT void SetEpsilonT (const Standard_Real anEpsT);
//! Sets boundaries for edge.
//! Sets the boundaries for the edge.
//! The algorithm processes edge inside these boundaries.
Standard_EXPORT void SetRange (const IntTools_Range& aRange);
void SetRange(const IntTools_Range& theRange)
{
myRange = theRange;
}
//! Sets boundaries for edge.
//! Sets the boundaries for the edge.
//! The algorithm processes edge inside these boundaries.
Standard_EXPORT void SetRange (const Standard_Real aFirst, const Standard_Real aLast);
void SetRange(const Standard_Real theFirst, const Standard_Real theLast)
{
myRange.SetFirst(theFirst);
myRange.SetLast(theLast);
}
//! Sets the intersecton context
Standard_EXPORT void SetContext (const Handle(IntTools_Context)& theContext);
//! Returns intersection range of the edge
const IntTools_Range& Range() const
{
return myRange;
}
//! Sets the intersection context
void SetContext(const Handle(IntTools_Context)& theContext)
{
myContext = theContext;
}
//! Returns the intersection context
const Handle(IntTools_Context)& Context() const
{
return myContext;
}
//! Gets the intersecton context
Standard_EXPORT const Handle(IntTools_Context)& Context() const;
//! Sets the Fuzzy value
Standard_EXPORT void SetFuzzyValue(const Standard_Real theFuzz);
void SetFuzzyValue(const Standard_Real theFuzz)
{
myFuzzyValue = Max(theFuzz, Precision::Confusion());
}
//! Returns Fuzzy value
//! Returns the Fuzzy value
Standard_Real FuzzyValue() const
{
return myFuzzyValue;
}
//! Launches the process
Standard_EXPORT void Perform();
//! Returns true if computation was done
//! successfully, otherwise returns false
Standard_EXPORT Standard_Boolean IsDone() const;
//! Returns code of completion
//! 0 - means successful completion
//! 1 - the process was not started
//! 2,3,4,5 - invalid source data for the algorithm
//! 6 - discretization failed
//! 7 - no projectable ranges found
//! 11 - distance computing error
Standard_EXPORT Standard_Integer ErrorStatus() const;
//! Returns results
Standard_EXPORT const IntTools_SequenceOfCommonPrts& CommonParts() const;
//! Returns boundaries for edge
Standard_EXPORT const IntTools_Range& Range() const;
//! Sets the flag myQuickCoincidenceCheck
void UseQuickCoincidenceCheck(const Standard_Boolean bFlag) {
myQuickCoincidenceCheck=bFlag;
//! Sets the flag for quick coincidence check.
//! It is safe to use the quick check for coincidence only if both
//! of the following conditions are met:
//! - The vertices of edge are lying on the face;
//! - The edge does not intersect the boundaries of the face on the given range.
void UseQuickCoincidenceCheck(const Standard_Boolean theFlag)
{
myQuickCoincidenceCheck = theFlag;
}
//! Returns the flag myQuickCoincidenceCheck
Standard_Boolean IsCoincidenceCheckedQuickly () {
Standard_Boolean IsCoincidenceCheckedQuickly()
{
return myQuickCoincidenceCheck;
}
protected:
public: //! @name Performing the operation
//! Launches the process
Standard_EXPORT void Perform();
public: //! @name Checking validity of the intersection
//! Returns TRUE if computation was successful.
//! Otherwise returns FALSE.
Standard_Boolean IsDone() const
{
return myIsDone;
}
//! Returns the code of completion:
//! 0 - means successful completion;
//! 1 - the process was not started;
//! 2,3 - invalid source data for the algorithm;
//! 4 - projection failed.
Standard_Integer ErrorStatus() const
{
return myErrorStatus;
}
public: //! @name Obtaining results
//! Returns resulting common parts
const IntTools_SequenceOfCommonPrts& CommonParts() const
{
return mySeqOfCommonPrts;
}
protected: //! @name Protected methods performing the intersection
Standard_EXPORT static Standard_Boolean IsEqDistance (const gp_Pnt& aP, const BRepAdaptor_Surface& aS, const Standard_Real aT, Standard_Real& aD);
Standard_EXPORT void CheckData();
@@ -161,18 +196,11 @@ protected:
//! Checks if the edge is in the face really.
Standard_EXPORT Standard_Boolean IsCoincident();
private:
TopoDS_Edge myEdge;
TopoDS_Face myFace;
Standard_Real myFuzzyValue;
Standard_Integer myDiscret;
Standard_Real myEpsT;
Standard_Real myDeflection;
BRepAdaptor_Curve myC;
BRepAdaptor_Surface myS;
Standard_Real myCriteria;
@@ -181,20 +209,7 @@ private:
Handle(IntTools_Context) myContext;
IntTools_SequenceOfCommonPrts mySeqOfCommonPrts;
IntTools_Range myRange;
//! Allows avoiding use Edge-Face intersection
//! algorithm (i.e. speeding up the Boolean algorithm)
//! if the edges are coincided really.
//! If it is not evidently set of this flag should
//! be avoided (otherwise, the performance of
//! Boolean algorithm will be slower).
Standard_Boolean myQuickCoincidenceCheck;
};
#endif // _IntTools_EdgeFace_HeaderFile