调用 Transfer() 时 Opencascade 崩溃

Val*_*Ral 3 step opencascade freecad

我测试过两种情况:

我使用 STEPCAFControl_Reader 然后 STEPControl_Reader 来读取我的步骤文件,但是当我分别调用 STEPCAFControl_Reader::Transfer 和 STEPControl_Reader:: TransferRoots 时,这两种方法都会崩溃。

通过使用 STEPControl_Reader,我在控制台上显示了一条日志,然后出现如下消息:

1 F:(BOUNDED_SURFACE、B_SPLINE_SURFACE、B_SPLINE_SURFACE_WITH_KNOTS、GEOMETRIC_REPRESENTATION_ITEM、RATIONAL_B_SPLINE_SURFACE、REPRESENTATION_ITEM、SURFACE):representation_item 的参数计数不为 1

编辑:

TransferRoots() 方法内有一个空引用。

const Handle(Transfer_TransientProcess) &proc = thesession->TransferReader()->TransientProcess();
if (proc->GetProgress().IsNull())
{
   //This condition does not exist from the source code
   std::cout << "GetProgress is null" << std::endl;
   return 0;
 }    
Message_ProgressSentry PS ( proc->GetProgress(), "Root", 0, nb, 1 );
Run Code Online (Sandbox Code Playgroud)

我的应用程序和 FreeCAD 崩溃,但如果我使用 CAD Assitant(OCC 官方查看器),它会加载。

gkv*_*311 5

看起来评论已经提供了问题的答案 - 或者更准确地说答案

  • STEPCAFControl_Reader::ReadFile()返回读取状态,应在调用STEPCAFControl_Reader::Transfer()之前检查该状态。

  • 通常,将 OCCT 算法放入try/catch块并检查 OCCT 异常 ( Standard_Failure ) 是一个很好的做法。

  • 在 try 语句的开头添加OCC_CATCH_SIGNALS (仅在 Linux 上需要)并在工作线程创建中添加 OSD::SetSignal(false)以将异常情况(访问冲突、NULL 取消引用等)重定向到 C++ 异常(OSD_SignalStandard_Failure的子类) 。这可能会与混合环境中的其他信号处理程序发生冲突 - 因此还要检查应用程序使用的其他框架的文档。

  • 如果您在使用有效参数调用 OCCT 算法时发现诸如 NULL 取消引用之类的失败 - 这是OCCT 中的一个错误,需要以一种或另一种方式修复,即使输入 STEP 文件包含触发此类问题的语法/逻辑错误。在 OCCT Bugtracker 上报告问题,并提供足够的信息来重现错误,包括示例文件 - 对于开发人员来说,仅仅说 OCCT 在某个地方崩溃是没有帮助的。还可以考虑通过调试 OCCT 代码和建议补丁来为这个开源项目做出贡献。

  • 检查 STEP 文件读取日志以了解文件本身可能存在的错误。考虑向生成损坏文件的系统报告问题,即使 STEP 读取器可以加载主文件内容。

在基于 OCCT 的应用程序(如 CAD Assistant)中使用OSD::SetSignal()是一种常见的做法,以提高其对应用程序/OCCT 代码中非致命错误的鲁棒性。它更方便用户报告内部错误消息,而不是默默地崩溃。

但应该注意的是,OSD::SetSignal()并不能保证应用程序不会崩溃,也不保证应用程序在捕获此类故障后可以正常工作 - 由于某些信号的异步特性,内存此时可能已经损坏,当引发 C++ 异常时会导致各种不良行为。因此,最好不要忽略此类异常,即使应用程序看起来可以很好地处理它们。

  OSD::SetSignal(false); // should be called ones at application startup
  STEPCAFControl_Reader aReader;
  try
  {
    OCC_CATCH_SIGNALS // necessary for redirecting signals on Linux
    if (aReader.ReadFile (theFilePath) != IFSelect_RetDone) { return false; }
    if (!aReader.Transfer (myXdeDoc)) { return false; }
  }
  catch (Standard_Failure const& theFailure)
  {
    std::cerr << "STEP import failed: " << theFailure.GetMessageString() << "\n";
    return false;
  }
  return true;
Run Code Online (Sandbox Code Playgroud)