6952 lines
200 KiB
C++
6952 lines
200 KiB
C++
// TDbDuctNode.cpp: implementation of the TDbDuctNode class.
|
||
//
|
||
//////////////////////////////////////////////////////////////////////
|
||
|
||
#include "stdafx.h"
|
||
#include "TDbDuctNode.h"
|
||
|
||
#include "GlobalFunction.h"
|
||
#include "PipeTools.h"
|
||
#include "DbDuct.h"
|
||
|
||
ACRX_DXF_DEFINE_MEMBERS(ATSDuctNode, ATSPipeNode, AcDb::kDHL_CURRENT,
|
||
AcDb::kMReleaseCurrent, 1, ATS_DUCTNODE,
|
||
"ATS_DUCTNODE图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
|
||
IMPLEMENT_TENTBASE(TDbDuctNode);
|
||
|
||
// sg modify
|
||
// const Adesk::UInt8 TDbDuctNode::g_nVersion = 1; // 7.5
|
||
const Adesk::UInt8 TDbDuctNode::g_nVersion = 2; // 7.6
|
||
|
||
|
||
|
||
///////////////////////////Construction/Destruction////////////////////////////
|
||
TDbDuctNode::TDbDuctNode():
|
||
m_nMain(0), m_nSysDrawMod(2), m_nDrawMod(0), m_dDrawParam(1), m_dDrawParam2(1),
|
||
m_bMuffler(FALSE), m_nMufflerMod(0), m_bShowDLYP(FALSE), m_nDLYPNum(3),
|
||
m_nDLYPType(0), m_nXMWNum(1), m_bValue(FALSE), m_nSpare(0), m_dSpare(0.0),
|
||
m_nAlign(4), m_dFlangeDis(100), m_dFlangeThick(50)
|
||
{
|
||
m_visibility = TPipeSys::kVisible; // 所有风管节点都应该是可见的
|
||
|
||
m_nType = kStem; // 连接件类型
|
||
m_nLinkType = kSingleFlange; // 连接方式
|
||
m_lstDuctIFace.Reset(); // 风管尺寸
|
||
}
|
||
|
||
TDbDuctNode::~TDbDuctNode()
|
||
{
|
||
}
|
||
|
||
void TDbDuctNode::SetLinkType(const Adesk::UInt8 nLinkMod) // 法兰连接类型
|
||
{
|
||
assertWriteEnabled();
|
||
m_nLinkType = (TDbDuctNode::FlangeLinkType)nLinkMod;
|
||
}
|
||
|
||
BOOL TDbDuctNode::Is(const CString &csType) const // 判断节点是否是指定的类型
|
||
{
|
||
CString trueType = _T("Stem");
|
||
DuctNodeType nType = GetNodeType();
|
||
if (nType == kStem) // 一般堵头
|
||
{
|
||
trueType = _T("Stem");
|
||
}
|
||
else if (nType == kElbow) // 弯头
|
||
{
|
||
trueType = _T("Elbow");
|
||
}
|
||
else if (nType == kKouElbow) // 扣弯
|
||
{
|
||
trueType = _T("KouElbow");
|
||
}
|
||
else if (nType == kYiZiElbow) // 乙字弯头
|
||
{
|
||
trueType = _T("YiZiElbow");
|
||
}
|
||
else if (nType == kTapered) // 变径
|
||
{
|
||
trueType = _T("Tapered");
|
||
}
|
||
else if (nType == kTianYuanDiFang) // 天圆地方
|
||
{
|
||
trueType = _T("TianYuanDiFang");
|
||
}
|
||
else if (nType == kFlange) // 法兰
|
||
{
|
||
trueType = _T("Flange");
|
||
}
|
||
else if (nType == k3Corner) // 三通
|
||
{
|
||
trueType = _T("3Corner");
|
||
}
|
||
else if (nType == k4Corner) // 四通
|
||
{
|
||
trueType = _T("4Corner");
|
||
}
|
||
else if (nType == kSoft) // 软接口
|
||
{
|
||
trueType = _T("Soft");
|
||
}
|
||
else if (nType == kOther) // 其他
|
||
{
|
||
trueType = _T("Other");
|
||
}
|
||
else if (nType == kTaoDong) // 掏洞三通
|
||
{
|
||
trueType = _T("TaoDong");
|
||
}
|
||
return trueType==csType;
|
||
}
|
||
|
||
|
||
|
||
/////////有关与管线之间连接点(m_lstInterface中的m_ptLocation)的相关函数////////
|
||
int TDbDuctNode::FindIdInLink(AcDbObjectId linkId) const // 查找指定ID
|
||
{
|
||
int nLen = GetInterfaceNum();
|
||
for (int i = 0; i < nLen; i++)
|
||
{
|
||
const AcDbObjectId &id = GetIPipe(i);
|
||
if (id == linkId)
|
||
{
|
||
return i;
|
||
}
|
||
}
|
||
return -1; // 找不到
|
||
}
|
||
|
||
// 获取所有连接的管线ID
|
||
void TDbDuctNode::GetAllLinkDucts(DList<AcDbObjectId> &ductIds) const
|
||
{
|
||
int nLen = GetInterfaceNum();
|
||
for (int i = 0; i < nLen; i++)
|
||
{
|
||
const AcDbObjectId &id = GetIPipe(i);
|
||
ductIds.Append(new AcDbObjectId(id));
|
||
}
|
||
}
|
||
|
||
AcDbIntArray TDbDuctNode::GetAllTypes() const // 获取所有的连接类型
|
||
{
|
||
AcDbIntArray types;
|
||
int nLen = GetDuctIFaceNum();
|
||
for (int i = 0; i < nLen; i++)
|
||
{
|
||
int nType = GetIType(i);
|
||
types.append(nType);
|
||
}
|
||
return types;
|
||
}
|
||
|
||
|
||
|
||
////////////////////////有关m_lstDuctIFace的相关函数///////////////////////////
|
||
BOOL TDbDuctNode::HasNullIFace(AcDbIntArray &ifaces) const // 节点中是否有空接口
|
||
{
|
||
if (!ifaces.isEmpty()) // 首先清空
|
||
{
|
||
ifaces.removeSubArray(0, ifaces.logicalLength()-1);
|
||
}
|
||
|
||
int nLen = GetDuctIFaceNum();
|
||
for (int i = 0; i < nLen; i++)
|
||
{
|
||
int nType = GetIType(i);
|
||
if (nType == 1) // 空接口1,原来连接的是管线
|
||
{
|
||
ifaces.append(i);
|
||
}
|
||
else if (nType == 2) // 空接口2,原来连接的是节点
|
||
{
|
||
const AcDbObjectId &idNode = GetIPipe(i);
|
||
if (idNode.isErased() || idNode.isNull()) // 连接的节点被删除
|
||
{
|
||
ifaces.append(i);
|
||
}
|
||
}
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
|
||
////////////////////////////Override TDbPipeNode///////////////////////////////
|
||
// 判断节点是否可以连接管段,nPos: 0--start; 1--end
|
||
BOOL TDbDuctNode::CanLinkSide(const AcDbObjectId &idPipe, int nPos) const
|
||
{
|
||
BOOL bRet(FALSE);
|
||
OPENOBJ_BEGIN(idPipe, AcDb::kForRead, TDbDuct, pDuct);
|
||
if (pDuct != NULL)
|
||
{
|
||
XPoint ptLoc = GetLocation();
|
||
const XPoint &ptRef = nPos?pDuct->EndPoint():pDuct->StartPoint();
|
||
if (ptRef.Distance(ptLoc) < PS_SNAP) // 与位置点一致
|
||
{
|
||
return TRUE;
|
||
}
|
||
|
||
int nLen = GetInterfaceNum();
|
||
for (int i=0; i<nLen; i++)
|
||
{
|
||
const XPoint &ptLink = GetILocation(i);
|
||
if (ptRef.Distance(ptLink) < PS_SNAP) // 与接口点一致
|
||
{
|
||
bRet = TRUE;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
return bRet;
|
||
}
|
||
|
||
void TDbDuctNode::RemoveInterface(TPipeSys::SysType st) // 删除两种接口
|
||
{
|
||
assertWriteEnabled();
|
||
int nCount = GetInterfaceNum();
|
||
for (int i=0; i<nCount; i++)
|
||
{
|
||
TPipeInterface &iFace = *m_lstInterface[i];
|
||
if (iFace.m_sysType == st)
|
||
{
|
||
m_lstInterface.Remove();
|
||
m_lstDuctIFace.Remove(i);
|
||
i--;
|
||
}
|
||
}
|
||
}
|
||
|
||
void TDbDuctNode::RemoveInterface(const AcDbObjectId &idPipe)
|
||
{
|
||
assertWriteEnabled();
|
||
int nCount = GetInterfaceNum();
|
||
for (int i=0; i<nCount; i++)
|
||
{
|
||
TPipeInterface &iFace = *m_lstInterface[i];
|
||
if (idPipe == (AcDbObjectId)iFace.m_idPipe)
|
||
{
|
||
m_lstInterface.Remove();
|
||
m_lstDuctIFace.Remove(i);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 转轴侧坐标
|
||
XPoint TransformPoint(const XPoint& point, double angle, const XPoint& basePoint)
|
||
{
|
||
XPoint pt = point - basePoint;
|
||
XPoint ptN(pt.x + cos(angle) * pt.y, pt.z + sin(angle) * pt.y, point.z);
|
||
return ptN;
|
||
}
|
||
|
||
// 注:打断、合并时替换,不考虑特殊情况,管线正常接连,ID都不为空,接口为0
|
||
// 空接口引出、空接口与其他连接时替换,ID都不为空,接口由1变为0或2
|
||
// 删除掏洞主管时替换,删除接口,不替换
|
||
// 生系统图时替换:1)连接件直接相连或空接口,新ID为空,调整向量,接口类型不变
|
||
// 2)掏洞接口,不删除接口,类型不变
|
||
void TDbDuctNode::ReplaceInterface(const AcDbObjectId &idOld,
|
||
const AcDbObjectId &idNew) // 替换两种接口
|
||
{
|
||
assertWriteEnabled();
|
||
int nIndex = FindIdInLink(idOld);
|
||
if (nIndex == -1) // 找不到
|
||
{
|
||
return;
|
||
}
|
||
|
||
int nType = GetIType(nIndex); // 接管类型
|
||
if ((nType==3) && (m_nSysDrawMod!=4)) // 非系统图的掏洞节点
|
||
{
|
||
RemoveInterface(idOld); // 断开连接,删除接口
|
||
return;
|
||
}
|
||
SetIPipe(nIndex, idNew); // 其他情况,一律替换ID
|
||
|
||
if ((m_nSysDrawMod==4) && (idNew.isNull() || idNew.isErased())) // 系统图,空接口
|
||
{
|
||
XPoint ptLink = GetILocation(nIndex);
|
||
XVector3D vec = GetIDirection(nIndex);
|
||
vec.Normalize();
|
||
vec.Scale(200);
|
||
XPoint ptVec = ptLink + vec; // 旧
|
||
|
||
XPoint ptChange1 = ::TransformPoint(ptVec, PI/4, XPoint()), // 注:角度暂时写死
|
||
ptChange2 = ::TransformPoint(ptLink, PI/4, XPoint());
|
||
vec = ptChange1 - ptChange2;
|
||
vec.Normalize();
|
||
SetIDirection(nIndex, vec); // 重新设置连接方向
|
||
return;
|
||
}
|
||
|
||
if (nType == 1) // 空接口,新连接的是节点
|
||
{
|
||
OPENOBJ_BEGIN(idNew, AcDb::kForRead, TDbPipeNode, pNode);
|
||
if (pNode != NULL)
|
||
{
|
||
SetIType(nIndex, 2);
|
||
return;
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
|
||
SetIType(nIndex, 0); // 其他情况均为接新管线,接口类型应为0
|
||
OPENOBJ_BEGIN(idNew, AcDb::kForRead, TDbDuct, pDuct);
|
||
if (pDuct != NULL)
|
||
{
|
||
SetIDrawType(nIndex, pDuct->GetSysDrawMod());
|
||
SetIDQSide(nIndex, pDuct->GetDQSide());
|
||
SetIDQType(nIndex, pDuct->GetDuiQi());
|
||
|
||
XPoint pt = ::GetNearPt(m_ptLocation, pDuct->GetStartPoint(), pDuct->GetEndPoint());
|
||
SetILocation(nIndex, pt);
|
||
TPipeSys::PtLoction nSide = TPipeSys::kStartPt;
|
||
XVector3D vt = pDuct->GetDirection(pt, nSide); // 向量
|
||
if (nSide == TPipeSys::kEndPt) // 终点
|
||
{
|
||
SetIFlowDir(nIndex, TPipeSys::kInlet);
|
||
SetIEle(nIndex, pDuct->GetElevationAt(1));
|
||
}
|
||
else // 起点
|
||
{
|
||
SetIFlowDir(nIndex, TPipeSys::kOutlet);
|
||
SetIEle(nIndex, pDuct->GetElevationAt(0)); // 标高
|
||
}
|
||
SetIDirection(nIndex, vt);
|
||
|
||
if (pDuct->IsVertical())
|
||
{
|
||
SetIVDAngle(nIndex, pDuct->GetVDAngle());
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
|
||
// 更新接口,注:同时更新m_lstInterface和m_lstDuctIFace,只处理连接管线的正常情况
|
||
void TDbDuctNode::UpdateInterface(TPipeSys::SysType st, const XPoint &ptAt,
|
||
const DList<AcDbObjectId> &ids,
|
||
const AcDbIntArray &types)
|
||
{
|
||
assertWriteEnabled();
|
||
int nCount1 = ids.Length(),
|
||
nCount2 = types.logicalLength();
|
||
if (nCount1 != nCount2) // 1、先判断链表数量是否正确
|
||
{
|
||
return;
|
||
}
|
||
|
||
int i(0);
|
||
DList<AcDbObjectId> lstDuct; // 2、存储需要新生成的接口
|
||
for (i=0; i<nCount1; i++)
|
||
{
|
||
lstDuct.Append(new AcDbObjectId(ids[i]));
|
||
}
|
||
AcDbIntArray aryTypes; // 存储新生成的连接类型
|
||
for (i=0; i<nCount2; i++)
|
||
{
|
||
aryTypes.append(types[i]);
|
||
}
|
||
|
||
nCount1 = lstDuct.Length();
|
||
nCount2 = types.logicalLength();
|
||
if (nCount1 != nCount2) // 3、再次判断链表数量是否正确
|
||
{
|
||
return;
|
||
}
|
||
|
||
m_ptLocation = ptAt; // 4、更新节点位置
|
||
|
||
int nLen = GetInterfaceNum(); // 5、更新或者删除老的接口
|
||
for (i=0; i<nLen; i++)
|
||
{
|
||
TPipeInterface &iFace = *m_lstInterface[i]; // 旧
|
||
for (int j=0; j<lstDuct.Length(); j++)
|
||
{
|
||
if (iFace.m_idPipe == *lstDuct[j]) // 新
|
||
{
|
||
int nType = aryTypes[j];
|
||
SetIType(i, nType); // 先修改类型,再删除
|
||
lstDuct.Remove();
|
||
aryTypes.removeAt(j);
|
||
if ((nType == 1) || (nType == 2)) // 空接口或者接节点,暂不更新
|
||
{
|
||
break;
|
||
}
|
||
|
||
// 判断是否符合几何条件,或更新接口
|
||
OPENOBJ_BEGIN(iFace.m_idPipe, AcDb::kForRead, TDbDuct, pDuct);
|
||
if (pDuct == NULL)
|
||
{
|
||
break;
|
||
}
|
||
|
||
iFace.m_sysType = st; // 系统类型
|
||
|
||
XPoint ptLink;
|
||
if (nType == 0) // 两边连接的节点
|
||
{
|
||
ptLink = ::GetNearPt(ptAt, pDuct->GetStartPoint(), pDuct->GetEndPoint());
|
||
}
|
||
else // 掏洞节点,nType=3
|
||
{
|
||
pDuct->ProjectToMe(ptAt, ptLink); // 注:暂时将其投影到中心线上
|
||
}
|
||
iFace.m_ptLocation = ptLink;
|
||
|
||
TPipeSys::PtLoction nSide = TPipeSys::kStartPt;
|
||
iFace.m_vtLocation = pDuct->GetDirection(ptLink, nSide); // 向量
|
||
if (nSide == TPipeSys::kEndPt) // 终点
|
||
{
|
||
iFace.m_flowDir = TPipeSys::kInlet;
|
||
SetIEle(i, pDuct->GetElevationAt(1)); // 标高
|
||
}
|
||
else // 起点,掏洞节点的连接方向取连接点的切线方向
|
||
{
|
||
iFace.m_flowDir = TPipeSys::kOutlet;
|
||
SetIEle(i, pDuct->GetElevationAt(0));
|
||
}
|
||
|
||
SetISection(i, pDuct->GetSectionType());
|
||
SetIDrawType(i, pDuct->GetSysDrawMod());
|
||
SetIWidth(i, pDuct->GetWidth());
|
||
SetIHeight(i, pDuct->GetHeight());
|
||
SetIFlDist(i, pDuct->GetFlChuTou());
|
||
SetIFlThick(i, pDuct->GetFlThick());
|
||
SetIDQSide(i, pDuct->GetDQSide());
|
||
SetIDQType(i, pDuct->GetDuiQi());
|
||
if (pDuct->IsVertical())
|
||
{
|
||
SetIVDAngle(i, pDuct->GetVDAngle());
|
||
}
|
||
OPENOBJ_END();
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
nLen = lstDuct.Length();
|
||
nCount2 = aryTypes.logicalLength();
|
||
if (nLen != nCount2) // 6、再次判断链表数量是否正确
|
||
{
|
||
return;
|
||
}
|
||
|
||
for (i=0; i<nLen; i++) // 7、生成新接口
|
||
{
|
||
AcDbObjectId &id = *lstDuct[i];
|
||
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbDuct, pDuct);
|
||
if (pDuct == NULL)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
TPipeInterface iFace;
|
||
iFace.m_sysType = st;
|
||
iFace.m_faceType = TPipeInterface::kNodeLocation;
|
||
iFace.m_idPipe = id;
|
||
|
||
double dEle(0);
|
||
TPipeSys::PtLoction nSide = TPipeSys::kStartPt;
|
||
XPoint ptNear = ::GetNearPt(ptAt, pDuct->GetStartPoint(), pDuct->GetEndPoint());
|
||
iFace.m_ptLocation = ptNear; // 连接位置
|
||
iFace.m_vtLocation = pDuct->GetDirection(ptNear, nSide); // 向量
|
||
if (nSide == TPipeSys::kEndPt) // 终点
|
||
{
|
||
dEle = pDuct->GetElevationAt(1);
|
||
iFace.m_flowDir = TPipeSys::kInlet; // 进口
|
||
}
|
||
else // 起点
|
||
{
|
||
dEle = pDuct->GetElevationAt(0);
|
||
iFace.m_flowDir = TPipeSys::kOutlet; // 出口
|
||
}
|
||
AddInterface(iFace);
|
||
|
||
TDuctIFaceMakeup iFaceMakeUp;
|
||
iFaceMakeUp.m_nType = aryTypes[i]; // 接管类型
|
||
iFaceMakeUp.m_dWidth = pDuct->GetWidth(); // 管线的几何属性
|
||
iFaceMakeUp.m_dHeight = pDuct->GetHeight();
|
||
iFaceMakeUp.m_nDrawType = (Adesk::UInt8)pDuct->GetSysDrawMod();
|
||
iFaceMakeUp.m_nSection = pDuct->GetSectionType();
|
||
iFaceMakeUp.m_dFlDist = pDuct->GetFlChuTou();
|
||
iFaceMakeUp.m_dFlThick = pDuct->GetFlThick();
|
||
iFaceMakeUp.m_dEle = dEle;
|
||
iFaceMakeUp.m_nDQSide = pDuct->GetDQSide();
|
||
iFaceMakeUp.m_nDQType = pDuct->GetDuiQi();
|
||
if (pDuct->IsVertical())
|
||
{
|
||
iFaceMakeUp.m_dVDAngle = pDuct->GetVDAngle();
|
||
}
|
||
AddDuctIFace(iFaceMakeUp);
|
||
OPENOBJ_END();
|
||
}
|
||
}
|
||
|
||
// 节点是否遮挡管线
|
||
BOOL TDbDuctNode::IsHidePipe() const
|
||
{
|
||
BOOL bRet1 = GetInterfaceNum()<2, // 一般堵头不遮挡
|
||
bRet2 = (m_nType==kTaoDong) && (m_nDrawMod==13), // 掏洞样式13不遮挡
|
||
bRet3 = (m_nSysDrawMod==1) || (m_nSysDrawMod==4), // 单线、系统图不遮挡
|
||
// 焊接连接、单线法兰不遮挡
|
||
bRet4 = (m_nLinkType==kSingleFlange) || (m_nLinkType==kSingleLine);
|
||
return !(bRet1 || bRet2 || bRet3 || bRet4);
|
||
}
|
||
|
||
|
||
|
||
//////////////////////////////Renew TDbPipeNode////////////////////////////////
|
||
// 获取节点连接的立管在接口链表中的索引号
|
||
AcDbIntArray TDbDuctNode::GetVerPipeIndex() const
|
||
{
|
||
AcDbIntArray indexArray;
|
||
int nLen = GetInterfaceNum();
|
||
for (int i=0; i<nLen; i++)
|
||
{
|
||
const XVector3D vt = GetIDirection(i);
|
||
if (fabs(vt.x)<1.0E-6 && fabs(vt.y)<1.0E-6)
|
||
{
|
||
indexArray.append(i);
|
||
}
|
||
}
|
||
return indexArray;
|
||
}
|
||
|
||
|
||
|
||
/////////////////////////////Override TDbEntity////////////////////////////////
|
||
void TDbDuctNode::CopyPropertiesFrom(AcDbEntity* pSrc, unsigned gMatchFlag)
|
||
{
|
||
assertWriteEnabled();
|
||
TDbPipeNode::CopyPropertiesFrom(pSrc, gMatchFlag);
|
||
TDbDuctNode *pNode = TDbDuctNode::cast(pSrc);
|
||
if (pNode != NULL)
|
||
{
|
||
m_nType = pNode->m_nType;
|
||
m_ptLocation = pNode->m_ptLocation;
|
||
m_nMain = pNode->m_nMain;
|
||
m_nSysDrawMod = pNode->m_nSysDrawMod;
|
||
m_nDrawMod = pNode->m_nDrawMod;
|
||
m_dDrawParam = pNode->m_dDrawParam;
|
||
m_dDrawParam2 = pNode->m_dDrawParam2;
|
||
m_nLinkType = pNode->m_nLinkType;
|
||
m_bShowDLYP = pNode->m_bShowDLYP;
|
||
m_nDLYPType = pNode->m_nDLYPType;
|
||
m_nDLYPNum = pNode->m_nDLYPNum;
|
||
m_bMuffler = pNode->m_bMuffler;
|
||
m_nMufflerMod = pNode->m_nMufflerMod;
|
||
m_bValue = pNode->m_bValue;
|
||
m_nXMWNum = pNode->m_nXMWNum;
|
||
}
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuctNode::subGetClassID(CLSID* pClsid) const
|
||
{
|
||
return Acad::eOk;
|
||
}
|
||
|
||
// 取动态属性显示数据
|
||
void TDbDuctNode::GetTips(DList<TObjInfoUnit> &info) const
|
||
{
|
||
CString csType = _T("堵头");
|
||
CStringArray csDrawMods;
|
||
if (m_nType==kElbow || m_nType==kKouElbow)
|
||
{
|
||
csType = (m_nType==kKouElbow)?_T("变高弯头"):_T("弯头");
|
||
csDrawMods.Add(_T("内外弧线"));
|
||
csDrawMods.Add(_T("内斜线"));
|
||
csDrawMods.Add(_T("内弧线"));
|
||
csDrawMods.Add(_T("内外直角线"));
|
||
csDrawMods.Add(_T("虾米弯"));
|
||
}
|
||
else if (m_nType == kYiZiElbow)
|
||
{
|
||
csType = _T("乙字弯");
|
||
csDrawMods.Add(_T("双弧"));
|
||
csDrawMods.Add(_T("斜接"));
|
||
csDrawMods.Add(_T("角接"));
|
||
}
|
||
else if (m_nType==kTapered || m_nType==kTianYuanDiFang)
|
||
{
|
||
csType = (m_nType==kTianYuanDiFang)?_T("天圆地方"):_T("变径");
|
||
csDrawMods.Add(_T("宽度决定"));
|
||
csDrawMods.Add(_T("角度决定"));
|
||
csDrawMods.Add(_T("用户输入"));
|
||
}
|
||
else if (m_nType==k3Corner || m_nType==kTaoDong)
|
||
{
|
||
csType = (m_nType==kTaoDong)?_T("三通"):_T("插管三通");
|
||
csDrawMods.Add(_T("普通三通"));
|
||
csDrawMods.Add(_T("直角三通"));
|
||
csDrawMods.Add(_T("圆角三通"));
|
||
csDrawMods.Add(_T("承插三通"));
|
||
csDrawMods.Add(_T("Y型三通"));
|
||
csDrawMods.Add(_T("T型三通"));
|
||
csDrawMods.Add(_T("平行三通"));
|
||
csDrawMods.Add(_T("圆管三通"));
|
||
csDrawMods.Add(_T("圆管三通"));
|
||
csDrawMods.Add(_T("斜插三通"));
|
||
csDrawMods.Add(_T("斜插三通"));
|
||
csDrawMods.Add(_T("叉形三通"));
|
||
csDrawMods.Add(_T("圆管三通"));
|
||
}
|
||
else if (m_nType == k4Corner)
|
||
{
|
||
csType = _T("四通");
|
||
csDrawMods.Add(_T("圆角四通"));
|
||
csDrawMods.Add(_T("直角四通"));
|
||
csDrawMods.Add(_T("承插四通"));
|
||
csDrawMods.Add(_T("交叉四通"));
|
||
csDrawMods.Add(_T("普通四通"));
|
||
csDrawMods.Add(_T("直角四通"));
|
||
csDrawMods.Add(_T("圆管四通"));
|
||
csDrawMods.Add(_T("圆管四通"));
|
||
}
|
||
else if (m_nType == kFlange)
|
||
{
|
||
csType = _T("法兰");
|
||
}
|
||
else if (m_nType == kOther)
|
||
{
|
||
csType = _T("未知连接件");
|
||
}
|
||
else if (m_nType == kSoft)
|
||
{
|
||
csType = _T("软接口");
|
||
}
|
||
|
||
CStringArray csFls;
|
||
csFls.Add(_T("单线法兰"));
|
||
csFls.Add(_T("双线法兰"));
|
||
csFls.Add(_T("三线法兰"));
|
||
csFls.Add(_T("双竖线"));
|
||
csFls.Add(_T("焊接"));
|
||
|
||
info.Append(new TObjInfoUnit(_T("连接件类型"), csType));
|
||
info.Append(new TObjInfoUnit(_T("连接件位置"), Point3d2Str(m_ptLocation)));
|
||
info.Append(new TObjInfoUnit(_T("连接方式"), csFls[m_nLinkType]));
|
||
info.Append(new TObjInfoUnit(_T("接口数量"), Dist2Str(GetInterfaceNum())));
|
||
if (m_nType==kOther || m_nType==kStem || m_nType==kSoft || m_nType==kTaoDong
|
||
|| m_nType==kFlange)
|
||
{
|
||
return; // 没有其他内容需要显示
|
||
}
|
||
|
||
if (m_nType==kTianYuanDiFang || m_nType==kTapered)
|
||
{
|
||
info.Append(new TObjInfoUnit(_T("长度计算法"), csDrawMods[m_nDrawMod]));
|
||
if (m_nDrawMod == 1)
|
||
{
|
||
info.Append(new TObjInfoUnit(_T("角度"), XString(_T("%.1f度"),
|
||
Rad2Degree(m_dDrawParam))));
|
||
}
|
||
else if (m_nDrawMod == 2)
|
||
{
|
||
info.Append(new TObjInfoUnit(_T("固定长度"), Dist2Str(m_dDrawParam2)));
|
||
}
|
||
return;
|
||
}
|
||
|
||
info.Append(new TObjInfoUnit(_T("绘制样式"), csDrawMods[m_nDrawMod]));
|
||
if (m_nType==kYiZiElbow)
|
||
{
|
||
info.Append(new TObjInfoUnit(_T("角度"), XString(_T("%.1f度"),
|
||
Rad2Degree(m_dDrawParam))));
|
||
if (m_nDrawMod == 1) // 斜接
|
||
{
|
||
info.Append(new TObjInfoUnit(_T("曲率半径"), Dist2Str(m_dDrawParam2)));
|
||
}
|
||
return;
|
||
}
|
||
|
||
info.Append(new TObjInfoUnit(_T("曲率半径"), Dist2Str(m_dDrawParam)));
|
||
if (m_nType == kElbow)
|
||
{
|
||
CString csMuffler = m_bMuffler?_T("是"):_T("否");
|
||
info.Append(new TObjInfoUnit(_T("消声弯头"), csMuffler));
|
||
if (m_bMuffler)
|
||
{
|
||
CStringArray csMufflers;
|
||
csMufflers.Add(_T("样式一"));
|
||
csMufflers.Add(_T("样式二"));
|
||
csMufflers.Add(_T("样式三"));
|
||
info.Append(new TObjInfoUnit(_T("消声弯头样式"),
|
||
csMufflers[m_nMufflerMod]));
|
||
}
|
||
|
||
CString csShowDLYP = m_bShowDLYP?_T("是"):_T("否");
|
||
info.Append(new TObjInfoUnit(_T("显示导流片"), csShowDLYP));
|
||
if (m_bShowDLYP)
|
||
{
|
||
info.Append(new TObjInfoUnit(_T("导流片类型"), _T("单层")));
|
||
info.Append(new TObjInfoUnit(_T("导流片数量"), Dist2Str(m_nDLYPNum)));
|
||
}
|
||
return;
|
||
}
|
||
|
||
if ((m_nType==k3Corner) && (m_nDrawMod==9 || m_nDrawMod==10 || m_nDrawMod==11))
|
||
{
|
||
info.Append(new TObjInfoUnit(_T("角度"), XString(_T("%.0f度"),
|
||
Rad2Degree(m_dDrawParam2))));
|
||
}
|
||
if ((m_nType==k4Corner) && (m_nDrawMod==7))
|
||
{
|
||
info.Append(new TObjInfoUnit(_T("角度"), XString(_T("%.0f度"),
|
||
Rad2Degree(m_dDrawParam2))));
|
||
}
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuctNode::GetGripText(int idx, CString &cs) const
|
||
{
|
||
if (m_nType == TDbDuctNode::kStem)
|
||
{
|
||
return Acad::eOk;
|
||
}
|
||
|
||
if (IsVisible() && (idx == 0))
|
||
{
|
||
cs = _T("移动风管节点");
|
||
}
|
||
return Acad::eOk;
|
||
}
|
||
|
||
|
||
|
||
////////////////////////////////存储数据////////////////////////////////////////////
|
||
Acad::ErrorStatus TDbDuctNode::dwgInFields(AcDbDwgFiler* pFiler)
|
||
{
|
||
assertWriteEnabled();
|
||
Acad::ErrorStatus es = TDbPipeNode::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;
|
||
}
|
||
|
||
Adesk::UInt8 nTmpNum;
|
||
pFiler->readItem(&nTmpNum);
|
||
m_nType = (TDbDuctNode::DuctNodeType)nTmpNum;
|
||
pFiler->readItem((AcGePoint3d*)&m_ptLocation);
|
||
pFiler->readItem(&m_nMain);
|
||
pFiler->readItem(&m_nSysDrawMod);
|
||
pFiler->readItem(&m_nAlign);
|
||
pFiler->readItem(&m_nDrawMod);
|
||
pFiler->readItem(&m_dDrawParam);
|
||
pFiler->readItem(&m_dDrawParam2);
|
||
pFiler->readItem(&nTmpNum);
|
||
m_nLinkType = (TDbDuctNode::FlangeLinkType)nTmpNum;
|
||
pFiler->readItem(&m_dFlangeDis);
|
||
pFiler->readItem(&m_dFlangeThick);
|
||
//pFiler->readItem(&m_bMuffler);
|
||
FilerRead(pFiler, m_bMuffler);
|
||
pFiler->readItem(&m_nMufflerMod);
|
||
//pFiler->readItem(&m_bShowDLYP);
|
||
FilerRead(pFiler, m_bShowDLYP);
|
||
pFiler->readItem(&m_nDLYPNum);
|
||
|
||
m_lstDuctIFace.Reset();
|
||
Adesk::UInt16 nNum = 0;
|
||
pFiler->readItem(&nNum);
|
||
for (Adesk::UInt16 i=0; i<nNum; i++)
|
||
{
|
||
TDuctIFaceMakeup *pDuctIFace = new TDuctIFaceMakeup;
|
||
m_lstDuctIFace.Append(pDuctIFace);
|
||
es = pDuctIFace->DwgInFields(pFiler);
|
||
if (es != Acad::eOk)
|
||
return es;
|
||
}
|
||
|
||
pFiler->readItem(&m_idDoteLayer);
|
||
pFiler->readItem(&m_idFlangeLayer);
|
||
|
||
if (nVer > 1) // 7.6
|
||
{
|
||
pFiler->readItem(&m_nDLYPType);
|
||
pFiler->readItem(&m_nXMWNum);
|
||
//pFiler->readItem(&m_bValue);
|
||
FilerRead(pFiler, m_bValue);
|
||
pFiler->readItem(&m_nSpare);
|
||
pFiler->readItem(&m_dSpare);
|
||
ReadString(pFiler, m_szSpare);
|
||
}
|
||
else // 7.5
|
||
{
|
||
m_nDLYPType = 0;
|
||
m_nXMWNum = 1;
|
||
m_bValue = FALSE;
|
||
m_nSpare = 0;
|
||
m_dSpare = 0.0;
|
||
m_szSpare = _T("");
|
||
|
||
if ((m_nType==k3Corner) && (m_nDrawMod==6))
|
||
{
|
||
m_nDrawMod = 7; // 针对7.5图的读取,做的修改
|
||
}
|
||
|
||
for (int j=0; j<nNum; j++)
|
||
{
|
||
SetIFlDist(j, m_dFlangeDis);
|
||
SetIFlThick(j, m_dFlangeThick);
|
||
}
|
||
}
|
||
return pFiler->filerStatus();
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuctNode::dwgOutFields(AcDbDwgFiler* pFiler) const
|
||
{
|
||
assertReadEnabled();
|
||
Acad::ErrorStatus es = TDbPipeNode::dwgOutFields(pFiler);
|
||
if (es != Acad::eOk)
|
||
return es;
|
||
|
||
pFiler->writeItem(g_nVersion);
|
||
pFiler->writeItem((Adesk::UInt8)m_nType);
|
||
pFiler->writeItem((const AcGePoint3d &)m_ptLocation);
|
||
pFiler->writeItem(m_nMain);
|
||
pFiler->writeItem(m_nSysDrawMod);
|
||
pFiler->writeItem(m_nAlign);
|
||
pFiler->writeItem(m_nDrawMod);
|
||
pFiler->writeItem(m_dDrawParam);
|
||
pFiler->writeItem(m_dDrawParam2);
|
||
pFiler->writeItem((Adesk::UInt8)m_nLinkType);
|
||
pFiler->writeItem(m_dFlangeDis);
|
||
pFiler->writeItem(m_dFlangeThick);
|
||
//pFiler->writeItem(m_bMuffler);
|
||
FilerWrite(pFiler, m_bMuffler);
|
||
pFiler->writeItem(m_nMufflerMod);
|
||
//pFiler->writeItem(m_bShowDLYP);
|
||
FilerWrite(pFiler, m_bShowDLYP);
|
||
pFiler->writeItem(m_nDLYPNum);
|
||
|
||
Adesk::UInt16 nCount = (Adesk::UInt16)m_lstDuctIFace.Length();
|
||
pFiler->writeItem(nCount);
|
||
BOOL bValid = objectId().isValid();
|
||
for (Adesk::UInt16 i=0; i<nCount; i++)
|
||
{
|
||
m_lstDuctIFace[i].DwgOutFields(pFiler, bValid);
|
||
}
|
||
|
||
pFiler->writeItem(m_idDoteLayer);
|
||
pFiler->writeItem(m_idFlangeLayer);
|
||
|
||
|
||
if (g_nSaveTArchVer > 6)
|
||
{
|
||
pFiler->writeItem(m_nDLYPType);
|
||
pFiler->writeItem(m_nXMWNum);
|
||
//pFiler->writeItem(m_bValue);
|
||
FilerWrite(pFiler, m_bValue);
|
||
pFiler->writeItem(m_nSpare);
|
||
pFiler->writeItem(m_dSpare);
|
||
pFiler->writeItem((const TCHAR *)m_szSpare);
|
||
}
|
||
return pFiler->filerStatus();
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuctNode::dxfInFields(AcDbDxfFiler* pFiler)
|
||
{
|
||
assertWriteEnabled();
|
||
Acad::ErrorStatus es = TDbPipeNode::dxfInFields(pFiler);
|
||
if (es != Acad::eOk)
|
||
return es;
|
||
|
||
if (!pFiler->atSubclassData(_T("TDbDuctNode")))
|
||
return Acad::eBadDxfSequence;
|
||
return pFiler->filerStatus();
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuctNode::dxfOutFields(AcDbDxfFiler* pFiler) const
|
||
{
|
||
Acad::ErrorStatus es = TDbPipeNode::dxfOutFields(pFiler);
|
||
assert(es == Acad::eOk);
|
||
|
||
es = pFiler->writeItem(AcDb::kDxfSubclass, _T("TDbDuctNode"));
|
||
assert(es == Acad::eOk);
|
||
return es;
|
||
}
|
||
|
||
// 如果是节点被复制,强制将全部接口的类型设置为1
|
||
Acad::ErrorStatus TDbDuctNode::subDeepClone(AcDbObject *pOwner, AcDbObject *&pClonedObject,
|
||
AcDbIdMapping &idMap,
|
||
Adesk::Boolean isPrimary) const
|
||
{
|
||
Acad::ErrorStatus es = TDbEntity::subDeepClone(pOwner, pClonedObject, idMap, isPrimary);
|
||
if (es != Acad::eOk)
|
||
{
|
||
return es;
|
||
}
|
||
|
||
TDbDuctNode* pNewNode = TDbDuctNode::cast(pClonedObject);
|
||
if (pNewNode != NULL)
|
||
{
|
||
int nLen = pNewNode->GetInterfaceNum();
|
||
for (int i=0; i<nLen; i++)
|
||
{
|
||
pNewNode->SetIType(i, 1);
|
||
}
|
||
}
|
||
return Acad::eOk;
|
||
}
|
||
|
||
|
||
/////////////////////////////////拾取有关////////////////////////////////////////
|
||
Acad::ErrorStatus
|
||
TDbDuctNode::subGetOsnapPoints(AcDb::OsnapMode osnapMode, INT_PTR gsSelectionMark,
|
||
const AcGePoint3d &ptPick, const AcGePoint3d &lastPoint,
|
||
const AcGeMatrix3d &viewXform,
|
||
AcGePoint3dArray &snapPoints, AcDbIntArray &geomIds) const
|
||
{
|
||
assertReadEnabled();
|
||
if (osnapMode==AcDb::kOsModeIns || osnapMode==AcDb::kOsModeNode)
|
||
{
|
||
snapPoints.append(m_ptLocation);
|
||
}
|
||
|
||
Acad::ErrorStatus es = TDbPipeNode::subGetOsnapPoints(osnapMode, gsSelectionMark,
|
||
ptPick, lastPoint, viewXform, snapPoints, geomIds);
|
||
return es;
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuctNode::subGetGripPoints(AcGePoint3dArray &gripPoints,
|
||
AcDbIntArray &osnapModes,
|
||
AcDbIntArray &geomIds) const
|
||
{
|
||
assertReadEnabled();
|
||
if (m_nType == TDbDuctNode::kStem)
|
||
{
|
||
return Acad::eOk;
|
||
}
|
||
|
||
if (IsVisible())
|
||
{
|
||
GetGSPoints(gripPoints);
|
||
}
|
||
return Acad::eOk;
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuctNode::subGetStretchPoints(AcGePoint3dArray &stretchPoints) const
|
||
{
|
||
assertReadEnabled();
|
||
if (m_nType == TDbDuctNode::kStem)
|
||
{
|
||
return Acad::eOk;
|
||
}
|
||
|
||
if (IsVisible())
|
||
{
|
||
GetGSPoints(stretchPoints);
|
||
}
|
||
return Acad::eOk;
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuctNode::GetGSPoints(AcGePoint3dArray &stretchPoints) const
|
||
{
|
||
if (m_nType == TDbDuctNode::kStem)
|
||
{
|
||
return Acad::eOk;
|
||
}
|
||
|
||
stretchPoints.append(m_ptLocation);
|
||
return Acad::eOk;
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuctNode::subMoveGripPointsAt(const AcDbIntArray &indices,
|
||
const AcGeVector3d &offset)
|
||
{
|
||
assertWriteEnabled();
|
||
Acad::ErrorStatus es = Acad::eOk;
|
||
if (m_nType == TDbDuctNode::kStem)
|
||
{
|
||
return Acad::eOk;
|
||
}
|
||
|
||
if (IsVisible())
|
||
{
|
||
es = MoveGSPointsAt(indices, offset);
|
||
}
|
||
|
||
if (objectId().isValid())
|
||
{
|
||
int nLen = GetInterfaceNum();
|
||
for (int i=0; i<nLen; i++)
|
||
{
|
||
SetIType(i, 1);
|
||
}
|
||
}
|
||
return es;
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuctNode::subMoveStretchPointsAt(const AcDbIntArray &indices,
|
||
const AcGeVector3d &offset)
|
||
{
|
||
assertWriteEnabled();
|
||
Acad::ErrorStatus es = Acad::eOk;
|
||
if (m_nType == TDbDuctNode::kStem)
|
||
{
|
||
return Acad::eOk;
|
||
}
|
||
|
||
if (IsVisible())
|
||
{
|
||
es = MoveGSPointsAt(indices, offset);
|
||
}
|
||
return es;
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuctNode::MoveGSPointsAt(const AcDbIntArray &indices,
|
||
const AcGeVector3d &offset)
|
||
{
|
||
if (m_nType == TDbDuctNode::kStem)
|
||
{
|
||
return Acad::eOk;
|
||
}
|
||
|
||
AcGeMatrix3d mat;
|
||
mat.setToTranslation(offset);
|
||
Acad::ErrorStatus es = subTransformBy(mat);
|
||
return es;
|
||
}
|
||
|
||
|
||
///////////////////////////////Override AcDbEntity///////////////////////////////
|
||
Acad::ErrorStatus TDbDuctNode::subTransformBy(const AcGeMatrix3d& xform)
|
||
{
|
||
assertWriteEnabled();
|
||
Acad::ErrorStatus es = TDbPipeNode::subTransformBy(xform);
|
||
m_ptLocation.TransformBy(xform);
|
||
|
||
if (!!objectId())
|
||
{
|
||
XString &sCmd = GetCurDocData()->m_sCurCommand;
|
||
if (_tcsicmp(sCmd, _T("MOVE")) == 0)
|
||
{
|
||
int nLen = GetInterfaceNum();
|
||
for (int i=0; i<nLen; i++)
|
||
{
|
||
SetIType(i, 1);
|
||
}
|
||
}
|
||
}
|
||
return es;
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuctNode::GetExtents(XPoint &ptLow, XPoint &ptUp) const
|
||
{
|
||
Acad::ErrorStatus es = TDbPipeNode::GetExtents(ptLow, ptUp);
|
||
if (es == Acad::eOk)
|
||
{
|
||
if (ptLow==XPoint() && ptUp==XPoint())
|
||
{
|
||
ptLow = m_ptLocation;
|
||
ptUp = m_ptLocation;
|
||
}
|
||
else
|
||
{
|
||
ptLow = Min(ptLow, m_ptLocation);
|
||
ptUp = Max(ptUp, m_ptLocation);
|
||
}
|
||
}
|
||
return es;
|
||
}
|
||
|
||
|
||
|
||
|
||
///////////////////////////////////二维绘制/////////////////////////////////////
|
||
Acad::ErrorStatus TDbDuctNode::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;
|
||
}
|
||
int nLen1 = GetInterfaceNum(),
|
||
nLen2 = GetDuctIFaceNum();
|
||
if (nLen1 != nLen2)
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
Acad::ErrorStatus es = Acad::eOk;
|
||
if (m_nSysDrawMod == 4) // 系统图
|
||
{
|
||
es = ExplodeOrDrawSys(dc);
|
||
return es;
|
||
}
|
||
|
||
BOOL bTYDF = m_nType==kTianYuanDiFang;
|
||
switch(m_nType)
|
||
{
|
||
case kElbow: // 弯头
|
||
es = DrawElbow2D(dc);
|
||
break;
|
||
case kKouElbow: // 扣弯
|
||
es = DrawKElbow2D(dc);
|
||
break;
|
||
case kTapered: // 变径
|
||
case kTianYuanDiFang: // 天圆地方
|
||
es = DrawTapered2D(dc, bTYDF);
|
||
break;
|
||
case kYiZiElbow: // 乙字弯
|
||
es = DrawYZElbow2D(dc);
|
||
break;
|
||
case k3Corner: // 三通
|
||
es = Draw3Corner2D(dc);
|
||
break;
|
||
case kTaoDong: // 掏洞三通
|
||
es = DrawTaoDong2D(dc);
|
||
break;
|
||
case k4Corner: // 四通
|
||
es = Draw4Corner2D(dc);
|
||
break;
|
||
}
|
||
|
||
if (es == Acad::eOk)
|
||
{
|
||
es = DrawFL2D(dc); // 法兰
|
||
}
|
||
return es;
|
||
}
|
||
|
||
|
||
////////////////////////////二维辅助绘制/////////////////////////////
|
||
// 绘制节点中心线seg,先切换图层,然后绘制
|
||
void TDbDuctNode::DrawMidSegs(XExplodeDraw &dc, const DList<XCurveSegment> &segs) const
|
||
{
|
||
AcDbObjectId idLayerOld = dc.GetLayerId(), // 先保存,旧图层ID
|
||
idLineTypeOld = dc.GetLineTypeId(); // 旧线型ID
|
||
AcDbObjectId idLayer = m_idDoteLayer;
|
||
if (idLayer.isValid()) // 再创建,新图层ID
|
||
{
|
||
dc.SetLayer(idLayer);
|
||
}
|
||
dc.SetColorLayer(colorIndex(), idLayer);
|
||
|
||
AcDbObjectId idLineType;
|
||
OPENOBJ_BEGIN(idLayer, AcDb::kForRead, AcDbLayerTableRecord, pRec);
|
||
if (pRec != NULL)
|
||
{
|
||
idLineType = pRec->linetypeObjectId();
|
||
dc.SetLineType(idLineType);
|
||
}
|
||
OPENOBJ_END();
|
||
|
||
int nLen = segs.Length();
|
||
for (int i=0; i<nLen; i++)
|
||
{
|
||
dc << segs[i]; // 接着绘制
|
||
}
|
||
dc.SetLayer(idLayerOld); // 最后修改回原图层、线型
|
||
dc.SetColorLayer(colorIndex(), idLayerOld);
|
||
dc.SetLineType(idLineTypeOld);
|
||
}
|
||
|
||
// 绘制节点中需要分粗、细两种画法的seg
|
||
void TDbDuctNode::Draw2DSegs(XExplodeDraw &dc, const DList<XCurveSegment> &segs) const
|
||
{
|
||
double dDuct1Weight(0);
|
||
OPENOBJ_BEGIN(GetIPipe(0), AcDb::kForRead, TDbDuct, pDuct);
|
||
if (pDuct != NULL)
|
||
{
|
||
dDuct1Weight = pDuct->GetDuctWeight();
|
||
}
|
||
OPENOBJ_END();
|
||
|
||
int nLen = segs.Length();
|
||
double dWeight = GetPScale() * dDuct1Weight;
|
||
for (int i=0; i<nLen; i++)
|
||
{
|
||
XCurveSegment seg = segs[i];
|
||
if (g_bPipeWeight)
|
||
{
|
||
DrawWeight(dc, dWeight, seg, colorIndex(), linetypeScale());
|
||
}
|
||
else
|
||
{
|
||
dc << seg;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 绘制节点中细线seg
|
||
void TDbDuctNode::DrawXiSegs(XExplodeDraw &dc, const DList<XCurveSegment> &segs) const
|
||
{
|
||
int nLen = segs.Length();
|
||
for (int i=0; i<nLen; i++)
|
||
{
|
||
dc << segs[i];
|
||
}
|
||
}
|
||
|
||
// 绘制法兰层seg
|
||
void TDbDuctNode::DrawFLSegs(XExplodeDraw &dc, const DList<XCurveSegment> &segs) const
|
||
{
|
||
AcDbObjectId idLayerOld = dc.GetLayerId(), // 先保存,旧图层ID
|
||
idLineTypeOld = dc.GetLineTypeId(), // 旧线型ID
|
||
idLayer = m_idFlangeLayer;
|
||
if (idLayer.isValid()) // 再创建,新图层ID
|
||
{
|
||
dc.SetLayer(idLayer);
|
||
}
|
||
dc.SetColorLayer(colorIndex(), idLayer);
|
||
|
||
AcDbObjectId idLineType;
|
||
OPENOBJ_BEGIN(idLayer, AcDb::kForRead, AcDbLayerTableRecord, pRec);
|
||
if (pRec != NULL)
|
||
{
|
||
idLineType = pRec->linetypeObjectId();
|
||
dc.SetLineType(idLineType);
|
||
}
|
||
OPENOBJ_END();
|
||
|
||
int nLen = segs.Length();
|
||
for (int i=0; i<nLen; i++)
|
||
{
|
||
dc << segs[i]; // 接着绘制
|
||
}
|
||
dc.SetLayer(idLayerOld); // 最后修改回原图层、线型
|
||
dc.SetColorLayer(colorIndex(), idLayerOld);
|
||
}
|
||
|
||
|
||
////////////////////////二维辅助绘制构造Segs//////////////////////////
|
||
void TDbDuctNode::BuildSegs1(XPoint pt1, XPoint pt2, // 两点一线
|
||
DList<XCurveSegment> &segs) const
|
||
{
|
||
XCurveSegment seg;
|
||
seg = XLine(pt1, pt2, LS_FINITE);
|
||
segs.Append(new XCurveSegment(seg));
|
||
}
|
||
|
||
void TDbDuctNode::BuildSegs2(XPoint pt1, XPoint ptInt, XPoint pt2, // 三点两线
|
||
DList<XCurveSegment> &segs) const
|
||
{
|
||
XCurveSegment seg;
|
||
seg = XLine(pt1, ptInt, LS_FINITE);
|
||
segs.Append(new XCurveSegment(seg));
|
||
seg = XLine(ptInt, pt2, LS_FINITE);
|
||
segs.Append(new XCurveSegment(seg));
|
||
}
|
||
|
||
void TDbDuctNode::BuildSegs6(XPoint pt1, XPoint pt2, XPoint pt3, XPoint pt4,
|
||
DList<XCurveSegment> &segs) const // 四点三线
|
||
{
|
||
XCurveSegment seg;
|
||
seg = XLine(pt1, pt2, LS_FINITE);
|
||
segs.Append(new XCurveSegment(seg));
|
||
seg = XLine(pt2, pt3, LS_FINITE);
|
||
segs.Append(new XCurveSegment(seg));
|
||
seg = XLine(pt3, pt4, LS_FINITE);
|
||
segs.Append(new XCurveSegment(seg));
|
||
}
|
||
|
||
void TDbDuctNode::BuildSegs3(const XLine &line, DList<XCurveSegment> &segs) const // 线
|
||
{
|
||
XCurveSegment seg;
|
||
seg = line;
|
||
segs.Append(new XCurveSegment(seg));
|
||
}
|
||
|
||
void TDbDuctNode::BuildSegs4(XArc &arc, DList<XCurveSegment> &segs) const // 弧
|
||
{
|
||
XCurveSegment seg;
|
||
seg = arc;
|
||
segs.Append(new XCurveSegment(seg));
|
||
}
|
||
|
||
void TDbDuctNode::BuildSegs5(XCircle &circle, DList<XCurveSegment> &segs) const // 圆
|
||
{
|
||
XCurveSegment seg;
|
||
seg = circle;
|
||
segs.Append(new XCurveSegment(seg));
|
||
}
|
||
|
||
|
||
////////////////////////////公共绘制算法//////////////////////////////
|
||
// 类似不带消声的“内斜线”弯头中的内线,特点为两端为50长度短线
|
||
// 注:弯头中nSide是0,三/四通中nSide是1
|
||
BOOL TDbDuctNode::DrawLine(DList<XCurveSegment> &lstSeg, XLine l1,
|
||
XLine l2, int nSide) const
|
||
{
|
||
XPoint ptInt, ptTmp1, ptTmp2;
|
||
if (l1.Intersection(&l2, ptInt) != 1)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
XVector3D vt1 = ptInt - l1.EndPoint(),
|
||
vt2 = ptInt - l2.EndPoint();
|
||
vt1.Normalize();
|
||
vt2.Normalize();
|
||
vt1.Scale(50);
|
||
vt2.Scale(50);
|
||
|
||
XPoint ptStart1 = (nSide==0)?l1.StartPoint():l1.EndPoint(),
|
||
ptStart2 = (nSide==0)?l2.StartPoint():l2.EndPoint();
|
||
ptTmp1 = ptStart1 + vt1;
|
||
ptTmp2 = ptStart2 + vt2;
|
||
BuildSegs6(ptStart1, ptTmp1, ptTmp2, ptStart2, lstSeg);
|
||
return TRUE;
|
||
}
|
||
|
||
// 注:以较短距离的80%为长度,绘制相切弧
|
||
BOOL TDbDuctNode::DrawArc(DList<XCurveSegment> &lstSeg, XPoint ptCorner1,
|
||
XPoint ptCorner2, XPoint pt1, XPoint pt2, BOOL bIsBig) const
|
||
{
|
||
XPoint ptTmp1, ptTmp2, ptInt, ptCen;
|
||
double dAngle1 = ads_angle(XPoint(), XVector3D(ptCorner1-pt1)),
|
||
dAngle2 = ads_angle(XPoint(), XVector3D(ptCorner2-pt2));
|
||
ads_polar(pt1, dAngle1+PI/2, 800, ptTmp1);
|
||
ads_polar(pt2, dAngle2+PI/2, 800, ptTmp2);
|
||
|
||
XLine lineTmp1(ptTmp1, pt1, LS_INFINITE),
|
||
lineTmp2(ptTmp2, pt2, LS_INFINITE);
|
||
if (!lineTmp1.Intersection(&lineTmp2, ptInt))
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
XPoint ptNear = ::GetNearPt(ptInt, pt1, pt2);
|
||
double dScale = bIsBig?0.8:0.2,
|
||
dDist = ptInt.Distance(ptNear) * dScale; // 注:取较短距离的0.8
|
||
::AT_cal_fillet(pt1, ptInt, pt2, dDist, ptTmp1, ptCen, ptTmp2, FALSE);
|
||
|
||
BOOL bSwitch(TRUE);
|
||
XArc arc = ::GetRightArc(ptTmp1, ptCen, ptTmp2, bSwitch); // 选择优弧
|
||
BuildSegs4(arc, lstSeg);
|
||
BuildSegs1(pt1, ptTmp1, lstSeg);
|
||
BuildSegs1(ptTmp2, pt2, lstSeg);
|
||
return TRUE;
|
||
}
|
||
|
||
// 注:两端以50长度短线与弧线连接,类似弯头
|
||
BOOL TDbDuctNode::DrawArc2(DList<XCurveSegment> &lstSeg, int nIFace1, int nIFace2,
|
||
XPoint pt1, XPoint pt2, BOOL bMidLine, double dNum) const
|
||
{
|
||
XVector3D vt1 = GetIDirection(nIFace1),
|
||
vt2 = GetIDirection(nIFace2);
|
||
vt1.Normalize();
|
||
vt2.Normalize();
|
||
vt1.Scale(-dNum);
|
||
vt2.Scale(-dNum);
|
||
|
||
XPoint pt3 = pt1 + vt1,
|
||
pt4 = pt2 + vt2;
|
||
BuildSegs1(pt1, pt3, lstSeg); // 50长度短线
|
||
BuildSegs1(pt2, pt4, lstSeg);
|
||
|
||
XPoint ptInt;
|
||
XLine line1(pt1, pt3, LS_INFINITE),
|
||
line2(pt2, pt4, LS_INFINITE);
|
||
if (!line1.Intersection(&line2, ptInt)) // 交点
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
XPoint ptCen, ptTmp1, ptTmp2, ptMid;
|
||
double dDist = ptInt.Distance(pt4); // 获取圆心
|
||
::AT_cal_fillet(pt3, ptInt, pt4, dDist, ptTmp1, ptCen, ptTmp2, FALSE);
|
||
|
||
XArc arc;
|
||
BOOL bSwitch(TRUE);
|
||
|
||
if (bMidLine) // 中心线
|
||
{
|
||
arc = ::GetRightArc(ptTmp1, ptCen, ptTmp2, bSwitch);
|
||
if (bSwitch) // 获取优弧
|
||
{
|
||
arc.SetAngleByPoints(pt3, pt4);
|
||
}
|
||
else
|
||
{
|
||
arc.SetAngleByPoints(pt4, pt3);
|
||
}
|
||
}
|
||
else // 不是中心线
|
||
{
|
||
arc = ::GetRightArc(pt3, ptCen, pt4, bSwitch);
|
||
arc.MidPoint(ptMid);
|
||
double dWidth1 = GetIWidth(nIFace1),
|
||
dWidth2 = GetIWidth(nIFace2);
|
||
if (fabs(dWidth1 - dWidth2) > 0.001) // 管线宽度不一样
|
||
{
|
||
arc.MidPoint(ptMid);
|
||
if (bSwitch)
|
||
{
|
||
arc = XArc(pt3, ptMid, pt4);
|
||
}
|
||
else
|
||
{
|
||
arc = XArc(pt4, ptMid, pt3);
|
||
}
|
||
}
|
||
}
|
||
BuildSegs4(arc, lstSeg);
|
||
return TRUE;
|
||
}
|
||
|
||
// 注:三通样式9、10、11,四通样式7,斜接乙字弯中的弯头弧线画法
|
||
XPoint TDbDuctNode::GetArcPts(XPoint ptStart, double dWide, double dDirection,
|
||
XPoint ptRef, DList<XCurveSegment> &segs,
|
||
double &dNewAng) const
|
||
{
|
||
XPoint ptS50, ptEnd, ptE50, ptCen, ptMid;
|
||
ads_polar(ptStart, dDirection, -50, ptS50); // 获取第二点
|
||
BuildSegs1(ptStart, ptS50, segs);
|
||
|
||
ads_polar(ptStart, dDirection, -15*dWide, ptE50);
|
||
XCurveSegment seg(ptStart, ptE50, 0, LS_FINITE);
|
||
seg.ProjectToMe(ptRef, ptEnd);
|
||
XVector3D vtCen = ptRef - ptEnd; // 将参考点向线上做投影,确定圆心方向
|
||
vtCen.Normalize();
|
||
|
||
BOOL bYZElbow = GetNodeType()==kYiZiElbow;
|
||
double dAngle = (m_nDrawMod!=11)?(PI/2-m_dDrawParam2):PI/3, // 弯头角度
|
||
dRadius = dWide*m_dDrawParam + 50; // 旧的半径,考虑了曲率
|
||
dAngle = bYZElbow?m_dDrawParam:dAngle;
|
||
dRadius = bYZElbow?dWide:dRadius;
|
||
vtCen.Scale(dRadius);
|
||
ptCen = ptStart + vtCen; // 旧的圆心位置
|
||
|
||
double dSAng = ads_angle(XPoint(), XVector3D(ptStart-ptCen)); // 起点角度
|
||
dSAng = CT_std_angle(dSAng);
|
||
double dEAng = CT_std_angle(dSAng+dAngle),
|
||
dEAng2 = CT_std_angle(dSAng-dAngle);
|
||
ads_polar(ptCen, dEAng, dRadius, ptEnd);
|
||
ads_polar(ptCen, dEAng2, dRadius, ptE50);
|
||
ptEnd = ::GetNearPt(ptRef, ptEnd, ptE50); // 终点坐标
|
||
dEAng = ads_angle(XPoint(), XVector3D(ptEnd-ptCen)); // 终点角度
|
||
dEAng = CT_std_angle(dEAng);
|
||
|
||
Midpoint(ptStart, ptEnd, ptMid);
|
||
vtCen = ptMid - ptCen; // 两个圆心之间的方向
|
||
vtCen.Normalize();
|
||
double dLen = 50/(sin(dAngle*0.5)); // 两个圆心之间的距离
|
||
vtCen.Scale(dLen);
|
||
ptCen = ptCen + vtCen; // 新的圆心
|
||
dRadius = ptCen.Distance(ptS50);
|
||
ads_polar(ptCen, dEAng, dRadius, ptE50);
|
||
BuildSegs1(ptE50, ptEnd, segs);
|
||
dNewAng = ads_angle(XPoint(), XVector3D(ptEnd-ptE50));
|
||
|
||
BOOL bSwitch(FALSE);
|
||
XArc arc = ::GetRightArc(ptS50, ptCen, ptE50, bSwitch); // 选择优弧
|
||
BuildSegs4(arc, segs);
|
||
return ptEnd;
|
||
}
|
||
|
||
BOOL TDbDuctNode::DrawFlange(DList<XCurveSegment> &segs, XPoint pt, // 注:2D绘制法兰
|
||
double dAngle, double dFlDia, double dFlThick) const
|
||
{
|
||
pt.z = 0;
|
||
XPoint pt1, pt2; // 上下两点
|
||
ads_polar(pt, dAngle+PI/2, dFlDia/2, pt1);
|
||
ads_polar(pt, dAngle-PI/2, dFlDia/2, pt2);
|
||
if (m_nLinkType==kSingleLine || m_nLinkType==kSingleFlange)
|
||
{
|
||
BuildSegs1(pt1, pt2, segs); // 单线法兰、焊接
|
||
return TRUE;
|
||
}
|
||
|
||
if (m_nLinkType == kTrebleFlange) // 三线法兰
|
||
{
|
||
BuildSegs1(pt1, pt2, segs);
|
||
}
|
||
|
||
XPoint ptTmp, pt3, pt4;
|
||
ads_polar(pt, dAngle, dFlThick/2, ptTmp);
|
||
ads_polar(ptTmp, dAngle+PI/2, dFlDia/2, pt1); // 四个角点
|
||
ads_polar(ptTmp, dAngle-PI/2, dFlDia/2, pt2);
|
||
ads_polar(pt1, dAngle, -dFlThick, pt3);
|
||
ads_polar(pt2, dAngle, -dFlThick, pt4);
|
||
if (m_nLinkType==kBothFlange || m_nLinkType==kTrebleFlange)
|
||
{
|
||
BuildSegs2(pt1, pt2, pt4, segs); // 双线法兰、三线法兰
|
||
BuildSegs2(pt4, pt3, pt1, segs);
|
||
}
|
||
else if (m_nLinkType == kBothLine) // 双竖线
|
||
{
|
||
BuildSegs1(pt1, pt2, segs);
|
||
BuildSegs1(pt3, pt4, segs);
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
//////////////////////////////辅助绘制////////////////////////////////
|
||
XPoint TDbDuctNode::GetZeroPt() const // 将m_ptLocation的Z坐标置为0
|
||
{
|
||
XPoint ptLoc;
|
||
Spoint(ptLoc, m_ptLocation.x, m_ptLocation.y, 0);
|
||
return ptLoc;
|
||
}
|
||
|
||
// 获取法兰遮挡后与管线连接的点位置
|
||
// bSys:是否是系统图;bIs3D:是否为3D;b50Len:是否为50长度;bZero:是否自动将Z坐标归0
|
||
void TDbDuctNode::GetPtsIFace(XPointList &pts, BOOL bSys, BOOL bIs3D,
|
||
BOOL b50Len, BOOL bZero, double dNum) const
|
||
{
|
||
pts.Reset();
|
||
int nLen = GetInterfaceNum();
|
||
for (int i=0; i<nLen; i++)
|
||
{
|
||
XPoint pt = GetILocation(i); // 连接点
|
||
AcGeVector3d vec = GetIDirection(i).AsAcGeVector3d();
|
||
vec.normalize(); // 连接方向
|
||
|
||
double dThick(0.0);
|
||
if (!bSys)
|
||
{
|
||
dThick = GetIFlThick(i)*0.5; // 法兰厚度
|
||
if (!IsHidePipe()) // 法兰是否遮挡节点
|
||
{
|
||
dThick = bIs3D?2.0:0.0;
|
||
}
|
||
}
|
||
|
||
if (m_nType==k3Corner && fabs(vec.x)<1.0E-6 && fabs(vec.y)<1.0E-6)
|
||
{
|
||
pt = pt + XVector3D(vec*dThick); // 三通中的立管接口
|
||
}
|
||
else // 其他情况
|
||
{
|
||
dThick = (b50Len?dNum:0.0) + dThick;
|
||
pt = pt - XVector3D(vec*dThick);
|
||
}
|
||
|
||
if (bZero) // 将Z坐标归0
|
||
{
|
||
pt.z = 0;
|
||
}
|
||
pts.Append(new XPoint(pt));
|
||
}
|
||
}
|
||
|
||
// 获取各支管编号,注:逆时针排序
|
||
AcDbIntArray TDbDuctNode::GetBranchNums(int nMain) const
|
||
{
|
||
DList<AcDbObjectId> ids;
|
||
GetAllLinkDucts(ids);
|
||
AcDbIntArray types = GetAllTypes();
|
||
return ::GetCornerBranchNums(objectId(), m_ptLocation, ids, types, nMain);
|
||
}
|
||
|
||
// 获取m_ptLocation向各管线中线的投影,用于处理偏心
|
||
void TDbDuctNode::GetTrueMidPts(XPointList &pts) const
|
||
{
|
||
DList<AcDbObjectId> ids;
|
||
GetAllLinkDucts(ids);
|
||
AcDbIntArray types = GetAllTypes();
|
||
pts.Reset();
|
||
::GetDuctTrueMidPts(objectId(), m_ptLocation, ids, types, pts);
|
||
|
||
int nLen = pts.Length();
|
||
for (int i=0; i<nLen; i++)
|
||
{
|
||
pts[i]->z = 0;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/////////////////////////////系统图绘制///////////////////////////////
|
||
XCurveSegment GetArcSeg1(XPoint pt1, XPoint ptCen, XPoint pt2,
|
||
double dWidth1, double dWidth2);
|
||
XCurveSegment GetArcSeg2(XPoint pt1, XPoint ptInt, XPoint pt2,
|
||
double dRadius, double dWidth1, double dWidth2);
|
||
XCurveSegment GetArcSeg3(XPoint ptStart, XPoint ptCen, XPoint &ptEnd, double dRadius,
|
||
double dAngle, const AcGeVector3d &vecNormal,
|
||
const AcGeVector3d &vecRef);
|
||
Acad::ErrorStatus TDbDuctNode::ExplodeOrDrawSys(XExplodeDraw &dc) const
|
||
{
|
||
if (m_nSysDrawMod != 4) // 必须是系统图
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
Acad::ErrorStatus es = Acad::eOk;
|
||
switch(m_nType)
|
||
{
|
||
case kElbow: // 弯头
|
||
case kKouElbow: // 扣弯
|
||
es = DrawSysElbow(dc);
|
||
break;
|
||
case kTapered: // 变径
|
||
es = DrawSysTapered(dc);
|
||
break;
|
||
case kTianYuanDiFang: // 天圆地方
|
||
es = DrawSysTYDF(dc);
|
||
break;
|
||
case kYiZiElbow: // 乙字弯
|
||
es = DrawSysYZElbow(dc);
|
||
break;
|
||
case k3Corner: // 三通
|
||
es = DrawSys3T(dc);
|
||
break;
|
||
case kTaoDong: // 掏洞三通
|
||
es = DrawSysTD(dc);
|
||
break;
|
||
case k4Corner: // 四通
|
||
es = DrawSys4T(dc);
|
||
break;
|
||
}
|
||
return es; // 直接返回,不绘制法兰
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuctNode::DrawSysElbow(XExplodeDraw &dc) const // 弯头
|
||
{
|
||
XPointList pts;
|
||
GetPtsIFace(pts, TRUE, FALSE, FALSE, TRUE);
|
||
if (pts.Length() != 2) // 1、获取与管线相连点,考虑了法兰遮挡
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
DList<XCurveSegment> segs; // 2、绘制
|
||
XPoint ptLoc = GetZeroPt(),
|
||
ptCen, ptTmp1, ptTmp2;
|
||
double dDist = ptLoc.Distance(*pts[1]) * 0.25; // 只取实际曲率的1/4,其他补直线
|
||
::AT_cal_fillet(*pts[0], ptLoc, *pts[1], dDist, ptTmp1, ptCen, ptTmp2, FALSE);
|
||
|
||
BOOL bSwitch(TRUE);
|
||
XArc arc = ::GetRightArc(ptTmp1, ptCen, ptTmp2, bSwitch); // 选择优弧
|
||
BuildSegs4(arc, segs);
|
||
BuildSegs1(*pts[0], ptTmp1, segs);
|
||
BuildSegs1(ptTmp2, *pts[1], segs);
|
||
Draw2DSegs(dc, segs);
|
||
return Acad::eOk;
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuctNode::DrawSysTapered(XExplodeDraw &dc) const // 变径
|
||
{
|
||
XPointList pts;
|
||
GetPtsIFace(pts, TRUE, FALSE, FALSE, TRUE);
|
||
if (pts.Length() != 2) // 1、获取与管线相连点,考虑了法兰遮挡
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
double dDist = pts[0]->Distance(*pts[1]),
|
||
dDraw = (dDist > 300-1.0E-5)?(dDist/6.0):dDist;
|
||
dDraw = (dDist > 600-1.0E-5)?(dDist/3.0):dDraw; // 2、确定绘制长度
|
||
|
||
double dWidth1 = GetIWidth(0), // 管线尺寸
|
||
dWidth2 = GetIWidth(1),
|
||
dHigh1 = GetIHeight(0),
|
||
dHigh2 = GetIHeight(1);
|
||
int nBig(0);
|
||
double dTmp1 = fabs(dWidth1 - dWidth2),
|
||
dTmp2 = fabs(dHigh1 - dHigh2);
|
||
if (dTmp1 > dTmp2 - 1.0E-5) // 宽度变化
|
||
{
|
||
nBig = dWidth1>dWidth2-1.0E-5?0:1; // 2、获取较大管径编号
|
||
}
|
||
else // 高度变化
|
||
{
|
||
nBig = dHigh1>dHigh2-1.0E-5?0:1;
|
||
}
|
||
|
||
int nSmall = 1 - nBig;
|
||
DList<XCurveSegment> lstSeg;
|
||
double dAng = GetIAngle(nBig);
|
||
XPoint ptTmp1, ptTmp2, pt1, pt2, pt3, pt4;
|
||
ads_polar(*pts[nBig], dAng, -dDraw, ptTmp1);
|
||
ads_polar(*pts[nSmall], dAng, dDraw, ptTmp2);
|
||
BuildSegs1(*pts[nBig], ptTmp1, lstSeg); // 3、补充绘制
|
||
BuildSegs1(*pts[nSmall], ptTmp2, lstSeg);
|
||
|
||
ads_polar(ptTmp1, dAng-PI/4*3, 150, pt1);
|
||
ads_polar(ptTmp1, dAng+PI/4, 150, pt2);
|
||
ads_polar(ptTmp2, dAng-PI/4*3, 100, pt3);
|
||
ads_polar(ptTmp2, dAng+PI/4, 100, pt4);
|
||
BuildSegs1(pt1, pt3, lstSeg); // 4、绘制上下线
|
||
BuildSegs1(pt2, pt4, lstSeg);
|
||
|
||
ads_polar(ptTmp1, dAng-PI/4*3, 180, pt1);
|
||
ads_polar(ptTmp1, dAng+PI/4, 180, pt2);
|
||
ads_polar(ptTmp2, dAng-PI/4*3, 130, pt3);
|
||
ads_polar(ptTmp2, dAng+PI/4, 130, pt4);
|
||
BuildSegs1(pt1, pt2, lstSeg); // 5、绘制类法兰线
|
||
BuildSegs1(pt3, pt4, lstSeg);
|
||
Draw2DSegs(dc, lstSeg);
|
||
return Acad::eOk;
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuctNode::DrawSysTYDF(XExplodeDraw &dc) const // 天圆地方
|
||
{
|
||
XPointList pts;
|
||
GetPtsIFace(pts, TRUE, FALSE, FALSE, TRUE);
|
||
if (pts.Length() != 2) // 1、获取与管线相连点,考虑了法兰遮挡
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
double dDist = pts[0]->Distance(*pts[1]),
|
||
dDraw = (dDist > 300-1.0E-5)?(dDist/6.0):dDist;
|
||
dDraw = (dDist>600-1.0E-5)?(dDist/3.0):dDraw; // 2、确定绘制长度
|
||
|
||
int nRect = (GetISection(0)==0)?0:1, // 3、获取方管编号
|
||
nCircle = 1- nRect;
|
||
|
||
double dAng = GetIAngle(nRect);
|
||
DList<XCurveSegment> lstSeg;
|
||
XPoint ptTmp1, ptTmp2, pt1, pt2, pt3, pt4;
|
||
ads_polar(*pts[nRect], dAng, -dDraw, ptTmp1);
|
||
ads_polar(*pts[nCircle], dAng, dDraw, ptTmp2);
|
||
BuildSegs1(*pts[nRect], ptTmp1, lstSeg); // 4、补充绘制
|
||
BuildSegs1(*pts[nCircle], ptTmp2, lstSeg);
|
||
|
||
ads_polar(ptTmp1, dAng-PI/4*3, 150, pt1);
|
||
ads_polar(ptTmp1, dAng+PI/4, 150, pt2);
|
||
ads_polar(ptTmp2, dAng-PI/4*3, 110, pt3);
|
||
ads_polar(ptTmp2, dAng+PI/4, 110, pt4);
|
||
BuildSegs2(pt1, ptTmp2, pt2, lstSeg); // 5、绘制上下线
|
||
BuildSegs1(pt3, pt4, lstSeg);
|
||
|
||
ads_polar(ptTmp1, dAng-PI/4*3, 180, pt1);
|
||
ads_polar(ptTmp1, dAng+PI/4, 180, pt2);
|
||
BuildSegs1(pt1, pt2, lstSeg); // 6、绘制类法兰线
|
||
Draw2DSegs(dc, lstSeg);
|
||
return Acad::eOk;
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuctNode::DrawSysYZElbow(XExplodeDraw &dc) const // 乙字弯
|
||
{
|
||
XPointList pts;
|
||
GetPtsIFace(pts, FALSE, FALSE, FALSE, FALSE);
|
||
if (pts.Length() != 2) // 1、获取与管线相连点,注:考虑法兰遮挡节点
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
XPoint pt1 = *pts[0], // 2、获取绘制信息
|
||
pt2 = *pts[1];
|
||
DList<XCurveSegment> segs;
|
||
BOOL bSameEle = fabs(pt1.z-pt2.z)<1.0E-5; // 3、判断连接管线是否标高相同
|
||
if (!bSameEle || (m_nDrawMod == 2)) // 角接或不同标高
|
||
{
|
||
BuildSegs1(pt1, pt2, segs);
|
||
Draw2DSegs(dc, segs);
|
||
return Acad::eOk;
|
||
}
|
||
|
||
XVector3D vt1 = GetIDirection(0),
|
||
vt2 = GetIDirection(1), // 4、获取中线圆心方向
|
||
vtMid1(vt1), vtMid2(vt2);
|
||
XCurveSegment seg1(pt1, XPoint(pt1+vt1), 0, LS_INFINITE),
|
||
seg2(pt2, XPoint(pt2+vt2), 0, LS_INFINITE);
|
||
XPoint ptPro1, ptPro2;
|
||
seg2.ProjectToMe(pt1, ptPro1);
|
||
seg1.ProjectToMe(pt2, ptPro2);
|
||
vtMid1 = ptPro1 - pt1;
|
||
vtMid2 = ptPro2 - pt2;
|
||
|
||
double dDist1 = GetIWidth(0), // 管线宽度
|
||
dDist2 = GetIWidth(1),
|
||
dDistM = (dDist1+dDist2)/2.0;
|
||
double dLen = pt1.Distance(pt2), // 斜边长度
|
||
dRadius1 = (dLen*0.25)/sin(m_dDrawParam2/2), // 中线圆半径
|
||
dRadius2 = dRadius1;
|
||
if (m_nDrawMod == 1) // 斜接
|
||
{
|
||
dRadius1 = dDist1 * m_dDrawParam2;
|
||
dRadius2 = dDist2 * m_dDrawParam2;
|
||
}
|
||
|
||
vtMid1.Normalize();
|
||
vtMid2.Normalize();
|
||
vtMid1.Scale(dRadius1);
|
||
vtMid2.Scale(dRadius2);
|
||
XPoint ptCen1 = pt1 + vtMid1, // 5、获取圆心点
|
||
ptCen2 = pt2 + vtMid2;
|
||
pt1.z = pt2.z = ptCen1.z = ptCen2.z = 0;
|
||
XPoint ptLoc = GetZeroPt();
|
||
|
||
XCurveSegment seg;
|
||
XPoint ptTmp1, ptTmp2, ptTmp3, ptTmp4;
|
||
DList<XCurveSegment> midSegs; // 7、绘制中线
|
||
if (0 == m_nDrawMod) // 双弧
|
||
{
|
||
seg = ::GetArcSeg1(pt1, ptCen1, ptLoc, dDist1, dDistM);
|
||
midSegs.Append(new XCurveSegment(seg));
|
||
seg = ::GetArcSeg1(pt2, ptCen2, ptLoc, dDist2, dDistM);
|
||
midSegs.Append(new XCurveSegment(seg));
|
||
}
|
||
else if (1 == m_nDrawMod) // 斜接
|
||
{
|
||
seg = ::GetArcSeg3(pt1, ptCen1, ptTmp1, dRadius1, m_dDrawParam,
|
||
AcGeVector3d::kZAxis, vt1.AsAcGeVector3d());
|
||
midSegs.Append(new XCurveSegment(seg));
|
||
seg = ::GetArcSeg3(pt2, ptCen2, ptTmp2, dRadius2, m_dDrawParam,
|
||
AcGeVector3d::kZAxis, vt2.AsAcGeVector3d());
|
||
midSegs.Append(new XCurveSegment(seg));
|
||
BuildSegs1(ptTmp1, ptTmp2, midSegs);
|
||
}
|
||
Draw2DSegs(dc, midSegs);
|
||
return Acad::eOk;
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuctNode::DrawSys3T(XExplodeDraw &dc) const // 三通
|
||
{
|
||
XPointList pt0s;
|
||
GetPtsIFace(pt0s, FALSE, FALSE, FALSE, TRUE);
|
||
if (pt0s.Length() != 3)
|
||
{
|
||
return Acad::eInvalidInput; // 1、获取法兰遮挡后与管线相连点
|
||
}
|
||
|
||
XPoint ptLoc = GetZeroPt();
|
||
DList<XCurveSegment> lstSeg;
|
||
for (int i=0; i<3; i++)
|
||
{
|
||
BuildSegs1(GetZeroPt(), *pt0s[i], lstSeg);
|
||
}
|
||
Draw2DSegs(dc, lstSeg); // 2、绘制
|
||
return Acad::eOk;
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuctNode::DrawSysTD(XExplodeDraw &dc) const // 掏洞
|
||
{
|
||
XPointList pt0s;
|
||
GetPtsIFace(pt0s, FALSE, FALSE, FALSE, TRUE);
|
||
if (pt0s.Length() != 2)
|
||
{
|
||
return Acad::eInvalidInput; // 1、获取法兰遮挡后与管线相连点
|
||
}
|
||
|
||
int nBranch = 1 - m_nMain;
|
||
DList<XCurveSegment> lstSeg;
|
||
BuildSegs1(GetZeroPt(), *pt0s[nBranch], lstSeg);
|
||
Draw2DSegs(dc, lstSeg); // 2、绘制
|
||
return Acad::eOk;
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuctNode::DrawSys4T(XExplodeDraw &dc) const // 四通
|
||
{
|
||
XPointList pt0s;
|
||
GetPtsIFace(pt0s, FALSE, FALSE, FALSE, TRUE);
|
||
if (pt0s.Length() != 4)
|
||
{
|
||
return Acad::eInvalidInput; // 1、获取法兰遮挡后与管线相连点
|
||
}
|
||
|
||
XPoint ptLoc = GetZeroPt();
|
||
DList<XCurveSegment> lstSeg;
|
||
for (int i=0; i<4; i++)
|
||
{
|
||
BuildSegs1(ptLoc, *pt0s[i], lstSeg);
|
||
}
|
||
Draw2DSegs(dc, lstSeg); // 2、绘制
|
||
return Acad::eOk;
|
||
}
|
||
|
||
|
||
|
||
////////////////////////////////法兰//////////////////////////////////
|
||
Acad::ErrorStatus TDbDuctNode::DrawFL2D(XExplodeDraw &dc) const
|
||
{
|
||
BOOL bNoDraw1 = (m_nSysDrawMod==1) || (m_nSysDrawMod==4), // 单线、系统图
|
||
bNoDraw2 = (m_nDrawMod==13) && (m_nType==kTaoDong); // 样式13的掏洞
|
||
if (bNoDraw1 || bNoDraw2) // 1、首先判断出不绘制的条件
|
||
{
|
||
return Acad::eOk;
|
||
}
|
||
|
||
XCurveSegment seg;
|
||
DList<XCurveSegment> segs;
|
||
XPoint ptLoc = GetZeroPt(); // 2、将所有的点投影到XOY平面上
|
||
int nLen = GetInterfaceNum();
|
||
for (int i=0; i<nLen; i++) // 3、一个个接口的绘制法兰
|
||
{
|
||
const AcDbObjectId &id = GetIPipe(i); // ①获取连接的风管属性
|
||
double dAng = GetIAngle(i), // 法向
|
||
dDuctDia = GetIWidth(i), // 管径
|
||
dDuctHigh = GetIHeight(i); // 高度
|
||
double dFlDia(dDuctDia); // 法兰直径
|
||
|
||
XVector3D vt = GetIDirection(i); // ②判断是水平管还是立管
|
||
BOOL bVertical = (fabs(vt.x)<1.0E-6) && (fabs(vt.y)<1.0E-6);
|
||
|
||
XPoint pt1, pt2, pt3, pt4, ptTmp; // ③根据连接的不同类型,绘制不同样式的法兰
|
||
if (bVertical) // 立管
|
||
{
|
||
if (m_nType==kStem || m_nType==k3Corner) // 堵头、三通
|
||
{
|
||
continue; // 不绘制
|
||
}
|
||
|
||
if (m_nType==kTapered || m_nType==kTianYuanDiFang) // 变径、天圆地方
|
||
{
|
||
dFlDia += 2*GetIFlDist(i);
|
||
if (GetISection(i) == 1) // 圆
|
||
{
|
||
XCircle cirIn(ptLoc, dFlDia/2);
|
||
BuildSegs5(cirIn, segs);
|
||
continue;
|
||
}
|
||
|
||
XPoly2D poly(1);
|
||
::GetSquare(ptLoc, GetIVDAngle(i), dFlDia, dDuctHigh+2*GetIFlDist(i),
|
||
&poly, NULL);
|
||
for (int j=0; j<poly.TotalSegments(); j++)
|
||
{
|
||
poly.Nth(j, seg);
|
||
segs.Append(new XCurveSegment(seg));
|
||
}
|
||
continue;
|
||
}
|
||
|
||
if (m_nType == kKouElbow) // 扣弯
|
||
{
|
||
int nOther = i==0?1:0; // 水平管标号
|
||
BOOL bHasLowElbow(FALSE);
|
||
double dHDAngle = GetIVDAngle(nOther),
|
||
dVDAngle = GetIAngle(i);
|
||
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbDuct, pDuct);
|
||
if (pDuct != NULL)
|
||
{
|
||
bHasLowElbow = pDuct->IsUpPipesOk();
|
||
dVDAngle = pDuct->GetVDAngle(); // 立管绘制角度
|
||
XVector3D openDirVt;
|
||
pDuct->GetVerOpenDir(openDirVt);
|
||
dHDAngle = ads_angle(XPoint(), openDirVt); // 开口方向
|
||
}
|
||
OPENOBJ_END();
|
||
|
||
XPoint ptOnVDuct = GetILocation(i),
|
||
ptOnHDuct = GetILocation(nOther);
|
||
if (ptOnVDuct.z < (ptOnHDuct.z-1.0E-6)) // 下弯头
|
||
{
|
||
ptOnHDuct.z = ptOnVDuct.z = 0;
|
||
double dUpWidth = GetIWidth(nOther);
|
||
if (fabs(dDuctHigh) < 1.0E-6) // 圆
|
||
{
|
||
XArc tmpArc;
|
||
XPointList ptLst;
|
||
GetYKEFlPts(dHDAngle, dDuctDia, ptOnHDuct, dUpWidth,
|
||
tmpArc, GetIFlDist(i), ptLst);
|
||
if (ptLst.Length() != 5)
|
||
{
|
||
break;
|
||
}
|
||
XArc arc(*ptLst[0], *ptLst[2], *ptLst[4]);
|
||
BuildSegs4(arc, segs);
|
||
continue;
|
||
}
|
||
|
||
XPointList ptLst;
|
||
GetFKEFlPts(dHDAngle, dVDAngle, ptOnHDuct, dUpWidth,
|
||
i, ptLst); // 立管法兰边框点
|
||
for (int j=0; j<ptLst.Length()-1; j++)
|
||
{
|
||
BuildSegs1(*ptLst[j], *ptLst[j+1], segs);
|
||
}
|
||
}
|
||
else if (ptOnVDuct.z>(ptOnHDuct.z+1.0E-6) && !bHasLowElbow) // 上弯头
|
||
{
|
||
ptOnHDuct.z = ptOnVDuct.z = 0;
|
||
if (fabs(dDuctHigh) < 1.0E-6) // 圆
|
||
{
|
||
XCircle circle(ptLoc, dDuctDia/2+GetIFlDist(i));
|
||
BuildSegs5(circle, segs);
|
||
continue;
|
||
}
|
||
|
||
double dAngle = CT_std_angle(dVDAngle - dHDAngle),
|
||
dTmpDia(dDuctDia), dTmpHigh(dDuctHigh);
|
||
if (fabs(dAngle)<0.0001 || fabs(dAngle-PI)<0.0001)
|
||
{
|
||
dTmpDia = dDuctHigh;
|
||
dTmpHigh = dDuctDia;
|
||
}
|
||
|
||
ads_polar(ptLoc, dHDAngle, dTmpHigh/2+GetIFlDist(i), ptTmp);
|
||
ads_polar(ptTmp, dHDAngle+PI/2, dTmpDia/2+GetIFlDist(i), pt1);
|
||
ads_polar(ptTmp, dHDAngle-PI/2, dTmpDia/2+GetIFlDist(i), pt2);
|
||
ads_polar(pt2, dHDAngle, -dTmpHigh-2*GetIFlDist(i), pt3);
|
||
ads_polar(pt1, dHDAngle, -dTmpHigh-2*GetIFlDist(i), pt4);
|
||
BuildSegs2(pt1, pt2, pt3, segs);
|
||
BuildSegs2(pt3, pt4, pt1, segs);
|
||
}
|
||
}
|
||
continue;
|
||
}
|
||
|
||
if ((m_nType==kTaoDong) && (i==m_nMain)) // 插管三通,主风管上无法兰
|
||
{
|
||
continue;
|
||
}
|
||
|
||
if (m_nType == kStem) // 堵头
|
||
{
|
||
ads_polar(ptLoc, dAng+PI/2, dFlDia/2, pt1);
|
||
ads_polar(ptLoc, dAng-PI/2, dFlDia/2, pt2);
|
||
BuildSegs1(pt1, pt2, segs); // 水平管两端按焊接绘制
|
||
continue;
|
||
}
|
||
|
||
dFlDia += 2*GetIFlDist(i);
|
||
XPoint ptFlange = GetILocation(i);
|
||
DrawFlange(segs, ptFlange, dAng, dFlDia, GetIFlThick(i));
|
||
}
|
||
|
||
DrawFLSegs(dc, segs);
|
||
return Acad::eOk;
|
||
}
|
||
|
||
|
||
|
||
////////////////////////////弯头////////////////////////////
|
||
Acad::ErrorStatus TDbDuctNode::DrawElbow2D(XExplodeDraw &dc) const
|
||
{
|
||
if (GetInterfaceNum() != 2) // 1、保证所有的链表不越界
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
double dRightDist = 50 + (m_dDrawParam-0.5)*GetIWidth(1);
|
||
if (dRightDist < -1.0E-5)
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
else if (dRightDist < 50-1.0E-5)
|
||
{
|
||
dRightDist *= 0.2;
|
||
}
|
||
else
|
||
{
|
||
dRightDist = 50;
|
||
}
|
||
|
||
XPointList pts, pt50s;
|
||
GetPtsIFace(pts, FALSE, FALSE, FALSE, TRUE); // 法兰遮挡后的连接点
|
||
GetPtsIFace(pt50s, FALSE, FALSE, TRUE, TRUE, dRightDist); // 增加50以后的点
|
||
if ((pts.Length()!=2) || (pt50s.Length()!=2)) // 2、获取与管线相连点
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
if (m_nSysDrawMod != 3) // 3、除双线图外,绘制中心线
|
||
{
|
||
XPoint ptLoc = GetZeroPt(); // 将绘制标高变为0
|
||
DList<XCurveSegment> midSegs;
|
||
if ((m_nDrawMod == 1) || (m_nDrawMod == 3)) // 内斜线、内外直线
|
||
{
|
||
BuildSegs2(*pts[0], ptLoc, *pts[1], midSegs); // 绘制直线
|
||
}
|
||
else if ((m_nDrawMod == 0) || (m_nDrawMod == 2)) // 双弧线、内外弧线
|
||
{
|
||
if (m_bMuffler && (m_nMufflerMod==2) && (m_nDrawMod==2) &&
|
||
(m_nSysDrawMod==2))
|
||
{
|
||
; // 内外弧中的第三种消声弯头,不绘制中心线
|
||
}
|
||
else // 其他情况下
|
||
{
|
||
DrawArc2(midSegs, 0, 1, *pts[0], *pts[1], TRUE, dRightDist); // 绘制弧线
|
||
}
|
||
}
|
||
else // 虾米弯
|
||
{
|
||
XPointList ptsMid;
|
||
DrawXMSegs(midSegs, *pts[0], *pts[1], ptsMid, dRightDist);
|
||
}
|
||
|
||
if (m_nSysDrawMod == 1)
|
||
{
|
||
DrawXiSegs(dc, midSegs); // (2)单线图,细线绘制
|
||
return Acad::eOk;
|
||
}
|
||
DrawMidSegs(dc, midSegs); // (3)三线图,切换中心线图层、线型绘制
|
||
}
|
||
|
||
int k(0);
|
||
DList<XLine> lLst; // 4、储存临时用到的线,共8根
|
||
for (k=0; k<2; k++)
|
||
{
|
||
double dTmp1 = GetIWidth(k)/2.0,
|
||
dTmp2 = dTmp1 + GetIFlDist(k)*0.8;
|
||
if ((m_nMufflerMod == 2) && (m_nDrawMod == 2)) // 中广电消声样式
|
||
{
|
||
dTmp2 = dTmp1 + GetIFlDist(k);
|
||
}
|
||
XLine lTmp = XLine(*pts[k], *pt50s[k], LS_INFINITE).Offset(dTmp2);
|
||
lLst.Append(new XLine(lTmp));
|
||
lTmp = XLine(*pts[k], *pt50s[k], LS_INFINITE).Offset(dTmp1);
|
||
lLst.Append(new XLine(lTmp));
|
||
lTmp = XLine(*pts[k], *pt50s[k], LS_INFINITE).Offset(-dTmp1);
|
||
lLst.Append(new XLine(lTmp));
|
||
lTmp = XLine(*pts[k], *pt50s[k], LS_INFINITE).Offset(-dTmp2);
|
||
lLst.Append(new XLine(lTmp));
|
||
}
|
||
if (lLst.Length() != 8)
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
XPoint ptInt1, ptInt2, ptInt3, ptInt4; // 5、获取内外弧线的顶点、半径
|
||
if (!lLst[1]->Intersection(lLst[6], ptInt1) ||
|
||
!lLst[2]->Intersection(lLst[5], ptInt2))
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
double dDist1 = ptInt1.Distance(lLst[6]->EndPoint()), // 内外弧线半径
|
||
dDist2 = ptInt2.Distance(lLst[5]->EndPoint());
|
||
double dWide1 = GetIWidth(0), // 管线宽度
|
||
dWide2 = GetIWidth(1);
|
||
|
||
// 6、根据样式,绘制弯头上下线,首先不考虑消声,都按实线处理
|
||
DList<XCurveSegment> lstSeg; // 实线
|
||
if (m_nDrawMod == 0) // 内外曲线样式
|
||
{
|
||
DrawArc2(lstSeg, 0, 1, lLst[1]->GetStartPoint(), lLst[6]->GetStartPoint(), FALSE, dRightDist);
|
||
DrawArc2(lstSeg, 0, 1, lLst[2]->GetStartPoint(), lLst[5]->GetStartPoint(), FALSE, dRightDist);
|
||
}
|
||
else if (m_nDrawMod == 3) // 内外直线样式
|
||
{
|
||
BuildSegs2(lLst[1]->GetStartPoint(), ptInt1, lLst[6]->GetStartPoint(), lstSeg);
|
||
BuildSegs2(lLst[2]->GetStartPoint(), ptInt2, lLst[5]->GetStartPoint(), lstSeg);
|
||
}
|
||
else if (m_nDrawMod == 4) // 虾米弯样式
|
||
{
|
||
XPointList pts1, pts2; // 节线点
|
||
DrawXMSegs(lstSeg, lLst[1]->GetStartPoint(), lLst[6]->GetStartPoint(), pts1, dRightDist);
|
||
DrawXMSegs(lstSeg, lLst[2]->GetStartPoint(), lLst[5]->GetStartPoint(), pts2, dRightDist);
|
||
if ((pts1.Length()!=m_nXMWNum) || (pts2.Length()!=m_nXMWNum))
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
for (k=0; k<m_nXMWNum; k++)
|
||
{
|
||
BuildSegs1(*pts1[k], *pts2[k], lstSeg);
|
||
}
|
||
}
|
||
else if (m_nDrawMod == 1) // 内斜线样式
|
||
{
|
||
if (dDist1 > (dDist2 + 1.0E-6)) // 注:保证外侧是直线,1、6为外侧
|
||
{
|
||
BuildSegs2(lLst[1]->GetStartPoint(), ptInt1, lLst[6]->GetStartPoint(), lstSeg);
|
||
BuildSegs6(lLst[2]->GetStartPoint(), lLst[2]->GetEndPoint(), lLst[5]->GetEndPoint(),
|
||
lLst[5]->GetStartPoint(), lstSeg);
|
||
}
|
||
else // 2、5为外侧
|
||
{
|
||
BuildSegs2(lLst[2]->GetStartPoint(), ptInt2, lLst[5]->GetStartPoint(), lstSeg);
|
||
BuildSegs6(lLst[1]->GetStartPoint(), lLst[1]->GetEndPoint(), lLst[6]->GetEndPoint(),
|
||
lLst[6]->GetStartPoint(), lstSeg);
|
||
}
|
||
}
|
||
else // 内弧线样式
|
||
{
|
||
if (dDist1 > (dDist2 + 1.0E-6)) // 注:保证外侧是直线,1、6为外侧
|
||
{
|
||
BuildSegs2(lLst[1]->GetStartPoint(), ptInt1, lLst[6]->GetStartPoint(), lstSeg);
|
||
DrawArc2(lstSeg, 0, 1, lLst[2]->GetStartPoint(), lLst[5]->GetStartPoint(), FALSE, dRightDist);
|
||
}
|
||
else // 2、5为外侧
|
||
{
|
||
BuildSegs2(lLst[2]->GetStartPoint(), ptInt2, lLst[5]->GetStartPoint(), lstSeg);
|
||
DrawArc2(lstSeg, 0, 1, lLst[1]->GetStartPoint(), lLst[6]->GetStartPoint(), FALSE, dRightDist);
|
||
}
|
||
}
|
||
|
||
XCurveSegment seg;
|
||
if (m_bMuffler && (m_nDrawMod!=4)) // 7、绘制消声弯头,虾米弯没有消声
|
||
{
|
||
DList<XCurveSegment> lstDashSeg; // 虚线
|
||
for (k=0; k<lstSeg.Length(); k++)
|
||
{
|
||
seg = *lstSeg[k--];
|
||
lstDashSeg.Append(new XCurveSegment(seg)); // (1)将实现转为虚线
|
||
lstSeg.Remove();
|
||
}
|
||
|
||
if (!lLst[0]->Intersection(lLst[7], ptInt3) ||
|
||
!lLst[3]->Intersection(lLst[4], ptInt4)) // 消声内外弧线顶点
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
XPoint ptTmp1, ptTmp2, ptTmp3, ptTmp4, ptTmp5;
|
||
double dDist3 = ptInt3.Distance(lLst[7]->EndPoint()), // 消声内外弧线半径
|
||
dDist4 = ptInt4.Distance(lLst[4]->EndPoint());
|
||
// (2)绘制新实线部分
|
||
if (m_nDrawMod == 0) // 内外曲线样式
|
||
{
|
||
DrawArc2(lstSeg, 0, 1, lLst[0]->GetStartPoint(), lLst[7]->GetStartPoint(), FALSE, dRightDist);
|
||
DrawArc2(lstSeg, 0, 1, lLst[3]->GetStartPoint(), lLst[4]->GetStartPoint(), FALSE, dRightDist);
|
||
}
|
||
else if (m_nDrawMod == 3) // 内外直线样式
|
||
{
|
||
BuildSegs2(lLst[0]->GetStartPoint(), ptInt3, lLst[7]->GetStartPoint(), lstSeg);
|
||
BuildSegs2(lLst[3]->GetStartPoint(), ptInt4, lLst[4]->GetStartPoint(), lstSeg);
|
||
}
|
||
else if (m_nDrawMod == 1) // 内斜线样式,消声样式1
|
||
{
|
||
if (dDist3 > (dDist4 + 1.0E-6)) // 注:保证外侧是直线,0、7为外侧
|
||
{
|
||
BuildSegs2(lLst[0]->GetStartPoint(), ptInt3, lLst[7]->GetStartPoint(), lstSeg);
|
||
BuildSegs1(lLst[3]->GetStartPoint(), lLst[4]->GetStartPoint(), lstSeg);
|
||
}
|
||
else // 3、4为外侧
|
||
{
|
||
BuildSegs2(lLst[3]->GetStartPoint(), ptInt4, lLst[4]->GetStartPoint(), lstSeg);
|
||
BuildSegs1(lLst[0]->GetStartPoint(), lLst[7]->GetStartPoint(), lstSeg);
|
||
}
|
||
|
||
if (m_nMufflerMod == 0) // 消声样式1
|
||
{
|
||
lstDashSeg.Reset(); // 清空全部虚线
|
||
if (dDist3 > (dDist4 + 1.0E-6)) // 0、7为外侧
|
||
{
|
||
BuildSegs2(lLst[1]->GetStartPoint(), ptInt1, lLst[6]->GetStartPoint(), lstDashSeg);
|
||
BuildSegs1(lLst[2]->GetStartPoint(), lLst[5]->GetStartPoint(), lstDashSeg);
|
||
}
|
||
else // 3、4为外侧
|
||
{
|
||
BuildSegs2(lLst[2]->GetStartPoint(), ptInt2, lLst[5]->GetStartPoint(), lstDashSeg);
|
||
BuildSegs1(lLst[1]->GetStartPoint(), lLst[6]->GetStartPoint(), lstDashSeg);
|
||
}
|
||
}
|
||
}
|
||
else // 内弧线样式
|
||
{
|
||
if (m_nMufflerMod != 2) // 原有消声样式
|
||
{
|
||
if (dDist3 > (dDist4 + 1.0E-6)) // 注:保证外侧是直线,0、7为外侧
|
||
{
|
||
BuildSegs2(lLst[0]->GetStartPoint(), ptInt3, lLst[7]->GetStartPoint(), lstSeg);
|
||
DrawArc2(lstSeg, 0, 1, lLst[3]->GetStartPoint(), lLst[4]->GetStartPoint(), FALSE, dRightDist);
|
||
}
|
||
else // 3、4为外侧
|
||
{
|
||
BuildSegs2(lLst[3]->GetStartPoint(), ptInt4, lLst[4]->GetStartPoint(), lstSeg);
|
||
DrawArc2(lstSeg, 0, 1, lLst[0]->GetStartPoint(), lLst[7]->GetStartPoint(), FALSE, dRightDist);
|
||
}
|
||
}
|
||
else // 中广电消声样式,m_nMufflerMod==2
|
||
{
|
||
lstDashSeg.Reset(); // 无虚线
|
||
BuildSegs3(*lLst[1], lstSeg);
|
||
BuildSegs3(*lLst[2], lstSeg);
|
||
BuildSegs3(*lLst[5], lstSeg);
|
||
BuildSegs3(*lLst[6], lstSeg);
|
||
BuildSegs1(lLst[0]->EndPoint(), lLst[3]->EndPoint(), lstSeg);
|
||
BuildSegs1(lLst[4]->EndPoint(), lLst[7]->EndPoint(), lstSeg);
|
||
|
||
if (dDist3 > (dDist4 + 1.0E-6)) // 注:保证外侧是直线,0、7为外侧
|
||
{
|
||
BuildSegs2(lLst[0]->EndPoint(), ptInt3, lLst[7]->EndPoint(), lstSeg);
|
||
seg = ::GetArcSeg2(lLst[3]->EndPoint(), ptInt4, lLst[4]->EndPoint(),
|
||
dDist4, dWide1, dWide2);
|
||
lstSeg.Append(new XCurveSegment(seg)); // 先画弧线
|
||
|
||
XArc arc = seg.GetArc();
|
||
ptTmp5 = arc.GetCenterPt(); // 获取圆心
|
||
XLine lTmp1 = XLine(ptInt3, ptTmp5, LS_FINITE).Offset(50),
|
||
lTmp2 = XLine(ptInt3, ptTmp5, LS_FINITE).Offset(-50);
|
||
|
||
XLine lineTmp1(lLst[0]->GetStartPoint(), ptInt3);
|
||
lTmp2.Intersection(&lineTmp1, ptTmp1);
|
||
lTmp2.Intersection(&arc, ptTmp3, ptTmp5);
|
||
XLine lineTmp2(lLst[7]->GetStartPoint(), ptInt3);
|
||
lTmp1.Intersection(&lineTmp2, ptTmp2);
|
||
lTmp2.Intersection(&arc, ptTmp4, ptTmp5);
|
||
}
|
||
else // 3、4为外侧
|
||
{
|
||
BuildSegs2(lLst[3]->EndPoint(), ptInt4, lLst[4]->EndPoint(), lstSeg);
|
||
seg = ::GetArcSeg2(lLst[0]->EndPoint(), ptInt3, lLst[7]->EndPoint(),
|
||
dDist3, dWide1, dWide2);
|
||
lstSeg.Append(new XCurveSegment(seg));
|
||
|
||
XArc arc = seg.GetArc();
|
||
ptTmp5 = arc.GetCenterPt(); // 获取圆心
|
||
XLine lTmp1 = XLine(ptInt4, ptTmp5, LS_FINITE).Offset(50),
|
||
lTmp2 = XLine(ptInt4, ptTmp5, LS_FINITE).Offset(-50);
|
||
|
||
|
||
XLine lineTmp1(lLst[3]->GetStartPoint(), ptInt4);
|
||
lTmp1.Intersection(&lineTmp1, ptTmp1);
|
||
lTmp1.Intersection(&arc, ptTmp3, ptTmp5);
|
||
XLine lineTmp2(lLst[4]->GetStartPoint(), ptInt4);
|
||
lTmp2.Intersection(&lineTmp2, ptTmp2);
|
||
lTmp2.Intersection(&arc, ptTmp4, ptTmp5);
|
||
}
|
||
BuildSegs1(ptTmp1, ptTmp3, lstSeg);
|
||
BuildSegs1(ptTmp2, ptTmp4, lstSeg);
|
||
}
|
||
}
|
||
|
||
if ((m_nMufflerMod==1) && (m_nDrawMod!=0)) // (3)另一种绘制样式
|
||
{
|
||
lstDashSeg.Reset();
|
||
double dAng1 = GetIAngle(0), // 管线法向
|
||
dAng2 = GetIAngle(1);
|
||
if (dDist3 > (dDist4 + 1.0E-6)) // 注:保证外侧是直线,0、7为外侧
|
||
{
|
||
ads_polar(lLst[1]->GetStartPoint(), dAng1-PI/2, dWide1/3.0, ptTmp1);
|
||
ads_polar(ptTmp1, dAng1, -dDist2*1.3, ptTmp2);
|
||
ads_polar(lLst[7]->GetStartPoint(), dAng2, -dDist3/3.0, ptTmp3);
|
||
ads_polar(ptTmp3, dAng2+PI/2, dWide2*0.7, ptTmp4);
|
||
}
|
||
else
|
||
{
|
||
ads_polar(lLst[2]->GetStartPoint(), dAng1+PI/2, dWide1/3.0, ptTmp1);
|
||
ads_polar(ptTmp1, dAng1, -dDist1*1.3, ptTmp2);
|
||
ads_polar(lLst[4]->GetStartPoint(), dAng2, -dDist4/3.0, ptTmp3);
|
||
ads_polar(ptTmp3, dAng2-PI/2, dWide2*0.7, ptTmp4);
|
||
}
|
||
BuildSegs1(ptTmp2, ptTmp1, lstSeg);
|
||
BuildSegs1(ptTmp4, ptTmp3, lstSeg);
|
||
}
|
||
|
||
AcDbObjectId idLineTypeOld = dc.GetLineTypeId(),
|
||
idDashType = InitLineType(_T("DASH"), database());
|
||
if (idDashType.isValid())
|
||
{
|
||
dc.SetLineType(idDashType);
|
||
}
|
||
|
||
for (int i=0; i<lstDashSeg.Length(); i++)
|
||
{
|
||
dc << *lstDashSeg[i]; // 绘制虚线
|
||
}
|
||
dc.SetLineType(idLineTypeOld);
|
||
}
|
||
|
||
if (m_bShowDLYP) // 8、显示导流叶片
|
||
{
|
||
DList<XCurveSegment> lstDLYPSeg;
|
||
if (!DrawDLYPSegs(lstDLYPSeg, *pt50s[0], *pt50s[1]))
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
DrawXiSegs(dc, lstDLYPSeg);
|
||
}
|
||
|
||
Draw2DSegs(dc, lstSeg); // 9、绘制实线
|
||
return Acad::eOk;
|
||
}
|
||
|
||
// 获取虾米弯点的位置及弧段
|
||
BOOL TDbDuctNode::DrawXMSegs(DList<XCurveSegment> &lstSeg, XPoint ptStart,
|
||
XPoint ptEnd, XPointList &pts, double dNum) const
|
||
{
|
||
XPoint pt1, pt2, ptCen, ptTmp1, ptTmp2;
|
||
double dAng1 = GetIAngle(0), // 管线法向
|
||
dAng2 = GetIAngle(1);
|
||
double dAngle = CT_acute_angle(dAng1 - dAng2); // 两法兰线的夹角
|
||
ads_polar(ptStart, dAng1, -dNum, pt1);
|
||
ads_polar(ptEnd, dAng2, -dNum, pt2);
|
||
BuildSegs1(ptStart, pt1, lstSeg); // 50长度的短线
|
||
BuildSegs1(ptEnd, pt2, lstSeg);
|
||
|
||
ads_polar(pt1, dAng1-PI/2, 500, ptTmp1);
|
||
ads_polar(pt2, dAng2-PI/2, 500, ptTmp2);
|
||
|
||
XLine lineTmp(ptTmp2, pt2,LS_INFINITE);
|
||
if (!XLine(ptTmp1, pt1, LS_INFINITE).Intersection(&lineTmp, ptCen)) // 获取弧心
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
XCurveSegment seg;
|
||
double dWidth1 = GetIWidth(0), // 管径
|
||
dWidth2 = GetIWidth(1);
|
||
seg = ::GetArcSeg1(pt1, ptCen, pt2, dWidth1, dWidth2);
|
||
if (!seg.Is(CURVE_ARC))
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
XArc arc = seg.GetArc();
|
||
ptCen = arc.GetCenterPt(); // 获取圆心
|
||
double dRadius = arc.GetRadius(); // 半径
|
||
dAng1 = arc.GetStarAngle(); // 起点角度
|
||
arc.SetAngleByPoints(pt1, pt2); // 起、止点
|
||
|
||
dAngle = (PI - dAngle)/m_nXMWNum;
|
||
for (int i = 0; i <= m_nXMWNum; i++)
|
||
{
|
||
if ((i == 0) || (i == m_nXMWNum))
|
||
{
|
||
dAng1 += dAngle/2.0; // 端节角度
|
||
if (i == 0)
|
||
{
|
||
ptTmp1 = pt1;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
dAng1 += dAngle; // 中节角度
|
||
}
|
||
|
||
ads_polar(ptCen, dAng1, dRadius, ptTmp2);
|
||
if (i != m_nXMWNum)
|
||
{
|
||
pts.Append(new XPoint(ptTmp2));
|
||
}
|
||
BuildSegs1(ptTmp1, ptTmp2, lstSeg);
|
||
ptTmp1 = ptTmp2;
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
// 获取导流叶片的位置点
|
||
void TDbDuctNode::GetDLYPPts(XPoint ptStart, XPoint ptEnd, XPointList &pts) const
|
||
{
|
||
double dD = 5.0, // 公差
|
||
dDist = ptStart.Distance(ptEnd); // 等差数列和
|
||
int nCount = m_nDLYPNum + 1; // 项数
|
||
double dA1 = dDist/nCount - (nCount-1)*dD*0.5; // 首项
|
||
|
||
pts.Reset();
|
||
XPoint ptTmp(ptEnd);
|
||
XVector3D vt = ptStart - ptEnd;
|
||
for (int i=1; i<nCount; i++)
|
||
{
|
||
double dAn = dA1 + (i-1)*dD; // 通项公式
|
||
vt.Normalize();
|
||
vt.Scale(dAn);
|
||
ptTmp = ptTmp + vt;
|
||
pts.Append(new XPoint(ptTmp));
|
||
}
|
||
}
|
||
|
||
// 导流叶片的绘制算法,注:8.0以前仅绘制“单层”导流叶片
|
||
BOOL TDbDuctNode::DrawDLYPSegs(DList<XCurveSegment> &lstSeg, XPoint ptStart,
|
||
XPoint ptEnd) const
|
||
{
|
||
double dAng1 = GetIAngle(0), // 管线法向
|
||
dAng2 = GetIAngle(1),
|
||
dAngle = CT_acute_angle(dAng1 - dAng2); // 两法兰线的夹角
|
||
double dWidth1 = GetIWidth(0), // 管线宽度
|
||
dWidth2 = GetIWidth(1);
|
||
XPoint pt1, pt2, pt3, pt4, ptInt;
|
||
ads_polar(ptStart, dAng1-PI/2, dWidth1/2, pt1); // 上下线的起止点
|
||
ads_polar(ptStart, dAng1+PI/2, dWidth1/2, pt2);
|
||
ads_polar(ptEnd, dAng2-PI/2, dWidth2/2, pt3);
|
||
ads_polar(ptEnd, dAng2+PI/2, dWidth2/2, pt4);
|
||
|
||
XPointList ptLst1, ptLst2; // 导流叶片完整时的起、止点
|
||
double dDist1 = pt1.Distance(pt4),
|
||
dDist2 = pt2.Distance(pt3);
|
||
if (dDist1 > dDist2 - 1.0E-5) // 注:保证点的方向正确,由外向内
|
||
{
|
||
GetDLYPPts(pt1, pt2, ptLst1); // 获取导流叶片的位置点
|
||
GetDLYPPts(pt4, pt3, ptLst2);
|
||
}
|
||
else
|
||
{
|
||
GetDLYPPts(pt2, pt1, ptLst1);
|
||
GetDLYPPts(pt3, pt4, ptLst2);
|
||
}
|
||
if (ptLst1.Length()!=m_nDLYPNum || ptLst2.Length()!=m_nDLYPNum)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
XCurveSegment seg;
|
||
double dLen(0); // 导流叶片长度,取决于最内侧的导流叶片长度
|
||
BOOL bBreak(FALSE); // 是否绘制正确
|
||
for (int i=0; i<m_nDLYPNum; i++)
|
||
{
|
||
ads_polar(*ptLst1[i], dAng1, -dWidth1, pt1);
|
||
ads_polar(*ptLst2[i], dAng2, -dWidth2, pt2);
|
||
XLine lineTmp(*ptLst2[i], pt2, LS_INFINITE);
|
||
if (!XLine(*ptLst1[i], pt1, LS_INFINITE).Intersection(&lineTmp, ptInt))
|
||
{
|
||
bBreak = TRUE;
|
||
break;
|
||
}
|
||
|
||
double dDist = ptInt.Distance(*ptLst2[i]);
|
||
seg = ::GetArcSeg2(*ptLst1[i], ptInt, *ptLst2[i], dDist, dWidth1, dWidth2);
|
||
if (!seg.Is(CURVE_ARC))
|
||
{
|
||
bBreak = TRUE;
|
||
break;
|
||
}
|
||
|
||
XArc arc = seg.GetArc();
|
||
double dRadius = arc.GetRadius(); // 半径
|
||
if (i == 0) // 角度
|
||
{
|
||
dAngle = (PI - dAngle)*1.0/3.0; // Ang1
|
||
}
|
||
else
|
||
{
|
||
dAngle = dLen/dRadius; // AngN
|
||
}
|
||
|
||
double dMidAngle = arc.MidAngle(), // 弧段中点角度
|
||
dTmpAng1 = dMidAngle + dAngle*0.5,
|
||
dTmpAng2 = dMidAngle - dAngle*0.5;
|
||
XPoint ptCen = arc.GetCenterPt(); // 圆心
|
||
ads_polar(ptCen, dTmpAng1, dRadius, pt3);
|
||
ads_polar(ptCen, dTmpAng2, dRadius, pt4);
|
||
arc.SetAngleByPoints(pt4, pt3);
|
||
if (i == 0)
|
||
{
|
||
dLen = arc.GetLength();
|
||
}
|
||
BuildSegs4(arc, lstSeg);
|
||
}
|
||
return !bBreak;
|
||
}
|
||
|
||
|
||
////////////////////////////扣弯////////////////////////////
|
||
Acad::ErrorStatus TDbDuctNode::DrawKElbow2D(XExplodeDraw &dc) const
|
||
{
|
||
if (GetInterfaceNum() != 2) // 1、保证所有的链表不越界
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
AcDbIntArray indexArray = GetVerPipeIndex();
|
||
int nLen = indexArray.logicalLength(); // 2、获取连接的立管数量
|
||
if (nLen != 1)
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
int nVNum = indexArray[0], // 3、获取立管、水平管索引号
|
||
nHNum = 1-nVNum;
|
||
XPoint ptStart = GetILocation(nHNum), // 绘制点;注:指定非立管连接点为绘制起点
|
||
ptEnd = GetILocation(nVNum);
|
||
double dAngle1 = GetIAngle(nHNum); // 非立管法向
|
||
ads_polar(ptStart, dAngle1, -GetIFlThick(nHNum)/2, ptStart); // 仅改变绘制的长度
|
||
|
||
XPoint ptNodeLoc = GetZeroPt(),
|
||
ptVDTmp(ptNodeLoc); // 扣弯中线的端点
|
||
XCurveSegment seg;
|
||
DList<XCurveSegment> lstSeg; // 4、绘制上、下弯头线
|
||
if (ptStart.z > ptEnd.z) // 下弯头
|
||
{
|
||
ptStart.z = ptEnd.z = 0;
|
||
XPoint ptVDuct1, ptVDuct2;
|
||
double dVDWidth = GetIWidth(nVNum), // 立管宽度
|
||
dVDHigh = GetIHeight(nVNum);
|
||
if (fabs(dVDHigh) < 1.0E-6) // 圆
|
||
{
|
||
ads_polar(ptNodeLoc, dAngle1, -dVDWidth/2, ptVDTmp);
|
||
ads_polar(ptNodeLoc, dAngle1+PI/2, dVDWidth/2, ptVDuct1);
|
||
ads_polar(ptNodeLoc, dAngle1-PI/2, dVDWidth/2, ptVDuct2);
|
||
XArc arc(ptVDuct1, ptVDTmp, ptVDuct2);
|
||
BuildSegs4(arc, lstSeg);
|
||
}
|
||
else // 矩形
|
||
{
|
||
double dAngle2 = GetIVDAngle(nVNum),
|
||
dAng = CT_acute_angle(dAngle1 - dAngle2);
|
||
if (fabs(dAng-PI/2) < 1.0E-6)
|
||
{
|
||
TchPrivate::Exchange(dVDWidth, dVDHigh);
|
||
}
|
||
ads_polar(ptNodeLoc, dAngle1, -dVDWidth/2, ptVDTmp);
|
||
ads_polar(ptVDTmp, dAngle1+PI/2, dVDHigh/2, ptVDuct1);
|
||
ads_polar(ptVDTmp, dAngle1-PI/2, dVDHigh/2, ptVDuct2);
|
||
BuildSegs1(ptVDuct1, ptVDuct2, lstSeg);
|
||
}
|
||
|
||
XPoint pt1, pt2;
|
||
ads_polar(ptStart, dAngle1+PI/2, GetIWidth(nHNum)/2, pt1);
|
||
ads_polar(ptStart, dAngle1-PI/2, GetIWidth(nHNum)/2, pt2);
|
||
BuildSegs1(pt1, ptVDuct1, lstSeg);
|
||
BuildSegs1(pt2, ptVDuct2, lstSeg);
|
||
}
|
||
else // 上弯头
|
||
{
|
||
ptStart.z = ptEnd.z = 0;
|
||
BOOL bHasLowElbow(FALSE);
|
||
OPENOBJ_BEGIN(GetIPipe(nVNum), AcDb::kForRead, TDbDuct, pDuct);
|
||
if (pDuct != NULL)
|
||
{
|
||
bHasLowElbow = pDuct->IsUpPipesOk();
|
||
}
|
||
OPENOBJ_END();
|
||
|
||
BOOL bIsOk(TRUE);
|
||
if (!bHasLowElbow) // 无下弯头
|
||
{
|
||
bIsOk = DrawUpKElbow2D1(lstSeg, nVNum, nHNum, ptStart, ptVDTmp);
|
||
}
|
||
else // 有下弯头
|
||
{
|
||
bIsOk = DrawUpKElbow2D2(lstSeg, nVNum, ptStart, ptVDTmp);
|
||
}
|
||
if (!bIsOk)
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
}
|
||
|
||
if (m_nSysDrawMod != 3) // 5、除双线外,绘制中心线
|
||
{
|
||
DList<XCurveSegment> midSegs;
|
||
BuildSegs1(ptStart, ptVDTmp, midSegs);
|
||
if ((m_nSysDrawMod==1) || (m_nSysDrawMod==4))
|
||
{
|
||
DrawXiSegs(dc, midSegs);
|
||
return Acad::eOk;
|
||
}
|
||
DrawMidSegs(dc, midSegs);
|
||
}
|
||
Draw2DSegs(dc, lstSeg);
|
||
return Acad::eOk;
|
||
}
|
||
|
||
// 无下弯的上弯头
|
||
BOOL TDbDuctNode::DrawUpKElbow2D1(DList<XCurveSegment> &segs, int nVNum,
|
||
int nHNum, XPoint ptStart,
|
||
XPoint &ptVDTmp, BOOL bIs3T) const
|
||
{
|
||
XPoint ptLoc = GetZeroPt(),
|
||
ptSpare(ptStart);
|
||
ptSpare.z = 0;
|
||
|
||
double dVDAngle = GetIVDAngle(nVNum), // 立管角度
|
||
dLowAngle = GetIAngle(nHNum); // 非立管法向
|
||
double dWidth = GetIWidth(nHNum), // 非立管宽度
|
||
dVDWidth = GetIWidth(nVNum), // 立管宽度
|
||
dVDHigh = GetIHeight(nVNum); // 立管高度
|
||
XPoint pt1, pt2, pt3, pt4, ptInt1, ptInt2, ptTmp;
|
||
ads_polar(ptSpare, dLowAngle+PI/2, dWidth/2, pt1);
|
||
ads_polar(ptSpare, dLowAngle-PI/2, dWidth/2, pt2);
|
||
|
||
XLine tmpLine(ptLoc, ptSpare, LS_INFINITE);
|
||
XLine lowL1 = tmpLine.Offset(-dWidth/2), // 非立管管线边线
|
||
lowL2 = tmpLine.Offset(dWidth/2);
|
||
|
||
double dFlangeDis = bIs3T?0:GetIFlDist(nVNum);
|
||
if (fabs(dVDHigh) < 1.0E-6) // 圆
|
||
{
|
||
ads_polar(pt1, dLowAngle, -dWidth, pt3);
|
||
ads_polar(pt2, dLowAngle, -dWidth, pt4);
|
||
|
||
XCircle circle(ptLoc, dVDWidth/2+dFlangeDis);
|
||
if (lowL1.Intersection(&circle, ptInt1, ptTmp))
|
||
ptInt1 = ::GetNearPt(pt1, ptInt1, ptTmp); // 取较近的交点
|
||
else
|
||
ptInt1 = ::GetTangentPt2(circle, pt1, pt3); // 取切点
|
||
|
||
ptTmp = XPoint();
|
||
if (lowL2.Intersection(&circle, ptInt2, ptTmp))
|
||
ptInt2 = ::GetNearPt(pt2, ptInt2, ptTmp);
|
||
else
|
||
ptInt2 = ::GetTangentPt2(circle, pt2, pt4);
|
||
if (ptInt1==XPoint() || ptInt2==XPoint())
|
||
return FALSE;
|
||
|
||
ptTmp = XPoint();
|
||
XLine lineTmp(ptLoc, ptSpare);
|
||
if (circle.Intersection(&lineTmp, ptVDTmp, ptTmp))
|
||
ptVDTmp = ::GetNearPt(ptLoc, ptVDTmp, ptTmp);
|
||
else
|
||
return FALSE;
|
||
|
||
if (bIs3T) // 注:防止立管都被删除时,绘制错误
|
||
{
|
||
BuildSegs5(circle, segs);
|
||
}
|
||
|
||
}
|
||
else // 矩形
|
||
{
|
||
double dAngle = CT_std_angle(dVDAngle - dLowAngle);
|
||
if (fabs(dAngle)<1.0E-3 || fabs(dAngle-PI)<1.0E-3)
|
||
{
|
||
TchPrivate::Exchange(dVDWidth, dVDHigh);
|
||
}
|
||
|
||
XPoint ptVDuct1, ptVDuct2;
|
||
ads_polar(ptLoc, dLowAngle, dVDHigh/2+dFlangeDis, ptVDTmp);
|
||
ads_polar(ptVDTmp, dLowAngle+PI/2, dVDWidth/2+dFlangeDis, ptVDuct1);
|
||
ads_polar(ptVDTmp, dLowAngle-PI/2, dVDWidth/2+dFlangeDis, ptVDuct2);
|
||
|
||
XLine line(ptVDuct1, ptVDuct2, LS_FINITE);
|
||
if (!line.Intersection(&lowL1, ptInt1))
|
||
{
|
||
ptInt1 = ptVDuct1;
|
||
}
|
||
if (!line.Intersection(&lowL2, ptInt2))
|
||
{
|
||
ptInt2 = ptVDuct2;
|
||
}
|
||
if (ptInt1==XPoint() || ptInt2==XPoint())
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
if (!line.Intersection(&tmpLine, ptVDTmp))
|
||
{
|
||
Midpoint(ptInt1, ptInt2, ptVDTmp);
|
||
}
|
||
|
||
if (bIs3T) // 注:防止立管都被删除时,绘制错误
|
||
{
|
||
ads_polar(ptVDuct1, dLowAngle, -dVDHigh, ptVDuct1);
|
||
ads_polar(ptVDuct2, dLowAngle, -dVDHigh, ptVDuct2);
|
||
BuildSegs6(ptInt1, ptVDuct1, ptVDuct2, ptInt2, segs);
|
||
}
|
||
}
|
||
BuildSegs1(ptInt1, pt1, segs);
|
||
BuildSegs1(ptInt2, pt2, segs);
|
||
return TRUE;
|
||
}
|
||
|
||
// 矩形截面立管下扣弯法兰
|
||
void TDbDuctNode::GetFKEFlPts(double dUpAng, double dVDAng,
|
||
XPoint upNodePt, double dUpWide,
|
||
int nVDtNum, XPointList &pts) const
|
||
{
|
||
double dVDWidth = GetIWidth(nVDtNum), // 立管尺寸
|
||
dVDHigh = GetIHeight(nVDtNum),
|
||
dFlDis = GetIFlDist(nVDtNum); // 立管上的法兰尺寸
|
||
double dAng = CT_acute_angle(dUpAng - dVDAng); // 夹角
|
||
if (fabs(dAng-PI/2) > 1.0E-3)
|
||
{
|
||
TchPrivate::Exchange(dVDWidth, dVDHigh);
|
||
}
|
||
|
||
XPoint ptLoc = GetZeroPt(),
|
||
ptVF1, ptVF2, ptVF3, ptVF4, ptTmp; // 立管法兰边框点(逆时针顺序)
|
||
ads_polar(ptLoc, dUpAng, -(dVDHigh/2+dFlDis), ptTmp);
|
||
ads_polar(ptTmp, dUpAng+PI/2, dVDWidth/2+dFlDis, ptVF2);
|
||
ads_polar(ptTmp, dUpAng-PI/2, dVDWidth/2+dFlDis, ptVF3);
|
||
ads_polar(ptVF2, dUpAng, dVDHigh+2*dFlDis, ptVF1);
|
||
ads_polar(ptVF3, dUpAng, dVDHigh+2*dFlDis, ptVF4);
|
||
|
||
XPoint ptV1, ptV2; // 立管边框点(逆时针顺序)
|
||
ads_polar(ptTmp, dUpAng, dFlDis, ptTmp);
|
||
ads_polar(ptTmp, dUpAng+PI/2, dVDWidth/2, ptV1);
|
||
ads_polar(ptTmp, dUpAng-PI/2, dVDWidth/2, ptV2);
|
||
|
||
XPoint upSparePt(upNodePt), ptUp1, ptUp2, ptInt1, ptInt2;
|
||
upSparePt.z = 0;
|
||
ads_polar(upSparePt, dUpAng+PI/2, dUpWide/2, ptUp1); // 上节点非立管边线点
|
||
ads_polar(upSparePt, dUpAng-PI/2, dUpWide/2, ptUp2);
|
||
|
||
pts.Reset();
|
||
XLine line1(ptV1, ptUp1, LS_FINITE),
|
||
line2(ptVF1, ptVF4, LS_FINITE),
|
||
line3(ptVF2, ptVF1, LS_FINITE);
|
||
if (!line1.Intersection(&line2, ptInt1))
|
||
{
|
||
if (line1.Intersection(&line3, ptInt1))
|
||
pts.Append(new XPoint(ptInt1));
|
||
}
|
||
else
|
||
{
|
||
pts.Append(new XPoint(ptInt1));
|
||
pts.Append(new XPoint(ptVF1));
|
||
}
|
||
|
||
pts.Append(new XPoint(ptVF2));
|
||
pts.Append(new XPoint(ptVF3));
|
||
line1.SetPoints(ptV2, ptUp2);
|
||
if (!line1.Intersection(&line2, ptInt2))
|
||
{
|
||
line3.SetPoints(ptVF3, ptVF4);
|
||
if (line1.Intersection(&line3, ptInt2))
|
||
pts.Append(new XPoint(ptInt2));
|
||
}
|
||
else
|
||
{
|
||
pts.Append(new XPoint(ptVF4));
|
||
pts.Append(new XPoint(ptInt2));
|
||
}
|
||
}
|
||
|
||
// 圆截面立管下扣弯法兰
|
||
void TDbDuctNode::GetYKEFlPts(double dUpAng, double dVDWidth,
|
||
XPoint upNodePt, double dUpWidth,
|
||
XArc &tmpArc, double dVDFlDist, XPointList &pts) const
|
||
{
|
||
XPoint ptNodeLoc = GetZeroPt(),
|
||
upSparePt(upNodePt);
|
||
upSparePt.z = 0;
|
||
|
||
XPoint ptV1, ptV2; // 立管边框点(逆时针顺序)
|
||
ads_polar(ptNodeLoc, dUpAng+PI/2, dVDWidth/2, ptV1);
|
||
ads_polar(ptNodeLoc, dUpAng-PI/2, dVDWidth/2, ptV2);
|
||
// tmpArc.center = ptNodeLoc;
|
||
tmpArc.SetCenterPt(ptNodeLoc);
|
||
tmpArc.SetAngleByPoints(ptV2, ptV1);
|
||
tmpArc.SetRadius(ptNodeLoc.Distance(ptV1));
|
||
|
||
XPoint ptVF1, ptVF2, // 立管法兰边框点(逆时针顺序)
|
||
ptMid; // 圆弧中点
|
||
ads_polar(ptNodeLoc, dUpAng, -(dVDWidth/2+dVDFlDist), ptMid);
|
||
ads_polar(ptNodeLoc, dUpAng+PI/2, dVDWidth/2+dVDFlDist, ptVF1);
|
||
ads_polar(ptNodeLoc, dUpAng-PI/2, dVDWidth/2+dVDFlDist, ptVF2);
|
||
|
||
XPoint ptTmp1, ptTmp2, ptInt1, ptInt2, ptTmp;
|
||
ads_polar(upSparePt, dUpAng+PI/2, dUpWidth/2, ptTmp1); // 上节点非立管管线边线点
|
||
ads_polar(upSparePt, dUpAng-PI/2, dUpWidth/2, ptTmp2);
|
||
XLine UpNodeSideL1(ptV1, ptTmp1, LS_FINITE), // 上节点非立管管线边线点
|
||
UpNodeSideL2(ptV2, ptTmp2, LS_FINITE);
|
||
|
||
pts.Reset();
|
||
XCircle circle(ptNodeLoc, dVDWidth/2+dVDFlDist);
|
||
if (UpNodeSideL1.Intersection(&circle, ptInt1, ptTmp)) {
|
||
ptInt1 = ::GetNearPt(ptTmp1, ptInt1, ptTmp);
|
||
pts.Append(new XPoint(ptInt1));
|
||
}
|
||
pts.Append(new XPoint(ptVF1));
|
||
pts.Append(new XPoint(ptMid));
|
||
pts.Append(new XPoint(ptVF2));
|
||
if (UpNodeSideL2.Intersection(&circle, ptInt2, ptTmp)) {
|
||
ptInt2 = ::GetNearPt(ptTmp2, ptInt2, ptTmp);
|
||
pts.Append(new XPoint(ptInt2));
|
||
}
|
||
}
|
||
|
||
// 有下弯头的上弯头
|
||
BOOL TDbDuctNode::DrawUpKElbow2D2(DList<XCurveSegment> &segs, int nVNum,
|
||
XPoint ptStart, XPoint &ptVDTmp) const
|
||
{
|
||
XPointList pts; // 立管上节点所连接的非立管,管线信息
|
||
DList<XVector3D> vts;
|
||
AcGeDoubleArray widths;
|
||
int nType(-1); // 立管上节点类型:0--下扣弯,1--连2根立管的三通,2--连1根立管的三通
|
||
OPENOBJ_BEGIN(GetIPipe(nVNum), AcDb::kForRead, TDbDuct, pDuct);
|
||
if (pDuct==NULL || !pDuct->IsVertical())
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
pDuct->GetUpPipesPt(pts);
|
||
widths = pDuct->GetUpPipesWidth();
|
||
pDuct->GetUpPipesVec(vts);
|
||
int nNumber = pts.Length();
|
||
if ((widths.logicalLength()!=nNumber) || (vts.Length()!=nNumber))
|
||
{
|
||
return FALSE; // 数量一定是相等的
|
||
}
|
||
|
||
AcDbObjectId upNodeId = pDuct->GetVerUpNode(); // 上节点
|
||
OPENOBJ_BEGIN(upNodeId, AcDb::kForRead, TDbDuctNode, pNode);
|
||
if (pNode != NULL)
|
||
{
|
||
if (!(pNode->Is(_T("KouElbow")) || pNode->Is(_T("3Corner")) || (nNumber!=0)))
|
||
{
|
||
return TRUE; // 上节点不遮挡“上弯头”,nType = -1
|
||
}
|
||
|
||
nType = (pNode->Is(_T("3Corner")))?(3-nNumber):0; // 判断上节点类型
|
||
if (nNumber == 3)
|
||
{
|
||
return FALSE;
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
OPENOBJ_END();
|
||
|
||
int nHNum = 1 - nVNum; // 水平管标号
|
||
double dWide = GetIWidth(nHNum), // 本节点非立管管线宽度
|
||
dLowAngle = GetIAngle(nHNum); // 管线方向
|
||
double dVDWide = GetIWidth(nVNum), // 立管尺寸
|
||
dVDFlDist = GetIFlDist(nVNum), // 立管法兰出头长度
|
||
dVDHigh = GetIHeight(nVNum),
|
||
dVDAngle = GetIVDAngle(nVNum); // 立管角度
|
||
XPoint ptLoc = GetZeroPt(), ptSpare(ptStart), pt1, pt2;
|
||
ptSpare.z = 0;
|
||
ads_polar(ptSpare, dLowAngle+PI/2, dWide/2, pt1); // 本节点非立管管线边线点
|
||
ads_polar(ptSpare, dLowAngle-PI/2, dWide/2, pt2);
|
||
|
||
XLine tmpLine(ptLoc, ptSpare, LS_INFINITE);
|
||
XLine lowL1 = tmpLine.Offset(-dWide/2), // 本节点非立管管线边线
|
||
lowL2 = tmpLine.Offset(dWide/2);
|
||
|
||
XCurveSegment seg;
|
||
XPoint ptInt1, ptInt2, ptTmp; // 临时点
|
||
if (nType == 0) // 扣弯
|
||
{
|
||
double dUpAngle = ads_angle(XPoint(), *vts[0]), // 开口方向
|
||
dAng = CT_std_angle(dUpAngle - dLowAngle); // 夹角
|
||
if (fabs(dVDHigh) < 1.0E-6) // 圆
|
||
{
|
||
XArc tmpArc;
|
||
XPointList ptLst;
|
||
GetYKEFlPts(dUpAngle, dVDWide, *pts[0], widths[0],
|
||
tmpArc, dVDFlDist, ptLst);
|
||
if (ptLst.Length() != 5)
|
||
return FALSE;
|
||
|
||
XArc arc(*ptLst[0], *ptLst[2], *ptLst[4]); // 立管法兰边框
|
||
if (lowL1.Intersection(&arc, ptInt1, ptTmp))
|
||
ptInt1 = ::GetNearPt(pt1, ptInt1, ptTmp); // 取一个较近的交点
|
||
if (lowL2.Intersection(&arc, ptInt2, ptTmp))
|
||
ptInt2 = ::GetNearPt(pt2, ptInt2, ptTmp);
|
||
|
||
XPoint ptMid;
|
||
tmpArc.MidPoint(ptMid);
|
||
XCircle circle(ptLoc, dVDWide/2+dVDFlDist);
|
||
if (dAng>1.0E-6 && dAng<(PI/2+1.0E-6))
|
||
{
|
||
if (ptInt2 == XPoint())
|
||
{
|
||
ptInt2 = ::GetTangentPt1(arc, pt2, *ptLst[2]);
|
||
if (ptInt2 == XPoint())
|
||
ptInt2 = *ptLst[2];
|
||
}
|
||
|
||
if (dAng>1.0E-6 && dAng<(PI/2-1.0E-6))
|
||
ads_polar(pt1, dLowAngle, -100, ptInt1);
|
||
else if (fabs(dAng-PI/2)<1.0E-6 && ptInt1==XPoint())
|
||
{
|
||
ptInt1 = ::GetTangentPt1(tmpArc, pt1, ptMid);
|
||
if (ptInt1 == XPoint())
|
||
ptInt1 = ptMid;
|
||
XLine lineTmp(pt1, ptInt1, LS_INFINITE);
|
||
if (!circle.Intersection(&lineTmp, ptInt1, ptTmp))
|
||
return FALSE;
|
||
ptInt1 = ::GetNearPt(pt1, ptInt1, ptTmp);
|
||
}
|
||
}
|
||
else if (dAng>(PI/2+1.0E-6) && dAng<(1.5*PI-1.0E-6))
|
||
{
|
||
ptTmp = *ptLst[1];
|
||
if (dAng > (PI+1.0E-6))
|
||
ptTmp = *ptLst[0];
|
||
if (ptInt2 == XPoint())
|
||
{
|
||
ptInt2 = ::GetTangentPt1(arc, pt2, ptTmp);
|
||
if (ptInt2 == XPoint())
|
||
ptInt2 = ptTmp;
|
||
}
|
||
|
||
ptTmp = *ptLst[3];
|
||
if (dAng > (PI+1.0E-6))
|
||
ptTmp = *ptLst[2];
|
||
if (ptInt1 == XPoint())
|
||
{
|
||
ptInt1 = ::GetTangentPt1(arc, pt1, ptTmp);
|
||
if (ptInt1 == XPoint())
|
||
ptInt1 = ptTmp;
|
||
}
|
||
}
|
||
else if (dAng>(PI*1.5-1.0E-6) && dAng<(2*PI-1.0E-6))
|
||
{
|
||
if (dAng>(PI*1.5+1.0E-6) && dAng<(2*PI-1.0E-6))
|
||
ads_polar(pt2, dLowAngle, -100, ptInt2);
|
||
else if (fabs(dAng-PI*1.5)<0.001 && ptInt2==XPoint())
|
||
{
|
||
ptInt2 = ::GetTangentPt1(tmpArc, pt2, ptMid);
|
||
if (ptInt2 == XPoint())
|
||
ptInt2 = ptMid;
|
||
|
||
XLine lineTmp1(pt2, ptInt2, LS_INFINITE);
|
||
if (!circle.Intersection(&lineTmp1, ptInt2, ptTmp))
|
||
return FALSE;
|
||
ptInt2 = ::GetNearPt(pt2, ptInt2, ptTmp);
|
||
}
|
||
|
||
if (ptInt1 == XPoint())
|
||
{
|
||
ptInt1 = ::GetTangentPt1(arc, pt1, *ptLst[2]);
|
||
if (ptInt1 == XPoint())
|
||
ptInt1 = *ptLst[2];
|
||
}
|
||
}
|
||
|
||
ads_polar(ptSpare, dLowAngle, -dWide, ptTmp);
|
||
XLine line(ptTmp, ptSpare, LS_INFINITE);
|
||
if (line.Intersection(&arc, ptVDTmp, ptTmp))
|
||
ptVDTmp = ::GetNearPt(pt1, ptVDTmp, ptTmp);
|
||
else
|
||
{
|
||
line.SetPoints(ptSpare, ptLoc);
|
||
if (line.Intersection(&arc, ptVDTmp, ptTmp))
|
||
ptVDTmp = ::GetNearPt(pt1, ptVDTmp, ptTmp);
|
||
else
|
||
return FALSE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
XPointList flangePts;
|
||
GetFKEFlPts(dUpAngle, dVDAngle, *pts[0], widths[0],
|
||
nVNum, flangePts); // 立管法兰边框点
|
||
int nPtCount = flangePts.Length();
|
||
if (nPtCount!=4 && nPtCount!=6)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
int n1 = nPtCount==4?0:1, // 注:角标与立管法兰对应,在链表中的号
|
||
n2 = nPtCount==4?1:2,
|
||
n3 = nPtCount==4?2:3,
|
||
n4 = nPtCount==4?3:4;
|
||
if (fabs(dAng-PI*0.5)<1.0E-6 || fabs(dAng-PI)<1.0E-6 ||
|
||
fabs(dAng-PI*1.5)<1.0E-6)
|
||
{
|
||
XLine line(*flangePts[n2], *flangePts[n3], LS_FINITE);
|
||
if (fabs(dAng-PI*0.5) < 1.0E-6)
|
||
line.SetPoints(*flangePts[n3], *flangePts[n4]);
|
||
else if (fabs(dAng-PI*1.5)<1.0E-6)
|
||
line.SetPoints(*flangePts[n1], *flangePts[n2]);
|
||
|
||
if (!lowL1.Intersection(&line, ptInt1))
|
||
ptInt1 = line.EndPoint();
|
||
if (!lowL2.Intersection(&line, ptInt2))
|
||
ptInt2 = line.StartPoint();
|
||
ptVDTmp = line.MidPoint();
|
||
}
|
||
else if ((dAng>(PI/2+1.0E-6)&&dAng<(PI-1.0E-6)) ||
|
||
(dAng>(PI+1.0E-6)&&dAng<(1.5*PI-1.0E-6))) // 钝角
|
||
{
|
||
XLine line1(*flangePts[n2], *flangePts[n3], LS_FINITE),
|
||
line2(*flangePts[n2], *flangePts[n1], LS_FINITE);
|
||
if (dAng>(PI/2+1.0E-6) && dAng<(PI-1.0E-6))
|
||
line2.SetPoints(*flangePts[n3], *flangePts[n4]);
|
||
|
||
if (!lowL1.Intersection(&line1, ptInt1))
|
||
{
|
||
if (dAng>(PI/2+1.0E-6) && dAng<(PI-1.0E-6))
|
||
{
|
||
if (!lowL1.Intersection(&line2, ptInt1))
|
||
ptInt1 = line2.EndPoint();
|
||
}
|
||
else
|
||
ptInt1 = line1.EndPoint();
|
||
}
|
||
if (!lowL2.Intersection(&line1, ptInt2))
|
||
{
|
||
if (dAng>(PI/2+1.0E-6) && dAng<(PI-1.0E-6))
|
||
ptInt2 = line1.StartPoint();
|
||
else
|
||
{
|
||
if (!lowL2.Intersection(&line2, ptInt2))
|
||
ptInt2 = line2.EndPoint();
|
||
}
|
||
}
|
||
|
||
ads_polar(ptSpare, dLowAngle, -dWide, ptTmp);
|
||
XLine line3(ptSpare, ptTmp, LS_INFINITE);
|
||
if (!line3.Intersection(&line1, ptVDTmp))
|
||
{
|
||
if (!line3.Intersection(&line2, ptVDTmp))
|
||
return FALSE;
|
||
}
|
||
}
|
||
else if (dAng>1.0E-6 && dAng<(PI/2+1.0E-6)) // 锐角
|
||
{
|
||
XLine line(*flangePts[n3], *flangePts[n4], LS_FINITE);
|
||
if (!lowL2.Intersection(&line, ptInt2))
|
||
ptInt2 = *flangePts[n3];
|
||
ads_polar(pt1, dLowAngle, -100, ptInt1);
|
||
ads_polar(ptStart, dLowAngle, -100, ptVDTmp);
|
||
}
|
||
else if (dAng>(PI*1.5-1.0E-6) && dAng<(2*PI-1.0E-6)) // 锐角
|
||
{
|
||
XLine line(*flangePts[n1], *flangePts[n2], LS_FINITE);
|
||
if (!lowL1.Intersection(&line, ptInt1))
|
||
ptInt1 = *flangePts[n2];
|
||
ads_polar(pt2, dLowAngle, -100, ptInt2);
|
||
ads_polar(ptSpare, dLowAngle, -100, ptVDTmp);
|
||
}
|
||
}
|
||
BuildSegs1(ptInt1, pt1, segs);
|
||
BuildSegs1(ptInt2, pt2, segs);
|
||
return TRUE;
|
||
}
|
||
|
||
if (nType == 1) // 连2根立管的三通
|
||
{
|
||
if (fabs(dVDHigh) < 1.0E-6) // 圆
|
||
{
|
||
XPoint pt3, pt4;
|
||
ads_polar(pt1, dLowAngle, -dWide, pt3);
|
||
ads_polar(pt2, dLowAngle, -dWide, pt4);
|
||
XCircle circle(ptLoc, dVDWide/2);
|
||
if (circle.Intersection(&lowL1, ptInt1, ptTmp) != 0)
|
||
ptInt1 = ::GetNearPt(pt1, ptInt1, ptTmp);
|
||
else {
|
||
ptInt1 = ::GetTangentPt2(circle, pt1, pt3);
|
||
if (ptInt1 == XPoint())
|
||
ads_polar(pt1, dLowAngle, -200, ptInt1);
|
||
}
|
||
|
||
if (circle.Intersection(&lowL2, ptInt2, ptTmp) != 0)
|
||
ptInt2 = ::GetNearPt(pt2, ptInt2, ptTmp);
|
||
else {
|
||
ptInt2 = ::GetTangentPt2(circle, pt2, pt4);
|
||
if (ptInt2 == XPoint())
|
||
ads_polar(pt2, dLowAngle, -200, ptInt2);
|
||
}
|
||
|
||
if (circle.Intersection(&tmpLine, ptVDTmp, ptTmp) == 0)
|
||
return FALSE;
|
||
ptVDTmp = ::GetNearPt(ptSpare, ptVDTmp, ptTmp);
|
||
}
|
||
else
|
||
{
|
||
double dAng = CT_std_angle(dLowAngle - dVDAngle); // 夹角
|
||
if (fabs(dAng) < 1.0E-6)
|
||
{
|
||
ads_polar(ptLoc, dVDAngle, dVDWide/2, ptTmp);
|
||
ads_polar(ptTmp, dVDAngle+PI/2, dVDHigh/2, ptInt1);
|
||
ads_polar(ptTmp, dVDAngle-PI/2, dVDHigh/2, ptInt2);
|
||
ptVDTmp = ptTmp;
|
||
}
|
||
else if (fabs(dAng-PI) < 1.0E-6)
|
||
{
|
||
ads_polar(ptLoc, dVDAngle, -dVDWide/2, ptTmp);
|
||
ads_polar(ptTmp, dVDAngle+PI/2, dVDHigh/2, ptInt2);
|
||
ads_polar(ptTmp, dVDAngle-PI/2, dVDHigh/2, ptInt1);
|
||
ptVDTmp = ptTmp;
|
||
}
|
||
else if (fabs(dAng-PI*0.5)<1.0E-6 || fabs(dAng-PI*1.5)<1.0E-6)
|
||
{
|
||
ads_polar(ptLoc, dLowAngle, dVDHigh/2, ptTmp);
|
||
ads_polar(ptTmp, dLowAngle+PI/2, dVDWide/2, ptInt1);
|
||
ads_polar(ptTmp, dLowAngle-PI/2, dVDWide/2, ptInt2);
|
||
ptVDTmp = ptTmp;
|
||
}
|
||
else
|
||
{
|
||
ads_polar(pt1, dLowAngle, -200, ptInt1);
|
||
ads_polar(pt2, dLowAngle, -200, ptInt2);
|
||
ads_polar(ptSpare, dLowAngle, -200, ptVDTmp);
|
||
}
|
||
}
|
||
BuildSegs1(ptInt1, pt1, segs);
|
||
BuildSegs1(ptInt2, pt2, segs);
|
||
return TRUE;
|
||
}
|
||
|
||
// 连1根立管的三通
|
||
double dOpenAng = ads_angle(XPoint(), *vts[0]); // 管线方向
|
||
double dAng = CT_std_angle(dLowAngle - dOpenAng); // 夹角
|
||
if (fabs(dAng-PI*0.5)<1.0E-6 || fabs(dAng-PI*1.5)<1.0E-6)
|
||
{
|
||
XPoint ptTmp1, ptTmp2, ptTmp3, ptTmp4; // 下节点非立管管线边线点
|
||
ads_polar(*pts[0], dOpenAng+PI/2, widths[0]/2, ptTmp1);
|
||
ads_polar(*pts[0], dOpenAng-PI/2, widths[0]/2, ptTmp3);
|
||
ads_polar(*pts[1], dOpenAng+PI/2, widths[1]/2, ptTmp2);
|
||
ads_polar(*pts[1], dOpenAng-PI/2, widths[1]/2, ptTmp4);
|
||
ptTmp1 = ::GetNearPt(ptSpare, ptTmp1, ptTmp3);
|
||
ptTmp2 = ::GetNearPt(ptSpare, ptTmp2, ptTmp4);
|
||
XLine tmpLine1(ptTmp1, ptTmp2, LS_INFINITE);
|
||
tmpLine1.Intersection(&lowL1, ptInt1);
|
||
tmpLine1.Intersection(&lowL2, ptInt2);
|
||
tmpLine1.Intersection(&tmpLine, ptVDTmp);
|
||
BuildSegs1(ptInt1, pt1, segs);
|
||
BuildSegs1(ptInt2, pt2, segs);
|
||
}
|
||
else
|
||
{
|
||
ptVDTmp = ptLoc;
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
/////////////////////////变径、天圆地方/////////////////////
|
||
Acad::ErrorStatus TDbDuctNode::DrawTapered2D(XExplodeDraw &dc, BOOL bIsTYDF) const
|
||
{
|
||
if (GetInterfaceNum() != 2) // 1、保证所有的链表不越界
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
XPointList pts;
|
||
GetPtsIFace(pts, FALSE, FALSE, FALSE, TRUE);
|
||
if (pts.Length() != 2) // 2、获取与管线相连点,考虑了法兰遮挡
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
if (m_nSysDrawMod != 3) // 3、绘制中线
|
||
{
|
||
DList<XCurveSegment> midSegs;
|
||
BuildSegs1(*pts[0], *pts[1], midSegs);
|
||
if (m_nSysDrawMod == 1) // 单线图
|
||
{
|
||
DrawXiSegs(dc, midSegs);
|
||
return Acad::eOk;
|
||
}
|
||
DrawMidSegs(dc, midSegs); // 三线图
|
||
}
|
||
|
||
// 4、获取绘制信息
|
||
double dWidth1 = GetIWidth(0), // 管线尺寸
|
||
dWidth2 = GetIWidth(1),
|
||
dHigh1 = GetIHeight(0),
|
||
dHigh2 = GetIHeight(1);
|
||
XVector3D vt1 = GetIDirection(0),
|
||
vt2 = GetIDirection(1);
|
||
BOOL bIsVDuct1(FALSE), bIsVDuct2(FALSE),
|
||
bCircle1 = GetISection(0)==1, // 1接口是否为圆管
|
||
bCircle2 = GetISection(1)==1; // 2接口是否为圆管
|
||
if (fabs(vt1.x)<1.0E-6 && fabs(vt1.y)<1.0E-6) // 1接口接立管
|
||
{
|
||
bIsVDuct1 = TRUE;
|
||
}
|
||
if (fabs(vt2.x)<1.0E-6 && fabs(vt2.y)<1.0E-6) // 2接口接立管
|
||
{
|
||
bIsVDuct2 = TRUE;
|
||
}
|
||
|
||
XCurveSegment seg;
|
||
DList<XCurveSegment> lstSeg; // 5、绘制上下线
|
||
if (bIsVDuct1 && bIsVDuct2)
|
||
{
|
||
if (bCircle1)
|
||
{
|
||
XCircle circle(*pts[0], dWidth1/2);
|
||
BuildSegs5(circle, lstSeg);
|
||
}
|
||
else
|
||
{
|
||
XPoly2D rect(1);
|
||
::GetSquare(*pts[0], GetIVDAngle(0), dWidth1, dHigh1, &rect, NULL);
|
||
if (rect.Length() != 4)
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
rect.AppendNode(*rect[0]);
|
||
for (int j=0; j<4; j++)
|
||
{
|
||
BuildSegs1(*rect[j], *rect[j+1], lstSeg);
|
||
}
|
||
}
|
||
|
||
if (bCircle2)
|
||
{
|
||
XCircle circle(*pts[1], dWidth2/2);
|
||
BuildSegs5(circle, lstSeg);
|
||
}
|
||
else
|
||
{
|
||
XPoly2D rect(1);
|
||
::GetSquare(*pts[1], GetIVDAngle(1), dWidth2, dHigh2, &rect, NULL);
|
||
if (rect.Length() != 4)
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
rect.AppendNode(*rect[0]);
|
||
for (int j=0; j<4; j++)
|
||
{
|
||
BuildSegs1(*rect[j], *rect[j+1], lstSeg);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
XPoint pt1, pt2, pt3, pt4;
|
||
double dAng = GetIAngle(0);
|
||
ads_polar(*pts[0], dAng-PI/2, dWidth1/2, pt1);
|
||
ads_polar(*pts[0], dAng+PI/2, dWidth1/2, pt2);
|
||
ads_polar(*pts[1], dAng-PI/2, dWidth2/2, pt3);
|
||
ads_polar(*pts[1], dAng+PI/2, dWidth2/2, pt4);
|
||
BuildSegs1(pt1, pt3, lstSeg);
|
||
BuildSegs1(pt2, pt4, lstSeg);
|
||
|
||
if (bIsTYDF && bCircle1)
|
||
{
|
||
BuildSegs2(pt3, *pts[0], pt4, lstSeg);
|
||
}
|
||
else if (bIsTYDF && bCircle2)
|
||
{
|
||
BuildSegs2(pt1, *pts[1], pt2, lstSeg);
|
||
}
|
||
}
|
||
Draw2DSegs(dc, lstSeg);
|
||
return Acad::eOk;
|
||
}
|
||
|
||
|
||
///////////////////////////乙字弯///////////////////////////
|
||
void GetNewPts(XPoint &pt1, XPoint &pt2, double dLen)
|
||
{
|
||
XVector3D vt = pt1 - pt2;
|
||
vt.Normalize();
|
||
vt.Scale(dLen);
|
||
pt1 = pt1 + vt;
|
||
vt.Scale(-1);
|
||
pt2 = pt2 + vt;
|
||
return;
|
||
}
|
||
|
||
Acad::ErrorStatus TDbDuctNode::DrawYZElbow2D(XExplodeDraw &dc) const
|
||
{
|
||
if (GetInterfaceNum() != 2) // 1、保证所有的链表不越界
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
XPointList pts;
|
||
GetPtsIFace(pts, FALSE, FALSE, FALSE, FALSE);
|
||
if (pts.Length() != 2) // 2、获取与管线相连点,注:考虑法兰遮挡节点
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
XPoint pt1 = *pts[0],
|
||
pt2 = *pts[1];
|
||
BOOL bSameEle = (fabs(pt1.z-pt2.z)<1.0E-5); // 3、判断连接管线是否标高相同
|
||
pt1.z = pt2.z = 0;
|
||
|
||
double dAng1 = GetIAngle(0), // 方向
|
||
dAng2 = GetIAngle(1);
|
||
double dDist1 = GetIWidth(0), // 管线宽度
|
||
dDist2 = GetIWidth(1);
|
||
double dThick1 = GetIFlThick(0), // 法兰厚度
|
||
dThick2 = GetIFlThick(1);
|
||
double dFlDia1 = dDist1 + 2*GetIFlDist(0), // 法兰直径
|
||
dFlDia2 = dDist2 + 2*GetIFlDist(1);
|
||
|
||
XPoint p1, p2, p3, p4;
|
||
XPoint ptTmp1, ptTmp2, ptTmp3, ptTmp4;
|
||
DList<XCurveSegment> lstSeg; // 绘制边线
|
||
if (bSameEle && (m_nDrawMod == 2)) // 4、角接样式
|
||
{
|
||
ads_polar(pt1, dAng1, -(dDist1-dThick1), p1); // 按照从左到右的顺序排列
|
||
ads_polar(pt1, dAng1, -dDist1, p2);
|
||
ads_polar(pt2, dAng2, -dDist2, p3);
|
||
ads_polar(pt2, dAng2, -(dDist2-dThick2), p4);
|
||
|
||
if (m_nSysDrawMod != 3) // 绘制中心线
|
||
{
|
||
DList<XCurveSegment> midSegs;
|
||
BuildSegs1(pt1, p1, midSegs);
|
||
BuildSegs1(p2, p3, midSegs);
|
||
BuildSegs1(pt2, p4, midSegs);
|
||
|
||
if (m_nSysDrawMod == 1) // 单线图
|
||
{
|
||
DrawXiSegs(dc, midSegs);
|
||
return Acad::eOk;
|
||
}
|
||
DrawMidSegs(dc, midSegs); // 三线图
|
||
}
|
||
|
||
Midpoint(p1, p2, ptTmp1); // 中间法兰位置点
|
||
Midpoint(p3, p4, ptTmp2);
|
||
DrawFlange(lstSeg, ptTmp1, dAng1, dFlDia1, dThick1);
|
||
DrawFlange(lstSeg, ptTmp2, dAng2, dFlDia2, dThick2);
|
||
DrawFLSegs(dc, lstSeg); // 绘制法兰
|
||
|
||
lstSeg.Reset();
|
||
dDist1 *= 0.5;
|
||
dDist2 *= 0.5;
|
||
BuildSegs3(XLine(pt1, p1, LS_FINITE).Offset(dDist1), lstSeg);
|
||
BuildSegs3(XLine(pt1, p1, LS_FINITE).Offset(-dDist1), lstSeg);
|
||
BuildSegs3(XLine(pt2, p4, LS_FINITE).Offset(dDist2), lstSeg);
|
||
BuildSegs3(XLine(pt2, p4, LS_FINITE).Offset(-dDist2), lstSeg);
|
||
|
||
ads_polar(p2, dAng1+PI/2, dDist1, ptTmp1);
|
||
ads_polar(p2, dAng1-PI/2, dDist1, ptTmp2);
|
||
ads_polar(p3, dAng2+PI/2, dDist2, ptTmp3);
|
||
ads_polar(p3, dAng2-PI/2, dDist2, ptTmp4);
|
||
BuildSegs1(ptTmp1, ptTmp4, lstSeg);
|
||
BuildSegs1(ptTmp2, ptTmp3, lstSeg);
|
||
Draw2DSegs(dc, lstSeg); // 绘制边线
|
||
return Acad::eOk;
|
||
}
|
||
|
||
double dLen = pt1.Distance(pt2); // 斜边长度
|
||
ads_polar(pt1, dAng1+PI/2, dDist1/2, p1);
|
||
ads_polar(pt1, dAng1-PI/2, dDist1/2, p2);
|
||
ads_polar(pt2, dAng2+PI/2, dDist2/2, p3);
|
||
ads_polar(pt2, dAng2-PI/2, dDist2/2, p4);
|
||
|
||
if (!bSameEle) // 5、标高不等下,乙字弯画法由中广电提供
|
||
{
|
||
if (m_nSysDrawMod != 3) // 绘制中心线
|
||
{
|
||
DList<XCurveSegment> midSegs;
|
||
BuildSegs1(pt1, pt2, midSegs);
|
||
|
||
if (m_nSysDrawMod == 1) // 单线图
|
||
{
|
||
DrawXiSegs(dc, midSegs);
|
||
return Acad::eOk;
|
||
}
|
||
DrawMidSegs(dc, midSegs); // 三线图
|
||
}
|
||
|
||
BuildSegs1(p1, p4, lstSeg);
|
||
BuildSegs1(p2, p3, lstSeg);
|
||
Draw2DSegs(dc, lstSeg); // 绘制边线
|
||
|
||
double dEle1 = pts[0]->z, // 标高
|
||
dEle2 = pts[1]->z;
|
||
dAng1 = CT_std_angle(dAng1); // 将角度调整到0到2PI范围内
|
||
dAng2 = CT_std_angle(dAng2);
|
||
double dAngle = dAng1 - dAng2;
|
||
if (((dEle1>dEle2)&&(dAngle>1.0E-5)) || ((dEle1<dEle2)&&(dAngle<1.0E-5)))
|
||
{
|
||
ads_polar(p2, dAng1+PI/2, dDist1/8, ptTmp1); // 2-->4
|
||
ads_polar(p4, dAng2+PI/2, dDist2/8, ptTmp3);
|
||
}
|
||
else // 1-->3
|
||
{
|
||
ads_polar(p1, dAng1-PI/2, dDist1/8, ptTmp1);
|
||
ads_polar(p3, dAng2-PI/2, dDist2/8, ptTmp3);
|
||
}
|
||
|
||
ads_polar(ptTmp1, dAng1, -dLen*0.05, ptTmp1);
|
||
ads_polar(ptTmp1, dAng1, -dLen*0.15, ptTmp2);
|
||
ads_polar(ptTmp3, dAng2, -dLen*0.05, ptTmp3);
|
||
ads_polar(ptTmp3, dAng2, -dLen*0.15, ptTmp4);
|
||
|
||
lstSeg.Reset();
|
||
BuildSegs6(ptTmp1, ptTmp2, ptTmp4, ptTmp3, lstSeg);
|
||
DrawFLSegs(dc, lstSeg); // 绘制
|
||
return Acad::eOk;
|
||
}
|
||
|
||
XVector3D vt1 = GetIDirection(0),
|
||
vt2 = GetIDirection(1);
|
||
XVector3D vtMid1(vt1), vtMid2(vt2); // 6、获取中线圆心方向
|
||
XCurveSegment seg1(pt1, XPoint(pt1+vt1), 0, LS_INFINITE),
|
||
seg2(pt2, XPoint(pt2+vt2), 0, LS_INFINITE);
|
||
XPoint ptPro1, ptPro2;
|
||
seg2.ProjectToMe(pt1, ptPro1);
|
||
seg1.ProjectToMe(pt2, ptPro2);
|
||
vtMid1 = ptPro1 - pt1;
|
||
vtMid2 = ptPro2 - pt2;
|
||
|
||
double dDistM = (dDist1+dDist2)/2.0;
|
||
double dRadius1 = (dLen*0.25)/sin(m_dDrawParam/2), // 中线圆半径
|
||
dRadius2 = dRadius1;
|
||
if (m_nDrawMod == 1) // 斜接样式
|
||
{
|
||
dRadius1 = dDist1*m_dDrawParam2 - (dThick1*0.5)/tan(m_dDrawParam/2);
|
||
dRadius2 = dDist2*m_dDrawParam2 - (dThick2*0.5)/tan(m_dDrawParam/2);
|
||
}
|
||
|
||
vtMid1.Normalize();
|
||
vtMid2.Normalize();
|
||
vtMid1.Scale(dRadius1);
|
||
vtMid2.Scale(dRadius2);
|
||
XPoint ptCen1 = pt1 + vtMid1, // 7、获取圆心点
|
||
ptCen2 = pt2 + vtMid2;
|
||
ptCen1.z = ptCen2.z = 0;
|
||
XPoint ptLoc = GetZeroPt();
|
||
|
||
XCurveSegment seg;
|
||
double dNewAng1(0), dNewAng2(0);
|
||
if (m_nSysDrawMod != 3) // 8、绘制中心线
|
||
{
|
||
DList<XCurveSegment> midSegs;
|
||
if (m_nDrawMod == 1) // 斜接样式
|
||
{
|
||
ptTmp1 = GetArcPts(pt1, dRadius1, dAng1, pt2, midSegs, dNewAng1);
|
||
ptTmp2 = GetArcPts(pt2, dRadius2, dAng2, pt1, midSegs, dNewAng2);
|
||
ads_polar(ptTmp1, dNewAng1, dThick1, ptTmp3);
|
||
ads_polar(ptTmp2, dNewAng2, dThick2, ptTmp4);
|
||
BuildSegs1(ptTmp3, ptTmp4, midSegs);
|
||
}
|
||
else // 双弧样式
|
||
{
|
||
seg = ::GetArcSeg1(pt1, ptCen1, ptLoc, dDist1, dDistM);
|
||
midSegs.Append(new XCurveSegment(seg));
|
||
seg = ::GetArcSeg1(pt2, ptCen2, ptLoc, dDist2, dDistM);
|
||
midSegs.Append(new XCurveSegment(seg));
|
||
}
|
||
|
||
if (m_nSysDrawMod == 1) // 单线图
|
||
{
|
||
DrawXiSegs(dc, midSegs);
|
||
return Acad::eOk;
|
||
}
|
||
DrawMidSegs(dc, midSegs); // 三线图
|
||
}
|
||
|
||
XPoint ptNear1 = ::GetNearPt(ptCen1, p1, p2),
|
||
ptNear2 = ::GetNearPt(ptCen2, p3, p4),
|
||
ptFar1 = ::GetFarPt(ptCen1, p1, p2),
|
||
ptFar2 = ::GetFarPt(ptCen2, p3, p4);
|
||
if (m_nDrawMod == 1) // 斜接样式
|
||
{
|
||
DList<XCurveSegment> segs;
|
||
ptTmp1 = GetArcPts(pt1, dRadius1, dAng1, pt2, segs, dNewAng1);
|
||
ptTmp2 = GetArcPts(pt2, dRadius2, dAng2, pt1, segs, dNewAng2);
|
||
ads_polar(ptTmp1, dNewAng1, dThick1*0.5, ptTmp3); // 中间法兰位置点
|
||
ads_polar(ptTmp2, dNewAng2, dThick2*0.5, ptTmp4);
|
||
DrawFlange(lstSeg, ptTmp3, dNewAng1, dFlDia1, dThick1);
|
||
DrawFlange(lstSeg, ptTmp4, dNewAng2, dFlDia2, dThick2);
|
||
DrawFLSegs(dc, lstSeg); // 绘制法兰
|
||
|
||
lstSeg.Reset();
|
||
pt2.Mirror(ptCen2, ptTmp3);
|
||
ptTmp1 = GetArcPts(ptNear1, (dRadius1-dDist1*0.5), dAng1, ptTmp3, lstSeg, dNewAng1);
|
||
ptTmp2 = GetArcPts(ptFar2, (dRadius2+dDist2*0.5), dAng2, pt1, lstSeg, dNewAng2);
|
||
ads_polar(ptTmp1, dNewAng1, dThick1, ptTmp3);
|
||
ads_polar(ptTmp2, dNewAng2, dThick2, ptTmp4);
|
||
BuildSegs1(ptTmp3, ptTmp4, lstSeg);
|
||
|
||
pt1.Mirror(ptCen1, ptTmp3);
|
||
ptTmp1 = GetArcPts(ptFar1, (dRadius1+dDist1*0.5), dAng1, pt2, lstSeg, dNewAng1);
|
||
ptTmp2 = GetArcPts(ptNear2, (dRadius2-dDist2*0.5), dAng2, ptTmp3, lstSeg, dNewAng2);
|
||
ads_polar(ptTmp1, dNewAng1, dThick1, ptTmp3);
|
||
ads_polar(ptTmp2, dNewAng2, dThick2, ptTmp4);
|
||
BuildSegs1(ptTmp3, ptTmp4, lstSeg);
|
||
Draw2DSegs(dc, lstSeg); // 绘制边线
|
||
return Acad::eOk;
|
||
}
|
||
|
||
vtMid1 = ptCen1 - ptLoc;
|
||
vtMid2 = ptCen2 - ptLoc;
|
||
vtMid1.Normalize();
|
||
vtMid2.Normalize();
|
||
vtMid1.Scale(dDistM/2);
|
||
vtMid2.Scale(dDistM/2);
|
||
XPoint pt5 = ptLoc + vtMid1,
|
||
pt6 = ptLoc + vtMid2;
|
||
|
||
seg = ::GetArcSeg1(ptNear1, ptCen1, pt5, dDist1, dDistM);
|
||
lstSeg.Append(new XCurveSegment(seg));
|
||
seg = ::GetArcSeg1(ptFar1, ptCen1, pt6, dDist1, dDistM);
|
||
lstSeg.Append(new XCurveSegment(seg));
|
||
seg = ::GetArcSeg1(ptNear2, ptCen2, pt6, dDist2, dDistM);
|
||
lstSeg.Append(new XCurveSegment(seg));
|
||
seg = ::GetArcSeg1(ptFar2, ptCen2, pt5, dDist2, dDistM);
|
||
lstSeg.Append(new XCurveSegment(seg));
|
||
Draw2DSegs(dc, lstSeg); // 绘制边线
|
||
return Acad::eOk;
|
||
}
|
||
|
||
|
||
////////////////////////////掏洞////////////////////////////
|
||
Acad::ErrorStatus TDbDuctNode::DrawTaoDong2D(XExplodeDraw &dc) const
|
||
{
|
||
if (GetInterfaceNum() != 2) // 1、保证所有的链表不越界
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
XPointList pts;
|
||
GetPtsIFace(pts, FALSE, FALSE, FALSE, TRUE); // 法兰遮挡后的连接点
|
||
if (pts.Length() != 2) // 2、获取与管线相连点
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
int nB = 1 - m_nMain; // 支管
|
||
DList<XCurveSegment> midSegs, lstSeg;
|
||
if (m_nSysDrawMod != 3) // 3、除双线图外,绘制中心线
|
||
{
|
||
XPoint ptLoc = GetZeroPt(); // 将绘制标高变为0
|
||
BuildSegs1(*pts[nB], ptLoc, midSegs);
|
||
if (m_nSysDrawMod == 1)
|
||
{
|
||
DrawXiSegs(dc, midSegs); // 单线图,细线绘制
|
||
return Acad::eOk;
|
||
}
|
||
DrawMidSegs(dc, midSegs); // 三线图,切换中心线图层、线型绘制
|
||
}
|
||
|
||
if (m_nDrawMod == 13) // 4、样式13只绘制中心线
|
||
{
|
||
return Acad::eOk;
|
||
}
|
||
|
||
XPoint ptM(*pts[m_nMain]), ptM2;
|
||
ads_polar(ptM, GetIAngle(m_nMain), -10000, ptM2);
|
||
XCurveSegment mSeg(ptM, ptM2, 0, LS_INFINITE); // 主管中心线
|
||
|
||
XPoint ptB(*pts[nB]), ptB1(*pts[nB]), ptB2, ptBTmp;
|
||
mSeg.ProjectToMe(ptB, ptBTmp);
|
||
XVector3D vtTmp = ptB - ptBTmp;
|
||
vtTmp.Normalize();
|
||
vtTmp.Scale(GetIWidth(m_nMain)*0.5);
|
||
ptM = ptM + vtTmp;
|
||
ptM2 = ptM2 + vtTmp;
|
||
mSeg.SetPoints(ptM, ptM2); // 与支管连接的主管侧壁
|
||
|
||
double dBAngle = GetIAngle(nB);
|
||
ads_polar(ptB, dBAngle, 10000, ptBTmp);
|
||
XCurveSegment bSeg(ptB, ptBTmp, 0, LS_INFINITE); // 插管中心线
|
||
bSeg.ProjectToMe(ptM2, ptBTmp);
|
||
vtTmp = ptM2 - ptBTmp;
|
||
vtTmp.Normalize();
|
||
vtTmp.Scale(GetIWidth(nB)*0.5);
|
||
ptB1 = ptB + vtTmp;
|
||
ptB.Mirror(ptB1, ptB2);
|
||
ptBTmp = ptBTmp + vtTmp;
|
||
bSeg.SetPoints(ptB1, ptBTmp); // 与主管侧壁组成小弧的支管侧壁
|
||
|
||
XPoint ptInt, ptTmp, ptTmp1, ptTmp2, ptCen;
|
||
if (!mSeg.Intersection(bSeg, ptInt, ptTmp))
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
BOOL bSwitch(TRUE); // 大、小弧的优、劣是一致的
|
||
double dDist = ptInt.Distance(ptB1)*0.8;
|
||
::AT_cal_fillet(ptM2, ptInt, ptB1, dDist, ptTmp1, ptCen, ptTmp2, FALSE);
|
||
BuildSegs1(ptTmp2, ptB1, lstSeg);
|
||
XArc smallArc = ::GetRightArc(ptTmp1, ptCen, ptTmp2, bSwitch); // 选择优弧
|
||
BuildSegs4(smallArc, lstSeg); // 小弧
|
||
|
||
ads_polar(ptB2, dBAngle, -dDist*0.25, ptTmp1); // ptTmp1为大弧起点
|
||
XLine tmpL1(ptB2, ptTmp1, LS_INFINITE);
|
||
if (!mSeg.Intersection(tmpL1, ptTmp, ptTmp2)) // ptTmp为与主管侧壁交点
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
if (m_nDrawMod == 14) // 大弧线连接
|
||
{
|
||
dDist = ptCen.Distance(ptTmp1); // 大弧半径
|
||
XLine tmpL2(ptInt, ptTmp, LS_FINITE);
|
||
XCircle circle(ptCen, dDist);
|
||
if (!circle.Intersection(&tmpL2, ptTmp2, ptBTmp)) // 没有交点
|
||
{
|
||
BuildSegs1(ptB2, ptTmp, lstSeg); // 改用直线连接
|
||
}
|
||
else // 有交点则用弧线连接
|
||
{
|
||
BuildSegs1(ptB2, ptTmp1, lstSeg);
|
||
XArc bigArc = ::GetRightArc(ptTmp2, ptCen, ptTmp1, bSwitch); // 选择优弧
|
||
BuildSegs4(bigArc, lstSeg); // 小弧
|
||
}
|
||
}
|
||
else // 直线
|
||
{
|
||
BuildSegs1(ptB2, ptTmp, lstSeg);
|
||
}
|
||
Draw2DSegs(dc, lstSeg); // 绘制实线
|
||
return Acad::eOk;
|
||
}
|
||
|
||
|
||
////////////////////////////三通////////////////////////////
|
||
Acad::ErrorStatus TDbDuctNode::Draw3Corner2D(XExplodeDraw &dc) const
|
||
{
|
||
if (GetInterfaceNum() != 3) // 1 、保证所有的链表不越界
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
XPointList pts, pt0s;
|
||
GetPtsIFace(pts, FALSE, FALSE, FALSE, FALSE);
|
||
GetPtsIFace(pt0s, FALSE, FALSE, FALSE, TRUE);
|
||
if ((pts.Length() != 3) || (pt0s.Length() != 3))
|
||
{
|
||
return Acad::eInvalidInput; // 2、获取法兰遮挡后与管线相连点
|
||
}
|
||
|
||
DList<AcDbObjectId> linkIds;
|
||
GetAllLinkDucts(linkIds);
|
||
AcGeIntArray types = GetAllTypes();
|
||
|
||
int nVDuct1(-1), nVDuct2(-1); // 3、判断是否有立管
|
||
::Get3TVDuctNums(objectId(), linkIds, types, nVDuct1, nVDuct2);
|
||
|
||
int nDrawMod(m_nDrawMod); // 绘制样式,会自动调整
|
||
if (m_nSysDrawMod != 3) // 4、除双线外,绘制中心线
|
||
{
|
||
BOOL bFlag(TRUE);
|
||
DList<XCurveSegment> midSegs;
|
||
if ((nVDuct1 == -1) && (nVDuct2 == 1)) // 不带立管,根据绘制样式绘制
|
||
{
|
||
bFlag = FALSE;
|
||
int nO1(-1), nO2(-1), nTmp(5); // 获取支管标号
|
||
::GetAnotherPipe(m_nMain, nO1, nO2, nTmp);
|
||
|
||
double dTmpAng(0);
|
||
XPoint ptNew1, ptNew2, ptTmp(*pt0s[m_nMain]);
|
||
switch(m_nDrawMod)
|
||
{
|
||
case 6: // 平行型
|
||
BuildSegs2(*pt0s[nO2], ptTmp, *pt0s[nO1], midSegs);
|
||
break;
|
||
case 9:
|
||
case 10: // 斜插型
|
||
{
|
||
nTmp = ::IsParallel(GetIDirection(m_nMain),
|
||
GetIDirection(nO1))?nO2:nO1; // 获取不平行管线
|
||
AcGeVector3d vtM = GetIDirection(m_nMain).AsAcGeVector3d()*(-1),
|
||
vtT = GetIDirection(nTmp).AsAcGeVector3d();
|
||
double dCurrent = vtM.angleTo(vtT);
|
||
if ((dCurrent<PI*4/9-1.0E-5) || (dCurrent>PI*11/18+1.0E-5))
|
||
{
|
||
bFlag = TRUE;
|
||
nDrawMod = 7; // 不满足样式9/10的要求,自动修改绘制样式
|
||
}
|
||
else // 按照样式9或10绘制
|
||
{
|
||
ptNew1 = GetArcPts(*pt0s[nTmp], GetIWidth(nTmp), // 法兰点
|
||
GetIAngle(nTmp), ptTmp, midSegs, dTmpAng);
|
||
nTmp = nTmp==nO1?nO2:nO1; // 与主风管平行
|
||
BuildSegs2(ptNew1, ptTmp, *pt0s[nTmp], midSegs);
|
||
}
|
||
}
|
||
break;
|
||
case 11: // 叉型
|
||
ptNew1 = GetArcPts(*pt0s[nO1], GetIWidth(nO1), GetIAngle(nO1),
|
||
ptTmp, midSegs, dTmpAng); // 法兰点1
|
||
ptNew2 = GetArcPts(*pt0s[nO2], GetIWidth(nO2), GetIAngle(nO2),
|
||
ptTmp, midSegs, dTmpAng); // 法兰点2
|
||
BuildSegs2(ptNew2, ptTmp, ptNew1, midSegs);
|
||
break;
|
||
case 12:
|
||
ptNew1 = GetYTopPt(ptTmp);
|
||
Midpoint(ptNew1, ptTmp, ptNew2);
|
||
BuildSegs1(ptTmp, ptNew1, midSegs);
|
||
BuildSegs2(*pt0s[nO1], ptNew2, *pt0s[nO2], midSegs);
|
||
break;
|
||
default: // 其他
|
||
bFlag = TRUE;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (bFlag) // 除特殊样式外,其他都按标准样式绘制中心线
|
||
{
|
||
XPoint ptLoc = GetZeroPt();
|
||
for (int i=0; i<3; i++)
|
||
{
|
||
BuildSegs1(ptLoc, *pt0s[i], midSegs);
|
||
}
|
||
}
|
||
|
||
if (m_nSysDrawMod == 1)
|
||
{
|
||
DrawXiSegs(dc, midSegs); // 单线图
|
||
return Acad::eOk;
|
||
}
|
||
DrawMidSegs(dc, midSegs); // 三线图
|
||
}
|
||
|
||
DList<XCurveSegment> lstSeg;
|
||
if ((nVDuct1>-1) && (nVDuct2>-1)) // 5、连接了两根立管
|
||
{
|
||
int nHDuct(0), nTmp(5); // 获取水平管编号
|
||
::GetAnotherPipe(nVDuct1, nVDuct2, nHDuct, nTmp);
|
||
|
||
XPoint ptVDTmp;
|
||
nTmp = (pts[nVDuct1]->z>(pts[nVDuct2]->z+1.0E-6))?nVDuct1:nVDuct2;
|
||
if (DrawUpKElbow2D1(lstSeg, nTmp, nHDuct, *pts[nHDuct], ptVDTmp, TRUE))
|
||
{
|
||
Draw2DSegs(dc, lstSeg); // 按照无下弯头的上弯头绘制
|
||
return Acad::eOk;
|
||
}
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
if (nVDuct1 > -1) // 6、连接了一根立管
|
||
{
|
||
int nHDuct1(-1), nHDuct2(-1), nTmp(5);
|
||
::GetAnotherPipe(nVDuct1, nHDuct1, nHDuct2, nTmp); // 获取水平管编号
|
||
|
||
XPoint pt1, pt2, pt3, pt4, pt5, pt6;
|
||
double dAng1 = GetIAngle(nHDuct1),
|
||
dAng2 = GetIAngle(nHDuct2);
|
||
ads_polar(*pt0s[nHDuct1], dAng1+PI/2, GetIWidth(nHDuct1)/2, pt1);
|
||
ads_polar(*pt0s[nHDuct1], dAng1-PI/2, GetIWidth(nHDuct1)/2, pt2);
|
||
ads_polar(*pt0s[nHDuct2], dAng2+PI/2, GetIWidth(nHDuct2)/2, pt3);
|
||
ads_polar(*pt0s[nHDuct2], dAng2-PI/2, GetIWidth(nHDuct2)/2, pt4);
|
||
|
||
XVector3D vtOpen;
|
||
double dUpDuctWidth(0);
|
||
BOOL bHasLowElbow(FALSE);
|
||
OPENOBJ_BEGIN(GetIPipe(nVDuct1), AcDb::kForRead, TDbDuct, pDuct);
|
||
if (pDuct != NULL)
|
||
{
|
||
AcDbObjectId upNodeId = pDuct->GetVerUpNode(); // 立管上节点
|
||
if (upNodeId != objectId())
|
||
{
|
||
bHasLowElbow = pDuct->IsUpPipesOk();
|
||
if (bHasLowElbow)
|
||
{
|
||
pDuct->GetVerOpenDir(vtOpen);
|
||
AcGeDoubleArray tmpWidths = pDuct->GetUpPipesWidth();
|
||
dUpDuctWidth = tmpWidths[0];
|
||
}
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
|
||
if (bHasLowElbow && fabs(dAng1-dAng2)<(PI+1.0E-6)) // 有下弯头,且平行
|
||
{
|
||
AcGeVector3d vecOpen = vtOpen.AsAcGeVector3d(),
|
||
vecHDuct1 = GetIDirection(nHDuct1).AsAcGeVector3d();
|
||
double dAngle = vecHDuct1.angleTo(vecOpen, AcGeVector3d::kZAxis),
|
||
dDist = (pt1.Distance(pt4)-dUpDuctWidth)*0.5;
|
||
if (dAngle>(PI+1.0E-6) && dAngle<(2*PI-1.0E-6))
|
||
{
|
||
ads_polar(pt2, dAng1, -dDist, pt5);
|
||
ads_polar(pt3, dAng2, -dDist, pt6);
|
||
BuildSegs1(pt2, pt5, lstSeg);
|
||
BuildSegs1(pt3, pt6, lstSeg);
|
||
BuildSegs1(pt1, pt4, lstSeg);
|
||
}
|
||
else
|
||
{
|
||
ads_polar(pt1, dAng1, -dDist, pt5);
|
||
ads_polar(pt4, dAng2, -dDist, pt6);
|
||
BuildSegs1(pt2, pt3, lstSeg);
|
||
BuildSegs1(pt1, pt5, lstSeg);
|
||
BuildSegs1(pt6, pt4, lstSeg);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
BuildSegs1(pt1, pt4, lstSeg);
|
||
BuildSegs1(pt2, pt3, lstSeg);
|
||
}
|
||
Draw2DSegs(dc, lstSeg); // 绘制
|
||
return Acad::eOk;
|
||
}
|
||
|
||
XPointList lstMids;
|
||
GetTrueMidPts(lstMids);
|
||
AcDbIntArray branchs = GetBranchNums(m_nMain); // 7、获取支管编号和位置点偏移
|
||
if (branchs.logicalLength()!=2 || lstMids.Length()!=3)
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
AcDbIntArray idxs(branchs);
|
||
idxs.insertAt(0, m_nMain);
|
||
|
||
XPointList ptLst;
|
||
DList<XLine> lstLine;
|
||
for (int j=0; j<idxs.logicalLength(); j++) // 8、计算其他需要的点和线
|
||
{
|
||
int nTmp = idxs[j];
|
||
XLine line(LS_FINITE); // 注:线与点的角标是对应的
|
||
line = XLine(*lstMids[nTmp], *pt0s[nTmp]).Offset(-GetIWidth(nTmp)/2);
|
||
ptLst.Append(new XPoint(line.EndPoint()));
|
||
lstLine.Append(new XLine(line));
|
||
line = XLine(*lstMids[nTmp], *pt0s[nTmp]).Offset(GetIWidth(nTmp)/2);
|
||
ptLst.Append(new XPoint(line.EndPoint()));
|
||
lstLine.Append(new XLine(line));
|
||
}
|
||
if (lstLine.Length()!=6 || ptLst.Length()!=6)
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
BOOL bIsOk(TRUE);
|
||
DList<XCurveSegment> flSegs;
|
||
switch(nDrawMod) { // 9、根据连接管线的不同情况,绘制不同的样式
|
||
case 0: // 普通三通
|
||
case 1: // 直角三通
|
||
bIsOk = DrawRandom3T(lstSeg, ptLst, lstLine, branchs[1]);
|
||
break;
|
||
case 2: // 圆角三通
|
||
bIsOk = DrawCAngle3T(pt0s, lstSeg, ptLst, branchs[1]);
|
||
break;
|
||
case 3: // 承插三通
|
||
bIsOk = DrawInsert3T(lstSeg, ptLst, lstLine, branchs[1]);
|
||
break;
|
||
case 4: // Y型三通
|
||
case 5: // T型三通
|
||
bIsOk = DrawY3T(pt0s, lstSeg, ptLst, branchs[1]);
|
||
break;
|
||
case 6: // 平行三通
|
||
bIsOk = DrawParall3T(pt0s, lstSeg, ptLst, branchs[1]);
|
||
break;
|
||
case 7: // 圆管三通
|
||
case 8:
|
||
bIsOk = DrawCircle3T(lstSeg, ptLst, lstLine, branchs[1]);
|
||
break;
|
||
case 9: // 斜插三通
|
||
case 10:
|
||
bIsOk = DrawXieInsert3T(pt0s, lstSeg, ptLst, branchs[1], flSegs);
|
||
break;
|
||
case 11: // 叉型三通
|
||
bIsOk = DrawAcross3T(pt0s, lstSeg, ptLst, branchs[1], flSegs);
|
||
break;
|
||
case 12: // 样式12三通
|
||
bIsOk = Draw12Mod3T(pt0s, lstSeg, ptLst, branchs[1]);
|
||
break;
|
||
}
|
||
|
||
if (!bIsOk)
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
Draw2DSegs(dc, lstSeg); // 10、绘制
|
||
DrawFLSegs(dc, flSegs);
|
||
return Acad::eOk;
|
||
}
|
||
|
||
// 绘制3D调节阀,注:目前只在样式0到2中可以绘制
|
||
BOOL TDbDuctNode::DrawValve(XPoint pt, int nB, DList<XCurveSegment> &segs) const
|
||
{
|
||
if (!m_bValue)
|
||
{
|
||
return TRUE;
|
||
}
|
||
|
||
XPoint ptRet;
|
||
double dAngMain = GetIAngle(m_nMain), // 主风方向
|
||
dAngB = GetIAngle(nB);
|
||
double dDist = GetIWidth(nB) * 0.7;
|
||
ads_polar(pt, dAngMain, dDist, ptRet);
|
||
ads_polar(ptRet, dAngB, -dDist, ptRet);
|
||
BuildSegs1(pt, ptRet, segs);
|
||
return TRUE;
|
||
}
|
||
|
||
// 普通三通、直角三通
|
||
BOOL TDbDuctNode::DrawRandom3T(DList<XCurveSegment> &segs, const XPointList &pts,
|
||
const DList<XLine> &llst, int nB2) const
|
||
{
|
||
XPoint ptInt;
|
||
if (!llst[5].Intersection(&llst[2], ptInt))
|
||
{
|
||
return FALSE;
|
||
}
|
||
BuildSegs2(pts[5], ptInt, pts[2], segs);
|
||
|
||
int nB1(-1), nTmp1(nB2), nTmp2(5);
|
||
::GetAnotherPipe(m_nMain, nTmp1, nB1, nTmp2);
|
||
XVector3D vt1 = GetIDirection(m_nMain),
|
||
vt2 = GetIDirection(nB2);
|
||
if (::IsParallel(vt1, vt2) != 0) // 平行或相反
|
||
{
|
||
DrawValve(ptInt, nB1, segs);
|
||
BuildSegs1(pts[1], pts[4], segs);
|
||
if (m_nDrawMod == 0) // 普通三通
|
||
{
|
||
if (!llst[0].Intersection(&llst[3], ptInt))
|
||
{
|
||
return FALSE;
|
||
}
|
||
BuildSegs2(pts[0], ptInt, pts[3], segs);
|
||
return TRUE;
|
||
}
|
||
return DrawLine(segs, llst[0], llst[3], 1);
|
||
}
|
||
|
||
XVector3D vt3 = GetIDirection(nB1);
|
||
if (::IsParallel(vt1, vt3) != 0) // 平行或相反
|
||
{
|
||
DrawValve(ptInt, nB2, segs);
|
||
BuildSegs1(pts[0], pts[3], segs);
|
||
if (m_nDrawMod == 1) // 直角三通
|
||
{
|
||
return DrawLine(segs, llst[1], llst[4], 1);
|
||
}
|
||
}
|
||
else // 都不平行,交于一点的情况,不绘制调节阀
|
||
{
|
||
if (m_nDrawMod == 1) // 直角三通
|
||
{
|
||
BuildSegs1(pts[1], pts[4], segs);
|
||
return DrawLine(segs, llst[0], llst[3], 1);
|
||
}
|
||
llst[3].Intersection(&llst[0], ptInt);
|
||
BuildSegs2(pts[0], ptInt, pts[3], segs);
|
||
}
|
||
|
||
if (!llst[1].Intersection(&llst[4], ptInt))
|
||
{
|
||
return FALSE;
|
||
}
|
||
BuildSegs2(pts[1], ptInt, pts[4], segs);
|
||
return TRUE;
|
||
}
|
||
|
||
// 圆角三通
|
||
BOOL TDbDuctNode::DrawCAngle3T(const XPointList &pts, DList<XCurveSegment> &segs,
|
||
const XPointList &ptLst, int nB2) const
|
||
{
|
||
int nB1(-1), n(5);
|
||
::GetAnotherPipe(m_nMain, nB2, nB1, n);
|
||
XVector3D vt1 = GetIDirection(m_nMain),
|
||
vt2 = GetIDirection(nB2);
|
||
int nTmp = (::IsParallel(vt1, vt2)!=0)?nB1:nB2; // 与主管不平行管线
|
||
n = (nTmp==nB1)?0:1; // 选择nums中的第几组
|
||
int nB = (n==0)?nB2:nB1; // 与主管平行
|
||
double dTmp = (n==0)?(-PI/2):(PI/2);
|
||
|
||
int nums[2][6] = {{1, 4, 0, 3, 2, 5}, {0, 3, 1, 4, 5, 2}}; // 统一代码使用
|
||
BuildSegs1(ptLst[nums[n][0]], ptLst[nums[n][1]], segs);
|
||
if (!DrawArc(segs, pts[m_nMain], pts[nTmp], ptLst[nums[n][2]], ptLst[nums[n][3]]))
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
XPoint ptCen, ptInt1, ptInt2, ptTmp, ptNear;
|
||
XLine line1(ptLst[nums[n][0]], ptLst[nums[n][2]], LS_INFINITE),
|
||
line2(ptLst[nums[n][4]], ptLst[nums[n][3]], LS_INFINITE);
|
||
if (!line1.Intersection(&line2, ptCen))
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
BOOL bSwitch(FALSE);
|
||
double dAngMain = GetIAngle(m_nMain); // 管线法向
|
||
double dRadius = ptLst[nums[n][4]].Distance(ptCen),
|
||
dDist = ptLst[nums[n][2]].Distance(ptLst[nums[n][5]]);
|
||
ads_polar(ptCen, dAngMain+dTmp, dRadius, ptTmp);
|
||
XArc arc = ::GetRightArc(ptTmp, ptCen, ptLst[nums[n][4]], bSwitch); // 选择优弧
|
||
|
||
ads_polar(ptLst[nums[n][5]], GetIAngle(nB), -dDist, ptTmp);
|
||
XLine lineTmp(ptTmp, ptLst[nums[n][5]], LS_FINITE);
|
||
if (!arc.Intersection(&lineTmp, ptInt1, ptInt2))
|
||
{
|
||
ads_polar(ptLst[nums[n][4]], GetIAngle(nTmp), -dDist, ptTmp);
|
||
XLine lineTmp(ptLst[nums[n][4]], ptTmp);
|
||
if (!lineTmp.Intersection(&lineTmp, ptNear))
|
||
{
|
||
return FALSE;
|
||
}
|
||
ads_polar(ptNear, GetIAngle(nB), -100, ptNear);
|
||
BuildSegs1(ptNear, ptLst[nums[n][4]], segs);
|
||
}
|
||
else
|
||
{
|
||
ptNear = ::GetNearPt(ptLst[nums[n][5]], ptInt1, ptInt2);
|
||
if (bSwitch)
|
||
{
|
||
arc.SetAngleByPoints(ptNear, ptLst[nums[n][4]]);
|
||
}
|
||
else
|
||
{
|
||
arc.SetAngleByPoints(ptLst[nums[n][4]], ptNear);
|
||
}
|
||
BuildSegs4(arc, segs);
|
||
}
|
||
BuildSegs1(ptNear, ptLst[nums[n][5]], segs);
|
||
DrawValve(ptNear, nTmp, segs);
|
||
return TRUE;
|
||
}
|
||
|
||
// 承插三通
|
||
BOOL TDbDuctNode::DrawInsert3T(DList<XCurveSegment> &segs, const XPointList &pts,
|
||
const DList<XLine> &llst, int nB2) const
|
||
{
|
||
int nB1(-1), n(5);
|
||
::GetAnotherPipe(m_nMain, nB2, nB1, n);
|
||
XVector3D vt1 = GetIDirection(m_nMain),
|
||
vt2 = GetIDirection(nB2);
|
||
int nTmp = (::IsParallel(vt1, vt2)!=0)?nB1:nB2;
|
||
n = (nTmp==nB1)?0:1;
|
||
|
||
int nums[2][6] = {{1, 4, 0, 3, 5, 2}, {0, 3, 1, 4, 2, 5}}; // 统一代码使用
|
||
BuildSegs1(pts[nums[n][0]], pts[nums[n][1]], segs);
|
||
if (!DrawLine(segs, llst[nums[n][2]], llst[nums[n][3]], 1))
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
XPoint ptInt1, ptInt2;
|
||
ads_polar(pts[nums[n][2]], GetIAngle(m_nMain), -50, ptInt1);
|
||
BuildSegs1(ptInt1, pts[nums[n][4]], segs);
|
||
XLine line(ptInt1, pts[nums[n][4]], LS_INFINITE);
|
||
if (!llst[nums[n][5]].Intersection(&line, ptInt2))
|
||
{
|
||
return FALSE;
|
||
}
|
||
BuildSegs1(pts[nums[n][5]], ptInt2, segs);
|
||
return TRUE;
|
||
}
|
||
|
||
// 获取Y型、15样式三通中,顶点位置
|
||
XPoint TDbDuctNode::GetYTopPt(XPoint ptOld) const
|
||
{
|
||
XPointList pt0s;
|
||
GetPtsIFace(pt0s, FALSE, FALSE, FALSE, TRUE);
|
||
if (pt0s.Length() != 3)
|
||
{
|
||
return XPoint();
|
||
}
|
||
|
||
int nNum1(-1), nNum2(-1), nTmp(5);
|
||
XPoint ptTmp1, ptTmp2, ptTmp3, ptInt1, ptInt2;
|
||
::GetAnotherPipe(m_nMain, nNum1, nNum2, nTmp);
|
||
ads_polar(ptOld, GetIAngle(m_nMain), -1000, ptTmp1);
|
||
ads_polar(*pt0s[nNum1], GetIAngle(nNum1), -1000, ptTmp2);
|
||
ads_polar(*pt0s[nNum2], GetIAngle(nNum2), -1000, ptTmp3);
|
||
XLine l1(ptOld, ptTmp1, LS_INFINITE),
|
||
l2(*pt0s[nNum1], ptTmp2, LS_INFINITE),
|
||
l3(*pt0s[nNum2], ptTmp3, LS_INFINITE);
|
||
if (!l1.Intersection(&l2, ptInt1) || !l1.Intersection(&l3, ptInt2))
|
||
{
|
||
return XPoint();
|
||
}
|
||
|
||
ads_polar(ptInt1, GetIAngle(m_nMain), -0.25*GetIWidth(nNum1), ptInt1);
|
||
ads_polar(ptInt2, GetIAngle(m_nMain), -0.25*GetIWidth(nNum2), ptInt2);
|
||
ptTmp1 = ::GetNearPt(ptOld, ptInt1, ptInt2);
|
||
return ptTmp1;
|
||
}
|
||
|
||
// Y型、T型三通
|
||
BOOL TDbDuctNode::DrawY3T(const XPointList &pts, DList<XCurveSegment> &lstSeg,
|
||
const XPointList &ptLst, int nB2) const
|
||
{
|
||
int nB1(-1), n(5);
|
||
::GetAnotherPipe(m_nMain, nB2, nB1, n);
|
||
if (!DrawArc(lstSeg, pts[m_nMain], pts[nB1], ptLst[0], ptLst[3]))
|
||
{
|
||
return FALSE; // 绘制两小圆弧
|
||
}
|
||
if (!DrawArc(lstSeg, pts[m_nMain], pts[nB2], ptLst[1], ptLst[4]))
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
if (m_nDrawMod == 5) // T型三通
|
||
{
|
||
BuildSegs1(ptLst[5], ptLst[2], lstSeg);
|
||
return TRUE;
|
||
}
|
||
|
||
XPoint ptOffset; // 偏移后,主风管中线位置
|
||
double dAngMain = GetIAngle(m_nMain), // 主风管法向
|
||
dWidthM = GetIWidth(m_nMain), // 管线宽度
|
||
dWidth1 = GetIWidth(nB1),
|
||
dWidth2 = GetIWidth(nB2);
|
||
double dScale = dWidth2/(dWidth1+dWidth2); // 注:按支管管径比例偏移主风管中线
|
||
ads_polar(ptLst[1], dAngMain+PI/2, dWidthM*dScale, ptOffset);
|
||
XPoint ptYInt = GetYTopPt(ptOffset); // Y型中,两大弧交点
|
||
|
||
XPoint ptMid1, ptMid2, ptCen1, ptCen2, ptTmp;
|
||
Midpoint(ptYInt, ptLst[5], ptMid1); // 中点
|
||
Midpoint(ptYInt, ptLst[2], ptMid2);
|
||
|
||
XVector3D vtTmp = ptLst[5] - ptYInt;
|
||
double dAngle = ads_angle(XPoint(), vtTmp);
|
||
ads_polar(ptMid1, dAngle+PI/2, dWidth1, ptTmp);
|
||
XLine line1(ptTmp, ptMid1, LS_INFINITE),
|
||
line2(ptLst[5], ptLst[4], LS_INFINITE);
|
||
if (!line1.Intersection(&line2, ptCen1))
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
vtTmp = ptLst[2] - ptYInt;
|
||
dAngle = ads_angle(XPoint(), vtTmp);
|
||
ads_polar(ptMid2, dAngle-PI/2, dWidth2, ptTmp);
|
||
line1.SetPoints(ptTmp, ptMid2);
|
||
line2.SetPoints(ptLst[2], ptLst[3]);
|
||
if (!line1.Intersection(&line2, ptCen2))
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
BOOL bSwitch(TRUE);
|
||
XArc arc = ::GetRightArc(ptLst[5], ptCen1, ptYInt, bSwitch);
|
||
BuildSegs4(arc, lstSeg);
|
||
arc = ::GetRightArc(ptLst[2], ptCen2, ptYInt, bSwitch);
|
||
BuildSegs4(arc, lstSeg);
|
||
return TRUE;
|
||
}
|
||
|
||
// 第12种样式三通
|
||
BOOL TDbDuctNode::Draw12Mod3T(const XPointList &pts, DList<XCurveSegment> &lstSeg,
|
||
const XPointList &ptLst, int nB2) const
|
||
{
|
||
int nB1(-1), nTmp(5);
|
||
::GetAnotherPipe(m_nMain, nB2, nB1, nTmp);
|
||
|
||
XPointList newPts;
|
||
for (int i=0; i<6; i++)
|
||
{
|
||
nTmp = (i<2)?m_nMain:nB1;
|
||
nTmp = (i<4)?nTmp:nB2;
|
||
XPoint ptTmp;
|
||
ads_polar(ptLst[i], GetIAngle(nTmp), -100, ptTmp);
|
||
BuildSegs1(ptLst[i], ptTmp, lstSeg);
|
||
newPts.Append(new XPoint(ptTmp));
|
||
}
|
||
if (newPts.Length() != 6)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
XPoint ptYInt = GetYTopPt(pts[m_nMain]); // Y型顶点
|
||
BuildSegs6(*newPts[2], *newPts[3], *newPts[0], *newPts[1], lstSeg);
|
||
BuildSegs2(*newPts[1], *newPts[4], *newPts[5], lstSeg);
|
||
BuildSegs2(*newPts[2], ptYInt, *newPts[5], lstSeg);
|
||
return TRUE;
|
||
}
|
||
|
||
// 圆管三通
|
||
BOOL TDbDuctNode::DrawCircle3T(DList<XCurveSegment> &lstSeg, const XPointList &ptLst,
|
||
const DList<XLine> &llst, int nB2) const
|
||
{
|
||
int nP1(0), nP2(0);
|
||
BOOL bParal(FALSE); // 不含有平行管线
|
||
for (int i=0; i<3&&!bParal; i++)
|
||
{
|
||
for (int j=i+1; j<3; j++)
|
||
{
|
||
if (::IsParallel(GetIDirection(i), GetIDirection(j)) != 0)
|
||
{
|
||
nP1 = i;
|
||
nP2 = j;
|
||
bParal = TRUE; // 平行
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
nP1 = bParal?nP1:m_nMain;
|
||
nP2 = bParal?nP2:nB2;
|
||
int nOther(-1), nTmp(5); // 找到不平行管线
|
||
::GetAnotherPipe(nP1, nP2, nOther, nTmp);
|
||
|
||
XPoint ptInt1, ptInt2, ptMid;
|
||
if (nOther == m_nMain) // 圆管Y型
|
||
{
|
||
XLine l(ptLst[4], ptLst[3], LS_FINITE);
|
||
if (!llst[1].Intersection(&l, ptInt1) || !llst[0].Intersection(&l, ptInt2))
|
||
{
|
||
return FALSE;
|
||
}
|
||
BuildSegs1(ptLst[5], ptLst[2], lstSeg);
|
||
BuildSegs2(ptLst[1], ptInt1, ptLst[4], lstSeg);
|
||
BuildSegs2(ptLst[0], ptInt2, ptLst[3], lstSeg);
|
||
}
|
||
else // 圆管普通型
|
||
{
|
||
if (nOther == nB2)
|
||
{
|
||
XLine l(ptLst[2], ptLst[1], LS_FINITE);
|
||
if (!llst[5].Intersection(&l, ptInt1) || !llst[4].Intersection(&l, ptInt2))
|
||
{
|
||
return FALSE;
|
||
}
|
||
BuildSegs1(ptLst[3], ptLst[0], lstSeg);
|
||
BuildSegs2(ptLst[2], ptInt1, ptLst[5], lstSeg);
|
||
BuildSegs2(ptLst[1], ptInt2, ptLst[4], lstSeg);
|
||
}
|
||
else // 包含不含有平行管线的情况
|
||
{
|
||
XLine l(ptLst[0], ptLst[5], LS_FINITE);
|
||
if (!llst[3].Intersection(&l, ptInt1) || !llst[2].Intersection(&l, ptInt2))
|
||
{
|
||
return FALSE;
|
||
}
|
||
BuildSegs1(ptLst[1], ptLst[4], lstSeg);
|
||
BuildSegs2(ptLst[3], ptInt1, ptLst[0], lstSeg);
|
||
BuildSegs2(ptLst[2], ptInt2, ptLst[5], lstSeg);
|
||
}
|
||
}
|
||
|
||
if (m_nDrawMod == 8) // 相等的情况,样式8
|
||
{
|
||
XPoint ptLoc = GetZeroPt();
|
||
BuildSegs2(ptInt2, ptLoc, ptInt1, lstSeg);
|
||
return TRUE;
|
||
}
|
||
|
||
double dMin = min(GetIWidth(nP1), GetIWidth(nP2)) * 0.125, // 管径较小的
|
||
dAngle = ads_angle(XPoint(), XVector3D(ptInt1-ptInt2));
|
||
Midpoint(ptInt1, ptInt2, ptMid);
|
||
ads_polar(ptMid, dAngle-PI/2, dMin, ptMid); // 弧中点
|
||
|
||
XArc arc(ptInt1, ptMid, ptInt2); // 相贯线
|
||
BuildSegs4(arc, lstSeg);
|
||
return TRUE;
|
||
}
|
||
|
||
// 平行三通
|
||
BOOL TDbDuctNode::DrawParall3T(const XPointList &pts, DList<XCurveSegment> &lstSeg,
|
||
const XPointList &ptLst, int nB2) const
|
||
{
|
||
int nB1(-1), nTmp(5); // 找到支管标号
|
||
::GetAnotherPipe(m_nMain, nB2, nB1, nTmp);
|
||
BuildSegs1(ptLst[0], ptLst[3], lstSeg);
|
||
BuildSegs1(ptLst[1], ptLst[4], lstSeg);
|
||
|
||
XPoint ptTmp;
|
||
ads_polar(pts[m_nMain], GetIAngle(m_nMain)+PI/2, 1000, ptTmp);
|
||
XCurveSegment seg(pts[m_nMain], ptTmp, 0, LS_FINITE);
|
||
seg.ProjectToMe(pts[nB1], ptTmp);
|
||
double dDist = pts[nB1].Distance(ptTmp) * 0.35;
|
||
ads_polar(pts[m_nMain], GetIAngle(m_nMain), -dDist, ptTmp);
|
||
BuildSegs2(ptLst[2], ptTmp, ptLst[5], lstSeg);
|
||
return TRUE;
|
||
}
|
||
|
||
// 斜插三通
|
||
BOOL TDbDuctNode::DrawXieInsert3T(const XPointList &pts, DList<XCurveSegment> &lstSeg,
|
||
const XPointList &ptLst, int nB2,
|
||
DList<XCurveSegment> &flSegs) const
|
||
{
|
||
int nB1(-1), nTmp(5), m(5), n(0), nOther(0); // 找到支管标号
|
||
::GetAnotherPipe(m_nMain, nB2, nB1, nTmp);
|
||
nTmp = ::IsParallel(GetIDirection(m_nMain), GetIDirection(nB1))?nB2:nB1;
|
||
nOther = (nTmp==nB1)?nB2:nB1; // nOther与主管平行
|
||
m = (nTmp==nB1)?2:5; // nTmp为不平行管线,统一角标
|
||
n = (nTmp==nB1)?3:4;
|
||
|
||
double dRate(m_dDrawParam), dTmpAng(0); // 曲率半径
|
||
XPoint ptNew1 = GetArcPts(ptLst[m], GetIWidth(nTmp)*(dRate+0.5)/dRate,
|
||
GetIAngle(nTmp), pts[m_nMain], lstSeg, dTmpAng); // 大弧,绘制
|
||
XPoint ptNew2 = GetArcPts(ptLst[n], GetIWidth(nTmp)*(dRate-0.5)/dRate,
|
||
GetIAngle(nTmp), pts[m_nMain], lstSeg, dTmpAng); // 小弧,绘制
|
||
|
||
XPoint ptTmp1(ptNew1), ptTmp2(ptNew2);
|
||
::GetNewPts(ptTmp1, ptTmp2, GetIFlDist(nTmp));
|
||
BuildSegs1(ptTmp1, ptTmp2, flSegs); // 法兰绘制
|
||
|
||
DList<XCurveSegment> segs;
|
||
XPoint ptInt1(pts[m_nMain]), ptInt2(pts[nOther]), ptMid,
|
||
ptLoc = GetZeroPt();
|
||
XCurveSegment segTmp(ptInt1, ptInt2, 0, LS_FINITE);
|
||
segTmp.ProjectToMe(ptLoc, ptMid);
|
||
BOOL bFlag = (ptMid&segTmp)==PR_INSIDE;
|
||
|
||
XPoint ptNew = GetArcPts(pts[nTmp], GetIWidth(nTmp), GetIAngle(nTmp),
|
||
ptInt1, segs, dTmpAng); // 中心线,不绘制
|
||
XLine mirrorLine(ptInt1, ptNew, LS_INFINITE);
|
||
if (nOther == nB2) // 主管与支2平行
|
||
{
|
||
m = bFlag?5:4; // 和0对应
|
||
n = bFlag?4:5; // 和1对应
|
||
BuildSegs1(ptLst[1], ptLst[n], lstSeg);
|
||
XLine l(ptLst[0], ptLst[m], LS_INFINITE);
|
||
if (m_nDrawMod == 10)
|
||
{
|
||
BuildSegs1(ptLst[0], ptNew2, lstSeg);
|
||
XLine line(ptLst[0], ptNew2, LS_INFINITE);
|
||
XLine retL = ::GetMirrorLine(line, mirrorLine);
|
||
if (!retL.Intersection(&l, ptInt1))
|
||
{
|
||
return FALSE;
|
||
}
|
||
BuildSegs2(pts[m_nMain], ptInt1, ptLst[m], lstSeg);
|
||
BuildSegs1(ptInt1, ptNew1, lstSeg);
|
||
return TRUE;
|
||
}
|
||
|
||
ads_polar(ptNew, dTmpAng, 5*GetIWidth(m_nMain), ptInt1);
|
||
mirrorLine.SetPoints(ptInt1, ptNew);
|
||
XLine line1 = mirrorLine.Offset(-GetIWidth(nB1)*0.5),
|
||
line2 = mirrorLine.Offset(GetIWidth(nB1)*0.5);
|
||
if (!l.Intersection(&line1, ptInt2) || !l.Intersection(&line2, ptInt1))
|
||
{
|
||
return FALSE;
|
||
}
|
||
BuildSegs2(ptLst[0], ptInt1, ptNew2, lstSeg);
|
||
BuildSegs2(ptLst[m], ptInt2, ptNew1, lstSeg);
|
||
}
|
||
else // 主管与支1平行
|
||
{
|
||
m = bFlag?3:2; // 和0对应
|
||
n = bFlag?2:3; // 和1对应
|
||
BuildSegs1(ptLst[0], ptLst[m], lstSeg);
|
||
XLine l(ptLst[n], ptLst[1], LS_INFINITE);
|
||
if (m_nDrawMod == 10)
|
||
{
|
||
BuildSegs1(ptLst[1], ptNew2, lstSeg);
|
||
XLine line(ptLst[1], ptNew2, LS_INFINITE);
|
||
XLine retL = ::GetMirrorLine(line, mirrorLine);
|
||
if (!retL.Intersection(&l, ptInt1))
|
||
{
|
||
return FALSE;
|
||
}
|
||
BuildSegs2(pts[m_nMain], ptInt1, ptLst[n], lstSeg);
|
||
BuildSegs1(ptInt1, ptNew1, lstSeg);
|
||
return TRUE;
|
||
}
|
||
|
||
ads_polar(ptNew, dTmpAng, 5*GetIWidth(m_nMain), ptInt1);
|
||
mirrorLine.SetPoints(ptInt1, ptNew);
|
||
XLine line1 = mirrorLine.Offset(-GetIWidth(nB1)*0.5),
|
||
line2 = mirrorLine.Offset(GetIWidth(nB1)*0.5);
|
||
if (!l.Intersection(&line1, ptInt2) || !l.Intersection(&line2, ptInt1))
|
||
{
|
||
return FALSE;
|
||
}
|
||
BuildSegs2(ptLst[1], ptInt2, ptNew2, lstSeg);
|
||
BuildSegs2(ptLst[n], ptInt1, ptNew1, lstSeg);
|
||
}
|
||
|
||
m = (nTmp==nB1)?nB2:nB1;
|
||
double dMin = GetIWidth(m) * 0.125, // 管径较小的
|
||
dAngle = ads_angle(XPoint(), XVector3D(ptInt1-ptInt2));
|
||
Midpoint(ptInt1, ptInt2, ptLoc);
|
||
ads_polar(ptLoc, dAngle-PI/2, dMin, ptLoc); // 弧中点
|
||
|
||
XArc arc(ptInt1, ptLoc, ptInt2); // 相贯线
|
||
BuildSegs4(arc, lstSeg);
|
||
return TRUE;
|
||
}
|
||
|
||
// 叉型三通
|
||
BOOL TDbDuctNode::DrawAcross3T(const XPointList &pts, DList<XCurveSegment> &lstSeg,
|
||
const XPointList &ptLst, int nB2,
|
||
DList<XCurveSegment> &flSegs) const
|
||
{
|
||
int nB1(-1), nTmp(5); // 找到支管标号
|
||
::GetAnotherPipe(m_nMain, nB2, nB1, nTmp);
|
||
|
||
double dScale1 = (m_dDrawParam-0.5)/m_dDrawParam,
|
||
dScale2 = (m_dDrawParam+0.5)/m_dDrawParam, dTmpAng(0);
|
||
XPoint pt2 = GetArcPts(ptLst[2], GetIWidth(nB1)*dScale2, GetIAngle(nB1),
|
||
pts[m_nMain], lstSeg, dTmpAng); // 大弧
|
||
XPoint pt3 = GetArcPts(ptLst[3], GetIWidth(nB1)*dScale1, GetIAngle(nB1),
|
||
pts[m_nMain], lstSeg, dTmpAng); // 小弧
|
||
XPoint pt5 = GetArcPts(ptLst[5], GetIWidth(nB2)*dScale2, GetIAngle(nB2),
|
||
pts[m_nMain], lstSeg, dTmpAng); // 大弧
|
||
XPoint pt4 = GetArcPts(ptLst[4], GetIWidth(nB2)*dScale1, GetIAngle(nB2),
|
||
pts[m_nMain], lstSeg, dTmpAng); // 小弧
|
||
BuildSegs1(pt3, ptLst[0], lstSeg);
|
||
BuildSegs1(pt4, ptLst[1], lstSeg);
|
||
|
||
DList<XCurveSegment> segs; // 不绘制
|
||
XPoint ptMid1 = GetArcPts(pts[nB1], GetIWidth(nB1), GetIAngle(nB1),
|
||
pts[m_nMain], segs, dTmpAng);
|
||
XPoint ptMid2 = GetArcPts(pts[nB2], GetIWidth(nB2), GetIAngle(nB2),
|
||
pts[m_nMain], segs, dTmpAng);
|
||
|
||
XLine line(pt3, ptLst[0], LS_INFINITE),
|
||
mirrorLine(pts[m_nMain], ptMid1, LS_INFINITE);
|
||
XLine retL1 = ::GetMirrorLine(line, mirrorLine); // 获取镜像后的线
|
||
|
||
line.SetPoints(pt4, ptLst[1]);
|
||
mirrorLine.SetPoints(pts[m_nMain], ptMid2);
|
||
XLine retL2 = ::GetMirrorLine(line, mirrorLine);
|
||
|
||
ads_polar(pts[m_nMain], GetIAngle(m_nMain), 1000, ptMid1);
|
||
line.SetPoints(pts[m_nMain], ptMid1);
|
||
if (!line.Intersection(&retL1, ptMid1) || !line.Intersection(&retL2, ptMid2))
|
||
{
|
||
return FALSE;
|
||
}
|
||
BuildSegs1(pt2, ptMid1, lstSeg);
|
||
BuildSegs1(pt5, ptMid2, lstSeg);
|
||
ptMid1 = ::GetFarPt(pts[m_nMain], ptMid1, ptMid2);
|
||
BuildSegs1(ptMid1, pts[m_nMain], lstSeg);
|
||
|
||
GetNewPts(pt2, pt3, GetIFlDist(nB1));
|
||
GetNewPts(pt5, pt4, GetIFlDist(nB2));
|
||
BuildSegs1(pt2, pt3, flSegs); // 用来画法兰
|
||
BuildSegs1(pt4, pt5, flSegs);
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
////////////////////////////四通////////////////////////////
|
||
Acad::ErrorStatus TDbDuctNode::Draw4Corner2D(XExplodeDraw &dc) const
|
||
{
|
||
if (GetInterfaceNum() != 4) // 1、保证所有的链表不越界
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
XPointList pts;
|
||
GetPtsIFace(pts, FALSE, FALSE, FALSE, TRUE); // 2、法兰遮挡后的管线连接点
|
||
if (pts.Length() != 4)
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
XPointList midPts;
|
||
GetTrueMidPts(midPts); // 3、获取支管编号和中心点偏移
|
||
AcDbIntArray aryBs = GetBranchNums(m_nMain);
|
||
if (aryBs.logicalLength()!=3 || midPts.Length()!=4)
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
if (m_nSysDrawMod != 3) // 4、除双线外,绘制中心线
|
||
{
|
||
XPoint ptLoc = GetZeroPt(); // 修正Z坐标为0
|
||
DList<XCurveSegment> midSegs;
|
||
switch(m_nDrawMod)
|
||
{
|
||
case 6: // 圆管四通,不带弯头
|
||
{
|
||
AcGeVector3d vtMain = GetIDirection(m_nMain).AsAcGeVector3d(),
|
||
vtB1 = GetIDirection(aryBs[0]).AsAcGeVector3d(),
|
||
vtB3 = GetIDirection(aryBs[2]).AsAcGeVector3d();
|
||
if (vtMain.isPerpendicularTo(vtB1)==Adesk::kTrue || // 主管与支1垂直
|
||
vtMain.isPerpendicularTo(vtB3)==Adesk::kTrue || // 主管与支3垂直
|
||
vtB1.isParallelTo(vtB3)==Adesk::kTrue) // 支1与支3平行
|
||
{
|
||
for (int i=0; i<4; i++)
|
||
{
|
||
BuildSegs1(ptLoc, *pts[i], midSegs);
|
||
}
|
||
}
|
||
else // 不垂直,且两支管不平行
|
||
{
|
||
BuildSegs1(*pts[m_nMain], *pts[aryBs[1]], midSegs);
|
||
BuildSegs2(*pts[aryBs[0]], *pts[m_nMain], *pts[aryBs[2]], midSegs);
|
||
}
|
||
}
|
||
break;
|
||
case 7: // 圆管四通,带弯头
|
||
{
|
||
double dTmpAng(0);
|
||
XPoint ptNew1 = GetArcPts(*pts[aryBs[0]], GetIWidth(aryBs[0]),
|
||
GetIAngle(aryBs[0]), *pts[m_nMain], midSegs, dTmpAng);
|
||
XPoint ptNew2 = GetArcPts(*pts[aryBs[2]], GetIWidth(aryBs[2]),
|
||
GetIAngle(aryBs[2]), *pts[m_nMain], midSegs, dTmpAng);
|
||
BuildSegs1(*pts[m_nMain], *pts[aryBs[1]], midSegs);
|
||
BuildSegs2(ptNew1, *pts[m_nMain], ptNew2, midSegs);
|
||
}
|
||
break;
|
||
default: // 方管四通
|
||
for (int i=0; i<4; i++)
|
||
{
|
||
BuildSegs1(ptLoc, *pts[i], midSegs);
|
||
}
|
||
break;
|
||
}
|
||
|
||
if (m_nSysDrawMod == 1)
|
||
{
|
||
DrawXiSegs(dc, midSegs); // 单线图,细线绘制
|
||
return Acad::eOk;
|
||
}
|
||
DrawMidSegs(dc, midSegs); // 三线图,切换中心线图层、线型绘制
|
||
}
|
||
|
||
AcDbIntArray idxs(aryBs);
|
||
idxs.insertAt(0, m_nMain);
|
||
|
||
XPointList ptLst; // 5、计算其他需要的点和线
|
||
DList<XLine> lstLine;
|
||
for (int j=0; j<idxs.logicalLength(); j++)
|
||
{
|
||
int nTmp = idxs[j];
|
||
XLine line(LS_FINITE); // 注:线与点的角标是对应的
|
||
line = XLine(*midPts[nTmp], *pts[nTmp]).Offset(-GetIWidth(nTmp)/2);
|
||
ptLst.Append(new XPoint(line.EndPoint()));
|
||
lstLine.Append(new XLine(line));
|
||
line = XLine(*midPts[nTmp], *pts[nTmp]).Offset(GetIWidth(nTmp)/2);
|
||
ptLst.Append(new XPoint(line.EndPoint()));
|
||
lstLine.Append(new XLine(line));
|
||
}
|
||
if (lstLine.Length()!=8 || ptLst.Length()!=8)
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
BOOL bIsOk(TRUE);
|
||
DList<XCurveSegment> lstSeg; // 6、绘制四通其他线
|
||
DList<XCurveSegment> flSegs;
|
||
switch(m_nDrawMod) {
|
||
case 0: // 圆角四通
|
||
bIsOk = DrawRound4T(pts, lstSeg, ptLst, lstLine, aryBs[0], aryBs[2]);
|
||
break;
|
||
case 1: // 直角四通
|
||
case 3: // 交叉四通
|
||
case 5:
|
||
bIsOk = DrawCAngle4T(lstSeg, ptLst, lstLine, aryBs[0], aryBs[2]);
|
||
break;
|
||
case 2: // 承插四通
|
||
bIsOk = DrawInsert4T(lstSeg, ptLst, lstLine, aryBs[0], aryBs[2]);
|
||
break;
|
||
case 4: // 通用四通
|
||
bIsOk = DrawRandom4T(lstSeg, ptLst, lstLine);
|
||
break;
|
||
case 6: // 圆管四通
|
||
case 7:
|
||
bIsOk = DrawCircle4T(pts, lstSeg, ptLst, aryBs[0], aryBs[2], flSegs);
|
||
break;
|
||
}
|
||
|
||
if (!bIsOk)
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
Draw2DSegs(dc, lstSeg); // 7、绘制
|
||
DrawFLSegs(dc, flSegs);
|
||
return Acad::eOk;
|
||
}
|
||
|
||
// 圆角四通
|
||
BOOL TDbDuctNode::DrawRound4T(const XPointList &pts, DList<XCurveSegment> &lstSeg,
|
||
const XPointList &ptLst, const DList<XLine> &llst,
|
||
int nB1, int nB3) const
|
||
{
|
||
BOOL bOk1 = DrawArc(lstSeg, pts[m_nMain], pts[nB1], ptLst[0], ptLst[3]),
|
||
bOk2 = DrawArc(lstSeg, pts[m_nMain], pts[nB3], ptLst[1], ptLst[6]);
|
||
if (!(bOk1 && bOk2)) // 绘制内弧
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
double dAng1 = GetIAngle(m_nMain), // 法向
|
||
dAng2 = GetIAngle(nB1),
|
||
dAng3 = GetIAngle(nB3);
|
||
XPoint ptArc1, ptArc2, ptArc3, ptArc4, ptCen1, ptCen2, ptInt, ptTmp;
|
||
ads_polar(ptLst[2], dAng2, -50, ptArc1);
|
||
ads_polar(ptLst[7], dAng3, -50, ptArc2);
|
||
BuildSegs1(ptArc1, ptLst[2], lstSeg);
|
||
BuildSegs1(ptArc2, ptLst[7], lstSeg);
|
||
|
||
double dRadius1 = GetIWidth(nB1) * (2*m_dDrawParam+1) * 0.5, // 外弧半径
|
||
dRadius2 = GetIWidth(nB3) * (2*m_dDrawParam+1) * 0.5;
|
||
ads_polar(ptArc1, dAng2-PI/2, dRadius1, ptCen1); // 外弧圆心
|
||
ads_polar(ptArc2, dAng3+PI/2, dRadius2, ptCen2);
|
||
ads_polar(ptCen1, dAng1-PI/2, dRadius1, ptArc3);
|
||
ads_polar(ptCen2, dAng1+PI/2, dRadius2, ptArc4);
|
||
|
||
XLine line1 = llst[5],
|
||
line2 = llst[4];
|
||
XPoint ptRes1 = line1.NearPoint(ptLst[0]), // 相当于投影
|
||
ptRes2 = line2.NearPoint(ptLst[1]);
|
||
line1.SetPoints(ptLst[5], ptRes1);
|
||
line2.SetPoints(ptLst[4], ptRes2);
|
||
|
||
int nB2(-1);
|
||
::GetAnotherPipe(m_nMain, nB1, nB3, nB2);
|
||
|
||
BOOL bSwitch(FALSE);
|
||
XArc arc = ::GetRightArc(ptArc1, ptCen1, ptArc3, bSwitch); // 选择优弧
|
||
if (arc.Intersection(&line1, ptInt, ptTmp))
|
||
{
|
||
BuildSegs1(ptInt, ptLst[5], lstSeg);
|
||
if (bSwitch)
|
||
{
|
||
TchPrivate::Exchange(ptInt, ptArc1);
|
||
}
|
||
arc.SetAngleByPoints(ptInt, ptArc1);
|
||
BuildSegs4(arc, lstSeg);
|
||
}
|
||
else
|
||
{
|
||
if (!DrawArc(lstSeg, pts[nB2], pts[nB1], ptLst[5], ptLst[2], FALSE))
|
||
{
|
||
return FALSE;
|
||
}
|
||
}
|
||
|
||
arc = ::GetRightArc(ptArc2, ptCen2, ptArc4, bSwitch); // 选择优弧
|
||
if (arc.Intersection(&line2, ptInt, ptTmp))
|
||
{
|
||
BuildSegs1(ptInt, ptLst[4], lstSeg);
|
||
if (bSwitch)
|
||
{
|
||
TchPrivate::Exchange(ptArc2, ptInt);
|
||
}
|
||
arc.SetAngleByPoints(ptInt, ptArc2);
|
||
BuildSegs4(arc, lstSeg);
|
||
}
|
||
else
|
||
{
|
||
if (!DrawArc(lstSeg, pts[nB2], pts[nB3], ptLst[4], ptLst[7], FALSE))
|
||
{
|
||
return FALSE;
|
||
}
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
// 直角、交叉四通
|
||
BOOL TDbDuctNode::DrawCAngle4T(DList<XCurveSegment> &lstSeg, const XPointList &ptLst,
|
||
const DList<XLine> &llst, int nB1, int nB3) const
|
||
{
|
||
BOOL bOk1 = DrawLine(lstSeg, llst[0], llst[3], 1),
|
||
bOk2 = DrawLine(lstSeg, llst[1], llst[6], 1);
|
||
if (!(bOk1 && bOk2))
|
||
{
|
||
return FALSE;
|
||
}
|
||
if (m_nDrawMod == 3) // 交叉四通
|
||
{
|
||
int nB2(-1);
|
||
::GetAnotherPipe(m_nMain, nB1, nB3, nB2);
|
||
bOk1 = DrawLine(lstSeg, llst[5], llst[2], 1);
|
||
bOk2 = DrawLine(lstSeg, llst[4], llst[7], 1);
|
||
return (bOk1 && bOk2);
|
||
}
|
||
|
||
XPoint ptInt1, ptInt2;
|
||
if (!llst[2].Intersection(&llst[5], ptInt1) || !llst[4].Intersection(&llst[7], ptInt2))
|
||
{
|
||
return FALSE;
|
||
}
|
||
if (m_nDrawMod == 5)
|
||
{
|
||
BuildSegs2(ptLst[2], ptInt1, ptLst[5], lstSeg);
|
||
BuildSegs2(ptLst[4], ptInt2, ptLst[7], lstSeg);
|
||
return TRUE;
|
||
}
|
||
|
||
XPoint pt1, pt2, pt3, pt4;
|
||
ads_polar(ptLst[2], GetIAngle(nB1), -50, pt1);
|
||
ads_polar(ptInt1, GetIAngle(m_nMain), 50, pt2);
|
||
ads_polar(ptLst[7], GetIAngle(nB3), -50, pt3);
|
||
ads_polar(ptInt2, GetIAngle(m_nMain), 50, pt4);
|
||
BuildSegs6(ptLst[2], pt1, pt2, ptLst[5], lstSeg);
|
||
BuildSegs6(ptLst[7], pt3, pt4, ptLst[4], lstSeg);
|
||
return TRUE;
|
||
}
|
||
|
||
// 承插四通
|
||
BOOL TDbDuctNode::DrawInsert4T(DList<XCurveSegment> &lstSeg, const XPointList &ptLst,
|
||
const DList<XLine> &llst, int nB1, int nB3) const
|
||
{
|
||
BOOL bOk1 = DrawLine(lstSeg, llst[0], llst[3], 1),
|
||
bOk2 = DrawLine(lstSeg, llst[1], llst[6], 1);
|
||
if (!(bOk1 && bOk2))
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
int nB2(-1);
|
||
::GetAnotherPipe(m_nMain, nB1, nB3, nB2);
|
||
XPoint ptInt1, ptInt2, pt1, pt2, pt3, pt4;
|
||
ads_polar(ptLst[0], GetIAngle(m_nMain), -50, pt1);
|
||
ads_polar(ptLst[1], GetIAngle(m_nMain), -50, pt2);
|
||
ads_polar(ptLst[5], GetIAngle(nB2), -50, pt3);
|
||
ads_polar(ptLst[4], GetIAngle(nB2), -50, pt4);
|
||
|
||
XLine l1(pt1, pt3, LS_FINITE),
|
||
l2(pt2, pt4, LS_FINITE);
|
||
if (!l1.Intersection(&llst[2], ptInt1) || !l2.Intersection(&llst[7], ptInt2))
|
||
{
|
||
return FALSE;
|
||
}
|
||
BuildSegs2(ptLst[5], pt3, pt1, lstSeg);
|
||
BuildSegs1(ptInt1, ptLst[2], lstSeg);
|
||
BuildSegs2(ptLst[4], pt4, pt2, lstSeg);
|
||
BuildSegs1(ptInt2, ptLst[7], lstSeg);
|
||
return TRUE;
|
||
}
|
||
|
||
// 通用四通
|
||
BOOL TDbDuctNode::DrawRandom4T(DList<XCurveSegment> &lstSeg, const XPointList &ptLst,
|
||
const DList<XLine> &llst) const
|
||
{
|
||
XPoint p1, p2, p3, p4;
|
||
if (!llst[0].Intersection(&llst[3], p1) || !llst[2].Intersection(&llst[5], p2) ||
|
||
!llst[4].Intersection(&llst[7], p3) || !llst[6].Intersection(&llst[1], p4))
|
||
{
|
||
return FALSE;
|
||
}
|
||
BuildSegs2(ptLst[0], p1, ptLst[3], lstSeg);
|
||
BuildSegs2(ptLst[2], p2, ptLst[5], lstSeg);
|
||
BuildSegs2(ptLst[4], p3, ptLst[7], lstSeg);
|
||
BuildSegs2(ptLst[6], p4, ptLst[1], lstSeg);
|
||
return TRUE;
|
||
}
|
||
|
||
// 圆管四通
|
||
BOOL TDbDuctNode::DrawCircle4T(const XPointList &pts, DList<XCurveSegment> &lstSeg,
|
||
const XPointList &ptLst, int nB1, int nB3,
|
||
DList<XCurveSegment> &flSegs) const
|
||
{
|
||
int nB2(-1);
|
||
::GetAnotherPipe(m_nMain, nB1, nB3, nB2); // 获取支管2的标号
|
||
|
||
BOOL bFlag(TRUE); // 标志位置点是否在连接件内部
|
||
double dWide1 = GetIWidth(nB1), dWide2 = GetIWidth(nB3),
|
||
dAng1 = GetIAngle(nB1), dAng3 = GetIAngle(nB3);
|
||
XPoint ptLoc = pts[m_nMain], // 中心点修正
|
||
ptB1(pts[nB1]), ptB3(pts[nB3]); // 连接点
|
||
XPoint p2(ptLst[2]), p3(ptLst[3]), p6(ptLst[6]), p7(ptLst[7]);
|
||
if (m_nDrawMod == 7) // 绘制弯头
|
||
{
|
||
double d1 = (m_dDrawParam-0.5)/m_dDrawParam, // 小弧修正
|
||
d2 = (m_dDrawParam+0.5)/m_dDrawParam; // 大弧修正
|
||
p2 = GetArcPts(p2, dWide1*d2, GetIAngle(nB1), ptLoc, lstSeg, dAng1); // 大
|
||
p3 = GetArcPts(p3, dWide1*d1, GetIAngle(nB1), ptLoc, lstSeg, dAng1); // 小
|
||
p6 = GetArcPts(p6, dWide2*d1, GetIAngle(nB3), ptLoc, lstSeg, dAng3); // 大
|
||
p7 = GetArcPts(p7, dWide2*d2, GetIAngle(nB3), ptLoc, lstSeg, dAng3); // 小
|
||
|
||
XPoint ptTmp1(p2), ptTmp2(p3);
|
||
::GetNewPts(ptTmp1, ptTmp2, GetIFlDist(nB1));
|
||
BuildSegs1(ptTmp1, ptTmp2, flSegs); // 法兰绘制
|
||
ptTmp1 = p6;
|
||
ptTmp2 = p7;
|
||
::GetNewPts(ptTmp1, ptTmp2, GetIFlDist(nB3));
|
||
BuildSegs1(ptTmp1, ptTmp2, flSegs);
|
||
|
||
DList<XCurveSegment> segs; // 不绘制
|
||
ptB1 = GetArcPts(ptB1, dWide1, GetIAngle(nB1), ptLoc, segs, dAng1);
|
||
ptB3 = GetArcPts(ptB3, dWide2, GetIAngle(nB3), ptLoc, segs, dAng3);
|
||
|
||
ptTmp2 = pts[nB2];
|
||
XCurveSegment segTmp(ptLoc, ptTmp2, 0, LS_FINITE);
|
||
ptLoc = GetZeroPt();
|
||
segTmp.ProjectToMe(ptLoc, ptTmp1);
|
||
bFlag = (ptTmp1&segTmp)==PR_INSIDE;
|
||
}
|
||
|
||
double dTmp = (m_nDrawMod==7)?1:-1;
|
||
int m = bFlag?5:4; // 和0对应
|
||
XPoint ptInt1, ptInt2;
|
||
ads_polar(ptB1, dAng1, 5*dTmp*GetIWidth(m_nMain), ptInt1);
|
||
XLine tmpL1(ptLst[0], ptLst[m], LS_INFINITE),
|
||
tmpL2(ptInt1, ptB1, LS_INFINITE);
|
||
XLine l1 = tmpL2.Offset(-GetIWidth(nB1)*0.5),
|
||
l2 = tmpL2.Offset(GetIWidth(nB1)*0.5);
|
||
if (!tmpL1.Intersection(&l1, ptInt2) || !tmpL1.Intersection(&l2, ptInt1))
|
||
{
|
||
return FALSE;
|
||
}
|
||
BuildSegs2(ptLst[0], ptInt1, p3, lstSeg);
|
||
BuildSegs2(ptLst[m], ptInt2, p2, lstSeg);
|
||
|
||
m = bFlag?4:5; // 和1对应
|
||
XPoint ptInt3, ptInt4;
|
||
tmpL1.SetPoints(ptLst[1], ptLst[m]);
|
||
ads_polar(ptB3, dAng3, 5*dTmp*GetIWidth(m_nMain), ptInt3);
|
||
tmpL2.SetPoints(ptInt3, ptB3);
|
||
XLine l3 = tmpL2.Offset(-GetIWidth(nB3)*0.5),
|
||
l4 = tmpL2.Offset(GetIWidth(nB3)*0.5);
|
||
if (!tmpL1.Intersection(&l3, ptInt3) || !tmpL1.Intersection(&l4, ptInt4))
|
||
{
|
||
return FALSE;
|
||
}
|
||
BuildSegs2(p6, ptInt3, ptLst[1], lstSeg);
|
||
BuildSegs2(p7, ptInt4, ptLst[m], lstSeg);
|
||
|
||
double dMin = GetIWidth(nB2) * 0.125; // 管径较小的
|
||
dAng1 = ads_angle(XPoint(), XVector3D(ptInt1-ptInt2));
|
||
dAng3 = ads_angle(XPoint(), XVector3D(ptInt3-ptInt4));
|
||
Midpoint(ptInt1, ptInt2, ptB1);
|
||
Midpoint(ptInt3, ptInt4, ptB3);
|
||
ads_polar(ptB1, dAng1-PI/2, dMin, ptB1); // 弧中点
|
||
ads_polar(ptB3, dAng3+PI/2, dMin, ptB3);
|
||
|
||
XArc arc1(ptInt1, ptB1, ptInt2), // 相贯线
|
||
arc2(ptInt3, ptB3, ptInt4);
|
||
BuildSegs4(arc1, lstSeg);
|
||
BuildSegs4(arc2, lstSeg);
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
|
||
///////////////////////////////////三维绘制/////////////////////////////////////
|
||
Acad::ErrorStatus TDbDuctNode::ExplodeOrDraw3d(XExplodeDraw &dc) const
|
||
{
|
||
if (GetInterfaceNum() != GetDuctIFaceNum()) // 首先保证连表数量正确
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
Acad::ErrorStatus es = Acad::eOk;
|
||
if (m_nSysDrawMod == 4) // 系统图
|
||
{
|
||
es = ExplodeOrDrawSys(dc);
|
||
return es;
|
||
}
|
||
|
||
switch(m_nType)
|
||
{
|
||
case kElbow: // 弯头
|
||
es = DrawElbow3D(dc);
|
||
break;
|
||
case kKouElbow: // 扣弯
|
||
es = DrawKElbow3D(dc);
|
||
break;
|
||
case kTapered: // 变径
|
||
es = DrawTapered3D(dc);
|
||
break;
|
||
case kTianYuanDiFang: // 天圆地方
|
||
es = DrawTYDF3D(dc);
|
||
break;
|
||
case kYiZiElbow: // 乙字弯
|
||
es = DrawYZElbow3D(dc);
|
||
break;
|
||
case k3Corner: // 三通
|
||
es = Draw3T3D(dc);
|
||
break;
|
||
case k4Corner: // 四通
|
||
es = Draw4T3D(dc);
|
||
break;
|
||
}
|
||
|
||
if (es == Acad::eOk)
|
||
{
|
||
es = DrawFL3D(dc); // 法兰
|
||
}
|
||
return es;
|
||
}
|
||
|
||
|
||
////////////////////////////法兰////////////////////////////
|
||
Acad::ErrorStatus TDbDuctNode::DrawFL3D(XExplodeDraw &dc) const
|
||
{
|
||
int nLen = GetInterfaceNum();
|
||
if (nLen == 1) // 注:一般堵头时,不绘制
|
||
{
|
||
return Acad::eOk;
|
||
}
|
||
if ((m_nDrawMod==13) && (m_nType==kTaoDong)) // 注:样式13的掏洞不绘制
|
||
{
|
||
return Acad::eOk;
|
||
}
|
||
|
||
AcDbObjectId idLayerOld = dc.GetLayerId(),
|
||
idDoteLayer = m_idFlangeLayer; // 法兰层
|
||
if (idDoteLayer.isValid())
|
||
{
|
||
dc.SetLayer(idDoteLayer);
|
||
}
|
||
dc.SetColorLayer(colorIndex(), idDoteLayer);
|
||
|
||
for (int i=0; i<nLen; i++)
|
||
{
|
||
BOOL bIsVDuct(FALSE);
|
||
XVector3D vtDraw = GetIDirection(i); // 法向
|
||
vtDraw.Normalize();
|
||
if (fabs(vtDraw.x)<1.0E-6 && fabs(vtDraw.y)<1.0E-6)
|
||
bIsVDuct = TRUE; // 判断是否为立管
|
||
|
||
if (m_nType == k3Corner) // 注:当有两根立管与三通连接时,立管上的法兰不绘制
|
||
{
|
||
int nSum(0);
|
||
for (int j=0; j<3; j++)
|
||
{
|
||
const XVector3D &vt = GetIDirection(j); // 判断有几根立管
|
||
if (fabs(vt.x)<1.0E-6 && fabs(vt.y)<1.0E-6)
|
||
nSum += (2*j+1);
|
||
}
|
||
|
||
if (bIsVDuct && (nSum==4 || nSum==6 || nSum==8)) // 连接了两根立管
|
||
continue;
|
||
}
|
||
|
||
double dThick = GetIFlThick(i); // 法兰片厚度
|
||
if (fabs(dThick) < 1.0E-6)
|
||
dThick = 4;
|
||
XPoint ptLink = GetILocation(i); // 连接点位置
|
||
vtDraw.Scale(dThick/2);
|
||
XPoint ptStart = ptLink + vtDraw, // 路径起止点
|
||
ptEnd = ptLink - vtDraw;
|
||
|
||
double dDia = GetIWidth(i), // 管径或宽度
|
||
dHigh = GetIHeight(i); // 高度
|
||
dDia += 2.0*GetIFlDist(i);
|
||
if (fabs(dHigh) < 1.0E-6) // 圆风管
|
||
{
|
||
DList<X3DFace> lstFaces;
|
||
BOOL bIsOk = ::GetColumn3DFaces(ptStart, dDia/2.0, vtDraw, ptEnd,
|
||
dDia/2.0, vtDraw, lstFaces, g_nSplitNum, 4);
|
||
if (!bIsOk)
|
||
break;
|
||
|
||
int nCount = lstFaces.Length();
|
||
for (int k=0; k<nCount; k++)
|
||
{
|
||
X3DFace face = *lstFaces[k];
|
||
dc << face;
|
||
}
|
||
}
|
||
else // 方风管
|
||
{
|
||
dHigh += 2.0*GetIFlDist(i);
|
||
XPointList ductPts1, ductPts2;
|
||
if (bIsVDuct)
|
||
{
|
||
double dVDAngle = GetIVDAngle(i);
|
||
XPoly2D pts1, pts2;
|
||
::GetSquare(ptStart, dVDAngle, dDia, dHigh, &pts1, NULL); // 立管截面
|
||
::GetSquare(ptEnd, dVDAngle, dDia, dHigh, &pts2, NULL);
|
||
if (pts1.Length()!=4 || pts2.Length()!=4)
|
||
break;
|
||
|
||
int k(0);
|
||
for (k=0; k<4; k++)
|
||
ductPts1.Append(new XPoint(*pts1[k]));
|
||
for (k=0; k<4; k++)
|
||
ductPts2.Append(new XPoint(*pts2[k]));
|
||
}
|
||
else
|
||
{
|
||
::GetDuctSidePts(ptStart, dDia, dHigh, vtDraw, ductPts1);
|
||
::GetDuctSidePts(ptEnd, dDia, dHigh, vtDraw, ductPts2);
|
||
}
|
||
if (ductPts1.Length()!=4 || ductPts2.Length()!=4)
|
||
break;
|
||
|
||
dc << ::GetFace1(*ductPts1[0], *ductPts1[1], *ductPts1[2], *ductPts1[3]);
|
||
dc << ::GetFace1(*ductPts2[0], *ductPts2[1], *ductPts2[2], *ductPts2[3]);
|
||
dc << ::GetFace1(*ductPts1[0], *ductPts1[1], *ductPts2[1], *ductPts2[0]);
|
||
dc << ::GetFace1(*ductPts1[3], *ductPts1[2], *ductPts2[2], *ductPts2[3]);
|
||
dc << ::GetFace1(*ductPts1[0], *ductPts1[3], *ductPts2[3], *ductPts2[0]);
|
||
dc << ::GetFace1(*ductPts1[1], *ductPts1[2], *ductPts2[2], *ductPts2[1]);
|
||
}
|
||
}
|
||
|
||
dc.SetLayer(idLayerOld);
|
||
dc.SetColorLayer(colorIndex(), idLayerOld);
|
||
return Acad::eOk;
|
||
}
|
||
|
||
|
||
////////////////////////////弯头////////////////////////////
|
||
Acad::ErrorStatus TDbDuctNode::DrawElbow3D(XExplodeDraw &dc) const
|
||
{
|
||
if ((GetInterfaceNum()!=2) || (GetDuctIFaceNum()!=2))
|
||
return Acad::eInvalidInput; // 保证链表不越界
|
||
|
||
XPointList lstBasePts;
|
||
GetPtsIFace(lstBasePts, FALSE, TRUE, FALSE, FALSE);
|
||
if (lstBasePts.Length() != 2) // 获取与管线相连点,考虑了法兰遮挡节点
|
||
return Acad::eInvalidInput;
|
||
|
||
XPoint ptStart = *lstBasePts[0], // 与管线相连点
|
||
ptEnd = *lstBasePts[1];
|
||
XVector3D vt1 = GetIDirection(0), // 管线法向
|
||
vt2 = GetIDirection(1);
|
||
double dWidth1 = GetIWidth(0), // 管线宽度
|
||
dWidth2 = GetIWidth(1),
|
||
dHigh1 = GetIHeight(0),
|
||
dHigh2 = GetIHeight(1);
|
||
if (m_bMuffler) // 消声弯头
|
||
{
|
||
dWidth1 += GetIFlDist(0)*1.6;
|
||
dWidth2 += GetIFlDist(1)*1.6;
|
||
}
|
||
|
||
XPoint ptLoc(m_ptLocation);
|
||
if (fabs(dHigh1)<1.0E-6 && fabs(dHigh2)<1.0E-6 && m_nDrawMod==0) // 圆管内外弧线
|
||
{
|
||
XPointList pts;
|
||
::GetTHSplitPts(ptStart, ptEnd, vt1, vt2, g_nSplitNum, pts, 0, ptLoc);
|
||
int nLen = pts.Length(), i(0);
|
||
if (nLen != g_nSplitNum+2)
|
||
return Acad::eInvalidInput;
|
||
|
||
DList<X3DFace> lstFaces;
|
||
XPoint ptTmp1(*pts[1]), ptTmp2(*pts[g_nSplitNum]);
|
||
BOOL bIsOk1 = ::GetColumn3DFaces(*pts[0], dWidth1/2, vt1, ptTmp1, dWidth1/2,
|
||
vt1, lstFaces, g_nSplitNum, 4, FALSE, FALSE, FALSE, FALSE);
|
||
BOOL bIsOk2 = ::GetColumn3DFaces(ptTmp2, dWidth2/2, vt2, *pts[g_nSplitNum+1],
|
||
dWidth2/2, vt2, lstFaces, g_nSplitNum, 4, FALSE, FALSE, FALSE, FALSE);
|
||
if (!bIsOk1 || !bIsOk2)
|
||
return Acad::eInvalidInput;
|
||
|
||
double dChange = (dWidth2-dWidth1)/(g_nSplitNum-1);
|
||
AcGeCircArc3d arc(ptTmp1, *pts[g_nSplitNum/2], ptTmp2);
|
||
for (i=1; i<g_nSplitNum; 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;
|
||
|
||
AcGeVector3d vtTmp1 = tangentL1.direction(),
|
||
vtTmp2 = tangentL2.direction();
|
||
double dNum1 = dWidth1 + dChange*(i-1),
|
||
dNum2 = dWidth1 + dChange*i;
|
||
BOOL bIsOk = ::GetColumn3DFaces(*pts[i], dNum1/2.0, XVector3D(vtTmp1),
|
||
*pts[i+1], dNum2/2.0, XVector3D(vtTmp2), lstFaces, g_nSplitNum, 4,
|
||
FALSE, FALSE, FALSE, FALSE);
|
||
if (!bIsOk)
|
||
break;
|
||
}
|
||
|
||
nLen = lstFaces.Length();
|
||
for (i=0; i<nLen; i++)
|
||
dc << *lstFaces[i];
|
||
return Acad::eOk;
|
||
}
|
||
|
||
|
||
if (fabs(dHigh1) < 1.0E-6) // 注:不分方圆,一率按方管处理
|
||
dHigh1 = dWidth1;
|
||
if (fabs(dHigh2) < 1.0E-6)
|
||
dHigh2 = dWidth2;
|
||
XPointList lPts1, lPts2;
|
||
::GetDuctSidePts(ptStart, dWidth1, dHigh1, vt1, lPts1);
|
||
::GetDuctSidePts(ptEnd, dWidth2, dHigh2, vt2, lPts2);
|
||
if (lPts1.Length()!=4 || lPts2.Length()!=4) // 管线连接处的截面四个角点
|
||
return Acad::eInvalidInput;
|
||
|
||
int nExSplit(1), nInSplit(1), nType(0); // 连接件边线分割份数
|
||
BOOL bExShow(TRUE), bInShow(TRUE); // 是否显示边线
|
||
if (m_nDrawMod == 0) // 内外弧线
|
||
{
|
||
nExSplit = nInSplit = g_nSplitNum;
|
||
bExShow = bInShow = FALSE;
|
||
}
|
||
else if (m_nDrawMod == 1) // 内斜线
|
||
{
|
||
nInSplit = m_bMuffler?0:2;
|
||
}
|
||
else if (m_nDrawMod == 2) // 内弧线
|
||
{
|
||
nInSplit = g_nSplitNum;
|
||
bInShow = FALSE;
|
||
}
|
||
else if (m_nDrawMod == 4) // 虾米弯头
|
||
{
|
||
nInSplit = nExSplit = m_nXMWNum;
|
||
nType = 3;
|
||
}
|
||
|
||
|
||
XPointList pts1, pts2, // 分别为内上、下线
|
||
pts3, pts4; // 分别为外上、下线
|
||
double dDist1 = lPts1[0]->Distance(*lPts2[1]),
|
||
dDist2 = lPts1[1]->Distance(*lPts2[0]);
|
||
if (dDist1 > (dDist2+1.0e-6)) // 判断内外
|
||
{
|
||
::GetTHSplitPts(*lPts1[1], *lPts2[0], vt1, vt2, nInSplit, pts1, nType, ptLoc);
|
||
::GetTHSplitPts(*lPts1[2], *lPts2[3], vt1, vt2, nInSplit, pts2, nType, ptLoc);
|
||
::GetTHSplitPts(*lPts1[0], *lPts2[1], vt1, vt2, nExSplit, pts3, nType, ptLoc);
|
||
::GetTHSplitPts(*lPts1[3], *lPts2[2], vt1, vt2, nExSplit, pts4, nType, ptLoc);
|
||
}
|
||
else
|
||
{
|
||
::GetTHSplitPts(*lPts1[0], *lPts2[1], vt1, vt2, nInSplit, pts1, nType, ptLoc);
|
||
::GetTHSplitPts(*lPts1[3], *lPts2[2], vt1, vt2, nInSplit, pts2, nType, ptLoc);
|
||
::GetTHSplitPts(*lPts1[1], *lPts2[0], vt1, vt2, nExSplit, pts3, nType, ptLoc);
|
||
::GetTHSplitPts(*lPts1[2], *lPts2[3], vt1, vt2, nExSplit, pts4, nType, ptLoc);
|
||
}
|
||
int nLen1 = pts1.Length(), // 获取分割点
|
||
nLen2 = pts2.Length(),
|
||
nLen3 = pts3.Length(),
|
||
nLen4 = pts4.Length();
|
||
if (nLen1!=nLen2 || nLen1!=nInSplit+2 || nLen3!=nLen4 || nLen3!=nExSplit+2)
|
||
return Acad::eInvalidInput;
|
||
|
||
|
||
int m(0), n(0);
|
||
for (m=0; m<nLen1-1; m++) // 绘制内、外面
|
||
{
|
||
if (m == 0) // 内
|
||
dc << ::GetFace1(*pts1[m], *pts2[m], *pts2[m+1], *pts1[m+1],
|
||
TRUE, TRUE, bInShow);
|
||
else if (m == nLen1-2)
|
||
dc << ::GetFace1(*pts1[m], *pts2[m], *pts2[m+1], *pts1[m+1], bInShow);
|
||
else
|
||
dc << ::GetFace1(*pts1[m], *pts2[m], *pts2[m+1], *pts1[m+1],
|
||
bInShow, TRUE, bInShow);
|
||
}
|
||
|
||
for (n=0; n<nLen3-1; n++)
|
||
{
|
||
if (n == 0) // 外
|
||
dc << ::GetFace1(*pts3[n], *pts4[n], *pts4[n+1], *pts3[n+1],
|
||
TRUE, TRUE, bExShow);
|
||
else if (n == nLen3-2)
|
||
dc << ::GetFace1(*pts3[n], *pts4[n], *pts4[n+1], *pts3[n+1], bExShow);
|
||
else
|
||
dc << ::GetFace1(*pts3[n], *pts4[n], *pts4[n+1], *pts3[n+1],
|
||
bExShow, TRUE, bExShow);
|
||
}
|
||
|
||
|
||
// 绘制上下面
|
||
if (m_nDrawMod == 0) // 内外弧线
|
||
{
|
||
if (nLen1 != nLen3) // = g_nSplitNum+2
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
for (m=0; m<nLen1-1; m++)
|
||
{
|
||
BOOL bShow1 = (m==nLen1-2),
|
||
bShow2 = (m==0);
|
||
dc << ::GetFace2(*pts1[m], *pts1[m+1], *pts3[m+1], TRUE, bShow1);
|
||
dc << ::GetFace2(*pts2[m], *pts2[m+1], *pts4[m+1], TRUE, bShow1);
|
||
dc << ::GetFace2(*pts1[m], *pts3[m], *pts3[m+1], bShow2, TRUE);
|
||
dc << ::GetFace2(*pts2[m], *pts4[m], *pts4[m+1], bShow2, TRUE);
|
||
}
|
||
return Acad::eOk;
|
||
}
|
||
|
||
if (m_nDrawMod == 4) // 虾米弯
|
||
{
|
||
if (nLen1 != nLen3) // = m_nXMWNum+2
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
for (m=0; m<nLen1-1; m++)
|
||
{
|
||
dc << ::GetFace1(*pts1[m], *pts1[m+1], *pts3[m+1], *pts3[m]);
|
||
dc << ::GetFace1(*pts2[m], *pts2[m+1], *pts4[m+1], *pts4[m]);
|
||
}
|
||
return Acad::eOk;
|
||
}
|
||
|
||
if (m_nDrawMod == 3) // 内外直线
|
||
{
|
||
if (nLen1 != nLen3) // = 3
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
dc << ::GetFace1(*pts1[1], *pts3[1], *pts3[0], *pts1[0], FALSE);
|
||
dc << ::GetFace1(*pts1[1], *pts3[1], *pts3[2], *pts1[2], FALSE);
|
||
|
||
dc << ::GetFace1(*pts2[1], *pts4[1], *pts4[0], *pts2[0], FALSE);
|
||
dc << ::GetFace1(*pts2[1], *pts4[1], *pts4[2], *pts2[2], FALSE);
|
||
return Acad::eOk;
|
||
}
|
||
|
||
if (m_nDrawMod==1 && !m_bMuffler) // 不带消声的内外直线
|
||
{
|
||
dc << ::GetFace1(*pts1[1], *pts3[1], *pts3[0], *pts1[0], FALSE);
|
||
dc << ::GetFace1(*pts1[2], *pts3[1], *pts3[2], *pts1[3], FALSE);
|
||
dc << ::GetFace2(*pts1[1], *pts1[2], *pts3[1], TRUE);
|
||
dc << ::GetFace1(*pts2[1], *pts4[1], *pts4[0], *pts2[0], FALSE);
|
||
dc << ::GetFace1(*pts2[2], *pts4[1], *pts4[2], *pts2[3], FALSE);
|
||
dc << ::GetFace2(*pts2[1], *pts2[2], *pts4[1], TRUE);
|
||
return Acad::eOk;
|
||
}
|
||
|
||
dc << ::GetFace2(*pts1[0], *pts3[0], *pts3[1], TRUE, TRUE);
|
||
dc << ::GetFace2(*pts1[nLen1-1], *pts3[2], *pts3[1], TRUE, TRUE);
|
||
dc << ::GetFace2(*pts2[0], *pts4[0], *pts4[1], TRUE, TRUE);
|
||
dc << ::GetFace2(*pts2[nLen1-1], *pts4[2], *pts4[1], TRUE, TRUE);
|
||
|
||
if (m_nDrawMod == 1) // 带消声的内外直线
|
||
{
|
||
dc << ::GetFace2(*pts1[0], *pts1[1], *pts3[1], TRUE);
|
||
dc << ::GetFace2(*pts2[0], *pts2[1], *pts4[1], TRUE);
|
||
return Acad::eOk;
|
||
}
|
||
|
||
for (m=0; m<nLen1-1; m++) // 内弧线
|
||
{
|
||
dc << ::GetFace2(*pts1[m], *pts1[m+1], *pts3[1], TRUE);
|
||
dc << ::GetFace2(*pts2[m], *pts2[m+1], *pts4[1], TRUE);
|
||
}
|
||
return Acad::eOk;
|
||
}
|
||
|
||
|
||
//////////////////////////变高弯头//////////////////////////
|
||
Acad::ErrorStatus TDbDuctNode::DrawKElbow3D(XExplodeDraw &dc) const
|
||
{
|
||
if ((GetInterfaceNum()!=2) || (GetDuctIFaceNum()!=2))
|
||
return Acad::eInvalidInput; // 保证链表不越界
|
||
|
||
XPointList lstBasePts;
|
||
GetPtsIFace(lstBasePts, FALSE, TRUE, FALSE, FALSE);
|
||
if (lstBasePts.Length() != 2) // 1、获取与管线相连点,注:考虑法兰遮挡节点
|
||
return Acad::eInvalidInput;
|
||
|
||
XVector3D vt1 = GetIDirection(0), // 管线法向
|
||
vt2 = GetIDirection(1);
|
||
int nVDuct(0);
|
||
if (fabs(vt2.x)<1.0E-6 && fabs(vt2.y)<1.0E-6) // 2、判断立管编号
|
||
nVDuct = 1;
|
||
int nHDuct = 1 - nVDuct; // 水平管编号
|
||
|
||
vt1 = GetIDirection(nHDuct); // 3、获取管线信息
|
||
vt2 = GetIDirection(nVDuct);
|
||
XPoint pt1 = *lstBasePts[nHDuct], // 与管线相连点
|
||
pt2 = *lstBasePts[nVDuct];
|
||
double dWidth1 = GetIWidth(nHDuct), // 管线宽度
|
||
dWidth2 = GetIWidth(nVDuct),
|
||
dHigh1 = GetIHeight(nHDuct),
|
||
dHigh2 = GetIHeight(nVDuct);
|
||
|
||
// 4、圆管的内外弧线
|
||
XPoint ptLoc(m_ptLocation);
|
||
if (fabs(dHigh1)<1.0E-6 && fabs(dHigh2)<1.0E-6 && m_nDrawMod==0)
|
||
{
|
||
XPointList pts;
|
||
::GetTHSplitPts(pt1, pt2, vt1, vt2, g_nSplitNum, pts); // 路径
|
||
int nLen = pts.Length(), i(0);
|
||
if (nLen != g_nSplitNum+2)
|
||
return Acad::eInvalidInput;
|
||
|
||
DList<X3DFace> lstFaces;
|
||
XPoint ptTmp1(*pts[1]), ptTmp2(*pts[g_nSplitNum]);
|
||
AcGeCircArc3d arc(ptTmp1, *pts[g_nSplitNum/2], ptTmp2);
|
||
double dChange = (dWidth2-dWidth1)/(nLen-1);
|
||
for (i=1; i<g_nSplitNum; 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;
|
||
|
||
AcGeVector3d vtTmp1 = tangentL1.direction(),
|
||
vtTmp2 = tangentL2.direction();
|
||
double dNum1 = dWidth1 + dChange*i,
|
||
dNum2 = dWidth1 + dChange*(i+1);
|
||
|
||
BOOL bIsOk(TRUE);
|
||
if (i != g_nSplitNum-1)
|
||
{
|
||
bIsOk = ::GetColumn3DFaces(*pts[i], dNum1/2.0, XVector3D(vtTmp1),
|
||
*pts[i+1], dNum2/2.0, XVector3D(vtTmp2), lstFaces, g_nSplitNum,
|
||
4, FALSE, FALSE, FALSE, FALSE);
|
||
}
|
||
else // 注:在立管与水平管连接处,需要特殊处理一下向量关系
|
||
{
|
||
bIsOk = ::GetColumn3DFaces(*pts[i], dNum1/2.0, XVector3D(vtTmp1),
|
||
*pts[i+1], dNum2/2.0, XVector3D(vtTmp1), lstFaces, g_nSplitNum,
|
||
4, FALSE, FALSE, FALSE, FALSE);
|
||
}
|
||
|
||
if (!bIsOk)
|
||
break;
|
||
}
|
||
|
||
AcGeVector3d vtSpare1 = vt1.AsAcGeVector3d(),
|
||
vtSpare2 = vt2.AsAcGeVector3d();
|
||
ptTmp1 = ptTmp1 - XVector3D(vtSpare1.normalize());
|
||
ptTmp2 = ptTmp2 - XVector3D(vtSpare2.normalize());
|
||
BOOL bIsOk1 = ::GetColumn3DFaces(pt1, dWidth1/2, vt1, ptTmp1, dWidth1/2,
|
||
vt1, lstFaces, g_nSplitNum, 4, FALSE, FALSE, FALSE, FALSE);
|
||
BOOL bIsOk2 = ::GetColumn3DFaces(ptTmp2, dWidth2/2, vt2, pt2, dWidth2/2,
|
||
vt2, lstFaces, g_nSplitNum, 4, FALSE, FALSE, FALSE, FALSE);
|
||
if (!bIsOk1 || !bIsOk2)
|
||
return Acad::eInvalidInput;
|
||
|
||
nLen = lstFaces.Length();
|
||
for (i=0; i<nLen; i++)
|
||
dc << *lstFaces[i];
|
||
return Acad::eOk;
|
||
}
|
||
|
||
|
||
if (fabs(dHigh1) < 1.0E-6) // 注:不分方圆,一率按方管处理
|
||
dHigh1 = dWidth1;
|
||
if (fabs(dHigh2) < 1.0E-6)
|
||
dHigh2 = dWidth2;
|
||
|
||
// 5、获取管线的边线点
|
||
XPointList pts1;
|
||
::GetDuctSidePts(pt1, dWidth1, dHigh1, vt1, pts1); // 水平管截面
|
||
XPoly2D pts2;
|
||
double dVDAngle = GetIVDAngle(nVDuct); // 立管角度
|
||
::GetSquare(pt2, dVDAngle, dWidth2, dHigh2, &pts2, NULL); // 立管截面
|
||
if (pts1.Length()!=4 || pts2.Length()!=4)
|
||
return Acad::eInvalidInput;
|
||
|
||
BOOL bUpKowWan(FALSE);
|
||
if (vt2.z > 1.0E-6) // 6、判断是否是上扣弯
|
||
bUpKowWan = TRUE;
|
||
|
||
int nUpSplit(g_nSplitNum), nLowSplit(g_nSplitNum); // 7、获取连接件边线分割份数
|
||
if (bUpKowWan && m_nDrawMod!=0)
|
||
{
|
||
nLowSplit = 1;
|
||
if (m_nDrawMod == 1) // 两条直线
|
||
nUpSplit = 2;
|
||
else if (m_nDrawMod == 3)
|
||
nUpSplit = 1;
|
||
}
|
||
else if (!bUpKowWan && m_nDrawMod!=0)
|
||
{
|
||
nUpSplit = 1;
|
||
if (m_nDrawMod == 1)
|
||
nLowSplit = 2;
|
||
else if (m_nDrawMod == 3)
|
||
nLowSplit = 1;
|
||
}
|
||
|
||
double dHDAngle = GetIAngle(nHDuct),
|
||
dAngle = CT_std_angle(dVDAngle-dHDAngle);
|
||
int nIndexNum(0);
|
||
if (bUpKowWan)
|
||
{
|
||
if ((dAngle>-1.0E-6 && dAngle<PI/4-1.0E-6) ||
|
||
(dAngle>PI/4*7+1.0E-6 && dAngle<PI*2-1.0E-6))
|
||
nIndexNum = 2;
|
||
else if (dAngle>PI/4-1.0E-6 && dAngle<PI/4*3+1.0E-6)
|
||
nIndexNum = 3;
|
||
else if (dAngle>PI/4*3+1.0E-6 && dAngle<PI/4*5-1.0E-6)
|
||
nIndexNum = 0;
|
||
else
|
||
nIndexNum = 1;
|
||
}
|
||
else
|
||
{
|
||
if ((dAngle>-1.0E-6 && dAngle<PI/4-1.0E-6) ||
|
||
(dAngle>PI/4*7+1.0E-6 && dAngle<PI*2-1.0E-6))
|
||
nIndexNum = 6;
|
||
else if (dAngle>PI/4-1.0E-6 && dAngle<PI/4*3+1.0E-6)
|
||
nIndexNum = 7;
|
||
else if (dAngle>PI/4*3+1.0E-6 && dAngle<PI/4*5-1.0E-6)
|
||
nIndexNum = 4;
|
||
else
|
||
nIndexNum = 5;
|
||
}
|
||
|
||
// 注:pts2中,分别与pts1顺序相连的角标
|
||
int nSerialNum[8][4] = {{2, 3, 0, 1}, {3, 0, 1, 2}, {0, 1, 2, 3}, {1, 2, 3, 0},
|
||
{1, 0, 3, 2}, {2, 1, 0, 3}, {3, 2, 1, 0}, {0, 3, 2, 1}};
|
||
int nNum0 = nSerialNum[nIndexNum][0],
|
||
nNum1 = nSerialNum[nIndexNum][1],
|
||
nNum2 = nSerialNum[nIndexNum][2],
|
||
nNum3 = nSerialNum[nIndexNum][3];
|
||
|
||
// 8、分割连接件边线,注:角标与水平管的角点相对应
|
||
XPointList lstPt1, lstPt2, lstPt3, lstPt4;
|
||
::GetTHSplitPts(*pts1[0], *pts2[nNum0], vt1, vt2, nUpSplit, lstPt1);
|
||
::GetTHSplitPts(*pts1[1], *pts2[nNum1], vt1, vt2, nUpSplit, lstPt2);
|
||
::GetTHSplitPts(*pts1[2], *pts2[nNum2], vt1, vt2, nLowSplit, lstPt3);
|
||
::GetTHSplitPts(*pts1[3], *pts2[nNum3], vt1, vt2, nLowSplit, lstPt4);
|
||
int nLen1 = lstPt1.Length(),
|
||
nLen2 = lstPt3.Length();
|
||
if (nLen1!=nUpSplit+2 || lstPt2.Length()!=nLen1 || nLen2!=nLowSplit+2
|
||
|| lstPt4.Length()!=nLen2)
|
||
return Acad::eInvalidInput;
|
||
|
||
int m(0);
|
||
for (m=0; m<nLen1-1; m++) // 8、绘制上、下面
|
||
{
|
||
BOOL bShow1 = (m==0),
|
||
bShow2 = (m==nLen1-2);
|
||
dc << ::GetFace1(*lstPt1[m], *lstPt2[m], *lstPt2[m+1], *lstPt1[m+1],
|
||
bShow1, TRUE, bShow2);
|
||
}
|
||
|
||
for (m=0; m<nLen2-1; m++)
|
||
{
|
||
BOOL bShow1 = (m==0),
|
||
bShow2 = (m==nLen2-2);
|
||
dc << ::GetFace1(*lstPt3[m], *lstPt4[m], *lstPt4[m+1], *lstPt3[m+1],
|
||
bShow1, TRUE, bShow2);
|
||
}
|
||
|
||
|
||
// 9、绘制内、外面
|
||
if (m_nDrawMod == 0) // 内外弧线
|
||
{
|
||
for (m=0; m<g_nSplitNum+1; m++)
|
||
{
|
||
BOOL bShow1 = (m==0),
|
||
bShow2 = (m==g_nSplitNum);
|
||
dc << ::GetFace2(*lstPt1[m], *lstPt4[m], *lstPt4[m+1], bShow1, TRUE);
|
||
dc << ::GetFace2(*lstPt1[m], *lstPt4[m+1], *lstPt1[m+1], FALSE, bShow2, TRUE);
|
||
dc << ::GetFace2(*lstPt2[m], *lstPt3[m], *lstPt3[m+1], bShow1, TRUE);
|
||
dc << ::GetFace2(*lstPt2[m], *lstPt3[m+1], *lstPt2[m+1], FALSE, bShow2, TRUE);
|
||
}
|
||
return Acad::eOk;
|
||
}
|
||
|
||
if (m_nDrawMod == 1) // 内斜线
|
||
{
|
||
dc << ::GetFace1(*lstPt1[1], *lstPt4[1], *lstPt4[0], *lstPt1[0], FALSE);
|
||
dc << ::GetFace1(*lstPt2[1], *lstPt3[1], *lstPt3[0], *lstPt2[0], FALSE);
|
||
if (bUpKowWan)
|
||
{
|
||
dc << ::GetFace2(*lstPt1[1], *lstPt1[2], *lstPt4[1], TRUE);
|
||
dc << ::GetFace1(*lstPt1[2], *lstPt4[1], *lstPt4[2], *lstPt1[3], FALSE);
|
||
dc << ::GetFace2(*lstPt2[1], *lstPt2[2], *lstPt3[1], TRUE);
|
||
dc << ::GetFace1(*lstPt2[2], *lstPt3[1], *lstPt3[2], *lstPt2[3], FALSE);
|
||
}
|
||
else
|
||
{
|
||
dc << ::GetFace2(*lstPt4[1], *lstPt4[2], *lstPt1[1], TRUE);
|
||
dc << ::GetFace1(*lstPt4[2], *lstPt1[1], *lstPt1[2], *lstPt4[3], FALSE);
|
||
dc << ::GetFace2(*lstPt3[1], *lstPt3[2], *lstPt2[1], TRUE);
|
||
dc << ::GetFace1(*lstPt3[2], *lstPt2[1], *lstPt2[2], *lstPt3[3], FALSE);
|
||
}
|
||
return Acad::eOk;
|
||
}
|
||
|
||
if (m_nDrawMod == 3) // 内外直角
|
||
{
|
||
dc << ::GetFace1(*lstPt1[1], *lstPt4[1], *lstPt4[0], *lstPt1[0], FALSE);
|
||
dc << ::GetFace1(*lstPt1[1], *lstPt4[1], *lstPt4[2], *lstPt1[2], FALSE);
|
||
dc << ::GetFace1(*lstPt2[1], *lstPt3[1], *lstPt3[0], *lstPt2[0], FALSE);
|
||
dc << ::GetFace1(*lstPt2[1], *lstPt3[1], *lstPt3[2], *lstPt2[2], FALSE);
|
||
return Acad::eOk;
|
||
}
|
||
|
||
// 内弧线
|
||
if (bUpKowWan)
|
||
{
|
||
dc << ::GetFace2(*lstPt1[0], *lstPt4[0], *lstPt4[1], TRUE, TRUE);
|
||
dc << ::GetFace2(*lstPt1[g_nSplitNum+1], *lstPt4[2], *lstPt4[1], TRUE, TRUE);
|
||
dc << ::GetFace2(*lstPt2[0], *lstPt3[0], *lstPt3[1], TRUE, TRUE);
|
||
dc << ::GetFace2(*lstPt2[g_nSplitNum+1], *lstPt3[2], *lstPt3[1], TRUE, TRUE);
|
||
for (m=0; m<g_nSplitNum+1; m++)
|
||
{
|
||
dc << ::GetFace2(*lstPt1[m], *lstPt1[m+1], *lstPt4[1], TRUE);
|
||
dc << ::GetFace2(*lstPt2[m], *lstPt2[m+1], *lstPt3[1], TRUE);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
dc << ::GetFace2(*lstPt4[0], *lstPt1[0], *lstPt1[1], TRUE, TRUE);
|
||
dc << ::GetFace2(*lstPt4[g_nSplitNum+1], *lstPt1[2], *lstPt1[1], TRUE, TRUE);
|
||
dc << ::GetFace2(*lstPt3[0], *lstPt2[0], *lstPt2[1], TRUE, TRUE);
|
||
dc << ::GetFace2(*lstPt3[g_nSplitNum+1], *lstPt2[2], *lstPt2[1], TRUE, TRUE);
|
||
for (m=0; m<g_nSplitNum+1; m++)
|
||
{
|
||
dc << ::GetFace2(*lstPt4[m], *lstPt4[m+1], *lstPt1[1], TRUE);
|
||
dc << ::GetFace2(*lstPt3[m], *lstPt3[m+1], *lstPt2[1], TRUE);
|
||
}
|
||
}
|
||
return Acad::eOk;
|
||
}
|
||
|
||
|
||
////////////////////////////变径////////////////////////////
|
||
Acad::ErrorStatus TDbDuctNode::DrawTapered3D(XExplodeDraw &dc) const
|
||
{
|
||
if ((GetInterfaceNum()!=2) || (GetDuctIFaceNum()!=2))
|
||
return Acad::eInvalidInput; // 保证链表不越界
|
||
|
||
XPointList lstBasePts;
|
||
GetPtsIFace(lstBasePts, FALSE, TRUE, FALSE, FALSE);
|
||
if (lstBasePts.Length() != 2) // 获取与管线相连点,考虑了法兰遮挡节点
|
||
return Acad::eInvalidInput;
|
||
|
||
XPoint ptStart = *lstBasePts[0], // 与管线相连点
|
||
ptEnd = *lstBasePts[1];
|
||
XVector3D vt1 = GetIDirection(0), // 法向
|
||
vt2 = GetIDirection(1);
|
||
double dWidth1 = GetIWidth(0)/2, // 宽度一半
|
||
dWidth2 = GetIWidth(1)/2;
|
||
double dHigh1 = GetIHeight(0), // 高度
|
||
dHigh2 = GetIHeight(1);
|
||
|
||
BOOL bIsOk(TRUE);
|
||
DList<X3DFace> lstFaces;
|
||
if (fabs(dHigh1)<1.0E-6 && fabs(dHigh2)<1.0E-6) // 两个圆管
|
||
{
|
||
vt2.Scale(-1);
|
||
bIsOk = ::GetColumn3DFaces(ptStart, dWidth1, vt1, ptEnd, dWidth2,
|
||
vt2, lstFaces, g_nSplitNum, 2, FALSE, FALSE);
|
||
if (!bIsOk)
|
||
return Acad::eInvalidInput;
|
||
}
|
||
else // 两个方管
|
||
{
|
||
if (fabs(vt1.x)<1.0E-6 && fabs(vt1.y)<1.0E-6 && fabs(vt2.x)<1.0E-6 &&
|
||
fabs(vt2.y)<1.0E-6) // 两个立管
|
||
{
|
||
XPoly2D pts1, pts2;
|
||
double dVDAngle = GetIVDAngle(0); // 立管角度
|
||
::GetSquare(ptStart, dVDAngle, dWidth1*2, dHigh1, &pts1, NULL);
|
||
::GetSquare(ptEnd, dVDAngle, dWidth2*2, dHigh2, &pts2, NULL); // 立管截面
|
||
if (pts1.Length()!=4 || pts2.Length()!=4)
|
||
return Acad::eInvalidInput;
|
||
|
||
dc << ::GetFace1(*pts1[0], *pts1[1], *pts2[1], *pts2[0]);
|
||
dc << ::GetFace1(*pts1[1], *pts1[2], *pts2[2], *pts2[1]);
|
||
dc << ::GetFace1(*pts1[2], *pts1[3], *pts2[3], *pts2[2]);
|
||
dc << ::GetFace1(*pts1[3], *pts1[0], *pts2[0], *pts2[3]);
|
||
return Acad::eOk;
|
||
}
|
||
|
||
if (!DrawCube3d(ptStart, 0, ptEnd, 1, vt1, lstFaces))
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
int nCount = lstFaces.Length();
|
||
for (int k=0; k<nCount; k++)
|
||
{
|
||
X3DFace face = *lstFaces[k];
|
||
dc << face;
|
||
}
|
||
return Acad::eOk;
|
||
}
|
||
|
||
|
||
//////////////////////////天圆地方//////////////////////////
|
||
Acad::ErrorStatus TDbDuctNode::DrawTYDF3D(XExplodeDraw &dc) const
|
||
{
|
||
if ((GetInterfaceNum()!=2) || (GetDuctIFaceNum()!=2))
|
||
return Acad::eInvalidInput; // 保证链表不越界
|
||
|
||
// 获取与管线相连点,考虑法兰遮挡节点
|
||
XPointList ptDrawLst;
|
||
GetPtsIFace(ptDrawLst, FALSE, TRUE, FALSE, FALSE);
|
||
if (ptDrawLst.Length() != 2)
|
||
return Acad::eInvalidInput;
|
||
|
||
int nCircleNum(0), nRectNum(1); // 管1为圆管,管2为方管
|
||
BOOL bIsCircle = ::IsCircleDuct(objectId(), GetIPipe(0), 0);
|
||
if (!bIsCircle)
|
||
{
|
||
nCircleNum = 1; // 管2为圆管,管1为方管
|
||
nRectNum = 0;
|
||
}
|
||
|
||
XPointList circlePts1; // 注:与方管顶点连接
|
||
::GetSplitCirclePts(*ptDrawLst[nCircleNum], GetIWidth(nCircleNum)/2,
|
||
GetIDirection(nCircleNum), g_nSplitNum, circlePts1);
|
||
XPointList circlePts2; // 注:与方管边连接
|
||
::GetSplitCirclePts(*ptDrawLst[nCircleNum], GetIWidth(nCircleNum)/2,
|
||
GetIDirection(nCircleNum), 4, circlePts2);
|
||
int nLen1 = circlePts1.Length(),
|
||
nLen2 = circlePts2.Length();
|
||
if (nLen1==0 || nLen1!=g_nSplitNum+1 || nLen2==0 || nLen2!=5)
|
||
return Acad::eInvalidInput;
|
||
|
||
double dWidth = GetIWidth(nRectNum), // 方管尺寸
|
||
dHigh = GetIHeight(nRectNum);
|
||
XVector3D vt1 = GetIDirection(nCircleNum), // 管线法向
|
||
vt2 = GetIDirection(nRectNum);
|
||
if (fabs(vt1.x)<1.0E-6 && fabs(vt1.y)<1.0E-6 && fabs(vt2.x)<1.0E-6 &&
|
||
fabs(vt2.y)<1.0E-6) // 两个立管
|
||
{
|
||
XPoly2D pts;
|
||
double dVDAngle = GetIVDAngle(nRectNum); // 立管角度
|
||
::GetSquare(*ptDrawLst[nRectNum], dVDAngle, dWidth, dHigh, &pts, NULL);
|
||
if (pts.Length() != 4) // 立管截面
|
||
return Acad::eInvalidInput;
|
||
|
||
int nIndex(0);
|
||
if (vt1.z > vt2.z+1.0E-6) // 圆管在上
|
||
{
|
||
if (fabs(dVDAngle-PI/2) < 1.0E-6)
|
||
nIndex = 1;
|
||
else if (dVDAngle > PI/2+1.0E-6)
|
||
nIndex = 2;
|
||
}
|
||
else
|
||
{
|
||
if (fabs(dVDAngle-PI/2) < 1.0E-6)
|
||
nIndex = 4;
|
||
else if (dVDAngle > PI/2+1.0E-6)
|
||
nIndex = 5;
|
||
else
|
||
nIndex = 3;
|
||
}
|
||
|
||
int nSerialNum1[6][4] = {{0, 3, 2, 1}, {1, 0, 3, 2}, {2, 1, 0, 3}, {2, 3, 0, 1},
|
||
{1, 2, 3, 0}, {0, 1, 2, 3}};
|
||
int nNum0 = nSerialNum1[nIndex][0],
|
||
nNum1 = nSerialNum1[nIndex][1],
|
||
nNum2 = nSerialNum1[nIndex][2],
|
||
nNum3 = nSerialNum1[nIndex][3];
|
||
dc << ::GetFace2(*circlePts2[nNum0], *pts[0], *pts[1], TRUE, TRUE, FALSE, TRUE);
|
||
dc << ::GetFace2(*circlePts2[nNum1], *pts[1], *pts[2], TRUE, TRUE, FALSE, TRUE);
|
||
dc << ::GetFace2(*circlePts2[nNum2], *pts[2], *pts[3], TRUE, TRUE, FALSE, TRUE);
|
||
dc << ::GetFace2(*circlePts2[nNum3], *pts[3], *pts[0], TRUE, TRUE, FALSE, TRUE);
|
||
|
||
int nSerialNum2[6][4] = {{0, 3, 2, 1}, {1, 0, 3, 2}, {2, 1, 0, 3}, {3, 0, 1, 2},
|
||
{0, 1, 2, 3}, {1, 2, 3, 0}};
|
||
AcDbIntArray nSerialNum3;
|
||
for (int j=0; j<4; j++)
|
||
{
|
||
int nNum = nSerialNum2[nIndex][j];
|
||
nSerialNum3.append(nNum);
|
||
}
|
||
|
||
int nItemNum = g_nSplitNum/4; // 每份个数
|
||
for (int k=0; k<nLen1-1; k++)
|
||
{
|
||
int nInRectNum = k/nItemNum,
|
||
nNum = nSerialNum3[nInRectNum];
|
||
dc << ::GetFace2(*pts[nNum], *circlePts1[k], *circlePts1[k+1],
|
||
FALSE, TRUE, FALSE, FALSE);
|
||
}
|
||
return Acad::eOk;
|
||
}
|
||
|
||
XPointList rectPts;
|
||
::GetDuctSidePts(*ptDrawLst[nRectNum], dWidth, dHigh, GetIDirection(nCircleNum),
|
||
rectPts);
|
||
if (rectPts.Length() != 4)
|
||
return Acad::eInvalidInput;
|
||
|
||
dc << ::GetFace2(*circlePts2[0], *rectPts[0], *rectPts[3], TRUE, TRUE, FALSE, TRUE);
|
||
dc << ::GetFace2(*circlePts2[1], *rectPts[0], *rectPts[1], TRUE, TRUE, FALSE, TRUE);
|
||
dc << ::GetFace2(*circlePts2[2], *rectPts[1], *rectPts[2], TRUE, TRUE, FALSE, TRUE);
|
||
dc << ::GetFace2(*circlePts2[3], *rectPts[2], *rectPts[3], TRUE, TRUE, FALSE, TRUE);
|
||
|
||
int nItemNum = g_nSplitNum/4; // 每份个数
|
||
for (int k=0; k<nLen1-1; k++)
|
||
{
|
||
int nInRectNum = k/nItemNum;
|
||
dc << ::GetFace2(*rectPts[nInRectNum], *circlePts1[k], *circlePts1[k+1],
|
||
FALSE, TRUE, FALSE, FALSE);
|
||
}
|
||
return Acad::eOk;
|
||
}
|
||
|
||
|
||
///////////////////////////乙字弯///////////////////////////
|
||
Acad::ErrorStatus TDbDuctNode::DrawYZElbow3D(XExplodeDraw &dc) const
|
||
{
|
||
if ((GetInterfaceNum()!=2) || GetDuctIFaceNum()!=2) // 保证链表不越界
|
||
return Acad::eInvalidInput;
|
||
|
||
XPointList linkPts;
|
||
GetPtsIFace(linkPts, FALSE, TRUE, FALSE, FALSE);
|
||
if (linkPts.Length() != 2)
|
||
return Acad::eInvalidInput; // 1、获取与管线相连点,考虑了法兰遮挡节点
|
||
|
||
BOOL bSameEle(TRUE);
|
||
XPoint ptStart = *linkPts[0], // 2、获取绘制信息
|
||
ptEnd = *linkPts[1],
|
||
ptLoc; // 注:修正m_ptLocation点标高
|
||
Spoint(ptLoc, m_ptLocation.x, m_ptLocation.y, (ptStart.z+ptEnd.z)/2.0);
|
||
if (fabs(ptStart.z-ptEnd.z) > 1.0E-6)
|
||
bSameEle = FALSE; // 3、判断是等标高乙字弯,或变高乙字弯
|
||
|
||
XVector3D vtStart = GetIDirection(0), // 向量
|
||
vtEnd = GetIDirection(1);
|
||
double dWStart = GetIWidth(0), // 宽度
|
||
dWEnd = GetIWidth(1);
|
||
double dHStart = GetIHeight(0), // 高度
|
||
dHEnd = GetIHeight(1);
|
||
|
||
|
||
XPoint ptPro1, ptPro2;
|
||
DList<X3DFace> lstFaces;
|
||
if (m_nDrawMod == 2) // 角接乙字弯
|
||
{
|
||
double dTmp1 = (!bSameEle && fabs(dHStart)>1.0E-6)?dHStart:dWStart,
|
||
dTmp2 = (!bSameEle && fabs(dHEnd)>1.0E-6)?dHEnd:dWEnd;
|
||
vtStart.Normalize();
|
||
vtEnd.Normalize();
|
||
vtStart.Scale(dTmp1);
|
||
vtEnd.Scale(dTmp2);
|
||
ptPro1 = ptStart - vtStart;
|
||
ptPro2 = ptEnd - vtEnd;
|
||
|
||
BOOL bIsOk1(TRUE), bIsOk2(TRUE), bIsOk3(TRUE);
|
||
if (fabs(dHStart)<1.0E-6 && fabs(dHEnd)<1.0E-6) // 两个圆管
|
||
{
|
||
bIsOk1 = ::GetColumn3DFaces(ptStart, dWStart/2.0, vtStart, ptPro1,
|
||
dWStart/2.0, vtStart, lstFaces, g_nSplitNum, 4, TRUE, FALSE);
|
||
bIsOk2 = ::GetColumn3DFaces(ptEnd, dWEnd/2.0, vtEnd, ptPro2,
|
||
dWEnd/2.0, vtEnd, lstFaces, g_nSplitNum, 4, TRUE, FALSE);
|
||
bIsOk3 = ::GetColumn3DFaces(ptPro1, dWStart/2.0, vtStart, ptPro2,
|
||
dWEnd/2.0, vtStart, lstFaces, g_nSplitNum, 4, TRUE, FALSE);
|
||
}
|
||
else
|
||
{
|
||
bIsOk1 = DrawCube3d(ptStart, 0, ptPro1, 0, vtStart, lstFaces);
|
||
bIsOk2 = DrawCube3d(ptPro1, 0, ptPro2, 1, vtStart, lstFaces);
|
||
bIsOk3 = DrawCube3d(ptPro2, 1, ptEnd, 1, vtStart, lstFaces);
|
||
}
|
||
if (!bIsOk1 || !bIsOk2 || !bIsOk3)
|
||
{
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
int nCount = lstFaces.Length();
|
||
for (int k=0; k<nCount; k++)
|
||
{
|
||
X3DFace face = *lstFaces[k];
|
||
dc << face;
|
||
}
|
||
return Acad::eOk;
|
||
}
|
||
|
||
|
||
XCurveSegment segStart(ptStart, XPoint(ptStart+vtStart), 0),
|
||
segEnd(ptEnd, XPoint(ptEnd+vtEnd), 0);
|
||
segEnd.ProjectToMe(ptStart, ptPro1);
|
||
segStart.ProjectToMe(ptEnd, ptPro2);
|
||
|
||
XVector3D vtMid1 = ptPro1 - ptStart, // 4、获取中线圆心方向
|
||
vtMid2 = ptPro2 - ptEnd;
|
||
vtMid1.Normalize();
|
||
vtMid2.Normalize();
|
||
|
||
double dDist = ptStart.Distance(ptEnd), // 斜边长度
|
||
dRadius = dDist/(4*sin(m_dDrawParam/2)), // 中线圆半径
|
||
dRadius1(dWStart*m_dDrawParam2), dRadius2(dWEnd*m_dDrawParam2);
|
||
if (m_nDrawMod == 1) // 斜接乙字弯
|
||
{
|
||
if (!bSameEle && fabs(dHStart)>1.0E-6 && fabs(dHEnd)>1.0E-6)
|
||
{
|
||
dRadius1 = dHStart*m_dDrawParam2; // 不等标高的方管
|
||
dRadius2 = dHEnd*m_dDrawParam2;
|
||
}
|
||
vtMid1.Scale(dRadius1);
|
||
vtMid2.Scale(dRadius2);
|
||
}
|
||
else // 双弧乙字弯
|
||
{
|
||
vtMid1.Scale(dRadius);
|
||
vtMid2.Scale(dRadius);
|
||
}
|
||
|
||
XPoint ptSCen = ptStart + vtMid1, // 5、获取圆心点
|
||
ptECen = ptEnd + vtMid2;
|
||
|
||
// 6、根据不同绘制样式,来绘制乙字弯
|
||
if (m_nDrawMod == 0) // 双弧乙字弯
|
||
{
|
||
if (!bSameEle) // 不等标高
|
||
{
|
||
vtMid1 = ptSCen - ptLoc;
|
||
vtMid2 = ptECen - ptLoc;
|
||
}
|
||
else // 中间点接口方向
|
||
{
|
||
vtMid1 = XVector3D((ptSCen-ptLoc).AsAcGeVector3d().perpVector());
|
||
vtMid2 = XVector3D((ptECen-ptLoc).AsAcGeVector3d().perpVector());
|
||
if (vtStart.AsAcGeVector3d().dotProduct(vtMid1.AsAcGeVector3d()) > 1.0E-6)
|
||
TchPrivate::Exchange(vtMid1, vtMid2);
|
||
}
|
||
|
||
double dWMid = (dWStart+dWEnd)/2.0;
|
||
// 7、根据方圆管的不同进行绘制——圆管
|
||
if (fabs(dHStart)<1.0E-6 && fabs(dHEnd)<1.0E-6)
|
||
{
|
||
if (!bSameEle) // 注:当标高不等时,需要修正中间点接口方向
|
||
{
|
||
AcGePlane tmpPlane(ptSCen, (ptStart-ptSCen).AsAcGeVector3d(),
|
||
(ptLoc-ptSCen).AsAcGeVector3d());
|
||
AcGeCircArc3d tmpArc(ptSCen, tmpPlane.normal(), dRadius);
|
||
AcGeLine3d line;
|
||
if (tmpArc.tangent(ptLoc, line)==Adesk::kFalse)
|
||
return Acad::eInvalidInput;
|
||
vtMid1 = XVector3D(line.direction());
|
||
vtMid2 = XVector3D(line.direction()*(-1));
|
||
}
|
||
|
||
XPointList path1, path2;
|
||
::GetTHSplitPts(ptStart, ptLoc, vtStart, vtMid1, g_nSplitNum, path1);
|
||
::GetTHSplitPts(ptLoc, ptEnd, vtMid2, vtEnd, g_nSplitNum, path2); // 节点中心线
|
||
if (path1.Length()!=g_nSplitNum+2 || path2.Length()!=g_nSplitNum+2)
|
||
return Acad::eInvalidInput;
|
||
|
||
XPoint ptTmp1(*path1[1]), ptTmp2(*path1[g_nSplitNum]),
|
||
ptTmp3(*path2[1]), ptTmp4(*path2[g_nSplitNum]);
|
||
AcGeVector3d vtSpare1 = vtStart.AsAcGeVector3d(),
|
||
vtSpare2 = vtMid1.AsAcGeVector3d(),
|
||
vtSpare3 = vtMid2.AsAcGeVector3d(),
|
||
vtSpare4 = vtEnd.AsAcGeVector3d();
|
||
ptTmp1 = ptTmp1 - XVector3D(vtSpare1.normalize()*10);
|
||
ptTmp2 = ptTmp2 + XVector3D(vtSpare1.normalize()*10);
|
||
ptTmp3 = ptTmp3 - XVector3D(vtSpare1.normalize()*10);
|
||
ptTmp4 = ptTmp4 + XVector3D(vtSpare1.normalize()*10);
|
||
|
||
BOOL bIsOk1 = ::GetColumn3DFaces(*path1[0], dWStart/2, vtStart, ptTmp1, dWStart/2,
|
||
vtStart, lstFaces, g_nSplitNum, 2, FALSE, FALSE, FALSE, FALSE),
|
||
bIsOk2 = ::GetColumn3DFaces(ptTmp2, dWMid/2, vtMid1, *path1[g_nSplitNum+1],
|
||
dWMid/2, vtMid1, lstFaces, g_nSplitNum, 2, FALSE, FALSE, FALSE, FALSE);
|
||
BOOL bIsOk3 = ::GetColumn3DFaces(*path2[0], dWMid/2, vtMid2, ptTmp3, dWMid/2,
|
||
vtMid2, lstFaces, g_nSplitNum, 2, FALSE, FALSE, FALSE, FALSE),
|
||
bIsOk4 = ::GetColumn3DFaces(ptTmp4, dWEnd/2, vtEnd, *path2[g_nSplitNum+1], dWEnd/2,
|
||
vtEnd, lstFaces, g_nSplitNum, 2, FALSE, FALSE, FALSE, FALSE);
|
||
if (!bIsOk1 || !bIsOk2 || !bIsOk3 || !bIsOk4)
|
||
return Acad::eInvalidInput;
|
||
|
||
int i(1);
|
||
AcGeCircArc3d arc1(*path1[1], *path1[g_nSplitNum/2], *path1[g_nSplitNum]); // 弧线
|
||
double dChange1 = (dWMid-dWStart)/(g_nSplitNum+1);
|
||
for (i=1; i<g_nSplitNum; i++)
|
||
{
|
||
AcGeLine3d tangentLine1, tangentLine2;
|
||
if (arc1.tangent(path1[i]->AsAcGePoint3d(), tangentLine1)==Adesk::kFalse ||
|
||
arc1.tangent(path1[i+1]->AsAcGePoint3d(), tangentLine2)==Adesk::kFalse)
|
||
return Acad::eInvalidInput;
|
||
|
||
AcGeVector3d vtTmp1 = tangentLine1.direction(),
|
||
vtTmp2 = tangentLine2.direction();
|
||
double dNum1 = dWStart + dChange1*i,
|
||
dNum2 = dWStart + dChange1*(i+1);
|
||
BOOL bIsOk = ::GetColumn3DFaces(*path1[i], dNum1/2.0, XVector3D(vtTmp1),
|
||
*path1[i+1], dNum2/2.0, XVector3D(vtTmp2), lstFaces, g_nSplitNum, 2,
|
||
FALSE, FALSE, FALSE, FALSE);
|
||
if (!bIsOk)
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
AcGeCircArc3d arc2(*path2[1], *path2[g_nSplitNum/2], *path2[g_nSplitNum]);
|
||
double dChange2 = (dWEnd-dWMid)/(g_nSplitNum+1);
|
||
for (i=1; i<g_nSplitNum; i++)
|
||
{
|
||
AcGeLine3d tangentLine1, tangentLine2;
|
||
if (arc2.tangent(path2[i]->AsAcGePoint3d(), tangentLine1)==Adesk::kFalse ||
|
||
arc2.tangent(path2[i+1]->AsAcGePoint3d(), tangentLine2)==Adesk::kFalse)
|
||
return Acad::eInvalidInput;
|
||
|
||
AcGeVector3d vtTmp1 = tangentLine1.direction(),
|
||
vtTmp2 = tangentLine2.direction();
|
||
double dNum1 = dWMid + dChange2*i,
|
||
dNum2 = dWMid + dChange2*(i+1);
|
||
|
||
BOOL bIsOk = ::GetColumn3DFaces(*path2[i], dNum1/2.0, XVector3D(vtTmp1), *path2[i+1],
|
||
dNum2/2.0, XVector3D(vtTmp2), lstFaces, g_nSplitNum, 2, FALSE, FALSE, FALSE, FALSE);
|
||
if (!bIsOk)
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
int nLen = lstFaces.Length();
|
||
for (i=0; i<nLen; i++)
|
||
dc << *lstFaces[i];
|
||
return Acad::eOk;
|
||
}
|
||
|
||
double dHMid = (dHStart+dHEnd)/2.0; // 方管
|
||
XPointList pts1, pts2, pts3, pts4;
|
||
::GetDuctSidePts(ptStart, dWStart, dHStart, vtStart, pts1);
|
||
::GetDuctSidePts(ptEnd, dWEnd, dHEnd, vtEnd, pts4);
|
||
if (bSameEle)
|
||
{
|
||
::GetDuctSidePts(ptLoc, dWMid, dHMid, vtMid1, pts2);
|
||
::GetDuctSidePts(ptLoc, dWMid, dHMid, vtMid2, pts3);
|
||
}
|
||
else
|
||
{
|
||
vtMid1.Normalize();
|
||
vtMid1.Scale(dHMid/2.0);
|
||
XPoint ptTmp1(ptLoc+vtMid1), ptTmp2(ptLoc-vtMid1);
|
||
if (ptStart.z > (ptEnd.z+1.0E-6))
|
||
TchPrivate::Exchange(ptTmp1, ptTmp2);
|
||
|
||
XVector3D vtTmp = *pts1[1] - *pts1[0];
|
||
vtTmp.Normalize();
|
||
vtTmp.Scale(dWMid/2.0);
|
||
|
||
XPoint pt0 = ptTmp1 + vtTmp,
|
||
pt1 = ptTmp1 - vtTmp,
|
||
pt2 = ptTmp2 - vtTmp,
|
||
pt3 = ptTmp2 + vtTmp;
|
||
pts2.Append(new XPoint(pt0)); // 注:当标高不等时,手动添加中间截面的四个角点
|
||
pts2.Append(new XPoint(pt1));
|
||
pts2.Append(new XPoint(pt2));
|
||
pts2.Append(new XPoint(pt3));
|
||
|
||
pts3.Append(new XPoint(pt1));
|
||
pts3.Append(new XPoint(pt0));
|
||
pts3.Append(new XPoint(pt3));
|
||
pts3.Append(new XPoint(pt2));
|
||
}
|
||
if (pts1.Length()!=4 || pts2.Length()!=4 || pts3.Length()!=4 || pts4.Length()!=4)
|
||
return Acad::eInvalidInput;
|
||
|
||
if (!bSameEle) // 注:当标高不等时,需要修正中间点接口方向
|
||
{
|
||
AcGeVector3d vtTmp1 = (*pts2[1]-*pts2[0]).AsAcGeVector3d(),
|
||
vtTmp2 = (*pts2[3]-*pts2[0]).AsAcGeVector3d();
|
||
AcGePlane plane(pts2[0]->AsAcGePoint3d(), vtTmp1, vtTmp2);
|
||
AcGeVector3d vtNormal = plane.normal();
|
||
vtMid1 = XVector3D(vtNormal);
|
||
vtMid2 = XVector3D(vtNormal*(-1));
|
||
if (ptStart.z > (ptEnd.z+1.0E-6))
|
||
TchPrivate::Exchange(vtMid1, vtMid2);
|
||
}
|
||
|
||
XPointList lstPt1, lstPt2, lstPt3, lstPt4;
|
||
::GetTHSplitPts(*pts1[0], *pts2[1], vtStart, vtMid1, g_nSplitNum, lstPt1);
|
||
::GetTHSplitPts(*pts1[3], *pts2[2], vtStart, vtMid1, g_nSplitNum, lstPt2);
|
||
::GetTHSplitPts(*pts1[1], *pts2[0], vtStart, vtMid1, g_nSplitNum, lstPt3);
|
||
::GetTHSplitPts(*pts1[2], *pts2[3], vtStart, vtMid1, g_nSplitNum, lstPt4);
|
||
int nLen = lstPt1.Length(), m(0);
|
||
if (nLen!=g_nSplitNum+2 || lstPt2.Length()!=nLen || lstPt3.Length()!=nLen
|
||
|| lstPt4.Length()!=nLen)
|
||
return Acad::eInvalidInput;
|
||
|
||
for (m=0; m<nLen-1; m++)
|
||
{
|
||
BOOL bShow1(FALSE), bShow2(FALSE);
|
||
if (m == 0)
|
||
bShow1 = TRUE;
|
||
else if (m == nLen-2)
|
||
bShow2 = TRUE;
|
||
|
||
// 绘制内、外面
|
||
dc << ::GetFace1(*lstPt1[m], *lstPt2[m], *lstPt2[m+1], *lstPt1[m+1], bShow1, TRUE, bShow2);
|
||
dc << ::GetFace1(*lstPt3[m], *lstPt4[m], *lstPt4[m+1], *lstPt3[m+1], bShow1, TRUE, bShow2);
|
||
// 绘制上、下面
|
||
dc << ::GetFace2(*lstPt3[m], *lstPt1[m], *lstPt1[m+1], bShow1, TRUE); // 内
|
||
dc << ::GetFace2(*lstPt4[m], *lstPt2[m], *lstPt2[m+1], bShow1, TRUE);
|
||
dc << ::GetFace2(*lstPt3[m], *lstPt3[m+1], *lstPt1[m+1], TRUE, bShow2); // 外
|
||
dc << ::GetFace2(*lstPt4[m], *lstPt4[m+1], *lstPt2[m+1], TRUE, bShow2);
|
||
}
|
||
|
||
XPointList lstPt5, lstPt6, lstPt7, lstPt8;
|
||
::GetTHSplitPts(*pts3[0], *pts4[1], vtMid2, vtEnd, g_nSplitNum, lstPt5);
|
||
::GetTHSplitPts(*pts3[3], *pts4[2], vtMid2, vtEnd, g_nSplitNum, lstPt6);
|
||
::GetTHSplitPts(*pts3[1], *pts4[0], vtMid2, vtEnd, g_nSplitNum, lstPt7);
|
||
::GetTHSplitPts(*pts3[2], *pts4[3], vtMid2, vtEnd, g_nSplitNum, lstPt8);
|
||
nLen = lstPt5.Length();
|
||
if (nLen!=g_nSplitNum+2 || lstPt6.Length()!=nLen || lstPt7.Length()!=nLen
|
||
|| lstPt8.Length()!=nLen)
|
||
return Acad::eInvalidInput;
|
||
|
||
for (m=0; m<nLen-1; m++)
|
||
{
|
||
BOOL bShow1(FALSE), bShow2(FALSE);
|
||
if (m == 0)
|
||
bShow1 = TRUE;
|
||
else if (m == nLen-2)
|
||
bShow2 = TRUE;
|
||
|
||
// 绘制内、外面
|
||
dc << ::GetFace1(*lstPt5[m], *lstPt6[m], *lstPt6[m+1], *lstPt5[m+1], bShow1, TRUE, bShow2);
|
||
dc << ::GetFace1(*lstPt7[m], *lstPt8[m], *lstPt8[m+1], *lstPt7[m+1], bShow1, TRUE, bShow2);
|
||
// 绘制上、下面
|
||
dc << ::GetFace2(*lstPt7[m], *lstPt5[m], *lstPt5[m+1], bShow1, TRUE); // 内
|
||
dc << ::GetFace2(*lstPt8[m], *lstPt6[m], *lstPt6[m+1], bShow1, TRUE);
|
||
dc << ::GetFace2(*lstPt7[m], *lstPt7[m+1], *lstPt5[m+1], TRUE, bShow2); // 外
|
||
dc << ::GetFace2(*lstPt8[m], *lstPt8[m+1], *lstPt6[m+1], TRUE, bShow2);
|
||
}
|
||
return Acad::eOk;
|
||
}
|
||
|
||
// 斜接乙字弯
|
||
AcGePlane plane1(ptStart.AsAcGePoint3d(), vtStart.AsAcGeVector3d(),
|
||
vtMid1.AsAcGeVector3d());
|
||
AcGePlane plane2(ptEnd.AsAcGePoint3d(), vtEnd.AsAcGeVector3d(),
|
||
vtMid2.AsAcGeVector3d());
|
||
AcGeVector3d vtNormal1 = plane1.normal(),
|
||
vtNormal2 = plane2.normal();
|
||
|
||
XPoint ptSTmp, ptETmp;
|
||
XCurveSegment segTmp1 = ::GetArcSeg3(ptStart, ptSCen, ptSTmp, dRadius1,
|
||
m_dDrawParam, vtNormal1, vtStart);
|
||
XCurveSegment segTmp2 = ::GetArcSeg3(ptEnd, ptECen, ptETmp, dRadius2,
|
||
m_dDrawParam, vtNormal2, vtEnd);
|
||
XVector3D vtSTmp = ptETmp - ptSTmp, // 方向
|
||
vtETmp = ptSTmp - ptETmp;
|
||
|
||
if (fabs(dHStart)<1.0E-6 && fabs(dHEnd)<1.0E-6) // 两个圆管
|
||
{
|
||
XPointList sidePts1, sidePts2;
|
||
::GetTHSplitPts(ptStart, ptSTmp, vtStart, vtSTmp, g_nSplitNum, sidePts1);
|
||
::GetTHSplitPts(ptEnd, ptETmp, vtEnd, vtETmp, g_nSplitNum, sidePts2);
|
||
int nLen = sidePts1.Length(), i(0);
|
||
if (nLen!=g_nSplitNum+2 || sidePts2.Length()!=g_nSplitNum+2)
|
||
return Acad::eInvalidInput;
|
||
|
||
XPoint ptTmp1(*sidePts1[1]), ptTmp2(*sidePts1[g_nSplitNum]),
|
||
ptTmp3(*sidePts2[1]), ptTmp4(*sidePts2[g_nSplitNum]);
|
||
AcGeVector3d vtSpare1 = vtStart.AsAcGeVector3d(),
|
||
vtSpare2 = vtSTmp.AsAcGeVector3d();
|
||
ptTmp1 = ptTmp1 - XVector3D(vtSpare1.normalize()*10);
|
||
ptTmp2 = ptTmp2 - XVector3D(vtSpare2.normalize()*10);
|
||
AcGeVector3d vtSpare3 = vtEnd.AsAcGeVector3d(),
|
||
vtSpare4 = vtETmp.AsAcGeVector3d();
|
||
ptTmp3 = ptTmp3 - XVector3D(vtSpare3.normalize()*10);
|
||
ptTmp4 = ptTmp4 - XVector3D(vtSpare4.normalize()*10);
|
||
|
||
BOOL bIsOk1 = ::GetColumn3DFaces(*sidePts1[0], dWStart/2, vtStart, ptTmp1, dWStart/2,
|
||
vtStart, lstFaces, g_nSplitNum, 2, FALSE, FALSE, FALSE, FALSE),
|
||
bIsOk2 = ::GetColumn3DFaces(ptTmp2, dWStart/2, vtSTmp, *sidePts1[g_nSplitNum+1],
|
||
dWStart/2, vtSTmp, lstFaces, g_nSplitNum, 2, FALSE, FALSE, FALSE, FALSE),
|
||
bIsOk3 = ::GetColumn3DFaces(*sidePts2[0], dWEnd/2, vtEnd, ptTmp3, dWEnd/2, vtEnd,
|
||
lstFaces, g_nSplitNum, 2, FALSE, FALSE, FALSE, FALSE),
|
||
bIsOk4 = ::GetColumn3DFaces(ptTmp4, dWEnd/2, vtETmp, *sidePts2[g_nSplitNum+1],
|
||
dWEnd/2, vtETmp, lstFaces, g_nSplitNum, 2, FALSE, FALSE, FALSE, FALSE);
|
||
if (!bIsOk1 || !bIsOk2 || !bIsOk3 || !bIsOk4)
|
||
return Acad::eInvalidInput;
|
||
|
||
|
||
AcGeCircArc3d arc1(*sidePts1[1], *sidePts1[g_nSplitNum/2], *sidePts1[g_nSplitNum]),
|
||
arc2(*sidePts2[1], *sidePts2[g_nSplitNum/2], *sidePts2[g_nSplitNum]);
|
||
for (i=1; i<g_nSplitNum; i++)
|
||
{
|
||
AcGeLine3d tangentLine1, tangentLine2, tangentLine3, tangentLine4;
|
||
if (arc1.tangent(sidePts1[i]->AsAcGePoint3d(), tangentLine1)==Adesk::kFalse ||
|
||
arc1.tangent(sidePts1[i+1]->AsAcGePoint3d(), tangentLine2)==Adesk::kFalse)
|
||
return Acad::eInvalidInput;
|
||
if (arc2.tangent(sidePts2[i]->AsAcGePoint3d(), tangentLine3)==Adesk::kFalse ||
|
||
arc2.tangent(sidePts2[i+1]->AsAcGePoint3d(), tangentLine4)==Adesk::kFalse)
|
||
return Acad::eInvalidInput;
|
||
|
||
AcGeVector3d vtTmp1 = tangentLine1.direction(),
|
||
vtTmp2 = tangentLine2.direction(),
|
||
vtTmp3 = tangentLine3.direction(),
|
||
vtTmp4 = tangentLine4.direction();
|
||
BOOL bIsOk1 = ::GetColumn3DFaces(*sidePts1[i], dWStart/2.0, XVector3D(vtTmp1),
|
||
*sidePts1[i+1], dWStart/2.0, XVector3D(vtTmp2), lstFaces, g_nSplitNum, 2,
|
||
FALSE, FALSE, FALSE, FALSE),
|
||
bIsOk2 = ::GetColumn3DFaces(*sidePts2[i], dWEnd/2.0, XVector3D(vtTmp3),
|
||
*sidePts2[i+1], dWEnd/2.0, XVector3D(vtTmp4), lstFaces, g_nSplitNum, 2,
|
||
FALSE, FALSE, FALSE, FALSE);
|
||
if (!bIsOk1 || !bIsOk2)
|
||
break;
|
||
}
|
||
|
||
bIsOk1 = ::GetColumn3DFaces(ptSTmp, dWStart/2, vtSTmp, ptETmp, dWEnd/2,
|
||
vtSTmp, lstFaces, g_nSplitNum, 2, FALSE, FALSE, FALSE, FALSE);
|
||
if (!bIsOk1)
|
||
return Acad::eInvalidInput;
|
||
|
||
nLen = lstFaces.Length();
|
||
for (i=0; i<nLen; i++)
|
||
dc << *lstFaces[i];
|
||
return Acad::eOk;
|
||
}
|
||
else // 两个方管
|
||
{
|
||
XPointList segPts1, segPts2, segPts3, segPts4;
|
||
::GetDuctSidePts(ptStart, dWStart, dHStart, vtStart, segPts1);
|
||
::GetDuctSidePts(ptSTmp, dWStart, dHStart, vtSTmp, segPts2);
|
||
::GetDuctSidePts(ptEnd, dWEnd, dHEnd, vtEnd, segPts3);
|
||
::GetDuctSidePts(ptETmp, dWEnd, dHEnd, vtETmp, segPts4);
|
||
if (segPts1.Length()!=4 || segPts2.Length()!=4 || segPts3.Length()!=4
|
||
|| segPts4.Length()!=4) // 管端截面的四个角点
|
||
return Acad::eInvalidInput;
|
||
|
||
XPointList pts1, pts2, pts3, pts4, pts5, pts6, pts7, pts8;
|
||
::GetTHSplitPts(*segPts1[1], *segPts2[0], vtStart, vtSTmp, g_nSplitNum, pts1);
|
||
::GetTHSplitPts(*segPts1[2], *segPts2[3], vtStart, vtSTmp, g_nSplitNum, pts2);
|
||
::GetTHSplitPts(*segPts1[0], *segPts2[1], vtStart, vtSTmp, g_nSplitNum, pts3);
|
||
::GetTHSplitPts(*segPts1[3], *segPts2[2], vtStart, vtSTmp, g_nSplitNum, pts4);
|
||
::GetTHSplitPts(*segPts3[1], *segPts4[0], vtEnd, vtETmp, g_nSplitNum, pts5);
|
||
::GetTHSplitPts(*segPts3[2], *segPts4[3], vtEnd, vtETmp, g_nSplitNum, pts6);
|
||
::GetTHSplitPts(*segPts3[0], *segPts4[1], vtEnd, vtETmp, g_nSplitNum, pts7);
|
||
::GetTHSplitPts(*segPts3[3], *segPts4[2], vtEnd, vtETmp, g_nSplitNum, pts8);
|
||
int nLen = pts1.Length();
|
||
if (nLen!=g_nSplitNum+2 || pts2.Length()!=nLen || pts3.Length()!=nLen || pts4.Length()!=nLen
|
||
|| pts5.Length()!=nLen || pts6.Length()!=nLen || pts7.Length()!=nLen || pts8.Length()!=nLen)
|
||
return Acad::eInvalidInput;
|
||
for (int m=0; m<nLen-1; m++)
|
||
{
|
||
BOOL bShow1(FALSE), bShow2(FALSE);
|
||
if (m == 0)
|
||
bShow2 = TRUE;
|
||
else if (m == nLen - 2)
|
||
bShow1 = TRUE;
|
||
|
||
// 绘制内、外面
|
||
dc << ::GetFace1(*pts1[m], *pts2[m], *pts2[m+1], *pts1[m+1], bShow2, TRUE, bShow1);
|
||
dc << ::GetFace1(*pts3[m], *pts4[m], *pts4[m+1], *pts3[m+1], bShow2, TRUE, bShow1);
|
||
dc << ::GetFace1(*pts5[m], *pts6[m], *pts6[m+1], *pts5[m+1], bShow2, TRUE, bShow1);
|
||
dc << ::GetFace1(*pts7[m], *pts8[m], *pts8[m+1], *pts7[m+1], bShow2, TRUE, bShow1);
|
||
// 绘制上下面
|
||
dc << ::GetFace2(*pts1[m], *pts1[m+1], *pts3[m+1], TRUE, bShow1);
|
||
dc << ::GetFace2(*pts2[m], *pts2[m+1], *pts4[m+1], TRUE, bShow1);
|
||
dc << ::GetFace2(*pts1[m], *pts3[m], *pts3[m+1], bShow2, TRUE);
|
||
dc << ::GetFace2(*pts2[m], *pts4[m], *pts4[m+1], bShow2, TRUE);
|
||
dc << ::GetFace2(*pts5[m], *pts5[m+1], *pts7[m+1], TRUE, bShow1);
|
||
dc << ::GetFace2(*pts6[m], *pts6[m+1], *pts8[m+1], TRUE, bShow1);
|
||
dc << ::GetFace2(*pts5[m], *pts7[m], *pts7[m+1], bShow2, TRUE);
|
||
dc << ::GetFace2(*pts6[m], *pts8[m], *pts8[m+1], bShow2, TRUE);
|
||
}
|
||
|
||
dc << ::GetFace1(*segPts2[0], *segPts2[1], *segPts4[0], *segPts4[1]);
|
||
dc << ::GetFace1(*segPts2[1], *segPts2[2], *segPts4[3], *segPts4[0]);
|
||
dc << ::GetFace1(*segPts2[2], *segPts2[3], *segPts4[2], *segPts4[3]);
|
||
dc << ::GetFace1(*segPts2[3], *segPts2[0], *segPts4[1], *segPts4[2]);
|
||
}
|
||
return Acad::eOk;
|
||
}
|
||
|
||
|
||
////////////////////////////三通////////////////////////////
|
||
Acad::ErrorStatus TDbDuctNode::Draw3T3D(XExplodeDraw &dc) const
|
||
{
|
||
if (GetInterfaceNum() != 3) // 保证链表不越界
|
||
return Acad::eInvalidInput;
|
||
XPointList lstBasePts;
|
||
GetPtsIFace(lstBasePts, FALSE, TRUE, FALSE, FALSE); // 1、获取与管线相连点,注:考虑法兰遮挡节点
|
||
if (lstBasePts.Length() != 3)
|
||
return Acad::eInvalidInput;
|
||
|
||
int nSum(0), i(0);
|
||
for (i=0; i<3; i++)
|
||
{
|
||
const XVector3D &vt = GetIDirection(i); // 2、判断有几根立管
|
||
if (fabs(vt.x)<1.0E-6 && fabs(vt.y)<1.0E-6)
|
||
nSum += (2*i+1);
|
||
}
|
||
|
||
if (nSum == 9) // 连接了三根立管
|
||
return Acad::eInvalidInput;
|
||
int nMain(m_nMain); // 注:临时修正主管编号,方便计算
|
||
if (nSum==4 || nSum==6 || nSum==8) { // 连接了两根立管,nMain为向上的立管
|
||
int nHDuct(0), nVDuct1(-1), nVDuct2(-1), nTmp(5);
|
||
if (nSum == 4) // 获取水平管编号
|
||
nHDuct = 2;
|
||
else if (nSum == 6)
|
||
nHDuct = 1;
|
||
::GetAnotherPipe(nHDuct, nVDuct1, nVDuct2, nTmp); // 获取立管编号
|
||
|
||
const XVector3D &vtVDuct = GetIDirection(nVDuct1);
|
||
if (vtVDuct.z > 1.0E-6)
|
||
nMain = nVDuct1;
|
||
else
|
||
nMain = nVDuct2;
|
||
}
|
||
else if (nSum==1 || nSum==3 || nSum==5) { // 连接了一根立管
|
||
int nVDuct(0), nHDuct1(-1), nHDuct2(-1), nTmp(5);
|
||
if (nSum == 3) // 获取立管编号
|
||
nVDuct = 1;
|
||
else if (nSum == 5)
|
||
nVDuct = 2;
|
||
::GetAnotherPipe(nVDuct, nHDuct1, nHDuct2, nTmp);
|
||
nMain = nHDuct1;
|
||
}
|
||
|
||
AcDbIntArray branchArray = GetBranchNums(nMain); // 3、获取支管编号
|
||
if (branchArray.logicalLength() != 2)
|
||
return Acad::eInvalidInput;
|
||
|
||
const XVector3D &vtM = GetIDirection(nMain);
|
||
const XVector3D &vt1 = GetIDirection(branchArray[0]);
|
||
const XVector3D &vt2 = GetIDirection(branchArray[1]);
|
||
double dWidthM = GetIWidth(nMain),
|
||
dWidth1 = GetIWidth(branchArray[0]),
|
||
dWidth2 = GetIWidth(branchArray[1]),
|
||
dHighM = GetIHeight(nMain),
|
||
dHigh1 = GetIHeight(branchArray[0]),
|
||
dHigh2 = GetIHeight(branchArray[1]);
|
||
BOOL bMDuctIsCircle(FALSE);
|
||
if (fabs(dHighM) < 1.0E-6) { // 注:暂时圆管按照方管处理
|
||
dHighM = dWidthM;
|
||
bMDuctIsCircle = TRUE;
|
||
}
|
||
if (fabs(dHigh1) < 1.0E-6)
|
||
dHigh1 = dWidth1;
|
||
if (fabs(dHigh2) < 1.0E-6)
|
||
dHigh2 = dWidth2;
|
||
XPointList ptsM, pts1, pts2;
|
||
::GetDuctSidePts(*lstBasePts[nMain], dWidthM, dHighM, vtM, ptsM);
|
||
::GetDuctSidePts(*lstBasePts[branchArray[0]], dWidth1, dHigh1, vt1, pts1);
|
||
::GetDuctSidePts(*lstBasePts[branchArray[1]], dWidth2, dHigh2, vt2, pts2);
|
||
if (pts1.Length()!=4 || pts2.Length()!=4 || ptsM.Length()!=4) // 4、获取风管边线点
|
||
return Acad::eInvalidInput;
|
||
|
||
// 5、根据连接立管数量的不同,绘制不同的样式
|
||
if (nSum==4 || nSum==6 || nSum==8) { // 连接了两根立管
|
||
BOOL bIsBranch2 = ::IsParallel(vtM, vt2);
|
||
int nBranch = bIsBranch2?branchArray[1]:branchArray[0]; // 向下的立管
|
||
double dW = bIsBranch2?dWidth2:dWidth1,
|
||
dH = bIsBranch2?dHigh2:dHigh1;
|
||
double dVDAngle = GetIVDAngle(nMain);
|
||
if (bMDuctIsCircle) { // 立管为圆管
|
||
double dTmpAngle = GetIAngle(nBranch);
|
||
dVDAngle = dTmpAngle + PI/2;
|
||
}
|
||
|
||
XPoly2D polyM(1), polyB(1); // 主截面
|
||
::GetSquare(*lstBasePts[nMain], dVDAngle, dWidthM, dHighM, &polyM, NULL);
|
||
::GetSquare(*lstBasePts[nBranch], dVDAngle, dW, dH, &polyB, NULL);
|
||
if (polyM.Length()!=4 || polyB.Length()!=4)
|
||
return Acad::eInvalidInput;
|
||
dc << ::GetFace1(*polyM[0], *polyM[1], *polyB[1], *polyB[0]);
|
||
dc << ::GetFace1(*polyM[1], *polyM[2], *polyB[2], *polyB[1]);
|
||
dc << ::GetFace1(*polyM[2], *polyM[3], *polyB[3], *polyB[2]);
|
||
dc << ::GetFace1(*polyM[3], *polyM[0], *polyB[0], *polyB[3]);
|
||
|
||
int nHNum(-1), nAnother(5), nIndex(1);
|
||
::GetAnotherPipe(nMain, nBranch, nHNum, nAnother);
|
||
double dHAngle = GetIAngle(nHNum),
|
||
dAng = CT_std_angle(dHAngle - dVDAngle); // 夹角
|
||
if (fabs(dAng) < 1.0E-6)
|
||
nIndex = 0;
|
||
else if (fabs(dAng-PI*0.5) < 1.0E-6)
|
||
nIndex = 3;
|
||
else if (fabs(dAng-PI) < 1.0E-6)
|
||
nIndex = 2;
|
||
|
||
int nSerialNum[4][3] = {{1, 0, 0}, {2, 1, 1}, {3, 2, 2}, {0, 3, 3}};
|
||
int nNum0 = nSerialNum[nIndex][0],
|
||
nNum1 = nSerialNum[nIndex][1],
|
||
nNum2 = nSerialNum[nIndex][2];
|
||
AcGePoint3d ptM1 = polyM[nNum0]->AsAcGePoint3d(),
|
||
ptM2 = polyM[nNum1]->AsAcGePoint3d(),
|
||
ptB1 = polyB[nNum2]->AsAcGePoint3d();
|
||
AcGePlane plane(ptM2, ptM1, ptB1);
|
||
|
||
XPointList tmpPts;
|
||
for (i=0; i<4; i++)
|
||
{
|
||
AcGePoint3d ptTmp1;
|
||
if (bIsBranch2)
|
||
ptTmp1 = pts1[i]->AsAcGePoint3d();
|
||
else
|
||
ptTmp1 = pts2[i]->AsAcGePoint3d();
|
||
|
||
AcGePoint3d ptTmp2 = ptTmp1.orthoProject(plane);
|
||
if (nIndex==0 || nIndex==2) {
|
||
double dZ = ptTmp2.z;
|
||
double dDist1 = ptTmp2.distanceTo(ptM1),
|
||
dDist2 = ptTmp2.distanceTo(ptM2);
|
||
if (dDist1 > (dDist2+1.0E-6))
|
||
ptTmp2 = AcGePoint3d(ptM2.x, ptM2.y, dZ);
|
||
else
|
||
ptTmp2 = AcGePoint3d(ptM1.x, ptM1.y, dZ);
|
||
}
|
||
tmpPts.Append(new XPoint(ptTmp2));
|
||
}
|
||
|
||
if (tmpPts.Length() != 4)
|
||
return Acad::eInvalidInput;
|
||
if (bIsBranch2) {
|
||
dc << ::GetFace1(*pts1[0], *pts1[1], *tmpPts[1], *tmpPts[0]);
|
||
dc << ::GetFace1(*pts1[1], *pts1[2], *tmpPts[2], *tmpPts[1]);
|
||
dc << ::GetFace1(*pts1[2], *pts1[3], *tmpPts[3], *tmpPts[2]);
|
||
dc << ::GetFace1(*pts1[3], *pts1[0], *tmpPts[0], *tmpPts[3]);
|
||
}
|
||
else {
|
||
dc << ::GetFace1(*pts2[0], *pts2[1], *tmpPts[1], *tmpPts[0]);
|
||
dc << ::GetFace1(*pts2[1], *pts2[2], *tmpPts[2], *tmpPts[1]);
|
||
dc << ::GetFace1(*pts2[2], *pts2[3], *tmpPts[3], *tmpPts[2]);
|
||
dc << ::GetFace1(*pts2[3], *pts2[0], *tmpPts[0], *tmpPts[3]);
|
||
}
|
||
return Acad::eOk;
|
||
}
|
||
|
||
if (nSum==1 || nSum==3 || nSum==5) { // 连接了一根立管
|
||
dc << ::GetFace1(*ptsM[0], *ptsM[1], *pts2[0], *pts2[1]);
|
||
dc << ::GetFace1(*ptsM[1], *ptsM[2], *pts2[3], *pts2[0]);
|
||
dc << ::GetFace1(*ptsM[2], *ptsM[3], *pts2[2], *pts2[3]);
|
||
dc << ::GetFace1(*ptsM[3], *ptsM[0], *pts2[1], *pts2[2]);
|
||
|
||
XPoly2D polyV(1); // 主截面
|
||
double dVDAngle = GetIVDAngle(branchArray[0]);
|
||
::GetSquare(*lstBasePts[branchArray[0]], dVDAngle, dWidth1, dHigh1, &polyV, NULL);
|
||
if (polyV.Length() != 4)
|
||
return Acad::eInvalidInput;
|
||
|
||
const XVector3D &vtVDuct = GetIDirection(branchArray[0]);
|
||
AcGePlane plane;
|
||
if (vtVDuct.z>1.0E-6) // 向上的立管
|
||
plane.set(ptsM[1]->AsAcGePoint3d(), ptsM[0]->AsAcGePoint3d(), pts2[1]->AsAcGePoint3d());
|
||
else
|
||
plane.set(ptsM[2]->AsAcGePoint3d(), ptsM[3]->AsAcGePoint3d(), pts2[2]->AsAcGePoint3d());
|
||
|
||
XPointList tmpPts;
|
||
for (i=0; i<4; i++)
|
||
{
|
||
AcGePoint3d ptTmp1 = polyV[i]->AsAcGePoint3d(),
|
||
ptTmp2 = ptTmp1.orthoProject(plane);
|
||
tmpPts.Append(new XPoint(ptTmp2));
|
||
}
|
||
|
||
dc << ::GetFace1(*polyV[0], *tmpPts[0], *tmpPts[1], *polyV[1]);
|
||
dc << ::GetFace1(*polyV[1], *tmpPts[1], *tmpPts[2], *polyV[2]);
|
||
dc << ::GetFace1(*polyV[2], *tmpPts[2], *tmpPts[3], *polyV[3]);
|
||
dc << ::GetFace1(*polyV[3], *tmpPts[3], *tmpPts[0], *polyV[0]);
|
||
return Acad::eOk;
|
||
}
|
||
|
||
XPointList lstPt1, lstPt2, lstPt3, lstPt4, lstPt5, lstPt6;
|
||
::GetTHSplitPts(*ptsM[0], *pts1[1], vtM, vt1, 1, lstPt1);
|
||
::GetTHSplitPts(*ptsM[3], *pts1[2], vtM, vt1, 1, lstPt2),
|
||
::GetTHSplitPts(*ptsM[1], *pts2[0], vtM, vt2, 1, lstPt3),
|
||
::GetTHSplitPts(*ptsM[2], *pts2[3], vtM, vt2, 1, lstPt4),
|
||
::GetTHSplitPts(*pts1[0], *pts2[1], vt1, vt2, 1, lstPt5),
|
||
::GetTHSplitPts(*pts1[3], *pts2[2], vt1, vt2, 1, lstPt6);
|
||
if (lstPt1.Length()!=3 || lstPt2.Length()!=3 || lstPt3.Length()!=3 ||
|
||
lstPt4.Length()!=3 || lstPt5.Length()!=3 || lstPt6.Length()!=3)
|
||
return Acad::eInvalidInput;
|
||
|
||
dc << ::GetFace1(*lstPt1[1], *lstPt3[1], *ptsM[1], *ptsM[0], FALSE); // 绘制上下面
|
||
dc << ::GetFace1(*lstPt2[1], *lstPt4[1], *ptsM[2], *ptsM[3], FALSE);
|
||
dc << ::GetFace1(*lstPt3[1], *lstPt5[1], *pts2[1], *pts2[0], FALSE);
|
||
dc << ::GetFace1(*lstPt4[1], *lstPt6[1], *pts2[2], *pts2[3], FALSE);
|
||
dc << ::GetFace1(*lstPt5[1], *lstPt1[1], *pts1[1], *pts1[0], FALSE);
|
||
dc << ::GetFace1(*lstPt6[1], *lstPt2[1], *pts1[2], *pts1[3], FALSE);
|
||
dc << ::GetFace2(*lstPt1[1], *lstPt3[1], *lstPt5[1]);
|
||
dc << ::GetFace2(*lstPt2[1], *lstPt4[1], *lstPt6[1]);
|
||
|
||
if (m_nDrawMod==4 || m_nDrawMod==5) { // Y型
|
||
dc << ::GetFace1(*lstPt1[0], *lstPt2[0], *lstPt2[1], *lstPt1[1]);
|
||
dc << ::GetFace1(*lstPt1[1], *lstPt2[1], *lstPt2[2], *lstPt1[2]);
|
||
dc << ::GetFace1(*lstPt3[0], *lstPt4[0], *lstPt4[1], *lstPt3[1]);
|
||
dc << ::GetFace1(*lstPt3[1], *lstPt4[1], *lstPt4[2], *lstPt3[2]);
|
||
|
||
BOOL bShow(FALSE);
|
||
if (::IsParallel(vt1, vt2) == 0) // 不平行
|
||
bShow = TRUE;
|
||
dc << ::GetFace1(*lstPt5[1], *lstPt6[1], *lstPt6[0], *lstPt5[0], bShow);
|
||
dc << ::GetFace1(*lstPt5[1], *lstPt6[1], *lstPt6[2], *lstPt5[2], bShow);
|
||
}
|
||
else { // 其他样式
|
||
dc << ::GetFace1(*lstPt5[0], *lstPt6[0], *lstPt6[1], *lstPt5[1]);
|
||
dc << ::GetFace1(*lstPt5[1], *lstPt6[1], *lstPt6[2], *lstPt5[2]);
|
||
|
||
if (::IsParallel(vtM, vt1) !=0) {
|
||
dc << ::GetFace1(*lstPt1[0], *lstPt2[0], *lstPt2[2], *lstPt1[2]);
|
||
dc << ::GetFace1(*lstPt3[0], *lstPt4[0], *lstPt4[1], *lstPt3[1]);
|
||
dc << ::GetFace1(*lstPt3[1], *lstPt4[1], *lstPt4[2], *lstPt3[2]);
|
||
}
|
||
else if (::IsParallel(vtM, vt2) != 0) {
|
||
dc << ::GetFace1(*lstPt3[0], *lstPt4[0], *lstPt4[2], *lstPt3[2]);
|
||
dc << ::GetFace1(*lstPt1[0], *lstPt2[0], *lstPt2[1], *lstPt1[1]);
|
||
dc << ::GetFace1(*lstPt1[1], *lstPt2[1], *lstPt2[2], *lstPt1[2]);
|
||
}
|
||
else {
|
||
dc << ::GetFace1(*lstPt1[0], *lstPt2[0], *lstPt2[1], *lstPt1[1]);
|
||
dc << ::GetFace1(*lstPt1[1], *lstPt2[1], *lstPt2[2], *lstPt1[2]);
|
||
dc << ::GetFace1(*lstPt3[0], *lstPt4[0], *lstPt4[1], *lstPt3[1]);
|
||
dc << ::GetFace1(*lstPt3[1], *lstPt4[1], *lstPt4[2], *lstPt3[2]);
|
||
}
|
||
}
|
||
return Acad::eOk;
|
||
}
|
||
|
||
|
||
////////////////////////////四通////////////////////////////
|
||
Acad::ErrorStatus TDbDuctNode::Draw4T3D(XExplodeDraw &dc) const
|
||
{
|
||
if (GetInterfaceNum() != 4) // 保证链表不越界
|
||
return Acad::eInvalidInput;
|
||
XPointList lstBasePts;
|
||
GetPtsIFace(lstBasePts, FALSE, TRUE, FALSE, FALSE); // 1、获取与管线相连点,注:考虑法兰遮挡节点
|
||
if (lstBasePts.Length() != 4)
|
||
return Acad::eInvalidInput;
|
||
AcDbIntArray branchArray = GetBranchNums(m_nMain); // 2、获取支管编号
|
||
if (branchArray.logicalLength() != 3)
|
||
return Acad::eInvalidInput;
|
||
|
||
const XVector3D &vtM = GetIDirection(m_nMain);
|
||
const XVector3D &vt1 = GetIDirection(branchArray[0]);
|
||
const XVector3D &vt2 = GetIDirection(branchArray[1]);
|
||
const XVector3D &vt3 = GetIDirection(branchArray[2]);
|
||
double dWidthM = GetIWidth(m_nMain),
|
||
dWidth1 = GetIWidth(branchArray[0]),
|
||
dWidth2 = GetIWidth(branchArray[1]),
|
||
dWidth3 = GetIWidth(branchArray[2]),
|
||
dHighM = GetIHeight(m_nMain),
|
||
dHigh1 = GetIHeight(branchArray[0]),
|
||
dHigh2 = GetIHeight(branchArray[1]),
|
||
dHigh3 = GetIHeight(branchArray[1]);
|
||
if (fabs(dHighM) < 1.0E-6) // 注:暂时圆管按照方管处理
|
||
dHighM = dWidthM;
|
||
if (fabs(dHigh1) < 1.0E-6)
|
||
dHigh1 = dWidth1;
|
||
if (fabs(dHigh2) < 1.0E-6)
|
||
dHigh2 = dWidth2;
|
||
if (fabs(dHigh3) < 1.0E-6)
|
||
dHigh3 = dWidth3;
|
||
XPointList ptsM, pts1, pts2, pts3;
|
||
::GetDuctSidePts(*lstBasePts[m_nMain], dWidthM, dHighM, vtM, ptsM);
|
||
::GetDuctSidePts(*lstBasePts[branchArray[0]], dWidth1, dHigh1, vt1, pts1);
|
||
::GetDuctSidePts(*lstBasePts[branchArray[1]], dWidth2, dHigh2, vt2, pts2);
|
||
::GetDuctSidePts(*lstBasePts[branchArray[2]], dWidth3, dHigh3, vt3, pts3);
|
||
// 3、获取风管边线点
|
||
if (pts1.Length()!=4 || pts2.Length()!=4 || ptsM.Length()!=4 || pts3.Length()!=4)
|
||
return Acad::eInvalidInput;
|
||
|
||
XPointList lstPt1, lstPt2, lstPt3, lstPt4, lstPt5, lstPt6, lstPt7, lstPt8;
|
||
::GetTHSplitPts(*ptsM[0], *pts1[1], vtM, vt1, 1, lstPt1);
|
||
::GetTHSplitPts(*ptsM[3], *pts1[2], vtM, vt1, 1, lstPt2);
|
||
::GetTHSplitPts(*ptsM[1], *pts3[0], vtM, vt3, 1, lstPt3);
|
||
::GetTHSplitPts(*ptsM[2], *pts3[3], vtM, vt3, 1, lstPt4);
|
||
::GetTHSplitPts(*pts2[0], *pts3[1], vt2, vt3, 1, lstPt5);
|
||
::GetTHSplitPts(*pts2[3], *pts3[2], vt2, vt3, 1, lstPt6);
|
||
::GetTHSplitPts(*pts2[1], *pts1[0], vt2, vt1, 1, lstPt7);
|
||
::GetTHSplitPts(*pts2[2], *pts1[3], vt2, vt1, 1, lstPt8);
|
||
if (lstPt1.Length()!=3 || lstPt2.Length()!=3 || lstPt3.Length()!=3 || lstPt4.Length()!=3 ||
|
||
lstPt5.Length()!=3 || lstPt6.Length()!=3 || lstPt7.Length()!=3 || lstPt8.Length()!=3)
|
||
return Acad::eInvalidInput;
|
||
|
||
dc << ::GetFace1(*lstPt1[1], *lstPt3[1], *ptsM[1], *ptsM[0], FALSE); // 绘制上下面
|
||
dc << ::GetFace1(*lstPt2[1], *lstPt4[1], *ptsM[2], *ptsM[3], FALSE);
|
||
dc << ::GetFace1(*lstPt3[1], *lstPt5[1], *pts3[1], *pts3[0], FALSE);
|
||
dc << ::GetFace1(*lstPt4[1], *lstPt6[1], *pts3[2], *pts3[3], FALSE);
|
||
dc << ::GetFace1(*lstPt5[1], *lstPt7[1], *pts2[1], *pts2[0], FALSE);
|
||
dc << ::GetFace1(*lstPt6[1], *lstPt8[1], *pts2[2], *pts2[3], FALSE);
|
||
dc << ::GetFace1(*lstPt7[1], *lstPt1[1], *pts1[1], *pts1[0], FALSE);
|
||
dc << ::GetFace1(*lstPt8[1], *lstPt2[1], *pts1[2], *pts1[3], FALSE);
|
||
dc << ::GetFace1(*lstPt1[1], *lstPt3[1], *lstPt5[1], *lstPt7[1], FALSE, FALSE, FALSE, FALSE);
|
||
dc << ::GetFace1(*lstPt2[1], *lstPt4[1], *lstPt6[1], *lstPt8[1], FALSE, FALSE, FALSE, FALSE);
|
||
|
||
dc << ::GetFace1(*lstPt1[0], *lstPt2[0], *lstPt2[1], *lstPt1[1]); // 绘制边面
|
||
dc << ::GetFace1(*lstPt1[1], *lstPt2[1], *lstPt2[2], *lstPt1[2]);
|
||
dc << ::GetFace1(*lstPt3[0], *lstPt4[0], *lstPt4[1], *lstPt3[1]);
|
||
dc << ::GetFace1(*lstPt3[1], *lstPt4[1], *lstPt4[2], *lstPt3[2]);
|
||
dc << ::GetFace1(*lstPt5[0], *lstPt6[0], *lstPt6[1], *lstPt5[1]);
|
||
dc << ::GetFace1(*lstPt5[1], *lstPt6[1], *lstPt6[2], *lstPt5[2]);
|
||
dc << ::GetFace1(*lstPt7[0], *lstPt8[0], *lstPt8[1], *lstPt7[1]);
|
||
dc << ::GetFace1(*lstPt7[1], *lstPt8[1], *lstPt8[2], *lstPt7[2]);
|
||
return Acad::eOk;
|
||
}
|
||
|
||
|
||
BOOL TDbDuctNode::DrawCube3d(XPoint pt1, int nIndex1, XPoint pt2, int nIndex2,
|
||
XVector3D vt, DList<X3DFace> &faces,
|
||
BOOL bShow1, BOOL bShow2) const
|
||
{
|
||
double dWidth1 = GetIWidth(nIndex1),
|
||
dHigh1 = GetIHeight(nIndex1);
|
||
if (fabs(dHigh1) < 1.0E-3)
|
||
{
|
||
dHigh1 = dWidth1;
|
||
}
|
||
|
||
double dWidth2 = GetIWidth(nIndex2),
|
||
dHigh2 = GetIHeight(nIndex2);
|
||
if (fabs(dHigh2) < 1.0E-3)
|
||
{
|
||
dHigh2 = dWidth2;
|
||
}
|
||
|
||
XPointList pts1, pts2;
|
||
::GetDuctSidePts(pt1, dWidth1, dHigh1, vt, pts1);
|
||
::GetDuctSidePts(pt2, dWidth2, dHigh2, vt, 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;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/////////////////////////////////////////////////////////////////////////////////
|
||
void InitDbDuctNode(BOOL bTrue)
|
||
{
|
||
if (bTrue)
|
||
{
|
||
TDbDuctNode::rxInit();
|
||
TDbDuctNode::InitMatchProtocol(TRUE);
|
||
}
|
||
else
|
||
{
|
||
deleteAcRxClass(TDbDuctNode::desc());
|
||
TDbDuctNode::InitMatchProtocol(FALSE);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
////////////////////////////////所需全局函数/////////////////////////////////////
|
||
// 注:1、主要用于获取管径不等时,弯头中的弧段
|
||
// 2、其中,1为已知圆心的情况,2为已知角顶点的情况
|
||
XCurveSegment GetArcSeg1(XPoint pt1, XPoint ptCen, XPoint pt2,
|
||
double dWidth1, double dWidth2)
|
||
{
|
||
XPoint ptArcMid;
|
||
BOOL bSwitch(TRUE);
|
||
XArc arc = ::GetRightArc(pt1, ptCen, pt2, bSwitch); // 获取优弧
|
||
if (fabs(dWidth1 - dWidth2) > 0.001) // 管线宽度不一样
|
||
{
|
||
arc.MidPoint(ptArcMid);
|
||
if (bSwitch)
|
||
arc = XArc(pt1, ptArcMid, pt2);
|
||
else
|
||
arc = XArc(pt2, ptArcMid, pt1);
|
||
}
|
||
|
||
XCurveSegment seg;
|
||
seg = arc;
|
||
return seg;
|
||
}
|
||
|
||
XCurveSegment GetArcSeg2(XPoint pt1, XPoint ptInt, XPoint pt2,
|
||
double dRadius, double dWidth1, double dWidth2)
|
||
{
|
||
XPoint ptTmp1, ptTmp2, ptTmpCen;
|
||
AT_cal_fillet(pt1, ptInt, pt2, dRadius, ptTmp1, ptTmpCen, ptTmp2, FALSE); // 获取圆心
|
||
XCurveSegment seg = ::GetArcSeg1(pt1, ptTmpCen, pt2, dWidth1, dWidth2);
|
||
return seg;
|
||
}
|
||
|
||
|
||
XCurveSegment GetArcSeg3(XPoint ptStart, XPoint ptCen, XPoint &ptEnd,
|
||
double dRadius, double dAngle,
|
||
const AcGeVector3d &vecNormal, const AcGeVector3d &vecRef)
|
||
{
|
||
AcGePoint3d pt1 = ptStart.AsAcGePoint3d(),
|
||
pt2 = ptCen.AsAcGePoint3d();
|
||
AcGeVector3d vec1 = pt1 - pt2,
|
||
vec2 = pt1 - pt2;
|
||
vec1 = vec1.rotateBy(dAngle, vecNormal);
|
||
vec2 = vec2.rotateBy(2*PI-dAngle, vecNormal);
|
||
|
||
XCurveSegment seg;
|
||
double dDotProduct = vec1.dotProduct(vecRef);
|
||
if (dDotProduct > 1.0E-6)
|
||
{
|
||
vec2 = vec2.normalize();
|
||
AcGePoint3d ptTmp = pt2 + vec2*dRadius;
|
||
ptEnd = XPoint(ptTmp);
|
||
XArc arc(ptEnd, ptStart, dAngle);
|
||
seg = arc;
|
||
}
|
||
else
|
||
{
|
||
vec1 = vec1.normalize();
|
||
AcGePoint3d ptTmp = pt2 + vec1*dRadius;
|
||
ptEnd = XPoint(ptTmp);
|
||
XArc arc(ptStart, ptEnd, dAngle);
|
||
seg = arc;
|
||
}
|
||
return seg;
|
||
}
|
||
|
||
|
||
/*============================================================================*
|
||
* 函 数 名: GetDuctTrueMidPts
|
||
* 功能描述: 将连接件的位置点ptLoc,向各管线的中线做投影,获取投影点
|
||
* 备 注: 主要用于带偏心的三、四通绘制
|
||
==============================================================================*/
|
||
void GetDuctTrueMidPts(AcDbObjectId id, XPoint ptLoc,
|
||
const DList<AcDbObjectId> &ids,
|
||
const AcDbIntArray &types, XPointList &lstPts)
|
||
{
|
||
lstPts.Reset();
|
||
DList<XCurveSegment> lstSegs;
|
||
::GetSegs(id, ptLoc, ids, types, lstSegs);
|
||
int nLen = ids.Length();
|
||
if (lstSegs.Length() != nLen)
|
||
{
|
||
return;
|
||
}
|
||
|
||
for (int i=0; i<nLen; i++)
|
||
{
|
||
XPoint ptRes;
|
||
lstSegs[i]->ProjectToMe(ptLoc, ptRes);
|
||
lstPts.Append(new XPoint(ptRes));
|
||
}
|
||
}
|
||
|
||
|
||
/*============================================================================*
|
||
* 函 数 名: GetDuctSidePts
|
||
* 功能描述: 根据中线点ptMid,获取边线的四个角点
|
||
* 备 注: 如果是圆,则取其外接矩形;vtDraw为节点中的GetIDirection(i)
|
||
==============================================================================*/
|
||
void GetDuctSidePts(XPoint ptMid, double dWidth, double dHigh,
|
||
XVector3D vtDraw, XPointList &lstPt)
|
||
{
|
||
AcGeVector3d vt1 = vtDraw.AsAcGeVector3d(), // 长度方向
|
||
vt2 = vt1.perpVector(), // 宽度方向
|
||
vt3 = vt1.crossProduct(vt2); // 高度方向
|
||
|
||
XVector3D vtZ(vt3);
|
||
vtZ.Normalize();
|
||
vtZ.Scale(dHigh/2.0);
|
||
XPoint ptTmp1 = ptMid + vtZ,
|
||
ptTmp2 = ptMid - vtZ;
|
||
|
||
XVector3D vtY(vt2);
|
||
vtY.Normalize();
|
||
vtY.Scale(dWidth/2.0);
|
||
XPoint pt1 = ptTmp1 + vtY,
|
||
pt2 = ptTmp1 - vtY,
|
||
pt4 = ptTmp2 + vtY,
|
||
pt3 = ptTmp2 - vtY;
|
||
|
||
lstPt.Reset();
|
||
lstPt.Append(new XPoint(pt1));
|
||
lstPt.Append(new XPoint(pt2));
|
||
lstPt.Append(new XPoint(pt3));
|
||
lstPt.Append(new XPoint(pt4));
|
||
}
|
||
|
||
|
||
/*============================================================================*
|
||
* 函 数 名: Get2LineIntPts
|
||
* 功能描述: 求两条线的交点
|
||
==============================================================================*/
|
||
BOOL Get2LineIntPts(AcGePoint3d pt1, AcGePoint3d pt3, AcGePoint3d pt2,
|
||
AcGePoint3d pt4, AcGePoint3d &ptInt)
|
||
{
|
||
AcGePoint3dArray aryPts;
|
||
AcDbLine line1(pt1, pt3),
|
||
line2(pt4, pt2);
|
||
if (line1.intersectWith(&line2, AcDb::kExtendBoth, aryPts) != Acad::eOk)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
if (aryPts.logicalLength() == 1) // 两直线直接相交
|
||
{
|
||
ptInt = aryPts[0];
|
||
return TRUE;
|
||
}
|
||
|
||
AcGeVector3d vec1 = pt1 - pt3,
|
||
vec2 = pt4 - pt2;
|
||
if (vec1.isParallelTo(vec2) == Adesk::kTrue) // 两直线平行
|
||
{
|
||
AcGeVector3d vec = pt1 - pt2;
|
||
ptInt = pt1 - vec*0.5;
|
||
return TRUE;
|
||
}
|
||
|
||
AcGePlane proPlane1(pt3, vec1, vec2); // 投影平面
|
||
AcGePoint3d ptPro1 = pt1.orthoProject(proPlane1), // 先投影到proPlane1平面内
|
||
ptPro2 = pt2.orthoProject(proPlane1),
|
||
ptPro3 = pt3.orthoProject(proPlane1),
|
||
ptPro4 = pt4.orthoProject(proPlane1);
|
||
AcDbLine l1(ptPro1, ptPro3),
|
||
l2(ptPro4, ptPro2);
|
||
AcGePoint3dArray IntPts1;
|
||
if (l1.intersectWith(&l2, AcDb::kExtendBoth, IntPts1) != Acad::eOk) // 求交点
|
||
{
|
||
return FALSE;
|
||
}
|
||
if (IntPts1.logicalLength() < 1) // 没有交点
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
AcGePlane proPlane2(pt4, vec1, vec2);
|
||
ptPro1 = pt1.orthoProject(proPlane2); // 再投影到proPlane2平面内
|
||
ptPro2 = pt2.orthoProject(proPlane2);
|
||
ptPro3 = pt3.orthoProject(proPlane2);
|
||
ptPro4 = pt4.orthoProject(proPlane2);
|
||
AcDbLine l3(ptPro1, ptPro3),
|
||
l4(ptPro4, ptPro2);
|
||
AcGePoint3dArray IntPts2;
|
||
if (l3.intersectWith(&l4, AcDb::kExtendBoth, IntPts2) != Acad::eOk) // 求交点
|
||
{
|
||
return FALSE;
|
||
}
|
||
if (IntPts2.logicalLength() < 1)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
AcGePoint3d ptInt1 = IntPts1[0], // 注:交点只可能有一个
|
||
ptInt2 = IntPts2[0];
|
||
vec1 = ptInt1 - ptInt2;
|
||
ptInt = ptInt1 - vec1*0.5;
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
/*============================================================================*
|
||
* 函 数 名: GetTHSplitPts
|
||
* 功能描述: 将DuctNode中的边线,分隔成指定的份数
|
||
* 备 注: 1、point1、point2:要获得的点的起止点,带Z坐标;
|
||
vt1、vt2:方向(GetIDirection(i));
|
||
pointMid:弧中点,用来确定优劣弧及方向
|
||
2、nSplitNum:从pt1到pt2的曲线上,分隔点的数量
|
||
0——返回2点,直线
|
||
1——返回3点,交点,虾米弯例外
|
||
3、nMod:切割方式
|
||
0——用于弯头,两边为50短线,不够50时,用1
|
||
1——保证中间段为相切弧,取较短距离的0.9
|
||
2——用于风管,整体为一弧段
|
||
3——虾米弯
|
||
==============================================================================*/
|
||
void GetTHSplitPts(XPoint point1, XPoint point2, XVector3D vt1, XVector3D vt2,
|
||
int nSplitNum, XPointList &lstPts, int nMod, XPoint pointMid)
|
||
{
|
||
lstPts.Reset();
|
||
lstPts.Append(new XPoint(point1));
|
||
if (nSplitNum == 0)
|
||
{
|
||
lstPts.Append(new XPoint(point2));
|
||
return; // 注:总2个点
|
||
}
|
||
|
||
AcGePoint3d pt1 = point1.AsAcGePoint3d(),
|
||
pt2 = point2.AsAcGePoint3d();
|
||
AcGeVector3d vec1 = vt1.AsAcGeVector3d(), // 原来向量
|
||
vec2 = vt2.AsAcGeVector3d();
|
||
vec1.normalize();
|
||
vec2.normalize();
|
||
|
||
AcGePoint3d ptInt, ptCen;
|
||
AcGePoint3d pt3 = pt1 - vec1*800, // 确定交点方向
|
||
pt4 = pt2 - vec2*800;
|
||
if (!::Get2LineIntPts(pt1, pt3, pt2, pt4, ptInt)) // 交点
|
||
{
|
||
return; // 注:非正常情况,只有一个点
|
||
}
|
||
|
||
if ((nSplitNum == 1) && (nMod != 3) && (nMod != 2))
|
||
{
|
||
lstPts.Append(new XPoint(ptInt));
|
||
lstPts.Append(new XPoint(point2));
|
||
return; // 注:没有弧段,总3个点
|
||
}
|
||
|
||
|
||
int nMode(nMod);
|
||
double dDist1 = ptInt.distanceTo(pt1),
|
||
dDist2 = ptInt.distanceTo(pt2);
|
||
if ((nMod == 0) && (dDist1<50+1.0E-5 || dDist2<50+1.0E-5))
|
||
{
|
||
nMode = 1; // 不够50长度短线,改为0.9倍短线,注:从此往下应该用nMode
|
||
}
|
||
|
||
if (nMode == 1) // 保证中间段为相切弧,取较短距离的0.9
|
||
{
|
||
vec1 = ptInt - pt1;
|
||
vec2 = ptInt - pt2;
|
||
vec1.normalize();
|
||
vec2.normalize();
|
||
|
||
double dDist = dDist1>(dDist2+1.0E-6)?(0.9*dDist2):(0.9*dDist1); // 距顶点的距离
|
||
AcGePoint3d ptRet1 = ptInt - vec1*dDist,
|
||
ptRet2 = ptInt - vec2*dDist;
|
||
lstPts.Append(new XPoint(ptRet1));
|
||
if (nSplitNum == 2) // 注:没有弧段,总4个点
|
||
{
|
||
lstPts.Append(new XPoint(ptRet2));
|
||
lstPts.Append(new XPoint(point2));
|
||
return;
|
||
}
|
||
|
||
// 3、获得圆弧分隔点
|
||
AcGeVector3d vecTmp = ptRet2 - ptRet1;
|
||
AcGePoint3d ptMid1 = ptRet1 + vecTmp*0.5; // 直线中点
|
||
double dTmpDist1 = ptMid1.distanceTo(ptRet1),
|
||
dTmpDist2 = ptMid1.distanceTo(ptInt),
|
||
dRadius = (dTmpDist1*dDist)/dTmpDist2, // 弧半径
|
||
dTmp = sqrt(dRadius*dRadius + dDist*dDist) - dRadius;
|
||
|
||
vecTmp = ptMid1 - ptInt;
|
||
vecTmp.normalize();
|
||
AcGePoint3d ptMid2 = ptInt + vecTmp*dTmp; // 弧中点
|
||
|
||
AcGeCircArc3d arc(ptRet1, ptMid2, ptRet2); // 4、构造圆弧,平分为nSplitNum-1段
|
||
double dStartParam = arc.paramOf(arc.startPoint()),
|
||
dEndParam = arc.paramOf(arc.endPoint()),
|
||
dLen = arc.length(dStartParam, dEndParam);
|
||
dLen /= (nSplitNum-1);
|
||
for (int i=1; i<nSplitNum-1; i++)
|
||
{
|
||
double dNewParam = arc.paramAtLength(dStartParam, dLen*i);
|
||
AcGePoint3d ptTmp = arc.evalPoint(dNewParam);
|
||
lstPts.Append(new XPoint(ptTmp));
|
||
}
|
||
lstPts.Append(new XPoint(ptRet2));
|
||
lstPts.Append(new XPoint(point2)); // 5、获得全部拆分点
|
||
return;
|
||
}
|
||
|
||
|
||
AcGePoint3d ptA1(pt1), ptA2(pt2);
|
||
if (nMode == 0) // 注:统一代码使用
|
||
{
|
||
ptA1 = pt1 - vec1*50;
|
||
ptA2 = pt2 - vec2*50;
|
||
}
|
||
|
||
AcGeVector3d vec3 = vec1.perpVector(), // 垂直向量
|
||
vec4 = vec2.perpVector(),
|
||
vecLine = ptA2 - ptA1; // 1—>2
|
||
vec3.normalize();
|
||
vec4.normalize();
|
||
|
||
int nAType(0); // 1—>2顺时针
|
||
double dAngle = vec1.angleTo(vec2, AcGeVector3d::kZAxis);
|
||
if (dAngle > PI + 1.0E-6)
|
||
{
|
||
nAType += 1; // 2——>1为顺时针
|
||
}
|
||
|
||
AcGePoint3d ptTmp = pointMid.AsAcGePoint3d();
|
||
if ((nMod == 0) || (nMod == 3)) // 注:弯头为了防止内外弧发生位置错误
|
||
{
|
||
ptTmp = ptInt;
|
||
}
|
||
AcGeVector3d vecPerp = ptTmp - pt1;
|
||
dAngle = vecLine.angleTo(vecPerp, AcGeVector3d::kZAxis);
|
||
if (dAngle > PI + 1.0E-6)
|
||
{
|
||
nAType += 2; // 劣弧
|
||
}
|
||
|
||
AcGePoint3d pt5 = ptA1 + vec3*800, // 确定圆心方向
|
||
pt6 = ptA2 - vec4*800;
|
||
if ((nAType == 2) || (nAType == 3))
|
||
{
|
||
pt5 = ptA1 - vec3*800;
|
||
pt6 = ptA2 + vec4*800;
|
||
}
|
||
|
||
if (!::Get2LineIntPts(ptA1, pt5, ptA2, pt6, ptCen)) // 圆心
|
||
{
|
||
return; // 注:非正常情况,只有一个点
|
||
}
|
||
|
||
vec3 = ptA1 - ptCen;
|
||
vec4 = ptA2 - ptCen;
|
||
dAngle = vec4.angleTo(vec3, AcGeVector3d::kZAxis);
|
||
if (dAngle > PI + 1.0E-6)
|
||
{
|
||
dAngle = 2*PI - dAngle;
|
||
}
|
||
dAngle *= 0.5; // 夹角一半
|
||
|
||
double dDist = ptA1.distanceTo(ptA2)*0.5,
|
||
dRadius = dDist/fabs(sin(dAngle)); // 弧半径
|
||
dDist1 = sqrt(dRadius*dRadius - dDist*dDist);
|
||
dDist2 = (nAType==0||nAType==3)?(dRadius-dDist1):(dRadius+dDist1);
|
||
dDist2 = (nAType==2||nAType==3)?(-dDist2):dDist2; // 两中点距离
|
||
|
||
vec2 = vecLine.perpVector(); // 垂直方向
|
||
vec2.normalize();
|
||
|
||
AcGePoint3d ptMid = ptA2 - vecLine*0.5, // 弦中点
|
||
ptArcMid = ptMid + vec2*dDist2; // 弧中点
|
||
AcGeCircArc3d arc(ptA1, ptArcMid, ptA2);
|
||
double dStartParam = arc.paramOf(arc.startPoint()),
|
||
dEndParam = arc.paramOf(arc.endPoint()),
|
||
dLen = arc.length(dStartParam, dEndParam);
|
||
|
||
if (nMode == 0) // 50短线
|
||
{
|
||
lstPts.Append(new XPoint(ptA1));
|
||
if (nSplitNum == 2) // 注:没有弧段,总4个点
|
||
{
|
||
lstPts.Append(new XPoint(ptA2));
|
||
lstPts.Append(new XPoint(point2));
|
||
return;
|
||
}
|
||
|
||
dLen /= (nSplitNum-1);
|
||
for (int i=1; i<nSplitNum-1; i++)
|
||
{
|
||
double dNewParam = arc.paramAtLength(dStartParam, dLen*i);
|
||
AcGePoint3d ptTmp = arc.evalPoint(dNewParam);
|
||
lstPts.Append(new XPoint(ptTmp));
|
||
}
|
||
lstPts.Append(new XPoint(ptA2));
|
||
}
|
||
else // 2、3
|
||
{
|
||
if (nSplitNum == 1)
|
||
{
|
||
lstPts.Append(new XPoint(ptArcMid));
|
||
lstPts.Append(new XPoint(point2));
|
||
return;
|
||
}
|
||
|
||
if (nMode == 2) // 用于风管,整体为一弧段
|
||
{
|
||
dLen /= (nSplitNum+1);
|
||
for (int i=1; i<nSplitNum+1; i++)
|
||
{
|
||
double dNewParam = arc.paramAtLength(dStartParam, dLen*i);
|
||
AcGePoint3d ptTmp = arc.evalPoint(dNewParam);
|
||
lstPts.Append(new XPoint(ptTmp));
|
||
}
|
||
}
|
||
else // 虾米弯
|
||
{
|
||
dLen /= (nSplitNum*2.0);
|
||
for (int i=1; i<nSplitNum+1; i++)
|
||
{
|
||
double dNewParam = arc.paramAtLength(dStartParam, dLen*i);
|
||
if (i != 1)
|
||
{
|
||
dNewParam = arc.paramAtLength(dStartParam, dLen*(i*2-1));
|
||
}
|
||
AcGePoint3d ptTmp = arc.evalPoint(dNewParam);
|
||
lstPts.Append(new XPoint(ptTmp));
|
||
}
|
||
}
|
||
}
|
||
lstPts.Append(new XPoint(point2)); // 5、获得全部拆分点
|
||
}
|