570 lines
13 KiB
C++
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);
|
|
}
|
|
}
|
|
}
|