OCCT icon indicating copy to clipboard operation
OCCT copied to clipboard

BRepOffsetAPI_ThruSections cannot work for closed B-spline curve

Open lavender-lee opened this issue 6 months ago • 1 comments

Description

I have 5 closed sections in B-spline form as shown below, I want to generate surface with BRepOffsetAPI_ThruSections.

Image

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.

Image

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

sections.zip

lavender-lee avatar May 26 '25 14:05 lavender-lee

Other case

If all the sections are open, the a surface can be generated normally.

Image

open sections

open-sections.zip

lavender-lee avatar May 26 '25 14:05 lavender-lee