OCCT
OCCT copied to clipboard
BRepOffsetAPI_ThruSections cannot work for closed B-spline curve
Description
I have 5 closed sections in B-spline form as shown below, I want to generate surface with BRepOffsetAPI_ThruSections.
Expected Behavior
A surface/solid can be generated normally.
Actual Behavior
However, the runtime exception BRepFill :: profiles are inconsistent was thrown when calling BRepOffsetAPI_ThruSections::Build()
==== read section 1 ====
==== read section 2 ====
==== read section 3 ====
==== read section 4 ====
==== read section 5 ====
catch exception BRepFill :: profiles are inconsistent
===== build solid by sections failed.
In addition, if all the sections are open, the surface can be generated normally.
Sample Code or DRAW Tcl Script
Considering the following code:
std::vector<double> read_data_from_file(const std::string &filename, int &n_rows, int &n_cols)
{
std::ifstream fin(filename);
std::vector<double> points;
std::string line;
n_rows = 0;
n_cols = 0;
bool done = false;
if (fin.fail())
{
throw std::runtime_error("read file failed!");
}
while (std::getline(fin, line))
{
std::stringstream str_stream(line);
std::string token;
while (std::getline(str_stream, token, ','))
{
if (!done)
{
n_cols++;
}
points.push_back(std::stod(token));
}
// count the number of columns done
done = true;
++n_rows;
}
fin.close();
return points;
}
Handle(Geom_BSplineCurve) build_Geom_BSplineCurve(std::vector<double> &P, std::vector<double> &U)
{
int n = static_cast<int>(U.size()) - 5; // cubic spline
int nb_poles = n + 1;
int degree = 3;
TColgp_Array1OfPnt poles(1, nb_poles);
int idx = 0;
for (int i = 1; i <= nb_poles; i++)
{
double x = P[idx + 0];
double y = P[idx + 1];
double z = P[idx + 2];
poles(i) = gp_Pnt(x, y, z);
idx += 3;
}
// knots sequence
int knot_seq_size = nb_poles + degree + 1;
TColStd_Array1OfReal knotsSeq(1, knot_seq_size);
memcpy(&knotsSeq[1], &U[0], knot_seq_size * sizeof(double)); // one-based index
TColStd_Array1OfReal knots(1, BSplCLib::KnotsLength(knotsSeq, /*is_periodic*/ false));
TColStd_Array1OfInteger mults(1, knots.Upper());
BSplCLib::Knots(knotsSeq, knots, mults);
return new Geom_BSplineCurve(poles, knots, mults, degree, /*is_periodic*/ false);
}
// OCC 7.7.0
void test_BRepOffsetAPI_ThruSections()
{
BRepOffsetAPI_ThruSections thruSections;
bool is_solid = true; // false
bool is_ruled = false;
double precison = 1.0e-06;
thruSections.Init(is_solid, is_ruled, precison);
int n_rows, n_cols;
char buffer[150];
char buffer2[150];
int nCurves = 5;
for (int i = 1; i <= nCurves; ++i)
{
sprintf(buffer, "D:/data/sections/P-%d.txt", i); // see attacments
std::string filename_P(buffer);
sprintf(buffer2, "D:/data/sections/U-%d.txt", i);
std::string filename_U(buffer2);
printf("==== read section %d ====\n", i);
std::vector<double> P = read_data_from_file(filename_P, n_rows, n_cols);
std::vector<double> U = read_data_from_file(filename_U, n_rows, n_cols);
const Handle(Geom_BSplineCurve) &curve = build_Geom_BSplineCurve(P, U);
BRepBuilderAPI_MakeEdge makeEdge(curve);
if (makeEdge.IsDone())
{
TopoDS_Edge edge = makeEdge.Edge();
BRepBuilderAPI_MakeWire makeWire(edge);
if (makeWire.IsDone())
thruSections.AddWire(makeWire.Wire());
else
printf("makeWire failed\n");
}
else
{
printf("makeEdge failed\n");
}
}
try
{
thruSections.Build();
}
catch (const Standard_Failure &e)
{
printf("catch exception %s\n", e.GetMessageString());
}
catch (...)
{
printf("catch unknown exception\n");
}
if (!thruSections.IsDone())
{
printf("===== build solid by sections failed.\n");
return;
}
printf("===== build solid by sections success.\n");
TopoDS_Shape bladeSurface = thruSections.Shape();
}
Operating System
Windows
Compiler
MSVC
Bitness
64-bit
OCCT Version
7.7
Additional Files
Other case
If all the sections are open, the a surface can be generated normally.