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

本页目录

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

本篇解释 mdb.models['Model-1'].parts['Part-1'] 背后的 C++ 数据结构,以及插件如何安全读取 Part、Feature、Node 和 Element。

1. 数据层次 ​

text
basBasis
  `-- basMdb
        `-- basModelMap
              `-- basNewModel
                    +-- ptoKPartRepository
                    |     `-- ptoKPart
                    |           `-- ftrFeatureList
                    |                 `-- bmeMesh / omeMesh
                    |                       +-- bmeNodeData
                    |                       +-- bmeElementData
                    |                       `-- bmeElementClass
                    +-- Materials / Sections
                    +-- Steps / Loads / BCs
                    +-- Interactions
                    `-- Assembly / Sketch / Output Requests
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

Python 中的 mdb 是该底层模型通过 Python 接口包装后的用户视图,不代表底层由 Python 字典直接保存。

2. 数据库根对象 ​

2.1 basBasis ​

进程级数据库入口/单例。

cpp
static basBasis* Instance();
static void Finalize();
const basMdb& Fetch();
const basMdb& GetMdb();
void Replace(const basMdb& root);
void UncheckedReplace(const basMdb& root);
void NewMdb();
void OpenMdb(const QString& fileName);
void CloseMdb();
void OpenDdb(const QString& fileName);
void SaveDdb();
void SaveDdbAs(const QString& fileName);
void CloseDdb();
void CleanDdbCows();
1
2
3
4
5
6
7
8
9
10
11
12
13
14

读取当前数据库通常从 basBasis::Instance()->GetMdb() 开始。

2.2 basMdb ​

当前 MDB 根对象。

cpp
basModelMap& GetModels();
const basModelMap& ConstGetModels() const;
void SetModels(const basModelMap&);
mdlRepository& GetJobs();
const mdlRepository& ConstGetJobs() const;
basUserData& GetUserData();
const basUserData& ConstGetUserData() const;
double ConstGetModCount() const;
void UpdateModCount();
int GetLastModelID() const;
void IncrementModelIDCounter();
1
2
3
4
5
6
7
8
9
10
11

2.3 basModelMap ​

由宏生成:

cpp
MDLIDREPOSITORY_DECL(QString, basNewModel, basModelMap);
1

逻辑含义是 QString 模型名 -> basNewModel。它基于 SAM 仓库模板,不应直接假定为 std::map。

3. Model ​

3.1 basNewModel ​

表示单个分析模型,内部以 Repository/Extension 保存不同业务对象。

cpp
mdlRepository& GetPart();
const mdlRepository& ConstGetPart() const;
mdlRepository& GetSketch();
mdlRepository& GetMaterials();
mdlRepository& GetSections();
mdlRepository& GetSteps();
mdlRepository& GetLoads();
mdlRepository& GetBCs();
mdlRepository& GetInteractions();
mdlRepository& GetInteractionProperties();
mdlRepository& GetFieldOutputs();
mdlRepository& GetHistoryOutputs();
mdlExtension& GetAssy();
const mdlExtension& ConstGetAssy() const;
void Rewire(const QString& modelName);
void RewireMissingExtensions(const QString& modelName);
void AssertValid() const;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

主要子仓库包括:

  • Part、Sketch、Assembly;
  • Material、Section、Profile;
  • Step、Load、Boundary Condition;
  • Interaction、Interaction Property;
  • Field/History Output Request;
  • Constraint、Connector、Amplitude;
  • Remeshing Rule、Analytical Field 等。

读取时优先使用 ConstGet*(),只有明确修改模型且理解 SAM 的 COW、回调和再生机制时才使用可写接口。

4. Part 与 Feature ​

4.1 ptoKPartRepository ​

由仓库宏生成,逻辑映射为:

text
QString Part 名 -> ptoKPart
1

ptoKPartReposRewireCB() 用于模型或 Part 重命名后的引用重连。

4.2 ptoKPart ​

Part 的核心 C++ 对象,继承 ftrPrimaryObject。

cpp
ptoKPart(bdoTheory theory, const QString& name);
ftrPrimaryObject* Copy() const;
ptoKPart* CopyCompress(const QString& newName) const;
bdoSpace GetSpace() const;
bdoAnalysis GetAnalysis() const;
bdoTheory GetTheory() const;
bool HasTwistDof() const;
void SetAnalysis(bdoAnalysis);
void SetSpace(bdoSpace);
void SetTwistDof(bool);
void SetStartNodeLabel(uint);
void SetStartElemLabel(uint);
bool Regenerate(basNewModel&);
void Restore();
void Backup();
void UpdateScene();
bool IsLocked() const;
bool Lock();
bool UnLock(...);
bool IsValid() const;
void SetName(const QString&);
QString GetColor() const;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

Part 不只是节点和单元数组,还包含 Feature 历史、属性分配、几何、网格、锁定和再生状态。

4.3 ftrFeatureList ​

管理 Part 的 Feature 历史和求值结果。

cpp
int NmrFeatures() const;
cowListInt GetIds() const;
cowListInt GetUserVisibleIds() const;
ftrFeature* Get(int featureId) const;
const ftrFeature* ConstGet(int featureId) const;
bool FeatureExists(const QString&) const;
bool IsOutOfDate() const;
bool Suppress(int id, bool user = true);
bool Resume(int id);
bool Delete(int featureId);
bool Regenerate(const cowListInt& featureIds);
bool RegenerateFeatureAndAppend(ftrFeature*);
bool MeshExists(uint instanceId) const;
const bmeMesh* ConstGetMesh(uint instanceId) const;
bmeMesh* GetMesh(uint instanceId);
bool DeleteMesh(uint instanceId);
gslBBox GetBBox(...) const;
void Backup();
void Restore();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

修改 Feature 或 Mesh 后需要考虑再生、时间戳、有效性和场景更新。

5. Mesh ​

5.1 bmeMesh ​

基础有限元网格对象。

cpp
bmeMesh(bmeMeshType type);
virtual bmeMesh* VirtualCopy() const;
bool HasOrphanElements() const;
bool HasNativeElements() const;
bool HasOrphanNodes() const;
bool AllElementsOrphan() const;
bool HasNativeNodes() const;
uint NumNodes() const;
uint NumElements() const;
uint Dim() const;
uint MeshNodeIndex(int userNodeLabel) const;
uint NumElementClasses() const;
bmeElementClass& ElemClass(uint classIndex);
int GetMeshElemIndexFromLabel(int userElementLabel) const;
uint GetClassIndex(uint meshElementIndex) const;
uint GetClassElemIndex(uint meshElementIndex) const;
gslBBox GetBBox() const;
void ApplyTransform(const gslMatrix&);
void InvalidateMeshData();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

必须区分:

  • User Node/Element Label:用户界面看到的编号;
  • Mesh Index:内部连续索引;
  • Class Index:单元类型组索引;
  • Class Element Index:某个单元类型组内部的索引。

5.2 bmeNodeData ​

节点坐标和标签容器。

cpp
uint NumNodes() const;
bool HasUserNodeLabel() const;
int GetUserNodeLabel(uint meshNodeIndex) const;
uint GetMeshNodeIndex(int userNodeLabel) const;
void GetUserNodeLabels(cowListInt&) const;
int GetMinUserNodeLabel() const;
int GetMaxUserNodeLabel() const;
const utiCoordCont3D& CoordContainer() const;
bool DeleteNode(uint meshNodeIndex);
void AppendNodes(const bmeNodeData&);
void AppendNodes(const utiCoordCont3D&);
bool SetUserNodeLabel(uint index, int label);
bool SetUserNodeLabels(const cowListInt&);
void SetDimension(uint);
gslBBox GetBBox() const;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

5.3 bmeElementData ​

管理单元类、连接关系和用户标签。

cpp
const bmeElementClass& GetClass(uint classIndex) const;
bmeElementClass& GetClassToModify(uint classIndex);
const bmeElementClass& GetElemClass(uint meshElementIndex) const;
int GetMeshElemIndexFromLabel(uint userLabel) const;
uint GetClassIndex(uint meshElementIndex) const;
uint GetClassElemIndex(uint meshElementIndex) const;
bool SetElementType(uint classIndex, const QString&);
bool AddElements(uint classIndex,
                 const cowListInt& connectivity);
bool AddElementClass(bmeElementClass*);
bool RemoveElements(const bmeFEMElemList&);
void UpdateConnectivity(const int* nodeMap);
int GetUserElementLabel(uint meshElementIndex) const;
bool SetUserElementLabel(uint meshElementIndex, int label);
bool SetUserElementLabels(const cowListInt&);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

5.4 bmeElementClass ​

表示同一单元类型的一组单元。

cpp
virtual bmeElementClass* Copy() const;
int NumNodesPerElem() const;
void SetElemType(const QString&);
const bmeElemCtrlParams& GetElemControlParams() const;
bmeElemCtrlParams& ElemControlParams();
void SetElemControlParams(const bmeElemCtrlParams&);
void InvertElementsConnectivities();
void InvertElementConnectivity(int elementIndex);
void RemoveElement(int classElementNumber);
void RemoveElements(int count, int* classElementNumbers);
1
2
3
4
5
6
7
8
9
10

5.5 omeMesh ​

孤立网格实现:

cpp
omeMesh();
omeMesh(const omeMesh&, uint instanceId);
omeMesh(const bmeMesh&, uint instanceId);
virtual bmeMesh* VirtualCopy() const;
virtual void ResetOrphanElements();
1
2
3
4
5

6. SAMReMesh ​

高层网格处理辅助类。

cpp
SAMReMesh(ftrFeatureList*);
void GetAllNodesData(bmeNodeData&, vector<str_NODE>&);
void GetAllNodesID(bmeNodeData&, cowListInt&);
void GetAllElementsData(bmeElementData&,
                        vector<str_ELEMENT>&);
bool GetNodeIDAndCoordinates(bmeNodeData&,
                             int label,
                             str_NODE&);
void GetNodesCoordinates(...);
bool addNewNodes(...);
bool deleteOldElement(const vector<int>&);
bool createNewNodes(const cowList<str_NODE>&);
bool modifyElemConnection(const cowList<str_ELEMENT>&);
bool detachMesh(...);
static bool getFreeEdge(...);
double calculateTriangleArea(...);
bool calculateQuadrilateralCentroid(...);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

它适合工程网格处理,但不能绕开以下规则:

  • 用户 Label 与内部 Index 的转换;
  • Element Class 的连接关系;
  • Feature 再生和 Part 有效性;
  • 模型修改通知和场景更新;
  • 修改失败时的恢复策略。

7. 数据修改的推荐流程 ​

text
取得当前 basMdb
  -> 定位 basNewModel
  -> 定位 ptoKPart
  -> 检查锁定、有效性和网格存在性
  -> Backup/建立可恢复状态
  -> 修改 Feature 或 Mesh
  -> 更新标签、连接和缓存
  -> Regenerate/AssertValid
  -> UpdateScene
  -> 失败时 Restore
1
2
3
4
5
6
7
8
9
10

具体项目仍应优先通过已验证的 SAM Kernel 命令修改模型,因为直接写底层 C++ 对象可能绕过 Journal、Replay、Undo 和 GUI 通知。

8. Python 数据视图 ​

典型 Python 层次:

python
mdb
mdb.models
mdb.models['Model-1']
mdb.models['Model-1'].parts
mdb.models['Model-1'].parts['Part-1']
part.nodes
part.elements
part.sets
1
2
3
4
5
6
7
8

如果:

python
print(mdb.models['Model-1'].parts.keys())
1

返回空列表,说明 Model 存在但没有 Part;此时读取节点、单元或面积当然不会有结果。

9. 常见错误 ​

  • 把节点 Label 当作内部数组索引;
  • 修改连接后未更新逆连接和缓存;
  • 只改临时 Mesh 副本,没有写回 Feature/Part;
  • 修改模型但未触发再生和 Scene 更新;
  • 在没有 Part 或没有 Mesh 时直接解引用;
  • 跨 DLL/PYD 长期保存已经失效的 SAM 对象指针;
  • 在只读操作中错误取得可写 COW 对象,造成无意修改。

最后更新于:

Pager
上一篇12. SAM 命令桥、Python 与 PYD 扩展 API / SAM Command Bridge, Python, and PYD Extension APIs
下一篇14. SAM 场景、显示表示与渲染 API / SAM Scene, Display Representation, and Rendering APIs

持续记录,持续成长

Copyright © Tidenflow