Files
envi-code/SourceCode/Code2026/CoreLibrary/Implement/i_ImpHvacOffset.cpp
T
2026-09-28 15:28:50 +08:00

1738 lines
48 KiB
C++

#include "stdafx.h"
#include "ImpHvacOffset.h"
#include "AuxTools.h"
#include "AecDbEntityBase.h"
using namespace AecEqui;
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( AecComplexCurve &cplCurve, AecCurveElement &cplEle,
const AcGePoint3d &ptS, const AcGePoint3d &ptMid, const AcGePoint3d &ptE )
{
cplEle.ptGe[0] = ptS;
cplEle.ptGe[1] = ptMid;
cplEle.ptGe[2] = ptE;
return cplCurve.append(cplEle);
}
ImpHvacOffset::ImpHvacOffset()
{
m_pXDataMap = NULL;
m_pOwnerEnt = NULL;
}
ImpHvacOffset::~ImpHvacOffset()
{
}
void ImpHvacOffset::list() const
{
ASSERT(NULL != m_pXDataMap);
// 管件类型
acutPrintf(_T("\n\t\t\t\t\t\t\t\t\t\t\t 暖通:乙字弯"));
// 截面类型
ESection eSectType = eRect;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType);
switch (eSectType)
{
case eRect: acutPrintf(_T("\n\t\t\t\t\t\t\t\t\t\t\t 截面:矩形")); break;
case eCircle: acutPrintf(_T("\n\t\t\t\t\t\t\t\t\t\t\t 截面:圆形")); break;
case eOblate: acutPrintf(_T("\n\t\t\t\t\t\t\t\t\t\t\t 截面:扁圆形")); break;
}
// 圆型截面显示直径
if ( eCircle == 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);
}
AecEqui::Position ImpHvacOffset::ExplainGripIndex( int nIndex ) const
{
AecEqui::Position ePos = AecEqui::eStart;
switch(nIndex)
{
case 0:
ePos = AecEqui::eStart;
break;
case 1:
ePos = AecEqui::eEnd;
break;
case 2:
ePos = AecEqui::eCommand0;
break;
case 3:
ePos = AecEqui::eCommand1;
break;
default:
break;
}
return ePos;
}
Acad::ErrorStatus ImpHvacOffset::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);
return Acad::eOk;
}
AcGeVector3d ImpHvacOffset::StartVect() const
{
ASSERT(NULL != m_pXDataMap);
AcGeVector3d vtSta(AcGeVector3d::kIdentity);
if (NULL != m_pXDataMap)
m_pXDataMap->GetAt(HOFF_StartDir, vtSta);
return vtSta;
}
AcGeVector3d ImpHvacOffset::EndVect() const
{
ASSERT(NULL != m_pXDataMap);
AcGeVector3d vtEnd(AcGeVector3d::kIdentity);
if (NULL != m_pXDataMap)
m_pXDataMap->GetAt(HOFF_EndDir, vtEnd);
return vtEnd;
}
AcGeVector3d ImpHvacOffset::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 ImpHvacOffset::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 ImpHvacOffset::IsSideVertAlignment() const
{
ASSERT(NULL != m_pXDataMap);
AcGeVector3d vtUserZAxis = TAuxTools::GetUcsZvt();
return StartVect().isParallelTo(vtUserZAxis);
}
BOOL ImpHvacOffset::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 ImpHvacOffset::IsSingleLine() const
{
ASSERT(NULL != m_pXDataMap);
BOOL bSingleLine = FALSE;
m_pXDataMap->GetAt(HVAC_IsSingleLine, (int&)bSingleLine);
return bSingleLine;
}
BOOL ImpHvacOffset::IsBaseLine() const
{
ASSERT(NULL != m_pXDataMap);
BOOL bBaseLine = FALSE;
m_pXDataMap->GetAt(HVAC_HasBaseLine, (int&)bBaseLine);
return bBaseLine;
}
Acad::ErrorStatus ImpHvacOffset::Draw3d( AcGiDraw &mode ) const
{
if (NULL == m_pXDataMap)
return Acad::eNotImplementedYet;
if (!IsCanDraw())
return Acad::eNotImplementedYet;
AecHvac::HvacOffsetType eType =AecHvac::eArcuateLink;
ESection eSectType = eRect;
m_pXDataMap->GetAt(HOFF_Type, (int&)eType);
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType);
if (eType ==AecHvac::eArcuateLink)
{
if (eSectType == eRect)
return DrawRectArcuate3d(mode);
else if (eSectType ==eCircle)
return DrawCircleArcuate3d(mode);
}
else if (eType ==AecHvac::eLinearLink)
{
if (eSectType == eRect)
return DrawRectLinear3d(mode);
else if (eSectType ==eCircle)
return DrawCircleLinear3d(mode);
}
return Acad::eNotImplementedYet;
}
BOOL ImpHvacOffset::DrawMesh(AcGiDraw &mode,const Adesk::UInt32 rows,const Adesk::UInt32 columns,const AcGePoint3d* pVertexList) const
{
AcGePoint3dArray vertexArray;
AcArray<Adesk::Int32> faceArray;
int nV0 = 0,nV1 = 0,nV2 = 0;
int nV3= 0;
int nFaceIndex = 0;
AcGePoint3d ptFace[4];
for (int i = 0;i < rows - 1;i++)
{
for (int j = 0;j < columns - 1;j++)
{
nV0 = i * columns + j;
nV1 = nV0 + 1;
//第二行,第一个
nV2 = (i + 1) * columns + j;
nV3 = nV2 + 1;
//三角:nV0-nV1-nV2
faceArray.append(3);
faceArray.append(nV0);//v0
faceArray.append(nV1);//v1
faceArray.append(nV2);//v2
ptFace[0] = pVertexList[nV0];
ptFace[1] = pVertexList[nV1];
ptFace[2] = pVertexList[nV2];
ptFace[3] = ptFace[0];
//mode.DrawFace(ptFace);
//三角:nV2-nV1-nV3
faceArray.append(3);
faceArray.append(nV2);//v2
faceArray.append(nV1);//v1
faceArray.append(nV3);//v3
ptFace[0] = pVertexList[nV2];
ptFace[1] = pVertexList[nV1];
ptFace[2] = pVertexList[nV3];
ptFace[3] = ptFace[0];
//mode.DrawFace(ptFace);
}
}
if (!faceArray.isEmpty())
{
int nIndex = 0;
for (int i = 0;i < rows;i++)
{
for (int j = 0;j < columns;j++)
{
nIndex = i * columns + j;
vertexArray.append(pVertexList[nIndex]);
}
}
AcDbSubDMesh* pSubMesh = new AcDbSubDMesh;
if ( Acad::eOk == pSubMesh->setSubDMesh(vertexArray,faceArray,0) )
{
mode.DrawEntity(pSubMesh);
m_ar3DDrableBufPtrs_.append(pSubMesh);
//有时候失败?
/*Acad::ErrorStatus es;
AcDb3dSolid* pSolid = new AcDb3dSolid;
if ( Acad::eOk == (es = pSubMesh->convertToSolid(false,false,pSolid) ) )
{
mode.DrawEntity(pSolid);
}
delete pSubMesh;
*/
return TRUE;
}
delete pSubMesh;
}
mode.DrawMeshS (rows,columns,pVertexList,false);
return FALSE;
}
BOOL ImpHvacOffset::DrawShell(AcGiDraw &mode,const Adesk::UInt32 nbVertex,const AcGePoint3d* pVertexList,const Adesk::UInt32 faceListSize,const Adesk::Int32* pFaceList) const
{
AcGePoint3dArray vertexArray;
AcArray<Adesk::Int32> faceArray;
for(int i = 0;i < nbVertex;i++)
{
vertexArray.append(pVertexList[i]);
}
for (int j = 0;j < faceListSize;j++)
{
faceArray.append(pFaceList[j]);
}
AcDbSubDMesh* pSubMesh = new AcDbSubDMesh;
if ( Acad::eOk == pSubMesh->setSubDMesh(vertexArray,faceArray,0) )
{
mode.DrawEntity(pSubMesh);
m_ar3DDrableBufPtrs_.append(pSubMesh);
//有时候失败?
/*Acad::ErrorStatus es;
AcDb3dSolid* pSolid = new AcDb3dSolid;
if ( Acad::eOk == (es = pSubMesh->convertToSolid(false,false,pSolid) ) )
{
mode.DrawEntity(pSolid);
}
delete pSubMesh;
*/
return TRUE;
}
delete pSubMesh;
mode.DrawShell (nbVertex,pVertexList,faceListSize,pFaceList);
return FALSE;
}
void ImpHvacOffset::Move3DBuffer(AcDbVoidPtrArray& ar3DBuffer) const
{
if (!m_ar3DDrableBufPtrs_.isEmpty())
{
ar3DBuffer.append(m_ar3DDrableBufPtrs_);
m_ar3DDrableBufPtrs_.removeAll();
}
}
bool ImpHvacOffset::Has3DBuffer() const
{
return !m_ar3DDrableBufPtrs_.isEmpty();
}
Acad::ErrorStatus ImpHvacOffset::Draw2d( AcGiDraw &mode ) const
{
if (NULL == m_pXDataMap)
return Acad::eNotImplementedYet;
AecComplexCurve cplCurve;
MakeCurves(cplCurve);
AecComplexCurveDraw edage;
edage.SetEdage(cplCurve);
AcDbObjectId idReal = m_idDoubleLayer;
AcDbObjectId idDash = m_idDashLayer;
AcDbObjectId idCent = m_idCenterLayer;
edage.Draw2d(mode,idReal,idDash,idCent,NULL,FALSE,FALSE);
AecComplexCurve cplCen;
GetCurvesInSide(cplCen);
edage.SetEdage(cplCen);
edage.Draw2d(mode,idReal,idDash,idCent,NULL,FALSE,FALSE);
return Acad::eOk;
}
BOOL ImpHvacOffset::MakeCurves( AecComplexCurve& compCurve ) const
{
if (NULL == m_pXDataMap)
return FALSE;
if (!IsSingleLine() && !IsCanDraw())
return FALSE;
if (IsHorzAlignment())
{
AecHvac::HvacOffsetType eType =AecHvac::eArcuateLink;
m_pXDataMap->GetAt(HOFF_Type, (int&)eType);
if (eType ==AecHvac::eArcuateLink)
return MakeHorizArcuate2DCurves(compCurve, 0);
else if (eType ==AecHvac::eLinearLink)
return MakeHorizLinear2DCurves(compCurve, 0);
}
else if (IsSideVertAlignment())
{
ESection eSectType = eRect;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType);
if (eSectType == eRect)
return MakeSideVertRect2DCurves(compCurve, 0);
else if (eSectType ==eCircle)
return MakeSideVertCircle2DCurves(compCurve, 0);
}
else if (IsFaceVertAlignment())
{
return MakeFaceVert2DCurves(compCurve, 0);
}
return FALSE;
}
BOOL ImpHvacOffset::GetCurvesInSide( AecComplexCurve& compCurve ) const
{
if (NULL == m_pXDataMap)
return FALSE;
if (!IsSingleLine() && !IsCanDraw())
return FALSE;
if (IsHorzAlignment())
{
AecHvac::HvacOffsetType eType = AecHvac::eArcuateLink;
m_pXDataMap->GetAt(HOFF_Type, (int&)eType);
if (eType == AecHvac::eArcuateLink)
return MakeHorizArcuate2DCurves(compCurve, 1);
else if (eType == AecHvac::eLinearLink)
return MakeHorizLinear2DCurves(compCurve, 1);
}
else if (IsSideVertAlignment())
{
ESection eSectType = eRect;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType);
if (eSectType == eRect)
return MakeSideVertRect2DCurves(compCurve, 1);
else if (eSectType == eCircle)
return MakeSideVertCircle2DCurves(compCurve, 1);
}
else if (IsFaceVertAlignment())
{
return MakeFaceVert2DCurves(compCurve, 1);
}
return FALSE;
}
Acad::ErrorStatus ImpHvacOffset::DrawRectArcuate3d( AcGiDraw &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);
}
DrawMesh(mode,ptLeftArr.length(), 5, ptMeshArr.asArrayPtr());
return Acad::eOk;
}
Acad::ErrorStatus ImpHvacOffset::DrawRectLinear3d( AcGiDraw &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]);
DrawMesh(mode,4, 5, ptMeshArr.asArrayPtr());
return Acad::eOk;
}
// 先找出左右两侧弧所有最小分度角点,然后循环求出每段圆中各分度角点
Acad::ErrorStatus ImpHvacOffset::DrawCircleArcuate3d( AcGiDraw &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]);
}
DrawMesh(mode,ptLeftArr.length(), nCirclePart + 1, ptArrMesh.asArrayPtr());
return Acad::eOk;
}
Acad::ErrorStatus ImpHvacOffset::DrawCircleLinear3d( AcGiDraw &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);
}
DrawMesh(mode,nPart + 1, 4, ptMeshArr.asArrayPtr());
return Acad::eOk;
}
// 按两个弯头连接,有变径时在起始端半部变
BOOL ImpHvacOffset::MakeHorizArcuate2DCurves( AecComplexCurve& cplCurve, const int &nOutOrIn ) const
{
AecCurveElement tCurveEle;
memset(&tCurveEle, 0, sizeof(AecCurveElement));
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 ImpHvacOffset::MakeHorizLinear2DCurves( AecComplexCurve& cplCurve, const int &nOutOrIn ) const
{
AecCurveElement tCurveEle;
memset(&tCurveEle, 0, sizeof(AecCurveElement));
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 ImpHvacOffset::MakeSideVertRect2DCurves( AecComplexCurve& cplCurve, const int &nOutOrIn ) const
{
AecCurveElement tCurveEle;
memset(&tCurveEle, 0, sizeof(AecCurveElement));
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;
tCurveEle.idSubLay = m_idCenterLayer;
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 = m_idCenterLayer;
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 ImpHvacOffset::MakeSideVertCircle2DCurves( AecComplexCurve& cplCurve, const int &nOutOrIn ) const
{
AecCurveElement tCurveEle;
memset(&tCurveEle, 0, sizeof(AecCurveElement));
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 ImpHvacOffset::MakeFaceVert2DCurves( AecComplexCurve& cplCurve, const int &nOutOrIn ) const
{
AecCurveElement tCurveEle;
memset(&tCurveEle, 0, sizeof(AecCurveElement));
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;
tCurveEle.idSubLay = m_idCenterLayer;
AutoAppendPt(cplCurve, tCurveEle, ptStart.orthoProject(planStd),
ptEnd.orthoProject(planStd), ptEnd.orthoProject(planStd));
return Acad::eOk;
}
if (nOutOrIn == 1)
{
if (IsBaseLine())
{
tCurveEle.dWidth = dCentWidth;
tCurveEle.idSubLay = m_idCenterLayer;
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) // 起始点流向终点
{
// 注:乙字弯的流向在外部没有使用,所以暂未考虑逆向的画法
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;
}
}
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)
{
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) // 起始点流向终点
{
// 注:乙字弯的流向在外部没有使用,所以暂未考虑逆向的画法
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;
}
/*
0━7
┃ \
┃ \
S ┃ \
┃ \
┃ \
1━2 6━ 5
\ ┃
\ ┃
\ ┃
\ ┃ E
\ ┃
3━4
*/
void ImpHvacOffset::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)
{
m_pXDataMap->GetAt(KEY_HIDEWIDTH, dStaWidth); // 遮挡宽度
dEndWidth = dStaWidth;
}
else
{
m_pXDataMap->GetAt(HOFF_StartWidth, dStaWidth);
m_pXDataMap->GetAt(HOFF_EndWidth, dEndWidth);
ESection eSectType = eRect;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType);
if (eSectType ==eCircle)
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 ImpHvacOffset::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);
ESection eSect = eRect;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSect);
if (eSect ==eCircle)
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 ImpHvacOffset::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 ImpHvacOffset::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)
{
m_pXDataMap->GetAt(KEY_HIDEWIDTH, dHalfStartWidth); // 遮挡宽度
dHalfEndWidth = dHalfStartWidth;
}
else
{
m_pXDataMap->GetAt(HOFF_StartWidth, dHalfStartWidth);
m_pXDataMap->GetAt(HOFF_EndWidth, dHalfEndWidth);
ESection eSectType = eRect;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType);
if (eSectType ==eCircle)
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 ImpHvacOffset::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 ImpHvacOffset::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;
AecHvac::HvacOffsetType eType =AecHvac::eArcuateLink;
m_pXDataMap->GetAt(HOFF_Type, (int&)eType);
if (eType ==AecHvac::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;
}
AcDbObjectId ImpHvacOffset::GetBaseLayerId() const
{
return m_idDoubleLayer;
}
double ImpHvacOffset::GetEdgeLineWidth() const
{
ASSERT(NULL != m_pXDataMap);
double dWidth(0.0);
m_pXDataMap->GetAt(HVAC_EdgeWidth, dWidth);
return dWidth;
}
double ImpHvacOffset::GetCentLineWidth() const
{
ASSERT(NULL != m_pXDataMap);
double dWidth(0.0);
m_pXDataMap->GetAt(HVAC_CentWidth, dWidth);
return dWidth;
}
double ImpHvacOffset::GetEndLineWidth() const
{
ASSERT(NULL != m_pXDataMap);
double dWidth(0.0);
m_pXDataMap->GetAt(HVAC_EndWidth, dWidth);
return dWidth;
}
double ImpHvacOffset::GetAngle() const
{
ASSERT(NULL != m_pXDataMap);
// 基本参数
AecHvac::HvacOffsetType eType = AecHvac::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 (AecHvac::eArcuateLink == eType)
{
dAngle = PI*0.5 - dAngle;
dAngle = PI - dAngle * 2;
}
return dAngle;
}
AcGePoint3d ImpHvacOffset::GetEndPointByAngle()
{
ASSERT(NULL != m_pXDataMap);
// 基本参数
AecHvac::HvacOffsetType eType = AecHvac::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 (AecHvac::eArcuateLink == eType) // 双弧Angle:表示弯头角度
dHorizLen = dPerlDist / tan(dAngle * 0.5); // 水平偏移距离
else if (AecHvac::eLinearLink == eType) // 角接时,dAngle:表示倾斜角度
dHorizLen = dPerlDist / tan(dAngle);
AcGePoint3d ptArcSta = ptStart - dFlangPlus * vtStart;// 弧开始点
ptEnd = ptArcSta + vtOffSet - (dHorizLen + dFlangPlus) * vtStart;
return ptEnd;
}
AcGePoint3d ImpHvacOffset::GetEndPtByLength()
{
ASSERT(NULL != m_pXDataMap);
// 基本参数
AecHvac::HvacOffsetType eType = AecHvac::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 (AecHvac::eArcuateLink == eType)
dAngle *= 2;
m_pXDataMap->SetAt(HOFF_Angle, dAngle);
return GetEndPointByAngle();
}
return AcGePoint3d::kOrigin;
}
BOOL ImpHvacOffset::GetInterfaceSizeData(int nIndex, AecInterface& inf) const
{
if(NULL == m_pXDataMap)
return FALSE;
// 获取截面类型
ESection eSectType = eRect;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType);
// 获取接口截面、宽度、厚度数据key值
LPCTSTR pszWidthKey, pszThickKey;
switch (nIndex)
{
case 0:
pszWidthKey = ((eCircle == eSectType) ? HOFF_Diameter : HOFF_StartWidth);
pszThickKey = HOFF_Thick;
break;
case 1:
pszWidthKey = ((eCircle == 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);
// 设置接口数据
inf.nSectType = eSectType;
inf.dSize1 = dWidth;
inf.dSize2 = dThick;
return TRUE;
}
bool ImpHvacOffset::GetInterface(AcArray<AecInterface>& arInfs) 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());
AecInterface inf;
for (int nIndex = 0;nIndex < 2;nIndex++)
{
switch(nIndex)
{
case 0:
{
inf.vtDir = vtStart;
inf.ptPos = ptStart;
inf.idOwner = m_pOwnerEnt->objectId();
GetInterfaceSizeData(nIndex, inf);
break;
}
case 1:
{
inf.vtDir = vtEnd;
inf.ptPos = ptEnd;
inf.idOwner = m_pOwnerEnt->objectId();
GetInterfaceSizeData(nIndex, inf);
break;
}
}
arInfs.append(inf);
}
return true;
}