#include "stdafx.h" //#include "Resource.h" #include "KTCadUtility.h" #include #include #include "Kingtouch.h" #include "KTCadTempOverrides.h" #include "EarThwormDef.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #if !defined(KTCHECK) #define KTCHECK(EXPRESION) assert(EXPRESION) #endif // !defined(KTCHECK) // 比较计算的精度 double CKTCadUtility::m_KTTol = AcGeContext::gTol.equalPoint(); BOOL CKTCadUtility::CanHighLight(AcDbObjectId idObj) { AcDbObject* pObj; if (acdbOpenObject(pObj, idObj, AcDb::kForRead) != Acad::eOk) return FALSE; if (!pObj->isKindOf(AcDbEntity::desc()) || pObj->isKindOf(AcDbBlockBegin::desc()) || pObj->isKindOf(AcDbBlockEnd::desc())) { pObj->close(); return FALSE; } pObj->close(); return TRUE; } BOOL CKTCadUtility::HighLightEntity(AcDbObjectId idObj, BOOL bHighLight,AcApDocument* pDoc) { acDocManager->lockDocument(pDoc); acDocManager->activateDocument(pDoc); AcDbObject* pObj; if (acdbOpenObject(pObj, idObj, AcDb::kForRead) != Acad::eOk) { acDocManager->unlockDocument(pDoc); return FALSE; } if (!pObj->isKindOf(AcDbEntity::desc()) || pObj->isKindOf(AcDbBlockBegin::desc()) || pObj->isKindOf(AcDbBlockEnd::desc())) { pObj->close(); acDocManager->unlockDocument(pDoc); return FALSE; } if (pDoc->isQuiescent()) { pObj->close(); AcDbGroup* pGroup; AcDbObjectIdArray aridGroups; int iPos = GetItemGroups(idObj, aridGroups); if (bHighLight) { ads_name entName; acdbGetAdsName(entName, idObj); ads_name ssPick; acedSSAdd(entName, NULL, ssPick); while ((--iPos) >= 0) { AcDbObjectIdArray aridEnts; int iIdx = GetGroupItems(aridGroups[iPos], aridEnts); while ((--iIdx) >= 0) { acdbGetAdsName(entName, aridEnts[iIdx]); acedSSAdd(entName, ssPick, ssPick); } } acedSSSetFirst(ssPick, ssPick); acedSSFree(ssPick); } else { acedSSSetFirst(NULL, NULL); while ((--iPos) >= 0) { if (Acad::eOk != acdbOpenObject(pGroup, aridGroups[iPos], AcDb::kForRead)) continue; pGroup->setHighlight(false); pGroup->close(); } } } else { if (bHighLight) ((AcDbEntity*)pObj)->highlight(); else ((AcDbEntity*)pObj)->unhighlight(); pObj->close(); } actrTransactionManager->flushGraphics(); acedUpdateDisplay(); acDocManager->unlockDocument(pDoc); return TRUE; } AcDbObjectId CKTCadUtility::Initlayer(const TCHAR *szLayer, Adesk::UInt16 nCr/* = 256*/,AcDbDatabase *pDb) { if (pDb == NULL) pDb = acdbCurDwg(); AcDbObjectId idLayer = AcDbObjectId::kNull; AcDbLayerTable* pTable = NULL; BOOL bFind = FALSE; pDb->getLayerTable(pTable,AcDb::kForWrite); if (pTable != NULL) { if (Acad::eOk == pTable->getAt(szLayer,idLayer)) { bFind = TRUE; } if (!bFind) { AcDbObjectId idLt; AcDbLinetypeTable *pLinetypeTbl = NULL; pDb->getLinetypeTable(pLinetypeTbl, AcDb::kForRead); pLinetypeTbl->getAt(_T("Continuous"),idLt); pLinetypeTbl->close(); AcDbLayerTableRecord* pRec = new AcDbLayerTableRecord; pRec->setName(szLayer); pRec->setLinetypeObjectId(idLt); AcCmColor cr; cr.setColorIndex(nCr); pRec->setColor(cr); pTable->add(idLayer,pRec); pRec->close(); } pTable->close(); } return idLayer; } AcDbObjectId CKTCadUtility::InitTextStyle(const TCHAR *pszStyle, AcDbDatabase *pDb) { if (pDb == NULL) pDb = acdbCurDwg(); AcDbObjectId id; AcDbTextStyleTable* pTxtTbl = NULL; if (Acad::eOk == pDb->getTextStyleTable(pTxtTbl,AcDb::kForWrite)) { if (Acad::eOk == pTxtTbl->getAt(pszStyle,id)) { pTxtTbl->close(); return id; } else { AcDbTextStyleTableRecord* pTxtRec = new AcDbTextStyleTableRecord; pTxtRec->setFileName(_T("gbenor")); pTxtRec->setBigFontFileName(_T("gbcbig")); pTxtRec->setXScale(0.75); pTxtRec->setName(pszStyle); pTxtTbl->add(id,pTxtRec); pTxtRec->close(); } pTxtTbl->close(); } return id; } // 取得系统变量值 BOOL CKTCadUtility::GetSystemVar(LPCTSTR pszVarName, short& iVal) { BOOL bRet = FALSE; struct resbuf rb; ZeroMemory(&rb, sizeof(struct resbuf)); acedGetVar(pszVarName, &rb); AcDb::DwgDataType iType = ResBufType2DwgDataType(rb.restype); if (iType == AcDb::kDwgInt16 || iType == AcDb::kDwgInt8) { iVal = rb.resval.rint; bRet = TRUE; } FreeResBuf(&rb); return bRet; } BOOL CKTCadUtility::GetSystemVar(LPCTSTR pszVarName, int& iVal) { BOOL bRet = FALSE; struct resbuf rb; ZeroMemory(&rb, sizeof(struct resbuf)); acedGetVar(pszVarName, &rb); AcDb::DwgDataType iType = ResBufType2DwgDataType(rb.restype); if (iType == AcDb::kDwgInt16 || iType == AcDb::kDwgInt8) { iVal = rb.resval.rint; bRet = TRUE; } FreeResBuf(&rb); return bRet; } BOOL CKTCadUtility::GetSystemVar(LPCTSTR pszVarName, long& lVal) { BOOL bRet = FALSE; struct resbuf rb; ZeroMemory(&rb, sizeof(struct resbuf)); acedGetVar(pszVarName, &rb); AcDb::DwgDataType iType = ResBufType2DwgDataType(rb.restype); if (iType == AcDb::kDwgInt32) { lVal = rb.resval.rlong; bRet = TRUE; } FreeResBuf(&rb); return bRet; } BOOL CKTCadUtility::GetSystemVar(LPCTSTR pszVarName, double& dVal) { BOOL bRet = FALSE; struct resbuf rb; ZeroMemory(&rb, sizeof(struct resbuf)); acedGetVar(pszVarName, &rb); AcDb::DwgDataType iType = ResBufType2DwgDataType(rb.restype); if (iType == AcDb::kDwgReal) { dVal = rb.resval.rreal; bRet = TRUE; } FreeResBuf(&rb); return bRet; } BOOL CKTCadUtility::GetSystemVar(LPCTSTR pszVarName, CString& sVal) { BOOL bRet = FALSE; struct resbuf rb; ZeroMemory(&rb, sizeof(struct resbuf)); acedGetVar(pszVarName, &rb); AcDb::DwgDataType iType = ResBufType2DwgDataType(rb.restype); if (iType == AcDb::kDwgText) { sVal = rb.resval.rstring; bRet = TRUE; } FreeResBuf(&rb); return bRet; } BOOL CKTCadUtility::GetSystemVar(LPCTSTR pszVarName, ads_point ptVal) { BOOL bRet = FALSE; struct resbuf rb; ZeroMemory(&rb, sizeof(struct resbuf)); acedGetVar(pszVarName, &rb); AcDb::DwgDataType iType = ResBufType2DwgDataType(rb.restype); if (iType == AcDb::kDwg3Real) { CopyMemory(ptVal, rb.resval.rpoint, sizeof(ads_point)); bRet = TRUE; } FreeResBuf(&rb); return bRet; } // 设置系统变量值 BOOL CKTCadUtility::SetSystemVar(LPCTSTR pszVarName, short iVal) { struct resbuf rb; ZeroMemory(&rb, sizeof(struct resbuf)); rb.restype = RTSHORT; rb.resval.rint = iVal; return (acedSetVar(pszVarName, &rb) == RTNORM); } BOOL CKTCadUtility::SetSystemVar(LPCTSTR pszVarName, int iVal) { struct resbuf rb; ZeroMemory(&rb, sizeof(struct resbuf)); rb.restype = RTSHORT; rb.resval.rint = iVal; return (acedSetVar(pszVarName, &rb) == RTNORM); } BOOL CKTCadUtility::SetSystemVar(LPCTSTR pszVarName, long lVal) { struct resbuf rb; ZeroMemory(&rb, sizeof(struct resbuf)); rb.restype = RTLONG; rb.resval.rlong = lVal; return (acedSetVar(pszVarName, &rb) == RTNORM); } BOOL CKTCadUtility::SetSystemVar(LPCTSTR pszVarName, double dVal) { struct resbuf rb; ZeroMemory(&rb, sizeof(struct resbuf)); rb.restype = RTREAL; rb.resval.rreal = dVal; return (acedSetVar(pszVarName, &rb) == RTNORM); } BOOL CKTCadUtility::SetSystemVar(LPCTSTR pszVarName, LPCTSTR pszVal) { struct resbuf rb; ZeroMemory(&rb, sizeof(struct resbuf)); rb.restype = RTSTR; rb.resval.rstring = (LPTSTR)pszVal; return (acedSetVar(pszVarName, &rb) == RTNORM); } BOOL CKTCadUtility::SetSystemVar(LPCTSTR pszVarName, ads_point ptVal) { struct resbuf rb; ZeroMemory(&rb, sizeof(struct resbuf)); rb.restype = RT3DPOINT; CopyMemory(rb.resval.rpoint, ptVal, sizeof(ads_point)); return (acedSetVar(pszVarName, &rb) == RTNORM); } // 加入块表记录 Acad::ErrorStatus CKTCadUtility::AddToBlockTableRecord(AcDbEntity* pEnt, // 实体对象 LPCTSTR pszBlock, // 块名, 默认为模型空间 AcDbDatabase* pDb) // 数据库名, 默认为当前数据库 { AcDbObjectId idEnt; return CKTCadUtility::AddToBlockTableRecord(idEnt, pEnt, pszBlock, pDb); } // 加入块表记录 Acad::ErrorStatus CKTCadUtility::AddToBlockTableRecord(AcDbObjectId& idEnt, // 返回对象ID AcDbEntity* pEnt, // 实体对象 LPCTSTR pszBlock, // 块名, 默认为模型空间 AcDbDatabase* pDb) // 数据库名, 默认为当前数据库 { ASSERT(pEnt != NULL); if (pDb == NULL) { pDb = acdbHostApplicationServices()->workingDatabase(); } ASSERT(pDb != NULL); if (pszBlock == NULL) { pszBlock = ACDB_MODEL_SPACE; } AcDbBlockTable* pBT = NULL; Acad::ErrorStatus es = pDb->getBlockTable(pBT, AcDb::kForRead); if (es == Acad::eOk) { ASSERT(pBT != NULL); AcDbBlockTableRecord* pBTR = NULL; es = pBT->getAt(pszBlock, pBTR, AcDb::kForWrite); pBT->close(); if (es == Acad::eOk) { ASSERT(pBTR != NULL); es = pBTR->appendAcDbEntity(idEnt, pEnt); pBTR->close(); } } return es; } Acad::ErrorStatus CKTCadUtility::AddToCurrentSpace(AcDbEntity* pEnt) { ASSERT(pEnt != NULL); AcDbDatabase* pDb = acdbHostApplicationServices()->workingDatabase(); ASSERT(pDb != NULL); AcDbBlockTableRecord* pBTR = NULL; Acad::ErrorStatus es = acdbOpenObject(pBTR, pDb->currentSpaceId(), AcDb::kForWrite); if (es != Acad::eOk) return es; es = pBTR->appendAcDbEntity(pEnt); pBTR->close(); return es; } Acad::ErrorStatus CKTCadUtility::AddToCurrentSpace(AcDbEntity* pEnt, AcDbObjectId& idEnt) { ASSERT(pEnt != NULL); AcDbDatabase* pDb = acdbHostApplicationServices()->workingDatabase(); ASSERT(pDb != NULL); AcDbBlockTableRecord* pBTR = NULL; Acad::ErrorStatus es = acdbOpenObject(pBTR, pDb->currentSpaceId(), AcDb::kForWrite); if (es != Acad::eOk) return es; es = pBTR->appendAcDbEntity(idEnt, pEnt); pBTR->close(); return es; } // 在相同Database中,拷贝实体, 仅适合简单实体, 且复制对象没有加入数据库 Acad::ErrorStatus CKTCadUtility::CloneObject(AcDbObject*& pObjDest, const AcDbObject* pObjSrc) { ASSERT(pObjSrc != NULL); BOOL bCreate = FALSE; if (pObjDest == NULL) { pObjDest = (AcDbObject*)pObjSrc->isA()->create(); KTCHECK(pObjDest != NULL); bCreate = TRUE; } else { if (!pObjDest->isKindOf(pObjSrc->isA())) return Acad::eWrongObjectType; } Acad::ErrorStatus es; AcDbDeepCloneFiler filer; if ((es = pObjSrc->dwgOut(&filer)) != Acad::eOk) { if (bCreate) { DELETE_PTR(pObjDest); } return es; } filer.seek(0l, AcDb::kSeekFromStart); if ((es = pObjDest->dwgIn(&filer)) != Acad::eOk) { if (bCreate) { DELETE_PTR(pObjDest); } } return es; } // 在相同Database中,拷贝实体数据, 仅适合加入数据库的实体, pObjDest必须传入NULL Acad::ErrorStatus CKTCadUtility::DeepCloneObject(AcDbObject*& pObjDest, // 返回目标对象 AcDbObject* pObjSrc, // 被拷贝对象 AcDbObjectId idOwner) // 目标对象的属主 { ASSERT(pObjDest == NULL && pObjSrc != NULL); AcDbObjectId id = pObjSrc->objectId(); if (!id.isValid()) return Acad::eNotInDatabase; AcDbDatabase* pDb = pObjSrc->database(); ASSERT(pDb != NULL); BOOL bWrite = pObjSrc->isWriteEnabled(); if (bWrite) pObjSrc->downgradeOpen(); if (!idOwner.isValid()) idOwner = pObjSrc->ownerId(); AcDbIdMapping idMap; AcDbObjectIdArray arid; arid.append(id); Acad::ErrorStatus es = pDb->deepCloneObjects(arid, idOwner, idMap, false); if (bWrite) pObjSrc->upgradeOpen(); if (es != Acad::eOk) return es; AcDbIdPair pair; pair.setKey(id); idMap.compute(pair); ASSERT(pair.value().isValid()); return acdbOpenObject(pObjDest, pair.value(), AcDb::kForWrite); } // 创建一个块,如果块名为NULL则为无名块 AcDbObjectId CKTCadUtility::CreateBlockTableRecord(AcDbVoidPtrArray& arpEnt, const AcGePoint3d& ptOrigin, LPCTSTR pszBlk, AcDbDatabase* pDb, BOOL bDeleteSrc) { AcDbObjectId id; if (pDb == NULL) { pDb = acdbHostApplicationServices()->workingDatabase(); } ASSERT(pDb != NULL); AcDbBlockTable* pBT = NULL; pDb->getSymbolTable(pBT, AcDb::kForWrite); if (pBT == NULL) return id; BOOL bAnonymous = (pszBlk == NULL || _tcslen(pszBlk) <= 0); if (!bAnonymous && pBT->has(pszBlk)) { pBT->close(); return id; } AcDbBlockTableRecord* pBTR = new AcDbBlockTableRecord; KTCHECK(pBTR != NULL); pBT->add(id, pBTR); if (!id.isValid()) { DELETE_PTR(pBTR); pBT->close(); return id; } pBT->close(); if (bAnonymous) pBTR->setName(_T("*U")); else pBTR->setName(pszBlk); pBTR->setOrigin(ptOrigin); AcDbEntity* pEnt; int iLen = arpEnt.length(); for (int i = iLen - 1; i >= 0; i--) { pEnt = (AcDbEntity*)arpEnt[i]; ASSERT(pEnt != NULL && pEnt->isKindOf(AcDbEntity::desc())); if (pEnt->objectId().isValid()) continue; if (pBTR->appendAcDbEntity(pEnt) == Acad::eOk) pEnt->close(); else DELETE_PTR(pEnt); arpEnt.removeAt(i); } pBTR->close(); AcDbEntity* pCpyEnt; iLen = arpEnt.length(); for (int i = iLen - 1; i >= 0; i--) { pEnt = (AcDbEntity*)arpEnt[i]; ASSERT(pEnt != NULL && pEnt->isKindOf(AcDbEntity::desc())); ASSERT(pEnt->objectId().isValid()); pCpyEnt = NULL; CKTCadUtility::DeepCloneObject((AcDbObject*&)pCpyEnt, pEnt, id); pCpyEnt->close(); if (bDeleteSrc && (pEnt->isWriteEnabled() || pEnt->upgradeOpen() == Acad::eOk)) pEnt->erase(); pEnt->close(); arpEnt.removeAt(i); } return id; } AcDbObjectId CKTCadUtility::CreateBlockTableRecord(AcDbObjectIdArray& arid, const AcGePoint3d& ptOrigin, LPCTSTR pszBlk, AcDbDatabase* pDb, BOOL bDeleteSrc) { AcDbObjectId id; if (pDb == NULL) { pDb = acdbHostApplicationServices()->workingDatabase(); } ASSERT(pDb != NULL); AcDbBlockTable* pBT = NULL; pDb->getSymbolTable(pBT, AcDb::kForWrite); if (pBT == NULL) return id; BOOL bAnonymous = (pszBlk == NULL || _tcslen(pszBlk) <= 0); if (!bAnonymous && pBT->has(pszBlk)) { pBT->close(); return id; } AcDbBlockTableRecord* pBTR = new AcDbBlockTableRecord; KTCHECK(pBTR != NULL); pBT->add(id, pBTR); if (!id.isValid()) { DELETE_PTR(pBTR); pBT->close(); return id; } pBT->close(); if (bAnonymous) pBTR->setName(_T("*U")); else pBTR->setName(pszBlk); pBTR->setOrigin(ptOrigin); pBTR->close(); AcDbEntity* pEnt; AcDbEntity* pCpyEnt; int iLen = arid.length(); for (int i = iLen - 1; i >= 0; i--) { ASSERT(arid[i].isValid()); if (acdbOpenObject(pEnt, arid[i], AcDb::kForRead) != Acad::eOk) continue; ASSERT(pEnt != NULL && pEnt->isKindOf(AcDbEntity::desc())); pCpyEnt = NULL; CKTCadUtility::DeepCloneObject((AcDbObject*&)pCpyEnt, pEnt, id); pCpyEnt->close(); if (bDeleteSrc && pEnt->upgradeOpen() == Acad::eOk) pEnt->erase(); pEnt->close(); arid.removeAt(i); } return id; } AcDbObjectId CKTCadUtility::CreateBlockTableRecord(AcDbObjectIdArray& arid, const AcGePoint3d& ptOrigin, LPCTSTR pszBlk, LPCTSTR pszComments, AcDbDatabase* pDb, BOOL bDeleteSrc) { AcDbObjectId id; if (pDb == NULL) { pDb = acdbHostApplicationServices()->workingDatabase(); } ASSERT(pDb != NULL); AcDbBlockTable* pBT = NULL; pDb->getSymbolTable(pBT, AcDb::kForWrite); if (pBT == NULL) return id; BOOL bAnonymous = (pszBlk == NULL || _tcslen(pszBlk) <= 0); if (!bAnonymous && pBT->has(pszBlk)) { pBT->close(); return id; } AcDbBlockTableRecord* pBTR = new AcDbBlockTableRecord; KTCHECK(pBTR != NULL); if (pszComments != NULL) pBTR->setComments(pszComments); pBT->add(id, pBTR); if (!id.isValid()) { DELETE_PTR(pBTR); pBT->close(); return id; } pBT->close(); if (bAnonymous) pBTR->setName(_T("*U")); else pBTR->setName(pszBlk); pBTR->setOrigin(ptOrigin); pBTR->close(); AcDbEntity* pEnt; AcDbEntity* pCpyEnt; int iLen = arid.length(); for (int i = iLen - 1; i >= 0; i--) { ASSERT(arid[i].isValid()); if (acdbOpenObject(pEnt, arid[i], AcDb::kForRead) != Acad::eOk) continue; ASSERT(pEnt != NULL && pEnt->isKindOf(AcDbEntity::desc())); pCpyEnt = NULL; CKTCadUtility::DeepCloneObject((AcDbObject*&)pCpyEnt, pEnt, id); pCpyEnt->close(); if (bDeleteSrc && pEnt->upgradeOpen() == Acad::eOk) pEnt->erase(); pEnt->close(); arid.removeAt(i); } return id; } // 创建一个组,如果组名为NULL则为无名组 AcDbObjectId CKTCadUtility::CreateAcDbGroup(const AcDbObjectIdArray& arid, LPCTSTR pszGroup, bool bSelectable) { AcDbObjectId id; AcDbDatabase* pDb = acdbHostApplicationServices()->workingDatabase(); ASSERT(pDb != NULL); AcDbDictionary* pDict = NULL; pDb->getGroupDictionary(pDict, AcDb::kForWrite); if (pDict == NULL) return id; BOOL bAnonymous = (pszGroup == NULL || _tcslen(pszGroup) <= 0); if (!bAnonymous && pDict->has(pszGroup)) { pDict->close(); return id; } AcDbGroup* pGroup = new AcDbGroup; KTCHECK(pGroup != NULL); pDict->setAt(_T("*A"), pGroup, id); if (!id.isValid()) { DELETE_PTR(pGroup); pDict->close(); return id; } pDict->close(); pGroup->setSelectable(bSelectable); if (bAnonymous) pGroup->setAnonymous(); else pGroup->setName((LPTSTR)pszGroup); pGroup->append(arid); pGroup->close(); return id; } bool CKTCadUtility::AddEntToGroup(AcDbObjectId &id2, AcDbObjectId &idGroup) { AcDbGroup *pGroup = NULL; if (Acad::eOk == acdbOpenObject(pGroup, idGroup, AcDb::kForWrite)) { pGroup->append(id2); pGroup->close(); return true; } return false; } int CKTCadUtility::GetItemGroups(const AcDbObjectId& idObj, AcDbObjectIdArray& aridGroups) { AcDbObject* pObj = NULL; acdbOpenObject(pObj, idObj, AcDb::kForRead); if (NULL == pObj) return 0; const AcDbVoidPtrArray* pReactors = pObj->reactors(); pObj->close(); if (NULL == pReactors) return 0; void *pSomething; AcDbGroup* pGroup; AcDbObjectId idGroup; int iPos = pReactors->length(); while ((--iPos) >= 0) { pSomething = pReactors->at(iPos); if (!acdbIsPersistentReactor(pSomething)) continue; idGroup = acdbPersistentReactorObjectId(pSomething); if (Acad::eOk != acdbOpenObject(pGroup, idGroup, AcDb::kForRead)) continue; aridGroups.append(idGroup); pGroup->close(); } return aridGroups.length(); } int CKTCadUtility::GetGroupItems(const AcDbObjectId& idGroup, AcDbObjectIdArray& aridObjs) { AcDbGroup* pGroup = NULL; acdbOpenObject(pGroup, idGroup, AcDb::kForRead); if (NULL == pGroup) return 0; pGroup->allEntityIds(aridObjs); pGroup->close(); return aridObjs.length(); } // 自动区分动态库类型,并加载它 HINSTANCE CKTCadUtility::LoadApplication(CString sPathName) { // 保存当前路径设置 CString sEnvironment; DWORD dwSize = GetEnvironmentVariable(_T("PATH"), NULL, 0); GetEnvironmentVariable(_T("PATH"), sEnvironment.GetBuffer(dwSize), dwSize); sEnvironment.ReleaseBuffer(); // 设置加载路径 sPathName.Replace(_T('/'), _T('\\')); int iFind = sPathName.ReverseFind(_T('\\')) + 1; if (iFind > 0) { CString sPath = sPathName.Left(iFind); SetEnvironmentVariable(_T("PATH"), sPath + _T(';') + sEnvironment); } // 装入动态库 HINSTANCE hDll = AfxLoadLibrary(sPathName); if (hDll == NULL) { // 恢复路径设置 if (!sEnvironment.IsEmpty()) SetEnvironmentVariable(_T("PATH"), sEnvironment); return NULL; } // 判断文件类型 KT::EAppType eType = KT::eUnknownApp; if (GetProcAddress(hDll, "acrxEntryPoint") != NULL) eType = KT::eArxApp; else eType = KT::eDllApp; // 根据不同类型, 使用不同方式加载 switch (eType) { case KT::eArxApp: AfxFreeLibrary(hDll); if (acrxLoadModule(sPathName, FALSE)) hDll = GetModuleHandle(sPathName); else hDll = NULL; break; case KT::eDllApp: break; default: AfxFreeLibrary(hDll); hDll = NULL; break; } // 恢复路径设置 if (!sEnvironment.IsEmpty()) SetEnvironmentVariable(_T("PATH"), sEnvironment); return hDll; } // 自动区分动态库类型,并卸载它 BOOL CKTCadUtility::UnloadApplication(HINSTANCE hDll) { // 判断文件类型 KT::EAppType eType = KT::eUnknownApp; if (GetProcAddress(hDll, "acrxEntryPoint") != NULL) eType = KT::eArxApp; else eType = KT::eDllApp; // 根据不同类型, 使用不同方式加载 BOOL bSuccess = FALSE; CString sFile; switch (eType) { case KT::eArxApp: GetModuleFileName(hDll, sFile.GetBuffer(MAX_PATH), MAX_PATH); sFile.ReleaseBuffer(); bSuccess = acrxUnloadModule(sFile); break; case KT::eDllApp: bSuccess = AfxFreeLibrary(hDll); break; default: break; } return bSuccess; } // 自动区分动态库类型,并卸载它 BOOL CKTCadUtility::UnloadApplication(LPCTSTR pszAppFile) { HINSTANCE hDll = GetModuleHandle(pszAppFile); if (hDll != NULL) { return CKTCadUtility::UnloadApplication(hDll); } return FALSE; } // 取得当前视口的数据 BOOL CKTCadUtility::GetActiveViewPortInfo(double &dHeight, // 高度 double &dWidth, // 宽度 AcGePoint3d &ptTarget, // 目标点 AcGeVector3d &vecViewDir, // 方向 double &dViewTwist, // ViewTwist BOOL bGetViewCenter) // 是否取视口中心 { // get the working db AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase(); // if not ok if (pDb == NULL) return FALSE; // lock current document CKTTempLockDoc docLock; // make sure the active view port is uptodate acedVports2VportTableRecords(); // open the view port records AcDbViewportTable *pVTable = NULL; Acad::ErrorStatus es = pDb->getViewportTable(pVTable, AcDb::kForRead); // if we opened them ok if (es == Acad::eOk) { AcDbViewportTableRecord *pViewPortRec = NULL; es = pVTable->getAt(_T("*Active"), pViewPortRec, AcDb::kForRead); if (es == Acad::eOk) { // get the height of the view dHeight = pViewPortRec->height(); // get the width dWidth = pViewPortRec->width(); // if the user wants the center of the viewport used if (bGetViewCenter) { struct resbuf rb; memset (&rb, 0, sizeof(struct resbuf)); // get the system var VIEWCTR acedGetVar(_T("VIEWCTR"), &rb); // set that as the target ptTarget = AcGePoint3d(rb.resval.rpoint[X], rb.resval.rpoint[Y], rb.resval.rpoint[Z]); } else { // we want the viewports camera target setting // get the target of the view ptTarget = pViewPortRec->target(); } // get the view direction vecViewDir = pViewPortRec->viewDirection(); // get the view twist of the viewport dViewTwist = pViewPortRec->viewTwist(); } // close after use pVTable->close(); pViewPortRec->close(); } return TRUE; } // 取得当前视口数据 BOOL CKTCadUtility::GetCurrentViewInfo(AcGePoint3d & ptPosition, // 位置点 AcGePoint3d & ptTarget, // 目标点 AcGeVector3d& vecUpVector, // UpVector double& dFieldWidth, // 宽度 double& dFieldHeight) // 高度 { // get the view port information - see parameter list double dHeight = 0.0, dWidth = 0.0, dViewTwist = 0.0; AcGePoint3d ptTargetView; AcGeVector3d vecViewDir; GetActiveViewPortInfo(dHeight, dWidth, ptTargetView, vecViewDir, dViewTwist, TRUE); // we are only interested in the directions of the view, not the sizes, so we normalise. vecViewDir.normalize(); // Our view coordinate space consists of z direction // get a perp vector off the z direction // Make sure its normalised AcGeVector3d vecViewXDir = vecViewDir.perpVector().normal(); // correct the x angle by applying the twist vecViewXDir = vecViewXDir.rotateBy (dViewTwist, -vecViewDir); // now we can work out y, this is of course perp to the x and z directions. No need to normalise this, // as we know that x and z are of unit length, and perpendicular, so their cross product must be on unit length vecUpVector = vecViewDir.crossProduct (vecViewXDir); // the current editor drawing AcDbDatabase* pDb = acdbHostApplicationServices()->workingDatabase(); // Calculate the extents in WCS AcGePoint3d ptExtMax = pDb->extmax(); AcGePoint3d ptExtMin = pDb->extmin(); // find a nice point around which to transform the view. We'll use the same point as the center of the view. ptTarget = ptExtMin + 0.5 * (ptExtMax - ptExtMin); ptPosition = ptTarget + vecViewDir; // create a transform from WCS to View space // this represents the transformation from WCS to the view space. (Actually not quite since // we are keeping the fixed point as the center of the box for convenience ) AcGeMatrix3d matView; matView = AcGeMatrix3d::alignCoordSys(ptTarget, AcGeVector3d::kXAxis, AcGeVector3d::kYAxis, AcGeVector3d::kZAxis, ptTarget, vecViewXDir, vecUpVector, vecViewDir).inverse(); AcDbExtents extWcsExtents(ptExtMin, ptExtMax); // now we have the view Extents AcDbExtents extViewExtents = extWcsExtents; // transforms the extents in WCS->view space extViewExtents.transformBy(matView); // get the extents of the AutoCAD view dFieldWidth = fabs(extViewExtents.maxPoint ().x - extViewExtents.minPoint ().x); dFieldHeight = fabs(extViewExtents.maxPoint ().y - extViewExtents.minPoint ().y); return TRUE; } #if ARX<20 // 取得ShadeMode系统变量值 AcGsView::RenderMode CKTCadUtility::GetShadeMode(int iVP) { int iTileMode; GetSystemVar(_T("TILEMODE"), iTileMode); if (iTileMode == 0) return AcGsView::k2DOptimized; AcGsView * pView = acgsGetGsView(iVP, FALSE); return ((pView != NULL)? pView->mode() : AcGsView::k2DOptimized); } // 取得ShadeMode系统变量值 AcGsView::RenderMode CKTCadUtility::GetCurrentShadeMode() { int iTileMode; GetSystemVar(_T("TILEMODE"), iTileMode); if (iTileMode == 0) return AcGsView::k2DOptimized; int iCurView; GetSystemVar(_T("CVPORT"), iCurView); AcGsView * pView = acgsGetGsView(iCurView, FALSE); return ((pView != NULL)? pView->mode() : AcGsView::k2DOptimized); } #endif BOOL CKTCadUtility::GetCurrentViewSize(double& dWidth, double& dHeight) { ads_point ptScreen; GetSystemVar(_T("VIEWSIZE"), dHeight); GetSystemVar(_T("SCREENSIZE"), ptScreen); dWidth = ptScreen[0] / ptScreen[1] * dHeight; return TRUE; } BOOL CKTCadUtility::GetCurrentViewSize(AcGePoint3d& ptMin, AcGePoint3d& ptMax) { double dWidth, dHeight; GetCurrentViewSize(dWidth, dHeight); ads_point ptViewCtr; GetSystemVar(_T("VIEWCTR"), ptViewCtr); ptMin.set(ptViewCtr[0] - dWidth / 2.0, ptViewCtr[1] - dHeight / 2.0, ptViewCtr[2]); ptMax.set(ptViewCtr[0] + dWidth / 2.0, ptViewCtr[1] + dHeight / 2.0, ptViewCtr[2]); return TRUE; } // 缩放图形窗口 BOOL CKTCadUtility::ZoomExtents() { ads_point pt1, pt2; CKTCadUtility::GetSystemVar(_T("EXTMIN"), pt1); CKTCadUtility::GetSystemVar(_T("EXTMAX"), pt2); return Zoom(asPnt3d(pt1), asPnt3d(pt2)); } BOOL CKTCadUtility::Zoom(const AcGePoint3d& ptMin, const AcGePoint3d& ptMax) { ads_point ptDir; GetSystemVar(_T("VIEWDIR"), ptDir); AcGePlane plane(GetUcsOrigin(), GetUcsZAxis()); AcGePoint2d pt1 = ptMin.convert2d(plane); AcGePoint2d pt2 = ptMax.convert2d(plane); AcGePoint2d pt = GetMiddlePoint(pt1, pt2); AcDbViewTableRecord VTR; VTR.setCenterPoint(pt); VTR.setViewDirection(asVec3d(ptDir)); VTR.setWidth(fabs(pt2.x - pt1.x)); VTR.setHeight(fabs(pt2.y - pt1.y)); return (acedSetCurrentView(&VTR, NULL) == Acad::eOk); } // 平移绘图窗口 BOOL CKTCadUtility::Pan(const AcGeVector3d& vecPan) { ads_point ptDir; GetSystemVar(_T("VIEWDIR"), ptDir); ads_point ptCtr; GetSystemVar(_T("VIEWCTR"), ptCtr); AcGePlane plane(GetUcsOrigin(), GetUcsZAxis()); AcGePoint3d ptNewCtr = asPnt3d(ptCtr) + vecPan; AcGePoint2d pt = ptNewCtr.convert2d(plane); double dWidth, dHeight; GetCurrentViewSize(dWidth, dHeight); AcDbViewTableRecord VTR; VTR.setCenterPoint(pt); VTR.setViewDirection(asVec3d(ptDir)); VTR.setWidth(dWidth); VTR.setHeight(dHeight); return (acedSetCurrentView(&VTR, NULL) == Acad::eOk); } // 将窗口缩放/平移到当前视口中 BOOL CKTCadUtility::ZoomInCurrentView(const AcGePoint3d& ptMin, const AcGePoint3d& ptMax) { AcGePlane plane(GetUcsOrigin(), GetUcsZAxis()); AcGePoint3d ptView1, ptView2; GetCurrentViewSize(ptView1, ptView2); AcGePoint2d ptBox1 = ptView1.convert2d(plane); AcGePoint2d ptBox2 = ptView2.convert2d(plane); AcGePoint2d ptWnd1 = ptMin.convert2d(plane); AcGePoint2d ptWnd2 = ptMax.convert2d(plane); BOOL bPt1In = IsPointInBox(ptWnd1, ptBox1, ptBox2); BOOL bPt2In = IsPointInBox(ptWnd2, ptBox1, ptBox2); // 在视口中无需处理 if (bPt1In && bPt2In) return FALSE; if (fabs(ptWnd2.x - ptWnd1.x) < fabs(ptBox2.x - ptBox1.x) && fabs(ptWnd2.y - ptWnd1.y) < fabs(ptBox2.y - ptBox1.y)) { // 小于视口尺寸, 使用Pan方式 Pan(GetMiddlePoint(ptMin, ptMax) - GetMiddlePoint(ptView1, ptView2)); } else { // 大于视口尺寸, 使用Zoom方式 Zoom(ptMin, ptMax); } return TRUE; } // 取得UCS坐标系统信息 AcGeVector3d CKTCadUtility::GetUcsXAxis() { AcGeVector3d vec; GetSystemVar(_T("UCSXDIR"), asDblArray(vec)); return vec; } AcGeVector3d CKTCadUtility::GetUcsYAxis() { AcGeVector3d vec; GetSystemVar(_T("UCSYDIR"), asDblArray(vec)); return vec; } AcGeVector3d CKTCadUtility::GetUcsZAxis() { return GetUcsXAxis().crossProduct(GetUcsYAxis()); } AcGePoint3d CKTCadUtility::GetUcsOrigin() { AcGePoint3d pt; GetSystemVar(_T("UCSORG"), asDblArray(pt)); return pt; } // 对角度Ucs和Wcs转换 double CKTCadUtility::Ucs2Wcs(double dAngle) { ads_point adsPt = {cos(dAngle), sin(dAngle), 0.0}; acdbUcs2Wcs(adsPt, adsPt, TRUE); ads_point adsOrg = {0.0, 0.0, 0.0}; return acutAngle(adsOrg, adsPt); } double CKTCadUtility::Wcs2Ucs(double dAngle) { ads_point adsPt = {cos(dAngle), sin(dAngle), 0.0}; acdbWcs2Ucs(adsPt, adsPt, TRUE); ads_point adsOrg = {0.0, 0.0, 0.0}; return acutAngle(adsOrg, adsPt); } // 点和向量Ucs和Wcs转换 AcGePoint3d CKTCadUtility::Ucs2Wcs(const AcGePoint3d& pt) { ads_point adsPt; acdbUcs2Wcs(asDblArray(pt), adsPt, FALSE); return asPnt3d(adsPt); } AcGePoint3d CKTCadUtility::Wcs2Ucs(const AcGePoint3d& pt) { ads_point adsPt; acdbWcs2Ucs(asDblArray(pt), adsPt, FALSE); return asPnt3d(adsPt); } AcGeVector3d CKTCadUtility::Ucs2Wcs(const AcGeVector3d& vec) { ads_point adsPt; acdbUcs2Wcs(asDblArray(vec), adsPt, TRUE); return asVec3d(adsPt); } AcGeVector3d CKTCadUtility::Wcs2Ucs(const AcGeVector3d& vec) { ads_point adsPt; acdbWcs2Ucs(asDblArray(vec), adsPt, TRUE); return asVec3d(adsPt); } // 取得屏幕和视口转换 int CKTCadUtility::Wcs2Pixel(double dLen) { double dViewSize; ads_point ptScreen; GetSystemVar(_T("VIEWSIZE"), dViewSize); GetSystemVar(_T("SCREENSIZE"), ptScreen); if (_IsZero_(dViewSize)) return 0; else return int((ptScreen[1] / dViewSize) * dLen + 0.5); } CPoint CKTCadUtility::Wcs2Pixel(const AcGePoint3d& pt) { CPoint ptRet; int iCVPort = 2; GetSystemVar(_T("CVPORT"), iCVPort); acedCoordFromWorldToPixel(iCVPort, asDblArray(pt), ptRet); return ptRet; } double CKTCadUtility::Pixel2Wcs(int iLen) { double dViewSize; ads_point ptScreen; GetSystemVar(_T("VIEWSIZE"), dViewSize); GetSystemVar(_T("SCREENSIZE"), ptScreen); if (_IsZero_(ptScreen[1])) return 0.0; else return ((dViewSize / ptScreen[1]) * iLen); } AcGePoint3d CKTCadUtility::Pixel2Wcs(const CPoint& pt) { AcGePoint3d ptRet; int iCVPort = 2; GetSystemVar(_T("CVPORT"), iCVPort); acedCoordFromPixelToWorld(iCVPort, pt, asDblArray(ptRet)); return ptRet; } // 得到耙区在WCS下的大小 double CKTCadUtility::GetApertureSize() { int iAperture = 1; GetSystemVar(_T("APERTURE"), iAperture); return Pixel2Wcs(iAperture); } // 得到拾取框在WCS下的大小 double CKTCadUtility::GetPickBoxSize() { int iPickBox = 0; GetSystemVar(_T("PICKBOX"), iPickBox); return Pixel2Wcs(iPickBox); } // 取得两点构成的立方体的最小点/最大点 AcGePoint3d CKTCadUtility::GetMinPoint(const AcGePoint3d& pt1, const AcGePoint3d& pt2) { AcGePoint3d pt; pt.x = min(pt1.x, pt2.x); pt.y = min(pt1.y, pt2.y); pt.z = min(pt1.z, pt2.z); return pt; } AcGePoint3d CKTCadUtility::GetMaxPoint(const AcGePoint3d& pt1, const AcGePoint3d& pt2) { AcGePoint3d pt; pt.x = max(pt1.x, pt2.x); pt.y = max(pt1.y, pt2.y); pt.z = max(pt1.z, pt2.z); return pt; } AcGePoint2d CKTCadUtility::GetMinPoint(const AcGePoint2d& pt1, const AcGePoint2d& pt2) { AcGePoint2d pt; pt.x = min(pt1.x, pt2.x); pt.y = min(pt1.y, pt2.y); return pt; } AcGePoint2d CKTCadUtility::GetMaxPoint(const AcGePoint2d& pt1, const AcGePoint2d& pt2) { AcGePoint2d pt; pt.x = max(pt1.x, pt2.x); pt.y = max(pt1.y, pt2.y); return pt; } // 判断点是否在立体框内 BOOL CKTCadUtility::IsPointInBox(const AcGePoint3d pt, const AcGePoint3d& ptBox1, const AcGePoint3d& ptBox2) { AcGePoint3d pt1 = GetMinPoint(ptBox1, ptBox2); AcGePoint3d pt2 = GetMaxPoint(ptBox1, ptBox2); return (!(pt.x < pt1.x || pt.x > pt2.x || pt.y < pt1.y || pt.y > pt2.y || pt.z < pt1.z || pt.z > pt2.z)); } BOOL CKTCadUtility::IsPointInBox(const AcGePoint2d pt, const AcGePoint2d& ptBox1, const AcGePoint2d& ptBox2) { AcGePoint2d pt1 = GetMinPoint(ptBox1, ptBox2); AcGePoint2d pt2 = GetMaxPoint(ptBox1, ptBox2); return (!(pt.x < pt1.x || pt.x > pt2.x || pt.y < pt1.y || pt.y > pt2.y)); } // 取得中点 AcGePoint3d CKTCadUtility::GetMiddlePoint(const AcGePoint3d& pt1, const AcGePoint3d& pt2) { AcGePoint3d pt((pt1.x + pt2.x) / 2.0, (pt1.y + pt2.y) / 2.0, (pt1.z + pt2.z) / 2.0); return pt; } AcGePoint2d CKTCadUtility::GetMiddlePoint(const AcGePoint2d& pt1, const AcGePoint2d& pt2) { AcGePoint2d pt((pt1.x + pt2.x) / 2.0, (pt1.y + pt2.y) / 2.0); return pt; } // acutPolar包装 AcGePoint3d CKTCadUtility::GetPolarPoint(const AcGePoint3d& ptBase, double dAngle, double dDistance) { AcGePoint3d pt; acutPolar(asDblArray(ptBase), dAngle, dDistance, asDblArray(pt)); return pt; } // acutAngle包装 double CKTCadUtility::GetAngle(const AcGePoint3d& pt1, const AcGePoint3d& pt2) { return acutAngle(asDblArray(pt1), asDblArray(pt2)); } double CKTCadUtility::GetAngle(const AcGePoint2d& pt1, const AcGePoint2d& pt2) { return acutAngle(asDblArray(pt1), asDblArray(pt2)); } double CKTCadUtility::GetAngle(const AcGeVector3d& vec) { return acutAngle(asDblArray(AcGePoint3d::kOrigin), asDblArray(vec)); } double CKTCadUtility::GetAngle(const AcGeVector2d& vec) { return acutAngle(asDblArray(AcGePoint2d::kOrigin), asDblArray(vec)); } double CKTCadUtility::GetAngle(const AcGeVector3d& vec1, const AcGeVector3d& vec2) { AcGeVector3d v1 = vec1.project(vec2, vec2); AcGeVector3d v2 = vec2.perpVector(); double dAngle = GetAngle(AcGePoint3d::kOrigin, (AcGePoint3d&)v1, vec2) - GetAngle(AcGePoint3d::kOrigin, (AcGePoint3d&)v2, vec2); if (dAngle < 0.0) dAngle += _2PI; if (dAngle < PI_2) dAngle = -dAngle; else if (dAngle < PI * 1.5) dAngle = PI - dAngle; else dAngle = _2PI - dAngle; v1 = vec1; v2 = vec2.crossProduct(v2); v1.rotateBy(dAngle, vec2); dAngle = GetAngle(AcGePoint3d::kOrigin, (AcGePoint3d&)v1, v2) - GetAngle(AcGePoint3d::kOrigin, (AcGePoint3d&)vec2, v2); return (dAngle < 0.0 ? _2PI + dAngle : dAngle); } double CKTCadUtility::GetAngle(const AcGePoint3d& pt1, const AcGePoint3d& pt2, const AcGeVector3d& vecNormal) { AcGePlane plane(AcGePoint3d::kOrigin, vecNormal); return GetAngle(pt1.convert2d(plane), pt2.convert2d(plane)); } // 由起点到终点和bulge定义的圆弧,求圆弧中心,半径,始末角 BOOL CKTCadUtility::GetArcParam(const AcGePoint3d& ptStart, const AcGePoint3d&ptEnd, double dBulge, const AcGeVector3d& vecNormal, AcGePoint3d& ptCenter, double& dRadius, double& dStartAngle, double& dEndAngle) { if (fabs(dBulge) < m_KTTol || ptStart == ptEnd) return FALSE; // 圆心角 double dAngle1 = atan(fabs(dBulge)) * 4.0; // 等腰三角形底角 double dAngle2 = (PI - dAngle1) / 2.0; // 正弦定律求半径 double dDistance = ptStart.distanceTo(ptEnd); dRadius = dDistance / sin(dAngle1) * sin(dAngle2); AcGeVector3d vec = ptEnd - ptStart; vec.normalize(); vec.rotateBy(dBulge > 0.0 ? dAngle2 : -dAngle2, vecNormal); ptCenter = ptStart + vec * dRadius; if (dBulge > 0) { dStartAngle = GetAngle(ptCenter, ptStart, vecNormal); dEndAngle = GetAngle(ptCenter, ptEnd, vecNormal); } else { dEndAngle = GetAngle(ptCenter, ptStart, vecNormal); dStartAngle = GetAngle(ptCenter, ptEnd, vecNormal); } return TRUE; } // 比较resbuf数据>, =, < int CKTCadUtility::CompareResBuf(const struct resbuf* pRb1, const struct resbuf* pRb2) { ASSERT(pRb1 != NULL); ASSERT(pRb2 != NULL); int iCmp = pRb1->restype - pRb2->restype; if (iCmp != 0) return iCmp; double dSub; AcDbObjectId id1, id2; AcDbHandle handle1, handle2; switch (ResBufType2DwgDataType(pRb1->restype)) { case AcDb::kDwgInt8: iCmp = pRb1->resval.rint - pRb2->resval.rint; break; case AcDb::kDwgInt16: iCmp = pRb1->resval.rint - pRb2->resval.rint; break; case AcDb::kDwgInt32: iCmp = pRb1->resval.rlong - pRb2->resval.rlong; break; case AcDb::kDwgReal: dSub = pRb1->resval.rreal - pRb2->resval.rreal; iCmp = int(dSub); iCmp += (dSub > iCmp); iCmp -= (dSub < iCmp); break; case AcDb::kDwgText: iCmp = _tcscmp(pRb1->resval.rstring, pRb2->resval.rstring); break; case AcDb::kDwg3Real: dSub = pRb1->resval.rpoint[0] - pRb2->resval.rpoint[0]; iCmp = int(dSub); iCmp += (dSub > iCmp); iCmp -= (dSub < iCmp); if (iCmp == 0) { dSub = pRb1->resval.rpoint[1] - pRb2->resval.rpoint[1]; iCmp = int(dSub); iCmp += (dSub > iCmp); iCmp -= (dSub < iCmp); } if (iCmp == 0) { dSub = pRb1->resval.rpoint[2] - pRb2->resval.rpoint[2]; iCmp = int(dSub); iCmp += (dSub > iCmp); iCmp -= (dSub < iCmp); } break; case AcDb::kDwgHardOwnershipId: case AcDb::kDwgSoftOwnershipId: case AcDb::kDwgHardPointerId: case AcDb::kDwgSoftPointerId: acdbGetObjectId(id1, pRb1->resval.rlname); acdbGetObjectId(id2, pRb2->resval.rlname); iCmp = (int)(id1.asOldId() - id2.asOldId()); break; case AcDb::kDwgHandle: handle1.copyFromOldType(pRb1->resval.ihandle); handle2.copyFromOldType(pRb1->resval.ihandle); iCmp = (Adesk::UInt32)handle1 - (Adesk::UInt32)handle2; break; case AcDb::kDwgBChunk: iCmp = pRb1->resval.rbinary.clen - pRb2->resval.rbinary.clen; break; case AcDb::kDwgNull: break; case AcDb::kDwgNotRecognized: break; default: break; } return iCmp; } // 拷贝Resbuf, 如有string和binary, 也拷贝 BOOL CKTCadUtility::CopyResBuf(struct resbuf* pRbDest, const struct resbuf* pRbSrc) { ASSERT(pRbDest != NULL); ASSERT(pRbSrc != NULL); pRbDest->restype = pRbSrc->restype; CopyMemory(&pRbDest->resval, &pRbSrc->resval, sizeof(ads_u_val)); switch (ResBufType2DwgDataType(pRbDest->restype)) { case AcDb::kDwgText: if (acutNewString(pRbSrc->resval.rstring, pRbDest->resval.rstring) != Acad::eOk) { pRbDest->resval.rstring = NULL; return FALSE; } break; case AcDb::kDwgBChunk: if (acutNewBuffer(pRbDest->resval.rbinary.buf, pRbSrc->resval.rbinary.clen) != Acad::eOk) { pRbDest->resval.rbinary.clen = 0; pRbDest->resval.rbinary.buf = NULL; return FALSE; } CopyMemory(pRbDest->resval.rbinary.buf, pRbSrc->resval.rbinary.buf, pRbSrc->resval.rbinary.clen); break; } return TRUE; } // 将resbuf中的restype类型(AcDb::kDxfCode和RTREAL, RT..)转换为AcDb::DwgDataType类型 AcDb::DwgDataType CKTCadUtility::ResBufType2DwgDataType(int iType) { AcDb::DwgDataType restype; switch (iType) { case RTSHORT: restype = AcDb::kDwgInt16; break; case RTLONG: restype = AcDb::kDwgInt32; break; case RTREAL: case RTANG: case RTORINT: restype = AcDb::kDwgReal; break; case RTSTR: case RTDXF0: restype = AcDb::kDwgText; break; case RTPOINT: case RT3DPOINT: restype = AcDb::kDwg3Real; break; case RTENAME: case RTPICKS: restype = AcDb::kDwgSoftPointerId; break; case RTNONE: case RTVOID: restype = AcDb::kDwgNull; break; case RTLB: case RTLE: case RTDOTE: case RTNIL: case RTT: case RTRESBUF: restype = AcDb::kDwgNotRecognized; break; default: restype = acdbGroupCodeToType(iType); break; } return restype; } // 将resbuf中有效的string和binary中的内容释放掉(释放当前节点), 其它数据不变 void CKTCadUtility::FreeResBuf(struct resbuf* pRb) { ASSERT(pRb != NULL); switch (ResBufType2DwgDataType(pRb->restype)) { case AcDb::kDwgText: if (pRb->resval.rstring != NULL) { acutDelString(pRb->resval.rstring); pRb->resval.rstring = NULL; } break; case AcDb::kDwgBChunk: if (pRb->resval.rbinary.buf != NULL) { acutDelBuffer(pRb->resval.rbinary.buf); pRb->resval.rbinary.buf = NULL; pRb->resval.rbinary.clen = 0; } break; } } // 将rbList中所有内容都释放掉 void CKTCadUtility::FreeRbList(struct resbuf* pRbList) { for (struct resbuf* pTemp = pRbList; pTemp != NULL; pTemp = pTemp->rbnext) { FreeResBuf(pTemp); } acutRelRb(pRbList); } // 取得当前选择集 BOOL CKTCadUtility::GetCurrentPickSet(ads_name ssSet, const struct resbuf* pRbFilter) { return (acedSSGet(_T("I"), NULL, NULL, pRbFilter, ssSet) == RTNORM); } // 判断实体是否符合过滤表 BOOL CKTCadUtility::FilterEntity(ads_name adsEnt, const struct resbuf* pRbFilter) { if (pRbFilter == NULL) return TRUE; ads_name ssSet; if (acedSSGet(_T("X"), NULL, NULL, pRbFilter, ssSet) != RTNORM) return TRUE; BOOL bMatch = (acedSSMemb(adsEnt, ssSet) == RTNORM); acedSSFree(ssSet); return bMatch; } // 按给定的过滤表选择实体(考虑当前选择集) int CKTCadUtility::SelectEntity(LPCTSTR pszPrompt, ads_name adsEnt, const struct resbuf* pRbFilter, ads_point adsPt, int iFlag, LPCTSTR pszKeyWord) { ads_name ssSet; if (adsPt == NULL && acedSSGet(_T("I"), NULL, NULL, pRbFilter, ssSet) == RTNORM) { Adesk::Int32 lLen = 0l; BOOL bFind = (acedSSLength(ssSet, &lLen) == RTNORM && lLen == 1l && acedSSName(ssSet, 0l, adsEnt) == RTNORM); acedSSFree(ssSet); if (bFind) { return RTNORM; } } int iRet; ads_name ent; ads_point pt; while (TRUE) { if (iFlag >= 0) acedInitGet(iFlag, pszKeyWord); iRet = acedEntSel(pszPrompt, ent, pt); if (iRet != RTNORM) break; if (FilterEntity(ent, pRbFilter)) { CopyMemory(adsEnt, ent, sizeof(ads_name)); if (adsPt != NULL) CopyMemory(adsPt, pt, sizeof(ads_point)); return RTNORM; } } return iRet; } int CKTCadUtility::SelectEntity1(LPCTSTR pszPrompt, ads_name adsEnt, const struct resbuf* pRbFilter, ads_point adsPt, int iFlag, LPCTSTR pszKeyWord, double dPickTol) { ads_name ssSet; if (adsPt == NULL && acedSSGet(_T("I"), NULL, NULL, pRbFilter, ssSet) == RTNORM) { Adesk::Int32 lLen = 0l; BOOL bFind = (acedSSLength(ssSet, &lLen) == RTNORM && lLen == 1l && acedSSName(ssSet, 0l, adsEnt) == RTNORM); acedSSFree(ssSet); if (bFind) { return RTNORM; } } if (dPickTol < 0.0) dPickTol = GetPickBoxSize(); int iRet; ads_point pt, pt1, pt2; while (TRUE) { if (iFlag >= 0) acedInitGet(iFlag, pszKeyWord); iRet = acedGetPoint(NULL, pszPrompt, pt); if (iRet != RTNORM) break; pt1[0] = pt[0] - dPickTol; pt1[1] = pt[1] - dPickTol; pt1[2] = pt[2]; pt2[0] = pt[0] + dPickTol; pt2[1] = pt[1] + dPickTol; pt2[2] = pt[2]; iRet = acedSSGet(_T("C"), pt1, pt2, pRbFilter, ssSet); if (iRet == RTNORM) { acedSSName(ssSet, 0, adsEnt); acedSSFree(ssSet); if (adsPt != NULL) CopyMemory(adsPt, pt, sizeof(ads_point)); return RTNORM; } } return iRet; } int CKTCadUtility::SelectEntity2(LPCTSTR pszPrompt, ads_name adsEnt, const struct resbuf* pRbFilter) { ads_name ssSet; LPCTSTR pszMsg[] = {pszPrompt, _T("")}; int iRet = acedSSGet(_T(":S:$-I"), pszMsg, NULL, pRbFilter, ssSet); if (iRet != RTNORM) return iRet; acedSSName(ssSet, 0, adsEnt); acedSSFree(ssSet); return iRet; } // 按给定的过滤表选择多个实体(考虑当前选择集) int CKTCadUtility::SelectEntities(LPCTSTR pszPrompt, ads_name ssSet, const struct resbuf* pRbFilter) { LPCTSTR pszMsg[] = {pszPrompt, _T("")}; return acedSSGet(_T(":$-I"), pszMsg, NULL, pRbFilter, ssSet); } int CKTCadUtility::SelectEntities2(LPCTSTR pszPrompt , ads_name ssSet , const resbuf *pRbFilter , LPCTSTR keyWordList , resbuf *(*key_func)(const ACHAR *)) { if (!key_func || !keyWordList) { return SelectEntities(pszPrompt, ssSet, pRbFilter); } else { resbuf *(*oldFunc) (const ACHAR *); acedSSGetKwordCallbackPtr(&oldFunc); acedSSSetKwordCallbackPtr(*key_func); LPCTSTR pszMsg[] = {pszPrompt, _T("")}; int nRes = acedSSGet(_T(":K:$-I"), pszMsg, keyWordList, pRbFilter, ssSet); acedSSSetKwordCallbackPtr(*oldFunc); return nRes; } return 0; } // 将数组中的点都进行旋转变换 void CKTCadUtility::RotateBy(AcGePoint3dArray& arpt, double dAngle, const AcGeVector3d& vecNormal, const AcGePoint3d& ptOrg) { int iLen = arpt.length(); for (int i = 0; i < iLen; i++) { arpt[i].rotateBy(dAngle, vecNormal, ptOrg); } } // 将数组中的向量都进行旋转变换 void CKTCadUtility::RotateBy(AcGeVector3dArray& arvec, double dAngle, const AcGeVector3d& vecNormal) { int iLen = arvec.length(); for (int i = 0; i < iLen; i++) { arvec[i].rotateBy(dAngle, vecNormal); } } // 将数组中的点都进行比例变换 void CKTCadUtility::ScaleBy(AcGePoint3dArray& arpt, double dScale, const AcGePoint3d& ptOrg) { int iLen = arpt.length(); for (int i = 0; i < iLen; i++) { arpt[i] += (arpt[i] - ptOrg) * dScale; } } // 将数组中的向量都进行比例变换 void CKTCadUtility::ScaleBy(AcGeVector3dArray& arvec, double dScale) { int iLen = arvec.length(); for (int i = 0; i < iLen; i++) { arvec[i] *= dScale; } } // 将数组中的点都进行位移变换 void CKTCadUtility::MoveBy(AcGePoint3dArray& arpt, const AcGeVector3d& vecMove) { int iLen = arpt.length(); for (int i = 0; i < iLen; i++) { arpt[i] += vecMove; } } // 将数组中的点都通过xform变换 void CKTCadUtility::TransformBy(AcGePoint3dArray& arpt, const AcGeMatrix3d& xform) { int iLen = arpt.length(); for (int i = 0; i < iLen; i++) { arpt[i].transformBy(xform); } } // 将数组中的向量都通过xform变换 void CKTCadUtility::TransformBy(AcGeVector3dArray& arvec, const AcGeMatrix3d& xform) { int iLen = arvec.length(); for (int i = 0; i < iLen; i++) { arvec[i].transformBy(xform); } } // 将AcDbEntity对象通过矩阵变换,传入的元素必须是AcDbEntity派生的 void CKTCadUtility::TransformBy(AcDbVoidPtrArray& arpEnties, const AcGeMatrix3d& xform) { int iLen = arpEnties.length(); for (int i = 0; i < iLen; i++) { ASSERT(NULL != AcDbEntity::cast((AcRxObject*)arpEnties[i])); ((AcDbEntity*)arpEnties[i])->transformBy(xform); } } // 取得一组点的中心点 AcGePoint3d CKTCadUtility::GetCenterPoint(const AcGePoint3dArray& arpt) { AcDbExtents ext; int iLen = arpt.length(); for (int i = 0; i < iLen; i++) { ext.addPoint(arpt[i]); } return GetMiddlePoint(ext.minPoint(), ext.maxPoint()); } // 求点在直线上的投影点 AcGePoint3d CKTCadUtility::GetProjectPoint(const AcGePoint3d& pt, const AcGePoint3d& ptLine, const AcGeVector3d& vecLine) { double dLen = pt.distanceTo(ptLine); if (dLen < m_KTTol) return pt; double dAngle = CKTCadUtility::GetAngle(vecLine, pt - ptLine); dLen *= cos(dAngle); return (ptLine + vecLine.normal() * dLen); } // 求旋转后的点 AcGePoint3d CKTCadUtility::GetRotatePoint(const AcGePoint3d& pt, double dAngle, const AcGeVector3d& vecNormal, const AcGePoint3d& ptOrg) { AcGePoint3d ptRet(pt); ptRet.rotateBy(dAngle, vecNormal, ptOrg); return ptRet; } // 求旋转后的向量 AcGeVector3d CKTCadUtility::GetRotateVector(const AcGeVector3d& vec, double dAngle, const AcGeVector3d& vecNormal) { AcGeVector3d vecRet(vec); vecRet.rotateBy(dAngle, vecNormal); return vecRet; } BOOL CKTCadUtility::GetTextBox(AcDbExtents& ext, LPCTSTR pszTextStr, LPCTSTR pszTextStyle, double dHeight, double dWidthFactor, double dOblique) { struct resbuf* pRb = acutBuildList(RTDXF0, _T("TEXT"), 1, pszTextStr, 7, pszTextStyle, 40, dHeight, 41, dWidthFactor, 51, dOblique, 0); ASSERT(NULL != pRb); ads_point ptLowLeft, ptUpRight; int iRet = acedTextBox(pRb, ptLowLeft, ptUpRight); ext.addPoint(asPnt3d(ptLowLeft)); ext.addPoint(asPnt3d(ptUpRight)); acutRelRb(pRb); return (RTNORM == iRet); } void EWDimData::writeXDataMap(AcDbEntity *pEnt, const EWSegment &seg, const int idx) { EWFnctNode node = seg.pDeformationJoints[idx]; _tcscpy(node.szStake, seg.szStake); writeXDataMap(pEnt, node); }; void EWDimData::writeXDataMap(AcDbEntity *pEnt, const EWFnctNode &node) { AecDbObjXDataMap map; map.SetAt(_T("dDistFromPre"), node.dDistFromPre); map.SetAt(_T("eFnType"), node.eFnType); CString strSpec(_T("")), strName(_T("")); switch (node.eFnType) { case kStartOrEnd: strSpec = _T("起始位置"); break; case kEspJoint: strSpec = _T("变形缝"); break; case kDrainWell: strSpec = _T("集水井"); break; case kPipeDoghouse: strSpec = _T("管类投料口"); break; case kCableDoghouse: strSpec = _T("线缆类投料口"); break; case kHeatDoghouse: strSpec = _T("热力投料口"); break; case kVenDoghouse: strSpec = _T("通风口"); break; case kFirwWall: strSpec = _T("防火墙"); break; case kEscapeHatch: strSpec = _T("逃生口"); break; case kFireOutlet: strSpec = _T("消防引出口"); break; case kEWOutLethouse: strSpec = _T("水电管廊引出口"); break; case kHTOutLetHouse: strSpec = _T("热力舱引出口"); break; case kCrossUplifted: strSpec = _T("管廊交叉隆起"); break; case kUserDoghouse: strSpec = _T("任意开口上下左右"); break; case kSinkOutletRoom: strSpec = _T("管廊交叉交叉下沉,预制结构"); break; case kSinkOutletRoom20: strSpec = _T("管廊交叉上部八边形上部结构"); break; case kSinkOutletRoom21: strSpec = _T("管廊交叉下沉八边形下部结构"); break; case kProModel: strSpec = node.szNodeDefSpec; strName = node.szNodeSpec; break; case kStackNode: strSpec = _T("里程节点"); break; case kBDOutLetHouse: strSpec = _T("直埋引出"); break; case kSubEspJoint: strSpec = _T("变形缝"); break; default: break; } CString str(_T("")); for (int i = 0; i < 64; ++i) { str.Format(_T("fNodeDef%d"), i); map.SetAt(str, node.fNodeDef[i]); } map.SetAt(_T("szStake"), node.szStake); map.SetAt(_T("szLockId"), node.szLockId); map.SetAt(_T("szNodeSpec"), strSpec); map.SetAt(_T("szNodeName"), strName); //map.SetAt(_T("szNodeDefSpec"), node.szNodeDefSpec); map.SetAt(_T("nRoomIndex"), node.nRoomIndex); map.SetAt(_T("nFlag"), node.nFlag); map.Write(pEnt, _T("DIM_DATA"), false, true); } CString CKTCadUtility::GetCurrentVS() { AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase(); if (pDb == NULL) return _T(""); AcString s; AcDbViewportTable *pVTable = NULL; Acad::ErrorStatus es = pDb->getViewportTable(pVTable, AcDb::kForRead); if (es == Acad::eOk) { AcDbViewportTableRecord *pViewPortRec = NULL; es = pVTable->getAt(_T("*Active"), pViewPortRec, AcDb::kForRead); if (es == Acad::eOk) { AcDbObjectId vsid = pViewPortRec->visualStyle(); AcDbDictionary *pDict; es = pDb->getVisualStyleDictionary(pDict, AcDb::kForRead); if (es == Acad::eOk) { pDict->nameAt(vsid, s); pDict->close(); } } pVTable->close(); pViewPortRec->close(); } return (LPCTSTR)s; }