800 lines
19 KiB
C++
800 lines
19 KiB
C++
#include "StdAfx.h"
|
||||
|
|
#include "ExternRefClone.h"
|
|||
|
|
#include "DbEquipment.h"
|
|||
|
|
#include "DbPump.h"
|
|||
|
|
#include "DbPool.h"
|
|||
|
|
#include <STACK>
|
|||
|
|
|
|||
|
|
#include "twtdef.h"
|
|||
|
|
#include "tapi.h"
|
|||
|
|
|
|||
|
|
|
|||
|
|
void CreateTwoDimArray(int**& tab, int nLen, int nCap)
|
|||
|
|
{
|
|||
|
|
tab = new int*[nLen];
|
|||
|
|
for(int i = 0; i < nLen; i++)
|
|||
|
|
{
|
|||
|
|
tab[i] = new int[nCap];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void DestroyTwoDimArray(int**& tab, int nLen)
|
|||
|
|
{
|
|||
|
|
for(int i = 0; i < nLen; i++)
|
|||
|
|
delete []tab[i];
|
|||
|
|
delete []tab;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int PackageX(int Weight[], int nLen, int nCapacity)
|
|||
|
|
{
|
|||
|
|
int * Table = new int [nCapacity+1];
|
|||
|
|
memset(Table,0,(nCapacity+1)*sizeof(int));
|
|||
|
|
|
|||
|
|
int** Path = NULL;
|
|||
|
|
CreateTwoDimArray(Path, nLen+1, nCapacity+1); //创建二维数组
|
|||
|
|
|
|||
|
|
for(int i = 0; i < nLen; i++)
|
|||
|
|
{
|
|||
|
|
for(int j = Weight[i]; j <=nCapacity; j++)
|
|||
|
|
{
|
|||
|
|
if(Table[j] < Table[j-Weight[i]] + /*Weight[i]*/i + 1)
|
|||
|
|
{
|
|||
|
|
Table[j] = Table[j-Weight[i]]+ /*Weight[i]*/i + 1;
|
|||
|
|
Path[i+1][j] = 1;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
int iAll = 0;
|
|||
|
|
int ix = nLen, jx = nCapacity;
|
|||
|
|
while(ix > 0 && jx > 0)
|
|||
|
|
{
|
|||
|
|
if(Path[ix][jx] == 1)
|
|||
|
|
{
|
|||
|
|
int nn = Weight[ix-1];
|
|||
|
|
iAll += nn;
|
|||
|
|
// cout << Weight[ix-1] << " ";
|
|||
|
|
jx -= Weight[ix-1];
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
ix--;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
int nRet = Table[nCapacity];
|
|||
|
|
DestroyTwoDimArray(Path,nLen+1); //销毁二维数组
|
|||
|
|
delete [] Table;
|
|||
|
|
return nRet;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CloneExternRefEnts2()
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
XPoint ptBase;
|
|||
|
|
Entity ent;
|
|||
|
|
RBList rb;
|
|||
|
|
if (SelectEntity(_T("\npick ent<退出>:"), ent, rb) != RTNORM)
|
|||
|
|
return;
|
|||
|
|
AcDbObjectId id;
|
|||
|
|
PickSet ssUnit;
|
|||
|
|
if (ent.Is(_T("INSERT"))) {
|
|||
|
|
ssUnit.Free();
|
|||
|
|
ssUnit.IncludeBegin();
|
|||
|
|
ads_command(RTSTR, _T(".EXPLODE"), RTENAME, (TLong_ptr *)ent, RTNONE);
|
|||
|
|
ssUnit.IncludeEnd();
|
|||
|
|
}
|
|||
|
|
id=MakeBlock(_T("*U"), ssUnit, ptBase);
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
Entity ent2;
|
|||
|
|
if (SelectEntity(_T("\npick line<退出>:"), ent2, rb) != RTNORM)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
XPoly2D basePoly(ent2);
|
|||
|
|
TDbRail *pRail=new TDbRail;
|
|||
|
|
pRail->SetUnitId(id);
|
|||
|
|
pRail->SetInitDist(0);
|
|||
|
|
pRail->SetUnitWidth(250);
|
|||
|
|
pRail->SetLeftAlign(1);
|
|||
|
|
pRail->SetAutoExpand(1);
|
|||
|
|
pRail->SetHas2D(1);
|
|||
|
|
pRail->SetHas3D(1);
|
|||
|
|
pRail->SetPathPoly(basePoly,pRail->GetNormal().AsAcGeVector3d());
|
|||
|
|
pRail->AddToMSpace(Adesk::kTrue);
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CloneExternRefEnts()
|
|||
|
|
{
|
|||
|
|
// 选取克隆外部参照
|
|||
|
|
Entity entExternRef;
|
|||
|
|
RBList rbBlk(RTDXF0, _T("INSERT"), NULL);
|
|||
|
|
while(true)
|
|||
|
|
{
|
|||
|
|
if (SelectEntity(_T("\n外部参照<退出>:"), entExternRef, rbBlk) != RTNORM)
|
|||
|
|
{
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (IsExternalBlock(entExternRef))
|
|||
|
|
{
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
acutPrintf(_T("\n不是外部参照请重新选择!"));
|
|||
|
|
}
|
|||
|
|
ExternRefClone eRc;
|
|||
|
|
eRc.SetExternRef(entExternRef);
|
|||
|
|
|
|||
|
|
Entity ent;
|
|||
|
|
TCHAR chKey;
|
|||
|
|
EntData data;
|
|||
|
|
std::vector<std::pair<Entity,EntData> > vecEnt;
|
|||
|
|
int nRet = eRc.SelectEnt(_T("\n请选择参考图元进行克隆[单体克隆(A)]<退出>:"), ent, data, _T("A"), chKey);
|
|||
|
|
if (nRet == RTNORM) // 按图元拷贝同图层同类实体
|
|||
|
|
{
|
|||
|
|
PickSet ss(SS_FREE);
|
|||
|
|
ss += ent;
|
|||
|
|
vecEnt.push_back(std::make_pair(ent, data));
|
|||
|
|
Entity entTemp;
|
|||
|
|
entTemp = ss[0l];
|
|||
|
|
while (eRc.SelectEnt(_T("\n请选择下一个参考实体"), entTemp, data) == RTNORM)
|
|||
|
|
{
|
|||
|
|
if (ss.IsInclude(entTemp))
|
|||
|
|
{
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
vecEnt.push_back(std::make_pair(entTemp, data));
|
|||
|
|
}
|
|||
|
|
eRc.CloneByCondition(vecEnt);
|
|||
|
|
}
|
|||
|
|
else if (nRet == RTKWORD) // 单体克隆 选择什么拷贝什么
|
|||
|
|
{
|
|||
|
|
vecEnt.push_back(std::make_pair(ent, data));
|
|||
|
|
PickSet ss(SS_FREE);
|
|||
|
|
Entity entTemp;
|
|||
|
|
while (eRc.SelectEnt(_T("\n请选择克隆实体"), entTemp, data) == RTNORM)
|
|||
|
|
{
|
|||
|
|
if (ss.IsInclude(entTemp))
|
|||
|
|
{
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
ss += entTemp;
|
|||
|
|
vecEnt.push_back(std::make_pair(entTemp, data));
|
|||
|
|
}
|
|||
|
|
eRc.CloneBySel(vecEnt);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int ExternRefClone::SelectEnt( const CString &sTip, Entity &ent, EntData &data, const CString &sKeyWord, TCHAR &chKey )
|
|||
|
|
{
|
|||
|
|
ads_point ptResult;
|
|||
|
|
ads_matrix xformres;
|
|||
|
|
resbuf* refstkres = NULL;
|
|||
|
|
int nRet = RTNORM;
|
|||
|
|
INITGET_BEG(0, sKeyWord);
|
|||
|
|
nRet = acedNEntSelP(sTip, ent, ptResult, 0, xformres, &refstkres);
|
|||
|
|
INITGET_END();
|
|||
|
|
if (refstkres != NULL)
|
|||
|
|
{
|
|||
|
|
ads_relrb(refstkres);
|
|||
|
|
}
|
|||
|
|
memcpy(&data.mat, xformres, sizeof(AcGeMatrix3d));
|
|||
|
|
data.ptPick = ptResult;
|
|||
|
|
if (nRet == RTKWORD)
|
|||
|
|
{
|
|||
|
|
TCHAR szKey[256];
|
|||
|
|
acedGetInput(szKey);
|
|||
|
|
if (_tcslen(szKey) > 0)
|
|||
|
|
{
|
|||
|
|
chKey = szKey[0];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return nRet;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int ExternRefClone::SelectEnt( const CString &sTip, Entity &ent, EntData &data)
|
|||
|
|
{
|
|||
|
|
ads_point ptResult;
|
|||
|
|
ads_matrix xformres;
|
|||
|
|
resbuf* refstkres = NULL;
|
|||
|
|
int nRet = acedNEntSelP(sTip, ent, ptResult, 0, xformres, &refstkres);
|
|||
|
|
if (refstkres != NULL)
|
|||
|
|
{
|
|||
|
|
ads_relrb(refstkres);
|
|||
|
|
}
|
|||
|
|
memcpy(&data.mat, xformres, sizeof(AcGeMatrix3d));
|
|||
|
|
data.ptPick = ptResult;
|
|||
|
|
return nRet;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void ExternRefClone::CloneByCondition( std::vector<std::pair<Entity,EntData> > &vecEnt )
|
|||
|
|
{
|
|||
|
|
// 当选择的拷贝实体中包括图块时,需修改选择的实体信息
|
|||
|
|
UpdateSelectionSet(vecEnt);
|
|||
|
|
// 获得拷贝条件
|
|||
|
|
std::vector<CloneCondition> vecCdn;
|
|||
|
|
GetCloneCondition(vecEnt, vecCdn);
|
|||
|
|
|
|||
|
|
// 绘制同图层同类型的外部参照中的实体
|
|||
|
|
int nCloneNum = 0;
|
|||
|
|
DrawEntity(m_entExternRef, vecCdn, nCloneNum);
|
|||
|
|
// 统计克隆实体个数
|
|||
|
|
CString sCloneNum;
|
|||
|
|
sCloneNum.Format(_T("\n成功克隆%d个实体!"), nCloneNum);
|
|||
|
|
acutPrintf(sCloneNum);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void ExternRefClone::CloneBySel( std::vector<std::pair<Entity,EntData> > &vecEnt )
|
|||
|
|
{
|
|||
|
|
// 当选择的拷贝实体中包括图块时,需修改选择的实体信息
|
|||
|
|
UpdateSelectionSet(vecEnt);
|
|||
|
|
AcGeMatrix3d mat;
|
|||
|
|
OPENOBJ_BEGIN(m_entExternRef, AcDb::kForRead, AcDbBlockReference, pRef);
|
|||
|
|
if (pRef != NULL)
|
|||
|
|
{
|
|||
|
|
mat = pRef->blockTransform();
|
|||
|
|
}
|
|||
|
|
OPENOBJ_END();
|
|||
|
|
|
|||
|
|
// 拷贝选择实体
|
|||
|
|
AcDbObjectId id;
|
|||
|
|
std::vector<std::pair<Entity,EntData> >::iterator it, itEnd = vecEnt.end();
|
|||
|
|
// 成功克隆实体个数
|
|||
|
|
int nCloneNum = 0;
|
|||
|
|
const std::vector<CloneCondition> vecCdn;
|
|||
|
|
for (it = vecEnt.begin(); it != itEnd; ++it)
|
|||
|
|
{
|
|||
|
|
Acad::ErrorStatus st = acdbGetObjectId(id, it->first);
|
|||
|
|
AcDbEntity *pEnt = NULL;
|
|||
|
|
st = acdbOpenObject(pEnt, id, AcDb::kForRead);
|
|||
|
|
if(pEnt != NULL)
|
|||
|
|
{
|
|||
|
|
AcDbEntity *pCloneEnt = NULL;
|
|||
|
|
CloneEntity(pEnt, vecCdn, nCloneNum, pCloneEnt);
|
|||
|
|
if (pCloneEnt != NULL)
|
|||
|
|
{
|
|||
|
|
pCloneEnt->transformBy(it->second.mat);
|
|||
|
|
AcDbBlockReference *pRef = AcDbBlockReference::cast(pEnt);
|
|||
|
|
if (pRef != NULL)
|
|||
|
|
{
|
|||
|
|
mat = pRef->blockTransform();
|
|||
|
|
pCloneEnt->transformBy(mat.invert());
|
|||
|
|
}
|
|||
|
|
AddToCurrentSpace(pCloneEnt, Adesk::kTrue);
|
|||
|
|
++nCloneNum;
|
|||
|
|
}
|
|||
|
|
pEnt->close();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
CString sCloneNum;
|
|||
|
|
sCloneNum.Format(_T("\n成功克隆%d个实体!"), nCloneNum);
|
|||
|
|
acutPrintf(sCloneNum);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
AcDbObjectId ExternRefClone::CreateCloneLayer( const CString &sLayer )
|
|||
|
|
{
|
|||
|
|
AcDbObjectId idCloneLayer;
|
|||
|
|
// 克隆图层名
|
|||
|
|
CString sCloneLayer = sLayer;
|
|||
|
|
UpdateCString(sCloneLayer);
|
|||
|
|
// 判断图层是否存在
|
|||
|
|
AcDbLayerTable *pTbl = NULL;
|
|||
|
|
acdbCurDwg()->getLayerTable(pTbl, AcDb::kForRead);
|
|||
|
|
if (pTbl != NULL)
|
|||
|
|
{
|
|||
|
|
AcDbLayerTableIterator *it = NULL;
|
|||
|
|
pTbl->newIterator(it);
|
|||
|
|
AcDbLayerTableRecord *pRec = NULL;
|
|||
|
|
for (it->start(); !it->done(); it->step())
|
|||
|
|
{
|
|||
|
|
it->getRecord(pRec, AcDb::kForRead);
|
|||
|
|
if (pRec == NULL)
|
|||
|
|
{
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
TCHAR *pszName = NULL;
|
|||
|
|
pRec->getName(pszName);
|
|||
|
|
if (sCloneLayer.CompareNoCase(pszName) == 0)
|
|||
|
|
{
|
|||
|
|
idCloneLayer = pRec->objectId();
|
|||
|
|
pRec->close();
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
pRec->close();
|
|||
|
|
}
|
|||
|
|
delete it;
|
|||
|
|
pTbl->close();
|
|||
|
|
// 找到图层
|
|||
|
|
if (!idCloneLayer.isNull())
|
|||
|
|
{
|
|||
|
|
return idCloneLayer;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 图层不存在时,克隆实体图层
|
|||
|
|
AcDbObjectId idLayer = GetLayerIdFromString(sLayer);
|
|||
|
|
AcDbLayerTableRecord *pRec = NULL;
|
|||
|
|
acdbOpenObject(pRec, idLayer, AcDb::kForRead);
|
|||
|
|
if (pRec != NULL)
|
|||
|
|
{
|
|||
|
|
AcDbLayerTableRecord *pNewRec = new AcDbLayerTableRecord;
|
|||
|
|
pNewRec->setName(sCloneLayer);
|
|||
|
|
AcDbObjectId idCloneLinetype = CreateCloneLinetype(pRec->linetypeObjectId());
|
|||
|
|
pNewRec->setLinetypeObjectId(idCloneLinetype);
|
|||
|
|
pNewRec->setLineWeight(pRec->lineWeight());
|
|||
|
|
pNewRec->setColor(pRec->color());
|
|||
|
|
acdbCurDwg()->getLayerTable(pTbl, AcDb::kForWrite);
|
|||
|
|
if (pTbl != NULL)
|
|||
|
|
{
|
|||
|
|
pTbl->add(idCloneLayer, pNewRec);
|
|||
|
|
pNewRec->close();
|
|||
|
|
pTbl->close();
|
|||
|
|
}
|
|||
|
|
pRec->close();
|
|||
|
|
}
|
|||
|
|
return idCloneLayer;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void ExternRefClone::SetExternRef( Entity &ent )
|
|||
|
|
{
|
|||
|
|
m_entExternRef = ent;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void ExternRefClone::DrawEntity( Entity &entBlkRef, const std::vector<CloneCondition> &vecCdn, int &nDrawNum )
|
|||
|
|
{
|
|||
|
|
OPENOBJ_BEGIN(m_entExternRef, AcDb::kForRead, AcDbBlockReference, pRef);
|
|||
|
|
if (pRef != NULL)
|
|||
|
|
{
|
|||
|
|
DrawEntity(pRef, vecCdn, nDrawNum);
|
|||
|
|
}
|
|||
|
|
OPENOBJ_END();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void ExternRefClone::DrawEntity( AcDbBlockReference *pRef, const std::vector<CloneCondition> &vecCdn, int &nDrawNum )
|
|||
|
|
{
|
|||
|
|
if (vecCdn.empty())
|
|||
|
|
{
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
AcDbVoidPtrArray arPtr;
|
|||
|
|
pRef->explode(arPtr);
|
|||
|
|
int nLen = arPtr.length();
|
|||
|
|
AcDbEntity *pEnt = NULL;
|
|||
|
|
CString sLayer;
|
|||
|
|
AcDbObjectId idLayer;
|
|||
|
|
for (int i = 0; i < nLen; ++i)
|
|||
|
|
{
|
|||
|
|
pEnt = AcDbEntity::cast((AcRxObject*)arPtr[i]);
|
|||
|
|
if (pEnt == NULL)
|
|||
|
|
{
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
AcDbBlockReference *pRef = AcDbBlockReference::cast(pEnt);
|
|||
|
|
if (pRef != NULL) // 处理图块中的外部参照
|
|||
|
|
{
|
|||
|
|
if (IsExternRef(pRef->blockTableRecord()))
|
|||
|
|
{
|
|||
|
|
DrawEntity(pRef, vecCdn, nDrawNum);
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
CloneCondition data;
|
|||
|
|
GetCloneCondition(pEnt, data);
|
|||
|
|
if (FindCloneCondition(vecCdn, data)) // 满足克隆条件
|
|||
|
|
{
|
|||
|
|
AcDbEntity *pCloneEnt = NULL;
|
|||
|
|
CloneEntity(pEnt, vecCdn, nDrawNum, pCloneEnt);
|
|||
|
|
if (pCloneEnt != NULL)
|
|||
|
|
{
|
|||
|
|
AddToCurrentSpace(pCloneEnt, Adesk::kTrue);
|
|||
|
|
++nDrawNum;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
ReleaseEntSet(arPtr);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool ExternRefClone::IsExternRef( const AcDbObjectId &idRec )
|
|||
|
|
{
|
|||
|
|
bool bExternBlk = false;
|
|||
|
|
AcDbBlockTableRecord *pRec = NULL;
|
|||
|
|
acdbOpenObject(pRec, idRec, AcDb::kForRead);
|
|||
|
|
if (pRec != NULL)
|
|||
|
|
{
|
|||
|
|
TCHAR *pszName = NULL;
|
|||
|
|
pRec->getName(pszName);
|
|||
|
|
if (pRec->isFromExternalReference())
|
|||
|
|
{
|
|||
|
|
bExternBlk = true;
|
|||
|
|
}
|
|||
|
|
pRec->close();
|
|||
|
|
}
|
|||
|
|
return bExternBlk;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool ExternRefClone::IsOrdinaryRef( const AcDbObjectId &idRec )
|
|||
|
|
{
|
|||
|
|
bool bBlk = false;
|
|||
|
|
AcDbBlockTableRecord *pRec = NULL;
|
|||
|
|
acdbOpenObject(pRec, idRec, AcDb::kForRead);
|
|||
|
|
if (pRec != NULL)
|
|||
|
|
{
|
|||
|
|
TCHAR *pszName = NULL;
|
|||
|
|
pRec->getName(pszName);
|
|||
|
|
CString sName = pszName;
|
|||
|
|
if (sName.CompareNoCase(ACDB_MODEL_SPACE) != 0)
|
|||
|
|
{
|
|||
|
|
bBlk = true;
|
|||
|
|
}
|
|||
|
|
pRec->close();
|
|||
|
|
}
|
|||
|
|
return bBlk;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool ExternRefClone::GetBlkId( const AcDbObjectId &idRec, const EntData &data, AcDbObjectId &idBlk )
|
|||
|
|
{
|
|||
|
|
// 获得所有外部参照
|
|||
|
|
AcDbObjectIdArray arrIds;
|
|||
|
|
OPENOBJ_BEGIN(idRec, AcDb::kForRead, AcDbBlockTableRecord, pRec);
|
|||
|
|
if (pRec != NULL)
|
|||
|
|
{
|
|||
|
|
pRec->getBlockReferenceIds(arrIds);
|
|||
|
|
}
|
|||
|
|
OPENOBJ_END();
|
|||
|
|
|
|||
|
|
// 选择的外部参照中的图块插入点
|
|||
|
|
XPoint ptIns(0.0, 0.0, 0.0);
|
|||
|
|
ptIns.TransformBy(data.mat);
|
|||
|
|
|
|||
|
|
// 找出包含pt点的外部参照,并获得图层名,图块名
|
|||
|
|
int nLen = arrIds.length();
|
|||
|
|
AcDbBlockReference *pRef = NULL;
|
|||
|
|
AcGeMatrix3d mat;
|
|||
|
|
XPoint ptLoc;
|
|||
|
|
for(int i = 0; i < nLen; ++i)
|
|||
|
|
{
|
|||
|
|
acdbOpenObject(pRef, arrIds[i], AcDb::kForWrite);
|
|||
|
|
if (pRef != NULL)
|
|||
|
|
{
|
|||
|
|
mat = data.mat * pRef->blockTransform().inverse();
|
|||
|
|
ptLoc = pRef->position();
|
|||
|
|
pRef->close();
|
|||
|
|
ptLoc.TransformBy(mat);
|
|||
|
|
if(ptLoc.Distance2d(ptIns) < 0.001)
|
|||
|
|
{
|
|||
|
|
idBlk = arrIds[i];
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void ExternRefClone::UpdateSelectionSet( std::vector<std::pair<Entity,EntData> > &vecSelEnt )
|
|||
|
|
{
|
|||
|
|
std::vector<std::pair<Entity,EntData> >::iterator it, itEnd = vecSelEnt.end();
|
|||
|
|
AcDbObjectId idOwner, idBlk;
|
|||
|
|
for (it = vecSelEnt.begin(); it != itEnd; ++it)
|
|||
|
|
{
|
|||
|
|
OPENOBJ_BEGIN(it->first, AcDb::kForRead, AcDbEntity, pEnt);
|
|||
|
|
if (pEnt != NULL)
|
|||
|
|
{
|
|||
|
|
// 实体是否为普通图块的组成部分
|
|||
|
|
idOwner = pEnt->ownerId();
|
|||
|
|
if(!IsOrdinaryRef(idOwner))
|
|||
|
|
{
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 获得实体所属图块id
|
|||
|
|
if (GetBlkId(idOwner,it->second, idBlk))
|
|||
|
|
{
|
|||
|
|
// 将选择实体修改为图块
|
|||
|
|
acdbGetAdsName(it->first.name, idBlk);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
OPENOBJ_END();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void ExternRefClone::GetCloneCondition( std::vector<std::pair<Entity,EntData> > &vecSelEnt, std::vector<CloneCondition> &vecCdn )
|
|||
|
|
{
|
|||
|
|
std::vector<std::pair<Entity,EntData> >::iterator it, itEnd = vecSelEnt.end();
|
|||
|
|
CloneCondition data;
|
|||
|
|
for (it = vecSelEnt.begin(); it != itEnd; ++it)
|
|||
|
|
{
|
|||
|
|
OPENOBJ_BEGIN(it->first, AcDb::kForRead, AcDbEntity, pEnt);
|
|||
|
|
if (pEnt != NULL)
|
|||
|
|
{
|
|||
|
|
GetCloneCondition(pEnt, data);
|
|||
|
|
if (!FindCloneCondition(vecCdn, data))
|
|||
|
|
{
|
|||
|
|
vecCdn.push_back(data);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
OPENOBJ_END();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void ExternRefClone::GetCloneCondition( AcDbEntity *pEnt, CloneCondition &data )
|
|||
|
|
{
|
|||
|
|
TCHAR *pszLayer = pEnt->layer();
|
|||
|
|
data.sLayer = pszLayer;
|
|||
|
|
delete pszLayer;
|
|||
|
|
pszLayer = NULL;
|
|||
|
|
int nIndex = data.sLayer.Find(_T("|"));
|
|||
|
|
if (nIndex > -1)
|
|||
|
|
{
|
|||
|
|
int nLen = data.sLayer.GetLength();
|
|||
|
|
data.sLayer = data.sLayer.Right(nLen - nIndex - 1);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool ExternRefClone::FindCloneCondition( const std::vector<CloneCondition> &vecCdn, const CloneCondition &data )
|
|||
|
|
{
|
|||
|
|
std::vector<CloneCondition>::const_iterator it, itEnd = vecCdn.end();
|
|||
|
|
it = std::find(vecCdn.begin(), itEnd, data);
|
|||
|
|
if (it != itEnd)
|
|||
|
|
{
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
inline void ExternRefClone::UpdateCString( CString &sText, const CString &sTok /*= _T("|")*/ )
|
|||
|
|
{
|
|||
|
|
int nIndex = sText.Find(sTok);
|
|||
|
|
if(nIndex > -1)
|
|||
|
|
{
|
|||
|
|
int nLen = sText.GetLength() ;
|
|||
|
|
sText = sText.Right(nLen - nIndex - 1);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
AcDbObjectId ExternRefClone::CreateCloneBlkRecord( const CString &sBlkName )
|
|||
|
|
{
|
|||
|
|
AcDbObjectId idCloneBlk;
|
|||
|
|
// 图块名
|
|||
|
|
CString sCloneBlkName = sBlkName;
|
|||
|
|
UpdateCString(sCloneBlkName);
|
|||
|
|
// 查看块表记录是否存在
|
|||
|
|
idCloneBlk = GetBlkIdByName(sCloneBlkName);
|
|||
|
|
if (!idCloneBlk.isNull())
|
|||
|
|
{
|
|||
|
|
return idCloneBlk;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 创建新块
|
|||
|
|
AcDbObjectId idBlk = GetBlkIdByName(sBlkName);
|
|||
|
|
AcDbBlockTableRecord *pRec = NULL;
|
|||
|
|
acdbOpenObject(pRec, idBlk, AcDb::kForRead);
|
|||
|
|
if (pRec != NULL)
|
|||
|
|
{
|
|||
|
|
AcDbBlockTableRecord *pNewRec = new AcDbBlockTableRecord;
|
|||
|
|
AcDbBlockTableRecordIterator *it = NULL;
|
|||
|
|
pRec->newIterator(it);
|
|||
|
|
pRec->close();
|
|||
|
|
for (it->start(); !it->done(); it->step())
|
|||
|
|
{
|
|||
|
|
AcDbEntity *pEnt = NULL;
|
|||
|
|
it->getEntity(pEnt, AcDb::kForRead);
|
|||
|
|
if (pEnt == NULL)
|
|||
|
|
{
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
AcDbBlockReference *pRef = AcDbBlockReference::cast(pEnt);
|
|||
|
|
if (pRef != NULL)
|
|||
|
|
{
|
|||
|
|
CString sName = GetBlkNameById(pRef->blockTableRecord());
|
|||
|
|
AcDbObjectId idRec = CreateCloneBlkRecord(sName);
|
|||
|
|
AcDbBlockReference *pNewRef = new AcDbBlockReference;
|
|||
|
|
pNewRef->setPosition(pRef->position());
|
|||
|
|
pNewRef->setRotation(pRef->rotation());
|
|||
|
|
pNewRef->setScaleFactors(pRef->scaleFactors());
|
|||
|
|
pNewRef->setBlockTransform(pRef->blockTransform());
|
|||
|
|
pNewRef->setBlockTableRecord(idRec);
|
|||
|
|
pNewRec->appendAcDbEntity(pNewRef);
|
|||
|
|
pNewRef->close();
|
|||
|
|
pRef->close();
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
AcDbEntity *pNewEnt = static_cast<AcDbEntity*>(pEnt->clone());
|
|||
|
|
pNewRec->appendAcDbEntity(pNewEnt);
|
|||
|
|
pNewEnt->close();
|
|||
|
|
pEnt->close();
|
|||
|
|
}
|
|||
|
|
delete it;
|
|||
|
|
|
|||
|
|
pNewRec->setName(sCloneBlkName);
|
|||
|
|
pNewRec->setOrigin(pRec->origin());
|
|||
|
|
AcDbBlockTable *pTbl = NULL;
|
|||
|
|
acdbCurDwg()->getBlockTable(pTbl, AcDb::kForWrite);
|
|||
|
|
if (pTbl != NULL)
|
|||
|
|
{
|
|||
|
|
pTbl->add(idCloneBlk, pNewRec);
|
|||
|
|
pNewRec->close();
|
|||
|
|
pTbl->close();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return idCloneBlk;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void ExternRefClone::CloneEntity( const AcDbEntity *pEnt,const std::vector<CloneCondition> &vecCdn, int &nDrawNum, AcDbEntity *&pCloneEnt )
|
|||
|
|
{
|
|||
|
|
ASSERT(pEnt != NULL);
|
|||
|
|
pCloneEnt = NULL;
|
|||
|
|
while(true)
|
|||
|
|
{
|
|||
|
|
// 图块
|
|||
|
|
AcDbBlockReference *pRef = AcDbBlockReference::cast(pEnt);
|
|||
|
|
if (pRef != NULL)
|
|||
|
|
{
|
|||
|
|
// 创建普通图块
|
|||
|
|
CString sBlkName = GetBlkNameById(pRef->blockTableRecord());
|
|||
|
|
AcDbObjectId idRec = CreateCloneBlkRecord(sBlkName);
|
|||
|
|
if (idRec.isNull())
|
|||
|
|
{
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
AcDbBlockReference *pNewRef = new AcDbBlockReference;
|
|||
|
|
pNewRef->setBlockTableRecord(idRec);
|
|||
|
|
pNewRef->transformBy(pRef->blockTransform());
|
|||
|
|
pNewRef->setPosition(pRef->position());
|
|||
|
|
pCloneEnt = pNewRef;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
// 水泵
|
|||
|
|
TDbPump *pPump = TDbPump::cast(pEnt);
|
|||
|
|
if (pPump != NULL)
|
|||
|
|
{
|
|||
|
|
AcDbObjectId idBlk2d = pPump->GetBlock2d();
|
|||
|
|
AcDbObjectId idBlk3d = pPump->GetBlock3d();
|
|||
|
|
CString sBlk2dName = GetBlkNameById(idBlk2d);
|
|||
|
|
CString sBlk3dName = GetBlkNameById(idBlk3d);
|
|||
|
|
idBlk2d = CreateCloneBlkRecord(sBlk2dName);
|
|||
|
|
idBlk3d = CreateCloneBlkRecord(sBlk3dName);
|
|||
|
|
TDbPump *pNewPump = static_cast<TDbPump*>(pPump->clone());
|
|||
|
|
pNewPump->SetBlock2d(idBlk2d);
|
|||
|
|
pNewPump->SetBlock3d(idBlk3d);
|
|||
|
|
pCloneEnt = pNewPump;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
// 水池
|
|||
|
|
TDbPool *pPool = TDbPool::cast(pEnt);
|
|||
|
|
if (pPool != NULL)
|
|||
|
|
{
|
|||
|
|
AcDbObjectId idBlk2d = pPool->GetBlock2d();
|
|||
|
|
AcDbObjectId idBlk3d = pPool->GetBlock3d();
|
|||
|
|
CString sBlk2dName = GetBlkNameById(idBlk2d);
|
|||
|
|
CString sBlk3dName = GetBlkNameById(idBlk3d);
|
|||
|
|
idBlk2d = CreateCloneBlkRecord(sBlk2dName);
|
|||
|
|
idBlk3d = CreateCloneBlkRecord(sBlk3dName);
|
|||
|
|
|
|||
|
|
TDbPool *pNewPool = static_cast<TDbPool*>(pPool->clone());
|
|||
|
|
pNewPool->SetBlock2d(idBlk2d);
|
|||
|
|
pNewPool->SetBlock3d(idBlk3d);
|
|||
|
|
pCloneEnt = pNewPool;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
// 设备
|
|||
|
|
TDbEquipment *pEuqip = TDbEquipment::cast(pEnt);
|
|||
|
|
if (pEuqip != NULL)
|
|||
|
|
{
|
|||
|
|
AcDbObjectId idBlk2d = pEuqip->GetBlock2d();
|
|||
|
|
AcDbObjectId idBlk3d = pEuqip->GetBlock3d();
|
|||
|
|
CString sBlk2dName = GetBlkNameById(idBlk2d);
|
|||
|
|
CString sBlk3dName = GetBlkNameById(idBlk3d);
|
|||
|
|
idBlk2d = CreateCloneBlkRecord(sBlk2dName);
|
|||
|
|
idBlk3d = CreateCloneBlkRecord(sBlk3dName);
|
|||
|
|
TDbEquipment *pNewEquip = static_cast<TDbEquipment*>(pEuqip->clone());
|
|||
|
|
pNewEquip->SetBlock2d(idBlk2d);
|
|||
|
|
pNewEquip->SetBlock3d(idBlk3d);
|
|||
|
|
pCloneEnt = pNewEquip;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
// 门窗
|
|||
|
|
TDbOpening *pOpen = TDbOpening::cast(pEnt);
|
|||
|
|
if (pOpen != NULL)
|
|||
|
|
{
|
|||
|
|
AcDbObjectId idBlk2d = pOpen->m_nIdStyle2d;
|
|||
|
|
AcDbObjectId idBlk3d = pOpen->m_nIdStyle3d;
|
|||
|
|
CString sBlk2dName = GetBlkNameById(idBlk2d);
|
|||
|
|
CString sBlk3dName = GetBlkNameById(idBlk3d);
|
|||
|
|
idBlk2d = CreateCloneBlkRecord(sBlk2dName);
|
|||
|
|
idBlk3d = CreateCloneBlkRecord(sBlk3dName);
|
|||
|
|
TDbOpening *pNewOpen = static_cast<TDbOpening*>(pOpen->clone());
|
|||
|
|
pNewOpen->m_nIdStyle2d = idBlk2d;
|
|||
|
|
pNewOpen->m_nIdStyle3d = idBlk3d;
|
|||
|
|
pCloneEnt = pNewOpen;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
// 非块实体包含块
|
|||
|
|
if (IsIncludeBlk(pEnt))
|
|||
|
|
{
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
// 普通实体,不包含块
|
|||
|
|
pCloneEnt = static_cast<AcDbEntity*>(pEnt->clone());
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
// 克隆实体图层
|
|||
|
|
TCHAR *pszLayer = pEnt->layer();
|
|||
|
|
CString sLayerName = pszLayer;
|
|||
|
|
delete pszLayer;
|
|||
|
|
AcDbObjectId idLayer = CreateCloneLayer(sLayerName);
|
|||
|
|
pCloneEnt->setLayer(idLayer);
|
|||
|
|
// 设置线型
|
|||
|
|
AcDbObjectId idCloneLinetype = CreateCloneLinetype(pEnt->linetypeId());
|
|||
|
|
pCloneEnt->setLinetype(idCloneLinetype);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
CString ExternRefClone::GetLinetypeName( const AcDbObjectId &idLinetype )
|
|||
|
|
{
|
|||
|
|
CString sLinetypeName;
|
|||
|
|
AcDbLinetypeTableRecord *pRec = NULL;
|
|||
|
|
acdbOpenObject(pRec, idLinetype, AcDb::kForRead);
|
|||
|
|
if (pRec != NULL)
|
|||
|
|
{
|
|||
|
|
TCHAR *pszName = NULL;
|
|||
|
|
pRec->getName(pszName);
|
|||
|
|
sLinetypeName = pszName;
|
|||
|
|
delete pszName;
|
|||
|
|
pRec->close();
|
|||
|
|
}
|
|||
|
|
return sLinetypeName;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool ExternRefClone::IsIncludeBlk( const AcDbEntity *pEnt )
|
|||
|
|
{
|
|||
|
|
AcDbVoidPtrArray arrPtrs;
|
|||
|
|
pEnt->explode(arrPtrs);
|
|||
|
|
int nLen = arrPtrs.length();
|
|||
|
|
AcDbEntity *pNewEnt = NULL;
|
|||
|
|
AcDbBlockReference *pRef = NULL;
|
|||
|
|
for (int i = 0; i < nLen; ++i)
|
|||
|
|
{
|
|||
|
|
pNewEnt = static_cast<AcDbEntity*>(arrPtrs[i]);
|
|||
|
|
if (pEnt == NULL)
|
|||
|
|
{
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 包含块
|
|||
|
|
pRef = AcDbBlockReference::cast(pNewEnt);
|
|||
|
|
if (pRef != NULL)
|
|||
|
|
{
|
|||
|
|
ReleaseEntSet(arrPtrs);
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (IsIncludeBlk(pNewEnt))
|
|||
|
|
{
|
|||
|
|
ReleaseEntSet(arrPtrs);
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
ReleaseEntSet(arrPtrs);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
AcDbObjectId ExternRefClone::CreateCloneLinetype( const AcDbObjectId &idLinetype )
|
|||
|
|
{
|
|||
|
|
CString sLinetypeName = GetLinetypeName(idLinetype);
|
|||
|
|
UpdateCString(sLinetypeName);
|
|||
|
|
AcDbObjectId idCloneLinetype = GetLinetypeIdFromString(sLinetypeName);
|
|||
|
|
if (idCloneLinetype.isNull())
|
|||
|
|
{
|
|||
|
|
idCloneLinetype = GetLinetypeIdFromString(_T("CONTINUOUS"));
|
|||
|
|
}
|
|||
|
|
return idCloneLinetype;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|