Files
envi-code/SourceCode/Code2026/Dimension/SprinklerCalc.cpp
T
2026-09-28 15:28:50 +08:00

1618 lines
52 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 "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);
if (((csKind == _T("平面阀门")) || (csKind == _T("平面附件"))) && (csDrawing != _T(""))) {
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();
}
// if(xsTmpSys == _T("")) // sys17下不这么写, 返回乱码
// 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("")) {
CString csBlk = GetPlanValve(csRocord);//如果是系统阀门,就找到对应的平面阀门,统计结果算平面的
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)) {
AfxMessageBox(_T("对不起,没有发现pipe.dbf文件!"));
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;
}
double GetDangLenByTaiIn(int iDn1, int iDn2) //接头当量长度
{
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;
}
//自动喷水灭火系统设计规范 附录C 当量长度表
double GetDangLenByCorner(int iDn) //3通4通当量长度
{
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;
}
//建筑给水排水设计规范 P106 附录B 当量长度表
double GetDangLenByElbowCorner(int iDn) //3通 转角流
{
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;
}
//建筑给水排水设计规范 P106 附录B 当量长度表
double GetDangLenByLineCorner(int iDn) //3通 直向流
{
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;
}
//自动喷水灭火系统设计规范 附录C 当量长度表
double GetDangLenByElbow90(int iDn1, int iDn2) //90度弯头当量长度
{
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);
//}
//得到下一个标注节点 根据节点编号是否为空
//3个条件
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);
if(idx < idx2){ //条件1: 当前节点的祖先编号小于临时节点的祖先编号
pDisadvantage = pListAll;
}
else if(idx == 0){ //条件2:
if(pDisadvantage && nCurPipeLength > pDisadvantage->m_nLength)
pDisadvantage = pListAll;
}
else if(idx == idx2){//条件3: 当前节点的祖先编号等于临时节点的祖先编号, 但离起始节点最远
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
pDisadvantage = pListAll; //条件3: 临时节点为空
}
}
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;
}
//得到下一个导出WORD节点 根据节点计算顺序排序
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;
}
//得到下一个计算支路的起点节点 根据起点压力是否为0
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);
if(idx < idx2){ //条件1: 当前节点的祖先编号小于临时节点的祖先编号
pDisadvantage = pListAll;
}
else if(idx == 0 || idx == idx2){//条件2: 当前节点的祖先编号等于临时节点的祖先编号, 但离起始节点最远
if(pDisadvantage && nCurPipeLength > pDisadvantage->m_nLength)
pDisadvantage = pListAll;
}
else if(pDisadvantage->m_nLength < pListAll->m_nLength)
{
//虽然节点编号大于pDisadvantage编号,但pDisadvantage是当前节点的父节点
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
pDisadvantage = pListAll; //条件3: 临时节点为空
}
}
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;
}
//得到最不利节点
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;
//}
//本节点往前所有节点进行标注
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)
pListLast->m_nDang = 255; //GetFirstAncestorSerial 这个函数会用到
if(DoDimSerialNumber(id, idx))
idx++;
else
return idx;
}
if(pListLast->m_pPrevious)
idx = DoSerialNumber(pListLast->m_pPrevious, idx, IsMainNode);
return idx;
}
//本支路往前是否有交叉计算节点
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){
SSearchPipeList *pList2 = pListLast->m_pPrevious; //得到前节点
int num = pList2->m_lstNode.Length(); //前节点有几个分支
if(fabs(pList2->m_nStartPress) > 0.01 && num > 1){ // 1:计算过 2:2个以上分支
int iNum(0);
for(int i=0;i<pList2->m_lstNode.Length();i++){
SSearchPipeList *pListTmp = pList2->m_lstNode[i];
if(pListTmp->m_csName != _T("")) // 2个以上需要计算的节点
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;
}
//本支路往前是否有交叉计算节点
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){
SSearchPipeList *pList2 = pListLast->m_pPrevious; //得到前节点
int num = pList2->m_lstNode.Length(); //前节点有几个分支
if(fabs(pList2->m_nStartPress) > 0.01 && num > 1){ // 1:计算过 2:2个以上分支
int iNum(0);
for(int i=0;i<pList2->m_lstNode.Length();i++){
SSearchPipeList *pListTmp = pList2->m_lstNode[i];
if(pListTmp->m_csName != _T("")) // 2个以上需要计算的节点
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;
}
//本支路往前是否有双迭代交叉计算节点, 类似HasReCalcNode
//HasReCalcNode 返回 1:是否有交叉计算节点 2:交叉计算节点的起点压力
//HasReReCalcNode 返回 是否有双迭代交叉计算节点
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){
SSearchPipeList *pList2 = pListLast->m_pPrevious; //得到前节点
int num = pList2->m_lstNode.Length(); //前节点有几个分支
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;
}
//根据管径,阀门名称得到当量
//由于规范上没有列举所有的阀门所对应的当量,本软件只提供
// 闸阀 球阀 碟阀 止回阀 其它阀暂时按闸阀处理
//参考规范 《建筑给水排水设计规范》附录B 《自动喷水灭火系统设计规范》附录C
double GetValveNg(double nDn, AcDbObjectId id)
{
CString csBlkName, csDesName;
GetValveNameById(id, csBlkName, csDesName);
if(csDesName == _T(""))
return 0;
if(csDesName.Find(_T("球阀")) > -1){
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;
}
else if(csDesName.Find(_T("止回阀")) > -1){
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;
}
else if(csDesName.Find(_T("蝶阀")) > -1){
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;
}
else{ //闸阀 和 其它阀
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;
}
//计算节点
double DoCalcListNode(SSearchPipeList *pListLast, BOOL bReturn, int &idx, double nK)
{
double nRet(0);
AcDbObjectId id = NULL;
id = pListLast->m_ID;
pListLast->m_iNum = 0;
BOOL bIsCornerNode = FALSE; //本变量记录该交叉节点计算条件不成熟
if(pListLast->m_iType == 0){
OPENOBJ_BEGIN(id, AcDb::kForRead, CDbPipe, pPipe);
if(pPipe){
int iDn = (int)pPipe->GetDnDiameter();
double nRadius = GetPipeCalcDiameter(id)/1000; //本管计算半径
if(pListLast->m_lstNode.Length() == 1){
double nPipeQ(0);
SSearchPipeList *pList = pListLast->m_lstNode[0]; //得到后节点
double nStartPress = pList->m_nStartPress;
nPipeQ = pList->m_nPipeQ; //得到后管的管段流量
int iK = pList->m_iSpare;
BOOL bFlag = FALSE;
if(pListLast->m_pPrevious){
SSearchPipeList *pList2 = pListLast->m_pPrevious; //得到前节点
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("")){
bIsCornerNode = TRUE;//交叉点还有输入端没计算
}
}
if(iNumTmp > 1)
bFlag = TRUE; //此处为交叉计算节点
}
}
double nCalcK(0);
if(iK > 1)
nCalcK = 0.42 / 80 * iK;
else
nCalcK = nK;
double nQ = nCalcK * sqrt(nStartPress); // Q = K * SQRT(H1); 节点流量
if(pList->m_bNeedCale)
nQ += nPipeQ; // (需要计算的节点)管段流量 = 本节点流量 + 上管段流量
else
nQ = nPipeQ; // (不需要计算的节点)管段流量 = 上管段流量
double nV = 4 * nQ / (PI * nRadius * nRadius)/1000; //流速 4 × Q / (PI * DN * DN) m/s
double i = 0.00107 * nV * nV / (pow(nRadius, 1.3)); //水力陂降 /计算半径的1.3次方
// double nPipeLen = pPipe->Length()/1000;
double nPipeLen = pPipe->Length();
if(nRadius < 0.01){
nV = 0;
i = 0;
}
double dDang = pListLast->m_nDang;
pListLast->m_nLost = (nPipeLen + dDang) * i; //损失
pListLast->m_nStartPress = nStartPress; //起点压力
pListLast->m_nPipeQ = nQ; //管段流量 L/s
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){
if(!bFlag) //上一节点的起点压力
pListLast->m_pPrevious->m_nStartPress = nStartPress + pListLast->m_nLost;
if(bFlag){ //交叉计算节点
if(bReturn)
return nStartPress + pListLast->m_nLost; //返回交叉计算节点的压力
else
pListLast->m_pPrevious->m_nPipeQ += nQ; //管段流量 = 多段管线流量之和
}
else
pListLast->m_pPrevious->m_nPipeQ = nQ; //管段流量 L/s
}
if(bIsCornerNode && !bReturn)
return idx;
else if(bIsCornerNode && bReturn && bFlag)
return nStartPress + pListLast->m_nLost; //返回交叉计算节点的压力
}
}
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;
idx = DoSerialNumber(pNode, idx, IsMainNode); //标注节点编号
pNode = GetNextDimNode(pListAll, NULL); //得到下一支路起点节点
}
DoDimPipeSerialNumber(pListAll); //标注管段编号
}
//判断本节点是否包含指定名称的节点
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;
}
// 把喷淋系统中的1部分,COPY到一个新的数据结构中。
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;
pListTo->m_nPipeQ = 0; //以下5个需要重新计算
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];
// 如果已经计算过了,就无需再copy
if(pList->m_nStartPress > 0.01 && len > 1)
continue;
if(pListFrom->m_csName == csHeadName) //根节点,要判断一下分支
{//2008.10.31 只考虑1条分支
if(!HasNodeNameInList(pList, csTermName))
continue;
}
SSearchPipeList *pListNew = new SSearchPipeList();
pListNew->m_pPrevious = pListTo;
pListTo->m_lstNode.Append(pListNew);
CopySprinklerSubSys(pList, pListNew, csHeadName, csTermName);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//计算主模块 已知最不利喷头压力 求入口压力
void DoSprinklerCalc(SSearchPipeList *pListAll, double nPress, double nK, int iStart)
{
int idx = iStart;
SSearchPipeList *pNode = GetNextCalcNode(pListAll, NULL); //得到下一支路起点节点
idx = iStart;
while(pNode){
pNode->m_nStartPress = nPress;
if(nPress < 0.01)
break;
double nStartPress(0), nCalcPress(0);
BOOL bFlag = TRUE;
SSearchPipeList *pListCalc = HasReCalcNode(pNode, nStartPress, NULL);//是否有交叉计算节点?
if(pListCalc != NULL){
if(HasReReCalcNode(pNode)){ //太复杂了,超过3级,需要进行计算2
bFlag = FALSE;
SSearchPipeList *pListNew = new SSearchPipeList();
pListNew->m_pPrevious = NULL;
pListNew->m_nLength = 0;
// 1.把交叉计算节点往下都copy到一个新的结构中
CopySprinklerSubSys(pListCalc, pListNew, pListCalc->m_csName, pNode->m_csName);
// 2.对这个新系统进行“已知入口压力,反算末端压力”
int iStartTmp = _ttoi(pNode->m_csName);
double dRet = DoSprinklerCalc2(pListNew, nStartPress, nK, iStartTmp);
delete pListNew;
if(dRet > 0.1)//if(dRet > nPress) 有可能最不利点的位置选择不合适,本节点的起始压力就是小于最不利点压力
pNode->m_nStartPress = dRet;
}
}
else
bFlag = FALSE;
if(bFlag){ //有交叉计算节点
int iTmp(0);
nCalcPress = DoCalcListNode(pNode, TRUE, iTmp, nK); //返回交叉计算节点起点压力
double nPlus(nPress), nVal(0), nTmp(nPress);
double dTolerance(0.1); //迭代误差 2007-5-11 加强10以下的精度
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;
//以下循环, 不断进行反推, 根据交叉节点压力, 反算第二支路起点压力
while(fabs(nStartPress - nCalcPress) > dTolerance){
n++;
pNode->m_nStartPress = nPress + nPlus;
iTmp = 0;
nCalcPress = DoCalcListNode(pNode, TRUE, iTmp, nK);
nVal = nStartPress - nCalcPress;
//sr modify 对于仓库危险级,起点压力50,误差太大 2007-5-11 所以由固定10改为nPress
nTmp = nPress * pow(2.0, -n); //10、5、2.5、1.25、0.625、0.3125 ... ...
if(nVal < 0)
nPlus = nPlus - nTmp;
else
nPlus = nPlus + nTmp;
if(n > 20) //死循环, 主动退出
break;
}
}
idx = (int)DoCalcListNode(pNode, FALSE, idx, nK);
idx++;
CString csTmpName = pNode->m_csName;
pNode = GetNextCalcNode(pListAll, NULL); //对当前支路进行计算
if(pNode && csTmpName == pNode->m_csName)
break;
}
}
/*
//计算主模块 已知入口压力 求各喷头压力
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;
acedSetStatusBarProgressMeter(_T("喷淋计算中..."), 0, 20);
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;
nTmp = 10 * pow(2.0, -n); //10、5、2.5、1.25、0.625、0.3125 ... ...
if(nVal > 0)
nTmpPress = nTmpPress - nTmp;
else
nTmpPress = nTmpPress + nTmp;
if(n > 30) //死循环, 主动退出
break;
}
acedRestoreStatusBar();
}
*/
//计算主模块 已知入口压力 求各喷头压力
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;
csPrompt.Format(_T("%s节点,喷淋计算中..."), pListAll->m_csName);
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;
// 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 ... ...
if(nVal > 0)
nTmpPress = nTmpPress - nTmp;
else
nTmpPress = nTmpPress + nTmp;
if(n > 30) //死循环, 主动退出
break;
}
acedRestoreStatusBar();
return nTmpPress;
}
//得到计算范围,返回要计算的喷头
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"));
nRetCode = ads_getpoint(NULL, _T("\n选择第一点[选取闭合PLINE(S)/多选喷头(D)]"), pt1);
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);
if(GlobalFunc::SelectEntity(_T("\n请选择表示作用面积的闭合PLINE:<退出>"), entPoly, rbMask2) != RTNORM)
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{
if(GlobalFunc::SelectEntities(_T("\n请选择作用面积内的喷头:<退出>"), ss, rbMask) != RTNORM)
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;
int iRet = ads_grread(5, &itype, &pointbuf); //得到动态点pointbuf
ads_point_set(pointbuf.resval.rpoint, pt2); //ptend动态点,也就是引出支线的结束点
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;
csArea.Format(_T("%.2f 平方米"), nArea);
pdate->m_csDesName = csArea;
pdate->m_csRecord = _T("面积");
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);
}
//计算本节点往后有多少喷头
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;
}
}
//***************************************************************************************************
// 喷淋计算
//***************************************************************************************************
//主函数
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);
if(GlobalFunc::SelectEntity(_T("\n请选择喷淋干管<退出>"), entMainPipe, rbMaskPipe) != RTNORM) {
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)){
AfxMessageBox(_T("喷淋系统有回路!"));
delete pListAll;
return;
}
if(!GlobalFunc::CalcLstPipeLength(pListAll, NULL, ssAll)){
AfxMessageBox(_T("喷淋系统没有标注管径,请先执行命令[喷淋管径]或[管径标注]"));
delete pListAll;
return;
}
int iStart(1);
ads_getint(_T("\n请输入起点编号<1>"), &iStart);
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;
if(GlobalFunc::SelectEntity(_T("\n请选择最不利喷头<系统默认>:"), entLong, rbMask) == RTNORM && entLong.In(&ssAll))
{
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;
g_Option::instance().adsout << _T("图中红叉为系统最不利点, 请选择计算范围:");
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();
//计算源头应为节点,而不是管线. 以下计算管线2节点哪个是源头
CalcSprinkNum(pListAll); //所连喷头多的节点是源头
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();
//重新搜索系统
if(!GlobalFunc::SearchSprinkPipeSys(ent, NULL, pListAll, ssAll)){
AfxMessageBox(_T("喷淋系统有回路!"));
delete pListAll;
entBlk.Erase();
return;
}
pListAll->m_iType = 1;
GlobalFunc::CalcLstPipeLength(pListAll, NULL, ss);
}
if(ssAll.Length() < 3){
g_Option::instance().adsout << _T("\n喷淋系统可能存在断线! 内容太少");
entBlk.Erase();
delete pListAll;
return;
}
CSprinklerCalcDlg dlg;
if(!!entLong)//用户重新设置最不利点
{
AcDbObjectId id = NULL;
acdbGetObjectId(id, entLong);
pDisadvantage = dlg.GetNodeById(pListAll, id, NULL);
if(pDisadvantage == NULL)
{
g_Option::instance().adsout << _T("\n所选最不利喷头不在要计算的喷淋系列内,请检查!");
entBlk.Erase();
delete pListAll;
return;
}
iStart = DoSerialNumber(pDisadvantage, iStart, TRUE); //标注节点编号
DoSprinklerDimName(pListAll, iStart, FALSE);
}
else
DoSprinklerDimName(pListAll, iStart, TRUE);
actrTransactionManager->flushGraphics(); //acad 刷新
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;
}
//主函数
void SprinklerCalc2()
{
Entity entMainPipe;
RBList rbMask(RTDXF0, _T("ATS_EQUIPMENT"), 8, _T("*"), NULL);
RBList rbMaskPipe(RTDXF0, _T("ATS_PIPE"), 8, LAY_PIPE_SPRINKLE, NULL);
if(GlobalFunc::SelectEntity(_T("\n请选择喷淋干管<退出>"), entMainPipe, rbMaskPipe) != RTNORM) {
return;
}
SSearchPipeList *pListAll = new SSearchPipeList();
PickSet ssAll(SS_FREE);
ssAll += entMainPipe;
if(!GlobalFunc::SearchSprinkPipeSys(entMainPipe, NULL, pListAll, ssAll)){
AfxMessageBox(_T("喷淋系统有回路!"));
delete pListAll;
return;
}
if(!GlobalFunc::CalcLstPipeLength(pListAll, NULL, ssAll)){
AfxMessageBox(_T("喷淋系统没有标注管径,请先执行命令[喷淋管径]或[管径标注]"));
delete pListAll;
return;
}
int iStart(1);
ads_getint(_T("\n请输入起点编号<1>"), &iStart);
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();
g_Option::instance().adsout << _T("图中红叉为系统最不利点, 请选择计算范围:");
}
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();
//计算源头应为节点,而不是管线. 以下计算管线2节点哪个是源头
CalcSprinkNum(pListAll); //所连喷头多的节点是源头
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();
//重新搜索系统
if(!GlobalFunc::SearchSprinkPipeSys(ent, NULL, pListAll, ssAll)){
AfxMessageBox(_T("喷淋系统有回路!"));
delete pListAll;
entBlk.Erase();
return;
}
pListAll->m_iType = 1;
GlobalFunc::CalcLstPipeLength(pListAll, NULL, ss);
}
if(ssAll.Length() < 3){
g_Option::instance().adsout << _T("\n喷淋系统可能存在断线! 内容太少");
entBlk.Erase();
delete pListAll;
return;
}
DoSprinklerDimName(pListAll, iStart);
actrTransactionManager->flushGraphics(); //acad 刷新
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;
}
//***************************************************************************************************
// 最远路径
//***************************************************************************************************
//得到最不利节点
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);
if(GlobalFunc::SelectEntity(_T("\n请选择主干管(搜索指定干管所连最远路径):<指定范围搜索>"), entMain, rbMaskPipe) == RTNORM)
{
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);
if(GlobalFunc::SelectEntities(_T("\n请选择搜索范围:<整图搜索>"), ssAllDwg, rbMaskAllPipe) != RTNORM)
ssAllDwg.Get(_T("X"), NULL, NULL, rbMaskAllPipe);
int len = ssAllDwg.Length();
//仅仅要连1根直管的立管,排除扣弯
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();
g_Option::instance().adsout << XString(_T("\n共%d根立管!"), len);
}
PickSet ssLong(SS_FREE);
double nLongDist(0);
acedSetStatusBarProgressMeter(_T("计算中..."), 0, ss.Length());
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)){
AfxMessageBox(_T("喷淋系统有回路!"));
delete pListAll;
break;
}
if(!GlobalFunc::CalcLstPipeLength(pListAll, NULL, ssAll)){
AfxMessageBox(_T("喷淋系统没有标注管径,请先执行命令[喷淋管径]或[管径标注]"));
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();
g_Option::instance().adsout << XString(_T("\n立管距最不利点距离:%.2f!"), nLongDist);
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);
}*/