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

455 lines
13 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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();
// }
//}