Files

1004 lines
26 KiB
C++
Raw Permalink Normal View History

2026-10-04 00:04:20 +08:00
#include "stdafx.h"
2026-09-28 15:28:50 +08:00
#include <set>
#include <sstream>
#include <algorithm>
#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<CString> &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 <class T>
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<NodeDim> &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)
{
2026-10-04 00:04:20 +08:00
//电力舱:通风口;逃生口|综合舱:通风口;人员出入口
2026-09-28 15:28:50 +08:00
std::vector<CString> vec(0), vTypes(0);
split(node.szNodeDefSpec, _T('|'), vec);
2026-10-04 00:04:20 +08:00
//split(_T("电力舱:通风口;逃生口;集水井|综合舱:通风口;逃生口;集水井"), _T('|'), vec);
2026-09-28 15:28:50 +08:00
if (vec.empty()) return;
int idx(-1);
CString str(_T(""));
CString room(_T("")), types(_T(""));
std::vector<NodeDim::ENodeType> 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<NodeDim::ENodeType>()));
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<CString>()));
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);
}
2026-10-04 00:04:20 +08:00
// 通过 数组dims 内的索引 idx,得到其前面的对应舱室的防火墙个数,并拼成字符串
2026-09-28 15:28:50 +08:00
void getDimTextForFireWall(const int &idx, const std::vector<NodeDim> &dims, const NodeDim::ENodeType &type, std::vector<CString> &left, std::vector<CString> &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)
2026-10-04 00:04:20 +08:00
{ // 向前搜索,寻找有type的此类舱室
2026-09-28 15:28:50 +08:00
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;
}
2026-10-04 00:04:20 +08:00
sLeft.Format(_T("%s防火分区%d"), sRoom, num + 1);
sRight.Format(_T("%s防火分区%d"), sRoom, num + 2);
2026-09-28 15:28:50 +08:00
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<CString> &vLeft
, std::vector<CString> &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];
2026-10-04 00:04:20 +08:00
left += _T("、");
2026-09-28 15:28:50 +08:00
right += vRight[i];
2026-10-04 00:04:20 +08:00
right += _T("、");
2026-09-28 15:28:50 +08:00
}
2026-10-04 00:04:20 +08:00
left.TrimRight(_T("、"));
right.TrimRight(_T("、"));
2026-09-28 15:28:50 +08:00
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);
2026-10-04 00:04:20 +08:00
// 此时文字为水平方向,取出长度
2026-09-28 15:28:50 +08:00
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<CString> &vLeft
, std::vector<CString> &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);
2026-10-04 00:04:20 +08:00
// 画竖线
2026-09-28 15:28:50 +08:00
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);
2026-10-04 00:04:20 +08:00
// 将竖线最后一个点(远离管廊)存入管廊的扩展数据内
2026-09-28 15:28:50 +08:00
// 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);
2026-10-04 00:04:20 +08:00
// 画横线
2026-09-28 15:28:50 +08:00
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);
2026-10-04 00:04:20 +08:00
// 画两个箭头
2026-09-28 15:28:50 +08:00
drawArrow(vt, aW, ptHs, ids);
drawArrow(-1 * vt, aW, ptHe, ids);
2026-10-04 00:04:20 +08:00
// 绘制文字
2026-09-28 15:28:50 +08:00
drawFireDimText(dim.vt, ptCross, txtH, idStyle, vLeft, vRight, true, ids);
CoreTools::generateGroup(NULL, ids);
}
template <class T1, class T2>
void _insert_(std::map<T1, std::set<T2>> &mm, const T1 &key, const T2 &value)
{
if (mm.find(key) == mm.end())
mm.insert(std::make_pair(key, std::set<T2>()));
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)
{
2026-10-04 00:04:20 +08:00
// 是否有相同的类型
2026-09-28 15:28:50 +08:00
NodeDim::TypeRooms::iterator preIt = pDim->type_rooms.find(it->first);
if (preIt == pDim->type_rooms.end())
2026-10-04 00:04:20 +08:00
{ // 不存在,直接插入
2026-09-28 15:28:50 +08:00
pDim->type_rooms.insert(*it);
}
else
2026-10-04 00:04:20 +08:00
{ // 存在,合并
2026-09-28 15:28:50 +08:00
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)
{
2026-10-04 00:04:20 +08:00
// 是否有相同的舱室
2026-09-28 15:28:50 +08:00
NodeDim::RoomTypes::iterator preIt = pDim->room_types.find(it->first);
if (preIt == pDim->room_types.end())
2026-10-04 00:04:20 +08:00
{ // 不存在,直接插入
2026-09-28 15:28:50 +08:00
pDim->room_types.insert(*it);
}
else
2026-10-04 00:04:20 +08:00
{ // 存在,合并
2026-09-28 15:28:50 +08:00
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<NodeDim> &nodeDims
, bool includeFire
, NodeDim *pNodeStart = NULL
, NodeDim *pNodeEnd = NULL)
{
AcDbObjectIdArray arrIDs;
GetConnectedWorms(idEw, arrIDs);
if (arrIDs.isEmpty()) return;
AcArray<ELongParam> arLongParam(0);
OPENOBJ_BEGIN(idEw, AcDb::kForRead, AecDbEarthWorm, pEw)
{
if (!pEw) return;
pEw->CalEarthWork(arLongParam);
}
OPENOBJ_END()
if (arLongParam.isEmpty()) return;
std::map<CString, double> 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<EWFnctNode> 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);
2026-10-04 00:04:20 +08:00
// 遍历每个中心点,然后调用GetFncNodeAt函数,得到节点信息
2026-09-28 15:28:50 +08:00
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<CString, double>::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;
2026-10-04 00:04:20 +08:00
// 填充type_rooms结构
2026-09-28 15:28:50 +08:00
_insert_<NodeDim::ENodeType, CString>(nd.type_rooms, nodeType, nameRoom);
2026-10-04 00:04:20 +08:00
// 填充room_types结构
2026-09-28 15:28:50 +08:00
_insert_<CString, NodeDim::ENodeType>(nd.room_types, nameRoom, nodeType);
}
}
2026-10-04 00:04:20 +08:00
// 在这里,对参通风口节点做特殊处理
// 由于 插入通风口时,可以同时插入防火土墙和另一个通风口,
// 所以在这里,对相同桩号进行融合
// 由于,桩号是排好序的,所以只需要和前一个桩号对比即可
2026-09-28 15:28:50 +08:00
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<CString>::iterator it = room_##type.begin(); it != room_##type.end(); ++it)\
{\
_insert_<CString, NodeDim::ENodeType>(nodS.room_types, *it, NodeDim::##type);\
_insert_<NodeDim::ENodeType, CString>(nodS.type_rooms, NodeDim::##type, *it);\
_insert_<CString, NodeDim::ENodeType>(nodE.room_types, *it, NodeDim::##type);\
_insert_<NodeDim::ENodeType, CString>(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<NodeDim> &nodeDims, bool includeFire)
{
NodeDim nodS, nodE;
collectNodeInfoForDim(idEw, nodeDims, includeFire, &nodS, &nodE);
if (nodeDims.empty()) return;
2026-10-04 00:04:20 +08:00
// 如果舱室存在 防火墙 或 通风口 ,则在此舱室头尾加上相应的节点
2026-09-28 15:28:50 +08:00
std::set<CString> room_eFireWall;
std::set<CString> room_eVenDoghouse;
std::set<CString> room_eEscapeHatch;
std::set<CString> room_eDrainWell;
std::set<CString> room_eDoghouse;
std::set<CString> 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());
2026-10-04 00:04:20 +08:00
if (EQUAL(nodeDims.begin()->distFromHead, nodS.distFromHead)) // 存在首节点
2026-09-28 15:28:50 +08:00
nodS = *nodeDims.begin();
2026-10-04 00:04:20 +08:00
if (EQUAL(nodeDims.rbegin()->distFromHead, nodE.distFromHead)) // 存在尾节点
2026-09-28 15:28:50 +08:00
nodE = *nodeDims.rbegin();
INS_TYPE(eFireWall);
INS_TYPE(eVenDoghouse);
INS_TYPE(eDrainWell);
INS_TYPE(eDoghouse);
INS_TYPE(eEscapeHatch);
INS_TYPE(eOutlet);
2026-10-04 00:04:20 +08:00
if (!EQUAL(nodeDims.begin()->distFromHead, nodS.distFromHead)) // 不存在首节点
2026-09-28 15:28:50 +08:00
nodeDims.insert(nodeDims.begin(), nodS);
else
*(nodeDims.begin()) = nodS;
2026-10-04 00:04:20 +08:00
if (!EQUAL(nodeDims.rbegin()->distFromHead, nodE.distFromHead)) // 不存在尾节点
2026-09-28 15:28:50 +08:00
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)
{
2026-10-04 00:04:20 +08:00
ss << (LPCTSTR)it->first << _T(":");
2026-09-28 15:28:50 +08:00
for (std::set<NodeDim::ENodeType>::const_iterator itType = it->second.begin(); itType != it->second.end(); ++itType)
{
if (*itType == NodeDim::eFireWall) continue;
2026-10-04 00:04:20 +08:00
ss << (LPCTSTR)*itType << _T("、");
2026-09-28 15:28:50 +08:00
}
wstr = ss.str().substr(0, ss.str().size() - 1);
ss.str(_T(""));
2026-10-04 00:04:20 +08:00
ss << wstr << _T(",");
2026-09-28 15:28:50 +08:00
}
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<CString>::const_iterator itRoom = it->second.begin(); itRoom != it->second.end(); ++itRoom)
{
2026-10-04 00:04:20 +08:00
ss << (LPCTSTR)*itRoom << _T("、");
2026-09-28 15:28:50 +08:00
}
wstr = ss.str().substr(0, ss.str().size() - 1);
ss.str(_T(""));
ss << wstr;
2026-10-04 00:04:20 +08:00
ss << (LPCTSTR)getNodeName(it->first) << _T(",");
2026-09-28 15:28:50 +08:00
}
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
2026-10-04 00:04:20 +08:00
, const bool &byCenterLine) // 相同舱室、功能的节点序号
2026-09-28 15:28:50 +08:00
{
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);
2026-10-04 00:04:20 +08:00
// 管廊宽
2026-09-28 15:28:50 +08:00
double w = getEwSectionWidth(dim.idEw);
AcGePoint3d ptIns = dim.pntIns;
AcGeVector3d vt = dim.vt;
2026-10-04 00:04:20 +08:00
// 转90
2026-09-28 15:28:50 +08:00
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;
2026-10-04 00:04:20 +08:00
// 如果当前桩号上有防火墙标注
2026-09-28 15:28:50 +08:00
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<func_##sfunc>(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);
2026-10-04 00:04:20 +08:00
if (str == _T("集水井"))
2026-09-28 15:28:50 +08:00
return NodeDim::eDrainWell;
2026-10-04 00:04:20 +08:00
else if (str == _T("投料口"))
2026-09-28 15:28:50 +08:00
return NodeDim::eDoghouse;
2026-10-04 00:04:20 +08:00
else if (str == _T("通风口"))
2026-09-28 15:28:50 +08:00
return NodeDim::eVenDoghouse;
2026-10-04 00:04:20 +08:00
else if (str == _T("防火墙"))
2026-09-28 15:28:50 +08:00
return NodeDim::eFireWall;
2026-10-04 00:04:20 +08:00
else if (str == _T("逃生口"))
2026-09-28 15:28:50 +08:00
return NodeDim::eEscapeHatch;
2026-10-04 00:04:20 +08:00
else if (str == _T("管线分支口"))
2026-09-28 15:28:50 +08:00
return NodeDim::eOutlet;
2026-10-04 00:04:20 +08:00
else if (str == _T("变形缝"))
2026-09-28 15:28:50 +08:00
return NodeDim::eEspJoint;
else
return NodeDim::eNone;
return NodeDim::eNone;
}
CString getNodeName(const NodeDim::ENodeType &type)
{
switch (type)
{
case NodeDim::eDrainWell:
2026-10-04 00:04:20 +08:00
return _T("集水井");
2026-09-28 15:28:50 +08:00
case NodeDim::eDoghouse:
2026-10-04 00:04:20 +08:00
return _T("投料口");
2026-09-28 15:28:50 +08:00
case NodeDim::eVenDoghouse:
2026-10-04 00:04:20 +08:00
return _T("通风口");
2026-09-28 15:28:50 +08:00
case NodeDim::eFireWall:
2026-10-04 00:04:20 +08:00
return _T("防火墙");
2026-09-28 15:28:50 +08:00
case NodeDim::eEscapeHatch:
2026-10-04 00:04:20 +08:00
return _T("逃生口");
2026-09-28 15:28:50 +08:00
case NodeDim::eOutlet:
2026-10-04 00:04:20 +08:00
return _T("管线分支口");
2026-09-28 15:28:50 +08:00
case NodeDim::eEspJoint:
2026-10-04 00:04:20 +08:00
return _T("变形缝");
2026-09-28 15:28:50 +08:00
default:
return _T("");
}
return _T("");
}
void collectNodeInfo_Dim(AcDbObjectId idEw, std::vector<NodeDim> &nodeDims, bool includeFire)
{
::collectNodeInfoForDim(idEw, nodeDims, includeFire);
}
void collectNodeInfo_Statistic(AcDbObjectId idEw, std::vector<NodeDim> &nodeDims, bool includeFire)
{
::collectNodeInfoForStatistic(idEw, nodeDims, includeFire);
}
}
namespace MK_DIM
{
void insertFireWallDim()
{
2026-10-04 00:04:20 +08:00
// 选择管廊
2026-09-28 15:28:50 +08:00
ads_point adsPnt;
ads_name adsName;
2026-10-04 00:04:20 +08:00
int nRes = acedEntSel(_T("\n请选择要标注的管廊。"), adsName, adsPnt);
2026-09-28 15:28:50 +08:00
if (nRes != RTNORM) return;
AcDbObjectId idEw(AcDbObjectId::kNull);
acdbGetObjectId(idEw, adsName);
if (!GLTools::isThisClass<AecDbEarthWorm>(idEw))
{
2026-10-04 00:04:20 +08:00
acutPrintf(_T("\n请选择一段管廊。"));
2026-09-28 15:28:50 +08:00
return;
}
2026-10-04 00:04:20 +08:00
// 绘制参数-------------------------------
// 标注 宽,高,箭头宽,字高,文字比例
2026-09-28 15:28:50 +08:00
double w(50), h(50), aW(2), txtH(1);
AcDbObjectId idStyle;
2026-10-04 00:04:20 +08:00
// 弹对话框
2026-09-28 15:28:50 +08:00
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"));
2026-10-04 00:04:20 +08:00
// 收集参数-------------------------------
2026-09-28 15:28:50 +08:00
std::vector<NodeDim> nodeDims(0);
collectNodeInfo_Dim(idEw, nodeDims, true);
2026-10-04 00:04:20 +08:00
// 绘制
2026-09-28 15:28:50 +08:00
AcGePoint3d ptCross(AcGePoint3d::kOrigin), ptOldCross(AcGePoint3d::kOrigin);
double maxW(.0), oldMaxW(.0);
2026-10-04 00:04:20 +08:00
bool bRight(dlg.m_iSide == 0); // 是标在管廊方向右侧还是左侧
2026-09-28 15:28:50 +08:00
2026-10-04 00:04:20 +08:00
// 整理一下,把有防火墙的挑出来,之后再统一处理
2026-09-28 15:28:50 +08:00
std::vector<NodeDim> 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<CString> 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];
2026-10-04 00:04:20 +08:00
// 不是第一个
2026-09-28 15:28:50 +08:00
if (i)
{
2026-10-04 00:04:20 +08:00
AcDbObjectIdArray ids(0); // 临时,无用
2026-09-28 15:28:50 +08:00
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()
{
2026-10-04 00:04:20 +08:00
// 选择管廊
2026-09-28 15:28:50 +08:00
ads_point adsPnt;
ads_name adsName;
2026-10-04 00:04:20 +08:00
int nRes = acedEntSel(_T("\n请选择要标注的管廊。"), adsName, adsPnt);
2026-09-28 15:28:50 +08:00
if (nRes != RTNORM) return;
AcDbObjectId idEw(AcDbObjectId::kNull);
acdbGetObjectId(idEw, adsName);
if (!GLTools::isThisClass<AecDbEarthWorm>(idEw))
{
2026-10-04 00:04:20 +08:00
acutPrintf(_T("\n请选择一段管廊。"));
2026-09-28 15:28:50 +08:00
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"));
2026-10-04 00:04:20 +08:00
// 收集参数-------------------------------
2026-09-28 15:28:50 +08:00
std::vector<NodeDim> 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<CString> mmapStrs;
typedef std::multiset<CString>::iterator mmapIt;
std::pair<mmapIt, mmapIt> 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();
}
}
}