2819 lines
71 KiB
C++
2819 lines
71 KiB
C++
// DbDuct.cpp: implementation of the TDbDuct class.
|
||
//
|
||
//////////////////////////////////////////////////////////////////////
|
||
|
||
#include "stdafx.h"
|
||
#include "DbDuct.h"
|
||
#include "PipePrototype.h"
|
||
#include "DbPipe.h"
|
||
#include "DbDoubleLinePipe.h"
|
||
|
||
#include "PipeTools.h"
|
||
#include "DbPipeLabel.h"
|
||
#include "DbPipeValve.h"
|
||
#include "HDbEquipment.h"
|
||
|
||
#include "GlobalFunction.h"
|
||
#include "TDbDuctNode.h"
|
||
|
||
ACRX_DXF_DEFINE_MEMBERS(ATSDuct, ATSPipePrototype, AcDb::kDHL_CURRENT,
|
||
AcDb::kMReleaseCurrent, 1, ATS_VENTPIPE,
|
||
"ATS_VENTPIPE图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
|
||
IMPLEMENT_TENTBASE(TDbDuct);
|
||
|
||
// sg modify 2008-1-14
|
||
// const Adesk::UInt8 TDbDuct::g_nVersion = 1; // 7.5
|
||
const Adesk::UInt8 TDbDuct::g_nVersion = 2; // 7.6
|
||
|
||
|
||
|
||
//////////////////////////////////////////////////////////////////////
|
||
// Construction/Destruction
|
||
//////////////////////////////////////////////////////////////////////
|
||
TDbDuct::TDbDuct():
|
||
m_dWidth(800), m_dHeight(500), m_dOldWidth(0), m_dOldHeight(0), m_dDuctWeight(0.35),
|
||
m_dVDAngle(0), m_nMaterial(0), m_dSpeedSubMid(0), m_dSpeedLength(0), m_dFlChuTou(100),
|
||
m_dFlThick(50), m_dCalWeight(0)
|
||
{
|
||
m_sysType = TPipeSys::kUnknownSys;
|
||
m_nSection = 0;
|
||
m_nSysDrawMod = 2;
|
||
m_eDQType = kMidMid;
|
||
m_eDQSide = TPipeSys::kStartPt;
|
||
|
||
m_nSpare = 0;
|
||
m_dSpare = 0.0;
|
||
}
|
||
|
||
|
||
|
||
/////////////////////////////////Get函数/////////////////////////////////////////
|
||
// 获取指定端坐标
|
||
XPoint TDbDuct::GetVertexPt(const TPipeSys::PtLoction nSide) const
|
||
{
|
||
XPoint pt(GetStartPoint());
|
||
if (nSide == TPipeSys::kEndPt)
|
||
{
|
||
pt = EndPoint();
|
||
}
|
||
return pt;
|
||
}
|
||
|
||
// 获取另一端坐标
|
||
XPoint TDbDuct::GetOtherPt(const TPipeSys::PtLoction nSide) const
|
||
{
|
||
TPipeSys::PtLoction nOther = (TPipeSys::PtLoction)(1-(int)nSide);
|
||
return GetVertexPt(nOther);
|
||
}
|
||
|
||
// 获取管线法向
|
||
XVector3D TDbDuct::GetDirection(const XPoint &pt, TPipeSys::PtLoction &nSide) const
|
||
{
|
||
XVector3D vt;
|
||
XCurveSegment seg = GetCurve(); // 管段
|
||
if (seg.Is(CURVE_LINE)) // 直线管段
|
||
{
|
||
double dDis1 = pt.Distance(StartPoint()),
|
||
dDis2 = pt.Distance(EndPoint());
|
||
if (dDis1 > (dDis2+1.0E-6))
|
||
{
|
||
vt = StartPoint() - EndPoint(); // S——>E
|
||
nSide = TPipeSys::kEndPt; // pt点接近管线终点
|
||
}
|
||
else
|
||
{
|
||
vt = EndPoint() - StartPoint(); // E——>S
|
||
nSide = TPipeSys::kStartPt; // pt点接近管线起点
|
||
}
|
||
return vt;
|
||
}
|
||
|
||
XPoint ptRet, ptStart, ptEnd; // 注:弧管起止点可能会相反
|
||
seg.ProjectToMe(pt, ptRet); // 保证点在管段上
|
||
XArc arc = seg.GetArc();
|
||
arc.GetStartPoint(ptStart);
|
||
arc.GetEndPoint(ptEnd);
|
||
|
||
// arc.GetPoints(ptStart, ptEnd); // 弧管上的起、止点坐标
|
||
|
||
AcGePoint3d ptOnCurve = ptRet.AsAcGePoint3d(), ptOnHit;
|
||
AcDbCurve *pCurve = GetBaseCurve();
|
||
pCurve->getClosestPointTo(ptOnCurve, ptOnHit);
|
||
ASSERT(pCurve);
|
||
AcGeVector3d vec; // S——>E
|
||
pCurve->getFirstDeriv(ptOnHit, vec); // 求切线向量
|
||
delete pCurve;
|
||
vt = XVector3D(vec);
|
||
|
||
double dDis1 = pt.Distance(ptStart),
|
||
dDis2 = pt.Distance(ptEnd);
|
||
BOOL bChange = ptStart.Distance(StartPoint())>1.0E-5; // 标志是否发生了反向
|
||
if (dDis1 > (dDis2+1.0E-6))
|
||
{
|
||
vt.Scale(-1); // E——>S
|
||
nSide = bChange?TPipeSys::kStartPt:TPipeSys::kEndPt; // pt点接近管线终点
|
||
}
|
||
else
|
||
{
|
||
nSide = bChange?TPipeSys::kEndPt:TPipeSys::kStartPt; // pt点接近管线起点
|
||
}
|
||
return vt;
|
||
}
|
||
|
||
|
||
|
||
//////////////////////////有关管段上附着的设备/////////////////////////////////
|
||
void TDbDuct::AddEquipment(const AcDbObjectId &id) // 增加节点
|
||
{
|
||
assertWriteEnabled();
|
||
if (!FindEquipment(id))
|
||
{
|
||
m_lstEquipment.Append(new AcDbSoftPointerId(id));
|
||
}
|
||
}
|
||
|
||
void TDbDuct::RemoveEquipment(const AcDbObjectId &id) // 移除节点
|
||
{
|
||
assertWriteEnabled();
|
||
if (m_lstEquipment.FindNode(&id, CompareObjectId))
|
||
{
|
||
m_lstEquipment.Remove();
|
||
}
|
||
}
|
||
|
||
BOOL TDbDuct::FindEquipment(const AcDbObjectId &id) const // 查找节点
|
||
{
|
||
TDbDuct *pThis = TDbDuct::cast(this);
|
||
BOOL bFind = (pThis->m_lstEquipment.FindNode(&id, CompareObjectId)!=NULL);
|
||
return bFind;
|
||
}
|
||
|
||
int TDbDuct::GetEquipNum() const // 获取连接的节点数量
|
||
{
|
||
return m_lstEquipment.Length();
|
||
}
|
||
|
||
// 获取节点ID
|
||
void TDbDuct::GetEquipments(DList<AcDbObjectId> &lstEquipment) const
|
||
{
|
||
int nCount = m_lstEquipment.Length();
|
||
for (int i=0; i<nCount; i++)
|
||
{
|
||
lstEquipment.Append(new AcDbObjectId(m_lstEquipment[i]));
|
||
}
|
||
}
|
||
|
||
// 获取节点位置
|
||
void TDbDuct::GetEquipPts(XPointList &lstPts) const
|
||
{
|
||
int nCount = m_lstEquipment.Length();
|
||
for (int i=0; i<nCount; i++)
|
||
{
|
||
AcDbObjectId idOp = m_lstEquipment[i];
|
||
OPENOBJ_BEGIN(idOp, AcDb::kForRead, TDbPipeNode, pNode);
|
||
if (pNode != NULL)
|
||
{
|
||
XPoint ptLoc = pNode->GetLocation();
|
||
lstPts.Append(new XPoint(ptLoc));
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
}
|
||
|
||
// 判断管线与设备是否能在指定接口处,产生附着关系
|
||
BOOL TDbDuct::CanAttachEquipment(const THDbEquipment &equipment,
|
||
const int &nIFaceNum) const
|
||
{
|
||
BOOL bRet(FALSE);
|
||
XPoint ptProject;
|
||
const XPoint &ptLink = equipment.GetILocation(nIFaceNum);
|
||
if (getClosestPointTo(ptLink, ptProject, Adesk::kFalse) != Acad::eOk)
|
||
{
|
||
return bRet;
|
||
}
|
||
|
||
int nSection = GetSectionType();
|
||
BOOL bSys = GetModelType()==TPipeSys::kSystem ||
|
||
GetModelType()==TPipeSys::kPrinciple;
|
||
if (nSection == 1) // 圆管
|
||
{
|
||
double dDist = ptProject.Distance(ptLink);
|
||
bRet = fabs(dDist-m_dWidth/2.0)<1.0E-6;
|
||
if (bSys)
|
||
{
|
||
bRet = dDist < m_dHeight/2.0 + 1.0E-6;
|
||
}
|
||
}
|
||
else if (nSection == 0) // 方管
|
||
{
|
||
if (bSys)
|
||
{
|
||
CString sBlkName, sDesName;
|
||
GetBlkNameById(equipment.GetBlock2d(), sBlkName, sDesName);
|
||
|
||
XPoint ptTmp1(ptLink), ptTmp2(ptProject);
|
||
ptTmp1.z = ptTmp2.z = 0;
|
||
double dDist = ptTmp1.Distance(ptTmp2);
|
||
if (_tcsicmp(sDesName, _T("sysD")) == 0) // 下接风口
|
||
{
|
||
bRet = dDist < m_dHeight/2.0 + 1.0E-6;
|
||
|
||
}
|
||
else if (_tcsicmp(sDesName, _T("sysS")) == 0) // 侧接风口
|
||
{
|
||
bRet = dDist < m_dWidth/2.0 + 1.0E-6;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
XPoly2D poly1, poly2;
|
||
XPointList lstPts1, lstPts2;
|
||
XVector3D vtDuct1 = EndPoint() - StartPoint(),
|
||
vtDuct2 = StartPoint() - EndPoint();
|
||
::GetDuctSidePts(ptProject, m_dWidth, m_dHeight, vtDuct1, lstPts1);
|
||
::GetDuctSidePts(ptProject, m_dWidth, m_dHeight, vtDuct2, lstPts2);
|
||
int nLen = lstPts1.Length(), i(0);
|
||
for (i=0; i<nLen; i++)
|
||
{
|
||
poly1.AppendNode(*lstPts1[i], 0);
|
||
}
|
||
|
||
nLen = lstPts2.Length();
|
||
for (i=0; i<nLen; i++)
|
||
{
|
||
poly2.AppendNode(*lstPts2[i], 0);
|
||
}
|
||
|
||
BOOL bRet1 = (ptLink&poly1)==PR_EDGE,
|
||
bRet2 = (ptLink&poly2)==PR_EDGE;
|
||
bRet = bRet1 || bRet2;
|
||
}
|
||
}
|
||
return bRet;
|
||
}
|
||
|
||
// 重新验证同自身全部附着的设备之间的关系,并调整配属, 在系统结束后处理
|
||
// 注:只处理设备,不处理掏洞节点
|
||
void TDbDuct::ValidateEquipmentShip()
|
||
{
|
||
int i(0),
|
||
nCount = m_lstEquipment.Length();
|
||
DList<AcDbObjectId> lstEquipment;
|
||
for (i=0; i<nCount; i++)
|
||
{
|
||
lstEquipment.Append(new AcDbObjectId(*m_lstEquipment[i]));
|
||
}
|
||
|
||
for (i=0; i<lstEquipment.Length(); i++)
|
||
{
|
||
AcDbObjectId idOp = *lstEquipment[i];
|
||
OPENOBJ_BEGIN(idOp, AcDb::kForRead, TDbPipeNode, pNode);
|
||
if (pNode == NULL)
|
||
{
|
||
RemoveEquipment(idOp);
|
||
continue;
|
||
}
|
||
|
||
if (pNode->isKindOf(TDbDuctNode::desc())) // 掏洞节点
|
||
{
|
||
continue;
|
||
}
|
||
|
||
if (pNode->isKindOf(THDbEquipment::desc())) // 设备
|
||
{
|
||
THDbEquipment *pEquipment = THDbEquipment::cast(pNode);
|
||
int nLen = pEquipment->GetInterfaceNum();
|
||
for (int j=0; j<nLen; j++)
|
||
{
|
||
AcDbObjectId ductId = pEquipment->GetIPipe(j);
|
||
if (ductId==objectId() && !CanAttachEquipment(*pEquipment, j))
|
||
{
|
||
RemoveEquipment(idOp); // 不存在相互连接关系
|
||
if (pEquipment->upgradeOpen() == Acad::eOk)
|
||
{
|
||
pEquipment->SetIPipe(j, AcDbObjectId::kNull);
|
||
pEquipment->downgradeOpen();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
}
|
||
|
||
|
||
///////////////////////////Override TDbEntity////////////////////////////////////
|
||
void TDbDuct::CopyPropertiesFrom(AcDbEntity* pSrc, unsigned gMatchFlag)
|
||
{
|
||
assertWriteEnabled();
|
||
TDbPipePrototype::CopyPropertiesFrom(pSrc, gMatchFlag);
|
||
TDbDuct *pDuct = TDbDuct::cast(pSrc);
|
||
if (pDuct != NULL)
|
||
{
|
||
m_nSysDrawMod = pDuct->m_nSysDrawMod;
|
||
m_nSection = pDuct->m_nSection;
|
||
m_dWidth = pDuct->m_dWidth;
|
||
m_dHeight = pDuct->m_dHeight;
|
||
m_dDuctWeight = pDuct->m_dDuctWeight;
|
||
m_dVDAngle = pDuct->m_dVDAngle;
|
||
m_nMaterial = pDuct->m_nMaterial;
|
||
m_sLabel = pDuct->m_sLabel;
|
||
m_eDQType = pDuct->m_eDQType;
|
||
m_eDQSide = pDuct->m_eDQSide;
|
||
m_dFlChuTou = pDuct->m_dFlChuTou;
|
||
m_dFlThick = pDuct->m_dFlThick;
|
||
m_dCalWeight = pDuct->m_dCalWeight;
|
||
}
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuct::subGetClassID(CLSID* pClsid) const
|
||
{
|
||
return Acad::eOk;
|
||
}
|
||
|
||
// 取动态属性显示数据
|
||
void TDbDuct::GetTips(DList<TObjInfoUnit> &lstInfo) const
|
||
{
|
||
if (IsVertical())
|
||
{
|
||
lstInfo.Append(new TObjInfoUnit(_T("对象类型"), _T("立管")));
|
||
}
|
||
else
|
||
{
|
||
lstInfo.Append(new TObjInfoUnit(_T("对象类型"), _T("管段")));
|
||
}
|
||
|
||
TDbPipePrototype::GetTips(lstInfo);
|
||
if (m_nSection == 0) // 矩形截面
|
||
{
|
||
lstInfo.Append(new TObjInfoUnit(_T("宽度"), Dist2Str(m_dWidth)));
|
||
lstInfo.Append(new TObjInfoUnit(_T("高度"), Dist2Str(m_dHeight)));
|
||
}
|
||
else if ((1 == m_nSection) || (2 == m_nSection)) // 圆、软管截面
|
||
{
|
||
lstInfo.Append(new TObjInfoUnit(_T("直径"), Dist2Str(m_dWidth)));
|
||
}
|
||
// 暂时无,8.0以后添加
|
||
// else if (m_nSection == 3) // 椭圆截面
|
||
// {
|
||
// lstInfo.Append(new TObjInfoUnit(_T("短轴长度"), Dist2Str(m_dWidth)));
|
||
// lstInfo.Append(new TObjInfoUnit(_T("长轴长度"), Dist2Str(m_dHeight)));
|
||
// }
|
||
// else if (m_nSection = 4) // 扁圆截面
|
||
// {
|
||
// lstInfo.Append(new TObjInfoUnit(_T("长度A"), Dist2Str(m_dWidth)));
|
||
// lstInfo.Append(new TObjInfoUnit(_T("长度B"), Dist2Str(m_dHeight)));
|
||
// }
|
||
|
||
double dVelocity = CalVelocity();
|
||
CString csTmp;
|
||
csTmp.Format(_T("%.2f"), dVelocity);
|
||
lstInfo.Append(new TObjInfoUnit(_T("风量"), Dist2Str(m_dCalWeight)));
|
||
lstInfo.Append(new TObjInfoUnit(_T("风速"), csTmp));
|
||
|
||
XStringList lstMaterial;
|
||
if (GetDuctMaterial(lstMaterial) && m_nMaterial>=0 &&
|
||
m_nMaterial<lstMaterial.Length())
|
||
{
|
||
lstInfo.Append(new TObjInfoUnit(_T("材料"),lstMaterial[m_nMaterial]));
|
||
}
|
||
}
|
||
|
||
// 取得夹点说明
|
||
Acad::ErrorStatus TDbDuct::GetGripText(int idx, CString &cs) const
|
||
{
|
||
Acad::ErrorStatus es = TDbPipePrototype::GetGripText(idx, cs);
|
||
return es;
|
||
}
|
||
|
||
|
||
|
||
///////////////////////////Override AcDbEntity///////////////////////////////////
|
||
Acad::ErrorStatus
|
||
TDbDuct::subGetOsnapPoints(AcDb::OsnapMode osnapMode, INT_PTR gsSelectionMark,
|
||
const AcGePoint3d &ptPick, const AcGePoint3d &lastPoint,
|
||
const AcGeMatrix3d &viewXform, AcGePoint3dArray &snapPoints,
|
||
AcDbIntArray &geomIds) const
|
||
{
|
||
assertReadEnabled();
|
||
Acad::ErrorStatus es = Acad::eOk;
|
||
if (!g_nPipeOsnap)
|
||
{
|
||
es = TDbCurveEntity::subGetOsnapPoints(osnapMode, gsSelectionMark, ptPick,
|
||
lastPoint, viewXform, snapPoints, geomIds);
|
||
}
|
||
else
|
||
{
|
||
if (IsVertical()) // 立管
|
||
{
|
||
switch(osnapMode) {
|
||
case AcDb::kOsModeCen:
|
||
case AcDb::kOsModeNode:
|
||
snapPoints.append(GetVerUpCenter());
|
||
snapPoints.append(GetVerLowCenter());
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
else // 水平管,7.6版本以上增加边线的拾取
|
||
{
|
||
es = TEntityBase::GetOsnapPoints(osnapMode, gsSelectionMark, ptPick,
|
||
lastPoint, viewXform, snapPoints, geomIds);
|
||
}
|
||
}
|
||
return es;
|
||
}
|
||
|
||
// 取得所有的夹点,注:有关立管夹点的问题,在此修改
|
||
Acad::ErrorStatus TDbDuct::subGetGripPoints(AcGePoint3dArray& gripPoints,
|
||
AcDbIntArray& osnapModes,
|
||
AcDbIntArray& geomIds) const
|
||
{
|
||
assertReadEnabled();
|
||
Acad::ErrorStatus es = TDbPipePrototype::subGetGripPoints(gripPoints, osnapModes,
|
||
geomIds);
|
||
return es;
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuct::subMoveGripPointsAt(const AcDbIntArray& indices,
|
||
const AcGeVector3d& offset)
|
||
{
|
||
assertWriteEnabled();
|
||
Acad::ErrorStatus es = TDbPipePrototype::subMoveGripPointsAt(indices, offset);
|
||
if (es != Acad::eOk)
|
||
{
|
||
return es;
|
||
}
|
||
|
||
if (objectId().isValid()) // 管线的整体拖拽、夹点拖拽操作,要提供变化给节点
|
||
{
|
||
ApplyChangeToNode();
|
||
}
|
||
return es;
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuct::subMoveStretchPointsAt(const AcDbIntArray &indices,
|
||
const AcGeVector3d &offset)
|
||
{
|
||
assertWriteEnabled();
|
||
Acad::ErrorStatus es = TDbPipePrototype::subMoveStretchPointsAt(indices, offset);
|
||
if (es != Acad::eOk)
|
||
{
|
||
return es;
|
||
}
|
||
|
||
if (objectId().isValid())
|
||
{
|
||
ApplyChangeToNode();
|
||
}
|
||
return es;
|
||
}
|
||
|
||
// 提供管线的移动变化到节点,用于moveGripPointsAt、transformBy中
|
||
void TDbDuct::ApplyChangeToNode(BOOL bSXTT)
|
||
{
|
||
int i(0);
|
||
for (i = 0; i < 2; i++) // 首先处理管线两端的节点、设备
|
||
{
|
||
TPipeSys::PtLoction nSide = (TPipeSys::PtLoction)i;
|
||
XPoint ptSide = GetVertexPt(nSide); // 新坐标
|
||
|
||
OPENOBJ_BEGIN(GetNode(i), AcDb::kForRead, TDbPipeNode, pNode);
|
||
if (pNode != NULL)
|
||
{
|
||
if (pNode->isKindOf(TDbDuctNode::desc())) // 节点
|
||
{
|
||
TDbDuctNode *pDuctNode = TDbDuctNode::cast(pNode);
|
||
TDbDuctNode::DuctNodeType nType = pDuctNode->GetNodeType(); // 节点类型
|
||
if (nType == TDbDuctNode::kStem) // 堵头
|
||
{
|
||
if (pDuctNode->upgradeOpen() == Acad::eOk)
|
||
{
|
||
pDuctNode->SetLocation(ptSide); // 修改m_ptLocation
|
||
pDuctNode->SetILocation(0, ptSide);
|
||
pDuctNode->downgradeOpen();
|
||
}
|
||
}
|
||
else if (nType == TDbDuctNode::kTaoDong) // 掏洞
|
||
{
|
||
SetNode(i, AcDbObjectId::kNull); // 管线节点设置为空
|
||
if (pDuctNode->upgradeOpen() == Acad::eOk)
|
||
{
|
||
pDuctNode->erase(); // 掏洞节点直接被删除
|
||
pDuctNode->downgradeOpen();
|
||
}
|
||
}
|
||
else // 其他
|
||
{
|
||
int nIndex = pDuctNode->FindIdInLink(objectId());
|
||
if (nIndex != -1) // 存在连接关系
|
||
{
|
||
SetNode(i, AcDbObjectId::kNull); // 管线节点设置为空
|
||
if (pDuctNode->upgradeOpen() == Acad::eOk)
|
||
{
|
||
pDuctNode->SetIType(nIndex, 1); // 接口设置为空
|
||
pDuctNode->downgradeOpen();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else if (pNode->isKindOf(THDbEquipment::desc())) // 设备,8.0以后再做处理
|
||
{
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
|
||
if (bSXTT) // 当前正在进行的命令是“生系统图”
|
||
{
|
||
return;
|
||
}
|
||
|
||
for (i = 0; i < m_lstEquipment.Length(); i++) // 再处理附着的设备及节点
|
||
{
|
||
AcDbObjectId id = *m_lstEquipment[i];
|
||
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbPipeNode, pNode);
|
||
if (pNode != NULL)
|
||
{
|
||
if (pNode->isKindOf(TDbDuctNode::desc())) // 掏洞节点
|
||
{
|
||
TDbDuctNode *pDuctNode = TDbDuctNode::cast(pNode);
|
||
if (pDuctNode->upgradeOpen() == Acad::eOk)
|
||
{
|
||
pDuctNode->RemoveInterface(objectId()); // 删除被掏洞接口
|
||
pDuctNode->SetNodeType(TDbDuctNode::kStem);
|
||
pDuctNode->downgradeOpen();
|
||
}
|
||
RemoveEquipment(id);
|
||
i--;
|
||
}
|
||
else if (pNode->isKindOf(THDbEquipment::desc())) // 设备
|
||
{
|
||
THDbEquipment *pEquipment = THDbEquipment::cast(pNode);
|
||
int nCount = pEquipment->GetInterfaceNum();
|
||
for (int j=0; j<nCount; j++)
|
||
{
|
||
AcDbObjectId ductId = pEquipment->GetIPipe(j);
|
||
if (ductId==objectId() && !CanAttachEquipment(*pEquipment, j)) // 断开
|
||
{
|
||
if (pEquipment->upgradeOpen() == Acad::eOk)
|
||
{
|
||
pEquipment->SetIPipe(j, AcDbObjectId::kNull);
|
||
pEquipment->downgradeOpen();
|
||
}
|
||
break;
|
||
RemoveEquipment(id);
|
||
i--;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuct::subTransformBy(const AcGeMatrix3d& xform)
|
||
{
|
||
assertWriteEnabled();
|
||
Acad::ErrorStatus es = TDbPipePrototype::subTransformBy(xform);
|
||
|
||
BOOL bApplyToNode(TRUE),
|
||
bSXTT(FALSE); // 是否提供变化给节点
|
||
if (!!objectId())
|
||
{
|
||
XString &sCmd = GetCurDocData()->m_sCurCommand;
|
||
if (_tcsicmp(sCmd, _T("MIRROR"))==0 || _tcsicmp(sCmd, _T("COPY"))==0 ||
|
||
_tcsicmp(sCmd, _T("COPYCLIP"))==0 || _tcsicmp(sCmd, _T("PASTECLIP"))==0)
|
||
{
|
||
bApplyToNode = FALSE; // 管线的复制、镜像操作,不提供变化给节点
|
||
}
|
||
|
||
bSXTT = _tcsicmp(sCmd, _T("sxtt"))==0;
|
||
}
|
||
|
||
if (objectId().isValid() && bApplyToNode)
|
||
{
|
||
ApplyChangeToNode(bSXTT); // 管线的移动、旋转操作,提供变化给节点
|
||
}
|
||
return es;
|
||
}
|
||
|
||
|
||
|
||
///////////////////////////////存储数据///////////////////////////////////////////
|
||
Acad::ErrorStatus TDbDuct::dwgInFields(AcDbDwgFiler* pFiler)
|
||
{
|
||
assertWriteEnabled();
|
||
Acad::ErrorStatus es = TDbPipePrototype::dwgInFields(pFiler);
|
||
if (es != Acad::eOk)
|
||
{
|
||
return es;
|
||
}
|
||
|
||
Adesk::UInt8 nVer;
|
||
pFiler->readItem(&nVer);
|
||
if (nVer > g_nVersion) // Version is too new
|
||
{
|
||
return Acad::eMakeMeProxy;
|
||
}
|
||
|
||
pFiler->readItem(&m_nSysDrawMod);
|
||
pFiler->readItem(&m_dWidth);
|
||
pFiler->readItem(&m_dHeight);
|
||
pFiler->readItem(&m_dDuctWeight);
|
||
pFiler->readItem(&m_dVDAngle);
|
||
|
||
pFiler->readItem(&m_nMaterial);
|
||
ReadString(pFiler, m_sLabel);
|
||
pFiler->readItem(&m_dSpeedSubMid);
|
||
pFiler->readItem(&m_dSpeedLength);
|
||
|
||
m_lstEquipment.Reset();
|
||
Adesk::UInt8 nCount = 0;
|
||
pFiler->readItem(&nCount);
|
||
for (Adesk::UInt8 i=0; i<nCount; i++)
|
||
{
|
||
AcDbSoftPointerId id;
|
||
pFiler->readItem(&id);
|
||
m_lstEquipment.Append(new AcDbSoftPointerId(id));
|
||
}
|
||
|
||
pFiler->readItem(&m_idDoteLayer);
|
||
|
||
if (nVer > 1) // 7.6
|
||
{
|
||
pFiler->readItem(&m_nSection);
|
||
pFiler->readItem(&m_dFlChuTou);
|
||
pFiler->readItem(&m_dFlThick);
|
||
|
||
Adesk::UInt8 nTmpNum = 0;
|
||
pFiler->readItem(&nTmpNum);
|
||
m_eDQType = (TDbDuct::DuiQiType)nTmpNum;
|
||
pFiler->readItem(&nTmpNum);
|
||
m_eDQSide = (TPipeSys::PtLoction)nTmpNum;
|
||
|
||
pFiler->readItem(&m_dCalWeight);
|
||
pFiler->readItem(&m_nSpare);
|
||
pFiler->readItem(&m_dSpare);
|
||
ReadString(pFiler, m_csSpare);
|
||
m_dVer = 7.6;
|
||
}
|
||
else // 7.5
|
||
{
|
||
m_nSection = IsCircleDuct()?1:0;
|
||
m_dFlChuTou = 100.0;
|
||
m_dFlThick = 50.0;
|
||
|
||
m_eDQType = (TDbDuct::DuiQiType)0;
|
||
m_eDQSide = (TPipeSys::PtLoction)0;
|
||
|
||
m_dCalWeight = 0;
|
||
m_nSpare = 0;
|
||
m_dSpare = 0.0;
|
||
m_csSpare = _T("");
|
||
m_dVer = 7.5;
|
||
}
|
||
return pFiler->filerStatus();
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuct::dwgOutFields(AcDbDwgFiler* pFiler) const
|
||
{
|
||
assertReadEnabled();
|
||
Acad::ErrorStatus es = TDbPipePrototype::dwgOutFields(pFiler);
|
||
if (es != Acad::eOk)
|
||
{
|
||
return es;
|
||
}
|
||
|
||
// if (g_nSaveTArchVer == 7) // 8.0使用
|
||
// {
|
||
// pFiler->writeItem((Adesk::UInt8)2);
|
||
// }
|
||
// else
|
||
// {
|
||
// pFiler->writeItem(g_nVersion);
|
||
// }
|
||
pFiler->writeItem(g_nVersion);
|
||
|
||
pFiler->writeItem(m_nSysDrawMod);
|
||
pFiler->writeItem(m_dWidth);
|
||
pFiler->writeItem(m_dHeight);
|
||
pFiler->writeItem(m_dDuctWeight);
|
||
pFiler->writeItem(m_dVDAngle);
|
||
|
||
pFiler->writeItem(m_nMaterial);
|
||
pFiler->writeItem((const TCHAR *)m_sLabel);
|
||
pFiler->writeItem(m_dSpeedSubMid);
|
||
pFiler->writeItem(m_dSpeedLength);
|
||
|
||
Adesk::UInt8 nCount = (Adesk::UInt8)m_lstEquipment.Length();
|
||
pFiler->writeItem(nCount);
|
||
for (Adesk::UInt8 i = 0; i < nCount; i++)
|
||
{
|
||
pFiler->writeItem(m_lstEquipment[i]);
|
||
}
|
||
|
||
pFiler->writeItem(m_idDoteLayer);
|
||
|
||
if (g_nSaveTArchVer > 6)
|
||
{
|
||
pFiler->writeItem(m_nSection);
|
||
pFiler->writeItem(m_dFlChuTou);
|
||
pFiler->writeItem(m_dFlThick);
|
||
pFiler->writeItem((Adesk::UInt8)m_eDQType);
|
||
pFiler->writeItem((Adesk::UInt8)m_eDQSide);
|
||
|
||
pFiler->writeItem(m_dCalWeight);
|
||
pFiler->writeItem(m_nSpare);
|
||
pFiler->writeItem(m_dSpare);
|
||
pFiler->writeItem((const TCHAR *)m_csSpare);
|
||
}
|
||
return pFiler->filerStatus();
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuct::dxfInFields(AcDbDxfFiler* pFiler)
|
||
{
|
||
assertWriteEnabled();
|
||
Acad::ErrorStatus es = TDbPipePrototype::dxfInFields(pFiler);
|
||
if (es != Acad::eOk)
|
||
return es;
|
||
|
||
if (!pFiler->atSubclassData(_T("TDbDuct")))
|
||
return Acad::eBadDxfSequence;
|
||
|
||
resbuf rb;
|
||
while ((es==Acad::eOk) && ((es=pFiler->readResBuf(&rb))==Acad::eOk))
|
||
{
|
||
switch (rb.restype) {
|
||
case AcDb::kDxfXTextString+1:
|
||
m_sLabel = rb.resval.rstring;
|
||
break;
|
||
case AcDb::kDxfXReal:
|
||
m_dWidth = rb.resval.rreal;
|
||
break;
|
||
case AcDb::kDxfXReal+1:
|
||
m_dHeight = rb.resval.rreal;
|
||
break;
|
||
case AcDb::kDxfXReal+2:
|
||
m_dTextHeight = rb.resval.rreal;
|
||
break;
|
||
case AcDb::kDxfXCoord:
|
||
m_ptLabel = rb.resval.rpoint;
|
||
break;
|
||
default:
|
||
pFiler->pushBackItem();
|
||
es = Acad::eEndOfFile;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (es != Acad::eEndOfFile)
|
||
return Acad::eInvalidResBuf;
|
||
return pFiler->filerStatus();
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuct::dxfOutFields(AcDbDxfFiler* pFiler) const
|
||
{
|
||
Acad::ErrorStatus es = TDbPipePrototype::dxfOutFields(pFiler);
|
||
assert(es == Acad::eOk);
|
||
es = pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbDuct"));
|
||
assert(es == Acad::eOk);
|
||
|
||
pFiler->writeString(AcDb::kDxfXTextString+1, (const TCHAR*)m_sLabel);
|
||
pFiler->writeDouble(AcDb::kDxfXReal, m_dWidth);
|
||
pFiler->writeDouble(AcDb::kDxfXReal+1, m_dHeight);
|
||
pFiler->writeDouble(AcDb::kDxfXReal+2, m_dTextHeight);
|
||
pFiler->writePoint3d(AcDb::kDxfXCoord, m_ptLabel);
|
||
pFiler->writeUInt8(AcDb::kDxfInt8, IsVertical());
|
||
return es;
|
||
}
|
||
|
||
|
||
|
||
////////////////////////////////////处理实体/////////////////////////////////
|
||
// 处理管线打开
|
||
Acad::ErrorStatus TDbDuct::subOpen(AcDb::OpenMode mode)
|
||
{
|
||
Acad::ErrorStatus es = TDbPipePrototype::subOpen(mode);
|
||
if (es==Acad::eOk && g_nCmdReactor!=CMD_UPDATE)
|
||
{
|
||
if (mode==AcDb::kForWrite && database()==acdbCurDwg())
|
||
{
|
||
m_dOldHeight = m_dHeight;
|
||
m_dOldWidth = m_dWidth;
|
||
}
|
||
}
|
||
return es;
|
||
}
|
||
|
||
// 处理管线实体,注:在此处解决阀门比例问题
|
||
Acad::ErrorStatus TDbDuct::subClose()
|
||
{
|
||
Acad::ErrorStatus es = TDbPipePrototype::subClose();
|
||
if (es==Acad::eOk && isModified() && database()==acdbCurDwg())
|
||
{
|
||
for (int i=0; i<m_lstAttachment.Length(); i++) // 修改管径时同时修改阀门比例
|
||
{
|
||
OPENOBJ_BEGIN(*m_lstAttachment[i], AcDb::kForRead, TDbPipeValve, pAttach);
|
||
if (pAttach != NULL)
|
||
{
|
||
BOOL bCanAttach = CanAttach(*pAttach);
|
||
if (bCanAttach)
|
||
{
|
||
double dScale = pAttach->GetYScale(),
|
||
dNewScale = m_dWidth/1000;
|
||
if (fabs(dScale - dNewScale) > 0.001)
|
||
{
|
||
if (pAttach->upgradeOpen() == Acad::eOk)
|
||
{
|
||
pAttach->assertWriteEnabled();
|
||
pAttach->SetYScale(dNewScale);
|
||
pAttach->downgradeOpen();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
}
|
||
return es;
|
||
}
|
||
|
||
// 处理管线删除
|
||
Acad::ErrorStatus TDbDuct::subErase(Adesk::Boolean bErasing)
|
||
{
|
||
Acad::ErrorStatus es = TDbPipePrototype::subErase(bErasing); // 删除附件
|
||
if (es==Acad::eOk && bErasing==Adesk::kTrue && database()==acdbCurDwg())
|
||
{
|
||
int i(0);
|
||
for (i=0; i<2; i++)
|
||
{
|
||
AcDbObjectId id = GetNode(i);
|
||
OPENOBJ_BEGIN(id, AcDb::kForWrite, TDbDuctNode, pDuctNode);
|
||
if (pDuctNode != NULL) // 将风管节点中的本接口的接口类型设置为1(空)
|
||
{
|
||
int nIndex = pDuctNode->FindIdInLink(objectId());
|
||
if (nIndex != -1) // 存在连接关系
|
||
{
|
||
pDuctNode->SetIType(nIndex, 1);
|
||
}
|
||
|
||
if (pDuctNode->Is("TaoDong"))
|
||
{
|
||
int nMain = pDuctNode->GetMainDuctNum();
|
||
if (nMain != nIndex)
|
||
{
|
||
pDuctNode->erase(); // 当支管被删时,掏洞节点应同时被删
|
||
continue;
|
||
}
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
|
||
for (i=0; i<m_lstEquipment.Length(); i++) // 解除与附着设备、接口的连接
|
||
{
|
||
AcDbObjectId &id = *m_lstEquipment[i];
|
||
OPENOBJ_BEGIN(id, AcDb::kForWrite, TDbPipeNode, pNode);
|
||
if (pNode != NULL)
|
||
{
|
||
if (pNode->isKindOf(TDbDuctNode::desc())) // 节点
|
||
{
|
||
TDbDuctNode *pDuctNode = TDbDuctNode::cast(pNode);
|
||
pDuctNode->RemoveInterface(objectId());
|
||
pDuctNode->SetNodeType(TDbDuctNode::kStem);
|
||
continue;
|
||
}
|
||
else if (pNode->isKindOf(THDbEquipment::desc())) // 设备
|
||
{
|
||
THDbEquipment *pEquipment = THDbEquipment::cast(pNode);
|
||
int nCount = pEquipment->GetInterfaceNum();
|
||
for (int j=0; j<nCount; j++)
|
||
{
|
||
const AcDbObjectId &ductId = pEquipment->GetIPipe(j);
|
||
if (ductId == objectId())
|
||
{
|
||
pEquipment->SetIPipe(j, AcDbObjectId::kNull);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
}
|
||
return es;
|
||
}
|
||
|
||
|
||
|
||
////////////////////////////////////绘图部分/////////////////////////////////
|
||
Acad::ErrorStatus TDbDuct::ExplodeOrDraw2d(XExplodeDraw &dc) const
|
||
{
|
||
// cet 2016.10.17 add 图层关闭时,实体不显示,不进行绘制(打印时,也不会绘制)
|
||
AcDbLayerTableRecordPointer player(this->layerId(), AcDb::kForRead);
|
||
if (player.openStatus() == Acad::eOk && player->isOff())
|
||
{
|
||
return Acad::eOk;
|
||
}
|
||
Acad::ErrorStatus es = Acad::eOk;
|
||
if (!IsVisibleEntity(this)) // 查询管线系统的显示属性
|
||
{
|
||
return es;
|
||
}
|
||
|
||
BOOL bIsWeight = g_bPipeWeight; // 是否管线加粗(针对非垂直管线)
|
||
if (dc.IsFullExplode())
|
||
{
|
||
AcDbDatabase* pDb = database();
|
||
if (pDb != NULL)
|
||
{
|
||
AcDbDictionary* pRootDict = NULL;
|
||
es = pDb->getNamedObjectsDictionary(pRootDict, AcDb::kForRead);
|
||
assert(es == Acad::eOk);
|
||
|
||
AcDbObject* pObj = NULL;
|
||
es = pRootDict->getAt(g_sDbPsConfig, pObj, AcDb::kForRead);
|
||
if (es == Acad::eOk)
|
||
{
|
||
bIsWeight = ((TDbPsConfig *)pObj)->IsLineWeight();
|
||
pObj->close();
|
||
}
|
||
pRootDict->close();
|
||
}
|
||
}
|
||
|
||
if (IsVertical())
|
||
{
|
||
es = DrawVerDuct2d(dc); // 立管
|
||
}
|
||
else
|
||
{
|
||
es = DrawHorDuct2d(dc); // 非立管
|
||
}
|
||
|
||
if (es == Acad::eOk && IsShowPropertyText() && IsModel())
|
||
{
|
||
es = DrawPropertyText(dc); // 在管线中点位置显示管线的属性(针对非立管)
|
||
}
|
||
|
||
if (IsDrawLabel()) // 绘制非立管管径标注
|
||
{
|
||
DrawLabelText(dc);
|
||
}
|
||
return es;
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuct::DrawVerDuct2d(XExplodeDraw &dc) const // 立管
|
||
{
|
||
XPoint ptCenter(GetStartPoint().x, GetEndPoint().y);
|
||
if ((1 == m_nSysDrawMod) || (2 == m_nSection)) // 单线图或软管
|
||
{
|
||
dc << ptCenter;
|
||
return Acad::eOk;
|
||
}
|
||
|
||
XCurveSegment seg1, seg2; // 圆线
|
||
XPoly2D rectPoly, vDuctPoly; // 方线
|
||
|
||
// 1、判断截面形状,并获取绘制线
|
||
if (m_nSection == 1) // 圆截面
|
||
{
|
||
XCircle cirIn(ptCenter, m_dWidth/2);
|
||
seg1 = cirIn; // 圆外线
|
||
|
||
XVector3D vtTmp1(1, 1, 0), vtTmp2(-1, 1, 0);
|
||
vtTmp1.Normalize();
|
||
vtTmp2.Normalize();
|
||
vtTmp1.Scale(m_dWidth/2);
|
||
vtTmp2.Scale(m_dWidth/4);
|
||
XPoint pt1 = ptCenter + vtTmp1,
|
||
pt2 = ptCenter + vtTmp2,
|
||
pt3 = ptCenter - vtTmp1,
|
||
pt4 = pt2 + vtTmp2;
|
||
XArc arc(pt1, pt2, pt3);
|
||
seg2 = arc; // 圆内线
|
||
}
|
||
else if (m_nSection == 0) // 方截面
|
||
{
|
||
::GetSquare(ptCenter, GetVDAngle(), m_dWidth, m_dHeight, &rectPoly, &vDuctPoly);
|
||
}
|
||
// else if (m_nSection == 3) // 椭圆截面
|
||
// {
|
||
// }
|
||
// else if (m_nSection == 4) // 扁圆截面
|
||
// {
|
||
// }
|
||
|
||
// 2、判断绘制情况:(1)虚线、实线,(2)是否绘制方内线
|
||
int nDrawMod(0); // 实线,有内线
|
||
AcDbObjectId upNodeId = GetVerUpNode();
|
||
OPENOBJ_BEGIN(upNodeId, AcDb::kForRead, TDbPipeNode, pNode);
|
||
if (pNode != NULL)
|
||
{
|
||
if (pNode->isKindOf(THDbEquipment::desc()))
|
||
{
|
||
nDrawMod = 1; // 虚线,无内线
|
||
}
|
||
else if (pNode->isKindOf(TDbDuctNode::desc()))
|
||
{
|
||
TDbDuctNode *pDuctNode = TDbDuctNode::cast(pNode);
|
||
if (!pDuctNode->Is(_T("Stem")))
|
||
{
|
||
nDrawMod = 1;
|
||
}
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
|
||
AcDbObjectId idLineTypeOld;
|
||
if (nDrawMod == 1) // 注:立管被遮挡
|
||
{
|
||
idLineTypeOld = dc.GetLineTypeId();
|
||
AcDbObjectId idDashType = InitLineType(_T("DASH"), database());
|
||
if (idDashType.isValid())
|
||
{
|
||
dc.SetLineType(idDashType);
|
||
}
|
||
}
|
||
|
||
double dWeight = GetPScale()*m_dDuctWeight;
|
||
if (m_nSection == 1) // 圆管
|
||
{
|
||
if (g_bPipeWeight && (nDrawMod==0))
|
||
{
|
||
DrawWeight(dc, dWeight, seg1, colorIndex(), linetypeScale());
|
||
}
|
||
else
|
||
{
|
||
dc << seg1;
|
||
}
|
||
|
||
if (nDrawMod == 0)
|
||
{
|
||
dc << seg2;
|
||
}
|
||
}
|
||
else if (m_nSection == 0) // 方管
|
||
{
|
||
if (g_bPipeWeight && (nDrawMod==0))
|
||
{
|
||
DrawWeight(dc, dWeight, rectPoly, colorIndex(), linetypeScale());
|
||
}
|
||
else
|
||
{
|
||
dc << rectPoly;
|
||
}
|
||
|
||
if (nDrawMod == 0)
|
||
{
|
||
dc << vDuctPoly;
|
||
}
|
||
}
|
||
|
||
if (nDrawMod == 1)
|
||
{
|
||
dc.SetLineType(idLineTypeOld);
|
||
}
|
||
return Acad::eOk;
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuct::DrawHorDuct2d(XExplodeDraw &dc) const // 水平管
|
||
{
|
||
XCurveSegment cvHide;
|
||
GetHideCurve(cvHide); // 考虑遮挡的当前曲线
|
||
|
||
DList<XCurveSegment> lstCurve; // 存储打断后的曲线(中心线)
|
||
if (g_bBreakPipe) // 打断
|
||
{
|
||
GetBrokenCurves(cvHide, lstCurve); // 获取打断后的曲线
|
||
}
|
||
else
|
||
{
|
||
lstCurve.Append(new XCurveSegment(cvHide));
|
||
}
|
||
|
||
int i(0),
|
||
nCount = lstCurve.Length();
|
||
double dWeight = GetPScale()*m_dDuctWeight;
|
||
TPipeSys::ModelType nModelType = GetModelType();
|
||
if (m_nSysDrawMod==1 || nModelType==TPipeSys::kSystem ||
|
||
nModelType==TPipeSys::kPrinciple) // 1、绘制中线的情况
|
||
{
|
||
for (i=0; i<nCount; i++) // 单线,系统图,在边线层画中心线
|
||
{
|
||
XCurveSegment &seg = *lstCurve[i];
|
||
BOOL bWeight = nModelType==TPipeSys::kSystem ||
|
||
nModelType==TPipeSys::kPrinciple;
|
||
if (g_bPipeWeight && bWeight) // 单线图不加粗
|
||
{
|
||
DrawWeight(dc, dWeight, seg, colorIndex(), linetypeScale());
|
||
}
|
||
else
|
||
{
|
||
dc << seg;
|
||
}
|
||
}
|
||
return Acad::eOk;
|
||
}
|
||
|
||
if (m_nSysDrawMod == 2) // 三线图,在中心线层绘制中心线
|
||
{
|
||
AcDbObjectId idLayerOld = dc.GetLayerId(), // 保留原来的值
|
||
idLineTypeOld = dc.GetLineTypeId();
|
||
AcDbObjectId idDoteLayer = m_idDoteLayer;
|
||
if (idDoteLayer.isValid())
|
||
{
|
||
dc.SetLayer(idDoteLayer);
|
||
}
|
||
dc.SetColorLayer(colorIndex(), idDoteLayer);
|
||
|
||
AcDbObjectId idDashType;
|
||
OPENOBJ_BEGIN(idDoteLayer, AcDb::kForRead, AcDbLayerTableRecord, pRec);
|
||
if (pRec != NULL)
|
||
{
|
||
idDashType = pRec->linetypeObjectId();
|
||
dc.SetLineType(idDashType);
|
||
}
|
||
OPENOBJ_END();
|
||
|
||
for (i = 0; i < nCount; i++)
|
||
{
|
||
XCurveSegment &seg = *lstCurve[i];
|
||
dc << seg; // 绘制中心线
|
||
}
|
||
dc.SetLayer(idLayerOld);
|
||
dc.SetColorLayer(colorIndex(), idLayerOld);
|
||
dc.SetLineType(idLineTypeOld);
|
||
}
|
||
|
||
|
||
XCurveSegment segUp, segDown;
|
||
XDirectionCurve segDir(cvHide.StartPoint(), cvHide.EndPoint(), cvHide.GetBulge());
|
||
segUp = segDir.Offset(m_dWidth/2, LS_FINITE);
|
||
segDown = segDir.Offset(-m_dWidth/2, LS_FINITE);
|
||
|
||
DList<XCurveSegment> lstCurve1;
|
||
if (g_bBreakPipe) // 2、绘制风管上线
|
||
{
|
||
GetBrokenCurves(segUp, lstCurve1);
|
||
}
|
||
else
|
||
{
|
||
lstCurve1.Append(new XCurveSegment(segUp));
|
||
}
|
||
|
||
nCount = lstCurve1.Length();
|
||
for (i=0; i<nCount; i++)
|
||
{
|
||
XCurveSegment &seg1 = *lstCurve1[i];
|
||
if (g_bPipeWeight)
|
||
{
|
||
DrawWeight(dc, dWeight, seg1, colorIndex(), linetypeScale());
|
||
}
|
||
else
|
||
{
|
||
dc << seg1;
|
||
}
|
||
}
|
||
|
||
DList<XCurveSegment> lstCurve2;
|
||
if (g_bBreakPipe) // 3、绘制风管下线
|
||
{
|
||
GetBrokenCurves(segDown, lstCurve2);
|
||
}
|
||
else
|
||
{
|
||
lstCurve2.Append(new XCurveSegment(segDown));
|
||
}
|
||
|
||
nCount = lstCurve2.Length();
|
||
for (i=0; i<lstCurve2.Length(); i++)
|
||
{
|
||
XCurveSegment &seg2 = *lstCurve2[i];
|
||
if (g_bPipeWeight)
|
||
{
|
||
DrawWeight(dc, dWeight, seg2, colorIndex(), linetypeScale());
|
||
}
|
||
else
|
||
{
|
||
dc << seg2;
|
||
}
|
||
}
|
||
return Acad::eOk;
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuct::DrawLabelText(XExplodeDraw &dc) const // 标注
|
||
{
|
||
XPoint ptOnThis;
|
||
if (ProjectToMe(m_ptLabel, ptOnThis))
|
||
{
|
||
double dRotation(0);
|
||
if (!IsVertical()) // 不是立管
|
||
{
|
||
if (Is(CURVE_LINE))
|
||
{
|
||
dRotation = Direction(ptOnThis);
|
||
}
|
||
else if (Is(CURVE_ARC))
|
||
{
|
||
XPoint ptCenter;
|
||
GetArc().Center(ptCenter);
|
||
dRotation = ads_angle(ptCenter, m_ptLabel) + PI/2;
|
||
}
|
||
|
||
dRotation = CT_std_angle(dRotation);
|
||
if (fabs(dRotation) < 1.0E-6)
|
||
{
|
||
dRotation = 0;
|
||
}
|
||
if (fabs(dRotation-PI/2) < 1.0E-6)
|
||
{
|
||
dRotation = PI/2;
|
||
}
|
||
if (fabs(dRotation-PI/2*3) < 1.0E-5)
|
||
{
|
||
dRotation = PI/2*3;
|
||
}
|
||
if ((dRotation>(PI/2+1.0E-6) && dRotation<(PI*3/2+1.0E-6)))
|
||
{
|
||
dRotation = CT_std_angle(dRotation + PI);
|
||
}
|
||
}
|
||
|
||
AcDbObjectId idLayerOld = dc.GetLayerId(),
|
||
idLayer = m_idLabelLayer;
|
||
// if (m_idLabelLayer.isValid())
|
||
// {
|
||
// dc.SetLayer(m_idLabelLayer);
|
||
// }
|
||
OPENOBJ_BEGIN(m_idLabelLayer, AcDb::kForRead, AcDbLayerTableRecord, pRec);
|
||
if (pRec != NULL)
|
||
{
|
||
dc.SetLayer(m_idLabelLayer);
|
||
}
|
||
OPENOBJ_END();
|
||
dc.SetColorLayer(colorIndex(), idLayer);
|
||
|
||
TDbText text;
|
||
text.setPropertiesFrom(this);
|
||
text.setLayer(m_idLabelLayer);
|
||
text.SetStyleId(m_idTextStyle);
|
||
text.SetText(GetLabelText());
|
||
text.SetRotation(dRotation);
|
||
text.SetLocation(XPoint(m_ptLabel.x, m_ptLabel.y, 0));
|
||
text.SetHeight(m_dTextHeight);
|
||
text.SetAlignment(XExplodeDraw::kMiddleCenter);
|
||
|
||
TPushProperty vProp(&text, dc);
|
||
if (dc.IsFullExplode())
|
||
{
|
||
text.ExplodeOrDraw2d(dc);
|
||
}
|
||
else
|
||
{
|
||
dc.DrawEntity(text);
|
||
}
|
||
dc.SetColorLayer(colorIndex(), idLayerOld);
|
||
dc.SetLayer(idLayerOld);
|
||
}
|
||
return Acad::eOk;
|
||
}
|
||
|
||
|
||
Acad::ErrorStatus TDbDuct::ExplodeOrDraw3d(XExplodeDraw &dc) const
|
||
{
|
||
// sg delete,防止三维下炸开会崩溃
|
||
// if (!dc.IsFullExplode()) // 如果是动态预演,则简单绘制
|
||
// {
|
||
// AcGiCommonDraw* dcCommon = ((XAcGiViewDraw &)dc).GetCommonDraw();
|
||
// if (dcCommon->isDragging())
|
||
// {
|
||
// XCurveSegment segTmp = (*this);
|
||
// dc << segTmp;
|
||
// return Acad::eOk;
|
||
// }
|
||
// }
|
||
|
||
if (GetModelType()==TPipeSys::kSystem || GetModelType()==TPipeSys::kPrinciple)
|
||
{
|
||
XCurveSegment segTmp = (*this);
|
||
dc << segTmp;
|
||
return Acad::eOk; // 系统和原理图
|
||
}
|
||
|
||
////////////////模型图////////////////
|
||
double dFThick = m_dFlThick * 0.5; // 获取管线两端法兰遮挡管线的宽度
|
||
if (fabs(dFThick) < 1.0E-5)
|
||
{
|
||
dFThick = 2; // 通常钢板厚度为4
|
||
}
|
||
|
||
XPoint ptS(GetStartPoint()), ptE(GetEndPoint());
|
||
TPipeSys::PtLoction nSide = TPipeSys::kStartPt;
|
||
XVector3D vtS = GetDirection(ptS, nSide), // 切线方向
|
||
vtE = GetDirection(ptE, nSide);
|
||
vtS.Normalize();
|
||
vtE.Normalize();
|
||
vtS.Scale(dFThick);
|
||
vtE.Scale(dFThick);
|
||
ptS = ptS + vtS; // 绘制时的起、止点,扣除了法兰遮挡
|
||
ptE = ptE + vtE;
|
||
|
||
BOOL bIsOk(TRUE);
|
||
DList<X3DFace> faces;
|
||
if (IsVertical()) // 立管
|
||
{
|
||
if (m_nSection == 1) // 圆管
|
||
{
|
||
if (!DrawColumn3d(ptS, vtS, ptE, vtS, faces))
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
}
|
||
else // 矩形
|
||
{
|
||
XPoly2D pts1, pts2;
|
||
::GetSquare(ptS, m_dVDAngle, m_dWidth, m_dHeight, &pts1, NULL); // 截面
|
||
::GetSquare(ptE, m_dVDAngle, m_dWidth, m_dHeight, &pts2, NULL);
|
||
if (pts1.Length()!=4 || pts2.Length()!=4)
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
X3DFace face = ::GetFace1(*pts1[0], *pts1[1], *pts1[2], *pts1[3]);
|
||
faces.Append(new X3DFace(face));
|
||
face = ::GetFace1(*pts2[0], *pts2[1], *pts2[2], *pts2[3]);
|
||
faces.Append(new X3DFace(face));
|
||
face = ::GetFace1(*pts1[0], *pts1[1], *pts2[1], *pts2[0]);
|
||
faces.Append(new X3DFace(face));
|
||
face = ::GetFace1(*pts1[3], *pts1[2], *pts2[2], *pts2[3]);
|
||
faces.Append(new X3DFace(face));
|
||
face = ::GetFace1(*pts1[0], *pts1[3], *pts2[3], *pts2[0]);
|
||
faces.Append(new X3DFace(face));
|
||
face = ::GetFace1(*pts1[1], *pts1[2], *pts2[2], *pts2[1]);
|
||
faces.Append(new X3DFace(face));
|
||
}
|
||
}
|
||
else if (Is(CURVE_ARC)) // 弧管
|
||
{
|
||
XPoint ptArc; // 弧中点,但在3D状态下不直接用,防止标高出错
|
||
XCurveSegment seg = GetCurve(); // 管段
|
||
XArc arcSeg = seg.GetArc();
|
||
arcSeg.MidPoint(ptArc);
|
||
|
||
XVector3D vecS(-vtS.x, -vtS.y, -vtS.z),
|
||
vecE(-vtE.x, -vtE.y, -vtE.z);
|
||
XPointList pts;
|
||
::GetTHSplitPts(ptS, ptE, vecS, vecE, g_nSplitNum, pts, 2, ptArc);
|
||
int nLen = pts.Length(); // 切割成若干小圆柱或立方体
|
||
if (nLen != g_nSplitNum+2)
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
AcGeCircArc3d arc(*pts[0], *pts[g_nSplitNum/2], *pts[g_nSplitNum+1]);
|
||
for (int i=0; i<g_nSplitNum+1; i++) // 循环处理弧段
|
||
{
|
||
AcGeLine3d tangentL1, tangentL2;
|
||
if (arc.tangent(pts[i]->AsAcGePoint3d(), tangentL1)==Adesk::kFalse ||
|
||
arc.tangent(pts[i+1]->AsAcGePoint3d(), tangentL2)==Adesk::kFalse)
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
BOOL bSHow1 = i==0,
|
||
bSHow2 = i==g_nSplitNum;
|
||
AcGeVector3d vt1 = tangentL1.direction(),
|
||
vt2 = tangentL2.direction();
|
||
if (m_nSection == 1) // 圆管
|
||
{
|
||
XVector3D __vt2(vt2);
|
||
bIsOk = DrawColumn3d(*pts[i], XVector3D(vt1), *pts[i+1],
|
||
__vt2, faces, bSHow1, bSHow2);
|
||
}
|
||
else // 矩形
|
||
{
|
||
XVector3D __vt2(vt2);
|
||
bIsOk = DrawCube3d(*pts[i], XVector3D(vt1), *pts[i+1],
|
||
__vt2, faces, bSHow1, bSHow2);
|
||
}
|
||
|
||
if (!bIsOk)
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
}
|
||
}
|
||
else // 直管
|
||
{
|
||
if (m_nSection == 1) // 圆管
|
||
{
|
||
bIsOk = DrawColumn3d(ptS, vtS, ptE, vtS, faces);
|
||
}
|
||
else // 矩形
|
||
{
|
||
bIsOk = DrawCube3d(ptS, vtS, ptE, vtS, faces);
|
||
}
|
||
|
||
if (!bIsOk)
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
}
|
||
|
||
int nCount = faces.Length();
|
||
for (int k=0; k<nCount; k++)
|
||
{
|
||
X3DFace face = *faces[k];
|
||
dc << face;
|
||
}
|
||
return Acad::eOk;
|
||
}
|
||
|
||
BOOL TDbDuct::DrawCube3d(XPoint pt1, XVector3D vt1, XPoint pt2, XVector3D &vt2,
|
||
DList<X3DFace> &faces, BOOL bShow1, BOOL bShow2) const
|
||
{
|
||
XPointList pts1, pts2;
|
||
::GetDuctSidePts(pt1, m_dWidth, m_dHeight, vt1, pts1);
|
||
::GetDuctSidePts(pt2, m_dWidth, m_dHeight, vt2, pts2);
|
||
if (pts1.Length()!=4 || pts2.Length()!=4)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
X3DFace face;
|
||
face = ::GetFace1(*pts1[0], *pts1[1], *pts2[1], *pts2[0], bShow1, TRUE, bShow2);
|
||
faces.Append(new X3DFace(face));
|
||
face = ::GetFace1(*pts1[0], *pts1[3], *pts2[3], *pts2[0], bShow1, TRUE, bShow2);
|
||
faces.Append(new X3DFace(face));
|
||
face = ::GetFace1(*pts1[3], *pts1[2], *pts2[2], *pts2[3], bShow1, TRUE, bShow2);
|
||
faces.Append(new X3DFace(face));
|
||
face = ::GetFace1(*pts1[1], *pts1[2], *pts2[2], *pts2[1], bShow1, TRUE, bShow2);
|
||
faces.Append(new X3DFace(face));
|
||
|
||
if (bShow1) // 起点面
|
||
{
|
||
face = ::GetFace1(*pts1[0], *pts1[1], *pts1[2], *pts1[3]);
|
||
faces.Append(new X3DFace(face));
|
||
}
|
||
if (bShow2) // 终点面
|
||
{
|
||
face = ::GetFace1(*pts2[0], *pts2[1], *pts2[2], *pts2[3]);
|
||
faces.Append(new X3DFace(face));
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
BOOL TDbDuct::DrawColumn3d(XPoint pt1, XVector3D vt1, XPoint pt2, XVector3D &vt2,
|
||
DList<X3DFace> &faces, BOOL bShow1, BOOL bShow2) const
|
||
{
|
||
BOOL bIsOk = ::GetColumn3DFaces(pt1, m_dWidth/2.0, vt1, pt2, m_dWidth/2.0,
|
||
vt2, faces, g_nSplitNum, 4, bShow1, bShow2, bShow1, bShow2);
|
||
return bIsOk;
|
||
}
|
||
|
||
|
||
|
||
///////////////////////////Override TDbPipePrototype//////////////////////////
|
||
XExtent TDbDuct::GetExtent() const
|
||
{
|
||
if (IsVertical())
|
||
{
|
||
if (m_nSection == 1) // 圆
|
||
{
|
||
return XExtent(m_dWidth, m_dWidth);
|
||
}
|
||
if (m_nSection == 0) // 方
|
||
{
|
||
return XExtent(m_dWidth, m_dHeight);
|
||
}
|
||
}
|
||
return TDbPipePrototype::GetExtent();
|
||
}
|
||
|
||
XExtent TDbDuct::GetOldExtent() const
|
||
{
|
||
if (IsVertical()) // 立管
|
||
{
|
||
if (m_nSection == 1) // 圆
|
||
{
|
||
return XExtent(m_dOldWidth, m_dOldWidth);
|
||
}
|
||
if (m_nSection == 0) // 方
|
||
{
|
||
return XExtent(m_dOldWidth, m_dOldHeight);
|
||
}
|
||
}
|
||
|
||
return TDbPipePrototype::GetOldExtent(); // 非立管
|
||
}
|
||
|
||
int TDbDuct::GetExtend(XPoint &low, XPoint &up) const
|
||
{
|
||
if (!IsVertical()) // 非立管
|
||
{
|
||
return TDbPipePrototype::GetExtend(low, up);
|
||
}
|
||
|
||
low = up = StartPoint(); // 立管
|
||
XExtent ex = GetExtent();
|
||
ex /= 2;
|
||
low -= ex;
|
||
up += ex;
|
||
return RTNORM;
|
||
}
|
||
|
||
|
||
XString TDbDuct::GetLabelText() const
|
||
{
|
||
XString sLabel = m_sLabel;
|
||
return sLabel;
|
||
}
|
||
|
||
void TDbDuct::ApplyDnDiameterChangeToLabel()
|
||
{
|
||
for (int i=0; i<m_lstAttachment.Length(); i++)
|
||
{
|
||
OPENOBJ_BEGIN(*m_lstAttachment[i], AcDb::kForRead, TDbPipeLabel, pLabel);
|
||
if (pLabel != NULL)
|
||
{
|
||
double dWide = GetWidth(),
|
||
dHigh = GetHeight();
|
||
if (pLabel->GetPipeType()!=TDbPipeLabel::kDuct ||
|
||
dWide!=pLabel->GetPipeWidth() || dHigh!= pLabel->GetPipeHeight())
|
||
{
|
||
if (pLabel->upgradeOpen() == Acad::eOk)
|
||
{
|
||
pLabel->assertWriteEnabled();
|
||
pLabel->SetPipeType(TDbPipeLabel::kDuct);
|
||
pLabel->SetPipeWidth(dWide);
|
||
pLabel->SetPipeHeight(dHigh);
|
||
pLabel->downgradeOpen();
|
||
}
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
}
|
||
|
||
void TDbDuct::ResetDrawSpeed()
|
||
{
|
||
assertWriteEnabled();
|
||
double dSpeedLength(0), // 初始化
|
||
dSpeedSubMid(0);
|
||
OPENOBJ_BEGIN(GetNode(1), AcDb::kForRead, TDbDuctNode, pNode);
|
||
if (pNode != NULL)
|
||
{
|
||
if (pNode->IsHidePipe())
|
||
{
|
||
double dWidth = m_dFlThick*0.5; // 是否节点遮挡管线
|
||
if (dWidth > 1.0E-3)
|
||
{
|
||
dSpeedLength -= dWidth;
|
||
dSpeedSubMid -= dWidth/2;
|
||
}
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
|
||
OPENOBJ_BEGIN(GetNode(0), AcDb::kForRead, TDbDuctNode, pNode);
|
||
if (pNode != NULL)
|
||
{
|
||
if (pNode->IsHidePipe())
|
||
{
|
||
double dWidth = m_dFlThick*0.5; // 是否节点遮挡管线
|
||
if (dWidth > 1.0E-3)
|
||
{
|
||
dSpeedLength -= dWidth;
|
||
dSpeedSubMid += dWidth/2;
|
||
}
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
|
||
if (fabs(dSpeedLength)>1.0E-3 || fabs(dSpeedSubMid)>1.0E-3)
|
||
{
|
||
XCurveSegment cv = GetCurve();
|
||
cv.SetElevation(0); // 设置为二维,z=0
|
||
if (cv.Is(CURVE_ARC)) // 注:本版本弧管不支持加速
|
||
{
|
||
m_dSpeedLength = 0;
|
||
m_dSpeedSubMid = 0;
|
||
}
|
||
else
|
||
{
|
||
double dLength = cv.GetLength();
|
||
m_dSpeedLength = dLength + dSpeedLength;
|
||
m_dSpeedSubMid = dLength/2 + dSpeedSubMid;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
m_dSpeedLength = 0;
|
||
m_dSpeedSubMid = 0;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
//////////////////////////Renew TDbPipePrototype///////////////////////////////
|
||
// 判断立管的上节点是否连接了非立管
|
||
BOOL TDbDuct::IsUpPipesOk() const
|
||
{
|
||
if (!IsVertical())
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
AcDbObjectId upNodeId = GetVerUpNode(); // 上节点
|
||
OPENOBJ_BEGIN(upNodeId, AcDb::kForRead, TDbDuctNode, pNode);
|
||
if (pNode != NULL)
|
||
{
|
||
int nLen = pNode->GetInterfaceNum();
|
||
if (nLen > 1) // 至少连接了一个立管
|
||
{
|
||
for (int i=0; i<nLen; i++)
|
||
{
|
||
if (pNode->GetIPipe(i) != objectId())
|
||
{
|
||
OPENOBJ_BEGIN(pNode->GetIPipe(i), AcDb::kForRead, TDbDuct, pDuct);
|
||
if (pDuct!=NULL && !pDuct->IsVertical())
|
||
{
|
||
return TRUE;
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
return FALSE;
|
||
}
|
||
|
||
// 立管上节点连接的管线中,非立管的连接点
|
||
void TDbDuct::GetUpPipesPt(XPointList &pts) const
|
||
{
|
||
pts.Reset();
|
||
if (!IsUpPipesOk())
|
||
{
|
||
return;
|
||
}
|
||
|
||
AcDbObjectId upNodeId = GetVerUpNode();
|
||
OPENOBJ_BEGIN(upNodeId, AcDb::kForRead, TDbDuctNode, pNode);
|
||
if (pNode != NULL)
|
||
{
|
||
int nLen = pNode->GetInterfaceNum();
|
||
for (int i=0; i<nLen; i++)
|
||
{
|
||
XVector3D vt = pNode->GetIDirection(i);
|
||
vt.Normalize();
|
||
if (fabs(vt.x)>1.0E-6 || fabs(vt.y)>1.0E-6)
|
||
{
|
||
XPoint ptTmp = pNode->GetILocation(i);
|
||
pts.Append(new XPoint(ptTmp));
|
||
}
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
|
||
// 立管上节点连接的管线中,非立管的管径
|
||
AcGeDoubleArray TDbDuct::GetUpPipesWidth() const
|
||
{
|
||
AcGeDoubleArray widths;
|
||
if (!IsUpPipesOk())
|
||
{
|
||
return widths;
|
||
}
|
||
|
||
AcDbObjectId upNodeId = GetVerUpNode();
|
||
OPENOBJ_BEGIN(upNodeId, AcDb::kForRead, TDbDuctNode, pNode);
|
||
if (pNode != NULL)
|
||
{
|
||
int nLen = pNode->GetInterfaceNum();
|
||
for (int i=0; i<nLen; i++)
|
||
{
|
||
XVector3D vt = pNode->GetIDirection(i);
|
||
vt.Normalize();
|
||
if (fabs(vt.x)>1.0E-6 || fabs(vt.y)>1.0E-6)
|
||
{
|
||
widths.append(pNode->GetIWidth(i));
|
||
}
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
return widths;
|
||
}
|
||
|
||
// 非立管的向量
|
||
void TDbDuct::GetUpPipesVec(DList<XVector3D> &vts) const
|
||
{
|
||
if (!IsUpPipesOk())
|
||
{
|
||
return;
|
||
}
|
||
|
||
AcDbObjectId upNodeId = GetVerUpNode();
|
||
OPENOBJ_BEGIN(upNodeId, AcDb::kForRead, TDbDuctNode, pNode);
|
||
if (pNode != NULL)
|
||
{
|
||
int nLen = pNode->GetInterfaceNum();
|
||
for (int i=0; i<nLen; i++)
|
||
{
|
||
XVector3D vt = pNode->GetIDirection(i);
|
||
if (fabs(vt.x)>1.0E-6 || fabs(vt.y)>1.0E-6)
|
||
{
|
||
vts.Append(new XVector3D(vt));
|
||
}
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
|
||
|
||
//////////////////////////增加连接件到当前数据库///////////////////////////////
|
||
// 增加节点到当前数据库,ids-该节点自动连接的管线
|
||
AcDbObjectId TDbDuct::AddNodeToDb(const XPoint &ptAt, const DList<AcDbObjectId> &ids,
|
||
const AcDbIntArray &types, const int &nMainDuct)
|
||
{
|
||
int nLen = ids.Length();
|
||
if (nLen < 1)
|
||
{
|
||
return AcDbObjectId::kNull;
|
||
}
|
||
|
||
Adesk::UInt8 nMode = 0; // 传给实体
|
||
double dParam1(1.0), dParam2(0.0);
|
||
TDbDuctNode::DuctNodeType nType =
|
||
::GetNodeType(AcDbObjectId::kNull, ptAt, types, ids); // 节点类型
|
||
int nLink = ::GetDNodeConfig(nType, nMode, dParam1, dParam2); // 获取绘制参数
|
||
if (nType==TDbDuctNode::kTaoDong && nLink!=13)
|
||
{
|
||
BOOL bVDuct1 = ::IsVerDuct(AcDbObjectId::kNull, ids[0], types[0]),
|
||
bVDuct2 = ::IsVerDuct(AcDbObjectId::kNull, ids[1], types[1]);
|
||
if (bVDuct1 || bVDuct2)
|
||
{
|
||
nMode = 13; // 立管一律用样式13
|
||
}
|
||
}
|
||
|
||
TDbDuctNode* pNode = new TDbDuctNode;
|
||
pNode->SetNodeType(nType);
|
||
|
||
Adesk::UInt8 nDrawMod = GetSysDrawMod();
|
||
if (nDrawMod==1 && (GetModelType()==TPipeSys::kSystem ||
|
||
GetModelType()==TPipeSys::kPrinciple))
|
||
{
|
||
nDrawMod = 4; // 系统图
|
||
}
|
||
pNode->SetSysDrawMod(nDrawMod);
|
||
pNode->SetDrawMod(nMode); // 注:主要考虑到打断新生成的三、四通
|
||
pNode->SetDrawParam(dParam1);
|
||
pNode->SetDrawParam2(dParam2);
|
||
pNode->SetXMWNum((Adesk::UInt8)dParam2);
|
||
pNode->SetMainDuctNum(nMainDuct);
|
||
pNode->SetLocation(ptAt); // 死机处
|
||
pNode->SetLinkType((Adesk::UInt8)nLink);
|
||
pNode->UpdateInterface(GetSysType(), ptAt, ids, types);
|
||
|
||
TCHAR *layer;
|
||
layer = this->layer();
|
||
TCHAR szLayer[256]; // 图层
|
||
_tcscpy(szLayer, layer);
|
||
pNode->setLayer(szLayer);
|
||
pNode->setColor(AcCmColor());
|
||
pNode->setLinetype(this->linetype()); // 线型
|
||
pNode->SetDoteLayer(m_idDoteLayer);
|
||
pNode->SetFlangeLayer(::InitLayer(GetDuctFLLayerName(this->GetSysType()), database()));
|
||
AcDbObjectId id = AddToCurrentSpace(pNode, Adesk::kTrue);
|
||
delete []layer;
|
||
return id;
|
||
}
|
||
|
||
// 获取风管法兰图层名
|
||
CString GetDuctFLLayerName(const TPipeSys::SysType st)
|
||
{
|
||
int nIndex = (int)st - 50;
|
||
if (nIndex<0 || nIndex>5)
|
||
{
|
||
return CString();
|
||
}
|
||
|
||
CString csLayer[] = {LAYER_DUCT_SUPPLYFL, LAYER_DUCT_RETURNFL, LAYER_DUCT_FRESHFL,
|
||
LAYER_DUCT_VENTFL, LAYER_DUCT_SMOKEPREVENTIONFL, LAYER_DUCT_PRESSURESUPPLYFL};
|
||
return csLayer[nIndex];
|
||
}
|
||
|
||
|
||
|
||
/////////////////////打断、遮挡、连接、自动生成节点////////////////////////////
|
||
// 判断是否可以连接
|
||
// 注:风管中,要找的是起止节点是否连接的是同一个节点
|
||
BOOL TDbDuct::CanMergeWith(const TDbDuct &other, int* iPosThis, int* iPosOther) const
|
||
{
|
||
if (GetSysType() != other.GetSysType()) // 1、系统类型相同
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
int bLine1 = Is(CURVE_LINE),
|
||
bLine2 = other.Is(CURVE_LINE);
|
||
if (bLine1 != bLine2) // 2. 几何特征判断
|
||
{
|
||
return FALSE;
|
||
}
|
||
if (m_nSection!=other.m_nSection || fabs(m_dWidth-other.GetWidth())>_distSnap
|
||
|| fabs(m_dHeight-other.GetHeight())>_distSnap) // 3、截面相同,宽、高相同
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
const AcDbObjectId thisStartId = GetNode(0),
|
||
thisEndId = GetNode(1),
|
||
otherStartId = other.GetNode(0),
|
||
otherEndId = other.GetNode(1);
|
||
|
||
double nSweepAng(0.0);
|
||
AcDbObjectId mergeNodeId;
|
||
int nPosFlag(0), nThis(-1), nOther(-1); // 0-起点;1-终点
|
||
if (thisStartId == otherStartId)
|
||
{
|
||
nThis = nOther = 0;
|
||
mergeNodeId = thisStartId;
|
||
nPosFlag = 1; // Merge at both StartPoint
|
||
nSweepAng = GetBulge() - other.GetBulge();
|
||
}
|
||
else if (thisStartId == otherEndId)
|
||
{
|
||
nThis = 0;
|
||
nOther = 1;
|
||
mergeNodeId = thisStartId;
|
||
nPosFlag = 2; // Merge at this StartPoint() and that EndPoint()
|
||
nSweepAng = GetBulge() + other.GetBulge();
|
||
}
|
||
else if (thisEndId == otherStartId)
|
||
{
|
||
nThis = 1;
|
||
nOther = 0;
|
||
mergeNodeId = thisEndId;
|
||
nPosFlag = 4; // Merge at this EndPoint() and that StartPoint()
|
||
nSweepAng = GetBulge() + other.GetBulge();
|
||
}
|
||
else if (thisEndId == otherEndId)
|
||
{
|
||
nThis = nOther = 1;
|
||
mergeNodeId = thisEndId;
|
||
nPosFlag = 3; // Merge at both EndPoint()
|
||
nSweepAng = GetBulge() - other.GetBulge();
|
||
}
|
||
if (mergeNodeId.isNull())
|
||
{
|
||
return TDbPipePrototype::CanMergeWith(other, iPosThis, iPosOther);
|
||
}
|
||
|
||
TDbPipeNode *pNode = NULL;
|
||
if (acdbOpenObject(pNode, mergeNodeId, AcDb::kForRead) == Acad::eOk)
|
||
{
|
||
if (pNode->isKindOf(TDbDuctNode::desc())) // 节点
|
||
{
|
||
int nLen = pNode->GetInterfaceNum();
|
||
if (nLen > 2)
|
||
{
|
||
pNode->Close();
|
||
return FALSE;
|
||
}
|
||
|
||
TDbDuctNode *pDuctNode = TDbDuctNode::cast(pNode);
|
||
TDbDuctNode::DuctNodeType nType = pDuctNode->GetNodeType();
|
||
if ((nType == TDbDuctNode::kYiZiElbow) || (nType ==
|
||
TDbDuctNode::kFlange) || (nType == TDbDuctNode::kTaoDong))
|
||
{
|
||
pDuctNode->Close();
|
||
return FALSE;
|
||
}
|
||
pDuctNode->Close();
|
||
}
|
||
else // 设备
|
||
{
|
||
pNode->Close();
|
||
return TDbPipePrototype::CanMergeWith(other, iPosThis, iPosOther);
|
||
}
|
||
}
|
||
|
||
// 注:以下部分只对TDbDuctNode有效
|
||
if (!nPosFlag || GreatEqual(fabs(nSweepAng), 2*PI, _angSnap))
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
AcGeVector3d vtDuctThis, vtDuctOther;
|
||
if (getFirstDeriv((nThis?EndPoint():StartPoint()), vtDuctThis)!=Acad::eOk ||
|
||
other.getFirstDeriv((nOther?other.EndPoint():other.StartPoint()),
|
||
vtDuctOther)!=Acad::eOk)
|
||
{
|
||
return FALSE;
|
||
}
|
||
if (::IsParallel(vtDuctOther, vtDuctThis) == 0)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
if (iPosThis)
|
||
{
|
||
*iPosThis = nThis;
|
||
}
|
||
if (iPosOther)
|
||
{
|
||
*iPosOther = nOther;
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
BOOL TDbDuct::MergeWith(TDbDuct &other)
|
||
{
|
||
assertWriteEnabled();
|
||
int nThis(-1), nOther(-1);
|
||
BOOL bMerge = CanMergeWith(other, &nThis, &nOther); // 判断是否可以合并
|
||
if (!bMerge)
|
||
{
|
||
return bMerge;
|
||
}
|
||
|
||
BOOL bLabel = m_ptLabel!=XPoint(); // 管线标注
|
||
if (!m_bDrawLabel)
|
||
{
|
||
m_bDrawLabel = other.m_bDrawLabel;
|
||
}
|
||
|
||
double dDist2Pipe = 200,
|
||
dScale2Start = 0.5;
|
||
if (bLabel)
|
||
{
|
||
GetLabelLocation(dDist2Pipe, dScale2Start);
|
||
}
|
||
|
||
// 注:由于考虑对齐方式,需要对第二根管线进行处理,偏移其中心线
|
||
XCurveSegment seg(StartPoint(), EndPoint(), GetBulge());
|
||
XPoint ptNewStart, ptNewEnd;
|
||
seg.ProjectToMe(other.StartPoint(), ptNewStart);
|
||
seg.ProjectToMe(other.EndPoint(), ptNewEnd);
|
||
|
||
if (nThis==0 && nOther==0) // 合并
|
||
{
|
||
StartPoint() = ptNewEnd;
|
||
m_nodeStart = other.m_nodeEnd;
|
||
SetBulge(GetBulge() - other.GetBulge());
|
||
}
|
||
else if (nThis==0 && nOther==1)
|
||
{
|
||
StartPoint() = ptNewStart;
|
||
m_nodeStart = other.m_nodeStart;
|
||
SetBulge(GetBulge() + other.GetBulge());
|
||
}
|
||
else if (nThis==1 && nOther==0)
|
||
{
|
||
EndPoint() = ptNewEnd;
|
||
m_nodeEnd = other.m_nodeEnd;
|
||
SetBulge(GetBulge() + other.GetBulge());
|
||
}
|
||
else if (nThis==1 && nOther==1)
|
||
{
|
||
EndPoint() = ptNewStart;
|
||
m_nodeEnd = other.m_nodeStart;
|
||
SetBulge(GetBulge() - other.GetBulge());
|
||
}
|
||
|
||
int i(0);
|
||
for (i=0; i<other.m_lstAttachment.Length(); i++)
|
||
{
|
||
AddAttachment(*other.m_lstAttachment[i]);
|
||
}
|
||
for (i=0; i<other.m_lstHidePipe.Length(); i++)
|
||
{
|
||
AddHidePipe(*other.m_lstHidePipe[i]);
|
||
}
|
||
for (i=0; i<other.m_lstEquipment.Length(); i++)
|
||
{
|
||
AddEquipment(*other.m_lstEquipment[i]);
|
||
}
|
||
|
||
if (bLabel) // 管线标注
|
||
{
|
||
ResetLabelLocation(dDist2Pipe, dScale2Start);
|
||
}
|
||
|
||
other.assertWriteEnabled();
|
||
other.ResetAllShip();
|
||
for (i=0; i<other.m_lstEquipment.Length(); i++)
|
||
{
|
||
other.RemoveEquipment(*other.m_lstEquipment[i]);
|
||
}
|
||
return bMerge;
|
||
}
|
||
|
||
// 考虑遮挡的当前曲线,二维,z=0
|
||
void TDbDuct::GetHideCurve(XCurveSegment& cvHide) const
|
||
{
|
||
XCurveSegment cvHideTemp = GetCurve();
|
||
cvHideTemp.SetElevation(0); // 设置为二维,z=0
|
||
|
||
// 改为将数据写入数据库加速二维显示速度
|
||
if (fabs(m_dSpeedLength)>1.0E-3 && fabs(m_dSpeedSubMid)>1.0E-3)
|
||
{
|
||
double dChordLength = cvHideTemp.GetChordLength(m_dSpeedLength);
|
||
XPointDir2d ptSubMid;
|
||
cvHideTemp.Polar(m_dSpeedSubMid, ptSubMid);
|
||
cvHideTemp.GetSubSegment(ptSubMid, dChordLength, cvHide);
|
||
return;
|
||
}
|
||
cvHide = cvHideTemp;
|
||
}
|
||
|
||
// 打断部分的宽度
|
||
double TDbDuct::GetBreakWidth() const
|
||
{
|
||
double dWidth(2);
|
||
TDbPsConfig* pConfig = GetDwgPsGlobal(AcDb::kForRead);
|
||
if (pConfig != NULL)
|
||
{
|
||
dWidth = pConfig->GetBreakWidth();
|
||
if (pConfig->IsLineWeight())
|
||
{
|
||
dWidth += m_dDuctWeight;
|
||
}
|
||
pConfig->close();
|
||
}
|
||
dWidth *= GetPScale();
|
||
return dWidth;
|
||
}
|
||
|
||
// 通过管件附件打断的曲线,二维,z=0
|
||
void TDbDuct::GetBrokenCurves(const XCurveSegment &cv,
|
||
DList<XCurveSegment> &lstCurve) const
|
||
{
|
||
int nAttach = m_lstAttachment.Length(),
|
||
nHide = m_lstHidePipe.Length();
|
||
if (nAttach<=0 && nHide<=0) // 没有管件附件,也没有遮挡关系
|
||
{
|
||
lstCurve.Append(new XCurveSegment(cv));
|
||
return;
|
||
}
|
||
|
||
XVector3D vtDir(cv.EndPoint() - cv.StartPoint()); // 以直线段初始化方向
|
||
AcGeVector3d vtAttachment(vtDir); // 管线附件在基线上的方向
|
||
vtAttachment.z = 0;
|
||
vtAttachment.normalize();
|
||
|
||
AcGePoint3dArray arPoint(20); // 剪裁点
|
||
DList<XPoint> lstLocation; // 交点或者附件所在点
|
||
DList<XCurveSegment> lstBreakCurve; // 被剪裁的线段
|
||
double dDisThis = cv.GetLength(); // 管线长
|
||
|
||
int i(0);
|
||
for (i=0; i<nAttach; i++) // 取得临时管线附件和管件附件的在管线上的端点
|
||
{
|
||
const AcDbObjectId &id = m_lstAttachment[i];
|
||
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbPipeAttachment, pAttachment);
|
||
if (pAttachment != NULL)
|
||
{
|
||
if (pAttachment->IsCheckSysType() && pAttachment->GetSysType()!=GetSysType())
|
||
{
|
||
continue;
|
||
}
|
||
|
||
double dWidth = pAttachment->GetWidth()/2,
|
||
dScale = pAttachment->GetScale();
|
||
dWidth *= dScale;
|
||
|
||
TDbPipeValve* pValve = NULL;
|
||
if (pValve = TDbPipeValve::cast(pAttachment))
|
||
{
|
||
if(pValve->HasFlange()) // 如果是带法兰的阀门,宽度要增加法兰厚度
|
||
dWidth += pValve->GetFlangeWidth()*pValve->GetScale()
|
||
*GetPScale()/100/2;
|
||
}
|
||
|
||
if (dWidth > 1.0E-3)
|
||
{
|
||
XPoint ptLocation(pAttachment->GetLocation());
|
||
cv.ProjectToMe(ptLocation, ptLocation);
|
||
ptLocation.z = 0;
|
||
lstLocation.Append(new XPoint(ptLocation));
|
||
DisposeBreak(cv, arPoint, ptLocation, dWidth, dDisThis, vtAttachment,
|
||
lstBreakCurve); // 获得被打断部分的曲线,和打断点
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
|
||
int j(0);
|
||
for(j=0; j<nHide; j++) // 管线的遮挡关系
|
||
{
|
||
OPENOBJ_BEGIN(m_lstHidePipe[j], AcDb::kForRead, TDbPipePrototype, pPipe);
|
||
if (pPipe!=NULL && IsVisibleEntity(pPipe))
|
||
{
|
||
AcGeVector3d vt1 = pPipe->Direction3d().AsAcGeVector3d(),
|
||
vt2 = this->Direction3d().AsAcGeVector3d();
|
||
double dAngle = vt1.angleTo(vt2);
|
||
double dBreakWidth = pPipe->GetBreakWidth(),
|
||
dWidth(0);
|
||
|
||
if (pPipe->isKindOf(TDbDuct::desc())) // 方风管
|
||
{
|
||
TDbDuct *pDuct = (TDbDuct*)pPipe;
|
||
dWidth = pDuct->GetWidth();
|
||
if ((1 == m_nSysDrawMod) || (2 == m_nSection) ||
|
||
pDuct->GetModelType()==TPipeSys::kSystem ||
|
||
pDuct->GetModelType()==TPipeSys::kPrinciple)
|
||
{
|
||
dWidth = 0;
|
||
}
|
||
}
|
||
else if (pPipe->isKindOf(TDbDoubleLinePipe::desc())) // TWT双线管
|
||
{
|
||
TDbDoubleLinePipe *pDLine = (TDbDoubleLinePipe*)pPipe;
|
||
dWidth = pDLine->GetDnDiameter();
|
||
}
|
||
|
||
// 注:打断宽度,不同于水管
|
||
dBreakWidth = (dBreakWidth + dWidth/sin(dAngle))/2.0;
|
||
|
||
if (dBreakWidth > 1.0E-3)
|
||
{
|
||
XCurveSegment cvPipe = *pPipe;
|
||
cvPipe.SetElevation(0); // 设置标高为0
|
||
|
||
XPoint ptIntersect, ptTemp;
|
||
if (cv.Intersection(cvPipe, ptIntersect, ptTemp))
|
||
{
|
||
ptIntersect.z = 0;
|
||
lstLocation.Append(new XPoint(ptIntersect));
|
||
|
||
DisposeBreak(cv, arPoint, ptIntersect, dBreakWidth, dDisThis,
|
||
vtAttachment, lstBreakCurve); // 获得被打断部分的曲线,和打断点
|
||
}
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
|
||
// 按定位点到起点的距离快速排序(由小到大)
|
||
int nCount = arPoint.length();
|
||
if (nCount > 1)
|
||
{
|
||
DList<double> lstDist; // 打断点在曲线段上的距离
|
||
for (i=0; i<nCount; i++) // 为提高效率先计算出距离
|
||
{
|
||
XPoint ptTmp = arPoint[i];
|
||
double dDist = cv.PathDistance(arPoint[i]);
|
||
lstDist.Append(new double(dDist));
|
||
}
|
||
|
||
for (i=0; i<nCount-1; i++)
|
||
{
|
||
for (j=0; j<nCount-1-i; j++)
|
||
{
|
||
if (*lstDist[j]>*lstDist[j+1]) //Swap
|
||
{
|
||
lstDist.Swap(j, j+1);
|
||
arPoint.swap(j, j+1);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
nCount = arPoint.length();
|
||
|
||
// 得到管线基线,并用管线附件打断管线成AcDbCurve
|
||
AcDbVoidPtrArray arSeg; // 裁剪后的曲线段,包括显示和不显示的管线
|
||
TDbPipePrototype pipeCv;
|
||
(XCurveSegment&)pipeCv = cv;
|
||
|
||
AcDbCurve* pCurve = pipeCv.GetBaseCurve();
|
||
Acad::ErrorStatus es2 = pCurve->getSplitCurves(arPoint, arSeg); // 裁剪
|
||
if (pCurve && es2==Acad::eInvalidInput) // 要裁剪的部分不在管线上,或不存在
|
||
{
|
||
AcGeMatrix3d mat;
|
||
mat.setToScaling(0.1);
|
||
pCurve->transformBy(mat);
|
||
|
||
// 可能由于坐标过大导致返回eInvalidInput,管线无法打断
|
||
AcGePoint3dArray arPoint2(20);
|
||
int k(0);
|
||
for (k=0; k<nCount; k++)
|
||
{
|
||
AcGePoint3d ptCur = arPoint[k];
|
||
ptCur.transformBy(mat);
|
||
pCurve->getClosestPointTo(ptCur, ptCur);
|
||
arPoint2.append(ptCur);
|
||
}
|
||
|
||
es2 = pCurve->getSplitCurves(arPoint2, arSeg);
|
||
if (es2 != Acad::eOk) // 不能打断
|
||
{
|
||
lstCurve.Append(new XCurveSegment(cv));
|
||
if (pCurve != NULL)
|
||
{
|
||
delete pCurve;
|
||
}
|
||
return;
|
||
}
|
||
|
||
mat.invert();
|
||
nCount = arSeg.length();
|
||
for (k=0; k<nCount; k++)
|
||
{
|
||
AcDbCurve *pCurve0 = (AcDbCurve *)arSeg[k];
|
||
pCurve0->transformBy(mat);
|
||
}
|
||
}
|
||
else if (pCurve == NULL || es2 != Acad::eOk) // 基线不存在,导致无法打断
|
||
{
|
||
lstCurve.Append(new XCurveSegment(cv));
|
||
if (pCurve != NULL)
|
||
{
|
||
delete pCurve;
|
||
}
|
||
return;
|
||
}
|
||
delete pCurve;
|
||
|
||
nCount = arSeg.length(); // 打断后,总段数
|
||
int nLocation = lstLocation.Length(); // 打断点个数
|
||
if (nCount == nLocation*2 + 1) // 正常情况,奇偶性
|
||
{
|
||
for (int k=0; k<nCount; k=k+2)
|
||
{
|
||
AcDbCurve *pCurve0 = (AcDbCurve *)arSeg[k];
|
||
TDbPipePrototype pipe;
|
||
pipe.SetBaseCurve(pCurve0); // 设置基线
|
||
delete pCurve0;
|
||
|
||
// 判断有没有反方向绘制的线段
|
||
XCurveSegment *pSeg = new XCurveSegment(pipe.GetCurve()); // 显示的管线
|
||
XPoint ptCurveS = pSeg->StartPoint(),
|
||
ptCurveE = pSeg->EndPoint();
|
||
BOOL bStartInside = FALSE,
|
||
bEndInside = FALSE;
|
||
|
||
for (int m=0; m<lstBreakCurve.Length(); m++)
|
||
{
|
||
XCurveSegment segTmp = *lstBreakCurve[m]; // 不显示的管线
|
||
if (segTmp.Is(CURVE_LINE))
|
||
{
|
||
XLine lineTmp = segTmp;
|
||
int nRet1 = ptCurveS&lineTmp,
|
||
nRet2 = ptCurveE&lineTmp;
|
||
if (nRet1 == PR_INSIDE)
|
||
{
|
||
bStartInside = TRUE;
|
||
}
|
||
if (nRet2 == PR_INSIDE)
|
||
{
|
||
bEndInside = TRUE;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (!bStartInside || !bEndInside)
|
||
{
|
||
lstCurve.Append(pSeg);
|
||
}
|
||
}
|
||
}
|
||
else // 非正常情况,比如附件的遮挡范围超出基线
|
||
{
|
||
for (int k=0; k<nCount; k++)
|
||
{
|
||
AcDbCurve *pCurve0 = (AcDbCurve *)arSeg[k]; // 转换成AcDbCurve
|
||
TDbPipePrototype pipe;
|
||
pipe.SetBaseCurve(pCurve0);
|
||
delete pCurve0;
|
||
|
||
// 转换成XCurveSegment,并判断是否是附件的基线
|
||
XCurveSegment *pSeg = new XCurveSegment(pipe.GetCurve());
|
||
XPoint ptS = pSeg->StartPoint(),
|
||
ptE = pSeg->EndPoint();
|
||
BOOL bAppend = TRUE;
|
||
for (int j=0; j<nLocation; j++)
|
||
{
|
||
XPoint &pt = *lstLocation[j];
|
||
pt.z = 0;
|
||
int nResult = pt&(*pSeg);
|
||
if (nResult==PR_EDGE || nResult==PR_INSIDE)
|
||
{
|
||
bAppend = FALSE;
|
||
delete pSeg;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (bAppend) // 添加显示的曲线段
|
||
{
|
||
lstCurve.Append(pSeg);
|
||
}
|
||
}
|
||
}
|
||
|
||
if (lstCurve.Length() <= 0)
|
||
{
|
||
lstCurve.Append(new XCurveSegment(cv));
|
||
}
|
||
return;
|
||
}
|
||
|
||
// 处理打断,得到打断点数组arPoint,和不显示的管段的链表lstBreakCurve
|
||
void TDbDuct::DisposeBreak(const XCurveSegment &cv, AcGePoint3dArray &arPoint,
|
||
const XPoint ptLoc, double dWidth,
|
||
double dDistance, const AcGeVector3d &vtDir,
|
||
DList<XCurveSegment> &lstBreakCurve) const
|
||
{
|
||
if (Is(CURVE_ARC))
|
||
{
|
||
XArc arc2 = cv.GetArc();
|
||
XPoint pt3, pt4, ptMid;
|
||
arc2.GetStartPoint(pt3);
|
||
arc2.GetEndPoint(pt4);
|
||
|
||
// arc2.GetPoints(pt3, pt4);
|
||
arc2.MidPoint(ptMid);
|
||
pt3.z = 0;
|
||
pt4.z = 0;
|
||
ptMid.z = 0;
|
||
|
||
XArc arc(pt3, ptMid, pt4); // 先把arc标高设为0
|
||
|
||
AcDbArc *pArc = new AcDbArc;
|
||
pArc->setCenter(arc.GetCenterPt());
|
||
pArc->setRadius(arc.GetRadius());
|
||
pArc->setStartAngle(arc.GetStarAngle());
|
||
pArc->setEndAngle(arc.GetEndAngle());
|
||
|
||
XPoint pt1, pt2;
|
||
double dParam(0);
|
||
pArc->getParamAtPoint(ptLoc, dParam);
|
||
pArc->getPointAtParam(dParam+dWidth/arc.GetRadius(), pt1);
|
||
pArc->getPointAtParam(dParam-dWidth/arc.GetRadius(), pt2);
|
||
delete pArc;
|
||
|
||
cv.ProjectToMe(pt1, pt1);
|
||
cv.ProjectToMe(pt2, pt2);
|
||
pt1.z = 0;
|
||
pt2.z = 0;
|
||
arPoint.append((AcGePoint3d)pt1);
|
||
arPoint.append((AcGePoint3d)pt2);
|
||
}
|
||
else
|
||
{
|
||
XVector3D vtAdd = vtDir * dWidth;
|
||
XPoint ptStart = ptLoc - vtAdd,
|
||
ptEnd = ptLoc + vtAdd;
|
||
double dStart = cv.PathDistance(ptStart),
|
||
dEnd = cv.PathDistance(ptEnd);
|
||
|
||
if (fabs(StartPoint().z-EndPoint().z) < 0.01)
|
||
{
|
||
getClosestPointTo(ptStart, ptStart);
|
||
getClosestPointTo(ptEnd, ptEnd);
|
||
}
|
||
ptStart.z = 0;
|
||
ptEnd.z = 0;
|
||
|
||
if (dStart>1.0E-5 && dStart<dDistance-1.0E-5)
|
||
{
|
||
arPoint.append((AcGePoint3d)ptStart);
|
||
}
|
||
if (dEnd>1.0E-5 && dEnd<dDistance-1.0E-5)
|
||
{
|
||
arPoint.append((AcGePoint3d)ptEnd);
|
||
}
|
||
|
||
XLine line(ptStart, ptEnd, LS_FINITE);
|
||
XCurveSegment seg;
|
||
seg = line;
|
||
lstBreakCurve.Append(new XCurveSegment(seg));
|
||
}
|
||
}
|
||
|
||
|
||
|
||
//////////////////////////////////其他/////////////////////////////////////////
|
||
// 交换风管的起止点和连接的接点ID
|
||
void TDbDuct::SwitchVane()
|
||
{
|
||
TchPrivate::Exchange(StartPoint(), EndPoint());
|
||
TchPrivate::Exchange(m_nodeStart, m_nodeEnd);
|
||
}
|
||
|
||
double TDbDuct::CalVelocity() const // 计算风速
|
||
{
|
||
double dVelocity(0.0);
|
||
if (m_nSection == 0) // 矩形
|
||
{
|
||
if ((m_dWidth > 1.0E-6) && (m_dHeight > 1.0E-6))
|
||
{
|
||
dVelocity = m_dCalWeight/(3.6E-3 * m_dWidth * m_dHeight);
|
||
}
|
||
}
|
||
else if (m_nSection == 1) // 圆形
|
||
{
|
||
if (m_dWidth > 1.0E-6)
|
||
{
|
||
dVelocity = m_dCalWeight/(9.0E-4 * PI * pow(m_dWidth, 2));
|
||
}
|
||
}
|
||
|
||
CString csTmp;
|
||
csTmp.Format(_T("%.2f"), dVelocity);
|
||
dVelocity = _tstof(csTmp);
|
||
return dVelocity;
|
||
}
|
||
|
||
|
||
|
||
|
||
//////////////////////////////////////////////////////////////////////////
|
||
void InitDbDuct(BOOL bTrue)
|
||
{
|
||
if (bTrue)
|
||
{
|
||
TDbDuct::rxInit();
|
||
TDbDuct::InitMatchProtocol(TRUE);
|
||
}
|
||
else
|
||
{
|
||
TDbDuct::InitMatchProtocol(FALSE);
|
||
deleteAcRxClass(TDbDuct::desc());
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/////////////////////////////////////////////////////////////////////////////////
|
||
// 所需要的全局函数
|
||
/////////////////////////////////////////////////////////////////////////////////
|
||
/*============================================================================*
|
||
* 函 数 名: GetSquare
|
||
* 功能描述: 获取矩形风管的截面
|
||
——>dAngle
|
||
pt4------dWide-----pt1 |
|
||
| | |
|
||
| | |
|
||
ptTmp2----ptCen----ptTmp1 dHigh
|
||
| | |
|
||
| | |
|
||
pt3----------------pt2 |
|
||
==============================================================================*/
|
||
void GetSquare(const XPoint &ptCen, const double &dAngle, const double &dWide,
|
||
const double &dHigh, XPoly2D* poly, XPoly2D* vDuctPoly)
|
||
{
|
||
XPoint ptTmp1, ptTmp2, pt1, pt2, pt3, pt4, pt5;
|
||
ads_polar(ptCen, dAngle, 0.5*dWide, ptTmp1);
|
||
ads_polar(ptCen, dAngle, -0.5*dWide, ptTmp2);
|
||
|
||
ads_polar(ptTmp1, dAngle+PI/2, 0.5*dHigh, pt1);
|
||
ads_polar(ptTmp1, dAngle-PI/2, 0.5*dHigh, pt2);
|
||
ads_polar(ptTmp2, dAngle-PI/2, 0.5*dHigh, pt3);
|
||
ads_polar(ptTmp2, dAngle+PI/2, 0.5*dHigh, pt4);
|
||
|
||
poly->Reset();
|
||
poly->SetFlag(1);
|
||
poly->AppendNode(pt1);
|
||
poly->AppendNode(pt2);
|
||
poly->AppendNode(pt3);
|
||
poly->AppendNode(pt4);
|
||
|
||
if (vDuctPoly != NULL) { // 注:立管用
|
||
double dAng = ads_angle(ptCen, pt4),
|
||
dDist = pt4.Distance(ptCen);
|
||
ads_polar(ptCen, dAng, 0.5*dDist, pt5);
|
||
|
||
vDuctPoly->Reset();
|
||
vDuctPoly->SetFlag(0);
|
||
vDuctPoly->AppendNode(pt1);
|
||
vDuctPoly->AppendNode(pt5);
|
||
vDuctPoly->AppendNode(pt3);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*============================================================================*
|
||
* 函 数 名: GetWidths
|
||
* 功能描述: 获取一组风管的管径
|
||
==============================================================================*/
|
||
AcGeDoubleArray GetWidths(AcDbObjectId id, const DList<AcDbObjectId> &ids,
|
||
const AcDbIntArray &aryTypes)
|
||
{
|
||
AcGeDoubleArray widthArray;
|
||
int nLen = ids.Length();
|
||
for (int i=0; i<nLen; i++)
|
||
{
|
||
double dWidth(0);
|
||
int nType = aryTypes[i];
|
||
if ((nType == 1) || (nType == 2)) // 此时的id一定不为空
|
||
{
|
||
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbDuctNode, pNode);
|
||
if (pNode == NULL)
|
||
{
|
||
return widthArray;
|
||
}
|
||
|
||
int nIndex = pNode->FindIdInLink(ids[i]);
|
||
if (nIndex != -1) // 存在连接关系
|
||
{
|
||
dWidth = pNode->GetIWidth(nIndex);
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
else
|
||
{
|
||
OPENOBJ_BEGIN(ids[i], AcDb::kForRead, TDbDuct, pDuct);
|
||
if (pDuct != NULL)
|
||
{
|
||
dWidth = pDuct->GetWidth();
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
widthArray.append(dWidth);
|
||
}
|
||
return widthArray;
|
||
}
|
||
|
||
/*============================================================================*
|
||
* 函 数 名: GetHeights
|
||
* 功能描述: 获取一组风管的高度
|
||
==============================================================================*/
|
||
AcGeDoubleArray GetHeights(AcDbObjectId id, const DList<AcDbObjectId> &ids,
|
||
const AcDbIntArray &aryTypes)
|
||
{
|
||
AcGeDoubleArray heightArray;
|
||
int nLen = ids.Length();
|
||
for (int i=0; i<nLen; i++)
|
||
{
|
||
double dHeight(0);
|
||
int nType = aryTypes[i];
|
||
if ((nType == 1) || (nType == 2)) // 此时的id一定不为空
|
||
{
|
||
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbDuctNode, pNode);
|
||
if (pNode == NULL)
|
||
{
|
||
return heightArray;
|
||
}
|
||
|
||
int nIndex = pNode->FindIdInLink(ids[i]);
|
||
if (nIndex != -1) // 存在连接关系
|
||
{
|
||
dHeight = pNode->GetIHeight(nIndex);
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
else
|
||
{
|
||
OPENOBJ_BEGIN(ids[i], AcDb::kForRead, TDbDuct, pDuct);
|
||
if (pDuct != NULL)
|
||
{
|
||
dHeight = pDuct->GetHeight();
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
heightArray.append(dHeight);
|
||
}
|
||
return heightArray;
|
||
}
|
||
|
||
/*============================================================================*
|
||
* 函 数 名: GetSegs
|
||
* 功能描述: 获取一组风管的中心线
|
||
==============================================================================*/
|
||
void GetSegs(AcDbObjectId id, XPoint ptLoc, const DList<AcDbObjectId> &ids,
|
||
const AcDbIntArray &aryTypes, DList<XCurveSegment> &lstSeg)
|
||
{
|
||
int nLen = ids.Length();
|
||
for (int i=0; i<nLen; i++)
|
||
{
|
||
XPoint pt1;
|
||
XVector3D vt;
|
||
int nType = aryTypes[i];
|
||
if ((nType == 1) || (nType == 2)) // 此时的id一定不为空
|
||
{
|
||
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbDuctNode, pNode);
|
||
if (pNode == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
int nIndex = pNode->FindIdInLink(ids[i]);
|
||
if (nIndex != -1) // 存在连接关系
|
||
{
|
||
pt1 = pNode->GetILocation(nIndex);
|
||
vt = pNode->GetIDirection(nIndex);
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
else
|
||
{
|
||
OPENOBJ_BEGIN(ids[i], AcDb::kForRead, TDbDuct, pDuct);
|
||
if (pDuct != NULL)
|
||
{
|
||
TPipeSys::PtLoction nSide = TPipeSys::kStartPt;
|
||
vt = pDuct->GetDirection(ptLoc, nSide);
|
||
pt1 = pDuct->GetVertexPt(nSide);
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
|
||
vt.Normalize();
|
||
vt.Scale(100);
|
||
XPoint pt2 = pt1 + vt;
|
||
lstSeg.Append(new XCurveSegment(pt1, pt2, 0, LS_FINITE));
|
||
}
|
||
}
|
||
|
||
/*============================================================================*
|
||
* 函 数 名: GetVectors
|
||
* 功能描述: 获取一组风管的法向
|
||
* 备 注: 离指定点较近的端点——>较远的端点
|
||
==============================================================================*/
|
||
void GetVectors(AcDbObjectId id, XPoint ptLoc, const DList<AcDbObjectId> &ids,
|
||
const AcDbIntArray &aryTypes, DList<XVector3D> &lstVt)
|
||
{
|
||
int nLen = ids.Length();
|
||
for (int i=0; i<nLen; i++)
|
||
{
|
||
XVector3D vt;
|
||
int nType = aryTypes[i];
|
||
if ((nType == 1) || (nType == 2)) // 此时的id一定不为空
|
||
{
|
||
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbDuctNode, pNode);
|
||
if (pNode == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
int nIndex = pNode->FindIdInLink(ids[i]);
|
||
if (nIndex != -1) // 存在连接关系
|
||
{
|
||
vt = pNode->GetIDirection(nIndex);
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
else
|
||
{
|
||
OPENOBJ_BEGIN(ids[i], AcDb::kForRead, TDbDuct, pDuct);
|
||
if (pDuct != NULL)
|
||
{
|
||
TPipeSys::PtLoction nSide = TPipeSys::kStartPt;
|
||
vt = pDuct->GetDirection(ptLoc, nSide);
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
lstVt.Append(new XVector3D(vt));
|
||
}
|
||
}
|
||
|
||
/*============================================================================*
|
||
* 函 数 名: GetAngles
|
||
* 功能描述: 获取一组风管的法向
|
||
* 备 注: 与GetVectors一致
|
||
==============================================================================*/
|
||
AcGeDoubleArray GetAngles(AcDbObjectId id, XPoint ptLoc, const DList<AcDbObjectId> &ids,
|
||
const AcDbIntArray &aryTypes)
|
||
{
|
||
DList<XVector3D> lstVts;
|
||
::GetVectors(id, ptLoc, ids, aryTypes, lstVts);
|
||
|
||
AcGeDoubleArray angleArray;
|
||
int nLen = lstVts.Length();
|
||
for (int i=0; i<nLen; i++)
|
||
{
|
||
double dAng = ads_angle(XPoint(), *lstVts[i]);
|
||
angleArray.append(dAng);
|
||
}
|
||
return angleArray;
|
||
}
|
||
|
||
/*============================================================================*
|
||
* 函 数 名: GetPtLocations
|
||
* 功能描述: 获取一组风管中,离指定点较近的端点的位置(是起点,还是终点)
|
||
==============================================================================*/
|
||
void GetPtLocations(AcDbObjectId id, XPoint ptLoc, const DList<AcDbObjectId> &ids,
|
||
const AcDbIntArray &aryTypes, DList<TPipeSys::PtLoction> &lstLoc)
|
||
{
|
||
int nLen = ids.Length();
|
||
for (int i=0; i<nLen; i++)
|
||
{
|
||
int nType = aryTypes[i];
|
||
TPipeSys::PtLoction nSide = TPipeSys::kStartPt;
|
||
if ((nType == 1) || (nType == 2))
|
||
{
|
||
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbDuctNode, pNode);
|
||
if (pNode == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
int nIndex = pNode->FindIdInLink(ids[i]);
|
||
if (nIndex != -1) // 存在连接关系
|
||
{
|
||
TPipeSys::FlowLet nLet = pNode->GetIFlowDir(nIndex);
|
||
if (nLet == TPipeSys::kInlet)
|
||
{
|
||
nSide = TPipeSys::kEndPt;
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
else
|
||
{
|
||
OPENOBJ_BEGIN(ids[i], AcDb::kForRead, TDbDuct, pDuct);
|
||
if (pDuct != NULL)
|
||
{
|
||
pDuct->GetDirection(ptLoc, nSide);
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
lstLoc.Append(new TPipeSys::PtLoction(nSide));
|
||
}
|
||
}
|
||
|
||
/*============================================================================*
|
||
* 函 数 名: IsCircleDuct
|
||
* 功能描述: 获取某风管是否是圆风管
|
||
==============================================================================*/
|
||
BOOL IsCircleDuct(AcDbObjectId idNode, AcDbObjectId id, int nType)
|
||
{
|
||
int nSection(0);
|
||
if ((nType == 1) || (nType == 2))
|
||
{
|
||
OPENOBJ_BEGIN(idNode, AcDb::kForRead, TDbDuctNode, pNode);
|
||
if (pNode != NULL)
|
||
{
|
||
int nIndex = pNode->FindIdInLink(id);
|
||
if (nIndex != -1) // 存在连接关系
|
||
{
|
||
nSection = pNode->GetISection(nIndex);
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
return (nSection==1);
|
||
}
|
||
|
||
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbDuct, pDuct);
|
||
if (pDuct != NULL)
|
||
{
|
||
nSection = pDuct->GetSectionType();
|
||
}
|
||
OPENOBJ_END();
|
||
return (nSection == 1);
|
||
}
|
||
|
||
/*============================================================================*
|
||
* 函 数 名: IsVerDuct
|
||
* 功能描述: 获取某风管是否是立管
|
||
==============================================================================*/
|
||
BOOL IsVerDuct(AcDbObjectId idNode, AcDbObjectId id, int nType)
|
||
{
|
||
BOOL bIsVDuct(FALSE);
|
||
if ((nType == 1) || (nType == 2))
|
||
{
|
||
OPENOBJ_BEGIN(idNode, AcDb::kForRead, TDbDuctNode, pNode);
|
||
if (pNode != NULL)
|
||
{
|
||
int nIndex = pNode->FindIdInLink(id);
|
||
if (nIndex != -1) // 存在连接关系
|
||
{
|
||
XVector3D vt = pNode->GetIDirection(nIndex);
|
||
vt.Normalize();
|
||
bIsVDuct = fabs(vt.x)<1.0E-6 && fabs(vt.y)<1.0E-6;
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
return bIsVDuct;
|
||
}
|
||
|
||
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbDuct, pDuct);
|
||
if (pDuct != NULL)
|
||
{
|
||
TPipeSys::ModelType nMode = pDuct->GetModelType();
|
||
if (nMode == TPipeSys::kModel) // 模型图
|
||
{
|
||
bIsVDuct = pDuct->IsVertical();
|
||
}
|
||
else if (nMode == TPipeSys::kSystem) // 系统图
|
||
{
|
||
XVector3D vt = pDuct->EndPoint() - pDuct->StartPoint();
|
||
vt.Normalize();
|
||
bIsVDuct = fabs(vt.z)>0.001;
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
return bIsVDuct;
|
||
}
|