Files
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

570 lines
13 KiB
C++

#include "stdafx.h"
#include "insertequ.h"
#include "KTCadUtilityex.h"
#include "AecDbEarthWorm.h"
#include "UITools.h"
#include "AecDbPortRoom.h"
#include "coretools.h"
void DLLIMPEXP ConnectEarthWorm(AecDbEarthWorm* pWorm1, AecDbEarthWorm* pWorm2);
namespace
{
#define ALIGN_OFFSET _T("Align_Offset")
#define ALIGN_ROOM _T("Align_Room")
#define ALIGN_TYPE _T("Align_Type")
struct INSPos
{
AcGePoint3d m_pt;
AcGeVector3d m_normal;
double m_angle;
int m_idDb;
};
bool getEw(AcDbObjectIdArray &ids)
{
ads_name ent;
ads_point pt;
AcDbObjectId idSt(AcDbObjectId::kNull), idEd(AcDbObjectId::kNull);
int nRes = acedEntSel(_T("\n请选择管廊起始段:"), ent, pt);
if (nRes != RTNORM) return false;
acdbGetObjectId(idSt, ent);
if (!idSt.isValid()) return false;
nRes = acedEntSel(_T("\n请选择管廊结束段:"), ent, pt);
if (nRes != RTNORM)
idEd = idSt;
else
acdbGetObjectId(idEd, ent);
if (!idEd.isValid()) return false;
if (!GetConnectedWorms(idSt, idEd, ids))
{
acutPrintf(_T("\n提取管廊段失败。"));
return false;
}
CString str(_T("")), strSection(_T("")), strFstSection(_T(""));
int idx(-1);
for (int i = 0; i < ids.length(); i++)
{
OPENOBJ_BEGIN(ids[i], AcDb::kForRead, AecDbEarthWorm, pEw)
if (!pEw) continue;
pEw->GetCrossSectionScr(str);
idx = str.Find(_T("ext"));
if (idx == -1) // 说明没有扩展数据,全部字符串都为几何信息
strSection = str;
else
strSection = str.Left(idx);
if (i == 0) // 用第一个做标准,来检测后面的每一段管廊
{
strFstSection = strSection;
continue;
}
else
{
if (strSection.Compare(strFstSection) != 0) // 不一致,走人
{
acutPrintf(_T("\n所选的管廊中,尺寸不完全一致,请检查。"));
return false;
}
}
OPENOBJ_END()
}
return !ids.isEmpty();
}
bool getEwCenterLine(const int iRoom
, const bool &bWhole
, const AcDbObjectIdArray &ids
, std::vector<AcGeLineSeg3d> &segs)
{
EROOM room;
AcArray<LineSeg> arLnCenSegs(0);
for (int i = 0; i < ids.length(); ++i)
{
OPENOBJ_BEGIN(ids[i], AcDb::kForRead, AecDbEarthWorm, pEw)
if (!pEw) continue;
arLnCenSegs.removeAll();
pEw->getCenterLineForPipe(arLnCenSegs, iRoom, bWhole);
for (int j = 0; j < arLnCenSegs.length(); ++j)
{
LineSeg &lnseg = arLnCenSegs[j];
segs.push_back(AcGeLineSeg3d(lnseg.ptFr, lnseg.ptTo));
}
OPENOBJ_END()
}
return !segs.empty();
}
int getEwRoomCount(AcDbObjectId &id)
{
OPENOBJ_BEGIN(id, AcDb::kForRead, AecDbEarthWorm, pEw)
if (pEw) return pEw->GetRoomCount();
OPENOBJ_END()
return 0;
}
bool getInsPos_BOSS(LPCTSTR pszBoss, const std::vector<AcGeLineSeg3d> &segs)
{
//BOSS: 房间|左右位置|侧间隙|水平间隙|宽|高|长|直径|用途|公称直径|壁厚|重量|管道材质|管道系统|颜色|线形|编号|支墩类型|偏移|行|间隙|3D索引
return false;
}
// 外宽,外高,外壁厚,内壁厚
bool getEwGeoInfo(AecDbEarthWorm *pEw, double &dW, double &dH, double &dOutW, double &dInnerW)
{
if (!pEw) return false;
AcGePoint2dArray arDatas;
ESection sectionType;
sectionType = pEw->ExtractEarthWormScr(arDatas);
if (sectionType != eRect) return false;
////外壁厚,内隔壁厚
if (arDatas.length() > 0)
{
dOutW = arDatas.last().x;
dInnerW = arDatas.last().y;
}
//总宽度
for (int i = 0; i < arDatas.length() - 1; i++)
{
dW+= arDatas.at(i).x;
}
dW+= (arDatas.length() - 2) * dInnerW;
dW+= dOutW * 2.0;
//总高度
dH = arDatas.first().y;
dH += 2 * arDatas.last().x;
return true;
}
void drawCircle(const AcGePoint2d &pt, const double &d = 1, const int &clr = 1)
{
#ifndef NDEBUG
AcDbCircle *p = new AcDbCircle(AcGePoint3d(pt.x, pt.y, .0), AcGeVector3d::kZAxis, d);
p->setColorIndex(clr);
CoreTools::AddToModelSpace(p);
#endif
}
void drawRay(const AcGePoint2d &pt, const AcGeVector2d &vt)
{
#ifndef NDEBUG
AcDbRay *p = new AcDbRay();
p->setUnitDir(AcGeVector3d(vt.x, vt.y, .0));
p->setBasePoint(AcGePoint3d(pt.x, pt.y, .0));
CoreTools::AddToModelSpace(p);
#endif
}
void drawXLine(const AcGePoint2d &pt, const AcGeVector2d &vt)
{
#ifndef NDEBUG
AcDbXline *p = new AcDbXline();
p->setUnitDir(AcGeVector3d(vt.x, vt.y, .0));
p->setBasePoint(AcGePoint3d(pt.x, pt.y, .0));
CoreTools::AddToModelSpace(p);
#endif
}
void offsetEw(AecDbEarthWorm *pEw, const double &dOffset)
{
if (!pEw) return;
AcGePoint2d pt2dStart(AcGePoint2d::kOrigin), pt2dEnd(AcGePoint2d::kOrigin);
AcGeVector2d dir(AcGeVector2d::kIdentity);
dir = pEw->EndPoint(true) - pEw->StartPoint();
dir.normalize();
dir.rotateBy(PI * .5);
dir *= dOffset;
pt2dStart = pEw->StartPoint();
pt2dStart += dir;
pEw->SetStartPoint(pt2dStart);
pt2dEnd = pEw->EndPoint(true);
pt2dEnd += dir;
pEw->SetEndPoint(pt2dEnd);
}
}
namespace InsEqu
{
void insertEqu()
{
AcDbObjectIdArray ids(0);
if (!getEw(ids)) return;
std::vector<AcGeLineSeg3d> segs(0);
if (!getEwCenterLine(0, true, ids, segs)) return;
for (size_t i = 0; i < segs.size(); ++i)
{
AcGeLineSeg3d &seg(segs[i]);
AcDbLine *pLine = new AcDbLine(seg.startPoint(), seg.endPoint());
CoreTools::AddToModelSpace(pLine);
}
}
bool getAlignTypeByOffset(AecDbEarthWorm *pEw, int &alignType, int &idxRoom, double &dOffset)
{
if (!pEw)
{
dOffset = .0;
alignType = eNone;
idxRoom = -1;
return false;
}
if (pEw->GetSpecialtyData()->GetAt(ALIGN_TYPE, alignType)
&& pEw->GetSpecialtyData()->GetAt(ALIGN_OFFSET, dOffset)
&& pEw->GetSpecialtyData()->GetAt(ALIGN_ROOM, idxRoom))
return true;
return false;
/*
AcGePoint2d pt2d1, pt2d2;
double dRoom // 舱内径宽
, dOutW(.0) // 外壁厚
, dInnerW(.0) // 内壁厚
, dW(.0); // 总宽
pt2d2 = pEw->GetSize(pt2d1);
dOutW = pt2d1.x;
dInnerW = pt2d1.y;
dW = pt2d2.x;
double dDelta(.5*dW + dOffset);
ERoom rm;
double dist(dOutW);
int nCount(pEw->GetRoomCount());
for (size_t i = 0; i < nCount; ++i)
{
pEw->GetRoom(i, rm);
dRoom = rm.ptGe[0].distanceTo(rm.ptGe[1]);
idxRoom = i;
if (DOWNEQUAL(dDelta, dist))
return eAlignLeft;
dist += dRoom * .5;
if (DOWNEQUAL(dDelta, dist))
return eAlignCenter;
dist += dRoom * .5;
if (DOWNEQUAL(dDelta, dist))
return eAlignRight;
dist += dInnerW;
}
return eNone;
*/
}
int getAlignType(const AecDbEarthWorm *pEw)
{
if (!pEw) return eNone;
int type(eNone);
pEw->GetSpecialtyData()->GetAt(ALIGN_TYPE, type);
return type;
}
int getAlignType(const AcDbObjectId & id)
{
OPENOBJ_BEGIN(id, AcDb::kForRead, AecDbEarthWorm, pEw)
if (pEw)
return getAlignType(pEw);
OPENOBJ_END()
return eNone;
}
int getAlignRoom(const AecDbEarthWorm *pEw)
{
if (!pEw) return -1;
int idx(-1);
pEw->GetSpecialtyData()->GetAt(ALIGN_ROOM, idx);
return idx;
}
int getAlignRoom(const AcDbObjectId & id)
{
OPENOBJ_BEGIN(id, AcDb::kForRead, AecDbEarthWorm, pEw)
if (pEw)
return getAlignRoom(pEw);
OPENOBJ_END()
return -1;
}
double getAlignOffset(const AecDbEarthWorm *pEw)
{
if (!pEw) return .0;
double dOffset(.0);
pEw->GetSpecialtyData()->GetAt(ALIGN_OFFSET, dOffset);
return dOffset;
}
double getAlignOffset(const AcDbObjectId & id)
{
OPENOBJ_BEGIN(id, AcDb::kForRead, AecDbEarthWorm, pEw)
if (pEw)
return getAlignOffset(pEw);
OPENOBJ_END()
return 0.0;
}
void generateControlLine()
{
AcDbObjectIdArray arIds(0);
if (!GLTools::getConnectWorms(arIds)) return;
if (arIds.isEmpty()) return;
AcGePoint3d ptS(AcGePoint3d::kOrigin), ptE(AcGePoint3d::kOrigin), pt(AcGePoint3d::kOrigin);
AcGePoint2d pt2d, pt2d1;
double dH(.0),dOutW(.0), dBom(.0), dTop(.0)
, dLeftH(.0), dRightH(.0), dInnerH(.0)
, deltaL(.0), deltaR(.0);
double dElevS(.0), dElevE(.0);
AcDbCurve *pCurve(NULL);
AcGeVector3d vt(AcGeVector3d::kIdentity);
AcGeLineSeg3d seg;
AcArray<ERoom> rms;
for (int i = 0; i < arIds.length(); ++i)
{
OPENOBJ_BEGIN(arIds[i], AcDb::kForRead, AecDbEarthWorm, pEw)
{
if (!pEw) continue;
// 带标高的basecurve就在廊径中间,以它为标准做变换
pCurve = pEw->GetBaseCurve(true);
if (!pCurve) continue;
pCurve->getStartPoint(ptS);
pCurve->getEndPoint(ptE);
ptS.z = ptE.z = .0;
vt = ptE - ptS;
dElevS = pEw->StartElevation();
dElevE = pEw->EndElevation();
ptS.z = dElevS;
ptE.z = dElevE;
pEw->GetSize(pt2d);
dOutW = pt2d.x; // 外壁
dBom = pEw->GetBomThickAdd();
dBom += dOutW; // 下壁厚
dTop = pEw->GetTopThickAdd();
dTop += dOutW; // 上壁厚
dLeftH = pEw->GetLeftRoomHeight(); // 最左舱内高
dRightH = pEw->GetRightRoomHeight();// 最右舱内高
seg.set(ptS, ptE);
rms.removeAll();
pEw->GetSectionRoomsTo(seg, rms, pt2d);
for (int r = 0; r < rms.length(); ++r)
{
ERoom &ro(rms[r]);
dInnerH = ro.ptGe[0].distanceTo(ro.ptGe[3]);
dH = dInnerH + dTop + dBom;
Midpoint(ro.ptGe[0], ro.ptGe[2], pt);
if (r == 0) // 最左
{
deltaL = abs(dInnerH - dLeftH);
pt.z -= deltaL * .5;
}
if (r == rms.length() - 1) // 最右
{
deltaR = abs(dInnerH - dRightH);
pt.z -= deltaR * .5;
}
AcDbLine *pL = new AcDbLine(pt, pt + vt);
pL->setColorIndex(r + 1);
CoreTools::AddToModelSpace(pL);
}
}
OPENOBJ_END()
}
}
double getEarthwormOffset(AecDbEarthWorm * pEw, const int & idxRoom, const EAlignType & alignType)
{
if (!pEw) return .0;
if (idxRoom == -1) return .0;
if (alignType == eNone) return .0;
AcGePoint2d pt2d1, pt2d2;
double dRoom // 舱内径宽
, dOutW(.0) // 外壁厚
, dInnerW(.0) // 内壁厚
, dW(.0); // 总宽
pt2d2 = pEw->GetSize(pt2d1);
dOutW = pt2d1.x;
dInnerW = pt2d1.y;
dW = pt2d2.x;
ERoom rm;
double dDelta(dOutW); // 先把左侧外壁厚加上
int nCount(pEw->GetRoomCount());
for (size_t i = 0; i < nCount; ++i)
{
pEw->GetRoom(i, rm);
dRoom = rm.ptGe[0].distanceTo(rm.ptGe[1]);
dDelta += dRoom; // 再加上此舱室内径宽
dDelta += dInnerW; // 再加上其右侧内壁厚
if (idxRoom == i)
{
// 把右侧内壁厚减掉
dDelta -= dInnerW;
if (alignType == eAlignLeft) // 左对齐
dDelta -= dRoom;
else if (alignType == eAlignCenter) // 中对齐
dDelta -= dRoom * .5;
else // 右对齐
{
// 不用动
}
break;
}
}
// 管廊默认是按照总宽度一半来做为中心的
return dDelta - dW * .5;
}
double getEarthwormOffset(AcDbObjectId & id, const int & idxRoom, const EAlignType & alignType)
{
OPENOBJ_BEGIN(id, AcDb::kForRead, AecDbEarthWorm, pEw)
if (pEw)
return getEarthwormOffset(pEw, idxRoom, alignType);
OPENOBJ_END()
return .0;
}
// 目的是先进行偏移(并不使用AecDbEarthworm类中的m_dOffset变量)
void offsetAndConnectEws(AcDbObjectIdArray &ids
, const int &alignType
, const int &idxRoom
, const double &dOldOffset)
{
if (ids.isEmpty()) return;
if (alignType == eNone) return;
double dOffset(.0);
dOffset = getEarthwormOffset(ids.first(), idxRoom, (EAlignType)alignType);
dOffset -= dOldOffset;
AcDbObjectIdArray arPorts(0);
for (int i = 0; i < ids.length(); ++i)
{
AcDbObjectId &id(ids[i]);
OPENOBJ_BEGIN(id, AcDb::kForWrite, AecDbEarthWorm, pEw)
{
if (!pEw) continue;
offsetEw(pEw, dOffset);
pEw->GetPortRoomIds(arPorts);
pEw->GetSpecialtyData()->SetAt(ALIGN_TYPE, alignType);
pEw->GetSpecialtyData()->SetAt(ALIGN_ROOM, idxRoom);
pEw->GetSpecialtyData()->SetAt(ALIGN_OFFSET, dOffset + dOldOffset);
}
OPENOBJ_END()
}
if (true) // 为测试加此语句
{
for (int i = 0; i < ids.length() - 1; ++i)
{
AcDbObjectId &id1(ids[i]), &id2(ids[i + 1]);
OPENOBJ_BEGIN(id1, AcDb::kForWrite, AecDbEarthWorm, pEw1)
{
OPENOBJ_BEGIN(id2, AcDb::kForWrite, AecDbEarthWorm, pEw2)
{
if (!pEw1 || !pEw2) continue;
ConnectEarthWorm(pEw1, pEw2);
}
OPENOBJ_END()
}
OPENOBJ_END()
}
}
for (int i = 0; i < arPorts.length(); ++i)
{
AcDbObjectId &id(arPorts.at(i));
OPENOBJ_BEGIN(id, AcDb::kForWrite, AecDbPortRoom, pPort)
{
if (!pPort) continue;
pPort->UpdateDraw();
}
OPENOBJ_END()
}
}
void generateControlLine_old()
{
ads_name ent;
ads_point pt;
AcDbObjectId idSt(AcDbObjectId::kNull), idEd(AcDbObjectId::kNull);
int nRes = acedEntSel(_T("\n请选择管廊:"), ent, pt);
if (nRes != RTNORM) return;
acdbGetObjectId(idSt, ent);
if (!idSt.isValid()) return;
AcDbObjectIdArray ids(0);
if (!GetConnectedWorms(idSt, ids))
{
acutPrintf(_T("\n获取相连管廊失败。"));
return;
}
int count = getEwRoomCount(idSt);
if (!count) return;
std::vector<AcGeLineSeg3d> segs(0);
if (!getEwCenterLine(0, false, ids, segs)) return;
for (size_t j = 0; j < segs.size(); ++j)
{
AcGeLineSeg3d &seg(segs[j]);
AcDbLine *pLine = new AcDbLine(seg.startPoint(), seg.endPoint());
CoreTools::AddToModelSpace(pLine);
}
}
}