#include "StdAfx.h" #include "KTCad.h" #include "aec_mcp_common.h" #include "mcp_plugin_api.h" namespace aec_mcp { // =========================================================================== // 结果封装 // =========================================================================== nlohmann::json okJson(const nlohmann::json& body) { // 统一信封:{"ok":true, ...业务字段} nlohmann::json o = nlohmann::json::object(); o["ok"] = true; if (body.is_object()) { for (nlohmann::json::const_iterator it = body.begin(); it != body.end(); ++it) o[it.key()] = it.value(); } else if (!body.is_null()) { o["data"] = body; } std::string s = o.dump(); return mcp_Tool_Utility::make_text_result(mcp_Tool_Utility::utf8ToWString(s)); } nlohmann::json errJson(int code, const std::wstring& msg) { return mcp_Tool_Utility::make_error(code, msg); } // =========================================================================== // 参数读取 // =========================================================================== bool hasKey(const nlohmann::json& a, const char* key) { return a.is_object() && a.contains(key) && !a[key].is_null(); } double numOr(const nlohmann::json& a, const char* key, double defVal) { if (!hasKey(a, key)) return defVal; const nlohmann::json& v = a[key]; if (v.is_number()) return v.get(); if (v.is_boolean()) return v.get() ? 1.0 : 0.0; if (v.is_string()) { try { return std::stod(v.get()); } catch (...) { return defVal; } } return defVal; } int intOr(const nlohmann::json& a, const char* key, int defVal) { return (int)numOr(a, key, (double)defVal); } std::wstring wstrOr(const nlohmann::json& a, const char* key, const wchar_t* defVal) { if (!hasKey(a, key) || !a[key].is_string()) return std::wstring(defVal ? defVal : L""); return mcp_Tool_Utility::utf8ToWString(a[key].get()); } bool pointOf(const nlohmann::json& v, AcGePoint3d& pt) { if (v.is_object()) { if (!v.contains("x") || !v.contains("y")) return false; pt.x = v.value("x", 0.0); pt.y = v.value("y", 0.0); pt.z = v.value("z", 0.0); return true; } if (v.is_array() && v.size() >= 2) { pt.x = v[0].get(); pt.y = v[1].get(); pt.z = (v.size() >= 3) ? v[2].get() : 0.0; return true; } return false; } bool readPoint(const nlohmann::json& a, const char* key, AcGePoint3d& pt) { if (!hasKey(a, key)) return false; return pointOf(a[key], pt); } bool readPoint2dArray(const nlohmann::json& a, const char* key, AcGePoint2dArray& pts) { if (!hasKey(a, key) || !a[key].is_array()) return false; const nlohmann::json& arr = a[key]; for (size_t i = 0; i < arr.size(); ++i) { const nlohmann::json& e = arr[i]; if (e.is_object() && e.contains("x") && e.contains("y")) pts.append(AcGePoint2d(e.value("x", 0.0), e.value("y", 0.0))); else if (e.is_array() && e.size() >= 2) pts.append(AcGePoint2d(e[0].get(), e[1].get())); else return false; } return !pts.isEmpty(); } // =========================================================================== // 图纸 / 对象 // =========================================================================== AcDbDatabase* workingDb() { return acdbHostApplicationServices()->workingDatabase(); } DocLock::DocLock() : m_bLocked(false), m_pDoc(NULL) { m_pDoc = acDocManager->curDocument(); if (m_pDoc != NULL && acDocManager->lockDocument(m_pDoc) == Acad::eOk) m_bLocked = true; } DocLock::~DocLock() { if (m_bLocked && m_pDoc != NULL) acDocManager->unlockDocument(m_pDoc); } AcDbEntity* openByHandle(const std::string& handleStr, AcDb::OpenMode mode, AcDbObjectId* pIdOut) { if (handleStr.empty()) return NULL; AcDbDatabase* pDb = workingDb(); if (pDb == NULL) return NULL; std::wstring ws = utf8ToWstr(handleStr); AcDbHandle h(ws.c_str()); AcDbObjectId id; if (pDb->getAcDbObjectId(id, false, h) != Acad::eOk || id.isNull()) return NULL; AcDbEntity* pEnt = NULL; if (acdbOpenObject(pEnt, id, mode) != Acad::eOk) return NULL; if (pIdOut != NULL) *pIdOut = id; return pEnt; } std::string handleOf(AcDbObject* pObj) { if (pObj == NULL) return std::string(); AcDbHandle h; pObj->getAcDbHandle(h); ACHAR szBuf[64] = { 0 }; h.getIntoAsciiBuffer(szBuf, 64); return acharToUtf8(szBuf); } Acad::ErrorStatus addToSpace(AcDbEntity* pEnt, AcDbObjectId* pIdOut, const std::wstring& space) { AcDbDatabase* pDb = workingDb(); if (pDb == NULL || pEnt == NULL) return Acad::eInvalidInput; AcDbBlockTable* pBT = NULL; if (pDb->getBlockTable(pBT, AcDb::kForRead) != Acad::eOk || pBT == NULL) return Acad::eInvalidInput; AcDbObjectId idSpace; Acad::ErrorStatus es = Acad::eKeyNotFound; if (space.empty() || space == L"Model" || space == L"model") { es = pBT->getAt(ACDB_MODEL_SPACE, idSpace); } else { es = pBT->getAt(space.c_str(), idSpace); } pBT->close(); if (es != Acad::eOk) return es; AcDbBlockTableRecord* pRec = NULL; es = acdbOpenObject(pRec, idSpace, AcDb::kForWrite); if (es != Acad::eOk || pRec == NULL) return es; AcDbObjectId idNew; es = pRec->appendAcDbEntity(idNew, pEnt); pRec->close(); if (es != Acad::eOk) return es; if (pIdOut != NULL) *pIdOut = idNew; // appendAcDbEntity 不接管关闭;调用方仍然负责 close return Acad::eOk; } AcDbObjectId layerIdByName(const std::wstring& name) { AcDbObjectId id; if (name.empty()) return id; AcDbDatabase* pDb = workingDb(); if (pDb == NULL) return id; AcDbLayerTable* pTable = NULL; if (pDb->getLayerTable(pTable, AcDb::kForRead) != Acad::eOk || pTable == NULL) return id; pTable->getAt(name.c_str(), id); pTable->close(); return id; } // =========================================================================== // 其它 // =========================================================================== std::wstring utf8ToWstr(const std::string& s) { return mcp_Tool_Utility::utf8ToWString(s); } std::string acharToUtf8(const ACHAR* s) { if (s == NULL) return std::string(); #ifdef _UNICODE return mcp_Tool_Utility::WStringToUtf8(std::wstring(s)); #else return std::string(s); #endif } std::string classNameOf(AcDbObject* pObj) { if (pObj == NULL || pObj->isA() == NULL) return std::string(); std::string n = acharToUtf8(pObj->isA()->name()); if (n.rfind("AecDb", 0) == 0) n = n.substr(5); return n; } bool entityBBox(AcDbEntity* pEnt, AcGePoint3d& ptMin, AcGePoint3d& ptMax) { if (pEnt == NULL) return false; try { AcDbExtents ext; if (pEnt->getGeomExtents(ext) != Acad::eOk) return false; ptMin = ext.minPoint(); ptMax = ext.maxPoint(); return true; } catch (...) { return false; } } void touchEntity(AcDbEntity* pEnt) { if (pEnt == NULL) return; // 几何改了要让显示缓存失效(AecDb* 的 2D/3D 缓存由 assertWriteEnabled 清), // 再通知 CAD 重画这一段 pEnt->recordGraphicsModified(Adesk::kTrue); } } // namespace aec_mcp