3

我测试了两种情况:

我使用 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 );

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

4

1 回答 1

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 助手)中使用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;
于 2020-02-13T19:07:16.117 回答