跳转至

如何使用 OCC 内核编写脚本

0. Visual Studio 工程名称

本文中一共用到三个 Visual Studio 工程,其代称意义如下。

  • OCCT:下载好的 OCC 源码工程
  • OCCT_Build:OCC 源码经过 CMake 构建之后的工程
  • OCC_Test:准备使用 OCC 内核编写脚本的工程

此外,本文中提到的 OCCTOCC Technology,一般在文件路径中用到该名称

1. OCC 编译

在下载好 OCC 的源码并通过 CMake 构建之后,会得到上图所示的 OCC 解决方案(此处目录为下文提到的 Your_OCCT_BuildPath)。

右键选择 CMakePredefinedTargets 文件夹中的 ALL_BUILD,点击生成,即编译所有的目标。

这一步主要是为了生成编写 OCC 内核脚本所需要的 lib 和 dll 文件

2. 设置依赖文件

使用 Visual Studio 构建的 OCC 脚本工程如上图所示,接着右键选择 OCC_Test,点击属性,进行编辑。

注意在属性页面中,配置默认为 DEBUG 模式,建议先选择为所有配置模式

2.1 设置 dll 环境

点击配置属性->调试->环境,输入 path=Your_OCCT_BuildPath\win64\vc14\bin

在启动项目时根据该设置可以自动链接到 dll 文件

2.2 设置头文件目录

点击配置属性->C/C++->常规->附加包含目录,输入 Your_OCCT_BuildPath\inc

2.3 设置 lib 目录

点击配置属性->链接器->常规->附加库目录,输入 Your_OCCT_BuildPath\win64\vc14\lib

2.4 设置使用到的 lib 文件

点击配置属性->链接器->输入->附加依赖项,输入 Your_OCCT_BuildPath\win64\vc14\lib 中的所有文件类型为 lib 的完整文件名

此处建议使用下列 CMD 命令将完整文件名输出为一个 txt 文件后复制输入,手动输入过于麻烦

进入到 lib 文件目录后,打开 CMD,输入:dir /b *.lib > lib_list.txt

2.5 复制 freetype.h 文件

进入到 OCC 源码中,若 OCC 已经通过 CMake 构建,则认为已经设置好所需的所有第三方依赖

在其第三方依赖中需要的 freetype.dll 通常存放在 OCC 源码目录中

比如目录:OCCT\3rdparty-vc14-64\freetype-2.13.3-x64\bin\freetype.dll

freetype.dll 复制到构建好的 OCC 解决方案目录中:OCCT_Build\win64\vc14\bin

注:这里复制该文件是为了使用 OCC 的读入 STEP 文件函数,根据实际情况自行选择

3. 示例脚本

完成上述步骤后,已经可以运行下列光线与 CAD 模型求交的脚本

注:将下列脚本放到上面提到的 OCC_Test 工程源码中即可

#include <TopoDS_Shape.hxx>
#include <TopExp_Explorer.hxx>
#include <BRepTools.hxx>
#include <IntCurvesFace_Intersector.hxx>
#include <gp_Lin.hxx>
#include <gp_Pnt.hxx>
#include <gp_Dir.hxx>
#include <BRep_Builder.hxx>
#include <TopAbs.hxx>
#include <TopoDS_Face.hxx>
#include <iostream>
#include <TopoDS.hxx>
#include <STEPControl_Reader.hxx>
#include <IFSelect_ReturnStatus.hxx>
#include <string>

void ReadStepFile(TopoDS_Shape& resShape, const std::string& fileName) 
{
    STEPControl_Reader reader;
    IFSelect_ReturnStatus status = reader.ReadFile(fileName.c_str());

    if (status != IFSelect_RetDone) 
    {
        std::cerr << "Failed to read STEP file." << std::endl;
        return;
    }

    // Turn STEP data into OCC Topo Data
    bool failsonly = false;
    reader.PrintCheckLoad(failsonly, IFSelect_ItemsByEntity);
    reader.TransferRoots();

    // Get TopoDS_Shape
    resShape = reader.OneShape();
    std::cout << "STEP file loaded successfully." << std::endl;
}

int main() 
{
    TopoDS_Shape shape;
    BRep_Builder builder;
    std::string fileName = "YourStep.stp";

    ReadStepFile(shape, fileName);

    gp_Pnt origin(0, 0, 100);
    gp_Dir dir(0, 0, -1);
    gp_Lin ray(origin, dir);

    for (TopExp_Explorer exp(shape, TopAbs_FACE); exp.More(); exp.Next()) 
    {
        TopoDS_Face face = TopoDS::Face(exp.Current());
        IntCurvesFace_Intersector intersector(face, 1e-7);
        intersector.Perform(ray, 0.0, 1000.0);

        if (intersector.IsDone()) 
        {
            if (intersector.NbPnt() <= 0)
            {
                std::cout << "Not Hit!" << std::endl;
            }
            for (int i = 1; i <= intersector.NbPnt(); ++i) {
                gp_Pnt pt = intersector.Pnt(i);
                std::cout << "Hit at: " << pt.X() << ", " << pt.Y() << ", " << pt.Z() << std::endl;
            }
        }
    }

    return 0;
}