前言第一章 BIMHome基础1.1 专业(插件)开发环境搭建1.1.1 安装BIMHome1.1.2 下载API库1.1.3 CMake创建插件工程及其配置1.2 工作台创建1.3 命令创建1.4 IDocument含义及其创建1.5 IDocumentObject含义及其创建1.6 Hello World示例第二章 算法2.1 构造算法2.1.1 基础图形2.1.2 几何元素2.1.2.1 曲线2.1.2.2 组合体2.1.2.3 面2.1.2.4 壳2.1.2.5 实体2.1.2.6 基础拓扑元素助手2.1.3 几何特征算法2.1.4 专业构件2.2 修复2.3 几何关系算法2.3.1 极值2.3.2 投影2.4 操作编辑算法2.4.1 布尔运算2.4.2 离散运算2.4.2 倒直角操作2.4.3 倒圆角操作2.4.4 抽壳操作2.4.5 裁剪操作2.4.6 偏移操作2.4.7 变换2.5 工具2.6 地质专业2.6.1 地质第三章 二维出图3.1 IDrawPage3.1.1 IDrawPage介绍3.1.2 DXF模板加载(此模块有问题,待修改)3.1.2.1节点树查找与更新3.1.2.2 加载DXF文件3.2 IDrawView3.2.1 绘制基础图形3.2.1.1 非填充几何绘制3.2.1.2 填充几何3.2.2 标注(此模块有问题,待改进)3.2.2.1 尺寸标注3.2.2.2 引线标注3.2.2.3 图注3.2.3 文本绘制3.2.4 表格绘制3.2.4.1 表格的基本操作3.2.4.2 绘制表格3.2.5 投影3.2.5.1 投影3.2.5.1 剖面投影3.2.6 填充3.3 IDrawPage参数定义3.3.1 结构体类型3.4 IDrawView参数定义3.4.1 结构体类型3.4.2 枚举类类型第四章 视图4.1 IViewProvider4.2 主窗口视图4.2.1 IMainWindow4.3 多文档视图4.3.1 IMDIView 4.4 菜单视图4.4.1 IMenuItem4.5 对话框视图4.5.1 ITaskDialog4.6 标签视图4.6.1 IQRibbon4.7 树状视图4.7.1 ITreeWidgetObservationDelegate4.7.2 ITreeItem4.7.3 ITreeWidget4.7.4 ITreePanel4.8 IWorkBench第五章 事件交互5.1 选择事件5.1.1 ISelection5.1.2 ISelectionChanges5.1.3 ISelectionFilterGate5.1.4 ISelectionObserver5.2 控制事件5.2.1 IControl5.3 捕捉事件5.3.1 ISnapProcessedBase5.3.2 ISnapper5.3.3 SnapHandle5.4 命令事件5.4.1 ICommand第六章 常见问题
BIMHome三维图形平台是一款基于自主研发的H3D三维图形引擎开发的图形平台,旨在响应国家对核心技术自主可控的要求,推动工业软件国产化替代进程。平台攻克了底层引擎“卡脖子”难题,实现了从通用到专业的特征建模、网格建模能力,具备高效链接式装配、有限元分析、碰撞检测、几何约束求解等全方位分析计算能力。同时,平台支持多源异构三维数据融合,配备多元材质能力,具备二三维出图、数据协同以及多格式兼容的交互能力,还提供开放融合的二次开发支持。
BIMHome平台的核心技术完全自主可控,适配信创环境。通过自主研发,平台保障了设计单位在产业和技术迭代升级中的自主性,为我国工业工程设计领域的信息安全提供了坚实保障。

从网站上下载BIMHome,点击 下载BIMHome 跳转到下载地址。
从网站上下载API库,点击 下载API库 跳转到下载地址。
CMake是一个强大的跨平台编译和安装工具,它被设计用来简化和标准化构建过程。CMake通过编写平台无关的配置文件CMakeLists.txt,来生成特定平台的Makefile或项目文件,从而实现“一次编写,到处编译”的目标。所以我们推荐使用CMake来构建工程,当然,你也可以使用你喜欢的任何方式去构建工程!
在开始构建之前,确保已经安装了CMake软件和QT软件。
本次以BIMHomeTestDemo作为演示,来构建一个.dll动态链接库。
项目概述:
BIMHomeTestDemo 是一个基于 Qt 和 BIMHomeSDK 的动态链接库(DLL)项目,主要用于 BIM相关的功能扩展和测试。该项目包含多个功能模块,如型钢建模、基础图形创建、管道设计等,并提供界面的支持。
CMake基础配置部分
声明CMake版本和项目声明:这里指定CMake最低版本为3.15.4和项目名称为BIMHomeTestDemo,并允许使用C和C++语言。
x#CMakeLists.txt
#这里规定了camke的版本至少为3.15.4cmake_minimum_required(VERSION 3.15.4 FATAL_ERROR)
#这里用于设置项目的名称和所使用的代码语言project(BIMHomeTestDemo LANGUAGES C CXX)设置库路径
xxxxxxxxxx#CMakeLists.txt
#set命令用来创建变量,在这里用于将目录路径保存到前面的定义的变量中去set(LIBRARY_DIR CACHE STRING "")set(QT_INCLUDE_PATH "${LIBRARY_DIR}/Third/Qt/include")set(QT_LIB_PATH "${LIBRARY_DIR}/Third/Qt/lib")set(QT_BIN_PATH "${LIBRARY_DIR}/Third/Qt/bin")set(BIMHomeSDK_INCLUDE_PATH "${LIBRARY_DIR}/BimHomeSDK/Inc")set(BIMHomeSDK_LIB_PATH "${LIBRARY_DIR}/BimHomeSDK/lib")set(BIMHomeSDK_BIN_PATH "${LIBRARY_DIR}/BimHomeSDK/bin")set(CMAKE_PREFIX_PATH "${LIBRARY_DIR}/Third/Qt")BIMHomeSDK和QT库如下图所示


启用QT 的AUTOMOC
xxxxxxxxxx#CMakeLists.txt
#启用之后可以让cmake自动扫描头文件里的'Q_OBJECT'宏并调用'moc'set(CMAKE_AUTOMOC ON)
#该命令用于查询并加载QT5#REQUIRED表示当查找不到就立刻终止报错# COMPONENTS Core Widgets UiTools表示用到的模块,并将对应的目标一起导入文件夹find_package(Qt5 REQUIRED COMPONENTS Core Widgets UiTools)添加子目录:这里为了将源码子目录添加进来。
xxxxxxxxxx#CMakeLists.txt
#这里添加子目录,该子目录包含我们的源码文件add_subdirectory(BIMHomeTestDemo)
基础配置部分完整CMakeLists.txt文件
xxxxxxxxxx#CMakeLists.txtcmake_minimum_required(VERSION 3.15.4 FATAL_ERROR)
project(BIMHomeTestDemo LANGUAGES C CXX)
set(LIBRARY_DIR CACHE STRING "")set(QT_INCLUDE_PATH "${LIBRARY_DIR}/Third/Qt/include")set(QT_LIB_PATH "${LIBRARY_DIR}/Third/Qt/lib")set(QT_BIN_PATH "${LIBRARY_DIR}/Third/Qt/bin")set(BIMHomeSDK_INCLUDE_PATH "${LIBRARY_DIR}/BimHomeSDK/Inc")set(BIMHomeSDK_LIB_PATH "${LIBRARY_DIR}/BimHomeSDK/lib")set(BIMHomeSDK_BIN_PATH "${LIBRARY_DIR}/BimHomeSDK/bin")set(CMAKE_PREFIX_PATH "${LIBRARY_DIR}/Third/Qt")
set(CMAKE_AUTOMOC ON)find_package(Qt5 REQUIRED COMPONENTS Core Widgets UiTools)
add_subdirectory(BIMHomeTestDemo)
子目录部分:源代码和资源管理部分
定义头文件搜索路径
xxxxxxxxxx#CMakeLists.txt
#这里将括号里列出的所有目录,追加到全局的头文件搜索路径里去,让编译器在任何地方都能找到这些目录下.h文件include_directories(    ${CMAKE_CURRENT_BINARY_DIR}    ${QT_INCLUDE_PATH}    ${QT_INCLUDE_PATH}/QtCore    ${QT_INCLUDE_PATH}/QtWidgets    ${QT_INCLUDE_PATH}/QtGui    ${QT_INCLUDE_PATH}/ActiveQt    ${BIMHomeSDK_INCLUDE_PATH}    ${CMAKE_CURRENT_SOURCE_DIR}/Hanger)定义库搜索路径
xxxxxxxxxx#CMakeLists.txt
#这里将括号里列出的QT库和BIMHomeSDK库加入到全局库搜索路径link_directories(    ${QT_LIB_PATH}    ${BIMHomeSDK_LIB_PATH})定义依赖库:这里debug xxx.lib指仅在Debug配置下生效;optimized xxx.lib仅在Release配置下生效。
xxxxxxxxxx#CMakeLists.txt
set(BIMHomeTestDemo_LIBS    #Debug    debug Qt5OpenGLd.lib    debug Qt5PrintSupportd.lib    debug Qt5Svgd.lib    debug Qt5Networkd.lib    debug Qt5UiToolsd.lib    debug Qt5Concurrentd.lib    debug Qt5WinExtrasd.lib    debug Qt5Xmld.lib    debug Qt5Widgetsd.lib    debug Qt5Guid.lib    debug Qt5Cored.lib    debug Qt5AxBased.lib    debug Qt5AxContainerd.lib        debug BIMHomeApp_d.lib    debug BIMHomeGui_d.lib    debug BIMHomeBase_d.lib    debug PartInterface_d.lib    debug PipingDesignInterface_d.lib        #release    optimized Qt5OpenGL.lib    optimized Qt5PrintSupport.lib    optimized Qt5Svg.lib    optimized Qt5Network.lib    optimized Qt5UiTools.lib    optimized Qt5Concurrent.lib    optimized Qt5WinExtras.lib    optimized Qt5Xml.lib    optimized Qt5Widgets.lib    optimized Qt5Gui.lib    optimized Qt5Core.lib    optimized Qt5AxBase.lib    optimized Qt5AxContainer.lib        optimized BIMHomeApp.lib    optimized BIMHomeGui.lib    optimized BIMHomeBase.lib    optimized PartInterface.lib    optimized Surface.lib    optimized PipingDesignInterface.lib)
定义QT资源处理和UI文件处理
xxxxxxxxxx#CMakeLists.txtset(BIMHomeTestDemo_UI    CreateLoftDlg.ui    Hanger/TaskWidgets/CreateHangerDlg.ui    Hanger/TaskWidgets/LogicHangerDialog.ui    Hanger/TaskWidgets/CreateLineTextDlg.ui    MeasureLengthDlg.ui    LoftByCirclesDlg.ui    SelectObjectDlg.ui    SelectObjectsDlg.ui    SewingEdgesDlg.ui    CreateMDIViewDialog.ui    CreateSpaceCurveDialog.ui    CreateExtrusionDialog.ui    ExpressCurveDialog.ui)#这里使用qt5_wrap_ui命令将每个.ui文件编译成对应的C++头文件如 ui_xxx.h#并把这些头文件存到变量BIMHomeTestDemo_UIC_HDRS中去qt5_wrap_ui(BIMHomeTestDemo_UIC_HDRS ${BIMHomeTestDemo_UI})
#该命令是分组命令,让FILES后面的文件会被加入到GeneratedFiles这个虚拟文件夹中SOURCE_GROUP("GeneratedFiles" FILES ${BIMHomeTestDemo_UIC_HDRS})定义将源码进行逻辑分组,并将相应的源码加入到目录中。
xxxxxxxxxx#CMakeLists.txtset(BIMHomeTestDemo_Hanger_Command_FILES    Hanger/CommandBuriedIron.h    Hanger/CommandLoadPoint.h    Hanger/CommandLogicBuriedIron.h    Hanger/CommandLogicHanger.h    Hanger/CommandLogicLoadPoint.h    Hanger/CreateAssistedLineText.h    Hanger/CreateHanger.h    Hanger/CreateHanger.cpp)SOURCE_GROUP("Hanger" FILES ${BIMHomeTestDemo_Hanger_Command_FILES})
set(BIMHomeTestDemo_Hanger_TaskWidgets_FILES    Hanger/TaskWidgets/CreateBuriedIronLoadPoint.h    Hanger/TaskWidgets/CreateBuriedIronLoadPoint.cpp    Hanger/TaskWidgets/CreateHangerDlg.h    Hanger/TaskWidgets/CreateHangerDlg.cpp    Hanger/TaskWidgets/CreateHangerDlg.ui    Hanger/TaskWidgets/CreateLineTextDlg.h    Hanger/TaskWidgets/CreateLineTextDlg.cpp    Hanger/TaskWidgets/CreateLineTextDlg.ui    Hanger/TaskWidgets/LogicHangerDialog.h    Hanger/TaskWidgets/LogicHangerDialog.cpp    Hanger/TaskWidgets/LogicHangerDialog.ui)SOURCE_GROUP("Hanger" FILES ${BIMHomeTestDemo_Hanger_TaskWidgets_FILES})
set(BIMHomeTestDemo_ProfileSteel_FILES    ProfileSteel/CreateBeamChannel.h    ProfileSteel/CreateDoubleAngleSteel.h    ProfileSteel/CreateDoubleChannelSteel.h    ProfileSteel/CreateEquilateralAngleSteel.h    ProfileSteel/CreateHBeam.h    ProfileSteel/CreateIBeam.h    ProfileSteel/CreatePolygonRoundSteelTube.h    ProfileSteel/CreateRectangularSquareSteelTube.h    ProfileSteel/CreateRoundSteelTube.h    ProfileSteel/CreateSquareSteelTube.h    ProfileSteel/CreateTBeam.h    ProfileSteel/CreateBeamChannel.cpp    ProfileSteel/CreateDoubleAngleSteel.cpp    ProfileSteel/CreateDoubleChannelSteel.cpp    ProfileSteel/CreateEquilateralAngleSteel.cpp    ProfileSteel/CreateHBeam.cpp    ProfileSteel/CreateIBeam.cpp    ProfileSteel/CreatePolygonRoundSteelTube.cpp    ProfileSteel/CreateRectangularSquareSteelTube.cpp    ProfileSteel/CreateRoundSteelTube.cpp    ProfileSteel/CreateSquareSteelTube.cpp    ProfileSteel/CreateTBeam.cpp)SOURCE_GROUP("ProfileSteel" FILES ${BIMHomeTestDemo_ProfileSteel_FILES})
set(BIMHomeTestDemo_BaseFigure_FILES    BaseFigure/CreateBendingCylindrical.h    BaseFigure/CreateCable.h    BaseFigure/CreateCircularfixedplate.h    BaseFigure/CreateCircularGasket.h    BaseFigure/CreateConePorcelainBushing.h    BaseFigure/CreateCuboid.h    BaseFigure/CreateCylinder.h    BaseFigure/CreateEccentricTruncatedCone.h    BaseFigure/CreateEllipticRing.h    BaseFigure/CreateInsulator.h    BaseFigure/CreateOffsetRectangularTable.h    BaseFigure/CreatePorcelainBushing.h    BaseFigure/CreateRectangularfixedplate.h    BaseFigure/CreateRectangularRing.h    BaseFigure/CreateRing.h    BaseFigure/CreateRotationalEllipsoid.h    BaseFigure/CreateSphere.h    BaseFigure/CreateSquareGasket.h    BaseFigure/CreateStretchedBody.h    BaseFigure/CreateTable.h    BaseFigure/CreateTableGasket.h    BaseFigure/CreateTerminalBlock.h    BaseFigure/CreateVTypeInsulator.h    BaseFigure/CreateWire.h    BaseFigure/CreateBendingCylindrical.cpp    BaseFigure/CreateCable.cpp    BaseFigure/CreateCircularfixedplate.cpp    BaseFigure/CreateCircularGasket.cpp    BaseFigure/CreateConePorcelainBushing.cpp    BaseFigure/CreateCuboid.cpp    BaseFigure/CreateCylinder.cpp    BaseFigure/CreateEccentricTruncatedCone.cpp    BaseFigure/CreateEllipticRing.cpp    BaseFigure/CreateInsulator.cpp    BaseFigure/CreateOffsetRectangularTable.cpp    BaseFigure/CreatePorcelainBushing.cpp    BaseFigure/CreateRectangularfixedplate.cpp    BaseFigure/CreateRectangularRing.cpp    BaseFigure/CreateRing.cpp    BaseFigure/CreateRotationalEllipsoid.cpp    BaseFigure/CreateSphere.cpp    BaseFigure/CreateSquareGasket.cpp    BaseFigure/CreateStretchedBody.cpp    BaseFigure/CreateTable.cpp    BaseFigure/CreateTableGasket.cpp    BaseFigure/CreateTerminalBlock.cpp    BaseFigure/CreateVTypeInsulator.cpp    BaseFigure/CreateWire.cpp)SOURCE_GROUP("BaseFigure" FILES ${BIMHomeTestDemo_BaseFigure_FILES})
SET(BIMHomeTestDemo_SRCS    ${BIMHomeTestDemo_UIC_HDRS}    ${BIMHomeTestDemo_Hanger_Command_FILES}    ${BIMHomeTestDemo_Hanger_TaskWidgets_FILES}    ${BIMHomeTestDemo_ProfileSteel_FILES}    ${BIMHomeTestDemo_BaseFigure_FILES}        MeasureLengthCmd.h    MeasureLengthCmd.cpp        CreateLoftCmd.h    CreateLoftCmd.cpp        MeasureLengthDlg.h    MeasureLengthDlg.cpp    MeasureLengthDlg.ui        CreateLoftDlg.h    CreateLoftDlg.cpp    CreateLoftDlg.ui
    SelectObjectDlg.h    SelectObjectDlg.cpp    SelectObjectDlg.ui        SelectObjectsDlg.h    SelectObjectsDlg.cpp    SelectObjectsDlg.ui        SewingEdgesDlg.h    SewingEdgesDlg.cpp    SewingEdgesDlg.ui        LoftByCirclesDlg.h    LoftByCirclesDlg.cpp    LoftByCirclesDlg.ui        CreateExpressCurveCmd.h    CreateExpressCurveCmd.cpp        CreatePadCmd.h    CreatePadCmd.cpp        CreateExtrusionCmd.h    CreateExtrusionCmd.cpp          CreateCurvebyDataCmd.h    CreateCurvebyDataCmd.cpp        CreateSewCmd.h    CreateSewCmd.cpp        CreateSweepCmd.h    CreateSweepCmd.cpp            CreateLoftByCirclesCmd.h    CreateLoftByCirclesCmd.cpp         CreateSpaceCurveCmd.h     CreateSpaceCurveCmd.cpp         CreatePipebyDataCmd.h    CreatePipebyDataCmd.cpp        CreateCirclebyDataCmd.h    CreateCirclebyDataCmd.cpp        CreateViewCmd.h    CreateViewCmd.cpp        CreateMDIViewDialog.h    CreateMDIViewDialog.cpp        CreateSpaceCurveDialog.h    CreateSpaceCurveDialog.cpp     CreateSpaceCurveDialog.ui        CreateExtrusionDialog.h    CreateExtrusionDialog.cpp    CreateExtrusionDialog.ui        ExpressCurveDialog.h    ExpressCurveDialog.cpp    ExpressCurveDialog.ui
    framework.h    SelectElementGate.h    SelectElementGate.cpp        ShowSelectObjCmd.h    ShowSelectObjCmd.cpp        TestCSharpCmd.h    TestCSharpCmd.cpp        WorkbenchTest.h    WorkbenchTest.cpp)分组后的效果

创建共享库目标
xxxxxxxxxx#CMakeLists.txt
#这里创建一个BIMHomeTestDemo的共享库,把${}里面列出的文件编进这个库去add_library(BIMHomeTestDemo SHARED ${BIMHomeTestDemo_SRCS})
#这里指明在链接BIMHomeTestDemo库时,需要把${}里面列出的所有库一起链接进去target_link_libraries(BIMHomeTestDemo ${BIMHomeTestDemo_LIBS})定义输出配置
xxxxxxxxxx#CMakeLists.txtset_target_properties(BIMHomeTestDemo PROPERTIES    #设置debug输出路径    RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/bin/Debug"         #设置release输出路径    RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/bin/Release"        #设置debug输出名    RELEASE_OUTPUT_NAME "BIMHomeTestDemo"         #设置release输出名    DEBUG_OUTPUT_NAME "BIMHomeTestDemod")完整的CMakeLists.txt文件
xxxxxxxxxx#子目录CMakeLists.txtinclude_directories(    ${CMAKE_CURRENT_BINARY_DIR}    ${QT_INCLUDE_PATH}    ${QT_INCLUDE_PATH}/QtCore    ${QT_INCLUDE_PATH}/QtWidgets    ${QT_INCLUDE_PATH}/QtGui    ${QT_INCLUDE_PATH}/ActiveQt    ${BIMHomeSDK_INCLUDE_PATH}    ${BIMHomeSDK_INCLUDE_PATH}/Part    ${BIMHomeSDK_INCLUDE_PATH}/App    ${BIMHomeSDK_INCLUDE_PATH}/Gui    ${Boost_INCLUDE_DIR}    ${Boost_INCLUDE_DIR}/boost    ${CMAKE_CURRENT_SOURCE_DIR}    ${CMAKE_CURRENT_SOURCE_DIR}/App    ${CMAKE_CURRENT_SOURCE_DIR}/MainWindow    ${CMAKE_CURRENT_SOURCE_DIR}/Common    ${CMAKE_CURRENT_SOURCE_DIR}/Common/Ui    ${CMAKE_CURRENT_SOURCE_DIR}/CustDelegate    ${CMAKE_CURRENT_SOURCE_DIR}/Module    ${CMAKE_CURRENT_SOURCE_DIR}/Module/Topographies    ${CMAKE_CURRENT_SOURCE_DIR}/Module/GISDataImage    ${THIRD_LIB_PATH}/    ${THIRD_LIB_PATH}/GDAL/include    ${THIRD_LIB_PATH}/zlib)
link_directories(    ${QT_LIB_PATH}    ${BIMHomeSDK_LIB_PATH})
set(BIMHomeTestDemo_LIBS    #Debug    debug Qt5OpenGLd.lib    debug Qt5PrintSupportd.lib    debug Qt5Svgd.lib    debug Qt5Networkd.lib    debug Qt5UiToolsd.lib    debug Qt5Concurrentd.lib    debug Qt5WinExtrasd.lib    debug Qt5Xmld.lib    debug Qt5Widgetsd.lib    debug Qt5Guid.lib    debug Qt5Cored.lib    debug Qt5AxBased.lib    debug Qt5AxContainerd.lib        debug BIMHomeApp_d.lib    debug BIMHomeGui_d.lib    debug BIMHomeBase_d.lib    debug PartInterface_d.lib    debug PipingDesignInterface_d.lib        #release    optimized Qt5OpenGL.lib    optimized Qt5PrintSupport.lib    optimized Qt5Svg.lib    optimized Qt5Network.lib    optimized Qt5UiTools.lib    optimized Qt5Concurrent.lib    optimized Qt5WinExtras.lib    optimized Qt5Xml.lib    optimized Qt5Widgets.lib    optimized Qt5Gui.lib    optimized Qt5Core.lib    optimized Qt5AxBase.lib    optimized Qt5AxContainer.lib        optimized BIMHomeApp.lib    optimized BIMHomeGui.lib    optimized BIMHomeBase.lib    optimized PartInterface.lib    optimized Surface.lib    optimized PipingDesignInterface.lib)
qt5_add_resources(BIMHomeTestDemo_SRCS Resources/Resource.qrc)
set(BIMHomeTestDemo_UI    CreateLoftDlg.ui    Hanger/TaskWidgets/CreateHangerDlg.ui    Hanger/TaskWidgets/LogicHangerDialog.ui    Hanger/TaskWidgets/CreateLineTextDlg.ui    MeasureLengthDlg.ui    LoftByCirclesDlg.ui    SelectObjectDlg.ui    SelectObjectsDlg.ui    SewingEdgesDlg.ui    CreateMDIViewDialog.ui    CreateSpaceCurveDialog.ui    CreateExtrusionDialog.ui    ExpressCurveDialog.ui)qt5_wrap_ui(BIMHomeTestDemo_UIC_HDRS ${BIMHomeTestDemo_UI})SOURCE_GROUP("GeneratedFiles" FILES ${BIMHomeTestDemo_UIC_HDRS})
set(BIMHomeTestDemo_Hanger_Command_FILES    Hanger/CommandBuriedIron.h    Hanger/CommandLoadPoint.h    Hanger/CommandLogicBuriedIron.h    Hanger/CommandLogicHanger.h    Hanger/CommandLogicLoadPoint.h    Hanger/CreateAssistedLineText.h    Hanger/CreateHanger.h    Hanger/CreateHanger.cpp)SOURCE_GROUP("Hanger" FILES ${BIMHomeTestDemo_Hanger_Command_FILES})
set(BIMHomeTestDemo_Hanger_TaskWidgets_FILES    Hanger/TaskWidgets/CreateBuriedIronLoadPoint.h    Hanger/TaskWidgets/CreateBuriedIronLoadPoint.cpp    Hanger/TaskWidgets/CreateHangerDlg.h    Hanger/TaskWidgets/CreateHangerDlg.cpp    Hanger/TaskWidgets/CreateHangerDlg.ui    Hanger/TaskWidgets/CreateLineTextDlg.h    Hanger/TaskWidgets/CreateLineTextDlg.cpp    Hanger/TaskWidgets/CreateLineTextDlg.ui    Hanger/TaskWidgets/LogicHangerDialog.h    Hanger/TaskWidgets/LogicHangerDialog.cpp    Hanger/TaskWidgets/LogicHangerDialog.ui)SOURCE_GROUP("Hanger" FILES ${BIMHomeTestDemo_Hanger_TaskWidgets_FILES})
set(BIMHomeTestDemo_ProfileSteel_FILES    ProfileSteel/CreateBeamChannel.h    ProfileSteel/CreateDoubleAngleSteel.h    ProfileSteel/CreateDoubleChannelSteel.h    ProfileSteel/CreateEquilateralAngleSteel.h    ProfileSteel/CreateHBeam.h    ProfileSteel/CreateIBeam.h    ProfileSteel/CreatePolygonRoundSteelTube.h    ProfileSteel/CreateRectangularSquareSteelTube.h    ProfileSteel/CreateRoundSteelTube.h    ProfileSteel/CreateSquareSteelTube.h    ProfileSteel/CreateTBeam.h    ProfileSteel/CreateBeamChannel.cpp    ProfileSteel/CreateDoubleAngleSteel.cpp    ProfileSteel/CreateDoubleChannelSteel.cpp    ProfileSteel/CreateEquilateralAngleSteel.cpp    ProfileSteel/CreateHBeam.cpp    ProfileSteel/CreateIBeam.cpp    ProfileSteel/CreatePolygonRoundSteelTube.cpp    ProfileSteel/CreateRectangularSquareSteelTube.cpp    ProfileSteel/CreateRoundSteelTube.cpp    ProfileSteel/CreateSquareSteelTube.cpp    ProfileSteel/CreateTBeam.cpp)SOURCE_GROUP("ProfileSteel" FILES ${BIMHomeTestDemo_ProfileSteel_FILES})
set(BIMHomeTestDemo_BaseFigure_FILES    BaseFigure/CreateBendingCylindrical.h    BaseFigure/CreateCable.h    BaseFigure/CreateCircularfixedplate.h    BaseFigure/CreateCircularGasket.h    BaseFigure/CreateConePorcelainBushing.h    BaseFigure/CreateCuboid.h    BaseFigure/CreateCylinder.h    BaseFigure/CreateEccentricTruncatedCone.h    BaseFigure/CreateEllipticRing.h    BaseFigure/CreateInsulator.h    BaseFigure/CreateOffsetRectangularTable.h    BaseFigure/CreatePorcelainBushing.h    BaseFigure/CreateRectangularfixedplate.h    BaseFigure/CreateRectangularRing.h    BaseFigure/CreateRing.h    BaseFigure/CreateRotationalEllipsoid.h    BaseFigure/CreateSphere.h    BaseFigure/CreateSquareGasket.h    BaseFigure/CreateStretchedBody.h    BaseFigure/CreateTable.h    BaseFigure/CreateTableGasket.h    BaseFigure/CreateTerminalBlock.h    BaseFigure/CreateVTypeInsulator.h    BaseFigure/CreateWire.h    BaseFigure/CreateBendingCylindrical.cpp    BaseFigure/CreateCable.cpp    BaseFigure/CreateCircularfixedplate.cpp    BaseFigure/CreateCircularGasket.cpp    BaseFigure/CreateConePorcelainBushing.cpp    BaseFigure/CreateCuboid.cpp    BaseFigure/CreateCylinder.cpp    BaseFigure/CreateEccentricTruncatedCone.cpp    BaseFigure/CreateEllipticRing.cpp    BaseFigure/CreateInsulator.cpp    BaseFigure/CreateOffsetRectangularTable.cpp    BaseFigure/CreatePorcelainBushing.cpp    BaseFigure/CreateRectangularfixedplate.cpp    BaseFigure/CreateRectangularRing.cpp    BaseFigure/CreateRing.cpp    BaseFigure/CreateRotationalEllipsoid.cpp    BaseFigure/CreateSphere.cpp    BaseFigure/CreateSquareGasket.cpp    BaseFigure/CreateStretchedBody.cpp    BaseFigure/CreateTable.cpp    BaseFigure/CreateTableGasket.cpp    BaseFigure/CreateTerminalBlock.cpp    BaseFigure/CreateVTypeInsulator.cpp    BaseFigure/CreateWire.cpp)SOURCE_GROUP("BaseFigure" FILES ${BIMHomeTestDemo_BaseFigure_FILES})
SET(BIMHomeTestDemo_SRCS    ${BIMHomeTestDemo_UIC_HDRS}    ${BIMHomeTestDemo_Hanger_Command_FILES}    ${BIMHomeTestDemo_Hanger_TaskWidgets_FILES}    ${BIMHomeTestDemo_ProfileSteel_FILES}    ${BIMHomeTestDemo_BaseFigure_FILES}        MeasureLengthCmd.h    MeasureLengthCmd.cpp        CreateLoftCmd.h    CreateLoftCmd.cpp        MeasureLengthDlg.h    MeasureLengthDlg.cpp    MeasureLengthDlg.ui        CreateLoftDlg.h    CreateLoftDlg.cpp    CreateLoftDlg.ui
    SelectObjectDlg.h    SelectObjectDlg.cpp    SelectObjectDlg.ui        SelectObjectsDlg.h    SelectObjectsDlg.cpp    SelectObjectsDlg.ui        SewingEdgesDlg.h    SewingEdgesDlg.cpp    SewingEdgesDlg.ui        LoftByCirclesDlg.h    LoftByCirclesDlg.cpp    LoftByCirclesDlg.ui        CreateExpressCurveCmd.h    CreateExpressCurveCmd.cpp        CreatePadCmd.h    CreatePadCmd.cpp        CreateExtrusionCmd.h    CreateExtrusionCmd.cpp          CreateCurvebyDataCmd.h    CreateCurvebyDataCmd.cpp        CreateSewCmd.h    CreateSewCmd.cpp        CreateSweepCmd.h    CreateSweepCmd.cpp            CreateLoftByCirclesCmd.h    CreateLoftByCirclesCmd.cpp         CreateSpaceCurveCmd.h     CreateSpaceCurveCmd.cpp         CreatePipebyDataCmd.h    CreatePipebyDataCmd.cpp        CreateCirclebyDataCmd.h    CreateCirclebyDataCmd.cpp        CreateViewCmd.h    CreateViewCmd.cpp        CreateMDIViewDialog.h    CreateMDIViewDialog.cpp        CreateSpaceCurveDialog.h    CreateSpaceCurveDialog.cpp     CreateSpaceCurveDialog.ui        CreateExtrusionDialog.h    CreateExtrusionDialog.cpp    CreateExtrusionDialog.ui        ExpressCurveDialog.h    ExpressCurveDialog.cpp    ExpressCurveDialog.ui
    framework.h    SelectElementGate.h    SelectElementGate.cpp        ShowSelectObjCmd.h    ShowSelectObjCmd.cpp        TestCSharpCmd.h    TestCSharpCmd.cpp        WorkbenchTest.h    WorkbenchTest.cpp)    add_library(BIMHomeTestDemo SHARED ${BIMHomeTestDemo_SRCS})target_link_libraries(BIMHomeTestDemo ${BIMHomeTestDemo_LIBS})
set_target_properties(BIMHomeTestDemo PROPERTIES    RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/bin/Debug"      RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/bin/Release"     RELEASE_OUTPUT_NAME "BIMHomeTestDemo"     DEBUG_OUTPUT_NAME "BIMHomeTestDemod")定义好CMakeLists.txt文件后,这里使用可视化cmake-gui构建项目
打开cmake-gui:

设置源码路径

设置输出路径并点击Configure

选择x64并点击Finish:

这里在LIBRARY_DIR处添加库路径P:\code\BIMHomeTestDemo\lib(该路径应是你的库路径的位置)


点击Generate,生成成功

打卡Visual studio,打开这个项目,点击生成解决方案,生成成功


最终构建.dll动态链接库如下所示:
debug模式下:

Release模式下:(选择release,重复步骤7)

首先,我们创建一个工作台类MyWorkBench,该类继承自Gui::IWorkbench,由于Gui ::IWorkbench是抽象类,我们需在我们子类MyWorkBench中重写该类的所有纯虚函数。
MyWorkBench.h的示例代码如下所示:
xxxxxxxxxx//MyWorkBench.h
class MyWorkBench : public Gui::IWorkbench{public:    MyWorkBench();    ~MyWorkBench();
    /**    * @brief                获取工作台名称    * @details              获取工作台名称    * @return               返回一个字符串,值为工作台名称    */    virtual std::string getName();
    /**    * @brief                获取按钮icon    * @details              获取按钮icon    * @return               返回一个字符串,值为 按钮icon    */    virtual std::string getIcon();
    /**    * @brief                获取按钮text    * @details              获取按钮text    * @return               返回一个字符串,值为按钮text    */    virtual std::string getMenuText();
    /**    * @brief                获取按钮ToolTip    * @details              获取按钮ToolTip    * @return               返回一个字符串,值为按钮ToolTip    */    virtual std::string getToolTip();
    /**    * @brief                设置工作台工具栏    * @details              设置工作台工具栏    */    virtual void setupMenuBar(Gui::IMenuItem* pItem) const;
    //右键菜单    virtual void setupContextMenu(const char* recipient, Gui::IMenuItem* pItem) const;
    /**     * @brief 切换为当前活动工作台事件     * @details 工作台激活事件。     */    virtual void activated();
    /**     * @brief 退出当前活动工作台事件     * @details 退出当前活动工作台事件。     */    virtual void deactivated();
};MyWorkBench.cpp示例代码如下所示:
xxxxxxxxxx//MyWorkBench.cpp
using namespace Gui;
//使用REGISTER_WORKBENCH_CMD注册工作台REGISTER_WORKBENCH_CMD(MyWorkBench);
MyWorkBench::MyWorkBench() {}
MyWorkBench::~MyWorkBench() {}
std::string MyWorkBench::getName(){    return "MyWorkBench";}
std::string MyWorkBench::getIcon(){    return "test.svg";}
std::string MyWorkBench::getMenuText(){    return "MyWorkBench";}
std::string MyWorkBench::getToolTip(){    return "MyWorkBench";}
void MyWorkBench::activated(){}
void MyWorkBench::deactivated(){}
void MyWorkBench::setupMenuBar(Gui::IMenuItem* pItem) const{    //获取编辑节点    Gui::IMenuItem* Edit = pItem->findItem("&Edit");    Gui::IMenuItem * MyCommandItem = Gui::IMenuItem::create();    MyCommandItem->setCommand("Create");    //"MyCommand"该值应与创建命令里面的getCommandID保持一致    *MyCommandItem << "MyCommand";
    pItem->insertItem(Edit, MyCommandItem);}
void MyWorkBench::setupContextMenu(const char* recipient, Gui::IMenuItem* item) const{}效果展示

首先,我们创建一个命令类MyCommand,该类继承自Gui::ICommand,由于Gui ::ICommand是抽象类,我们需在我们子类MyCommand中重写该类的所有纯虚函数。
MyCommand.h的示例代码如下所示:
xxxxxxxxxx//MyCommand.h
class MyCommand : public Gui::ICommand{public:    MyCommand();    ~MyCommand();
       /**       * @brief             获取命令所在模块       * @details           获取命令所在模块       * @return            返回命令所在的模块名称       */    virtual const char* getAppModule();
    /**    * @brief                获取命令所在分组    * @details              获取命令所在分组    * @return               返回命令所在分组名称    */    virtual const char* getGroup();
    /**    * @brief                获取命令名称信息    * @details              获取命令名称信息    * @return               返回命令名称信息    */    virtual const char* getMenuText();
    /**    * @brief                获取命令提示信息    * @details              获取命令提示信息    * @return               返回命令提示信息    */    virtual const char* getToolTipText();
    /**    * @brief                获取命令状态栏提示信息    * @details              获取命令状态栏提示信息    * @return               返回命令状态栏提示信息    */    virtual const char* getStatusTip();
    /**    * @brief                获取命令图片    * @details              获取命令图片    * @return               返回图像资源(例如图标)的名称    */    virtual const char* getPixmap() ;
    /**    * @brief                获取命令ID    * @details              获取命令ID    * @return               返回一个命令的唯一标识符    */    virtual const char* getCommandID();
    /**    * @brief                获取命令类名    * @details              获取命令类名    * @return               返回一个类的名称    */    virtual const char* className() const;
    /**     * @brief 触发命令并在必要时显示警告消息框     * @param[in] iMsg 状态信息码,用于区分不同触发场景     */    virtual void activated(int iMsg);
    /**     * @brief 判断命令菜单项是否应处于高亮(可用)状态     * @return true 表示当前环境满足命令执行条件,菜单高亮;false 表示不满足,菜单置灰     */    virtual bool isActive(void);
};MyCommand.cpp的示例代码如下所示:
xxxxxxxxxx//MyCommand.cpp
using namespace Gui;
//使用REGISTER_COMMAND_CMD注册命令REGISTER_COMMAND_CMD(MyCommand);
MyCommand::MyCommand() {}
MyCommand::~MyCommand() {}
const char* MyCommand::getAppModule() {    return "My Command";}
const char* MyCommand::getGroup() {    return "Surface";}
const char* MyCommand::getMenuText() {    return "My Command";}
const char* MyCommand::getToolTipText() {    return "My Command";}
const char* MyCommand::getStatusTip() {    return "My Command";}
const char* MyCommand::getPixmap() {    return "MyCommand";}
const char* MyCommand::getCommandID() {    return "MyCommand";}
const char* MyCommand::className() const {    return "MyCommand";}
/////////////////////////////////命令的触发/////////////////////////////
void MyCommand::activated(int iMsg) {    QMessageBox::warning(nullptr, QString::fromLocal8Bit("测试"), QString::fromLocal8Bit("对外扩展自定义命令"));}
bool MyCommand::isActive(void) {    return true;}getCommandID
效果展示:

定义:
IDocument 是BIMHome 数据结构的顶层容器,代表一个 BIMHome 项目或文件(通常以 .BIMPart 格式保存)。它是一个逻辑上的工作空间,包含了所有的建模对象、参数、视图信息等。
功能:
管理文档中的对象、属性和依赖关系。
提供对象的创建、访问、修改和删除接口。
支持多文档管理,允许同时打开多个文档。
保存和恢复文档状态,支持事务处理
组成:
包含多个 IDocumentObject,这些对象是文档中的实际建模元素
包含视图信息,用于管理文档在图形界面中的显示
该类提供了create、getFileName、getParentDocument、getTemplateDirName、getAvailableRedos、getObject、locateObjs、setObserverDelegate等接口函数。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
以创建一个IDocumen为例:
xxxxxxxxxx//示例代码//创建IDocument具体接口函数/*** @brief                            创建一个新文档* @details                          创建一个新文档 * @param[in] pName                 文档名称 * @param[in] pProduct              指向装配的指针,默认为 nullptr * @param[in] pUserName             用户名,默认为 nullptr * @param[in] createView            是否创建视图,默认为 true * @param[in] tempDoc               是否是临时文档,默认为 false * @param[in] type                  文档类型,默认为 Component* @return                           返回一个创建的新文档对象的指针*/static IDocument* create(    const char* pName,    IDocument *pProduct = nullptr,    const char* pUserName = nullptr,    bool createView = true,    bool tempDoc = false,    DocType type = DocType::Component);xxxxxxxxxx//示例代码const char* docName = "MyNewDocument";
// 创建一个新文档IDocument* newDoc = IDocument::create(    docName,                // 文档名称    nullptr,                // 指向装配的指针,默认为 nullptr    nullptr,                // 用户名,默认为 nullptr    true,                   // 是否创建视图,默认为 true    false,                  // 是否是临时文档,默认为 false    DocType::Component      // 文档类型,默认为 Component);
// 检查文档是否创建成功if (newDoc){    std::cout << "文档创建成功,文档名称为: " << docName << std::endl;}else{    std::cerr << "文档创建失败" << std::endl;}
定义:
IDocumentObject 是 IDocument 中包含的实际对象,每个对象代表具体的建模元素或功能,例如一个立方体、草图、约束、几何体等。它是 BIMHome 的核心建模单位,所有的几何体、关系和属性都存储在这些对象中。
功能:
表示文档中的单个对象,包含属性和依赖关系。
提供对象的属性管理,支持持久化存储。
支持对象的重新计算和状态管理。
组成:
包含对象的构造参数(如几何形状、尺寸等)。
包含对象的图形表示(如颜色、线型等),这部分信息存储在对应的 ViewProvider 中。
该类提供了create、getViewProviderName、getNameInBimPart、setDocument、getInListRecursive、getParents、hasChildElement等接口函数。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
以创建一个IDocumentObject为例:
xxxxxxxxxx//示例代码//创建IDocumentObject具体接口函数:      /** * @brief                           在给定的父文档中创建一个新的文档对象 * @details                         在给定的父文档中创建一个新的文档对象,并返回该对象的指针 * @param[in] pParent               指向父文档的指针 * @param[in] pObjectName           对象名称,默认为 nullptr * @param[in] pDocObjDelegateName   文档对象代理名称,默认为 nullptr * @return                          新创建的文档对象指针 */static IDocumentObject* create(    IDocument* pParent,    const char* pObjectName = nullptr,    const char* pDocObjDelegateName = nullptr);xxxxxxxxxx//示例代码// 创建一个新的父文档IDocument* parentDoc = IDocument::create(    "MyParentDocument",  // 文档名称    nullptr,             // 指向装配的指针,默认为 nullptr    nullptr,             // 用户名,默认为 nullptr    true,                // 是否创建视图,默认为 true    false,               // 是否是临时文档,默认为 false    DocType::Component   // 文档类型,默认为 Component);
// 检查父文档是否创建成功if (!parentDoc){    std::cerr << "父文档创建失败" << std::endl;    return -1;}
// 在父文档中创建一个新的文档对象IDocumentObject* newDocObj = IDocumentObject::create(    parentDoc,                // 指向父文档的指针    "MyNewObject",            // 对象名称    nullptr                   // 文档对象代理名称,默认为 nullptr);
// 检查文档对象是否创建成功if (newDocObj){    std::cout << "文档对象创建成功,对象名称为: " << newDocObj->getName() << std::endl;
}else{    std::cerr << "文档对象创建失败" << std::endl;}
修改MyCommand文件里面的activated函数。点击My Command按钮,屏幕中出现Hello World。其效果展示如下:

该类主要是通过的各种接口函数去创建各类基础图源,包括创建立方体、创建圆柱体、创建长方体,以及更复杂的几何体图形。
该类提供了创建基础图源接口函数createBox、createVertex、createSphere、createCylinder等等和更新基础图源接口函数updateBoxParameters、updateVertexParameters、updateSphereParameters等等。所有的接口信息参见API接口文档,点击获取更多跳转到API 文档。
其中,以创建球体createSphere为例,该接口需要传入7个参数,参数radius为球体的半径;参数angle1、angle2、angle3,用来控制球体创建的范围,如果我们像创建一个完整的球体,那么angle1、angle2、angle3的应设置为-90、90、360;参数objName为创建球体的名称;参数placement为放置位置,如果未传入参数,默认放置在原点;参数pDoc为所属文档,如果为 nullptr,则使用当前活动的文档;具体创建过程,可以参考以下示例代码:
xxxxxxxxxx//示例代码//创建球体具体接口函数/*App::IDocumentObject* createSphere(double radius, double angle1 = -90.0f, double angle2 = 90.0f, double angle3 = 360.0f, const std::string& objName = "Sphere", const Base::Placement& placement = Base::Placement(), App::IDocument* pDoc = nullptr);*/
//第一部分:确定半径,以及球体的范围大小(这里创建一个完整的球体)double radius=5.5;double angle1 = -90.0f; double angle2 = 90.0f;double angle3 = 360.0f;
//第二部分:设置名称、放置位置和父文档std::string objName="Sphere";
App::IDocument* pIDocument;//IDocument文件提供了getPlacement()函数来获得placement参数App::IDocument* placement=pIDocument->getPlacement();//也可以调用默认构造函数,即Base::Placement& placement = Base::Placement();
//IDocument文件中提供了getDocument()函数来获得pParentDoc参数App::IDocument* pDoc=pIDocument->getParentDocument();//也可以设置为空,即App::IDocument* pDoc = nullptr;
//第三部分:调用接口函数App::IDocumentObject* iSphere=BaseFigureFactory::createSphere(radius,angle1, angle2,angle3,objName,placement, pDoc);
其中,以更新球体参数updateSphereParameters为例,该接口有5个参数:参数pObj为待更新的几何体对象;参数radius为球体的半径;参数angle1、angle2、angle3,用来控制球体创建的范围。具体示例代码如下所示:
xxxxxxxxxx//示例代码//更新球体参数具体接口函数/*void updateSphereParameters(App::IDocumentObject* pObj, double radius, double angle1 = -90.0f, double angle2 = 90.0f, double angle3 = 360.0f)*/
//第一部分:获得待更新的球体对象//这里我们使用上面创建的球体对象 iSphere
//设置新的半径以及球体范围的值double radius=10.0;double angle1 = -45.0f;double angle2 = 45.0f;double angle3 = 180.0f;
//第三部分:调用接口函数BaseFigureFactory::updateSphereParameters(iSphere,radius,angle1,angle2,angle3);
该类是创建曲线工厂类,通过该文件提供的各种接口创建各种曲线(直线,线段,弧等)对象。初次之外,该文件还包含更新曲线参数的接口函数,通过已有的曲线特征来创建曲线。
该类提供了创建曲线的接口函数createLine/createLine2D、createLineSegment/createLineSegment2D、CreateSpaceApproximateBSpline等等和更新曲线参数接口函数updateLine/updateLine2D、updateLineSegment/updateLineSegment2D、updateBSpline/updateBSpline2D等等。所有的接口信息参见API接口文档,点击获取更多跳转到API 文档。
其中,以createArcofCircle和createArcofCircle2D为例,去创建一条3D圆弧和一条2D圆弧,示例代码如下。创建3D圆弧时,参数有4个:参数arcofcircle为输入的圆弧对象,参数objName为圆弧对象名称,参数placement为放置位置,如果未传入参数,默认放置在原点。最后一个参数pParentDoc为所属文档,如果为 nullptr,则使用当前活动的文档。最后返回一个圆弧对象指针。
xxxxxxxxxx//示例代码//创建3D圆弧的具体接口函数/*App::IDocumentObject* createArcofCircle(const Base::ArcofCircle& arcofcircle,const std::string& objName = "ArcofCircle", const Base::Placement& placement = Base::Placement(), App::IDocument* pParentDoc = nullptr);*/
//第一部分:构建3D圆弧基础图源/*Base::ArcofCircle提供了三种构建圆弧的构造函数第一种:基于圆心,法向量,基准向量,半径,起始角度构造圆弧ArcofCircle(Base::Vector3d center,Base::Vector3d normal,Base::Vector3d refvec,double radius,double startangle,double endangle);第二种:基于一个已有的圆对象和圆上的两个角度(起始角度、终止角度)构造圆弧ArcofCircle(const Base::Circle& circle,const double angle1,const double angle2);第三种:基于三点构造一个圆弧ArcofCircle(Base::Vector3d pt1, Base::Vector3d pt2, Base::Vector3d pt3);*/
//这里采用基于三点创建3D圆弧Base::Vector3d v1(1.5,1.5,1.5);Base::Vector3d v2(2.5,2.5,2.5);Base::Vector3d v3(3.5,3.5,3.5);Base::ArcofCircle arcCircle=new ArcofCircle(v1,v2,v3);
//第二部分:获得图形对象名称、placement参数、pParentDoc参数std::string objName="3D圆弧";
App::IDocument* pIDocument;//IDocument文件提供了getPlacement()函数来获得placement参数App::IDocument* placement=pIDocument->getPlacement();//也可以调用默认构造函数,即Base::Placement& placement = Base::Placement();
//IDocument文件中提供了getDocument()函数来获得pParentDoc参数App::IDocument* pParentDoc=pIDocument->getParentDocument();//也可以设置为空,即App::IDocument* pParentDoc = nullptr;
//第三部分:调用createArcofCircle创建3D圆弧App::IDocumentObject* iArcCirle=CurveFactory::createArcofCircle(arcCircle,objName,placement,pParentDoc);创建2D圆弧对象同理。
xxxxxxxxxx//示例代码//创建2D圆弧的具体接口函数/*App::IDocumentObject* createArcofCircle2D(const Base::ArcofCircle2D& arcofcircle2d,const std::string& objName = "ArcofCircle2D", const Base::Placement& placement = Base::Placement(), App::IDocument* pParentDoc = nullptr);*/
//第一部分:构建2D圆弧基础图源/*Base::ArcofCircle2D提供了三种构建圆弧的构造函数第一种:默认构造函数ArcofCircle2D();第二种:基于圆心、半径、起始角度、终止角度构造2D圆弧ArcofCircle2D(Base::Vector2d center, double radius, double startangle, double endangle);第三种:基于三点构造一个2D圆弧ArcofCircle2D(Base::Vector2d pt1, Base::Vector2d pt2, Base::Vector2d pt3);*/
//这里采用基于圆心、半径、起始角度、终止角度构造2D圆弧Base::Vector2d v1(1.5,1.5);double radius=5.5;double startangle=0;double endangle=180;Base::ArcofCircle2D arcCircle2d=new ArcofCircle2D(v1,radius,startangle,endangle);
//第二部分:获得图形对象名称、placement参数、pParentDoc参数std::string objName="2D圆弧";
App::IDocument* pIDocument;//IDocument文件提供了getPlacement()函数来获得placement参数App::IDocument* placement=pIDocument->getPlacement();//也可以调用默认构造函数,即Base::Placement& placement = Base::Placement();
//IDocument文件中提供了getDocument()函数来获得pParentDoc参数App::IDocument* pParentDoc=pIDocument->getParentDocument();//也可以设置为空,即App::IDocument* pParentDoc = nullptr;
//第三部分:调用createArcofCircle2D创建2D圆弧App::IDocumentObject* iArcCirle=CurveFactory::createArcofCircle(arcCircle2d,objName,placement,pParentDoc);
其中,以updateArcofCircle和updateArcofCircle2D为例,去更新一条3D圆弧和一条2D圆弧,其示例代码如下。更新3D圆弧参数时,该接口函数参数有2个:参数parcofcircle为要更新参数的圆弧对象名称,参数arcofcircle为新的输入的圆弧数据。
xxxxxxxxxx//示例代码//更新3D圆弧对象具体接口函数/*void updateArcofCircle(App::IDocumentObject* parcofcircle, const Base::ArcofCircle& arcofcircle);*/
//第一部分:更新3D圆弧对象//这里采用上面代码示例,三点创建3D圆弧Base::Vector3d v1(1.5,1.5,1.5);Base::Vector3d v2(2.5,2.5,2.5);Base::Vector3d v3(3.5,3.5,3.5);Base::ArcofCircle arcCircle=new Base::ArcofCircle(v1,v2,v3);
//第二部分:更新3D圆弧CurveFactory::updateArcofCircle(iArcCirle, arcCircle);
更新2D圆弧数据同理。
xxxxxxxxxx//示例代码//更新2D圆弧参数具体接口函数/*void updateArcofCircle2D(App::IDocumentObject* parcofcircle2d, const Base::ArcofCircle2D& arcofcircle2d);*/
//第一部分:更新2D圆弧对象//这里采用上面示例基于圆心、半径、起始角度、终止角度构造2D圆弧Base::Vector2d v1(1.5,1.5,1.5);double radius=5.5;double startangle=0;double endangle=180;Base::ArcofCircle2D arcCircle2d=new Base::ArcofCircle2D(v1,radius,startangle,endangle);
//第二部分:更新2D圆弧CurveFactory::updateArcofCircle2D(iArcCirle, arcCircle);
该文件是一个曲线助手类,主要通过该文件提供的接口函数来获取曲线的某些特性。
该文件提供了getCurveType、getBasisCurveOfTrimmedCurve、getParameter等接口函数。所有的接口信息参见API接口文档,点击获取更多跳转到API 文档。
其中,以getCurveStartPointAndEndPoint为例,该函数是获取曲线的起点坐标和终点坐标,共有参数3个:pCurve指传入的曲线,startPoint和endpoint为获取的起点和终点坐标,其参考代码如下所示:
xxxxxxxxxx//示例代码//获取曲线起点坐标和终点坐标具体接口函数/*bool getCurveStartPointAndEndPoint(App::IDocumentObject* pCurve, Base::Vector3d& startPoint, Base::Vector3d& endPoint);*/
//获得一个曲线数组std::vector<App::IDocumentObject*> slopeLineList2 = pSlopePartHelper->getSlopeLineList();
//构建两个存放起始点和终止点的数组std::vector<Base::Vector3d> startPoints1, endPoints1;
for (int i = 0; i < slopeLineList1.size(); i++){       Base::Vector3d start, end;                                                              //调用该函数获得起始点和终止点    CurveHelper::getCurveStartPointAndEndPoint(slopeLineList1[i], start, end);    //将点存入起始点数组和终止点数组    startPoints1.push_back(start);    endPoints1.push_back(end);}
该类是一个抽象类,子类需重写该类的接口函数,但在底层我们已经重写了该类,所以既可以重写该类,也可以直接调用该类的接口函数。该类主要是计算圆的一些特征数据,包括计算圆的面积,计算圆的圆的圆心、计算圆的周长、计算给定点到圆上的点的最短距离等等。
该类提供了area、axis、length、location等接口函数。所有的接口信息参见API接口文档,点击获取更多跳转到API 文档。
该该类是一个抽象类,子类需重写该类的接口函数,但在底层我们已经重写了该类,所以既可以继承重写该类,也可以直接调用该类的接口函数。以area为例,该函数示例代码如下:
xxxxxxxxxx//示例代码//计算圆的面积具体接口函数/*virtual double area() const = 0;*/
//方式一:直接调用//构建圆心Base::Vector2d center(1,1);//构建半径double radius=5.5;//创建一个圆 这里采用基于圆心半径的方式构建2D圆Base::Circle2D* circle2d=new Circle2D(center,radius);//调用该方法计算圆的面积circle2d->area();
//方式二:通过继承方式,重写该类的方法class PCircle : public IGeometryCircle{public:     PCircle(App::IDocumentObject* pCurveObj);    ~PCircle();
public:    virtual double area() const;  private:    Platform::pCircle* m_GeometryCurve = nullptr;}double PCircle::area()const{    return m_GeometryCurve->area();    //底层逻辑是 return M_PI * radius * radius;}
该类是一个抽象类,和上面的IGeometryCircle类似,子类需重写该类的接口函数,但在底层我们已经重写了该类,所以既可以重写该类,也可以直接调用该类的接口函数。该类主要是计算曲线的一些特征数据,包括计算曲线起始/终止参数值,判断曲线是否闭合,计算导数等等。
该类提供了firstParameter、isClosed、dN等接口函数。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
由于该类和上面IGeometryCircle类继承和调用方式类似,示例代码可参考IGeometryCircle的示例代码。
该文件是组合对象工厂类,提供函数接口将多个obj对应的Shape生成一个组合Shape。
该文件创建组合体的接口函数createCompound和更新组合体的接口函数updateCompound。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
通过调用createCompound函数可以将多个几何对象组合成一个复合对象。其中,参数pObjs为输入的待组合的几何对象指针数组;参数objName为生成的复合对象的名称;参数pParentDoc为所属文档,如果为 nullptr,则使用当前活动的文档;它的返回值为复合对象的指针。示例代码如下:
xxxxxxxxxx//示例代码//创建组合体的具体接口函数/*App::IDocumentObject* createCompound(std::vector<App::IDocumentObject*> pObjs, const std::string& objName = "Compound", App::IDocument* pParentDoc = nullptr)*/
//第一部分:获得一个几何对象数组,这里采用创建的方式获取集合对象数组,也可以使用已存在的数组App::IDocumentObject* pIDocument1=new IDocumentObject();App::IDocumentObject* pIDocument2=new IDocumentObject();App::IDocumentObject* pIDocument3=new IDocumentObject();
std::vector<App::IDocumentObject*>  pObjs;pObjs.push_back(pIDocument1);pObjs.push_back(pIDocument2);pObjs.push_back(pIDocument3);
//第二部分:获得图形对象名称、pParentDoc参数std::string objName="Compound";
App::IDocument* pIDocument;//IDocument文件中提供了getDocument()函数来获得pParentDoc参数App::IDocument* pParentDoc=pIDocument->getParentDocument();//也可以设置为空,即App::IDocument* pParentDoc = nullptr;
//第三部分:调用createCompound创建复合对象App::IDocumentObject* createCom=CpmpoundFactory::createCompound(pObjs,objName,pParentDoc);
通过调用updateCompound函数可以更新复合对象中的子对象。其中,参数pCompoundObj为待更新的复合对象指针;参数pObjs为新的子对象列表。示例代码如下:
xxxxxxxxxx//示例代码//更新组合体参数的具体接口函数/*void updateCompound(App::IDocumentObject* pCompoundObj, std::vector<App::IDocumentObject*> pObjs)*/
//第一部分:待更新的复合对象指针,这里采用上面创建的几何对象数组pCompoundObj
//第二部分:获得一个几何对象数组,这里采用创建的方式获取集合对象数组,也可以使用已存在的数组App::IDocumentObject* pIDocument1=new IDocumentObject();App::IDocumentObject* pIDocument2=new IDocumentObject();App::IDocumentObject* pIDocument3=new IDocumentObject();
std::vector<App::IDocumentObject*>  pObjs;pObjs.push_back(pIDocument1);pObjs.push_back(pIDocument2);pObjs.push_back(pIDocument3);
//第三部分:调用updateCompound更新复合对象中的子对象CpmpoundFactory::updateCompound(pCompoundObj, pObjs);
该类是曲面工厂类,可以通过该类提供的各类接口函数多方式创建曲面,包括三点创建平面、通过线段集合创建曲面、通过单条曲线创建曲面、根据两条曲线创建直纹曲面等等。
该类提供了createFaceByThreePoint、updateFaceByThreePoint、createPlanede、createSurfaceBySegmentLines等创建曲面的接口函数。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
以通过曲线数据创建曲面createSurfaceByCurveDatas为例,该函数有3个参数,参数curveList为曲线数据数组;参数objName为创建的曲面对象名称;参数pParentDoc为所属文档,如果为 nullptr,则使用当前活动的文档。具体可以参考以下示例代码:
xxxxxxxxxx//示例代码//通过曲线数据创建曲面具体接口函数/*App::IDocumentObject* createSurfaceByCurveDatas(const std::vector<std::shared_ptr<Base::Curve>>& curveList, const std::string& objName = "Surface", App::IDocument* pParentDoc = nullptr);*/
//第一部分:获得曲线数据数组//创建一条圆弧,两条直线段,用于构建曲线数组Base::Vector3d pt1(1.5,1.5,1.5);Base::Vector3d pt2(2.5,2.5,2.5);Base::Vector3d pt3(3.5,3.5,3.5);//构造圆弧采用三点构造法,构造直线段采用两点构造法std::shared_ptr< Base::ArcofCircle> arcCircle(new Base::ArcofCircle(pt1, pt2, pt3));std::shared_ptr< Base::ArcofCircle> lineSegment1(new Base::ArcofCircle(pt1, pt2));std::shared_ptr< Base::ArcofCircle> lineSegment2(new Base::ArcofCircle(pt2, pt3));
std::vector<std::shared_ptr<Base::Curve>> vec;vec.push_back(arcCircle);vec.push_back(lineSegment1);vec.push_back(lineSegment2);
//第二部分:设置曲面对象名称和父文档std::string objName="Surface";
App::IDocument* pIDocument;//IDocument文件中提供了getDocument()函数来获得pParentDoc参数App::IDocument* pParentDoc=pIDocument->getParentDocument();//也可以设置为空,即App::IDocument* pParentDoc = nullptr;
//第三部分:调用接口函数App::IDocumentObject* curveObj=SurfaceFactory::createSurfaceByCurveDatas(vec,objName,pParentDoc);
该类是曲面助手类,里面提供了一些获取曲面特征数据的接口函数,比如获取外轮廓对象、获取内轮廓对象。
该类提供了getOuterProfileBySurface、getInterProfilesBySurface等接口函数。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
以获取外轮廓对象getOuterProfileBySurface为例,该接口有3个参数,参数pSurface为输入曲面对象指针,作为生成外轮廓的基础曲面;参数objName为获得的外轮廓名称;参数pParentDoc为所属文档,如果为 nullptr,则使用当前活动的文档。可以参考以下示例代码:
xxxxxxxxxx//示例代码//获取外轮廓对象函数具体接口函数/*App::IDocumentObject* getOuterProfileBySurface(App::IDocumentObject* pSurface, const std::string& objName = "OuterProfile", App::IDocument* pParentDoc = nullptr);*/
//第一部分:获取输入曲面对象//这里采用上面创建的curveObj曲面
//第二部分:设置外轮廓对象名称和父文档std::string objName="OuterProfile";
App::IDocument* pIDocument;//IDocument文件中提供了getDocument()函数来获得pParentDoc参数App::IDocument* pParentDoc=pIDocument->getParentDocument();//也可以设置为空,即App::IDocument* pParentDoc = nullptr;
//第三部分:调用接口函数App::IDocumentObject* outerProfile=SurfaceFactory::getOuterProfileBySurface(curveObj,objName,pParentDoc);
该类主要是创建壳体类,通过该类提供的接口函数可以创建一个壳体。
该类提供了生成壳体createShellByFaces的接口函数。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
以createShellByFaces接口函数为例,参数faces为输入的文档壳对象;objName为壳对象名称;pParentDoc为所属文档,如果为 nullptr,则使用当前活动的文档。其示例代码如下:
xxxxxxxxxx//示例代码//接口的具体信息/*App::IDocumentObject* createShellByFaces(std::vector<App::IDocumentObject*> faces, const std::string& objName = "Shell", App::IDocument* pParentDoc = nullptr);*/
//第一部分:创建面的数组集合//上面我们已经列出了一种创建面的方式,我们重复该步骤,得到多个面,并将该这些面存入faces数组里
//第二部分:设置壳对象名称以及父文档std::string objName="Shell";
App::IDocument* pIDocument;//IDocument文件中提供了getDocument()函数来获得pParentDoc参数App::IDocument* pParentDoc=pIDocument->getParentDocument();//也可以设置为空,即App::IDocument* pParentDoc = nullptr;
//第三部分:调用接口函数App::IDocumentObject* pshell =ShellFactory::createShellByFaces(faces,objName,pParentDoc);
该类主要是创建实体类,通过该类提供的接口函数可以创建一个实体。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
该类提供了createHalfSpace 、updateHalfSpace等创建和更新实体。
由于该类逻辑和ShellFactory类相似,故不展示示例代码,示例代码可参考上面的createShellByFaces。
该类主要是基础拓扑元素(线,面,壳,体)助手类。可以对基础拓扑元素进行一些操作,如反转等。
该类提供了接口函数reversed,用于反转曲线方向。点击获取更多,跳转到该文件所在的API文档,了解接口详细信息。
该类是拉伸工厂类,主要是通过该类提供的接口函数去创建各种拉伸体。
该类提供了createExtrusion、updateExtrusionParameters等创建拉伸体和更新拉伸体的接口函数。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
以创建拉伸体createExtrusion为例,该接口函数有7个参数:参数pIObj为拉伸所需对象;参数vDir为拉伸方向;参数dLength为拉伸长度,负值为反向拉伸;参数bSolid为是否创建实体;参数sObjname为拉伸的对象名称;参数pIDoc所在文档,如果为 nullptr,则使用当前活动的文档。其参考的示例代码如下所示:
xxxxxxxxxx//示例代码//创建拉伸的具体接口函数/*App::IDocumentObject* createExtrusion(App::IDocumentObject* pIObj, const Base::Vector3d& vDir,double dLength, bool bSolid, const std::string& sObjname = "Extrusion", App::IDocument* pIDoc = nullptr);*/
//第一部分:创建一个图形,作为拉伸的对象。这里选择创建一个圆。double radius= 1;Base::Vector2d center(1,1);//这里调用Circle2D类里面的Circle2D(Base::Vector2d center, double radius)构造函数Base::Circle2D cir2d=new Circle2D(center,radius);
//调用CurveFactory类的createCircle2D接口函数创建一个2d圆,这里的objName,placement,pParentDoc获得方法同上面示例代码,然而也可以不设置,用默认参数App::IDocumentObject* circle2d=CurveFactory::createCircle2D(cir2d,objName,placement,pParentDoc);
//第二部分:设置方向、拉伸长度、是否创建实体Base::Vector3d vDir(1.5,1.5,1.5);doube dLength=5;bool bSolid=true;
//第三部分:设置拉伸对象名称,以及父文档std::string sObjname="Extrusion";App::IDocument* pIDocument;//IDocument文件中提供了getDocument()函数来获得pParentDoc参数App::IDocument* pParentDoc=pIDocument->getParentDocument();//也可以设置为空,即App::IDocument* pParentDoc = nullptr;
//第四部分:调用接口函数App::IDocumentObject* extrusion =createExtrusion(circle2d,vDir,dLength,bSolid, sObjname,pParentDoc);
以更新拉伸体updateExtrusionParameters为例,该函数接口有5个参数:参数pIObj为拉伸后的对象;参数pBase为拉伸的对象;参数vDir为拉伸方向;参数dLength为拉伸长度,负值为反向拉伸;参数bSolid为是否创建实体。其参考的示例代码如下:
xxxxxxxxxx//示例代码//更新拉伸具体接口函数/*void updateExtrusionParameters(App::IDocumentObject* pIObj, App::IDocumentObject* pBase, const Base::Vector3d& vDir,double dLength, bool bSolid);*/
//第一部分:获取待拉伸体对象,这里采用上面创建的拉伸体对象extrusion//第二部分:设置新的拉伸体的参数Base::Vector3d vDir(1.5,1.5,1.5);double dLength=10.0;bool bSolid =false;
//第三部分:调用接口函数App::IDocumentObject* pIObj;ExtrusionFactory::updateExtrusionParameters(pIObj, extrusion, vDir,dLength,bSolid);
该类是创建放样工厂类。可以通过该类提供的接口函数创建各种放样体。
该类提供了createLoft、updateLoftParameters等创建和更新放样体的接口函数。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
以上函数接口示例代码与ExtrusionFactory的示例代码相似,可以参考ExtrusionFactory的示例代码,并按规律应用到本接口函数中。
该类是旋转工厂类,可以通过该类提供的接口函数创建旋转体。
该类提供了创建旋转体createRevolution和更新旋转体updateRevelutionParameters的接口函数。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
以上函数接口示例代码与ExtrusionFactory的示例代码相似,可以参考ExtrusionFactory的示例代码,并按规律应用到本接口函数中。
该类是扫掠工厂类,可以通过该类提供的接口函数创建各种扫掠体,包括根据多个对象创建扫掠、通过线和圆放样生成扫掠、通过点和圆放样生成扫掠等。
该类提供了createSweep、createSweep、creatPipeByLine等创建扫掠体和updateSweepParameters、updateSweepParameters、updatePipeByLineParameters等更新扫掠体的接口函数。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
以上函数接口示例代码与ExtrusionFactory的示例代码相似,可以参考ExtrusionFactory的示例代码,并按规律应用到本接口函数中。
该类是创建钢构件工厂类,可以通过该类提供的接口函数创建各种钢构件,包括钢槽、钢管、型钢等等。
该类提供了创建钢构件接口函数createBeamChannel、createDoubleAngleSteel、createDoubleChannelSteel等等和更新钢构件updateBeamChannelParameters、updateDoubleAngleSteelParameters、updateDoubleChannelSteelParameters等等。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
这里以创建钢槽createBeamChannel为例,该接口函数有8个参数,参数d、t、r1、r2、l,分别为构建钢槽的边长、厚度、两端圆弧半径、内圆弧半径、长度;参数objName为新创建对象的名称;参数placement为对象在三维空间中的位置和方向,如果未传入参数,默认放置在原点;参数pDoc为对象应该被添加到的文档,如果为 nullptr,则使用当前活动的文档。具体示例代码如下:
xxxxxxxxxx//示例代码//创建钢槽的具体接口函数/*App::IDocumentObject* createBeamChannel(double d,double t,double r1,double r2,double l,const std::string& objName = "BeamChannel",const Base::Placement& placement = Base::Placement(),App::IDocument* pDoc = nullptr);*/
//第一部分:设置钢槽数据double d=30;double t=1;double r1=5;double r2=4;double l=10;
//第二部分:设置名称,构建位置,以及父文档std::string objName="BeamChannel";
App::IDocument* pIDocument;//IDocument文件提供了getPlacement()函数来获得placement参数App::IDocument* placement=pIDocument->getPlacement();//也可以调用默认构造函数,即Base::Placement& placement = Base::Placement();
//IDocument文件中提供了getDocument()函数来获得pParentDoc参数App::IDocument* pParentDoc=pIDocument->getParentDocument();//也可以设置为空,即App::IDocument* pParentDoc = nullptr;
//第三部分:调用接口函数App::IDocumentObject* BeamChannel=ProfileSteelFactory::createBeamChannel(d,t,r1,r2,l,objName ,placement,pParentDoc);
这里以更新钢槽参数updateBeamChannelParameters为例,该函数有6个参数:参数pObj为待更新参数的钢槽对象;参数d、t、r1、r2、l,分别为新的钢槽的边长、厚度、两端圆弧半径、内圆弧半径、长度。具体示例代码如下:
xxxxxxxxxx//示例代码//更新钢槽参数的具体接口函数/*void updateBeamChannelParameters(App::IDocumentObject* pObj,double d,double t,double r1,double r2,double l);*///第一部分:获得待更新参数的钢槽对象,这里采用上面创建的钢槽对象BeamChannel
//第二部分:设置钢槽参数值double d=40;double t=2;double r1=6;double r2=5;double l=111;
//第三部分:调用接口函数ProfileSteelFactory::updateBeamChannelParameters(BeamChannel,d,t,r1,r2,l);
该类是构建输电构件的工厂类,主要通过该类提供的接口函数去创建各种输电构件,包括
该类提供了createPorcelainBushing、createConePorcelainBushing、createInsulator等创建输电构件的接口函数以及updatePorcelainBushingParameters 、updateConePorcelainBushingParameters、updateInsulatorParameters等更新输电构件参数的接口函数。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
创建和更新输电构件的示例代码可参考钢构建的示例代码。
该类是几何修复工具类,通过遍历子元素(点、边、面)并执行修复操作(修复面的连续性、缝合边、移除微小几何)。
该类提供了修复几何对象fixObject接口函数。具体的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
以fixObject为例,该接口函数只需要传入一个参数,为待修复的集合对象,调用过程可参考以下示例代码:
xxxxxxxxxx//示例代码//几何修复具体接口函数/*bool fixObject(App::IDocumentObject* pObj);*///按照在2.1.3里圆的创建过程,我们创建一个2D圆double radius= 1;Base::Vector2d center(1,1);Base::Circle2D cir2d=new Circle2D(center,radius);App::IDocumentObject* circle2d=CurveFactory::createCircle2D(cir2d,objName,placement,pParentDoc);
//调用接口函数bool result=FixShapeTool::fixObject(circle2d);
//我们可以通过查看result结果来判断修复是否成功std::cout<<result;
该类主要计算曲线之间的一些特征数据,包括极值,极值点对坐标等等。
该类提供了createExtremaCurveCurve、nbExtrema、points、parameters 等接口函数。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
以createExtremaCurveCurve计算两曲线之间的极值,该接口函数有2个参数:分别为带传入的两条曲线pCurve1和pCurve2。具体示例代码参考如下:
xxxxxxxxxx//示例代码//计算两曲线之间的极值具体及入口函数/*std::shared_ptr<IExtremaCurveCurve> createExtremaCurveCurve(std::shared_ptr<Base::Curve> pCurve1 ,std::shared_ptr<Base::Curve> pCurve2);*///第一部分:获得两条曲线,这里采用创建两条圆弧//这里采用基于三点创建3D圆弧Base::Vector3d pt1(1.5,1.5,1.5);Base::Vector3d pt2(2.5,2.5,2.5);Base::Vector3d pt3(3.5,3.5,3.5);Base::Vector3d pt4(4.5,4.5,4.5);Base::Vector3d pt5(5.5,5.5,5.5);Base::Vector3d pt6(6.5,6.5,6.5);
std::shared_ptr< Base::ArcofCircle> arcCircle1(new Base::ArcofCircle(pt1, pt2, pt3));std::shared_ptr< Base::ArcofCircle> arcCircle2(new Base::ArcofCircle(pt4, pt5, pt6));
// 第二部分:调用接口函数计算极值auto extrema = createExtremaCurveCurve(arcCircle1, arcCircle2);
该类是投影助手类,可以通过该类的接口函数来计算点到三维/二维多段线的最短投影点。
该类提供了getNearestPointByProjectPointOnCurves、getNearestPointByProjectPointOnCurves2D等接口函数。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
这里以计算点到三维多段线的最短投影点getNearestPointByProjectPointOnCurves为例。该接口函数有2个参数:参数polyLine为多线段;参数point为投影点坐标。具体示例代码如下所示:
xxxxxxxxxx//示例代码//计算点到三维多段线的最短投影点接口函数的具体接口/*Base::Vector3d getNearestPointByProjectPointOnCurves(const Base::PolyLine& polyLine, const Base::Vector3d& point);*/
//第一部分:获取一条三维多线段//创建一条圆弧,两条直线段,用于构建曲线数组Base::Vector3d pt1(1.5,1.5,1.5);Base::Vector3d pt2(2.5,2.5,2.5);Base::Vector3d pt3(3.5,3.5,3.5);//构造圆弧采用三点构造法,构造直线段采用两点构造法std::shared_ptr< Base::ArcofCircle> arcCircle(new Base::ArcofCircle(pt1, pt2, pt3));std::shared_ptr< Base::ArcofCircle> lineSegment1(new Base::ArcofCircle(pt1, pt2));std::shared_ptr< Base::ArcofCircle> lineSegment2(new Base::ArcofCircle(pt2, pt3));
std::vector<std::shared_ptr<Base::Curve>> vec;vec.push_back(arcCircle);vec.push_back(lineSegment1);vec.push_back(lineSegment2);//第二部分:构造多线段,这里采用多线段的构造函数PolyLine(const std::vector<std::shared_ptr<Curve>>& polyline);来构造一条多线段Base::PolyLine polyline(vec);
//第三部分:调用接口函数Base::Vector3d point;Base::Vector3d Pt=ProjectHelper::getNearestPointByProjectPointOnCurves(polyLine,point);
该类是布尔运算工厂类,通过该类提供的接口函数可以完成几何体对象之间的交、并、截面、分割运算等。
该类提供了createCommon、createCut、createFuse等创建布尔运算集的接口函数以及updateCutParameters、updateFuseParameters、updateMultiFuseParameters等更新布尔运算集的接口函数。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
以计算几何体对象之间的交集createCommon为例,分为两个对象之间的交集运算和批量对象的交集运算。
两个对象之间的交集运算,该函数接口有4个参数:参数pObj1和pObj2为两个几何体对象,用于进行交集运算;参数objName为创建的交集的对象名称;参数pParentDoc为所属文档,如果为 nullptr,则使用当前活动的文档。具体示例代码如下:
xxxxxxxxxx//示例代码//两个对象的交集运算的具体接口函数/*App::IDocumentObject* createCommon(App::IDocumentObject* pObj1, App::IDocumentObject* pObj2, const std::string& objName = "Common", App::IDocument* pParentDoc = nullptr);*/
//第一部分:获得两个几何体对象,这里调用BasicFeature里的createBox来创建两个不同的正方体//对象
double dLength1=10.0; double dLength1=15.0; App::IDocumentObject* box1=BasicFeature::createBox(dLength1,dLength1,dLength1, sObjname, pIDoc);App::IDocumentObject* box2=BasicFeature::createBox(dLength2,dLength2,dLength2, sObjname, pIDoc);
//第二部分:调用接口函数,其余参数使用默认参数App::IDocumentObject* common=BooleanFactory::createCommon(box1, box2,objName,pParentDoc);批量对象之间的交集运算,接口函数有4个参数:参数arguments为第一组几何体对象;参数tools为第二组几何体对象;参数objName为创建的交集的对象名称;参数pParentDoc为所属文档,如果为 nullptr,则使用当前活动的文档。具体示例代码如下:
xxxxxxxxxx//示例代码//批量对象之间的交集运算的具体接口函数/*App::IDocumentObject* createCommon(std::vector<App::IDocumentObject*> arguments, std::vector<App::IDocumentObject*> tools, const std::string& objName = "Common", App::IDocument* pParentDoc = nullptr);*/
//第一部分:创建两组几何体对象,这里创建一组正方体对象和一组长方体对象//这里只演示一组里面只有一个几何体对象,来代表一组里面有多个对象//创建正方体double dLength1=10.0; App::IDocumentObject* box1=BasicFeature::createBox(dLength,dLength,dLength, sObjname, pIDoc);std::vector<App::IDocumentObject*> arguments;arguments.push_back(box1);
//创建长方体,这里调用BasicFeature里的createCuboid来创建长方体double length=15;double height=20;double width=15;App::IDocumentObject* cuboid=BasicFeature::createCuboid(length,height, width,objName, placement, pDoc);std::vector<App::IDocumentObject*> tools;tools.push_back(cuboid);
//第二部分:调用接口函数,其余参数使用接口函数默认参数App::IDocumentObject* common=BooleanFactory::createCommon(arguments, tools, objName,pParentDoc);以更新交集updateCommonParameters为例,该接口函数有4个参数:参数pIObj为新交集对象;参数pBase和pTool为要更新的两个交集对象;参数bRefine为是否优化,这里设置为false。具体示例代码如下:
xxxxxxxxxx//示例代码//更新交集的具体接口函数/*void updateCommonParameters(App::IDocumentObject* pIObj, App::IDocumentObject* pBase,App::IDocumentObject* pTool,bool bRefine);*/
//第一部分:获取两个几何对象,这里采用上面创建的box1和box2两个正方体对象
//第二部分:调用接口函数App::IDocumentObject* pIObj;BooleanFactory::updateCommonParameters(pIObj,box1,box2,false);
该类创建离散曲线类,通过该类提供的接口函数可以通过多种方式离散曲线,包括通过弦高、固定长度、点数量等离散曲线。
该类提供了dispersionByDeflection、dispersionByLength、dispersionByTangentialDeflection等离散曲线接口函数。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
以通过弦高离散曲线dispersionByDeflection,该接口函数有4个参数:参数pOriginalCurveObj为指向原始曲线对象的指针;参数deflection代表弦高,通常弦高越小,离散线段越多,逼近越精确,但计算量增大,也就会越慢;参数toler为容差值,代表离散后的线段与原始曲线的最大偏离距离,容差越小,代表生成的线段越多,精度就越高;参数precision为是否获取精准结果,精度高,点数目多,速度慢 精度低,点数目少,速度快。具体参考代码如下所示:
xxxxxxxxxx//示例代码//通过弦高离散曲线的具体接口函数/*static std::shared_ptr<IDispersionCurve> dispersionByDeflection(App::IDocumentObject* pOriginalCurveObj, const double deflection, const double toler = -1, bool precision = false);*/
//第一部分:获取一条曲线对象//这里采用基于三点创建一条3D圆弧Base::Vector3d v1(1.5,1.5,1.5);Base::Vector3d v2(2.5,2.5,2.5);Base::Vector3d v3(3.5,3.5,3.5);Base::ArcofCircle arcCircle=new ArcofCircle(v1,v2,v3);//这里调用CurveFactory里的createArcofCircle来创建一条IDocumentObject类型的3D圆弧App::IDocumentObject* arccircle=CurveFactory::createArcofCircle(arcCircle,objName, placement,pParentDoc);
//设置其他参数double deflection=1;double toler =0.1;bool precision = false;
//第三部分:调用接口函数std::shared_ptr<IDispersionCurve> dispersion=IDispersionCurve::dispersionByDeflection(arccircle,deflection,toler,precision);
该类是加工操作工厂类,通过该类提供的接口函数对几何体对象执行倒直角操作。
该类提供了创建倒直角createChamfer和更新倒直角参数updateChamferParameters 的接口函数。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
以创建倒直角为例,该函数有4个参数:参数pBase为要倒直角的几何对象;参数vEdges为倒直角的直线信息,是vector数组,里面存储的是边和倒直角数据的结构体;参数sObjname为倒直角后的名称;参数pIDoc为所在文档,如果为 nullptr,则使用当前活动的文档。具体示例代码如下:
//示例代码//创建倒直角的具体接口函数/*App::IDocumentObject* createChamfer(App::IDocumentObject* pBase, const std::vector<EdgesInfo>& vEdges,const std::string& sObjname = "Chamfer", App::IDocument* pIDoc = nullptr);*/
//第一部分:获得待倒角的几何对象,这里调用BasicFeature里的createBox来创建一个立方体double dLength=10.0; App::IDocumentObject* box=BasicFeature::createBox(dLength,dLength,dLength, sObjname, pIDoc);
//第二部分:准备要倒直角边的数据/*struct EdgesInfo{    int edgeid;    double radius1;    double radius2;};该结构体存储的是倒直角边的数据,edgeid为边的序号ID,表示在哪条边上倒角;radius1和radius2为与该边相交两条边距离该相交顶点的距离(在倒圆角中,radius1和radius2分别代表该边两端点的倒角圆的半径大小)。*///这里我们创建一个结构体对象用于演示,在其他时候,通过鼠标点击事件和前端设置属性值来获取边的数据struct EdgesInfo edges={1,5,2};std::vector<EdgesInfo> vEdges;vEdges.push_back(edges);
//第三部分:设置名称、放置位置和父文档std::string objName="Chamfer";
App::IDocument* pIDocument;//IDocument文件中提供了getDocument()函数来获得pParentDoc参数App::IDocument* pDoc=pIDocument->getParentDocument();//也可以设置为空,即App::IDocument* pDoc = nullptr;
//第四部分:调用接口函数,其余参数使用默认参数App::IDocumentObject* chamfer=ChamferFactory::createChamfer(box,vEdges,objName ,pDoc);
以更新倒直角updateChamferParameters为例,该函数接口有3个参数:参数pIObj为更新后的对象;参数pBase待更新的几何对象;参数vEdges为倒直角的直线信息。具体示例代码如下:
xxxxxxxxxx//示例代码//更新倒直角的具体接口函数/*void updateChamferParameters(App::IDocumentObject* pIObj, App::IDocumentObject* pBase, const std::vector<EdgesInfo>& vEdges);*/
//第一部分:获得要更新倒直角的几何对象,这里采用上面创建的对象chamfer、//第二部分:设置倒直角数据struct EdgesInfo edges={1,4,4};std::vector<EdgesInfo> vEdges;vEdges.push_back(edges);
//第三部分:调用接口函数App::IDocumentObject* pObj;ChamferFactory::updateChamferParameters(pObj,chamfer,vEdges);
该类是加工操作工厂类,通过该类提供的接口函数对几何体对象执行倒圆角操作。
该类提供了创建倒圆角createFillet和更新倒圆角updateFilletParameters的接口函数。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
该类与倒直角ChamferFactory相似,该部分的参考代码可参考ChamferFactory部分。
该类是加工操作工厂类,通过该类提供的接口函数对几何体对象执行抽壳操作。
该类提供了创建抽壳体createThickness和更新抽壳体updateThicknessParameters的接口函数。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
以创建抽壳createThickness为例,该函数接口有8个参数:参数pFaces为待抽壳对象,具体指得是要抽壳的面或者是实体;参数dValue为抽壳值,用于控制抽壳的厚度值;参数lMode为抽壳的模式,具体有“Skin”、“Pipe”、“Recto Verso”,这里以枚举相对应;参数lJoin为结合类型,具体有“Arc”、“Tangent”、“Intersection”,这里也是以枚举相对应;参数bIntersection启用后将避免某些模型中的自交集;参数bSelfIntersection为是否交叉;参数sObjname为抽壳后的对象名称;参数pIDoc为所在文档,如果为 nullptr,则使用当前活动的文档。具体示例代码如下所示:
xxxxxxxxxx//示例代码//创建抽壳的具体接口函数/*App::IDocumentObject* createThickness(App::IDocumentObject* pFaces, double dValue,long lMode, long lJoin, bool bIntersection, bool bSelfIntersection, const std::string& sObjname = "Thickness", App::IDocument* pIDoc = nullptr);*/
//第一部分:获得待抽壳对象,这里调用BasicFeature里的createBox来创建一个立方体double dLength=10.0; App::IDocumentObject* box=BasicFeature::createBox(dLength,dLength,dLength, sObjname, pIDoc);
//第二部分:设置其他参数值double dValue=2;long lMode=0;long lJoin=1;bool bIntersection=true;bool bSelfIntersection=false;
//第三部分:设置名称和父文档std::string objName="Thickness";
App::IDocument* pIDocument;//IDocument文件中提供了getDocument()函数来获得pParentDoc参数App::IDocument* pDoc=pIDocument->getParentDocument();//也可以设置为空,即App::IDocument* pDoc = nullptr;
//第四部分:调用接口函数App::IDocumentObject* thickness=ThicknessFactory::createThickness(box, dValue,lMode,lJoin,bIntersection,bSelfIntersection,sObjname,pIDoc);
以更新抽壳updateThicknessParameters为例,给接口函数有7个参数:参数pIObj为更新的抽壳对象;参数pFaces为待更新的抽壳对象;其余参数和上面所对应。具体示例代码如下所示:
xxxxxxxxxx//示例代码//更新抽壳的具体接口函数/*void updateThicknessParameters(App::IDocumentObject* pIObj, App::IDocumentObject* pFaces, double dValue,long lMode, long lJoin, bool bIntersection, bool bSelfIntersection);*/
//第一部分:获取待更新抽壳对象,这里用上面创建的抽壳对象thickness
//第二部分:设置新参数值double dValue=3;long lMode=0;long lJoin=1;bool bIntersection=true;bool bSelfIntersection=false;
//第三部分:调用接口函数App::IDocumentObject* pIObj;ThicknessFactory::updateThicknessParameters(pIObj, thickness,dValue,lMode,lJoin,bIntersection,bSelfIntersection);
该类是裁剪曲线工厂类,通过该类提供的接口函数可以裁剪曲线。
该类提供了createClipCurveByDistanceInterval等创建裁剪曲线接口函数和updateClipCurveByDistanceInterval更新裁剪曲线参数的接口函数。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
以根据距离空间,创建裁剪曲线createClipCurveByDistanceInterval为例,该接口函数有5个参数:参数pOriginalCurveObj为原始曲线对象;参数startDistance和endDistance分别为距离起始端点的开始距离和终止距离;参数objName为裁剪后的曲线对象名称;参数pParentDoc为所在文档,如果为 nullptr,则使用当前活动的文档。具体示例代码如下所示:
xxxxxxxxxx//示例代码//创建裁剪曲线的具体接口函数/*App::IDocumentObject* createClipCurveByDistanceInterval(App::IDocumentObject* pOriginalCurveObj, double startDistance, double endDistance, const std::string& objName = "ClipCurve", App::IDocument* pParentDoc = nullptr);*/
//第一部分:获得一条待裁剪曲线//这里采用基于三点创建一条3D圆弧Base::Vector3d v1(1.5,1.5,1.5);Base::Vector3d v2(2.5,2.5,2.5);Base::Vector3d v3(3.5,3.5,3.5);Base::ArcofCircle arcCircle=new ArcofCircle(v1,v2,v3);//这里调用CurveFactory里的createArcofCircle来创建一条IDocumentObject类型的3D圆弧,除//圆弧数据外,其余参数这里使用默认参数App::IDocumentObject* arccircle=CurveFactory::createArcofCircle(arcCircle,objName, placement,pParentDoc);
//第二部分:设置其他参数double startDistance=2.3;double endDistance=6.7;
std::string objName="ClipCurve";
App::IDocument* pIDocument;//IDocument文件中提供了getDocument()函数来获得pParentDoc参数App::IDocument* pDoc=pIDocument->getParentDocument();//也可以设置为空,即App::IDocument* pDoc = nullptr;
//第三部分:调用接口函数App::IDocumentObject* clipcurve=ClippingCurveFactory::createClipCurveByDistanceInterval(arccircle, startDistance,endDistance,objName,pDoc);
以更新裁剪曲线的距离区间updateClipCurveByDistanceInterval为例,该接口函数有4个参数:参数pClipCurveObj为裁剪后的曲线对象;参数pOriginalCurveObj为待裁剪的曲线对向;参数startDistance和endDistance分别为距离起始端点的开始距离和终止距离。具体示例代码如下所示:
xxxxxxxxxx//示例代码//更新裁剪曲线的距离空间的具体接口函数/*void updateClipCurveByDistanceInterval(App::IDocumentObject* pClipCurveObj, App::IDocumentObject* pOriginalCurveObj, double startDistance, double endDistance);*/
//第一部分:获得一条原始曲线,这里使用上面新创建的arccircle
//第二部分:设置起始和终止距离double startDistance=3.3;double endDistance=5.7;
//第三部分:调用接口函数App::IDocumentObject* pClipCurveObj;ClippingCurveFactory::updateClipCurveByDistanceInterval(pClipCurveObj,arccircle,startDistance,endDistance);
该类分割曲线工厂类,可以通过该类提供的接口函数将几何对象分割成几个子对象。
该类提供了createSubObjsByPlaneSplit等通过多种方式分割几何对象的接口函数。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
以通过平面分割创建子对象createSubObjsByPlaneSplit为例,该接口函数有5个参数:参数pObj为待分割的几何对象;参数points为用来定义分割平面的点集;参数isGetSubElement为是否获取子元素;参数objName为生成子对象的名称;参数pParentDoc所属文档,如果为 nullptr,则使用当前活动的文档。具体示例代码如下所示:
xxxxxxxxxx//示例代码//通过平面分割创建子对象/*std::vector<App::IDocumentObject*> createSubObjsByPlaneSplit(App::IDocumentObject* pObj, std::vector<Base::Vector3d> points, const bool isGetSubElement = false, const std::string& objName = "SplitSubObj", App::IDocument* pParentDoc = nullptr);*/
//第一部分:获得待分割对象,这里调用BasicFeature里的createBox来创建一个立方体,作为分割对象double dLength=10.0; App::IDocumentObject* box=BasicFeature::createBox(dLength,dLength,dLength, sObjname, pIDoc);
//第二部分:定义分割平面的点集和其他参数Base::Vector3d pt1(1.5,1.5,1.5);Base::Vector3d pt2(2.5,2.5,2.5);Base::Vector3d pt3(3.5,3.5,3.5);std::vector<Base::Vector3d> points;points.push_back(pt1);points.push_back(pt2);points.push_back(pt3);
bool isGetSubElement = false;
std::string objName="SplitSubObj" ;
App::IDocument* pIDocument;//IDocument文件中提供了getDocument()函数来获得pParentDoc参数App::IDocument* pDoc=pIDocument->getParentDocument();//也可以设置为空,即App::IDocument* pDoc = nullptr;
//第三部分:调用接口函数std::vector<App::IDocumentObject*> splitsubobj=SplitShapeFactory::createSubObjsByPlaneSplit(box,points,isGetSubElement,objName,pParentDoc);
该类是偏移工厂类,可以根据该类提供的接口函数将输入的几何对象进行偏移从而生成新的对象。
该类提供了基于已有几何对象创建新的偏移对象createOffsetObj的接口函数。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
由于该类与裁剪曲线和分割对象类似,故该代码示例可参考上面已经展示的示例代码,所以不过多赘述。
该类创建偏移工具类,该类提供多方式去创建偏移的对象。
该类提供了offset、createOffsetByBaseGeometry等创建偏移对象的接口函数。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
由于该类和裁剪曲线和分割对象类似,故该代码示例可参考上面已经展示的示例代码,所以不过多赘述。
该类是变换工厂类,可以通过该类提供的接口函数去执行平移、镜像等变换。
该类提供了translation、rotation、scale等平移、镜像变换的接口函数。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
由于该类与裁剪曲线和分割对象类似,故该代码示例可参考上面已经展示的示例代码,所以不过多赘述。
该类是变换助手类,该类提供的接口函数主要是计算源坐标系到目标坐标系的4D变换矩阵。
该类提供了transform接口函数,用于计算从源坐标系到目标坐标系的4D变换矩阵。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
该类是DocumentObject工具类,通过该类提供的接口函数可以获得几何元素的一些特征数据,包括获取子元素数量,所有线的中心,所有面的面心。
该类提供了updateGeoFeaturePlacement、getFeaturePlacement、updateGeoFeatureLocalPlacement、getSubElements、getAllIntersectionPoints等接口函数。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
以获取所有线的端点getAllCurvePoints为例,该函数有1个参数:参数pObj,是包含几何元素的数组。具体示例代码如下所示:
xxxxxxxxxx//示例代码//获取线的所有端点的具体接口函数/*std::vector<Base::Vector3d> getAllCurvePoints(std::vector<App::IDocumentObject*> pObj);*/
//第一部分:创建线段数组//这里采用构造函数LineSegment(Base::Vector3d startPoint, Base::Vector3d endPoint);来构//造三条线段Base::Vector3d v1(1.5,1.5,1.5);Base::Vector3d v2(2.5,2.5,2.5);Base::Vector3d v3(3.5,3.5,3.5);Base::Vector3d v4(4.5,4.5,4.5);Base::Vector3d v5(5.5,5.5,5.5);Base::Vector3d v6(6.5,6.5,6.5);Base::LineSegment ls1=new Base::LineSegment(v1,v2);Base::LineSegment ls2=new Base::LineSegment(v3,v4);Base::LineSegment ls3=new Base::LineSegment(v5,v6);
//调用CurveFactory中的createLineSegment来创建线段几何元素,该接口函数其余参数采用默认参数App::IDocumentObject* ls4=CurveFactory::createLineSegment(ls1,objName,placement,pParentDoc);App::IDocumentObject* ls5=CurveFactory::createLineSegment(ls2,objName,placement,pParentDoc);App::IDocumentObject* ls6=CurveFactory::createLineSegment(ls3,objName,placement,pParentDoc);
//创建数组std::vector<App::IDocumentObject*> pObj;pObj.push_back(ls4);pObj.push_back(ls5);pObj.push_back(ls6);
//第二部分:调用接口函数std::vector<Base::Vector3d> curvepoints=DocumentObjectTool::getAllCurvePoints(pObj);
该类是测量工具类,通过该类提供的接口函数可以获得几何元素的一些特征数据,包括曲线长度,面的长度,形心等。
该类提供了getCurveLength、getCurve2dLength、getMatrixOfInertia、getSolidCenter等接口函数。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
由于该类与DocumentObjectToo类似,故该代码示例可参考上面已经展示的示例代码,所以不过多赘述。
该类是向量工具类。
该类提供了rotation接口函数,用于对三维向量进行旋转操作。接口信息请参见API接口文档,点击获取更多跳转到API 文档。
由于该类与DocumentObjectTool类似,故该代码示例可参考上面已经展示的示例代码,所以不过多赘述。
该类地质工厂类,通过该类提供的接口函数可以生成和地质相关的元素,包括拟合第地质图形,生成山体和切割山体等。
该类提供了createGeologySurface、createGeologyMountain、createGeologicalMountainCut接口函数。所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
以通过点集拟合地质图形createGeologySurface为例,该接口函数有3个参数:参数points包含三维点的向量,用于拟合地质图形表面;参数objName为生成的地质图形对象的名称,默认为 "GeologyMeshSurface";参数pDoc为所属文档,如果为 nullptr,则使用当前活动的文档。具体示例代码如下所示:
xxxxxxxxxx//示例代码//通过点集拟合地质图形的具体接口函数/*App::IDocumentObject* createGeologySurface(const std::vector<Base::Vector3d>& points,const std::string& objName = "GeologyMeshSurface,App::IDocument* pDoc = nullptr)*/
//第一部分:获得点集,假设一个点集数组里面有N个点Base::Vector3d v1,v2,v3,···,vn;std::vector<Base::Vector3d> ponits;points.push_back(v1);points.push_back(v2);points.push_back(v3);        ·        ·        ·points.push_back(vn);
//第二部分:设置额外参数std::string objName="GeologyMeshSurface" ;
App::IDocument* pIDocument;//IDocument文件中提供了getDocument()函数来获得pParentDoc参数App::IDocument* pDoc=pIDocument->getParentDocument();//也可以设置为空,即App::IDocument* pDoc = nullptr;
//第三部分:调用接口函数App::IDocumentObject* geologysurface=GeologyFactory::createGeologySurface(points, objName,pDoc);
IDrawPage是一个 定义绘图页面核心功能的接口(Interface),用于规范绘图页面的基本行为和属性。它可以理解为 “绘图页面的抽象契约”,规定了一个绘图页面必须具备的能力(如管理视图、设置页面属性、支持打印等),具体由不同的实现类(如普通图纸页、工程标准页等)来完成实际功能。
本文以添加A2图纸模板为例,逐步讲解如何加载DXF模板。加载A2图纸模板,主要用于固定绘图区域,如果加载的不是类似于A2这类的图纸模板,那么当中的一些步骤可能并不通用,具体使用情况还需要看项目进行具体分析。
通过App::GetApplication().getActiveDocument()先获得当前活动界面的节点树,然后再利用getClassTypeId在节点树上查找是否已经添加过某一类型的节点,避免重复添加相同节点。在节点树中利用getObjectsOfType进行节点搜索,并通过pPages返回搜索到的所有结果。
相关示例代码如下所示:
xxxxxxxxxx//示例代码//取得当前活动页面的节点树App::Document* pDoc = App::GetApplication().getActiveDocument();TechDraw::DrawPage* page = nullptr;std::vector<App::DocumentObject*> pPages;
//从节点树上取得指定类型的节点数据pDoc->getObjectsOfType(TechDraw::DrawPage::getClassTypeId(), pPages); 注意:当前活动页面的结点树数量是唯一的,所以一次只能拿到一颗树;在节点树上的搜索节点是不唯一的,可能同时拿到多个节点。
二维出图和详图都是DrawPage的类型,所以在使用getObjectsOfType搜索DrawPage时,就可能出现多个返回值。在DrawPage中有一个Label属性,这个Label标签可以认为是DrawPage在节点树中的展现的名称,在同类型中具有唯一性(人为控制其唯一性)。

上图中可以发现子节点和父节点的名称相同,但其父节点的类型为BimProduct,在getObjectsOfType搜索DrawPage时,会将父节点的BimProduct排除。
如果当前已经加载了其目标节点,可直接拿到该节点进行一些的操作:
xxxxxxxxxx//示例代码QString qpagename = QString::fromLocal8Bit("二维图纸");std::string pagename = qpagename.toStdString();for (auto it : pPages) {    if (std::string(it->Label.getValue()) != pagename)        continue;        // 动态类型转化,从基类转化为子类    page = dynamic_cast<TechDraw::DrawPage*>(it);     if (nullptr != page) {                // 清空绘制数据        page->deleteAllViews();         break;    }}关于类型转化那一步,其实可以理解为在最开始的getObjectsOfType查找中,存在将子类DrawPage转化为基类DocumentObject的过程,然后在此只是再将基类还原为子类。关于dynamic_cast的特性可自行上网检索。
如果在节点树中没有发现其目标节点对象,则还需要往树节点中添加其节点。
我们通过defaultTemplate 接口函数来进行文件路径拼接;通过getUniqueObjectName 接口函数确保名称具有唯一性。通过addObject 添加对象。
加载DXF文件的示例代码如下所示:
xxxxxxxxxx//示例代码std::string temType = "A2-H";QString templateFilePath = TechDraw::Preferences::defaultTemplate(temType); // 利用文件名,拼接出完整的文件路径std::string PageName = pDoc->getUniqueObjectName(pageName.c_str()); //DrawPage节点名称std::string TemplateName = pDoc->getUniqueObjectName("Template"); // 模板名称templateFilePath = Base::Tools::escapeEncodeFilename(templateFilePath); // 路径
/**************************父节点BimProduct加载************************************/App::BimProduct* pBimProduct = dynamic_cast<App::BimProduct*>(pDoc);if (!pBimProduct)    return;PipeLine::PipeLineBase* pPipeLineBase = nullptr;auto pPartMap = pBimProduct->getPartMap();auto pPartMapIter = pPartMap.begin();while (pPartMapIter != pPartMap.end()) {    if ((*pPartMapIter).second->isDerivedFrom(PipeLine::PipeLineBase::getClassTypeId())) {        pPipeLineBase = dynamic_cast<PipeLine::PipeLineBase*>((*pPartMapIter).second);        App::DocumentFileInfo info;        info.type = App::Component;        info.name = PageName;        App::Document* midDoc = pPartMapIter->second;        App::BimProduct* midBimProduct = dynamic_cast<App::BimProduct*>(midDoc);        if (!midBimProduct)            return;        App::BimPart* pPlotPart = dynamic_cast<App::BimPart*>(midBimProduct->addPartOrProduct(info));
        pPlotPart->setStatus(App::Document::SkipRecompute, true);        if (!pPlotPart)            return;        break;    }    pPartMapIter++;}/************************************************************************************/// 文件信息Base::FileInfo tfi(templateFilePath.toUtf8().constData()); // 判断文件是否存在,文件是否可读if (tfi.isReadable()) {     Gui::WaitCursor wc;    // 添加DrawPage对象,此处也可以是其它继承自DrawPage的类名称    App::DocumentObject* pObj1 = pDoc->addObject("PipeLine::DrawPage",PageName.c_str());     if (!pObj1)        return;     // 类型转化    PipeLine::DrawPage* pDrawPage = dynamic_cast<PipeLine::DrawPage*>(pObj1);    if (!pDrawPage)        return;    if (tfi.hasExtension("dxf")) {        // 添加DrawDXFTemplate对象        App::DocumentObject* pObj2 = pDoc->addObject("TechDraw::DrawDXFTemplate", TemplateName.c_str());         if (!pObj2)            return;        // 类型转化        TechDraw::DrawDXFTemplate* pDrawDXFTemplate = dynamic_cast<TechDraw::DrawDXFTemplate*>(pObj2);        // 设置模板路径        pDrawDXFTemplate->Template.setValue(templateFilePath.toUtf8().constData());         // 将DrawDXFTemplate加到pDrawPage中        pDrawPage->Template.setValue(pDrawDXFTemplate);             }
    PipeLine::DrawPage* fp = dynamic_cast<PipeLine::DrawPage*>(pDoc->getObject(PageName.c_str()));    if (!fp) {        throw Base::TypeError("找不到CmdTechDrawNewPagePick fp/n");    }    Gui::ViewProvider* vp = Gui::Application::Instance->getDocument(pDoc)->getViewProvider(fp);    PipeLineGui::ViewProviderPage* dvp = dynamic_cast<PipeLineGui::ViewProviderPage*>(vp);    if (dvp) {        // 页面展示        dvp->show();     }    else {        Base::Console().Log("信息 - 模板: %s 对于页面: %s 无法找到/n", PageName.c_str(), TemplateName.c_str());    }}else {    QMessageBox::critical(Gui::getMainWindow(),        qApp->translate("error", "No template"),        qApp->translate("error", "Template file is invalid"));}注意:接口defaultTemplate只能拼接固定的文件路径,如果需要使用defaultTemplate接口的话,那么目标文件必须放在指定的目录\data\Mod\TechDraw\Templates\中;接口getUniqueObjectName能确保名称具有唯一性,因为如果存在冲突,它将自动在字符串后面添加字符。
示意图如下所示:

在计算机图形学、CAD(计算机辅助设计)及相关领域中,非填充几何(Non-filled Geometry) 是指仅绘制图形的轮廓边界(如线条、曲线、边缘),而不对图形内部区域进行颜色、图案或纹理填充的几何图形。
我们通过调用loadDrawviewGeometryList 来加载几何图形列表视图。该接口函数共有1个类型为DrawViewGeometryListParam的参数,从而生成一个可显示的视图对象,以便在绘图界面中展示这些几何数据。其绘制图形的坐标系原点在图纸模板的中心,X轴和Y轴的正方向朝向和图纸模板的坐标系一致。
绘制几何图形的示例代码如下:
xxxxxxxxxx//示例代码//示例代码
//线段Base::LineSegment* line = new Base::LineSegment();//设置起始点和终止点line->setStartPoint(Base::Vector3d(0, 0, 0));line->setEndPoint(Base::Vector3d(200, 0, 0));//添加几何图形属性Base::GeometryAttribute attr;//颜色设置为红色attr.setColor(Base::Color(0, 0, 1));//线宽设置attr.setLineWidth(2.0);//设置线段类型为连续线(CONTINUOUS为非虚线)attr.setLineType(Base::DefineLineType::CONTINUOUS);//将配置好的属性绑定到线段对象上line->setAttribute(attr);//将之前创建的线段对象 line 包装成智能指针 pgeo,并添加到 geolist 中,便于批量加载图形std::vector<std::shared_ptr<Base::Geometry>> geolist;std::shared_ptr<Base::LineSegment> pgeo(line);geolist.push_back(pgeo);//几何参数DrawViewGeometryListParam param;//加载几何图形TechDraw::IDrawView* pview = loadIDrawviewGeometryList(nullptr, geolist, param);//设置图形在图纸的中心位置,图纸的左下角为原点(pagew为getPageWidth,pageH为getpageHeight)pview->setViewPosition(pageW / 2, pageH / 2);
//圆弧//构造一个圆弧,基于圆心,法向量,基准向量,半径,起始角度,终止角度//设置圆心Base::Vector3d centerpoint = Base::Vector3d(0, 0, 0);//所在平面法向量为z轴Base::Vector3d normal = Base::Vector3d(0, 0, 1);//所在平面基准角度为x轴Base::Vector3d refvec = Base::Vector3d(1, 0, 0);//半径double radius = 1000;//起始角度double startAngle = 0;//终止角度(弧度制)double endAngle = M_PI;Base::ArcofCircle* arc = new Base::ArcofCircle(centerpoint, normal, refvec, radius, startAngle, endAngle); //添加圆弧属性Base::GeometryAttribute attr;//颜色设置为蓝色attr.setColor(Base::Color(0, 0, 1));//线宽设置attr.setLineWidth(6.0);//设置线段类型为连续线(CONTINUOUS为非虚线)attr.setLineType(Base::DefineLineType::CONTINUOUS);//将配置好的属性绑定到圆弧对象上arc->setAttribute(attr);//将之前创建的圆弧对象 arc 包装成智能指针 pgeo,并添加到 geolist 中,便于批量加载图形std::vector<std::shared_ptr<Base::Geometry>> geolist;std::shared_ptr<Base::ArcofCircle> pgeo(arc);geolist.push_back(pgeo);// 几何参数DrawViewGeometryListParam param; // 加载几何图形TechDraw::IDrawView* pView= loadIDrawviewGeometryList(nullptr, geolist, param); //设置图形在图纸的中心位置pView->setViewPosition(pageW / 2, pageH / 2);
//圆Base::Circle* circle = new Base::Circle();//设置圆心circle->setCenterPoint(Base::Vector3d(0, 0, 0));//所在平面的法向量为z轴circle->setNormal(Base::Vector3d(0, 0, 1));//所在平面的基准角度为x轴circle->setRefVec(Base::Vector3d(1, 0, 0));//设置圆心circle->setRadius(1000);//添加几何图形属性Base::GeometryAttribute attr;//颜色设置为红色attr.setColor(Base::Color(1, 0, 0));//线宽设置attr.setLineWidth(2.0);//设置线段类型为连续线(CONTINUOUS为非虚线)attr.setLineType(Base::DefineLineType::CONTINUOUS);//将配置好的属性绑定到圆对象上circle->setAttribute(attr);
//将之前创建的圆对象 circle 包装成智能指针 pgeo,并添加到 geolist 中,便于批量加载图形std::vector<std::shared_ptr<Base::Geometry>> geolist;std::shared_ptr<Base::Circle> pgeo(circle);geolist.push_back(pgeo);//几何参数DrawViewGeometryListParam param;//加载几何图形TechDraw::IDrawView* pview = loadIDrawviewGeometryList(nullptr, geolist, param);//设置图形在图纸的中心位置pview->setViewPosition(pageW / 2, pageH / 2);
//椭圆弧Base::Vector3d centerpoint = Base::Vector3d(0, 0, 0);//所在平面法向量为z轴Base::Vector3d normal = Base::Vector3d(0, 0, 1);//主轴方向为x轴Base::Vector3d majorAxisDir(1, 0, 0); //主轴半径double majorRadius = 1000;//副轴半径double minorRadius = 100;//起始角度(弧度制)double startAngle = 30 * M_PI / 180;//终止角度(弧度制)double endAngle = 300 * M_PI/180;Base::ArcofEllipse* Ellarc = new Base::ArcofEllipse(centerpoint, majorAxisDir, majorRadius, minorRadius, startAngle, endAngle,false); Base::GeometryAttribute attr;//颜色设置为白色attr.setColor(Base::Color(1, 1, 1));//线宽设置attr.setLineWidth(6.0);//设置线段类型attr.setLineType(Base::DefineLineType::CONTINUOUS);//Ellarc->setMajorAxisDir(Base::Vector3d(1, 0, 0));//将配置好的属性绑定到圆弧对象上Ellarc->setAttribute(attr);//将之前创建的圆弧对象 arc 包装成智能指针 pgeo,并添加到 geolist 中,便于批量加载图形std::vector<std::shared_ptr<Base::Geometry>> geolist;std::shared_ptr<Base::ArcofEllipse> pgeo(Ellarc);geolist.push_back(pgeo);
DrawViewGeometryListParam param; TechDraw::IDrawView* pView = loadIDrawviewGeometryList(nullptr, geolist, param); pView->setViewPosition(pageW / 2, pageH / 2);
//椭圆Base::Ellipse* ellipse = new Base::Ellipse(); // 椭圆的中心点设置,(0,0,0)位置可以认为是在图纸的中心,绘制的为二维图形,所以Z轴填0ellipse->setCenterPoint(Base::Vector3d(0, 0, 0)); //设置法向量为z轴ellipse->setNormal(Base::Vector3d(0, 0, 1));// 椭圆长半轴长度ellipse->setMajorRadius(100); // 椭圆短半轴长度ellipse->setMinorRadius(50); ellipse->setMajorAxisDir(Base::Vector3d(0, 1, 0));Base::GeometryAttribute attr;//颜色设置为红色attr.setColor(Base::Color(1, 0, 0));attr.setLineWidth(6.0);attr.setLineType(Base::DefineLineType::CONTINUOUS);ellipse->setAttribute(attr);
//将之前创建的圆对象 circle 包装成智能指针 pgeo,并添加到 geolist 中,便于批量加载图形std::vector<std::shared_ptr<Base::Geometry>> geolist;std::shared_ptr<Base::Ellipse> pgeo(ellipse);geolist.push_back(pgeo);
DrawViewGeometryListParam param;TechDraw::IDrawView* pview = loadIDrawviewGeometryList(nullptr, geolist, param);pview->setViewPosition(pageW / 2, pageH / 2);
//打组// 线段Base::LineSegment* line = new Base::LineSegment(); // 起始点设置line->setStartPoint(Base::Vector3d(0, 0, 0)); //终止点设置 line->setEndPoint(Base::Vector3d(415, 415, 0));//圆弧Base::Vector3d centerpoint = Base::Vector3d(0, 0, 0);Base::Vector3d normal = Base::Vector3d(0, 0, 1);Base::Vector3d refvec = Base::Vector3d(1, 0, 0);//半径double radius = 1000;//起始角度double startAngle = 0;//终止角度(弧度制)double endAngle = M_PI;Base::ArcofCircle* arc = new Base::ArcofCircle(centerpoint, normal, refvec, radius, startAngle, endAngle);Base::Block* geo = new Base::Block(); // 将line, arc这两个几何图形打成一组geo->setGeometryList(std::vector<Base::Geometry*>{ line, arc}); //添加几何图形属性Base::GeometryAttribute attr;//颜色设置为红色attr.setColor(Base::Color(1, 0, 0));attr.setLineWidth(2.0);//设置线段类型为连续线(CONTINUOUS为非虚线)attr.setLineType(Base::DefineLineType::CONTINUOUS);geo->setAttribute(attr);
//将之前创建的圆对象 circle 包装成智能指针 pgeo,并添加到 geolist 中,便于批量加载图形std::vector<std::shared_ptr<Base::Geometry>> geolist;std::shared_ptr<Base::Block> pgeo(geo);geolist.push_back(pgeo);
DrawViewGeometryListParam param;TechDraw::IDrawView* pview = loadIDrawviewGeometryList(nullptr, geolist, param);pview->setViewPosition(pageW / 2, pageH / 2);
//多段线// 创建多段线对象Base::PolyLine* pline = new Base::PolyLine();Base::LineSegment* line = new Base::LineSegment();// 创建曲线段来构建多段线// 第一段:从(0,0,0)到(100,0,0)的直线std::shared_ptr<Base::LineSegment> line1 = std::make_shared<Base::LineSegment>();line1->setStartPoint(Base::Vector3d(0, 0, 0));line1->setEndPoint(Base::Vector3d(100, 0, 0));
// 第二段:从(100,0,0)到(100,100,0)的直线std::shared_ptr<Base::LineSegment> line2 = std::make_shared<Base::LineSegment>();line2->setStartPoint(Base::Vector3d(100, 0, 0));line2->setEndPoint(Base::Vector3d(100, 100, 0));
// 第三段:从(100,100,0)到(0,100,0)的直线std::shared_ptr<Base::LineSegment> line3 = std::make_shared<Base::LineSegment>();line3->setStartPoint(Base::Vector3d(100, 100, 0));line3->setEndPoint(Base::Vector3d(0, 100, 0));
// 第四段:从(0,100,0)到(0,0,0)的直线,形成一个矩形std::shared_ptr<Base::LineSegment> line4 = std::make_shared<Base::LineSegment>();line4->setStartPoint(Base::Vector3d(0, 100, 0));line4->setEndPoint(Base::Vector3d(0, 0, 0));
// 将曲线段添加到多段线std::vector<std::shared_ptr<Base::Curve>> curves;curves.push_back(line1);curves.push_back(line2);curves.push_back(line3);curves.push_back(line4);pline->setPolyline(curves);
// 设置多段线属性// 颜色设置为绿色Base::GeometryAttribute attr;attr.setColor(Base::Color(0, 1, 0));  attr.setLineWidth(3.0); attr.setLineType(Base::DefineLineType::ACAD_ISO07W100);  pline->setAttribute(attr);
// 将多段线对象包装成智能指针并添加到几何列表std::vector<std::shared_ptr<Base::Geometry>> geolist;std::shared_ptr<Base::PolyLine> pgeo(pline);geolist.push_back(pgeo);
// 加载几何图形到视图DrawViewGeometryListParam param;TechDraw::IDrawView* pview = loadIDrawviewGeometryList(nullptr, geolist, param);pview->setViewPosition(pageW / 2, pageH / 2);其绘制的示意图如下所示:
直线示意图:

圆弧示意图:

圆的示意图

椭圆弧示意图

椭圆示意图

打组示意图

多线段示意图

在计算机图形学和 CAD(计算机辅助设计)领域,填充几何(Filled Geometry) 指的是具有封闭边界且内部被填充特定颜色、图案或材质的二维几何图形。它与仅由线条构成的 “轮廓几何” 不同,填充几何强调边界内部的区域渲染,常用于表达实体区域、截面、标注等。
我们通过调用loadDrawviewGeometryList l来加载几何图形列表视图,首先需准备好待加载的几何对象列表,将直线、圆、椭圆等各类图形实例(需继承自 Base::Geometry 基类)通过智能指针存入 std::vector 容器,并确保已为每个对象设置好颜色、线宽等属性;接着配置 DrawViewGeometryListParam 类型的视图参数,可根据需求指定视图背景、缩放比例等全局属性;随后调用函数时,第一个参数传入父视图指针(为 nullptr 时创建新视图),第二个参数传入几何对象列表,第三个参数传入配置好的视图参数;函数执行后会返回一个 TechDraw::IDrawView*类型的视图指针,通过该指针可进一步调整视图位置、大小等属性,最终实现多个几何图形在同一视图中的统一显示与管理,适用于工程图纸绘制、复杂模型可视化等场景。
绘制填充几何的示例代码如下:
xxxxxxxxxx//示例代码// 1. 创建圆形对象(作为填充边界)Base::Circle* circle = new Base::Circle();// 圆心circle->setCenterPoint(Base::Vector3d(0, 0, 0));  // 法向量(z轴方向,确定平面)circle->setNormal(Base::Vector3d(0, 0, 1));      // 基准向量(x轴方向)circle->setRefVec(Base::Vector3d(1, 0, 0));      // 设置半径circle->setRadius(1000);                        
// 设置圆的轮廓属性(边界线)Base::GeometryAttribute circleAttr;// 白色轮廓circleAttr.setColor(Base::Color(0, 0, 0));       circleAttr.setLineWidth(100.0);circleAttr.setLineType(Base::DefineLineType::CONTINUOUS);circle->setAttribute(circleAttr);
// 2. 创建填充对象(Hatch)Base::Hatch* hatch = new Base::Hatch();hatch->setGeoList(std::vector<Base::Geometry*>{circle});
// 设置填充属性Base::GeometryAttribute hatchAttr;// 红色填充(点的颜色)hatchAttr.setColor(Base::Color(1, 0, 0));       hatch->setAttribute(hatchAttr);
// 3. 将圆和填充对象都添加到几何列表(确保边界和填充都能显示)std::vector<std::shared_ptr<Base::Geometry>> geolist; //添加圆形边界std::shared_ptr<Base::Circle> circleGeo(circle);geolist.push_back(circleGeo);// 添加填充std::shared_ptr<Base::Geometry> hatchGeo(hatch);geolist.push_back(hatchGeo);
// 4. 加载到视图DrawViewGeometryListParam param;TechDraw::IDrawView* pview = loadIDrawviewGeometryList(nullptr, geolist, param);pview->setViewPosition(pageW / 2, pageH / 2);绘制填充几何的示意图如下所示:

线性标注
线性标注是工程图中用于表示两个点之间直线距离的尺寸标注方式,可用于水平、垂直。下述是以垂直方向为例,编写的示例代码,如果需要计算水平方向距离,将initDimension(dimensionParam, "DistanceY")这个代码中的DistanceY改为DistanceX,以及调整一些相关的偏移属性。
我们通过调用loadIDimension 接口函数来加载线性标注,该接口函数主要功能是从模板或标注库中读取线性标注的样式(如箭头类型、文本格式、线宽等)和规则;
绘制线性标注的示例代码如下所示:
xxxxxxxxxx//示例代码
// 标注类型TechDraw::DrawViewDimensionParam dimensionParam; // 起始点位置设置,如果存在缩放比例,则需要乘上缩放系数Base::Vector3d startPot(10000 * Scale.getValue(), -10000 * Scale.getValue(), 0.0); // 终止点位置设置,如果存在缩放比例,则需要乘上缩放系数Base::Vector3d endPot(10500 * Scale.getValue(), -10500 * Scale.getValue(), 0); // 设置标注方式,水平(DistanceX)、垂直(DistanceY)dimensionParam.mDimType = "DistanceY"; // 标注文本与标注线之间的距离设置,仅在导出为DXF文件时才生效// dimensionParam.mTextToLineDistance = 0; // 起始点、终止点设置dimensionParam.mLinelist = std::vector<Base::Vector3d>{ startPot,endPot }; // 标注绘制起点偏移,偏移情况和mDimType类型关联,如果mDimType类型为水平方向,则只能设置Y方向偏移dimensionParam.mStartPotoffset = Base::Vector3d(0, 0, 0);  // 标注整体偏移,只有当mDimType为对齐方式时,该参数才生效// dimensionParam.mEntityOffset = Base::Vector3d(0,-100, 0); // 标注文本及标注线和被标注对象之间的距离设置dimensionParam.mDistance = 0; // 文本参数设置,例如此处的文本字体大小设置dimensionParam.mAttribute.mFontSize = mDimensionTextSizeInDxf.getValue(); // 加载标注loadIDimension(parent, dimensionParam); 对齐标注
对齐标注和线性标注没有太大的区别,对齐标注也是用于表示两个点之间直线距离的尺寸标注方式,但是,对齐标注可以标注任意方向。
对齐标注和线性标注及其相识,唯一的不同就是initDimension(dimensionParam, "Distance")这行代码,线性标注为DistanceX或者DistanceY,对齐标注为Distance。所以其示例代码可参考线性标注的代码。
对齐标注示意图如下所示:
直径、半径标注
直径标注和半径标注一般应用于圆,用于标识圆的直径和半径。
我们通过调用loadIRadiusOrDiameterDimension 来加载直径、半径标注。
绘制直径标注的示例代码如下:
xxxxxxxxxx//示例代码// 中心点设置,如果存在缩放比例,则需要乘上缩放系数Base::Vector3d center(10000 * Scale.getValue(), 10000 * Scale.getValue(), 0);// 直径标注绘制loadIRadiusOrDiameterDimension(nullptr, 30, 100, "Diameter", mDimensionTextSizeInDxf.getValue(), center);
// 半径标注绘制loadRadiusOrDiameterDimension(nullptr, 30, 100, "Radius", mDimensionTextSizeInDxf.getValue(), center); 直径标注示意图如下所示:

半径标注示意图如下所示:

角度标注一般应用在圆弧的角度和线之间的夹角。
我们通过调用loadIAngleDimension 加载角度标注。
其示例代码如下所示:
xxxxxxxxxx//示例代码// 中心点设置,如果存在缩放比例,则需要乘上缩放系数Base::Vector3d center(10000 * Scale.getValue(), 10000 * Scale.getValue(), 0); // 角度标注绘制TechDraw::DrawView* angleDimension = loadAngleDimension(nullptr, 30 * M_PI / 180, center, 200 * Scale.getValue()); 角度标注的示意图如下所示:
单行文本的绘制
在绘制单行文本的时候,通过调用IDrawPage里面loadIText接口函数来加载文本视图,该接口函数共4个参数,参数parentObj为跟随移动的视图对象;参数text为文本内容;参数type为绘制单行/多行文本;参数attr为结构体变量BaseAttribute,用于设置基础属性;
绘制一个单行文本的示例代码如下所示:
xxxxxxxxxx//绘制单行文本示例代码//绘制单行文本的具体接口函数/*IDrawView* loadIText(IDrawView* parentObj,const std::string text,bool type = true,const BaseAttribute& attr = BaseAttribute())*/
string text = "单行文本绘制测试"; string codeText;//对中文符号进行编码,防止显示乱码Base::FileInfo::gb2312ToUtf8(text, codeText);//设置单行或多行文本对象,true 单行, false:多行bool type = true; 
//文本属性BaseAttribute attr;//文本颜色设置,默认为黑色//注意:设置字体颜色不可以和背景颜色一致,否则系统会取反当前颜色,用于区分背景色attr.mTextColor = Base::Color(1, 1, 1); //设置文字大小attr.mFontSize = 300;//只有单行文本对象才可以设置文字的宽的因子,大于1,文字变宽,小于1,文字变窄attr.mFontWidthFactor = 1.0; 
//调用接口函数,加载文本IDrawView* drawText = loadIText(nullptr, codeText, type, attr); 绘制单行文本的示意图如下所示:

多行文本的绘制
在绘制多行文本的时候,也通过调用IDrawPage里面loadIText接口函数来加载文本视图,只不过和单行文本绘制的区别是,在传入参数type,需要设置为false,来表示进行绘制多行文本;通过检测文本中\n换行符来一行的结束,同时,要注意的是,只有多行文本对象才能正常响应\n换行符号。
绘制多行文本的示例代码如下所示:
xxxxxxxxxx//绘制多行文本的示例代码
string text = "多行文本绘制测试\n多行文本绘制测试\n多行文本绘制测试";string codeText;Base::FileInfo::gb2312ToUtf8(text, codeText);//设置多行文本对象bool type = false; 
//设置文本属性BaseAttribute attr; 
//文本颜色设置,默认为黑色attr.mTextColor = Base::Color(1, 1, 1);//设置文字大小attr.mFontSize = 300; 
//调用接口函数来绘制多行文本IDrawView* drawText = loadIText(nullptr, codeText, type, attr);绘制多行文本的示意图如下所示:

在工程图纸中表格具有规范和集中表达关键信息,如图纸名称、零部件清单、技术要求和修改记录等,这不仅是行业标准,还是提高效率的一大途径。表格有助于生产、施工、归档和信息检索,避免误解和错误,保障工程设计与实施的准确性与一致性,所以绘制表格也是图纸中非常重要一部分。
在BIMHome中,表格操作可以看成是对标Excel表格操作的,但是其操作上也有些不同,Excel表格主要在于图形界面操作,而BIMHome表格操作在于代码实现。
单元格合并及其文本信息设置
我们首先绘制一个3行6列的表格,我们用map<int, map<int, string>>来存储单元格文字,然后我们TableSpanInfo结构体来存储单元格的信息。需要注意的是,单元格行列的起始编号从0开始。
进行单元格合并的示例代码如下所示:
xxxxxxxxxx//单元格合并的示例代码map<int, map<int, string>> tabledata;
//1.该参数主要存储用于合并单元格,如果当前单元格不存在合并,可以不用填写信息;//2.有合并的单元格,文字位置必须是在左上角的那个单元格,否则会出现文字位置错误。std::vector<TechDraw::TableSpanInfo> spanData;
tabledata[0][0] = "第0行0列的文字";//0行0列的文字需要占据1个单元格spanData.push_back(TableSpanInfo(0, 0, 1, 1));
tabledata[0][1] = "第0行1列的文字";//注意:这里将第0行2列的单元格也给占据了,所以后面将避开第0行2列这个单元格//0行1列的文字需要占据2个列单元格spanData.push_back(TableSpanInfo(0, 1, 1, 2)); 
tabledata[0][3] = "第0行3列的文字";// 注意:这里将第1行3列的单元格也给占据了,所以后面将避开第1行3列这个单元格//0行3列的文字需要占据2个行单元格spanData.push_back(TableSpanInfo(0, 3, 2, 1)); 
tabledata[0][4] = "第0行4列的文字";//这里将第0行5列、第1行4列、第1行5列的单元格也给占据了,//所以后面将避开第0行5列、第1行4列、第1行5列这几个单元格//0行4列的文字需要占据2个行单元格和2个列单元格spanData.push_back(TableSpanInfo(0, 4, 2, 2));
tabledata[1][0] = "第1行0列的文字";//1行0列的文字需要占据1个单元格spanData.push_back(TableSpanInfo(1, 0, 1, 1)); 
tabledata[1][1] = "第1行1列的文字";//0行4列的文字需要占据1个单元格spanData.push_back(TableSpanInfo(1, 1, 1, 1)); tabledata[1][2] = "第1行2列的文字";//0行4列的文字需要占据1个单元格spanData.push_back(TableSpanInfo(1, 2, 1, 1)); 
tabledata[2][0] = "第2行0列的文字";//注意:这里将第2行1列也给占据了,所以后面将避开第2行1列这个单元格//2行0列的文字需要占据1个行单元格和2个列单元格spanData.push_back(TableSpanInfo(2, 0, 1, 2)); 
tabledata[2][2] = "第2行2列的文字";//注意:这里将第2行3列、第2行4列、第2行5列也给占据了,//所以后面将避开第2行3列、第2行4列、第2行5列这几个单元格//2行2列的文字需要占据1个行单元格和4个列单元格spanData.push_back(TableSpanInfo(2, 2, 1, 4)); 这里理想的实现效果如下所示:

单元格行列宽度、高度设置
在设置单元格的行列宽度、高度时,我们用map<std::string, std::string> 类型来存储行/列对应的高度/宽度。通过调用Base::FileInfo::getFontWidth来获取字体宽度,该接口函数有4个参数,参数fontFamily为字体名称,参数text为文本内容,参数fontheight为字体高度,参数widthFactor为宽度因子;通过调用getITextFontFamily接口函数来获得文字的字体名称;通过调用getITextWidthFactor接口函数来获得宽度因子。
设置行高或列宽的示例代码如下所示:
xxxxxxxxxx//设置行高或列宽的示例代码
//设置单元格文字map<int, map<int, string>> tabledata;
std::map<std::string, std::string> rowHeightMap, colWidthMap;//设置字体高度double fontHeight = 300; //这里将行高设置为文字的三倍高std::string rowHeight = std::to_string(3 * fontHeight); //设置每行的行高for (int i = 0; i < 3; i++) {     rowHeightMap[std::to_string(i)] = rowHeight; }// 计算文本字宽,注意编码转化std::string colWidth =to_string(Base::FileInfo::getFontWidth(QString::fromStdString(getTextFontFamily()),QString::fromLocal8Bit(tabledata[0][0].c_str()), fontHeight,getITextWidthFactor())); 
//设置每列的列宽for (int i = 0; i < 6; i++) {     colWidthMap[std::to_string(i)] =std::to_string(i) colWidth; } 
单元格的边框线显隐设置
在进行单元格的边框设置时,我们可以对每个单元格独立设置边框线的显隐,对于合并的单元格,则可以认为是一个比较大的单元格。边框线的显隐可通过TableCellFrameShowInfo结构体中的sFrameShowFlag枚举类来进行设置,具体的界面展示可以参考Excel的边框设置。
设置单元格的边框线显隐的示例代码如下所示:
xxxxxxxxxx//单元格边框设置std::vector<TechDraw::TableCellFrameShowInfo> frameshow;TableCellFrameShowInfo frameInfo;frameInfo.sRow = 0; frameInfo.sCol = 0;frameInfo.sRowCount = 1; frameInfo.sColCount = 1;
//0行0列的文字所占据1的个单元格显示外边框frameInfo.sFrameShowFlag = FrameShowFlag::OUT_FRAME;
frameshow.push_back(frameInfo);
frameInfo.sRow = 0; frameInfo.sCol = 1;frameInfo.sRowCount = 1; frameInfo.sColCount = 2;
//0行1列的文字所占据的2个列单元格显示外边框frameInfo.sFrameShowFlag = FrameShowFlag::OUT_FRAME; 
frameshow.push_back(frameInfo);
frameInfo.sRow = 0; frameInfo.sCol = 3;frameInfo.sRowCount = 2; frameInfo.sColCount = 1;
//0行3列的文字所占据的2个行单元格显示外边框frameInfo.sFrameShowFlag = FrameShowFlag::OUT_FRAME; 
frameshow.push_back(frameInfo);
frameInfo.sRow = 0; frameInfo.sCol = 4;frameInfo.sRowCount = 2; frameInfo.sColCount = 2;
//0行4列的文字所占据的2个行单元格和2个列单元格显示外边框frameInfo.sFrameShowFlag = FrameShowFlag::OUT_FRAME;
frameshow.push_back(frameInfo);
frameInfo.sRow = 1; frameInfo.sCol = 0;frameInfo.sRowCount = 1; frameInfo.sColCount = 1;
//1行0列的文字所占据的1个单元格显示外边框frameInfo.sFrameShowFlag = FrameShowFlag::OUT_FRAME; 
frameshow.push_back(frameInfo);
frameInfo.sRow = 1; frameInfo.sCol = 1;frameInfo.sRowCount = 1; frameInfo.sColCount = 1;//1行1列的文字所占据的1个单元格显示外边框frameInfo.sFrameShowFlag = FrameShowFlag::OUT_FRAME; 
frameshow.push_back(frameInfo);
frameInfo.sRow = 1; frameInfo.sCol = 2;frameInfo.sRowCount = 1; frameInfo.sColCount = 1;
//1行2列的文字所占据的1个单元格显示外边框frameInfo.sFrameShowFlag = FrameShowFlag::OUT_FRAME; 
frameshow.push_back(frameInfo);
frameInfo.sRow = 2; frameInfo.sCol = 0;frameInfo.sRowCount = 1; frameInfo.sColCount = 2;
//2行0列的文字所占据的2个列单元格显示外边框frameInfo.sFrameShowFlag = FrameShowFlag::OUT_FRAME; 
frameshow.push_back(frameInfo);
frameInfo.sRow = 2; frameInfo.sCol = 2;frameInfo.sRowCount = 1; frameInfo.sColCount = 4;
//2行2列的文字所占据的4个列单元格显示外边框frameInfo.sFrameShowFlag = FrameShowFlag::OUT_FRAME; 
frameshow.push_back(frameInfo);需要注意的是,边框显示逻辑流程是先选中frameInfo中的单元格,如果是合并的单元格,则选中的是合并后的那个大单元格,然后显示单元格的所有框线,最后,再按照frameInfo.sFrameShowFlag的进行显示。
单元格对齐方式设置
除了可以对每个单元格内设置边框,也可以对每个单元格的文字设置对齐方式,对于合并的单元格,则可以认为是一个比较大的单元格,具体的界面展示操作可以参考Excel的单元格对齐方式。
对齐方式一般分为水平和垂直对齐,水平对齐方式又分为左对齐、右对齐、左右居中对齐,垂直对齐方式又分为顶端对齐、底部对齐、上下居中对齐。BIMHome中利用CellAlignType的枚举方式来确定水平和垂直对齐方式。
设置单元格的对齐方式的示例代码如下所示:
xxxxxxxxxx//设置单元格对齐方式的示例代码
//水平对齐,默认为左对齐std::map<int, std::map<int, TechDraw::CellAlignType>> horAlgn;//垂直对齐,默认为顶端对齐std::map<int, std::map<int, TechDraw::CellAlignType>> veralign;
//0行0列的文字在水平对齐方式使用右对齐horAlgn[0][0] = CellAlignType::RIGHT; //0行0列的文字在垂直对齐方式使用顶端对齐veralign[0][0] = CellAlignType::TOP; 
//0行1列的文字在水平对齐方式使用右对齐horAlgn[0][1] = CellAlignType::RIGHT; //0行1列的文字在垂直对齐方式使用底部对齐veralign[0][1] = CellAlignType::BOTTOM;
//0行3列的文字在水平对齐方式使用右对齐horAlgn[0][3] = CellAlignType::RIGHT; //0行3列的文字在垂直对齐方式使用上下居中veralign[0][3] = CellAlignType::TBCENTER; 
//0行4列的文字在水平对齐方式使用左对齐horAlgn[0][4] = CellAlignType::LEFT; //0行4列的文字在垂直对齐方式使用顶端对齐veralign[0][4] = CellAlignType::TOP; 
//1行0列的文字在水平对齐方式使用左对齐horAlgn[1][0] = CellAlignType::LEFT; //1行0列的文字在垂直对齐方式使用底部对齐veralign[1][0] = CellAlignType::BOTTOM; 
//1行1列的文字在水平对齐方式使用左对齐horAlgn[1][1] = CellAlignType::LEFT; //1行1列的文字在垂直对齐方式使用上下居中veralign[1][1] = CellAlignType::TBCENTER; 
//1行2列的文字在水平对齐方式使用左右居中horAlgn[1][2] = CellAlignType::LRCENTER; //1行2列的文字在垂直对齐方式使用顶端对齐veralign[1][2] = CellAlignType::TOP; 
//2行0列的文字在水平对齐方式使用左右居中horAlgn[2][0] = CellAlignType::LRCENTER; //2行0列的文字在垂直对齐方式使用底部对齐veralign[2][0] = CellAlignType::BOTTOM; 
//2行2列的文字在水平对齐方式使用左右居中horAlgn[2][2] = CellAlignType::LRCENTER; //2行2列的文字在垂直对齐方式使用上下居中veralign[2][2] = CellAlignType::TBCENTER; 经过以上的步骤,我们可以通过调用IDrawPage提供的loadIOptimizeTable接口函数用于加载表格视图,该接口函数有1个类型为TabelParam的参数,用于设置表格数据。
绘制表格的示例代码如下所示:
xxxxxxxxxx//绘制表格的示例代码
TechDraw::TabelParam param;//用我们上面创建好的变量对param进行初始化param.mRowCount = 3;param.mColCount = 6;param.mSpanData = spanData;param.mFrameShow = frameshow;param.mTableData = tabledata;param.mRowHeight = rowHeightMap;param.mColWidth = colWidthMap;param.mHorAlign = horAlgn;param.mVerAlign = veralign;param.attr.mFontSize = fontHeight;
//调用IDrawPage中的loadIOptimizeTable方法进行绘制表格TechDraw::DrawView* pTable = loadOptimizeTable(param); 绘制的表格示意图如下所示:

投影是指将三维物体按照一定的规则投射到二维平面上,从而形成物体在特定方向上的视图。
在创建投影视图的时候,我们通过调用IDrawpage里面的loadIDrawViewPart接口函数来完成投影视图的创建投影,该接口函数共有1个参数为param,类型为DrawViewSectionParam结构体变量。
其中,需要注意的是结构体DrawViewSectionParam的参数mDirection为投影方向,Base::Vector3d(0, 1, 0)的意思为向Y轴正方向投影;
而结构体DrawViewSectionParam的参数mXDirection可以理解为投影旋转控制,通过设置旋转的方向向量来旋转投影。 例如,Base::Vector3d(-1, 0, 0)改为Base::Vector3d(1,0, 0),其意思为X轴旋转180°,投影也旋转180°,其示意图如下所示:

创建投影的示例代码如下所示:
xxxxxxxxxx//创建投影的示例代码
//这里我们获得一个隧洞对象作为演示PipeLine::SubsurfaceTunnel* pTunnel = getSubsurfaceTunnelObj();
vector<App::DocumentObject*> shapes;pTunnel->getObjects(shapes);
//将DocumenObject类型转换为IDocumentObject类型vector<App::IDocumentObject*> ishapes;for (auto shape : shapes){    ishapes.push_back(shape);}//参数声明TechDraw::DrawViewSectionParam SectionParam = TechDraw::DrawViewSectionParam(); SectionParam.mPartShape = ishapes;SectionParam.mSectionShape = ishapes;SectionParam.mDirection = Base::Vector3d(0, 1, 0); // 投影方向,指向屏幕外的轴和方向设置SectionParam.mXDirection = Base::Vector3d(-1, 0, 0); // 投影旋转控制,指向屏幕右边的轴和方向
//这里我们暂时不设置填充信息TechDraw::SectionHatchInfo hatchInfo;//填充信息SectionParam.mHatchInfo = hatchInfo; //填充数据
//调用接口函数,创建投影视图TechDraw::IDrawView* plateformDBView = loadIDrawViewPart(SectionParam); 投影的示意图如下所示:

剖面投影是通过一个假想的剖切平面将一个三维物体切开,然后将切开后剩余部分按照一定的规则投射到二维平面上,所得到的二维视图。通过调用IDrawPage里提供的loadIDrawViewSection接口函数来绘制剖面投影,该接口函数共有1个参数param,类型为DrawViewSectionParam结构体变量。
其中mXDirection和mDirection可参考3.2.5.1里面的解释。
绘制剖面投影的示例代码如下所示:
xxxxxxxxxx//绘制剖面投影的示例代码
//这里同样获得一个隧洞对象作为演示PipeLine::SubsurfaceTunnel* pTunnel = getSubsurfaceTunnelObj();vector<App::DocumentObject*> shapes;pTunnel->getObjects(shapes);
vector<App::IDocumentObject*> ishapes;for (auto shape : shapes){    ishapes.push_back(shape);}
//参数声明TechDraw::DrawViewSectionParam SectionParam = TechDraw::DrawViewSectionParam();//剖切投影对象SectionParam.mPartShape = ishapes; //填充对象SectionParam.mSectionShape = ishapes;//剖切方向,沿着Z轴正方向切割SectionParam.mSectionNormal = Base::Vector3d(0, 0, 1);//第一次剖切位置SectionParam.mSectionOrigin = Base::Vector3d(0, 0, 10);//投影方向,指向屏幕外的轴和方向设置SectionParam.mDirection = Base::Vector3d(0, 0, 1); //投影旋转控制,指向屏幕右边的轴和方向SectionParam.mXDirection = Base::Vector3d(1, 0, 0);
//这里暂不设置填充数据TechDraw::SectionHatchInfo hatchInfo; SectionParam.mHatchInfo = hatchInfo; // 填充数据// TechDraw::SectionAreaInfo areaInfo;// areaInfo.sFlag = true; // 是否剖切两次,默认为false// areaInfo.sSectionOrigin = Base::Vector3d(0, 0, cutminz); // 第二次剖切位置// SectionParam.mAreaInfo = areaInfo; // 第二次剖切数据
// 调用接口函数,加载剖面投影TechDraw::IDrawView* plateformDBView = loadIDrawViewSection(SectionParam);其实意图如下所示:

为了简化IDrawPage中接口函数的参数,我们定义了DrawPageParameterDefine文件,该文件将IDrawPage中接口函数的参数抽取出来封装成结构体,,这样无论是以后的参数传入还是参数修改都提供了很大的便携。
该结构体主要用来设置边界属性,该结构体包含的变量如下所示:
| 类型 | 变量名 | 描述 | 
|---|---|---|
| double | sLeft | 左边界值 | 
| double | sRight | 右边界值 | 
| double | sTop | 上边界值 | 
| double | sBottom | 下边界值 | 
同样,为了简化IDrawView中接口函数的参数,我们还定义了DrawViewParameterDefine文件,该文件将IDrawView中接口函数的参数抽取出来封装成结构体,这样无论是以后的参数传入还是参数修改都提供了很大的便携。
该结构体主要用于存储图纸中字体的相关信息,其所包含的变量如下所示:
| 类型 | 变量名 | 描述 | 
|---|---|---|
| Base::Color | mTextColor | 文本颜色 | 
| double | mFontSize | 文本字体大小 | 
| FontFamily | mFontFamily | 文本字体 | 
| double | mFontWidthFactor | 字体宽度因子 | 
| bool | mFixedfontSize | 字体大小固定标志 | 
该结构体主要用于存储线的相关信息,其所包含的变量如下所示:
| 类型 | 变量名 | 描述 | 
|---|---|---|
| Base::DefineLineType | mLineType | 线型 | 
| Base::Color | mLineColor | 线颜色 | 
| bool | mLineWidthShow | 线宽显示标志位 | 
| double | mLineWidth | 线宽 | 
该结构体用于设置气球标注的基本属性,其所包含的变量如下所示:
| 类型 | 变量名 | 描述 | 
|---|---|---|
| string | mLabel | 气球标注文字主文字 | 
| DefineLeaderType | mLeaderType | 引线方向 | 
| DefineBubbleType | mBubbleShape | 气泡形状 | 
| Base::Vector3d | mBasePt | 定点 | 
| double | mRotation | 旋转角度 | 
| vector<std::string> | mAttachedLabel | 线上附加文字 | 
| double | mLeaderLineOffsetX | 引线x偏移量 | 
| double | mLeaderLineOffsetY | 引线y偏移量 | 
| vector<Base::Vector3d> | mIntervals | 多引线间隔 | 
| FontAttribute | mLeaderFontAttr | 引线文本属性 | 
| LineAttribute | mLeaderLineAttr | 引线属性 | 
| FontAttribute | mIndexFontAttr | 索引文本属性 | 
| LineAttribute | mIndexLineAttr | 索引线属性 | 
| double | mShapeIndexLength | 标注形状大小,圆形时代表半径、菱形时代表高度、矩形时代表边长 | 
| bool | mScenePoint | 气泡标注的起点是否基于场景坐标 | 
| bool | isInkLengthZero | 气球标注没有附加文字时,引线上面一段的长度是否为0 | 
该结构体主要用于设置标注的基本属性,其所包含的变量如下所示:
| 类型 | 变量名 | 描述 | 
|---|---|---|
| DimensionType | mDimType | 标注类型 | 
| vector<Base::Vector3d> | mLinelist | 距离标注 | 
| Base::Vector3d | mStartPotoffset | 标注起点偏移量(x左负右正 y上负下正) | 
| Base::Vector3d | mEntityOffset | 标注整体偏移量(平移) | 
| double | mDistance | 标注文本label与标注起点终点线间距 | 
| double | mLabelOffset | 标注写文本的横线与标注位置连线之间的距离 | 
| double | mTextToLineDistance | 标注文本与文本线距离 | 
| double | mAngle | 标注旋转角度 | 
| double | mCustormDistance | 标注线文本内容(-1为默认的计算值,非-1为传入的自定义值) | 
| Base::Color | mDimHorizonLineColor | 水平标注线颜色 | 
| Base::Color | mDimVerticalLineColor | 垂直标注线颜色 | 
| FontAttribute | mFontAttr | 标注文本属性 | 
| LineAttribute | mLineAttr | 引线属性 | 
| double | mLeadLineAngle | 引线角度(角度值) | 
该结构体主要用来设置填充的相关属性,其所包含的变量如下所示:
| 类型 | 变量名 | 描述 | 
|---|---|---|
| map<std::string, std::string> | sSectionFaceHatch | 填充区域名称和填充类型对应map | 
| bool | sfillIfSectionSourceIsEmpty | 是否填充标记 | 
| bool | sDrawSectionEdge | 填充区域外边框是否显示 | 
| bool | sFuseBeforeCut | 传入填充区域是否融合 | 
| double | sDefaultScaleInView | qt填充比例 | 
| double | sDefaultScaleInDxf | 导出dxf填充比例 | 
| char* | sHatchType | 填充类型是pat还是svg | 
该结构体主要用于存储工程图纸的剖面区域的相关信息,其所包含的变量如下所示:
| 类型 | 变量名 | 描述 | 
|---|---|---|
| bool | sFlag | 是否是区域 | 
| Base::Vector3d | sSectionOrigin | 区域Origin | 
该结构体主要用来存储工程图纸中剖面视图的额外信息,其所包含的变量如下所示:
| 类型 | 变量名 | 描述 | 
|---|---|---|
| bool | sFlag | 是否有额外的shape | 
| string | sLabel | shape对应documentObject的Label | 
| int | sLineType | 线型 | 
该结构体主要用来设置剖面图的相关属性,该结构体所包含的变量如下所示:
| 类型 | 变量名 | 描述 | 
|---|---|---|
| string | mName | 视图名称 | 
| vector<App::IDocumentObject*> | mPartShape | 剖切或投影对象 | 
| Base::Vector3d | mDirection | 面向剖切或投影方向的反方向 | 
| Base::Vector3d | mXDirection | 面向剖切或投影方向,右手指向 | 
| LineAttribute | mAttribute | 基础属性 | 
| Base::Vector3d | mSectionNormal | 剖切方向 | 
| Base::Vector3d | mSectionOrigin | 剖切位置 | 
| vector<App::IDocumentObject*> | mSectionShape | 填充对象 | 
| SectionHatchInfo | mHatchInfo | 填充数据 | 
| SectionAreaInfo | mAreaInfo | 剖切区域数据 | 
| SectionExtraInfo | mExtraInfo | 独立需要绘制的对象 | 
| bool | mCustomcutflag | 自定义剖切标志位 | 
| vector<App::IDocumentObject*> | mCustomCutObjecVec | 自定义剖切对象列表 | 
struct DrawViewSketchTemplateParam
该结构体主要用于存储和配置工程图纸中草图模板视图的相关参数,其所包含的变量如下所示:
| 类型 | 变量名 | 描述 | 
|---|---|---|
| float | mAmplify | 放大倍数 | 
| int | mLoadTextFlag | 文本解析方式(0-不加载text 1-加载text 2-只加载text编号 | 
| map<std::string, std::string> | mBalloonIndexMap | 模版中气球标注索引修改对应map | 
| string | name | 模版显示名称 | 
| string | className | 模版类名,支持草图模版及其子类 | 
struct DrawViewGeometryListParam
该结构体主要用于存储和管理与工程图纸视图几何列表的相关信息,其所包含的变量如下所示:
| 类型 | 变量名 | 描述 | 
|---|---|---|
| double | mAmplify | 放大倍数 | 
| string | mName | 几何列表的名称 | 
该结构体主要用来存储表格中合并单元格的信息,其所包含的示例代码如下所示:
| 类型 | 变量名 | 描述 | 
|---|---|---|
| int | row | 哪一行 | 
| int | col | 哪一列 | 
| int | rowcount | 合并的行数 | 
| int | colcount | 合并的列数 | 
| double | colwidth | 合并后的单元格宽度 | 
| double | rowheight | 合并之后的单元格高度 | 
| string | Spanbstr | 合并单元格中显示的文本内容(默认是空格) | 
该结构体主要用于存储所选中表格区域的信息,其所包含的变量如下所示:
| 类型 | 变量名 | 描述 | 
|---|---|---|
| int | sRow | 起始行 | 
| int | sCol | 起始列 | 
| int | sRowCount | 所选中行数 | 
| int | sColCount | 所选中列数 | 
| FrameShowFlag | sFrameShowFlag | 边框样式 | 
该结构体主要用于设置表格参数,其所包含的变量如下所示:
| 类型 | 变量名 | 描述 | 
|---|---|---|
| int | mRowCount | 行数 | 
| int | mColCount | 列数 | 
| std::map<int, std::map<int, std::string>> | mTableData | 文字数据 | 
| std::map<std::string, std::string> | mRowHeight | 行高 | 
| std::map<std::string, std::string> | mColWidth | 列宽 | 
| std::vector<TechDraw::TableSpanInfo> | mSpanData | 单元格属性 | 
| std::vector<TableCellFrameShowInfo> | mFrameShow | 单元格边框设置 | 
| std::map<int, std::map<int, TechDraw::CellAlignType>> | mHorAlign | 水平对齐方式 | 
| std::map<int, std::map<int, TechDraw::CellAlignType>> | mVerAlign | 垂直对齐方式 | 
| FontAttribute | mFontAttr | 文本属性 | 
| LineAttribute | mLineAttr | 线条属性 | 
该结构体主要用来存储工程图纸中 标注文本的相关信息,其所包含的变量如下所示:
| 类型 | 变量名 | 描述 | 
|---|---|---|
| string | mText | 文本 | 
| LineFlag | mLineFlag | 下划线显示标志位 | 
| bool | mType | true:比例图注 false:普通文本图注 | 
| double | mTextToFirstLineDistance | 文本与第一条下划线的距离 | 
| double | mTwoLineDistance | 两条下划线间距 | 
| string | mExpress | 与父节点相对位置表达式(coe1a+coe2b+coe3) | 
| FontAttribute | mFontAttr | 文本属性 | 
| LineAttribute | mFirstLineAttr | 第一条下划线的属性 | 
| LineAttribute | mSecondLineAttr | 第二条下划线的属性 | 
该枚举主要定义的是字体族,其所包含的枚举常量如下所示:
| 枚举常量 | 描述 | 
|---|---|
| TSSDENG | CAD显示钢筋符号字体 | 
该枚举类主要定义线的类型,其所包含的的枚举常量如下所示:
| 枚举常量 | 描述 | 
|---|---|
| CONTINUOUS | 实线 | 
| CENTER | 长空短相间隔 | 
| ACAD_ISO02W100 | 虚短线 | 
| ACAD_ISO04W100 | 点划线 | 
| ACAD_ISO05W100 | 点点划线 | 
| ACAD_ISO07W100 | 虚点线 | 
| DOUBLE_BROKEN | 双折线 | 
| ZIGZAGLINE | 波浪线 | 
该枚举类主要定义标注引线与文本的相对位置关系,其所包含的枚举常量如下所示:
| 枚举常量 | 描述 | 
|---|---|
| TextInRightTopOfArrow | 右上 | 
| TextInRightBottomOfArrow | 右下 | 
| TextInLeftTopOfArrow | 左上 | 
| TextInLeftBottomOfArrow | 左下 | 
该枚举类主要定义气球标注类型,其所包含的枚举常量如下所示:
| 枚举常量 | 描述 | 
|---|---|
| Circular | 圆圈 | 
| Line | 直线 | 
| Diamond | 菱形 | 
| Rectangle | 矩形 | 
| Triangle | 三角形 | 
该枚举类主要定义尺寸标注类型,其所包含的枚举常量如下所示:
| 枚举常量 | 描述 | 
|---|---|
| DISTANCEX | 水平长度标注 | 
| DISTANCEY | 垂直长度标注 | 
| DISTANCE | 对齐长度标注 | 
| RADIUS | 半径标注 | 
| DIAMETER | 直径标注 | 
| ANGLEDIMENSION | 角度标注 | 
该枚举主要定义边框的显示区域,其所包含的枚举常量如下所示:
| 枚举常量 | 描述 | 
|---|---|
| NO_FRAME | 无边框 | 
| ALL_FRAME | 所有边框 | 
| OUT_FRAME | 外围边框 | 
| LEFT_FRAME | 左侧边框 | 
| RIGHT_FRAME | 右侧边框 | 
| TOP_FRAME | 顶部边框 | 
| BOTTOM_FRAME | 底部边框 | 
该枚举类主要定义图注的相关参数,其所包含的枚举常量如下所示:
| 枚举常量 | 描述 | 
|---|---|
| NONE | 没有下划线 | 
| ONE | 一条下划线,单线段 | 
| TWO | 两条下划线,第一条是多段线,第二条是单线段 | 
该枚举类主要定义对齐方式的相关参数,其所包含的枚举常量如下所示:
| 枚举常量 | 描述 | 
|---|---|
| TOP | 顶端对齐 | 
| BOTTOM | 底部对齐 | 
| LEFT | 左对齐 | 
| RIGHT | 右对齐 | 
| LRCENTER | 左右居中 | 
| TBCENTER | 上下居中 | 
该类IViewProvider是一个抽象接口类,提供了视图相关功能的接口,主要用于管理视图提供者的属性和行为,包括属性访问、可见性控制、颜色和纹理设置等。
该类提供的接口函数有getPropertyAccessor(获取属性访问器)、getAttachObject(void)(获取附加对象)、setPointColor(设置点颜色)、setFaceTextures(设置面纹理)等等。获得所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
该类IMainWindow是主窗口类,通过该类提供的接口函数可以将MDIView对象添加/删除到主窗口,同时,还可以获取/设置当前活动的MDIView对象等等。
该类提供的接口函数有addWindow(添加IMIDView对象)、removeWindow(移除IMIDView对象)、 activeIWindow(获取当前活动 MDIView 对象)、setActiveWindow(设置当前活动 MDIView 对象)等等。获得所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
将MIDView对象添加到主窗口中的示例代码可以参考4.3节:
主窗口的示意图如下所示:

该类IMDIView是多文档视图类。通过该类提供的接口函数可以创建多文档视图以及可以设置多文档视图的属性。
该类提供的接口函数有create(创建一个新的多文档界面视图)、getDocument(获取当前视图所关联的文档)、widget(获取MDIView的窗口对象)、getIGuiDocument(获取MDIView的文档对象)等等。获得所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
创建一个IMDIView对象并将该对象添加到主窗口的示例代码如下所示:
xxxxxxxxxx//示例代码Gui::IDocument* GuiIDocument;
IMDIView* mdiView = IMDIView::create(GuiIDocument, nullptr, MAINWINDOW);mdiView->setCustomWindowTitle("name");mdiView->setCenterWidget(widget);
Gui::IMainWindow::get()->addWindow(mdiView);创建一个IMDIView并将该对象添加到主窗口的示意图

该类IMenuItem是创建菜单类。通过该类提供的接口函数可以创建菜单按钮对象、获取菜单项命令名称、查找具体指定名称的菜单项等。
该类提供的接口函数有create(创建一个新的菜单按钮对象)、setCommand(设置菜单项的命令名称)、findItem(查找具有指定名称的菜单项)等等。获得所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
创建一个菜单按钮对象的示例代码如下:
xxxxxxxxxx//示例代码
//获取编辑节点,我们要在编辑节点前插入新的create节点Gui::IMenuItem* Edit = pItem->findItem("&Edit");
//创建新节点Gui::IMenuItem * MyCommandItem = Gui::IMenuItem::create();MyCommandItem->setCommand("Create");
//"MyCommand"该值应与创建命令里面的getCommandID保持一致*MyCommandItem << "MyCommand";
//调用该类提供的接口函数完成插入pItem->insertItem(Edit, MyCommandItem);创建的按钮示意图如下所示:

该类ITaskDialog是对话框基类,继承自QObject类。通过该类提供的接口函数,可以设置对话框的属性,包括设置/获取对话框中按钮位置、获取对话框的内容等等。
该类提供的接口函数有setButtonPosition(设置对话框中按钮位置)、buttonPosition(获取对话框中按钮的位置)、canClose(检查对话框是否可以关闭)等等。获得所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
创建一个ITaskDialog的示例代码如下所示:
xxxxxxxxxx//示例代码//MyTaskDialog.h
class MyTaskDialog : public Gui::ITaskDialog{    Q_OBJECTpublic:    MyTaskDialog(QWidget* parent = nullptr);    ~MyTaskDialog();        //重写基类接口函数    QDialogButtonBox::StandardButtons getStandardButtons() const;    bool accept();    bool reject();    void helpRequested();    bool needsFullSpace(){ return false; }
    QString userName() const { return m_lineEdit->text(); }
private:    //定义一个widget控件和文本框    QWidget*       m_contentWidget = nullptr;    QLineEdit*     m_lineEdit      = nullptr;};xxxxxxxxxx//示例代码//MyTaskDialog.cpp
MyTaskDialog::MyTaskDialog(QWidget* parent){    //创建内容    m_contentWidget = new QWidget(parent);    auto* lay = new QVBoxLayout(m_contentWidget);
    lay->addWidget(new QLabel("请输入一些内容"));    m_lineEdit = new QLineEdit;    lay->addWidget(m_lineEdit);    lay->addStretch();
    //把内容交给框架    addContext(m_contentWidget);
    //设置一些属性    setButtonPosition(South);              // 按钮放在下方    setEscapeButtonEnabled(true);          // 允许 Esc 关闭    setAutoCloseOnTransactionChange(true); // 事务变更时自动关闭}
QDialogButtonBox::StandardButtons MyTaskDialog::getStandardButtons() const{    // 设置按钮    return QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Help;}
bool MyTaskDialog::accept(){    if (m_lineEdit->text().trimmed().isEmpty()) {        m_lineEdit->setPlaceholderText("不能为空!");        return false; // 不允许关闭    }    qDebug("对话框接受", qPrintable(m_lineEdit->text()));    return true;}
bool MyTaskDialog::reject(){    qDebug("对话框取消");    return true;}
void MyTaskDialog::helpRequested(){    qDebug("已点击帮助");}
该类IQRibbon是创建标签类,目前该类只有一个接口函数setTabIndexForWorkbench,通过该接口函数可以设置工作台的选项卡索引。如果想了解该接口的详细信息,点击获取更多跳转到API文档。
设置工作台的选项卡索引的示例代码如下所示:
xxxxxxxxxx//示例代码Gui::IQRibbon::setTabIndexForWorkbench(Gui::getMainWindow(), 4);
该类ITreeWidgetObservationDelegate是左侧视图树事件监听代理类,主要负责判断树上Item是否改变以及双击树上Item触发事件等等。
该类提供的接口函数有itemSelectionChanged(树上item是否改变)、itemDoubleClicked(双击树上item)等等。获得所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
使用该类的示例代码如下所示:
xxxxxxxxxx//示例代码//TreeObserverDelegate.h
class TreeObserverDelegate : public Gui::ITreeWidgetObservationDelegate{public:    // ITreeWidgetObservationDelegate 接口实现    void itemSelectionChanged(ITreeWidget* pTreeWidget, std::vector<ITreeItem*> itemVec);    void itemDoubleClicked(ITreeWidget* pTreeWidget, ITreeItem* item);        //新增接口    void onItemSelected(Gui::ITreeItem* pTreeItem);    void onItemAdded(Gui::ITreeItem* pTreeItem);     void onItemRemoved(Gui::ITreeItem* pTreeItem);};xxxxxxxxxx//示例代码//TreeObserverDelegate.cpp
void TreeObserverDelegate::itemSelectionChanged(ITreeWidget* pTreeWidget, std::vector<ITreeItem*> itemVec){    std::cout << "Selection changed. Selected items: " << itemVec.size() << std::endl;    for (auto item : itemVec) {        std::cout << " - Item type: " << item->getItemType() << std::endl;         //获取关联的文档对象        if (auto docObj = pTreeWidget->getDocumentObject(item)) {            std::cout << "   Document object: " << docObj->getName() << std::endl;        }    }}
void TreeObserverDelegate::itemDoubleClicked(ITreeWidget* pTreeWidget, ITreeItem* item){       //双击时获取文档信息    if (auto doc = pTreeWidget->getGuiDocument(item)) {        std::cout << "Associated document: " << doc->getDocumentName() << std::endl;    }}
void TreeObserverDelegate::onItemSelected(Gui::ITreeItem* pTreeItem){    std::cout << "Type:" << pTreeItem->getItemType() << std::endl;}
void TreeObserverDelegate::onItemAdded(Gui::ITreeItem* pTreeItem){    std::cout << "Type:" << pTreeItem->getItemType() << std::endl;}
void TreeObserverDelegate::onItemRemoved(Gui::ITreeItem* pTreeItem){    std::cout << "Type:" << pTreeItem->getItemType() << std::endl;}
该类ITreeItem是视图树Item接口类。主要通过该类来获取树上节点的接口类型。
该类提供了接口函数getItemType(获得树上接口类型)。获得该接口信息请参见API接口文档,点击获取更多跳转到API 文档。
使用该类的示例代码如下所示:
xxxxxxxxxx//示例代码//MyTreeItem.h
class MyTreeItem : public Gui::ITreeItem{public:    explicit MyTreeItem(Gui::TreeItemType type,                         Gui::IDocument* doc = nullptr,                        App::IDocumentObject* obj = nullptr);        //ITreeItem 接口实现    Gui::TreeItemType getItemType();        //自定义方法    void setDocument(Gui::IDocument* doc) { m_document = doc; }    void setDocumentObject(App::IDocumentObject* obj) { m_docObject = obj; }    Gui::IDocument* getDocument() const { return m_document; }    App::IDocumentObject* getDocumentObject() const { return m_docObject; }
private:    Gui::TreeItemType m_type;    Gui::IDocument* m_document;    App::IDocumentObject* m_docObject;};
xxxxxxxxxx//示例代码//MyTreeItem.cpp
MyTreeItem::MyTreeItem(Gui::TreeItemType type, Gui::IDocument* doc,App::IDocumentObject* obj): m_type(type), m_document(doc), m_docObject(obj){}
MyTreeItem::getItemType(){     return m_type;}
该类ITreeWidget是左侧视图树接口类。主要用于管理树上控件。
该类提供了接口函数addObservationDelegate(添加观察者委托)、removeObservationDelegate(移除观察者委托)、getGuiDocument(获取传入的 TreeItem 对应的文档)等等。获得所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
使用该类的示例代码如下所示:
xxxxxxxxxx//示例代码//MyTreeWidget.h
class MyTreeWidget : public Gui::ITreeWidget{public:    MyTreeWidget();    ~MyTreeWidget();        // 重写ITreeWidget 接口    void addObservationDelegate(Gui::ITreeWidgetObservationDelegate* pObservation);    void removeObservationDelegate(Gui::ITreeWidgetObservationDelegate* pObservation);    Gui::IDocument* getGuiDocument(Gui::ITreeItem* pTreeItem);    App::IDocumentObject* getDocumentObject(Gui::ITreeItem* pTreeItem);        // 模拟树形控件操作    void selectItem(Gui::ITreeItem* item);    void addItem(std::unique_ptr<Gui::ITreeItem> item);    void removeItem(Gui::ITreeItem* item);
private:    std::vector<TreeObserverDelegate*> m_observers;    std::vector<std::unique_ptr<Gui::ITreeItem>> m_items;    Gui::ITreeItem* m_currentItem = nullptr;};
xxxxxxxxxx//MyTreeWidget.cpp
MyTreeWidget::MyTreeWidget(){    // 初始化测试数据    m_items.emplace_back(new MyTreeItem(Gui::ProductItemType));    m_items.emplace_back(new MyTreeItem(Gui::PartItemType));    m_items.emplace_back(new MyTreeItem(Gui::ObjectItemType));}
MyTreeWidget::~MyTreeWidget(){    // 清除所有观察者    m_observers.clear();}
void MyTreeWidget::addObservationDelegate(Gui::ITreeWidgetObservationDelegate* pObservation){    if (pObservation && std::find(m_observers.begin(), m_observers.end(), pObservation) == m_observers.end()) {        m_observers.push_back(pObservation);    }}
void MyTreeWidget::removeObservationDelegate(Gui::ITreeWidgetObservationDelegate* pObservation){    auto it = std::find(m_observers.begin(), m_observers.end(), pObservation);    if (it != m_observers.end()) {        m_observers.erase(it);    }}
Gui::IDocument* MyTreeWidget::getGuiDocument(Gui::ITreeItem* pTreeItem){    if (auto item = dynamic_cast<TreeItemImpl*>(pTreeItem)) {        return item->getDocument();    }    return nullptr;}
App::IDocumentObject* MyTreeWidget::getDocumentObject(Gui::ITreeItem* pTreeItem){    if (auto item = dynamic_cast<TreeItemImpl*>(pTreeItem)) {        return item->getDocumentObject();    }    return nullptr;}
void MyTreeWidget::selectItem(Gui::ITreeItem* item){    m_currentItem = item;    // 通知所有观察者    for (auto observer : m_observers) {        observer->onItemSelected(item);    }}
void MyTreeWidget::addItem(std::unique_ptr<Gui::ITreeItem> item){    m_items.push_back(std::move(item));    // 通知所有观察者    for (auto observer : m_observers) {        observer->onItemAdded(m_items.back().get());    }}
void MyTreeWidget::removeItem(Gui::ITreeItem* item){    auto it = std::find_if(m_items.begin(), m_items.end(),         [item](const std::unique_ptr<Gui::ITreeItem>& i) { return i.get() == item; });        if (it != m_items.end()) {        // 通知所有观察者        for (auto observer : m_observers) {            observer->onItemRemoved(item);        }        m_items.erase(it);    }}
该类ITreePanel是获取当前视图树接口类。通过该类可以获取树上的控件等等。
该类提供的接口函数有get(获取 ITreePanel 的单例对象)、getCurrentTreeWidget(获取当前活动的树形控件)等等。获得所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
使用该类的示例代码如下所示:
xxxxxxxxxx//示例代码//MyTreePanel.h
class MyTreePanel : public Gui::ITreePanel{public:    static MyTreePanel& instance();        // ITreePanel 接口实现    Gui::ITreeWidget* getCurrentTreeWidget(){ return &m_treeWidget; }        // 自定义方法    MyTreeWidget& getTreeWidget() { return m_treeWidget; }
private:    MyTreePanel();    ~MyTreePanel();        MyTreeWidget m_treeWidget;};
xxxxxxxxxx//示例代码//MyTreePanel.cpp
MyTreePanel& MyTreePanel::instance(){    static MyTreePanel theInstance;    return theInstance;}
该类IWorkBench是抽象类,子类需重写该类的方法。通过该类,可以去创建一个工作台。
该类提供的接口函数有getName(获取工作台名称)、getMenuText(获取按钮的文本)、setupMenuBar(设置工作台的工作栏)、setupContextMenu(设置右键菜单)等等。获得所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
创建工作台的示例代码和示意图可以参考 第一章 1.2 工作台的创建。
该类ISelection是选择管理主接口类。该类作为单例模式实现,统一管理文档、视图、树控件等选择操作。
该类提供的接口函数有get(返回ISelection的单例实例)、addSelectionGate(添加新的选择过滤器)、rmvSelectionGate(移除当前活动的选择过滤器)等等。获得所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
使用该类的示例代码如下所示:
xxxxxxxxxx//示例代码
//获取选择系统单例ISelection& selection = ISelection::get();
//向文档"MyDocument"中添加选择项//参数说明:"MyDocument"(文档名称);"123"(对象ID);"line"(子对象名称);"10.5f, 20.3f, 5.0f"(选择点的坐标);“true”(清除预选择)bool success = selection.addToSelection("MyDocument",123,"line",10.5f, 20.3f, 5.0f,true);
if(success) {    std::cout << "成功添加选择项" << std::endl;}
//获取当前选择//参数说明:"MyDocument"(指定文档);"ResolveMode::NewStyleElemen"(使用新式解析);"false"(获取所有选择项)std::vector<SelectedObj> selected = selection.getFromSelection("MyDocument",ResolveMode::NewStyleElement,false);
// 清除选择selection.clearSelection("MyDocument"); // 只清除"MyDocument"中的选择
该类ISelectionChanges是选择变更时间类。该类主要用于封装和传递选择状态变更信息。当用户进行任何选择时,系统会创建该类的实例来通知观察者。
该类提供的接口函数有getMsgType(获得消息类型)、getSubType(获得消息来源)、getObjectId(获得对象ID)、getX(获得X坐标)等等。获得所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
使用该类的示例代码如下所示:
xxxxxxxxxx//示例代码//创建一个添加选择项的消息ISelectionChanges addMsg(    ISelectionChanges::AddSelection,  //消息类型    "Document1",                      //文档名    101,                              //对象ID    "Face5",                          //子元素名    "Part::Box",                      //对象类型    10.5f, 20.3f, 5.0f,               //坐标XYZ    ISelectionChanges::MsgSource::TreeView //消息来源);
//使用消息中的数据std::cout << "操作类型: " << addMsg.getMsgType() <<          << "文档: " << addMsg.getDocName() <<          << "对象ID: " << addMsg.getObjectId() <<           << "子元素: " << (addMsg.getSubName() ? addMsg.getSubName() : "无") <<          << "坐标:" << addMsg.getX() << ", " << addMsg.getY() << ", " << addMsg.getZ() << std::endl;
该类ISelectionFilterGate表示选择过滤类。该类主要用于在图形用户界面中控制哪些对象可以被选择或交互。它的核心作用是提供一种机制来筛选/过滤用户的选择操作,确保只有符合特定条件的对象才能被选中。
该类提供的接口函数有allow(判断是否允许对文档对象执行操作)。获得该接口信息请参见API接口文档,点击获取更多跳转到API 文档。
使用该类的示例代码如下所示:
xxxxxxxxxx//示例代码//实现一个只允许选择特定类型对象的过滤器class TypeFilterGate : public ISelectionFilterGate {public:    explicit TypeFilterGate(const std::string& allowedType):m_allowedType(allowedType) {}        bool allow(App::IDocument* pDocument,App::IDocumentObject* pObject, const char* pSubElementName) override {        // 获取对象类型        const char* objType = pObject->getTypeId().getName();                // 只允许选择指定类型的对象        if(m_allowedType == objType) {            return true;        }                // 不允许选择其他类型        std::cout << "阻止选择类型: " << objType << std::endl;        return false;    }
private:    std::string m_allowedType;};
// 使用过滤器void setupFilter() {    // 创建只允许选择"Part::Box"类型的过滤器    TypeFilterGate* boxFilter = new TypeFilterGate("Part::Box");        // 添加到选择系统    ISelection::get().addSelectionGate(boxFilter);        // 当不需要时移除过滤器    // ISelection::get().rmvSelectionGate();}
该类ISelectionObserver是允许观察选择变化类。该类通过订阅机制发出的变更事件。实现业务逻辑和UI交互。
该类提供的接口函数有blockSelection(阻塞/解阻塞选择消息)、attachSelection(附加到发布-订阅系统)、detachSelection(从发布-订阅系统分离)等等。获得所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
使用该类的示例代码如下所示:
xxxxxxxxxx//示例代码class DetailedSelectionObserver : public ISelectionObserver {public:    DetailedSelectionObserver()         : ISelectionObserver(true, IResolveMode::NewStyleElement) {        std::cout << "观察者已创建并附加到选择系统" << std::endl;    }        ~DetailedSelectionObserver() override {        detachSelection();        std::cout << "观察者已销毁" << std::endl;    }        void onSelectionChanged(const ISelectionChanges& msg) override {        //先检查是否阻塞        if(isSelectionBlocked()) {            return;        }                //根据消息类型处理        switch(msg.getMsgType()) {            case ISelectionChanges::AddSelection:                handleAddSelection(msg);                break;            case ISelectionChanges::RmvSelection:                handleRemoveSelection(msg);                break;            case ISelectionChanges::ClrSelection:                std::cout << "选择已清除 - 文档: " << (msg.getDocName() ? msg.getDocName() : "所有文档")<< std::endl;                break;            //其他消息类型...            default:                break;        }    }
private:    void handleAddSelection(const ISelectionChanges& msg) {        std::cout << "添加选择项 - 文档: " << msg.getDocName()<< ", 对象ID: " << msg.getObjectId();                if(msg.getSubName()) {            std::cout << ", 子元素: " << msg.getSubName();        }                if(msg.getTypeName()) {            std::cout << ", 类型: " << msg.getTypeName();        }                std::cout << ", 位置: (" << msg.getX() << ", " << msg.getY() << ", " << msg.getZ() << ")"<< std::endl;    }        void handleRemoveSelection(const ISelectionChanges& msg) {        std::cout << "移除选择项 - 文档: " << msg.getDocName()<< ", 对象ID: " << msg.getObjectId();                if(msg.getSubName()) {            std::cout << ", 子元素: " << msg.getSubName();        }                std::cout << std::endl;    }};
// 使用观察者void setupObserver() {    //创建观察者实例    DetailedSelectionObserver* observer = new DetailedSelectionObserver();        //临时阻塞选择消息    observer->blockSelection(true);    //执行一些不希望触发回调的操作...    observer->blockSelection(false);        //当不需要时可以分离观察者    //observer->detachSelection();    }
该类IControl是界面控制的类,采用单例设计模式,负责对话框的显示、视图控制以及操作权限验证等功能。
该类提供的接口有instance(实现一个单例模式)、showDialog(显示对话框)、isAllowedAlterDocument(查询是否允许修改文档)、accept(处理任务面板的接受操作)等等。获得所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
该类的示例代码如下所示:
xxxxxxxxxx//示例代码class IControlDemo {public:    void startEditing() {        //获取控制实例        IControl& control = IControl::instance();                //检查权限        if (!control.isAllowedAlterDocument() ||             !control.isAllowedAlterView()) {            showPermissionError();            return;        }                //显示模型视图        control.showModelView();                //创建并显示编辑对话框        m_editDialog = new MyTaskDialog();        control.showDialog(m_editDialog);                //连接信号槽        connect(m_editDialog, &MyTaskEditDialog::accepted,                 this, &IControlDemo::onEditAccepted);        connect(m_editDialog, &MyTaskDialog::rejected,                this, &IControlDemo::onEditRejected);    }    private slots:    void onEditAccepted() {        //处理接受操作        //applyChanges();自定义操作        IControl::instance().closeDialog();    }        void onEditRejected() {        //处理拒绝操作        //discardChanges();自定义操作        IControl::instance().closeDialog();    }    private:    ITaskDialog* m_editDialog = nullptr;};
该类ISnapProcessedBase处理事件类,通过该类提供的接口函数可以对鼠标、鼠标移动、键盘事件等做出相应的处理。
该类提供的接口函数有mouseClickEvent(鼠标点击事件)、mouseMoveEvent(鼠标移动事件)、keyBoardEvent(键盘事件)等等。获得所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
使用该类的示例代码如下所示:
xxxxxxxxxx//示例代码//SnapProcessor.h
class SnapProcessor : public PlatformUI::ISnapProcessedBase{public:    //ISnapProcessedBase 接口实现    void mouseClickEvent(const PlatformUI::MouseKeyType mouseType, const PlatformUI::UpDownType eventType, const Base::Vector3d currentPt);        void mouseMoveEvent(Base::Vector3d snapPos);        void keyBoardEvent(const PlatformUI::KeyBoardType keyType, const PlatformUI::UpDownType eventType, const Base::Vector3d currentPt);
    //自定义方法    void setSnapEnabled(bool enabled) { m_snapEnabled = enabled; }    bool isSnapEnabled() const { return m_snapEnabled; }
private:    bool m_snapEnabled = true;};
xxxxxxxxxx//示例代码//SnapProcessor.cpp
void SnapProcessor::mouseClickEvent(const PlatformUI::MouseKeyType mouseType,const PlatformUI::UpDownType eventType,const Base::Vector3d currentPt){    std::string button = (mouseType == PlatformUI::MouseKeyType::Left) ? "Left" : "Right";    std::string action = (eventType == PlatformUI::UpDownType::Down) ? "Pressed" : "Released";        std::cout << "Mouse " << button << " button " << action               << " at (" << currentPt.x << ", " << currentPt.y << ", " << currentPt.z << ")"              << std::endl;}
void SnapProcessor::mouseMoveEvent(Base::Vector3d snapPos){    if (m_snapEnabled) {        std::cout << "点击位置:("                   << snapPos.x << ", " << snapPos.y << ", " << snapPos.z << ")"                  << std::endl;    }}
void SnapProcessor::keyBoardEvent(const PlatformUI::KeyBoardType keyType,const PlatformUI::UpDownType eventType,const Base::Vector3d currentPt){    std::string action = (eventType == PlatformUI::UpDownType::Down) ? "Pressed" : "Released";        std::cout << "Key " << static_cast<int>(keyType) << " " << action              << " at (" << currentPt.x << ", " << currentPt.y << ", " << currentPt.z << ")"              << std::endl;        //这里设置按空格键切换捕捉状态    if (keyType == PlatformUI::KeyBoardType::SPACE && eventType == PlatformUI::UpDownType::Down) {        m_snapEnabled = !m_snapEnabled;        std::cout << "Snap " << (m_snapEnabled ? "enabled" : "disabled") << std::endl;    }}
该类ISnapper是自定义捕捉类,通过该类提供的接口函数可以设置捕捉的模式、捕捉的范围、拾取的范围等。
该类提供的接口函数setSnapMode(设置捕捉模式)、setSnapRange(设置捕捉范围)、setPickRange(设置拾取范围)等等。获得所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
使用该类的示例代码如下所示:
xxxxxxxxxx//示例代码//MySnapper.h
class MySnapper : public PlatformUI::ISnapper{public:    MySnapper(PlatformUI::ISnapProcessedBase* process,PlatformUI::SnapMode mode,double range,double pickRange);        ~MySnapper() override;        //ISnapper 接口实现    void setSnapMode(PlatformUI::SnapMode mode, bool enabled);    bool isSnapModeEnabled(PlatformUI::SnapMode mode) const;        void setSnapRange(double range);    double getSnapRange() const;        void setPickRange(double range);    double getPickRange() const;        void processMouseMove(const double x, const double y, bool bPicked, const Base::Vector3d& newpos);    void processMouseClick(const PlatformUI::MouseKeyType mouseType, const PlatformUI::UpDownType eventType);    void processKeyBoard(const PlatformUI::KeyBoardType keyType, const PlatformUI::UpDownType eventType);
private:    //定义处理变量    PlatformUI::ISnapProcessedBase* m_processor;    //定义触发模式变量    PlatformUI::SnapMode m_snapMode;        //定义捕捉、拾取范围    double m_snapRange;    double m_pickRange;    Base::Vector3d m_lastPosition;};
xxxxxxxxxx//示例代码//MySnapper.cpp
MySnapper::MySnapper(PlatformUI::ISnapProcessedBase* process, PlatformUI::SnapMode mode, double range, double pickRange)    :m_processor(process),m_snapMode(mode),m_snapRange(range),m_pickRange(pickRange){}
MySnapper::~MySnapper(){    //清理资源}
void MySnapper::setSnapMode(PlatformUI::SnapMode mode, bool enabled){    if (enabled) {        m_snapMode = static_cast<PlatformUI::SnapMode>(static_cast<int>(m_snapMode) | static_cast<int>(mode));    } else {        m_snapMode = static_cast<PlatformUI::SnapMode>(static_cast<int>(m_snapMode) & ~static_cast<int>(mode));    }}
bool MySnapper::isSnapModeEnabled(PlatformUI::SnapMode mode) const{    return (static_cast<int>(m_snapMode) & static_cast<int>(mode)) != 0;}
void MySnapper::setSnapRange(double range){    m_snapRange = range;}
double MySnapper::getSnapRange() const{    return m_snapRange;}
void MySnapper::setPickRange(double range){    m_pickRange = range;}
double MySnapper::getPickRange() const{    return m_pickRange;}
void MySnapper::processMouseMove(const double x, const double y, bool bPicked, const Base::Vector3d& newpos){    m_lastPosition = newpos;        // 定义简单的捕捉逻辑    Base::Vector3d snappedPos = newpos;    if (isSnapModeEnabled(PlatformUI::SnapMode::Endpoint)) {        //模拟端点捕捉        snappedPos.x = std::round(snappedPos.x / 10.0) * 10.0;        snappedPos.y = std::round(snappedPos.y / 10.0) * 10.0;    }        if (isSnapModeEnabled(PlatformUI::SnapMode::Midpoint)) {        //模拟中点捕捉        if (std::fmod(snappedPos.x, 20.0) > 10.0) {            snappedPos.x = std::floor(snappedPos.x / 20.0) * 20.0 + 10.0;        } else {            snappedPos.x = std::floor(snappedPos.x / 20.0) * 20.0;        }    }        //通知处理器    if (m_processor) {        m_processor->mouseMoveEvent(snappedPos);    }}
void MySnapper::processMouseClick(const PlatformUI::MouseKeyType mouseType, const PlatformUI::UpDownType eventType){    if (m_processor) {        m_processor->mouseClickEvent(mouseType, eventType, m_lastPosition);    }}
void MySnapper::processKeyBoard(const PlatformUI::KeyBoardType keyType, const PlatformUI::UpDownType eventType){    if (m_processor) {        m_processor->keyBoardEvent(keyType, eventType, m_lastPosition);    }}
该类SnapHandle创建并初始化一个捕捉句柄对象,用于在交互过程中管理特定捕捉模式的行为,包括:记录负责实际捕捉逻辑的处理者、设置当前生效的捕捉模式、指定触发捕捉的有效半径、指定对象拾取半径。
该类一个构造函数和析构函数,用于创建捕捉句柄对象和销毁捕捉句柄对象。了解构造函数和析构函数信息请参见API接口文档,点击获取更多跳转到API 文档。
使用该类的示例代码如下所示:
xxxxxxxxxx//示例代码//SnapHandle.h
class SnapHandle : public PlatformUI::ISnapHandle{public:    SnapHandle(PlatformUI::ISnapProcessedBase* process,PlatformUI::SnapMode mode = PlatformUI::SnapMode::All, double range = 10, double pickRange = 50);        ~SnapHandle() override;        //获取内部 snapper    PlatformUI::ISnapper* getSnapper() const { return mISnapper; }
private:    std::unique_ptr<PlatformUI::ISnapper> m_snapper;};
xxxxxxxxxx//示例代码//SnapHandle.cpp
SnapHandle::SnapHandle(PlatformUI::ISnapProcessedBase* process,                       PlatformUI::SnapMode mode,                       double range,                       double pickRange){    m_snapper.reset(PlatformUI::ISnapper::Create(process, mode, range, pickRange));    mISnapper = m_snapper.get();}
SnapHandle::~SnapHandle(){    //自动清理 m_snapper}
该类ICommand是抽象类,子类需重写该类的方法。通过该类,可以去创建一个命令。
该类提供的接口函数有getAppModule(获取命令所在模块)、getGroup(获取命令所在分组)、activated(触发命令并在必要时显示警告消息框)、getCommandID(获取命令ID)等等。获得所有的接口信息请参见API接口文档,点击获取更多跳转到API 文档。
创建命令的示例代码和示意图可以参考 第一章 1.3 命令创建。
? 布尔运算失效
A : 布尔运算要使用实体Solid;
? 二维曲线求交点失败
A: 二维曲线相交必须要转成三维曲线(必须确定所在平面)才可以相交;