Files
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

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;
}