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

1005 lines
26 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 <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)
{
//电力舱:通风口;逃生口|综合舱:通风口;人员出入口
std::vector<CString> 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<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);
}
// 通过 数组dims 内的索引 idx,得到其前面的对应舱室的防火墙个数,并拼成字符串
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)
{ // 向前搜索,寻找有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<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];
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<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);
// 画竖线
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 <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)
{
// 是否有相同的类型
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<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);
// 遍历每个中心点,然后调用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<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;
// 填充type_rooms结构
_insert_<NodeDim::ENodeType, CString>(nd.type_rooms, nodeType, nameRoom);
// 填充room_types结构
_insert_<CString, NodeDim::ENodeType>(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<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;
// 如果舱室存在 防火墙 或 通风口 ,则在此舱室头尾加上相应的节点
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());
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<NodeDim::ENodeType>::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<CString>::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<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);
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<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()
{
// 选择管廊
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<AecDbEarthWorm>(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<NodeDim> 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<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];
// 不是第一个
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<AecDbEarthWorm>(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<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();
}
}
}