// 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 &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; iGetSysDrawMod()); 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 &ids, const AcDbIntArray &types) { assertWriteEnabled(); int nCount1 = ids.Length(), nCount2 = types.logicalLength(); if (nCount1 != nCount2) // 1、先判断链表数量是否正确 { return; } int i(0); DList lstDuct; // 2、存储需要新生成的接口 for (i=0; iGetStartPoint(), 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; iGetStartPoint(), 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; im_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 &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; iDwgInFields(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; jfilerStatus(); } 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; iwriteItem(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; iSetIType(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; im_sCurCommand; if (_tcsicmp(sCmd, _T("MOVE")) == 0) { int nLen = GetInterfaceNum(); for (int i=0; ilayerId(), 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 &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 &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 &segs) const { int nLen = segs.Length(); for (int i=0; i &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 &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 &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 &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 &segs) const // 线 { XCurveSegment seg; seg = line; segs.Append(new XCurveSegment(seg)); } void TDbDuctNode::BuildSegs4(XArc &arc, DList &segs) const // 弧 { XCurveSegment seg; seg = arc; segs.Append(new XCurveSegment(seg)); } void TDbDuctNode::BuildSegs5(XCircle &circle, DList &segs) const // 圆 { XCurveSegment seg; seg = circle; segs.Append(new XCurveSegment(seg)); } ////////////////////////////公共绘制算法////////////////////////////// // 类似不带消声的“内斜线”弯头中的内线,特点为两端为50长度短线 // 注:弯头中nSide是0,三/四通中nSide是1 BOOL TDbDuctNode::DrawLine(DList &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 &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 &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 &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 &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 ids; GetAllLinkDucts(ids); AcDbIntArray types = GetAllTypes(); return ::GetCornerBranchNums(objectId(), m_ptLocation, ids, types, nMain); } // 获取m_ptLocation向各管线中线的投影,用于处理偏心 void TDbDuctNode::GetTrueMidPts(XPointList &pts) const { DList ids; GetAllLinkDucts(ids); AcDbIntArray types = GetAllTypes(); pts.Reset(); ::GetDuctTrueMidPts(objectId(), m_ptLocation, ids, types, pts); int nLen = pts.Length(); for (int i=0; iz = 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 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 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 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 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 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 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 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 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 segs; XPoint ptLoc = GetZeroPt(); // 2、将所有的点投影到XOY平面上 int nLen = GetInterfaceNum(); for (int i=0; iIsUpPipesOk(); 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(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 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 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 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 (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 lstDashSeg; // 虚线 for (k=0; kIntersection(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 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 &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 &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 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 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 &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 &segs, int nVNum, XPoint ptStart, XPoint &ptVDTmp) const { XPointList pts; // 立管上节点所连接的非立管,管线信息 DList 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 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 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 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 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 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)) || ((dEle14 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 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 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 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 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 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 ((dCurrentPI*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 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 lstLine; for (int j=0; j 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 &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 &segs, const XPointList &pts, const DList &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 &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 &segs, const XPointList &pts, const DList &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 &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 &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 &lstSeg, const XPointList &ptLst, const DList &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 &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 &lstSeg, const XPointList &ptLst, int nB2, DList &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 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 &lstSeg, const XPointList &ptLst, int nB2, DList &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 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 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 lstLine; for (int j=0; j lstSeg; // 6、绘制四通其他线 DList 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 &lstSeg, const XPointList &ptLst, const DList &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 &lstSeg, const XPointList &ptLst, const DList &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 &lstSeg, const XPointList &ptLst, const DList &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 &lstSeg, const XPointList &ptLst, const DList &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 &lstSeg, const XPointList &ptLst, int nB1, int nB3, DList &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 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 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 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; iAsAcGePoint3d(), 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; iDistance(*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 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; iAsAcGePoint3d(), 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 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 && dAnglePI/4*7+1.0E-6 && dAnglePI/4-1.0E-6 && dAnglePI/4*3+1.0E-6 && dAngle-1.0E-6 && dAnglePI/4*7+1.0E-6 && dAnglePI/4-1.0E-6 && dAnglePI/4*3+1.0E-6 && dAngle 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 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 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 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; k1.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; iAsAcGePoint3d(), 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; iAsAcGePoint3d(), 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 (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; mAsAcGePoint3d(), 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 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 &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 &ids, const AcDbIntArray &types, XPointList &lstPts) { lstPts.Reset(); DList lstSegs; ::GetSegs(id, ptLoc, ids, types, lstSegs); int nLen = ids.Length(); if (lstSegs.Length() != nLen) { return; } for (int i=0; iProjectToMe(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; i2 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