1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-09 18:50:54 +03:00

0023008: Too many intersection vertices between line and cylinder

This commit is contained in:
pkv 2012-03-10 14:07:24 +04:00 committed by inv
parent 41c52af3a7
commit e8997bbd95

@ -312,8 +312,8 @@ void IntTools_BeanFaceIntersector::Perform()
{ {
myIsDone = Standard_False; myIsDone = Standard_False;
myResults.Clear(); myResults.Clear();
Standard_Boolean bRet;
Standard_Integer aDiscretization = 30; // corresponds to discretization of BSpline usually approximated by 30 points. Standard_Integer aDiscretization = 30;
Standard_Real aRelativeDeflection = 0.01; Standard_Real aRelativeDeflection = 0.01;
myDeflection = aRelativeDeflection; myDeflection = aRelativeDeflection;
// //
@ -378,7 +378,12 @@ void IntTools_BeanFaceIntersector::Perform()
IntTools_CArray1OfReal aParams; IntTools_CArray1OfReal aParams;
if(IntTools::PrepareArgs(myCurve, myLastParameter, myFirstParameter, aDiscretization, aRelativeDeflection, aParams)) { if(IntTools::PrepareArgs(myCurve,
myLastParameter,
myFirstParameter,
aDiscretization,
aRelativeDeflection,
aParams)) {
return; return;
} }
@ -387,8 +392,9 @@ void IntTools_BeanFaceIntersector::Perform()
if(myRangeManager.Length()==0) { if(myRangeManager.Length()==0) {
return; return;
} }
//
if(FastComputeExactIntersection()) { bRet=FastComputeExactIntersection();
if(bRet) {
IntTools_Range aRange(myFirstParameter, myLastParameter); IntTools_Range aRange(myFirstParameter, myLastParameter);
myResults.Append(aRange); myResults.Append(aRange);
myIsDone = Standard_True; myIsDone = Standard_True;
@ -695,99 +701,115 @@ void IntTools_BeanFaceIntersector::ComputeAroundExactIntersection()
// ================================================================================== // ==================================================================================
Standard_Boolean IntTools_BeanFaceIntersector::FastComputeExactIntersection() Standard_Boolean IntTools_BeanFaceIntersector::FastComputeExactIntersection()
{ {
Standard_Boolean aresult = Standard_False; Standard_Boolean aresult;
GeomAbs_CurveType aCT;
if((myCurve.GetType() == GeomAbs_BezierCurve) || GeomAbs_SurfaceType aST;
(myCurve.GetType() == GeomAbs_BSplineCurve) || //
(myCurve.GetType() == GeomAbs_OtherCurve)) { aresult = Standard_False;
aCT=myCurve.GetType();
aST=mySurface.GetType();
//
if((aCT==GeomAbs_BezierCurve) ||
(aCT==GeomAbs_BSplineCurve) ||
(aCT==GeomAbs_OtherCurve)) {
return aresult; return aresult;
} }
if(mySurface.GetType() == GeomAbs_Plane) { if(aST==GeomAbs_Plane) {
gp_Pln surfPlane = mySurface.Plane(); gp_Pln surfPlane = mySurface.Plane();
if(myCurve.GetType() == GeomAbs_Line) { if(aCT==GeomAbs_Line) {
if((surfPlane.Distance(myCurve.Value(myFirstParameter)) < myCriteria) && if((surfPlane.Distance(myCurve.Value(myFirstParameter)) < myCriteria) &&
(surfPlane.Distance(myCurve.Value(myLastParameter)) < myCriteria)) { (surfPlane.Distance(myCurve.Value(myLastParameter)) < myCriteria)) {
myRangeManager.InsertRange(myFirstParameter, myLastParameter, 2); myRangeManager.InsertRange(myFirstParameter, myLastParameter, 2);
aresult = Standard_True; aresult = Standard_True;
} }
} }
else { else { // else 1
gp_Dir aDir; gp_Dir aDir;
switch(myCurve.GetType()) { switch(aCT) {
case GeomAbs_Circle: { case GeomAbs_Circle: {
aDir = myCurve.Circle().Axis().Direction(); aDir = myCurve.Circle().Axis().Direction();
break; break;
} }
case GeomAbs_Ellipse: { case GeomAbs_Ellipse: {
aDir = myCurve.Ellipse().Axis().Direction(); aDir = myCurve.Ellipse().Axis().Direction();
break; break;
} }
case GeomAbs_Hyperbola: { case GeomAbs_Hyperbola: {
aDir = myCurve.Hyperbola().Axis().Direction(); aDir = myCurve.Hyperbola().Axis().Direction();
break; break;
} }
case GeomAbs_Parabola: { case GeomAbs_Parabola: {
aDir = myCurve.Parabola().Axis().Direction(); aDir = myCurve.Parabola().Axis().Direction();
break; break;
} }
default: { default: {
return aresult; return aresult;
} }
} }
//
Standard_Real anAngle = aDir.Angle(surfPlane.Axis().Direction()); Standard_Real anAngle = aDir.Angle(surfPlane.Axis().Direction());
if(anAngle < Precision::Angular()) { if(anAngle < Precision::Angular()) {
Standard_Boolean insertRange = Standard_False; Standard_Boolean insertRange = Standard_False;
switch(myCurve.GetType()) { switch(aCT) {
case GeomAbs_Circle: { case GeomAbs_Circle: {
Standard_Real adist = surfPlane.Distance(myCurve.Circle().Location()) + myCurve.Circle().Radius() * Precision::Angular(); Standard_Real adist =
surfPlane.Distance(myCurve.Circle().Location()) +
if(adist < myCriteria) { myCurve.Circle().Radius() * Precision::Angular();
insertRange = Standard_True;
if(adist < myCriteria) {
insertRange = Standard_True;
}
break;
} }
break; case GeomAbs_Ellipse: {
} Standard_Real adist =
case GeomAbs_Ellipse: { surfPlane.Distance(myCurve.Ellipse().Location()) +
Standard_Real adist = surfPlane.Distance(myCurve.Ellipse().Location()) + myCurve.Ellipse().MajorRadius() * Precision::Angular(); myCurve.Ellipse().MajorRadius() * Precision::Angular();
if(adist < myCriteria) { if(adist < myCriteria) {
insertRange = Standard_True; insertRange = Standard_True;
}
break;
} }
break; case GeomAbs_Hyperbola:
} case GeomAbs_Parabola: {
case GeomAbs_Hyperbola: Standard_Real aMaxPar =
case GeomAbs_Parabola: { (Abs(myFirstParameter) > Abs(myLastParameter)) ?
Standard_Real aMaxPar = (Abs(myFirstParameter) > Abs(myLastParameter)) ? Abs(myFirstParameter) : Abs(myLastParameter); Abs(myFirstParameter) : Abs(myLastParameter);
gp_Pnt aLoc = (myCurve.GetType() == GeomAbs_Parabola) ? myCurve.Parabola().Location() : myCurve.Hyperbola().Location();
Standard_Real adist = aLoc.Distance(myCurve.Value(aMaxPar)); gp_Pnt aLoc = (aCT == GeomAbs_Parabola) ?
adist = surfPlane.Distance(aLoc) + adist * Precision::Angular(); myCurve.Parabola().Location() :
myCurve.Hyperbola().Location();
if(adist < myCriteria) { Standard_Real adist = aLoc.Distance(myCurve.Value(aMaxPar));
insertRange = Standard_True; adist = surfPlane.Distance(aLoc) + adist * Precision::Angular();
if(adist < myCriteria) {
insertRange = Standard_True;
}
break;
}
default: {
break;
} }
break;
} }
default: { //
break;
}
}
if(insertRange) { if(insertRange) {
myRangeManager.InsertRange(myFirstParameter, myLastParameter, 2); myRangeManager.InsertRange(myFirstParameter, myLastParameter, 2);
aresult = Standard_True; aresult = Standard_True;
} }
} }//if(anAngle < Precision::Angular()) {
} }//else { // else 1
} }// if(aST==GeomAbs_Plane) {
if(myCurve.GetType() == GeomAbs_Circle) { if(aCT==GeomAbs_Circle) {
gp_Circ aCircle = myCurve.Circle(); gp_Circ aCircle = myCurve.Circle();
if(mySurface.GetType() == GeomAbs_Cylinder) { if(aST==GeomAbs_Cylinder) {
gp_Cylinder aCylinder = mySurface.Cylinder(); gp_Cylinder aCylinder = mySurface.Cylinder();
gp_Dir aDir1(aCylinder.Axis().Direction()); gp_Dir aDir1(aCylinder.Axis().Direction());
gp_Dir aDir2(aCircle.Axis().Direction()); gp_Dir aDir2(aCircle.Axis().Direction());
@ -805,7 +827,9 @@ Standard_Boolean IntTools_BeanFaceIntersector::FastComputeExactIntersection()
Standard_Real acylradius = aCylinder.Radius(); Standard_Real acylradius = aCylinder.Radius();
Standard_Real atmpvalue = aCircle.Radius() * sin(Precision::Angular()); Standard_Real atmpvalue = aCircle.Radius() * sin(Precision::Angular());
Standard_Real aprojectedradius = atmpvalue; Standard_Real aprojectedradius = atmpvalue;
aprojectedradius = sqrt((aCircle.Radius() * aCircle.Radius()) - (aprojectedradius * aprojectedradius)); aprojectedradius =
sqrt((aCircle.Radius() * aCircle.Radius())
- (aprojectedradius * aprojectedradius));
adiff = aprojectedradius - acylradius; adiff = aprojectedradius - acylradius;
adist = alocdist + Abs(adiff); adist = alocdist + Abs(adiff);
@ -815,16 +839,17 @@ Standard_Boolean IntTools_BeanFaceIntersector::FastComputeExactIntersection()
} }
} }
} }
} }// if(aST==GeomAbs_Cylinder)
if(mySurface.GetType() == GeomAbs_Sphere) { if(aST==GeomAbs_Sphere) {
gp_Pln aCirclePln(aCircle.Location(), aCircle.Axis().Direction()); gp_Pln aCirclePln(aCircle.Location(), aCircle.Axis().Direction());
IntAna_QuadQuadGeo anInter(aCirclePln, mySurface.Sphere()); IntAna_QuadQuadGeo anInter(aCirclePln, mySurface.Sphere());
if(anInter.IsDone()) { if(anInter.IsDone()) {
if(anInter.TypeInter() == IntAna_Circle) { if(anInter.TypeInter() == IntAna_Circle) {
gp_Circ aCircleToCompare = anInter.Circle(1); gp_Circ aCircleToCompare = anInter.Circle(1);
Standard_Real adist = aCircleToCompare.Location().Distance(aCircle.Location()); Standard_Real adist =
aCircleToCompare.Location().Distance(aCircle.Location());
Standard_Real adiff = aCircle.Radius() - aCircleToCompare.Radius(); Standard_Real adiff = aCircle.Radius() - aCircleToCompare.Radius();
adist += Abs(adiff); adist += Abs(adiff);
@ -834,8 +859,65 @@ Standard_Boolean IntTools_BeanFaceIntersector::FastComputeExactIntersection()
} }
} }
} }
} }// 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();
const gp_Pnt& aLocL=aLin.Location();
//
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_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){
myRangeManager.InsertRange(myFirstParameter, myLastParameter, 2);
aresult = Standard_True;
return aresult;
}
}
}//if(aCT==GeomAbs_Line) {
} }
//modified by NIZNHY-PKV Thu Mar 01 11:54:06 2012t
return aresult; return aresult;
} }