B-Spline ctor sensitive to merged knots

Forums: 

A discussion open per recommendation of Andrey Betenev, following the bug report #25971.

The issue background is that due to various modeling algorithms (e.g. those invoked from Shape Healing) a B-Spline can eventually have very near knots (e.g. differing at the 17th position after the dot). The B-Spline ctor verifies collision using Epsilon() function, i.e. tries to be as benign as possible in run-time. However once such a B-Spline get stored in a text file (where round-off errors is unavoidable), e.g. in STEP, BRep, etc then retrieving such a file becomes impossible as the rounded values becomes fully equal. BSpline ctor throws an exception.

There are various options to address an issue, for instance:
1. Make various adjustments in multiple algorithms (during import/export, ConvertToBSpline, BSplineCurve::Segment(),...)
2. Create an explicit pre-processing function (e.g. in BSplCLib) which would check and adjust knot array by moving them apart by at least Precision::PConfusion(). Such fixes are often made in IGES and STEP importers.
3. Make BSpline ctor less sensitive to merged knots and for instance have it call to the above function. In this case B-Spline ctor itself could be less sensitive to such round-off errors.

What are your thoughts on the best one ?

I am currently inclined to #2 and using it (or similar adjustments) in some methods which may most likely create such a risky knot array. The latter includes BSplCLib::Reparametrize() which currently tries to use Epsilon() as a threshold.

Mikhail Sazonov's picture

I think we should consider BSpline class as a placement for geometric data. It should not make any changes in the data before storing them in the fields. If the caller provides erroneous data this error will be highlighted by an exception in the ctor, and this will preserve consistent behavior of the class methods.
Certainly, in this case a tool for preprocessing knots array will be very useful to prepare valid data. Also, this tool should warn the caller about erroneous data in the case it corrects them.
Therefore, I also prefer the option 2.