#include "StdAfx.h" #include "EWCheckerData.h" #include #include "aecdbearthworm.h" #include "KTCADUtilityEx.h" #include "BrowseForFolder.h" #include "stakeoper.h" #include #include "MakeDim.h" #include "UITools.h" #include "TJSZDlg.h" int DLLIMPEXP GetConnectedWorms(const AcDbObjectId& idHit, AcDbObjectIdArray& arIds); int DLLIMPEXP GetConnectedWorms(const AecDbEarthWorm* pEW, AcDbObjectIdArray& arIds); extern Acad::ErrorStatus AddToModelSpace(AcDbEntity* pEnt,AcDbDatabase* pDb,bool bClose); namespace { using namespace MK_DIM; using namespace GLStatistics; struct Statistics { CString sStake; // 桩号字符串 CString sRoom; // 舱室名称 CString sType; // 节点类型字符串 NodeDim::ENodeType eType; // 节点类型 double dDist; // 桩号距离 double dVenNum; // 换气次数,只有在 eType 为eVenDoghouse时有效 }; // 设置 TJConfig g_config; // 集水井 std::vector g_DrainWells; // 料口 std::vector g_Doghouses; // 通风口 std::vector g_VenDoghouses; // 防火墙 std::vector g_Firewalls; // 逃生口 std::vector g_EscapeHatchs; // 引出口 std::vector g_Outlets; // 舱室列表 std::vector g_Tanks; // 舱室长宽高信息 (舱名-(宽+高)) std::map> g_TankWHs; void initGlobalData(std::vector &nodes) { g_DrainWells.clear(); g_Doghouses.clear(); g_VenDoghouses.clear(); g_Firewalls.clear(); g_EscapeHatchs.clear(); g_Outlets.clear(); Statistics stat; for (size_t i = 0; i < nodes.size(); ++i) { NodeDim &nd = nodes[i]; //if (!GLTools::analyStakeString(nd.stake, stat.dDist)) continue; stat.sStake = nd.stake; stat.dDist = nd.distFromHead; NodeDim::RoomTypes::const_iterator itRT = nd.room_types.begin(); for (; itRT != nd.room_types.end(); ++itRT) { if (itRT->second.empty()) continue; stat.sRoom = itRT->first; std::set::const_iterator itType = itRT->second.begin(); for (; itType != itRT->second.end(); ++itType) { stat.eType = *itType; stat.sType = getNodeName(*itType); switch (*itType) { case NodeDim::eDrainWell: g_DrainWells.push_back(stat); break; case NodeDim::eFireWall: g_Firewalls.push_back(stat); break; case NodeDim::eVenDoghouse: g_VenDoghouses.push_back(stat); break; case NodeDim::eEscapeHatch: g_EscapeHatchs.push_back(stat); break; case NodeDim::eDoghouse: g_Doghouses.push_back(stat); break; case NodeDim::eOutlet: g_Outlets.push_back(stat); break; default: break; } } } } } } namespace GLStatistics { using namespace MK_DIM; bool init(bool includeFire) { // 选择管廊 ads_point adsPnt; ads_name adsName; int nRes = acedEntSel(_T("\n请选择要校核的管廊。"), adsName, adsPnt); if (nRes != RTNORM) return false; AcDbObjectId idEw(AcDbObjectId::kNull); acdbGetObjectId(idEw, adsName); ERoom room; double w(.0), h(.0); OPENOBJ_BEGIN(idEw, AcDb::kForRead, AecDbEarthWorm, pEw) if (!pEw) { acutPrintf(_T("\n请选择一段管廊。")); return false; } g_Tanks.clear(); g_TankWHs.clear(); pEw->GetRoomCount(); for (int i = 0; i < pEw->GetRoomCount(); ++i) { if (pEw->GetRoom(i, room)) { w = room.ptGe[0].distanceTo(room.ptGe[1]); h = room.ptGe[1].distanceTo(room.ptGe[2]); } g_Tanks.push_back(pEw->GetRoomTypeByIdx(i)); g_TankWHs.insert(std::make_pair(*g_Tanks.rbegin(), std::make_pair(w, h))); } OPENOBJ_END() std::vector nodes(0); collectNodeInfo_Statistic(idEw, nodes, includeFire); if (nodes.empty()) return false; initGlobalData(nodes); return true; } std::vector& getGlobalData(const MK_DIM::NodeDim::ENodeType &type) { switch (type) { case MK_DIM::NodeDim::eFireWall: return g_Firewalls; case MK_DIM::NodeDim::eDoghouse: return g_Doghouses; case MK_DIM::NodeDim::eVenDoghouse: return g_VenDoghouses; case MK_DIM::NodeDim::eOutlet: return g_Outlets; case MK_DIM::NodeDim::eDrainWell: return g_DrainWells; case MK_DIM::NodeDim::eEscapeHatch: return g_EscapeHatchs; default: return g_Firewalls; } return g_Firewalls; } void statisticEarthworm(const MK_DIM::NodeDim::ENodeType &type) { if (!init(type == MK_DIM::NodeDim::eFireWall)) return; // 弹对话框 CAcModuleResourceOverride myResources; CTJSZDlg dlg(type, g_Tanks); if (dlg.DoModal() != IDOK) return; readConfig(g_config); if (g_config.empty()) return; std::vector &ss = getGlobalData(type); GLReport::CEWGLReport report; GLReport::CEWTank tank; GLReport::EWNodeData data; for (size_t tk = 0; tk < g_Tanks.size(); ++tk) { tank.clear(); CString &name(g_Tanks[tk]); tank.setName(name); tank.setWidth(g_TankWHs[name].first); tank.setHeight(g_TankWHs[name].second); tank.setOption(g_config[name]); for (size_t i = 0; i < ss.size(); ++i) { Statistics &st(ss[i]); if (st.sRoom == name) { data.m_stake = st.sStake; data.m_dDistance = st.dDist; tank.appendData(type, data); } } tank.calcData(type); report.appendTank(tank); } report.outputCADTable(type); return; } void statisticDrainWell() { statisticEarthworm(MK_DIM::NodeDim::eDrainWell); } void statisticDoghouse() { statisticEarthworm(MK_DIM::NodeDim::eDoghouse); } void statisticVenDoghouse() { statisticEarthworm(MK_DIM::NodeDim::eVenDoghouse); } void statisticFireWall() { statisticEarthworm(MK_DIM::NodeDim::eFireWall); } void statisticEscapeHatch() { statisticEarthworm(MK_DIM::NodeDim::eEscapeHatch); } void statisticOutlet() { statisticEarthworm(MK_DIM::NodeDim::eOutlet); } CString getConfigFilePath() { CString path = FilePath::getProgramDataFolder(); path += _T("\\tjsz.dat"); return path; } void readConfig(TJConfig &config) { config.clear(); CString str(_T("")); CString path = getConfigFilePath(); if (_taccess(path, 0x0) != 0x0) return; std::vector sections(0); INITools::getSections(path, sections); std::map mapV; for (size_t i = 0; i < sections.size(); ++i) { const CString &sec(sections[i]); INITools::getSectionContent(path, sec, mapV); if (mapV.empty()) continue; config.insert(std::make_pair(sec, std::map())); for (std::map::const_iterator it = mapV.begin(); it != mapV.end(); ++it) { config[sec].insert(std::make_pair(it->first, _ttof(it->second))); } } return; } } namespace { AcDbObjectId getTableStyleID(LPCTSTR psz) { AcDbObjectId idTblStyle(AcDbObjectId::kNull); if (!psz) return idTblStyle; AcDbDictionary *pDict(NULL); acdbHostApplicationServices()->workingDatabase()->getTableStyleDictionary(pDict, AcDb::kForRead); pDict->getAt(psz, idTblStyle); pDict->close(); return idTblStyle; } AcDbObjectId getTextStyleID(LPCTSTR psz) { AcDbObjectId idTxtStyle(AcDbObjectId::kNull); if (!psz) return idTxtStyle; AcDbTextStyleTable *pTextStyle(NULL); acdbHostApplicationServices()->workingDatabase()->getTextStyleTable(pTextStyle, AcDb::kForRead); pTextStyle->getAt(psz, idTxtStyle); pTextStyle->close(); return idTxtStyle; } } namespace GLReport { AcDbTable* CEWGLReport::outputDataCAD(const MK_DIM::NodeDim::ENodeType &type) { AcDbTable *pTbl = new AcDbTable; AcDbObjectId idTblStyle(getTableStyleID(_T("Standard"))); if (!idTblStyle.isValid()) return NULL; pTbl->setTableStyle(idTblStyle); AcDbObjectId idTextStyle(getTextStyleID(_T("Standard"))); if (!idTextStyle.isValid()) return NULL; pTbl->setTextStyle(idTextStyle); // 总列数 (舱室名称|桩号范围|长度) int cols((int)m_tanks.size() * 2 + 1); // 设置列数 pTbl->setNumColumns(cols); pTbl->setNumRows(3); // 合并第0行 pTbl->mergeCells(0, 0, 0, cols - 1); // 为第0行打上文字 pTbl->setTextString(0, 0, MK_DIM::getNodeName(type) + _T("统计")); // 合并第1行 for (int i = 0; i < m_tanks.size(); ++i) { pTbl->mergeCells(1, 1, i * 2 + 1, i * 2 + 2); pTbl->setTextString(1, i * 2 + 1, m_tanks[i].getName()); } pTbl->setTextString(2, 0, _T("序号")); for (int i = 0; i < m_tanks.size(); ++i) { pTbl->setTextString(2, i * 2 + 1, _T("桩号范围")); pTbl->setTextString(2, i * 2 + 2, _T("长度(m)")); } pTbl->setColumnWidth(30); const EWNodeDatas *pDatas(NULL); EWNodeDatas datas(0); AcCmColor clr; clr.setColorIndex(1); // 总行数 int rows(3); int col1(0), col2(0); for (size_t tk = 0; tk < m_tanks.size(); ++tk) { pDatas = NULL; const CEWTank &tank = m_tanks[tk]; std::map &conf = g_config[tank.getName()]; switch (type) { case MK_DIM::NodeDim::eFireWall: pDatas = &tank.getFireZoneData(); break; case MK_DIM::NodeDim::eEscapeHatch: pDatas = &tank.getEscapeData(); break; case MK_DIM::NodeDim::eDoghouse: pDatas = &tank.getDoghouseData(); break; case MK_DIM::NodeDim::eOutlet: pDatas = &tank.getOutletData(); break; case MK_DIM::NodeDim::eDrainWell: pDatas = &tank.getWellData(); break; default: break; } col1 = (int)tk * 2 + 1; col2 = (int)tk * 2 + 2; rows = 3; if (pDatas) { for (size_t i = 0; i < pDatas->size(); ++i) { const EWNodeData &da = pDatas->at(i); if (pTbl->numRows() <= rows) pTbl->insertRows(rows, 5); pTbl->setTextString(rows, col1, da.m_stake.c_str()); pTbl->setTextString(rows, col2, _convert_(da.m_dDistance).c_str()); if (da.m_dDistance > conf[MK_DIM::getNodeName(type)]) { pTbl->setContentColor(rows, col1, clr); pTbl->setContentColor(rows, col2, clr); } ++rows; } } } CString str(_T("")); for (size_t i= 3; i < pTbl->numRows(); ++i) { str.Format(_T("%d"), i - 2); pTbl->setTextString((int)i, 0, str); } int tblHeight(3); pTbl->setTextHeight(tblHeight); pTbl->setRowHeight(5); pTbl->generateLayout(); return pTbl; } AcDbTable* CEWGLReport::outputVentilateCAD() { CString str(_T("")); AcDbTable *pTbl = new AcDbTable; AcDbObjectId idTblStyle(getTableStyleID(_T("Standard"))); if (!idTblStyle.isValid()) return NULL; pTbl->setTableStyle(idTblStyle); AcDbObjectId idTextStyle(getTextStyleID(_T("Standard"))); if (!idTextStyle.isValid()) return NULL; pTbl->setTextStyle(idTextStyle); // 总列数 (舱室名称|桩号范围|长度) int cols((int)m_tanks.size() * 5 + 1); // 设置列数 pTbl->setNumColumns(cols); pTbl->setNumRows(3); // 合并第0行 pTbl->mergeCells(0, 0, 0, cols - 1); // 为第0行打上文字 pTbl->setTextString(0, 0, _T("通风计算")); // 合并第1行 for (int i = 0; i < m_tanks.size(); ++i) { str.Format(_T("%s(%.1fmX%.1fm)"), m_tanks[i].getName(), m_tanks[i].getLength(), m_tanks[i].getWidth()); pTbl->mergeCells(1, 1, i * 5 + 1, i * 5 + 5); pTbl->setTextString(1, i * 5 + 1, str); } pTbl->setTextString(2, 0, _T("序号")); for (int i = 0; i < m_tanks.size(); ++i) { pTbl->setTextString(2, i * 5 + 1, _T("桩号范围")); pTbl->setTextString(2, i * 5 + 2, _T("长度(m)")); pTbl->setTextString(2, i * 5 + 3, _T("体积(m3)")); pTbl->setTextString(2, i * 5 + 4, _T("通风次数(次/h)")); pTbl->setTextString(2, i * 5 + 5, _T("通风量(m3/h)")); } pTbl->setColumnWidth(30); // 总行数 AcCmColor clr; clr.setColorIndex(1); int rows(3); int col1(0), col2(0), col3(0), col4(0), col5(0); for (size_t tk = 0; tk < m_tanks.size(); ++tk) { const CEWTank &tank = m_tanks[tk]; std::map &conf = g_config[tank.getName()]; const EWVentilates &datas(tank.getVentilateData()); col1 = (int)tk * 5 + 1; col2 = (int)tk * 5 + 2; col3 = (int)tk * 5 + 3; col4 = (int)tk * 5 + 4; col5 = (int)tk * 5 + 5; rows = 3; for (size_t i = 0; i < datas.size(); ++i) { const EWVentilate &da = datas[i]; if (pTbl->numRows() <= rows) pTbl->insertRows(rows, 5); pTbl->setTextString(rows, col1, da.m_stake.c_str()); pTbl->setTextString(rows, col2, _convert_(da.m_dDistance).c_str()); if (da.m_dDistance > conf[MK_DIM::getNodeName(MK_DIM::NodeDim::eVenDoghouse)]) { pTbl->setContentColor(rows, col2, clr); } pTbl->setTextString(rows, col3, _convert_(da.m_dVolum).c_str()); pTbl->setTextString(rows, col4, _convert_(da.m_dNumVentilate).c_str()); pTbl->setTextString(rows, col5, _convert_(da.m_dAirHr).c_str()); ++rows; } } for (size_t i = 3; i < pTbl->numRows(); ++i) { str.Format(_T("%d"), i - 2); pTbl->setTextString((int)i, 0, str); } int tblHeight(3); pTbl->setTextHeight(tblHeight); pTbl->setRowHeight(5); pTbl->generateLayout(); return pTbl; } void CEWGLReport::outputCADTable(const MK_DIM::NodeDim::ENodeType &type) { AcDbTable *pTbl(NULL); if (type == MK_DIM::NodeDim::eVenDoghouse) pTbl = outputVentilateCAD(); else pTbl = outputDataCAD(type); if (!pTbl) return; AcGeVector3d vtx = acdbCurDwg()->ucsxdir(); double angle = AcGeVector3d::kXAxis.angleTo(vtx, AcGeVector3d::kZAxis); pTbl->setDirection(vtx); pTbl->recomputeTableBlock(true); pTbl->generateLayout(); TableJig jig(pTbl, _T("\n请确定表格位置<退出>: ")); if (jig.doIt() != AcEdJig::kNormal) { DELETE_PTR(pTbl); return; } AddToModelSpace(pTbl, NULL, true); } ////////////////////////////////////////////////////////////////////////// void CEWTank::setOption(const std::map &op) { m_options.insert(op.begin(), op.end()); } void CEWTank::appendData(const MK_DIM::NodeDim::ENodeType &type, const EWNodeData &data) { switch (type) { case MK_DIM::NodeDim::eFireWall: m_fireWall.push_back(data); break; case MK_DIM::NodeDim::eEscapeHatch: m_escape.push_back(data); break; case MK_DIM::NodeDim::eVenDoghouse: m_Ventilate.push_back(data); break; case MK_DIM::NodeDim::eDoghouse: m_doghouse.push_back(data); break; case MK_DIM::NodeDim::eDrainWell: m_wells.push_back(data); break; case MK_DIM::NodeDim::eOutlet: m_outlets.push_back(data); break; default: break; } } void CEWTank::calcData(const MK_DIM::NodeDim::ENodeType &type) { switch (type) { case MK_DIM::NodeDim::eFireWall: calcFireZone(); break; case MK_DIM::NodeDim::eEscapeHatch: calcEscape(); break; case MK_DIM::NodeDim::eVenDoghouse: calcVentilateZone(); calcVentilate(); break; case MK_DIM::NodeDim::eDoghouse: calcDoghouse(); break; case MK_DIM::NodeDim::eDrainWell: calcWell(); break; case MK_DIM::NodeDim::eOutlet: calcOutlet(); break; default: break; } } void CEWTank::calcFireZone() { calc(m_calcFireZone, m_fireWall); } void CEWTank::calcVentilateZone() { EWVentilate v; for (size_t i = 0; i < m_Ventilate.size(); ++i) { if (i + 1 < m_Ventilate.size()) { const EWNodeData d1 = m_Ventilate[i]; const EWNodeData d2 = m_Ventilate[i + 1]; v.m_stake = d1.m_dDistance > d2.m_dDistance ? d2.m_stake + _T("~") + d1.m_stake : d1.m_stake + _T("~") + d2.m_stake; v.m_dDistance = abs(d1.m_dDistance - d2.m_dDistance); v.m_dNumVentilate = m_options[VEN_NUM]; v.m_dArea = getSectionArea(); m_calcVentilate.push_back(v); } } } void CEWTank::calcVentilate() { // 进行本次计算前,应该先计算出通风分区 calcVentilateZone() for (size_t i = 0; i < m_calcVentilate.size(); ++i) { EWVentilate &v = m_calcVentilate[i]; v.m_dVolum = v.m_dDistance * v.m_dArea; v.m_dAirHr = v.m_dVolum * v.m_dNumVentilate; } } void CEWTank::calcEscape() { calc(m_calcEscape, m_escape); } void CEWTank::calcDoghouse() { calc(m_calcDoghouse, m_doghouse); } void CEWTank::calcWell() { calc(m_calcWell, m_wells); } void CEWTank::calcOutlet() { calc(m_calcOutlet, m_outlets); } void CEWTank::calc(EWNodeDatas &out, const EWNodeDatas &data) { out.clear(); for (size_t i = 0; i < data.size(); ++i) { if (i + 1 < data.size()) { const EWNodeData &d1 = data[i]; const EWNodeData &d2 = data[i + 1]; out.push_back( EWNodeData( d1.m_dDistance > d2.m_dDistance ? d2.m_stake + _T("~") + d1.m_stake : d1.m_stake + _T("~") + d2.m_stake , abs(d1.m_dDistance - d2.m_dDistance)) ); } } } void SetRoomTypeByIdx() { return; } ////////////////////////////////////////////////////////////////////////// AcEdJig::DragStatus TableJig::doIt() { setDispPrompt(m_Prompt); AcEdJig::DragStatus st = drag(); return st; } AcEdJig::DragStatus TableJig::sampler() { AcEdJig::DragStatus st = acquirePoint(m_ptPos); return st; } Adesk::Boolean TableJig::update() { if (!m_pTbl) return Adesk::kFalse; m_pTbl->setPosition(m_ptPos); m_pTbl->generateLayout(); return Adesk::kTrue; } }