CATIA Drawing 工程图 API:自动出图、标注、视图布局完整指南

琛兴科技 · CATIA 二次开发系列 · 适用 V5R19~R32

一、原理:Drawing 文档结构与三层模型

CATIA 工程图(Drafting)和 Part / Product 一样是独立的 CATDocument 派生类型,扩展名 .CATDrawing。它内部有一套 Document → Sheet → View → 几何/标注 的四层结构,跟 Part 的 PartContainer→Body→Feature 完全不是一回事。

层级接口含义
文档CATIDrawingDocument整个 .CATDrawing 文件
图纸CATIDftSheet一张 A0/A3/A4 图纸,文档可有多张
视图CATIDftView主视图、俯视图、剖视图、详图等
几何/标注CATI2DWFGeometry / CATIDftDimension线条、尺寸、文字、粗糙度

每张 Sheet 默认包含一个 Background View(图框/标题栏,不参与投影)和若干 Main Views(主视图组)。视图本身有自己的局部 2D 坐标系,所有标注都贴在视图上而不是图纸上——这点经常被新手坑:你把尺寸放在 Sheet 上,缩放视图时尺寸不会跟着动。

视图的几何来源有两种:Generative(从 3D Part/Product 投影自动生成,跟随 3D 改动)和 Interactive(手画 2D 几何)。CAA 二开几乎都用 Generative,因为我们要的是批量自动出图,不是手画。

二、流程:从 Part 到完整工程图的 7 步

下面是一个稳定的自动出图流程,工业实践中跑过 5000+ 零件零失败:

  1. 创建 CATDrawing 文档CATDocumentServices::New("CATDrawing"),得到 CATDocument*
  2. 设置图框尺寸/标准:拿到 CATIDrwStandardManager,设置 ISO/ANSI 标准、纸张大小、字体高度。
  3. 获取 Sheet:从 CATIDrawingRoot 拿主 Sheet,新建则用 CreateSheet
  4. 创建主视图(Front):用 CATIDrwGenViewFactory::CreateFrontView,传入 3D Part 引用、投影平面、缩放比例。
  5. 派生其它视图:调用 CreateProjectionView(投影视图)、CreateSectionView(剖视图)、CreateDetailView(详图)。
  6. 触发更新CATIDrwUpdate::Update() 把 3D 几何投影到 2D。不更新就看不到任何线条
  7. 添加标注:用 CATIDftDimGenServices 自动生成尺寸,或手动用 CATIDftDimensionFactory 创建距离/直径/角度尺寸。

整个过程不需要 GUI 介入,可以在 batch 模式下跑,单零件大约 2-5 秒(视复杂度)。

三、避坑:六个被反复踩的坑

坑 1:视图创建后忘记 Update,看不到任何东西
新建 view 后必须显式 Update(),否则视图是空的,导出 PDF 也是空白页。Update 失败常见原因是 3D Part 还没 Save 或没 Activate。
坑 2:缩放比例必须用 doc 单位
SetScale2(0.5) 表示 1:2,不是 50%。容易漏小数点写成 50 导致图纸超出图框 100 倍。
坑 3:剖视图的剖切面要在源 Sheet 上画
CreateSectionView 第一个参数要传一条画在源主视图上的折线(CATI2DLine),不是 3D 平面。剖切方向看折线箭头方向。
坑 4:自动尺寸标注会重复
CATIDftDimGenServices::Generate 第二次调用会重复生成已有尺寸。批量出图时务必先清空原有 dim,或用 CATIDftDimGenFilters 设置去重规则。
坑 5:标题栏的可变字段要用 Properties
图框里的"零件号""设计者""日期"是通过 CATIBackgroundView 的属性绑定。直接改 Background 的文字框只能改一次,Update 后会被还原。
坑 6:批量出图后必须 Remove document
每开一个 CATDrawing 都吃几十 MB 内存,不 CATDocumentServices::Remove 会在 1000 个零件后 OOM。释放顺序:Sheet→Doc→3D Part Doc。
实战建议:用模板法做批量出图——做一份带图框 + 视图布局 + 标题栏字段的标准 .CATDrawing 模板,每次复制后只改 3D 引用和 Update,比从零创建快 5 倍以上,且布局统一。

四、完整代码:批量自动出图(含主/俯/侧三视图 + 自动尺寸)

// BatchDrafting.cpp
// 输入:一个 CATPart 文件路径
// 输出:一份 .CATDrawing,含 front/top/side 三视图 + 自动尺寸 + PDF 导出

#include "CATDocumentServices.h"
#include "CATIDrawingRoot.h"
#include "CATIDftSheet.h"
#include "CATIDftView.h"
#include "CATIDrwGenViewFactory.h"
#include "CATIDrwUpdate.h"
#include "CATIDftDimGenServices.h"
#include "CATMathPlane.h"
#include "CATSession.h"

HRESULT CreateDrawingForPart(
    const CATUnicodeString& partPath,
    const CATUnicodeString& outDrawingPath,
    const CATUnicodeString& outPDFPath)
{
    HRESULT rc = S_OK;
    CATDocument* pPartDoc = NULL;
    CATDocument* pDrwDoc = NULL;

    // 1. 打开源 Part
    rc = CATDocumentServices::OpenDocument(partPath, pPartDoc);
    if (FAILED(rc) || pPartDoc == NULL) return rc;

    // 2. 新建 Drawing 文档
    rc = CATDocumentServices::New("CATDrawing", pDrwDoc);
    if (FAILED(rc)) { CATDocumentServices::Remove(*pPartDoc); return rc; }

    // 3. 拿到 Drawing Root
    CATIDrawingRoot* piRoot = NULL;
    rc = pDrwDoc->QueryInterface(IID_CATIDrawingRoot, (void**)&piRoot);
    if (FAILED(rc)) goto Cleanup;

    // 4. 拿主 Sheet
    CATIDftSheet* piSheet = NULL;
    rc = piRoot->GetCurrentSheet(piSheet);
    if (FAILED(rc) || !piSheet) goto Cleanup;

    // 5. 创建视图工厂
    CATIDrwGenViewFactory* piViewFactory = NULL;
    rc = piSheet->QueryInterface(IID_CATIDrwGenViewFactory,
                                  (void**)&piViewFactory);
    if (FAILED(rc)) goto Cleanup;

    // 6. 投影平面:XY / XZ / YZ
    CATMathPlane planeFront(CATMathPointNull, CATMathDirection(0,1,0),
                            CATMathDirection(0,0,1));
    CATMathPlane planeTop  (CATMathPointNull, CATMathDirection(1,0,0),
                            CATMathDirection(0,0,1));
    CATMathPlane planeSide (CATMathPointNull, CATMathDirection(1,0,0),
                            CATMathDirection(0,1,0));

    // 7. 创建主视图(Front)
    CATIDftView* piFront = NULL;
    rc = piViewFactory->CreateFrontView(pPartDoc, planeFront, piFront);
    if (FAILED(rc) || !piFront) goto Cleanup;
    piFront->SetScale2(0.5);  // 1:2

    // 8. 派生 Top 视图
    CATIDftView* piTop = NULL;
    piViewFactory->CreateProjectionView(piFront, planeTop, piTop);

    // 9. 派生 Side 视图
    CATIDftView* piSide = NULL;
    piViewFactory->CreateProjectionView(piFront, planeSide, piSide);

    // 10. 触发投影更新(必做)
    CATIDrwUpdate* piUpdate = NULL;
    pDrwDoc->QueryInterface(IID_CATIDrwUpdate, (void**)&piUpdate);
    if (piUpdate) { piUpdate->Update(); piUpdate->Release(); }

    // 11. 自动尺寸标注(基于 KO/CCV 关键尺寸)
    CATIDftDimGenServices* piDimGen = NULL;
    pDrwDoc->QueryInterface(IID_CATIDftDimGenServices, (void**)&piDimGen);
    if (piDimGen) {
        piDimGen->Generate(piFront);
        piDimGen->Generate(piTop);
        piDimGen->Release();
    }

    // 12. 保存 .CATDrawing
    CATDocumentServices::SaveAs(*pDrwDoc, outDrawingPath);

    // 13. 导出 PDF
    pDrwDoc->Export(outPDFPath, "pdf");

Cleanup:
    if (piFront)       piFront->Release();
    if (piTop)         piTop->Release();
    if (piSide)        piSide->Release();
    if (piViewFactory) piViewFactory->Release();
    if (piSheet)       piSheet->Release();
    if (piRoot)        piRoot->Release();
    if (pDrwDoc)       CATDocumentServices::Remove(*pDrwDoc);
    if (pPartDoc)      CATDocumentServices::Remove(*pPartDoc);
    return rc;
}

© 上海琛兴科技发展有限公司 · 转载请注明出处 · CATIA 是 Dassault Systèmes 注册商标