Files
envi-code/SourceCode/Code2026/Dimension/SprinklerCalc.cpp
T

1617 lines
54 KiB
C++
Raw Normal View History

2026-10-04 00:04:20 +08:00
#include "stdafx.h"
2026-09-28 15:28:50 +08:00
#include "AcDbObjectPtr.h"
#include "PickEntSet.h"
#include "RBGroups.h"
#include "DbPipeLabel.h"
#include "DbEquipment.h"
#include "DbPipe.h"
#include "SprinklerCalcDlg.h"
#include "TGAs.h"
#include "SlideStatic.h"
#include "tipwnd.h"
#include "DbPipeValve.h"
extern BOOL DoDimSerialNumber(AcDbObjectId id, int idx);
extern void DoDimPipeSerialNumber(SSearchPipeList *pListAll);
extern AcDbObjectId InitLayer(const TCHAR *szLayer, AcDbDatabase *pDb = NULL);
extern BOOL GetValveNameById(AcDbObjectId id, CString &csBlkName, CString &csDesName);
double DoSprinklerCalc2(SSearchPipeList *pListAll, double nPress, double nK, int iStart);
extern TCHAR *LAY_PIPE_SPRINKLE;
extern TCHAR *LAY_PIPE_SPRINKLE2;
extern TCHAR *LAY_PIPE_SPRINKLE3;
extern TCHAR *LAY_VPIPE_SPRINKLE;
extern TCHAR *LAY_VPIPE_SPRINKLE2;
extern TCHAR *LAY_VPIPE_SPRINKLE3;
extern TCHAR *LAY_EQUIP_SPRINKLE;
extern TCHAR *LAY_CALC_TEXT;
CString GetPlanValve(const TCHAR *szSysName)
{
CString csRet = _T("");
CodeBase db;
db.read_only = 1;
CString csKind, csItem, csDrawing;
CString csSysTKName = g_csDwbPath + _T("VALVE.tk");
DbfTable *pTable = db.Open(csSysTKName);
if (!pTable) return csRet;
pTable->MoveFirst();
while (!pTable->IsEOF()) {
GET_FIELD(pTable, _T("kind"), csKind);
GET_FIELD(pTable, _T("item"), csItem);
GET_FIELD(pTable, _T("Drawing"), csDrawing);
2026-10-04 00:04:20 +08:00
if (((csKind == _T("平面阀门")) || (csKind == _T("平面附件"))) && (csDrawing != _T(""))) {
2026-09-28 15:28:50 +08:00
CString csSysBlk = (const TCHAR *)csItem;
csSysBlk = csSysBlk.Right(8);
CString csDwb = g_csDwbPath + _T("valve");
if (_tcsicmp(csSysBlk, szSysName) == 0)
{
TCHAR szBlkName[256];
if (GlobalFunc::LoadDwbBlock(csDwb, (const TCHAR *)csDrawing, szBlkName) != RTNORM)
return csRet;
csRet = (const TCHAR *)szBlkName;
break;
}
}
pTable->MoveNext();
}
2026-10-04 00:04:20 +08:00
// if(xsTmpSys == _T("")) // sys17下不这么写, 返回乱码
2026-09-28 15:28:50 +08:00
// return _T("");
return csRet;
}
BOOL GetValveNameById(AcDbObjectId id, CString &csBlkName, CString &csDesName)
{
csBlkName = _T("");
OPENOBJ_BEGIN(id, AcDb::kForRead, CDbPipeValve, pEquip);
if (pEquip) {
const TCHAR *szBlkName;
AcDbObjectId eqId = pEquip->GetBlock2d();
OPENOBJ_BEGIN(eqId, AcDb::kForRead, AcDbBlockTableRecord, pRecord);
if (pRecord)
pRecord->getName(szBlkName);
OPENOBJ_END();
csBlkName = szBlkName;
CString csTKName, csRocord;
GlobalFunc::SplitBlkStr(csBlkName, csTKName, csRocord);
csTKName = g_csDwbPath + csTKName + _T(".tk");
csDesName = GlobalFunc::GetBlkDesName((const TCHAR *)csRocord, (const TCHAR *)csTKName);
int idx = csDesName.Find(_T("-"));
if (idx > -1) {
csDesName = csDesName.Left(idx);
}
idx = csDesName.Find(_T("("));
if (idx > -1) {
csDesName = csDesName.Left(idx);
}
CString csSysBlk = pEquip->GetSysBlock();
if (csSysBlk == _T("")) {
2026-10-04 00:04:20 +08:00
CString csBlk = GetPlanValve(csRocord);//如果是系统阀门,就找到对应的平面阀门,统计结果算平面的
2026-09-28 15:28:50 +08:00
if (csBlk != _T(""))
csBlkName = csBlk;
}
if (csBlkName != _T(""))
return TRUE;
}
OPENOBJ_END();
return FALSE;
}
double GetPipeCalcDiameter(AcDbObjectId id)
{
double nRet(0);
int iMat(-1), iPipeDn(0);
OPENOBJ_BEGIN(id, AcDb::kForRead, CDbPipe, pPipe);
if (pPipe) {
iMat = pPipe->GetMaterial();
iPipeDn = (int)pPipe->GetDnDiameter();
}
OPENOBJ_END();
if (iMat < 0)
return nRet;
CodeBase db;
XString fullFile;
if (!GlobalFunc::FindFile(_T("pipe.dbf"), fullFile)) {
2026-10-04 00:04:20 +08:00
AfxMessageBox(_T("对不起,没有发现pipe.dbf文件!"));
2026-09-28 15:28:50 +08:00
return nRet;
}
CString csMat = GlobalFunc::GetPipeMaterialByIdx(iMat);
DbfTable *pTable = db.Open(fullFile);
if (!pTable)
return nRet;
CString csMaterial;
int iDn(0);
double nDj(0);
for (pTable->MoveFirst(); !pTable->IsEOF(); pTable->MoveNext()) {
GET_FIELD(pTable, _T("GC"), csMaterial);
GET_FIELD(pTable, _T("DN"), iDn);
GET_FIELD(pTable, _T("DJ"), nDj);
if (_tcsicmp((const TCHAR *)csMaterial, (const TCHAR *)csMat) == 0
&& iPipeDn == iDn) {
nRet = nDj;
return nRet;
}
}
return (double)iPipeDn;
}
2026-10-04 00:04:20 +08:00
double GetDangLenByTaiIn(int iDn1, int iDn2) //接头当量长度
2026-09-28 15:28:50 +08:00
{
if((iDn1 == 25 && iDn2 == 32) || (iDn2 == 25 && iDn1 == 32))
return 0.2;
else if((iDn1 == 40 && iDn2 == 32) || (iDn2 == 40 && iDn1 == 32))
return 0.3;
else if((iDn1 == 40 && iDn2 == 50) || (iDn2 == 40 && iDn1 == 50))
return 0.3;
else if((iDn1 == 65 && iDn2 == 50) || (iDn2 == 65 && iDn1 == 50))
return 0.5;
else if((iDn1 == 65 && iDn2 == 80) || (iDn2 == 65 && iDn1 == 80))
return 0.6;
else if((iDn1 == 100 && iDn2 == 80) || (iDn2 == 100 && iDn1 == 80))
return 0.8;
else if((iDn1 == 100 && iDn2 == 125) || (iDn2 == 100 && iDn1 == 125))
return 1.1;
else if((iDn1 == 150 && iDn2 == 125) || (iDn2 == 150 && iDn1 == 125))
return 1.3;
else if((iDn1 == 150 && iDn2 == 200) || (iDn2 == 150 && iDn1 == 200))
return 1.6;
else if((iDn1 == 32 && iDn2 == 50) || (iDn2 == 32 && iDn1 == 50))
return 0.3;
else if((iDn1 == 32 && iDn2 >= 65) || (iDn1 >= 65 && iDn2 == 32))
return 0.5;
else if((iDn1 == 40 && iDn2 == 65) || (iDn1 == 65 && iDn2 == 40))
return 0.5;
else if((iDn1 == 40 && iDn2 >= 80) || (iDn1 >= 80 && iDn2 == 40))
return 0.6;
else if((iDn1 == 50 && iDn2 == 80) || (iDn1 == 80 && iDn2 == 50))
return 0.6;
else if((iDn1 == 50 && iDn2 >= 100) || (iDn1 >= 100 && iDn2 == 50))
return 0.8;
else if((iDn1 == 65 && iDn2 == 100) || (iDn1 == 100 && iDn2 == 65))
return 0.8;
else if((iDn1 == 65 && iDn2 >= 125) || (iDn1 >= 125 && iDn2 == 65))
return 1.1;
else if((iDn1 == 80 && iDn2 == 125) || (iDn2 == 80 && iDn1 == 125))
return 1.1;
else if((iDn1 == 80 && iDn2 >= 150) || (iDn2 == 80 && iDn1 >= 150))
return 1.3;
else if((iDn1 == 100 && iDn2 == 150) || (iDn2 == 150 && iDn1 == 100))
return 1.3;
else if((iDn1 == 100 && iDn2 >= 200) || (iDn1 >= 200 && iDn2 == 100))
return 1.6;
else if((iDn1 == 125 && iDn2 == 200) || (iDn1 == 200 && iDn2 == 125))
return 1.6;
else
return 0;
}
2026-10-04 00:04:20 +08:00
//自动喷水灭火系统设计规范 附录C 当量长度表
double GetDangLenByCorner(int iDn) //3通4通当量长度
2026-09-28 15:28:50 +08:00
{
if(iDn == 25)
return 1.5;
else if(iDn == 32)
return 1.8;
else if(iDn == 40)
return 2.4;
else if(iDn == 50)
return 3.1;
else if(iDn == 65)
return 3.7;
else if(iDn == 80)
return 4.6;
else if(iDn == 100)
return 6.1;
else if(iDn == 125)
return 7.6;
else if(iDn == 150)
return 9.2;
else
return 0;
}
2026-10-04 00:04:20 +08:00
//建筑给水排水设计规范 P106 附录B 当量长度表
double GetDangLenByElbowCorner(int iDn) //3通 转角流
2026-09-28 15:28:50 +08:00
{
if(iDn == 25)
return 1.5;
else if(iDn == 32)
return 1.8;
else if(iDn == 40)
return 2.1;
else if(iDn == 50)
return 3.0;
else if(iDn == 65)
return 3.6;
else if(iDn == 80)
return 4.6;
else if(iDn == 100)
return 6.4;
else if(iDn == 125)
return 7.6;
else if(iDn == 150)
return 9.1;
else if(iDn == 175)
return 9.1;
else
return 0;
}
2026-10-04 00:04:20 +08:00
//建筑给水排水设计规范 P106 附录B 当量长度表
double GetDangLenByLineCorner(int iDn) //3通 直向流
2026-09-28 15:28:50 +08:00
{
if(iDn == 25)
return 0.3;
else if(iDn == 32)
return 0.4;
else if(iDn == 40)
return 0.5;
else if(iDn == 50)
return 0.6;
else if(iDn == 65)
return 0.8;
else if(iDn == 80)
return 0.9;
else if(iDn == 100)
return 1.2;
else if(iDn == 125)
return 1.5;
else if(iDn == 150)
return 1.8;
else if(iDn == 175)
return 1.8;
else
return 0;
}
2026-10-04 00:04:20 +08:00
//自动喷水灭火系统设计规范 附录C 当量长度表
double GetDangLenByElbow90(int iDn1, int iDn2) //90度弯头当量长度
2026-09-28 15:28:50 +08:00
{
if(iDn1 == 25 || iDn2 == 25)
return 0.6;
else if(iDn1 == 32 || iDn2 == 32)
return 0.9;
else if(iDn1 == 40 || iDn2 == 40)
return 1.2;
else if(iDn1 == 50 || iDn2 == 50)
return 1.5;
else if(iDn1 == 65 || iDn2 == 65)
return 1.8;
else if(iDn1 == 80 || iDn2 == 80)
return 2.1;
else if(iDn1 == 100 || iDn2 == 100)
return 3.1;
else if(iDn1 == 125 || iDn2 == 125)
return 3.7;
else if(iDn1 == 150 || iDn2 == 150)
return 4.3;
else
return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////
void ChangeEqColor(PickSet &ss, int iCol)
{
long len = ss.Length();
for(long i=0;i<len;i++){
Entity entBlk = ss[i];
AcDbBlockTableRecord *pRecord = NULL;
AcDbObjectId recordId = NULL;
OPENOBJ_BEGIN(entBlk, AcDb::kForRead, CDbEquipment, pEquip);
if(!pEquip)
continue;
recordId = pEquip->GetBlock2d();
OPENOBJ_END();
OPENOBJ_BEGIN(recordId, AcDb::kForRead, AcDbBlockTableRecord, pRecord);
if(pRecord){
AcDbBlockTableRecordIterator *pIterator = NULL;
pRecord->newIterator(pIterator);
if(!pIterator)
return;
for(pIterator->start(); !pIterator->done(); pIterator->step()){
AcDbEntity *pEnt = NULL;
pIterator->getEntity(pEnt, AcDb::kForWrite);
if(pEnt){
pEnt->setLayer(_T("0"));
pEnt->setColorIndex(iCol);
pEnt->close();
}
}
delete pIterator;
}
OPENOBJ_END();
entBlk.Update();
}
}
extern void GrdrawRect(XRectAngle &rect);
//{
// ads_grdraw(rect.GetLowLeft(), rect.GetUpLeft(), 7, 0);
// ads_grdraw(rect.GetLowLeft(), rect.GetLowRight(), 7, 0);
// ads_grdraw(rect.GetUpRight(), rect.GetLowRight(), 7, 0);
// ads_grdraw(rect.GetUpLeft(), rect.GetUpRight(), 7, 0);
//}
2026-10-04 00:04:20 +08:00
//得到下一个标注节点 根据节点编号是否为空
//3个条件
2026-09-28 15:28:50 +08:00
SSearchPipeList *GetNextDimNode(SSearchPipeList *pListAll, SSearchPipeList *pDisadvantage)
{
AcDbObjectId id = NULL;
id = pListAll->m_ID;
double nCurPipeLength(0);
nCurPipeLength = pListAll->m_nLength;
if(pListAll->m_bNeedCale){
if(pListAll->m_csName == _T("")){
int idx = GlobalFunc::GetFirstAncestorSerial(pListAll);
if(pDisadvantage){
int idx2 = GlobalFunc::GetFirstAncestorSerial(pDisadvantage);
2026-10-04 00:04:20 +08:00
if(idx < idx2){ //条件1: 当前节点的祖先编号小于临时节点的祖先编号
2026-09-28 15:28:50 +08:00
pDisadvantage = pListAll;
}
2026-10-04 00:04:20 +08:00
else if(idx == 0){ //条件2:
2026-09-28 15:28:50 +08:00
if(pDisadvantage && nCurPipeLength > pDisadvantage->m_nLength)
pDisadvantage = pListAll;
}
2026-10-04 00:04:20 +08:00
else if(idx == idx2){//条件3: 当前节点的祖先编号等于临时节点的祖先编号, 但离起始节点最远
2026-09-28 15:28:50 +08:00
int iParentIdx1 = GlobalFunc::GetAncestorSerial(pListAll);
int iParentIdx2 = GlobalFunc::GetAncestorSerial(pDisadvantage);
if(iParentIdx1 == iParentIdx2){
if(pDisadvantage && nCurPipeLength > pDisadvantage->m_nLength)
pDisadvantage = pListAll;
}
else if(iParentIdx1 < iParentIdx2 || iParentIdx2 == idx2){
pDisadvantage = pListAll;
}
}
}
else
2026-10-04 00:04:20 +08:00
pDisadvantage = pListAll; //条件3: 临时节点为空
2026-09-28 15:28:50 +08:00
}
}
int len = pListAll->m_lstNode.Length();
for(long i=0;i<len;i++){
SSearchPipeList *pList = pListAll->m_lstNode[i];
pDisadvantage = GetNextDimNode(pList, pDisadvantage);
}
return pDisadvantage;
}
2026-10-04 00:04:20 +08:00
//得到下一个导出WORD节点 根据节点计算顺序排序
2026-09-28 15:28:50 +08:00
SSearchPipeList *GetNextExportNode(SSearchPipeList *pListAll, SSearchPipeList *pDisadvantage)
{
int idx = pListAll->m_iNum;
if(idx > 0){
if(!pDisadvantage || (pDisadvantage && idx < pDisadvantage->m_iNum))
pDisadvantage = pListAll;
}
int len = pListAll->m_lstNode.Length();
for(long i=0;i<len;i++){
SSearchPipeList *pList = pListAll->m_lstNode[i];
pDisadvantage = GetNextExportNode(pList, pDisadvantage);
}
return pDisadvantage;
}
2026-10-04 00:04:20 +08:00
//得到下一个计算支路的起点节点 根据起点压力是否为0
2026-09-28 15:28:50 +08:00
SSearchPipeList *GetNextCalcNode(SSearchPipeList *pListAll, SSearchPipeList *pDisadvantage)
{
AcDbObjectId id = NULL;
id = pListAll->m_ID;
double nCurPipeLength(0);
nCurPipeLength = pListAll->m_nLength;
if(pListAll->m_bNeedCale){
if(pListAll->m_nStartPress == 0){
int idx = GlobalFunc::GetAncestorSerial(pListAll);
if(pDisadvantage){
int idx2 = GlobalFunc::GetAncestorSerial(pDisadvantage);
2026-10-04 00:04:20 +08:00
if(idx < idx2){ //条件1: 当前节点的祖先编号小于临时节点的祖先编号
2026-09-28 15:28:50 +08:00
pDisadvantage = pListAll;
}
2026-10-04 00:04:20 +08:00
else if(idx == 0 || idx == idx2){//条件2: 当前节点的祖先编号等于临时节点的祖先编号, 但离起始节点最远
2026-09-28 15:28:50 +08:00
if(pDisadvantage && nCurPipeLength > pDisadvantage->m_nLength)
pDisadvantage = pListAll;
}
else if(pDisadvantage->m_nLength < pListAll->m_nLength)
{
2026-10-04 00:04:20 +08:00
//虽然节点编号大于pDisadvantage编号,但pDisadvantage是当前节点的父节点
2026-09-28 15:28:50 +08:00
BOOL bFlag = FALSE;
SSearchPipeList *pListTmp = pListAll;
while(1)
{
if(pListTmp->m_pPrevious != NULL)
{
pListTmp = pListTmp->m_pPrevious;
if(pListTmp == pDisadvantage)
{
bFlag = TRUE;
break;
}
}
else
break;
}
if(bFlag)
pDisadvantage = pListAll;
}
}
else
2026-10-04 00:04:20 +08:00
pDisadvantage = pListAll; //条件3: 临时节点为空
2026-09-28 15:28:50 +08:00
}
}
int len = pListAll->m_lstNode.Length();
for(long i=0;i<len;i++){
SSearchPipeList *pList = pListAll->m_lstNode[i];
pDisadvantage = GetNextCalcNode(pList, pDisadvantage);
}
return pDisadvantage;
}
2026-10-04 00:04:20 +08:00
//得到最不利节点
2026-09-28 15:28:50 +08:00
extern SSearchPipeList *GetDisadvantageNode(SSearchPipeList *pListAll, SSearchPipeList *pDisadvantage);
//{
// AcDbObjectId id = NULL;
// id = pListAll->m_ID;
// double nCurPipeLength(0);
// nCurPipeLength = pListAll->m_nLength;
// if(GlobalFunc::IsSprinkler(id)){
// if(!pDisadvantage || (pDisadvantage && nCurPipeLength > pDisadvantage->m_nLength))
// pDisadvantage = pListAll;
// }
// int len = pListAll->m_lstNode.Length();
// for(long i=0;i<len;i++){
// SSearchPipeList *pList = pListAll->m_lstNode[i];
// pDisadvantage = GetDisadvantageNode(pList, pDisadvantage);
// }
// return pDisadvantage;
//}
2026-10-04 00:04:20 +08:00
//本节点往前所有节点进行标注
2026-09-28 15:28:50 +08:00
int DoSerialNumber(SSearchPipeList *pListLast, int idx, BOOL IsMainNode)
{
AcDbObjectId id = NULL;
id = pListLast->m_ID;
if(pListLast->m_iType == 2 || pListLast->m_iType == 1 || pListLast->m_iType == 3){
if(pListLast->m_csName != _T(""))
return idx;
pListLast->m_csName.Format(_T("%d"), idx);
if(IsMainNode)
2026-10-04 00:04:20 +08:00
pListLast->m_nDang = 255; //GetFirstAncestorSerial 这个函数会用到
2026-09-28 15:28:50 +08:00
if(DoDimSerialNumber(id, idx))
idx++;
else
return idx;
}
if(pListLast->m_pPrevious)
idx = DoSerialNumber(pListLast->m_pPrevious, idx, IsMainNode);
return idx;
}
2026-10-04 00:04:20 +08:00
//本支路往前是否有交叉计算节点
2026-09-28 15:28:50 +08:00
BOOL HasReCalcNode2(SSearchPipeList *pListLast, double &nStartPress, SSearchPipeList *pListCalc)
{
BOOL bFlag = FALSE;
AcDbObjectId id = NULL;
id = pListLast->m_ID;
if(pListLast->m_iType == 0){
OPENOBJ_BEGIN(id, AcDb::kForRead, CDbPipe, pPipe);
if(pPipe){
if(pListLast->m_lstNode.Length() == 1){
if(pListLast->m_pPrevious){
2026-10-04 00:04:20 +08:00
SSearchPipeList *pList2 = pListLast->m_pPrevious; //得到前节点
int num = pList2->m_lstNode.Length(); //前节点有几个分支
if(fabs(pList2->m_nStartPress) > 0.01 && num > 1){ // 1:计算过 2:2个以上分支
2026-09-28 15:28:50 +08:00
int iNum(0);
for(int i=0;i<pList2->m_lstNode.Length();i++){
SSearchPipeList *pListTmp = pList2->m_lstNode[i];
2026-10-04 00:04:20 +08:00
if(pListTmp->m_csName != _T("")) // 2个以上需要计算的节点
2026-09-28 15:28:50 +08:00
iNum++;
}
if(iNum > 1){
nStartPress = pList2->m_nStartPress;
pListCalc = pList2;
bFlag = TRUE;
return TRUE;
}
}
}
}
}
OPENOBJ_END();
}
if(pListLast->m_pPrevious){
bFlag = HasReCalcNode2(pListLast->m_pPrevious, nStartPress, pListCalc);
if(bFlag)
return TRUE;
}
return bFlag;
}
2026-10-04 00:04:20 +08:00
//本支路往前是否有交叉计算节点
2026-09-28 15:28:50 +08:00
SSearchPipeList * HasReCalcNode(SSearchPipeList *pListLast, double &nStartPress, SSearchPipeList *pListCalc)
{
AcDbObjectId id = NULL;
id = pListLast->m_ID;
if(pListLast->m_iType == 0){
OPENOBJ_BEGIN(id, AcDb::kForRead, CDbPipe, pPipe);
if(pPipe){
if(pListLast->m_lstNode.Length() == 1){
if(pListLast->m_pPrevious){
2026-10-04 00:04:20 +08:00
SSearchPipeList *pList2 = pListLast->m_pPrevious; //得到前节点
int num = pList2->m_lstNode.Length(); //前节点有几个分支
if(fabs(pList2->m_nStartPress) > 0.01 && num > 1){ // 1:计算过 2:2个以上分支
2026-09-28 15:28:50 +08:00
int iNum(0);
for(int i=0;i<pList2->m_lstNode.Length();i++){
SSearchPipeList *pListTmp = pList2->m_lstNode[i];
2026-10-04 00:04:20 +08:00
if(pListTmp->m_csName != _T("")) // 2个以上需要计算的节点
2026-09-28 15:28:50 +08:00
iNum++;
}
if(iNum > 1){
nStartPress = pList2->m_nStartPress;
pListCalc = pList2;
return pListCalc;
}
}
}
}
}
OPENOBJ_END();
}
if(pListLast->m_pPrevious){
SSearchPipeList *pRet = HasReCalcNode(pListLast->m_pPrevious, nStartPress, pListCalc);
return pRet;
}
return NULL;
}
2026-10-04 00:04:20 +08:00
//本支路往前是否有双迭代交叉计算节点, 类似HasReCalcNode
//HasReCalcNode 返回 1:是否有交叉计算节点 2:交叉计算节点的起点压力
//HasReReCalcNode 返回 是否有双迭代交叉计算节点
2026-09-28 15:28:50 +08:00
BOOL HasReReCalcNode(SSearchPipeList *pListLast)
{
AcDbObjectId id = NULL;
id = pListLast->m_ID;
if(pListLast->m_iType == 0){
OPENOBJ_BEGIN(id, AcDb::kForRead, CDbPipe, pPipe);
if(pPipe){
if(pListLast->m_lstNode.Length() == 1){
if(pListLast->m_pPrevious){
2026-10-04 00:04:20 +08:00
SSearchPipeList *pList2 = pListLast->m_pPrevious; //得到前节点
int num = pList2->m_lstNode.Length(); //前节点有几个分支
2026-09-28 15:28:50 +08:00
int iNum(0);
for(int i=0;i<pList2->m_lstNode.Length();i++){
SSearchPipeList *pListTmp = pList2->m_lstNode[i];
if(pListTmp->m_csName != _T(""))
iNum++;
}
if(iNum > 1 && fabs(pList2->m_nStartPress) < 0.01){
return TRUE;
}
else if(iNum > 1 && fabs(pList2->m_nStartPress) > 0.01){
return FALSE;
}
}
}
}
OPENOBJ_END();
}
if(pListLast->m_pPrevious){
return HasReReCalcNode(pListLast->m_pPrevious);
}
return FALSE;
}
2026-10-04 00:04:20 +08:00
//根据管径,阀门名称得到当量
//由于规范上没有列举所有的阀门所对应的当量,本软件只提供
// 闸阀 球阀 碟阀 止回阀 其它阀暂时按闸阀处理
//参考规范 《建筑给水排水设计规范》附录B 《自动喷水灭火系统设计规范》附录C
2026-09-28 15:28:50 +08:00
double GetValveNg(double nDn, AcDbObjectId id)
{
CString csBlkName, csDesName;
GetValveNameById(id, csBlkName, csDesName);
if(csDesName == _T(""))
return 0;
2026-10-04 00:04:20 +08:00
if(csDesName.Find(_T("球阀")) > -1){
2026-09-28 15:28:50 +08:00
if(nDn < 12.7)
return 2.4;
else if(nDn < 19.1)
return 4.6;
else if(nDn < 25.4)
return 6.1;
else if(nDn < 31.8)
return 7.6;
else if(nDn < 38.1)
return 10.6;
else if(nDn < 50.8)
return 13.7;
else if(nDn < 63.5)
return 16.7;
else if(nDn < 76.2)
return 19.8;
else if(nDn < 101.6)
return 24.3;
else if(nDn < 127)
return 38;
else if(nDn < 152.4)
return 42.6;
else
return 50.2;
}
2026-10-04 00:04:20 +08:00
else if(csDesName.Find(_T("止回阀")) > -1){
2026-09-28 15:28:50 +08:00
if(nDn < 32)
return 1.5;
else if(nDn < 40)
return 2.1;
else if(nDn < 50)
return 2.7;
else if(nDn < 65)
return 3.4;
else if(nDn < 80)
return 4.3;
else if(nDn < 100)
return 4.9;
else if(nDn < 125)
return 6.7;
else if(nDn < 150)
return 8.3;
else
return 9.8;
}
2026-10-04 00:04:20 +08:00
else if(csDesName.Find(_T("蝶阀")) > -1){
2026-09-28 15:28:50 +08:00
if(nDn < 65)
return 1.8;
else if(nDn < 80)
return 2.1;
else if(nDn < 100)
return 3.1;
else if(nDn < 125)
return 3.7;
else if(nDn < 150)
return 2.7;
else
return 3.1;
}
2026-10-04 00:04:20 +08:00
else{ //闸阀 和 其它阀
2026-09-28 15:28:50 +08:00
if(nDn < 19.1)
return 0.1;
else if(nDn < 38.1)
return 0.2;
else if(nDn < 50.8)
return 0.3;
else if(nDn < 63.5)
return 0.4;
else if(nDn < 76.2)
return 0.5;
else if(nDn < 101.6)
return 0.6;
else if(nDn < 127)
return 0.8;
else if(nDn < 152.4)
return 1;
else
return 1.2;
}
return 0;
}
2026-10-04 00:04:20 +08:00
//计算节点
2026-09-28 15:28:50 +08:00
double DoCalcListNode(SSearchPipeList *pListLast, BOOL bReturn, int &idx, double nK)
{
double nRet(0);
AcDbObjectId id = NULL;
id = pListLast->m_ID;
pListLast->m_iNum = 0;
2026-10-04 00:04:20 +08:00
BOOL bIsCornerNode = FALSE; //本变量记录该交叉节点计算条件不成熟
2026-09-28 15:28:50 +08:00
if(pListLast->m_iType == 0){
OPENOBJ_BEGIN(id, AcDb::kForRead, CDbPipe, pPipe);
if(pPipe){
int iDn = (int)pPipe->GetDnDiameter();
2026-10-04 00:04:20 +08:00
double nRadius = GetPipeCalcDiameter(id)/1000; //本管计算半径
2026-09-28 15:28:50 +08:00
if(pListLast->m_lstNode.Length() == 1){
double nPipeQ(0);
2026-10-04 00:04:20 +08:00
SSearchPipeList *pList = pListLast->m_lstNode[0]; //得到后节点
2026-09-28 15:28:50 +08:00
double nStartPress = pList->m_nStartPress;
2026-10-04 00:04:20 +08:00
nPipeQ = pList->m_nPipeQ; //得到后管的管段流量
2026-09-28 15:28:50 +08:00
int iK = pList->m_iSpare;
BOOL bFlag = FALSE;
if(pListLast->m_pPrevious){
2026-10-04 00:04:20 +08:00
SSearchPipeList *pList2 = pListLast->m_pPrevious; //得到前节点
2026-09-28 15:28:50 +08:00
int iNum(0);
iNum = pList2->m_lstNode.Length();
if(iNum > 1){
int iNumTmp(0);
for(int i=0;i<iNum;i++){
SSearchPipeList *pListTmp = pList2->m_lstNode[i];
if(fabs(pListTmp->m_nStartPress) > 0.01)
iNumTmp++;
else if(pListTmp == pListLast)
iNumTmp++;
else if(fabs(pListTmp->m_nStartPress) < 0.01 && pListTmp->m_csName != _T("")){
2026-10-04 00:04:20 +08:00
bIsCornerNode = TRUE;//交叉点还有输入端没计算
2026-09-28 15:28:50 +08:00
}
}
if(iNumTmp > 1)
2026-10-04 00:04:20 +08:00
bFlag = TRUE; //此处为交叉计算节点
2026-09-28 15:28:50 +08:00
}
}
double nCalcK(0);
if(iK > 1)
nCalcK = 0.42 / 80 * iK;
else
nCalcK = nK;
2026-10-04 00:04:20 +08:00
double nQ = nCalcK * sqrt(nStartPress); // Q = K * SQRT(H1); 节点流量
2026-09-28 15:28:50 +08:00
if(pList->m_bNeedCale)
2026-10-04 00:04:20 +08:00
nQ += nPipeQ; // (需要计算的节点)管段流量 = 本节点流量 + 上管段流量
2026-09-28 15:28:50 +08:00
else
2026-10-04 00:04:20 +08:00
nQ = nPipeQ; // (不需要计算的节点)管段流量 = 上管段流量
double nV = 4 * nQ / (PI * nRadius * nRadius)/1000; //流速 4 × Q / (PI * DN * DN) m/s
2026-09-28 15:28:50 +08:00
2026-10-04 00:04:20 +08:00
double i = 0.00107 * nV * nV / (pow(nRadius, 1.3)); //水力陂降 /计算半径的1.3次方
2026-09-28 15:28:50 +08:00
// double nPipeLen = pPipe->Length()/1000;
double nPipeLen = pPipe->Length();
if(nRadius < 0.01){
nV = 0;
i = 0;
}
double dDang = pListLast->m_nDang;
2026-10-04 00:04:20 +08:00
pListLast->m_nLost = (nPipeLen + dDang) * i; //损失
pListLast->m_nStartPress = nStartPress; //起点压力
pListLast->m_nPipeQ = nQ; //管段流量 L/s
2026-09-28 15:28:50 +08:00
pListLast->m_iDn = iDn;
//pListLast->m_nDang = nDang;
pListLast->m_nI = i;
pListLast->m_nV = nV;
pListLast->m_nLength = pPipe->Length();
// pListLast->m_nLength = pPipe->Length()/1000;
if(idx > 0){
pListLast->m_iNum = idx;
idx++;
}
if(pListLast->m_pPrevious){
2026-10-04 00:04:20 +08:00
if(!bFlag) //上一节点的起点压力
2026-09-28 15:28:50 +08:00
pListLast->m_pPrevious->m_nStartPress = nStartPress + pListLast->m_nLost;
2026-10-04 00:04:20 +08:00
if(bFlag){ //交叉计算节点
2026-09-28 15:28:50 +08:00
if(bReturn)
2026-10-04 00:04:20 +08:00
return nStartPress + pListLast->m_nLost; //返回交叉计算节点的压力
2026-09-28 15:28:50 +08:00
else
2026-10-04 00:04:20 +08:00
pListLast->m_pPrevious->m_nPipeQ += nQ; //管段流量 = 多段管线流量之和
2026-09-28 15:28:50 +08:00
}
else
2026-10-04 00:04:20 +08:00
pListLast->m_pPrevious->m_nPipeQ = nQ; //管段流量 L/s
2026-09-28 15:28:50 +08:00
}
if(bIsCornerNode && !bReturn)
return idx;
else if(bIsCornerNode && bReturn && bFlag)
2026-10-04 00:04:20 +08:00
return nStartPress + pListLast->m_nLost; //返回交叉计算节点的压力
2026-09-28 15:28:50 +08:00
}
}
OPENOBJ_END();
}
if(pListLast->m_pPrevious){
nRet = DoCalcListNode(pListLast->m_pPrevious, bReturn, idx, nK);
if(bReturn)
return nRet;
else
nRet = idx;
}
return nRet;
}
void DoSprinklerDimName(SSearchPipeList *pListAll, int iStart, BOOL bIsStart = TRUE)
{
int idx = iStart;
SSearchPipeList *pNode = GetNextDimNode(pListAll, NULL);
while(pNode){
BOOL IsMainNode = FALSE;
if(idx == iStart && bIsStart)
IsMainNode = TRUE;
2026-10-04 00:04:20 +08:00
idx = DoSerialNumber(pNode, idx, IsMainNode); //标注节点编号
pNode = GetNextDimNode(pListAll, NULL); //得到下一支路起点节点
2026-09-28 15:28:50 +08:00
}
2026-10-04 00:04:20 +08:00
DoDimPipeSerialNumber(pListAll); //标注管段编号
2026-09-28 15:28:50 +08:00
}
2026-10-04 00:04:20 +08:00
//判断本节点是否包含指定名称的节点
2026-09-28 15:28:50 +08:00
BOOL HasNodeNameInList(SSearchPipeList *pListCalc, CString csName)
{
BOOL bRet = FALSE;
if(pListCalc->m_csName == csName)
return TRUE;
int len = pListCalc->m_lstNode.Length();
for(int i=0;i<len;i++){
SSearchPipeList *pList = pListCalc->m_lstNode[i];
bRet = HasNodeNameInList(pList, csName);
if(bRet)
return TRUE;
}
return bRet;
}
2026-10-04 00:04:20 +08:00
// 把喷淋系统中的1部分,COPY到一个新的数据结构中。
2026-09-28 15:28:50 +08:00
void CopySprinklerSubSys(SSearchPipeList *pListFrom, SSearchPipeList *pListTo, CString csHeadName, CString csTermName)
{
if(pListFrom == NULL)
return;
pListTo->m_ID = pListFrom->m_ID;
pListTo->m_iNum = pListFrom->m_iNum;
pListTo->m_iType = pListFrom->m_iType;
pListTo->m_iDn = pListFrom->m_iDn;
pListTo->m_iSpare = pListFrom->m_iSpare;
pListTo->m_bNeedCale = pListFrom->m_bNeedCale;
pListTo->m_csName = pListFrom->m_csName;
pListTo->m_nLength = pListFrom->m_nLength;
pListTo->m_nDang = pListFrom->m_nDang;
2026-10-04 00:04:20 +08:00
pListTo->m_nPipeQ = 0; //以下5个需要重新计算
2026-09-28 15:28:50 +08:00
pListTo->m_nStartPress = 0;
pListTo->m_nI = 0;
pListTo->m_nV = 0;
pListTo->m_nLost = 0;
pListTo->m_nSpare = pListFrom->m_nSpare;
int len = pListFrom->m_lstNode.Length();
for(int i=0;i<len;i++){
SSearchPipeList *pList = pListFrom->m_lstNode[i];
2026-10-04 00:04:20 +08:00
// 如果已经计算过了,就无需再copy
2026-09-28 15:28:50 +08:00
if(pList->m_nStartPress > 0.01 && len > 1)
continue;
2026-10-04 00:04:20 +08:00
if(pListFrom->m_csName == csHeadName) //根节点,要判断一下分支
{//2008.10.31 只考虑1条分支
2026-09-28 15:28:50 +08:00
if(!HasNodeNameInList(pList, csTermName))
continue;
}
SSearchPipeList *pListNew = new SSearchPipeList();
pListNew->m_pPrevious = pListTo;
pListTo->m_lstNode.Append(pListNew);
CopySprinklerSubSys(pList, pListNew, csHeadName, csTermName);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2026-10-04 00:04:20 +08:00
//计算主模块 已知最不利喷头压力 求入口压力
2026-09-28 15:28:50 +08:00
void DoSprinklerCalc(SSearchPipeList *pListAll, double nPress, double nK, int iStart)
{
int idx = iStart;
2026-10-04 00:04:20 +08:00
SSearchPipeList *pNode = GetNextCalcNode(pListAll, NULL); //得到下一支路起点节点
2026-09-28 15:28:50 +08:00
idx = iStart;
while(pNode){
pNode->m_nStartPress = nPress;
if(nPress < 0.01)
break;
double nStartPress(0), nCalcPress(0);
BOOL bFlag = TRUE;
2026-10-04 00:04:20 +08:00
SSearchPipeList *pListCalc = HasReCalcNode(pNode, nStartPress, NULL);//是否有交叉计算节点?
2026-09-28 15:28:50 +08:00
if(pListCalc != NULL){
2026-10-04 00:04:20 +08:00
if(HasReReCalcNode(pNode)){ //太复杂了,超过3级,需要进行计算2
2026-09-28 15:28:50 +08:00
bFlag = FALSE;
SSearchPipeList *pListNew = new SSearchPipeList();
pListNew->m_pPrevious = NULL;
pListNew->m_nLength = 0;
2026-10-04 00:04:20 +08:00
// 1.把交叉计算节点往下都copy到一个新的结构中
2026-09-28 15:28:50 +08:00
CopySprinklerSubSys(pListCalc, pListNew, pListCalc->m_csName, pNode->m_csName);
2026-10-04 00:04:20 +08:00
// 2.对这个新系统进行“已知入口压力,反算末端压力”
2026-09-28 15:28:50 +08:00
int iStartTmp = _ttoi(pNode->m_csName);
double dRet = DoSprinklerCalc2(pListNew, nStartPress, nK, iStartTmp);
delete pListNew;
2026-10-04 00:04:20 +08:00
if(dRet > 0.1)//if(dRet > nPress) 有可能最不利点的位置选择不合适,本节点的起始压力就是小于最不利点压力
2026-09-28 15:28:50 +08:00
pNode->m_nStartPress = dRet;
}
}
else
bFlag = FALSE;
2026-10-04 00:04:20 +08:00
if(bFlag){ //有交叉计算节点
2026-09-28 15:28:50 +08:00
int iTmp(0);
2026-10-04 00:04:20 +08:00
nCalcPress = DoCalcListNode(pNode, TRUE, iTmp, nK); //返回交叉计算节点起点压力
2026-09-28 15:28:50 +08:00
double nPlus(nPress), nVal(0), nTmp(nPress);
2026-10-04 00:04:20 +08:00
double dTolerance(0.1); //迭代误差 2007-5-11 加强10以下的精度
2026-09-28 15:28:50 +08:00
if(nPress<9 && nPress>6)
dTolerance = 0.05;
else if(nPress<6.1)
dTolerance = 0.01;
nVal = nStartPress - nCalcPress;
int n(-1);
if(nVal < 0)
nPlus = -nPress;
2026-10-04 00:04:20 +08:00
//以下循环, 不断进行反推, 根据交叉节点压力, 反算第二支路起点压力
2026-09-28 15:28:50 +08:00
while(fabs(nStartPress - nCalcPress) > dTolerance){
n++;
pNode->m_nStartPress = nPress + nPlus;
iTmp = 0;
nCalcPress = DoCalcListNode(pNode, TRUE, iTmp, nK);
nVal = nStartPress - nCalcPress;
2026-10-04 00:04:20 +08:00
//sr modify 对于仓库危险级,起点压力50,误差太大 2007-5-11 所以由固定10改为nPress
nTmp = nPress * pow(2.0, -n); //10、5、2.5、1.25、0.625、0.3125 ... ...
2026-09-28 15:28:50 +08:00
if(nVal < 0)
nPlus = nPlus - nTmp;
else
nPlus = nPlus + nTmp;
2026-10-04 00:04:20 +08:00
if(n > 20) //死循环, 主动退出
2026-09-28 15:28:50 +08:00
break;
}
}
idx = (int)DoCalcListNode(pNode, FALSE, idx, nK);
idx++;
CString csTmpName = pNode->m_csName;
2026-10-04 00:04:20 +08:00
pNode = GetNextCalcNode(pListAll, NULL); //对当前支路进行计算
2026-09-28 15:28:50 +08:00
if(pNode && csTmpName == pNode->m_csName)
break;
}
}
/*
2026-10-04 00:04:20 +08:00
//计算主模块 已知入口压力 求各喷头压力
2026-09-28 15:28:50 +08:00
void DoSprinklerCalc2(SSearchPipeList *pListAll, double nPress, double nK, int iStart, CMapStringToString &map)
{
double nTmpPress(10);
double nPlus(5), nTmp(5);
DoSprinklerCalc(pListAll, nTmpPress, nK, iStart, map);
double nLastPress = pListAll->m_nLost + pListAll->m_nStartPress;
if(nLastPress > nPress)
nTmpPress = 5;
2026-10-04 00:04:20 +08:00
acedSetStatusBarProgressMeter(_T("喷淋计算中..."), 0, 20);
2026-09-28 15:28:50 +08:00
int n(1);
while(1){
acedSetStatusBarProgressMeterPos(n);
n++;
CSprinklerCalcDlg::ResetList(pListAll);
DoSprinklerCalc(pListAll, nTmpPress, nK, iStart, map);
nLastPress = pListAll->m_nLost + pListAll->m_nStartPress;
if(fabs(nLastPress - nPress) < 0.005)
break;
double nVal = nLastPress - nPress;
2026-10-04 00:04:20 +08:00
nTmp = 10 * pow(2.0, -n); //10、5、2.5、1.25、0.625、0.3125 ... ...
2026-09-28 15:28:50 +08:00
if(nVal > 0)
nTmpPress = nTmpPress - nTmp;
else
nTmpPress = nTmpPress + nTmp;
2026-10-04 00:04:20 +08:00
if(n > 30) //死循环, 主动退出
2026-09-28 15:28:50 +08:00
break;
}
acedRestoreStatusBar();
}
*/
2026-10-04 00:04:20 +08:00
//计算主模块 已知入口压力 求各喷头压力
2026-09-28 15:28:50 +08:00
double DoSprinklerCalc2(SSearchPipeList *pListAll, double nPress, double nK, int iStart)
{
double nTmpPress(10);
double nPlus(5), nTmp(5);
DoSprinklerCalc(pListAll, nTmpPress, nK, iStart);
double nLastPress = pListAll->m_nLost + pListAll->m_nStartPress;
if(nLastPress > nPress)
nTmpPress = 7.5;
CString csPrompt;
2026-10-04 00:04:20 +08:00
csPrompt.Format(_T("%s节点,喷淋计算中..."), pListAll->m_csName);
2026-09-28 15:28:50 +08:00
acedSetStatusBarProgressMeter(csPrompt, 0, 30);
int n(0);
while(1){
acedSetStatusBarProgressMeterPos(n);
n++;
CSprinklerCalcDlg::ResetList(pListAll);
DoSprinklerCalc(pListAll, nTmpPress, nK, iStart);
nLastPress = pListAll->m_nLost + pListAll->m_nStartPress;
if(fabs(nLastPress - nPress) < 0.005)
break;
double nVal = nLastPress - nPress;
2026-10-04 00:04:20 +08:00
// nTmp = 10 * pow(2.0, -n); //10、5、2.5、1.25、0.625、0.3125 ... ...
nTmp = nPress * pow(2.0, -n); //10、5、2.5、1.25、0.625、0.3125 ... ...
2026-09-28 15:28:50 +08:00
if(nVal > 0)
nTmpPress = nTmpPress - nTmp;
else
nTmpPress = nTmpPress + nTmp;
2026-10-04 00:04:20 +08:00
if(n > 30) //死循环, 主动退出
2026-09-28 15:28:50 +08:00
break;
}
acedRestoreStatusBar();
return nTmpPress;
}
2026-10-04 00:04:20 +08:00
//得到计算范围,返回要计算的喷头
2026-09-28 15:28:50 +08:00
void GetCalcSprinkler(PickSet &ss, double &nArea)
{
XPoint pt1, pt2;
RBList rbMask(RTDXF0, _T("ATS_EQUIPMENT"), 8, LAY_EQUIP_SPRINKLE, NULL);
int nRetCode;
INITGET_BEG(0, _T("S D"));
2026-10-04 00:04:20 +08:00
nRetCode = ads_getpoint(NULL, _T("\n选择第一点[选取闭合PLINE(S)/多选喷头(D)]"), pt1);
2026-09-28 15:28:50 +08:00
INITGET_END();
if(nRetCode==RTKWORD) {
XString sKeyword;
ads_getinput(sKeyword);
TCHAR cKey = sKeyword[0];
if(cKey==_T('S')){
Entity entPoly;
RBList rbMask2(RTDXF0, _T("LWPOLYLINE"), 8, _T("*"), NULL);
2026-10-04 00:04:20 +08:00
if(GlobalFunc::SelectEntity(_T("\n请选择表示作用面积的闭合PLINE:<退出>"), entPoly, rbMask2) != RTNORM)
2026-09-28 15:28:50 +08:00
return;
XPoly2D poly(entPoly);
poly.TransUCS(RBGroups(0), RBGroups(1));//RBGroups(0) wcs, RBGroups(1) ucs
nArea = _AS_SQMETER(poly.Area());
RBList rbFence = poly.Fence();
XPoint ptLow3, ptUp3;
poly.GetExtend(ptLow3, ptUp3);
GlobalFunc::AssureInCurrentView(GlobalFunc::Ucs2Wcs(ptLow3), GlobalFunc::Ucs2Wcs(ptUp3));
ss.Get(_T("CP"), rbFence, NULL, rbMask);
int len = ss.Length();
return;
}
else{
2026-10-04 00:04:20 +08:00
if(GlobalFunc::SelectEntities(_T("\n请选择作用面积内的喷头:<退出>"), ss, rbMask) != RTNORM)
2026-09-28 15:28:50 +08:00
return;
XPoint ptLow, ptUp;
ss.GetExtend(ptLow, ptUp);
XRectAngle rect(ptLow, ptUp);
nArea = _AS_SQMETER(rect.Area());
return;
}
}
else if(nRetCode != RTNORM)
return;
CTipWnd *pTextDlg = NULL;
int itype = -1;
double dAng(0);
int pickbox;
VERIFY(xg_getvar(_T("PICKBOX"), &pickbox)==RTNORM);
while(1){
struct resbuf pointbuf;
2026-10-04 00:04:20 +08:00
int iRet = ads_grread(5, &itype, &pointbuf); //得到动态点pointbuf
ads_point_set(pointbuf.resval.rpoint, pt2); //ptend动态点,也就是引出支线的结束点
2026-09-28 15:28:50 +08:00
ads_redraw(NULL, 1);
if(itype == 5){
XRectAngle rect(pt1, pt2);
GrdrawRect(rect);
if (pTextDlg) {
pTextDlg->DestroyWindow();
delete pTextDlg;
pTextDlg = NULL;
}
if(!pTextDlg){
CPoint pt;
int cvport;
VERIFY(xg_getvar(_T("CVPORT"), &cvport)==RTNORM);
acedCoordFromWorldToPixel(cvport, pt2, pt);
acedGetAcadDwgView()->ClientToScreen(&pt);
acedGetAcadFrame()->ScreenToClient(&pt);
DList<CBlockStruct> lstInfo;
CBlockStruct *pdate = new CBlockStruct;
CString csArea;
nArea = rect.Area()/1000000;
2026-10-04 00:04:20 +08:00
csArea.Format(_T("%.2f 平方米"), nArea);
2026-09-28 15:28:50 +08:00
pdate->m_csDesName = csArea;
2026-10-04 00:04:20 +08:00
pdate->m_csRecord = _T("面积");
2026-09-28 15:28:50 +08:00
lstInfo.Append(pdate);
pTextDlg = new CTipWnd();
pTextDlg->Create(lstInfo, pt.x+pickbox*2, pt.y+pickbox*2, acedGetAcadFrame());
}
}
else
break;
}
if(pTextDlg){
pTextDlg->DestroyWindow();
delete pTextDlg;
}
ss.Get(_T("C"), pt1, pt2, rbMask);
}
2026-10-04 00:04:20 +08:00
//计算本节点往后有多少喷头
2026-09-28 15:28:50 +08:00
void CalcSprinkNum(SSearchPipeList *pListAll)
{
AcDbObjectId id = NULL;
id = pListAll->m_ID;
pListAll->m_iNum = 0;
if(pListAll->m_iType == 2)
pListAll->m_iNum = 1;
ads_name ent;
acdbGetAdsName(ent, id);
long len = pListAll->m_lstNode.Length();
for(long i=0;i<len;i++){
SSearchPipeList *pList = pListAll->m_lstNode[i];
CalcSprinkNum(pList);
pListAll->m_iNum += pList->m_iNum;
}
}
//***************************************************************************************************
2026-10-04 00:04:20 +08:00
// 喷淋计算
2026-09-28 15:28:50 +08:00
//***************************************************************************************************
2026-10-04 00:04:20 +08:00
//主函数
2026-09-28 15:28:50 +08:00
void SprinklerCalc()
{
GlobalFunc::DocGetPickFirst().Free();
Entity entMainPipe;
RBList rbMaskPipe = ads_buildlist( -4, _T("<or"),
-4, _T("<and"), RTDXF0, _T("ATS_PIPE"), 8, LAY_PIPE_SPRINKLE, -4, _T("and>"),
-4, _T("<and"), RTDXF0, _T("ATS_PIPE"), 8, LAY_PIPE_SPRINKLE2, -4, _T("and>"),
-4, _T("<and"), RTDXF0, _T("ATS_PIPE"), 8, LAY_PIPE_SPRINKLE3, -4, _T("and>"),
-4, _T("<and"), RTDXF0, _T("ATS_PIPE"), 8, LAY_VPIPE_SPRINKLE, -4, _T("and>"),
-4, _T("<and"), RTDXF0, _T("ATS_PIPE"), 8, LAY_VPIPE_SPRINKLE2, -4, _T("and>"),
-4, _T("<and"), RTDXF0, _T("ATS_PIPE"), 8, LAY_VPIPE_SPRINKLE3, -4, _T("and>"),
-4, _T("or>"), NULL);
// RBList rbMaskPipe(RTDXF0, _T("ATS_PIPE"), 8, LAY_PIPE_SPRINKLE, NULL);
2026-10-04 00:04:20 +08:00
if(GlobalFunc::SelectEntity(_T("\n请选择喷淋干管<退出>"), entMainPipe, rbMaskPipe) != RTNORM) {
2026-09-28 15:28:50 +08:00
return;
}
RBList rbMask(RTDXF0, _T("ATS_EQUIPMENT"), 8, _T("*"), NULL);
SSearchPipeList *pListAll = new SSearchPipeList();
PickSet ssAll(SS_FREE);
ssAll += entMainPipe;
if(!GlobalFunc::SearchSprinkPipeSys(entMainPipe, NULL, pListAll, ssAll)){
2026-10-04 00:04:20 +08:00
AfxMessageBox(_T("喷淋系统有回路!"));
2026-09-28 15:28:50 +08:00
delete pListAll;
return;
}
if(!GlobalFunc::CalcLstPipeLength(pListAll, NULL, ssAll)){
2026-10-04 00:04:20 +08:00
AfxMessageBox(_T("喷淋系统没有标注管径,请先执行命令[喷淋管径]或[管径标注]"));
2026-09-28 15:28:50 +08:00
delete pListAll;
return;
}
int iStart(1);
2026-10-04 00:04:20 +08:00
ads_getint(_T("\n请输入起点编号<1>"), &iStart);
2026-09-28 15:28:50 +08:00
SSearchPipeList *pDisadvantage = NULL;
pDisadvantage = GetDisadvantageNode(pListAll, NULL);
Entity entMain, entBlk;
CString csDwb = g_csDwbPath + _T("TwtSys");
XString xsTmp;
if(GlobalFunc::LoadDwbBlock(csDwb, _T("00000069"), xsTmp) != RTNORM){
delete pListAll;
return;
}
double dDisadvantageEle(0);
double dEnteranceEle(0);
if(pDisadvantage){
AcDbObjectId id = NULL;
id = pDisadvantage->m_ID;
OPENOBJ_BEGIN(id, AcDb::kForRead, CDbPipeNode, pNode);
if(pNode){
XPoint pt = pNode->GetLocation();
dDisadvantageEle = pt.z;
GlobalFunc::InsertBlock((const TCHAR*)xsTmp, asPnt3d(pt), 500, 500, 0, _T("0"));
entBlk.GetLast();
}
OPENOBJ_END();
}
Entity entLong;
2026-10-04 00:04:20 +08:00
if(GlobalFunc::SelectEntity(_T("\n请选择最不利喷头<系统默认>:"), entLong, rbMask) == RTNORM && entLong.In(&ssAll))
2026-09-28 15:28:50 +08:00
{
entBlk.Erase();
OPENOBJ_BEGIN(entLong, AcDb::kForRead, CDbPipeNode, pNode);
if(pNode){
XPoint pt = pNode->GetLocation();
dDisadvantageEle = pt.z;
GlobalFunc::InsertBlock((const TCHAR*)xsTmp, asPnt3d(pt), 500, 500, 0, _T("0"));
entBlk.GetLast();
}
OPENOBJ_END();
}
XPoint ptS, ptE;
GlobalFunc::GetPipePoint(entMainPipe, ptS, ptE);
if(ptS.z > dDisadvantageEle && ptE.z > dDisadvantageEle)
dEnteranceEle = ptS.z > ptE.z ? ptS.z : ptE.z;
else if(ptS.z < dDisadvantageEle && ptE.z < dDisadvantageEle)
dEnteranceEle = ptS.z < ptE.z ? ptS.z : ptE.z;
else
dEnteranceEle = dDisadvantageEle;
double dElePress = dDisadvantageEle - dEnteranceEle;
dElePress = dElePress / 1000;
2026-10-04 00:04:20 +08:00
g_Option::instance().adsout << _T("图中红叉为系统最不利点, 请选择计算范围:");
2026-09-28 15:28:50 +08:00
PickSet ss(SS_FREE);
double nArea(0);
GetCalcSprinkler(ss, nArea);
if(ss.Length() < 1){
delete pListAll;
entBlk.Erase();
return;
}
InitLayer(LAY_CALC_TEXT);
GlobalFunc::CalcLstPipeLength(pListAll, NULL, ss);
if(pListAll->m_lstNode.Length() == 2){
ssAll.Free();
2026-10-04 00:04:20 +08:00
//计算源头应为节点,而不是管线. 以下计算管线2节点哪个是源头
CalcSprinkNum(pListAll); //所连喷头多的节点是源头
2026-09-28 15:28:50 +08:00
SSearchPipeList *p1 = pListAll->m_lstNode[0];
SSearchPipeList *p2 = pListAll->m_lstNode[1];
SSearchPipeList *p3 = p1->m_iNum > p2->m_iNum ? p2 : p1;
ads_name ent;
acdbGetAdsName(ent, p3->m_ID);
delete pListAll;
pListAll = new SSearchPipeList();
2026-10-04 00:04:20 +08:00
//重新搜索系统
2026-09-28 15:28:50 +08:00
if(!GlobalFunc::SearchSprinkPipeSys(ent, NULL, pListAll, ssAll)){
2026-10-04 00:04:20 +08:00
AfxMessageBox(_T("喷淋系统有回路!"));
2026-09-28 15:28:50 +08:00
delete pListAll;
entBlk.Erase();
return;
}
pListAll->m_iType = 1;
GlobalFunc::CalcLstPipeLength(pListAll, NULL, ss);
}
if(ssAll.Length() < 3){
2026-10-04 00:04:20 +08:00
g_Option::instance().adsout << _T("\n喷淋系统可能存在断线! 内容太少");
2026-09-28 15:28:50 +08:00
entBlk.Erase();
delete pListAll;
return;
}
CSprinklerCalcDlg dlg;
2026-10-04 00:04:20 +08:00
if(!!entLong)//用户重新设置最不利点
2026-09-28 15:28:50 +08:00
{
AcDbObjectId id = NULL;
acdbGetObjectId(id, entLong);
pDisadvantage = dlg.GetNodeById(pListAll, id, NULL);
if(pDisadvantage == NULL)
{
2026-10-04 00:04:20 +08:00
g_Option::instance().adsout << _T("\n所选最不利喷头不在要计算的喷淋系列内,请检查!");
2026-09-28 15:28:50 +08:00
entBlk.Erase();
delete pListAll;
return;
}
2026-10-04 00:04:20 +08:00
iStart = DoSerialNumber(pDisadvantage, iStart, TRUE); //标注节点编号
2026-09-28 15:28:50 +08:00
DoSprinklerDimName(pListAll, iStart, FALSE);
}
else
DoSprinklerDimName(pListAll, iStart, TRUE);
2026-10-04 00:04:20 +08:00
actrTransactionManager->flushGraphics(); //acad 刷新
2026-09-28 15:28:50 +08:00
CTemporaryResourceOverride vTemp;
dlg.m_pListAll = pListAll;
dlg.m_iStart = iStart;
dlg.m_dElePress = dElePress;
dlg.m_nUserArea = nArea;
if(dlg.DoModal() != IDOK){
entBlk.Erase();
delete pListAll;
return;
}
delete pListAll;
entBlk.Erase();
return;
}
2026-10-04 00:04:20 +08:00
//主函数
2026-09-28 15:28:50 +08:00
void SprinklerCalc2()
{
Entity entMainPipe;
RBList rbMask(RTDXF0, _T("ATS_EQUIPMENT"), 8, _T("*"), NULL);
RBList rbMaskPipe(RTDXF0, _T("ATS_PIPE"), 8, LAY_PIPE_SPRINKLE, NULL);
2026-10-04 00:04:20 +08:00
if(GlobalFunc::SelectEntity(_T("\n请选择喷淋干管<退出>"), entMainPipe, rbMaskPipe) != RTNORM) {
2026-09-28 15:28:50 +08:00
return;
}
SSearchPipeList *pListAll = new SSearchPipeList();
PickSet ssAll(SS_FREE);
ssAll += entMainPipe;
if(!GlobalFunc::SearchSprinkPipeSys(entMainPipe, NULL, pListAll, ssAll)){
2026-10-04 00:04:20 +08:00
AfxMessageBox(_T("喷淋系统有回路!"));
2026-09-28 15:28:50 +08:00
delete pListAll;
return;
}
if(!GlobalFunc::CalcLstPipeLength(pListAll, NULL, ssAll)){
2026-10-04 00:04:20 +08:00
AfxMessageBox(_T("喷淋系统没有标注管径,请先执行命令[喷淋管径]或[管径标注]"));
2026-09-28 15:28:50 +08:00
delete pListAll;
return;
}
int iStart(1);
2026-10-04 00:04:20 +08:00
ads_getint(_T("\n请输入起点编号<1>"), &iStart);
2026-09-28 15:28:50 +08:00
SSearchPipeList *pDisadvantage = NULL;
pDisadvantage = GetDisadvantageNode(pListAll, NULL);
Entity entMain, entBlk;
if(pDisadvantage){
AcDbObjectId id = NULL;
id = pDisadvantage->m_ID;
CString csDwb = g_csDwbPath + _T("TwtSys");
XString xsTmp;
if(GlobalFunc::LoadDwbBlock(csDwb, _T("00000069"), xsTmp) != RTNORM || !id){
delete pListAll;
return;
}
OPENOBJ_BEGIN(id, AcDb::kForRead, CDbPipeNode, pNode);
if(pNode){
XPoint pt = pNode->GetLocation();
GlobalFunc::InsertBlock((const TCHAR*)xsTmp, asPnt3d(pt), 500, 500, 0, _T("0"));
entBlk.GetLast();
}
OPENOBJ_END();
2026-10-04 00:04:20 +08:00
g_Option::instance().adsout << _T("图中红叉为系统最不利点, 请选择计算范围:");
2026-09-28 15:28:50 +08:00
}
PickSet ss(SS_FREE);
double nArea(0);
GetCalcSprinkler(ss, nArea);
if(ss.Length() < 1){
delete pListAll;
entBlk.Erase();
return;
}
InitLayer(LAY_CALC_TEXT);
GlobalFunc::CalcLstPipeLength(pListAll, NULL, ss);
if(pListAll->m_lstNode.Length() == 2){
ssAll.Free();
2026-10-04 00:04:20 +08:00
//计算源头应为节点,而不是管线. 以下计算管线2节点哪个是源头
CalcSprinkNum(pListAll); //所连喷头多的节点是源头
2026-09-28 15:28:50 +08:00
SSearchPipeList *p1 = pListAll->m_lstNode[0];
SSearchPipeList *p2 = pListAll->m_lstNode[1];
SSearchPipeList *p3 = p1->m_iNum > p2->m_iNum ? p2 : p1;
ads_name ent;
acdbGetAdsName(ent, p3->m_ID);
delete pListAll;
pListAll = new SSearchPipeList();
2026-10-04 00:04:20 +08:00
//重新搜索系统
2026-09-28 15:28:50 +08:00
if(!GlobalFunc::SearchSprinkPipeSys(ent, NULL, pListAll, ssAll)){
2026-10-04 00:04:20 +08:00
AfxMessageBox(_T("喷淋系统有回路!"));
2026-09-28 15:28:50 +08:00
delete pListAll;
entBlk.Erase();
return;
}
pListAll->m_iType = 1;
GlobalFunc::CalcLstPipeLength(pListAll, NULL, ss);
}
if(ssAll.Length() < 3){
2026-10-04 00:04:20 +08:00
g_Option::instance().adsout << _T("\n喷淋系统可能存在断线! 内容太少");
2026-09-28 15:28:50 +08:00
entBlk.Erase();
delete pListAll;
return;
}
DoSprinklerDimName(pListAll, iStart);
2026-10-04 00:04:20 +08:00
actrTransactionManager->flushGraphics(); //acad 刷新
2026-09-28 15:28:50 +08:00
CTemporaryResourceOverride vTemp;
CSprinklerCalcDlg dlg;
dlg.m_pListAll = pListAll;
dlg.m_iStart = iStart;
dlg.m_nUserArea = nArea;
if(dlg.DoModal() != IDOK){
entBlk.Erase();
delete pListAll;
return;
}
delete pListAll;
entBlk.Erase();
return;
}
//***************************************************************************************************
2026-10-04 00:04:20 +08:00
// 最远路径
2026-09-28 15:28:50 +08:00
//***************************************************************************************************
2026-10-04 00:04:20 +08:00
//得到最不利节点
2026-09-28 15:28:50 +08:00
extern void GetDisadvantage2Head(PickSet &ssTmp, SSearchPipeList *pDisadvantage);
//{
// AcDbObjectId id = NULL;
// id = pDisadvantage->m_ID;
// if(pDisadvantage->m_iType == 0)
// ssTmp += id;
// if(pDisadvantage->m_pPrevious != NULL)
// GetDisadvantage2Head(ssTmp, pDisadvantage->m_pPrevious);
//}
extern void FindLongPath();
/*{
RBList rbMaskPipe = ads_buildlist( -4, _T("<or"),
-4, _T("<and"), RTDXF0, _T("ATS_PIPE"), 8, LAY_PIPE_SPRINKLE, -4, _T("and>"),
-4, _T("<and"), RTDXF0, _T("ATS_PIPE"), 8, LAY_PIPE_SPRINKLE2, -4, _T("and>"),
-4, _T("<and"), RTDXF0, _T("ATS_PIPE"), 8, LAY_PIPE_SPRINKLE3, -4, _T("and>"),
-4, _T("or>"), NULL);
Entity entMain;
PickSet ss(SS_FREE);
2026-10-04 00:04:20 +08:00
if(GlobalFunc::SelectEntity(_T("\n请选择主干管(搜索指定干管所连最远路径):<指定范围搜索>"), entMain, rbMaskPipe) == RTNORM)
2026-09-28 15:28:50 +08:00
{
ss+= entMain;
}
else
{
PickSet ssAllDwg(SS_FREE);
// ZXL 2013.11.15 ADD
RBList rbMaskAllPipe = ads_buildlist( -4, _T("<or"),
-4, _T("<and"), RTDXF0, _T("ATS_PIPE"), 8, LAY_PIPE_SPRINKLE, -4, _T("and>"),
-4, _T("<and"), RTDXF0, _T("ATS_PIPE"), 8, LAY_PIPE_SPRINKLE2, -4, _T("and>"),
-4, _T("<and"), RTDXF0, _T("ATS_PIPE"), 8, LAY_PIPE_SPRINKLE3, -4, _T("and>"),
-4, _T("<and"), RTDXF0, _T("ATS_PIPE"), 8, LAY_VPIPE_SPRINKLE, -4, _T("and>"),
-4, _T("<and"), RTDXF0, _T("ATS_PIPE"), 8, LAY_VPIPE_SPRINKLE2, -4, _T("and>"),
-4, _T("<and"), RTDXF0, _T("ATS_PIPE"), 8, LAY_VPIPE_SPRINKLE3, -4, _T("and>"),
-4, _T("or>"), NULL);
2026-10-04 00:04:20 +08:00
if(GlobalFunc::SelectEntities(_T("\n请选择搜索范围:<整图搜索>"), ssAllDwg, rbMaskAllPipe) != RTNORM)
2026-09-28 15:28:50 +08:00
ssAllDwg.Get(_T("X"), NULL, NULL, rbMaskAllPipe);
int len = ssAllDwg.Length();
2026-10-04 00:04:20 +08:00
//仅仅要连1根直管的立管,排除扣弯
2026-09-28 15:28:50 +08:00
for(long i=0;i<len;i++){
Entity ent = ssAllDwg[i];
OPENOBJ_BEGIN(ent, AcDb::kForRead, CDbPipe, pPipe);
if(pPipe && pPipe->IsVertical()){
AcDbObjectId id1 = pPipe->GetNode(0);
AcDbObjectId id2 = pPipe->GetNode(1);
int count(0);
OPENOBJ_BEGIN(id1, AcDb::kForRead, CDbPipeNode, pNode);
if(pNode){
int num = pNode->GetInterfaceNum();
if(num == 1)
count++;
}
OPENOBJ_END();
OPENOBJ_BEGIN(id2, AcDb::kForRead, CDbPipeNode, pNode);
if(pNode){
int num = pNode->GetInterfaceNum();
if(num == 1)
count++;
}
OPENOBJ_END();
XPoint ptTmp1 = pPipe->StartPoint();
ptTmp1.z = 0;
if(count == 1){
BOOL bFlag = TRUE;
for(long j=0;j<ss.Length();j++){
Entity entTmp = ss[j];
XPoint pt1, pt2;
GlobalFunc::GetPipePoint(entTmp, pt1, pt2);
pt1.z = 0;
if(ptTmp1 == pt1){
bFlag = FALSE;
break;
}
}
if(bFlag)
ss += ent;
}
}
OPENOBJ_END();
}
len = ss.Length();
2026-10-04 00:04:20 +08:00
g_Option::instance().adsout << XString(_T("\n共%d根立管!"), len);
2026-09-28 15:28:50 +08:00
}
PickSet ssLong(SS_FREE);
double nLongDist(0);
2026-10-04 00:04:20 +08:00
acedSetStatusBarProgressMeter(_T("计算中..."), 0, ss.Length());
2026-09-28 15:28:50 +08:00
for(long j=0;j<ss.Length();j++){
acedSetStatusBarProgressMeterPos(j);
Entity entTmp = ss[j];
SSearchPipeList *pListAll = new SSearchPipeList();
PickSet ssAll(SS_FREE);
ssAll += entTmp;
if(!GlobalFunc::SearchSprinkPipeSys(entTmp, NULL, pListAll, ssAll)){
2026-10-04 00:04:20 +08:00
AfxMessageBox(_T("喷淋系统有回路!"));
2026-09-28 15:28:50 +08:00
delete pListAll;
break;
}
if(!GlobalFunc::CalcLstPipeLength(pListAll, NULL, ssAll)){
2026-10-04 00:04:20 +08:00
AfxMessageBox(_T("喷淋系统没有标注管径,请先执行命令[喷淋管径]或[管径标注]"));
2026-09-28 15:28:50 +08:00
delete pListAll;
break;
}
SSearchPipeList *pDisadvantage = NULL;
pDisadvantage = GetDisadvantageNode(pListAll, NULL);
if(pDisadvantage){
PickSet ssTmp(SS_FREE);
GetDisadvantage2Head(ssTmp, pDisadvantage);
double nDist(0);
for(long m=0;m<ssTmp.Length();m++){
Entity entPipe = ssTmp[m];
OPENOBJ_BEGIN(entPipe, AcDb::kForRead, CDbPipe, pPipe);
if(pPipe){
nDist += pPipe->Length();
}
OPENOBJ_END();
}
if(nDist > nLongDist){
ssLong.Free();
nLongDist = nDist;
ssLong += ssTmp;
}
}
delete pListAll;
}
acedRestoreStatusBar();
2026-10-04 00:04:20 +08:00
g_Option::instance().adsout << XString(_T("\n立管距最不利点距离:%.2f!"), nLongDist);
2026-09-28 15:28:50 +08:00
ads_sssetfirst(ssLong, ssLong);
int len2 = ssLong.Length();
if(len2 < 1)
return;
XPoint ptCen, ptLow, ptUp;
double x,y,z;
ssLong.GetExtend(ptCen, &x, &y, &z);
ptLow = ptUp = ptCen;
ptLow.x -= x;
ptLow.y -= y;
ptUp.x += x;
ptUp.y += y;
GlobalFunc::AssureInCurrentView(ptLow, ptUp);
}*/