2111 lines
49 KiB
C++
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;
|
|
} |