1459 lines
35 KiB
C++
1459 lines
35 KiB
C++
//////////////////////////////////////////////////////////////////////
|
|
/********************************************************************
|
|
created: 2007/12/12
|
|
created: 12:12:2007 12:47
|
|
filename: f:\tg_dev\水电开发\tch_public\comparedwg.cpp
|
|
file path: f:\tg_dev\水电开发\tch_public
|
|
file base: comparedwg
|
|
file ext: cpp
|
|
author: 沈睿
|
|
|
|
purpose: dwg进行比对
|
|
*********************************************************************/
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include <dbidmap.h>
|
|
#include <actrans.h>
|
|
//#include "xacgi.h"
|
|
//#include "arxtools.h"
|
|
//#include "Xgcom.h"
|
|
//#include "findfile.h"
|
|
#include "CompareDwg.h"
|
|
#include "DwgCompareDlg.h"
|
|
#include <AcExtensionModule.h>
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[]=__FILE__;
|
|
#define new DEBUG_NEW
|
|
#endif
|
|
|
|
|
|
//主函数
|
|
void CompareDwgCmd()
|
|
{
|
|
CCompareDwg cmpDwg;
|
|
cmpDwg.DoCompareFile();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//class CDataEntityList
|
|
CDataEntityList::CDataEntityList()
|
|
{
|
|
m_dataDList.clear();
|
|
}
|
|
|
|
CDataEntityList::CDataEntityList( int nCount )
|
|
{
|
|
m_dataDList.clear();
|
|
if(nCount <= 0)
|
|
{
|
|
return;
|
|
}
|
|
for (int i=0; i<nCount; i++)
|
|
{
|
|
m_dataDList.push_back(new DList<TCompareEntity>);
|
|
}
|
|
}
|
|
|
|
CDataEntityList::~CDataEntityList()
|
|
{
|
|
for (int n=0; n<Length(); n++)
|
|
{
|
|
DList<TCompareEntity>* p = m_dataDList[n];
|
|
if (p != NULL)
|
|
{
|
|
delete p;
|
|
p = NULL;
|
|
}
|
|
}
|
|
m_dataDList.clear();
|
|
}
|
|
|
|
int CDataEntityList::Length() const
|
|
{
|
|
return (int)m_dataDList.size();
|
|
}
|
|
|
|
DList<TCompareEntity>& CDataEntityList::operator[]( int n )
|
|
{
|
|
return (*(m_dataDList[n]));
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//class CCompareDwg
|
|
CCompareDwg::CCompareDwg( void )
|
|
{
|
|
|
|
}
|
|
|
|
CCompareDwg::~CCompareDwg( void )
|
|
{
|
|
|
|
}
|
|
|
|
BOOL CCompareDwg::DoCompareFile()
|
|
{
|
|
AcApDocument* pDoc = acDocManager->curDocument();
|
|
acDocManager->lockDocument(pDoc);
|
|
|
|
//加载文件
|
|
CDwgCompareDbMgr * pMgr1 = new CDwgCompareDbMgr();
|
|
CDwgCompareDbMgr * pMgr2 = new CDwgCompareDbMgr();
|
|
CAcModuleResourceOverride vTemp;
|
|
|
|
CDwgCompareDlg dlgCmp(pMgr1, pMgr2, 0);
|
|
if(dlgCmp.DoModal() == IDOK)
|
|
{
|
|
//开始比对
|
|
clock_t startTimeG, finishTimeG; //计时
|
|
double durationG;
|
|
startTimeG = clock();
|
|
|
|
m_bCmpBlockRef = dlgCmp.m_bCmpBlock; //设置是否比对块
|
|
m_bCmpHatch = dlgCmp.m_bCmpHatch; //设置是否比对填充
|
|
m_bCmpXref = dlgCmp.m_bCmpXref; //设置是否比对外部参照
|
|
m_iRow = dlgCmp.m_iRowCount; //设置分块行列数
|
|
m_iCol = dlgCmp.m_iColumnCount;
|
|
if(DoCompareFile(pMgr1, pMgr2))
|
|
{
|
|
ads_command(RTSTR, _T(".ZOOM"), RTSTR, _T("E"), NULL);
|
|
acedPostCommand(_T("REGEN\n"));
|
|
}
|
|
|
|
finishTimeG = clock();
|
|
durationG = (double)(finishTimeG - startTimeG) / CLOCKS_PER_SEC;
|
|
|
|
CString csTemp;
|
|
csTemp.Format(_T("\n文件1加载用时:%lf秒..\n[%s]"), dlgCmp.m_timeLoadFile1, pMgr1->GetFilePath());
|
|
acutPrintf(csTemp);
|
|
//WriteLogFile(dlgCmp.m_timeLoadFile1, csTemp);
|
|
csTemp.Format(_T("\n文件2加载用时:%lf秒..\n[%s]"), dlgCmp.m_timeLoadFile2, pMgr2->GetFilePath());
|
|
acutPrintf(csTemp);
|
|
//WriteLogFile(dlgCmp.m_timeLoadFile2, csTemp);
|
|
|
|
acutPrintf(_T("\n图纸比对用时:%lf秒.."), durationG);
|
|
//WriteLogFile(durationG);//比对信息写入记录文件
|
|
}
|
|
|
|
delete pMgr1;
|
|
pMgr1 =NULL;
|
|
delete pMgr2;
|
|
pMgr2 = NULL;
|
|
|
|
acDocManager->unlockDocument(pDoc);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CCompareDwg::SetRowCol( int iRow, int iCol )
|
|
{
|
|
m_iRow = iRow;
|
|
m_iCol = iCol;
|
|
if(m_iRow<1)
|
|
{
|
|
m_iRow=1;
|
|
}
|
|
if(m_iCol<1)
|
|
{
|
|
m_iCol=1;
|
|
}
|
|
}
|
|
|
|
|
|
BOOL CCompareDwg::DoCompareFile( CDwgCompareDbMgr * pDbMgr1, CDwgCompareDbMgr * pDbMgr2 )
|
|
{
|
|
if (pDbMgr1==NULL || pDbMgr2==NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
//ads_command(RTSTR, _T(".PURGE"), RTSTR, _T("ALL"), RTSTR, _T(""), RTSTR, _T("N"), NULL);
|
|
|
|
AcDbObjectId idBlock1 = AcDbObjectId::kNull;
|
|
AcDbObjectId idBlock2 = AcDbObjectId::kNull;
|
|
|
|
//图纸1插入图中
|
|
idBlock1 = InitBlockByFile(pDbMgr1);
|
|
if(idBlock1.isNull())
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
//把这个图块插入图中
|
|
XPoint ptIns;
|
|
//使用原点作为插入点
|
|
AcDbBlockReference *pInsert=new AcDbBlockReference(ptIns, idBlock1);
|
|
if (pInsert == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
AcDbObjectId idInsert=AddToCurrentSpace(pInsert, Adesk::kFalse);
|
|
if(!idInsert)
|
|
{
|
|
delete pInsert;
|
|
return FALSE;
|
|
}
|
|
//计算这个块的外包
|
|
AcDbExtents extBlk1;
|
|
pInsert->getGeomExtents(extBlk1);
|
|
pInsert->close();//关闭
|
|
|
|
//图纸2插入图中
|
|
idBlock2 = InitBlockByFile(pDbMgr2);
|
|
if(idBlock2.isNull())
|
|
{
|
|
return FALSE;
|
|
}
|
|
AcDbBlockReference *pInsert2=new AcDbBlockReference(ptIns, idBlock2);
|
|
if (pInsert2 == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
AcDbObjectId idInsert2=AddToCurrentSpace(pInsert2, Adesk::kFalse);
|
|
if(!idInsert2)
|
|
{
|
|
delete pInsert2;
|
|
return FALSE;
|
|
}
|
|
//计算这个块的外包
|
|
AcDbExtents extBlk2;
|
|
pInsert2->getGeomExtents(extBlk2);
|
|
pInsert2->close();//关闭
|
|
|
|
//解除所有图层特殊状态后再计算外包
|
|
BOOL bStatus = ResetAllLayerStatus();
|
|
|
|
//插入两个图块后执行清理
|
|
//ads_command(RTSTR, _T(".PURGE"), RTSTR, _T("ALL"), RTSTR, _T(""), RTSTR, _T("N"), NULL);
|
|
ads_command(RTSTR, _T(".ZOOM"), RTSTR, _T("E"), RTNONE);
|
|
//ads_command(RTSTR, _T("_REGEN"), NULL);
|
|
|
|
//计算外包,需要在炸开处理前计算
|
|
//因为炸开过程中同时对实体计算分块
|
|
// SetExtent();
|
|
/*AcDbExtents extDb1(pDbMgr1->GetDb()->extmin(), pDbMgr1->GetDb()->extmax());
|
|
AcDbExtents extDb2(pDbMgr2->GetDb()->extmin(), pDbMgr2->GetDb()->extmax());
|
|
//先设置比对外包为两个DB的
|
|
m_extBlk = extDb1;
|
|
m_extBlk.addExt(extDb2);
|
|
//SetExtent中,全图不改m_extBlk,局部使用参数
|
|
SetExtent(extBlk1, extBlk2);*/
|
|
SetExtent(extBlk1, extBlk2);
|
|
int iLength = m_iCol*m_iRow; //分块数目
|
|
CDataEntityList dataList1(iLength), dataList2(iLength);
|
|
|
|
/*取满足条件的图层和解除所有图层特殊状态不冲突
|
|
*获取比对图层是在原来的DB对象中进行的,解锁是当前图纸,涉及到3个DB
|
|
*/
|
|
|
|
//炸开块1,删除被炸开的实体,添加炸开后的实体到这个块中
|
|
//炸开过程中同时分块
|
|
OPENOBJ_BEGIN(idBlock1, AcDb::kForWrite, AcDbBlockTableRecord , pRec);
|
|
if(pRec)
|
|
{
|
|
DeepExplodeBlock(pRec, pDbMgr1, dataList1, 1);
|
|
}
|
|
OPENOBJ_END();
|
|
acutPrintf(_T("\n块 1 分析完成..."));
|
|
//炸开块2,删除被炸开的实体,添加炸开后的实体到这个块中
|
|
OPENOBJ_BEGIN(idBlock2, AcDb::kForWrite, AcDbBlockTableRecord , pRec);
|
|
if(pRec)
|
|
{
|
|
DeepExplodeBlock(pRec, pDbMgr2, dataList2, 2);
|
|
}
|
|
OPENOBJ_END();
|
|
acutPrintf(_T("\n块 2 分析完成..."));
|
|
|
|
m_iCountEnt =0;
|
|
int iLen1= dataList1.Length();
|
|
int iLen2= dataList2.Length();
|
|
int iLen = (iLen1>iLen2) ? iLen2 : iLen1; //取较小的, iLen1应该等于iLen2
|
|
acedSetStatusBarProgressMeter(_T("比对中..."), 0, iLen);
|
|
for (int i=0; i<iLen; i++)
|
|
{
|
|
acedSetStatusBarProgressMeterPos(i);
|
|
DList<TCompareEntity> &lstArea1 = dataList1[i];
|
|
DList<TCompareEntity> &lstArea2 = dataList2[i];
|
|
if (lstArea1.Length() <= 0 || lstArea2.Length() <= 0)
|
|
{
|
|
continue;
|
|
}
|
|
long lenList1=lstArea1.Length();
|
|
long lenList2=lstArea2.Length();
|
|
acutPrintf(_T("\n区域[%d]比对:[%d]*[%d]"), i, lenList1, lenList2);
|
|
CompareCurve(lstArea1, lstArea2);
|
|
}
|
|
acedRestoreStatusBar();
|
|
|
|
acutPrintf(_T("\n比对完成..."));
|
|
|
|
#ifdef _DEBUG
|
|
PrintInfo();//输出统计信息
|
|
#endif // _DEBUG
|
|
PrintInfo();//输出统计信息
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CCompareDwg::DoCompareFile( CString csFileName1, CString csFileName2, CString csBlkName1, CString csBlkName2 )
|
|
{
|
|
//加载文件
|
|
clock_t startTime, finishTime; //计时
|
|
double duration;
|
|
startTime = clock();
|
|
|
|
CDwgCompareDbMgr * pMgr1 = new CDwgCompareDbMgr();
|
|
if (!pMgr1->LoadFile(csBlkName1, csFileName1))
|
|
{
|
|
return FALSE;
|
|
}
|
|
CDwgCompareDbMgr * pMgr2 = new CDwgCompareDbMgr();
|
|
if (!pMgr2->LoadFile(csBlkName2, csFileName2))
|
|
{
|
|
return FALSE;
|
|
}
|
|
finishTime = clock();
|
|
duration = (double)(finishTime - startTime) / CLOCKS_PER_SEC;
|
|
|
|
CDwgCompareDlg dlgCmp(pMgr1, pMgr2, 2);
|
|
if(dlgCmp.DoModal() == IDOK)
|
|
{
|
|
//开始比对
|
|
clock_t startTimeG, finishTimeG; //计时
|
|
double durationG;
|
|
startTimeG = clock();
|
|
|
|
m_bCmpBlockRef = dlgCmp.m_bCmpBlock; //设置是否比对块
|
|
m_bCmpHatch = dlgCmp.m_bCmpHatch; //设置是否比对填充
|
|
m_bCmpXref = dlgCmp.m_bCmpXref; //设置是否比对外部参照
|
|
m_iRow = dlgCmp.m_iRowCount; //设置分块行列数
|
|
m_iCol = dlgCmp.m_iColumnCount;
|
|
if(DoCompareFile(pMgr1, pMgr2))
|
|
{
|
|
ads_command(RTSTR, _T(".ZOOM"), RTSTR, _T("E"), NULL);
|
|
acedPostCommand(_T("REGEN\n"));
|
|
}
|
|
|
|
finishTimeG = clock();
|
|
durationG = (double)(finishTimeG - startTimeG) / CLOCKS_PER_SEC;
|
|
|
|
CString csTemp;
|
|
csTemp.Format(_T("\n文件加载用时:%lf秒..\n[%s]\n[%s]"), duration, pMgr1->GetFilePath(), pMgr2->GetFilePath());
|
|
acutPrintf(csTemp);
|
|
//WriteLogFile(duration, csTemp);
|
|
acutPrintf(_T("\n图纸比对用时:%lf秒.."), durationG);
|
|
//WriteLogFile(durationG);//比对信息写入记录文件
|
|
}
|
|
|
|
delete pMgr1;
|
|
pMgr1 =NULL;
|
|
delete pMgr2;
|
|
pMgr2 = NULL;
|
|
|
|
return TRUE;
|
|
}
|
|
AcDbObjectId CCompareDwg::InitBlockByFile( CDwgCompareDbMgr * pDbMgr )
|
|
{
|
|
AcDbObjectId id = AcDbObjectId::kNull;
|
|
if (pDbMgr == NULL)
|
|
{
|
|
return id;
|
|
}
|
|
|
|
AcDbDatabase *pDb=NULL;
|
|
CString sFileName = pDbMgr->GetFileName();
|
|
XDbBlockTableRec blk(sFileName, AcDb::kForRead, pDb);
|
|
if(!blk)
|
|
{
|
|
if(!pDb)
|
|
pDb=acdbCurDwg();
|
|
AcDbDatabase * pDbInsert = pDbMgr->GetDb();
|
|
AcDbBlockTable* pBlockTable = NULL;
|
|
pDbInsert->getBlockTable(pBlockTable, AcDb::kForRead);
|
|
AcDbBlockTableIterator *pIterator=NULL;
|
|
Acad::ErrorStatus es1=pBlockTable->newIterator(pIterator);
|
|
pBlockTable->close();
|
|
if(es1==Acad::eOk && pIterator != NULL)
|
|
{
|
|
int len = 0;
|
|
int i=0;
|
|
for(pIterator->start(); !pIterator->done(); pIterator->step())
|
|
{
|
|
len++;
|
|
//外部参照加载
|
|
AcDbBlockTableRecord *pRec=NULL;
|
|
if(pIterator->getRecord(pRec, AcDb::kForWrite)==Acad::eOk && pRec)
|
|
{
|
|
const TCHAR *rName=NULL;
|
|
pRec->getName(rName);
|
|
BOOL bXref = pRec->isFromExternalReference();
|
|
pRec->close();
|
|
|
|
if (m_bCmpXref && bXref)
|
|
{
|
|
//关闭pRec,先Reload,再Bind
|
|
// Acad::ErrorStatus es = acedXrefReload(rName, true, pDbInsert);
|
|
Acad::ErrorStatus es = acedXrefReload(rName, true);
|
|
if (es == Acad::eOk)
|
|
{
|
|
// es = acedXrefBind(rName, false, true, pDbInsert);
|
|
es = acedXrefBind(rName, false, true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
acedSetStatusBarProgressMeter(_T("导入文件中..."), 0, len);
|
|
|
|
for(pIterator->start(); !pIterator->done(); pIterator->step())
|
|
{
|
|
acedSetStatusBarProgressMeterPos(i);
|
|
i++;
|
|
AcDbBlockTableRecord *pRec=NULL;
|
|
if(pIterator->getRecord(pRec, AcDb::kForWrite)==Acad::eOk && pRec)
|
|
{
|
|
const TCHAR *rName=NULL;
|
|
pRec->getName(rName);
|
|
|
|
BOOL bMspace=(_tcsicmp(rName, ACDB_MODEL_SPACE)==0 || _tcsicmp(rName, ACDB_PAPER_SPACE)==0);
|
|
if(!bMspace)
|
|
{
|
|
CString csName = rName;
|
|
csName = csName + _T("-") + sFileName;
|
|
pRec->setName(csName);
|
|
}
|
|
pRec->close();
|
|
}
|
|
}
|
|
delete pIterator;
|
|
acedRestoreStatusBar();
|
|
}
|
|
pDb->insert(id, sFileName, pDbInsert);
|
|
}
|
|
else
|
|
{
|
|
id=blk.m_pBlockTableRec->objectId();
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
void CCompareDwg::ProcessBlk( AcDbObjectId idBlock, int iColIdx, CDataEntityList &lstDwgRow )
|
|
{
|
|
int nLenLst = lstDwgRow.Length();
|
|
|
|
//遍历炸开后的块,进行分块
|
|
AcDbBlockTableRecordIterator *pIterator = NULL;
|
|
OPENOBJ_BEGIN(idBlock, AcDb::kForWrite, AcDbBlockTableRecord , pRec);
|
|
if(pRec)
|
|
{
|
|
pRec->newIterator(pIterator);
|
|
}
|
|
OPENOBJ_END();
|
|
|
|
for(pIterator->start(); !pIterator->done(); pIterator->step())
|
|
{
|
|
AcDbEntity *pEnt = NULL;
|
|
Acad::ErrorStatus es = pIterator->getEntity(pEnt, AcDb::kForWrite);
|
|
if(es == Acad::eOk && pEnt != NULL)
|
|
{
|
|
//设置图层 颜色
|
|
pEnt->setLayer(_T("0"));
|
|
pEnt->setColorIndex(iColIdx);
|
|
//根据外包计算列表下标
|
|
AcDbExtents bExtent;
|
|
pEnt->getGeomExtents(bExtent);
|
|
//处理字体缺失,文字外包不准确问题
|
|
AcDbText *pTextTemp = NULL;
|
|
if ( pTextTemp = AcDbText::cast(pEnt) )
|
|
{
|
|
bExtent.set(pTextTemp->position(), pTextTemp->position());
|
|
}
|
|
//int nIndex = GetIndexOfArea(bExtent);
|
|
int nIndex = GetIndexOfArea(bExtent, nLenLst);
|
|
//超出范围的实体不进行比对
|
|
if (nIndex<0 || nIndex>=nLenLst)
|
|
{
|
|
pEnt->close();
|
|
continue;
|
|
}
|
|
|
|
DList<TCompareEntity> &lstDwg = lstDwgRow[nIndex];
|
|
|
|
AcDbObjectId id = pEnt->objectId();
|
|
AcDbBlockReference *pBlockRef = NULL;
|
|
AcDbLine *pLine = NULL;
|
|
AcDbArc *pArc = NULL;
|
|
AcDbCircle *pCir = NULL;
|
|
AcDbPoint *pt = NULL;
|
|
AcDbSolid *pSolid = NULL;
|
|
AcDbText *pText = NULL;
|
|
AcDbAlignedDimension *pDim = NULL;
|
|
|
|
XCurveSegment seg;
|
|
if(pLine = AcDbLine::cast(pEnt))
|
|
{
|
|
XLine line(XPoint(pLine->startPoint()), XPoint(pLine->endPoint()));
|
|
seg = line;
|
|
TCompareEntity *pNew = new TCompareEntity(seg);
|
|
pNew->m_id = id;
|
|
lstDwg.Append(pNew);
|
|
}
|
|
else if(pArc = AcDbArc::cast(pEnt))
|
|
{
|
|
AcGePoint3d ptStart, ptEnd;
|
|
pArc->getStartPoint(ptStart);
|
|
pArc->getEndPoint(ptEnd);
|
|
double dAng(0), dLen(0);
|
|
pArc->getDistAtPoint(ptEnd, dLen);
|
|
dAng = dLen / pArc->radius();
|
|
XArc arc(XPoint(ptStart), XPoint(ptStart), dAng);
|
|
seg = arc;
|
|
TCompareEntity *pNew = new TCompareEntity(seg);
|
|
pNew->m_id = id;
|
|
lstDwg.Append(pNew);
|
|
}
|
|
else if(pCir = AcDbCircle::cast(pEnt))
|
|
{
|
|
AcGePoint3d ptCen = pCir->center();
|
|
XCircle cir(XPoint(ptCen), pCir->radius());
|
|
seg = cir;
|
|
TCompareEntity *pNew = new TCompareEntity(seg);
|
|
pNew->m_id = id;
|
|
lstDwg.Append(pNew);
|
|
}
|
|
else if(pt = AcDbPoint::cast(pEnt))
|
|
{
|
|
TCompareEntity *pNew = new TCompareEntity(pt->position());
|
|
pNew->m_id = id;
|
|
lstDwg.Append(pNew);
|
|
}
|
|
else if(pSolid = AcDbSolid::cast(pEnt))
|
|
{
|
|
AcGePoint3d p1, p2, p3, p4;
|
|
pSolid->getPointAt(0, p1);
|
|
pSolid->getPointAt(1, p2);
|
|
pSolid->getPointAt(2, p3);
|
|
pSolid->getPointAt(3, p4);
|
|
|
|
TCompareEntity *pNew = new TCompareEntity(p1, p2, p3, p4);
|
|
pNew->m_id = id;
|
|
lstDwg.Append(pNew);
|
|
}
|
|
else if(pText = AcDbText::cast(pEnt))
|
|
{
|
|
TCHAR *szText = pText->textString();
|
|
CString csText = szText;
|
|
delete szText;
|
|
AcGePoint3d ptLoc = pText->position();
|
|
TCompareEntity *pNew = new TCompareEntity(ptLoc, pText->height(), csText);
|
|
pNew->m_id = id;
|
|
lstDwg.Append(pNew);
|
|
}
|
|
else if(pDim = AcDbAlignedDimension::cast(pEnt))
|
|
{
|
|
TCHAR *szText = pDim->dimensionText();
|
|
CString csText = szText;
|
|
delete szText;
|
|
AcGePoint3d ptLoc = pDim->dimLinePoint();
|
|
AcGePoint3d p1 = pDim->xLine1Point();
|
|
AcGePoint3d p2 = pDim->xLine2Point();
|
|
TCompareEntity *pNew = new TCompareEntity(ptLoc, p1, p2, csText);
|
|
pNew->m_id = id;
|
|
lstDwg.Append(pNew);
|
|
}
|
|
else
|
|
{
|
|
//如果不是以上图元,有可能复杂图元没有完全炸碎,这里简化处理,将他们删除显示
|
|
//打印实体类型
|
|
//acutPrintf(_T("\n复杂图元:name[%s],dxfName[%s]"), pEnt->isA()->name(), pEnt->isA()->dxfName());
|
|
//m_mapOtherEnt[pEnt->isA()->name()]++;
|
|
m_mapOtherEnt[pEnt->isA()->dxfName()]++;
|
|
pEnt->erase();
|
|
}
|
|
pEnt->close();
|
|
}
|
|
}
|
|
delete pIterator;
|
|
}
|
|
|
|
void CCompareDwg::ProcessEnt( AcDbEntity * pEnt, int iColIdx, CDataEntityList &lstData )
|
|
{
|
|
//pEnt已是打开状态,不再打开或关闭
|
|
if (pEnt == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
int nLenLst = lstData.Length();
|
|
|
|
//设置图层 颜色
|
|
Acad::ErrorStatus es = pEnt->setLayer(_T("0"));
|
|
es = pEnt->setColorIndex(iColIdx);
|
|
//根据外包计算列表下标
|
|
AcDbExtents bExtent;
|
|
es = pEnt->getGeomExtents(bExtent);
|
|
//标注获取外包失败
|
|
if (es == Acad::eInvalidExtents && pEnt->isKindOf(AcDbAlignedDimension::desc()))
|
|
{
|
|
AcDbAlignedDimension * pDim = AcDbAlignedDimension::cast(pEnt);
|
|
if (pDim == NULL)
|
|
{
|
|
return;
|
|
}
|
|
bExtent.set(pDim->dimLinePoint(), pDim->dimLinePoint());
|
|
//设置标注文字颜色20130609
|
|
pDim->setColorIndex(iColIdx);
|
|
AcCmColor clr;
|
|
clr.setColorIndex(iColIdx);
|
|
pDim->setDimclre(clr);
|
|
pDim->setDimclrd(clr);
|
|
pDim->setDimclrt(clr);
|
|
}
|
|
//处理字体缺失,文字外包不准确问题
|
|
AcDbText *pTextTemp = NULL;
|
|
if ( pTextTemp = AcDbText::cast(pEnt) )
|
|
{
|
|
bExtent.set(pTextTemp->position(), pTextTemp->position());
|
|
}
|
|
int nIndex = GetIndexOfArea(bExtent, nLenLst);
|
|
//超出范围的实体不进行比对
|
|
if (nIndex<0 || nIndex>=nLenLst)
|
|
{
|
|
return;
|
|
}
|
|
|
|
DList<TCompareEntity> &lstDwg = lstData[nIndex];
|
|
|
|
AcDbObjectId id = pEnt->objectId();
|
|
AcDbLine *pLine = NULL;
|
|
AcDbArc *pArc = NULL;
|
|
AcDbCircle *pCir = NULL;
|
|
AcDbPoint *pt = NULL;
|
|
AcDbSolid *pSolid = NULL;
|
|
AcDbText *pText = NULL;
|
|
AcDbAlignedDimension *pDim = NULL;
|
|
|
|
XCurveSegment seg;
|
|
if(pLine = AcDbLine::cast(pEnt))
|
|
{
|
|
XLine line(XPoint(pLine->startPoint()), XPoint(pLine->endPoint()));
|
|
seg = line;
|
|
TCompareEntity *pNew = new TCompareEntity(seg);
|
|
pNew->m_id = id;
|
|
lstDwg.Append(pNew);
|
|
}
|
|
else if(pArc = AcDbArc::cast(pEnt))
|
|
{
|
|
AcGePoint3d ptStart, ptEnd;
|
|
pArc->getStartPoint(ptStart);
|
|
pArc->getEndPoint(ptEnd);
|
|
double dAng(0), dLen(0);
|
|
pArc->getDistAtPoint(ptEnd, dLen);
|
|
dAng = dLen / pArc->radius();
|
|
XArc arc(XPoint(ptStart), XPoint(ptStart), dAng);
|
|
seg = arc;
|
|
TCompareEntity *pNew = new TCompareEntity(seg);
|
|
pNew->m_id = id;
|
|
lstDwg.Append(pNew);
|
|
}
|
|
else if(pCir = AcDbCircle::cast(pEnt))
|
|
{
|
|
AcGePoint3d ptCen = pCir->center();
|
|
XCircle cir(XPoint(ptCen), pCir->radius());
|
|
seg = cir;
|
|
TCompareEntity *pNew = new TCompareEntity(seg);
|
|
pNew->m_id = id;
|
|
lstDwg.Append(pNew);
|
|
}
|
|
else if(pt = AcDbPoint::cast(pEnt))
|
|
{
|
|
TCompareEntity *pNew = new TCompareEntity(pt->position());
|
|
pNew->m_id = id;
|
|
lstDwg.Append(pNew);
|
|
}
|
|
else if(pSolid = AcDbSolid::cast(pEnt))
|
|
{
|
|
AcGePoint3d p1, p2, p3, p4;
|
|
pSolid->getPointAt(0, p1);
|
|
pSolid->getPointAt(1, p2);
|
|
pSolid->getPointAt(2, p3);
|
|
pSolid->getPointAt(3, p4);
|
|
|
|
TCompareEntity *pNew = new TCompareEntity(p1, p2, p3, p4);
|
|
pNew->m_id = id;
|
|
lstDwg.Append(pNew);
|
|
}
|
|
else if(pText = AcDbText::cast(pEnt))
|
|
{
|
|
TCHAR *szText = pText->textString();
|
|
CString csText = szText;
|
|
delete szText;
|
|
AcGePoint3d ptLoc = pText->position();
|
|
TCompareEntity *pNew = new TCompareEntity(ptLoc, pText->height(), csText);
|
|
pNew->m_id = id;
|
|
lstDwg.Append(pNew);
|
|
}
|
|
else if(pDim = AcDbAlignedDimension::cast(pEnt))
|
|
{
|
|
TCHAR *szText = pDim->dimensionText();
|
|
CString csText = szText;
|
|
delete szText;
|
|
AcGePoint3d ptLoc = pDim->dimLinePoint();
|
|
AcGePoint3d p1 = pDim->xLine1Point();
|
|
AcGePoint3d p2 = pDim->xLine2Point();
|
|
TCompareEntity *pNew = new TCompareEntity(ptLoc, p1, p2, csText);
|
|
pNew->m_id = id;
|
|
lstDwg.Append(pNew);
|
|
}
|
|
else
|
|
{
|
|
//如果不是以上图元,有可能复杂图元没有完全炸碎,这里简化处理,将他们删除显示
|
|
//打印实体类型
|
|
//acutPrintf(_T("\n复杂图元:name[%s],dxfName[%s]"), pEnt->isA()->name(), pEnt->isA()->dxfName());
|
|
//m_mapOtherEnt[pEnt->isA()->name()]++;
|
|
m_mapOtherEnt[pEnt->isA()->dxfName()]++;
|
|
pEnt->erase();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
BOOL CCompareDwg::DeepExplodeBlock( AcDbBlockTableRecord *pRec, CDwgCompareDbMgr * pDbMgr, CDataEntityList & dataList, int iColIdx )
|
|
{
|
|
if (pRec==NULL || pDbMgr==NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
AcDbBlockTableRecordIterator *pRecIter=NULL;
|
|
if(pRec->newIterator(pRecIter)!=Acad::eOk || !pRecIter)
|
|
return FALSE;
|
|
|
|
std::vector< CString > vtlayer;
|
|
pDbMgr->GetCmpLayer(vtlayer);
|
|
//对块表记录中的对象进行分解
|
|
AcDbVoidPtrArray arpNewSet;
|
|
AcDbObjectIdArray arrId;
|
|
for(pRecIter->start(); !pRecIter->done(); pRecIter->step())
|
|
{
|
|
AcDbEntity *pEnt=NULL;
|
|
Acad::ErrorStatus es = pRecIter->getEntity(pEnt, AcDb::kForWrite);
|
|
ASSERT(pEnt);
|
|
if(es==Acad::eOk && pEnt != NULL)
|
|
{
|
|
BOOL bDelete = FALSE;
|
|
if (!m_bCmpBlockRef && pEnt->isKindOf(AcDbBlockReference::desc()))
|
|
{
|
|
//删除块
|
|
bDelete = TRUE;
|
|
}
|
|
else if (!m_bCmpHatch && pEnt->isKindOf(AcDbHatch::desc()))
|
|
{
|
|
//删除填充
|
|
bDelete = TRUE;
|
|
}
|
|
else
|
|
{
|
|
//根据图层过滤,炸开后的实体不进行过滤
|
|
std::vector< CString >::iterator itrFind = find(vtlayer.begin(), vtlayer.end(), pEnt->layer());
|
|
if (itrFind == vtlayer.end())
|
|
{
|
|
bDelete =TRUE;
|
|
}
|
|
}
|
|
if (bDelete)
|
|
{
|
|
pEnt->erase();
|
|
pEnt->close();
|
|
continue;
|
|
}
|
|
int iRet = ExplodeEntity(pEnt, arpNewSet);
|
|
if(iRet == 1)
|
|
{
|
|
//循环炸碎对象, 如果能分解, 就把该对象删除
|
|
AcDbObjectId id = pEnt->objectId();
|
|
if ( !id.isNull() )
|
|
{
|
|
arrId.append(id);
|
|
}
|
|
//但现在不能删除, 因为自定义实体还有依赖关系. 先存放起来
|
|
}
|
|
else
|
|
{
|
|
//计算分块
|
|
ProcessEnt(pEnt, iColIdx, dataList);
|
|
}
|
|
pEnt->close();
|
|
}
|
|
}
|
|
delete pRecIter;
|
|
|
|
//对块表中的上华对象(复杂对象)进行删除
|
|
for(int j=0;j<arrId.length();j++)
|
|
{
|
|
AcDbEntity *pEnt=NULL;
|
|
AcDbObjectId id = arrId[j];
|
|
acdbOpenAcDbEntity(pEnt, id, AcDb::kForWrite);
|
|
if(pEnt != NULL)
|
|
{
|
|
pEnt->erase();
|
|
pEnt->close();
|
|
}
|
|
}
|
|
|
|
//把新对象加入图块记录中,同时计算分块
|
|
int idx = arpNewSet.length();
|
|
while((--idx) >= 0)
|
|
{
|
|
AcDbEntity* pNewEnt = (AcDbEntity*)arpNewSet[idx];
|
|
if (pNewEnt != NULL)
|
|
{
|
|
Acad::ErrorStatus es = pRec->appendAcDbEntity(pNewEnt);
|
|
VERIFY(es==Acad::eOk);
|
|
if (es == Acad::eOk)
|
|
{
|
|
//计算分块
|
|
ProcessEnt(pNewEnt, iColIdx, dataList);
|
|
pNewEnt->close();
|
|
}
|
|
//添加失败则删除临时实体
|
|
else
|
|
{
|
|
delete pNewEnt;
|
|
pNewEnt = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
int CCompareDwg::ExplodeEntity( AcDbEntity* pEnt, AcDbVoidPtrArray& arpNewSet )
|
|
{
|
|
if(pEnt == NULL)
|
|
return 0;
|
|
|
|
/*if(pEnt->isKindOf(AcDbDimension::desc()))
|
|
{
|
|
return 0;
|
|
}*/
|
|
|
|
if(m_bCmpBlockRef && pEnt->isKindOf(AcDbBlockReference::desc()))
|
|
{
|
|
//对于图块特殊处理, 因为炸开后, 属性字不能正常显示, 这里新生成一个文字
|
|
AcDbBlockReference *pInsert = (AcDbBlockReference *)pEnt;
|
|
CreateAttributeText(pInsert, arpNewSet);
|
|
}
|
|
|
|
AcDbVoidPtrArray entSet;
|
|
Acad::ErrorStatus es = pEnt->explode(entSet);
|
|
if (es == 600)//Acad::eInvalidObjectId sys17
|
|
{
|
|
//返回-1,如果是炸开后的临时实体直接delete
|
|
return -1;
|
|
}
|
|
|
|
int num=entSet.length();
|
|
if(num == 0)
|
|
{
|
|
//不能再炸开, 说明是简单对象, 返回0,如果是炸开后的临时实体则加入数据库
|
|
return 0;
|
|
}
|
|
|
|
//块参照内标注位置处理
|
|
BOOL bBlkRef = FALSE;
|
|
AcGePoint3d ptPosBlkRef;
|
|
if(pEnt->isKindOf(AcDbBlockReference::desc()))
|
|
{
|
|
bBlkRef = TRUE;
|
|
ptPosBlkRef = ((AcDbBlockReference *)pEnt)->position();
|
|
}
|
|
|
|
for(int n=0; n<num; n++)
|
|
{
|
|
AcDbEntity *pNewEnt=(AcDbEntity *)entSet[n];
|
|
if(pNewEnt == NULL)
|
|
continue;
|
|
|
|
//不比对块参照和填充
|
|
if (!m_bCmpBlockRef && pNewEnt->isKindOf(AcDbBlockReference::desc()))
|
|
{
|
|
delete pNewEnt;
|
|
pNewEnt = NULL;
|
|
continue;
|
|
}
|
|
else if (!m_bCmpHatch && pNewEnt->isKindOf(AcDbHatch::desc()))
|
|
{
|
|
delete pNewEnt;
|
|
pNewEnt = NULL;
|
|
continue;
|
|
}
|
|
|
|
//块参照内标注位置处理
|
|
if (bBlkRef && pNewEnt->isKindOf(AcDbDimension::desc()))
|
|
{
|
|
//炸开块后,标注位置根据块位置移动
|
|
AcGeMatrix3d mat;
|
|
//块相对原点的位移
|
|
mat.setToTranslation(ptPosBlkRef-AcGePoint3d(0,0,0));
|
|
pNewEnt->transformBy(mat);
|
|
// pNewEnt->recordGraphicsModified();
|
|
}
|
|
|
|
|
|
int ret = ExplodeEntity(pNewEnt, arpNewSet);
|
|
if(ret == 1 || ret == -1)
|
|
{
|
|
delete pNewEnt; //如果还能删除, delete掉父实体, 不会内存泄漏
|
|
pNewEnt = NULL;
|
|
}
|
|
else
|
|
{
|
|
arpNewSet.append(pNewEnt);//最末端实体, 直接加入链表
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
BOOL CCompareDwg::CompareCurve( DList<TCompareEntity> &lstDwg1, DList<TCompareEntity> &lstDwg2 )
|
|
{
|
|
long len=lstDwg1.Length();
|
|
long lenLst2=lstDwg2.Length();
|
|
//acutPrintf(_T("\n此区域比对:[%d]*[%d]"), len, lenLst2);
|
|
if(len > 10000)
|
|
{
|
|
m_iCountEnt++;
|
|
acutPrintf( _T("\n图元数量超过10000个比对速度比较慢,此区域比较数量%ld个..."), len);
|
|
|
|
/*TCHAR szYes[256];
|
|
int ret = ads_getstring(0, _T("\n图纸太大,图元数量超过10000个比对速度会比较慢(推荐使用局部比对命令),是否继续比对?<N>:"), szYes);
|
|
if(_tcsicmp(szYes, _T("Y")) != 0)
|
|
return FALSE;*/
|
|
}
|
|
|
|
DList<AcDbObjectId> lstDel;
|
|
// 7.下面开始比对, 首先把第一张图完全一致的线段置为白色。
|
|
long i=0;
|
|
for(i=0;i<len;i++)
|
|
{
|
|
|
|
if (lstDwg1[i] == NULL)
|
|
{
|
|
continue;
|
|
}
|
|
TCompareEntity curve = *lstDwg1[i];
|
|
long len2=lstDwg2.Length();
|
|
for(long j=0;j<len2;j++)
|
|
{
|
|
if (lstDwg2[j] == NULL)
|
|
{
|
|
continue;
|
|
}
|
|
TCompareEntity curve2 = *lstDwg2[j];
|
|
|
|
if(curve == curve2)
|
|
{
|
|
//首先检查有没有重合的线,已经在删除队列内了
|
|
BOOL bFindDeled = FALSE;
|
|
long len3 = lstDel.Length();
|
|
for(long m=0;m<lstDel.Length();m++)
|
|
{
|
|
AcDbObjectId idDel = *lstDel[m];
|
|
if(curve2.m_id == idDel)
|
|
{
|
|
bFindDeled = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
if(bFindDeled)
|
|
continue;//继续比对
|
|
|
|
OPENOBJ_BEGIN(curve.m_id, AcDb::kForWrite, AcDbEntity, pEnt);
|
|
if(pEnt)
|
|
{
|
|
AcDbAlignedDimension *pDim = NULL;
|
|
//修改尺寸的颜色
|
|
if(pDim = AcDbAlignedDimension::cast(pEnt))
|
|
{
|
|
AcCmColor color;
|
|
color.setColorIndex(7);
|
|
pDim->setDimclre(color);
|
|
pDim->setDimclrd(color);
|
|
AcDbObjectId idDimRec = pDim->dimBlockId();
|
|
//修改尺寸块记录的颜色
|
|
AcDbBlockTableRecordIterator *pDimIterator = NULL;
|
|
OPENOBJ_BEGIN(idDimRec, AcDb::kForRead, AcDbBlockTableRecord , pRec);
|
|
if(pRec)
|
|
{
|
|
pRec->newIterator(pDimIterator);
|
|
}
|
|
OPENOBJ_END();
|
|
for(pDimIterator->start(); !pDimIterator->done(); pDimIterator->step())
|
|
{
|
|
AcDbEntity *pEntDim = NULL;
|
|
pDimIterator->getEntity(pEntDim, AcDb::kForWrite);
|
|
if(pEntDim)
|
|
{
|
|
pEntDim->setLayer(_T("0"));
|
|
pEntDim->setColorIndex(7);
|
|
pEntDim->close();
|
|
}
|
|
}
|
|
delete pDimIterator;
|
|
}
|
|
pEnt->setColorIndex(7);
|
|
pEnt->recordGraphicsModified();
|
|
}
|
|
OPENOBJ_END();
|
|
lstDel.Append(new AcDbObjectId(curve2.m_id));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
// 8.把第二张图重复的图元删除
|
|
for(i=0;i<lstDel.Length();i++)
|
|
{
|
|
if ( (*lstDel[i]).isNull() )
|
|
{
|
|
continue;
|
|
}
|
|
OPENOBJ_BEGIN(*lstDel[i], AcDb::kForWrite, AcDbEntity, pEnt);
|
|
if(pEnt)
|
|
{
|
|
pEnt->erase();
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void CCompareDwg::CreateAttributeText( AcDbBlockReference * pInsert, AcDbVoidPtrArray& arpNewSet )
|
|
{
|
|
if (pInsert == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
AcDbObjectIterator *pAttrIterator = NULL;
|
|
pAttrIterator = pInsert->attributeIterator();
|
|
if(pAttrIterator != NULL)
|
|
{
|
|
for (pAttrIterator->start();!pAttrIterator->done();pAttrIterator->step())
|
|
{
|
|
AcDbObjectId att_id;
|
|
att_id = pAttrIterator->objectId();
|
|
AcDbEntity *pEnt2 = NULL;
|
|
AcDbAttribute *pAtt = NULL;
|
|
acdbOpenAcDbEntity(pEnt2, att_id, AcDb::kForRead);
|
|
if(pEnt2 != NULL)
|
|
{
|
|
pAtt = AcDbAttribute::cast(pEnt2);
|
|
if(pAtt && !pAtt->isInvisible()) //不可见不处理
|
|
{
|
|
AcDbText *pText = new AcDbText;
|
|
pText->copyFrom(pAtt);
|
|
TCHAR *szText2 = pAtt->textString();
|
|
pText->setTextString(szText2);
|
|
delete szText2;
|
|
szText2 = NULL;
|
|
pText->setHorizontalMode(pAtt->horizontalMode());
|
|
pText->setVerticalMode(pAtt->verticalMode());
|
|
pText->setPosition(pAtt->position());
|
|
pText->setAlignmentPoint(pAtt->alignmentPoint());
|
|
pText->setTextStyle(pAtt->textStyle());
|
|
pText->setHeight(pAtt->height());
|
|
arpNewSet.append(pText);
|
|
}
|
|
pEnt2->close();
|
|
}
|
|
}
|
|
delete pAttrIterator;
|
|
}
|
|
}
|
|
|
|
void CCompareDwg::SetExtent()
|
|
{
|
|
//使用当前图纸外包
|
|
m_extBlk.set(acdbCurDwg()->extmin(), acdbCurDwg()->extmax());
|
|
//根据外包计算分块单位,对图纸分割
|
|
m_dUnitX = ( m_extBlk.maxPoint().x - m_extBlk.minPoint().x ) / m_iCol;
|
|
m_dUnitY = ( m_extBlk.maxPoint().y - m_extBlk.minPoint().y ) / m_iRow;
|
|
}
|
|
|
|
void CCompareDwg::SetExtent( const AcDbExtents & ext1, const AcDbExtents & ext2 )
|
|
{
|
|
if (m_iCmpType == 2)
|
|
{
|
|
//版本比对使用传进来的外包
|
|
m_extBlk = ext1;
|
|
m_extBlk.addExt(ext2);
|
|
//根据外包计算分块单位,分割选择区域
|
|
m_dUnitX = ( m_extBlk.maxPoint().x - m_extBlk.minPoint().x ) / m_iCol;
|
|
m_dUnitY = ( m_extBlk.maxPoint().y - m_extBlk.minPoint().y ) / m_iRow;
|
|
}
|
|
else
|
|
{
|
|
SetExtent();
|
|
}
|
|
}
|
|
|
|
BOOL CCompareDwg::ResetAllLayerStatus()
|
|
{
|
|
AcDbLayerTable * pLayerTab = NULL;
|
|
Acad::ErrorStatus es = acdbCurDwg()->getLayerTable(pLayerTab, AcDb::kForRead);
|
|
if (es!=Acad::eOk || pLayerTab==NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
AcDbLayerTableIterator * pIte = NULL;
|
|
es = pLayerTab->newIterator(pIte);
|
|
pLayerTab->close();
|
|
if (es!=Acad::eOk || pIte==NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
for (pIte->start(); !pIte->done(); pIte->step())
|
|
{
|
|
AcDbLayerTableRecord * pLayerRec = NULL;
|
|
es = pIte->getRecord(pLayerRec, AcDb::kForWrite);
|
|
if (es!=Acad::eOk || pLayerRec==NULL)
|
|
{
|
|
continue;
|
|
}
|
|
pLayerRec->setIsOff(false);
|
|
pLayerRec->setIsFrozen(false);
|
|
pLayerRec->setIsLocked(false);
|
|
pLayerRec->close();
|
|
}
|
|
delete pIte;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CCompareDwg::PrintInfo()
|
|
{
|
|
//没有处理的实体类型
|
|
std::map<CString, int>::iterator itor= m_mapOtherEnt.begin();
|
|
for ( ; itor!=m_mapOtherEnt.end(); itor++)
|
|
{
|
|
//m_mapOtherEnt[(*itor).first];
|
|
acutPrintf(_T("\nName[%s],Count[%d]"), itor->first, itor->second);
|
|
}
|
|
if (m_iCountEnt>0)
|
|
{
|
|
acutPrintf(_T("\n第一张图纸中超过10000个实体的区域有[%d]个,建议增加分块数..."), m_iCountEnt);
|
|
}
|
|
}
|
|
int CCompareDwg::GetIndexOfArea( AcDbExtents & extEnt )
|
|
{
|
|
/*double dX = (extEnt.minPoint().x + extEnt.maxPoint().x) /2 - m_extBlk.minPoint().x;
|
|
double dY = (extEnt.minPoint().y + extEnt.maxPoint().y) /2 - m_extBlk.minPoint().y;*/
|
|
double dX = extEnt.minPoint().x - m_extBlk.minPoint().x;
|
|
double dY = extEnt.minPoint().y - m_extBlk.minPoint().y;
|
|
|
|
//误差不超过一个分割单位大小
|
|
if(dX>-m_dUnitX && dX<1e-15)
|
|
{
|
|
dX = 0.0;
|
|
}
|
|
if(dY>-m_dUnitY && dY<1e-15)
|
|
{
|
|
dY = 0.0;
|
|
}
|
|
dX /= m_dUnitX;
|
|
dY /= m_dUnitY;
|
|
|
|
int nIndex = (int)(floor(dY) * m_iCol + floor(dX));
|
|
return nIndex;
|
|
}
|
|
|
|
int CCompareDwg::GetIndexOfArea( AcDbExtents & extEnt, int iMaxValue )
|
|
{
|
|
int nIndex = GetIndexOfArea(extEnt);
|
|
//放到第一个区域
|
|
if (nIndex<0 && nIndex>-m_iCol)
|
|
{
|
|
nIndex = 0;
|
|
}
|
|
//超出范围不太多,在误差允许范围
|
|
else if (nIndex>=iMaxValue && nIndex<=iMaxValue+m_iCol)
|
|
{
|
|
nIndex = iMaxValue-1;
|
|
}
|
|
//超出范围太多不处理
|
|
else if (nIndex>iMaxValue+m_iCol || nIndex<-m_iCol)
|
|
{
|
|
nIndex = -1;
|
|
}
|
|
return nIndex;
|
|
}
|
|
|
|
void CCompareDwg::WriteLogFile( double dTimeSecond )
|
|
{
|
|
//比对记录
|
|
//CString g_csLogFile = _T("C:\\DwgCompare_LogFile_图纸比对记录.txt");
|
|
CStdioFile file;
|
|
CFileFind find;
|
|
if (find.FindFile(g_csLogFile))
|
|
{
|
|
if (!file.Open(g_csLogFile, CFile::modeWrite))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!file.Open(g_csLogFile,CFile::modeCreate | CFile::modeWrite))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
CString csLog = _T("");
|
|
CString csTemp = _T("\r\nBegin**********************");
|
|
csLog += csTemp;
|
|
|
|
SYSTEMTIME t;
|
|
GetLocalTime(&t);
|
|
csTemp.Format(_T("[%d-%d-%d %d:%d:%d:%d]"), t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond, t.wMilliseconds);
|
|
csLog += csTemp;
|
|
|
|
csTemp.Format(_T("\r\n分块比对时间:%lf秒"), dTimeSecond);
|
|
csLog += csTemp;
|
|
|
|
csTemp.Format(_T("\r\n行数:%d, 列数:%d"), m_iCol, m_iRow);
|
|
csLog += csTemp;
|
|
|
|
csTemp.Format(_T("\r\n块:%d, 填充:%d, 外部参照:%d"), m_bCmpBlockRef, m_bCmpHatch, m_bCmpXref);
|
|
csLog += csTemp;
|
|
|
|
csTemp = _T("\r\nEnd**********************");
|
|
csLog += csTemp;
|
|
|
|
file.SeekToEnd();
|
|
file.WriteString(csLog);
|
|
file.Close();
|
|
}
|
|
|
|
void CCompareDwg::WriteLogFile( double dTimeSecond, CString csInfo )
|
|
{
|
|
|
|
//比对记录
|
|
//CString g_csLogFile = _T("C:\\DwgCompare_LogFile_图纸比对记录.txt");
|
|
CStdioFile file;
|
|
CFileFind find;
|
|
if (find.FindFile(g_csLogFile))
|
|
{
|
|
if (!file.Open(g_csLogFile, CFile::modeWrite))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!file.Open(g_csLogFile,CFile::modeCreate | CFile::modeWrite))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
CString csLog = _T("");
|
|
CString csTemp = _T("\r\nBegin**********************");
|
|
csLog += csTemp;
|
|
|
|
SYSTEMTIME t;
|
|
GetLocalTime(&t);
|
|
csTemp.Format(_T("[%d-%d-%d %d:%d:%d:%d]"), t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond, t.wMilliseconds);
|
|
csLog += csTemp;
|
|
|
|
csLog += csInfo;
|
|
|
|
csTemp = _T("\r\nEnd**********************");
|
|
csLog += csTemp;
|
|
|
|
file.SeekToEnd();
|
|
file.WriteString(csLog);
|
|
file.Close();
|
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//class CComparePartOfDwg
|
|
CComparePartOfDwg::CComparePartOfDwg( void )
|
|
{
|
|
|
|
}
|
|
|
|
CComparePartOfDwg::~CComparePartOfDwg( void )
|
|
{
|
|
|
|
}
|
|
|
|
BOOL CComparePartOfDwg::DoComparePartOfFile(Entity ent, CString & csPath)
|
|
{
|
|
csPath.Empty();
|
|
//选取另一个文件
|
|
CAcModuleResourceOverride vTemp;
|
|
CString csFileName2;
|
|
CFileDialog dlg(TRUE,_T("*.dwg"),csFileName2,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
|
|
_T("Drawing(*.dwg) |*.dwg||"), acedGetAcadFrame());
|
|
TCHAR strDlgTitle[] = _T("选择要比对的DWG文件");
|
|
dlg.m_ofn.lpstrTitle = strDlgTitle;
|
|
if(dlg.DoModal()!=IDOK)
|
|
{
|
|
return FALSE;
|
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
|
XPoly2D poly(ent);
|
|
PickSet ss(SS_FREE);
|
|
poly.TransUCS(Groups(0), Groups(1));//Groups(0) wcs, Groups(1) ucs
|
|
RBList rbFence = poly.Fence();
|
|
XPoint ptLow3, ptUp3;
|
|
poly.GetExtend(ptLow3, ptUp3);
|
|
Acad::ErrorStatus es = AssureInCurrentView(ptLow3, ptUp3);
|
|
ss.Get(_T("CP"), rbFence, NULL, RBList());
|
|
ss-= ent;
|
|
|
|
AcDbObjectIdArray aryObj;
|
|
ss.AsIdArray(aryObj);
|
|
if (aryObj.length()<1)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
clock_t startTime, finishTime; //计时
|
|
double duration1, duration2;
|
|
startTime = clock();
|
|
|
|
//导出多段线内的实体
|
|
CString csFilePath1;
|
|
csFilePath1 = acDocManager->curDocument()->fileName();
|
|
CDwgCompareDbMgr mgr1;
|
|
AcDbDatabase * pDbCur = acdbCurDwg();
|
|
if (!mgr1.LoadDb(csFilePath1, pDbCur, aryObj, AcGePoint3d(0,0,0)))
|
|
//if (!mgr1.LoadFile(csFilePath1, csFilePath1, poly))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
finishTime = clock();
|
|
duration1 = (double)(finishTime - startTime) / CLOCKS_PER_SEC;
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
startTime = clock();
|
|
|
|
//读取另一个文件
|
|
CDwgCompareDbMgr mgr2;
|
|
if (!mgr2.LoadFile(dlg.GetFileName(), dlg.GetPathName(), poly))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
finishTime = clock();
|
|
duration2 = (double)(finishTime - startTime) / CLOCKS_PER_SEC;
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
CDwgCompareDlg dlgCmp(&mgr1, &mgr2, 1);
|
|
if(dlgCmp.DoModal() == IDOK)
|
|
{
|
|
clock_t startTimeG, finishTimeG; //计时
|
|
double durationG;
|
|
startTimeG = clock();
|
|
|
|
PickSet ssNew(SS_FREE);
|
|
ssNew.IncludeBegin();
|
|
m_bCmpBlockRef = dlgCmp.m_bCmpBlock; //设置是否比对块
|
|
m_bCmpHatch = dlgCmp.m_bCmpHatch; //设置是否比对填充
|
|
m_bCmpXref = dlgCmp.m_bCmpXref; //设置是否比对外部参照
|
|
m_iRow = dlgCmp.m_iRowCount; //设置分块行列数
|
|
m_iCol = dlgCmp.m_iColumnCount;
|
|
DoCompareFile(&mgr1, &mgr2);
|
|
ssNew.IncludeEnd();
|
|
|
|
XPoint ptIns;
|
|
TCHAR dwgPrefix[256]=_T("");
|
|
GetTempPath(255, dwgPrefix);
|
|
if(dwgPrefix[_tcslen(dwgPrefix)-1]!=_T('\\'))
|
|
_tcscat(dwgPrefix, _T("\\"));
|
|
CString csTempFile;
|
|
csTempFile.Format(_T("%sCompareDwg.dwg"), dwgPrefix);
|
|
if(FindFile(csTempFile))
|
|
{
|
|
if (!DeleteFile(csTempFile))
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
// 将对比的结果导出到一个临时文件中
|
|
BOOL ret = arxWBlock(ssNew, csTempFile, ptIns);
|
|
|
|
//错误说明:由于把结果文件CompareDwg.dwg置为了当前窗口, 所以在不切换窗口的情况下, 原图的内容和结果图一样
|
|
//解决方法:把删除原图的所有相关记录的代码提前到打开结果图代码前
|
|
//修改人、修改时间 LLJ 2010-02-05
|
|
// 删除本图所有相关记录
|
|
ssNew.Erase();
|
|
ads_command(RTSTR, _T(".PURGE"), RTSTR, _T("ALL"), RTSTR, _T(""), RTSTR, _T("N"), NULL);
|
|
/*if(ret != 0)
|
|
{
|
|
AcApDocument* pDoc = acDocManager->curDocument();
|
|
acDocManager->lockDocument(pDoc);
|
|
acDocManager->executeInApplicationContext(OpenDwgFile, (void *)(const TCHAR *)csTempFile);
|
|
acDocManager->unlockDocument(pDoc);
|
|
}*/
|
|
if(ret != 0)
|
|
{
|
|
csPath = csTempFile;
|
|
}
|
|
|
|
finishTimeG = clock();
|
|
durationG = (double)(finishTimeG - startTimeG) / CLOCKS_PER_SEC;
|
|
|
|
CString csTemp;
|
|
csTemp.Format(_T("\n局部比对文件1加载用时:%lf秒..\n[%s]"), duration1, mgr1.GetFilePath());
|
|
acutPrintf(csTemp);
|
|
//WriteLogFile(duration1, csTemp);
|
|
csTemp.Format(_T("\n局部比对文件2加载用时:%lf秒..\n[%s]"), duration2, mgr2.GetFilePath());
|
|
acutPrintf(csTemp);
|
|
//WriteLogFile(duration2, csTemp);
|
|
|
|
acutPrintf(_T("\n局部比对用时:%lf秒.."), durationG);
|
|
//WriteLogFile(durationG);//比对信息写入记录文件
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
int CComparePartOfDwg::GetIndexOfArea( AcDbExtents & extEnt, int iMaxValue )
|
|
{
|
|
double dX = extEnt.minPoint().x - m_extBlk.minPoint().x;
|
|
double dY = extEnt.minPoint().y - m_extBlk.minPoint().y;
|
|
|
|
//局部比对精确计算
|
|
if(dX>-1 && dX<1e-15)
|
|
{
|
|
dX = 0.0;
|
|
}
|
|
if(dY>-1 && dY<1e-15)
|
|
{
|
|
dY = 0.0;
|
|
}
|
|
dX /= m_dUnitX;
|
|
dY /= m_dUnitY;
|
|
|
|
int nIndex = (int)(floor(dY) * m_iCol + floor(dX));
|
|
if (nIndex>=iMaxValue && nIndex<=iMaxValue+m_iCol)
|
|
{
|
|
nIndex = iMaxValue-1;
|
|
}
|
|
|
|
return nIndex;
|
|
}
|
|
|
|
void CComparePartOfDwg::SetExtent( const AcDbExtents & ext1, const AcDbExtents & ext2 )
|
|
{
|
|
//局部比对使用传进来的外包
|
|
m_extBlk = ext1;
|
|
m_extBlk.addExt(ext2);
|
|
//根据外包计算分块单位,分割选择区域
|
|
m_dUnitX = ( m_extBlk.maxPoint().x - m_extBlk.minPoint().x ) / m_iCol;
|
|
m_dUnitY = ( m_extBlk.maxPoint().y - m_extBlk.minPoint().y ) / m_iRow;
|
|
} |