Archived issue #0032454
Use of BRepBuilderAPI_NurbsConvert create self intersecting 2d curves
Description
Our program converts a BRep model to NURBS, using ''BRepBuilderAPI_NurbsConvert''.
After loading the data file 0_541 of the ABC repository, in STEP format, after the run of ''BRepBuilderAPI_NurbsConvert'' one of the p-curve is an approximation of a line segment by a 2D NURBS curve of degree 3, with 25 poles and 23 knots.
After the conversion, the same p-curve is turned into a 2D NURBS curve of degree 8, with 55 poles and 8 knots. The curve is still a good approximation of a line segment, but it is no longer monotonous along its U parameter, and it self-intersects.
After loading the data file 0_541 of the ABC repository, in STEP format, after the run of ''BRepBuilderAPI_NurbsConvert'' one of the p-curve is an approximation of a line segment by a 2D NURBS curve of degree 3, with 25 poles and 23 knots.
After the conversion, the same p-curve is turned into a 2D NURBS curve of degree 8, with 55 poles and 8 knots. The curve is still a good approximation of a line segment, but it is no longer monotonous along its U parameter, and it self-intersects.
Steps to reproduce
In the zip file attached, there are three files:
- ''abc_0_541.step'' (the data file),
- ''bug.cpp'' (a short C++ code), and
- ''CMakeLists.txt''
Once compiled and run, the code dumps the BRep model before and after the conversion to NURBS:
<file cpp bug.cpp>
#include <BRepTools.hxx>
#include <STEPControl_Reader.hxx>
#include <TopoDS_Shape.hxx>
#include <BRepBuilderAPI_NurbsConvert.hxx>
int main() {
std::cerr.precision(17);
STEPControl_Reader stepreader;
const auto error = stepreader.ReadFile("abc_0_541.step");
if(error != IFSelect_RetDone) {
std::clog << "File abc_0_541.step is NOT loaded\n"
<< "\n Error code: " << static_cast<int>(error) << std::endl;
return EXIT_FAILURE;
}
(void)stepreader.TransferRoots();
TopoDS_Shape main_shape = stepreader.OneShape();
std::cerr << "== BEFORE CONVERSION ==\n";
BRepTools::Dump(main_shape, std::cerr);
std::cerr << "== AFTER CONVERSION ==\n";
BRepBuilderAPI_NurbsConvert nurbsconvert{main_shape};
BRepTools::Dump(nurbsconvert.Shape(), std::cerr);
}
</file>
In the two dumps, the TShape # 41 is a Face, with a trimmed cylinder as surface 27 (once converted to NURBS, it is a classical parametrization of a cylinder as a Bspline of degrees 2×1, with 6×2 poles). That Face # 41 has a wire (TShape # 42) that has the edge "TShape # 49" with this description in the first dump:
<code>
TShape # 49 : EDGE 01010000 0xa58b90
+55 -63
Tolerance : 9.[revision removed]-08
same parametrisation of curves
same range on curves
- Curve 3D : 35, range : 5.6641241593285541 6.4778357569350735
- PCurve : 27 on surface 14, range : 5.6641241593285541 6.4778357569350735
UV Points : 5.6641241593285523, -78.372705550958116 6.4778357569350717, -78.372705550958116
- Regularity C0 on surfaces : 14, 4
</code>
and that one once converted to NURBS:
<code>
TShape # 49 : EDGE 01010000 0x7acf7c0
+55 -63
Tolerance : 0.73942162508171971
same parametrisation of curves
same range on curves
- Curve 3D : 35, range : 5.664124159328555 6.4778357569350735
- PCurve : 69 on surface 14, range : 5.664124159328555 6.4778357569350735
UV Points : 5.6641241593285523, -78.372705550958116 6.5405210113735581, -78.372705550958116
- PCurve : 70 on surface 4, range : 5.664124159328555 6.4778357569350735
UV Points : 16.980732143350746, 12.098646034816255 20.456254854700788, -4.0328820116053947
</code>
The curve of interest is the p-curve on surface 14.
Its description in the first dump is:
<code>
27 : BSplineCurve
Degree 3, 25 Poles, 23 KnotsPoles :
1 : 5.6641241593285523, -78.372705550958116
2 : 5.6764531229286508, -78.372705550958116
3 : 5.7011110501288478, -78.372705550958116
4 : 5.7380979409291459, -78.372705550958116
5 : 5.7750848317294405, -78.372705550958131
6 : 5.8120717225297378, -78.372705550958116
7 : 5.8490586133300342, -78.372705550958102
8 : 5.8860455041303288, -78.372705550958088
9 : 5.9230323949306278, -78.372705550958116
10 : 5.9600192857309224, -78.372705550958116
11 : 5.9970061765312188, -78.372705550958102
12 : 6.0339930673315143, -78.372705550958116
13 : 6.0709799581318125, -78.372705550958116
14 : 6.1079668489321062, -78.372705550958102
15 : 6.1449537397324052, -78.372705550958116
16 : 6.1819406305326989, -78.372705550958102
17 : 6.2189275213329971, -78.372705550958116
18 : 6.2559144121332935, -78.372705550958116
19 : 6.2929013029335898, -78.372705550958116
20 : 6.3298881937338862, -78.372705550958116
21 : 6.3668750845341826, -78.372705550958116
22 : 6.4038619753344781, -78.372705550958102
23 : 6.4408488661347763, -78.372705550958131
24 : 6.4655067933349732, -78.372705550958116
25 : 6.4778357569350717, -78.372705550958116
Knots :
1 : 5.6641241593285541 4
2 : 5.7011110501288504 1
3 : 5.7380979409291468 1
4 : 5.7750848317294432 1
5 : 5.8120717225297396 1
6 : 5.849058613330036 1
7 : 5.8860455041303323 1
8 : 5.9230323949306287 1
9 : 5.9600192857309251 1
10 : 5.9970061765312215 1
11 : 6.033993067331517 1
12 : 6.0709799581318133 1
13 : 6.1079668489321097 1
14 : 6.1449537397324061 1
15 : 6.1819406305327025 1
16 : 6.2189275213329989 1
17 : 6.2559144121332952 1
18 : 6.2929013029335916 1
19 : 6.329888193733888 1
20 : 6.3668750845341844 1
21 : 6.4038619753344808 1
22 : 6.4408488661347771 1
23 : 6.4778357569350735 4
</code>
and after the conversion by ''BRepBuilderAPI_NurbsConvert'' it is:
<code>
69 : BSplineCurve
Degree 8, 55 Poles, 8 KnotsPoles :
1 : 5.6641241593285523, -78.372705550958116
2 : 5.7111045851503919, -78.372705550960319
3 : 5.7592102358313193, -78.372705550957733
4 : 5.8084883360166817, -78.372705550958344
5 : 5.8589891808044383, -78.37270555096211
6 : 5.9107665658578492, -78.372705550964923
7 : 5.9638782175181468, -78.372705550963076
8 : 6.0183862229172096, -78.372705550957491
9 : 6.1023430718217488, -78.372705550958059
10 : 6.1306945268855566, -78.372705550958031
11 : 6.1594201516579172, -78.372705550958017
12 : 6.1885286166717144, -78.372705550958017
13 : 6.2180289366164745, -78.372705550958017
14 : 6.2479304703383569, -78.372705550958031
15 : 6.2782429208401629, -78.372705550958074
16 : 6.3099367537295716, -78.372705550958116
17 : 6.3108975842300099, -78.372705550958116
18 : 6.3118588267826414, -78.372705550958116
19 : 6.3128204813874698, -78.372705550958116
20 : 6.313782548044494, -78.372705550958116
21 : 6.3147450267537142, -78.372705550958116
22 : 6.3157079175151303, -78.372705550958116
23 : 6.3166712203287432, -78.372705550958116
24 : 6.3160575415972273, -78.372705551446415
25 : 6.3257493288624103, -78.372705549933016
26 : 6.2888450152608568, -78.372705549933016
27 : 6.3435767701088919, -78.372705534100533
28 : 6.2987068102888299, -78.372705544810742
29 : 6.3212036902045368, -78.372705550398678
30 : 6.3151716882643525, -78.372705551271793
31 : 6.3161225077645842, -78.372705550958116
32 : 6.3162179819648268, -78.372705550958116
33 : 6.3163134561650667, -78.372705550958116
34 : 6.3164089303653093, -78.372705550958116
35 : 6.3165044045655518, -78.372705550958116
36 : 6.3165998787657944, -78.372705550958116
37 : 6.3166953529660352, -78.372705550958116
38 : 6.3167908271662769, -78.372705550958116
39 : 6.3168863013665204, -78.372705550958116
40 : 6.3312488804298921, -78.372705551446415
41 : 6.2953483294772452, -78.372705549933016
42 : 6.3602514406160919, -78.372705549933016
43 : 6.2880779955962209, -78.372705534100533
44 : 6.3440051331494471, -78.372705544810742
45 : 6.3185641157110224, -78.372705550398678
46 : 6.326795463567076, -78.372705551271793
47 : 6.3268158673841732, -78.372705550958116
48 : 6.3552521565805549, -78.372705550958059
49 : 6.3831644371139973, -78.372705550958031
50 : 6.4105694814602927, -78.372705550958017
51 : 6.4374833165857464, -78.372705550958017
52 : 6.4639212239471862, -78.372705550958017
53 : 6.4898977394919672, -78.372705550958031
54 : 6.5154266536579604, -78.372705550958074
55 : 6.5405210113735581, -78.372705550958116
Knots :
1 : 5.664124159328555 9
2 : 6.0709799581318142 7
3 : 6.2744078575334434 7
4 : 6.280764979389744 8
5 : 6.2823045948393172 8
6 : 6.2830683884412544 8
7 : 6.2891548687066861 8
8 : 6.4778357569350735 9
</code>
In both case, the p-curve is 2D line segment. The second coordinates of control points is always almost -78.37270555. Have a look at the first coordinate: you can see that it is not monotonous in curve 69, after the conversion. See for example:
<code>
41 : 6.2953483294772452, -78.372705549933016
42 : 6.3602514406160919, -78.372705549933016
43 : 6.2880779955962209, -78.372705534100533
44 : 6.3440051331494471, -78.372705544810742
45 : 6.3185641157110224, -78.372705550398678
</code>
That makes a curve that self-intersect, and that creates a bug in our application.
- ''abc_0_541.step'' (the data file),
- ''bug.cpp'' (a short C++ code), and
- ''CMakeLists.txt''
Once compiled and run, the code dumps the BRep model before and after the conversion to NURBS:
<file cpp bug.cpp>
#include <BRepTools.hxx>
#include <STEPControl_Reader.hxx>
#include <TopoDS_Shape.hxx>
#include <BRepBuilderAPI_NurbsConvert.hxx>
int main() {
std::cerr.precision(17);
STEPControl_Reader stepreader;
const auto error = stepreader.ReadFile("abc_0_541.step");
if(error != IFSelect_RetDone) {
std::clog << "File abc_0_541.step is NOT loaded\n"
<< "\n Error code: " << static_cast<int>(error) << std::endl;
return EXIT_FAILURE;
}
(void)stepreader.TransferRoots();
TopoDS_Shape main_shape = stepreader.OneShape();
std::cerr << "== BEFORE CONVERSION ==\n";
BRepTools::Dump(main_shape, std::cerr);
std::cerr << "== AFTER CONVERSION ==\n";
BRepBuilderAPI_NurbsConvert nurbsconvert{main_shape};
BRepTools::Dump(nurbsconvert.Shape(), std::cerr);
}
</file>
In the two dumps, the TShape # 41 is a Face, with a trimmed cylinder as surface 27 (once converted to NURBS, it is a classical parametrization of a cylinder as a Bspline of degrees 2×1, with 6×2 poles). That Face # 41 has a wire (TShape # 42) that has the edge "TShape # 49" with this description in the first dump:
<code>
TShape # 49 : EDGE 01010000 0xa58b90
+55 -63
Tolerance : 9.[revision removed]-08
same parametrisation of curves
same range on curves
- Curve 3D : 35, range : 5.6641241593285541 6.4778357569350735
- PCurve : 27 on surface 14, range : 5.6641241593285541 6.4778357569350735
UV Points : 5.6641241593285523, -78.372705550958116 6.4778357569350717, -78.372705550958116
- Regularity C0 on surfaces : 14, 4
</code>
and that one once converted to NURBS:
<code>
TShape # 49 : EDGE 01010000 0x7acf7c0
+55 -63
Tolerance : 0.73942162508171971
same parametrisation of curves
same range on curves
- Curve 3D : 35, range : 5.664124159328555 6.4778357569350735
- PCurve : 69 on surface 14, range : 5.664124159328555 6.4778357569350735
UV Points : 5.6641241593285523, -78.372705550958116 6.5405210113735581, -78.372705550958116
- PCurve : 70 on surface 4, range : 5.664124159328555 6.4778357569350735
UV Points : 16.980732143350746, 12.098646034816255 20.456254854700788, -4.0328820116053947
</code>
The curve of interest is the p-curve on surface 14.
Its description in the first dump is:
<code>
27 : BSplineCurve
Degree 3, 25 Poles, 23 KnotsPoles :
1 : 5.6641241593285523, -78.372705550958116
2 : 5.6764531229286508, -78.372705550958116
3 : 5.7011110501288478, -78.372705550958116
4 : 5.7380979409291459, -78.372705550958116
5 : 5.7750848317294405, -78.372705550958131
6 : 5.8120717225297378, -78.372705550958116
7 : 5.8490586133300342, -78.372705550958102
8 : 5.8860455041303288, -78.372705550958088
9 : 5.9230323949306278, -78.372705550958116
10 : 5.9600192857309224, -78.372705550958116
11 : 5.9970061765312188, -78.372705550958102
12 : 6.0339930673315143, -78.372705550958116
13 : 6.0709799581318125, -78.372705550958116
14 : 6.1079668489321062, -78.372705550958102
15 : 6.1449537397324052, -78.372705550958116
16 : 6.1819406305326989, -78.372705550958102
17 : 6.2189275213329971, -78.372705550958116
18 : 6.2559144121332935, -78.372705550958116
19 : 6.2929013029335898, -78.372705550958116
20 : 6.3298881937338862, -78.372705550958116
21 : 6.3668750845341826, -78.372705550958116
22 : 6.4038619753344781, -78.372705550958102
23 : 6.4408488661347763, -78.372705550958131
24 : 6.4655067933349732, -78.372705550958116
25 : 6.4778357569350717, -78.372705550958116
Knots :
1 : 5.6641241593285541 4
2 : 5.7011110501288504 1
3 : 5.7380979409291468 1
4 : 5.7750848317294432 1
5 : 5.8120717225297396 1
6 : 5.849058613330036 1
7 : 5.8860455041303323 1
8 : 5.9230323949306287 1
9 : 5.9600192857309251 1
10 : 5.9970061765312215 1
11 : 6.033993067331517 1
12 : 6.0709799581318133 1
13 : 6.1079668489321097 1
14 : 6.1449537397324061 1
15 : 6.1819406305327025 1
16 : 6.2189275213329989 1
17 : 6.2559144121332952 1
18 : 6.2929013029335916 1
19 : 6.329888193733888 1
20 : 6.3668750845341844 1
21 : 6.4038619753344808 1
22 : 6.4408488661347771 1
23 : 6.4778357569350735 4
</code>
and after the conversion by ''BRepBuilderAPI_NurbsConvert'' it is:
<code>
69 : BSplineCurve
Degree 8, 55 Poles, 8 KnotsPoles :
1 : 5.6641241593285523, -78.372705550958116
2 : 5.7111045851503919, -78.372705550960319
3 : 5.7592102358313193, -78.372705550957733
4 : 5.8084883360166817, -78.372705550958344
5 : 5.8589891808044383, -78.37270555096211
6 : 5.9107665658578492, -78.372705550964923
7 : 5.9638782175181468, -78.372705550963076
8 : 6.0183862229172096, -78.372705550957491
9 : 6.1023430718217488, -78.372705550958059
10 : 6.1306945268855566, -78.372705550958031
11 : 6.1594201516579172, -78.372705550958017
12 : 6.1885286166717144, -78.372705550958017
13 : 6.2180289366164745, -78.372705550958017
14 : 6.2479304703383569, -78.372705550958031
15 : 6.2782429208401629, -78.372705550958074
16 : 6.3099367537295716, -78.372705550958116
17 : 6.3108975842300099, -78.372705550958116
18 : 6.3118588267826414, -78.372705550958116
19 : 6.3128204813874698, -78.372705550958116
20 : 6.313782548044494, -78.372705550958116
21 : 6.3147450267537142, -78.372705550958116
22 : 6.3157079175151303, -78.372705550958116
23 : 6.3166712203287432, -78.372705550958116
24 : 6.3160575415972273, -78.372705551446415
25 : 6.3257493288624103, -78.372705549933016
26 : 6.2888450152608568, -78.372705549933016
27 : 6.3435767701088919, -78.372705534100533
28 : 6.2987068102888299, -78.372705544810742
29 : 6.3212036902045368, -78.372705550398678
30 : 6.3151716882643525, -78.372705551271793
31 : 6.3161225077645842, -78.372705550958116
32 : 6.3162179819648268, -78.372705550958116
33 : 6.3163134561650667, -78.372705550958116
34 : 6.3164089303653093, -78.372705550958116
35 : 6.3165044045655518, -78.372705550958116
36 : 6.3165998787657944, -78.372705550958116
37 : 6.3166953529660352, -78.372705550958116
38 : 6.3167908271662769, -78.372705550958116
39 : 6.3168863013665204, -78.372705550958116
40 : 6.3312488804298921, -78.372705551446415
41 : 6.2953483294772452, -78.372705549933016
42 : 6.3602514406160919, -78.372705549933016
43 : 6.2880779955962209, -78.372705534100533
44 : 6.3440051331494471, -78.372705544810742
45 : 6.3185641157110224, -78.372705550398678
46 : 6.326795463567076, -78.372705551271793
47 : 6.3268158673841732, -78.372705550958116
48 : 6.3552521565805549, -78.372705550958059
49 : 6.3831644371139973, -78.372705550958031
50 : 6.4105694814602927, -78.372705550958017
51 : 6.4374833165857464, -78.372705550958017
52 : 6.4639212239471862, -78.372705550958017
53 : 6.4898977394919672, -78.372705550958031
54 : 6.5154266536579604, -78.372705550958074
55 : 6.5405210113735581, -78.372705550958116
Knots :
1 : 5.664124159328555 9
2 : 6.0709799581318142 7
3 : 6.2744078575334434 7
4 : 6.280764979389744 8
5 : 6.2823045948393172 8
6 : 6.2830683884412544 8
7 : 6.2891548687066861 8
8 : 6.4778357569350735 9
</code>
In both case, the p-curve is 2D line segment. The second coordinates of control points is always almost -78.37270555. Have a look at the first coordinate: you can see that it is not monotonous in curve 69, after the conversion. See for example:
<code>
41 : 6.2953483294772452, -78.372705549933016
42 : 6.3602514406160919, -78.372705549933016
43 : 6.2880779955962209, -78.372705534100533
44 : 6.3440051331494471, -78.372705544810742
45 : 6.3185641157110224, -78.372705550398678
</code>
That makes a curve that self-intersect, and that creates a bug in our application.
Public activity
4 archived notes
Participants are labeled by their role within this record.
Note that I have tried with a recent version of the the Git master branch:
#define OCC_VERSION_MAJOR 7
#define OCC_VERSION_MINOR 6
#define OCC_VERSION_MAINTENANCE 0
#define OCC_VERSION_DEVELOPMENT "dev"
My HEAD is:
<code>
[revision removed] (upstream/master)
Author: kgv <[email removed]>
Date: Fri Jun 4 11:28:49 2021 +0300
0032419: Coding Rules - revert Overlaps() methods to SelectBasics_SelectingVolumeManager as deprecated aliases
Deprecated Overlaps() methods have been moved from subclass SelectMgr_SelectingVolumeManager
to the base class SelectBasics_SelectingVolumeManager,
so that they are actually accessible within Select3D_SensitiveEntity::Matches() implementations.
Several methods have been marked as pure virtual in the base interface.
Second SelectMgr_BaseIntersector::OverlapsPolygon() has been dropped from virtual interface
as useless (trivially replaceable).
</code>
#define OCC_VERSION_MAJOR 7
#define OCC_VERSION_MINOR 6
#define OCC_VERSION_MAINTENANCE 0
#define OCC_VERSION_DEVELOPMENT "dev"
My HEAD is:
<code>
[revision removed] (upstream/master)
Author: kgv <[email removed]>
Date: Fri Jun 4 11:28:49 2021 +0300
0032419: Coding Rules - revert Overlaps() methods to SelectBasics_SelectingVolumeManager as deprecated aliases
Deprecated Overlaps() methods have been moved from subclass SelectMgr_SelectingVolumeManager
to the base class SelectBasics_SelectingVolumeManager,
so that they are actually accessible within Select3D_SensitiveEntity::Matches() implementations.
Several methods have been marked as pure virtual in the base interface.
Second SelectMgr_BaseIntersector::OverlapsPolygon() has been dropped from virtual interface
as useless (trivially replaceable).
</code>
I have re-tested recently, and the bug is still there.
This time I checked with the following commit:
[revision removed] (upstream-dev/IR-2021-09-10, upstream-dev/CR0-WEEK-36)
Author: asuraven <[email removed]>
Date: Tue Jul 13 17:17:51 2021 +0300
0032450: Modeling Algorithms - change BRepLib_CheckCurveOnSurface & GeomLib_CheckCurveOnSurface interfaces to adapters
My remote upstream-dev is ssh://[email removed]/occt
This time I checked with the following commit:
[revision removed] (upstream-dev/IR-2021-09-10, upstream-dev/CR0-WEEK-36)
Author: asuraven <[email removed]>
Date: Tue Jul 13 17:17:51 2021 +0300
0032450: Modeling Algorithms - change BRepLib_CheckCurveOnSurface & GeomLib_CheckCurveOnSurface interfaces to adapters
My remote upstream-dev is ssh://[email removed]/occt
Analysis
This problem is caused by wrong working of projection algorithm
Related records