In ProjLib_ComputeApprox algorithm, compute correct parametric tolerance from the input 3D tolerance using surface resolution, in order to pass it to low-level 2D algorithm Approx_FitAndDivide2d (instantiation of the generic class Approx_ComputeCLine). Earlier 3D tolerance was used as parametric tolerance directly, which was a problem for surfaces with too small radius of curvature.
Also, eliminate redundant creation of the object of type AppParCurves_MultiCurve on each iteration in the method Approx_ComputeCLine::Compute.
The post treatment of the Edge/Edge intersections has been improved. Namely:
a. Making the procedure of sharing Edge/Edge intersection vertices consistent with intersection algorithm by enlarging bounding box of each vertex on half of Precision::Confusion();
b. Algorithm of computation of vertex tolerance (in order to cover tangent zone between Edges) has been changed for Line/Circle cases.
Test cases for issue CR27804
Adjusting test cases according to their new behavior.
Mark the test boolean/volumemaker/A8 as unstable between different versions of MSVS (2010 and 2013).
for (deg = mydegremin; deg <= mydegremax; deg++) {
- AppParCurves_MultiCurve mySCU(deg+1);
AppCont_LeastSquare LSquare(Line, Ufirst, Ulast, myfirstC, mylastC, deg, NbPoints);
mydone = LSquare.IsDone();
if (mydone) {
LSquare.Error(Fv, TheTol3d, TheTol2d);
if (TheTol3d <= mytol3d && TheTol2d <= mytol2d) {
- mySCU = LSquare.Value();
// Stockage de la multicurve approximee.
tolreached = Standard_True;
- myMultiCurves.Append(mySCU);
+ myMultiCurves.Append(LSquare.Value());
myfirstparam.Append(Ufirst);
mylastparam.Append(Ulast);
Tolers3d.Append(TheTol3d);
const IntTools_SequenceOfCommonPrts& aCPrts = anEdgeEdge.CommonParts();
aNbCPrts = aCPrts.Length();
//
- Standard_Boolean bLineLine = Standard_False;
+ Standard_Boolean bAnalytical = Standard_False;
if (aNbCPrts) {
const TopoDS_Edge& aOE1 = *(TopoDS_Edge*)&myDS->Shape(nE1);
const TopoDS_Edge& aOE2 = *(TopoDS_Edge*)&myDS->Shape(nE2);
//
BRepAdaptor_Curve aBAC1(aOE1), aBAC2(aOE2);
//
- bLineLine = (aBAC1.GetType() == GeomAbs_Line &&
- aBAC2.GetType() == GeomAbs_Line);
+ GeomAbs_CurveType aType1 = aBAC1.GetType();
+ GeomAbs_CurveType aType2 = aBAC2.GetType();
+ //
+ bAnalytical = (((aType1 == GeomAbs_Line) &&
+ (aType2 == GeomAbs_Line ||
+ aType2 == GeomAbs_Circle)) ||
+ ((aType2 == GeomAbs_Line) &&
+ (aType1 == GeomAbs_Line ||
+ aType1 == GeomAbs_Circle)));
}
//
for (i=1; i<=aNbCPrts; ++i) {
//
BOPTools_AlgoTools::MakeNewVertex(aE1, aT1, aE2, aT2, aVnew);
Standard_Real aTolVnew = BRep_Tool::Tolerance(aVnew);
- if (bLineLine) {
+ if (bAnalytical) {
// increase tolerance for Line/Line intersection, but do not update
// the vertex till its intersection with some other shape
- Standard_Real aTolMin = (aCR1.Last() - aCR1.First()) / 2.;
+ Standard_Real aTolMin = (BRepAdaptor_Curve(aE1).GetType() == GeomAbs_Line) ?
+ (aCR1.Last() - aCR1.First()) / 2. : (aCR2.Last() - aCR2.First()) / 2.;
if (aTolMin > aTolVnew) {
aTolVnew = aTolMin;
}
Bnd_Box> aTreeFiller(aBBTree);
BOPAlgo_VectorOfTNV aVTNV;
//
+ Standard_Real aTolAdd = Precision::Confusion() / 2.;
aNbV = theMVCPB.Extent();
for (i=1; i<=aNbV; ++i) {
const TopoDS_Vertex& aV = *((TopoDS_Vertex*)&theMVCPB.FindKey(i));
//
aTol = theMVCPB.FindFromIndex(i).Tolerance();
aBox.Add(BRep_Tool::Pnt(aV));
- aBox.SetGap(aTol);
+ aBox.SetGap(aTol + aTolAdd);
//
aTreeFiller.Add(i, aBox);
//
}
};
+//=======================================================================
+//function : ComputeTolU
+//purpose :
+//=======================================================================
+
+static Standard_Real ComputeTolU(const Handle(Adaptor3d_HSurface)& theSurf,
+ const Standard_Real theTolerance)
+{
+ Standard_Real aTolU = theSurf->UResolution(theTolerance);
+ if (theSurf->IsUPeriodic())
+ {
+ aTolU = Min(aTolU, 0.01*theSurf->UPeriod());
+ }
+
+ return aTolU;
+}
+
+//=======================================================================
+//function : ComputeTolV
+//purpose :
+//=======================================================================
+
+static Standard_Real ComputeTolV(const Handle(Adaptor3d_HSurface)& theSurf,
+ const Standard_Real theTolerance)
+{
+ Standard_Real aTolV = theSurf->VResolution(theTolerance);
+ if (theSurf->IsVPeriodic())
+ {
+ aTolV = Min(aTolV, 0.01*theSurf->VPeriod());
+ }
+
+ return aTolV;
+}
+
//=======================================================================
//function : ProjLib_ComputeApprox
//purpose :
Deg2 = 12;
}
//-------------
- Approx_FitAndDivide2d Fit(F,Deg1,Deg2,myTolerance,myTolerance,
- Standard_True);
+ const Standard_Real aTolU = ComputeTolU(S, myTolerance);
+ const Standard_Real aTolV = ComputeTolV(S, myTolerance);
+ const Standard_Real aTol2d = Max(Sqrt(aTolU*aTolU + aTolV*aTolV), Precision::PConfusion());
+
+ Approx_FitAndDivide2d Fit(F, Deg1, Deg2, myTolerance, aTol2d, Standard_True);
+
+ Standard_Real aNewTol2d = 0;
if(Fit.IsAllApproximated()) {
Standard_Integer i;
Standard_Integer NbCurves = Fit.NbMultiCurves();
// on essaie de rendre la courbe au moins C1
Convert_CompBezierCurves2dToBSplineCurve2d Conv;
- myTolerance = 0;
Standard_Real Tol3d,Tol2d;
for (i = 1; i <= NbCurves; i++) {
Fit.Error(i,Tol3d, Tol2d);
- myTolerance = Max(myTolerance, Tol2d);
+ aNewTol2d = Max(aNewTol2d, Tol2d);
AppParCurves_MultiCurve MC = Fit.Value( i); //Charge la Ieme Curve
TColgp_Array1OfPnt2d Poles2d( 1, MC.Degree() + 1);//Recupere les poles
MC.Curve(1, Poles2d);
if(NbCurves != 0) {
Standard_Real Tol3d,Tol2d;
Fit.Error(NbCurves,Tol3d, Tol2d);
- myTolerance = Tol2d;
+ aNewTol2d = Tol2d;
}
}
+ // restore tolerance 3d from 2d
+
+ //Here we consider that
+ // aTolU(new)/aTolV(new) = aTolU(old)/aTolV(old)
+ //(it is assumption indeed).
+ //Then,
+ // Tol3D(new)/Tol3D(old) = Tol2D(new)/Tol2D(old).
+ myTolerance *= (aNewTol2d / aTol2d);
+
//Return curve home
Standard_Real UFirst = F.FirstParameter();
gp_Pnt P3d = C->Value( UFirst );
# test script on make volume operation
# plane sphere
-puts "TODO OCC26020 Windows: Faulty shapes in variables faulty_1 to faulty_"
+puts "TODO ?OCC26020 Windows: Faulty shapes in variables faulty_1 to faulty_"
puts "TODO OCC26020 ALL: Error: bopcheck failed"
puts "TODO OCC26020 ALL: Error : The area of result shape is"
--- /dev/null
+puts "============"
+puts "OCC27804"
+puts "============"
+puts ""
+################################################################
+## Two breps cause intersections to loop for too long/infinitely
+################################################################
+
+# The main idea of the test is performance meter.
+
+restore [locate_data_file bug27804_il1.brep] b1
+restore [locate_data_file bug27804_il2.brep] b2
+
+bsection result b1 b2
+
+checkprops result -l 0.000335043
+checkshape result
+
+regexp {nb alone Vertices : ([-0-9.+eE]+)} [checksection result] full nbv
+if { $nbv != 0 } { puts "Error : Section is incorrect" }
+
+set nbshapes_expected "
+Number of shapes in shape
+ VERTEX : 1
+ EDGE : 1
+ WIRE : 0
+ FACE : 0
+ SHELL : 0
+ SOLID : 0
+ COMPSOLID : 0
+ COMPOUND : 1
+ SHAPE : 3
+"
+
+checknbshapes result -ref ${nbshapes_expected} -t -m "Section curve"
+
+checkview -display result -3d -path ${imagedir}/${test_image}.png
--- /dev/null
+puts "============"
+puts "OCC27804"
+puts "============"
+puts ""
+################################################################
+## Two breps cause intersections to loop for too long/infinitely
+################################################################
+
+# The main idea of the test is performance meter.
+
+
+restore [locate_data_file bug27804_il1.brep] b1
+restore [locate_data_file bug27804_il2.brep] b2
+
+explode b2 e
+
+#should create pcurve
+bhaspc b2_1 b1 do
+
+mk2dcurve c2d b2_1 b1
+
+if { [regexp "2d curve" [whatis c2d]] != 1 } {
+ puts "Faulty: No 2D curves detected"
+}
+
+v2d
+donly c2d
+2dfit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
\ No newline at end of file