Skip to content
Gains Summary
Main Navigation 首页 / Home
C++ 编程 / C++ Programming
系统与高性能 / Systems & Performance
Web 开发 / Web Development
人工智能 / Artificial Intelligence
工业软件 / Industrial Software
其他内容 / Other Topics
C++ 编程 / C++系统与性能 / SystemsWeb 开发 / Web人工智能 / AI工业软件 / Industrial

外观

Sidebar Navigation

← 工业软件 / Industrial Software

SAM 平台开发 / SAM Platform Development

1. SAM 二次开发总览与证据分级 / SAM Secondary Development Overview and Evidence Levels

2. 从 P0 到 P5:SAM 插件界面开发流程 / SAM Plugin Interface Development from P0 to P5

3. PYD 注册、Model Fragment 与 Part Fragment / PYD Registration, Model Fragments, and Part Fragments

4. Python 2 SAM API:已验证接口与失败清单 / Verified Python 2 SAM APIs and Known Failures

5. C++ SAM SDK:模型、网格与 ODB 接口 / C++ SAM SDK APIs for Models, Meshes, and ODB Data

6. SAM 参数化构件建模:从二维轮廓到三维网格 / SAM Parametric Component Modeling from 2D Profiles to 3D Meshes

7. Agent 接入 SAM:插件架构、工具注册与安全边界 / Integrating AI Agents into SAM with Plugins, Tools, and Safety Boundaries

8. SAM API 验证工作流:禁止猜测与七级验收门 / A Seven-Gate SAM API Validation Workflow Without Guesswork

9. 真实案例、当前边界与后续路线 / Validated Cases, Current Boundaries, and the Development Roadmap

10. SAM 二次开发指南:架构总览与系列索引 / SAM Secondary Development Architecture and Series Index

11. SAM GUI、Toolset 与交互类 API / SAM GUI, Toolset, and Interaction APIs

12. SAM 命令桥、Python 与 PYD 扩展 API / SAM Command Bridge, Python, and PYD Extension APIs

13. SAM 数据模型、Part 与 Mesh API / SAM Data Models, Parts, and Mesh APIs

14. SAM 场景、显示表示与渲染 API / SAM Scene, Display Representation, and Rendering APIs

15. SAM 插件编译、部署与故障排查 / Building, Deploying, and Troubleshooting SAM Plugins

16. SAM 二次开发旧入口 / Legacy Entry for SAM Secondary Development

17. SAM 二次开发知识体系 / SAM Secondary Development Knowledge System

本页目录

从 P0 到 P5:SAM 插件界面开发流程 / SAM Plugin Interface Development from P0 to P5 ​

📅 创建时间:2026-07-23
🏷️ 标签:#SAM #Qt插件 #Toolset #P0到P5
📚 前置知识:00-overview-and-evidence
📖 系列导航:总目录 · 上一篇:00-overview-and-evidence · 下一篇:02-pyd-registration-and-fragments


第2部分:从 P0 到 P5 的插件开发流程 ​

D:\wx702\OpenOLTranSim-main\7231 将开发过程拆成了清晰的阶段:

text
P0 原始骨架
  ↓
P1 编辑菜单栏
  ↓
P2 菜单信号槽
  ↓
P3 生成参数界面
  ↓
P4 调用模块接口
  ↓
P5 调用 Part 核心数据接口
1
2
3
4
5
6
7
8
9
10
11

2.1 P0:建立双工程 ​

顶层工程至少包含:

text
src/
├── Example1/          # 输出 Example1.pyd
└── Example1Toolset/   # 输出 SAM.Pre.Example1Toolset.dll
1
2
3

顶层 CMake 要区分:

cmake
set(LIBS_SAM_ROOT "D:/Program Files/SAM")
set(LIBS_SAMSDK_ROOT "D:/SAMDevelopment/SAMSDK")
set(LIBS_PYTHON_ROOT ${LIBS_SAM_ROOT}/Python27)
1
2
3

7231 手册文字同时出现 Visual C++ 2017 和 VS2015 x64,示例 Qt 路径为 VC14。实际工程必须以老师提供的完整 SDK ABI 为准,不能仅凭手册中的单一版本文字自行选择工具链。

2.2 P1:创建并注册菜单 ​

Toolset GUI 继承:

cpp
class Example1ToolsetGui : public SAMToolsetGui,
                           public omiSingleton<Example1ToolsetGui>
{
    // ...
};
1
2
3
4
5

菜单创建:

cpp
SAMMenu* menu = new SAMMenu(this, tr("&Test"));
SAMMenuCommand* action = new SAMMenuCommand(
    this, menu, tr("&Example"));
menu->addAction(action);
1
2
3
4

Toolset 插件继承 SAMToolsetGuiInterface,并通过 Qt 元数据实现自动发现:

cpp
class Example1ToolsetPlugin : public QObject,
                              public SAMToolsetGuiInterface
{
    Q_OBJECT
    Q_PLUGIN_METADATA(IID SAMToolsetGuiPlugin_iid)
    Q_INTERFACES(SAMToolsetGuiInterface)
};
1
2
3
4
5
6
7

向 Part 模块注册:

cpp
SAMApp* app = SAMApp::getSAMApp();
SAMMainWindow* window = app->getSAMMainWindow();

if (window->getModule("Part")) {
    window->getModule("Part")->registerToolset(
        &Example1ToolsetGui::Instance(),
        GUI_IN_MENUBAR | GUI_IN_TOOLBAR);
}
1
2
3
4
5
6
7
8

2.3 P2:把菜单动作连接到功能 ​

cpp
connect(action,
        SIGNAL(triggered(bool)),
        this,
        SLOT(createUI()));
1
2
3
4

2.4 P3:显示参数界面 ​

cpp
void Example1ToolsetGui::createUI()
{
    Example1Form* form = new Example1Form(this);
    form->onCmdActivate(this, 0, 0);
}
1
2
3
4
5

界面通常使用:

text
SAMForm
SAMDataDialog
QLineEdit / QComboBox / QValidator
edtGSelectNodeWidget / 其他 SAM 视口选择控件
1
2
3
4

2.5 P4:GUI 调用 Python 模块接口 ​

模块方法注册:

cpp
static omuInterfaceObj::methodTable methods[] = {
    {"calcArea",
     (omuInterfaceObj::methodFunc)&Example1PytModule::calcArea},
    {0, 0}
};
1
2
3
4
5

参数读取:

cpp
omuPrimitive* Example1PytModule::calcArea(omuArguments& args)
{
    double length = 0.0;
    double width = 0.0;

    args.Begin();
    args.Get(length, "Length");
    args.Get(width, "Width");
    args.End();

    return new omuPrimNumber(length * width);
}
1
2
3
4
5
6
7
8
9
10
11
12

这里必须注意 7231 的资料存在一处源码与手册差异:

  • SAM二次开发手册.doc 给出的完整实现是 return new omuPrimNumber(area);;
  • P4/P5/Example1PytModule.cpp 的随附教学源码最后却写成 return nullptr;。

后者只能完成“参数进入 C++ 方法”的演示,Python 端拿不到面积结果。需要返回数值时,应采用手册中的 omuPrimNumber 写法,并在目标 SAM 版本中做一次实际调用验证。

GUI 调用:

cpp
omuArguments args(2);
args.Put(length, "Length");
args.Put(width, "Width");

omuMethodCall call("Example1", "calcArea", args);

cmdGCommandDeliveryRole::Instance().SendCommand("import Example1");
cmdGCommandDeliveryRole::Instance().SendCommand(call);
1
2
3
4
5
6
7
8

2.6 P5:把方法挂载到当前 Part ​

继承 ptsKPartFragment:

cpp
class SAMExample1Fragment : public ptsKPartFragment
{
public:
    omuPrimitive* getNodeInfo(omuArguments& args);
};
1
2
3
4
5

注册方法:

cpp
static omuInterfaceObj::methodTable methods[] = {
    {"getNodeInfo",
     (omuInterfaceObj::methodFunc)&SAMExample1Fragment::getNodeInfo},
    {0, 0}
};

SAMExample1Fragment::SAMExample1Fragment()
    : ptsKPartFragment()
{
    omuInterfaceObj::DescribeType(
        "SAMExample1Fragment", methods, members);
}
1
2
3
4
5
6
7
8
9
10
11
12

Python 2 侧就可以调用:

python
import Example1
mdb.models['Model-1'].parts['Part-1'].getNodeInfo(NodeID=1)
1
2

P5 的 getNodeInfo 同样只是接口挂载骨架:源码取得坐标后仍然 return nullptr,而且把 NodeID 直接交给 GetNodalCoord,其语义更接近网格内部索引。正式工具若接收用户看到的节点标签,应采用吊耳源码已经示范的转换:

cpp
int meshIndex = nodeData.GetMeshNodeIndex(userLabel);
nodeData.GetNodalCoord(meshIndex, x, y, z);
1
2

因此,P5 能证明 Part Fragment 的注册与访问路径,但不能直接证明其示例返回值和节点标签语义已经生产可用。


最后更新于:

Pager
上一篇1. SAM 二次开发总览与证据分级 / SAM Secondary Development Overview and Evidence Levels
下一篇3. PYD 注册、Model Fragment 与 Part Fragment / PYD Registration, Model Fragments, and Part Fragments

持续记录,持续成长

Copyright © Tidenflow