#include "stdafx.h" #include #include #include #include "UITools.h" #include "MakeDim.h" #include "AecDbEarthWorm.h" #include "coreTools.h" #include "FHBZSZDlg.h" #include "aecdbObjXDataMap.h" #include "JDZBDlg.h" void SortPoints(AcGePoint3dArray& points, AcDbCurve* pLine); ////////////////////////////////////////////////////////////////////////// namespace { #define XMAP_KEY _T("FIREDIM") using namespace MK_DIM; void split(LPCTSTR pszSrc, TCHAR sp, std::vector &vec) { if (!pszSrc) return; vec.clear(); CString src(pszSrc); CString oneString(_T("")); TCHAR ch; for (int i = 0; i < src.GetLength(); ++i) { ch = src[i]; if (ch == sp) { if (oneString.IsEmpty()) continue; else { vec.push_back(oneString); oneString.Empty(); } } else oneString += ch; } if (!oneString.IsEmpty()) vec.push_back(oneString); } template bool loadMkDimDll(T &proc, LPCSTR func, HINSTANCE &hmod) { if (!func) return false; #ifndef ZWCAD hmod = ::LoadLibrary(FilePath::GetArxDir() + _T("\\wfK.arx")); #else hmod = ::LoadLibrary(FilePath::GetArxDir() + _T("\\wfK.zrx")); #endif if (!hmod) return false; proc = (T)::GetProcAddress(hmod, func); if (!proc) return false; return true; } bool hasSameStake(std::vector &dims, LPCTSTR stake, NodeDim **pDim) { for (size_t i = 0; i < dims.size(); ++i) { if (dims[i].stake.CompareNoCase(stake) == 0) { *pDim = &dims[i]; return true; } } return false; } bool beNeedDim(const EFnctType &type, bool includeFire) { if (!includeFire) { if (type == kFirwWall) return false; } if ((type >= kDrainWell && type <= kHTOutLetHouse) || type == kProModel || type == kBDOutLetHouse ) //|| type == kSubEspJoint ) return true; return false; } bool IsFamilyNode(const EFnctType &type) { return type == kProModel; } CString getFamilyNodeName(const EWFnctNode &node) { return node.szNodeSpec; } void analyFamilyNode(const EWFnctNode &node, NodeDim &dim) { //电力舱:通风口;逃生口|综合舱:通风口;人员出入口 std::vector vec(0), vTypes(0); split(node.szNodeDefSpec, _T('|'), vec); //split(_T("电力舱:通风口;逃生口;集水井|综合舱:通风口;逃生口;集水井"), _T('|'), vec); if (vec.empty()) return; int idx(-1); CString str(_T("")); CString room(_T("")), types(_T("")); std::vector etypes(0); NodeDim::ENodeType ty(NodeDim::eNone); for (size_t i = 0; i < vec.size(); ++i) { etypes.clear(); str = vec[i]; str.TrimRight(); idx = str.Find(_T(':')); if (idx == -1) continue; room = str.Left(idx); types = str.Right(str.GetLength() - idx - 1); split(types, _T(';'), vTypes); if (vTypes.empty()) continue; for (size_t t = 0; t < vTypes.size(); ++t) { if ((ty = getNodeType(vTypes[t])) != NodeDim::eNone) etypes.push_back(ty); } if (dim.room_types.find(room) == dim.room_types.end()) dim.room_types.insert(std::make_pair(room, std::set())); dim.room_types[room].insert(etypes.begin(), etypes.end()); for (size_t t = 0; t < etypes.size(); t++) { NodeDim::ENodeType &type = etypes[t]; if (dim.type_rooms.find(type) == dim.type_rooms.end()) dim.type_rooms.insert(std::make_pair(type, std::set())); dim.type_rooms[type].insert(room); } } return; } void sortCenterPnt(AecDbEarthWorm *pEw, AcGePoint3dArray &arCenterPnts) { if (!pEw) return; AcGePoint2d pt2dS(pEw->StartPoint()), pt2dE(pEw->EndPoint()); AcDbLine line(AcGePoint3d(pt2dS.x, pt2dS.y, 0.), AcGePoint3d(pt2dE.x, pt2dE.y, 0.)); SortPoints(arCenterPnts, &line); } // 通过 数组dims 内的索引 idx,得到其前面的对应舱室的防火墙个数,并拼成字符串 void getDimTextForFireWall(const int &idx, const std::vector &dims, const NodeDim::ENodeType &type, std::vector &left, std::vector &right) { CString sLeft(_T("")), sRight(_T("")); int num(0); const NodeDim &curDim = dims[idx]; NodeDim::RoomTypes::const_iterator it = curDim.room_types.begin(); for (; it != curDim.room_types.end(); ++it) { // 向前搜索,寻找有type的此类舱室 sLeft.Empty(); sRight.Empty(); num = 0; const CString &sRoom = it->first; for (int i = 0; i < idx; ++i) { const NodeDim &dim = dims[i]; if (dim.room_types.find(sRoom) == dim.room_types.end()) continue; if (dim.type_rooms.find(type) == dim.type_rooms.end()) continue; ++num; } sLeft.Format(_T("%s防火分区%d"), sRoom, num + 1); sRight.Format(_T("%s防火分区%d"), sRoom, num + 2); left.push_back(sLeft); right.push_back(sRight); } } void drawArrow(const AcGeVector3d &v , const double &aW , const AcGePoint3d &ptS , AcDbObjectIdArray &ids) { AcDbObjectId id; AcGePoint3d ptE; double aL = aW * 100 / 33; AcGeVector3d vt(v); vt.normalize(); vt *= aL; ptE = ptS + vt; AcDbLine *p = new AcDbLine(ptS, ptE); CoreTools::AddToModelSpace(p, NULL, true, &id); ids.append(id); vt *= -1; double angle = atan(aW / (2 * aL)); vt.rotateBy(angle, AcGeVector3d::kZAxis); p = new AcDbLine(ptE, ptE + vt); CoreTools::AddToModelSpace(p, NULL, true, &id); ids.append(id); vt.rotateBy(2 * angle * -1, AcGeVector3d::kZAxis); p = new AcDbLine(ptE, ptE + vt); CoreTools::AddToModelSpace(p, NULL, true, &id); ids.append(id); } double drawFireDimText(const AcGeVector3d &vtEw , const AcGePoint3d &ptAlgn , const double &h , AcDbObjectId styleID , std::vector &vLeft , std::vector &vRight , const bool bDraw , AcDbObjectIdArray &ids) { CString left(_T("")), right(_T("")), room(_T("")); for (size_t i = 0; i < vLeft.size(); ++i) { left += vLeft[i]; left += _T("、"); right += vRight[i]; right += _T("、"); } left.TrimRight(_T("、")); right.TrimRight(_T("、")); AcGePoint3d ptLeft(ptAlgn), ptRight(ptAlgn); AcGeVector3d vt1(vtEw), vt2(vtEw); vt1.rotateBy(.5 * PI, AcGeVector3d::kZAxis); vt1.normalize(); vt2.normalize(); vt1 *= h; vt2 *= h; ptLeft += vt1; ptLeft -= vt2; ptRight += vt1; ptRight += vt2; double angle = AcGeVector3d::kXAxis.angleTo(vtEw, AcGeVector3d::kZAxis); // 此时文字为水平方向,取出长度 AcDbExtents ext, extAll; AcDbText *pLeft = new AcDbText; pLeft->setTextString(left); pLeft->setTextStyle(styleID); pLeft->setHeight(h); pLeft->setHorizontalMode(AcDb::kTextRight); pLeft->setAlignmentPoint(ptLeft); AcDbText *pRight = (AcDbText*)pLeft->clone(); pRight->setTextString(right); pRight->setHorizontalMode(AcDb::kTextLeft); pRight->setPosition(ptRight); pRight->getGeomExtents(ext); extAll.addExt(ext); pLeft->setRotation(angle); pRight->setRotation(angle); if (bDraw) { AcDbObjectId id; CoreTools::AddToModelSpace(pLeft, NULL, true, &id); ids.append(id); CoreTools::AddToModelSpace(pRight, NULL, true, &id); ids.append(id); } else { DELETE_PTR(pLeft); DELETE_PTR(pRight); } double len = extAll.maxPoint().x - extAll.minPoint().x; return len; } void drawFireDim(NodeDim &fd , const int &idx , const bool &bRight , const double &w , const double &h , const double &aW , const double &txtH , AcDbObjectId &idStyle , std::vector &vLeft , std::vector &vRight ) { AcDbObjectId id; AcDbObjectIdArray ids(0); AcGePoint3d ptHs(AcGePoint3d::kOrigin), ptHe(AcGePoint3d::kOrigin) , ptVs(AcGePoint3d::kOrigin), ptVe(AcGePoint3d::kOrigin) , ptCross(AcGePoint3d::kOrigin); AcGeVector3d vt(AcGeVector3d::kIdentity); // 画竖线 NodeDim &dim = fd; vt = dim.vt; vt.rotateBy(.5 * PI * (bRight ? -1 : 1), AcGeVector3d::kZAxis); vt.normalize(); vt *= h; ptVs = dim.pntIns; ptVe = ptVs + vt; AcDbLine *p = new AcDbLine(ptVs, ptVe); // 将竖线最后一个点(远离管廊)存入管廊的扩展数据内 // if (bRight) // { AecDbObjXDataMap xmap; xmap.Read(fd.idEw, XMAP_KEY); xmap.SetAt(fd.stake, ptVe); xmap.Write(fd.idEw, XMAP_KEY); // } CoreTools::AddToModelSpace(p, NULL, true, &id); ids.append(id); // 画横线 vt.normalize(); vt *= h * .75;// +vLeft.size() * txtH; ptCross = ptHs = ptHe = dim.pntIns; ptCross += vt; ptHs += vt; ptHe += vt; vt.normalize(); vt.rotateBy(.5 * PI, AcGeVector3d::kZAxis); vt *= w * .5; ptHs += vt; ptHe -= vt; p = new AcDbLine(ptHs, ptHe); CoreTools::AddToModelSpace(p, NULL, true, &id); ids.append(id); // 画两个箭头 drawArrow(vt, aW, ptHs, ids); drawArrow(-1 * vt, aW, ptHe, ids); // 绘制文字 drawFireDimText(dim.vt, ptCross, txtH, idStyle, vLeft, vRight, true, ids); CoreTools::generateGroup(NULL, ids); } template void _insert_(std::map> &mm, const T1 &key, const T2 &value) { if (mm.find(key) == mm.end()) mm.insert(std::make_pair(key, std::set())); mm[key].insert(value); } void mergeNode(const NodeDim &nd, NodeDim *pDim) { for (NodeDim::TypeRooms::const_iterator it = nd.type_rooms.begin(); it != nd.type_rooms.end(); ++it) { // 是否有相同的类型 NodeDim::TypeRooms::iterator preIt = pDim->type_rooms.find(it->first); if (preIt == pDim->type_rooms.end()) { // 不存在,直接插入 pDim->type_rooms.insert(*it); } else { // 存在,合并 preIt->second.insert(it->second.begin(), it->second.end()); } } for (NodeDim::RoomTypes::const_iterator it = nd.room_types.begin(); it != nd.room_types.end(); ++it) { // 是否有相同的舱室 NodeDim::RoomTypes::iterator preIt = pDim->room_types.find(it->first); if (preIt == pDim->room_types.end()) { // 不存在,直接插入 pDim->room_types.insert(*it); } else { // 存在,合并 preIt->second.insert(it->second.begin(), it->second.end()); } } } AcGePoint3d getInsertPt(const AcGePoint3d &ptOrg, const EWFnctNode &node, const AcGeVector3d &v) { AcGePoint3d pt(ptOrg); AcGeVector3d vt(v); vt.normalize(); double delta(GLTools::getNodeOffset(node)); pt += vt * delta; return pt; } void collectNodeInfoForDim(AcDbObjectId idEw , std::vector &nodeDims , bool includeFire , NodeDim *pNodeStart = NULL , NodeDim *pNodeEnd = NULL) { AcDbObjectIdArray arrIDs; GetConnectedWorms(idEw, arrIDs); if (arrIDs.isEmpty()) return; AcArray arLongParam(0); OPENOBJ_BEGIN(idEw, AcDb::kForRead, AecDbEarthWorm, pEw) { if (!pEw) return; pEw->CalEarthWork(arLongParam); } OPENOBJ_END() if (arLongParam.isEmpty()) return; std::map guids; for (int i = 0; i < arLongParam.length(); ++i) guids.insert(std::make_pair(arLongParam[i].szIDlock, arLongParam[i].dDistStakeLen)); AcGePoint3dArray arCenPoints; AcGeIntArray arEntTypes; CUIntArray arColors; AcArray arNodes; AcGePoint3dArray arNodePnts; AcGePoint3d pt(AcGePoint3d::kOrigin); CString nameNode(_T("")), nameRoom(_T("")); NodeDim::ENodeType nodeType; NodeDim nd; double dAllLengthForEW(.0); AcGePoint3d ptEwStart3d(AcGePoint3d::kOrigin); AcGePoint2d ptEwStart2d(AcGePoint2d::kOrigin); NodeDim nodS, nodE; EWSEGMENT seg; for (int i = 0; i < arrIDs.length(); ++i) { AcDbObjectId &id = arrIDs[i]; if (!i) nodS.idEw = id; if (i == arrIDs.length() - 1) nodE.idEw = id; arCenPoints.removeAll(); arEntTypes.removeAll(); arColors.RemoveAll(); OPENOBJ_BEGIN(id, AcDb::kForRead, AecDbEarthWorm, pEw) pEw->GetCenControlPoints(arCenPoints, arEntTypes, arColors, true); sortCenterPnt(pEw, arCenPoints); ptEwStart2d = pEw->StartPoint(); ptEwStart3d.x = ptEwStart2d.x; ptEwStart3d.y = ptEwStart2d.y; ptEwStart3d.z = pEw->StartElevation(); nd.vt = pEw->GetThisDir(); AcGePoint2d pt2d1(AcGePoint2d::kOrigin), pt2d2(AcGePoint2d::kOrigin); // 遍历每个中心点,然后调用GetFncNodeAt函数,得到节点信息 for (int iPnt = 0; iPnt < arCenPoints.length(); ++iPnt) { nd.type_rooms.clear(); nd.room_types.clear(); arNodes.removeAll(); AcGePoint3d &ptC = arCenPoints[iPnt]; pEw->GetFncNodeAt(ptC, .5, arNodes, arNodePnts); nd.idEw = pEw->objectId(); pt2d1.set(ptC.x, ptC.y); //nd.distFromHead = dAllLengthForEW + pt2d1.distanceTo(ptEwStart2d); nd.distFromHead = .0; std::map::iterator it(guids.end()); for (int iNd = 0; iNd < arNodes.length(); ++iNd) { EWFnctNode &node = arNodes[iNd]; it = guids.find(node.szLockId); if (it != guids.end()) nd.distFromHead = it->second; if (!beNeedDim(node.eFnType, includeFire)) continue; nd.pntIns = getInsertPt(ptC, node, nd.vt); if (!i && !iPnt/* && node.eFnType == kStackNode*/) { nodS.pntIns = ptC; nodS.stake = node.szStake; nodS.vt = pEw->GetThisDir(); } if (i == arrIDs.length() - 1 && iPnt == arCenPoints.length() - 1/* && node.eFnType == kStackNode*/) { nodE.pntIns = ptC; nodE.stake = node.szStake; nodE.vt = pEw->GetThisDir(); } nd.stake = node.szStake; nameRoom = pEw->GetRoomTypeByIdx(node.nRoomIndex); if (IsFamilyNode(node.eFnType)) { nameNode = getFamilyNodeName(node); nd.name = nameNode; analyFamilyNode(node, nd); } else { nodeType = getNodeType(node.eFnType); nameNode = getNodeName(nodeType); nd.name = nameNode; // 填充type_rooms结构 _insert_(nd.type_rooms, nodeType, nameRoom); // 填充room_types结构 _insert_(nd.room_types, nameRoom, nodeType); } } // 在这里,对参通风口节点做特殊处理 // 由于 插入通风口时,可以同时插入防火土墙和另一个通风口, // 所以在这里,对相同桩号进行融合 // 由于,桩号是排好序的,所以只需要和前一个桩号对比即可 NodeDim *preDim(NULL); if (hasSameStake(nodeDims, nd.stake, &preDim)) mergeNode(nd, preDim); else nodeDims.push_back(nd); } pEw->GetSegment(0, seg); dAllLengthForEW += seg.dDistLen; OPENOBJ_END() } if (pNodeStart) { *pNodeStart = nodS; pNodeStart->distFromHead = .0; } if (pNodeEnd) { *pNodeEnd = nodE; pNodeEnd->distFromHead = dAllLengthForEW; } } #define INS_TYPE(type)\ for (std::set::iterator it = room_##type.begin(); it != room_##type.end(); ++it)\ {\ _insert_(nodS.room_types, *it, NodeDim::##type);\ _insert_(nodS.type_rooms, NodeDim::##type, *it);\ _insert_(nodE.room_types, *it, NodeDim::##type);\ _insert_(nodE.type_rooms, NodeDim::##type, *it);\ } #define GET_TYPES(type)\ itTR = nd.type_rooms.find(NodeDim::##type);\ if (itTR != nd.type_rooms.end())\ room_##type.insert(itTR->second.begin(), itTR->second.end()) void collectNodeInfoForStatistic(AcDbObjectId idEw, std::vector &nodeDims, bool includeFire) { NodeDim nodS, nodE; collectNodeInfoForDim(idEw, nodeDims, includeFire, &nodS, &nodE); if (nodeDims.empty()) return; // 如果舱室存在 防火墙 或 通风口 ,则在此舱室头尾加上相应的节点 std::set room_eFireWall; std::set room_eVenDoghouse; std::set room_eEscapeHatch; std::set room_eDrainWell; std::set room_eDoghouse; std::set room_eOutlet; for (size_t i = 0; i < nodeDims.size(); ++i) { NodeDim &nd = nodeDims[i]; NodeDim::TypeRooms::iterator itTR; GET_TYPES(eFireWall); GET_TYPES(eVenDoghouse); GET_TYPES(eDrainWell); GET_TYPES(eDoghouse); GET_TYPES(eEscapeHatch); GET_TYPES(eOutlet); } std::sort(nodeDims.begin(), nodeDims.end(), NodeDim::_com_by_dist()); if (EQUAL(nodeDims.begin()->distFromHead, nodS.distFromHead)) // 存在首节点 nodS = *nodeDims.begin(); if (EQUAL(nodeDims.rbegin()->distFromHead, nodE.distFromHead)) // 存在尾节点 nodE = *nodeDims.rbegin(); INS_TYPE(eFireWall); INS_TYPE(eVenDoghouse); INS_TYPE(eDrainWell); INS_TYPE(eDoghouse); INS_TYPE(eEscapeHatch); INS_TYPE(eOutlet); if (!EQUAL(nodeDims.begin()->distFromHead, nodS.distFromHead)) // 不存在首节点 nodeDims.insert(nodeDims.begin(), nodS); else *(nodeDims.begin()) = nodS; if (!EQUAL(nodeDims.rbegin()->distFromHead, nodE.distFromHead)) // 不存在尾节点 nodeDims.push_back(nodE); else *(nodeDims.rbegin()) = nodE; } double getEwSectionWidth(AcDbObjectId id) { double w(.0); OPENOBJ_BEGIN(id, AcDb::kForRead, AecDbEarthWorm, pEw) if (!pEw) return w; AcGePoint2d pt = pEw->GetSize(); w = pt.x; OPENOBJ_END() return w; } CString mergeString(const NodeDim::RoomTypes &nds, LPCTSTR nodeName, LPCTSTR stake, const int *pIdx) { CString strFireWall = getNodeName(getNodeType(kFirwWall)); std::wstringstream ss; std::wstring wstr; ss << stake << _T(" ") << nodeName << _T(" "); for (NodeDim::RoomTypes::const_iterator it = nds.begin(); it != nds.end(); ++it) { ss << (LPCTSTR)it->first << _T(":"); for (std::set::const_iterator itType = it->second.begin(); itType != it->second.end(); ++itType) { if (*itType == NodeDim::eFireWall) continue; ss << (LPCTSTR)*itType << _T("、"); } wstr = ss.str().substr(0, ss.str().size() - 1); ss.str(_T("")); ss << wstr << _T(","); } wstr.clear(); wstr = ss.str().substr(0, ss.str().size() - 1); if (pIdx) { std::wstringstream _ss; _ss << *pIdx; return CString(wstr.c_str()) + _ss.str().c_str(); } return wstr.c_str(); } CString mergeString(const NodeDim::TypeRooms &nds, LPCTSTR nodeName, LPCTSTR stake, const int *pIdx) { std::wstringstream ss; std::wstring wstr; ss << stake << _T(" ") << nodeName << _T(" "); for (NodeDim::TypeRooms::const_iterator it = nds.begin(); it != nds.end(); ++it) { if (it->first == NodeDim::eFireWall) continue; for (std::set::const_iterator itRoom = it->second.begin(); itRoom != it->second.end(); ++itRoom) { ss << (LPCTSTR)*itRoom << _T("、"); } wstr = ss.str().substr(0, ss.str().size() - 1); ss.str(_T("")); ss << wstr; ss << (LPCTSTR)getNodeName(it->first) << _T(","); } wstr.clear(); wstr = ss.str().substr(0, ss.str().size() - 1); if (pIdx) { std::wstringstream _ss; _ss << *pIdx; return CString(wstr.c_str()) + _ss.str().c_str(); } return wstr.c_str(); } void drawNodeDimText(NodeDim &dim , const double h , const double len , AcDbObjectId style , bool bRight , AcDbObjectIdArray &ids , const int &idx , const bool &byCenterLine) // 相同舱室、功能的节点序号 { CString str(_T("")); if (!byCenterLine) { CString strL = StakeTools::generateStakeString(dim.distFromHead, _T("L")); str = mergeString(dim.type_rooms, dim.name, strL, &idx); } else str = mergeString(dim.type_rooms, dim.name, dim.stake, &idx); // 管廊宽 double w = getEwSectionWidth(dim.idEw); AcGePoint3d ptIns = dim.pntIns; AcGeVector3d vt = dim.vt; // 转90 vt.rotateBy(.5 * PI * (bRight ? -1 : 1), AcGeVector3d::kZAxis); vt.normalize(); vt *= .5 * w + len + h; AcDbLine *pLine = new AcDbLine(ptIns, ptIns + vt); vt.normalize(); vt *= .5 * w + len + 2*h; ptIns += vt; AcDbText *pTxt = new AcDbText(); pTxt->setTextString(str); pTxt->setVerticalMode(AcDb::kTextVertMid); if (bRight) pTxt->setHorizontalMode(AcDb::kTextRight); else pTxt->setHorizontalMode(AcDb::kTextLeft); pTxt->setTextStyle(style); double angle = AcGeVector3d::kXAxis.angleTo(vt * (bRight ? -1 : 1), AcGeVector3d::kZAxis); pTxt->setRotation(angle); pTxt->setHeight(h); AcDbObjectId id; // 如果当前桩号上有防火墙标注 AecDbObjXDataMap xmap; if (xmap.Read(dim.idEw, XMAP_KEY)) { AcGePoint3d pt; if (xmap.GetAt(dim.stake, pt)) { DELETE_PTR(pLine); vt.normalize(); vt *= h; pt += vt; ptIns = pt; } else { CoreTools::AddToModelSpace(pLine, NULL, true, &id); ids.append(id); } } else { CoreTools::AddToModelSpace(pLine, NULL, true, &id); ids.append(id); } pTxt->setAlignmentPoint(ptIns); CoreTools::AddToModelSpace(pTxt, NULL, true, &id); ids.append(id); } } #define func_process(sfunc, ...)\ AcDbEntity *pEnt(NULL);\ func_##sfunc proc(NULL);\ HINSTANCE hmod(NULL);\ if (loadMkDimDll(proc, #sfunc, hmod))\ {\ pEnt = proc(##__VA_ARGS__);\ ::FreeLibrary(hmod);\ }\ return pEnt namespace MK_DIM { NodeDim::ENodeType getNodeType(const EFnctType &type) { switch (type) { case kDrainWell: return NodeDim::eDrainWell; case kPipeDoghouse: case kCableDoghouse: case kHeatDoghouse: return NodeDim::eDoghouse; case kVenDoghouse: return NodeDim::eVenDoghouse; case kFirwWall: return NodeDim::eFireWall; case kEscapeHatch: return NodeDim::eEscapeHatch; case kSubEspJoint: return NodeDim::eEspJoint; case kFireOutlet: case kEWOutLethouse: case kHTOutLetHouse: case kBDOutLetHouse: return NodeDim::eOutlet; default: return NodeDim::eNone; } return NodeDim::eNone; } MK_DIM::NodeDim::ENodeType getNodeType(LPCTSTR psz) { CString str(psz); if (str == _T("集水井")) return NodeDim::eDrainWell; else if (str == _T("投料口")) return NodeDim::eDoghouse; else if (str == _T("通风口")) return NodeDim::eVenDoghouse; else if (str == _T("防火墙")) return NodeDim::eFireWall; else if (str == _T("逃生口")) return NodeDim::eEscapeHatch; else if (str == _T("管线分支口")) return NodeDim::eOutlet; else if (str == _T("变形缝")) return NodeDim::eEspJoint; else return NodeDim::eNone; return NodeDim::eNone; } CString getNodeName(const NodeDim::ENodeType &type) { switch (type) { case NodeDim::eDrainWell: return _T("集水井"); case NodeDim::eDoghouse: return _T("投料口"); case NodeDim::eVenDoghouse: return _T("通风口"); case NodeDim::eFireWall: return _T("防火墙"); case NodeDim::eEscapeHatch: return _T("逃生口"); case NodeDim::eOutlet: return _T("管线分支口"); case NodeDim::eEspJoint: return _T("变形缝"); default: return _T(""); } return _T(""); } void collectNodeInfo_Dim(AcDbObjectId idEw, std::vector &nodeDims, bool includeFire) { ::collectNodeInfoForDim(idEw, nodeDims, includeFire); } void collectNodeInfo_Statistic(AcDbObjectId idEw, std::vector &nodeDims, bool includeFire) { ::collectNodeInfoForStatistic(idEw, nodeDims, includeFire); } } namespace MK_DIM { void insertFireWallDim() { // 选择管廊 ads_point adsPnt; ads_name adsName; int nRes = acedEntSel(_T("\n请选择要标注的管廊。"), adsName, adsPnt); if (nRes != RTNORM) return; AcDbObjectId idEw(AcDbObjectId::kNull); acdbGetObjectId(idEw, adsName); if (!GLTools::isThisClass(idEw)) { acutPrintf(_T("\n请选择一段管廊。")); return; } // 绘制参数------------------------------- // 标注 宽,高,箭头宽,字高,文字比例 double w(50), h(50), aW(2), txtH(1); AcDbObjectId idStyle; // 弹对话框 CAcModuleResourceOverride myResources; CFHBZSZDlg dlg; if (dlg.DoModal() != IDOK) return; w = dlg.m_dW; h = dlg.m_dH; aW = dlg.m_dAW; txtH = dlg.m_dTxtH; idStyle = GLTools::getTextStyle(dlg.m_style); if (!idStyle.isValid()) idStyle = GLTools::getTextStyle(_T("standard")); // 收集参数------------------------------- std::vector nodeDims(0); collectNodeInfo_Dim(idEw, nodeDims, true); // 绘制 AcGePoint3d ptCross(AcGePoint3d::kOrigin), ptOldCross(AcGePoint3d::kOrigin); double maxW(.0), oldMaxW(.0); bool bRight(dlg.m_iSide == 0); // 是标在管廊方向右侧还是左侧 // 整理一下,把有防火墙的挑出来,之后再统一处理 std::vector dims(0); CString strName(_T("")); for (size_t i = 0; i < nodeDims.size(); ++i) { NodeDim &dim = nodeDims[i]; NodeDim::TypeRooms::iterator it = dim.type_rooms.find(NodeDim::eFireWall); if (it != dim.type_rooms.end()) dims.push_back(dim); } std::vector Left(0), Right(0); for (size_t i = 0; i < dims.size(); ++i) { Left.clear(); Right.clear(); getDimTextForFireWall(i, dims, NodeDim::eFireWall, Left, Right); NodeDim &dim = dims[i]; // 不是第一个 if (i) { AcDbObjectIdArray ids(0); // 临时,无用 NodeDim &pre_dim = dims[i - 1]; maxW = drawFireDimText(dim.vt, AcGePoint3d::kOrigin, txtH, idStyle, Left, Right, false, ids); oldMaxW = drawFireDimText(pre_dim.vt, AcGePoint3d::kOrigin, txtH, idStyle, Left, Right, false, ids); // if (dim.pntIns.distanceTo(pre_dim.pntIns) < __max(w, maxW + oldMaxW)) // bRight = !bRight; } drawFireDim(dim, i, bRight, w, h, aW, txtH, idStyle, Left, Right); } return; } void insertNodeDim() { // 选择管廊 ads_point adsPnt; ads_name adsName; int nRes = acedEntSel(_T("\n请选择要标注的管廊。"), adsName, adsPnt); if (nRes != RTNORM) return; AcDbObjectId idEw(AcDbObjectId::kNull); acdbGetObjectId(idEw, adsName); if (!GLTools::isThisClass(idEw)) { acutPrintf(_T("\n请选择一段管廊。")); return; } CAcModuleResourceOverride myResources; CJDZBDlg dlg; if (dlg.DoModal() != IDOK) return; double txtH(dlg.m_textH); double len(dlg.m_leaderL); CString textStyle(dlg.m_style); AcDbObjectId idStyle = GLTools::getTextStyle(textStyle); if (!idStyle.isValid()) idStyle = GLTools::getTextStyle(_T("standard")); // 收集参数------------------------------- std::vector nodeDims(0); collectNodeInfo_Dim(idEw, nodeDims, false); CString strFrieWall = getNodeName(getNodeType(kFirwWall)); CString strNodeName(_T("")), strOut(_T("")), _tmp(_T("")); std::wstringstream ss; std::wstring wstr; AcDbObjectIdArray ids(0); std::multiset mmapStrs; typedef std::multiset::iterator mmapIt; std::pair pr; size_t dif(0); for (size_t i = 0; i < nodeDims.size(); ++i) { _tmp = mergeString(nodeDims[i].type_rooms, nodeDims[i].name, _T("0"), NULL); mmapStrs.insert(_tmp); pr = std::equal_range(mmapStrs.begin(), mmapStrs.end(), _tmp); dif = std::distance(pr.first, pr.second); drawNodeDimText(nodeDims[i], txtH, len, idStyle, dlg.m_iSide == 0, ids, dif, dlg.m_bByCenterLine ? true : false); CoreTools::generateGroup(NULL, ids); ids.removeAll(); } } }