Files
envi-code/SourceCode/Code2026/tg_shs/shs_pipewire/TDbDuctNode.cpp
T
2026-09-28 15:28:50 +08:00

6952 lines
200 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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、获得全部拆分点
}