diff --git a/SourceCode/Code2026/cad_mcp_aec/aec_mcp_entity_tools.cpp b/SourceCode/Code2026/cad_mcp_aec/aec_mcp_entity_tools.cpp index b794aed..e47c8cb 100644 --- a/SourceCode/Code2026/cad_mcp_aec/aec_mcp_entity_tools.cpp +++ b/SourceCode/Code2026/cad_mcp_aec/aec_mcp_entity_tools.cpp @@ -22,6 +22,7 @@ #include "AecDbSlab.h" #include "AecDbColumn.h" #include "AecDbBeam.h" +#include "AecDbClimbStair.h" #include "AecDbObjXDataMap.h" #include "KTSetting.h" @@ -929,3 +930,212 @@ public: } }; EXPORT_MCP_TOOL(ToolUpdateBeam, UpdateAecBeamTool) + +// =========================================================================== +// 爬梯(AecDbClimbStair) +// 对应菜单命令 PL_ZXPT 直爬梯 / PL_YHZT 圆护爬梯(pool3dcmdCmd.cpp:5742)。 +// 建模序列照抄命令实现:setLayer -> SetSection(踏管直径) -> SetBaseCurve(底->顶) +// -> SetClimbStairData(参数体) -> 专业数据 2dStyle/朝向。 +// =========================================================================== +namespace +{ + // 爬梯参数体:没传的字段用"现有值",新建时用命令对话框里的缺省量级 + bool ApplyClimbStair(AecDbClimbStair* p, const nlohmann::json& a, bool bCreate, std::wstring& err) + { + AcGePoint3d ptS, ptE; + bool bHasS = readPoint(a, "start", ptS); + bool bHasE = readPoint(a, "end", ptE); + + if (bCreate && (!bHasS || !bHasE)) + { + err = L"add_aec_climb_stair 需要 start(梯段底部点) 与 end(顶部点)"; + return false; + } + + ClimbStair data; + ::memset(&data, 0, sizeof(ClimbStair)); + p->GetClimbStairData(data); + + if (bCreate) + { + data.nType = hasKey(a, "type") ? intOr(a, "type", 0) : 0; // 0 圆护直梯 1 圆护凸爬 + data.dSegSp = 300.0; + data.dSteepH = 300.0; + data.dSpWall = 180.0; + data.dD = 700.0; + data.dW = 450.0; + data.dd = 20.0; + data.dt = 2.5; + } + + if (hasKey(a, "type")) data.nType = intOr(a, "type", data.nType); + if (hasKey(a, "cage_diameter")) data.dD = numOr(a, "cage_diameter", data.dD); + if (hasKey(a, "width")) data.dW = numOr(a, "width", data.dW); + if (hasKey(a, "height")) data.dH = numOr(a, "height", data.dH); + if (hasKey(a, "bottom_elevation")) data.dBomEl = numOr(a, "bottom_elevation", data.dBomEl); + if (hasKey(a, "step_height")) data.dSteepH = numOr(a, "step_height", data.dSteepH); + if (hasKey(a, "step_spacing")) data.dSegSp = numOr(a, "step_spacing", data.dSegSp); + if (hasKey(a, "wall_distance")) data.dSpWall = numOr(a, "wall_distance", data.dSpWall); + if (hasKey(a, "bar_diameter")) data.dd = numOr(a, "bar_diameter", data.dd); + if (hasKey(a, "bar_thickness")) data.dt = numOr(a, "bar_thickness", data.dt); + if (hasKey(a, "material")) + { + CString sMat(wstrOr(a, "material", L"").c_str()); + _tcsncpy_s(data.m_sMaterial, 256, sMat, _TRUNCATE); + } + + if (data.dW <= 0.0 || data.dD <= 0.0) + { + err = L"爬梯需要 width 与 cage_diameter,且都 > 0"; + return false; + } + + // 梯段基线:命令里是按"放置点+朝向"算出来的,工具直接收两个端点(更直接) + if (bHasS && bHasE) + { + if (ptS.distanceTo(ptE) < 1e-9) + { + err = L"start 与 end 重合,梯段长度为 0"; + return false; + } + if (data.dH <= 1e-9) + data.dH = ptE.z - ptS.z; + if (data.dH <= 1e-9) + data.dH = 3000.0; + + p->SetSection(data.dd, 0.0); + p->SetBaseCurve(ptS, ptE); + } + + p->SetClimbStairData(data); + + // 朝向:命令里存的是"人面对的方向",缺省给 +Y + AcGeVector3d vtFace(0.0, 1.0, 0.0); + { + nlohmann::json jFace; + if (a.is_object() && a.contains("facing")) + { + AcGePoint3d ptFace; + if (readPoint(a, "facing", ptFace)) + vtFace = ptFace.asVector(); + } + vtFace.normalize(); + } + p->GetSpecialtyData()->SetAt(KEY_2DSTYLE, 0); + p->GetSpecialtyData()->SetAt(KEY_MAJBR, vtFace); + + return true; + } +} + +class ToolAddClimbStair : public mcp_Tool +{ +public: + std::string private_name() const override { return "add_aec_climb_stair"; } + + std::string private_description() const override + { + return "新建爬梯(AecDbClimbStair,对应菜单命令 直爬梯/圆护爬梯)。" + "给梯段底部点与顶部点,以及梯宽、护笼直径、总高;其余按对话框缺省。尺寸用图纸单位。"; + } + + nlohmann::json private_input_schema() const override + { + return nlohmann::json::parse(R"({ + "type": "object", + "properties": { + "start": { "type": "array", "items": { "type": "number" }, "description": "梯段底部点 [x,y] 或 [x,y,z]" }, + "end": { "type": "array", "items": { "type": "number" }, "description": "梯段顶部点" }, + "width": { "type": "number", "description": "梯宽,图纸单位(缺省 450)" }, + "cage_diameter": { "type": "number", "description": "护笼总直径(缺省 700)" }, + "height": { "type": "number", "description": "总高,不给则用 end.z - start.z" }, + "bottom_elevation": { "type": "number", "description": "底标高,缺省 0" }, + "type": { "type": "integer", "description": "0=圆护直梯(缺省)1=圆护凸爬" }, + "bar_diameter": { "type": "number", "description": "踏管直径(缺省 20)" }, + "step_height": { "type": "number", "description": "踏步高(缺省 300)" }, + "step_spacing": { "type": "number", "description": "踏棍间距(缺省 300)" }, + "wall_distance": { "type": "number", "description": "距墙距离(缺省 180)" }, + "facing": { "type": "array", "items": { "type": "number" }, "description": "人面对的方向 [x,y],缺省 +Y" }, + "material": { "type": "string", "description": "材质" }, + "layer": { "type": "string", "description": "图层,缺省 LAY_CSTAIR" } + }, + "required": [ "start", "end" ] + })"); + } + + nlohmann::json Execute(const nlohmann::json& args) override + { + if (workingDb() == NULL) return errJson(kErrNoDocument, L"没有活动图纸"); + DocLock lock; + if (!lock.isLocked()) return errJson(kErrInternal, L"拿不到图纸写锁(有别的命令在跑?)"); + + AecDbClimbStair* pStair = new AecDbClimbStair(); + std::wstring err; + if (!ApplyClimbStair(pStair, args, true, err)) + { + delete pStair; + return errJson(kErrBadParam, err); + } + + // 命令里固定用 LAY_CSTAIR 图层;工具允许覆盖 + if (!hasKey(args, "layer")) + { + AcDbObjectId idLay = layerIdByName(L"LAY_CSTAIR"); + if (!idLay.isNull()) + pStair->setLayer(idLay); + } + + return finishCreate(pStair, args, "climb_stair"); + } +}; +EXPORT_MCP_TOOL(ToolAddClimbStair, AddAecClimbStairTool) + +class ToolUpdateClimbStair : public mcp_Tool +{ +public: + std::string private_name() const override { return "update_aec_climb_stair"; } + + std::string private_description() const override + { + return "修改已有爬梯:只传要改的字段(端点、梯宽、护笼直径、总高、踏步、材质…)。"; + } + + nlohmann::json private_input_schema() const override + { + return nlohmann::json::parse(R"({ + "type": "object", + "properties": { + "handle": { "type": "string", "description": "爬梯句柄" }, + "start": { "type": "array", "items": { "type": "number" }, "description": "新起点(可选)" }, + "end": { "type": "array", "items": { "type": "number" }, "description": "新终点(可选)" }, + "width": { "type": "number" }, "cage_diameter": { "type": "number" }, + "height": { "type": "number" }, "bottom_elevation": { "type": "number" }, + "type": { "type": "integer" }, "bar_diameter": { "type": "number" }, + "step_height": { "type": "number" }, "step_spacing": { "type": "number" }, + "wall_distance": { "type": "number" }, "facing": { "type": "array", "items": { "type": "number" } }, + "material": { "type": "string" } + }, + "required": [ "handle" ] + })"); + } + + nlohmann::json Execute(const nlohmann::json& args) override + { + if (workingDb() == NULL) return errJson(kErrNoDocument, L"没有活动图纸"); + DocLock lock; + if (!lock.isLocked()) return errJson(kErrInternal, L"拿不到图纸写锁(有别的命令在跑?)"); + + nlohmann::json err; + AecDbClimbStair* pStair = openTyped(args, L"AecDbClimbStair", err); + if (pStair == NULL) return err; + + std::wstring msg; + if (!ApplyClimbStair(pStair, args, false, msg)) + { + pStair->close(); + return errJson(kErrBadParam, msg); + } + return finishUpdate(pStair, args["handle"].get(), "climb_stair"); + } +}; +EXPORT_MCP_TOOL(ToolUpdateClimbStair, UpdateAecClimbStairTool) diff --git a/SourceCode/Code2026/cad_mcp_aec/aec_mcp_query.cpp b/SourceCode/Code2026/cad_mcp_aec/aec_mcp_query.cpp index 17cbb2b..cf0d7fb 100644 --- a/SourceCode/Code2026/cad_mcp_aec/aec_mcp_query.cpp +++ b/SourceCode/Code2026/cad_mcp_aec/aec_mcp_query.cpp @@ -17,6 +17,7 @@ #include "AecDbSlab.h" #include "AecDbColumn.h" #include "AecDbBeam.h" +#include "AecDbClimbStair.h" #include "AecDbObjXDataMap.h" using namespace aec_mcp; @@ -29,6 +30,7 @@ const char* kTypeWall = "wall"; const char* kTypeSlab = "slab"; const char* kTypeColumn = "column"; const char* kTypeBeam = "beam"; +const char* kTypeClimb = "climb_stair"; // 实体 -> 五个受支持类型之一;不是这几类返回空串 std::string supportedTypeOf(AcDbEntity* pEnt) @@ -41,6 +43,7 @@ std::string supportedTypeOf(AcDbEntity* pEnt) if (AecDbXSlab::cast(pEnt)) return kTypeSlab; if (AecDbColumn::cast(pEnt)) return kTypeColumn; if (AecDbBeam::cast(pEnt)) return kTypeBeam; + if (AecDbClimbStair::cast(pEnt)) return kTypeClimb; return std::string(); } @@ -141,6 +144,26 @@ nlohmann::json paramsOf(AcDbEntity* pEnt, const std::string& sType) p["width"] = rc.y; p["rotation_deg"] = pCol->GetRotation() * 180.0 / PI; } + else if (sType == kTypeClimb) + { + AecDbClimbStair* pStair = AecDbClimbStair::cast(pEnt); + ClimbStair data; + ::memset(&data, 0, sizeof(ClimbStair)); + if (pStair != NULL) + { + pStair->GetClimbStairData(data); + p["type"] = data.nType; + p["cage_diameter"] = data.dD; + p["width"] = data.dW; + p["height"] = data.dH; + p["bottom_elevation"] = data.dBomEl; + p["step_height"] = data.dSteepH; + p["step_spacing"] = data.dSegSp; + p["wall_distance"] = data.dSpWall; + p["bar_diameter"] = data.dd; + p["material"] = acharToUtf8(data.m_sMaterial); + } + } else if (sType == kTypeBeam) { AecDbBeam* pBeam = AecDbBeam::cast(pEnt); @@ -203,7 +226,7 @@ public: return nlohmann::json::parse(R"({ "type": "object", "properties": { - "type": { "type": "string", "enum": [ "all", "pipe", "wall", "slab", "column", "beam" ], + "type": { "type": "string", "enum": [ "all", "pipe", "wall", "slab", "column", "beam", "climb_stair" ], "description": "要列出的类型,缺省 all" }, "space": { "type": "string", "description": "空间名:Model 或布局名,缺省 Model" }, "limit": { "type": "integer", "description": "最多返回多少条,缺省 200,上限 1000" }, diff --git a/SourceCode/Code2026/cad_mcp_aec/mcp_config.json b/SourceCode/Code2026/cad_mcp_aec/mcp_config.json index 3c5b8e7..7702864 100644 --- a/SourceCode/Code2026/cad_mcp_aec/mcp_config.json +++ b/SourceCode/Code2026/cad_mcp_aec/mcp_config.json @@ -1123,7 +1123,7 @@ }, { "name": "query_aec_entities", - "description": "列出本插件支持的 Envi3D 自定义实体(管道/墙/板/柱/梁),分页返回 total/returned/offset/items,每项含 handle、类型、图层、起终点、包围盒。改图之前先用它拿 handle。", + "description": "列出本插件支持的 Envi3D 自定义实体(管道/墙/板/柱/梁/爬梯),分页返回 total/returned/offset/items,每项含 handle、类型、图层、起终点、包围盒。改图之前先用它拿 handle。", "inputSchema": { "type": "object", "properties": { @@ -1135,7 +1135,8 @@ "wall", "slab", "column", - "beam" + "beam", + "climb_stair" ], "description": "要列出的类型,缺省 all" }, @@ -1734,6 +1735,164 @@ "dll_name": "cad_mcp_aec.dll", "factory_function": "UpdateAecBeamTool" } + }, + { + "name": "add_aec_climb_stair", + "description": "新建爬梯(AecDbClimbStair,对应菜单命令 直爬梯/圆护爬梯)。给梯段底部点与顶部点,以及梯宽、护笼直径、总高;其余按对话框缺省。尺寸用图纸单位。", + "inputSchema": { + "type": "object", + "properties": { + "start": { + "type": "array", + "items": { + "type": "number" + }, + "description": "梯段底部点 [x,y] 或 [x,y,z]" + }, + "end": { + "type": "array", + "items": { + "type": "number" + }, + "description": "梯段顶部点" + }, + "width": { + "type": "number", + "description": "梯宽(缺省 450)" + }, + "cage_diameter": { + "type": "number", + "description": "护笼总直径(缺省 700)" + }, + "height": { + "type": "number", + "description": "总高,不给则用 end.z-start.z" + }, + "bottom_elevation": { + "type": "number", + "description": "底标高,缺省 0" + }, + "type": { + "type": "integer", + "description": "0=圆护直梯(缺省)1=圆护凸爬" + }, + "bar_diameter": { + "type": "number", + "description": "踏管直径(缺省 20)" + }, + "step_height": { + "type": "number", + "description": "踏步高(缺省 300)" + }, + "step_spacing": { + "type": "number", + "description": "踏棍间距(缺省 300)" + }, + "wall_distance": { + "type": "number", + "description": "距墙距离(缺省 180)" + }, + "facing": { + "type": "array", + "items": { + "type": "number" + }, + "description": "人面对的方向 [x,y],缺省 +Y" + }, + "material": { + "type": "string", + "description": "材质" + }, + "layer": { + "type": "string", + "description": "图层,缺省 LAY_CSTAIR" + }, + "space": { + "type": "string", + "description": "空间:Model 或布局名,缺省 Model" + } + }, + "required": [ + "start", + "end" + ] + }, + "backend": { + "type": "c++_dll", + "dll_name": "cad_mcp_aec.dll", + "factory_function": "AddAecClimbStairTool" + } + }, + { + "name": "update_aec_climb_stair", + "description": "修改已有爬梯:只传要改的字段(端点、梯宽、护笼直径、总高、踏步、材质…)。", + "inputSchema": { + "type": "object", + "properties": { + "handle": { + "type": "string" + }, + "start": { + "type": "array", + "items": { + "type": "number" + }, + "description": "新起点(可选)" + }, + "end": { + "type": "array", + "items": { + "type": "number" + }, + "description": "新终点(可选)" + }, + "width": { + "type": "number" + }, + "cage_diameter": { + "type": "number" + }, + "height": { + "type": "number" + }, + "bottom_elevation": { + "type": "number" + }, + "type": { + "type": "integer" + }, + "bar_diameter": { + "type": "number" + }, + "step_height": { + "type": "number" + }, + "step_spacing": { + "type": "number" + }, + "wall_distance": { + "type": "number" + }, + "facing": { + "type": "array", + "items": { + "type": "number" + }, + "description": "新朝向(可选)" + }, + "material": { + "type": "string" + } + }, + "required": [ + "handle" + ] + }, + "backend": { + "type": "c++_dll", + "dll_name": "cad_mcp_aec.dll", + "factory_function": "UpdateAecClimbStairTool" + } } ] } diff --git a/cad-mcp-aec.md b/cad-mcp-aec.md index 42ae746..de121f7 100644 --- a/cad-mcp-aec.md +++ b/cad-mcp-aec.md @@ -167,3 +167,101 @@ MCP 工具是通过 `PostMessage` 在主线程的消息里跑的,**不在命 `cannot open target space for write`(`eLockViolation`)—— 补了 `dwg_annotate::DocLock`; 2. 上游 `cadsdk.h` 带 `NOMINMAX`,本仓库 `KTCad.h` 没有, `std::min/std::max` 被 windows 宏顶掉 —— 在用到它们的三个文件里 `#undef min/max`。 + +## 8. 菜单命令 → 实体 → 工具 对照表 + +来源:`c:\ShangHuaSoft\Envi3D-2026-M\sys\*.mnu`(8 个文件、674 条命令、GBK 编码)。 +做法:解析 `ID_xxx [四字说明]命令` → 用命令名在源码里找注册的 handler +(`ADD_CMD` / `acedRegCmds->addCommand`)→ 在 handler(含一层直接调用)里找 `new AecDbXxx` +→ 得到"会新建实体的命令"共 74 条、涉及 44 个实体类。 + +已实现的实体:管道/墙/板/柱/梁/爬梯(每类一个 `add_*` + 一个 `update_*`)。 +其余实体的创建参数还没梳理(多数要读对话框),标"(未实现)", +要补的话照 `add_aec_climb_stair` 的写法:命令实现里抄建模序列 → 抽出参数 → 加工具。 + +|cad命令|4字中文名称|实体名称|工具名称1|工具名称2| +| --- | --- | --- | --- | --- | +|PL_CRJZ|插入角柱|AecDbColumn|add_aec_column|update_aec_column| +|PL_GZZZ|构造柱子|AecDbColumn|add_aec_column|update_aec_column| +|PL_DXBQ|单线变墙|AecDbXWall|add_aec_wall|update_aec_wall| +|PL_HZMQ|绘制幕墙|AecDbGlassCurtainWall|(未实现)|| +|PL_QTDJ|墙体倒角|AecDbX3dPartEntity|(内部构件,不单独建)|| +|PL_QTDY|墙体倒圆|AecDbX3dPartEntity|(内部构件,不单独建)|| +|PL_ZXPT|直段爬梯|AecDbClimbStair|add_aec_climb_stair|update_aec_climb_stair| +|PL_YHZT|圆护爬梯|AecDbClimbStair|add_aec_climb_stair|update_aec_climb_stair| +|PL_PTLT|直线钢梯|AecDbLineStair|(内部构件,不单独建)|| +|PL_SPLT|双跑楼梯|AecDbZLineStair|(未实现)|| +|PL_SFPX|双平行梯|AecDbParaLlelStair|(未实现)|| +|PL_SFZJ|双分转角|AecDbCornerStair|(未实现)|| +|PL_SFSP|双分三跑|AecDbDoubleMulStair|(未实现)|| +|PL_JCLT|交叉楼梯|AecDbScissorsStair|(未实现)|| +|PL_JDLT|剪刀楼梯|AecDbCrossStair|(未实现)|| +|PL_SJLT|三角楼梯|AecDbTriangleStair|(未实现)|| +|PL_JXZJ|矩形转角|AecDbRectCornerStair|(未实现)|| +|PL_DDLT|多段楼梯|AecDbMRPLineStair|(未实现)|| +|PL_YHLT|圆弧楼梯|AecDbArcStair|(未实现)|| +|PL_ZXLT|直线楼梯|AecDbLineSegStair|(未实现)|| +|PL_RYPD|任意屋顶|AecDbXRoof|(未实现)|| +|PL_RZPD|人字屋顶|AecDbXRoof|(未实现)|| +|PL_ZJPD|攒尖屋顶|AecDbXRoof|(未实现)|| +|PL_JXPD|<-矩形屋顶|AecDbXRoof|(未实现)|| +|PL_ZHMC|组合门窗|AecDbGroupXOpening|(未实现)|| +|PL_ZHMC|组合门窗|AecDbXOpening|(未实现)|| +|PL_DXCH|带形窗户|AecDbZLineXOpening|(未实现)|| +|PL_ZJCH|转角窗户|AecDbZLineXOpening|(未实现)|| +|PL_JLHC|加老虎窗|AecDbXDormerWindow|(未实现)|| +|PL_JBWC|加保温层|AecDbInsulation|(未实现)|| +|PL_CBKD|墙体开洞|AecDbX3dPartEntity|(内部构件,不单独建)|| +|PL_CDKD|平板开洞|AecDbX3dPartEntity|(内部构件,不单独建)|| +|PL_YXKD|异形开洞|AecDbX3dPart|(内部构件,不单独建)|| +|PL_YXKD|异形开洞|AecDbX3dPartEntity|(内部构件,不单独建)|| +|PL_YXKD|异形开洞|AecDbXEquipment|(未实现)|| +|PL_ZLKD|阵列开洞|AecDbX3dPartEntity|(内部构件,不单独建)|| +|PL_YXCG|穿管开洞|AecDbX3dPart|(内部构件,不单独建)|| +|PL_YXCG|穿管开洞|AecDbX3dPartEntity|(内部构件,不单独建)|| +|PL_YXCG|穿管开洞|AecDbXEquipment|(未实现)|| +|PL_FZYT|放置阳台|AecDbBalcony|(未实现)|| +|PL_FZTJ|放置台阶|AecDbXStep|(未实现)|| +|PL_FZPD|放置坡道|AecDbAscent|(未实现)|| +|PL_FZSS|放置散水|AecDbXApron|(未实现)|| +|PL_FZHN|放置护栏|AecDbGuardBar|(内部构件,不单独建)|| +|PL_QXHN|<-曲线护栏|AecDbGuardBar|(内部构件,不单独建)|| +|PL_JFZJ|添加方井|AecDbX3dPartEntity|(内部构件,不单独建)|| +|PL_JYZJ|添加圆井|AecDbX3dPartEntity|(内部构件,不单独建)|| +|PL_JFYJ|加方圆井|AecDbX3dPartEntity|(内部构件,不单独建)|| +|PL_JYXJ|加异形井|AecDbX3dPartEntity|(内部构件,不单独建)|| +|PL_JJSK|加集水坑|AecDbX3dPartEntity|(内部构件,不单独建)|| +|PL_LSJM|绘制沟渠|AecDbEwPipeBase|(未实现)|| +|PL_YXGZ|<-异形构筑|AecDbMultiPartEntity|(未实现)|| +|PL_FZZJ|放置支架|AecDbHolder|(未实现)|| +|PL_LGGJ|立管固架|AecDbHolder|(未实现)|| +|PL_FZDJ|放置吊架|AecDbHanger|(未实现)|| +|PL_FZZD|<-放置支墩|AecDbBossHolder|(未实现)|| +|EL_HZXG|绘制线管|AecDb3dRoadAxisLine|(未实现)|| +|EL_HZXG|绘制线管|AecDbEwFlexiblePipe|(未实现)|| +|EL_JYZW|<-加乙字弯|AecDbEcFitting|(未实现)|| +|EL_HBLW|绘避雷网|AecDbEwEquipment|(未实现)|| +|EL_HBLW|绘避雷网|AecDbEwFlexiblePipe|(未实现)|| +|EL_HBLD|绘避雷带|AecDbEwEquipment|(未实现)|| +|EL_HBLD|绘避雷带|AecDbEwFlexiblePipe|(未实现)|| +|EL_JSSJ|加伸缩缝|AecDb3dRoadAxisLine|(未实现)|| +|EL_FWBR|<-翻弯避让|AecDb3dRoadAxisLine|(未实现)|| +|PL_DGTJ|单管托架|AecDbPipeHanger|(未实现)|| +|PL_SGTJ|双管托架|AecDbPipeHanger|(未实现)|| +|PL_LGTJ|立管托架|AecDbPipeHanger|(未实现)|| +|PL_PGZZ|平管支座|AecDbPipeHanger|(未实现)|| +|PL_WGZZ|弯管支座|AecDbPipeHanger|(未实现)|| +|PL_SBLG|设备连管|AecDbEwPipe|add_aec_pipe|update_aec_pipe| +|PL_RYGZ|任意管嘴|AecDbEwEquipment|(未实现)|| +|PL_XHBZ|序号标注|AecDbEwPipeDim|(未实现)|| +|PL_XHPB|序号批标|AecDbEwPipeDim|(未实现)|| +|DI_JDBZ|角度标注|AecDbDimension|(未实现)|| +|DI_JDBZ|角度标注|AecDbX3dPart|(内部构件,不单独建)|| +|DI_JDBZ|角度标注|AecDbXEquipment|(未实现)|| +|PL_DKBZ|洞口标注|AecDbEwPipeDim|(未实现)|| +|PL_TGBZ|套管标注|AecDbEwPipeDim|(未实现)|| +|PL_YHBZ|翼环标注|AecDbEwPipeDim|(未实现)|| +|PL_FMBZ|阀门标注|AecDbEwPipeDim|(未实现)|| +|HA_FBBZ|风管标注|AecDbEwPipeDim|(未实现)|| +|IS_BZFM|标注阀门|AecDbEwPipeDim|(未实现)|| +|IS_GZGJ|标注管件|AecDbEwPipeDim|(未实现)||