+
+ void ComputeErrFactors (const Standard_Real theDeflection,
+ const Handle(Adaptor3d_HSurface)& theFace,
+ Standard_Real& theErrFactorU,
+ Standard_Real& theErrFactorV)
+ {
+ theErrFactorU = theDeflection * 10.;
+ theErrFactorV = theDeflection * 10.;
+
+ switch (theFace->GetType ())
+ {
+ case GeomAbs_Cylinder:
+ case GeomAbs_Cone:
+ case GeomAbs_Sphere:
+ case GeomAbs_Torus:
+ break;
+
+ case GeomAbs_SurfaceOfExtrusion:
+ case GeomAbs_SurfaceOfRevolution:
+ {
+ Handle (Adaptor3d_HCurve) aCurve = theFace->BasisCurve ();
+ if (aCurve->GetType () == GeomAbs_BSplineCurve && aCurve->Degree () > 2)
+ {
+ theErrFactorV /= (aCurve->Degree () * aCurve->NbKnots ());
+ }
+ break;
+ }
+ case GeomAbs_BezierSurface:
+ {
+ if (theFace->UDegree () > 2)
+ {
+ theErrFactorU /= (theFace->UDegree ());
+ }
+ if (theFace->VDegree () > 2)
+ {
+ theErrFactorV /= (theFace->VDegree ());
+ }
+ break;
+ }
+ case GeomAbs_BSplineSurface:
+ {
+ if (theFace->UDegree () > 2)
+ {
+ theErrFactorU /= (theFace->UDegree () * theFace->NbUKnots ());
+ }
+ if (theFace->VDegree () > 2)
+ {
+ theErrFactorV /= (theFace->VDegree () * theFace->NbVKnots ());
+ }
+ break;
+ }
+
+ case GeomAbs_Plane:
+ default:
+ theErrFactorU = theErrFactorV = 1.;
+ }
+ }
+
+ void AdjustCellsCounts (const Handle(Adaptor3d_HSurface)& theFace,
+ const Standard_Integer theNbVertices,
+ Standard_Integer& theCellsCountU,
+ Standard_Integer& theCellsCountV)
+ {
+ const GeomAbs_SurfaceType aType = theFace->GetType ();
+ if (aType == GeomAbs_OtherSurface)
+ {
+ // fallback to the default behavior
+ theCellsCountU = theCellsCountV = -1;
+ return;
+ }
+
+ Standard_Real aSqNbVert = theNbVertices;
+ if (aType == GeomAbs_Plane)
+ {
+ theCellsCountU = theCellsCountV = (Standard_Integer)Ceiling (Pow (2, Log10 (aSqNbVert)));
+ }
+ else if (aType == GeomAbs_Cylinder || aType == GeomAbs_Cone)
+ {
+ theCellsCountV = (Standard_Integer)Ceiling (Pow (2, Log10 (aSqNbVert)));
+ }
+ else if (aType == GeomAbs_SurfaceOfExtrusion || aType == GeomAbs_SurfaceOfRevolution)
+ {
+ Handle (Adaptor3d_HCurve) aCurve = theFace->BasisCurve ();
+ if (aCurve->GetType () == GeomAbs_Line ||
+ (aCurve->GetType () == GeomAbs_BSplineCurve && aCurve->Degree () < 2))
+ {
+ // planar, cylindrical, conical cases
+ if (aType == GeomAbs_SurfaceOfExtrusion)
+ theCellsCountU = (Standard_Integer)Ceiling (Pow (2, Log10 (aSqNbVert)));
+ else
+ theCellsCountV = (Standard_Integer)Ceiling (Pow (2, Log10 (aSqNbVert)));
+ }
+ if (aType == GeomAbs_SurfaceOfExtrusion)
+ {
+ // V is always a line
+ theCellsCountV = (Standard_Integer)Ceiling (Pow (2, Log10 (aSqNbVert)));
+ }
+ }
+ else if (aType == GeomAbs_BezierSurface || aType == GeomAbs_BSplineSurface)
+ {
+ if (theFace->UDegree () < 2)
+ {
+ theCellsCountU = (Standard_Integer)Ceiling (Pow (2, Log10 (aSqNbVert)));
+ }
+ if (theFace->VDegree () < 2)
+ {
+ theCellsCountV = (Standard_Integer)Ceiling (Pow (2, Log10 (aSqNbVert)));
+ }
+ }
+
+ theCellsCountU = Max (theCellsCountU, 2);
+ theCellsCountV = Max (theCellsCountV, 2);
+ }