#include "stdafx.h" #include "THImpHvacOffset.h" #include "TDbInterfaceMsgWrite.h" #include "TDbHvacEquipment.h" #include "TAuxTools.h" using namespace TDb; extern void GetEndPointIndex(const AcGePoint3dArray &ptArr, int &nIndex1, int &nIndex2, AcGeVector3d* pRangeDir = NULL); // 获取标准基准投影面,2D相关绘制不在此面上的点都投影到此面上 AcGePlane GetStdPrjPlan( const AcGePoint3d &ptOnPlan ) { AcGeVector3d vtZAxis(TAuxTools::GetUcsZvt()); AcGePlane planStd(ptOnPlan, vtZAxis); AcGePoint3d ptPrj = AcGePoint3d::kOrigin.orthoProject(planStd); planStd.set(ptPrj, vtZAxis); return planStd; } // 辅助添加点函数,减少程序行数 int AutoAppendPt( TComplexCurve &cplCurve, TCurveElement &cplEle, AcGePoint3d &ptS, AcGePoint3d &ptMid, AcGePoint3d &ptE ) { cplEle.ptGe[0] = ptS; cplEle.ptGe[1] = ptMid; cplEle.ptGe[2] = ptE; return cplCurve.append(cplEle); } // 获取三点形成的弧的Bulge值,根据当前用户Z坐标确定正负 double GetBulge(AcGePoint3d ptStart, AcGePoint3d ptMid, AcGePoint3d ptEnd) { AcGeCircArc3d arc(ptStart, ptMid, ptEnd); double dSubAngle = arc.endAng() - arc.startAng(); double dBulge = tan(dSubAngle * 0.25); AcGeVector3d vtMid = ptMid - ptStart; AcGeVector3d vtE = ptEnd- ptStart; AcGeVector3d vtCross = vtMid.crossProduct(vtE); if (!vtCross.isCodirectionalTo(TAuxTools::GetUcsZvt())) dBulge *= -1; return dBulge; } ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// THImpHvacOffset::THImpHvacOffset() { } THImpHvacOffset::~THImpHvacOffset() { } Acad::ErrorStatus THImpHvacOffset::getClassID(CLSID* pClsid) const { // #if (ADS < 16) // // {C7DFDF6A-A5F2-4add-ADCC-7AC0675AB6E5} // CLSID CLSID_PipeBaseEntity = {0xC7DFDF6B, 0xA5F2, 0x4ADE, { 0xAD, 0xCC, 0x7A, 0xC0, 0x67, 0x5A, 0xB6, 0xE5 }}; // #endif // // #if (ADS == 16) // // {C7DFDF6A-A5F2-4add-ADCC-7AC0675AB6E5} // CLSID CLSID_PipeBaseEntity = {0xC7DFDF6B, 0xA5F2, 0x4ADE, { 0xAD, 0xCC, 0x7A, 0xC0, 0x67, 0x5A, 0xB6, 0xE6 }}; // #endif // // #if (ADS == 17) // // {C7DFDF6A-A5F2-4add-ADCC-7AC0675AB6E7} // CLSID CLSID_PipeBaseEntity = {0xC7DFDF6B, 0xA5F2, 0x4ADE, { 0xAD, 0xCC, 0x7A, 0xC0, 0x67, 0x5A, 0xB6, 0xE7 }}; // #endif // // #if (ADS == 18) // CLSID CLSID_PipeBaseEntity = {0xD7DFDF6B, 0xA5F2, 0x4ADE, { 0xAD, 0xCC, 0x7A, 0xC0, 0x67, 0x5A, 0xB6, 0xE8 }}; // #endif // // #if (ADS == 19) // CLSID CLSID_PipeBaseEntity = {0xD7DFDF6B, 0xA5F2, 0x4ADE, { 0xAD, 0xCC, 0x7A, 0xC0, 0x67, 0x5A, 0xB6, 0xE8 }}; // #endif return Acad::eOk; } BOOL THImpHvacOffset::OPMInfo(LPCTSTR pszName, TDb::OPMInfo* pInfo) { ASSERT(NULL != pszName && NULL != pInfo && NULL != m_pXDataMap); // 暖通基本参数设置 if (0 == _tcsicmp(pszName, KEY_RUNTIME)) { pInfo->bVisible = TRUE; pInfo->bEditable = FALSE; // 提供数据列表和对应关系 if (NULL != pInfo->parsValues && NULL != pInfo->parlValues) { pInfo->parsValues->Add(_T("乙字弯")); pInfo->parlValues->Add(TDb::eOffset); } return TRUE; } // 乙字弯样式 if (0 == _tcsicmp(pszName, HOFF_Type)) { pInfo->bVisible = TRUE; pInfo->bEditable = TRUE; // 提供数据列表和对应关系 if (NULL != pInfo->parsValues && NULL != pInfo->parlValues) { pInfo->parsValues->Add(_T("双弧")); pInfo->parlValues->Add(eArcuateLink); pInfo->parsValues->Add(_T("角接")); pInfo->parlValues->Add(eLinearLink); } return TRUE; } if (0 == _tcsicmp(pszName, HVAC_SectType)) { pInfo->bVisible = TRUE; pInfo->bEditable = TRUE; // 提供数据列表和对应关系 if (NULL != pInfo->parsValues && NULL != pInfo->parlValues) { pInfo->parsValues->Add(_T("矩形")); pInfo->parlValues->Add(TDb::eRectangular); pInfo->parsValues->Add(_T("圆形")); pInfo->parlValues->Add(TDb::eCircular); } TAuxTools::SetAndUpdateCover((TDbInterfacesObj*)m_pOwnerEnt, pszName, pInfo); return TRUE; } // 为了注册列表名,保证其他管件能用到此参数 if (0 == _tcsicmp(pszName, KEY_StartSectType) || 0 == _tcsicmp(pszName, KEY_EndSectType)) { pInfo->bVisible = FALSE; pInfo->bEditable = FALSE; // 提供数据列表和对应关系 if (NULL != pInfo->parsValues && NULL != pInfo->parlValues) { pInfo->parsValues->Add(_T("矩形")); pInfo->parlValues->Add(TDb::eRectangular); } return TRUE; } // 尺寸计算方式 为了注册列表名,保证其他管件能用到此参数 if (0 == _tcsicmp(pszName, HRED_ComputeType)) { pInfo->bVisible = FALSE; pInfo->bEditable = FALSE; // 提供数据列表和对应关系 if (NULL != pInfo->parsValues && NULL != pInfo->parlValues) { pInfo->parsValues->Add(_T("自动计算")); pInfo->parlValues->Add(TDb::eAuto); } return TRUE; } if (0 == _tcsicmp(pszName, HVAC_HasBaseLine)) { pInfo->bVisible = TRUE; pInfo->bEditable = TRUE; // 提供数据列表和对应关系 if (NULL != pInfo->parsValues && NULL != pInfo->parlValues) { pInfo->parsValues->Add(_T("隐藏")); pInfo->parlValues->Add(0); pInfo->parsValues->Add(_T("显示")); pInfo->parlValues->Add(1); } return TRUE; } if (0 == _tcsicmp(pszName, HVAC_IsSingleLine)) { pInfo->bVisible = TRUE; pInfo->bEditable = TRUE; // 提供数据列表和对应关系 if (NULL != pInfo->parsValues && NULL != pInfo->parlValues) { pInfo->parsValues->Add(_T("双线")); pInfo->parlValues->Add(0); pInfo->parsValues->Add(_T("单线")); pInfo->parlValues->Add(1); } TAuxTools::SetAndUpdateCover((TDbInterfacesObj*)m_pOwnerEnt, pszName, pInfo); return TRUE; } // 获得单线状态,当状态为单线时不显示 BOOL bSingleLine = FALSE; m_pXDataMap->GetAt(HVAC_IsSingleLine, bSingleLine); // 角度 if (0 == _tcsicmp(pszName, HOFF_Angle)) { pInfo->bVisible = TRUE; pInfo->bEditable = TRUE; if (NULL != pInfo->pXData) { // 获取数据 if (0 == pInfo->pXData->nVt) { m_pXDataMap->GetAt(HRED_Angle, *pInfo->pXData); pInfo->pXData->dVal[0] *= 180/PI; } else { m_pXDataMap->SetAt(HRED_Angle, pInfo->pXData->dVal[0]*PI/180); // 先记录更新前信息 AcGePoint3dArray ptArrOrig; AcDbObjectIdArray idArr; TAuxTools::GetInterfacePoint(this, ptArrOrig); TAuxTools::GetInterfaceId(this, idArr); IsValid(NULL); // 更新连接实体 if (NULL != m_pOwnerEnt) { AcGePoint3dArray ptArrNew; TAuxTools::GetInterfacePoint(this, ptArrNew); TAuxTools::DealWithConEnt(idArr, ptArrOrig, ptArrNew, m_pOwnerEnt->objectId()); m_pOwnerEnt->close(); acedPostCommand(_T("redraw\n")); } pInfo->pXData->nVt = 0; } } return TRUE; } if (0 == _tcsicmp(pszName, HOFF_StartWidth)) { // 获得截面,当截面不为圆型时显示并可改 HvacSectType eSectType = eRectangular; m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType); pInfo->bVisible = (TDb::eCircular != eSectType); pInfo->bEditable = TRUE; ValidOpmCanDraw(HOFF_StartWidth, pInfo); TAuxTools::SetAndUpdateCover((TDbInterfacesObj*)m_pOwnerEnt, pszName, pInfo); return TRUE; } if (0 == _tcsicmp(pszName, HOFF_EndWidth)) { // 获得截面,当截面不为圆型时显示并可改 HvacSectType eSectType = eRectangular; m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType); pInfo->bVisible = (TDb::eCircular != eSectType); pInfo->bEditable = TRUE; ValidOpmCanDraw(HOFF_EndWidth, pInfo); TAuxTools::SetAndUpdateCover((TDbInterfacesObj*)m_pOwnerEnt, pszName, pInfo); return TRUE; } if (0 == _tcsicmp(pszName, HOFF_Thick)) { // 获得截面,当截面不为圆型时显示并可改 HvacSectType eSectType = eRectangular; m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType); pInfo->bVisible = (TDb::eCircular != eSectType); pInfo->bEditable = TRUE; ValidOpmCanDraw(HOFF_Thick, pInfo); return TRUE; } // HOFF_Diameter和HOFF_StartWidth定义相同,为同一个值 // 为区分显示名称,借用未被使用的KEY_Diameter值来表达 if (0 == _tcsicmp(pszName, KEY_Diameter)) { // 获得截面,当截面为圆型时显示并可改 HvacSectType eSectType = eRectangular; m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType); pInfo->bVisible = (TDb::eCircular == eSectType); pInfo->bEditable = (!bSingleLine && TDb::eCircular == eSectType); // 替代属性,需要特殊处理数据获取和设置 if (NULL != pInfo->pXData) { // 获取数据 if (0 == pInfo->pXData->nVt) { m_pXDataMap->GetAt(HOFF_Diameter, *pInfo->pXData); } // 设置数据 else { ValidOpmCanDraw(HOFF_Thick, pInfo); TAuxTools::SetAndUpdateCover((TDbInterfacesObj*)m_pOwnerEnt, HOFF_Diameter, pInfo); } } return TRUE; } if (0 == _tcsicmp(pszName, HOFF_StartPoint)) { pInfo->bVisible = TRUE; pInfo->bEditable = TRUE; // 整体移动 if (NULL != pInfo->pXData && 0 != pInfo->pXData->nVt) { // 改变顶点变换行为 AcGePoint3d ptStart; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); AcGeVector3d offset = asPnt3d(pInfo->pXData->dVal) - ptStart; AcGeMatrix3d mat; mat.setToTranslation(offset); transformBy(mat); // pInfo->pXData->nVt = 0; // 设置处理完成标识 TAuxTools::SetAndUpdateCover((TDbInterfacesObj*)m_pOwnerEnt, pszName, pInfo); } return TRUE; } if (0 == _tcsicmp(pszName, HOFF_EndPoint)) { pInfo->bVisible = TRUE; pInfo->bEditable = TRUE; // 整体移动 if (NULL != pInfo->pXData && 0 != pInfo->pXData->nVt) { // 改变顶点变换行为 AcGePoint3d ptEnd; m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); AcGeVector3d offset = asPnt3d(pInfo->pXData->dVal) - ptEnd; AcGeMatrix3d mat; mat.setToTranslation(offset); transformBy(mat); // pInfo->pXData->nVt = 0; // 设置处理完成标识 TAuxTools::SetAndUpdateCover((TDbInterfacesObj*)m_pOwnerEnt, pszName, pInfo); } return TRUE; } return FALSE; } // 验证特性表修改值是否合法能绘制,否则改为原值 BOOL THImpHvacOffset::ValidOpmCanDraw(const CString &csKey, TDb::OPMInfo* pInfo) { // 有效性确认 BOOL bValid(TRUE); if (NULL != pInfo->pXData) { if (0 != pInfo->pXData->nVt) { if (pInfo->pXData->dVal[0] < 1e-9) { pInfo->pXData->nVt = 0; // 设置处理完成标识 return FALSE; } double dOrigValue(0.0); m_pXDataMap->GetAt(csKey, dOrigValue); m_pXDataMap->SetAt(csKey, pInfo->pXData->dVal[0]); if (!IsCanDraw()) { bValid = FALSE; m_pXDataMap->SetAt(csKey, dOrigValue); pInfo->pXData->nVt = 0; // 设置处理完成标识 } } } return bValid; } void THImpHvacOffset::GetTips(CMapStringToString& mapLable2Tip) const { } void THImpHvacOffset::list() const { ASSERT(NULL != m_pXDataMap); // 管件类型 acutPrintf(_T("\n\t\t\t\t\t\t\t\t\t\t\t 暖通:乙字弯")); // 截面类型 HvacSectType eSectType = eRectangular; m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType); switch (eSectType) { case TDb::eRectangular: acutPrintf(_T("\n\t\t\t\t\t\t\t\t\t\t\t 截面:矩形")); break; case TDb::eCircular: acutPrintf(_T("\n\t\t\t\t\t\t\t\t\t\t\t 截面:圆形")); break; case TDb::eOblate: acutPrintf(_T("\n\t\t\t\t\t\t\t\t\t\t\t 截面:扁圆形")); break; } // 圆型截面显示直径 if (TDb::eCircular == eSectType) { double dDiameter = 0.0; m_pXDataMap->GetAt(HOFF_Diameter, dDiameter); acutPrintf(_T("\n\t\t\t\t\t\t\t\t\t直径:%.2f"), dDiameter); } // 非圆型截面显示宽度和厚度 else { double dStartWidth = 0.0, dEndWidth = 0.0, dThick = 0.0; m_pXDataMap->GetAt(HOFF_StartWidth, dStartWidth); m_pXDataMap->GetAt(HOFF_EndWidth, dEndWidth); m_pXDataMap->GetAt(HOFF_Thick, dThick); acutPrintf(_T("\n\t\t\t\t\t\t\t\t始端宽度:%.2f 末端宽度:%.2f 厚度:%.2f"), dStartWidth, dEndWidth, dThick); } // 起点 AcGePoint3d pt; m_pXDataMap->GetAt(HOFF_StartPoint, pt); acutPrintf(_T("\n\t\t\t\t\t\t\t\t自 点,X=%.4f\t Y=%.4f\t Z=%.4f"), pt.x, pt.y, pt.z); // 终点 m_pXDataMap->GetAt(HOFF_EndPoint, pt); acutPrintf(_T("\n\t\t\t\t\t\t\t\t到 点,X=%.4f\t Y=%.4f\t Z=%.4f"), pt.x, pt.y, pt.z); } int THImpHvacOffset::GetInterfaceCount() const { return 2; } void THImpHvacOffset::GetKindName( CString& sName ) { sName = _T("TCH_OFFSET"); } BOOL THImpHvacOffset::GetInterfaceSizeData(int nIndex, TInterface& pipeInterface) const { ASSERT(NULL != m_pXDataMap); // 获取截面类型 TDb::HvacSectType eSectType = TDb::eRectangular; m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType); // 获取接口截面、宽度、厚度数据key值 LPCTSTR pszWidthKey, pszThickKey; switch (nIndex) { case 0: pszWidthKey = ((TDb::eCircular == eSectType) ? HOFF_Diameter : HOFF_StartWidth); pszThickKey = HOFF_Thick; break; case 1: pszWidthKey = ((TDb::eCircular == eSectType) ? HOFF_Diameter : HOFF_EndWidth); pszThickKey = HOFF_Thick; break; default: return FALSE; } // 获取尺寸 double dWidth = 0.0, dThick = 0.0; m_pXDataMap->GetAt(pszWidthKey, dWidth); m_pXDataMap->GetAt(pszThickKey, dThick); // 设置接口数据 pipeInterface.SetType(eSectType); pipeInterface.SetSize(dWidth, dThick); return TRUE; } BOOL THImpHvacOffset::GetInterface( int nIndex,TInterface& pipeInterface ) const { if (NULL == m_pXDataMap) return FALSE; // 获取各点位置 AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); // 求各端方向 AcGeVector3d vtStart(StartVect()), vtEnd(EndVect()); AcDbObjectId id; switch(nIndex) { case 0: // 如果起始接口和第一个管连接 if (m_pXDataMap->GetAt(KEY_IDCNT1, id) && MakesureInterfaceValidate(id, ptStart, vtStart, pipeInterface)) { GetInterfaceSizeData(nIndex, pipeInterface); return TRUE; } // 如果起始接口和第二个管连接 if (m_pXDataMap->GetAt(KEY_IDCNT2, id) && MakesureInterfaceValidate(id, ptStart, vtStart, pipeInterface)) { GetInterfaceSizeData(nIndex, pipeInterface); return TRUE; } // 没有管件连接 pipeInterface.SetOutDir(vtStart); pipeInterface.SetOwnerId(m_pOwnerEnt->objectId()); pipeInterface.SetPosition(ptStart); GetInterfaceSizeData(nIndex, pipeInterface); return TRUE; case 1: // 如果末尾接口和第一个管连接 if (m_pXDataMap->GetAt(KEY_IDCNT1, id) && MakesureInterfaceValidate(id, ptEnd, vtEnd, pipeInterface)) { GetInterfaceSizeData(nIndex, pipeInterface); return TRUE; } // 如果末尾接口和第二个管连接 if (m_pXDataMap->GetAt(KEY_IDCNT2, id) && MakesureInterfaceValidate(id, ptEnd, vtEnd, pipeInterface)) { GetInterfaceSizeData(nIndex, pipeInterface); return TRUE; } // 没有管件连接 pipeInterface.SetOutDir(vtEnd); pipeInterface.SetOwnerId(m_pOwnerEnt->objectId()); pipeInterface.SetPosition(ptEnd); GetInterfaceSizeData(nIndex, pipeInterface); return TRUE; } return FALSE; } BOOL THImpHvacOffset::GetInterface( const AcGePoint3d& ptConnect,TInterface& pipeInterface ) const { if (NULL == m_pXDataMap) return FALSE; // 获取各点位置 AcGePoint3d ptStart, ptEnd, ptBran; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); // 求各端方向 AcGeVector3d vtStart(StartVect()), vtEnd(EndVect()); // 计算测试点到始末点的距离 double dDist1 = ptConnect.distanceTo(ptStart); double dDist2 = ptConnect.distanceTo(ptEnd); AcDbObjectId id; // 位于起始点 if (dDist1 < 1e-3) { // 如果起始接口和第一个管连接 if (m_pXDataMap->GetAt(KEY_IDCNT1, id) && MakesureInterfaceValidate(id, ptStart, vtStart, pipeInterface)) { GetInterfaceSizeData(0, pipeInterface); return TRUE; } // 如果起始接口和第二个管件连接 if (m_pXDataMap->GetAt(KEY_IDCNT2, id) && MakesureInterfaceValidate(id, ptStart, vtStart, pipeInterface)) { GetInterfaceSizeData(0, pipeInterface); return TRUE; } // 没有管件连接 pipeInterface.SetOutDir(vtStart); pipeInterface.SetOwnerId(m_pOwnerEnt->objectId()); pipeInterface.SetPosition(ptStart); GetInterfaceSizeData(0, pipeInterface); return TRUE; } else if (dDist2 < 1e-3) // 位于末尾点 { // 如果末尾接口和第一个管连接 if (m_pXDataMap->GetAt(KEY_IDCNT1, id) && MakesureInterfaceValidate(id, ptEnd, vtEnd, pipeInterface)) { GetInterfaceSizeData(1, pipeInterface); return TRUE; } // 如果末尾接口和第二个管连接 if (m_pXDataMap->GetAt(KEY_IDCNT2, id) && MakesureInterfaceValidate(id, ptEnd, vtEnd, pipeInterface)) { GetInterfaceSizeData(1, pipeInterface); return TRUE; } // 没有管件连接 pipeInterface.SetOutDir(vtEnd); pipeInterface.SetOwnerId(m_pOwnerEnt->objectId()); pipeInterface.SetPosition(ptEnd); GetInterfaceSizeData(1, pipeInterface); return TRUE; } return FALSE; } BOOL THImpHvacOffset::HasInterface( const AcGePoint3d& ptConnect,const AcGeVector3d& vtDir ) { if (NULL == m_pXDataMap) return FALSE; // 获取各点位置 AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); // 求各端方向 AcGeVector3d vtStart(StartVect()), vtEnd(EndVect()); // 计算测试点到始末点的距离 double dDist1 = ptConnect.distanceTo(ptStart); double dDist2 = ptConnect.distanceTo(ptEnd); // 位于起始点 if (dDist1 < 1e-3) return (vtDir.isParallelTo(vtStart)); // 位于末尾点 if (dDist2 < 1.e-3) return (vtDir.isParallelTo(vtEnd)); return FALSE; } BOOL THImpHvacOffset::SetInterfaceRelation( const AcGePoint3d& ptConnect,const AcDbObjectId& idConnect ) { if (NULL == m_pXDataMap) return FALSE; // 打开对象 AcDbEntity* pEnt; if (Acad::eOk != acdbOpenObject(pEnt, idConnect, AcDb::kForRead)) return FALSE; // 检查对象类型,是否是暖通管件 if (!(pEnt->isKindOf(TDbHvacDuct::desc()) || pEnt->isKindOf(TDbHvacFitting::desc()) || pEnt->isKindOf(TDbHvacEquipment::desc()))) { pEnt->close(); return FALSE; } // 获取各点位置 AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); // 求各端方向 AcGeVector3d vtStart(StartVect()), vtEnd(EndVect()); // 计算测试点到各点的距离 double dDist1 = ptConnect.distanceTo(ptStart); double dDist2 = ptConnect.distanceTo(ptEnd); // 基类指针 TDbInterfacesObj* pInterfaceObj = TDbInterfacesObj::cast(pEnt); ASSERT(NULL != pInterfaceObj); // 位于起始点 if (dDist1 < 1e-3 && pInterfaceObj->HasInterface(ptStart, vtStart)) { m_pXDataMap->SetAt(KEY_IDCNT1, idConnect); pEnt->close(); return TRUE; } // 位于末尾点 if (dDist2 < 1.e-3 && pInterfaceObj->HasInterface(ptEnd, vtEnd)) { m_pXDataMap->SetAt(KEY_IDCNT2, idConnect); pEnt->close(); return TRUE; } pEnt->close(); return FALSE; } BOOL THImpHvacOffset::RemoveInterfaceRelation( const AcGePoint3d& ptConnect, const AcDbObjectId& idConnect ) { if (NULL == m_pXDataMap) return FALSE; // 浅层次删除; 命名字典中的关系,需要外面移除关系,只移除内部关系 AcDbObjectId id; m_pXDataMap->GetAt(KEY_IDCNT1, id); if (id == idConnect) { m_pXDataMap->SetAt(KEY_IDCNT1, AcDbObjectId::kNull); return TRUE; } m_pXDataMap->GetAt(KEY_IDCNT2, id); if (id == idConnect) { m_pXDataMap->SetAt(KEY_IDCNT2, AcDbObjectId::kNull); return TRUE; } return FALSE; } BOOL THImpHvacOffset::NotifyInterfaceToModify( const TInterfaceModifyMsg& iModiMsg, TInterfaceModifyMsgs& iModiMsgs ) { if (NULL == m_pXDataMap) return FALSE; // 获得消息传递设置, 确定是否传递消息 CString sDispatch = _T("0"); GetGlobalContext(KEY_DISPATCHMSG, sDispatch); BOOL bDispatch = (_ttoi(sDispatch) != 0); BOOL bMsgTranslate = FALSE; // 获得消息类型, 根据消息类型处理 TDb::InterfaceOper eOper = iModiMsg.GetInterfaceOper(); switch (eOper) { case TDb::eMoveGripPoint: // 夹点移动消息处理 bMsgTranslate = OnMoveGripPointMsgNotify(iModiMsg, iModiMsgs); break; case TDb::eTransformBy: // 对象移动消息处理 bMsgTranslate = OnTransformMsgNotify(iModiMsg, iModiMsgs); break; case TDb::eSize: // 尺寸调整消息处理 bMsgTranslate = OnSizeMsgNotify(iModiMsg, iModiMsgs); break; default: return bMsgTranslate; } // 记录修改标识 if (m_pOwnerEnt != NULL) m_pOwnerEnt->recordGraphicsModified(); return bMsgTranslate; } BOOL THImpHvacOffset::OnMoveGripPointMsgNotify( const TInterfaceModifyMsg& iModiMsg, TInterfaceModifyMsgs& iModiMsgs ) { if (!TAuxTools::IsAutoWorkOffset()) return FALSE; ASSERT(NULL != m_pXDataMap); BOOL bMsgTranslate = FALSE; AcDbObjectId id = iModiMsg.GetMsgOperateOn(); if (id != m_pOwnerEnt->objectId()) // 消息发送目标正确 return FALSE; AcGeVector3d vtOffset = iModiMsg.GetMoveGripOffset(); if (vtOffset.isZeroLength()) return FALSE; AcGePoint3d ptStart, ptEnd, ptMsg; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); ptMsg = iModiMsg.GetMsgPoint(); AcGeVector3d vtStart, vtEnd; m_pXDataMap->GetAt(HOFF_StartDir, vtStart); m_pXDataMap->GetAt(HOFF_EndDir, vtEnd); // 偏移向量跟法相不不垂直时,直接位移 AcGeVector3d vtNormal = normal(); if (!vtOffset.isPerpendicularTo(vtNormal)) { // 构造接口消息传递 开始端检查 AcDbObjectId idT; if (FindConnect(ptStart, vtStart, m_pOwnerEnt->objectId(), idT)) // sta 点的接口 { TInterfaceModifyMsg msg; msg.SetMsgPoint(ptStart); msg.SetMoveGripOffset(vtOffset); msg.SetMsgOperateOn(idT); msg.SetGripPosition(TDb::eStart); iModiMsgs.append(msg); bMsgTranslate = TRUE; } if (FindConnect(ptEnd, vtEnd, m_pOwnerEnt->objectId(), idT)) // End 点的接口 { TInterfaceModifyMsg msg; msg.SetMsgPoint(ptEnd); msg.SetMoveGripOffset(vtOffset); msg.SetMsgOperateOn(idT); msg.SetGripPosition(TDb::eEnd); iModiMsgs.append(msg); bMsgTranslate = TRUE; } // 移动自身 AcGePoint3d ptNewStart, ptNewEnd; ptNewStart = ptStart + vtOffset; ptNewEnd = ptEnd + vtOffset; m_pXDataMap->SetAt(HOFF_StartPoint, ptNewStart); m_pXDataMap->SetAt(HOFF_EndPoint, ptNewEnd); UpdateInterfaceRec(id, ptStart, ptNewStart); UpdateInterfaceRec(id, ptEnd, ptNewEnd); return bMsgTranslate; } // 先检查接口是否真实连接了实体 BOOL bStartCon(FALSE), bEndCon(FALSE); AcDbObjectId idStart(AcDbObjectId::kNull), idEnd(AcDbObjectId::kNull); m_pXDataMap->GetAt(KEY_IDCNT1, idStart); m_pXDataMap->GetAt(KEY_IDCNT2, idEnd); OPENOBJ_BEGIN(idStart, AcDb::kForRead, TDbInterfacesObj, pIfObj); if (NULL != pIfObj) { AcGePoint3d ptFind = ptStart; if (ptMsg.distanceTo(ptStart) < 1e-6) ptFind += vtOffset; if (pIfObj->GetInterface(ptFind, TInterface())) bStartCon = TRUE; } OPENOBJ_END(); OPENOBJ_BEGIN(idEnd, AcDb::kForRead, TDbInterfacesObj, pIfObj); if (NULL != pIfObj) { AcGePoint3d ptFind = ptEnd; if (ptMsg.distanceTo(ptEnd) < 1e-6) ptFind += vtOffset; if (pIfObj->GetInterface(ptFind, TInterface())) bEndCon = TRUE; } OPENOBJ_END(); if (ptMsg.distanceTo(ptStart) < 1e-6) { AcGePoint3d ptNewStart = ptStart + vtOffset; m_pXDataMap->SetAt(HOFF_StartPoint, ptNewStart); IsValid(NULL); bMsgTranslate = TRUE; if (IsCanDraw()) { AcGePoint3d ptNewEnd; m_pXDataMap->GetAt(HOFF_EndPoint, ptNewEnd); AcGeVector3d vtEndOff = ptNewEnd - ptEnd; vtEndOff = vtEndOff.orthoProject(vtEnd.perpVector()); if (bEndCon && !vtEndOff.isZeroLength()) TAuxTools::DealWithConEnt(idEnd, vtEndOff, id, ptEnd); } else // 不能绘制则返回原点 { m_pXDataMap->SetAt(HOFF_EndPoint, ptEnd); } AcGePoint3d ptNewEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptNewStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptNewEnd); UpdateInterfaceRec(id, ptStart, ptNewStart); UpdateInterfaceRec(id, ptEnd, ptNewEnd); } else if (ptMsg.distanceTo(ptEnd) < 1e-6) { AcGePoint3d ptNewEnd = ptEnd + vtOffset; m_pXDataMap->SetAt(HOFF_EndPoint, ptNewEnd); IsValid(NULL); AcGePoint3d ptFixedEnd; m_pXDataMap->GetAt(HOFF_EndPoint, ptFixedEnd); // 保证末点不变 AcGeVector3d vtChange = ptFixedEnd - ptEnd; AcGeVector3d vtPlan = ptEnd - ptStart; if (vtPlan.isParallelTo(vtStart)) // 非常规乙子弯 { double dAngle = vtChange.angleTo(vtStart); double dLen = vtChange.length() * cos(dAngle); if (vtChange.angleTo(vtStart) > PI*0.5) dLen *= -1; vtChange.setToProduct(vtStart, dLen); } else { vtPlan = vtStart.crossProduct(vtPlan); vtPlan = vtStart.crossProduct(vtPlan); vtChange = vtChange.orthoProject(vtPlan); } AcGePoint3d ptNewStart = ptStart - vtChange; m_pXDataMap->SetAt(HOFF_StartPoint, ptNewStart); m_pXDataMap->SetAt(HOFF_EndPoint, ptNewEnd); bMsgTranslate = TRUE; if (IsCanDraw()) { AcGePoint3d ptNewStart; m_pXDataMap->GetAt(HOFF_StartPoint, ptNewStart); AcGeVector3d vtStartOff = ptNewStart - ptStart; vtStartOff = vtStartOff.orthoProject(vtStart.perpVector()); if (bStartCon && !vtStartOff.isZeroLength()) TAuxTools::DealWithConEnt(idStart, vtStartOff, id, ptStart); } else // 不能绘制则返回原点 { m_pXDataMap->SetAt(HOFF_StartPoint, ptStart); } m_pXDataMap->GetAt(HOFF_StartPoint, ptNewStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptNewEnd); UpdateInterfaceRec(id, ptStart, ptNewStart); UpdateInterfaceRec(id, ptEnd, ptNewEnd); } acedPostCommand(_T("Redraw\n")); // 暂用于响应移动消息后,没有更新接口记录问题 return bMsgTranslate; } BOOL THImpHvacOffset::OnTransformMsgNotify( const TInterfaceModifyMsg& iModiMsg, TInterfaceModifyMsgs& iModiMsgs ) { if (!TAuxTools::IsAutoWorkOffset()) return FALSE; ASSERT(NULL != m_pXDataMap); BOOL bMsgTranslate = FALSE; AcDbObjectId id = iModiMsg.GetMsgOperateOn(); if (id != m_pOwnerEnt->objectId()) // 消息发送目标正确 return FALSE; AcGeMatrix3d mtTrans = iModiMsg.GetTransform(); AcGeVector3d vtSta, vtEnd; AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartDir, vtSta); m_pXDataMap->GetAt(HOFF_EndDir, vtEnd); m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); AcGePoint3d ptGeSOld = ptStart; AcGePoint3d ptGeEOld = ptEnd; ptStart.transformBy(mtTrans); ptEnd.transformBy(mtTrans); m_pXDataMap->SetAt(HOFF_StartPoint, ptStart); m_pXDataMap->SetAt(HOFF_EndPoint, ptEnd); // 构造接口消息传递 开始端检查 AcDbObjectId idT; if (FindConnect(ptGeSOld, vtSta, m_pOwnerEnt->objectId(), idT)) // sta 点的接口 { TInterfaceModifyMsg msg; msg.SetMsgPoint(ptGeSOld); msg.SetTransform(mtTrans); msg.SetMsgOperateOn(idT); iModiMsgs.append(msg); bMsgTranslate = TRUE; } // 构造接口消息传递 末端检查 if (FindConnect(ptGeEOld, vtEnd, m_pOwnerEnt->objectId(), idT)) // end 点的接口 { TInterfaceModifyMsg msg; msg.SetMsgPoint(ptGeEOld); msg.SetTransform(mtTrans); msg.SetMsgOperateOn(idT); iModiMsgs.append(msg); bMsgTranslate = TRUE; } // 更新模型空间的扩展字典的注册的接口数据 UpdateInterfaceRec(m_pOwnerEnt->objectId(), mtTrans); return bMsgTranslate;} BOOL THImpHvacOffset::OnSizeMsgNotify( const TInterfaceModifyMsg& iModiMsg, TInterfaceModifyMsgs& iModiMsgs ) { ASSERT(NULL != m_pXDataMap); BOOL bSizeChanged = FALSE; AcDbObjectId id = iModiMsg.GetMsgOperateOn(); if (id != m_pOwnerEnt->objectId()) // 消息发送目标正确 return FALSE; double dOrigStartWidth(0.0), dOrigEndWidth(0.0), dOrigThick(0.0); m_pXDataMap->GetAt(HOFF_StartWidth, dOrigStartWidth); m_pXDataMap->GetAt(HOFF_EndWidth, dOrigEndWidth); m_pXDataMap->GetAt(HOFF_Thick, dOrigThick); AcGeVector3d vtOffset = iModiMsg.GetMoveGripOffset(); AcGePoint3d ptOrigStart, ptOrigEnd, ptMsg; m_pXDataMap->GetAt(HOFF_StartPoint, ptOrigStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptOrigEnd); ptMsg = iModiMsg.GetMsgPoint(); // 先检查接口是否真实连接了实体 BOOL bStartCon(FALSE), bEndCon(FALSE); AcDbObjectId idStart(AcDbObjectId::kNull), idEnd(AcDbObjectId::kNull); m_pXDataMap->GetAt(KEY_IDCNT1, idStart); m_pXDataMap->GetAt(KEY_IDCNT2, idEnd); OPENOBJ_BEGIN(idStart, AcDb::kForRead, TDbInterfacesObj, pIfObj); if (NULL != pIfObj) { AcGePoint3d ptFind = ptOrigStart; if (ptMsg.distanceTo(ptOrigStart) < 1e-6) ptFind += vtOffset; if (pIfObj->GetInterface(ptFind, TInterface())) bStartCon = TRUE; } OPENOBJ_END(); OPENOBJ_BEGIN(idEnd, AcDb::kForRead, TDbInterfacesObj, pIfObj); if (NULL != pIfObj) { AcGePoint3d ptFind = ptOrigEnd; if (ptMsg.distanceTo(ptOrigEnd) < 1e-6) ptFind += vtOffset; if (pIfObj->GetInterface(ptFind, TInterface())) bEndCon = TRUE; } OPENOBJ_END(); HvacSectType eSect = TDb::eRectangular; m_pXDataMap->GetAt(HVAC_SectType, (int&)eSect); // 看哪个接口方向修改了尺寸,修改相应接口尺寸 int nModifyFrom(0); // 修改方向, 0:首,1:尾 // 设置各接口新尺寸 double dNewWidth, dNewHeigh(0.0); AcGeVector3d vtNormal = normal(); if (eSect == TDb::eRectangular) { AcGeVector3d vtWidthDir, vtHeighDir; iModiMsg.GetSizeDir(vtWidthDir, vtHeighDir); // 判断是否是空间连接或导致宽高互换 if (vtHeighDir.isParallelTo(vtNormal)) iModiMsg.GetSize(dNewWidth, dNewHeigh); else iModiMsg.GetSize(dNewHeigh, dNewWidth); } else { iModiMsg.GetSize(dNewWidth, dNewHeigh); dNewHeigh = dNewWidth; } if (ptMsg.distanceTo(ptOrigStart) < 1e-6) { if (eSect == TDb::eRectangular) { m_pXDataMap->SetAt(HOFF_StartWidth, dNewWidth); m_pXDataMap->SetAt(HOFF_Thick, dNewHeigh); } else if (eSect == TDb::eCircular) { m_pXDataMap->SetAt(HOFF_Diameter, dNewWidth); } bSizeChanged = TRUE; nModifyFrom = 0; AcGePoint3d ptNewStart = ptOrigStart + vtOffset; m_pXDataMap->SetAt(HOFF_StartPoint, ptNewStart); if (vtOffset.isParallelTo(vtNormal)) { AcGePoint3d ptNewEnd = ptOrigEnd + vtOffset; m_pXDataMap->SetAt(HOFF_EndPoint, ptNewEnd); } } else if (ptMsg.distanceTo(ptOrigEnd) < 1e-6) { if (eSect == TDb::eRectangular) { m_pXDataMap->SetAt(HOFF_EndWidth, dNewWidth); m_pXDataMap->SetAt(HOFF_Thick, dNewHeigh); } else if (eSect == TDb::eCircular) { m_pXDataMap->SetAt(HOFF_Diameter, dNewWidth); } bSizeChanged = TRUE; nModifyFrom = 1; AcGePoint3d ptNewEnd = ptOrigEnd + vtOffset; m_pXDataMap->SetAt(HOFF_EndPoint, ptNewEnd); if (vtOffset.isParallelTo(vtNormal)) { AcGePoint3d ptNewStart = ptOrigStart + vtOffset; m_pXDataMap->SetAt(HOFF_StartPoint, ptNewStart); } } // 由于尺寸变化,调用内部校正函数,接口点必须沿各向量方向校正, // 不能绘制则返回原来参数 if (!IsValid(NULL)) { m_pXDataMap->SetAt(HOFF_StartWidth, dOrigStartWidth); m_pXDataMap->SetAt(HOFF_EndWidth, dOrigEndWidth); m_pXDataMap->SetAt(HOFF_Thick, dOrigThick); m_pXDataMap->SetAt(HOFF_StartPoint, ptOrigStart); m_pXDataMap->SetAt(HOFF_EndPoint, ptOrigEnd); return FALSE; } AcGePoint3d ptNewStart, ptNewEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptNewStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptNewEnd); // 更新接口记录 AcGeVector3d vtStartOff = ptNewStart - ptOrigStart; AcGeVector3d vtEndOff = ptNewEnd - ptOrigEnd; if (vtStartOff.length() > 1e-6) UpdateInterfaceRec(id, ptOrigStart, ptNewStart); if (vtEndOff.length() > 1e-6) UpdateInterfaceRec(id, ptOrigEnd, ptNewEnd); // 纠正由于风管边壁偏移导致的向量差 AcGeVector3d vtPrj; AcGePoint3d ptFixedStart(ptOrigStart), ptFixedEnd(ptOrigEnd); if (nModifyFrom == 0) { ptFixedStart += vtOffset; AcGeVector3d vtStart; m_pXDataMap->GetAt(HOFF_StartDir, vtStart); vtPrj = vtStart.crossProduct(vtNormal); vtStartOff = vtStartOff.orthoProject(vtPrj); } else if (nModifyFrom == 1) { ptFixedEnd += vtOffset; AcGeVector3d vtEnd; m_pXDataMap->GetAt(HOFF_EndDir, vtEnd); vtPrj = vtEnd.crossProduct(vtNormal); vtEndOff = vtEndOff.orthoProject(vtPrj); } // 根据最终位移向量,处理接口端连接实体位置 if (vtStartOff.length() > 1e-6 && bStartCon) TAuxTools::DealWithConEnt(idStart, vtStartOff, id, ptFixedStart); if (vtEndOff.length() > 1e-6 && bEndCon) TAuxTools::DealWithConEnt(idEnd, vtEndOff, id, ptFixedEnd); return bSizeChanged; } Acad::ErrorStatus THImpHvacOffset::transformBy( const AcGeMatrix3d& xform ) { if (NULL == m_pXDataMap) return Acad::eNotApplicable; // 变换点位置 AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); ptStart.transformBy(xform); ptEnd.transformBy(xform); // 变换向量 AcGeVector3d vtSta(StartVect()), vtEnd(EndVect()); vtSta.transformBy(xform); vtEnd.transformBy(xform); vtSta.normalize(); vtEnd.normalize(); // 更新点 m_pXDataMap->SetAt(HOFF_StartPoint, ptStart); m_pXDataMap->SetAt(HOFF_EndPoint, ptEnd); // 更新向量 m_pXDataMap->SetAt(HOFF_StartDir, vtSta); m_pXDataMap->SetAt(HOFF_EndDir, vtEnd); // 设置尺寸 double dScale = xform.scale(); double dStaWidth(0.0), dEndWidth(0.), dHeigh(0.0); m_pXDataMap->GetAt(HOFF_StartWidth, dStaWidth); m_pXDataMap->GetAt(HOFF_EndWidth, dEndWidth); m_pXDataMap->GetAt(HOFF_Thick, dHeigh); dStaWidth *= dScale; dEndWidth *= dScale; dHeigh *= dScale; m_pXDataMap->SetAt(HOFF_StartWidth, dStaWidth); m_pXDataMap->SetAt(HOFF_EndWidth, dEndWidth); m_pXDataMap->SetAt(HOFF_Thick, dHeigh); // 传递消息 if (m_pOwnerEnt != NULL && m_pOwnerEnt->objectId().isValid()) { // 如果实体不是在当前模型空间中,不做写消息,更新接口处理 AcDbDatabase* pDb = m_pOwnerEnt->database(); if (pDb == NULL) pDb = acdbCurDwg(); AcDbObjectId idModel; AcDbBlockTable* pTable = NULL; pDb->getBlockTable(pTable, AcDb::kForRead); if (pTable != NULL) { pTable->getAt(ACDB_MODEL_SPACE, idModel); pTable->close(); } // 如果实体不是在当前模型空间中,不做写消息,更新接口处理 if (idModel == m_pOwnerEnt->blockId()) { // 写入接口更改消息 TInterfaceModifyMsg iMsg; iMsg.SetMsgValidate(TRUE); iMsg.SetTransform(xform); iMsg.SetMsgOperateOn(m_pOwnerEnt->objectId()); TDbInterfaceMsgWrite msgWrite; msgWrite.WriteInterfaceMsg(iMsg); //更新接口记录接口信息 UpdateInterfaceRec(m_pOwnerEnt->objectId(), xform); } } return Acad::eOk; } TDb::Position THImpHvacOffset::ExplainGripIndex( int nIndex ) const { Position ePos = eStart; switch(nIndex) { case 0: ePos = eStart; break; case 1: ePos = eEnd; break; case 2: ePos = eCommand0; break; case 3: ePos = eCommand1; break; default: break; } return ePos; } // 管件不需要拉伸 Acad::ErrorStatus THImpHvacOffset::getStretchPoints( AcGePoint3dArray& stretchPoints ) const { if (NULL == m_pXDataMap) return Acad::eNotApplicable; AcGePoint3d ptSta, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptSta); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); stretchPoints.append(ptSta); stretchPoints.append(ptEnd); return Acad::eOk; } Acad::ErrorStatus THImpHvacOffset::getGripPoints( AcGePoint3dArray& gripPoints, AcDbIntArray& osnapModes, AcDbIntArray& geomIds ) const { if (NULL == m_pXDataMap) return Acad::eNotApplicable; // 获取各点位置、向量 AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); AcGeVector3d vtStart(StartVect()), vtEnd(EndVect()); HvacOffsetType eType = eArcuateLink; HvacSectType eSectType = eRectangular; m_pXDataMap->GetAt(HOFF_Type, (int&)eType); m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType); double dStartWidth(0.0), dEndWidth(0.0), dThick(0.0); m_pXDataMap->GetAt(HOFF_StartWidth, dStartWidth); m_pXDataMap->GetAt(HOFF_EndWidth, dEndWidth); m_pXDataMap->GetAt(HOFF_Thick, dThick); gripPoints.append(ptStart); gripPoints.append(ptEnd); // 取得10个像素点在世界坐标系下的长度,距两端距离 // double dCmdOff = PixelToWcs(10); AcGePoint3d ptCommand1, ptCommand2; AcGeVector3d vtUserZAixs = TAuxTools::GetUcsZvt(); if (IsHorzAlignment() || IsFaceVertAlignment()) { ptCommand1 = ptStart + g_dCmdOff * vtStart; ptCommand2 = ptEnd + g_dCmdOff * vtEnd; } else if (IsSideVertAlignment()) { AcGeVector3d vtCmd = ptStart - ptEnd; vtCmd = vtCmd.orthoProject(vtUserZAixs); vtCmd.normalize(); vtCmd.rotateBy(PI*0.25, vtUserZAixs); ptCommand1 = ptStart + g_dCmdOff * vtCmd; ptCommand2 = ptEnd + g_dCmdOff * vtCmd; } gripPoints.append(ptCommand1); gripPoints.append(ptCommand2); return Acad::eOk; } Acad::ErrorStatus THImpHvacOffset::getOsnapPoints( AcDb::OsnapMode osnapMode, INT_PTR gsSelectionMark, const AcGePoint3d& pickPoint, const AcGePoint3d& lastPoint, const AcGeMatrix3d& viewXform, AcGePoint3dArray& snapPoints, AcDbIntArray& geomIds ) const { if (NULL == m_pXDataMap) return Acad::eNotApplicable; // 取得位置点 AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); // 根据捕捉模式处理 switch(osnapMode) { case AcDb::kOsModeEnd: snapPoints.append(ptStart); snapPoints.append(ptEnd); break; case AcDb::kOsModeMid: snapPoints.append(TAuxTools::Mid(ptStart,ptEnd)); break; case AcDb::kOsModeCen: break; case AcDb::kOsModePerp: break; case AcDb::kOsModeNear: break; } return Acad::eOk; } Acad::ErrorStatus THImpHvacOffset::moveStretchPointsAt( const AcDbIntArray& indices, const AcGeVector3d& offset ) { if (indices.length() < 2) return Acad::eNotImplementedYet; return MoveTransGripPointsAt(TDb::eStart, offset, FALSE); } Acad::ErrorStatus THImpHvacOffset::moveGripPointsAt( const AcDbIntArray& indices, const AcGeVector3d& offset ) { if (NULL == m_pXDataMap || offset.length() < 1e-6) return Acad::eNotImplementedYet; // 如果有多个点,则去除命令点后,有多个点时作为移动,单个点时使用该点类型 Position ePos; if (indices.length() == 1) { // 单个夹点 ePos = ExplainGripIndex(indices[0]); } else { // 多个夹点 int iCount = 0; Position eTemp; int iPos = indices.length(); while ((--iPos) >= 0 && iCount < 2) { eTemp = ExplainGripIndex(indices[iPos]); switch (eTemp) { case eStart: case eEnd: case eMid: case eDim1: case eSizeMid0: case eSizeMid1: ePos = eTemp; iCount++; break; } } // 多个命令夹点不处理 if (iCount == 0) return Acad::eOk; // 多个非命令夹点,移动整体 if (iCount > 1) { MoveTransGripPointsAt(eMid, offset, TRUE); return Acad::eOk; } } switch (ePos) { case eStart: case eEnd: // MoveTransGripPointsAt(ePos, offset); MoveGripRandom(ePos, offset); break; break; case eCommand0: case eCommand1: MoveCommandGripPointsAt(ePos, offset); break; default: break; } return Acad::eOk; } // 拖拽管件,支持转向等操作 Acad::ErrorStatus THImpHvacOffset::MoveGripRandom(TDb::Position ePos, const AcGeVector3d& offset ) { AcGePoint3d ptDrag; if (ePos == eStart) m_pXDataMap->GetAt(HOFF_StartPoint, ptDrag); else m_pXDataMap->GetAt(HOFF_EndPoint, ptDrag); TInterfaceModifyMsg iMsg; iMsg.SetMsgPoint(ptDrag); iMsg.SetGripPosition(ePos); iMsg.SetMoveGripOffset(offset); iMsg.SetMsgValidate(TRUE); iMsg.SetInterfaceOper(eNewCommand); iMsg.SetPreviewObjToCreate(eOffset, 0); // 写入接口更改消息 AcDbSoftPointerId idOwner; m_pXDataMap->GetAt(KEY_THISID, idOwner); iMsg.SetMsgOperateOn(idOwner); TDbInterfaceMsgWrite msgWrite; msgWrite.WriteInterfaceMsg(iMsg); // 发送消息 acedPostCommand(_T("\33")); acedPostCommand(_T("znyd\n")); return Acad::eOk; } Acad::ErrorStatus THImpHvacOffset::MoveTransGripPointsAt( TDb::Position ePos, const AcGeVector3d& offset, BOOL bAutoWork ) { ASSERT(NULL != m_pXDataMap); AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); ptStart += offset; ptEnd += offset; m_pXDataMap->SetAt(HOFF_StartPoint, ptStart); m_pXDataMap->SetAt(HOFF_EndPoint, ptEnd); // 传递修改消息 if (m_pOwnerEnt != NULL && m_pOwnerEnt->objectId().isValid()) { if (bAutoWork) { AcGePoint3d ptOper; if (ePos == eStart) ptOper = ptStart; else if (ePos == eEnd) ptOper = ptEnd; // 创建接口更改消息 TInterfaceModifyMsg iMsg; iMsg.SetMsgPoint(ptOper); iMsg.SetGripPosition(ePos); iMsg.SetMoveGripOffset(offset); iMsg.SetMsgValidate(TRUE); iMsg.SetInterfaceOper(eMoveGripPoint); iMsg.SetMsgOperateOn(m_pOwnerEnt->objectId()); // 写入接口更改消息 TDbInterfaceMsgWrite msgWrite; msgWrite.WriteInterfaceMsg(iMsg); } //更新自身模型空间的扩展字典的接口信息 AcGeMatrix3d xform; xform.setToTranslation(offset); UpdateInterfaceRec(m_pOwnerEnt->objectId(), xform); return Acad::eOk; } return Acad::eNotImplementedYet; } Acad::ErrorStatus THImpHvacOffset::MoveCommandGripPointsAt( TDb::Position ePos, const AcGeVector3d& offset ) { ASSERT(NULL != m_pXDataMap); // 获得夹点命令 CString sCmdStr; GetGlobalContext()->GetAt(KEY_HVACGRIPCMD, sCmdStr); if (sCmdStr.IsEmpty()) return Acad::eNotApplicable; AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); AcGeVector3d vtStart; m_pXDataMap->GetAt(HOFF_StartDir, vtStart); // 创建接口更改消息 TInterfaceModifyMsg iMsg; AcGePoint3d ptDrag; if (ePos == eCommand0) ptDrag = ptStart; else if (ePos == eCommand1) ptDrag = ptEnd; iMsg.SetMsgPoint(ptDrag); iMsg.SetGripPosition(ePos); iMsg.SetMoveGripOffset(offset); iMsg.SetMsgValidate(TRUE); iMsg.SetInterfaceOper(eNewCommand); iMsg.SetPreviewObjToCreate(eOffset, 0); // 写入接口更改消息 AcDbSoftPointerId idOwner; m_pXDataMap->GetAt(KEY_THISID, idOwner); iMsg.SetMsgOperateOn(idOwner); TDbInterfaceMsgWrite msgWrite; msgWrite.WriteInterfaceMsg(iMsg); // 发送消息 acedPostCommand(_T("\33")); acedPostCommand(sCmdStr + _T("\n")); return Acad::eOk; } AcGeVector3d THImpHvacOffset::StartVect() const { ASSERT(NULL != m_pXDataMap); AcGeVector3d vtSta(AcGeVector3d::kIdentity); if (NULL != m_pXDataMap) m_pXDataMap->GetAt(HOFF_StartDir, vtSta); return vtSta; } AcGeVector3d THImpHvacOffset::EndVect() const { ASSERT(NULL != m_pXDataMap); AcGeVector3d vtEnd(AcGeVector3d::kIdentity); if (NULL != m_pXDataMap) m_pXDataMap->GetAt(HOFF_EndDir, vtEnd); return vtEnd; } AcGeVector3d THImpHvacOffset::normal() const { ASSERT(NULL != m_pXDataMap); AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); AcGeVector3d vtEnd(EndVect()); AcGeVector3d vtDirect = ptEnd- ptStart; AcGeVector3d vtNormal = vtDirect.crossProduct(vtEnd); vtNormal.normalize(); return vtNormal; } BOOL THImpHvacOffset::IsHorzAlignment() const { ASSERT(NULL != m_pXDataMap); AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); AcGeVector3d vtUserZAxis = TAuxTools::GetUcsZvt(); AcGeVector3d vtSub = ptEnd - ptStart; return vtSub.isPerpendicularTo(vtUserZAxis); } BOOL THImpHvacOffset::IsSideVertAlignment() const { ASSERT(NULL != m_pXDataMap); AcGeVector3d vtUserZAxis = TAuxTools::GetUcsZvt(); return StartVect().isParallelTo(vtUserZAxis); } BOOL THImpHvacOffset::IsFaceVertAlignment() const { ASSERT(NULL != m_pXDataMap); AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); AcGeVector3d vtSub = ptEnd - ptStart; AcGeVector3d vtSta; m_pXDataMap->GetAt(HOFF_StartDir, vtSta); AcGeVector3d vtUserZAxis = TAuxTools::GetUcsZvt(); AcGeVector3d vtSubPrj = vtSub.orthoProject(TAuxTools::GetUcsZvt()); AcGeVector3d vtStaPrj = vtSta.orthoProject(TAuxTools::GetUcsZvt()); return vtSubPrj.isParallelTo(vtStaPrj); } BOOL THImpHvacOffset::IsSingleLine() const { ASSERT(NULL != m_pXDataMap); BOOL bSingleLine = FALSE; m_pXDataMap->GetAt(HVAC_IsSingleLine, (int&)bSingleLine); return bSingleLine; } BOOL THImpHvacOffset::IsBaseLine() const { ASSERT(NULL != m_pXDataMap); BOOL bBaseLine = FALSE; m_pXDataMap->GetAt(HVAC_HasBaseLine, (int&)bBaseLine); return bBaseLine; } Acad::ErrorStatus THImpHvacOffset::ExplodeOrDraw3d( XExplodeDraw &mode ) const { if (NULL == m_pXDataMap) return Acad::eNotImplementedYet; if (!IsCanDraw()) return Acad::eNotImplementedYet; HvacOffsetType eType = eArcuateLink; HvacSectType eSectType = eRectangular; m_pXDataMap->GetAt(HOFF_Type, (int&)eType); m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType); if (eType == eArcuateLink) { if (eSectType == eRectangular) return ExplodeOrDrawRectArcuate3d(mode); else if (eSectType == eCircular) return ExplodeOrDrawCircleArcuate3d(mode); } else if (eType == eLinearLink) { if (eSectType == eRectangular) return ExplodeOrDrawRectLinear3d(mode); else if (eSectType == eCircular) return ExplodeOrDrawCircleLinear3d(mode); } return Acad::eNotImplementedYet; } Acad::ErrorStatus THImpHvacOffset::ExplodeOrDraw2d( XExplodeDraw &mode ) const { if (NULL == m_pXDataMap) return Acad::eNotImplementedYet; TComplexCurve cplCurve; MakeCurves(cplCurve); TDbExtentsEdge edage; edage.SetEdage(cplCurve); AcDbObjectId idReal = ((TDbInterfacesObj*)m_pOwnerEnt)->layerId(); AcDbObjectId idDash = ((TDbInterfacesObj*)m_pOwnerEnt)->DashLayer(); AcDbObjectId idCent = ((TDbInterfacesObj*)m_pOwnerEnt)->CenterLayer(); edage.ExplodeOrDraw2d(mode,idReal,idDash,idCent,NULL,FALSE,FALSE); return Acad::eOk; } BOOL THImpHvacOffset::MakeCurves( TComplexCurve& compCurve ) const { if (NULL == m_pXDataMap) return FALSE; if (!IsSingleLine() && !IsCanDraw()) return FALSE; if (IsHorzAlignment()) { HvacOffsetType eType = eArcuateLink; m_pXDataMap->GetAt(HOFF_Type, (int&)eType); if (eType == eArcuateLink) return MakeHorizArcuate2DCurves(compCurve, 0); else if (eType == eLinearLink) return MakeHorizLinear2DCurves(compCurve, 0); } else if (IsSideVertAlignment()) { HvacSectType eSectType = eRectangular; m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType); if (eSectType == eRectangular) return MakeSideVertRect2DCurves(compCurve, 0); else if (eSectType == eCircular) return MakeSideVertCircle2DCurves(compCurve, 0); } else if (IsFaceVertAlignment()) { return MakeFaceVert2DCurves(compCurve, 0); } return FALSE; } BOOL THImpHvacOffset::GetCurvesInSide( TComplexCurve& compCurve ) const { if (NULL == m_pXDataMap) return FALSE; if (!IsSingleLine() && !IsCanDraw()) return FALSE; if (IsHorzAlignment()) { HvacOffsetType eType = eArcuateLink; m_pXDataMap->GetAt(HOFF_Type, (int&)eType); if (eType == eArcuateLink) return MakeHorizArcuate2DCurves(compCurve, 1); else if (eType == eLinearLink) return MakeHorizLinear2DCurves(compCurve, 1); } else if (IsSideVertAlignment()) { HvacSectType eSectType = eRectangular; m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType); if (eSectType == eRectangular) return MakeSideVertRect2DCurves(compCurve, 1); else if (eSectType == eCircular) return MakeSideVertCircle2DCurves(compCurve, 1); } else if (IsFaceVertAlignment()) { return MakeFaceVert2DCurves(compCurve, 1); } return FALSE; } AcDbPolyline* THImpHvacOffset::MakePolyCurve() const { if (NULL == m_pXDataMap) return NULL; if (IsHorzAlignment()) { HvacOffsetType eType = eArcuateLink; m_pXDataMap->GetAt(HOFF_Type, (int&)eType); if (eType == eArcuateLink) return MakeHorizArcuatePolyCurves(); else if (eType == eLinearLink) return MakeHorizLinearPolyCurves(); } else if (IsSideVertAlignment()) { HvacSectType eSectType = eRectangular; m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType); if (eSectType == eRectangular) return MakeSideVertRectPolyCurves(); else if (eSectType == eCircular) return MakeSideVertCirclePolyCurves(); } else if (IsFaceVertAlignment()) { return MakeFaceVertPolyCurves(); } return NULL; } BOOL THImpHvacOffset::MakePolyCurveFaces( AcDbVoidPtrArray& arFaces ) { if (NULL == m_pXDataMap) return FALSE; if (IsHorzAlignment()) { HvacOffsetType eType = eArcuateLink; m_pXDataMap->GetAt(HOFF_Type, (int&)eType); if (eType == eArcuateLink) return MakeHorizArcuateCurvesFaces(arFaces); else if (eType == eLinearLink) return MakeHorizLinearCurvesFaces(arFaces); } else if (IsSideVertAlignment()) { HvacSectType eSectType = eRectangular; m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType); if (eSectType == eRectangular) return MakeSideVertRectCurvesFaces(arFaces); else if (eSectType == eCircular) return MakeSideVertCircleCurvesFaces(arFaces); } else if (IsFaceVertAlignment()) { return MakeFaceVertCurvesFaces(arFaces); } return FALSE; } Acad::ErrorStatus THImpHvacOffset::ExplodeOrDrawRectArcuate3d( XExplodeDraw &mode ) const { AcGePoint3dArray ptLeftArr, ptRightArr; GetAllMinAnglePt(ptLeftArr, ptRightArr); if (ptLeftArr.length() != ptRightArr.length() || 7 > ptLeftArr.length()) return Acad::eNotImplementedYet; double dHalfThick(0.0); m_pXDataMap->GetAt(HOFF_Thick, dHalfThick); dHalfThick *= 0.5; AcGeVector3d vtNormal = normal(); AcGeVector3d vtOff = dHalfThick * vtNormal; AcGePoint3dArray ptMeshArr; int i(0); for (i = 0; i < ptLeftArr.length(); i++) { ptMeshArr.append(ptLeftArr[i] + vtOff); ptMeshArr.append(ptRightArr[i] + vtOff); ptMeshArr.append(ptRightArr[i] - vtOff); ptMeshArr.append(ptLeftArr[i] - vtOff); ptMeshArr.append(ptLeftArr[i] + vtOff); } mode.DrawMesh(ptLeftArr.length(), 5, ptMeshArr.asArrayPtr()); return Acad::eOk; } Acad::ErrorStatus THImpHvacOffset::ExplodeOrDrawRectLinear3d( XExplodeDraw &mode ) const { AcGePoint3dArray ptUpArr, ptDownArr; if (!GetTwoSideKeyPoints(ptUpArr, ptDownArr)) return Acad::eNotImplementedYet; if (8 != ptDownArr.length() || 8 != ptUpArr.length()) return Acad::eNotImplementedYet; AcGePoint3dArray ptMeshArr; ptMeshArr.append(ptUpArr[1]); ptMeshArr.append(ptUpArr[0]); ptMeshArr.append(ptDownArr[0]); ptMeshArr.append(ptDownArr[1]); ptMeshArr.append(ptUpArr[1]); ptMeshArr.append(ptUpArr[2]); ptMeshArr.append(ptUpArr[7]); ptMeshArr.append(ptDownArr[7]); ptMeshArr.append(ptDownArr[2]); ptMeshArr.append(ptUpArr[2]); ptMeshArr.append(ptUpArr[3]); ptMeshArr.append(ptUpArr[6]); ptMeshArr.append(ptDownArr[6]); ptMeshArr.append(ptDownArr[3]); ptMeshArr.append(ptUpArr[3]); ptMeshArr.append(ptUpArr[4]); ptMeshArr.append(ptUpArr[5]); ptMeshArr.append(ptDownArr[5]); ptMeshArr.append(ptDownArr[4]); ptMeshArr.append(ptUpArr[4]); mode.DrawMesh(4, 5, ptMeshArr.asArrayPtr()); // AcGePoint3dArray ptMeshArr; // ptMeshArr.append(ptUpArr[1]); // ptMeshArr.append(ptUpArr[2]); // ptMeshArr.append(ptDownArr[1]); // ptMeshArr.append(ptDownArr[2]); // ptMeshArr.append(ptDownArr[0]); // ptMeshArr.append(ptDownArr[3]); // ptMeshArr.append(ptUpArr[0]); // ptMeshArr.append(ptUpArr[3]); // ptMeshArr.append(ptUpArr[1]); // ptMeshArr.append(ptUpArr[2]); // mode.DrawMesh(5, 2, ptMeshArr.asArrayPtr()); return Acad::eOk; } // 先找出左右两侧弧所有最小分度角点,然后循环求出每段圆中各分度角点 Acad::ErrorStatus THImpHvacOffset::ExplodeOrDrawCircleArcuate3d( XExplodeDraw &mode ) const { AcGePoint3dArray ptLeftArr, ptRightArr; GetAllMinAnglePt(ptLeftArr, ptRightArr); if (ptLeftArr.length() != ptRightArr.length() || 7 > ptLeftArr.length()) return Acad::eNotImplementedYet; double dMinAngle(TAuxTools::GetMinDiffAngle()); double dCircleMinAngle(0.0); int nCirclePart = (int)(PI*2 / dMinAngle) + 1; dCircleMinAngle = PI*2 / nCirclePart; // 每段圆左/右侧点,循环点, 每段圆心点 AcGePoint3d ptLeft, ptRight, ptNow, ptCenter; // 每段相切、垂直向量, 法向 AcGeVector3d vtTangEvery, vtPerlEvery, vtNormal(normal()); AcGePoint3dArray ptArrMesh; int i(0), j(0); for (i = 0; i < ptLeftArr.length(); i++) { vtPerlEvery = ptLeftArr[i] - ptRightArr[i]; vtTangEvery = vtPerlEvery.crossProduct(vtNormal); ptCenter = TAuxTools::Mid(ptLeftArr[i], ptRightArr[i]); ptNow = ptLeftArr[i]; for (j = 0; j < nCirclePart; j++) { ptArrMesh.append(ptNow); ptNow.rotateBy(dCircleMinAngle, vtTangEvery, ptCenter); } ptArrMesh.append(ptLeftArr[i]); } mode.DrawMesh(ptLeftArr.length(), nCirclePart + 1, ptArrMesh.asArrayPtr()); return Acad::eOk; } Acad::ErrorStatus THImpHvacOffset::ExplodeOrDrawCircleLinear3d( XExplodeDraw &mode ) const { double dRadius(0.0), dPluse(0.0); m_pXDataMap->GetAt(HOFF_Diameter, dRadius); dRadius *= 0.5; m_pXDataMap->GetAt(HVAC_PlusEdge, dPluse); AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); AcGeVector3d vtStart(StartVect()); AcGeVector3d vtDirect = (ptEnd + dPluse * vtStart) - (ptStart - dPluse * vtStart); AcGeVector3d vtNormal = normal(); double dMinAngle(TAuxTools::GetMinDiffAngle()); int nPart = (int)(PI*2 / dMinAngle) + 1; dMinAngle = PI*2 / nPart; AcGePoint3dArray ptMeshArr; AcGePoint3d ptStartFirst = ptStart + dRadius * vtNormal; AcGePoint3d ptStartNow = ptStartFirst; AcGePoint3d ptNext; int i(0); for (i = 0; i < nPart + 1; i++) { ptMeshArr.append(ptStartNow); ptNext = ptStartNow - dPluse * vtStart; ptMeshArr.append(ptNext); ptNext += vtDirect; ptMeshArr.append(ptNext); ptNext -= dPluse * vtStart; ptMeshArr.append(ptNext); ptStartNow.rotateBy(dMinAngle, vtStart, ptStart); } mode.DrawMesh(nPart + 1, 4, ptMeshArr.asArrayPtr()); return Acad::eOk; } // 按两个弯头连接,有变径时在起始端半部变 BOOL THImpHvacOffset::MakeHorizArcuate2DCurves( TComplexCurve& cplCurve, const int &nOutOrIn ) const { TCurveElement tCurveEle; memset(&tCurveEle, 0, sizeof(TCurveElement)); tCurveEle.bHided = FALSE; tCurveEle.dWidth = 0.0; tCurveEle.gsMark = 0; double dEdgeWidth(GetEdgeLineWidth()); if (IsSingleLine() || (IsBaseLine() && nOutOrIn == 1)) { AcGePoint3dArray ptBaseArr; if (!GetArcBaseKeyPt(ptBaseArr) || ptBaseArr.length() != 7) return FALSE; if (IsSingleLine()) tCurveEle.dWidth = dEdgeWidth; else { tCurveEle.dWidth = GetCentLineWidth(); tCurveEle.idSubLay = GetBaseLayerId(); } AutoAppendPt(cplCurve, tCurveEle, ptBaseArr[0], ptBaseArr[1], ptBaseArr[1]); AutoAppendPt(cplCurve, tCurveEle, ptBaseArr[1], ptBaseArr[2], ptBaseArr[3]); AutoAppendPt(cplCurve, tCurveEle, ptBaseArr[3], ptBaseArr[4], ptBaseArr[5]); AutoAppendPt(cplCurve, tCurveEle, ptBaseArr[5], ptBaseArr[6], ptBaseArr[6]); } else if (nOutOrIn == 0) { AcGePoint3dArray ptLeftArr, ptRightArr; if (!GetArcTwoSideKeyPt(ptLeftArr, ptRightArr)) return FALSE; if (7 != ptLeftArr.length() || 7 != ptRightArr.length()) return FALSE; tCurveEle.dWidth = dEdgeWidth; AutoAppendPt(cplCurve, tCurveEle, ptLeftArr[0], ptLeftArr[1], ptLeftArr[1]); AutoAppendPt(cplCurve, tCurveEle, ptLeftArr[1], ptLeftArr[2], ptLeftArr[3]); AutoAppendPt(cplCurve, tCurveEle, ptLeftArr[3], ptLeftArr[4], ptLeftArr[5]); AutoAppendPt(cplCurve, tCurveEle, ptLeftArr[5], ptLeftArr[6], ptLeftArr[6]); AutoAppendPt(cplCurve, tCurveEle, ptRightArr[0], ptRightArr[1], ptRightArr[1]); AutoAppendPt(cplCurve, tCurveEle, ptRightArr[1], ptRightArr[2], ptRightArr[3]); AutoAppendPt(cplCurve, tCurveEle, ptRightArr[3], ptRightArr[4], ptRightArr[5]); AutoAppendPt(cplCurve, tCurveEle, ptRightArr[5], ptRightArr[6], ptRightArr[6]); tCurveEle.dWidth = GetEndLineWidth(); m_pXDataMap->GetAt(HVAC_EndLayer, tCurveEle.idSubLay); AutoAppendPt(cplCurve, tCurveEle, ptLeftArr[0], ptRightArr[0], ptRightArr[0]); AutoAppendPt(cplCurve, tCurveEle, ptLeftArr[6], ptRightArr[6], ptRightArr[6]); } return TRUE; } BOOL THImpHvacOffset::MakeHorizLinear2DCurves( TComplexCurve& cplCurve, const int &nOutOrIn ) const { TCurveElement tCurveEle; memset(&tCurveEle, 0, sizeof(TCurveElement)); tCurveEle.bHided = FALSE; tCurveEle.dWidth = 0.0; tCurveEle.gsMark = 0; double dEdgeWidth(GetEdgeLineWidth()); if (IsSingleLine() || (IsBaseLine() && nOutOrIn == 1)) { AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); double dPlus(0.0); m_pXDataMap->GetAt(HVAC_PlusEdge, dPlus); AcGeVector3d vtSta(StartVect()), vtEnd(EndVect()); AcGePoint3d ptStaPlus = ptStart - dPlus * vtSta; AcGePoint3d ptEndPlus = ptEnd - dPlus * vtEnd; if (IsSingleLine()) tCurveEle.dWidth = dEdgeWidth; else { tCurveEle.dWidth = GetCentLineWidth(); tCurveEle.idSubLay = GetBaseLayerId(); } AutoAppendPt(cplCurve, tCurveEle, ptStart, ptStaPlus, ptStaPlus); AutoAppendPt(cplCurve, tCurveEle, ptStaPlus, ptEndPlus, ptEndPlus); AutoAppendPt(cplCurve, tCurveEle, ptEndPlus, ptEnd, ptEnd); return TRUE; } else if (nOutOrIn == 0) { AcGePoint3dArray ptArr; GetMidKeyPoints(ptArr); int i(0); for (i = 0; i < ptArr.length() - 1; i++) { if (i == 0 || i == 4) { tCurveEle.dWidth = GetEndLineWidth(); m_pXDataMap->GetAt(HVAC_EndLayer, tCurveEle.idSubLay); } else { tCurveEle.dWidth = dEdgeWidth; tCurveEle.idSubLay.setNull(); } AutoAppendPt(cplCurve, tCurveEle, ptArr[i], ptArr[i+1], ptArr[i+1]); } AutoAppendPt(cplCurve, tCurveEle, ptArr[i], ptArr[0], ptArr[0]); } return TRUE; } BOOL THImpHvacOffset::MakeSideVertRect2DCurves( TComplexCurve& cplCurve, const int &nOutOrIn ) const { TCurveElement tCurveEle; memset(&tCurveEle, 0, sizeof(TCurveElement)); tCurveEle.bHided = FALSE; tCurveEle.dWidth = 0.0; tCurveEle.gsMark = 0; AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); AcGePoint3d ptMid = TAuxTools::Mid(ptStart, ptEnd); AcGePlane planStd = GetStdPrjPlan(ptMid); double dEdgeWidth(GetEdgeLineWidth()), dCentWidth(GetCentLineWidth()); if (IsSingleLine()) { tCurveEle.dWidth = dEdgeWidth; AutoAppendPt(cplCurve, tCurveEle, ptStart.orthoProject(planStd), ptEnd.orthoProject(planStd), ptEnd.orthoProject(planStd)); return TRUE; } AcGePoint3dArray ptUpArr, ptDownArr; GetTwoSideKeyPoints(ptUpArr, ptDownArr); if (8 != ptUpArr.length() || 8 != ptDownArr.length()) return FALSE; int nEnd1(0), nEnd2(0); GetEndPointIndex(ptUpArr, nEnd1, nEnd2); if(nOutOrIn == 1) { tCurveEle.dWidth = dEdgeWidth; int i(0); for (i = 0; i < ptUpArr.length(); i++) { if (i == nEnd1 || i == nEnd2) continue; AutoAppendPt(cplCurve, tCurveEle, ptDownArr[i].orthoProject(planStd), ptUpArr[i].orthoProject(planStd), ptUpArr[i].orthoProject(planStd)); } if (IsBaseLine()) { tCurveEle.dWidth = dCentWidth; tCurveEle.idSubLay = GetBaseLayerId(); AutoAppendPt(cplCurve, tCurveEle, ptStart.orthoProject(planStd), ptEnd.orthoProject(planStd), ptEnd.orthoProject(planStd)); } } else if (nOutOrIn == 0) { tCurveEle.dWidth = dEdgeWidth; // 端点两边 AutoAppendPt(cplCurve, tCurveEle, ptDownArr[nEnd1].orthoProject(planStd), ptUpArr[nEnd1].orthoProject(planStd), ptUpArr[nEnd1].orthoProject(planStd)); AutoAppendPt(cplCurve, tCurveEle, ptDownArr[nEnd2].orthoProject(planStd), ptUpArr[nEnd2].orthoProject(planStd), ptUpArr[nEnd2].orthoProject(planStd)); // 侧部两边 AutoAppendPt(cplCurve, tCurveEle, ptDownArr[nEnd1].orthoProject(planStd), ptDownArr[nEnd2].orthoProject(planStd), ptDownArr[nEnd2].orthoProject(planStd)); AutoAppendPt(cplCurve, tCurveEle, ptUpArr[nEnd1].orthoProject(planStd), ptUpArr[nEnd2].orthoProject(planStd), ptUpArr[nEnd2].orthoProject(planStd)); } return Acad::eOk; } BOOL THImpHvacOffset::MakeSideVertCircle2DCurves( TComplexCurve& cplCurve, const int &nOutOrIn ) const { TCurveElement tCurveEle; memset(&tCurveEle, 0, sizeof(TCurveElement)); tCurveEle.bHided = FALSE; tCurveEle.dWidth = 0.0; tCurveEle.gsMark = 0; AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); double dRadius(0.0); m_pXDataMap->GetAt(HOFF_Diameter, dRadius); dRadius *= 0.5; AcGePoint3d ptMid = TAuxTools::Mid(ptStart, ptEnd); AcGePlane planStd = GetStdPrjPlan(ptMid); ptStart = ptStart.orthoProject(planStd); ptEnd = ptEnd.orthoProject(planStd); double dEdgeWidth(GetEdgeLineWidth()), dCentWidth(GetCentLineWidth()); if (IsSingleLine()) { tCurveEle.dWidth = dEdgeWidth; AutoAppendPt(cplCurve, tCurveEle, ptStart, ptEnd, ptEnd); return TRUE; } AcGeVector3d vtNormal = normal(); AcGeVector3d vtDirect = ptEnd - ptStart; vtDirect.normalize(); AcGePoint3d ptStartCirSta, ptStartCirMid, ptStartCirEnd; // 起始半圆各点 AcGePoint3d ptEndCirSta, ptEndCirMid, ptEndCirEnd; // 末半圆各点 ptStartCirSta = ptStart + dRadius * vtNormal; ptStartCirEnd = ptStart - dRadius * vtNormal; ptEndCirSta = ptEnd + dRadius * vtNormal; ptEndCirEnd = ptEnd - dRadius * vtNormal; if(nOutOrIn == 1) { tCurveEle.dWidth = dEdgeWidth; // 起始端半圆 ptStartCirMid = ptStart + dRadius * vtDirect; AutoAppendPt(cplCurve, tCurveEle, ptStartCirSta, ptStartCirMid, ptStartCirEnd); // 末端半圆 ptEndCirMid = ptEnd - dRadius * vtDirect; AutoAppendPt(cplCurve, tCurveEle, ptEndCirSta, ptEndCirMid, ptEndCirEnd); if (IsBaseLine()) { tCurveEle.dWidth = dCentWidth; tCurveEle.idSubLay = GetBaseLayerId(); AutoAppendPt(cplCurve, tCurveEle, ptStart, ptEnd, ptEnd); } } else if (nOutOrIn == 0) { tCurveEle.dWidth = dEdgeWidth; // 两边 AutoAppendPt(cplCurve, tCurveEle, ptStartCirSta, ptEndCirSta, ptEndCirSta); AutoAppendPt(cplCurve, tCurveEle, ptStartCirEnd, ptEndCirEnd, ptEndCirEnd); // 两半圆 ptStartCirMid = ptStart - dRadius * vtDirect; AutoAppendPt(cplCurve, tCurveEle, ptStartCirSta, ptStartCirMid, ptStartCirEnd); ptEndCirMid = ptEnd + dRadius * vtDirect; AutoAppendPt(cplCurve, tCurveEle, ptEndCirSta, ptEndCirMid, ptEndCirEnd); } return TRUE; } BOOL THImpHvacOffset::MakeFaceVert2DCurves( TComplexCurve& cplCurve, const int &nOutOrIn ) const { TCurveElement tCurveEle; memset(&tCurveEle, 0, sizeof(TCurveElement)); tCurveEle.bHided = FALSE; tCurveEle.dWidth = 0.0; tCurveEle.gsMark = 0; AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); AcGePoint3d ptMid = TAuxTools::Mid(ptStart, ptEnd); AcGePlane planStd = GetStdPrjPlan(ptMid); AcGePoint3dArray ptUpArr, ptDownArr; GetTwoSideKeyPoints(ptUpArr, ptDownArr); if (8 != ptUpArr.length() || 8 != ptDownArr.length()) return FALSE; double dEdgeWidth(GetEdgeLineWidth()), dCentWidth(GetCentLineWidth()); if (IsSingleLine()) { tCurveEle.dWidth = dEdgeWidth; AutoAppendPt(cplCurve, tCurveEle, ptStart.orthoProject(planStd), ptEnd.orthoProject(planStd), ptEnd.orthoProject(planStd)); return Acad::eOk; } if (nOutOrIn == 1) { // 技术支持反馈,不画端部弧直分隔线 // tCurveEle.dWidth = dEdgeWidth; // AutoAppendPt(cplCurve, tCurveEle, ptDownArr[2].orthoProject(planStd), // ptUpArr[2].orthoProject(planStd), ptUpArr[2].orthoProject(planStd)); // // AutoAppendPt(cplCurve, tCurveEle, ptDownArr[3].orthoProject(planStd), // ptUpArr[3].orthoProject(planStd), ptUpArr[3].orthoProject(planStd)); if (IsBaseLine()) { tCurveEle.dWidth = dCentWidth; tCurveEle.idSubLay = GetBaseLayerId(); AutoAppendPt(cplCurve, tCurveEle, ptStart.orthoProject(planStd), ptEnd.orthoProject(planStd), ptEnd.orthoProject(planStd)); } } else if (nOutOrIn == 0) { tCurveEle.dWidth = dEdgeWidth; AutoAppendPt(cplCurve, tCurveEle, ptUpArr[1].orthoProject(planStd), ptUpArr[4].orthoProject(planStd), ptUpArr[4].orthoProject(planStd)); AutoAppendPt(cplCurve, tCurveEle, ptDownArr[4].orthoProject(planStd), ptDownArr[1].orthoProject(planStd), ptDownArr[1].orthoProject(planStd)); tCurveEle.dWidth = GetEndLineWidth(); m_pXDataMap->GetAt(HVAC_EndLayer, tCurveEle.idSubLay); AutoAppendPt(cplCurve, tCurveEle, ptDownArr[1].orthoProject(planStd), ptUpArr[1].orthoProject(planStd), ptUpArr[1].orthoProject(planStd)); AutoAppendPt(cplCurve, tCurveEle, ptUpArr[4].orthoProject(planStd), ptDownArr[4].orthoProject(planStd), ptDownArr[4].orthoProject(planStd)); // 中间加箭头标示,上升(下降)摇手弯,及气流方向 // 长度为乙子弯长度1/2,三条线均分宽度 // 箭头7.5度 /* 0━━━━━━1 高标高 \ \ Start \ 4 End \ \ \ \ 2━━━━━━━━3 低标高 */ int nDrawMode(0); m_pXDataMap->GetAt(HOFF_VertDrawStyle, nDrawMode); if (1 == nDrawMode) { int nFlowDir(0); m_pXDataMap->GetAt(HVAC_FlowDirect, nFlowDir); AcGePoint3d ptArrorArr[5], ptRectArr[4]; ptRectArr[0] = ptDownArr[1].orthoProject(planStd); ptRectArr[1] = ptUpArr[1].orthoProject(planStd); ptRectArr[2] = ptUpArr[4].orthoProject(planStd); ptRectArr[3] = ptDownArr[4].orthoProject(planStd); double dLen = ptRectArr[0].distanceTo(ptRectArr[3]); double dWidth = ptRectArr[0].distanceTo(ptRectArr[1]); AcGeVector3d vtLen, vtWidth; vtLen = (ptRectArr[3] - ptRectArr[0]).normalize(); vtWidth = (ptRectArr[1] - ptRectArr[0]).normalize(); AcGeVector3d vtHook = vtWidth; double dHookOff = dLen/12 * tan(7.5/180.0*PI); if (dHookOff > dWidth/3) dHookOff = dWidth/3; if (nFlowDir == 0) // 起始点流向终点 { // ptArrorArr[0] = ptRectArr[0] + vtWidth * dWidth/3 + vtLen * dLen/4; // ptArrorArr[1] = ptArrorArr[0] + vtLen * dLen/6; // ptArrorArr[3] = ptRectArr[2] - vtWidth * dWidth/3 - vtLen * dLen/4; // ptArrorArr[2] = ptArrorArr[3] - vtLen * dLen/6; // ptArrorArr[4] = ptArrorArr[3] - vtLen * dLen/12; // // // 纠正末尾钩子方向 // AcGeVector3d vtDirect = ptArrorArr[3] - ptArrorArr[0]; // vtDirect.rotateBy(PI*0.5, TAuxTools::GetUcsZvt()); // if (vtHook.angleTo(vtDirect) > PI*0.5) // vtHook *= -1; // // ptArrorArr[4] += vtHook * dHookOff; // add by dyw 2015.12.1 绘制乙字弯时上述图形有时不与风管的标高方向一致 TFS9874 // 注:乙字弯的流向在外部没有使用,所以暂未考虑逆向的画法 AcGeVector3d vecTmp = ptEnd - ptStart; if(vecTmp.angleTo(TAuxTools::GetUcsXvt()) - PI * 0.5 < 1E-6) { ptArrorArr[0] = ptRectArr[0] + vtWidth * dWidth/3 + vtLen * dLen/4; ptArrorArr[1] = ptArrorArr[0] + vtLen * dLen/6; ptArrorArr[3] = ptRectArr[2] - vtWidth * dWidth/3 - vtLen * dLen/4; ptArrorArr[2] = ptArrorArr[3] - vtLen * dLen/6; ptArrorArr[4] = ptArrorArr[3] - vtLen * dLen/12; // 纠正末尾钩子方向 AcGeVector3d vtDirect = ptArrorArr[3] - ptArrorArr[0]; vtDirect.rotateBy(PI*0.5, TAuxTools::GetUcsZvt()); if (vtHook.angleTo(vtDirect) > PI*0.5) vtHook *= -1; ptArrorArr[4] += vtHook * dHookOff; } else { ptArrorArr[0] = ptRectArr[1] - vtWidth * dWidth/3 + vtLen * dLen/4; ptArrorArr[1] = ptArrorArr[0] + vtLen * dLen/6; ptArrorArr[3] = ptRectArr[3] + vtWidth * dWidth/3 - vtLen * dLen/4; ptArrorArr[2] = ptArrorArr[3] - vtLen * dLen/6; ptArrorArr[4] = ptArrorArr[3] - vtLen * dLen/12; AcGeVector3d vtDirect = ptArrorArr[3] - ptArrorArr[0]; vtDirect.rotateBy(PI*0.5, TAuxTools::GetUcsZvt()); if (vtHook.angleTo(vtDirect) < PI*0.5) vtHook *= -1; ptArrorArr[4] += vtHook * dHookOff; } // add end } else { vtLen *= -1; ptArrorArr[0] = ptRectArr[3] + vtWidth * dWidth/3 + vtLen * dLen/4; ptArrorArr[1] = ptArrorArr[0] + vtLen * dLen/6; ptArrorArr[3] = ptRectArr[1] - vtWidth * dWidth/3 - vtLen * dLen/4; ptArrorArr[2] = ptArrorArr[3] - vtLen * dLen/6; ptArrorArr[4] = ptArrorArr[3] - vtLen * dLen/12; AcGeVector3d vtDirect = ptArrorArr[3] - ptArrorArr[0]; vtDirect.rotateBy(PI*0.5, TAuxTools::GetUcsZvt()); if (vtHook.angleTo(vtDirect) > PI*0.5) vtHook *= -1; ptArrorArr[4] += vtHook * dHookOff; } tCurveEle.dWidth = dEdgeWidth; tCurveEle.idSubLay.setNull(); AutoAppendPt(cplCurve, tCurveEle, ptArrorArr[0], ptArrorArr[1], ptArrorArr[1]); AutoAppendPt(cplCurve, tCurveEle, ptArrorArr[1], ptArrorArr[2], ptArrorArr[2]); AutoAppendPt(cplCurve, tCurveEle, ptArrorArr[2], ptArrorArr[3], ptArrorArr[3]); AutoAppendPt(cplCurve, tCurveEle, ptArrorArr[3], ptArrorArr[4], ptArrorArr[4]); } else if (2 == nDrawMode) // add by cq 2016-07-12 增加乙字弯样式 TFS14954 { int nFlowDir(0); m_pXDataMap->GetAt(HVAC_FlowDirect, nFlowDir); AcGePoint3d ptArrorArr[5], ptRectArr[4]; ptRectArr[0] = ptDownArr[1].orthoProject(planStd); ptRectArr[1] = ptUpArr[1].orthoProject(planStd); ptRectArr[2] = ptUpArr[4].orthoProject(planStd); ptRectArr[3] = ptDownArr[4].orthoProject(planStd); double dLen = ptRectArr[0].distanceTo(ptRectArr[3]); double dWidth = ptRectArr[0].distanceTo(ptRectArr[1]); AcGeVector3d vtLen, vtWidth; vtLen = (ptRectArr[3] - ptRectArr[0]).normalize(); vtWidth = (ptRectArr[1] - ptRectArr[0]).normalize(); AcGeVector3d vtHook = vtWidth; double dHookOff = dLen/12 * tan(7.5/180.0*PI); if (dHookOff > dWidth/3) dHookOff = dWidth/3; if (nFlowDir == 0) // 起始点流向终点 { // add by dyw 2015.12.1 绘制乙字弯时上述图形有时不与风管的标高方向一致 TFS9874 // 注:乙字弯的流向在外部没有使用,所以暂未考虑逆向的画法 AcGeVector3d vecTmp = ptEnd - ptStart; if(vecTmp.angleTo(TAuxTools::GetUcsXvt()) - PI * 0.5 < 1E-6) { ptArrorArr[0] = ptRectArr[0] + vtWidth * dWidth/3 + vtLen * dLen/4; ptArrorArr[1] = ptArrorArr[0] + vtLen * dLen/6; ptArrorArr[3] = ptRectArr[2] - vtWidth * dWidth/3 - vtLen * dLen/4; ptArrorArr[2] = ptArrorArr[3] - vtLen * dLen/6; } else { ptArrorArr[0] = ptRectArr[1] - vtWidth * dWidth/3 + vtLen * dLen/4; ptArrorArr[1] = ptArrorArr[0] + vtLen * dLen/6; ptArrorArr[3] = ptRectArr[3] + vtWidth * dWidth/3 - vtLen * dLen/4; ptArrorArr[2] = ptArrorArr[3] - vtLen * dLen/6; } } else { vtLen *= -1; ptArrorArr[0] = ptRectArr[3] + vtWidth * dWidth/3 + vtLen * dLen/4; ptArrorArr[1] = ptArrorArr[0] + vtLen * dLen/6; ptArrorArr[3] = ptRectArr[1] - vtWidth * dWidth/3 - vtLen * dLen/4; ptArrorArr[2] = ptArrorArr[3] - vtLen * dLen/6; } tCurveEle.dWidth = dEdgeWidth; tCurveEle.idSubLay.setNull(); AutoAppendPt(cplCurve, tCurveEle, ptArrorArr[0], ptArrorArr[1], ptArrorArr[1]); AutoAppendPt(cplCurve, tCurveEle, ptArrorArr[1], ptArrorArr[2], ptArrorArr[2]); AutoAppendPt(cplCurve, tCurveEle, ptArrorArr[2], ptArrorArr[3], ptArrorArr[3]); } } return Acad::eOk; } AcDbPolyline* THImpHvacOffset::MakeHorizArcuatePolyCurves() const { AcGePoint3dArray ptLeftArr, ptRightArr; if (!GetArcTwoSideKeyPt(ptLeftArr, ptRightArr, IsSingleLine())) return NULL; if (7 != ptLeftArr.length() || 7 != ptRightArr.length()) return NULL; AcGePlane planStd = GetStdPrjPlan(ptLeftArr[0]); double dBulge(0.0); AcDbPolyline* pPolyLine = new AcDbPolyline; pPolyLine->addVertexAt(0, ptLeftArr[0].convert2d(planStd)); dBulge = GetBulge(ptLeftArr[1], ptLeftArr[2], ptLeftArr[3]); pPolyLine->addVertexAt(1, ptLeftArr[1].convert2d(planStd), dBulge); dBulge = GetBulge(ptLeftArr[3], ptLeftArr[4], ptLeftArr[5]); pPolyLine->addVertexAt(2, ptLeftArr[3].convert2d(planStd), dBulge); pPolyLine->addVertexAt(3, ptLeftArr[5].convert2d(planStd)); pPolyLine->addVertexAt(4, ptLeftArr[6].convert2d(planStd)); pPolyLine->addVertexAt(5, ptRightArr[6].convert2d(planStd)); dBulge = GetBulge(ptRightArr[5], ptRightArr[4], ptRightArr[3]); pPolyLine->addVertexAt(6, ptRightArr[5].convert2d(planStd), dBulge); dBulge = GetBulge(ptRightArr[3], ptRightArr[2], ptRightArr[1]); pPolyLine->addVertexAt(7, ptRightArr[3].convert2d(planStd), dBulge); pPolyLine->addVertexAt(8, ptRightArr[1].convert2d(planStd)); pPolyLine->addVertexAt(9, ptRightArr[0].convert2d(planStd)); pPolyLine->setClosed(Adesk::kTrue); pPolyLine->setNormal(planStd.normal()); pPolyLine->setElevation(TAuxTools::GetPlaneEle(planStd)); return pPolyLine; } AcDbPolyline* THImpHvacOffset::MakeHorizLinearPolyCurves() const { AcGePoint3dArray ptArr; GetMidKeyPoints(ptArr, IsSingleLine()); if (8 != ptArr.length()) return NULL; AcGePlane planStd = GetStdPrjPlan(ptArr[0]); AcDbPolyline* pPolyLine = new AcDbPolyline; int i(0); for (i = 0; i < ptArr.length(); i++) { pPolyLine->addVertexAt(i, ptArr[i].convert2d(planStd)); } pPolyLine->setClosed(Adesk::kTrue); pPolyLine->setNormal(planStd.normal()); pPolyLine->setElevation(TAuxTools::GetPlaneEle(planStd)); return pPolyLine; } AcDbPolyline* THImpHvacOffset::MakeSideVertRectPolyCurves() const { AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); BOOL bSingleLine(IsSingleLine()); // if (bSingleLine) // { // double dHideEle(0.0); // 遮挡标高 // m_pXDataMap->GetAt(HVAC_Elevation, dHideEle); // ptStart.z = ptEnd.z = dHideEle; // // } AcGePoint3d ptMid = TAuxTools::Mid(ptStart, ptEnd); AcGePlane planStd = GetStdPrjPlan(ptMid); AcGePoint3dArray ptUpArr, ptDownArr; GetTwoSideKeyPoints(ptUpArr, ptDownArr, bSingleLine); if (8 != ptUpArr.length() || 8 != ptDownArr.length()) return FALSE; int nEnd1(0), nEnd2(0); GetEndPointIndex(ptUpArr, nEnd1, nEnd2); AcDbPolyline* pPolyLine = new AcDbPolyline; pPolyLine->addVertexAt(0, ptUpArr[nEnd1].convert2d(planStd)); pPolyLine->addVertexAt(1, ptDownArr[nEnd1].convert2d(planStd)); pPolyLine->addVertexAt(2, ptDownArr[nEnd2].convert2d(planStd)); pPolyLine->addVertexAt(3, ptUpArr[nEnd2].convert2d(planStd)); pPolyLine->setClosed(Adesk::kTrue); pPolyLine->setElevation(TAuxTools::GetPlaneEle(planStd)); pPolyLine->setNormal(planStd.normal()); return pPolyLine; } AcDbPolyline* THImpHvacOffset::MakeSideVertCirclePolyCurves() const { AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); // BOOL bSingleLine(IsSingleLine()); // if (bSingleLine) // { // double dHideEle(0.0); // 遮挡标高 // m_pXDataMap->GetAt(HVAC_Elevation, dHideEle); // ptStart.z = ptEnd.z = dHideEle; // } double dRadius(0.0); m_pXDataMap->GetAt(HOFF_Diameter, dRadius); dRadius *= 0.5; AcGePoint3d ptMid = TAuxTools::Mid(ptStart, ptEnd); AcGePlane planStd = GetStdPrjPlan(ptMid); ptStart = ptStart.orthoProject(planStd); ptEnd = ptEnd.orthoProject(planStd); AcGeVector3d vtNormal = normal(); AcGeVector3d vtDirect = ptEnd - ptStart; vtDirect.normalize(); // 起始半圆各点 AcGePoint3d ptStartCirSta, ptStartCirMid, ptStartCirEnd; ptStartCirSta = ptStart + dRadius * vtNormal; ptStartCirMid = ptStart - dRadius * vtDirect; ptStartCirEnd = ptStart - dRadius * vtNormal; AcGePoint3d ptEndCirSta, ptEndCirMid, ptEndCirEnd; ptEndCirSta = ptEnd + dRadius * vtNormal; ptEndCirEnd = ptEnd - dRadius * vtNormal; ptEndCirMid = ptEnd + dRadius * vtDirect; AcDbPolyline* pPolyLine = new AcDbPolyline; double dBulge(0.0); pPolyLine->addVertexAt(0, ptStartCirSta.convert2d(planStd)); dBulge = GetBulge(ptEndCirSta, ptEndCirMid, ptEndCirEnd); pPolyLine->addVertexAt(1, ptEndCirSta.convert2d(planStd), dBulge); pPolyLine->addVertexAt(2, ptEndCirEnd.convert2d(planStd)); dBulge = GetBulge(ptStartCirEnd, ptStartCirMid, ptStartCirSta); pPolyLine->addVertexAt(3, ptStartCirEnd.convert2d(planStd), dBulge); pPolyLine->setClosed(Adesk::kTrue); pPolyLine->setNormal(planStd.normal()); pPolyLine->setElevation(TAuxTools::GetPlaneEle(planStd)); return pPolyLine; } AcDbPolyline* THImpHvacOffset::MakeFaceVertPolyCurves() const { BOOL bSingleLine(IsSingleLine()); AcGePoint3dArray ptUpArr, ptDownArr; GetTwoSideKeyPoints(ptUpArr, ptDownArr, bSingleLine); if (8 != ptUpArr.length() || 8 != ptDownArr.length()) return NULL; AcGePoint3d ptStart, ptEnd, ptMid; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); // if (bSingleLine) // { // double dHideEle(0.0); // 遮挡标高 // m_pXDataMap->GetAt(HVAC_Elevation, dHideEle); // ptStart.z = ptEnd.z = dHideEle; // } ptMid = TAuxTools::Mid(ptStart, ptEnd); AcGePlane planStd = GetStdPrjPlan(ptMid); AcDbPolyline* pPolyLine = new AcDbPolyline; pPolyLine->addVertexAt(0, ptUpArr[1].convert2d(planStd)); pPolyLine->addVertexAt(1, ptUpArr[4].convert2d(planStd)); pPolyLine->addVertexAt(2, ptDownArr[4].convert2d(planStd)); pPolyLine->addVertexAt(3, ptDownArr[1].convert2d(planStd)); pPolyLine->setClosed(Adesk::kTrue); pPolyLine->setNormal(planStd.normal()); pPolyLine->setElevation(TAuxTools::GetPlaneEle(planStd)); return pPolyLine; } BOOL THImpHvacOffset::MakeHorizArcuateCurvesFaces( AcDbVoidPtrArray& arFaces ) const { AcGePoint3dArray ptLeftArr, ptRightArr; GetAllMinAnglePt(ptLeftArr, ptRightArr, IsSingleLine()); if (ptLeftArr.length() != ptRightArr.length() || 7 > ptLeftArr.length()) return FALSE; int i(0); for (i = 0; i < ptLeftArr.length()-1; i++) { AcDbFace* pFace = new AcDbFace; pFace->setVertexAt(0, ptLeftArr[i]); pFace->setVertexAt(1, ptLeftArr[i+1]); pFace->setVertexAt(2, ptRightArr[i+1]); pFace->setVertexAt(3, ptRightArr[i]); arFaces.append(pFace); } return arFaces.length() > 0; } BOOL THImpHvacOffset::MakeHorizLinearCurvesFaces( AcDbVoidPtrArray& arFaces ) const { AcGePoint3dArray ptArr; GetMidKeyPoints(ptArr, IsSingleLine()); if (8 != ptArr.length()) return FALSE; AcDbFace* pFace = new AcDbFace; pFace->setVertexAt(0, ptArr[0]); pFace->setVertexAt(1, ptArr[1]); pFace->setVertexAt(2, ptArr[2]); pFace->setVertexAt(3, ptArr[7]); arFaces.append(pFace); pFace = new AcDbFace; pFace->setVertexAt(0, ptArr[2]); pFace->setVertexAt(1, ptArr[3]); pFace->setVertexAt(2, ptArr[6]); pFace->setVertexAt(3, ptArr[7]); arFaces.append(pFace); pFace = new AcDbFace; pFace->setVertexAt(0, ptArr[3]); pFace->setVertexAt(1, ptArr[4]); pFace->setVertexAt(2, ptArr[5]); pFace->setVertexAt(3, ptArr[6]); arFaces.append(pFace); return arFaces.length() > 0; } BOOL THImpHvacOffset::MakeSideVertRectCurvesFaces( AcDbVoidPtrArray& arFaces ) const { AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); // if (bSingleLine) // { // double dHideEle(0.0); // 遮挡标高 // m_pXDataMap->GetAt(HVAC_Elevation, dHideEle); // ptStart.z = ptEnd.z = dHideEle; // } AcGePoint3d ptMid = TAuxTools::Mid(ptStart, ptEnd); AcGePlane planStd = GetStdPrjPlan(ptMid); AcGePoint3dArray ptUpArr, ptDownArr; BOOL bSingleLine(IsSingleLine()); GetTwoSideKeyPoints(ptUpArr, ptDownArr, bSingleLine); if (8 != ptUpArr.length() || 8 != ptDownArr.length()) return FALSE; int nEnd1(0), nEnd2(0); GetEndPointIndex(ptUpArr, nEnd1, nEnd2); AcDbFace* pFace = new AcDbFace; pFace->setVertexAt(0, ptUpArr[nEnd1].orthoProject(planStd)); pFace->setVertexAt(1, ptDownArr[nEnd1].orthoProject(planStd)); pFace->setVertexAt(2, ptDownArr[nEnd2].orthoProject(planStd)); pFace->setVertexAt(3, ptUpArr[nEnd2].orthoProject(planStd)); arFaces.append(pFace); return arFaces.length() > 0; } BOOL THImpHvacOffset::MakeSideVertCircleCurvesFaces( AcDbVoidPtrArray& arFaces ) const { AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); // BOOL bSingleLine(IsSingleLine()); // if (bSingleLine) // { // double dHideEle(0.0); // 遮挡标高 // m_pXDataMap->GetAt(HVAC_Elevation, dHideEle); // ptStart.z = ptEnd.z = dHideEle; // } double dRadius(0.0); m_pXDataMap->GetAt(HOFF_Diameter, dRadius); dRadius *= 0.5; AcGePoint3d ptMid = TAuxTools::Mid(ptStart, ptEnd); AcGePlane planStd = GetStdPrjPlan(ptMid); ptStart = ptStart.orthoProject(planStd); ptEnd = ptEnd.orthoProject(planStd); AcGeVector3d vtNormal = normal(); AcGeVector3d vtDirect = ptEnd - ptStart; vtDirect.normalize(); // 起始半圆各点 AcGePoint3d ptStartCirSta, ptStartCirMid, ptStartCirEnd; ptStartCirSta = ptStart + dRadius * vtNormal; ptStartCirMid = ptStart - dRadius * vtDirect; ptStartCirEnd = ptStart - dRadius * vtNormal; AcGePoint3d ptEndCirSta, ptEndCirMid, ptEndCirEnd; ptEndCirSta = ptEnd + dRadius * vtNormal; ptEndCirEnd = ptEnd - dRadius * vtNormal; ptEndCirMid = ptEnd + dRadius * vtDirect; // 中间矩形Face AcDbFace* pFace = new AcDbFace; pFace->setVertexAt(0, ptStartCirSta); pFace->setVertexAt(1, ptStartCirEnd); pFace->setVertexAt(2, ptEndCirEnd); pFace->setVertexAt(3, ptEndCirSta); arFaces.append(pFace); double dMinAngle(TAuxTools::GetMinDiffAngle()); int nPart = (int)(PI / dMinAngle) + 1; dMinAngle = PI / nPart; // 首端半圆 AcGePoint3d ptNow = ptStartCirSta; AcGeVector3d vtRotAixs = AcGeVector3d(ptStartCirMid - ptStart).crossProduct(vtNormal); int i(0); for (i = 0; i < nPart; i++) { AcDbFace* pFace = new AcDbFace; pFace->setVertexAt(0, ptStart); pFace->setVertexAt(1, ptNow); ptNow.rotateBy(-dMinAngle, vtRotAixs, ptStart); pFace->setVertexAt(2, ptNow); pFace->setVertexAt(3, ptStart); arFaces.append(pFace); } // 末端半圆 ptNow = ptEndCirSta; vtRotAixs = AcGeVector3d(ptEndCirMid - ptEnd).crossProduct(vtNormal); for (i = 0; i < nPart; i++) { AcDbFace* pFace = new AcDbFace; pFace->setVertexAt(0, ptEnd); pFace->setVertexAt(1, ptNow); ptNow.rotateBy(-dMinAngle, vtRotAixs, ptEnd); pFace->setVertexAt(2, ptNow); pFace->setVertexAt(3, ptEnd); arFaces.append(pFace); } return arFaces.length() > 0; } BOOL THImpHvacOffset::MakeFaceVertCurvesFaces( AcDbVoidPtrArray& arFaces ) const { BOOL bSingleLine(IsSingleLine()); AcGePoint3dArray ptUpArr, ptDownArr; GetTwoSideKeyPoints(ptUpArr, ptDownArr, bSingleLine); if (8 != ptUpArr.length() || 8 != ptDownArr.length()) return FALSE; AcGePoint3d ptStart, ptEnd, ptMid; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); // if (bSingleLine) // { // double dHideEle(0.0); // 遮挡标高 // m_pXDataMap->GetAt(HVAC_Elevation, dHideEle); // ptStart.z = ptEnd.z = dHideEle; // } ptMid = TAuxTools::Mid(ptStart, ptEnd); AcGePlane planStd = GetStdPrjPlan(ptMid); AcDbFace* pFace = new AcDbFace; pFace->setVertexAt(0, ptUpArr[1].orthoProject(planStd)); pFace->setVertexAt(1, ptUpArr[4].orthoProject(planStd)); pFace->setVertexAt(2, ptDownArr[4].orthoProject(planStd)); pFace->setVertexAt(3, ptDownArr[1].orthoProject(planStd)); arFaces.append(pFace); return arFaces.length() > 0; } /* 0━7 ┃ \ ┃ \ S ┃ \ ┃ \ ┃ \ 1━2 6━ 5 \ ┃ \ ┃ \ ┃ \ ┃ E \ ┃ 3━4 */ void THImpHvacOffset::GetMidKeyPoints( AcGePoint3dArray &ptArr, BOOL bSingleLine /*= FALSE*/ ) const { ASSERT(NULL != m_pXDataMap); AcGePoint3d ptS, ptE; m_pXDataMap->GetAt(HOFF_StartPoint, ptS); m_pXDataMap->GetAt(HOFF_EndPoint, ptE); AcGeVector3d vtStart(StartVect()), vtEnd(EndVect()); AcGeVector3d vtStaSide(vtStart), vtEndSide(vtEnd); AcGeVector3d vtPerl = normal(); vtStaSide.rotateBy(PI*0.5, vtPerl); vtEndSide.rotateBy(PI*0.5, vtPerl); double dStaWidth(0.0), dEndWidth(0.0), dHeigh(0.0), dPluse(0); m_pXDataMap->GetAt(HOFF_Thick, dHeigh); m_pXDataMap->GetAt(HVAC_PlusEdge, dPluse); if (bSingleLine) { GetGlobalContext()->GetAt(KEY_HIDEWIDTH, dStaWidth); // 遮挡宽度 dEndWidth = dStaWidth; // double dHideEle(0.0); // 遮挡标高 // m_pXDataMap->GetAt(HVAC_Elevation, dHideEle); // ptS.z = ptE.z = dHideEle; } else { m_pXDataMap->GetAt(HOFF_StartWidth, dStaWidth); m_pXDataMap->GetAt(HOFF_EndWidth, dEndWidth); HvacSectType eSectType = eRectangular; m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType); if (eSectType == eCircular) dEndWidth = dStaWidth; } AcGePoint3d ptTempArr[8]; ptTempArr[0] = ptS - dStaWidth * 0.5 * vtStaSide; ptTempArr[1] = ptTempArr[0] + dStaWidth * vtStaSide; ptTempArr[4] = ptE - dEndWidth * 0.5 * vtEndSide; ptTempArr[5] = ptTempArr[4] + dEndWidth * vtEndSide; ptTempArr[2] = ptTempArr[1] - dPluse * vtStart; ptTempArr[7] = ptTempArr[0] - dPluse * vtStart; ptTempArr[3] = ptTempArr[4] - dPluse * vtEnd; ptTempArr[6] = ptTempArr[5] - dPluse * vtEnd; int i(0); for (i = 0; i < 8; i++) { ptArr.append(ptTempArr[i]); } } BOOL THImpHvacOffset::GetTwoSideKeyPoints( AcGePoint3dArray &ptUpArr, AcGePoint3dArray &ptDownArr, BOOL bSingleLine /*= FALSE*/ ) const { GetMidKeyPoints(ptUpArr, bSingleLine); if (ptUpArr.length() < 1) return FALSE; AcGeVector3d vtPerl = normal(); double dThick(0.0); m_pXDataMap->GetAt(HOFF_Thick, dThick); HvacSectType eSect = eRectangular; m_pXDataMap->GetAt(HVAC_SectType, (int&)eSect); if (eSect == eCircular) m_pXDataMap->GetAt(HOFF_Diameter, dThick); AcGeVector3d vtOffSet = dThick * vtPerl * 0.5; int i(0); for (i = 0; i < ptUpArr.length(); i++) { ptDownArr.append(ptUpArr[i] - vtOffSet); ptUpArr[i] += vtOffSet; } return TRUE; } BOOL THImpHvacOffset::GetArcBaseKeyPt( AcGePoint3dArray &ptKeyArr ) const { AcGePoint3d ptStart, ptEnd, ptMid; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); ptMid = TAuxTools::Mid(ptStart, ptEnd); AcGeVector3d vtUserZAixs = normal(); AcGeVector3d vtStart(StartVect()), vtEnd(EndVect()); double dPluse(0.0); m_pXDataMap->GetAt(HVAC_PlusEdge, dPluse); AcGePoint3d ptStartArc = ptStart - dPluse * vtStart; // 起始端弧开始点 AcGePoint3d ptEndArc = ptEnd - dPluse * vtEnd; //末端弧开始点 // 起始端弧 AcGeVector3d vtStartPer(vtStart); vtStartPer.rotateBy(PI * 0.5, vtUserZAixs); AcGeLine3d lineStaPer(ptStartArc, ptStartArc + 100 * vtStartPer); AcGePoint3d ptStaMid = TAuxTools::Mid(ptStartArc, ptMid); AcGeVector3d vtMidPer = ptEndArc - ptStartArc; vtMidPer.rotateBy(PI * 0.5, vtUserZAixs); vtMidPer.normalize(); AcGeLine3d lineStartMidPer(ptStaMid, ptStaMid + 100 * vtMidPer); AcGePoint3d ptStaCenter; // 起始端弧圆心 if (lineStaPer.intersectWith(lineStartMidPer, ptStaCenter) != Adesk::kTrue) return FALSE; AcGeVector3d vtStartArc = ptStaMid - ptStaCenter; if (vtStartArc.angleTo(vtStart) < PI * 0.5) vtStartArc *= -1; vtStartArc.normalize(); double dStartRadius = ptStartArc.distanceTo(ptStaCenter); AcGePoint3d ptStarArcMid = ptStaCenter + dStartRadius * vtStartArc; // 起始端弧中点 // 末端弧 AcGeVector3d vtEndPer(vtEnd); vtEndPer.rotateBy(PI * 0.5, vtUserZAixs); AcGeLine3d lineEndPer(ptEndArc, ptEndArc + 100 * vtEndPer); AcGePoint3d ptEndMid = TAuxTools::Mid(ptEndArc, ptMid); AcGeLine3d lineEndMidPer(ptEndMid, ptEndMid + 100 * vtMidPer); AcGePoint3d ptEndCenter; // 末端弧圆心 if (lineEndPer.intersectWith(lineEndMidPer, ptEndCenter) != Adesk::kTrue) return FALSE; AcGeVector3d vtEndArc = ptEndMid - ptEndCenter; if (vtEndArc.angleTo(vtEnd) < PI * 0.5) vtEndArc *= -1; vtEndArc.normalize(); double dEndRadius = ptEndArc.distanceTo(ptEndCenter); AcGePoint3d ptEndArcMid = ptEndCenter + dEndRadius * vtEndArc; // 末端弧中点 ptKeyArr.append(ptStart); ptKeyArr.append(ptStartArc); ptKeyArr.append(ptStarArcMid); ptKeyArr.append(ptMid); ptKeyArr.append(ptEndArcMid); ptKeyArr.append(ptEndArc); ptKeyArr.append(ptEnd); return TRUE; } BOOL THImpHvacOffset::GetArcTwoSideKeyPt( AcGePoint3dArray &ptArrLeft, AcGePoint3dArray &ptArrRight, BOOL bSingleLine /*= FALSE*/ ) const { AcGePoint3dArray ptBaseArr; if (!GetArcBaseKeyPt(ptBaseArr)) return FALSE; AcGePoint3d ptStart, ptEnd, ptMid; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); ptMid = TAuxTools::Mid(ptStart, ptEnd); double dHalfStartWidth(0.0), dHalfEndWidth(0.0); if (bSingleLine) { GetGlobalContext()->GetAt(KEY_HIDEWIDTH, dHalfStartWidth); // 遮挡宽度 dHalfEndWidth = dHalfStartWidth; // double dHideEle(0.0); // 遮挡标高 // m_pXDataMap->GetAt(HVAC_Elevation, dHideEle); // ptStart.z = ptEnd.z = ptMid.z = dHideEle; // // int i(0); // for (i = 0; i < ptBaseArr.length(); i++) // { // ptBaseArr[i].z = dHideEle; // } } else { m_pXDataMap->GetAt(HOFF_StartWidth, dHalfStartWidth); m_pXDataMap->GetAt(HOFF_EndWidth, dHalfEndWidth); HvacSectType eSectType = eRectangular; m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType); if (eSectType == eCircular) m_pXDataMap->GetAt(HOFF_Diameter, dHalfEndWidth); } dHalfStartWidth *= 0.5; dHalfEndWidth *= 0.5; AcGeVector3d vtUserZAixs = normal(); AcGeVector3d vtStart(StartVect()), vtEnd(EndVect()); AcGeVector3d vtMidPer = ptEnd - ptStart; vtMidPer.rotateBy(PI * 0.5, vtUserZAixs); vtMidPer.normalize(); AcGeVector3d vtStartPer(vtStart), vtEndPer(vtEnd); vtStartPer.rotateBy(PI * 0.5, vtUserZAixs); vtEndPer.rotateBy(PI * 0.5, vtUserZAixs); // 左边(从起始端法向方向 往末端法向看) double dEverWidth = (dHalfStartWidth + dHalfEndWidth) * 0.5; AcGeCircArc3d arc(ptBaseArr[1], ptBaseArr[2], ptBaseArr[3]); AcGePoint3d ptCenter = arc.center(); AcGeVector3d vtMid = ptMid - ptCenter; vtMid.normalize(); AcGeVector3d vtStartMid = ptBaseArr[2] - ptCenter; // 起始端弧中点到圆心的向量 vtStartMid.normalize(); if (vtStartMid.angleTo(vtStartPer) > PI * 0.5) { vtStartMid *= -1; vtMid *= -1; } ptArrLeft.append(ptStart - dHalfStartWidth * vtStartPer); ptArrLeft.append(ptBaseArr[1] - dHalfStartWidth * vtStartPer); ptArrLeft.append(ptBaseArr[2] - dEverWidth * vtStartMid); ptArrLeft.append(ptMid - dHalfEndWidth * vtMid); arc.set(ptBaseArr[3], ptBaseArr[4], ptBaseArr[5]); ptCenter = arc.center(); AcGeVector3d vtEndMid = ptBaseArr[4] - ptCenter; // 末端弧中点到圆心的向量 vtEndMid.normalize(); if (vtEndMid.angleTo(vtEndPer) > PI * 0.5) { vtEndMid *= -1; } ptArrLeft.append(ptBaseArr[4] + dHalfEndWidth * vtEndMid); ptArrLeft.append(ptBaseArr[5] + dHalfEndWidth * vtEndPer); ptArrLeft.append(ptEnd + dHalfEndWidth * vtEndPer); // 右边 vtStartMid *= -1; vtMid *= -1; vtEndMid *= -1; ptArrRight.append(ptStart + dHalfStartWidth * vtStartPer); ptArrRight.append(ptBaseArr[1] + dHalfStartWidth * vtStartPer); ptArrRight.append(ptBaseArr[2] - dEverWidth * vtStartMid); ptArrRight.append(ptMid - dHalfEndWidth * vtMid); ptArrRight.append(ptBaseArr[4] + dHalfEndWidth * vtEndMid); ptArrRight.append(ptBaseArr[5] - dHalfEndWidth * vtEndPer); ptArrRight.append(ptEnd - dHalfEndWidth * vtEndPer); return TRUE; } void THImpHvacOffset::GetAllMinAnglePt( AcGePoint3dArray &ptArrLeftPart, AcGePoint3dArray &ptArrRightPart, BOOL bSingleLine /*= FALSE*/ ) const { AcGePoint3dArray ptLeftArr, ptRightArr; if (!GetArcTwoSideKeyPt(ptLeftArr, ptRightArr, bSingleLine)) return; if (7 != ptLeftArr.length() || 7 != ptRightArr.length()) return; AcGeVector3d vtNormal = normal(); double dMinAngle(TAuxTools::GetMinDiffAngle()); // 首端法兰边直部分 ptArrLeftPart.append(ptLeftArr[0]); ptArrLeftPart.append(ptLeftArr[1]); ptArrRightPart.append(ptRightArr[0]); ptArrRightPart.append(ptRightArr[1]); // 起始端左侧 AcGeCircArc3d arcStartLeft(ptLeftArr[1], ptLeftArr[2], ptLeftArr[3]); AcGePoint3d ptStaLeftCent = arcStartLeft.center(); double dStaLeftAngle = arcStartLeft.endAng() - arcStartLeft.startAng(); int nStartLeftPartNum = int(dStaLeftAngle / dMinAngle) + 1; // 起始端右侧 AcGeCircArc3d arcStartRight(ptRightArr[1], ptRightArr[2], ptRightArr[3]); AcGePoint3d ptStaRightCent = arcStartRight.center(); double dStaRightAngle = arcStartRight.endAng() - arcStartRight.startAng(); int nStartRightPartNum = int(dStaRightAngle / dMinAngle) + 1; // 按最大数目划分 int nStartMaxNum = nStartLeftPartNum > nStartRightPartNum ? nStartLeftPartNum : nStartRightPartNum; double dStartLeftMinAngle = dStaLeftAngle / nStartMaxNum; DOUBLE dStartRightMinAngle = dStaRightAngle / nStartMaxNum; AcGePoint3d ptLeftNow, ptRightNow; ptLeftNow = ptLeftArr[1]; ptRightNow = ptRightArr[1]; int i(0); for (i = 0; i < nStartMaxNum - 1; i++) { ptLeftNow.rotateBy(dStartLeftMinAngle, -vtNormal, ptStaLeftCent); ptRightNow.rotateBy(dStartRightMinAngle, -vtNormal, ptStaRightCent); ptArrLeftPart.append(ptLeftNow); ptArrRightPart.append(ptRightNow); } ptArrLeftPart.append(ptLeftArr[3]); ptArrRightPart.append(ptRightArr[3]); // 末端左侧 AcGeCircArc3d arcEndLeft(ptLeftArr[3], ptLeftArr[4], ptLeftArr[5]); AcGePoint3d ptEndLeftCent = arcEndLeft.center(); double dEndLeftAngle = arcEndLeft.endAng() - arcEndLeft.startAng(); int nEndLeftPartNum = int(dEndLeftAngle / dMinAngle) + 1; double dEndLeftMinAngle = dEndLeftAngle / nEndLeftPartNum; // 末端右侧 AcGeCircArc3d arcEndRight(ptRightArr[3], ptRightArr[4], ptRightArr[5]); AcGePoint3d ptEndRightCent = arcEndRight.center(); double dEndRightAngle = arcEndRight.endAng() - arcEndRight.startAng(); int nEndRightPartNum = int(dEndRightAngle / dMinAngle) + 1; double dEndRightMinAngle = dEndRightAngle / nEndRightPartNum; // 按最大数目划分 int nEndMaxNum = nEndLeftPartNum > nEndRightPartNum ? nEndLeftPartNum : nEndRightPartNum; dEndLeftMinAngle = dEndLeftAngle / nEndMaxNum; dEndRightMinAngle = dEndRightAngle / nEndMaxNum; ptLeftNow = ptLeftArr[3]; ptRightNow = ptRightArr[3]; for (i = 0; i < nEndMaxNum - 1; i++) { ptLeftNow.rotateBy(dEndLeftMinAngle, vtNormal, ptEndLeftCent); ptRightNow.rotateBy(dEndRightMinAngle, vtNormal, ptEndRightCent); ptArrLeftPart.append(ptLeftNow); ptArrRightPart.append(ptRightNow); } // 末端法兰部分 ptArrLeftPart.append(ptLeftArr[5]); ptArrLeftPart.append(ptLeftArr[6]); ptArrRightPart.append(ptRightArr[5]); ptArrRightPart.append(ptRightArr[6]); } BOOL THImpHvacOffset::IsCanDraw() const { if (NULL == m_pXDataMap) return FALSE; // 增加控制形态判断。2010.04.08 if (!IsHorzAlignment() && !IsSideVertAlignment() && !IsFaceVertAlignment()) return FALSE; AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); if (ptStart.distanceTo(ptEnd) < 1e-3) return FALSE; // 首尾法向量必须不同向平行 AcGeVector3d vtStart(StartVect()), vtEnd(EndVect()); if (!vtStart.isParallelTo(vtEnd) || vtStart.isCodirectionalTo(vtEnd)) return FALSE; // 首尾点方向与首尾法向量判断 AcGeVector3d vtDirect = ptEnd - ptStart; double dMaxAngle(PI * 0.5 - 0.1), dMinAngle(1e-3); if (vtDirect.angleTo(vtEnd) > dMaxAngle || vtDirect.angleTo(vtEnd) < dMinAngle) return FALSE; HvacOffsetType eType = eArcuateLink; m_pXDataMap->GetAt(HOFF_Type, (int&)eType); if (eType == eArcuateLink) { AcGePoint3dArray ptLeftArr, ptRightArr; if (!GetArcTwoSideKeyPt(ptLeftArr, ptRightArr)) return FALSE; double dSmallDist = ptLeftArr[3].distanceTo(ptStart); double dBigDist = ptLeftArr[4].distanceTo(ptStart); if (dBigDist < dSmallDist) return FALSE; // 因为起始端有可能有变径,右侧也判断一下 dSmallDist = ptRightArr[1].distanceTo(ptStart); dBigDist = ptRightArr[2].distanceTo(ptStart); if (dBigDist < dSmallDist) return FALSE; } return TRUE; } // 注意:pXMap == NULL表示不想得到返回值,只是判断数据是否合理 // 先取出m_pXDataMap中数据进行判断是否合理,返回判断结果 BOOL THImpHvacOffset::IsValid(TDbXDataMap* pXMap) { ASSERT(NULL != m_pXDataMap); AcGePoint3d ptOrigEnd, ptEnd; m_pXDataMap->GetAt(HOFF_EndPoint, ptOrigEnd); HvacOffsetComType eType = TDb::eOffComRatio; m_pXDataMap->GetAt(HOFF_ComputeType, (int&)eType); if (TDb::eOffComLength == eType) ptEnd = GetEndPtByLength(); else ptEnd = GetEndPointByAngle(); m_pXDataMap->SetAt(HOFF_EndPoint, ptEnd); if (IsCanDraw()) { if (NULL != m_pOwnerEnt) UpdateInterfaceRec(m_pOwnerEnt->objectId(), ptOrigEnd, ptEnd); if (NULL != pXMap) pXMap->SetAt(HOFF_EndPoint, ptEnd); return TRUE; } else m_pXDataMap->SetAt(HOFF_EndPoint, ptOrigEnd); return FALSE; } AcDbObjectId THImpHvacOffset::GetBaseLayerId() const { AcDbObjectId idBaseLayer(AcDbObjectId::kNull); TDbFittingBase* pFit = TDbFittingBase::cast(m_pOwnerEnt); if (NULL != pFit) idBaseLayer = pFit->CenterLayer(); return idBaseLayer; } double THImpHvacOffset::GetEdgeLineWidth() const { BOOL bShow(FALSE); GetGlobalContext( HVAC_SHOWWIDTH, bShow); // add by hh 2011-01-05 从图纸中读取加粗标识 避免全局参数对不同的图纸间的影响 TAuxTools::GetTHvacDataFromDwg(HVAC_SHOWWIDTH, bShow); if (!bShow) return 0.0; ASSERT(NULL != m_pXDataMap); double dWidth(0.0); m_pXDataMap->GetAt(HVAC_EdgeWidth, dWidth); return dWidth; } double THImpHvacOffset::GetCentLineWidth() const { BOOL bShow(FALSE); GetGlobalContext( HVAC_SHOWWIDTH, bShow); // add by hh 2011-01-05 从图纸中读取加粗标识 避免全局参数对不同的图纸间的影响 TAuxTools::GetTHvacDataFromDwg(HVAC_SHOWWIDTH, bShow); if (!bShow) return 0.0; ASSERT(NULL != m_pXDataMap); double dWidth(0.0); m_pXDataMap->GetAt(HVAC_CentWidth, dWidth); return dWidth; } double THImpHvacOffset::GetEndLineWidth() const { BOOL bShow(FALSE); GetGlobalContext( HVAC_SHOWWIDTH, bShow); // add by hh 2011-01-05 从图纸中读取加粗标识 避免全局参数对不同的图纸间的影响 TAuxTools::GetTHvacDataFromDwg(HVAC_SHOWWIDTH, bShow); if (!bShow) return 0.0; ASSERT(NULL != m_pXDataMap); double dWidth(0.0); m_pXDataMap->GetAt(HVAC_EndWidth, dWidth); return dWidth; } int THImpHvacOffset::GetXBaseShell( TXShell& xShell ) { ASSERT(NULL != m_pXDataMap); //设置精度,并恢复精度 double dOrigMinDiffAng = PI/12, dTempMinDiffAng = PI/4; GetGlobalContext()->GetAt(KEY_MINDIFFANG, dOrigMinDiffAng); GetGlobalContext()->SetAt(KEY_MINDIFFANG, dTempMinDiffAng); AcDbVoidPtrArray entSet; XExplodeStream dc(entSet); ExplodeOrDraw3d(dc); int nLen = entSet.length(); int i(0); AcDbEntity *pEnt = NULL; for(i = 0; i < nLen; i++) { pEnt = (AcDbEntity*)entSet[i]; if(NULL != pEnt && pEnt->isKindOf(AcDbFace::desc())) { xShell.AppendFace((AcDbFace*)pEnt); } } //计算开始和END端部的face GetEndSideShell(xShell); GetGlobalContext()->SetAt(KEY_MINDIFFANG, dOrigMinDiffAng); return 1; } int THImpHvacOffset::GetEndSideShell( TXShell& xShell ) { ASSERT(NULL != m_pXDataMap); AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); AcGeVector3d vtStart = StartVect(); AcGeVector3d vtEnd = EndVect(); AcGeVector3d vtNormal = normal(); HvacSectType eSect = TDb::eRectangular; m_pXDataMap->GetAt(HVAC_SectType, (int&)eSect); if (eSect == TDb::eRectangular) { double dStartWidh(0.0), dEndWidth(0.0), dThick(0.0); m_pXDataMap->GetAt(HOFF_StartWidth, dStartWidh); m_pXDataMap->GetAt(HOFF_EndWidth, dEndWidth); m_pXDataMap->GetAt(HOFF_Thick, dThick); TAuxTools::BuildRecFace(ptStart, dStartWidh, dThick, vtNormal, vtStart, xShell); TAuxTools::BuildRecFace(ptEnd, dEndWidth, dThick, vtNormal, vtEnd, xShell); } else if (eSect == TDb::eCircular) { double dDia(0.0); m_pXDataMap->GetAt(HOFF_Diameter, dDia); TAuxTools::BuildCirFace(ptStart, dDia, vtNormal, vtStart, xShell); TAuxTools::BuildCirFace(ptEnd, dDia, vtNormal, vtEnd, xShell); } return 1; } int THImpHvacOffset::GetBodyBox( AcDbExtents& ext ) { ASSERT(NULL != m_pXDataMap); //设置精度,并恢复精度 double dOrigMinDiffAng = PI/12, dTempMinDiffAng = PI/4; GetGlobalContext()->GetAt(KEY_MINDIFFANG, dOrigMinDiffAng); GetGlobalContext()->SetAt(KEY_MINDIFFANG, dTempMinDiffAng); AcGePoint3dArray ptArr; GetMidKeyPoints(ptArr); TAuxTools::BuildMinRectangle(ptArr, ext); GetGlobalContext()->SetAt(KEY_MINDIFFANG, dOrigMinDiffAng); return 1; } double THImpHvacOffset::GetAngle() { ASSERT(NULL != m_pXDataMap); // 基本参数 HvacOffsetType eType = TDb::eArcuateLink; m_pXDataMap->GetAt(HOFF_Type, (int&)eType); double dFlangPlus(0.0); m_pXDataMap->GetAt(HVAC_PlusEdge, dFlangPlus); AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); AcGeVector3d vtStart, vtEnd, vtOffSet; m_pXDataMap->GetAt(HOFF_StartDir, vtStart); m_pXDataMap->GetAt(HOFF_EndDir, vtEnd); // 先反求角度,再根据角度求末点,角度不变 AcGePoint3d ptArcStart = ptStart - vtStart * dFlangPlus; AcGePoint3d ptArcEnd = ptEnd - vtEnd * dFlangPlus; double dAngle = (ptArcEnd - ptArcStart).angleTo(vtEnd); if (dAngle > PI*0.5) dAngle = PI - dAngle; if (TDb::eArcuateLink == eType) // 双弧Angle:表示弯头角度 { dAngle = PI*0.5 - dAngle; dAngle = PI - dAngle * 2; } return dAngle; } AcGePoint3d THImpHvacOffset::GetEndPointByAngle() { ASSERT(NULL != m_pXDataMap); // 基本参数 HvacOffsetType eType = TDb::eArcuateLink; m_pXDataMap->GetAt(HOFF_Type, (int&)eType); double dAngle(0.0), dFlangPlus(0.0); m_pXDataMap->GetAt(HVAC_PlusEdge, dFlangPlus); m_pXDataMap->GetAt(HOFF_Angle, dAngle); AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); AcGeVector3d vtStart, vtOffSet; m_pXDataMap->GetAt(HOFF_StartDir, vtStart); vtOffSet = ptEnd - ptStart; vtOffSet = vtOffSet.orthoProject(vtStart); // 求末点 double dPerlDist = vtOffSet.length(); // 向下偏移的距离 double dHorizLen(0.0); // 水平偏移距离 if (TDb::eArcuateLink == eType) // 双弧Angle:表示弯头角度 dHorizLen = dPerlDist / tan(dAngle * 0.5); // 水平偏移距离 else if (TDb::eLinearLink == eType) // 角接时,dAngle:表示倾斜角度 dHorizLen = dPerlDist / tan(dAngle); AcGePoint3d ptArcSta = ptStart - dFlangPlus * vtStart; // 弧开始点 ptEnd = ptArcSta + vtOffSet - (dHorizLen + dFlangPlus) * vtStart; return ptEnd; } AcGePoint3d THImpHvacOffset::GetEndPtByLength() { ASSERT(NULL != m_pXDataMap); // 基本参数 HvacOffsetType eType = TDb::eArcuateLink; m_pXDataMap->GetAt(HOFF_Type, (int&)eType); double dLength(0.0), dOffset(0.0), dFlangPlus(0.0); m_pXDataMap->GetAt(HVAC_PlusEdge, dFlangPlus); m_pXDataMap->GetAt(HOFF_Length, dLength); m_pXDataMap->GetAt(HOFF_Offset, dOffset); double dOffsetArcLength = dLength - 2 * dFlangPlus; if (dOffsetArcLength > 0.1) { double dAngle = atan(dOffset / dOffsetArcLength); if (TDb::eArcuateLink == eType) dAngle *= 2; m_pXDataMap->SetAt(HOFF_Angle, dAngle); return GetEndPointByAngle(); } return AcGePoint3d::kOrigin; } // 导出XML // CString THImpHvacOffset::GetXml() const // { // if (NULL == m_pXDataMap || NULL == m_pOwnerEnt) // return _T(""); // // int nValue(0); // double dValue(0.0); // int nSizePreci = 3; // 尺寸精度 // int nPtPreci = 6; // 位置精度 // int nWhPreci = 0; // 宽度、高度精度 // // TXmlTree xmlTree; // CString csText; // CString csX, csY, csZ; // AcGePoint3d pt; // AcGeVector3d vt; // POSITION posRoot = xmlTree.Insert(_T("ATS_DBHFITTING"), NULL, NULL); // { // xmlTree.SetAttribute(posRoot, _T("name"), _T("乙字弯")); // xmlTree.SetAttribute(posRoot, _T("comment"), _T("上华对象名称")); // } // // POSITION posItemDrawStyle = xmlTree.Insert(_T("DrawStyle"), posRoot, NULL); // { // xmlTree.SetAttribute(posItemDrawStyle, _T("name"), _T("绘制样式")); // xmlTree.SetAttribute(posItemDrawStyle, _T("comment"), _T("绘制表现形式1:双弧,2:角接,3…")); // m_pXDataMap->GetAt(HOFF_Type, nValue); // csText.Format(_T("%d"), nValue); // xmlTree.SetItemText(posItemDrawStyle, csText); // } // // POSITION posItemSect = xmlTree.Insert(_T("SectionType"), posRoot, posItemDrawStyle); // { // xmlTree.SetAttribute(posItemSect, _T("name"), _T("截面类型")); // xmlTree.SetAttribute(posItemSect, _T("comment"), _T("截面的形状0:矩形,1:圆形")); // m_pXDataMap->GetAt(HVAC_SectType, nValue); // csText.Format(_T("%d"), nValue); // xmlTree.SetItemText(posItemSect, csText); // } // // POSITION posItemNorDir = xmlTree.Insert(_T("NormalDir"),posRoot, posItemSect); // { // xmlTree.SetAttribute(posItemNorDir, _T("name"), _T("法向量")); // vt = normal(); // TAuxTools::DoubleToString(vt.x, nPtPreci, csX); // TAuxTools::DoubleToString(vt.y, nPtPreci, csY); // TAuxTools::DoubleToString(vt.z, nPtPreci, csZ); // csText.Format(_T("%s,%s,%s"), csX, csY, csZ); // xmlTree.SetItemText(posItemNorDir, csText); // } // // POSITION posItemStartPt = xmlTree.Insert(_T("Start_point"), posRoot, posItemNorDir); // { // xmlTree.SetAttribute(posItemStartPt, _T("name"), _T("起点位置")); // m_pXDataMap->GetAt(HOFF_StartPoint, pt); // TAuxTools::DoubleToString(pt.x, nPtPreci, csX); // TAuxTools::DoubleToString(pt.y, nPtPreci, csY); // TAuxTools::DoubleToString(pt.z, nPtPreci, csZ); // csText.Format(_T("%s,%s,%s"), csX, csY, csZ); // xmlTree.SetItemText(posItemStartPt, csText); // } // // POSITION posItemStartDir = xmlTree.Insert(_T("Start_direction"), posRoot, posItemStartPt); // { // xmlTree.SetAttribute(posItemStartDir, _T("name"), _T("起点方向")); // m_pXDataMap->GetAt(HOFF_StartDir, vt); // TAuxTools::DoubleToString(vt.x, nPtPreci, csX); // TAuxTools::DoubleToString(vt.y, nPtPreci, csY); // TAuxTools::DoubleToString(vt.z, nPtPreci, csZ); // csText.Format(_T("%s,%s,%s"), csX, csY, csZ); // xmlTree.SetItemText(posItemStartDir, csText); // } // // POSITION posItemEndPt = xmlTree.Insert(_T("End_point"), posRoot, posItemStartDir); // { // xmlTree.SetAttribute(posItemEndPt, _T("name"), _T("终点位置")); // m_pXDataMap->GetAt(HOFF_EndPoint, pt); // TAuxTools::DoubleToString(pt.x, nPtPreci, csX); // TAuxTools::DoubleToString(pt.y, nPtPreci, csY); // TAuxTools::DoubleToString(pt.z, nPtPreci, csZ); // csText.Format(_T("%s,%s,%s"), csX, csY, csZ); // xmlTree.SetItemText(posItemEndPt, csText); // } // // POSITION posItemEndDir = xmlTree.Insert(_T("End_direction"), posRoot, posItemEndPt); // { // xmlTree.SetAttribute(posItemEndDir, _T("name"), _T("终点方向")); // m_pXDataMap->GetAt(HOFF_EndDir, vt); // TAuxTools::DoubleToString(vt.x, nPtPreci, csX); // TAuxTools::DoubleToString(vt.y, nPtPreci, csY); // TAuxTools::DoubleToString(vt.z, nPtPreci, csZ); // csText.Format(_T("%s,%s,%s"), csX, csY, csZ); // xmlTree.SetItemText(posItemEndDir, csText); // } // // POSITION posItemWidthStr = xmlTree.Insert(_T("Width_Start"), posRoot, posItemEndDir); // { // xmlTree.SetAttribute(posItemWidthStr, _T("name"), _T("起始端宽度")); // m_pXDataMap->GetAt(HOFF_StartWidth, dValue); // TAuxTools::DoubleToString(dValue, nWhPreci, csText); // xmlTree.SetItemText(posItemWidthStr, csText); // } // // POSITION posItemWidthEnd = xmlTree.Insert(_T("Width_End"), posRoot, posItemWidthStr); // { // xmlTree.SetAttribute(posItemWidthEnd, _T("name"), _T("终止端宽度")); // m_pXDataMap->GetAt(HOFF_EndWidth, dValue); // TAuxTools::DoubleToString(dValue, nWhPreci, csText); // xmlTree.SetItemText(posItemWidthEnd, csText); // } // // POSITION posItemHghStr = xmlTree.Insert(_T("Height_Start"), posRoot, posItemWidthEnd); // { // xmlTree.SetAttribute(posItemHghStr, _T("name"), _T("起始端高度")); // m_pXDataMap->GetAt(HOFF_Thick, dValue); // TAuxTools::DoubleToString(dValue, nWhPreci, csText); // xmlTree.SetItemText(posItemHghStr, csText); // } // // POSITION posItemHghEnd = xmlTree.Insert(_T("Height_End"), posRoot, posItemHghStr); // { // xmlTree.SetAttribute(posItemHghEnd, _T("name"), _T("终止端高度")); // m_pXDataMap->GetAt(HOFF_Thick, dValue); // ??? // TAuxTools::DoubleToString(dValue, nWhPreci, csText); // xmlTree.SetItemText(posItemHghEnd, csText); // } // // POSITION posPlusEdge = xmlTree.Insert(_T("PlusEdge"), posRoot, posItemHghEnd); // { // xmlTree.SetAttribute(posPlusEdge, _T("name"),_T("咬口法兰翻边余量")); // m_pXDataMap->GetAt(HVAC_PlusEdge, dValue); // TAuxTools::DoubleToString(dValue, 1, csText); // xmlTree.SetItemText(posPlusEdge, csText); // } // // POSITION posObjId = xmlTree.Insert(_T("Object_ID"), posRoot, posPlusEdge); // { // xmlTree.SetAttribute(posObjId, _T("name"),_T("ID")); // xmlTree.SetAttribute(posObjId, _T("comment"),_T("乙字弯ID")); // // csText.Format(_T("%ld"), 0x7FFFFFFF & m_pOwnerEnt->objectId().asOldId()); // xmlTree.SetItemText(posObjId, csText); // } // // CString csXml = xmlTree.GetXml(); // // return csXml; // } CString THImpHvacOffset::GetXml(const AcGeMatrix3d& mat) const { if (NULL == m_pXDataMap || NULL == m_pOwnerEnt) return _T(""); int nValue(0); double dValue(0.0); int nSizePreci = 3; // 尺寸精度 int nPtPreci = 6; // 位置精度 int nWhPreci = 0; // 宽度、高度精度 TXmlTree xmlTree; CString csText; CString csX, csY, csZ; AcGePoint3d pt; AcGeVector3d vt; POSITION posRoot = xmlTree.Insert(_T("ATS_DBHFITTING"), NULL, NULL); { xmlTree.SetAttribute(posRoot, _T("name"), _T("乙字弯")); xmlTree.SetAttribute(posRoot, _T("comment"), _T("上华对象名称")); } POSITION posItemDrawStyle = xmlTree.Insert(_T("DrawStyle"), posRoot, NULL); { xmlTree.SetAttribute(posItemDrawStyle, _T("name"), _T("绘制样式")); xmlTree.SetAttribute(posItemDrawStyle, _T("comment"), _T("绘制表现形式1:双弧,2:角接,3…")); m_pXDataMap->GetAt(HOFF_Type, nValue); csText.Format(_T("%d"), nValue); xmlTree.SetItemText(posItemDrawStyle, csText); } POSITION posItemSect = xmlTree.Insert(_T("SectionType"), posRoot, posItemDrawStyle); { xmlTree.SetAttribute(posItemSect, _T("name"), _T("截面类型")); xmlTree.SetAttribute(posItemSect, _T("comment"), _T("截面的形状0:矩形,1:圆形")); m_pXDataMap->GetAt(HVAC_SectType, nValue); csText.Format(_T("%d"), nValue); xmlTree.SetItemText(posItemSect, csText); } POSITION posItemNorDir = xmlTree.Insert(_T("NormalDir"),posRoot, posItemSect); { xmlTree.SetAttribute(posItemNorDir, _T("name"), _T("法向量")); vt = normal(); TAuxTools::DoubleToString(vt.x, nPtPreci, csX); TAuxTools::DoubleToString(vt.y, nPtPreci, csY); TAuxTools::DoubleToString(vt.z, nPtPreci, csZ); csText.Format(_T("%s,%s,%s"), csX, csY, csZ); xmlTree.SetItemText(posItemNorDir, csText); } POSITION posItemStartPt = xmlTree.Insert(_T("Start_point"), posRoot, posItemNorDir); { xmlTree.SetAttribute(posItemStartPt, _T("name"), _T("起点位置")); m_pXDataMap->GetAt(HOFF_StartPoint, pt); pt.transformBy(mat); TAuxTools::DoubleToString(pt.x, nPtPreci, csX); TAuxTools::DoubleToString(pt.y, nPtPreci, csY); TAuxTools::DoubleToString(pt.z, nPtPreci, csZ); csText.Format(_T("%s,%s,%s"), csX, csY, csZ); xmlTree.SetItemText(posItemStartPt, csText); } POSITION posItemStartDir = xmlTree.Insert(_T("Start_direction"), posRoot, posItemStartPt); { xmlTree.SetAttribute(posItemStartDir, _T("name"), _T("起点方向")); m_pXDataMap->GetAt(HOFF_StartDir, vt); TAuxTools::DoubleToString(vt.x, nPtPreci, csX); TAuxTools::DoubleToString(vt.y, nPtPreci, csY); TAuxTools::DoubleToString(vt.z, nPtPreci, csZ); csText.Format(_T("%s,%s,%s"), csX, csY, csZ); xmlTree.SetItemText(posItemStartDir, csText); } POSITION posItemEndPt = xmlTree.Insert(_T("End_point"), posRoot, posItemStartDir); { xmlTree.SetAttribute(posItemEndPt, _T("name"), _T("终点位置")); m_pXDataMap->GetAt(HOFF_EndPoint, pt); pt.transformBy(mat); TAuxTools::DoubleToString(pt.x, nPtPreci, csX); TAuxTools::DoubleToString(pt.y, nPtPreci, csY); TAuxTools::DoubleToString(pt.z, nPtPreci, csZ); csText.Format(_T("%s,%s,%s"), csX, csY, csZ); xmlTree.SetItemText(posItemEndPt, csText); } POSITION posItemEndDir = xmlTree.Insert(_T("End_direction"), posRoot, posItemEndPt); { xmlTree.SetAttribute(posItemEndDir, _T("name"), _T("终点方向")); m_pXDataMap->GetAt(HOFF_EndDir, vt); TAuxTools::DoubleToString(vt.x, nPtPreci, csX); TAuxTools::DoubleToString(vt.y, nPtPreci, csY); TAuxTools::DoubleToString(vt.z, nPtPreci, csZ); csText.Format(_T("%s,%s,%s"), csX, csY, csZ); xmlTree.SetItemText(posItemEndDir, csText); } POSITION posItemWidthStr = xmlTree.Insert(_T("Width_Start"), posRoot, posItemEndDir); { xmlTree.SetAttribute(posItemWidthStr, _T("name"), _T("起始端宽度")); m_pXDataMap->GetAt(HOFF_StartWidth, dValue); TAuxTools::DoubleToString(dValue, nWhPreci, csText); xmlTree.SetItemText(posItemWidthStr, csText); } POSITION posItemWidthEnd = xmlTree.Insert(_T("Width_End"), posRoot, posItemWidthStr); { xmlTree.SetAttribute(posItemWidthEnd, _T("name"), _T("终止端宽度")); m_pXDataMap->GetAt(HOFF_EndWidth, dValue); TAuxTools::DoubleToString(dValue, nWhPreci, csText); xmlTree.SetItemText(posItemWidthEnd, csText); } POSITION posItemHghStr = xmlTree.Insert(_T("Height_Start"), posRoot, posItemWidthEnd); { xmlTree.SetAttribute(posItemHghStr, _T("name"), _T("起始端高度")); m_pXDataMap->GetAt(HOFF_Thick, dValue); TAuxTools::DoubleToString(dValue, nWhPreci, csText); xmlTree.SetItemText(posItemHghStr, csText); } POSITION posItemHghEnd = xmlTree.Insert(_T("Height_End"), posRoot, posItemHghStr); { xmlTree.SetAttribute(posItemHghEnd, _T("name"), _T("终止端高度")); m_pXDataMap->GetAt(HOFF_Thick, dValue); // ??? TAuxTools::DoubleToString(dValue, nWhPreci, csText); xmlTree.SetItemText(posItemHghEnd, csText); } POSITION posPlusEdge = xmlTree.Insert(_T("PlusEdge"), posRoot, posItemHghEnd); { xmlTree.SetAttribute(posPlusEdge, _T("name"),_T("咬口法兰翻边余量")); m_pXDataMap->GetAt(HVAC_PlusEdge, dValue); TAuxTools::DoubleToString(dValue, 1, csText); xmlTree.SetItemText(posPlusEdge, csText); } POSITION posObjId = xmlTree.Insert(_T("Object_ID"), posRoot, posPlusEdge); { xmlTree.SetAttribute(posObjId, _T("name"),_T("ID")); xmlTree.SetAttribute(posObjId, _T("comment"),_T("乙字弯ID")); csText.Format(_T("%ld"), 0x7FFFFFFF & m_pOwnerEnt->objectId().asOldId()); xmlTree.SetItemText(posObjId, csText); } // begin // add by wc 13-12-13 POSITION posSysName = xmlTree.Insert(_T("System"), posRoot, posObjId); { xmlTree.SetAttribute(posSysName, _T("name"), _T("管线类型")); xmlTree.SetAttribute(posSysName, _T("comment"), _T("回风/送风/通风...")); m_pXDataMap->GetAt(HVAC_System, csText); xmlTree.SetItemText(posSysName, csText); } POSITION posSingleLine = xmlTree.Insert(_T("IsSingleLine"), posRoot, posSysName); { xmlTree.SetAttribute(posSingleLine, _T("name"), _T("单线")); xmlTree.SetAttribute(posSingleLine, _T("comment"), _T("是否是单线: 1/是, 0/不是")); csText.Format(_T("%d"), (int)IsSingleLine()); xmlTree.SetItemText(posSingleLine, csText); } POSITION posHasLiningLine = xmlTree.Insert(_T("HasLiningLine"), posRoot, posSingleLine); { xmlTree.SetAttribute(posHasLiningLine, _T("name"), _T("内衬线")); xmlTree.SetAttribute(posHasLiningLine, _T("comment"), _T("是否有内衬线:0/不是, 1/是")); if (!m_pXDataMap->GetAt(HVAC_HasLining, nValue)) nValue = 0; csText.Format(_T("%d"), nValue); xmlTree.SetItemText(posHasLiningLine, csText); } POSITION posLiningLineType = xmlTree.Insert(_T("LiningLineType"), posRoot, posHasLiningLine); { AcDbObjectId idType; AcDbObject *pObjType = NULL; ACHAR *pChar = NULL; xmlTree.SetAttribute(posLiningLineType, _T("name"), _T("内衬线型")); xmlTree.SetAttribute(posLiningLineType, _T("comment"), _T("内衬线型的名称")); m_pXDataMap->GetAt(HVAC_LiningLine, idType); if (Acad::eOk != acdbOpenObject(pObjType, idType, AcDb::kForRead)) { } if (NULL != pObjType) { AcDbLinetypeTableRecord *pRec = AcDbLinetypeTableRecord::cast(pObjType); pRec->getName(pChar); pRec->close(); pObjType->close(); csText.Format(_T("%s"), pChar); delete pChar; } else csText.Empty(); xmlTree.SetItemText(posLiningLineType, csText); } POSITION posIsEdgeWidth = xmlTree.Insert(_T("IsEdgeWidth"), posRoot, posLiningLineType); { xmlTree.SetAttribute(posIsEdgeWidth, _T("name"), _T("边线是否加粗")); xmlTree.SetAttribute(posIsEdgeWidth, _T("comment"), _T("0/不加粗, 1/加粗")); if (!m_pXDataMap->GetAt(HVAC_EdgeWeight, nValue)) nValue = 0; csText.Format(_T("%d"), nValue); xmlTree.SetItemText(posIsEdgeWidth, csText); } POSITION posIsCentWidth = xmlTree.Insert(_T("IsCentWidth"), posRoot, posIsEdgeWidth); { xmlTree.SetAttribute(posIsCentWidth, _T("name"), _T("中线是否加粗")); xmlTree.SetAttribute(posIsCentWidth, _T("comment"), _T("0/不加粗, 1/加粗")); if (!m_pXDataMap->GetAt(HVAC_CentWeight, nValue)) nValue = 0; csText.Format(_T("%d"), nValue); xmlTree.SetItemText(posIsCentWidth, csText); } POSITION posIsEndWidth = xmlTree.Insert(_T("IsEndWidth"), posRoot, posIsCentWidth); { xmlTree.SetAttribute(posIsEndWidth, _T("name"), _T("端线是否加粗")); xmlTree.SetAttribute(posIsEndWidth, _T("comment"), _T("0/不加粗, 1/加粗")); if (!m_pXDataMap->GetAt(HVAC_EndWeight, nValue)) nValue = 0; csText.Format(_T("%d"), nValue); xmlTree.SetItemText(posIsEndWidth, csText); } POSITION posEdgeWidth = xmlTree.Insert(_T("EdgeWidth"), posRoot, posIsEndWidth); { xmlTree.SetAttribute(posEdgeWidth, _T("name"), _T("边线加粗量")); xmlTree.SetAttribute(posEdgeWidth, _T("comment"), _T("边线加粗的数值")); m_pXDataMap->GetAt(HVAC_EdgeWidth, dValue); csText.Format(_T("%f"), dValue); xmlTree.SetItemText(posEdgeWidth, csText); } POSITION posCentWidth = xmlTree.Insert(_T("CentWidth"), posRoot, posEdgeWidth); { xmlTree.SetAttribute(posCentWidth, _T("name"), _T("中线加粗量")); xmlTree.SetAttribute(posCentWidth, _T("comment"), _T("中线加粗的数值")); m_pXDataMap->GetAt(HVAC_CentWidth, dValue); csText.Format(_T("%f"), dValue); xmlTree.SetItemText(posCentWidth, csText); } POSITION posEndWidth = xmlTree.Insert(_T("EndWidth"), posRoot, posCentWidth); { xmlTree.SetAttribute(posEndWidth, _T("name"), _T("端线加粗量")); xmlTree.SetAttribute(posEndWidth, _T("comment"), _T("端线加粗的数值")); m_pXDataMap->GetAt(HVAC_EndWidth, dValue); csText.Format(_T("%f"), dValue); xmlTree.SetItemText(posEndWidth, csText); } // end CString csXml = xmlTree.GetXml(); return csXml; } bool THImpHvacOffset::GetSection(const AcDbFace &face, const AcGeVector3d &vtPlaneSecDir, std::vector §ionRecord, AcDbVoidPtrArray& arFillPtrs) const { if (NULL == m_pOwnerEnt || NULL == m_pXDataMap) return false; // 基本参数 AcDbObjectId idObj = m_pOwnerEnt->objectId(); AcDbObjectId idLayer = m_pOwnerEnt->layerId(); TGGeSectionPlane section_pln(face, vtPlaneSecDir); // 构造一个辅助剖面 int i = 0; double dElevation = 0; for(i = 0; i < 4; i++) { TGGePoly2D plOutline; if(Make3DOutline(plOutline, i + 1)) { TGGePoly2D poly; dElevation = SectionUtility::Projection_poly2plane(section_pln, plOutline, poly); if(!!poly) // add by hh 2011-03-11 增加投影后的Poly2D有效型判断 sectionRecord.push_back(TObjSectionRecord(idObj, idLayer, TObjSectionRecord::eTCH_DBHFITTING, dElevation, poly)); } } return true; } Acad::ErrorStatus THImpHvacOffset::GetExtents(TADSGePoint3d &ptLow, TADSGePoint3d &ptUp) const { if (NULL == m_pXDataMap) return Acad::eNotImplementedYet; AcGePoint3d ptStart, ptEnd; double dThick = 0; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); HvacSectType eSect = TDb::eRectangular; m_pXDataMap->GetAt(HVAC_SectType, (int&)eSect); if(eRectangular == eSect) m_pXDataMap->GetAt(HOFF_Thick, dThick); else m_pXDataMap->GetAt(HOFF_Diameter, dThick); dThick *= 0.5; AcGeVector3d vtNor = normal(); if(IsHorzAlignment()) { if (ptStart.z < ptEnd.z) { ptLow = ptStart - vtNor * dThick; ptUp = ptEnd + vtNor * dThick; } else { ptLow = ptEnd - vtNor * dThick; ptUp = ptStart + vtNor * dThick; } } else { vtNor = TAuxTools::GetUcsZvt(); if (ptStart.z < ptEnd.z) { ptLow = ptStart - vtNor * dThick; ptUp = ptEnd + vtNor * dThick; } else { ptLow = ptEnd - vtNor * dThick; ptUp = ptStart + vtNor * dThick; } } return Acad::eOk; } // 生成3D轮廓PL线 iFlag: 1 顶面 2 底面 3 前面 4 背面 BOOL THImpHvacOffset::Make3DOutline(TGGePoly2D& poly, int iFlag) const { if(NULL == m_pXDataMap) return FALSE; HvacSectType eSect = TDb::eRectangular; m_pXDataMap->GetAt(HVAC_SectType, (int&)eSect); // 圆形乙字弯暂按方形处理 //if(TDb::eRectangular == eSect) //{ return MakeRect3DOutline(poly, iFlag); //} //else //{ // return MakeCirc3DOutline(poly, iFlag); //} return TRUE; } BOOL THImpHvacOffset::MakeRect3DOutline(TGGePoly2D& poly, int iFlag) const { HvacOffsetType eOffType = eArcuateLink; m_pXDataMap->GetAt(HOFF_Type, (int&)eOffType); int i = 0; switch(eOffType){ case eArcuateLink: case eObliqueLink: { // 获取中截面所有的点 AcGePoint3dArray arPtLeft, arPtRight; GetAllMinAnglePt(arPtRight, arPtLeft, FALSE); int nPtCount = arPtLeft.length(); if(nPtCount != arPtRight.length()) return FALSE; // 取得偏移长度及方向 HvacSectType eSect = TDb::eRectangular; m_pXDataMap->GetAt(HVAC_SectType, (int&)eSect); double dHalfThick = 0; if(eRectangular == eSect) m_pXDataMap->GetAt(HOFF_Thick, dHalfThick); else m_pXDataMap->GetAt(HOFF_Diameter, dHalfThick); dHalfThick *= 0.5; AcGeVector3d vtNor = normal(); if(1 == iFlag || 2 == iFlag){ // 顶&底 if(2 == iFlag) vtNor *= -1; for(i = 0; i < nPtCount; i++) { poly.AppendNode(arPtLeft[i] + vtNor * dHalfThick); } for(i = nPtCount - 1; i >= 0; i--) { poly.AppendNode(arPtRight[i] + vtNor * dHalfThick); } }else if(3 == iFlag){ // 前面 for(i = 0; i < nPtCount; i++) { poly.AppendNode(arPtLeft[i] + vtNor * dHalfThick); } for(i = nPtCount - 1; i >= 0; i--) { poly.AppendNode(arPtLeft[i] - vtNor * dHalfThick); } }else if(4 == iFlag){ // 背面 for(i = 0; i < nPtCount; i++) { poly.AppendNode(arPtRight[i] + vtNor * dHalfThick); } for(i = nPtCount - 1; i >= 0; i--) { poly.AppendNode(arPtRight[i] - vtNor * dHalfThick); } }else{ return FALSE; } poly.SetClosed(); } break; case eLinearLink: { AcGePoint3dArray arPtUp, arPtDown; // 获取上下两面的关键点 if(!GetTwoSideKeyPoints(arPtUp, arPtDown)) return FALSE; if(8 != arPtUp.length() || 8 != arPtDown.length()) return FALSE; if(1 == iFlag || 2 == iFlag){ // 顶&底 AcGePoint3dArray* pArr = &arPtUp; if(2 == iFlag) pArr = &arPtDown; for(i = 0; i < 8; i++) { poly.AppendNode(pArr->at(i)); } }else if(3 == iFlag){ // 前面 poly.AppendNode(arPtUp[1]); poly.AppendNode(arPtUp[2]); poly.AppendNode(arPtUp[3]); poly.AppendNode(arPtUp[4]); poly.AppendNode(arPtDown[4]); poly.AppendNode(arPtDown[3]); poly.AppendNode(arPtDown[2]); poly.AppendNode(arPtDown[1]); }else if(4 == iFlag){ // 背面 poly.AppendNode(arPtUp[0]); poly.AppendNode(arPtUp[7]); poly.AppendNode(arPtUp[6]); poly.AppendNode(arPtUp[5]); poly.AppendNode(arPtDown[5]); poly.AppendNode(arPtDown[6]); poly.AppendNode(arPtDown[7]); poly.AppendNode(arPtDown[0]); }else{ return FALSE; } poly.SetClosed(); } break; default: return FALSE; } return TRUE; } BOOL THImpHvacOffset::MakeCirc3DOutline(TGGePoly2D& poly, int iFlag) const { return FALSE; } // add by hh 2014-08-06 支持管件与水管遮挡 Acad::ErrorStatus THImpHvacOffset::GetClipBoundary(TGGePoly2D& poly)const { AcDbPolyline* pLine = MakePolyCurve(); if(NULL == pLine) return Acad::eNotImplementedYet; double dBrWidth = 0; if(!TAuxTools::GetTHvacDataFromDwg(HVAC_PIPEHIDEWIDTH, dBrWidth)) GetGlobalContext()->GetAt(HVAC_PIPEHIDEWIDTH, dBrWidth); if(EQUAL_ZERO(dBrWidth)) { PolyConvert(*pLine, poly); } else { AcDbVoidPtrArray arPLines; pLine->getOffsetCurves(dBrWidth, arPLines); if(0 == arPLines.length()) { PolyConvert(*pLine, poly); } else { PolyConvert(*((AcDbPolyline*)arPLines[0]), poly); for(int i = 0; i < arPLines.length(); i++) { if(NULL != arPLines[i]) delete (AcDbEntity*)arPLines[i]; } } } delete pLine; return Acad::eOk; } bool THImpHvacOffset::IsMeClip() const { return true; } bool THImpHvacOffset::IsClipMe(const TEntityBase* pEnt)const//ok是否被裁剪 { if(NULL == pEnt) return false; //add by dyw 20150409 当图纸复杂时,遮挡的更改影响水管的绘制速度,暂时屏蔽掉 return false; //add end CString sClassName = pEnt->GetMe()->isA()->name(); if(0 == sClassName.Compare(_T("TDbPipe"))) // 水管 { TInterfaceModifyMsg iMsg; iMsg.SetInterfaceOper(TDb::eUpdateCover); iMsg.SetMsgOperateOn(m_pOwnerEnt->objectId()); // 写入接口更改消息 TDbInterfaceMsgWrite msgWrite; msgWrite.WriteInterfaceMsg(iMsg); return true; } return false; }