Files
envi-code/SourceCode/Code2026/CoreLibrary/KTCadUtility.cpp
T
2026-09-28 15:28:50 +08:00

2111 lines
49 KiB
C++

#include "stdafx.h"
//#include "Resource.h"
#include "KTCadUtility.h"
#include <dbidmap.h>
#include <acutil.h>
#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;
}