Files
envi-code/SourceCode/Code2026/tg_shs/shs_pipebase/THImpHvacDuct.cpp
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

7923 lines
208 KiB
C++
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "stdafx.h"
#include "THImpHvacDuct.h"
#include "TDbInterfaceMsgWrite.h"
#include "TDbPipeBase.h"
#include "math.h"
#include "dbelipse.h"
#include "TDbHvacEquipment.h"
using namespace TDb;
extern AcGePlane GetStdPrjPlan( const AcGePoint3d &ptOnPlan );
THImpHvacDuct::THImpHvacDuct()
{
// 初始化
m_pOwnerEnt = NULL;
}
THImpHvacDuct::THImpHvacDuct(TDbPipeBase* pOwner)
{
// 初始化
m_pOwnerEnt = pOwner;
m_pXDataMap = pOwner->GetSpecialtyData();
}
THImpHvacDuct::~THImpHvacDuct()
{
}
Acad::ErrorStatus THImpHvacDuct::getClassID(CLSID* pClsid) const
{
// #if (ADS < 16)
// // {C7DFDF6A-A5F2-4add-ADCC-7AC0675AB6E2}
// CLSID CLSID_PipeBaseEntity = {0xC7DFDF6B, 0xA5F2, 0x4ADE, { 0xAD, 0xCC, 0x7A, 0xC0, 0x67, 0x5A, 0xB6, 0xE2 }};
// #endif
//
// #if (ADS == 16)
// // {C7DFDF6A-A5F2-4add-ADCC-7AC0675AB6E3}
// CLSID CLSID_PipeBaseEntity = {0xC7DFDF6B, 0xA5F2, 0x4ADE, { 0xAD, 0xCC, 0x7A, 0xC0, 0x67, 0x5A, 0xB6, 0xE3 }};
// #endif
//
// #if (ADS == 17)
// // {C7DFDF6A-A5F2-4add-ADCC-7AC0675AB6E4}
// CLSID CLSID_PipeBaseEntity = {0xC7DFDF6B, 0xA5F2, 0x4ADE, { 0xAD, 0xCC, 0x7A, 0xC0, 0x67, 0x5A, 0xB6, 0xE4 }};
// #endif
//
// #if (ADS == 18)
// // {C7DFDF6A-A5F2-4add-ADCC-7AC0675AB6E5}
// CLSID CLSID_PipeBaseEntity = {0xC7DFDF6B, 0xA5F2, 0x4ADE, { 0xAD, 0xCC, 0x7A, 0xC0, 0x67, 0x5A, 0xB6, 0xE5 }};
// #endif
//
// #if (ADS == 19)
// // {C7DFDF6A-A5F2-4add-ADCC-7AC0675AB6E5}
// CLSID CLSID_PipeBaseEntity = {0xC7DFDF6B, 0xA5F2, 0x4ADE, { 0xAD, 0xCC, 0x7A, 0xC0, 0x67, 0x5A, 0xB6, 0xE5 }};
// #endif
return Acad::eOk;
}
BOOL THImpHvacDuct::OPMInfo(LPCTSTR pszName, TDb::OPMInfo* pInfo)
{
ASSERT(NULL != pszName && NULL != pInfo && NULL != m_pXDataMap);
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);
}
return TRUE;
}
if (0 == _tcsicmp(pszName, HVAC_DrawType))
{
pInfo->bVisible = TRUE;
pInfo->bEditable = TRUE;
// 提供数据列表和对应关系
if (NULL != pInfo->parsValues && NULL != pInfo->parlValues)
{
pInfo->parsValues->Add(_T("旧标准"));
pInfo->parlValues->Add(TDb::eOldStyle);
pInfo->parsValues->Add(_T("新标准进风"));
pInfo->parlValues->Add(TDb::eNewImmit);
pInfo->parsValues->Add(_T("新标准排风"));
pInfo->parlValues->Add(TDb::eNewEject);
}
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_HasLining))
{
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, HVAC_Elevation))
// {
// // 获得单线类型,当类型为单线时显示并可改
// pInfo->bEditable = bSingleLine;
// pInfo->bVisible = bSingleLine;
//
// return TRUE;
// }
if (0 == _tcsicmp(pszName, HDCT_Type))
{
pInfo->bVisible = TRUE;
pInfo->bEditable = FALSE;
// 提供数据列表和对应关系
if (NULL != pInfo->parsValues && NULL != pInfo->parlValues)
{
pInfo->parsValues->Add(_T("直管"));
pInfo->parlValues->Add(TDb::eStraight);
pInfo->parsValues->Add(_T("软管"));
pInfo->parlValues->Add(TDb::eSoft);
}
return TRUE;
}
if (0 == _tcsicmp(pszName, HDCT_Width))
{
// 获得风管截面,当截面不为圆型时显示并可改
HvacSectType eSectType = eRectangular;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType);
pInfo->bVisible = (TDb::eCircular != eSectType);
pInfo->bEditable = (TDb::eCircular != eSectType);
// 设置数据
if (NULL != pInfo->pXData && 0 != pInfo->pXData->nVt)
{
// 传递尺寸消息及更新遮挡
TDbHvacDuct* pDuct = TDbHvacDuct::cast(m_pOwnerEnt);
if (NULL != pDuct)
{
TAuxTools::SetAndUpdateCover(pDuct, pszName, pInfo);
if (TAuxTools::IsAutoWorkSize())
{
double dOrigHeigh(0.0);
m_pXDataMap->GetAt(HDCT_Thick, dOrigHeigh);
pDuct->WriteSizeChangeMsg(pInfo->pXData->dVal[0], dOrigHeigh);
}
//BEGIN====================================================
pDuct->UpdateDimData();
//修改时间:2010-04-15
//修改人 :王亚东
//修改原因:风管数据修改后更新标注内容
//END======================================================
// 点不变,也要更新下,否则下次接口记录找不到正确值,导致尺寸不联动
AcGePoint3d ptStart, ptEnd;
m_pXDataMap->GetAt(HDCT_START, ptStart);
m_pXDataMap->GetAt(HDCT_END , ptEnd);
pDuct->UpdateInterfaceRec(ptStart, ptStart);
pDuct->UpdateInterfaceRec(ptEnd, ptEnd);
pDuct->close();
acedPostCommand(_T("redraw\n"));
acedPostCommand(_T("redraw\n"));
}
}
return TRUE;
}
if (0 == _tcsicmp(pszName, HDCT_Thick))
{
// 获得风管截面,当截面不为圆型时显示并可改
HvacSectType eSectType = eRectangular;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType);
pInfo->bVisible = (TDb::eCircular != eSectType);
pInfo->bEditable = (TDb::eCircular != eSectType);
// 更新尺寸
if (NULL != pInfo->pXData && 0 != pInfo->pXData->nVt)
{
// 传递尺寸消息及更新遮挡
TDbHvacDuct* pDuct = TDbHvacDuct::cast(m_pOwnerEnt);
if (NULL != pDuct)
{
m_pXDataMap->SetAt(pszName, *pInfo->pXData);
pInfo->pXData->nVt = 0; // 设置处理完成标识
if (TAuxTools::IsAutoWorkSize())
{
double dOrigWidth(0.0);
m_pXDataMap->GetAt(HDCT_Width, dOrigWidth);
pDuct->WriteSizeChangeMsg(dOrigWidth, pInfo->pXData->dVal[0]);
}
//BEGIN====================================================
pDuct->UpdateDimData();
//修改时间:2010-04-15
//修改人 :王亚东
//修改原因:风管数据修改后更新标注内容
//END======================================================
AcGePoint3d ptStart, ptEnd;
m_pXDataMap->GetAt(HDCT_START, ptStart);
m_pXDataMap->GetAt(HDCT_END , ptEnd);
pDuct->UpdateInterfaceRec(ptStart, ptStart);
pDuct->UpdateInterfaceRec(ptEnd, ptEnd);
pDuct->close();
acedPostCommand(_T("redraw\n"));
acedPostCommand(_T("redraw\n"));
}
}
return TRUE;
}
// HDCT_Diameter和HDCT_Width定义相同,为同一个值
// 为区分显示名称,借用未被使用的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 = (TDb::eCircular == eSectType);
// 替代属性,需要特殊处理数据获取和设置
if (NULL != pInfo->pXData)
{
// 获取数据
if (0 == pInfo->pXData->nVt)
{
m_pXDataMap->GetAt(HDCT_Diameter, *pInfo->pXData);
}
// 设置数据
else
{
TAuxTools::SetAndUpdateCover((TDbInterfacesObj*)m_pOwnerEnt, HDCT_Diameter, pInfo);
// m_pXDataMap->SetAt(HDCT_Diameter, *pInfo->pXData);
// pInfo->pXData->nVt = 0; // 设置处理完成标识
TDbHvacDuct* pDuct = TDbHvacDuct::cast(m_pOwnerEnt);
if (NULL != pDuct)
{
if (TAuxTools::IsAutoWorkSize())
pDuct->WriteSizeChangeMsg(pInfo->pXData->dVal[0], pInfo->pXData->dVal[0]);
//BEGIN====================================================
pDuct->UpdateDimData();
//修改时间:2010-04-15
//修改人 :王亚东
//修改原因:风管数据修改后更新标注内容
//END======================================================
// 点不变,也要更新下,否则下次接口记录找不到正确值,导致尺寸不联动
AcGePoint3d ptStart, ptEnd;
m_pXDataMap->GetAt(HDCT_START, ptStart);
m_pXDataMap->GetAt(HDCT_END , ptEnd);
pDuct->UpdateInterfaceRec(ptStart, ptStart);
pDuct->UpdateInterfaceRec(ptEnd, ptEnd);
pDuct->close();
acedPostCommand(_T("redraw\n"));
acedPostCommand(_T("redraw\n"));
}
}
}
return TRUE;
}
if (0 == _tcsicmp(pszName, KEY_START))
{
pInfo->bVisible = TRUE;
pInfo->bEditable = TRUE;
// 位置变化,需要在设置之前更新接口位置和方向
if (NULL != pInfo->pXData && TXPT3D == pInfo->pXData->nVt)
{
// 获得原来的起点和终点
AcGePoint3d ptStart = StartPoint();
AcGePoint3d ptEnd = EndPoint();
// 获得新的起点和方向
AcGePoint3d ptNewStart = asPnt3d(pInfo->pXData->dVal);
// 贴壁联动,MoveNextToAirLet()要在风管首位点变化之前进行
BOOL bAutoOffset(FALSE);
AcGeVector3d vtOff;
GetGlobalContext(HVAC_AUTOOFFSET, bAutoOffset);
if (bAutoOffset)
{
vtOff = ptNewStart - ptStart;
if (vtOff.length() > 1e-6)
((TDbHvacDuct*)m_pOwnerEnt)->MoveNextToAirLet(vtOff);
}
m_pXDataMap->SetAt(KEY_START, ptNewStart);
// 设置normal
ResetNormalByPt();
AcGeVector3d vtStart, vtEnd;
GetDirect(vtStart, vtEnd);
// 更新接口方向和位置
((TDbInterfacesObj*)m_pOwnerEnt)->UpdateInterfaceRec(ptStart, vtStart);
((TDbInterfacesObj*)m_pOwnerEnt)->UpdateInterfaceRec(ptEnd, vtEnd);
((TDbInterfacesObj*)m_pOwnerEnt)->UpdateInterfaceRec(ptStart, ptNewStart);
TAuxTools::SetAndUpdateCover((TDbInterfacesObj*)m_pOwnerEnt, pszName, pInfo);
// 接口联动
if (bAutoOffset && vtOff.length() > 1e-6)
{
((TDbHvacDuct*)m_pOwnerEnt)->WriteMoveTransMsg(vtOff);
m_pOwnerEnt->close();
acedPostCommand(_T("redraw\n"));
}
}
return TRUE;
}
if (0 == _tcsicmp(pszName, KEY_END))
{
pInfo->bVisible = TRUE;
pInfo->bEditable = TRUE;
// 位置变化,需要在设置之前更新接口位置和方向
if (NULL != pInfo->pXData && TXPT3D == pInfo->pXData->nVt)
{
// 获得原来的起点和终点
AcGePoint3d ptStart = StartPoint();
AcGePoint3d ptEnd = EndPoint();
// 获得新的终点和方向
AcGePoint3d ptNewEnd = asPnt3d(pInfo->pXData->dVal);
// 贴壁联动,MoveNextToAirLet()要在风管首位点变化之前进行
BOOL bAutoOffset(FALSE);
AcGeVector3d vtOff;
GetGlobalContext(HVAC_AUTOOFFSET, bAutoOffset);
if (bAutoOffset)
{
vtOff = ptNewEnd - ptEnd;
if (vtOff.length() > 1e-6)
((TDbHvacDuct*)m_pOwnerEnt)->MoveNextToAirLet(vtOff);
}
m_pXDataMap->SetAt(KEY_END, ptNewEnd);
// 设置normal
ResetNormalByPt();
AcGeVector3d vtStart, vtEnd;
GetDirect(vtStart, vtEnd);
// 更新接口方向和位置
((TDbInterfacesObj*)m_pOwnerEnt)->UpdateInterfaceRec(ptStart, vtStart);
((TDbInterfacesObj*)m_pOwnerEnt)->UpdateInterfaceRec(ptEnd, vtEnd);
((TDbInterfacesObj*)m_pOwnerEnt)->UpdateInterfaceRec(ptEnd, ptNewEnd);
TAuxTools::SetAndUpdateCover((TDbInterfacesObj*)m_pOwnerEnt, pszName, pInfo);
// 接口连接联动
if (bAutoOffset)
{
if (vtOff.length() > 1e-6)
{
((TDbHvacDuct*)m_pOwnerEnt)->WriteMoveTransMsg(vtOff);
m_pOwnerEnt->close();
acedPostCommand(_T("redraw\n"));
}
}
}
return TRUE;
}
return FALSE;
}
void THImpHvacDuct::GetTips(CMapStringToString& mapLable2Tip) const
{
}
void THImpHvacDuct::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(HDCT_Diameter, dDiameter);
acutPrintf(_T("\n\t\t\t\t\t\t\t\t\t直径:%.2f"), dDiameter);
}
// 非圆型截面显示宽度和厚度
else
{
double dWidth = 0.0, dThick = 0.0;
m_pXDataMap->GetAt(HDCT_Width, dWidth);
m_pXDataMap->GetAt(HDCT_Thick, dThick);
acutPrintf(_T("\n\t\t\t\t\t\t\t\t\t宽度:%.2f\t 厚度:%.2f"), dWidth, dThick);
}
// 起点
AcGePoint3d pt;
pt = StartPoint();
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);
// 终点
pt = EndPoint();
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);
}
AcGePoint3d THImpHvacDuct::GetDirect(AcGeVector3d& vtStart, AcGeVector3d& vtEnd) const
{
ASSERT(NULL != m_pXDataMap);
// 风管类型
HvacDuctType eDuctType = eStraight;
m_pXDataMap->GetAt(HDCT_Type, (int&)eDuctType);
// 获得软风管曲率
double dBulge = 0.0;
if (eStraight != eDuctType)
m_pXDataMap->GetAt(HDCT_Bulge, dBulge);
// 获得风管参数
AcGePoint3d ptStart = StartPoint();
AcGePoint3d ptEnd = EndPoint();
// 计算软风管中点
AcGePoint3d ptMid;
Midpoint(ptStart, ptEnd, ptMid);
// 直管
if (fabs(dBulge) < 0.0000001)
{
vtStart = ptStart - ptEnd;
vtEnd = -vtStart;
return ptMid;
}
// 调整中点
AcGeVector3d vtNormal = normal();
AcGeVector3d vtDirect = (ptStart - ptEnd).normal();
vtDirect.rotateBy(PI / 2.0, vtNormal);
ptMid += vtDirect * dBulge * ptStart.distanceTo(ptEnd) / 2.0;
// 计算始末点方向
AcGeCircArc3d arc(ptStart, ptMid, ptEnd);
AcGePoint3d ptCenter = arc.center();
vtStart = ptStart - ptCenter;
vtEnd = ptEnd - ptCenter;
if (dBulge > 0.0)
{
vtStart.rotateBy(-PI / 2.0, vtNormal);
vtEnd.rotateBy(PI / 2.0, vtNormal);
}
else
{
vtStart.rotateBy(PI / 2.0, vtNormal);
vtEnd.rotateBy(-PI / 2.0, vtNormal);
}
// 对于弧管,如果人为设置了端点方向,使用设置的方向Lixl add 2012-3-1
if (eSoft == eDuctType)
{
m_pXDataMap->GetAt(HDCT_StartDir, vtStart);
m_pXDataMap->GetAt(HDCT_EndDir, vtEnd);
}
vtStart.normalize();
vtEnd.normalize();
return ptMid;
}
// 设置接口截面类型SectType,宽度Width,厚度Thick到pipeInterface
BOOL THImpHvacDuct::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) ? HDCT_Diameter : HDCT_Width);
pszThickKey = HDCT_Thick;
break;
case 1:
pszWidthKey = ((TDb::eCircular == eSectType) ? HDCT_Diameter : HDCT_Width);
pszThickKey = HDCT_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;
}
// 根据接口索引(0-起点,1-终点),获得风管接口信息
// 当前无接口,将信息填充到接口结构,确保返回的接口对象有效
BOOL THImpHvacDuct::GetInterface(int nIndex, TInterface& pipeInterface) const
{
ASSERT(NULL != m_pXDataMap);
// 获得风管参数
AcGePoint3d ptStart = StartPoint();
AcGePoint3d ptEnd = EndPoint();
// 获得始末方向向量
AcGeVector3d vtStart, vtEnd;
GetDirect(vtStart, vtEnd);
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.SetOwnerId(m_pOwnerEnt->objectId());
pipeInterface.SetPosition(ptStart);
pipeInterface.SetOutDir(vtStart);
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.SetOwnerId(m_pOwnerEnt->objectId());
pipeInterface.SetPosition(ptEnd);
pipeInterface.SetOutDir(vtEnd);
GetInterfaceSizeData(nIndex, pipeInterface);
return TRUE;
}
return FALSE;
}
BOOL THImpHvacDuct::GetInterface(const AcGePoint3d& ptConnect, TInterface& pipeInterface) const
{
ASSERT(NULL != m_pXDataMap);
// 获得风管参数
AcGePoint3d ptStart = StartPoint();
AcGePoint3d ptEnd = EndPoint();
// 获得始末方向向量
AcGeVector3d vtStart, vtEnd;
GetDirect(vtStart, vtEnd);
// 计算测试点到始末点的距离
double dDist1 = ptConnect.distanceTo(ptStart);
double dDist2 = ptConnect.distanceTo(ptEnd);
AcDbObjectId id;
// 位于起始点
if (dDist1 < 1.e-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;
}
// 位于末尾点
if (dDist2 < 1.e-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 THImpHvacDuct::HasInterface(const AcGePoint3d& ptConnect, const AcGeVector3d& vtDir)
{
ASSERT(NULL != m_pXDataMap);
// 获得风管参数
AcGePoint3d ptStart = StartPoint();
AcGePoint3d ptEnd = EndPoint();
// 获得始末方向向量
AcGeVector3d vtStart, vtEnd;
GetDirect(vtStart, vtEnd);
// 计算测试点到始末点的距离
double dDist1 = ptConnect.distanceTo(ptStart);
double dDist2 = ptConnect.distanceTo(ptEnd);
// 位于起始点
if (dDist1 < 1.e-3)
return (vtDir.isParallelTo(vtStart));
// 位于末尾点
if (dDist2 < 1.e-3)
return (vtDir.isParallelTo(vtEnd));
return FALSE;
}
BOOL THImpHvacDuct::NotifyInterfaceToModify(const TInterfaceModifyMsg& iModiMsg,
TInterfaceModifyMsgs& iModiMsgs)
{
if (NULL == m_pXDataMap)
return FALSE;
BOOL bMsgTranslate = FALSE;
// 获得消息类型, 根据消息类型处理
InterfaceOper eOper = iModiMsg.GetInterfaceOper();
switch (eOper)
{
case eMoveGripPoint:
// 夹点移动消息处理
bMsgTranslate = OnMoveGripPointMsgNotify(iModiMsg, iModiMsgs);
break;
case eTransformBy:
// 对象移动消息处理
bMsgTranslate = OnTransformMsgNotify(iModiMsg, iModiMsgs);
break;
case eSize:
// 尺寸调整消息处理
bMsgTranslate = OnSizeMsgNotify(iModiMsg, iModiMsgs);
break;
default:
return bMsgTranslate;
}
// 记录修改标识
if (m_pOwnerEnt != NULL)
m_pOwnerEnt->recordGraphicsModified();
return bMsgTranslate;
}
Acad::ErrorStatus THImpHvacDuct::ExplodeOrDraw3d(XExplodeDraw &mode) const
{
if (NULL == m_pXDataMap)
return Acad::eNotImplementedYet;
if (GetModeType() == eSystem)
return Acad::eNotImplementedYet;
// 风管类型
HvacDuctType eDuctType = eStraight;
m_pXDataMap->GetAt(HDCT_Type, (int&)eDuctType);
switch (eDuctType)
{
case eStraight: // 直风管
return ExplodeOrDrawStraight3d(mode);
case eSoft: // 软风管
return ExplodeOrDrawSoft3d(mode);
default:
break;
}
return Acad::eNotImplementedYet;
}
Acad::ErrorStatus THImpHvacDuct::ExplodeOrDraw2d( XExplodeDraw &mode ) const
{
if (m_pOwnerEnt != NULL)
{
//边界实体
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 THImpHvacDuct::MakeCurves(TComplexCurve& cplCurve) const
{
if (NULL == m_pXDataMap)
return FALSE;
// 如果管子水平放置
if (IsHorzAlignment())
return MakeHorz2DCurves(cplCurve, 0);
// 如果管子垂直放置
if (IsVertAlignment())
return MakeVert2DCurves(cplCurve, 0);
// 如果管子倾斜放置
return MakeIncl2DCurves(cplCurve, 0);
}
BOOL THImpHvacDuct::GetCurvesInSide(TComplexCurve& compCurve) const
{
if (NULL == m_pXDataMap)
return FALSE;
// 如果管子水平放置
if (IsHorzAlignment())
return MakeHorz2DCurves(compCurve, 1);
// 如果管子垂直放置
if (IsVertAlignment())
return MakeVert2DCurves(compCurve, 1);
// 如果管子倾斜放置
return MakeIncl2DCurves(compCurve, 1);
}
AcDbPolyline* THImpHvacDuct::MakePolyCurve() const
{
if (NULL == m_pXDataMap)
return NULL;
// 如果管子水平放置
if (IsHorzAlignment())
return MakeHorzPolyCurve();
// 如果管子垂直放置
if (IsVertAlignment())
return MakeVertPolyCurve();
// 如果管子倾斜放置
return MakeInclPolyCurve();
}
BOOL THImpHvacDuct::MakePolyCurveFaces(AcDbVoidPtrArray& arFaces)
{
if (NULL == m_pXDataMap)
return NULL;
// 如果管子水平放置
if (IsHorzAlignment())
return MakeHorzPolyCurveFaces(arFaces);
// 如果管子垂直放置
if (IsVertAlignment())
return MakeVertPolyCurveFaces(arFaces);
// 如果管子倾斜放置
return MakeInclPolyCurveFaces(arFaces);
}
BOOL THImpHvacDuct::IsHorzAlignment() const
{
// // 获得法向量
// AcGeVector3d vtNormal(normal());
//
// // 获得UCS坐标Z向量
// AcDbDatabase* pDb = acdbCurDwg();
// AcGeVector3d vtZAxis(pDb->ucsxdir().crossProduct(pDb->ucsydir()));
//
// return vtNormal.isParallelTo(vtZAxis);
// 获得UCS坐标Z向量
AcGeVector3d vtZAxis(TAuxTools::GetUcsZvt());
// 获得方向
AcGeVector3d vtDirect = EndPoint() - StartPoint();
return vtDirect.isPerpendicularTo(vtZAxis);
}
BOOL THImpHvacDuct::IsVertAlignment() const
{
// // 获得法向量
// AcGeVector3d vtNormal(normal());
//
// // 获得UCS坐标Z向量
// AcDbDatabase* pDb = acdbCurDwg();
// AcGeVector3d vtZAxis(pDb->ucsxdir().crossProduct(pDb->ucsydir()));
//
// return vtNormal.isPerpendicularTo(vtZAxis);
// 获得UCS坐标Z向量
AcGeVector3d vtZAxis(TAuxTools::GetUcsZvt());
// 获得方向
AcGeVector3d vtDirect = EndPoint() - StartPoint();
return vtDirect.isParallelTo(vtZAxis);
}
BOOL THImpHvacDuct::IsSingleLine() const
{
ASSERT(NULL != m_pXDataMap);
BOOL bSingleLine = FALSE;
m_pXDataMap->GetAt(HVAC_IsSingleLine, (int&)bSingleLine);
return bSingleLine;
}
HvacModelType THImpHvacDuct::GetModeType() const
{
ASSERT(NULL != m_pXDataMap);
HvacModelType eType = eModel;
m_pXDataMap->GetAt(HVAC_ModeType, (int&)eType);
return eType;
}
BOOL THImpHvacDuct::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;
AcGePoint3d ptGeCon = iModiMsg.GetMsgPoint();
AcGePoint3d ptGeSta = StartPoint();
AcGePoint3d ptGeEnd = EndPoint();
AcGePoint3d ptGeOldSta = ptGeSta;
AcGePoint3d ptGeOldEnd = ptGeEnd;
AcGeVector3d vtLine = ptGeEnd - ptGeSta;
AcGeVector3d vtOffset = iModiMsg.GetMoveGripOffset();
AcGeTol tol;
tol.setEqualVector(1e-1);
if (vtLine.isParallelTo(vtOffset, tol)) //平行
{
if (ptGeOldSta.distanceTo(ptGeCon) < 1.e-3 )//关联有效
{
ptGeSta += vtOffset;
SetStartPoint(ptGeSta);
//更新自身模型空间的扩展字典的接口信息
AcGeMatrix3d xform;
xform.setToTranslation(vtOffset);
UpdateInterfaceRec(m_pOwnerEnt->objectId(),xform,&ptGeOldSta);
//不在往下传递
}
if (ptGeOldEnd.distanceTo(ptGeCon) < 1.e-3)//关联有效
{
ptGeEnd += vtOffset;
SetEndPoint(ptGeEnd);
//更新自身模型空间的扩展字典的接口信息
AcGeMatrix3d xform;
xform.setToTranslation(vtOffset);
UpdateInterfaceRec(m_pOwnerEnt->objectId(),xform,&ptGeOldEnd);
//不在往下传递
}
}
else if (vtLine.isPerpendicularTo(vtOffset, tol)) // 垂直
{
// 处理风管壁连接的风口联动情况 暂
((TDbHvacDuct*)m_pOwnerEnt)->MoveNextToAirLet(vtOffset);
//接口更改
ptGeSta += vtOffset;
ptGeEnd += vtOffset;
//更新自身模型空间的扩展字典的接口信息
SetStartPoint(ptGeSta);
SetEndPoint(ptGeEnd);
AcGeMatrix3d xform;
xform.setToTranslation(vtOffset);
AcDbObjectId id1,id2;
m_pXDataMap->GetAt(KEY_IDCNT1,id1);
m_pXDataMap->GetAt(KEY_IDCNT2,id2);
// 构造新的接口传递消息,接口对象的均为Fitting基类派生
AcDbObjectId idT;
// 弧管纠正为弧管断点切线方向
AcGeVector3d vtSoftEnd;
if (IsArcDuct())
GetDirect(vtLine, vtSoftEnd);
//sta 端
if (FindConnect(ptGeOldSta,vtLine,m_pOwnerEnt->objectId(),idT)) // sta 点的接口
{
TInterfaceModifyMsg msg;
msg.SetMsgPoint(ptGeOldSta);
msg.SetTransform(xform);
msg.SetMoveGripOffset(iModiMsg.GetMoveGripOffset());
msg.SetGripPosition(TDb::eStart);
msg.SetMsgOperateOn(idT);
iModiMsgs.append(msg);
bMsgTranslate = TRUE;
}
if (IsArcDuct())
vtLine = vtSoftEnd;
//end 端
if (FindConnect(ptGeOldEnd,vtLine, m_pOwnerEnt->objectId(), idT)) // end 点的接口
{
TInterfaceModifyMsg msg;
msg.SetMsgPoint(ptGeOldEnd);
msg.SetTransform(xform);
msg.SetMoveGripOffset(iModiMsg.GetMoveGripOffset());
msg.SetGripPosition(TDb::eEnd);
msg.SetMsgOperateOn(idT);
iModiMsgs.append(msg);
bMsgTranslate = TRUE;
}
UpdateInterfaceRec(m_pOwnerEnt->objectId(),xform);
UpdateDimInReactor(TDb::eMid, vtOffset);
}
else // 倾斜情况,根据已有向量,求三角形斜边向量,并按此向量延伸
{
AcDbEntity* pEnt = NULL;
int nRet = acdbOpenAcDbEntity(pEnt, id, AcDb::kForRead);
if (NULL != pEnt && pEnt->isKindOf(TDbHvacEquipment::desc()))
{
pEnt->close();
return bMsgTranslate;
}
//求斜边的向量
double dAngle = vtOffset.angleTo(vtLine);
double dLen = fabs(cos(dAngle));
dLen = vtOffset.length() / dLen;
vtLine.normalize();
AcGeVector3d vtOffsetExtend = vtOffset.orthoProject(vtLine.perpVector());
vtOffsetExtend.normalize();
vtOffsetExtend *= dLen;
AcGeVector3d vtOffsetReBack;
AcDbObjectId idT;
if (ptGeOldSta.distanceTo(ptGeCon) < 1.e-3 ) // 关联有效
{
ptGeSta += vtOffsetExtend;
SetStartPoint(ptGeSta);
//更新自身模型空间的扩展字典的接口信息
AcGeMatrix3d xform;
xform.setToTranslation(vtOffsetExtend);
UpdateInterfaceRec(m_pOwnerEnt->objectId(),xform, &ptGeOldSta);
//sta 端
if (FindConnect(ptGeSta,vtLine,m_pOwnerEnt->objectId(),idT)) // sta 点的接口
{
vtOffsetReBack = vtOffsetExtend - vtOffset;
//设置消息回溯标记,表示处理过的对象二次再接收消息处理
iModiMsgs.SetFlowBackFlag(TRUE);
TInterfaceModifyMsg msg;
ptGeSta = ptGeOldSta + vtOffset;
msg.SetMsgPoint(ptGeSta);
msg.SetGripPosition(TDb::eStart);
msg.SetMoveGripOffset(vtOffsetReBack);
msg.SetMsgOperateOn(idT);
iModiMsgs.append(msg);
bMsgTranslate = TRUE;
}
}
if (ptGeOldEnd.distanceTo(ptGeCon) < 1.e-3)//关联有效
{
ptGeEnd += vtOffsetExtend;
SetEndPoint(ptGeEnd);
//更新自身模型空间的扩展字典的接口信息
AcGeMatrix3d xform;
xform.setToTranslation(vtOffsetExtend);
UpdateInterfaceRec(m_pOwnerEnt->objectId(),xform, &ptGeOldEnd);
//end 端
if (FindConnect(ptGeEnd, vtLine, m_pOwnerEnt->objectId(), idT)) // end 点的接口
{
vtOffsetReBack = vtOffsetExtend - vtOffset;
//设置消息回溯标记,表示处理过的对象二次再接收消息处理
iModiMsgs.SetFlowBackFlag(TRUE);
TInterfaceModifyMsg msg;
ptGeEnd = ptGeOldEnd + vtOffset;
msg.SetMsgPoint(ptGeEnd);
msg.SetGripPosition(TDb::eEnd);
msg.SetMoveGripOffset(vtOffsetReBack);
msg.SetMsgOperateOn(idT);
iModiMsgs.append(msg);
bMsgTranslate = TRUE;
}
}
}
// add by hh 2011-07-11 更新尺寸标注
if(NULL != m_pOwnerEnt)
((TDbHvacDuct*)m_pOwnerEnt)->UpdateDimData();
return bMsgTranslate;
}
BOOL THImpHvacDuct::OnTransformMsgNotify(const TInterfaceModifyMsg& iModiMsg,
TInterfaceModifyMsgs& iModiMsgs)
{
if (!TAuxTools::IsAutoWorkOffset())
return FALSE;
if (m_pXDataMap == NULL)
return FALSE;
AcDbObjectId id = iModiMsg.GetMsgOperateOn();
AcGePoint3d ptGeSta = StartPoint();
AcGePoint3d ptGeEnd = EndPoint();
AcGePoint3d ptGeOldSta = ptGeSta;
AcGePoint3d ptGeOldEnd = ptGeEnd;
AcGeVector3d vtLine = ptGeEnd - ptGeSta;
//接口位置更改
AcGeMatrix3d matTrans = iModiMsg.GetTransform();
ptGeSta.transformBy(matTrans);
ptGeEnd.transformBy(matTrans);
AcGePoint3d ptGeMsgOn = iModiMsg.GetMsgPoint();
AcGeVector3d vtLineE = ptGeEnd - ptGeOldEnd;
AcGeVector3d vtLineS = ptGeSta - ptGeOldSta;
// 平行 拉伸S端,不再传递新消息
if (vtLineS.isParallelTo(vtLine) && ptGeMsgOn.distanceTo(ptGeOldSta) < 1.e-3)
{
SetStartPoint(ptGeSta);
//更新自身命名字典的接口信息
UpdateInterfaceRec(m_pOwnerEnt->objectId(),ptGeOldSta,ptGeSta);
return TRUE;
}
// 平行 拉伸E端,不再传递新消息
if (vtLineE.isParallelTo(vtLine) && ptGeMsgOn.distanceTo(ptGeOldEnd) < 1.e-3)
{
SetEndPoint(ptGeEnd);
//更新自身命名字典的接口信息
UpdateInterfaceRec(m_pOwnerEnt->objectId(),ptGeOldEnd,ptGeEnd);
return TRUE;
}
BOOL bMsgTranslate = FALSE;
if (vtLineS.isPerpendicularTo(vtLine))
{
SetStartPoint(ptGeSta);
SetEndPoint(ptGeEnd);
AcDbObjectId id1,id2;
m_pXDataMap->GetAt(KEY_IDCNT1,id1);
m_pXDataMap->GetAt(KEY_IDCNT2,id2);
AcDbObjectId idT;
// 构造接口消息传递 开始端检查
if (FindConnect(ptGeOldSta, vtLine, m_pOwnerEnt->objectId(), idT)) // sta 点的接口
{
TInterfaceModifyMsg msg;
msg.SetMsgPoint(ptGeOldSta);
msg.SetTransform(matTrans);
msg.SetMsgOperateOn(idT);
iModiMsgs.append(msg);
bMsgTranslate = TRUE;
}
// 构造接口消息传递 末端检查
if (FindConnect(ptGeOldEnd, -vtLine, m_pOwnerEnt->objectId(), idT)) // sta 点的接口
{
TInterfaceModifyMsg msg;
msg.SetMsgPoint(ptGeOldEnd);
msg.SetTransform(matTrans);
msg.SetMsgOperateOn(idT);
iModiMsgs.append(msg);
bMsgTranslate = TRUE;
}
//更新自身的接口信息
UpdateInterfaceRec(m_pOwnerEnt->objectId(),iModiMsg.GetTransform());
AcGeVector3d vtOff = matTrans.translation();
if (vtOff.isPerpendicularTo(vtLine))
UpdateDimInReactor(TDb::eMid, vtOff);
}
return bMsgTranslate;
}
BOOL THImpHvacDuct::OnSizeMsgNotify(const TInterfaceModifyMsg& iModiMsg,
TInterfaceModifyMsgs& iModiMsgs)
{
ASSERT(NULL != m_pXDataMap);
// add by hh 2011-01-21 判断消息点是否存在接口信息,
// 用于处理风管打断时写入的错误接口数据问题(暂定方案)
TInterface ifTemp;
if(!GetInterface(iModiMsg.GetMsgPoint(), ifTemp))
return FALSE;
// add end
AcGePoint3d ptOrigStart = StartPoint();
AcGePoint3d ptOrigEnd = EndPoint();
double dNewWidth(0.0), dNewHeigh(0.0);
iModiMsg.GetSize(dNewWidth, dNewHeigh);
AcGeVector3d vtOff = iModiMsg.GetMoveGripOffset();
AcGePoint3d ptNewStart = ptOrigStart + vtOff;
AcGePoint3d ptNewEnd = ptOrigEnd + vtOff;
m_pXDataMap->SetAt(HDCT_Width, dNewWidth);
m_pXDataMap->SetAt(HDCT_Thick, dNewHeigh);
m_pXDataMap->SetAt(HDCT_START, ptNewStart);
m_pXDataMap->SetAt(HDCT_END, ptNewEnd);
// add by hh 2011-04-21 更新尺寸标注
((TDbHvacDuct*)m_pOwnerEnt)->UpdateDimData();
// 消息传递
AcGeVector3d vtLine = ptOrigEnd - ptOrigStart;
AcDbObjectId idFind;
if (FindConnect(ptOrigStart, vtLine, m_pOwnerEnt->objectId(), idFind)) // sta 点的接口
{
TInterfaceModifyMsg iMsg = iModiMsg;
iMsg.SetMsgOperateOn(idFind);
iMsg.SetMsgPoint(ptOrigStart);
iModiMsgs.append(iMsg);
}
if (FindConnect(ptOrigEnd, vtLine, m_pOwnerEnt->objectId(), idFind)) // End 点的接口
{
TInterfaceModifyMsg iMsg = iModiMsg;
iMsg.SetMsgOperateOn(idFind);
iMsg.SetMsgPoint(ptOrigEnd);
iModiMsgs.append(iMsg);
}
((TDbInterfacesObj*)m_pOwnerEnt)->UpdateInterfaceRec(ptOrigStart, ptNewStart);
((TDbInterfacesObj*)m_pOwnerEnt)->UpdateInterfaceRec(ptOrigEnd, ptNewEnd);
return TRUE;
}
Acad::ErrorStatus THImpHvacDuct::ExplodeOrDrawStraight3d( XExplodeDraw &mode ) const
{
ASSERT(NULL != m_pXDataMap);
// 截面类型
HvacSectType eSectType = eRectangular;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType);
switch (eSectType)
{
case eRectangular:
return ExplodeOrDrawRectStraight3d(mode);
case eCircular:
return ExplodeOrDrawCircStraight3d(mode);
case eOblate:
return ExplodeOrDrawOblateStraight3d(mode);
default:
break;
}
return Acad::eNotImplementedYet;
}
// 具体绘制三维矩形直风管
/*
↑默认法向
起始端 6━━━━━4 侧壁面 1━━3━━━5━━7━━9
┃ ┃ ┃ ┃ ┃ ┃
┃
┃ 起始端 ┃ ┃ ┃ ┃ ┃
┃
8 ┃ ┃ ┃ ┃ ┃
0━━━━━2 0━━2━━━4━━6━━8
*/
Acad::ErrorStatus THImpHvacDuct::ExplodeOrDrawRectStraight3d( XExplodeDraw &mode ) const
{
ASSERT(NULL != m_pXDataMap);
AcGePoint3d ptS = StartPoint();
AcGePoint3d ptE = EndPoint();
double dWidth(0.0), dThick(0.0);
m_pXDataMap->GetAt(HDCT_Width, dWidth);
m_pXDataMap->GetAt(HDCT_Thick, dThick);
AcGeVector3d vtNormal = normal();
AcGeVector3d vtDirect = ptE - ptS;
AcGeVector3d vtLevel = vtDirect;
vtLevel.normalize();
vtLevel.rotateBy(PI * 0.5, vtNormal);
// 四面管壁,5×2顶点
AcGePoint3d ptArrSide[5*2];
ptArrSide[0] = ptS - dThick * 0.5 * vtNormal + dWidth * 0.5 * vtLevel;
ptArrSide[2] = ptArrSide[0] - dWidth * vtLevel;
ptArrSide[4] = ptArrSide[2] + dThick * vtNormal;
ptArrSide[6] = ptArrSide[0] + dThick * vtNormal;
ptArrSide[8] = ptArrSide[0];
ptArrSide[1] = ptArrSide[0] + vtDirect;
ptArrSide[3] = ptArrSide[2] + vtDirect;
ptArrSide[5] = ptArrSide[4] + vtDirect;
ptArrSide[7] = ptArrSide[6] + vtDirect;
ptArrSide[9] = ptArrSide[1];
mode.DrawMesh(5, 2, ptArrSide);
return Acad::eOk;
}
// 具体绘制三维圆形直风管
// 侧壁分解为矩形网格,采用mesh()顶点, 主视图及顶点顺序类似于矩形风管
// 两端采用polygon()绘制多边形
/*
↑默认法向
┏━8━┓
起始端 10 6 侧壁面 1━━3━━━5━━7━━9...
┃ ┃ ┃ ┃ ┃ ┃
12 起始端 4 ┃ ┃ ┃ ┃
┃ ┃ ┃ ┃ ┃ ┃ ┃
14 2 0━━2━━━4━━6━━8...
┗━0━┛
*/
Acad::ErrorStatus THImpHvacDuct::ExplodeOrDrawCircStraight3d( XExplodeDraw &mode ) const
{
ASSERT(NULL != m_pXDataMap);
AcGePoint3d ptS = StartPoint();
AcGePoint3d ptE = EndPoint();
AcGeVector3d vtNormal = normal();
AcGeVector3d vtDirect = ptE - ptS;
vtDirect.normalize();
double dMinAngle(TAuxTools::GetMinDiffAngle());
int nPartNum = int(PI * 2 / dMinAngle);
dMinAngle = PI * 2 / nPartNum;
double dDiaMet(0.0);
m_pXDataMap->GetAt(HDCT_Diameter, dDiaMet);
AcGePoint3dArray ptArr;
// 修改为,三维最外轮廓跟返回Polylinje一致
// AcGeVector3d vtNow = vtNormal * -1; // 每组顶点法向
AcGeVector3d vtNow = vtNormal.crossProduct(vtDirect); // 每组顶点法向
int i(0);
for (i = 0; i < nPartNum * 2; i += 2)
{
ptArr.append(ptS + dDiaMet * 0.5 * vtNow);
ptArr.append(ptE + dDiaMet * 0.5 * vtNow);
vtNow.rotateBy(dMinAngle, vtDirect);
}
// 单独设置末点,防止误差
ptArr.append(ptArr.at(0));
ptArr.append(ptArr.at(1));
mode.DrawMesh(nPartNum + 1, 2, ptArr.asArrayPtr());
return Acad::eOk;
}
Acad::ErrorStatus THImpHvacDuct::ExplodeOrDrawOblateStraight3d( XExplodeDraw &mode ) const
{
ASSERT(NULL != m_pXDataMap);
return Acad::eOk;
}
Acad::ErrorStatus THImpHvacDuct::ExplodeOrDrawSoft3d( XExplodeDraw &mode ) const
{
ASSERT(NULL != m_pXDataMap);
// mcl add, 排除弧度极限值
double dBulge(0), dPosiBulge(0);
m_pXDataMap->GetAt(HDCT_Bulge, dBulge);
dPosiBulge = fabs((dBulge));
if (dPosiBulge < 1e-6)
return ExplodeOrDrawStraight3d(mode);
// 截面类型
HvacSectType eSectType = eRectangular;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType);
if (!IsCanDrawSoft())
return Acad::eNotImplementedYet;
switch (eSectType)
{
case eRectangular:
return ExplodeOrDrawRectSoft3d(mode);
case eCircular:
ExplodeOrDrawCircSoft3d(mode);
case eOblate:
return ExplodeOrDrawOblateSoft3d(mode);
default:
break;
}
return Acad::eNotImplementedYet;
}
// 矩形软风管绘制,网格序列方式如下:
/*
↑默认法向
起始端 2━━━━━1 剖开后网格 0━━1━━━2━━3━━4
┃ ┃ ┃ ┃ ┃ ┃ ┃
┃ ┃ 5━━6━━━7━━8━━9
┃ 起始端 ┃ ┃ ┃ ┃ ┃ ┃
┃ ┃
┃ ┃ ┃ ┃ ┃ ┃ ┃
3━━━━━40
*/
Acad::ErrorStatus THImpHvacDuct::ExplodeOrDrawRectSoft3d( XExplodeDraw &mode ) const
{
ASSERT(NULL != m_pXDataMap);
AcGePoint3d ptS = StartPoint();
AcGePoint3d ptE = EndPoint();
AcGeVector3d vtNormal = normal();
AcGeVector3d vtDirect = ptE - ptS;
vtDirect.normalize();
double dWidth(0.0), dThick(0.0);
m_pXDataMap->GetAt(HDCT_Width, dWidth);
m_pXDataMap->GetAt(HDCT_Thick, dThick);
double dBulge(0), dPosiBulge(0);
m_pXDataMap->GetAt(HDCT_Bulge, dBulge);
dPosiBulge = fabs(dBulge);
double dSignAngle = atan(dBulge) * 4;
double dAngle = fabs(dSignAngle);
double dMinAngle(TAuxTools::GetMinDiffAngle());
int nPartNum = int(dAngle / dMinAngle) + 1;
dMinAngle = dSignAngle / nPartNum; // 实际间隔角度
AcGePoint3d ptCenter = GetCirCenter();
AcGeVector3d vtEvery = ptS - ptCenter;
vtEvery.normalize();
AcGePoint3dArray ptArr;
AcGePoint3d ptFirst[5];
ptFirst[0] = ptS + dWidth * 0.5 * vtEvery - dThick * 0.5 * vtNormal;
ptFirst[1] = ptFirst[0] + dThick * vtNormal;
ptFirst[2] = ptFirst[1] - dWidth * vtEvery;
ptFirst[3] = ptFirst[0] - dWidth * vtEvery;
ptFirst[4] = ptFirst[0];
int i(0), j(0);
for (i = 0; i < nPartNum + 1; i++)
{
for (j = 0; j < 5; j++)
{
ptArr.append(ptFirst[j]);
ptFirst[j].rotateBy(dMinAngle, vtNormal, ptCenter);
}
}
mode.DrawMesh(nPartNum + 1, 5, ptArr.asArrayPtr());
return Acad::eOk;
}
// 圆形软风管
/*
↑默认法向
┏━4━┓ 侧壁面 7━━15━━.....
起始端 3 5 ┃ ┃
┃ ┃ . . .....
2 起始端6 ┃ ┃
┃ ┃ 0━━8━━━.....
1 7...
┗━0━┛
*/
Acad::ErrorStatus THImpHvacDuct::ExplodeOrDrawCircSoft3d( XExplodeDraw &mode ) const
{
ASSERT(NULL != m_pXDataMap);
AcGePoint3d ptS = StartPoint();
AcGePoint3d ptE = EndPoint();
AcGeVector3d vtNormal = normal();
AcGeVector3d vtDirect = ptE - ptS;
vtDirect.normalize();
double dBulge(0.0), dAngle(0.0);
m_pXDataMap->GetAt(HDCT_Bulge, dBulge);
dAngle = atan(dBulge) * 4;
vtDirect.rotateBy(-dAngle * 0.5, vtNormal); // 得到起始端界面垂直的法向
// 先绘制起始端网点
double dMinCirAngle(TAuxTools::GetMinDiffAngle());
int nColNum = int(PI * 2 / dMinCirAngle) + 1;
dMinCirAngle = PI * 2 / nColNum;
double dRadius(0.0);
m_pXDataMap->GetAt(HDCT_Diameter, dRadius);
dRadius /= 2;
AcGePoint3dArray ptArr;
AcGeVector3d vtNow = vtNormal * -1; // 每组顶点法向
int i(0);
for (i = 0; i < nColNum; i++)
{
ptArr.append(ptS + dRadius * vtNow);
vtNow.rotateBy(dMinCirAngle, vtDirect);
}
if (ptArr.length() < 1)
return Acad::eNotImplementedYet;
// 单独设置末点,防止误差
ptArr.append(ptArr.at(0));
// 绘制弧度上各个网格
int nRowNum = int(fabs(dAngle) / dMinCirAngle) + 1;
dMinCirAngle = dAngle / nRowNum;
AcGePoint3d ptCenter = GetCirCenter();
AcGeVector3d vtEvery = ptS - ptCenter;
double dEveryAngle = dMinCirAngle;
AcGePoint3d ptEvery;
int j(0);
int nOrigLen = ptArr.length();
for (i = 0; i < nRowNum + 1; i++)
{
for (j = 0; j < nOrigLen; j++)
{
ptEvery = ptArr[j];
ptEvery.rotateBy(dEveryAngle, vtNormal, ptCenter);
ptArr.append(ptEvery);
}
dEveryAngle += dMinCirAngle;
}
mode.DrawMesh(nRowNum + 1, nColNum + 1, ptArr.asArrayPtr());
return Acad::eOk;
}
Acad::ErrorStatus THImpHvacDuct::ExplodeOrDrawOblateSoft3d( XExplodeDraw &mode ) const
{
ASSERT(NULL != m_pXDataMap);
return Acad::eOk;
}
// 构件风管内衬图形 add by hh 2013-9-2
BOOL THImpHvacDuct::MakeDuctLiningCurves(TComplexCurve& cplCurve) const
{
if(NULL == m_pXDataMap)
return FALSE;
// 不处理垂直风管
if(IsVertAlignment())
return FALSE;
// 风管样式
HvacDuctType eDuctType = eStraight;
m_pXDataMap->GetAt(HDCT_Type, (int&)eDuctType);
// 凸度
double dBulge = 0;
m_pXDataMap->GetAt(HDCT_Bulge, dBulge);
// 风管宽度
double dWidth = 0;
m_pXDataMap->GetAt(HDCT_Width, dWidth);
// 内衬线的位置为风管宽度的1/10
double dLining = dWidth * 0.4;
// 起点终点
AcGePoint3d ptS = StartPoint();
AcGePoint3d ptE = EndPoint();
// 投影面
AcGePoint3d ptStd = ptE.z > ptS.z ? ptE:ptS;
AcGePlane planStd = GetStdPrjPlan(ptStd);
// 图层&线型
AcDbObjectId idLayer,idLine;
m_pXDataMap->GetAt(HVAC_LiningLayer, idLayer);
m_pXDataMap->GetAt(HVAC_LiningLine, idLine);
TCurveElement tCurveEle;
memset(&tCurveEle, 0, sizeof(TCurveElement));
tCurveEle.idSubLay = idLayer;
tCurveEle.idSubLty = idLine;
// Z
AcGeVector3d vtZAxis = TAuxTools::GetUcsZvt();
// 软风管
if(eSoft == eDuctType && fabs(dBulge) > 1e-6)
{
if(IsHorzAlignment()) // 仅处理水平放置的软风管
{
AcGePoint3d ptCenter = GetCirCenter();
AcGeVector3d vtStaDir = ptS - ptCenter;
AcGeVector3d vtEndDir = ptE - ptCenter;
vtStaDir.normalize();
vtEndDir.normalize();
AcGeVector3d vtDirect = ptE - ptS;
vtDirect.normalize();
AcGeVector3d vtLevel = (ptE - ptS) * 0.5;
vtLevel.rotateBy(-PI * 0.5, vtZAxis);
vtLevel *= dBulge;
AcGePoint3d ptMid = ptS + ptS.distanceTo(ptE) * 0.5 * vtDirect;
AcGePoint3d ptArc = ptMid + vtLevel;
vtLevel.normalize();
tCurveEle.ptGe[0] = (ptS + dLining * vtStaDir).orthoProject(planStd);
tCurveEle.ptGe[1] = (ptArc + dLining * vtLevel).orthoProject(planStd);
tCurveEle.ptGe[2] = (ptE + dLining * vtEndDir).orthoProject(planStd);
cplCurve.append(tCurveEle);
tCurveEle.ptGe[0] = (ptS - dLining * vtStaDir).orthoProject(planStd);
tCurveEle.ptGe[1] = (ptArc - dLining * vtLevel).orthoProject(planStd);
tCurveEle.ptGe[2] = (ptE - dLining * vtEndDir).orthoProject(planStd);
cplCurve.append(tCurveEle);
}
}
// 直风管
else
{
AcGeVector3d vtSide = AcGeVector3d::kZAxis;
AcGePlane plan(ptS, AcGeVector3d::kZAxis);
AcGePoint3d ptSS = ptS.orthoProject(plan);
AcGePoint3d ptEE = ptE.orthoProject(plan);
AcGeVector3d vtDirect = ptEE - ptSS;
vtDirect.normalize();
vtSide.rotateBy(-PI * 0.5, vtDirect);
if(!IsHorzAlignment()) // 倾斜绘制时 需修正一下起终点
{
HvacSectType eSectType = eRectangular;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType);
double dThick = 0;
AcGeVector3d vtExt = ptE - ptS;
vtExt.normalize();
double dExtend = 0;
if(eSectType == eRectangular) // 方形
{
m_pXDataMap->GetAt(HDCT_Thick, dThick);
AcGePlane plan(ptS, TAuxTools::GetUcsZvt());
AcGePoint3d ptPrj = ptE.orthoProject(plan);
double dAngle = asin(ptE.distanceTo(ptPrj) / ptS.distanceTo(ptE));
dExtend = dThick * 0.5 * tan(dAngle);
}
else if(eSectType == eCircular) // 圆形
{
m_pXDataMap->GetAt(HDCT_Diameter, dThick);
AcDbPolyline poly;
int nRet = 0;
if(ptS.z > ptE.z)
{
nRet = TAuxTools::GetEllipseFromCircle(ptS, dThick,
vtExt, vtZAxis, poly, vtExt);
}
else
{
nRet = TAuxTools::GetEllipseFromCircle(ptE, dThick,
vtExt, vtZAxis, poly, -vtExt);
}
if(2 == nRet)
{
// 计算交点
AcGePoint3d pt1 = (ptS - dLining * vtSide).orthoProject(planStd);
AcGePoint3d pt2 = (ptE - dLining * vtSide).orthoProject(planStd);
AcDbLine line(pt1, pt2);
AcGePoint3dArray arInter;
poly.intersectWith(&line, AcDb::kExtendArg, planStd, arInter);
if(1 == arInter.length())
{
dExtend = min(arInter[0].distanceTo(pt1), arInter[0].distanceTo(pt2));
vtExt = vtExt.orthoProject(planStd.normal());
vtExt.normalize();
}
}
}
if(ptS.z < ptE.z)
{
ptS = ptS - dExtend * vtExt;
ptE = ptE - dExtend * vtExt;
}
else
{
ptS = ptS + dExtend * vtExt;
ptE = ptE + dExtend * vtExt;
}
}
tCurveEle.ptGe[0] = (ptS - dLining * vtSide).orthoProject(planStd);
tCurveEle.ptGe[1] = (ptE - dLining * vtSide).orthoProject(planStd);
tCurveEle.ptGe[2] = (ptE - dLining * vtSide).orthoProject(planStd);
cplCurve.append(tCurveEle);
tCurveEle.ptGe[0] = (ptS + dLining * vtSide).orthoProject(planStd);
tCurveEle.ptGe[1] = (ptE + dLining * vtSide).orthoProject(planStd);
tCurveEle.ptGe[2] = (ptE + dLining * vtSide).orthoProject(planStd);
cplCurve.append(tCurveEle);
}
return TRUE;
}
BOOL THImpHvacDuct::MakeHorz2DCurves( TComplexCurve& cplCurve, int nOutOrIn ) const
{
ASSERT(NULL != m_pXDataMap);
// 风管类型
HvacDuctType eDuctType = eStraight;
m_pXDataMap->GetAt(HDCT_Type, (int&)eDuctType);
switch (eDuctType)
{
case eStraight: // 直风管
return MakeHorzStraight2DCurves(cplCurve, nOutOrIn);
case eSoft: // 软风管
return MakeHorzSoft2DCurves(cplCurve, nOutOrIn);
default:
return FALSE;
}
}
BOOL THImpHvacDuct::MakeHorzStraight2DCurves( TComplexCurve& cplCurve, int nOutOrIn ) const
{
ASSERT(NULL != m_pXDataMap);
// add by zh 2013-7-5
BOOL bSoft(FALSE);
m_pXDataMap->GetAt(HDCT_Soft, bSoft);
if (bSoft)
{
return MakeRealHorzSoft2DCurves(cplCurve, nOutOrIn);
}
//
TCurveElement tCurveEle;
memset(&tCurveEle, 0, sizeof(TCurveElement));
tCurveEle.bHided = FALSE;
tCurveEle.dWidth = 0.0;
tCurveEle.gsMark = 0;
AcGePoint3d ptS = StartPoint();
AcGePoint3d ptE = EndPoint();
BOOL bBaseLine(FALSE);
double dWidth(0.0); //
m_pXDataMap->GetAt(HVAC_HasBaseLine, bBaseLine);
// add by hh 2013-08-30 内衬
BOOL bLining = FALSE;
m_pXDataMap->GetAt(HVAC_HasLining, bLining);
if(!IsSingleLine() && bLining && nOutOrIn == 1)
{
MakeDuctLiningCurves(cplCurve);
}
// add end
double dEdgeWidth = GetEdgeLineWidth();
if (IsSingleLine() || (bBaseLine && nOutOrIn == 1))
{
tCurveEle.ptGe[0] = ptS;
tCurveEle.ptGe[1] = ptE;
tCurveEle.ptGe[2] = ptE;
if (IsSingleLine())
{
tCurveEle.dWidth = dEdgeWidth;
}
else
{
double dCentWidth = GetCentLineWidth();
tCurveEle.dWidth = dCentWidth;
tCurveEle.idSubLay = GetBaseLayerId();
}
cplCurve.append(tCurveEle);
}
else if (nOutOrIn == 0) // 四边
{
double dEndWidth = GetEndLineWidth();
tCurveEle.idSubLay.setNull();
tCurveEle.dWidth = dEdgeWidth;
AcDbObjectId idSideLayer(NULL);
m_pXDataMap->GetAt(HVAC_EndLayer, idSideLayer);
AcGePoint3dArray ptArr; // 各线起始点
GetFourKeyPoints(ptArr);
if (ptArr.length() != 4)
return FALSE;
tCurveEle.ptGe[0] = ptArr[0];
tCurveEle.ptGe[1] = ptArr[1];
tCurveEle.ptGe[2] = ptArr[1];
cplCurve.append(tCurveEle);
int nEndDrawType(0);
GetGlobalContext(HVAC_DuctEndDrawType, nEndDrawType);
// change by hh 2011-09-09 避免风管拖动预览时频繁访问接口
if(!m_pOwnerEnt->objectId().isValid())
{
tCurveEle.ptGe[0] = ptArr[1];
tCurveEle.ptGe[1] = ptArr[2];
tCurveEle.ptGe[2] = ptArr[2];
cplCurve.append(tCurveEle);
}
else
{
if (!IsEndConnect() && nEndDrawType == 0)
{
tCurveEle.ptGe[0] = ptArr[1];
tCurveEle.ptGe[1] = ptArr[2];
tCurveEle.ptGe[2] = ptArr[2];
cplCurve.append(tCurveEle);
}
else if (!IsHideEnd())
{
tCurveEle.ptGe[0] = ptArr[1];
tCurveEle.ptGe[1] = ptArr[2];
tCurveEle.ptGe[2] = ptArr[2];
tCurveEle.idSubLay = idSideLayer;
tCurveEle.dWidth = dEndWidth;
cplCurve.append(tCurveEle);
}
}
// if (!IsHideEnd())
// {
// tCurveEle.ptGe[0] = ptArr[1];
// tCurveEle.ptGe[1] = ptArr[2];
// tCurveEle.ptGe[2] = ptArr[2];
//
// if (IsEndConnect())
// {
// tCurveEle.idSubLay = idSideLayer;
// tCurveEle.dWidth = dEndWidth;
// }
// cplCurve.append(tCurveEle);
// }
tCurveEle.ptGe[0] = ptArr[2];
tCurveEle.ptGe[1] = ptArr[3];
tCurveEle.ptGe[2] = ptArr[3];
tCurveEle.idSubLay.setNull();
tCurveEle.dWidth = dEdgeWidth;
cplCurve.append(tCurveEle);
// change by hh 2011-09-09 避免风管拖动预览时频繁访问接口
if(!m_pOwnerEnt->objectId().isValid())
{
tCurveEle.ptGe[0] = ptArr[3];
tCurveEle.ptGe[1] = ptArr[0];
tCurveEle.ptGe[2] = ptArr[0];
cplCurve.append(tCurveEle);
}
else
{
if (!IsStartConnect() && nEndDrawType == 0)
{
tCurveEle.ptGe[0] = ptArr[3];
tCurveEle.ptGe[1] = ptArr[0];
tCurveEle.ptGe[2] = ptArr[0];
cplCurve.append(tCurveEle);
}
else if (!IsHideStart())
{
tCurveEle.ptGe[0] = ptArr[3];
tCurveEle.ptGe[1] = ptArr[0];
tCurveEle.ptGe[2] = ptArr[0];
tCurveEle.idSubLay = idSideLayer;
tCurveEle.dWidth = dEndWidth;
cplCurve.append(tCurveEle);
}
}
// if (!IsHideStart())
// {
// tCurveEle.ptGe[0] = ptArr[3];
// tCurveEle.ptGe[1] = ptArr[0];
// tCurveEle.ptGe[2] = ptArr[0];
// if (IsStartConnect())
// {
// tCurveEle.idSubLay = idSideLayer;
// tCurveEle.dWidth = dEndWidth;
// }
// cplCurve.append(tCurveEle);
// }
}
return TRUE;
}
BOOL THImpHvacDuct::MakeHorzSoft2DCurves( TComplexCurve& cplCurve, int nOutOrIn ) const
{
ASSERT(NULL != m_pXDataMap);
// add by zh 2013-7-5
BOOL bSoft(FALSE);
m_pXDataMap->GetAt(HDCT_Soft, bSoft);
if (bSoft)
return MakeRealHorzSoft2DCurves(cplCurve, nOutOrIn);
//
if (!IsSingleLine() && !IsCanDrawSoft())
return FALSE;
double dBulge(0);
m_pXDataMap->GetAt(HDCT_Bulge, dBulge);
if (fabs(dBulge) < 1e-6)
return MakeHorzStraight2DCurves(cplCurve, nOutOrIn);
TCurveElement tCurveEle;
memset(&tCurveEle, 0, sizeof(TCurveElement));
tCurveEle.bHided = FALSE;
tCurveEle.dWidth = 0.0;
tCurveEle.gsMark = 0;
double dWidth(0.0);
m_pXDataMap->GetAt(HDCT_Width, dWidth);
AcGePoint3d ptS = StartPoint();
AcGePoint3d ptE = EndPoint();
AcGeVector3d vtDirect = ptE - ptS;
AcGeVector3d vtNormal = TAuxTools::GetUcsZvt();
vtDirect.normalize();
AcGeVector3d vtLevel = (ptE - ptS) * 0.5; // 水平法向辅助求点用
vtLevel.rotateBy(-PI * 0.5, vtNormal);
vtLevel *= dBulge;
AcGePoint3d ptMid = ptS + ptS.distanceTo(ptE) * 0.5 * vtDirect;
AcGePoint3d ptArcMid = ptMid + vtLevel; // 圆弧中点
double dEdgeWidth = GetEdgeLineWidth();
if (IsSingleLine())
{
tCurveEle.ptGe[0] = ptS;
tCurveEle.ptGe[1] = ptArcMid;
tCurveEle.ptGe[2] = ptE;
tCurveEle.dWidth = dEdgeWidth;
cplCurve.append(tCurveEle);
return TRUE;
}
BOOL bBaseLine(FALSE);
m_pXDataMap->GetAt(HVAC_HasBaseLine, bBaseLine);
// add by hh 2013-08-30 内衬
BOOL bLining = FALSE;
m_pXDataMap->GetAt(HVAC_HasLining, bLining);
if(!IsSingleLine() && bLining && nOutOrIn == 1)
{
MakeDuctLiningCurves(cplCurve);
}
// add end
if (nOutOrIn == 1 && bBaseLine)
{
double dCentWidth = GetCentLineWidth();
tCurveEle.dWidth = dCentWidth;
tCurveEle.ptGe[0] = ptS;
tCurveEle.ptGe[1] = ptArcMid;
tCurveEle.ptGe[2] = ptE;
tCurveEle.idSubLay = GetBaseLayerId();
cplCurve.append(tCurveEle);
}
else if (nOutOrIn == 0) // 边线及两端
{
double dEndWidth = GetEndLineWidth();
AcDbObjectId idSideLayer(NULL);
m_pXDataMap->GetAt(HVAC_EndLayer, idSideLayer);
AcGePoint3dArray ptArr;
GetFourKeyPoints(ptArr);
if (ptArr.length() != 4)
return FALSE;
ConverFourKeyPts(ptArr);// 转换为实际边界点Lixl add 2012-2-28
vtLevel.normalize();
AcGePoint3d ptArcMidUp = ptArcMid - dWidth * 0.5 * vtLevel;
AcGePoint3d ptArcMidDown = ptArcMidUp + dWidth * vtLevel;
tCurveEle.dWidth = dEdgeWidth;
tCurveEle.ptGe[0] = ptArr[0];
tCurveEle.ptGe[1] = ptArcMidDown;
tCurveEle.ptGe[2] = ptArr[1];
cplCurve.append(tCurveEle);
if (!IsHideEnd())
{
tCurveEle.ptGe[0] = ptArr[1];
tCurveEle.ptGe[1] = ptArr[2];
tCurveEle.ptGe[2] = ptArr[2];
tCurveEle.idSubLay = idSideLayer;
tCurveEle.dWidth = dEndWidth;
cplCurve.append(tCurveEle);
}
tCurveEle.idSubLay.setNull();
tCurveEle.ptGe[0] = ptArr[2];
tCurveEle.ptGe[1] = ptArcMidUp;
tCurveEle.ptGe[2] = ptArr[3];
tCurveEle.dWidth = dEdgeWidth;
cplCurve.append(tCurveEle);
if (!IsHideStart())
{
tCurveEle.ptGe[0] = ptArr[3];
tCurveEle.ptGe[1] = ptArr[0];
tCurveEle.ptGe[2] = ptArr[0];
tCurveEle.idSubLay = idSideLayer;
tCurveEle.dWidth = dEndWidth;
cplCurve.append(tCurveEle);
}
}
return TRUE;
}
BOOL THImpHvacDuct::MakeVert2DCurves( TComplexCurve& cplCurve, int nOutOrIn ) const
{
ASSERT(NULL != m_pXDataMap);
if (IsSingleLine())
return FALSE;
// 风管类型
HvacDuctType eDuctType = eStraight;
m_pXDataMap->GetAt(HDCT_Type, (int&)eDuctType);
switch (eDuctType)
{
case eStraight: // 直风管
return MakeVertStraight2DCurves(cplCurve, nOutOrIn);
case eSoft: // 软风管
return MakeVertSoft2DCurves(cplCurve, nOutOrIn);
default:
return FALSE;
}
}
// 直立管平面绘制, LU:左上
/*
3━━━━━2   
┃ ┃ ┃
┃ ┃ ┃
┃ ptCenter┃ heigh
┃ ┃ ┃
┃ ┃ ┃
0━━━━━1 ┃
------width----
*/
BOOL THImpHvacDuct::MakeVertStraight2DCurves( TComplexCurve& cplCurve, int nOutOrIn ) const
{
ASSERT(NULL != m_pXDataMap);
TCurveElement tCurveEle;
memset(&tCurveEle, 0, sizeof(TCurveElement));
tCurveEle.bHided = FALSE;
tCurveEle.dWidth = GetEdgeLineWidth();
tCurveEle.gsMark = 0;
AcGePoint3dArray ptArr;
GetFourKeyPoints(ptArr);
if (ptArr.length() != 4)
return FALSE;
HvacSectType eSectType = eRectangular;
HvacDrawType eDrawType = eOldStyle;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType);
m_pXDataMap->GetAt(HVAC_DrawType, (int&)eDrawType);
if (eSectType == eRectangular)
{
if (nOutOrIn == 0)
{
tCurveEle.ptGe[0] = ptArr[0];
tCurveEle.ptGe[1] = ptArr[1];
tCurveEle.ptGe[2] = ptArr[1];
cplCurve.append(tCurveEle);
tCurveEle.ptGe[0] = ptArr[1];
tCurveEle.ptGe[1] = ptArr[2];
tCurveEle.ptGe[2] = ptArr[2];
cplCurve.append(tCurveEle);
tCurveEle.ptGe[0] = ptArr[2];
tCurveEle.ptGe[1] = ptArr[3];
tCurveEle.ptGe[2] = ptArr[3];
cplCurve.append(tCurveEle);
tCurveEle.ptGe[0] = ptArr[3];
tCurveEle.ptGe[1] = ptArr[0];
tCurveEle.ptGe[2] = ptArr[0];
cplCurve.append(tCurveEle);
}
else if (nOutOrIn == 1)
{
m_pXDataMap->GetAt(HVAC_EndLayer, tCurveEle.idSubLay);
tCurveEle.dWidth = GetEndLineWidth();
if (eDrawType == eOldStyle)
{
AcGePoint3d ptCenter = TAuxTools::Mid(ptArr[0], ptArr[2]);
AcGePoint3d ptLineMid = TAuxTools::Mid(ptCenter, ptArr[3]);
tCurveEle.ptGe[0] = ptArr[0];
tCurveEle.ptGe[1] = ptLineMid;
tCurveEle.ptGe[2] = ptLineMid;
cplCurve.append(tCurveEle);
tCurveEle.ptGe[0] = ptLineMid;
tCurveEle.ptGe[1] = ptArr[2];
tCurveEle.ptGe[2] = ptArr[2];
cplCurve.append(tCurveEle);
}
else if (eDrawType == eNewImmit || eDrawType == eNewEject)
{
tCurveEle.ptGe[0] = ptArr[0];
tCurveEle.ptGe[1] = ptArr[2];
tCurveEle.ptGe[2] = ptArr[2];
cplCurve.append(tCurveEle);
if (eDrawType == eNewImmit)
{
tCurveEle.ptGe[0] = ptArr[3];
tCurveEle.ptGe[1] = ptArr[1];
tCurveEle.ptGe[2] = ptArr[1];
cplCurve.append(tCurveEle);
}
}
}
}
else if (eSectType == eCircular)
{
if (nOutOrIn == 0)
{
tCurveEle.ptGe[0] = ptArr[0];
tCurveEle.ptGe[1] = ptArr[1];
tCurveEle.ptGe[2] = ptArr[2];
cplCurve.append(tCurveEle);
tCurveEle.ptGe[0] = ptArr[2];
tCurveEle.ptGe[1] = ptArr[3];
tCurveEle.ptGe[2] = ptArr[0];
cplCurve.append(tCurveEle);
}
else if (nOutOrIn == 1)
{
m_pXDataMap->GetAt(HVAC_EndLayer, tCurveEle.idSubLay);
tCurveEle.dWidth = GetEndLineWidth();
double dRadiu(0.0);
m_pXDataMap->GetAt(HDCT_Diameter, dRadiu);
dRadiu /= 2;
AcGeVector3d vtNormal = normal();
AcGePoint3d ptCenter = TAuxTools::Mid(ptArr[0], ptArr[2]);
AcGeVector3d vtPerDir = TAuxTools::GetUcsZvt(); // 该面垂直向上的法向
double dBulge(0.0);
m_pXDataMap->GetAt(HDCT_Bulge, dBulge);
if (fabs(dBulge) > 1e-6)
{
AcGePoint3d ptCirCt = GetCirCenter();
AcGeVector3d vtRad = ptCenter - ptCirCt;
vtPerDir = vtRad.crossProduct(vtNormal);
if (vtPerDir.z < 0)
vtPerDir *= -1;
}
AcGeVector3d vtSide = normal();
vtSide.rotateBy(-PI/4, vtPerDir);
if (eDrawType == eOldStyle)
{
AcGePoint3d ptArcS, ptArcMid, ptArcE;
ptArcS = ptCenter - dRadiu * vtSide;
ptArcE = ptCenter + dRadiu * vtSide;
vtSide.rotateBy(PI * 0.5, vtPerDir);
ptArcMid = ptCenter + dRadiu * 0.5 * vtSide;
tCurveEle.ptGe[0] = ptArcS;
tCurveEle.ptGe[1] = ptArcMid;
tCurveEle.ptGe[2] = ptArcE;
cplCurve.append(tCurveEle);
}
else if (eDrawType == eNewImmit || eDrawType == eNewEject)
{
AcGePoint3d ptS, ptE;
ptS = ptCenter - dRadiu * vtSide;
ptE = ptCenter + dRadiu * vtSide;
tCurveEle.ptGe[0] = ptS;
tCurveEle.ptGe[1] = ptE;
tCurveEle.ptGe[2] = ptE;
cplCurve.append(tCurveEle);
if (eDrawType == eNewImmit)
{
vtSide.rotateBy(PI * 0.5, vtPerDir);
ptS = ptCenter - dRadiu * vtSide;
ptE = ptCenter + dRadiu * vtSide;
tCurveEle.ptGe[0] = ptS;
tCurveEle.ptGe[1] = ptE;
tCurveEle.ptGe[2] = ptE;
cplCurve.append(tCurveEle);
}
}
}
}
return TRUE;
}
// 直立管平面绘制, LU:左上, 在直管位置点基础上,先旋转相应角度,再投影在水平面上即可
/*
LU━━━━━RU   
┃ ┃ ┃
┃ ┃ ┃
┃ ptStd ┃ heigh
┃ ┃ ┃
┃ ┃ ┃
LD━━━━━RD ┃
------width----
*/
BOOL THImpHvacDuct::MakeVertSoft2DCurves( TComplexCurve& cplCurve, int nOutOrIn ) const
{
ASSERT(NULL != m_pXDataMap);
TCurveElement tCurveEle;
memset(&tCurveEle, 0, sizeof(TCurveElement));
tCurveEle.bHided = FALSE;
tCurveEle.dWidth = GetEdgeLineWidth();
tCurveEle.gsMark = 0;
double dBulge(0), dPosiBulge(0);
m_pXDataMap->GetAt(HDCT_Bulge, dBulge);
dPosiBulge = fabs((dBulge));
if (dPosiBulge < 1e-6)
return MakeVertStraight2DCurves(cplCurve, nOutOrIn);
if (!IsCanDrawSoft())
return FALSE;
AcGePoint3d ptSta = StartPoint();
AcGePoint3d ptEnd = EndPoint();
AcGePoint3d ptStd = ptEnd.z > ptSta.z ? ptEnd:ptSta;
AcGePoint3d ptCenter = GetCirCenter();
AcGeVector3d vtStdToCenter = ptStd - ptCenter; // 标准点到圆心点向量
vtStdToCenter.normalize();
AcGeVector3d vtNormal = normal();
AcGeVector3d vtSide = vtNormal;
HvacSectType eSectType = eRectangular;
HvacDrawType eDrawType = eOldStyle;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType);
m_pXDataMap->GetAt(HVAC_DrawType, (int&)eDrawType);
AcGeVector3d vtUserZAixs = TAuxTools::GetUcsZvt();
AcGePlane planStd = GetStdPrjPlan(ptStd);
// 倾斜角度
double dRotAngle = atan(dPosiBulge) * 2;
if (eSectType == eRectangular)
{
vtSide.rotateBy(PI * 0.5, vtUserZAixs);
double dWidth(0.0), dHeigh(0.0);
m_pXDataMap->GetAt(HDCT_Width, dWidth);
m_pXDataMap->GetAt(HDCT_Thick, dHeigh);
AcGePoint3d ptLD, ptRD, ptRU, ptLU;
ptLD = ptStd + dWidth * 0.5 * vtStdToCenter - dHeigh * 0.5 * vtNormal;
ptLU = ptLD + dHeigh * vtNormal;
ptRU = ptLU - dWidth * vtStdToCenter;
ptRD = ptRU - dHeigh * vtNormal;
ptLD = ptLD.orthoProject(planStd);
ptLU = ptLU.orthoProject(planStd);
ptRU = ptRU.orthoProject(planStd);
ptRD = ptRD.orthoProject(planStd);
if (nOutOrIn == 0)
{
tCurveEle.ptGe[0] = ptLD;
tCurveEle.ptGe[1] = ptRD;
tCurveEle.ptGe[2] = ptRD;
cplCurve.append(tCurveEle);
tCurveEle.ptGe[0] = ptRD;
tCurveEle.ptGe[1] = ptRU;
tCurveEle.ptGe[2] = ptRU;
cplCurve.append(tCurveEle);
tCurveEle.ptGe[0] = ptRU;
tCurveEle.ptGe[1] = ptLU;
tCurveEle.ptGe[2] = ptLU;
cplCurve.append(tCurveEle);
tCurveEle.ptGe[0] = ptLU;
tCurveEle.ptGe[1] = ptLD;
tCurveEle.ptGe[2] = ptLD;
cplCurve.append(tCurveEle);
}
else if (nOutOrIn == 1)
{
m_pXDataMap->GetAt(HVAC_EndLayer, tCurveEle.idSubLay);
tCurveEle.dWidth = GetEndLineWidth();
if (eDrawType == eOldStyle)
{
AcGePoint3d ptLineMid = TAuxTools::Mid(ptStd, ptLU);
tCurveEle.ptGe[0] = ptLD;
tCurveEle.ptGe[1] = ptLineMid;
tCurveEle.ptGe[2] = ptLineMid;
cplCurve.append(tCurveEle);
tCurveEle.ptGe[0] = ptLineMid;
tCurveEle.ptGe[1] = ptRU;
tCurveEle.ptGe[2] = ptRU;
cplCurve.append(tCurveEle);
}
else if (eDrawType == eNewImmit || eDrawType == eNewEject)
{
tCurveEle.ptGe[0] = ptLD;
tCurveEle.ptGe[1] = ptRU;
tCurveEle.ptGe[2] = ptRU;
cplCurve.append(tCurveEle);
if (eDrawType == eNewImmit)
{
tCurveEle.ptGe[0] = ptLU;
tCurveEle.ptGe[1] = ptRD;
tCurveEle.ptGe[2] = ptRD;
cplCurve.append(tCurveEle);
}
}
}
}
else if (eSectType == eCircular)
{
if (nOutOrIn == 0)
{
double dDia(0.0);
m_pXDataMap->GetAt(HDCT_Diameter, dDia);
AcGeVector3d vtOrigCir = vtStdToCenter.crossProduct(vtNormal);
AcDbPolyline pPolyLine;
AcGePoint3dArray ptArcArr;
int nRet = TAuxTools::GetEllipseFromCircle(ptStd, dDia, vtOrigCir, vtUserZAixs, pPolyLine);
if (nRet == 2)
{
TAuxTools::GetArcPoint(pPolyLine, ptArcArr);
int i(0);
// for (i = 0; i < ptArcArr.length(); i++)
// {
// if (i > 1 && i%2 == 0)
// {
// tCurveEle.ptGe[0] = ptArcArr[i-2];
// tCurveEle.ptGe[1] = ptArcArr[i-1];
// tCurveEle.ptGe[2] = ptArcArr[i];
// cplCurve.append(tCurveEle);
// }
// }
for (i = 0; i < ptArcArr.length()-1; i++)
{
tCurveEle.ptGe[0] = ptArcArr[i];
tCurveEle.ptGe[1] = ptArcArr[i+1];
tCurveEle.ptGe[2] = ptArcArr[i+1];
cplCurve.append(tCurveEle);
}
}
}
else if (nOutOrIn == 1)
{
m_pXDataMap->GetAt(HVAC_EndLayer, tCurveEle.idSubLay);
tCurveEle.dWidth = GetEndLineWidth();
vtSide.rotateBy(-PI/4, vtUserZAixs);
double dRadiu(0.0);
m_pXDataMap->GetAt(HDCT_Diameter, dRadiu);
dRadiu /= 2;
if (eDrawType == eOldStyle)
{
AcGePoint3d ptArcS, ptArcMid, ptArcE;
ptArcS = ptStd - dRadiu * vtSide;
ptArcE = ptStd + dRadiu * vtSide;
vtSide.rotateBy(PI * 0.5, vtUserZAixs);
ptArcMid = ptStd + dRadiu * 0.5 * vtSide;
ptArcS.rotateBy(dRotAngle, vtNormal, ptStd);
ptArcE.rotateBy(dRotAngle, vtNormal, ptStd);
ptArcMid.rotateBy(dRotAngle, vtNormal, ptStd);
tCurveEle.ptGe[0] = ptArcS.orthoProject(planStd);
tCurveEle.ptGe[1] = ptArcMid.orthoProject(planStd);
tCurveEle.ptGe[2] =ptArcE.orthoProject(planStd);
cplCurve.append(tCurveEle);
}
else if (eDrawType == eNewImmit || eDrawType == eNewEject)
{
AcGePoint3d ptS, ptE;
ptS = ptStd - dRadiu * vtSide;
ptE = ptStd + dRadiu * vtSide;
AcGeMatrix3d matRot;
matRot.setToRotation(dRotAngle, vtNormal, ptStd);
ptS.transformBy(matRot);
ptE.transformBy(matRot);
tCurveEle.ptGe[0] = ptS.orthoProject(planStd);
tCurveEle.ptGe[1] = ptE.orthoProject(planStd);
tCurveEle.ptGe[2] =ptE.orthoProject(planStd);
cplCurve.append(tCurveEle);
if (eDrawType == eNewImmit)
{
vtSide.rotateBy(PI * 0.5, vtUserZAixs);
ptS = ptStd - dRadiu * vtSide;
ptE = ptStd + dRadiu * vtSide;
ptS.transformBy(matRot);
ptE.transformBy(matRot);
tCurveEle.ptGe[0] = ptS.orthoProject(planStd);
tCurveEle.ptGe[1] = ptE.orthoProject(planStd);
tCurveEle.ptGe[2] =ptE.orthoProject(planStd);
cplCurve.append(tCurveEle);
}
}
}
}
return TRUE;
}
BOOL THImpHvacDuct::MakeIncl2DCurves( TComplexCurve& cplCurve, int nOutOrIn ) const
{
ASSERT(NULL != m_pXDataMap);
// 风管类型
HvacDuctType eDuctType = eStraight;
m_pXDataMap->GetAt(HDCT_Type, (int&)eDuctType);
switch (eDuctType)
{
case eStraight: // 直风管
return MakeInclStraight2DCurves(cplCurve, nOutOrIn);
case eSoft: // 软风管
return MakeInclSoft2DCurves(cplCurve, nOutOrIn);
default:
return FALSE;
}
}
// 绘制直风管,倾斜时状态,求出两端延长部分,加在中截面延长方向上
BOOL THImpHvacDuct::MakeInclStraight2DCurves( TComplexCurve& cplCurve, int nOutOrIn ) const
{
ASSERT(NULL != m_pXDataMap);
TCurveElement tCurveEle;
memset(&tCurveEle, 0, sizeof(TCurveElement));
tCurveEle.bHided = FALSE;
tCurveEle.dWidth = 0.0;
tCurveEle.gsMark = 0;
AcGePoint3d ptS = StartPoint();
AcGePoint3d ptE = EndPoint();
AcDbObjectId idBaseLayer(GetBaseLayerId()), idSideLayer(NULL);
m_pXDataMap->GetAt(HVAC_EndLayer, idSideLayer);
double dEdgeWidth = GetEdgeLineWidth();
// add by hh 2013-08-30 内衬
BOOL bLining = FALSE;
m_pXDataMap->GetAt(HVAC_HasLining, bLining);
if(!IsSingleLine() && bLining && nOutOrIn == 1)
{
MakeDuctLiningCurves(cplCurve);
}
// add end
int nEndDrawType(0);
GetGlobalContext(HVAC_DuctEndDrawType, nEndDrawType);
if (IsSingleLine())
{
tCurveEle.ptGe[0] = ptS;
tCurveEle.ptGe[1] = ptE;
tCurveEle.ptGe[2] = ptE;
tCurveEle.dWidth = dEdgeWidth;
cplCurve.append(tCurveEle);
return TRUE;
}
double dWidth(0.0);
m_pXDataMap->GetAt(HDCT_Width, dWidth);
AcGeVector3d vtDirect = ptE - ptS;
vtDirect.normalize();
AcGePoint3dArray ptArr; // 各线起始点
GetFourKeyPoints(ptArr);
if (ptArr.length() != 4)
return FALSE;
AcDbDatabase* pDb = acdbCurDwg();
AcGeVector3d vtZAxis(pDb->ucsxdir().crossProduct(pDb->ucsydir()));
double dEle(0.0);
AcGePlane planStd = GetHidePlane(ptArr[0], ptArr[1], ptArr[2], vtZAxis, dEle);
double dExtend(0); // vtDirect 方向上的延伸距离
AcGePlane plan(ptS, TAuxTools::GetUcsZvt());
AcGePoint3d ptPrj = ptE.orthoProject(plan);
double dAngle = asin(ptE.distanceTo(ptPrj) / ptS.distanceTo(ptE));
HvacSectType eSectType = eRectangular;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType);
double dThick(0.0);
if (eSectType == eRectangular)
m_pXDataMap->GetAt(HDCT_Thick, dThick);
else if (eSectType == eCircular)
m_pXDataMap->GetAt(HDCT_Diameter, dThick);
dExtend = dThick * 0.5 * tan(dAngle);
double dEndWidth = GetEndLineWidth();
if (eSectType == eRectangular)
{
if (nOutOrIn == 1)
{
BOOL bBaseLine(FALSE);
m_pXDataMap->GetAt(HVAC_HasBaseLine, bBaseLine);
if (bBaseLine)
{
AcGePoint3d ptStaMidExten = ptS;
AcGePoint3d ptEndMidExten = ptE;
if (ptS.z < ptE.z)
{
ptStaMidExten = ptS - dExtend * vtDirect;
ptEndMidExten = ptE - dExtend * vtDirect;
}
else
{
ptStaMidExten = ptS + dExtend * vtDirect;
ptEndMidExten = ptE + dExtend * vtDirect;
}
double dCentWidth = GetCentLineWidth();
tCurveEle.dWidth = dCentWidth;
tCurveEle.ptGe[0] = ptStaMidExten.orthoProject(planStd);
tCurveEle.ptGe[1] = ptEndMidExten.orthoProject(planStd);
tCurveEle.ptGe[2] = ptEndMidExten.orthoProject(planStd);
tCurveEle.idSubLay = idBaseLayer;
cplCurve.append(tCurveEle);
}
tCurveEle.dWidth = dEndWidth;
tCurveEle.idSubLay = idSideLayer;
if (ptS.z > ptE.z) // 被遮挡的不绘制
{
ptArr[0] += dExtend * vtDirect;
ptArr[3] += dExtend * vtDirect;
tCurveEle.ptGe[0] = ptArr[0].orthoProject(planStd);
tCurveEle.ptGe[1] = ptArr[3].orthoProject(planStd);
tCurveEle.ptGe[2] = ptArr[3].orthoProject(planStd);
//BEGIN===========================================
if (nEndDrawType == 0) //0为随风管壁,1为随端线设置
{
tCurveEle.idSubLay.setNull();
tCurveEle.dWidth = dEdgeWidth;
}
else
{
tCurveEle.idSubLay = idSideLayer;
tCurveEle.dWidth = dEndWidth;
}
//修改时间:2010-05-06
//修改人 :王亚东
//修改原因:支持倾斜风管在按风管壁和端线设置时,线宽与图层对应
//END=============================================
cplCurve.append(tCurveEle);
}
else
{
ptArr[1] -= dExtend * vtDirect;
ptArr[2] -= dExtend * vtDirect;
tCurveEle.ptGe[0] = ptArr[1].orthoProject(planStd);
tCurveEle.ptGe[1] = ptArr[2].orthoProject(planStd);
tCurveEle.ptGe[2] = ptArr[2].orthoProject(planStd);
//BEGIN===========================================
if (nEndDrawType == 0)
{
tCurveEle.idSubLay.setNull();
tCurveEle.dWidth = dEdgeWidth;
}
else
{
tCurveEle.idSubLay = idSideLayer;
tCurveEle.dWidth = dEndWidth;
}
//修改时间:2010-05-06
//修改人 :王亚东
//修改原因:支持倾斜风管在按风管壁和端线设置时,线宽与图层对应
//END=============================================
cplCurve.append(tCurveEle);
}
}
else if (nOutOrIn == 0) // 四边
{
tCurveEle.dWidth = dEndWidth;
tCurveEle.idSubLay = idSideLayer;
ptArr[0] = ptArr[0] - dExtend * vtDirect;
ptArr[3] = ptArr[3] - dExtend * vtDirect;
ptArr[1] = ptArr[1] + dExtend * vtDirect;
ptArr[2] = ptArr[2] + dExtend * vtDirect;
int i(0);
for (i = 0; i < 3; i++)
{
tCurveEle.ptGe[0] = ptArr[i].orthoProject(planStd);
tCurveEle.ptGe[1] = ptArr[i+1].orthoProject(planStd);
tCurveEle.ptGe[2] = ptArr[i+1].orthoProject(planStd);
if (i == 1)
{
//BEGIN=====================================
if (nEndDrawType == 0)
{
tCurveEle.idSubLay.setNull();
tCurveEle.dWidth = dEdgeWidth;
}
else
{
tCurveEle.idSubLay = idSideLayer;
tCurveEle.dWidth = dEndWidth;
}
//修改时间:2010-05-06
//修改人 :王亚东
//修改原因:支持倾斜风管在按风管壁和端线设置时,线宽与图层对应
//END=======================================
}
else
{
tCurveEle.idSubLay.setNull();
tCurveEle.dWidth = dEdgeWidth;
}
cplCurve.append(tCurveEle);
}
tCurveEle.ptGe[0] = ptArr[3].orthoProject(planStd);
tCurveEle.ptGe[1] = ptArr[0].orthoProject(planStd);
tCurveEle.ptGe[2] = ptArr[0].orthoProject(planStd);
//BEGIN================================================
if (nEndDrawType == 0)
{
tCurveEle.idSubLay.setNull();
tCurveEle.dWidth = dEdgeWidth;
}
else
{
tCurveEle.idSubLay = idSideLayer;
tCurveEle.dWidth = dEndWidth;
}
//修改时间:2010-05-06
//修改人 :王亚东
//修改原因:支持倾斜风管在按风管壁和端线设置时,线宽与图层对应
//END==================================================
cplCurve.append(tCurveEle);
}
}
else if (eSectType == eCircular)
{
AcGePoint3d ptEllEnd = ptE/*.orthoProject(planStd)*/;
AcGePoint3d ptEllStart = ptS/*.orthoProject(planStd)*/;
// AcGeVector3d vtStaOffSet = ptEllStart.asVector();
// AcGeVector3d vtEndOffSet = ptEllEnd.asVector();
AcGePoint3dArray ptArcStaArr, ptArcEndArr; // 弧上的各点
AcDbPolyline polyLineSta;
AcDbPolyline polyLineEnd;
if (nOutOrIn == 1)
{
BOOL bBaseLine(FALSE);
m_pXDataMap->GetAt(HVAC_HasBaseLine, bBaseLine);
if (bBaseLine)
{
AcGePoint3d ptStaMidExten = ptS;
AcGePoint3d ptEndMidExten = ptE;
if (ptS.z < ptE.z)
{
ptStaMidExten = ptS - dExtend * vtDirect;
ptEndMidExten = ptE - dExtend * vtDirect;
}
else
{
ptStaMidExten = ptS + dExtend * vtDirect;
ptEndMidExten = ptE + dExtend * vtDirect;
}
double dCentWidth = GetCentLineWidth();
tCurveEle.dWidth = dCentWidth;
tCurveEle.ptGe[0] = ptStaMidExten.orthoProject(planStd);
tCurveEle.ptGe[1] = ptEndMidExten.orthoProject(planStd);
tCurveEle.ptGe[2] = ptEndMidExten.orthoProject(planStd);
tCurveEle.idSubLay = idBaseLayer;
cplCurve.append(tCurveEle);
}
// Begin---Lixl---Modify---2011-11-22-----
// 修改说明: 内部的边线,在nOutOrIn=0时候绘制
// 修改原因: 内部的边线,在nOutOrIn=1时候绘制,遮挡不住椭圆边线的中间的弧线(原因不明)
// tCurveEle.idSubLay = idSideLayer;
// tCurveEle.dWidth = dEndWidth;
// if (ptS.z > ptE.z) // 被遮挡的不绘制
// {
// // 起始端半个椭圆
// int nRet = TAuxTools::GetEllipseFromCircle(ptEllStart, dWidth, vtDirect, vtZAxis,
// polyLineSta, vtDirect);
// if (nRet == 2)
// {
// GetArcPoint(polyLineSta, ptArcStaArr);
// int i(0);
// for (i = 0; i < ptArcStaArr.length(); i++)
// {
// if (i > 1 && i%2 == 0)
// {
// tCurveEle.ptGe[0] = ptArcStaArr[i-2];
// tCurveEle.ptGe[1] = ptArcStaArr[i-1];
// tCurveEle.ptGe[2] = ptArcStaArr[i];
//
// //BEGIN=======================================
// if (nEndDrawType == 0)
// {
// tCurveEle.idSubLay.setNull();
// tCurveEle.dWidth = dEdgeWidth;
// }
// else
// {
// tCurveEle.idSubLay = idSideLayer;
// tCurveEle.dWidth = dEndWidth;
// }
// //修改时间:2010-05-06
// //修改人 :王亚东
// //修改原因:支持倾斜风管在按风管壁和端线设置时,线宽与图层对应
// //END=========================================
//
// cplCurve.append(tCurveEle);
// }
// }
// }
// }
// else
// {
// // 末端半个椭圆
// int nRet = TAuxTools::GetEllipseFromCircle(ptEllEnd, dWidth, vtDirect, vtZAxis,
// polyLineEnd, -vtDirect);
// if (nRet == 2)
// {
// GetArcPoint(polyLineEnd, ptArcEndArr);
//
// int i(0);
// for (i = 0; i < ptArcEndArr.length(); i++)
// {
// if (i > 1 && i%2 == 0)
// {
// tCurveEle.ptGe[0] = ptArcEndArr[i-2];
// tCurveEle.ptGe[1] = ptArcEndArr[i-1];
// tCurveEle.ptGe[2] = ptArcEndArr[i];
//
// //BEGIN==========================================
// if (nEndDrawType == 0)
// {
// tCurveEle.idSubLay.setNull();
// tCurveEle.dWidth = dEdgeWidth;
// }
// else
// {
// tCurveEle.idSubLay = idSideLayer;
// tCurveEle.dWidth = dEndWidth;
// }
// //修改时间:2010-05-06
// //修改人 :王亚东
// //修改原因:支持倾斜风管在按风管壁和端线设置时,线宽与图层对应
// //END============================================
//
// cplCurve.append(tCurveEle);
// }
// }
// }
// }
// End---------------------------------------------------------------------
}
else if (nOutOrIn == 0) // 四边轮廓
{
// 两边
tCurveEle.dWidth = dEdgeWidth;
tCurveEle.idSubLay.setNull();
tCurveEle.ptGe[0] = ptArr[0];
tCurveEle.ptGe[1] = ptArr[1];
tCurveEle.ptGe[2] = ptArr[1];
cplCurve.append(tCurveEle);
tCurveEle.ptGe[0] = ptArr[2];
tCurveEle.ptGe[1] = ptArr[3];
tCurveEle.ptGe[2] = ptArr[3];
cplCurve.append(tCurveEle);
// 末端半个椭圆
//BEGIN=================================================
if (nEndDrawType == 0)
{
tCurveEle.idSubLay.setNull();
tCurveEle.dWidth = dEdgeWidth;
}
else
{
tCurveEle.idSubLay = idSideLayer;
tCurveEle.dWidth = dEndWidth;
}
//修改时间:2010-05-06
//修改人 :王亚东
//修改原因:支持倾斜风管在按风管壁和端线设置时,线宽与图层对应
//END===================================================
int i(0);
//tCurveEle.dWidth = dEndWidth;
AcDbPolyline polyLineEnd;
int nRet = TAuxTools::GetEllipseFromCircle(ptEllEnd, dWidth, vtDirect, vtZAxis,
polyLineEnd, vtDirect);
if (nRet == 2)
{
TAuxTools::GetArcPoint(polyLineEnd, ptArcEndArr);
// for (i = 0; i < ptArcEndArr.length(); i++)
// {
// if (i > 1 && i%2 == 0)
// {
// tCurveEle.ptGe[0] = ptArcEndArr[i-2];
// tCurveEle.ptGe[1] = ptArcEndArr[i-1];
// tCurveEle.ptGe[2] = ptArcEndArr[i];
// cplCurve.append(tCurveEle);
// }
// }
for (i = 0; i < ptArcEndArr.length()-1; i++)
{
tCurveEle.ptGe[0] = ptArcEndArr[i];
tCurveEle.ptGe[1] = ptArcEndArr[i+1];
tCurveEle.ptGe[2] = ptArcEndArr[i+1];
cplCurve.append(tCurveEle);
}
}
// 起始端半个椭圆
nRet = TAuxTools::GetEllipseFromCircle(ptEllStart, dWidth, -vtDirect, vtZAxis, polyLineSta, -vtDirect);
if (nRet == 2)
{
TAuxTools::GetArcPoint(polyLineSta, ptArcStaArr);
int i(0);
// for (i = 0; i < ptArcStaArr.length(); i++)
// {
// if (i > 1 && i%2 == 0)
// {
// tCurveEle.ptGe[0] = ptArcStaArr[i-2];
// tCurveEle.ptGe[1] = ptArcStaArr[i-1];
// tCurveEle.ptGe[2] = ptArcStaArr[i];
// cplCurve.append(tCurveEle);
// }
// }
for (i = 0; i < ptArcStaArr.length()-1; i++)
{
tCurveEle.ptGe[0] = ptArcStaArr[i];
tCurveEle.ptGe[1] = ptArcStaArr[i+1];
tCurveEle.ptGe[2] = ptArcStaArr[i+1];
cplCurve.append(tCurveEle);
}
}
// Begin---Lixl---Modify---2011-11-22-----
// 修改说明: 内部的边线,在nOutOrIn=0时候绘制
// 修改原因: 内部的边线,在nOutOrIn=1时候绘制,遮挡不住椭圆边线的中间的弧线(原因不明)
AcDbPolyline polyline1,polyLine2;
ptArcStaArr.setLogicalLength(0);
ptArcEndArr.setLogicalLength(0);
if (ptS.z > ptE.z) // 被遮挡的不绘制
{
// 起始端半个椭圆
int nRet = TAuxTools::GetEllipseFromCircle(ptEllStart, dWidth, vtDirect, vtZAxis, polyline1, vtDirect);
if (nRet == 2)
{
TAuxTools::GetArcPoint(polyline1, ptArcStaArr);
// for (int i = 0; i < ptArcStaArr.length(); i++)
// {
// if (i > 1 && i%2 == 0)
// {
// tCurveEle.ptGe[0] = ptArcStaArr[i-2];
// tCurveEle.ptGe[1] = ptArcStaArr[i-1];
// tCurveEle.ptGe[2] = ptArcStaArr[i];
// cplCurve.append(tCurveEle);
// }
// }
for (i = 0; i < ptArcStaArr.length()-1; i++)
{
tCurveEle.ptGe[0] = ptArcStaArr[i];
tCurveEle.ptGe[1] = ptArcStaArr[i+1];
tCurveEle.ptGe[2] = ptArcStaArr[i+1];
cplCurve.append(tCurveEle);
}
}
}
else
{
// 末端半个椭圆
int nRet = TAuxTools::GetEllipseFromCircle(ptEllEnd, dWidth, vtDirect, vtZAxis,
polyLine2, -vtDirect);
if (nRet == 2)
{
TAuxTools::GetArcPoint(polyLine2, ptArcEndArr);
// for (int i = 0; i < ptArcEndArr.length(); i++)
// {
// if (i > 1 && i%2 == 0)
// {
// tCurveEle.ptGe[0] = ptArcEndArr[i-2];
// tCurveEle.ptGe[1] = ptArcEndArr[i-1];
// tCurveEle.ptGe[2] = ptArcEndArr[i];
// cplCurve.append(tCurveEle);
// }
// }
for (i = 0; i < ptArcEndArr.length()-1; i++)
{
tCurveEle.ptGe[0] = ptArcEndArr[i];
tCurveEle.ptGe[1] = ptArcEndArr[i+1];
tCurveEle.ptGe[2] = ptArcEndArr[i+1];
cplCurve.append(tCurveEle);
}
}
}
// End--------------------------------------------------------------------------------
}
}
return TRUE;
}
// 倾斜软风管 change by hh 2011-07-15
BOOL THImpHvacDuct::MakeInclSoft2DCurves( TComplexCurve& cplCurve, int nOutOrIn ) const
{
if(NULL == m_pXDataMap)
return FALSE;
// 数据转换后 直接调用水平软风管的方法 后再恢复数据
TDbXDataMap dataMap;
BOOL bTrans = TransInclSoftDuct(dataMap);
BOOL bRes = MakeHorzSoft2DCurves(cplCurve, nOutOrIn);
if(bTrans)
m_pXDataMap->CopyFrom(&dataMap);
return bRes;
}
AcDbPolyline* THImpHvacDuct::MakeHorzPolyCurve() const
{
ASSERT(NULL != m_pXDataMap);
// 风管类型
HvacDuctType eDuctType = eStraight;
m_pXDataMap->GetAt(HDCT_Type, (int&)eDuctType);
switch (eDuctType)
{
case eStraight: // 直风管
return MakeHorzStraightPolyCurve();
case eSoft: // 软风管
return MakeHorzSoftPolyCurve();
default:
return NULL;
}
}
AcDbPolyline* THImpHvacDuct::MakeHorzStraightPolyCurve() const
{
ASSERT(NULL != m_pXDataMap);
AcGePoint3dArray ptArr; // 各线起始点
if (IsSingleLine())
GetSingleKeyPoints(ptArr);
else
GetFourKeyPoints(ptArr);
if (ptArr.length() != 4)
return FALSE;
double dEl(0.0);
AcGePlane plan = GetHidePlane(ptArr[0], ptArr[1], ptArr[2], normal(), dEl);
AcDbPolyline* pPolyLine = new AcDbPolyline;
pPolyLine->addVertexAt(0, ptArr[0].convert2d(plan));
pPolyLine->addVertexAt(1, ptArr[1].convert2d(plan));
pPolyLine->addVertexAt(2,ptArr[2].convert2d(plan));
pPolyLine->addVertexAt(3, ptArr[3].convert2d(plan));
pPolyLine->setNormal(plan.normal());
pPolyLine->setElevation(dEl);
pPolyLine->setClosed(Adesk::kTrue);
return pPolyLine;
}
AcDbPolyline* THImpHvacDuct::MakeHorzSoftPolyCurve() const
{
ASSERT(NULL != m_pXDataMap);
double dBulge(0), dPosiBulge(0);
m_pXDataMap->GetAt(HDCT_Bulge, dBulge);
dPosiBulge = fabs((dBulge));
if (dPosiBulge < 1e-6)
return MakeHorzStraightPolyCurve();
if (!IsCanDrawSoft())
return NULL;
AcGePoint3dArray ptArr;
if (IsSingleLine())
GetSingleKeyPoints(ptArr);
else
GetFourKeyPoints(ptArr);
if (ptArr.length() != 4)
return FALSE;
AcGePlane plan = GetStdPrjPlan(ptArr[0]);
AcDbPolyline* pPolyLine = new AcDbPolyline;
pPolyLine->addVertexAt(0, ptArr[0].convert2d(plan), dBulge);
pPolyLine->addVertexAt(1, ptArr[1].convert2d(plan));
pPolyLine->addVertexAt(2, ptArr[2].convert2d(plan), -dBulge);
pPolyLine->addVertexAt(3, ptArr[3].convert2d(plan));
pPolyLine->setNormal(plan.normal());
pPolyLine->setElevation(TAuxTools::GetPlaneEle(plan));
pPolyLine->setClosed(Adesk::kTrue);
return pPolyLine;
}
AcDbPolyline* THImpHvacDuct::MakeVertPolyCurve() const
{
ASSERT(NULL != m_pXDataMap);
if (IsSingleLine())
return NULL;
// 风管类型
HvacDuctType eDuctType = eStraight;
m_pXDataMap->GetAt(HDCT_Type, (int&)eDuctType);
switch (eDuctType)
{
case eStraight: // 直风管
return MakeVertStraightPolyCurve();
case eSoft: // 软风管
return MakeVertSoftPolyCurve();
default:
return NULL;
}
}
AcDbPolyline* THImpHvacDuct::MakeVertStraightPolyCurve() const
{
ASSERT(NULL != m_pXDataMap);
AcGePoint3d ptS = StartPoint();
AcGePoint3d ptE = EndPoint();
AcGeVector3d vtDirect = ptE.z > ptS.z ? (ptE - ptS) : (ptS - ptE);
if (vtDirect.length() < 1e-9)
vtDirect = TAuxTools::GetUcsZvt();
HvacSectType eSectType = eRectangular;
HvacDrawType eDrawType = eOldStyle;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType);
m_pXDataMap->GetAt(HVAC_DrawType, (int&)eDrawType);
AcGePoint3dArray ptArr;
GetFourKeyPoints(ptArr);
if (ptArr.length() != 4)
return NULL;
double dEl(0.0);
AcGePlane plan = GetHidePlane(ptArr[0], ptArr[1], ptArr[2], vtDirect, dEl);
if (eSectType == eRectangular)
{
AcDbPolyline* pPolyLineAround = new AcDbPolyline;
pPolyLineAround->addVertexAt(0, ptArr[0].convert2d(plan));
pPolyLineAround->addVertexAt(1, ptArr[1].convert2d(plan));
pPolyLineAround->addVertexAt(2, ptArr[2].convert2d(plan));
pPolyLineAround->addVertexAt(3, ptArr[3].convert2d(plan));
pPolyLineAround->setNormal(vtDirect);
pPolyLineAround->setElevation(dEl);
pPolyLineAround->setClosed(Adesk::kTrue);
return pPolyLineAround;
}
else if (eSectType == eCircular)
{
AcDbPolyline* pPolyCir = new AcDbPolyline;
pPolyCir->addVertexAt(0, ptArr[0].convert2d(plan), 1);
pPolyCir->addVertexAt(1, ptArr[2].convert2d(plan), 1);
pPolyCir->setNormal(vtDirect);
pPolyCir->setElevation(dEl);
pPolyCir->setClosed(Adesk::kTrue);
return pPolyCir;
}
return NULL;
}
AcDbPolyline* THImpHvacDuct::MakeVertSoftPolyCurve() const
{
ASSERT(NULL != m_pXDataMap);
AcGePoint3dArray ptArr;
GetFourKeyPoints(ptArr);
if (ptArr.length() != 4)
return NULL;
AcGePoint3d ptStart(StartPoint()), ptEnd(EndPoint());
AcGePoint3d ptCenter = GetCirCenter();
AcGePoint3d ptStd = TAuxTools::Mid(ptArr[0], ptArr[2]);
AcGeVector3d vtStdToCenter = ptStd - ptCenter;
AcGeVector3d vtStd = vtStdToCenter.crossProduct(normal());
AcGePlane plan = GetStdPrjPlan(ptStd);
HvacSectType eSectType = eRectangular;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType);
if (eSectType == eRectangular)
{
AcDbPolyline* pPolyLine = new AcDbPolyline;
pPolyLine->addVertexAt(0, ptArr[0].convert2d(plan));
pPolyLine->addVertexAt(1, ptArr[1].convert2d(plan));
pPolyLine->addVertexAt(2, ptArr[2].convert2d(plan));
pPolyLine->addVertexAt(3, ptArr[3].convert2d(plan));
pPolyLine->setNormal(plan.normal());
pPolyLine->setElevation(TAuxTools::GetPlaneEle(plan));
pPolyLine->setClosed(Adesk::kTrue);
return pPolyLine;
}
else if (eSectType == eCircular)
{
AcDbPolyline pPolyLine;
double dDia(0.0);
m_pXDataMap->GetAt(HDCT_Diameter, dDia);
AcGePoint3d ptCenter = GetCirCenter();
AcGeVector3d vtStdToCenter = ptStd - ptCenter;
AcGeVector3d vtNormal = normal();
AcGeVector3d vtStd = vtStdToCenter.crossProduct(vtNormal);
TAuxTools::GetEllipseFromCircle(ptStd, dDia, vtStd, TAuxTools::GetUcsZvt(), pPolyLine);
AcDbPolyline* pNewPolyLine = (AcDbPolyline*)pPolyLine.clone();
return pNewPolyLine;
}
return NULL;
}
AcDbPolyline* THImpHvacDuct::MakeInclPolyCurve() const
{
ASSERT(NULL != m_pXDataMap);
// 风管类型
HvacDuctType eDuctType = eStraight;
m_pXDataMap->GetAt(HDCT_Type, (int&)eDuctType);
switch (eDuctType)
{
case eStraight: // 直风管
return MakeInclStraightPolyCurve();
case eSoft: // 软风管
return MakeInclSoftPolyCurve();
default:
return NULL;
}
}
AcDbPolyline* THImpHvacDuct::MakeInclStraightPolyCurve() const
{
ASSERT(NULL != m_pXDataMap);
AcGePoint3d ptS = StartPoint();
AcGePoint3d ptE = EndPoint();
AcGePoint3dArray ptArr; // 中心面四个点
double dWidth(0.0), dThick(0.0);
m_pXDataMap->GetAt(HDCT_Width, dWidth);
m_pXDataMap->GetAt(HDCT_Thick, dThick);
if (IsSingleLine())
{
GetSingleKeyPoints(ptArr);
GetGlobalContext()->GetAt(KEY_HIDEWIDTH, dWidth);
}
else
GetFourKeyPoints(ptArr);
HvacSectType eSectType = eRectangular;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType);
if (eSectType == eCircular)
dThick = dWidth;
//BEGIN=============================================
int nLength = ptArr.length();
//END===============================================
AcGePlane plan = GetStdPrjPlan(ptArr[0]);
AcGeVector3d vtDirect = ptE - ptS;
AcGeVector3d vtNormal = normal();
AcGeVector3d vtUseZAix(TAuxTools::GetUcsZvt());
double dExtend(0); // direct方向上延长或缩短的距离
AcGePlane planHor(ptS, vtUseZAix);
AcGePoint3d ptPrj = ptE.orthoProject(planHor);
double dPerCen = ptE.distanceTo(ptPrj) / ptS.distanceTo(ptE);
dExtend = dThick * 0.5 * dPerCen;
AcDbPolyline* pPolyLine = NULL;
if (eSectType == eRectangular)
{
vtDirect = vtDirect.orthoProject(plan.normal());
vtDirect.normalize();
ptArr[0] -= dExtend * vtDirect;
ptArr[1] += dExtend * vtDirect;
ptArr[2] += dExtend * vtDirect;
ptArr[3] -= dExtend * vtDirect;
pPolyLine = new AcDbPolyline;
pPolyLine->addVertexAt(0, ptArr[0].convert2d(plan));
pPolyLine->addVertexAt(1, ptArr[1].convert2d(plan));
pPolyLine->addVertexAt(2, ptArr[2].convert2d(plan));
pPolyLine->addVertexAt(3, ptArr[3].convert2d(plan));
pPolyLine->setNormal(plan.normal());
pPolyLine->setElevation(TAuxTools::GetPlaneEle(plan));
pPolyLine->setClosed(Adesk::kTrue);
}
else if (eSectType == eCircular)
{
AcDbPolyline polyLineStart, polyLineEnd;
TAuxTools::GetEllipseFromCircle(ptS, dWidth, -vtDirect, vtUseZAix, polyLineStart,-vtDirect);
TAuxTools::GetEllipseFromCircle(ptE, dWidth, vtDirect, vtUseZAix, polyLineEnd, vtDirect);
pPolyLine = new AcDbPolyline;
AcGePoint3d ptNow;
double dBulge(0.0);
for (int i = 0; i < (int)polyLineEnd.numVerts(); i++)
{
polyLineEnd.getBulgeAt(i, dBulge);
polyLineEnd.getPointAt(i, ptNow);
pPolyLine->addVertexAt(i, ptNow.convert2d(plan), dBulge);
}
int nNowMax = i;
int nStartNum = polyLineStart.numVerts();
for (i = nStartNum - 1; i > -1; i--)
{
polyLineStart.getBulgeAt(nStartNum - 1 - i, dBulge);
polyLineStart.getPointAt(i, ptNow);
pPolyLine->addVertexAt(nStartNum - 1 - i + nNowMax , ptNow.convert2d(plan), -dBulge);
}
// Begin---Lixl---Modify---2011-11-22--调整PolyCurve,画出内部椭圆线
polyLineEnd.getPointAt(0, ptNow);
pPolyLine->addVertexAt(pPolyLine->numVerts(), ptNow.convert2d(plan));
AcDbPolyline pLine;
if (ptS.z > ptE.z)
{
polyLineStart.getPointAt(0, ptNow);
pPolyLine->addVertexAt(pPolyLine->numVerts(), ptNow.convert2d(plan));
TAuxTools::GetEllipseFromCircle(ptS, dWidth, vtDirect, vtUseZAix, pLine, vtDirect);
TAuxTools::MergerPline(pPolyLine, &pLine);
}
else
{
TAuxTools::GetEllipseFromCircle(ptE, dWidth, vtDirect, vtUseZAix, pLine, -vtDirect);
TAuxTools::MergerPline(pPolyLine, &pLine);
}
// pPolyLine->setClosed(Adesk::kTrue);
// End---------------------------------------------------------------------
pPolyLine->setElevation(TAuxTools::GetPlaneEle(plan));
pPolyLine->setNormal(plan.normal());
}
return pPolyLine;
}
// 倾斜软风管 change by hh 2011-07-15
AcDbPolyline* THImpHvacDuct::MakeInclSoftPolyCurve() const
{
if(NULL == m_pXDataMap)
return NULL;
// 数据转换后 直接调用水平软风管的方法 后再恢复数据
TDbXDataMap dataMap;
BOOL bTrans = TransInclSoftDuct(dataMap);
AcDbPolyline* pPolyLine = MakeHorzSoftPolyCurve();
if(bTrans)
m_pXDataMap->CopyFrom(&dataMap);
return pPolyLine;
}
BOOL THImpHvacDuct::MakeHorzPolyCurveFaces(AcDbVoidPtrArray& arFaces) const
{
ASSERT(NULL != m_pXDataMap);
// 风管类型
HvacDuctType eDuctType = eStraight;
m_pXDataMap->GetAt(HDCT_Type, (int&)eDuctType);
switch (eDuctType)
{
case eStraight: // 直风管
return MakeHorzStraightPolyCurveFaces(arFaces);
case eSoft: // 软风管
return MakeHorzSoftPolyCurveFaces(arFaces);
default:
return NULL;
}
}
BOOL THImpHvacDuct::MakeHorzStraightPolyCurveFaces(AcDbVoidPtrArray& arFaces) const
{
ASSERT(NULL != m_pXDataMap);
AcGePoint3dArray ptArr; // 各线起始点
if (IsSingleLine())
GetSingleKeyPoints(ptArr); // 单线模式,按遮挡宽度要求返回宽度
else
GetFourKeyPoints(ptArr);
if (ptArr.length() != 4)
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[3]);
arFaces.append(pFace);
return arFaces.length() > 0;
}
BOOL THImpHvacDuct::MakeHorzSoftPolyCurveFaces(AcDbVoidPtrArray& arFaces) const
{
ASSERT(NULL != m_pXDataMap);
if (!IsCanDrawSoft())
return FALSE;
double dMinAngle(TAuxTools::GetMinDiffAngle());
double dBulge(0), dPosiBulge(0);
m_pXDataMap->GetAt(HDCT_Bulge, dBulge);
dPosiBulge = fabs(dBulge);
double dSignAngle = atan(dBulge) * 4;
double dAngle = fabs(dSignAngle);
int nPartNum = int(dAngle / dMinAngle) + 1;
dMinAngle = dSignAngle / nPartNum; // 实际间隔角度
AcGePoint3dArray ptUpArr, ptDownArr;
AcGePoint3d ptUpNow, ptDownNow;
AcGePoint3dArray ptArr;
if (IsSingleLine())
GetSingleKeyPoints(ptArr);
else
GetFourKeyPoints(ptArr);
if (ptArr.length() != 4)
return FALSE;
ptUpNow = ptArr[3];
ptDownNow = ptArr[0];
AcGePlane planStd = GetStdPrjPlan(ptUpNow);
AcGePoint3d ptCenter = GetCirCenter();
AcGeVector3d vtRotAix = TAuxTools::GetUcsZvt();
int i(0);
for (i = 0; i < nPartNum + 1; i++)
{
ptUpArr.append(ptUpNow);
ptDownArr.append(ptDownNow);
ptUpNow.rotateBy(dMinAngle, vtRotAix, ptCenter);
ptDownNow.rotateBy(dMinAngle, vtRotAix, ptCenter);
if (i > 0)
{
AcDbFace* pFace = new AcDbFace;
pFace->setVertexAt(0, ptDownArr.at(i));
pFace->setVertexAt(1, ptUpArr.at(i));
pFace->setVertexAt(2, ptUpArr.at(i-1));
pFace->setVertexAt(3, ptDownArr.at(i-1));
arFaces.append(pFace);
}
}
return arFaces.length() > 0;
}
BOOL THImpHvacDuct::MakeVertPolyCurveFaces(AcDbVoidPtrArray& arFaces) const
{
ASSERT(NULL != m_pXDataMap);
if (IsSingleLine())
return FALSE;
// 风管类型
HvacDuctType eDuctType = eStraight;
m_pXDataMap->GetAt(HDCT_Type, (int&)eDuctType);
switch (eDuctType)
{
case eStraight: // 直风管
return MakeVertStraightPolyCurveFaces(arFaces);
case eSoft: // 软风管
return MakeVertSoftPolyCurveFaces(arFaces);
default:
return NULL;
}
}
BOOL THImpHvacDuct::MakeVertStraightPolyCurveFaces(AcDbVoidPtrArray& arFaces) const
{
ASSERT(NULL != m_pXDataMap);
if (IsSingleLine())
return FALSE;
HvacSectType eSectType = eRectangular;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType);
if (eSectType == eRectangular)
{
AcGePoint3dArray ptArr;
GetFourKeyPoints(ptArr);
if (ptArr.length() != 4)
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[3]);
arFaces.append(pFace);
}
else if (eSectType == eCircular)
{
AcGePoint3d ptS = StartPoint();
AcGePoint3d ptE = EndPoint();
AcGeVector3d vtDirect = ptE - ptS;
AcGePoint3d ptCenter = ptE.z > ptS.z ? ptE:ptS;
AcGeVector3d vtNormal = normal();
AcGeVector3d vtSide = vtNormal;
vtSide.rotateBy(PI * 0.5, vtDirect);
double dRadius(0.0);
m_pXDataMap->GetAt(HDCT_Diameter, dRadius);
dRadius /= 2;
double dMinAngle(TAuxTools::GetMinDiffAngle());
int nPartNum = int(PI * 2 / dMinAngle) + 1;
dMinAngle = PI * 2 / nPartNum;
AcGePoint3d ptEvery = ptCenter + dRadius * vtSide;
AcGePoint3dArray ptArr;
int i(0);
for (i = 0; i < nPartNum + 1; i++)
{
ptArr.append(ptEvery);
ptEvery.rotateBy(dMinAngle, vtDirect, ptCenter);
if (i > 0)
{
AcDbFace* pFace = new AcDbFace;
pFace->setVertexAt(0, ptCenter);
pFace->setVertexAt(1, ptArr.at(i));
pFace->setVertexAt(2, ptArr.at(i-1));
pFace->setVertexAt(3, ptCenter);
arFaces.append(pFace);
}
}
}
return arFaces.length() > 0;
}
BOOL THImpHvacDuct::MakeVertSoftPolyCurveFaces(AcDbVoidPtrArray& arFaces) const
{
ASSERT(NULL != m_pXDataMap);
HvacSectType eSectType = eRectangular;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType);
if (eSectType == eRectangular)
{
AcGePoint3dArray ptArr;
GetFourKeyPoints(ptArr);
if (ptArr.length() != 4)
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[3]);
arFaces.append(pFace);
}
else if (eSectType == eCircular)
{
AcGePoint3d ptS = StartPoint();
AcGePoint3d ptE = EndPoint();
AcGePoint3d ptStd = ptE.z > ptS.z ? ptE:ptS; // 上面起起遮挡作用的端点
AcGeVector3d vtNormal = normal();
AcGePlane planStd = GetStdPrjPlan(ptStd);
double dRadius(0.0);
m_pXDataMap->GetAt(HDCT_Diameter, dRadius);
dRadius /= 2;
double dMinAngle(TAuxTools::GetMinDiffAngle());
int nPartNum = int(PI * 2 / dMinAngle) + 1;
dMinAngle = PI * 2 / nPartNum;
// 得到高端界面垂直的法向
AcGePoint3d ptCenter = GetCirCenter();
AcGeVector3d vtStdToCenter = ptStd - ptCenter;
AcGeVector3d vtHighPer = vtStdToCenter.crossProduct(vtNormal);
vtHighPer.normalize();
AcGePoint3dArray ptArr;
AcGeVector3d vtEvery = vtNormal;
AcGePoint3d ptEvery;
int i(0);
for (i = 0; i < nPartNum + 1; i++)
{
ptEvery = ptStd + dRadius * vtEvery;
ptArr.append(ptEvery);
vtEvery.rotateBy(dMinAngle, vtHighPer);
if (i > 0)
{
AcDbFace* pFace = new AcDbFace;
pFace->setVertexAt(0, ptStd);
pFace->setVertexAt(1, ptArr[i].orthoProject(planStd));
pFace->setVertexAt(2, ptArr[i-1].orthoProject(planStd));
pFace->setVertexAt(3, ptStd);
arFaces.append(pFace);
}
}
}
return arFaces.length() > 0;
}
BOOL THImpHvacDuct::MakeInclPolyCurveFaces(AcDbVoidPtrArray& arFaces) const
{
ASSERT(NULL != m_pXDataMap);
// 风管类型
HvacDuctType eDuctType = eStraight;
m_pXDataMap->GetAt(HDCT_Type, (int&)eDuctType);
switch (eDuctType)
{
case eStraight: // 直风管
return MakeInclStraightPolyCurveFaces(arFaces);
case eSoft: // 软风管
return MakeInclSoftPolyCurveFaces(arFaces);
default:
return NULL;
}
}
BOOL THImpHvacDuct::MakeInclStraightPolyCurveFaces(AcDbVoidPtrArray& arFaces) const
{
ASSERT(NULL != m_pXDataMap);
AcGePoint3d ptS = StartPoint();
AcGePoint3d ptE = EndPoint();
double dWidth(0.0), dThick(0.0);
m_pXDataMap->GetAt(HDCT_Width, dWidth);
m_pXDataMap->GetAt(HDCT_Thick, dThick);
AcGePoint3dArray ptArr; // 各线起始点
if (IsSingleLine())
{
GetSingleKeyPoints(ptArr);
m_pXDataMap->GetAt(KEY_HIDEWIDTH, dWidth);
}
else
GetFourKeyPoints(ptArr);
if (ptArr.length() != 4)
return FALSE;
AcGePlane planStd = GetStdPrjPlan(ptArr[0]);
AcGeVector3d vtNormal = normal();
AcGeVector3d vtDirect = (ptE - ptS).orthoProject(planStd.normal());
vtDirect.normalize();
AcGeVector3d vtLeve = vtNormal;
vtLeve.rotateBy(PI * 0.5, vtDirect);
HvacSectType eSectType = eRectangular;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType);
if (eSectType == eCircular)
dThick = dWidth;
double dExtend(0); // direct方向上延长或缩短的距离
AcGePlane planHor(ptS, TAuxTools::GetUcsZvt());
AcGePoint3d ptPrj = ptE.orthoProject(planHor);
double dPerCen = ptE.distanceTo(ptPrj) / ptS.distanceTo(ptE);
dExtend = dThick * 0.5 * dPerCen;
if (eSectType == eRectangular)
{
ptArr[0] -= dExtend * vtDirect;
ptArr[1] += dExtend * vtDirect;
ptArr[2] += dExtend * vtDirect;
ptArr[3] -= dExtend * vtDirect;
AcDbFace* pFace = new AcDbFace;
pFace->setVertexAt(0, ptArr[0]);
pFace->setVertexAt(1, ptArr[1]);
pFace->setVertexAt(2, ptArr[2]);
pFace->setVertexAt(3, ptArr[3]);
arFaces.append(pFace);
}
else if (eSectType == eCircular)
{
dExtend = dWidth * 0.5 * dPerCen;
// 中间矩形面
AcDbFace* pFace = new AcDbFace;
pFace->setVertexAt(0, ptArr[0]);
pFace->setVertexAt(1, ptArr[1]);
pFace->setVertexAt(2, ptArr[2]);
pFace->setVertexAt(3, ptArr[3]);
arFaces.append(pFace);
// 两端半圆
double dMinAngle(TAuxTools::GetMinDiffAngle());
// 修改内容: 倾斜圆风管消隐面由原来的半圆改为稍微精确的椭圆Lixlmodify
// dMinAngle *= 0.5;
int nPartNum = int(PI / dMinAngle) + 1;
dMinAngle = PI / nPartNum;
// ptS = ptS.orthoProject(planStd);
// ptE = ptE.orthoProject(planStd);
AcGeVector3d vtStaEvery = vtLeve;
AcGeVector3d vtEndEvery = vtLeve;
AcGePoint3dArray ptArrSta, ptArrEnd;
AcGePoint3d ptStaNow = ptArr[0];
AcGePoint3d ptEndNow = ptArr[1];
vtDirect = ptE - ptS;
vtDirect.normalize();
// vtStaEvery = vtNormal;
// vtStaEvery.rotateBy(PI * 0.5, vtDirect);
// vtStaEvery.normalize();
// vtEndEvery = vtNormal;
// vtEndEvery.rotateBy(PI * 0.5, vtDirect);
// vtEndEvery.normalize();
// ptStaNow = ptS + vtStaEvery * dWidth * 0.5;
// ptEndNow = ptE + vtEndEvery * dWidth * 0.5;
// Lixl modifyfor修正风管消隐面
AcGeVector3d vtZAxis(TAuxTools::GetUcsZvt());
vtStaEvery = vtDirect.crossProduct(vtZAxis);
ptStaNow = ptS + vtStaEvery.normalize() * dWidth * 0.5;
ptEndNow = ptE + vtStaEvery * dWidth * 0.5;
int i(0);
for (i = 0; i < nPartNum + 1; i++)
{
ptArrSta.append(ptStaNow.orthoProject(planStd));
ptArrEnd.append(ptEndNow.orthoProject(planStd));
// ptStaNow.rotateBy(-dMinAngle, vtNormal, ptS);
// ptEndNow.rotateBy(dMinAngle, vtNormal, ptE);
if (ptS.z > ptE.z)
{
ptStaNow.rotateBy(-dMinAngle, -vtDirect, ptS);
ptEndNow.rotateBy(dMinAngle, -vtDirect, ptE);
}
else
{
ptStaNow.rotateBy(-dMinAngle, vtDirect, ptS);
ptEndNow.rotateBy(dMinAngle, vtDirect, ptE);
}
if (i > 0)
{
AcDbFace* pStaFace = new AcDbFace;
pStaFace->setVertexAt(0, ptS.orthoProject(planStd));
pStaFace->setVertexAt(1, ptArrSta[i]);
pStaFace->setVertexAt(2, ptArrSta[i-1]);
pStaFace->setVertexAt(3, ptS.orthoProject(planStd));
arFaces.append(pStaFace);
AcDbFace* pEndFace = new AcDbFace;
pEndFace->setVertexAt(0, ptE.orthoProject(planStd));
pEndFace->setVertexAt(1, ptArrEnd[i]);
pEndFace->setVertexAt(2, ptArrEnd[i-1]);
pEndFace->setVertexAt(3, ptE.orthoProject(planStd));
arFaces.append(pEndFace);
}
}
}
return arFaces.length() > 0;
}
// 倾斜软风管 change by hh 2011-07-15
BOOL THImpHvacDuct::MakeInclSoftPolyCurveFaces(AcDbVoidPtrArray& arFaces) const
{
if(NULL == m_pXDataMap)
return FALSE;
// 数据转换后 直接调用水平软风管的方法 后再恢复数据
TDbXDataMap dataMap;
BOOL bTrans = TransInclSoftDuct(dataMap);
BOOL bRes = MakeHorzSoftPolyCurveFaces(arFaces);
if(bTrans)
m_pXDataMap->CopyFrom(&dataMap);
return bRes;
}
Acad::ErrorStatus THImpHvacDuct::transformBy(const AcGeMatrix3d& xform)
{
if (NULL == m_pXDataMap)
return Acad::eNotImplementedYet;
// 获得点
AcGePoint3d ptStart = StartPoint();
AcGePoint3d ptEnd = EndPoint();
AcGeVector3d vtNormal = normal();
// add by hh 2013-9-17 处理弧形管在镜像时曲率错误的问题
AcGePoint3d ptArc;
double dBulge = 0;
m_pXDataMap->GetAt(HDCT_Bulge, dBulge);
HvacDuctType eType = eSoft;
m_pXDataMap->GetAt(HDCT_Type, (int&)eType);
if(eType == eSoft && !EQUAL_ZERO(dBulge))
{
// 计算圆弧的中点
AcGeVector3d vtDir = ptEnd - ptStart;
vtDir.normalize();
AcGeVector3d vtLevel = (ptEnd - ptStart) * 0.5;
vtLevel.rotateBy(-PI * 0.5, TAuxTools::GetUcsZvt());
vtLevel *= dBulge;
AcGePoint3d ptMid = ptStart + ptStart.distanceTo(ptEnd) * 0.5 * vtDir;
ptArc = ptMid + vtLevel;
// 变换位置
ptArc.transformBy(xform);
ptStart.transformBy(xform);
ptEnd.transformBy(xform);
// 变换向量
vtNormal = vtNormal.transformBy(xform).normalize();
// 重新计算曲率
dBulge = TAuxTools::CalCurvature(ptStart, ptArc, ptEnd, &vtNormal);
m_pXDataMap->SetAt(HDCT_Bulge, dBulge);
}
else
{
// 变换位置
ptStart.transformBy(xform);
ptEnd.transformBy(xform);
// 变换向量
vtNormal = vtNormal.transformBy(xform).normalize();
}
// 更新点
SetStartPoint(ptStart);
SetEndPoint(ptEnd);
setNormal(vtNormal);
// 设置尺寸
double dScale = xform.scale();
double dWidth(0.0), dHeigh(0.0);
m_pXDataMap->GetAt(HDCT_Width, dWidth);
m_pXDataMap->GetAt(HDCT_Thick, dHeigh);
dWidth *= dScale;
dHeigh *= dScale;
m_pXDataMap->SetAt(HDCT_Width, dWidth);
m_pXDataMap->SetAt(HDCT_Thick, dHeigh);
if (m_pOwnerEnt != NULL && m_pOwnerEnt->objectId().isValid())
{
// 传递消息
AcGeVector3d vtDirect = ptEnd - ptStart;
AcGeVector3d vtOff = xform.translation();
// 如果实体不是在当前模型空间中,不做写消息,更新接口处理
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.SetGripPosition(TDb::eMid);
iMsg.SetMsgOperateOn(m_pOwnerEnt->objectId());
// 写入接口更改消息
TDbInterfaceMsgWrite msgWrite;
msgWrite.WriteInterfaceMsg(iMsg);
//更新接口记录接口信息
UpdateInterfaceRec(m_pOwnerEnt->objectId(), xform);
}
}
return Acad::eOk;
}
Position THImpHvacDuct::ExplainGripIndex(int nIndex) const
{
Position ePos = eStart;
if (IsVertAlignment())
{
HvacSectType eSectType = eRectangular;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType);
if (eSectType == eRectangular)
{
switch(nIndex)
{
case 0:
ePos = eMid;
break;
case 1:
ePos = eSizeMid0;
break;
case 2:
ePos = eSizeMid1;
break;
case 3:
ePos = eSizeMid2;
break;
case 4:
ePos = eSizeMid3;
break;
case 5:
ePos = eCommand0;
break;
default:
break;
}
}
else if (eSectType == eCircular)
{
switch(nIndex)
{
case 0:
ePos = eMid;
break;
case 1:
ePos = eSizeMid0;
break;
case 2:
ePos = eCommand0;
break;
default:
break;
}
}
}
else
{
HvacDuctType eType = eStraight;
m_pXDataMap->GetAt(HDCT_Type, (int&)eType);
switch(nIndex)
{
case 0:
ePos = eStart;
break;
case 1:
ePos = eEnd;
break;
case 2:
ePos = eMid;
break;
// case 3:
// ePos = eDim0;
// break;
case 3:
ePos = eSizeMid0;
break;
case 4:
ePos = eSizeMid1;
break;
case 5:
ePos = eCommand0;
break;
case 6:
ePos = eCommand1;
break;
case 7:
if (eStraight == eType)
ePos = eCommand2;
else if (eSoft == eType)
ePos = eAdjust0;
break;
case 8:
case 9:
case 10:
case 11:
ePos = eMid;
break;
default:
break;
}
}
return ePos;
}
Acad::ErrorStatus THImpHvacDuct::getStretchPoints( AcGePoint3dArray& stretchPoints ) const
{
stretchPoints.append(StartPoint());
stretchPoints.append(EndPoint());
return Acad::eOk;
}
Acad::ErrorStatus THImpHvacDuct::getGripPoints(AcGePoint3dArray& gripPoints,
AcDbIntArray& osnapModes, AcDbIntArray& geomIds) const
{
if (NULL == m_pXDataMap)
return Acad::eOk;
// 获得始末点和重点
AcGePoint3d ptStart = StartPoint();
AcGePoint3d ptEnd = EndPoint();
AcGePoint3d ptMid = TAuxTools::Mid(ptStart, ptEnd);
// 获得方向向量
AcGeVector3d vtDirect = (ptMid - ptStart);
// 方向向量单位化
vtDirect.normalize();
// 获得垂直向量
AcGeVector3d vtNormal = normal();
AcGeVector3d vtPerp = vtNormal.crossProduct(vtDirect);
// 初始化参数默认值
HvacDuctType eDuctType = eStraight;
HvacSectType eSectType = eRectangular;
double dSizeMain = 0.0;
// 获取参数
m_pXDataMap->GetAt(HDCT_Type, (int&)eDuctType);
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType);
m_pXDataMap->GetAt(HDCT_Width, dSizeMain);
// 获得软风管的曲率
double dBulge = 0.0;
m_pXDataMap->GetAt(HDCT_Bulge, dBulge);
// double dCmdOff = ::PixelToWcs(10); // 取得10个像素点在世界坐标系下的长度,距两端距离
AcGeVector3d vtCmd(vtNormal); // 命令点与中心点法向
vtCmd.rotateBy(-PI*0.25, vtDirect);
vtCmd *= g_dCmdOff;
AcGePoint3d ptCommand = ptMid + vtCmd; // 命令点
if (IsVertAlignment())
{
if (eDuctType == eSoft)
{
double dAngle = atan(dBulge) * 4;
vtDirect.rotateBy(dAngle * 0.5, vtNormal); // 得到末端界面垂直的法向
}
AcGeVector3d vtSide = vtNormal;
vtSide.rotateBy(PI * 0.5, vtDirect);
if (eSectType == eRectangular)
{
double dThick = 0.0;
m_pXDataMap->GetAt(HDCT_Thick, dThick);
AcGePoint3d ptUp, ptDown, ptLeft, ptRight; // 四个尺寸点
ptUp = ptMid + dThick * 0.5 * vtNormal;
ptDown = ptUp - dThick * vtNormal;
ptLeft = ptMid + dSizeMain * 0.5 * vtSide;
ptRight = ptLeft - dSizeMain * vtSide;
gripPoints.append(ptMid);
gripPoints.append(ptUp);
gripPoints.append(ptDown);
gripPoints.append(ptLeft);
gripPoints.append(ptRight);
gripPoints.append(ptCommand);
}
if (eSectType == eCircular)
{
double dRadius(0.0);
m_pXDataMap->GetAt(HDCT_Diameter, dRadius);
dRadius /= 2;
AcGePoint3d ptUp;
ptUp = ptMid + dRadius * vtNormal;
AcGePoint3d ptRight = GetAVertCirSizePt();
gripPoints.append(ptMid);
gripPoints.append(ptRight);
gripPoints.append(ptCommand);
}
}
else
{
AcGePoint3d ptCmdSta = ptStart - g_dCmdOff * vtDirect;
AcGePoint3d ptCmdEnd = ptEnd + g_dCmdOff * vtDirect;
AcGePoint3d ptCenter = GetCirCenter();
// 软风管时调整中点位置
if (eSoft == eDuctType && (fabs(dBulge) > 1e-6))
{
// 调整中心点
double dHight = ptStart.distanceTo(ptEnd) * 0.5 * dBulge;
ptMid -= (vtPerp * dHight);
// 命令点调整
AcGeVector3d vtSta = ptStart - ptCenter;
AcGeVector3d vtEnd = ptEnd - ptCenter;
AcGeVector3d vtPerSta = vtNormal.crossProduct(vtSta);
AcGeVector3d vtPerEnd = vtNormal.crossProduct(vtEnd);
vtPerSta.normalize();
vtPerEnd.normalize();
if (dBulge < 0)
{
vtPerSta *= -1;
vtPerEnd *= -1;
}
ptCmdSta = ptStart - g_dCmdOff * vtPerSta;
ptCmdEnd = ptEnd + g_dCmdOff * vtPerEnd;
}
// // 获得默认标注点
// AcGePoint3d ptDimPos;
// m_pXDataMap->GetAt(HVAC_DimBasePos, ptDimPos);
// if (ptDimPos == AcGePoint3d::kOrigin)
// {
// ReSetDimPoint();
// m_pXDataMap->GetAt(HVAC_DimBasePos, ptDimPos);
// }
// 计算尺寸点到中点的距离值
double dSizeEdge = dSizeMain * 0.5;
// 添加夹点
// 始末点
gripPoints.append(ptStart);
gripPoints.append(ptEnd);
// 中点
gripPoints.append(ptMid);
// 标注点
// gripPoints.append(ptDimPos);
// 尺寸点
gripPoints.append(ptMid + vtPerp * dSizeEdge);
gripPoints.append(ptMid - vtPerp * dSizeEdge);
// 增加三个命令夹点
gripPoints.append(ptCmdSta);
gripPoints.append(ptCmdEnd);
// 软风管没有中间命令点
if (eSoft == eDuctType)
{
gripPoints.append(GetAdjustPt());
// 辅助定位点,效果等同于中点
AcGePoint3d ptCenter = GetCirCenter();
AcGeVector3d vtCentToStart = (ptStart - ptCenter).normalize();
AcGeVector3d vtCentToEnd = (ptEnd - ptCenter).normalize();
gripPoints.append(ptStart + vtCentToStart * dSizeEdge);
gripPoints.append(ptStart - vtCentToStart * dSizeEdge);
gripPoints.append(ptEnd + vtCentToEnd * dSizeEdge);
gripPoints.append(ptEnd - vtCentToEnd * dSizeEdge);
}
else
{
gripPoints.append(ptMid + vtPerp * (dSizeEdge + g_dCmdOff));
// 辅助定位点,效果等同于中点
gripPoints.append(ptStart + vtPerp * dSizeEdge);
gripPoints.append(ptStart - vtPerp * dSizeEdge);
gripPoints.append(ptEnd + vtPerp * dSizeEdge);
gripPoints.append(ptEnd - vtPerp * dSizeEdge);
}
}
return Acad::eOk;
}
Acad::ErrorStatus THImpHvacDuct::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;
HvacDuctType eType = eStraight;
m_pXDataMap->GetAt(HDCT_Type, (int&)eType);
if (eType == eStraight)
{
AcDbLine line(StartPoint(),EndPoint());
line.getOsnapPoints(osnapMode,gsSelectionMark,pickPoint,lastPoint,viewXform,
snapPoints,geomIds);
}
else if (eType == eSoft)
{
AcDbArc arc;
if (InitArc(arc))
arc.getOsnapPoints(osnapMode, gsSelectionMark, pickPoint, lastPoint, viewXform,
snapPoints, geomIds);
else
return Acad::eNotImplementedYet;
}
// 外壁捕捉
AcDbPolyline* pPolyLine = MakePolyCurve();
if (NULL == pPolyLine)
return Acad::eOk;
AcDbVoidPtrArray arrPolyLine;
arrPolyLine.append(pPolyLine);
// 矩形管,三维视图,增加上下边捕捉,便于选中
struct resbuf rb = {NULL, RT3DPOINT, 0};
acedGetVar(_T("VIEWDIR"), &rb);
AcGeVector3d vtDir = asVec3d(rb.resval.rpoint);
if (!vtDir.isCodirectionalTo(TAuxTools::GetUcsZvt()))
{
HvacSectType eSect = TDb::eRectangular;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSect);
if (TDb::eRectangular == eSect)
{
double dHeigh(0.0);
m_pXDataMap->GetAt(HDCT_Thick, dHeigh);
dHeigh *= 0.5;
AcGeVector3d vtOff = normal();
vtOff *= dHeigh;
AcDbPolyline* pUpLine = (AcDbPolyline*)pPolyLine->clone();
if (NULL != pUpLine)
{
pUpLine->transformBy(vtOff);
arrPolyLine.append(pUpLine);
}
AcDbPolyline* pDwLine = (AcDbPolyline*)pPolyLine->clone();
if (NULL != pDwLine)
{
pDwLine->transformBy(-vtOff);
arrPolyLine.append(pDwLine);
}
}
}
int i(0);
for (i = 0; i < arrPolyLine.length(); i++)
{
AcDbEntity* pEnt = (AcDbEntity*)arrPolyLine[i];
if (NULL == pEnt)
continue;
AcDbPolyline* pPolyLine = AcDbPolyline::cast(pEnt);
if (NULL == pPolyLine)
{
delete pEnt;
continue;
}
AcDbVoidPtrArray arrLine;
pPolyLine->explode(arrLine);
int i(0);
for (i = 0; i < arrLine.length(); i++)
{
AcDbObject* pObj = (AcDbObject*)arrLine[i];
if (NULL == pObj)
continue;
AcDbCurve* pCurve = AcDbCurve::cast(pObj);
if (NULL != pCurve)
{
pCurve->getOsnapPoints(osnapMode, gsSelectionMark, pickPoint,
lastPoint, viewXform, snapPoints, geomIds);
}
delete pObj;
}
delete pPolyLine;
}
return Acad::eOk;
}
Acad::ErrorStatus THImpHvacDuct::moveStretchPointsAt( const AcDbIntArray& indices,
const AcGeVector3d& offset )
{
if (NULL == m_pXDataMap || offset.length() < 1e-6)
return Acad::eNotImplementedYet;
if (indices.length() == 1)
{
// 单个夹点
Position ePos = ExplainGripIndex(indices[0]);
if (ePos == TDb::eStart || ePos == TDb::eEnd)
MoveExtendGripPointsAt(ePos, offset, FALSE);
}
else
{
// 多个夹点
MoveTransGripPointsAt(TDb::eMid, offset, FALSE);
}
return Acad::eOk;
}
Acad::ErrorStatus THImpHvacDuct::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:
MoveExtendGripPointsAt(ePos, offset, TRUE);
break;
case eMid:
MoveTransGripPointsAt(ePos, offset, TRUE);
break;
case eDim0:
case eDim1:
case eDim2:
// MoveDimGripPointsAt(ePos, offset);
break;
case eSizeMid0:
case eSizeMid1:
case eSizeMid2:
case eSizeMid3:
MoveSizeGripPointsAt(ePos, offset);
break;
case eCommand0:
case eCommand1:
case eCommand2:
MoveCommandGripPointsAt(ePos, offset);
break;
case eAdjust0:
MoveAdjustGripPointsAt(ePos, offset);
break;
}
return Acad::eOk;
}
// 仅对非立管
Acad::ErrorStatus THImpHvacDuct::MoveExtendGripPointsAt( TDb::Position ePos,
const AcGeVector3d& offset,
BOOL bAutoWork )
{
Acad::ErrorStatus eRet = Acad::eOk;
ASSERT(NULL != m_pXDataMap);
AcGePoint3d ptStart = StartPoint();
AcGePoint3d ptEnd = EndPoint();
AcGePoint3d ptNewStart = ptStart;
AcGePoint3d ptNewEnd = ptEnd;
AcGeVector3d vtDirect = ptEnd - ptStart;
AcGeVector3d vtUcsZ = TAuxTools::GetUcsZvt();
AcGeVector3d vtValidOff = offset.orthoProject(vtUcsZ);
HvacDuctType eDucttype = eStraight;
m_pXDataMap->GetAt(HDCT_Type, (int&)eDucttype);
if (ePos == eStart)
{
ptNewStart += vtValidOff;
if (ptNewStart != ptEnd)
SetStartPoint(ptNewStart);
else
eRet = Acad::eNotImplementedYet;
}
else if (ePos == eEnd)
{
ptNewEnd += vtValidOff;
if (ptNewEnd != ptStart)
SetEndPoint(ptNewEnd);
else
eRet = Acad::eNotImplementedYet;
}
if (eSoft == eDucttype && !IsCanDrawSoft())
eRet = Acad::eNotImplementedYet;
// 对于斜管或拖拽点又Z坐标变化时重新设定Normal
if (eRet == Acad::eOk && (!IsHorzAlignment() || fabs(offset.z) > 1e-3))
{
AcGeVector3d vtNormal(vtUcsZ);
AcGePlane plane(ptStart, vtNormal);
AcGePlane planeEnd(ptEnd, vtNormal);
AcGePoint3d ptPrj = ptNewStart.orthoProject(plane);
if (ePos == eEnd)
{
ptPrj = ptNewEnd.orthoProject(plane);
}
else if (ePos == eStart)
{
ptPrj = ptNewStart.orthoProject(planeEnd);
}
AcGeLine3d line(ptNewStart, ptNewEnd);
AcGePoint3d ptOnLine = line.closestPointTo(ptPrj);
vtNormal = ptOnLine - ptPrj;
vtNormal.normalize();
setNormal(vtNormal);
}
if (eRet == Acad::eOk)
{
// 传递修改消息
if (m_pOwnerEnt != NULL && m_pOwnerEnt->objectId().isValid())
{
//BEGIN=================================================================
TDbHvacDuct *pDuctEnt = TDbHvacDuct::cast(m_pOwnerEnt);
if (pDuctEnt != NULL)
{
pDuctEnt->UpdateDimData();
}
//修改时间:2010-04-15
//修改人 :王亚东
//修改原因:风管数据修改后更新标注内容
//END===================================================================
// 水平延长拉伸时才创建接口更改消息
if (bAutoWork && vtValidOff.isParallelTo(vtDirect))
{
TInterfaceModifyMsg iMsg;
iMsg.SetMsgPoint(ePos == eStart ? ptNewStart:ptNewEnd);
iMsg.SetGripPosition(ePos);
iMsg.SetMoveGripOffset(offset);
iMsg.SetMsgValidate(TRUE);
iMsg.SetInterfaceOper(eMoveGripPoint);
iMsg.SetMsgOperateOn(m_pOwnerEnt->objectId());
// 写入接口更改消息
TDbInterfaceMsgWrite msgWrite;
msgWrite.WriteInterfaceMsg(iMsg);
}
AcGeVector3d vtStart, vtEnd;
GetDirect(vtStart, vtEnd);
((TDbInterfacesObj*)m_pOwnerEnt)->UpdateInterfaceRec(ptStart, vtStart);
((TDbInterfacesObj*)m_pOwnerEnt)->UpdateInterfaceRec(ptEnd, vtEnd);
//更新自身模型空间的扩展字典的接口信息
if (ePos == eStart)
((TDbInterfacesObj*)m_pOwnerEnt)->UpdateInterfaceRec(ptStart, ptNewStart);
else if (ePos == eEnd)
((TDbInterfacesObj*)m_pOwnerEnt)->UpdateInterfaceRec(ptEnd, ptNewEnd);
UpdateDimInReactor(ePos, offset);
}
}
else
{
SetStartPoint(ptStart);
SetEndPoint(ptEnd);
}
return eRet;
}
Acad::ErrorStatus THImpHvacDuct::MoveTransGripPointsAt( TDb::Position ePos,
const AcGeVector3d& offset,
BOOL bForcePer )
{
ASSERT(NULL != m_pXDataMap);
AcGePoint3d ptStart = StartPoint();
AcGePoint3d ptEnd = EndPoint();
AcGeVector3d vtValidOff = offset;
BOOL bAutoOff(FALSE);
GetGlobalContext(HVAC_AUTOOFFSET, bAutoOff);
if (bAutoOff)
{
AcGeVector3d vtDirct = ptEnd - ptStart;
if (bForcePer)
vtValidOff = vtValidOff.orthoProject(vtDirct);
}
AcGePoint3d ptNewStart = ptStart + vtValidOff;
AcGePoint3d ptNewEnd = ptEnd + vtValidOff;
SetStartPoint(ptNewStart);
SetEndPoint(ptNewEnd);
// // 位移标注夹点
// AcGePoint3d ptDim;
// m_pXDataMap->GetAt(HVAC_DimBasePos, ptDim);
// ptDim += offset;
// m_pXDataMap->SetAt(HVAC_DimBasePos, ptDim);
// 传递修改消息
if (m_pOwnerEnt != NULL && m_pOwnerEnt->objectId().isValid())
{
// 处理风管壁连接的风口联动情况,暂
if (bAutoOff)
{
// 先复原位置,为了寻找贴壁的风口
SetStartPoint(ptStart);
SetEndPoint(ptEnd);
// ((TDbHvacDuct*)m_pOwnerEnt)->MoveNextToAirLet(vtValidOff);
TDbHvacDuct *pDuct = TDbHvacDuct::cast(m_pOwnerEnt);//Lixl modify 2012-3-14
if (NULL != pDuct)
pDuct->MoveNextToAirLet(vtValidOff);
SetStartPoint(ptNewStart);
SetEndPoint(ptNewEnd);
}
// 创建接口更改消息
AcGeMatrix3d xform;
xform.setToTranslation(vtValidOff);
TInterfaceModifyMsg iMsg;
iMsg.SetMsgPoint(TAuxTools::Mid(ptNewStart, ptNewEnd));
iMsg.SetGripPosition(eMid);
iMsg.SetMsgValidate(TRUE);
iMsg.SetTransform(xform);
iMsg.SetMoveGripOffset(vtValidOff);
iMsg.SetInterfaceOper(eMoveGripPoint);
iMsg.SetMsgOperateOn(m_pOwnerEnt->objectId());
// 写入接口更改消息
TDbInterfaceMsgWrite msgWrite;
msgWrite.WriteInterfaceMsg(iMsg);
// add by hh 2011-09-22 更新遮挡 解决风管移动后遮挡无法自动更新的问题
((TDbHvacDuct*)m_pOwnerEnt)->UpdateCoverDisplay();
//更新自身模型空间的扩展字典的接口信息
UpdateInterfaceRec(m_pOwnerEnt->objectId(), xform);
UpdateDimInReactor(ePos, vtValidOff);
}
return Acad::eOk;
}
Acad::ErrorStatus THImpHvacDuct::MoveAdjustGripPointsAt(Position ePos, const AcGeVector3d& offset)
{
ASSERT(NULL != m_pXDataMap);
Acad::ErrorStatus eRet = Acad::eOk;
AcGePoint3d ptStart = StartPoint();
AcGePoint3d ptEnd = EndPoint();
HvacDuctType eType = eStraight;
m_pXDataMap->GetAt(HDCT_Type, (int&)eType);
if (eSoft == eType)
{
double dOrigBulge(0.0);
m_pXDataMap->GetAt(HDCT_Bulge, dOrigBulge);
AcGeVector3d vtValid = offset; // 有效向量
vtValid.orthoProject(normal());
AcGePoint3d ptOrigAdjust = GetAdjustPt();
AcGePoint3d ptGet = ptOrigAdjust + vtValid;
if (ptGet != ptStart && ptGet != ptEnd)
{
double dNewBulge(0.0);
AcGeCircArc3d arc(ptStart, ptGet, ptEnd);
double dSubAngle = arc.endAng() - arc.startAng();
dNewBulge = tan(dSubAngle*0.25);
AcGeVector3d vtOrigNormal = normal();
AcGeVector3d vtNormal = arc.normal();
if (!vtNormal.isCodirectionalTo(vtOrigNormal))
dNewBulge *= -1;
m_pXDataMap->SetAt(HDCT_Bulge, dNewBulge);
if (!IsCanDrawSoft())
eRet = Acad::eNotImplementedYet;
}
if (eRet == Acad::eOk)
{
// ReSetDimPoint();
// 传递修改消息
if (m_pOwnerEnt != NULL && m_pOwnerEnt->objectId().isValid())
{
// 创建接口更改消息
TInterfaceModifyMsg iMsg;
iMsg.SetMsgPoint(ptGet);
iMsg.SetGripPosition(ePos);
iMsg.SetMoveGripOffset(offset);
iMsg.SetMsgValidate(TRUE);
iMsg.SetInterfaceOper(eMoveGripPoint);
iMsg.SetMsgOperateOn(m_pOwnerEnt->objectId());
// 写入接口更改消息
TDbInterfaceMsgWrite msgWrite;
msgWrite.WriteInterfaceMsg(iMsg);
AcGeVector3d vtStart, vtEnd;
GetDirect(vtStart, vtEnd);
//更新自身模型空间的扩展字典的接口信息
((TDbInterfacesObj*)m_pOwnerEnt)->UpdateInterfaceRec(ptStart, vtStart);
((TDbInterfacesObj*)m_pOwnerEnt)->UpdateInterfaceRec(ptEnd, vtEnd);
}
}
else
m_pXDataMap->SetAt(HDCT_Bulge, dOrigBulge);
}
return eRet;
}
// Acad::ErrorStatus THImpHvacDuct::MoveDimGripPointsAt(Position ePos, const AcGeVector3d& offset)
// {
// ASSERT(NULL != m_pXDataMap);
//
// AcGePoint3d ptDim;
// m_pXDataMap->GetAt(HVAC_DimBasePos, ptDim);
// ptDim += offset;
// m_pXDataMap->SetAt(HVAC_DimBasePos, ptDim);
// m_pXDataMap->GetAt(HVAC_DimBasePos, ptDim);
// return Acad::eOk;
//
// return Acad::eNotImplementedYet;
// }
Acad::ErrorStatus THImpHvacDuct::MoveSizeGripPointsAt(Position ePos, const AcGeVector3d& offset)
{
ASSERT(NULL != m_pXDataMap);
Acad::ErrorStatus eRet = Acad::eOk;
AcGePoint3d ptStart = StartPoint();
AcGePoint3d ptEnd = EndPoint();
AcGePoint3d ptMid = TAuxTools::Mid(ptStart, ptEnd);
AcGeVector3d vtNormal = normal();
AcGeVector3d vtDirect = ptEnd - ptStart;
vtDirect.normalize();
AcGeVector3d vtPerp = vtDirect;
vtPerp.rotateBy(PI * 0.5, vtNormal);
double dSizeMain(0.0), dSizeThick(0.0);
m_pXDataMap->GetAt(HDCT_Width, dSizeMain);
m_pXDataMap->GetAt(HDCT_Thick, dSizeThick);
double dNewWidth(dSizeMain), dNewThick(dSizeThick);
HvacDuctType eDuctType = eStraight;
HvacSectType eSectType = eRectangular;
m_pXDataMap->GetAt(HDCT_Type, (int&)eDuctType);
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType);
AcGePoint3d ptNewStart;
AcGePoint3d ptNewEnd;
if (IsVertAlignment())
{
if (eSectType == eRectangular)
{
AcGeVector3d vtOrthPlanNormal = vtNormal; // 要投影到的面的法向
AcGeVector3d vtLeftSide = vtNormal;
vtLeftSide.rotateBy(PI * 0.5, vtDirect);
if (ePos == eSizeMid0 || ePos == eSizeMid1)
vtOrthPlanNormal = vtLeftSide;
AcGeVector3d vtOrth = offset.orthoProject(vtOrthPlanNormal);
ptNewStart = ptStart + vtOrth * 0.5;
ptNewEnd = ptEnd + vtOrth * 0.5;
SetStartPoint(ptNewStart);
SetEndPoint(ptNewEnd);
double dExtLen = vtOrth.length();
// 找出相反方向(即尺寸变小情况)
if ((ePos == eSizeMid0 && !vtOrth.isCodirectionalTo(vtNormal))
|| (ePos == eSizeMid1 && vtOrth.isCodirectionalTo(vtNormal))
|| (ePos == eSizeMid2 && !vtOrth.isCodirectionalTo(vtLeftSide))
|| (ePos == eSizeMid3 && vtOrth.isCodirectionalTo(vtLeftSide))
)
{
dExtLen *= -1;
}
if (ePos == eSizeMid0 || ePos == eSizeMid1)
{
dNewThick = dSizeThick + dExtLen;
if (dNewThick > 1e-6)
m_pXDataMap->SetAt(HDCT_Thick, dNewThick);
else
eRet = Acad::eNotImplementedYet;
}
else if (ePos == eSizeMid2 || ePos == eSizeMid3)
{
dNewWidth = dSizeMain + dExtLen;
if (dNewWidth > 1e-6)
m_pXDataMap->SetAt(HDCT_Width, dNewWidth);
else
eRet = Acad::eNotImplementedYet;
}
}
else if (eSectType == eCircular)
{
AcGePoint3d ptGet = GetAVertCirSizePt();
ptGet += offset;
double dNewRadius = ptGet.distanceTo(ptMid);
if (dNewRadius > 1e-6)
m_pXDataMap->SetAt(HDCT_Diameter, dNewRadius*2);
else
eRet = Acad::eNotImplementedYet;
}
}
else
{
AcGeVector3d vtDirectNonZ = vtDirect;
// 投影到中截面(考虑到斜管,要平行Z轴)上有效向量,且用户拖拽时,要忽略Z坐标
AcGeVector3d vtUcsZ = TAuxTools::GetUcsZvt();
AcGeVector3d vtOrth = offset.orthoProject(vtUcsZ);
// 要投影到风管截面垂直方向上的面
vtOrth = vtOrth.orthoProject(vtDirect);
double dExtLen = vtOrth.length();
ptNewStart = ptStart + vtOrth * 0.5;
ptNewEnd = ptEnd + vtOrth * 0.5;
SetStartPoint(ptNewStart);
SetEndPoint(ptNewEnd);
// 找出相反方向(即尺寸变小情况)
if (ePos == eSizeMid0 && !vtOrth.isCodirectionalTo(vtPerp)
|| ePos == eSizeMid1 && vtOrth.isCodirectionalTo(vtPerp))
{
dExtLen *= -1;
}
dNewWidth = dSizeMain + dExtLen;
if (dNewWidth > 1e-6)
m_pXDataMap->SetAt(HDCT_Width, dNewWidth);
else
eRet = Acad::eNotImplementedYet;
if (eDuctType == eSoft && !IsCanDrawSoft())
eRet = Acad::eNotImplementedYet;
}
if (eRet == Acad::eOk)
{
// 传递修改消息
if (m_pOwnerEnt != NULL && m_pOwnerEnt->objectId().isValid())
{
//BEGIN=================================================================
TDbHvacDuct *pDuctEnt = TDbHvacDuct::cast(m_pOwnerEnt);
if (pDuctEnt != NULL)
{
pDuctEnt->UpdateDimData();
}
//END===================================================================
BOOL bAutoSize(FALSE);
GetGlobalContext(HVAC_AUTOSIZE, bAutoSize);
if (bAutoSize)
{
AcGeVector3d vtUcsZ = TAuxTools::GetUcsZvt();
AcGeVector3d vtOrth = offset.orthoProject(vtUcsZ);
vtOrth = vtOrth.orthoProject(vtDirect);
AcGePoint3d ptDragOld; // 先/后拖拽点
if (IsVertAlignment())
{
if (ePos == eSizeMid0)
ptDragOld = ptMid + dSizeThick * 0.5 * vtNormal;
else if (ePos == eSizeMid1)
ptDragOld = ptMid - dSizeThick * 0.5 * vtNormal;
else
{
AcGeVector3d vtLeftSide = vtNormal;
vtLeftSide.rotateBy(PI * 0.5, TAuxTools::GetUcsZvt());
if (ePos == eSizeMid2)
ptDragOld = ptMid + dSizeMain * 0.5 * vtLeftSide;
else if (ePos == eSizeMid3)
ptDragOld = ptMid - dSizeMain * 0.5 * vtLeftSide;
}
}
else
{
if (ePos == eSizeMid0)
ptDragOld = ptMid + dSizeMain * 0.5 * vtPerp;
else if (ePos == eSizeMid1)
ptDragOld = ptMid - dSizeMain * 0.5 * vtPerp;
}
// 创建接口更改消息
TInterfaceModifyMsg iMsg;
iMsg.SetMsgPoint(ptDragOld);
iMsg.SetGripPosition(ePos);
iMsg.SetSize(dNewWidth, dNewThick);
iMsg.SetSizeDir(vtPerp, vtNormal);
iMsg.SetMsgValidate(TRUE);
iMsg.SetMoveGripOffset(vtOrth*0.5);
iMsg.SetInterfaceOper(eSize);
iMsg.SetMsgOperateOn(m_pOwnerEnt->objectId());
// 写入接口更改消息
TDbInterfaceMsgWrite msgWrite;
msgWrite.WriteInterfaceMsg(iMsg);
acedPostCommand(_T("Redraw\n")); // 暂用于响应尺寸消息后,没有更新接口记录问题
}
//更新自身模型空间的扩展字典的接口信息
((TDbInterfacesObj*)m_pOwnerEnt)->UpdateInterfaceRec(ptStart, ptNewStart);
((TDbInterfacesObj*)m_pOwnerEnt)->UpdateInterfaceRec(ptEnd, ptNewEnd);
}
}
else
{
SetStartPoint(ptStart);
SetEndPoint(ptEnd);
m_pXDataMap->SetAt(HDCT_Width, dSizeMain);
m_pXDataMap->SetAt(HDCT_Thick, dSizeThick);
}
return eRet;
}
Acad::ErrorStatus THImpHvacDuct::MoveCommandGripPointsAt(Position ePos, const AcGeVector3d& offset)
{
ASSERT(NULL != m_pXDataMap);
// 获得夹点命令
CString sCmdStr;
GetGlobalContext()->GetAt(KEY_HVACGRIPCMD, sCmdStr);
if (sCmdStr.IsEmpty())
return Acad::eNotApplicable;
// 创建接口更改消息
TInterfaceModifyMsg iMsg;
AcGePoint3d ptDrag;
if (ePos == eCommand0)
ptDrag = StartPoint();
else if (ePos == eCommand1)
ptDrag = EndPoint();
else if (ePos == eCommand2)
ptDrag = (StartPoint() + EndPoint().asVector()) * 0.5;
iMsg.SetMsgPoint(ptDrag);
iMsg.SetGripPosition(ePos);
iMsg.SetMoveGripOffset(offset);
iMsg.SetMsgValidate(TRUE);
iMsg.SetInterfaceOper(eNewCommand);
iMsg.SetPreviewObjToCreate(ePipe, 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;
}
AcGePoint3d THImpHvacDuct::GetCirCenter() const
{
ASSERT(NULL != m_pXDataMap);
int nType(0);
m_pXDataMap->GetAt(HDCT_Type, nType);
if (HvacDuctType(nType) != eSoft)
return AcGePoint3d(0,0,0);
AcGePoint3d ptS = StartPoint();
AcGePoint3d ptE = EndPoint();
AcGeVector3d vtNormal = normal();
AcGeVector3d vtDirect = ptE - ptS;
vtDirect.normalize();
double dBulge(0), dPosiBulge(0);
m_pXDataMap->GetAt(HDCT_Bulge, dBulge);
dPosiBulge = fabs(dBulge);
double dAngle = atan(dPosiBulge) * 4;
AcGeVector3d vtLevel = ptE - ptS;
vtLevel.rotateBy(-PI * 0.5, vtNormal);
vtLevel.normalize();
vtLevel *= ptS.distanceTo(ptE) * 0.5 * dBulge;
AcGePoint3d ptArcMid = ptS + ptS.distanceTo(ptE) * 0.5 * vtDirect;
ptArcMid += vtLevel;
dAngle /= 4;
double dDist = ptArcMid.distanceTo(ptE) * 0.5;
double dRadius = dDist / sin(dAngle);
vtLevel.normalize();
AcGePoint3d ptCenter = ptArcMid - dRadius * vtLevel;
return ptCenter;
}
double THImpHvacDuct::GetRadius() const
{
ASSERT(NULL != m_pXDataMap);
int nType(0);
m_pXDataMap->GetAt(HDCT_Type, nType);
if (HvacDuctType(nType) != eSoft)
return 0;
AcGePoint3d ptS = StartPoint();
AcGePoint3d ptE = EndPoint();
AcGeVector3d vtNormal = normal();
AcGeVector3d vtDirect = ptE - ptS;
vtDirect.normalize();
double dBulge(0), dPosiBulge(0);
m_pXDataMap->GetAt(HDCT_Bulge, dBulge);
dPosiBulge = fabs(dBulge);
double dAngle = atan(dPosiBulge) * 4;
AcGeVector3d vtLevel = ptE - ptS;
vtLevel.rotateBy(-PI * 0.5, vtNormal);
vtLevel.normalize();
vtLevel *= ptS.distanceTo(ptE) * 0.5 * dBulge;
AcGePoint3d ptArcMid = ptS + ptS.distanceTo(ptE) * 0.5 * vtDirect;
ptArcMid += vtLevel;
dAngle /= 4;
double dDist = ptArcMid.distanceTo(ptE) * 0.5;
double dRadius = dDist / sin(dAngle);
return dRadius;
}
BOOL THImpHvacDuct::IsCanDrawSoft() const
{
ASSERT(NULL != m_pXDataMap);
double dWidth(0.0);
m_pXDataMap->GetAt(HDCT_Width, dWidth);
double dRadius = GetRadius();
if (dRadius - dWidth < 1e-3)
return FALSE;
return TRUE;
}
AcGePlane THImpHvacDuct::GetHidePlane(AcGePoint3d pt1, AcGePoint3d pt2, AcGePoint3d pt3,
const AcGeVector3d vtNormal, double &dEle) const
{
ASSERT(NULL != m_pXDataMap);
AcGePlane plan(pt1, pt2, pt3);
AcGePoint3d ptOrth = AcGePoint3d::kOrigin.orthoProject(plan);
plan.set(ptOrth, vtNormal);
dEle = ptOrth.asVector().length();
if (!ptOrth.asVector().isCodirectionalTo(vtNormal))
dEle *= -1.0;
return plan;
}
// void THImpHvacDuct::ReSetDimPoint() const
// {
// ASSERT(NULL != m_pXDataMap);
//
// AcGePoint3d ptStart = StartPoint();
// AcGePoint3d ptEnd = EndPoint();
// AcGePoint3d ptMid = TAuxTools::Mid(ptStart, ptEnd);
// AcGePoint3d ptDimPos;
// double dDimPercent = 0.7; // 标注点在管线起始端至中点位置百分比
//
// AcGeVector3d vtNormal = normal();
// AcGeVector3d vtPerp = vtNormal.crossProduct(ptEnd - ptStart);
// vtPerp.normalize();
//
// HvacDuctType eDuctType = eStraight;
// m_pXDataMap->GetAt(HDCT_Type, (int&)eDuctType);
//
// // 获得软风管的曲率
// double dBulge = 0.0;
// m_pXDataMap->GetAt(HDCT_Bulge, dBulge);
//
// if (eStraight == eDuctType || fabs(dBulge) < 1e-6)
// {
// ptDimPos = ptStart + (ptMid - ptStart) * dDimPercent;
// }
// else if(eSoft == eDuctType)
// {
// double dHight = ptStart.distanceTo(ptEnd) * 0.5 * dBulge;
// ptMid -= (vtPerp * dHight);
//
// double dAngle = atan(dBulge) * 2;
// AcGePoint3d ptCenter = GetCirCenter();
// ptDimPos = ptMid;
// ptDimPos.rotateBy(-(dAngle * (1 - dDimPercent*2/3)), vtNormal, ptCenter);
// }
//
// m_pXDataMap->SetAt(HVAC_DimBasePos, ptDimPos);
// }
// 对于水平、斜管,四个点为沿管长方向的中心截面的四个点
// 对于立管,四个点为沿起遮挡作用的最高面四个点
/*
水平管
3━━━━━━━━━━2
┃ ──→ ┃
┃━━━━━━━━━ ┃
┃ ┃
0━━━━━━━━━━1
立管 ←vtSide ↑vtNormal
矩形 圆形
3━━━━━2 /~~2~~\
┃ ┃ / \
┃ ┃ 3 1
┃ ┃ \ /
0━━━━━1 \__0__/
width
*/
void THImpHvacDuct::GetFourKeyPoints( AcGePoint3dArray &ptArr ) const
{
ASSERT(NULL != m_pXDataMap);
AcGePoint3d ptS = StartPoint();
AcGePoint3d ptE = EndPoint();
//BEGIN============================================
//AcGeVector3d vtNormal = normal();
AcGeVector3d vtNormal;
int iRet = m_pXDataMap->GetAt(KEY_NORMAL, vtNormal);
if (iRet == 0)
{
AfxMessageBox(_T("Get Normal Failed!"));
}
//NED==============================================
if (vtNormal.length() < 1E-9)
return;
vtNormal.normalize();// Lixl add 2011-12-21 13:18防止应用层传递进来的不是标准化向量
HvacDuctType eDuctType = eStraight;
HvacSectType eSectType = eRectangular;
m_pXDataMap->GetAt(HDCT_Type, (int&)eDuctType);
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType);
double dWidth(0.0), dHeigh(0.0);
m_pXDataMap->GetAt(HDCT_Width, dWidth);
m_pXDataMap->GetAt(HDCT_Thick, dHeigh);
double dBulge(0.0);
m_pXDataMap->GetAt(HDCT_Bulge, dBulge);
AcGePoint3d ptCenter = GetCirCenter();
if (IsVertAlignment())
{
AcGeVector3d vtDirect = ptE.z > ptS.z ? (ptE - ptS):(ptS - ptE);
if (vtDirect.length() < 1e-9)
vtDirect = TAuxTools::GetUcsZvt();
else
vtDirect.normalize();
AcGePoint3d ptStd = ptE.z > ptS.z ? ptE:ptS;
AcGeVector3d vtSide = vtNormal;
vtSide.rotateBy(PI * 0.5, vtDirect);
if (eDuctType == eSoft && fabs(dBulge) > 1e-6)
{
vtSide = ptStd - ptCenter;
vtSide.normalize();
if (dBulge < 0)
vtSide *= -1;
}
if (eSectType == eRectangular)
{
ptArr.append(ptStd + dWidth * 0.5 * vtSide - dHeigh * 0.5 * vtNormal);
ptArr.append(ptArr[0] - dWidth * vtSide);
ptArr.append(ptArr[1] + dHeigh * vtNormal);
ptArr.append(ptArr[2] + dWidth * vtSide);
}
else if (eSectType == eCircular)
{
ptArr.append(ptStd - dWidth * 0.5 * vtNormal);
ptArr.append(ptStd - dWidth * 0.5 * vtSide);
ptArr.append(ptArr[0] + dWidth * vtNormal);
ptArr.append(ptArr[1] + dWidth * vtSide);
}
if (eDuctType == eSoft)
{
AcGePlane planStd = GetStdPrjPlan(ptStd);
int i(0);
for (i = 0; i < ptArr.length(); i++)
{
ptArr[i] = ptArr[i].orthoProject(planStd);
}
}
}
else
{
double dHalfWidth = dWidth * 0.5;
if (eDuctType == eStraight)
{
// change by hh 2011-11-14 修正倾斜风管点计算错误的问题
// AcGeVector3d vtSide = vtNormal;
// AcGeVector3d vtDirect = ptE - ptS;
AcGeVector3d vtSide = AcGeVector3d::kZAxis;
AcGePlane plan(ptS, AcGeVector3d::kZAxis);
AcGePoint3d ptSS = ptS.orthoProject(plan);
AcGePoint3d ptEE = ptE.orthoProject(plan);
AcGeVector3d vtDirect = ptEE - ptSS;
vtDirect.normalize();
vtSide.rotateBy(-PI * 0.5, vtDirect);
ptArr.append(ptS - dHalfWidth * vtSide);
ptArr.append(ptE - dHalfWidth * vtSide);
ptArr.append(ptE + dHalfWidth * vtSide);
ptArr.append(ptS + dHalfWidth * vtSide);
}
else if (eDuctType == eSoft && fabs(dBulge) > 1e-6)
{
AcGeVector3d vtStaDir = ptS - ptCenter;
AcGeVector3d vtEndDir = ptE - ptCenter;
vtStaDir.normalize();
vtEndDir.normalize();
ptArr.append(ptS + dHalfWidth * vtStaDir);
ptArr.append(ptE + dHalfWidth * vtEndDir);
ptArr.append(ptE - dHalfWidth * vtEndDir);
ptArr.append(ptS - dHalfWidth * vtStaDir);
}
if (!IsHorzAlignment())
{
AcGePoint3d ptCenter = TAuxTools::Mid(ptS, ptE);
AcGePlane planStd = GetStdPrjPlan(ptCenter);
int i(0);
int nLength = ptArr.length();
for (i = 0; i < nLength; i++)
{
ptArr[i] = ptArr[i].orthoProject(planStd);
}
}
}
//BEGIN=========================================================
int nLength = ptArr.length();
if (nLength == 0)
{
AfxMessageBox(_T("The pointArray returned NULL"));
}
//END===========================================================
}
/*
3━━━━━━━2
┃ ┃
┃━━━━━━ ┃
┃ ┃
0━━━━━━━1
*/
void THImpHvacDuct::GetSingleKeyPoints(AcGePoint3dArray &ptArr) const
{
ASSERT(NULL != m_pXDataMap);
double dHideWidth(50.0);
GetGlobalContext()->GetAt(KEY_HIDEWIDTH, dHideWidth);
// 遮挡标高
// double dHideEle(0.0);
// m_pXDataMap->GetAt(HVAC_Elevation, dHideEle);
AcGePoint3dArray ptOrigArr;
GetFourKeyPoints(ptOrigArr);
if (4 != ptOrigArr.length())
return;
double dOffset = (ptOrigArr[0].distanceTo(ptOrigArr[3]) - dHideWidth) * 0.5;
AcGeVector3d vt0To3((ptOrigArr[3] - ptOrigArr[0]).normalize());
AcGeVector3d vt1To2((ptOrigArr[2] - ptOrigArr[1]).normalize());
ptArr.append(ptOrigArr[0] + dOffset * vt0To3);
ptArr.append(ptOrigArr[1] + dOffset * vt1To2);
ptArr.append(ptOrigArr[2] - dOffset * vt1To2);
ptArr.append(ptOrigArr[3] - dOffset * vt0To3);
// int i(0);
// for (i = 0; i < ptArr.length(); i++)
// {
// ptArr[i].z = dHideEle;
// }
}
AcGePoint3d THImpHvacDuct::GetAdjustPt() const
{
ASSERT(NULL != m_pXDataMap);
HvacDuctType eDuctType = eStraight;
m_pXDataMap->GetAt(HDCT_Type, (int&)eDuctType);
if (eDuctType != eSoft)
return AcGePoint3d(0,0,0);
// 获得始末点和重点
AcGePoint3d ptStart = StartPoint();
AcGePoint3d ptEnd = EndPoint();
AcGePoint3d ptMid = TAuxTools::Mid(ptStart, ptEnd);
// 获得方向向量
AcGeVector3d vtDirect = (ptMid - ptStart);
vtDirect.normalize();
// 获得垂直向量
AcGeVector3d vtNormal = normal();
AcGeVector3d vtPerp = vtNormal.crossProduct(vtDirect);
// 获得软风管的曲率
double dBulge = 0.0;
m_pXDataMap->GetAt(HDCT_Bulge, dBulge);
double dAngle = atan(dBulge) * 2;
AcGePoint3d ptCenter = GetCirCenter();
AcGePoint3d ptAdjust;
double dAdjustPercent = 0.7; // 调节点在管线起始端至中点位置百分比
// 调整中心点
double dHight = ptStart.distanceTo(ptEnd) * 0.5 * dBulge;
ptMid -= (vtPerp * dHight);
// 找到调节点位置
ptAdjust = ptMid;
ptAdjust.rotateBy(-(dAngle * (1 - dAdjustPercent)), vtNormal, ptCenter);
return ptAdjust;
}
AcGePoint3d THImpHvacDuct::GetAVertCirSizePt() const
{
ASSERT(NULL != m_pXDataMap);
double dRadius;
m_pXDataMap->GetAt(HDCT_Width, dRadius);
dRadius *= 0.5;
// 获得始末点和重点
AcGePoint3d ptStart = StartPoint();
AcGePoint3d ptEnd = EndPoint();
AcGePoint3d ptMid = TAuxTools::Mid(ptStart, ptEnd);
// 获得方向向量
AcGeVector3d vtDirect = (ptMid - ptStart);
vtDirect.normalize();
AcGeVector3d vtNormal = normal();
AcGeVector3d vtSide = vtNormal;
HvacDuctType eType = eStraight;
m_pXDataMap->GetAt(HDCT_Type, (int&)eType);
if (eType == eSoft)
{
double dBulge;
m_pXDataMap->GetAt(HDCT_Bulge, dBulge);
double dAngle = atan(dBulge) * 4;
vtDirect.rotateBy(dAngle * 0.5, vtNormal); // 得到末端界面垂直的法向
}
vtSide.rotateBy(-PI * 0.5, vtDirect);
AcGePoint3d ptSize = ptMid + dRadius * vtSide;
return ptSize;
}
void THImpHvacDuct::GetArcPoint(AcDbPolyline &polyLine, AcGePoint3dArray &ptArcArr) const
{
if (polyLine.numVerts() != 4)
return;
double dPara1(0.0), dPara2(0.0);
double dPar1, dPar2;
AcGePoint3d pt0, pt1, pt2, pt3, ptMid;
polyLine.getPointAt(0, pt0);
polyLine.getPointAt(1, pt1);
polyLine.getPointAt(2, pt2);
polyLine.getPointAt(3, pt3);
polyLine.getParamAtPoint(pt0, dPar1);
polyLine.getParamAtPoint(pt1, dPar2);
polyLine.getPointAtParam((dPar1 + dPar2)*0.5, ptMid);
ptArcArr.append(pt0);
ptArcArr.append(ptMid);
ptArcArr.append(pt1);
polyLine.getParamAtPoint(pt1, dPar1);
polyLine.getParamAtPoint(pt2, dPar2);
polyLine.getPointAtParam((dPar1 + dPar2)*0.5, ptMid);
ptArcArr.append(ptMid);
ptArcArr.append(pt2);
polyLine.getParamAtPoint(pt2, dPar1);
polyLine.getParamAtPoint(pt3, dPar2);
polyLine.getPointAtParam((dPar1 + dPar2)*0.5, ptMid);
ptArcArr.append(ptMid);
ptArcArr.append(pt3);
if (polyLine.isClosed())
{
polyLine.getParamAtPoint(pt3, dPar1);
polyLine.getEndParam(dPar2);
polyLine.getPointAtParam((dPar1 + dPar2)*0.5, ptMid);
ptArcArr.append(ptMid);
ptArcArr.append(pt0);
}
}
BOOL THImpHvacDuct::IsValid(TDbXDataMap* pXMap)
{
if (NULL == m_pXDataMap)
return FALSE;
// 注意:pXMap == NULL表示不想得到返回值,只是判断数据是否合理
// 先取出m_pXDataMap中数据进行判断是否合理,返回判断结果
// 如果pXMap不为NULL,则将有效参数填入pXMap
return FALSE;
}
AcDbObjectId THImpHvacDuct::GetBaseLayerId() const
{
AcDbObjectId idBaseLayer(AcDbObjectId::kNull);
TDbPipeBase* pFit = TDbPipeBase::cast(m_pOwnerEnt);
if (NULL != pFit)
idBaseLayer = pFit->CenterLayer();
return idBaseLayer;
}
Acad::ErrorStatus THImpHvacDuct::getSplitCurves( const AcGePoint3dArray& points,
AcDbVoidPtrArray& curveSegments ) const
{
Acad::ErrorStatus eSta = Acad::eNotImplementedYet;
AcDbArc arc;
if (InitArc(arc))
eSta = arc.getSplitCurves(points, curveSegments);
else
eSta = TDbImpPipeBase::getSplitCurves(points, curveSegments);
return eSta;
}
Acad::ErrorStatus THImpHvacDuct::getSplitCurves( const AcGeDoubleArray& params,
AcDbVoidPtrArray& curveSegments ) const
{
Acad::ErrorStatus eSta = Acad::eNotImplementedYet;
AcDbArc arc;
if (InitArc(arc))
{
eSta = arc.getSplitCurves(params, curveSegments);
}
else
eSta = TDbImpPipeBase::getSplitCurves(params, curveSegments);
return eSta;
}
Acad::ErrorStatus THImpHvacDuct::getStartPoint( AcGePoint3d& x0 ) const
{
if (IsArcDuct())
{
AcDbArc arc;
if (InitArc(arc))
return arc.getStartPoint(x0);
}
else
return TDbImpPipeBase::getStartPoint(x0);
return Acad::eNotImplementedYet;
}
Acad::ErrorStatus THImpHvacDuct::getStartParam( double& x0 ) const
{
if (IsArcDuct())
{
AcDbArc arc;
if (InitArc(arc))
return arc.getStartParam(x0);
}
else
return TDbImpPipeBase::getStartParam(x0);
return Acad::eNotImplementedYet;
}
Acad::ErrorStatus THImpHvacDuct::getEndPoint( AcGePoint3d& x0 ) const
{
if (IsArcDuct())
{
AcDbArc arc;
if (InitArc(arc))
return arc.getEndPoint(x0);
}
else
return TDbImpPipeBase::getEndPoint(x0);
return Acad::eNotImplementedYet;
}
Acad::ErrorStatus THImpHvacDuct::getEndParam( double& x0 ) const
{
if (IsArcDuct())
{
AcDbArc arc;
if (InitArc(arc))
return arc.getEndParam(x0);
}
else
return TDbImpPipeBase::getEndParam(x0);
return Acad::eNotImplementedYet;
}
Acad::ErrorStatus THImpHvacDuct::getParamAtDist(double dist,double& param) const
{
if (IsArcDuct())
{
AcDbArc arc;
if (InitArc(arc))
return arc.getParamAtDist(dist, param);
}
else
return TDbImpPipeBase::getParamAtDist(dist, param);
return Acad::eNotImplementedYet;
}
Acad::ErrorStatus THImpHvacDuct::getParamAtPoint(const AcGePoint3d& x0,double& x1)const
{
if (IsArcDuct())
{
AcDbArc arc;
if (InitArc(arc))
return arc.getParamAtPoint(x0, x1);
}
else
return TDbImpPipeBase::getParamAtPoint(x0, x1);
return Acad::eNotImplementedYet;
}
Acad::ErrorStatus THImpHvacDuct::getPointAtDist(double x0,AcGePoint3d& x1) const
{
if (IsArcDuct())
{
AcDbArc arc;
if (InitArc(arc))
return arc.getPointAtDist(x0, x1);
}
else
return TDbImpPipeBase::getPointAtDist(x0, x1);
return Acad::eNotImplementedYet;
}
Acad::ErrorStatus THImpHvacDuct::getPointAtParam(double x0,AcGePoint3d& x1) const
{
if (IsArcDuct())
{
AcDbArc arc;
if (InitArc(arc))
return arc.getPointAtParam(x0, x1);
}
else
return TDbImpPipeBase::getPointAtParam(x0, x1);
return Acad::eNotImplementedYet;
}
Acad::ErrorStatus THImpHvacDuct::getDistAtPoint( const AcGePoint3d& x0, double& x1 ) const
{
if (IsArcDuct())
{
AcDbArc arc;
if (InitArc(arc))
return arc.getDistAtPoint(x0, x1);
}
else
return TDbImpPipeBase::getDistAtPoint(x0, x1);
return Acad::eNotImplementedYet;
}
Acad::ErrorStatus THImpHvacDuct::getDistAtParam( double param, double& dist ) const
{
if (IsArcDuct())
{
AcDbArc arc;
if (InitArc(arc))
return arc.getDistAtParam(param, dist);
}
else
return TDbImpPipeBase::getDistAtParam(param, dist);
return Acad::eNotImplementedYet;
}
Acad::ErrorStatus THImpHvacDuct::getClosestPointTo( const AcGePoint3d& givenPnt,
const AcGeVector3d& direction,
AcGePoint3d& pointOnCurve,
Adesk::Boolean extend) const
{
if (IsArcDuct())
{
AcDbArc arc;
if (InitArc(arc))
return arc.getClosestPointTo(givenPnt,direction,pointOnCurve,extend);
}
else
return TDbImpPipeBase::getClosestPointTo(givenPnt,direction,pointOnCurve,extend);
return Acad::eNotImplementedYet;
}
Acad::ErrorStatus THImpHvacDuct::getClosestPointTo( const AcGePoint3d& givenPnt, AcGePoint3d& pointOnCurve,
Adesk::Boolean extend /*= Adesk::kFalse*/ ) const
{
if (IsArcDuct())
{
AcDbArc arc;
if (InitArc(arc))
return arc.getClosestPointTo(givenPnt, pointOnCurve, extend);
}
else
return TDbImpPipeBase::getClosestPointTo(givenPnt, pointOnCurve, extend);
return Acad::eNotImplementedYet;
}
BOOL THImpHvacDuct::IsArcDuct() const
{
if (NULL != m_pXDataMap)
{
HvacDuctType eType = eStraight;
m_pXDataMap->GetAt(HDCT_Type, (int&)eType);
return (eType == eSoft);
}
return FALSE;
}
TDbXDataMap* THImpHvacDuct::GetSpecialtyDataReadOnly() const
{
return m_pXDataMap;
}
BOOL THImpHvacDuct::InitArc(AcDbArc &arc) const
{
ASSERT(NULL != m_pXDataMap);
HvacDuctType eType = eStraight;
m_pXDataMap->GetAt(HDCT_Type, (int&)eType);
if (eType != eSoft)
return FALSE;
AcGePoint3d ptStart = StartPoint();
AcGePoint3d ptCenter = GetCirCenter();
double dRadius = ptCenter.distanceTo(ptStart);
AcGeVector3d vtNormal = normal();
AcGeVector3d vtUcsX(TAuxTools::GetUcsXvt()), vtUcsZ(TAuxTools::GetUcsZvt());
ads_point vtAdsOcsAngle, vtAdsOcsX;
acdbWcs2Ecs(asDblArray(vtUcsX), vtAdsOcsX, asDblArray(vtNormal), true);
AcGeVector3d vtTX = asVec3d(vtAdsOcsX);
AcGeVector3d vtAngle = ptStart - ptCenter;
acdbWcs2Ecs(asDblArray(vtAngle), vtAdsOcsAngle, asDblArray(vtNormal), true);
double dStaAngle = vtTX.angleTo(vtAngle, vtNormal);
vtAngle = EndPoint() - ptCenter;
acdbWcs2Ecs(asDblArray(vtAngle), vtAdsOcsAngle, asDblArray(vtNormal), true);
double dEndAngle = vtTX.angleTo(vtAngle, vtNormal);
// 负曲率时,转换起始终止角
double dBulge(0);
m_pXDataMap->GetAt(HDCT_Bulge, dBulge);
if (dBulge < 0)
{
double dTemp = dStaAngle;
dStaAngle = dEndAngle;
dEndAngle = dTemp;
}
arc.setCenter(ptCenter);
arc.setNormal(vtNormal);
arc.setRadius(dRadius);
arc.setStartAngle(dStaAngle);
arc.setEndAngle(dEndAngle);
return TRUE;
}
Acad::ErrorStatus THImpHvacDuct::intersectWith( const AcDbEntity* pEnt, AcDb::Intersect intType,
const AcGePlane& projPlane, AcGePoint3dArray& points, INT_PTR thisGsMarker /*= 0*/, INT_PTR otherGsMarker /*= 0*/ ) const
{
if (IsArcDuct())
{
AcDbArc arc;
if (InitArc(arc))
return arc.intersectWith(pEnt,intType,projPlane,points,thisGsMarker,otherGsMarker);
}
else
return TDbImpPipeBase::intersectWith(pEnt,intType,projPlane,points,thisGsMarker,otherGsMarker);
return Acad::eNotImplementedYet;
}
Acad::ErrorStatus THImpHvacDuct::intersectWith( const AcDbEntity* pEnt, AcDb::Intersect intType,
AcGePoint3dArray& points, INT_PTR thisGsMarker /*= 0*/, INT_PTR otherGsMarker /*= 0*/ ) const
{
if (IsArcDuct())
{
AcDbArc arc;
if (InitArc(arc))
return arc.intersectWith(pEnt,intType,points,thisGsMarker,otherGsMarker);
}
else
return TDbImpPipeBase::intersectWith(pEnt,intType,points,thisGsMarker,otherGsMarker);
return Acad::eNotImplementedYet;
}
Acad::ErrorStatus THImpHvacDuct::extend( double newParam )
{
Acad::ErrorStatus eSta = Acad::eNotImplementedYet;
if (IsArcDuct())
{
AcDbArc arc;
if (!InitArc(arc))
return Acad::eNotImplementedYet;
eSta = arc.extend(newParam);
if (eSta == Acad::eOk)
{
AcGePoint3d ptOrigSta, ptNewSta;
AcGePoint3d ptOrigEnd, ptNewEnd;
getStartPoint(ptOrigSta);
getEndPoint(ptOrigEnd);
arc.getStartPoint(ptNewSta);
arc.getEndPoint(ptNewEnd);
SetStartPoint(ptNewSta);
SetEndPoint(ptNewEnd);
double dStaAngle = arc.startAngle();
double dEndAngle = arc.endAngle();
if (dEndAngle < dStaAngle)
dEndAngle += PI*2;
double dBulge = tan((dEndAngle - dStaAngle) * 0.25);
if (NULL != m_pXDataMap)
m_pXDataMap->SetAt(HDCT_Bulge, dBulge);
if (m_pOwnerEnt != NULL && !m_pOwnerEnt->objectId().isNull())
{
UpdateInterfaceRec(m_pOwnerEnt->objectId(), ptOrigSta, ptNewSta);
UpdateInterfaceRec(m_pOwnerEnt->objectId(), ptOrigEnd, ptNewEnd);
((TDbPipeBase*)m_pOwnerEnt)->UpdateCoverDisplay();
}
}
}
else
{
eSta = TDbImpPipeBase::extend(newParam);
}
return eSta;
}
Acad::ErrorStatus THImpHvacDuct::extend( Adesk::Boolean extendStart, const AcGePoint3d& toPoint )
{
Acad::ErrorStatus eSta = Acad::eNotImplementedYet;
if (IsArcDuct())
{
AcDbArc arc;
if (!InitArc(arc))
return Acad::eNotImplementedYet;
AcGePoint3d ptOn;
eSta = arc.getClosestPointTo(toPoint, ptOn, Adesk::kTrue);
if (eSta != Acad::eOk)
return eSta;
AcGePoint3d ptOrigSta, ptNewSta;
AcGePoint3d ptOrigEnd, ptNewEnd;
ptOrigSta = StartPoint();
ptOrigEnd = EndPoint();
if (NULL != m_pXDataMap)
{
double dStaAngle = arc.startAngle();
double dEndAngle = arc.endAngle();
if (dEndAngle < dStaAngle)
dEndAngle += PI*2;
double dBulge = tan((dEndAngle - dStaAngle) * 0.25);
m_pXDataMap->SetAt(HDCT_Bulge, dBulge);
}
if (extendStart)
{
//if (ptOn.distanceTo(ptOrigEnd) > AcGeContext::gTol.equalPoint())
if (ptOn.distanceTo(ptOrigEnd) > g_globalTol.equalPoint()) // modify by cq TFS8208
{
SetStartPoint(ptOn);
if (m_pOwnerEnt != NULL && !m_pOwnerEnt->objectId().isNull())
{
UpdateInterfaceRec(m_pOwnerEnt->objectId(), ptOrigSta, ptOn);
((TDbPipeBase*)m_pOwnerEnt)->UpdateCoverDisplay();
}
}
}
else
{
//if (ptOn.distanceTo(ptOrigSta) > AcGeContext::gTol.equalPoint())
if (ptOn.distanceTo(ptOrigSta) > g_globalTol.equalPoint()) // modify by cq TFS8208
{
SetEndPoint(ptOn);
if (m_pOwnerEnt != NULL && !m_pOwnerEnt->objectId().isNull())
{
UpdateInterfaceRec(m_pOwnerEnt->objectId(), ptOrigEnd, ptOn);
((TDbPipeBase*)m_pOwnerEnt)->UpdateCoverDisplay();
}
}
}
}
else
{
eSta = TDbImpPipeBase::extend(extendStart, toPoint);
}
return eSta;
}
double THImpHvacDuct::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 THImpHvacDuct::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 THImpHvacDuct::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;
}
// 非立管根据点计算normal后重新设置
AcGeVector3d THImpHvacDuct::ResetNormalByPt()
{
ASSERT(NULL != m_pXDataMap);
AcGeVector3d vtUcsZ = TAuxTools::GetUcsZvt();
AcGeVector3d vtDirect = StartPoint() - EndPoint();
if (vtDirect.isParallelTo(vtUcsZ))
return AcGeVector3d(0,0,0);
else if (vtDirect.length() < 1e-9)
return AcGeVector3d(0,0,0);
AcGeVector3d vtNormal = vtDirect.crossProduct(vtUcsZ);
vtNormal.rotateBy(-PI * 0.5, vtDirect);
m_pXDataMap->SetAt(HVAC_Normal, vtNormal.normalize());
return vtNormal;
}
BOOL THImpHvacDuct::IsHideStart() const
{
ASSERT(NULL != m_pXDataMap);
BOOL bNoCheck(FALSE), bHide(FALSE);
GetGlobalContext()->GetAt(HVAC_IsExplodeDraw, bNoCheck);
if (bNoCheck)
{
m_pXDataMap->GetAt(HDCT_HIDESTART, bHide);
return bHide;
}
TInterface tIf;
AcDbObjectId idCon(AcDbObjectId::kNull);
if (GetInterface(0, tIf))
{
idCon = tIf.GetConnectObject();
if (!idCon.isValid())
{
return FALSE;
m_pXDataMap->SetAt(HDCT_HIDESTART, FALSE);
}
}
OPENOBJ_BEGIN(idCon, AcDb::kForRead, TDbHvacFitting, pFit);
if (NULL != pFit)
{
TDbXDataMap* pMap = pFit->GetSpecialtyData();
if (NULL != pMap)
{
AcGePoint3d ptIf = tIf.GetPosition();
ObjectKind eKind;
pMap->GetAt(KEY_RUNTIME, (int&)eKind);
if (eKind == eTee)
{
HvacTeeType eTeeType = eOrthoBranch;
pMap->GetAt(HTEE_Type, (int&)eTeeType);
if (eTeeType == eInsertIntubBranch || eTeeType == eArcuateIntubBranch)
{
AcGePoint3d ptSta, ptEnd;
pMap->GetAt(HTEE_StartPoint, ptSta);
pMap->GetAt(HTEE_EndPoint, ptEnd);
if (ptIf == ptSta || ptIf == ptEnd)
bHide = TRUE;
}
}
else if (eKind == eCross)
{
HvacCrossType eCorssType = eOrthoCross;
pMap->GetAt(HCRS_Type, (int &)eCorssType);
if (eCorssType == eInsertIntubCross|| eCorssType == eArcuateIntubCross)
{
AcGePoint3d ptSta, ptEnd;
pMap->GetAt(HCRS_StartPoint, ptSta);
pMap->GetAt(HCRS_EndPoint, ptEnd);
if (ptIf == ptSta || ptIf == ptEnd)
bHide = TRUE;
}
}
// add by zh 2013-7-24 断管符号隐藏风管边线
else if (eKind == eBroSymbol)
{
AcGePoint3d ptIns;
pMap->GetAt(HBSM_InsertPoint, ptIns);
if (ptIf == ptIns)
bHide = TRUE;
}
}
}
OPENOBJ_END();
m_pXDataMap->SetAt(HDCT_HIDESTART, bHide);
return bHide;
}
BOOL THImpHvacDuct::IsHideEnd() const
{
ASSERT(NULL != m_pXDataMap);
BOOL bNoCheck(FALSE), bHide(FALSE);
GetGlobalContext()->GetAt(HVAC_IsExplodeDraw, bNoCheck);
if (bNoCheck)
{
m_pXDataMap->GetAt(HDCT_HIDEEND, bHide);
return bHide;
}
TInterface tIf;
AcDbObjectId idCon(AcDbObjectId::kNull);
if (GetInterface(1, tIf))
{
idCon = tIf.GetConnectObject();
if (!idCon.isValid())
{
m_pXDataMap->SetAt(HDCT_HIDEEND, FALSE);
return FALSE;
}
}
OPENOBJ_BEGIN(idCon, AcDb::kForRead, TDbHvacFitting, pFit);
if (NULL != pFit)
{
TDbXDataMap* pMap = pFit->GetSpecialtyData();
if (NULL != pMap)
{
AcGePoint3d ptIf = tIf.GetPosition();
ObjectKind eKind;
pMap->GetAt(KEY_RUNTIME, (int&)eKind);
if (eKind == eTee)
{
HvacTeeType eTeeType = eOrthoBranch;
pMap->GetAt(HTEE_Type, (int&)eTeeType);
if (eTeeType == eInsertIntubBranch || eTeeType == eArcuateIntubBranch)
{
AcGePoint3d ptSta, ptEnd;
pMap->GetAt(HTEE_StartPoint, ptSta);
pMap->GetAt(HTEE_EndPoint, ptEnd);
if (ptIf == ptSta || ptIf == ptEnd)
bHide = TRUE;
}
}
else if (eKind == eCross)
{
HvacCrossType eCorssType = eOrthoCross;
pMap->GetAt(HCRS_Type, (int &)eCorssType);
if (eCorssType == eInsertIntubCross || eCorssType == eArcuateIntubCross)
{
AcGePoint3d ptSta, ptEnd;
pMap->GetAt(HCRS_StartPoint, ptSta);
pMap->GetAt(HCRS_EndPoint, ptEnd);
if (ptIf == ptSta || ptIf == ptEnd)
bHide = TRUE;
}
}
// add by zh 2013-7-24 断管符号隐藏风管边线
else if (eKind == eBroSymbol)
{
AcGePoint3d ptIns;
pMap->GetAt(HBSM_InsertPoint, ptIns);
if (ptIf == ptIns)
bHide = TRUE;
}
}
}
OPENOBJ_END();
m_pXDataMap->SetAt(HDCT_HIDEEND, bHide);
return bHide;
}
BOOL THImpHvacDuct::IsStartConnect() const
{
BOOL bNoCheck(FALSE), bCon(FALSE);
GetGlobalContext()->GetAt(HVAC_IsExplodeDraw, bNoCheck);
if (bNoCheck)
{
m_pXDataMap->GetAt(HDCT_STARTCONNECTED, bCon);
return bCon;
}
TInterface tIf;
AcDbObjectId idCon(AcDbObjectId::kNull);
if (GetInterface(0, tIf))
{
idCon = tIf.GetConnectObject();
if (!idCon.isValid())
{
m_pXDataMap->SetAt(HDCT_STARTCONNECTED, FALSE);
return FALSE;
}
}
OPENOBJ_BEGIN(idCon, AcDb::kForRead, TDbInterfacesObj, pObj);
if (NULL != pObj)
{
if (pObj->GetInterface(tIf.GetPosition(), TInterface()))
bCon = TRUE;
}
OPENOBJ_END();
m_pXDataMap->SetAt(HDCT_STARTCONNECTED, bCon);
return bCon;
}
BOOL THImpHvacDuct::IsEndConnect() const
{
BOOL bNoCheck(FALSE), bCon(FALSE);
GetGlobalContext()->GetAt(HVAC_IsExplodeDraw, bNoCheck);
if (bNoCheck)
{
m_pXDataMap->GetAt(HDCT_ENDCONNECTED, bCon);
return bCon;
}
TInterface tIf;
AcDbObjectId idCon(AcDbObjectId::kNull);
if (GetInterface(1, tIf))
{
idCon = tIf.GetConnectObject();
if (!idCon.isValid())
{
m_pXDataMap->SetAt(HDCT_ENDCONNECTED, FALSE);
return FALSE;
}
}
OPENOBJ_BEGIN(idCon, AcDb::kForRead, TDbInterfacesObj, pObj);
if (NULL != pObj)
{
if (pObj->GetInterface(tIf.GetPosition(), TInterface()))
bCon = TRUE;
}
OPENOBJ_END();
m_pXDataMap->SetAt(HDCT_ENDCONNECTED, bCon);
return bCon;
}
void THImpHvacDuct::CopyPropertiesTo(AcDbObjectId& idTgr,unsigned gMatchFlag)
{
}
void THImpHvacDuct::CopyPropertiesTo(AcDbObjectIdArray& arIds,unsigned gMatchFlag)
{
AcDbObjectId IdDuct = m_pOwnerEnt->objectId();
CString sText;
//sText.Format(_T("%ld"), IdDuct.asOldId());
#ifdef _WIN64
sText.Format(_T("%I64u"), IdDuct.asOldId());
#else
sText.Format(_T("%ld"), IdDuct.asOldId());
#endif
// modify by cq 2017-09-13 支持win10保存64位数据 TFS29618
struct resbuf rbUr;
rbUr.restype = RTSTR;
rbUr.rbnext = NULL;
rbUr.resval.rstring = (LPTSTR)(LPCTSTR)sText;
acedSetVar(_T("USERS3"), &rbUr);
// 发送消息
acedPostCommand(_T("\33"));
acedPostCommand(_T("FGGSS\n"));
}
// 更新反应器中的标注(移动夹点导致的变化)
void THImpHvacDuct::UpdateDimInReactor( Position eGridPos, const AcGeVector3d& vtOff )
{
if (NULL == m_pOwnerEnt)
return;
TDbHvacDuct* pDuct = TDbHvacDuct::cast(m_pOwnerEnt);
if (NULL == pDuct)
return;
// 移动首尾夹点情况
double dAngle(0.0);
AcGeVector3d vtNormal = TAuxTools::GetUcsZvt();
AcGePoint3d ptStaic;
if (eGridPos == eStart || eGridPos == eEnd)
{
AcGePoint3d ptSta(StartPoint()), ptEnd(EndPoint());
AcGePoint3d ptMoveOrig, ptMoveNew; // 不动点, 移动前后点
if (eGridPos == eStart)
{
ptStaic = ptEnd;
ptMoveOrig = ptSta - vtOff;
ptMoveNew = ptSta;
}
else
{
ptStaic = ptSta;
ptMoveOrig = ptEnd - vtOff;
ptMoveNew = ptEnd;
}
AcGeVector3d vtOrig = ptMoveOrig - ptStaic;
AcGeVector3d vtNew = ptMoveNew - ptStaic;
dAngle = vtNew.angleTo(vtOrig);
if (vtOrig.crossProduct(vtNew).angleTo(vtNormal) > PI * 0.5) // 逆向角度
dAngle *= -1;
}
// 更新反应器中其他标注
const AcDbVoidPtrArray* pArrVoidPt = NULL; // 反应器数组
void* pReactSome = NULL; // 反应器指针
AcDbObjectId objId; // 反应器对应实体id
pArrVoidPt = pDuct->reactors();
if (NULL == pArrVoidPt || pArrVoidPt->length() < 1)
return;
int i(0);
for (i = 0; i < pArrVoidPt->length(); i++)
{
pReactSome = pArrVoidPt->at(i);
if (acdbIsPersistentReactor(pReactSome))
{
objId = acdbPersistentReactorObjectId(pReactSome);
OPENOBJ_BEGIN(objId, AcDb::kForWrite, TDbHvacDimension, pDim);
if (NULL != pDim)
{
if (eGridPos == eMid)
{
AcGeMatrix3d mat;
mat.setTranslation(vtOff);
pDim->transformBy(mat);
}
else if (eGridPos == eStart || eGridPos == eEnd)
{
AcGePoint3d ptDimBase = pDim->GetBasePoint();
ptDimBase.rotateBy(dAngle, vtNormal, ptStaic);
pDim->SetBasePoint(ptDimBase);
HvacDimType eType = pDim->GetType();
if (eType == eDimInnerPipe || eType == eDimAbovePipe || eType == eDimBelowPipe)
{
double dOrigAngle = pDim->GetTextAngle();
pDim->SetTextAngle(dOrigAngle + dAngle);
}
else
{
// 方向对调时,纠正角度
double dAngle(pDim->GetTextAngle());
AcGeVector3d vtLead(pDim->GetLeadPoint() - pDim->GetBasePoint());
XVector3D vt(cos(dAngle), sin(dAngle), 0);
if (vtLead.angleTo(vt) > PI * 0.5)
{
dAngle += PI;
// dAngle = AsStdAngle(dAngle);
dAngle = AngleRangeTo2PI(dAngle);
pDim->SetTextAngle(dAngle);
}
}
}
}
OPENOBJ_END();
}
}
}
int THImpHvacDuct::GetXBaseShell(TXShell& xShell)
{
if (NULL == m_pXDataMap)
{
return 0;
}
// 添加实体壁面
AcDbVoidPtrArray entSet;
XExplodeStream dc(entSet);
double dBulge = 0.0;
m_pXDataMap->GetAt(HDCT_Bulge, dBulge);
if (fabs(dBulge) < 1e-6)
{
double dMinDiffAngOLD = PI/12, dMinDiffAng = PI / 4;
GetGlobalContext()->GetAt(KEY_MINDIFFANG, dMinDiffAngOLD);
GetGlobalContext()->SetAt(KEY_MINDIFFANG, dMinDiffAng);
ExplodeOrDraw3d(dc);
GetGlobalContext()->SetAt(KEY_MINDIFFANG, dMinDiffAngOLD);
}
else
{
ExplodeOrDraw3d(dc);
}
int nLen=entSet.length();
for(int i = 0; i < nLen; i++)
{
AcDbEntity *pEnt=(AcDbEntity *)entSet[i];
if(pEnt->isKindOf(AcDbFace::desc()))
{
xShell.AppendFace((AcDbFace*)pEnt);
}
}
// 添加实体端口面
HvacSectType eSectType;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType);
if (TDb::eRectangular == eSectType)
{
// 获得参数
double dWidth = 0.0;
m_pXDataMap->GetAt(HDCT_Width, dWidth);
double dThick = 0.0;
m_pXDataMap->GetAt(HDCT_Thick, dThick);
AcGeVector3d vtNormal = normal();
vtNormal.normalize();
AcGePoint3d ptStart;
m_pXDataMap->GetAt(HDCT_START, ptStart);
AcGePoint3d ptEnd;
m_pXDataMap->GetAt(HDCT_END, ptEnd);
AcGeVector3d vtStart, vtEnd;
if (fabs(dBulge) < 1e-6)
{
vtStart = ptStart - ptEnd;
vtStart.normalize();
vtEnd = ptEnd - ptStart;
vtEnd.normalize();
}
else
{
AcGePoint3d ptCenter = GetCirCenter();
vtStart = ptCenter - ptStart;
vtEnd = ptCenter - ptEnd;
if (dBulge > 0.0)
{
vtStart.rotateBy(PI / 2.0, vtNormal);
vtEnd.rotateBy(-PI / 2.0, vtNormal);
}
else
{
vtStart.rotateBy(-PI / 2.0, vtNormal);
vtEnd.rotateBy(PI / 2.0, vtNormal);
}
vtStart.normalize();
vtEnd.normalize();
}
// 添加端口面
TAuxTools::BuildRecFace(ptStart, dWidth, dThick, vtNormal, vtStart, xShell);
TAuxTools::BuildRecFace(ptEnd, dWidth, dThick, vtNormal, vtEnd, xShell);
}
else if (TDb::eCircular == eSectType)
{
// 获得参数
double dDiameter = 0.0;
m_pXDataMap->GetAt(HDCT_Diameter, dDiameter);
AcGeVector3d vtNormal = normal();
vtNormal.normalize();
AcGePoint3d ptStart;
m_pXDataMap->GetAt(HDCT_START, ptStart);
AcGePoint3d ptEnd;
m_pXDataMap->GetAt(HDCT_END, ptEnd);
AcGeVector3d vtStart, vtEnd;
if (fabs(dBulge) < 1e-6)
{
vtStart = ptStart - ptEnd;
vtStart.normalize();
vtEnd = ptEnd - ptStart;
vtEnd.normalize();
}
else
{
AcGePoint3d ptCenter = GetCirCenter();
vtStart = ptCenter - ptStart;
vtEnd = ptCenter - ptEnd;
if (dBulge > 0.0)
{
vtStart.rotateBy(PI / 2.0, vtNormal);
vtEnd.rotateBy(-PI / 2.0, vtNormal);
}
else
{
vtStart.rotateBy(-PI / 2.0, vtNormal);
vtEnd.rotateBy(PI / 2.0, vtNormal);
}
vtStart.normalize();
vtEnd.normalize();
}
// 添加端口面
TAuxTools::BuildCirFace(ptStart, dDiameter, vtNormal, vtStart, xShell);
TAuxTools::BuildCirFace(ptEnd, dDiameter, vtNormal, vtEnd, xShell);
}
else
{
// 不做处理
}
return 1;
}
int THImpHvacDuct::GetBodyBox(AcDbExtents& ext)
{
if (NULL == m_pXDataMap)
{
return 0;
}
// 获得参数
double dWidth = 0.0;
m_pXDataMap->GetAt(HDCT_Width, dWidth);
double dHalfWidth = dWidth / 2.0;
double dThick = 0.0;
m_pXDataMap->GetAt(HDCT_Thick, dThick);
double dHalfThick = dThick / 2.0;
HvacSectType eSectType;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType);
if (TDb::eCircular == eSectType)
{
// 处理圆管数据
dHalfThick = dHalfWidth;
}
AcGeVector3d vtNormal;
m_pXDataMap->GetAt(HVAC_Normal, vtNormal);
vtNormal.normalize();
AcGePoint3d ptStart;
m_pXDataMap->GetAt(HDCT_START, ptStart);
AcGePoint3d ptEnd;
m_pXDataMap->GetAt(HDCT_END, ptEnd);
AcGeVector3d vtSide = ptEnd - ptStart;
vtSide.rotateBy(PI / 2.0, vtNormal);
vtSide.normalize();
double dBulge = 0.0;
m_pXDataMap->GetAt(HDCT_Bulge, dBulge);
// 计算端点
AcGePoint3dArray arpt;
arpt.append(ptStart + vtSide * dHalfWidth + vtNormal * dHalfThick);
arpt.append(ptStart + vtSide * dHalfWidth - vtNormal * dHalfThick);
arpt.append(ptStart - vtSide * dHalfWidth - vtNormal * dHalfThick);
arpt.append(ptStart - vtSide * dHalfWidth + vtNormal * dHalfThick);
arpt.append(ptEnd + vtSide * dHalfWidth + vtNormal * dHalfThick);
arpt.append(ptEnd + vtSide * dHalfWidth - vtNormal * dHalfThick);
arpt.append(ptEnd - vtSide * dHalfWidth - vtNormal * dHalfThick);
arpt.append(ptEnd - vtSide * dHalfWidth + vtNormal * dHalfThick);
if (fabs(dBulge) > 1e-6)
{
// 计算方向
AcGeVector3d vt = ptEnd - ptStart;
if (dBulge > 0.0)
{
vt.rotateBy(-PI / 2.0, vtNormal);
vt.normalize();
}
else
{
vt.rotateBy(PI / 2.0, vtNormal);
vt.normalize();
}
// 计算偏移距离
double dAng = 4.0 * atan(fabs(dBulge));
double dDis = ptEnd.distanceTo(ptStart);
double dOffset = (dDis / 2.0) * (1.0 - cos(dAng / 2.0)) / sin(dAng / 2.0);
// 计算顶点
AcGePoint3d pt;
Midpoint(ptStart, ptEnd, pt);
pt += vt * dOffset;
arpt.append(pt);
}
// 构造最小包含体
TAuxTools::BuildMinRectangle(arpt, ext);
return 1;
}
CString THImpHvacDuct::GetXml(const AcGeMatrix3d& mat) const
{
if (NULL == m_pXDataMap || NULL == m_pOwnerEnt)
return _T("");
int nValue(0);
double dValue(0.0);
int nSizePreci(3), nPtPreci(6); // 尺寸、位置精度
TXmlTree xmlTree;
CString csText;
AcGePoint3d pt;
CString csX, csY, csZ;
POSITION posRoot = xmlTree.Insert(_T("ATS_DBHVACDUCT"), NULL, NULL);
{
xmlTree.SetAttribute(posRoot, _T("name"), _T("风管"));
xmlTree.SetAttribute(posRoot, _T("comment"), _T("上华对象名称"));
}
POSITION posItemMaterial = xmlTree.Insert(_T("Material"),posRoot, NULL);
{
xmlTree.SetAttribute(posItemMaterial, _T("name"), _T("风管材料"));
xmlTree.SetAttribute(posItemMaterial, _T("comment"), _T("风管使用的材料"));
m_pXDataMap->GetAt(HVAC_Material, csText);
xmlTree.SetItemText(posItemMaterial, csText);
}
POSITION posItemSect = xmlTree.Insert(_T("SectionType"),posRoot, posItemMaterial);
{
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 posItemWidth = xmlTree.Insert(_T("Width"),posRoot, posItemSect);
{
xmlTree.SetAttribute(posItemWidth, _T("name"), _T("风管宽度参数"));
xmlTree.SetAttribute(posItemWidth, _T("comment"), _T("风管截面的宽度"));
m_pXDataMap->GetAt(HDCT_Width, dValue);
TAuxTools::DoubleToString(dValue, nSizePreci, csText);
xmlTree.SetItemText(posItemWidth, csText);
}
POSITION posItemHeigh = xmlTree.Insert(_T("Height"),posRoot, posItemWidth);
{
xmlTree.SetAttribute(posItemHeigh, _T("name"), _T("风管高度参数"));
xmlTree.SetAttribute(posItemHeigh, _T("comment"), _T("风管截面的高度"));
m_pXDataMap->GetAt(HDCT_Thick, dValue);
TAuxTools::DoubleToString(dValue, nSizePreci, csText);
xmlTree.SetItemText(posItemHeigh, csText);
}
AcGeVector3d vt;
POSITION posItemNorDir = xmlTree.Insert(_T("NormalDir"),posRoot, posItemHeigh);
{
xmlTree.SetAttribute(posItemNorDir, _T("name"), _T("法向量"));
m_pXDataMap->GetAt(HVAC_Normal, 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(posItemNorDir, csText);
}
POSITION posItemStaPt = xmlTree.Insert(_T("Start_point"),posRoot, posItemNorDir);
{
xmlTree.SetAttribute(posItemStaPt, _T("name"), _T("起点位置"));
pt = StartPoint();
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(posItemStaPt, csText);
}
POSITION posItemEndPt = xmlTree.Insert(_T("End_point"),posRoot, posItemStaPt);
{
xmlTree.SetAttribute(posItemEndPt, _T("name"), _T("终点位置"));
pt = EndPoint();
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);
}
TDb::HvacDuctType eDuctType(TDb::eStraight);
m_pXDataMap->GetAt(HDCT_Type, (int&)eDuctType);
if (TDb::eSoft == eDuctType)
{
if (m_pXDataMap->GetAt(HDCT_StartDir, vt))
{
POSITION posItemStaVt = xmlTree.Insert(_T("Start_Direct"), posRoot, posItemEndPt);
{
xmlTree.SetAttribute(posItemStaVt, _T("name"), _T("起点方向"));
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(posItemStaVt, csText);
}
posItemEndPt = posItemStaVt;
}
if (m_pXDataMap->GetAt(HDCT_EndDir, vt))
{
POSITION posItemEndVt = xmlTree.Insert(_T("End_Direct"), posRoot, posItemEndPt);
{
xmlTree.SetAttribute(posItemEndVt, _T("name"), _T("终点方向"));
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(posItemEndVt, csText);
}
posItemEndPt = posItemEndVt;
}
}
POSITION posItemBulge = xmlTree.Insert(_T("Bulge"),posRoot, posItemEndPt);
{
xmlTree.SetAttribute(posItemBulge, _T("name"), _T("凸度"));
xmlTree.SetAttribute(posItemBulge, _T("comment"), _T("弧管弯曲的程度(0时为直管)"));
dValue = 0.0;
m_pXDataMap->GetAt(HDCT_Bulge, dValue);
TAuxTools::DoubleToString(dValue, nPtPreci, csText);
xmlTree.SetItemText(posItemBulge, csText);
}
POSITION posObjId = xmlTree.Insert(_T("Object_ID"), posRoot, posItemBulge);
{
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-05 /////////
POSITION posAirLoadUnit = xmlTree.Insert(_T("AirLoadUnit"), posRoot, posObjId);
{
xmlTree.SetAttribute(posAirLoadUnit, _T("name"), _T("风量单位"));
xmlTree.SetAttribute(posAirLoadUnit, _T("comment"), _T("0:kg/h, 1:kg/s, 2:m^3/h..."));
m_pXDataMap->GetAt(HVAC_AirLoadUnit, nValue);
csText.Format(_T("%d"), nValue);
xmlTree.SetItemText(posAirLoadUnit, csText);
}
POSITION posAirLoad = xmlTree.Insert(_T("AirLoad"), posRoot, posAirLoadUnit);
{
xmlTree.SetAttribute(posAirLoad, _T("name"), _T("风量"));
xmlTree.SetAttribute(posAirLoad, _T("comment"), _T("风口风量"));
m_pXDataMap->GetAt(HVAC_AirLoad, dValue);
TAuxTools::DoubleToString(dValue, nSizePreci, csText);
xmlTree.SetItemText(posAirLoad, csText);
}
POSITION posSysName = xmlTree.Insert(_T("System"), posRoot, posAirLoad);
{
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 posDuctType = xmlTree.Insert(_T("DuctType"), posRoot, posSingleLine);
{
xmlTree.SetAttribute(posDuctType, _T("name"), _T("风管类型"));
xmlTree.SetAttribute(posDuctType, _T("comment"), _T(" 1/直风管, 2/软风管"));
m_pXDataMap->GetAt(HDCT_Type, nValue);
csText.Format(_T("%d"), nValue);
xmlTree.SetItemText(posDuctType, csText);
}
POSITION posSoft = xmlTree.Insert(_T("IsSoft"), posRoot, posDuctType);
{
xmlTree.SetAttribute(posSoft, _T("name"), _T("软风管"));
xmlTree.SetAttribute(posSoft, _T("comment"), _T("是否是软风管:0/不是, 1/是"));
// 绘制非软风管的 时候好像没有设置这个参数,因此默认为非软风管
if (!m_pXDataMap->GetAt(HDCT_Soft, nValue))
nValue = 0;
csText.Format(_T("%d"), nValue);
xmlTree.SetItemText(posSoft, csText);
}
POSITION posHasLiningLine = xmlTree.Insert(_T("HasLiningLine"), posRoot, posSoft);
{
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 THImpHvacDuct::GetSection( const AcDbFace &face, const AcGeVector3d &vtPlaneSecDir,
std::vector<TObjSectionRecord> &sectionRecord, AcDbVoidPtrArray& arFillPtrs ) const
{
if (NULL == m_pOwnerEnt || NULL == m_pXDataMap)
return false;
double dBulge = 0.0;
m_pXDataMap->GetAt(HDCT_Bulge, dBulge);
if (fabs(dBulge) < 1e-6) // 直风管
return GetStraightSection(face, vtPlaneSecDir, sectionRecord, arFillPtrs);
else
return GetArcSection(face, vtPlaneSecDir, sectionRecord, arFillPtrs);
return false;
}
bool THImpHvacDuct::GetStraightSection( const AcDbFace &face, const AcGeVector3d &vtPlaneSecDir,
std::vector<TObjSectionRecord> &sectionRecord, AcDbVoidPtrArray& arFillPtrs ) const
{
// 基本参数
AcGePoint3d ptS = StartPoint();
AcGePoint3d ptE = EndPoint();
AcGeVector3d vtDirect = ptE - ptS;
HvacDrawType eDrawType = eOldStyle;
m_pXDataMap->GetAt(HVAC_DrawType, (int&)eDrawType);
AcGePoint3d ptTemp;
TGGeLine tgLine(LS_FINITE);
AcDbObjectId idObj = m_pOwnerEnt->objectId();
AcDbObjectId idLayer = m_pOwnerEnt->layerId();
TGGeSectionPlane section_pln(face, vtPlaneSecDir); // 构造一个辅助剖面
HvacSectType eSect = TDb::eRectangular;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSect);
if (TDb::eRectangular == eSect)
{
// 判断方向,如果风管轴向垂直投影面,则有填充线
if (vtDirect.isParallelTo(vtPlaneSecDir))
{
// 3━━━━━2
// ┃ ┃
// ┃ ┃
// ┃ 起始端 ┃
// ┃ ┃
// ┃ ┃
// 0━━━━━1
// 离剖切线最近端标高
TGGeLine tgLine(LS_FINITE), tgLineOut(LS_FINITE);
tgLine.SetPoints(ptS, ptE);
short nRet = SectionUtility::Projection_line2plane(section_pln, tgLine, tgLineOut, ptTemp);
AcGePoint3d ptSNew = tgLineOut.StartPoint();
AcGePoint3d ptENew = tgLineOut.EndPoint();
if (1 == nRet) // 线与面垂直
ptSNew = ptENew = ptTemp;
// 最小距离即为要传入的标高参数
double dStaDist = ptSNew.distanceTo(ptS);
double dEndDist = ptENew.distanceTo(ptE);
double dMinDist = dStaDist < dEndDist ? dStaDist : dEndDist;
dMinDist *= -1;
// 基本点
AcGePoint3d ptBase(ptS); // 端部基点,要投影方向那一端
if (vtDirect.isCodirectionalTo(vtPlaneSecDir)) // 为了多根重合风管剖切填充线一致
{
ptBase = ptE;
vtDirect *= -1;
}
double dWidth(0.0), dThick(0.0);
m_pXDataMap->GetAt(HDCT_Width, dWidth);
m_pXDataMap->GetAt(HDCT_Thick, dThick);
AcGeVector3d vtNormal = normal();
AcGeVector3d vtLevel = vtDirect;
vtLevel.normalize();
vtLevel.rotateBy(PI * 0.5, vtNormal);
AcGePoint3d ptArrSide[4];
ptArrSide[0] = ptBase - dThick * 0.5 * vtNormal + dWidth * 0.5 * vtLevel;
ptArrSide[1] = ptArrSide[0] - dWidth * vtLevel;
ptArrSide[2] = ptArrSide[1] + dThick * vtNormal;
ptArrSide[3] = ptArrSide[0] + dThick * vtNormal;
// 端部面,构造端部面才有遮挡
TGGePoly2D poly2d;
poly2d.AppendNode(ptArrSide[0]);
poly2d.AppendNode(ptArrSide[1]);
poly2d.AppendNode(ptArrSide[2]);
poly2d.AppendNode(ptArrSide[3]);
poly2d.SetClosed();
if (!!poly2d)
sectionRecord.push_back(TObjSectionRecord(idObj, idLayer, TObjSectionRecord::eTCH_DBHVACDUCT,
dMinDist, poly2d));
TSectionFill* pFill = new TSectionFill;
pFill->SetBlockRef(false);
pFill->SetElevation(dMinDist);
pFill->SetLayer(idLayer);
// 内部填充样式
if (eDrawType == eOldStyle)
{
AcGePoint3d ptCenter = TAuxTools::Mid(ptArrSide[0], ptArrSide[2]);
AcGePoint3d ptLineMid = TAuxTools::Mid(ptCenter, ptArrSide[3]);
tgLine.SetPoints(ptArrSide[0], ptLineMid);
SectionUtility::Projection_line2plane(section_pln, tgLine, tgLine, ptTemp);
pFill->InsertLine(tgLine);
tgLine.SetPoints(ptLineMid, ptArrSide[2]);
SectionUtility::Projection_line2plane(section_pln, tgLine, tgLine, ptTemp);
pFill->InsertLine(tgLine);
}
else
{
tgLine.SetPoints(ptArrSide[0], ptArrSide[2]);
SectionUtility::Projection_line2plane(section_pln, tgLine, tgLine, ptTemp);
pFill->InsertLine(tgLine);
if (eDrawType == eNewImmit)
{
tgLine.SetPoints(ptArrSide[3], ptArrSide[1]);
SectionUtility::Projection_line2plane(section_pln, tgLine, tgLine, ptTemp);
pFill->InsertLine(tgLine);
}
}
arFillPtrs.append(pFill);
}
else
{
AcDbVoidPtrArray arFaces;
XExplodeStream dc(arFaces);
ExplodeOrDraw3d(dc);
double dElevation(0.0);
AcDbEntity* pEnt = NULL;
AcDbFace* pFace = NULL;
int i(0);
for (i = 0; i < arFaces.length(); ++i)
{
pEnt = (AcDbEntity*)arFaces[i];
if (NULL == pEnt)
continue;
pFace = AcDbFace::cast(pEnt);
if (pFace)
{
TGGeSectionPlane pln(*pFace, vtPlaneSecDir);
TGGePoly2D poly;
dElevation = SectionUtility::Projection_plane2plane(section_pln, pln, poly);
if(!!poly) // add by hh 2011-03-11 增加投影后的Poly2D有效型判断
sectionRecord.push_back(TObjSectionRecord(idObj, idLayer, TObjSectionRecord::eTCH_DBHVACDUCT, dElevation, poly));
}
delete pEnt;
}
}
}
else if (TDb::eCircular == eSect) // 圆管时
{
double dRadius(0.0);
m_pXDataMap->GetAt(HDCT_Diameter, dRadius);
dRadius *= 0.5;
TGGeLine tgLine(LS_FINITE), tgLineOut(LS_FINITE);
tgLine.SetPoints(ptS, ptE);
short nRet = SectionUtility::Projection_line2plane(section_pln, tgLine, tgLineOut, ptTemp);
AcGePoint3d ptSNew = tgLineOut.StartPoint();
AcGePoint3d ptENew = tgLineOut.EndPoint();
if (1 == nRet) // 线与面垂直
ptSNew = ptENew = ptTemp;
// 最小距离即为要传入的标高参数
double dStaDist = ptSNew.distanceTo(ptS);
double dEndDist = ptENew.distanceTo(ptE);
double dMinDist = dStaDist < dEndDist ? dStaDist : dEndDist;
dMinDist *= -1;
// 判断方向,如果风管轴向不垂直投影面,做一个投影到剖切面上的poly2d即可
if (!vtDirect.isParallelTo(vtPlaneSecDir))
{
// 求出投影后的矩形四点
AcGePoint3d ptSUp, ptSDown, ptEUp, ptEDown;
AcGeVector3d vtDirect = ptE - ptS;
// AcGeVector3d vtUp = (vtDirect.rotateBy(PI*0.5, vtPlaneSecDir)).normalize();
AcGeVector3d vtUp = normal();
if(IsVertAlignment()) // 立管
vtUp = (vtDirect.rotateBy(PI*0.5, vtPlaneSecDir)).normalize();
ptSUp = ptS + vtUp * dRadius;
ptSDown = ptS - vtUp * dRadius;
ptEUp = ptE + vtUp * dRadius;
ptEDown = ptE - vtUp * dRadius;
// 设置Poly2d后 传入参数
TGGePoly2D poly2d;
poly2d.AppendNode(ptSUp);
poly2d.AppendNode(ptEUp);
poly2d.AppendNode(ptEDown);
poly2d.AppendNode(ptSDown);
poly2d.SetClosed();
if(!!poly2d) // add by hh 2011-03-11 增加投影后的Poly2D有效型判断
sectionRecord.push_back(TObjSectionRecord(idObj, idLayer, TObjSectionRecord::eTCH_DBHVACDUCT, dMinDist, poly2d));
}
else // 风管轴向垂直投影面时,把截面圆分解为多边形,并填充内部线
{
int i(0);
double dRotAngle(TAuxTools::GetMinDiffAngle());
int nPartNum = int(PI * 2 / dRotAngle);
if (nPartNum%2 != 0) // 边数要为偶数,才能和填充线准确接合
nPartNum += 1;
dRotAngle = PI * 2 / nPartNum;
AcGePoint3d ptNow;
AcGeVector3d vtNow = vtPlaneSecDir.crossProduct(normal()); // 各实体统一开始点,接口处多边形才吻合
vtNow.normalize();
vtNow *= dRadius;
TGGePoly2D poly2d;
for (i = 0; i < nPartNum; i++)
{
ptNow = ptSNew + vtNow;
poly2d.AppendNode(ptNow);
vtNow.rotateBy(dRotAngle, vtPlaneSecDir);
}
poly2d.SetClosed();
if(!!poly2d) // add by hh 2011-03-11 增加投影后的Poly2D有效型判断
sectionRecord.push_back(TObjSectionRecord(idObj, idLayer, TObjSectionRecord::eTCH_DBHVACDUCT, dMinDist, poly2d));
// 内部填充线
int nLen = poly2d.Length();
if (nLen < 8) // 边数小于8时,填充线接合会不吻合,不绘制
return true;
// 求出两条填充线的首尾点
int nStat1, nStat2;
nStat1 = nLen/8;
nStat2 = nStat1 + nLen/4;
AcGePoint3d ptStat1 = *poly2d.GetAt(nStat1);
AcGePoint3d ptEnd1 = ptStat1;
ptEnd1.rotateBy(PI, vtPlaneSecDir, ptSNew);
AcGePoint3d ptStat2 = *poly2d.GetAt(nStat2);
AcGePoint3d ptEnd2 = ptStat2;
ptEnd2.rotateBy(PI, vtPlaneSecDir, ptSNew);
TSectionFill* pFill = new TSectionFill;
pFill->SetBlockRef(false);
pFill->SetElevation(dMinDist);
pFill->SetLayer(idLayer);
if (eDrawType == eOldStyle) // 老式填充方式中的弧分为多个支线段
{
AcGePoint3d ptArc = ptEnd1;
AcGeVector3d vtOff = ptStat1 - ptEnd1;
ptArc += vtOff * 0.25;
int nPartLine = 10; // 分为10段
AcGeCircArc3d geArc(ptStat2, ptArc, ptEnd2);
double dRadius = geArc.radius();
AcGePoint3d ptCenter = geArc.center();
double dAngle = geArc.endAng() - geArc.startAng();
double dEveAng = dAngle / nPartLine;
AcGeVector3d vtEnd = ptStat2 - ptCenter;
AcGeVector3d vtSta = ptEnd2 - ptCenter;
AcGePoint3d ptNow(ptEnd2) ,ptNext;
if (vtDirect.isCodirectionalTo(vtPlaneSecDir))
ptNow = ptStat2;
int i(0);
for (i = 0; i < nPartLine; i++)
{
ptNext = ptNow;
ptNext.rotateBy(dEveAng, vtDirect, ptCenter);
tgLine.SetPoints(ptNow, ptNext);
pFill->InsertLine(tgLine);
ptNow.rotateBy(dEveAng, vtDirect, ptCenter);
}
}
else
{
tgLine.SetPoints(ptStat2, ptEnd2);
pFill->InsertLine(tgLine);
if (eDrawType == eNewImmit)
{
tgLine.SetPoints(ptStat1, ptEnd1);
pFill->InsertLine(tgLine);
}
}
arFillPtrs.append(pFill);
}
}
else
{
return false;
}
return true;
}
// 求出风管边壁四角线上的点数组,组成四个poly2d,(圆形时两段单独处理下)
/*
↑默认法向
起始端 ptFirst[2] 3━━━━━2列 剖开后网格 0━━1━━━2━━3━━4━━5...
┃ ┃ ┃ ┃ ┃ ┃ ┃
┃ ┃ 0━━1━━━2━━3━━4━━5...
┃ 起始端 ┃ ┃ ┃ ┃ ┃ ┃
┃ ┃ 0━━1━━━2━━3━━4━━5...
┃ ┃ ┃ ┃ ┃ ┃ ┃
4━━━━━1列 ptFirst[0] 0━━1━━━2━━3━━4━━5...
*/
bool THImpHvacDuct::GetArcSection( const AcDbFace &face, const AcGeVector3d &vtPlaneSecDir,
std::vector<TObjSectionRecord> &sectionRecord, AcDbVoidPtrArray& arFillPtrs ) const
{
AcGePoint3d ptS = StartPoint();
AcGePoint3d ptE = EndPoint();
AcGeVector3d vtNormal = normal();
AcGeVector3d vtDirect = ptE - ptS;
vtDirect.normalize();
HvacSectType eSect = TDb::eRectangular;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSect);
double dWidth(0.0), dThick(0.0);
if (TDb::eRectangular == eSect)
{
m_pXDataMap->GetAt(HDCT_Width, dWidth);
m_pXDataMap->GetAt(HDCT_Thick, dThick);
}
else
{
m_pXDataMap->GetAt(HDCT_Diameter, dWidth);
dThick = dWidth;
}
double dBulge(0), dPosiBulge(0);
m_pXDataMap->GetAt(HDCT_Bulge, dBulge);
dPosiBulge = fabs(dBulge);
double dSignAngle = atan(dBulge) * 4;
double dAngle = fabs(dSignAngle);
double dMinAngle(TAuxTools::GetMinDiffAngle());
int nPartNum = int(dAngle / dMinAngle) + 1;
dMinAngle = dSignAngle / nPartNum; // 实际间隔角度
AcGePoint3d ptCenter = GetCirCenter();
AcGeVector3d vtEvery = ptCenter - ptS;
vtEvery.normalize();
AcGePoint3dArray ptArr1, ptArr2, ptArr3, ptArr4;
AcGePoint3d ptFirst[4];
ptFirst[0] = ptS + dWidth * 0.5 * vtEvery - dThick * 0.5 * vtNormal;
ptFirst[1] = ptFirst[0] + dThick * vtNormal;
ptFirst[2] = ptFirst[1] - dWidth * vtEvery;
ptFirst[3] = ptFirst[0] - dWidth * vtEvery;
ptArr1.append(ptFirst[0]);
ptArr2.append(ptFirst[1]);
ptArr3.append(ptFirst[2]);
ptArr4.append(ptFirst[3]);
int i(0);
for (i = 0; i < nPartNum; i++)
{
ptArr1.append(ptArr1.last());
ptArr1.last().rotateBy(dMinAngle, vtNormal, ptCenter);
ptArr2.append(ptArr2.last());
ptArr2.last().rotateBy(dMinAngle, vtNormal, ptCenter);
ptArr3.append(ptArr3.last());
ptArr3.last().rotateBy(dMinAngle, vtNormal, ptCenter);
ptArr4.append(ptArr4.last());
ptArr4.last().rotateBy(dMinAngle, vtNormal, ptCenter);
}
// 前后上下四边面
TGGePoly2D poly2dForce, poly2dBack, poly2dUp, poly2dDown;
for (i = 0; i < ptArr1.length(); i++)
{
poly2dForce.AppendNode(ptArr1[i]);
poly2dDown.AppendNode(ptArr1[i]);
}
for (i = ptArr2.length() - 1; i > -1; i--)
{
poly2dForce.AppendNode(ptArr2[i]);
poly2dUp.AppendNode(ptArr2[i]);
}
for (i = 0; i < ptArr3.length(); i++)
{
poly2dUp.AppendNode(ptArr3[i]);
poly2dBack.AppendNode(ptArr3[i]);
}
for (i = ptArr4.length() - 1; i > -1; i--)
{
poly2dBack.AppendNode(ptArr4[i]);
poly2dDown.AppendNode(ptArr4[i]);
}
poly2dForce.SetClosed();
poly2dBack.SetClosed();
poly2dUp.SetClosed();
poly2dDown.SetClosed();
// test
for (i = 0; i < poly2dForce.Length()-1; i++)
{
AcDbLine* pLine = new AcDbLine(*poly2dForce.GetPointListAt(i), *poly2dForce.GetPointListAt(i+1));
AddToCurrentSpace(pLine, Adesk::kTrue);
}
for (i = 0; i < poly2dBack.Length()-1; i++)
{
AcDbLine* pLine = new AcDbLine(*poly2dBack.GetPointListAt(i), *poly2dBack.GetPointListAt(i+1));
AddToCurrentSpace(pLine, Adesk::kTrue);
}
for (i = 0; i < poly2dUp.Length()-1; i++)
{
AcDbLine* pLine = new AcDbLine(*poly2dUp.GetPointListAt(i), *poly2dUp.GetPointListAt(i+1));
AddToCurrentSpace(pLine, Adesk::kTrue);
}
for (i = 0; i < poly2dDown.Length()-1; i++)
{
AcDbLine* pLine = new AcDbLine(*poly2dDown.GetPointListAt(i), *poly2dDown.GetPointListAt(i+1));
AddToCurrentSpace(pLine, Adesk::kTrue);
}
AcDbObjectId idObj = m_pOwnerEnt->objectId();
AcDbObjectId idLayer = m_pOwnerEnt->layerId();
TGGeSectionPlane section_pln(face, vtPlaneSecDir);
TGGePoly2D poly2Out;
double dMinDist = SectionUtility::Projection_poly2plane(section_pln, poly2dForce, poly2Out);
sectionRecord.push_back(TObjSectionRecord(idObj, idLayer, TObjSectionRecord::eTCH_DBHVACDUCT, dMinDist, poly2Out));
poly2Out.Reset();
dMinDist = SectionUtility::Projection_poly2plane(section_pln, poly2dBack, poly2Out);
sectionRecord.push_back(TObjSectionRecord(idObj, idLayer, TObjSectionRecord::eTCH_DBHVACDUCT, dMinDist, poly2Out));
poly2Out.Reset();
dMinDist = SectionUtility::Projection_poly2plane(section_pln, poly2dUp, poly2Out);
sectionRecord.push_back(TObjSectionRecord(idObj, idLayer, TObjSectionRecord::eTCH_DBHVACDUCT, dMinDist, poly2Out));
poly2Out.Reset();
dMinDist = SectionUtility::Projection_poly2plane(section_pln, poly2dDown, poly2Out);
sectionRecord.push_back(TObjSectionRecord(idObj, idLayer, TObjSectionRecord::eTCH_DBHVACDUCT, dMinDist, poly2Out));
return true;
}
Acad::ErrorStatus THImpHvacDuct::GetExtents( TADSGePoint3d &ptLow, TADSGePoint3d &ptUp ) const
{
if (NULL == m_pXDataMap)
return Acad::eNotImplementedYet;
double dHalfHeigh(0.0);
HvacSectType eSect = TDb::eRectangular;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSect);
if (eSect == eRectangular)
m_pXDataMap->GetAt(HDCT_Thick, dHalfHeigh);
else
m_pXDataMap->GetAt(HDCT_Diameter, dHalfHeigh);
dHalfHeigh *= 0.5;
AcGePoint3d ptSta = StartPoint();
AcGePoint3d ptEnd = EndPoint();
AcGeVector3d vtNormal = normal();
AcGeVector3d vtUcsZ = TAuxTools::GetUcsZvt();
if (ptSta.z < ptEnd.z)
{
ptLow = ptSta;
ptUp = ptEnd;
}
else
{
ptLow = ptEnd;
ptUp = ptSta;
}
if (vtNormal.isParallelTo(vtUcsZ))
{
ptLow -= vtNormal * dHalfHeigh;
ptUp += vtNormal * dHalfHeigh;
}
else /*if (vtNormal.isPerpendicularTo(vtUcsZ))*/ // 立管不用修正,暂不考虑斜管
{
}
return Acad::eOk;
}
BOOL THImpHvacDuct::TransInclSoftDuct(TDbXDataMap& dataMap) const
{
if(NULL == m_pXDataMap)
return FALSE;
// 拷贝原有数据 用于恢复
dataMap.CopyFrom(m_pXDataMap);
// 取得计算数据
double dBulge = 0;
m_pXDataMap->GetAt(HDCT_Bulge, dBulge);
AcGePoint3d ptS = StartPoint();
AcGePoint3d ptE = EndPoint();
AcGeVector3d vtDirect = ptE - ptS;
vtDirect.normalize();
// 计算弧管中点
AcGeVector3d vtLevel = vtDirect;
vtLevel.rotateBy(-PI * 0.5, normal());
vtLevel.normalize();
vtLevel *= ptS.distanceTo(ptE) * 0.5 * dBulge;
AcGePoint3d ptM = ptS + ptS.distanceTo(ptE) * 0.5 * vtDirect;
ptM += vtLevel;
AcGeVector3d vtZ = TAuxTools::GetUcsZvt();
AcGePlane plan(ptM, vtZ);
// 投影弧管三个点到中点所在平面
AcGePoint3d ptPlS = ptS.project(plan, vtZ);
AcGePoint3d ptPlM = ptM.project(plan, vtZ);
AcGePoint3d ptPlE = ptE.project(plan, vtZ);
// 计算投影后平面弧管的曲率
AcGeCircArc3d cirArc(ptPlS, ptPlM, ptPlE);
AcGePoint3d ptccc = cirArc.center();
dBulge = tan((cirArc.endAng() - cirArc.startAng()) * 0.25);
AcGeVector3d vtMid = ptPlM - ptS;
AcGeVector3d vtEnd = ptPlE - ptS;
AcGeVector3d vtCross = vtMid.crossProduct(vtEnd);
if(!vtCross.isCodirectionalTo(TAuxTools::GetUcsZvt()))
dBulge *= -1;
// 倾斜弧管修正为平面弧管
m_pXDataMap->SetAt(HVAC_Normal, vtZ);
m_pXDataMap->SetAt(HDCT_Bulge, dBulge);
m_pXDataMap->SetAt(HDCT_START, ptPlS);
m_pXDataMap->SetAt(HDCT_END, ptPlE);
return TRUE;
}
Acad::ErrorStatus THImpHvacDuct::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 THImpHvacDuct::IsMeClip() const
{
return true;
}
bool THImpHvacDuct::IsClipMe(const TEntityBase* pEnt)const//ok是否被裁剪
{
if(NULL == pEnt)
return true;
//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;
}
// 得到arc和line的交点中,距离pt近的点
bool GetInterPt(AcDbArc &arc, AcDbLine &line, AcGePoint3d &pt)
{
AcGePoint3dArray arPts;
Acad::ErrorStatus es = arc.intersectWith(&line, AcDb::kExtendBoth, arPts);
if (Acad::eOk != es)
return false;
if (arPts.length() == 1)
pt = arPts[0];
else if (2 == arPts.length())
{
if (pt.distanceTo(arPts[0]) < pt.distanceTo(arPts[1]))
pt = arPts[0];
else
pt = arPts[1];
}
else
return false;
return true;
}
// 根据弧管的方向,修正关键的4个点
void THImpHvacDuct::ConverFourKeyPts( AcGePoint3dArray &ptArr) const
{
if(NULL == m_pXDataMap)
return ;
if (!IsArcDuct())
return;
AcGeVector3d vtStaDir, vtEndDir, vtNor(normal());
GetDirect(vtStaDir, vtEndDir);
// 将起止端点方向旋转,得到实际弧管边界方向
vtStaDir.rotateBy(PI*0.5, vtNor);
vtEndDir.rotateBy(PI*0.5, vtNor);
AcGePoint3d ptStart(StartPoint()), ptEnd(EndPoint()), ptInter;
AcDbLine staline(ptStart, ptStart+vtStaDir);
AcDbLine endline(ptEnd, ptEnd+vtEndDir);
AcDbArc arc;
InitArc(arc);
double dWidth(0.0);
m_pXDataMap->GetAt(HDCT_Width, dWidth);
double dOrgRadius = arc.radius();
// 原风管外边线
arc.setRadius(dOrgRadius + dWidth*0.5);
// 纠正ptArr[0]
if (!GetInterPt(arc, staline, ptArr[0]))
return;
// 纠正ptArr[1]
if (!GetInterPt(arc, endline, ptArr[1]))
return;
// 原风管内边线
arc.setRadius(dOrgRadius - dWidth*0.5);
// 纠正ptArr[2]
if (!GetInterPt(arc, endline, ptArr[2]))
return;
// 纠正ptArr[3]
if (!GetInterPt(arc, staline, ptArr[3]))
return;
}
void THImpHvacDuct::DisPoseArcPoint(AcGePoint3dArray& ptArr, AcGePoint3d ptC, AcGeVector3d vtNor) const
{
AcGePoint3d ptOne, ptOther;
AcGeVector3d vtOne,vtOther;
AcGePoint3dArray ptArrTemp;
AcGePoint3d ptIns,ptM;
HvacDuctType eDuctType = eStraight;
m_pXDataMap->GetAt(HDCT_Type, (int&)eDuctType);
for (int i = 0; i < ptArr.length()-1; ++i)
{
ptOne = ptArr[i];
ptOther = ptArr[i+1];
if (eDuctType == eStraight)
{
Midpoint(ptOne, ptOther, ptIns);
// 将起止端点方向旋转,得到实际弧管边界方向
AcGeVector3d vtTemp = ptOther - ptOne;
vtTemp.rotateBy(PI/2, vtNor);
vtTemp.normalize();
if (i%2 == 0)
ptM = ptIns + ptIns.distanceTo(ptOne)*vtTemp;
else
ptM = ptIns - ptIns.distanceTo(ptOne)*vtTemp;
}
else
{
vtOne = ptOne - ptC;
vtOther = ptOther - ptC;
double dA = vtOne.angleTo(vtOther, vtNor);
AcGeVector3d vtTemp(vtOne);
// 将起止端点方向旋转,得到实际弧管边界方向
vtOne.rotateBy(PI*0.5, vtNor);
vtOther.rotateBy(PI*0.5, vtNor);
vtOne.normalize();
vtOther.normalize();
AcDbLine staline(ptOne, ptOne + vtOne);
AcDbLine endline(ptOther, ptOther + vtOther);
AcGePoint3dArray arPts;
Acad::ErrorStatus es = staline.intersectWith(&endline, AcDb::kExtendBoth, arPts);
if (Acad::eOk != es)
return;
if (arPts.length() == 1)
ptIns = arPts[0];
vtTemp = vtTemp.rotateBy(dA/2, vtNor);
vtTemp.normalize();
if (i%2 != 0)
ptM = ptIns + ptIns.distanceTo(ptOne)*vtTemp;
else
ptM = ptIns - ptIns.distanceTo(ptOne)*vtTemp;
}
ptArrTemp.append(ptOne);
ptArrTemp.append(ptM);
}
ptArrTemp.append(ptOther);
ptArr = ptArrTemp;
}
BOOL THImpHvacDuct::MakeRealHorzSoft2DCurves( TComplexCurve& cplCurve, int nOutOrIn ) const
{
ASSERT(NULL != m_pXDataMap);
double dBulge(0);
m_pXDataMap->GetAt(HDCT_Bulge, dBulge);
TCurveElement tCurveEle;
memset(&tCurveEle, 0, sizeof(TCurveElement));
tCurveEle.bHided = FALSE;
tCurveEle.dWidth = 0.0;
tCurveEle.gsMark = 0;
double dWidth(0.0);
m_pXDataMap->GetAt(HDCT_Width, dWidth);
AcGePoint3d ptS = StartPoint();
AcGePoint3d ptE = EndPoint();
AcGeVector3d vtDirect = ptE - ptS;
AcGeVector3d vtNormal = TAuxTools::GetUcsZvt();
vtDirect.normalize();
AcGeVector3d vtLevel = (ptE - ptS) * 0.5; // 水平法向辅助求点用
vtLevel.rotateBy(-PI * 0.5, vtNormal);
vtLevel *= dBulge;
AcGePoint3d ptMid = ptS + ptS.distanceTo(ptE) * 0.5 * vtDirect;
AcGePoint3d ptArcMid = ptMid + vtLevel; // 圆弧中点
double dEdgeWidth = GetEdgeLineWidth();
BOOL bBaseLine(FALSE);
m_pXDataMap->GetAt(HVAC_HasBaseLine, bBaseLine);
//
AcGePoint3dArray ptArrTop, ptArrBott;
double dPara = 100.0; // 按距离100划分
int i(0),nNum(0);
HvacDuctType eDuctType = eStraight;
m_pXDataMap->GetAt(HDCT_Type, (int&)eDuctType);
AcGePoint3d ptC;
if (eDuctType == eStraight)
{
ptArcMid = ptE;
double dLen = ptS.distanceTo(ptE);
nNum = int(dLen/dPara);
AcGeVector3d vecTemp = ptE-ptS;
vecTemp.normalize();
AcGeVector3d vt(vecTemp);
AcGeVector3d vtN = vecTemp.rotateBy(PI/2.0, vtNormal);
vtN.normalize();
AcGePoint3d ptTemp;
ptTemp = ptS + vtN * (dWidth/2);
ptArrTop.append(ptTemp);
ptTemp = ptS + vtN * (-dWidth/2);
ptArrBott.append(ptTemp);
AcGePoint3d ptTemp1;
for (i = 0; i < nNum; i++)
{
ptTemp1 = ptS + vt * dPara * (i+1);
ptTemp = ptTemp1 + vtN * (dWidth/2);
ptArrTop.append(ptTemp);
ptTemp = ptTemp1 + vtN * (-dWidth/2);
ptArrBott.append(ptTemp);
}
if (dLen - nNum*dPara != 0)
{
ptTemp1 = ptS + vt * dLen;
ptTemp = ptTemp1+ vecTemp * (dWidth/2);
ptArrTop.append(ptTemp);
ptTemp = ptTemp1 + vecTemp * (-dWidth/2);
ptArrBott.append(ptTemp);
}
}
else
{
ptC = GetCirCenter();
double dR = GetRadius();
double dAngle = atan(dBulge) * 4;;
double dArcLen = fabs(dAngle*dR);
nNum = int(dArcLen/dPara);
double dPerA = dPara*dAngle/dArcLen;
AcGeVector3d vecTemp = ptS - ptC;
vecTemp.normalize();
AcGePoint3d ptTemp;
ptTemp = ptC + vecTemp * (dR+dWidth/2);
ptArrTop.append(ptTemp);
ptTemp = ptC + vecTemp * (dR-dWidth/2);
ptArrBott.append(ptTemp);
for (i = 0; i < nNum; i++)
{
vecTemp = vecTemp.rotateBy(dPerA, vtNormal);
vecTemp.normalize();
ptTemp = ptC + vecTemp * (dR+dWidth/2);
ptArrTop.append(ptTemp);
ptTemp = ptC + vecTemp * (dR-dWidth/2);
ptArrBott.append(ptTemp);
}
if (dArcLen - nNum*dPara != 0)
{
double dLast = dArcLen - nNum*dPara;
dPerA = dLast*dAngle/dArcLen;
vecTemp = vecTemp.rotateBy(dPerA, vtNormal);
vecTemp.normalize();
ptTemp = ptC + vecTemp * (dR+dWidth/2);
ptArrTop.append(ptTemp);
ptTemp = ptC + vecTemp * (dR-dWidth/2);
ptArrBott.append(ptTemp);
}
}
DisPoseArcPoint(ptArrTop, ptC, vtNormal);
DisPoseArcPoint(ptArrBott, ptC, vtNormal);
//
if (IsSingleLine())
{
tCurveEle.ptGe[0] = ptS;
tCurveEle.ptGe[1] = ptArcMid;
tCurveEle.ptGe[2] = ptE;
tCurveEle.dWidth = dEdgeWidth;
cplCurve.append(tCurveEle);
return TRUE;
}
if (nOutOrIn == 1 && bBaseLine)
{
int n = 3;
while(n < ptArrTop.length())
{
tCurveEle.dWidth = GetCentLineWidth();
if (dBulge > 0)
{
tCurveEle.ptGe[0] = ptArrBott[n];
tCurveEle.ptGe[1] = ptArrTop[n-2];
tCurveEle.ptGe[2] = ptArrTop[n-2];
}
else
{
tCurveEle.ptGe[0] = ptArrTop[n];
tCurveEle.ptGe[1] = ptArrBott[n-2];
tCurveEle.ptGe[2] = ptArrBott[n-2];
}
cplCurve.append(tCurveEle);
n = n+4;
}
if (bBaseLine)
{
double dCentWidth = GetCentLineWidth();
tCurveEle.dWidth = dCentWidth;
tCurveEle.ptGe[0] = ptS;
tCurveEle.ptGe[1] = ptArcMid;
tCurveEle.ptGe[2] = ptE;
tCurveEle.idSubLay = GetBaseLayerId();
cplCurve.append(tCurveEle);
}
}
else if (nOutOrIn == 0) // 边线及两端
{
double dEndWidth = GetEndLineWidth();
AcDbObjectId idSideLayer(NULL);
m_pXDataMap->GetAt(HVAC_EndLayer, idSideLayer);
for (i = 0; i < ptArrTop.length()- 2; ++i)
{
tCurveEle.dWidth = dEdgeWidth;
tCurveEle.ptGe[0] = ptArrTop[i];
tCurveEle.ptGe[1] = ptArrTop[i+1];
tCurveEle.ptGe[2] = ptArrTop[i+2];
cplCurve.append(tCurveEle);
i = i+1;
}
if (!IsEdgeEnd())
{
tCurveEle.ptGe[0] = ptArrTop[ptArrTop.length()-1];
tCurveEle.ptGe[1] = ptArrBott[ptArrBott.length()-1];
tCurveEle.ptGe[2] = ptArrBott[ptArrBott.length()-1];
tCurveEle.idSubLay = idSideLayer;
tCurveEle.dWidth = dEndWidth;
cplCurve.append(tCurveEle);
}
for (i = 0; i < ptArrBott.length()- 2; ++i)
{
tCurveEle.idSubLay.setNull();
tCurveEle.dWidth = dEdgeWidth;
tCurveEle.ptGe[0] = ptArrBott[i];
tCurveEle.ptGe[1] = ptArrBott[i+1];
tCurveEle.ptGe[2] = ptArrBott[i+2];
cplCurve.append(tCurveEle);
i = i+1;
}
if (!IsEdgeStart())
{
tCurveEle.ptGe[0] = ptArrTop[0];
tCurveEle.ptGe[1] = ptArrBott[0];
tCurveEle.ptGe[2] = ptArrBott[0];
tCurveEle.idSubLay = idSideLayer;
tCurveEle.dWidth = dEndWidth;
cplCurve.append(tCurveEle);
}
}
return TRUE;
}
BOOL THImpHvacDuct::IsEdgeStart() const
{
ASSERT(NULL != m_pXDataMap);
BOOL bNoCheck(FALSE), bHide(FALSE);
GetGlobalContext()->GetAt(HVAC_IsExplodeDraw, bNoCheck);
if (bNoCheck)
{
m_pXDataMap->GetAt(HDCT_HIDEEND, bHide);
return bHide;
}
TInterface tIf;
AcDbObjectId idCon(AcDbObjectId::kNull);
if (GetInterface(0, tIf))
{
idCon = tIf.GetConnectObject();
if (!idCon.isValid())
{
m_pXDataMap->SetAt(HDCT_HIDEEND, FALSE);
return FALSE;
}
}
OPENOBJ_BEGIN(idCon, AcDb::kForRead, TDbHvacDuct, pDuct);
if (NULL != pDuct)
{
TDbXDataMap* pMap = pDuct->GetSpecialtyData();
if (NULL != pMap)
{
AcGePoint3d ptIf = tIf.GetPosition();
AcGePoint3d ptSta, ptEnd;
pMap->GetAt(KEY_START, ptSta);
pMap->GetAt(KEY_END, ptEnd);
if (ptIf == ptSta || ptIf == ptEnd)
bHide = TRUE;
}
}
OPENOBJ_END();
OPENOBJ_BEGIN(idCon, AcDb::kForRead, TDbHvacDuct, pDuct);
if (NULL != pDuct)
{
TDbXDataMap* pMap = pDuct->GetSpecialtyData();
if (NULL != pMap)
{
AcGePoint3d ptIf = tIf.GetPosition();
AcGePoint3d ptSta, ptEnd;
pMap->GetAt(KEY_START, ptSta);
pMap->GetAt(KEY_END, ptEnd);
if (ptIf == ptSta || ptIf == ptEnd)
bHide = TRUE;
}
}
OPENOBJ_END();
OPENOBJ_BEGIN(idCon, AcDb::kForRead, TDbHvacFitting, pFit);
if (NULL != pFit)
{
TDbXDataMap* pMap = pFit->GetSpecialtyData();
if (NULL != pMap)
{
AcGePoint3d ptIf = tIf.GetPosition();
ObjectKind eKind;
pMap->GetAt(KEY_RUNTIME, (int&)eKind);
if (eKind == eTee)
{
HvacTeeType eTeeType = eOrthoBranch;
pMap->GetAt(HTEE_Type, (int&)eTeeType);
if (eTeeType == eInsertIntubBranch || eTeeType == eArcuateIntubBranch)
{
AcGePoint3d ptSta, ptEnd;
pMap->GetAt(HTEE_StartPoint, ptSta);
pMap->GetAt(HTEE_EndPoint, ptEnd);
if (ptIf == ptSta || ptIf == ptEnd)
bHide = TRUE;
}
}
else if (eKind == eCross)
{
HvacCrossType eCorssType = eOrthoCross;
pMap->GetAt(HCRS_Type, (int &)eCorssType);
if (eCorssType == eInsertIntubCross|| eCorssType == eArcuateIntubCross)
{
AcGePoint3d ptSta, ptEnd;
pMap->GetAt(HCRS_StartPoint, ptSta);
pMap->GetAt(HCRS_EndPoint, ptEnd);
if (ptIf == ptSta || ptIf == ptEnd)
bHide = TRUE;
}
}
else if (eKind == eBroSymbol)
{
AcGePoint3d ptIns;
pMap->GetAt(HBSM_InsertPoint, ptIns);
if (ptIf == ptIns)
bHide = TRUE;
}
}
}
OPENOBJ_END();
m_pXDataMap->SetAt(HDCT_HIDEEND, bHide);
return bHide;
}
BOOL THImpHvacDuct::IsEdgeEnd() const
{
ASSERT(NULL != m_pXDataMap);
BOOL bNoCheck(FALSE), bHide(FALSE);
GetGlobalContext()->GetAt(HVAC_IsExplodeDraw, bNoCheck);
if (bNoCheck)
{
m_pXDataMap->GetAt(HDCT_HIDEEND, bHide);
return bHide;
}
TInterface tIf;
AcDbObjectId idCon(AcDbObjectId::kNull);
if (GetInterface(1, tIf))
{
idCon = tIf.GetConnectObject();
if (!idCon.isValid())
{
m_pXDataMap->SetAt(HDCT_HIDEEND, FALSE);
return FALSE;
}
}
OPENOBJ_BEGIN(idCon, AcDb::kForRead, TDbHvacDuct, pDuct);
if (NULL != pDuct)
{
TDbXDataMap* pMap = pDuct->GetSpecialtyData();
if (NULL != pMap)
{
AcGePoint3d ptIf = tIf.GetPosition();
AcGePoint3d ptSta, ptEnd;
pMap->GetAt(KEY_START, ptSta);
pMap->GetAt(KEY_END, ptEnd);
if (ptIf == ptSta || ptIf == ptEnd)
bHide = TRUE;
}
}
OPENOBJ_END();
OPENOBJ_BEGIN(idCon, AcDb::kForRead, TDbHvacFitting, pFit);
if (NULL != pFit)
{
TDbXDataMap* pMap = pFit->GetSpecialtyData();
if (NULL != pMap)
{
AcGePoint3d ptIf = tIf.GetPosition();
ObjectKind eKind;
pMap->GetAt(KEY_RUNTIME, (int&)eKind);
if (eKind == eTee)
{
HvacTeeType eTeeType = eOrthoBranch;
pMap->GetAt(HTEE_Type, (int&)eTeeType);
if (eTeeType == eInsertIntubBranch || eTeeType == eArcuateIntubBranch)
{
AcGePoint3d ptSta, ptEnd;
pMap->GetAt(HTEE_StartPoint, ptSta);
pMap->GetAt(HTEE_EndPoint, ptEnd);
if (ptIf == ptSta || ptIf == ptEnd)
bHide = TRUE;
}
}
else if (eKind == eCross)
{
HvacCrossType eCorssType = eOrthoCross;
pMap->GetAt(HCRS_Type, (int &)eCorssType);
if (eCorssType == eInsertIntubCross|| eCorssType == eArcuateIntubCross)
{
AcGePoint3d ptSta, ptEnd;
pMap->GetAt(HCRS_StartPoint, ptSta);
pMap->GetAt(HCRS_EndPoint, ptEnd);
if (ptIf == ptSta || ptIf == ptEnd)
bHide = TRUE;
}
}
else if (eKind == eBroSymbol)
{
AcGePoint3d ptIns;
pMap->GetAt(HBSM_InsertPoint, ptIns);
if (ptIf == ptIns)
bHide = TRUE;
}
}
}
OPENOBJ_END();
m_pXDataMap->SetAt(HDCT_HIDEEND, bHide);
return bHide;
}