458 lines
14 KiB
C++
458 lines
14 KiB
C++
#include "stdafx.h"
|
|
#include "resource.h"
|
|
#include "TextStyleDlg.h"
|
|
#include "GridSheetDlg.h"
|
|
#include "TDbColumn.h"
|
|
#include "Project.h"
|
|
|
|
Adesk::Boolean acedPostCommand(const TCHAR * );
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// 统计体积表 <dwg>.op
|
|
class TVolumeTableItem {
|
|
// int operator == (const TVolumeTableItem *p1, const XOpenignData *p2);
|
|
public:
|
|
XString m_sMainKind, m_sMaterial;
|
|
double m_nVolume; // m^3
|
|
int m_nCount;
|
|
DList<double> m_lstVolumes; //keep the number of the Elements in every story
|
|
DList<int> m_lstLayCnt;
|
|
public:
|
|
TVolumeTableItem():m_nCount(1) {}
|
|
TVolumeTableItem(const TDbColumn &src);
|
|
TVolumeTableItem(const TDbWall &src);
|
|
TVolumeTableItem(const TVolumeTableItem &src);
|
|
TVolumeTableItem & operator = (const TVolumeTableItem &src);
|
|
static int CompareForSort(const TVolumeTableItem *, const TVolumeTableItem *);
|
|
static int CompareForFind(const TVolumeTableItem *p1, const void *pv2);
|
|
};
|
|
|
|
/*
|
|
int operator== (const TVolumeTableItem &p1, const TVolumeTableItem &p2)
|
|
{
|
|
return (_tcsicmp(p1.m_sTypeCode, p2.m_sTypeCode)==0 &&
|
|
strcmp(p1.m_sOpKind, p2.m_sOpKind)==0 &&
|
|
strcmp(p1.m_sSize, p2.m_sSize)==0);
|
|
}*/
|
|
|
|
TVolumeTableItem::TVolumeTableItem(const TVolumeTableItem &src)
|
|
{
|
|
*this = src;
|
|
}
|
|
|
|
TVolumeTableItem::TVolumeTableItem(const TDbColumn &src)
|
|
:m_nCount(1)
|
|
{
|
|
m_sMainKind = _T("柱");
|
|
m_sMaterial = src.GetMaterialText();
|
|
m_nVolume = _AS_CUMETER(src.GetVolume());
|
|
}
|
|
|
|
|
|
TVolumeTableItem::TVolumeTableItem(const TDbWall &src)
|
|
:m_nCount(1)
|
|
{
|
|
m_sMainKind = _T("墙");
|
|
m_sMaterial = src.GetStyleText();
|
|
m_nVolume = _AS_CUMETER(src.GetVolume());
|
|
}
|
|
|
|
|
|
|
|
TVolumeTableItem & TVolumeTableItem:: operator = (const TVolumeTableItem &src)
|
|
{
|
|
m_sMainKind = src.m_sMainKind;
|
|
m_sMaterial = src.m_sMaterial;
|
|
m_nVolume = src.m_nVolume;
|
|
m_nCount = src.m_nCount;
|
|
return *this;
|
|
}
|
|
|
|
|
|
int TVolumeTableItem::CompareForFind(const TVolumeTableItem *p1, const void *pv2)
|
|
{
|
|
const TVolumeTableItem *p2=(const TVolumeTableItem *)pv2;
|
|
if(_tcsicmp(p1->m_sMainKind, p2->m_sMainKind)==0 &&
|
|
_tcsicmp(p2->m_sMaterial, p2->m_sMaterial)==0)
|
|
return 0;
|
|
return 1;
|
|
}
|
|
|
|
|
|
int TVolumeTableItem::CompareForSort(const TVolumeTableItem *p1, const TVolumeTableItem *p2)
|
|
{
|
|
int nSeqCode1= _tcsicmp(p1->m_sMainKind, p2->m_sMainKind);
|
|
if(!nSeqCode1)
|
|
return nSeqCode1;
|
|
|
|
int nSeqCode2=_tcsicmp(p1->m_sMaterial, p2->m_sMaterial);
|
|
return nSeqCode2;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////
|
|
// 统计体积表(DList<AcDbObjectId>)
|
|
int StaticVolumeFromDatabase(DList<AcDbObjectId>& ssElements, DList<TVolumeTableItem> &lstVolumes)
|
|
{
|
|
int lCount=ssElements.Length();
|
|
for(int i=0; i<lCount; i++) {
|
|
AcDbObjectId &ent = *ssElements[i];
|
|
XDbObject obj(ent, AcDb::kForRead);
|
|
if(!obj) continue;
|
|
TDbColumn *pColu=TDbColumn::cast(obj.m_pObject);
|
|
TDbWall *pWall=TDbWall::cast(obj.m_pObject);
|
|
if(!pColu && !pWall)
|
|
continue;
|
|
|
|
TVolumeTableItem *pData1=NULL;
|
|
XString sCode;
|
|
if(pWall) {
|
|
if(!pWall->Has3D() || pWall->GetUsageFlag()!=TWallData::kNormal)
|
|
continue;
|
|
pData1 = new TVolumeTableItem(*pWall);
|
|
} else {
|
|
if(!pColu->Has3D())
|
|
continue;
|
|
pData1 = new TVolumeTableItem(*pColu);
|
|
}
|
|
TVolumeTableItem *pData=lstVolumes.FindNode(pData1, TVolumeTableItem::CompareForFind);
|
|
if(!pData) { //没有发现相同数据的
|
|
lstVolumes.Append(pData1);
|
|
} else {
|
|
pData->m_nCount++;
|
|
pData->m_nVolume += pData1->m_nVolume;
|
|
delete pData1;
|
|
}
|
|
}
|
|
return RTNORM;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////
|
|
// 统计某个DWG中的体积表
|
|
int StaticVolumeFromDatabase(AcDbDatabase *db, DList<TVolumeTableItem> &lstOpenings,TProjectFloor*pFloor=NULL)
|
|
{
|
|
DList<AcDbObjectId> ssOpenings;
|
|
Acad::ErrorStatus es1;
|
|
if(pFloor==NULL||!pFloor->IsFloorInFrame())
|
|
es1=GetEntityFromDatabase(ssOpenings, *db, _T("ATS_WALL,ATS_COLUMN"), 1, ACDB_MODEL_SPACE);
|
|
else
|
|
{
|
|
XPoint ptMin,ptMax;
|
|
pFloor->GetRange(ptMin,ptMax);
|
|
es1=GetEntityFromDatabase(ssOpenings, *db, _T("ATS_WALL,ATS_COLUMN"), 1, ACDB_MODEL_SPACE,ptMin,ptMax);
|
|
}
|
|
if(es1 != Acad::eOk) {
|
|
return RTERROR;
|
|
}
|
|
StaticVolumeFromDatabase(ssOpenings, lstOpenings);
|
|
return RTNORM;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////
|
|
// 统计体积表, 对当前DWG
|
|
void StaticVolume()
|
|
{
|
|
DList<TVolumeTableItem> lstElements;
|
|
PickSet ss(SS_FREE);
|
|
RBList mask(RTDXF0, _T("ATS_WALL,ATS_COLUMN"), NULL);
|
|
g_ssPickFirst.Free();
|
|
if(SelectEntities(_T("\n请选择墙和柱:"), ss, mask)!=RTNORM)
|
|
return;
|
|
{
|
|
long lCount = ss.Length();
|
|
DList<AcDbObjectId> idSet;
|
|
for(long i=0L; i<lCount; i++) {
|
|
AcDbObjectId* pId = new AcDbObjectId;
|
|
acdbGetObjectId(*pId, ss[i]);
|
|
idSet.Append(pId);
|
|
}
|
|
StaticVolumeFromDatabase(idSet, lstElements);
|
|
lstElements.QuickSort(TVolumeTableItem::CompareForSort);
|
|
}
|
|
|
|
AcDbObjectId idTextStyle=InitTextStyle(TS_WDTABLE);
|
|
if(!idTextStyle)
|
|
return;
|
|
|
|
XPoint ptLoc;
|
|
TDbSheet *pSheet=new TDbSheet;
|
|
int nRowNum=lstElements.Length()+1;
|
|
pSheet->InitSheet(nRowNum, 5, 7.0, 14.0);
|
|
TSheetColumn column;
|
|
double nColWidthArray[5]={14.0, 22.0, 10.0, 30.0, 50.0};
|
|
for(int m=0; m<5; m++) {
|
|
column.SetWidth(nColWidthArray[m]);
|
|
pSheet->SetColumnAt(m, column);
|
|
}
|
|
|
|
|
|
|
|
pSheet->SetTitleText(_T("体积表"));
|
|
TGridStyle gridStyle;
|
|
gridStyle.SetOverrideAll(TRUE);
|
|
gridStyle.SetTextWrap(FALSE);
|
|
gridStyle.SetTextHeight(3.5);
|
|
gridStyle.SetHorMode(AcDb::kTextCenter);
|
|
gridStyle.SetVerMode(AcDb::kTextVertMid);
|
|
gridStyle.SetTextStyleId(idTextStyle);
|
|
pSheet->SetGridStyle(gridStyle);
|
|
|
|
TSheetTitle &title=pSheet->GetTitle();
|
|
title.SetHeight(16.0);
|
|
TGridStyle &gStyle=title.GetGridStyle();
|
|
gStyle.SetFlagBit(OF_TEXTHEIGHT);
|
|
gStyle.SetTextHeight(8.0);
|
|
TDividerStyle &dStyle=title.GetDividerStyle();
|
|
dStyle.SetDividerFlag(TDividerStyle::kNone);
|
|
|
|
{
|
|
const TCHAR *szHeadText[5]={_T("类型"),_T("材料"), _T("数量"), _T("体积"), _T("备注")};
|
|
for(int k=0;k<5;k++) {
|
|
TGridCell *pCell=(*pSheet)(0, k);
|
|
TGridStyle &grStyle=pCell->GetGridStyle();
|
|
grStyle.SetFlagBit(OF_TEXTHEIGHT);
|
|
grStyle.SetTextHeight(4.0);
|
|
pCell->SetText(szHeadText[k]);
|
|
}
|
|
}
|
|
for(int n=1; n<nRowNum; n++) {
|
|
TVolumeTableItem *pData=lstElements[n-1];
|
|
TGridCell *pCell=(*pSheet)(n, 0);
|
|
pCell->SetText(pData->m_sMainKind);
|
|
pCell=(*pSheet)(n, 1);
|
|
pCell->SetText(pData->m_sMaterial);
|
|
pCell=(*pSheet)(n, 2);
|
|
pCell->SetText(XString(_T("%d"), pData->m_nCount));
|
|
pCell=(*pSheet)(n, 3);
|
|
pCell->SetText(XString(_T("%.3f"), pData->m_nVolume));
|
|
}
|
|
if(pSheet->IsValid()) {
|
|
CTemporaryResourceOverride vTemp;
|
|
CGridSheetDlg dlg(pSheet, acedGetAcadFrame());
|
|
if(dlg.DoModal()==IDOK) {
|
|
if(XGetPoint(NULL, _T("\n体积表位置(左上角点)"), ptLoc)==RTNORM) {
|
|
pSheet->SetLocation(Ucs2Wcs(ptLoc));
|
|
AcDbObjectId id=pSheet->AddToCSpace(Adesk::kTrue);
|
|
} else
|
|
delete pSheet;
|
|
} else {
|
|
delete pSheet;
|
|
}
|
|
} else
|
|
delete pSheet;
|
|
|
|
return ;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////
|
|
// Command: 统计项目体积表
|
|
void StaticProjectVolumeTable()
|
|
{
|
|
if(g_project.IsEmpty())
|
|
{
|
|
AfxMessageBox(_T("请打开或新建一个工程项目,并在工程数据库中建立楼层表!"));
|
|
CString sCmd=GetFullCmdName(_T("TProjectBar")).cs();
|
|
acedPostCommand(sCmd+_T("\n"));
|
|
return;
|
|
}
|
|
|
|
TProjectGroupItem* pTable=GetFloorTable();
|
|
if(pTable==NULL)
|
|
return;
|
|
|
|
static int nAns=Q_YES;
|
|
|
|
DList<TVolumeTableItem> lstAllOpenings;
|
|
|
|
int nCurFloorIndex = 0;
|
|
XStringList szDescList;
|
|
CString sCurDwg=curDoc()->fileName();
|
|
int nStdLayerNum = pTable->GetLength();
|
|
for(pTable->MoveToFirst(); !pTable->IsOut(); pTable->MoveToNext()) {
|
|
TProjectFloor* pFloor=(TProjectFloor*)pTable->GetCurData();
|
|
XString sDwgFile=g_project.GetDwgFullName(pFloor->GetName());
|
|
XString sFloor=pFloor->GetLayerNo();
|
|
|
|
if(nAns==Q_YES) {
|
|
XString sFlrDesc(sFloor);
|
|
sFlrDesc << _T("层");
|
|
szDescList.Append(tstrnew(sFlrDesc));
|
|
}
|
|
DList<int> lstIndexes;
|
|
if(!StrToIntList(sFloor, lstIndexes)) {
|
|
adsout << _T("\n楼层的描述有错!");
|
|
return ;
|
|
}
|
|
int nLayerCount=lstIndexes.Length(); //自然层个数
|
|
ASSERT(nLayerCount>0);
|
|
|
|
adsout << _T("\n统计标准层") << (const TCHAR*)pFloor->GetName() << _T("的体积表...");
|
|
DList<TVolumeTableItem> lstOpenings;
|
|
if(_tcsicmp(sCurDwg, sDwgFile)==0) {//Current DWG
|
|
if(StaticVolumeFromDatabase(acdbCurDwg(), lstOpenings,pFloor)!=RTNORM) {
|
|
adsout << _T("\n图中有错, 中断统计!");
|
|
return ;
|
|
}
|
|
} else {
|
|
AcDbDatabase dwgDb(false, true);
|
|
#if ADS < 21
|
|
if(dwgDb.readDwgFile(sDwgFile, _SH_DENYNO, false)!=Acad::eOk)
|
|
#else
|
|
if(dwgDb.readDwgFile(sDwgFile, AcDbDatabase::kForReadAndAllShare, false)!=Acad::eOk)
|
|
#endif
|
|
{
|
|
adsout << _T("\n不能访问") << (const TCHAR*)sDwgFile << _T(", 中断统计!");
|
|
return ;
|
|
}
|
|
if(StaticVolumeFromDatabase(&dwgDb, lstOpenings,pFloor)!=RTNORM) {
|
|
adsout << _T("\n图中有错, 中断统计!");
|
|
return ;
|
|
}
|
|
}
|
|
|
|
// 累计所有楼层
|
|
int nCountOfOpening=lstOpenings.Length();
|
|
for(int idx=0; idx<nCountOfOpening; idx++) {
|
|
TVolumeTableItem *pData = lstOpenings[idx];
|
|
TVolumeTableItem *pData1=lstAllOpenings.FindNode(pData, TVolumeTableItem::CompareForFind);
|
|
if(!pData1) { //未发现相同数据
|
|
TVolumeTableItem *pNewData = new TVolumeTableItem(*pData);
|
|
if(nAns==Q_YES) {
|
|
for (int i = 0 ; i < nStdLayerNum ; i++) {
|
|
pNewData->m_lstVolumes.Append(new double(0.0));
|
|
pNewData->m_lstLayCnt.Append(new int(0));
|
|
}
|
|
*pNewData->m_lstVolumes[nCurFloorIndex] = pData->m_nVolume;
|
|
*pNewData->m_lstLayCnt[nCurFloorIndex] = nLayerCount;
|
|
}
|
|
|
|
pNewData->m_nCount *= nLayerCount;
|
|
pNewData->m_nVolume *= nLayerCount;
|
|
lstAllOpenings.Append(pNewData);
|
|
} else {
|
|
pData1->m_nCount += nLayerCount*pData->m_nCount;
|
|
pData1->m_nVolume += nLayerCount*pData->m_nVolume;
|
|
if(nAns==Q_YES) {
|
|
*pData1->m_lstVolumes[nCurFloorIndex] = pData->m_nVolume;
|
|
*pData1->m_lstLayCnt[nCurFloorIndex] = nLayerCount;
|
|
}
|
|
}
|
|
}
|
|
if(nAns==Q_YES) nCurFloorIndex++;
|
|
}
|
|
lstAllOpenings.QuickSort(TVolumeTableItem::CompareForSort);
|
|
|
|
AcDbObjectId idTextStyle=InitTextStyle(TS_WDTABLE);
|
|
if(!idTextStyle)
|
|
return;
|
|
|
|
TDbSheet *pSheet=new TDbSheet;
|
|
int nRowNum=lstAllOpenings.Length()+2;
|
|
pSheet->InitSheet(nRowNum, 5+szDescList.Length(), 7.0, 14.0);
|
|
|
|
TSheetColumn column;
|
|
double nColWidthArray[5]={14.0, 22.0, 10.0, 15.0, 50.0};
|
|
const TCHAR *szHeadArray[5]={_T("类型"), _T("材料"), _T("总数"), _T("总体积"), _T("备注")};
|
|
for(int m=0; m<3; m++) {
|
|
column.SetWidth(nColWidthArray[m]);
|
|
pSheet->SetColumnAt(m, column);
|
|
pSheet->MergeCells(0,m,1,m);
|
|
TGridCell *pCell=(*pSheet)(0, m);
|
|
pCell->SetText(szHeadArray[m]);
|
|
TGridStyle &grStyle=pCell->GetGridStyle();
|
|
grStyle.SetFlagBit(OF_TEXTHEIGHT);
|
|
grStyle.SetTextHeight(4.0);
|
|
}
|
|
int nStdFloorNum=szDescList.Length();
|
|
if(nStdFloorNum>1)
|
|
pSheet->MergeCells(0,3,0,2+nStdFloorNum); {
|
|
TGridCell *pCell=(*pSheet)(0, 3);
|
|
pCell->SetText(_T("体积"));
|
|
TGridStyle &grStyle=pCell->GetGridStyle();
|
|
grStyle.SetFlagBit(OF_TEXTHEIGHT);
|
|
grStyle.SetTextHeight(4.0);
|
|
}
|
|
for(m=3; m<nStdFloorNum+3; m++) {
|
|
column.SetWidth(nColWidthArray[3]);
|
|
pSheet->SetColumnAt(m, column);
|
|
TGridCell *pCell=(*pSheet)(1, m);
|
|
pCell->SetText(szDescList[m-3]);
|
|
TGridStyle &grStyle=pCell->GetGridStyle();
|
|
grStyle.SetFlagBit(OF_TEXTHEIGHT);
|
|
grStyle.SetTextHeight(4.0);
|
|
}
|
|
for(m=3; m<5; m++) {
|
|
column.SetWidth(nColWidthArray[m]);
|
|
pSheet->SetColumnAt(nStdFloorNum+m, column);
|
|
pSheet->MergeCells(0,m+nStdFloorNum,1,m+nStdFloorNum);
|
|
TGridCell *pCell=(*pSheet)(0, m+nStdFloorNum);
|
|
pCell->SetText(szHeadArray[m]);
|
|
TGridStyle &grStyle=pCell->GetGridStyle();
|
|
grStyle.SetFlagBit(OF_TEXTHEIGHT);
|
|
grStyle.SetTextHeight(4.0);
|
|
}
|
|
|
|
TGridStyle gridStyle;
|
|
gridStyle.SetOverrideAll(TRUE);
|
|
gridStyle.SetTextWrap(FALSE);
|
|
gridStyle.SetHorMode(AcDb::kTextCenter);
|
|
gridStyle.SetVerMode(AcDb::kTextVertMid);
|
|
gridStyle.SetTextHeight(3.5);
|
|
gridStyle.SetTextStyleId(idTextStyle);
|
|
pSheet->SetGridStyle(gridStyle);
|
|
|
|
// 设置标题
|
|
TSheetTitle &title=pSheet->GetTitle();
|
|
title.SetHeight(16.0);
|
|
TGridStyle &gStyle=title.GetGridStyle();
|
|
gStyle.SetFlagBit(OF_TEXTHEIGHT);
|
|
gStyle.SetTextHeight(8.0);
|
|
TDividerStyle &dStyle=title.GetDividerStyle();
|
|
dStyle.SetDividerFlag(TDividerStyle::kNone);
|
|
pSheet->SetTitleText(_T("体积总表"));
|
|
|
|
for(int n=2; n<nRowNum; n++) {
|
|
TVolumeTableItem *pData=lstAllOpenings[n-2];
|
|
TGridCell *pCell=(*pSheet)(n, 0);
|
|
pCell->SetText(pData->m_sMainKind);
|
|
pCell=(*pSheet)(n, 1);
|
|
pCell->SetText(pData->m_sMaterial);
|
|
pCell=(*pSheet)(n, 2);
|
|
pCell->SetText(XString(_T("%d"), pData->m_nCount));
|
|
|
|
int nNum = pData->m_lstVolumes.Length();
|
|
ASSERT(nNum==szDescList.Length());
|
|
for (int i = 0 ; i < nNum ; i++) {
|
|
int nLayCnt = *pData->m_lstLayCnt[i];
|
|
XString pStrDesc(_T("%.3f"), *pData->m_lstVolumes[i]);
|
|
if (nLayCnt > 1) {
|
|
XString pStrTemp(_T("X%d"), nLayCnt);
|
|
pStrDesc << pStrTemp;
|
|
}
|
|
pCell=(*pSheet)(n, i+3);
|
|
pCell->SetText(pStrDesc);
|
|
}
|
|
|
|
pCell=(*pSheet)(n, nNum+3);
|
|
pCell->SetText(XString(_T("%.3f"), pData->m_nVolume));
|
|
}
|
|
if(pSheet->IsValid()) {
|
|
CTemporaryResourceOverride vTemp;
|
|
CGridSheetDlg dlg(pSheet, acedGetAcadFrame());
|
|
if(dlg.DoModal()==IDOK) {
|
|
XPoint ptLoc;
|
|
if(XGetPoint(NULL, _T("\n体积表位置(左上角点)"), ptLoc)==RTNORM) {
|
|
pSheet->SetLocation(Ucs2Wcs(ptLoc));
|
|
AcDbObjectId id=pSheet->AddToCSpace(Adesk::kTrue);
|
|
} else
|
|
delete pSheet;
|
|
} else
|
|
delete pSheet;
|
|
} else
|
|
delete pSheet;
|
|
|
|
}
|