455 lines
13 KiB
C++
455 lines
13 KiB
C++
#include "stdafx.h"
|
||
#include "TgAs.h"
|
||
|
||
//EnergyTool.cpp
|
||
// 节能评估有关的程序
|
||
|
||
|
||
///////////////////////////////////////////////////////////////////
|
||
// 搜索外墙轮廓
|
||
// 局限性:适用于无天井、无沉降缝的情况
|
||
BOOL SearchFloorOutline(AcDbDatabase *pFloor, XPoly2D &poly)
|
||
{
|
||
ASSERT(pFloor);
|
||
DList<AcDbObjectId> lstWalls;
|
||
DList<AcDbObjectId> lstColus;
|
||
if (GetEntityFromDatabase(lstWalls, *pFloor, _T("TCH_WALL,TCH_CURTAIN_WALL"), 1, ACDB_MODEL_SPACE)!=Acad::eOk)
|
||
return FALSE;
|
||
|
||
GetEntityFromDatabase(lstColus, *pFloor, _T("TCH_COLUMN"), 0, ACDB_MODEL_SPACE);
|
||
|
||
XSearchSpaceFromWall aSearch;
|
||
try {
|
||
aSearch.InitStart(lstWalls, lstColus);
|
||
} catch (...) {
|
||
adsout << _T("\n发生例外情况!");
|
||
return FALSE;
|
||
}
|
||
|
||
XAecSpaceCell *pExt=aSearch.SearchSpaces();
|
||
if (!pExt)
|
||
return FALSE;
|
||
pExt->InternalPoly2D(poly,2);
|
||
poly.Compress();
|
||
BOOL bRet=(poly.Length()>1);
|
||
return bRet;
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// 取得室外空间轮廓
|
||
// 如果没有找到编号为0的房间,则搜索
|
||
BOOL GetFloorOutlines(AcDbDatabase *pFloor, DList<XPoly2D> &lstPoly)
|
||
{
|
||
lstPoly.Reset();
|
||
ASSERT(pFloor);
|
||
DList<AcDbObjectId> lstSpaces;
|
||
if (GetEntityFromDatabase(lstSpaces, *pFloor, _T("TCH_SPACE"), 0, ACDB_MODEL_SPACE)!=Acad::eOk)
|
||
return FALSE;
|
||
BOOL bFindExtSpace=FALSE;
|
||
for(int i=0; i<lstSpaces.Length(); i++) {
|
||
AcDbObjectId id=*lstSpaces[i];
|
||
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbSpace, pSpace);
|
||
if (pSpace) {
|
||
if (_tcscmp(pSpace->GetCode(), _T("0"))==0 && pSpace->m_outline.Length()) {
|
||
lstPoly.Append(new XPoly2D(pSpace->m_outline));
|
||
bFindExtSpace=TRUE;
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
if (!bFindExtSpace) {
|
||
XPoly2D poly(1);
|
||
bFindExtSpace=SearchFloorOutline(pFloor, poly);
|
||
if (bFindExtSpace)
|
||
lstPoly.Append(new XPoly2D(poly));
|
||
}
|
||
XPoint ptBase=pFloor->insbase();
|
||
ads_matrix mat;
|
||
ptBase.GetMoveMatrix(XPoint(), mat);
|
||
for(i=0; i<lstPoly.Length(); i++)
|
||
lstPoly[i]->TransUCS(mat);
|
||
return bFindExtSpace;
|
||
}
|
||
|
||
|
||
//////////////////////////////////////////////////////////////////////////
|
||
// 创建外墙轮廓
|
||
void MakeExtSpace()
|
||
{
|
||
g_ssPickFirst.Free();
|
||
PickSet ssWalls(SS_FREE), ssColus(SS_FREE);
|
||
RBList wallMask(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL,TCH_COLUMN"), NULL);
|
||
if (SelectEntities(_T("\n请选择构成一完整建筑物的所有维护结构:"), ssWalls, wallMask)!=RTNORM) {
|
||
return;
|
||
}
|
||
ssColus += ssWalls;
|
||
ssColus.BaseFilter(RBList(RTDXF0, _T("TCH_COLUMN"), NULL));
|
||
ssWalls -= ssColus;
|
||
//MakeWallSet(ssWalls);
|
||
|
||
//取得所有的裁剪区域
|
||
DList<AcDbObjectId> lstColu;
|
||
long lColuNum=ssColus.Length();
|
||
for(long idx=0L; idx<lColuNum; idx++) {
|
||
Entity ent=ssColus[idx];
|
||
AcDbObjectId id;
|
||
if (acdbGetObjectId(id, ent)==Acad::eOk) {
|
||
lstColu.Append(new AcDbObjectId(id));
|
||
}
|
||
}
|
||
|
||
XSearchSpaceFromWall aSearch;
|
||
try {
|
||
aSearch.InitStart(ssWalls, lstColu);
|
||
} catch(...) {
|
||
adsout << /*UMSG*/_T("\n发生例外情况!");
|
||
return;
|
||
}
|
||
|
||
XAecSpaceCell * extCell=aSearch.SearchSpaces();
|
||
if (extCell) {
|
||
XPoint ptLoc;
|
||
if (ads_getpoint(NULL, _T("\n标识位置<退出>:"), ptLoc)!=RTNORM)
|
||
return;;
|
||
ptLoc=Ucs2Wcs(ptLoc);
|
||
ptLoc.z = 0.0;
|
||
|
||
XPoly2D polySpace(1);
|
||
extCell->CenterPoly2D(polySpace);
|
||
polySpace.SetElevation(0.0); //投影到z=0的平面上
|
||
TDbSpace *pDbSpace = new TDbSpace();
|
||
pDbSpace->m_sCode=_T("0");
|
||
pDbSpace->m_sName = _T("外墙轮廓");
|
||
pDbSpace->SetHas3D(FALSE);
|
||
pDbSpace->m_ptLocation = ptLoc;
|
||
pDbSpace->SetTextStyleId(InitTextStyle(TS_SPACE));
|
||
pDbSpace->SetType(TDbSpace::kTotalArea); // sg add 081226,房间类型
|
||
|
||
if (pDbSpace->AddToMSpace(Adesk::kFalse).isValid()) {
|
||
pDbSpace->UpdateFrom(*extCell, TRUE);
|
||
pDbSpace->close();
|
||
} else {
|
||
delete pDbSpace;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
// Tool: 计算一层的建筑面积
|
||
// 单位:m2
|
||
double CalBuildingArea(AcDbDatabase *pFloor)
|
||
{
|
||
double nArea=0.0;
|
||
|
||
DList<XPoly2D> lstPoly;
|
||
if (GetFloorOutlines(pFloor, lstPoly)) {
|
||
for(int i=0; i<lstPoly.Length(); i++) {
|
||
XPoly2D &poly=*lstPoly[i];
|
||
nArea += _AS_SQMETER(poly.Area());
|
||
}
|
||
}
|
||
return nArea;
|
||
}
|
||
|
||
// Tool: 计算一层的建筑周长
|
||
// 单位:m
|
||
double CalBuildingPerimeter(AcDbDatabase *pFloor)
|
||
{
|
||
|
||
double nLen=0.0;
|
||
DList<XPoly2D> lstPoly;
|
||
if (GetFloorOutlines(pFloor, lstPoly)) {
|
||
for(int i=0; i<lstPoly.Length(); i++) {
|
||
XPoly2D &poly=*lstPoly[i];
|
||
nLen += _AS_METER(poly.Distance2d());
|
||
}
|
||
}
|
||
return nLen;
|
||
}
|
||
|
||
TARCH_IMPEXP int GetFloorData(const TCHAR *szFolder, XDbfTable &grp, DList<XFloorData> &lstFloors);
|
||
|
||
AcDbRegion *AsRegion(const DList<XPoly2D> &lstPoly)
|
||
{
|
||
AcDbRegion *pRegAll=NULL;
|
||
for(int i=0; i<lstPoly.Length(); i++) {
|
||
const XPoly2D &rPoly=lstPoly[i];
|
||
AcDb::BoolOperType op=rPoly.PathArea()<0? AcDb::kBoolUnite : AcDb::kBoolSubtract;
|
||
AcDbRegion *pReg=rPoly.AsRegion();
|
||
if (pRegAll) {
|
||
if (pRegAll->booleanOper(op, pReg)!=Acad::eOk) {
|
||
delete pRegAll;
|
||
delete pReg;
|
||
return NULL;
|
||
}
|
||
} else {
|
||
pRegAll=pReg;
|
||
}
|
||
}
|
||
return pRegAll;
|
||
}
|
||
|
||
// Tool: 计算某工程的指标
|
||
// sFloorTalbe-楼层表文件
|
||
// nOccupyArea(m2) = 占地面积,即首层建筑面积
|
||
// nBuildingArea(m2) = 建筑面积,不含阳台、凸窗
|
||
// nEnvelopArea(m2) = 外表面积, 侧面积、屋顶面积和挑出的楼板面积
|
||
// nBuildingVolume(m3) = 建筑体积,层高*建筑面积的累加
|
||
// nBuildingHeight(m) = 建筑高度,首层地面算起
|
||
BOOL GetBuildingPara(const TCHAR *sFloorTable,
|
||
double *nOccupyArea,
|
||
double *nBuildingArea,
|
||
double *nEnvelopArea,
|
||
double *nBuildingVolume,
|
||
double *nBuildingHeight)
|
||
{
|
||
XPathParser paser(sFloorTable);
|
||
XString sFolder;
|
||
sFolder << paser.m_sDrive << paser.m_sDir;
|
||
CodeBase cb;
|
||
cb.read_only=1;
|
||
XDbfTable *pTable=cb.Open(sFloorTable);
|
||
if (!pTable)
|
||
return FALSE;
|
||
|
||
DList<XFloorData> lstFloors;
|
||
if (GetFloorData(sFolder, *pTable, lstFloors)!=RTNORM || CheckFloorData(lstFloors)!=RTNORM)
|
||
return FALSE;
|
||
pTable->Close();
|
||
|
||
*nOccupyArea=0.0;
|
||
*nBuildingArea=0.0;
|
||
*nEnvelopArea=0.0;
|
||
*nBuildingVolume=0.0;
|
||
*nBuildingHeight=0.0;
|
||
DList<XPoly2D> lstPolyLast;
|
||
XString sLastDwg;
|
||
for(int i=0; i<lstFloors.Length(); i++) {
|
||
XFloorData *pData=lstFloors[i];
|
||
if (pData->m_nIndex<1)
|
||
continue;
|
||
|
||
if (_tcscmp(pData->m_sDwgFile, sLastDwg)==0) {
|
||
for(int k=0; k<lstPolyLast.Length(); k++) {
|
||
XPoly2D &poly2d=*lstPolyLast[k];
|
||
double nPerimeter=_AS_METER(poly2d.Distance2d());
|
||
double nArea=_AS_SQMETER(poly2d.Area());
|
||
if (pData->m_nIndex==1) {
|
||
*nOccupyArea=nArea;
|
||
}
|
||
*nBuildingArea += nArea;
|
||
*nEnvelopArea += nPerimeter*_AS_METER(pData->m_nHeight);
|
||
*nBuildingVolume += nArea*_AS_METER(pData->m_nHeight);
|
||
}
|
||
*nBuildingHeight += _AS_METER(pData->m_nHeight);
|
||
} else {
|
||
AcDbDatabase db(false, true);
|
||
#if ADS < 21
|
||
if (db.readDwgFile(pData->m_sDwgFile, _SH_DENYNO, false)!=Acad::eOk)
|
||
#else
|
||
if (db.readDwgFile(pData->m_sDwgFile, AcDbDatabase::kForReadAndAllShare, false)!=Acad::eOk)
|
||
#endif
|
||
return FALSE;
|
||
|
||
DList<XPoly2D> lstPolys;
|
||
if (GetFloorOutlines(&db, lstPolys)) {
|
||
for(int k=0; k<lstPolys.Length(); k++) {
|
||
XPoly2D &poly2d=*lstPolys[k];
|
||
double nPerimeter=_AS_METER(poly2d.Distance2d());
|
||
double nArea=_AS_SQMETER(poly2d.Area());
|
||
if (pData->m_nIndex==1) {
|
||
*nOccupyArea=nArea;
|
||
}
|
||
*nBuildingArea += nArea;
|
||
*nEnvelopArea += nPerimeter*_AS_METER(pData->m_nHeight); //加侧面积
|
||
*nBuildingVolume += nArea*_AS_METER(pData->m_nHeight);
|
||
}
|
||
*nBuildingHeight += _AS_METER(pData->m_nHeight);
|
||
/*
|
||
DList<XPoly2D> lstRoofs, lstGrounds;
|
||
Subtract(lstPolyLast, lstPolys, lstRoofs); //求得上层的屋顶
|
||
Subtract(lstPolys, lstPolyLast, lstGrounds); //求得本层暴露在室外的楼板
|
||
for(int n=0; n<lstRoofs.Length(); n++) {
|
||
*nEnvelopArea += _AS_SQMETER(lstRoofs[n]->Area());
|
||
}
|
||
for(int m=0; m<lstGrounds.Length(); m++) {
|
||
*nEnvelopArea += _AS_SQMETER(lstGrounds[m]->Area());
|
||
}*/
|
||
AcDbRegion *pRegLast=AsRegion(lstPolyLast);
|
||
if (pRegLast) {
|
||
double nRoofArea=0.0, nGroundArea=0.0; //上层屋顶,本层挑出地板
|
||
AcDbRegion *pRegCur=AsRegion(lstPolys);
|
||
if (!pRegCur) {
|
||
pRegLast->getArea(nRoofArea);
|
||
*nEnvelopArea += nRoofArea;
|
||
delete pRegLast;
|
||
return FALSE;
|
||
}
|
||
double nCurRoofArea=0.0;
|
||
pRegCur->getArea(nCurRoofArea);
|
||
|
||
AcDbRegion *pRegRoof=(AcDbRegion *)pRegLast->clone();
|
||
AcDbRegion *pRegGround=(AcDbRegion *)pRegCur->clone();
|
||
pRegRoof->booleanOper(AcDb::kBoolSubtract, pRegCur);
|
||
pRegGround->booleanOper(AcDb::kBoolSubtract, pRegLast);
|
||
pRegRoof->getArea(nRoofArea);
|
||
pRegGround->getArea(nGroundArea);
|
||
*nEnvelopArea += _AS_SQMETER(nRoofArea); //上表面超外的面积
|
||
*nEnvelopArea += _AS_SQMETER(nGroundArea); //下表面超外的面积
|
||
if (pData==lstFloors.Tail()) { //本层屋顶
|
||
*nEnvelopArea += _AS_SQMETER(nCurRoofArea);
|
||
}
|
||
delete pRegLast;
|
||
delete pRegCur;
|
||
delete pRegRoof;
|
||
delete pRegGround;
|
||
}
|
||
|
||
lstPolyLast.Reset();
|
||
for(k=0; k<lstPolys.Length(); k++) {
|
||
XPoly2D &poly2d=*lstPolys[k];
|
||
lstPolyLast.Append(new XPoly2D(poly2d));
|
||
}
|
||
} else {
|
||
for(int k=0; k<lstPolyLast.Length(); k++) {
|
||
XPoly2D &poly2d=*lstPolyLast[k];
|
||
*nEnvelopArea += _AS_SQMETER(poly2d.Area());
|
||
}
|
||
}
|
||
sLastDwg=pData->m_sDwgFile;
|
||
}
|
||
//adsout << _T("\nEnvelop=") << (*nEnvelopArea);
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
// 报告建筑工程量指标
|
||
void RepBuildingPara()
|
||
{
|
||
XString sFileName;
|
||
sFileName << _T("building.dbf");
|
||
if (GetFileDia(sFileName, 0, _T("dbf"), _T("FileName"))!=RTNORM)
|
||
return;
|
||
|
||
double nOccupyArea=0,
|
||
nBuildingArea=0,
|
||
nEnvelopArea=0,
|
||
nBuildingVolume=0,
|
||
nBuildingHeight=0;
|
||
if (GetBuildingPara(sFileName, &nOccupyArea, &nBuildingArea, &nEnvelopArea, &nBuildingVolume, &nBuildingHeight)) {
|
||
adsout << _T("\n占地面积 = ") << nOccupyArea
|
||
<< _T("\n建筑面积 = ") << nBuildingArea
|
||
<< _T("\n外表面积 = ") << nEnvelopArea
|
||
<< _T("\n建筑体积 = ") << nBuildingVolume
|
||
<< _T("\n建筑高度 = ") << nBuildingHeight
|
||
<< _T("\n体形系数 = ") << nEnvelopArea/nBuildingVolume;
|
||
} else {
|
||
adsout << _T("\n无法统计参数!");
|
||
}
|
||
}
|
||
|
||
|
||
// 计算露点温度(C)
|
||
// t--干球温度(C)
|
||
// p--大气压(Pa)
|
||
// rh--相对湿度(0--1.0)
|
||
double CalDewpoint(double t, double p, double rh)
|
||
{
|
||
double x[] = { -10.79574, 5.02808, -1.50475e-4, 18.2969, 0.42875e-3,
|
||
-4.76955 };
|
||
double y[4], tk, z, z1, z2, ps, pv, temp;
|
||
double td;
|
||
|
||
tk = t+273.16;
|
||
z = 273.16/tk;
|
||
y[0] = x[0]*(z-1.0);
|
||
y[1] = x[1]*log10(z);
|
||
z1 = x[3]*(1.0 - 1.0/z);
|
||
y[2] = x[2]*(pow(10.0,z1)-1.0);
|
||
z2 = x[5]*(z-1.0);
|
||
y[3] = x[4]*(pow(10.0,z2)-1.0)-2.2195768;
|
||
ps = p * pow(10.0, y[0]+y[1]+y[2]+y[3]);
|
||
pv = rh*ps;
|
||
temp = 2.015 + log(pv/1000.0);
|
||
if ( temp > 1.522)
|
||
td = -18.807 + 11.005*temp + 0.88887*temp*temp;
|
||
else
|
||
td = -19.237 + 11.533*temp + 0.72733*temp*temp;
|
||
|
||
return td;
|
||
}
|
||
|
||
// 计算内表面温度
|
||
// nAlfIn -- 内表明对流换热系数, 通常8.7W/m2.K
|
||
// nTempIn -- 室内温度(C)
|
||
// nTempOut -- 室外温度(C)
|
||
// uValue -- 平均传热系数
|
||
// NOTICE:
|
||
// Q = alf_in*(Tsuf_in-T_in) = U_val*(T_out-T_in)
|
||
// THEN:
|
||
// Tsuf_in = Q/alf_in + T_in
|
||
double CalSurfTemp(double nAlfIn, double nTempIn, double nTempOut, double uValue)
|
||
{
|
||
double q =uValue*(nTempOut - nTempIn);
|
||
double nTempSurf = nTempIn + q/nAlfIn;
|
||
return nTempSurf;
|
||
}
|
||
|
||
//Tool: 结露检查:民用建筑节能设计标准(采暖居住建筑部分)JGJ26-95的4.2.7规定了不结露的要求
|
||
// 判断内表面温度和露点温度的关系
|
||
void CondensionCheck()
|
||
{
|
||
double nPressure=99860.0; //大气压Pa,由气象数据库查找获得
|
||
double nTempOut=-9.0; //室外设计温度C
|
||
double nTempIn = 18.0; //室内设计温度C
|
||
double nHumidityIn=0.5; //室内相对湿度
|
||
|
||
double uValue=2.3; //搜索获得, W/m2.K
|
||
double nSurfInTemp=CalSurfTemp(8.7, nTempIn, nTempOut, uValue);
|
||
double nTempDewpoint=CalDewpoint(nTempIn, nPressure, nHumidityIn);
|
||
adsout << _T("\n露点温度=") << nTempDewpoint << _T("; 内表面温度=") << nSurfInTemp
|
||
<< _T(";") << ((nSurfInTemp>nTempDewpoint)? _T(" 结露!") : _T(" 不结露!"));
|
||
}
|
||
|
||
|
||
//// 报告墙的坐标
|
||
//void RepWallCoord()
|
||
//{
|
||
// DList<XCurveSegment> lstAxis;
|
||
// PickSet ssAxis(SS_FREE);
|
||
// if (ssAxis.Get(_T("X"), NULL, NULL, RBList(RTDXF0, _T("LINE,ARC"), 8, LAY_AXIS, NULL))!=RTNORM)
|
||
// return;
|
||
// long num=ssAxis.Length();
|
||
// for(long idx=0L; idx<num; idx++) {
|
||
// Entity ent=ssAxis[idx];
|
||
// XCurveSegment *pSeg=new XCurveSegment(ent);
|
||
// if (!(*pSeg))
|
||
// delete pSeg;
|
||
// else
|
||
// lstAxis.Append(pSeg);
|
||
// }
|
||
//
|
||
//
|
||
//
|
||
// DList<AcDbObjectId> lstLab;
|
||
// if (GetEntityFromDatabase(lstLab, *acdbCurDwg(), _T("TCH_AXIS_LABEL"), 0, ACDB_MODEL_SPACE)!=Acad::eOk)
|
||
// return;
|
||
// Entity entWall;
|
||
// if (SelectEntity(_T("\n选择墙体<退出>:"), entWall, RBList(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), NULL))==RTNORM) {
|
||
// OPENOBJ_BEGIN(entWall, AcDb::kForRead, TDbWall, pWall);
|
||
// if (pWall) {
|
||
// XString s1, s2, s3, s4;
|
||
// if (pWall->HitOnAxis(lstLab, lstAxis, s1, s2, s3, s4)) {
|
||
// adsout << _T("\n(") << s1 << _T(",") << s2 << _T(")~(") << s3 << _T(",") << s4 << _T(")");
|
||
// } else {
|
||
// adsout << _T("\nnone!");
|
||
// }
|
||
// }
|
||
// OPENOBJ_END();
|
||
// }
|
||
//}
|