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

4332 lines
120 KiB
C++

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