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

6249 lines
163 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "stdafx.h"
#include "ImpHvacElbow.h"
#include "AecDbObjXDataMap.h"
#include "KTSetting.h"
#include "AecDbEntityBase.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
double MayAsMUnit(double dVal)
{
struct resbuf rb;
acedGetVar(_T("INSUNITS"), &rb);
if (rb.resval.rint == AcDb::kUnitsMeters)
{
dVal *= 0.001;
}
return dVal;
}
//导流片参数{DN,片数,x,x,x,间距}
const int nLeader[][15] = {{500, 4, 95, 120, 140, 165, 0},
{630, 4, 115, 145, 170, 200, 0},
{800, 6, 105, 125, 140, 160, 175, 195, 0},
{1000, 7, 115, 130, 150, 165, 180, 200, 215, 0},
{1250, 8, 125, 140, 155, 170, 190, 205, 220, 235, 0},
{1600, 10, 135, 150, 160, 175, 190, 205, 215, 230, 245, 255, 0},
{2000, 12, 145, 155, 170, 180, 195, 205, 215, 230, 240, 255, 265, 280, 0}};
extern AcGePoint3d MidPoint(const AcGePoint3d& pt1,const AcGePoint3d& pt2);
extern AcGeVector3d GetUcsZvt();
extern Acad::ErrorStatus AddToModelSpace(AcDbEntity* pEnt,AcDbDatabase* pDb = NULL,bool bClose = true);
double GetMinDiffAngle()
{
double dMinDiffAng = PI/12;
return dMinDiffAng;
}
ImpHvacElbow::ImpHvacElbow()
{
m_pXDataMap = NULL;
m_pOwnerEnt = NULL;
}
ImpHvacElbow::~ImpHvacElbow()
{
}
BOOL ImpHvacElbow::IsHorzAlignment() const
{
// 取得位置点
AcGePoint3d ptStart, ptCorner, ptEnd, ptCornerAssist;
m_pXDataMap->GetAt(HELB_StartPoint, ptStart);
m_pXDataMap->GetAt(HELB_CornerPoint, ptCorner);
if (!m_pXDataMap->GetAt(HELB_AssisCornerPoint, ptCornerAssist))
{
ptCornerAssist = ptCorner;
}
m_pXDataMap->GetAt(HELB_EndPoint, ptEnd);
// 获得法向量
AcGeVector3d vtNormal((ptStart - ptCorner).crossProduct(ptEnd - ptCornerAssist));
// 获得UCS坐标Z向量
AcDbDatabase* pDb = acdbCurDwg();
AcGeVector3d vtZAxis(pDb->ucsxdir().crossProduct(pDb->ucsydir()));
AcGeTol tolTmp;
tolTmp.setEqualPoint(1);
tolTmp.setEqualVector(/*1*/1E-3);//Lixlmodify
return vtNormal.isParallelTo(vtZAxis, tolTmp);
}
BOOL ImpHvacElbow::IsVertAlignment() const
{
// 取得位置点
AcGePoint3d ptStart, ptCorner, ptEnd, ptCornerAssist;
m_pXDataMap->GetAt(HELB_StartPoint, ptStart);
m_pXDataMap->GetAt(HELB_CornerPoint, ptCorner);
if (!m_pXDataMap->GetAt(HELB_AssisCornerPoint, ptCornerAssist))
{
ptCornerAssist = ptCorner;
}
m_pXDataMap->GetAt(HELB_EndPoint, ptEnd);
// 获得法向量
AcGeVector3d vtNormal((ptStart - ptCorner).crossProduct(ptEnd - ptCornerAssist));
// 获得UCS坐标Z向量
AcDbDatabase* pDb = acdbCurDwg();
AcGeVector3d vtZAxis(pDb->ucsxdir().crossProduct(pDb->ucsydir()));
return vtNormal.isPerpendicularTo(vtZAxis);
}
BOOL ImpHvacElbow::IsInclineAlignment() const
{
// 取得位置点
AcGePoint3d ptStart, ptCorner, ptEnd, ptCornerAssist;
m_pXDataMap->GetAt(HELB_StartPoint, ptStart);
m_pXDataMap->GetAt(HELB_CornerPoint, ptCorner);
if (!m_pXDataMap->GetAt(HELB_AssisCornerPoint, ptCornerAssist))
{
ptCornerAssist = ptCorner;
}
m_pXDataMap->GetAt(HELB_EndPoint, ptEnd);
// 获得法向量
AcGeVector3d vtNormal((ptStart - ptCorner).crossProduct(ptEnd - ptCornerAssist));
// 获得UCS坐标Z向量
AcDbDatabase* pDb = acdbCurDwg();
AcGeVector3d vtZAxis(pDb->ucsxdir().crossProduct(pDb->ucsydir()));
return !vtNormal.isPerpendicularTo(vtZAxis) && !vtNormal.isParallelTo(vtZAxis);
}
BOOL ImpHvacElbow::IsSingleLine() const
{
ASSERT(NULL != m_pXDataMap);
BOOL bSingleLine = FALSE;
m_pXDataMap->GetAt(HVAC_IsSingleLine, (int&)bSingleLine);
return bSingleLine;
}
BOOL ImpHvacElbow::HasBaseLine() const
{
ASSERT(NULL != m_pXDataMap);
BOOL bHasBaseLine = FALSE;
m_pXDataMap->GetAt(HVAC_HasBaseLine, bHasBaseLine);
return bHasBaseLine;
}
Acad::ErrorStatus ImpHvacElbow::Draw3d(AcGiDraw &mode) const
{
if (NULL == m_pXDataMap)
return Acad::eOk;
// 弯头类型
AecHvac::HvacElbowType eElbowType = AecHvac::eAllArcuate;
m_pXDataMap->GetAt(HELB_Type, (int&)eElbowType);
// 根据不同类型绘制不同弯头
switch (eElbowType)
{
case AecHvac::eAllArcuate: // 内外圆弧
DrawAllArcuate3d(mode);
break;
case AecHvac::eAllArcWrap: // 内外圆弧消声
DrawAllArcWrap3d(mode);
break;
case AecHvac::eAllArcInWrap: // 消声弯头
DrawAllArcInWrap3d(mode);
break;
case AecHvac::eSegmental: // 分段拟合
DrawSegmental3d(mode);
break;
case AecHvac::eIncline: // 内斜线
DrawIncline3d(mode);
break;
case AecHvac::eInclineWrap: // 内斜线消声
DrawInclineWrap3d(mode);
break;
case AecHvac::eInclineBoard: // 内斜线隔板消声
DrawInclineBoard3d(mode);
break;
case AecHvac::eInclineLead: // 内斜线导流
DrawInclineLead3d(mode);
break;
case AecHvac::eArcuate: // 内弧线
DrawArcuate3d(mode);
break;
case AecHvac::eArcuateWrap: // 内弧线消声
DrawArcuateWrap3d(mode);
break;
case AecHvac::eArcuateBoard: // 内弧线隔板消声
DrawArcuateBoard3d(mode);
break;
case AecHvac::eArcuateSieve: // 内弧线筛板消声
DrawArcuateSieve3d(mode);
break;
case AecHvac::eArcuateLead: // 内弧线导流
DrawArcuateLead3d(mode);
break;
case AecHvac::eAllOrtho: // 内外直角
DrawAllOrtho3d(mode);
break;
case AecHvac::eOrthoWrap: // 内外直角消声
DrawOrthoWrap3d(mode);
break;
case AecHvac::eOrthoLead: // 内外直角导流
DrawOrthoLead3d(mode);
break;
}
return Acad::eOk;
}
AcDbObjectId ImpHvacElbow::layerId() const
{
if (m_pOwnerEnt != NULL)
{
m_pOwnerEnt->layerId();
}
return AcDbObjectId::kNull;
}
AcDbObjectId ImpHvacElbow::DashLayer() const
{
return m_idDashLayer;
}
AcDbObjectId ImpHvacElbow::CenterLayer() const
{
return m_idCenterLayer;
}
Acad::ErrorStatus ImpHvacElbow::Draw2d(AcGiDraw &mode) const
{
if (m_pXDataMap == NULL || m_pOwnerEnt == NULL)
{
return Acad::eOk;
}
AecComplexCurve cplCurve;
MakeCurves(cplCurve);
AecComplexCurveDraw edage;
edage.SetEdage(cplCurve);
BOOL bWeight = FALSE;
AcDbObjectId idReal = m_idDoubleLayer;
AcDbObjectId idDash = DashLayer();
AcDbObjectId idCent = CenterLayer();
edage.Draw2d(mode,idReal,idDash,idCent,NULL,bWeight,FALSE);
AecComplexCurve cplCen;
GetCurvesInSide(cplCen);
edage.SetEdage(cplCen);
edage.Draw2d(mode,idReal,idDash,idCent,NULL,bWeight,FALSE);
//缓存
//AcDbVoidPtrArray arPtrs;
//edage.explode(arPtrs,idReal,idDash,idCent,NULL,TRUE);
//m_pOwnerEnt->Add2DBuffer(arPtrs);
return Acad::eOk;
}
BOOL ImpHvacElbow::MakeCurves(AecComplexCurve& cplCurve) const
{
if (NULL == m_pXDataMap)
return FALSE;
// 弯头类型
AecHvac::HvacElbowType eElbowType = AecHvac::eAllArcuate;
m_pXDataMap->GetAt(HELB_Type, (int&)eElbowType);
int nIsSingleLine = 0;
m_pXDataMap->GetAt(HVAC_IsSingleLine, nIsSingleLine);
int nType = 0;
//单线形式直接return
if (1 == nIsSingleLine)
{
return FALSE;
}
// 根据不同类型构建外轮廓
switch (eElbowType)
{
case AecHvac::eAllArcuate: // 内外圆弧
return MakeAllArcuate2DCurves(cplCurve,nType);
case AecHvac::eAllArcWrap: // 内外圆弧消声
return MakeAllArcWrap2DCurves(cplCurve,nType);
case AecHvac::eAllArcInWrap: // 消声弯头
return MakeAllArcInWrap2DCurves(cplCurve,nType);
case AecHvac::eSegmental: // 分段拟合
return MakeSegmental2DCurves(cplCurve,nType);
case AecHvac::eIncline: // 内斜线
return MakeIncline2DCurves(cplCurve,nType);
case AecHvac::eInclineWrap: // 内斜线消声
return MakeInclineWrap2DCurves(cplCurve,nType);
case AecHvac::eInclineBoard: // 内斜线隔板消声
return MakeInclineBoard2DCurves(cplCurve,nType);
case AecHvac::eInclineLead: // 内斜线导流
return MakeInclineLead2DCurves(cplCurve,nType);
case AecHvac::eArcuate: // 内弧线
return MakeArcuate2DCurves(cplCurve,nType);
case AecHvac::eArcuateWrap: // 内弧线消声
return MakeArcuateWrap2DCurves(cplCurve,nType);
case AecHvac::eArcuateBoard: // 内弧线隔板消声
return MakeArcuateBoard2DCurves(cplCurve,nType);
case AecHvac::eArcuateSieve: // 内弧线筛板消声
return MakeArcuateSieve2DCurves(cplCurve,nType);
case AecHvac::eArcuateLead: // 内弧线导流
return MakeArcuateLead2DCurves(cplCurve,nType);
case AecHvac::eAllOrtho: // 内外直角
return MakeAllOrtho2DCurves(cplCurve,nType);
case AecHvac::eOrthoWrap: // 内外直角消声
return MakeOrthoWrap2DCurves(cplCurve,nType);
case AecHvac::eOrthoLead: // 内外直角导流
return MakeOrthoLead2DCurves(cplCurve,nType);
}
return FALSE;
}
BOOL ImpHvacElbow::GetCurvesInSide(AecComplexCurve& compCurve) const
{
if (NULL == m_pXDataMap)
return FALSE;
// 弯头类型
AecHvac::HvacElbowType eElbowType = AecHvac::eAllArcuate;
m_pXDataMap->GetAt(HELB_Type, (int&)eElbowType);
int nType = 1;
// 根据不同类型构建内部图形
switch (eElbowType)
{
case AecHvac::eAllArcuate: // 内外圆弧
return MakeAllArcuate2DCurves(compCurve,nType);
case AecHvac::eAllArcWrap: // 内外圆弧消声
return MakeAllArcWrap2DCurves(compCurve,nType);
case AecHvac::eSegmental: // 分段拟合
return MakeSegmental2DCurves(compCurve,nType);
case AecHvac::eIncline: // 内斜线
return MakeIncline2DCurves(compCurve,nType);
case AecHvac::eInclineWrap: // 内斜线消声
return MakeInclineWrap2DCurves(compCurve,nType);
case AecHvac::eInclineBoard: // 内斜线隔板消声
return MakeInclineBoard2DCurves(compCurve,nType);
case AecHvac::eInclineLead: // 内斜线导流
return MakeInclineLead2DCurves(compCurve,nType);
case AecHvac::eArcuate: // 内弧线
return MakeArcuate2DCurves(compCurve,nType);
case AecHvac::eArcuateWrap: // 内弧线消声
return MakeArcuateWrap2DCurves(compCurve,nType);
case AecHvac::eArcuateBoard: // 内弧线隔板消声
return MakeArcuateBoard2DCurves(compCurve,nType);
case AecHvac::eArcuateSieve: // 内弧线筛板消声
return MakeArcuateSieve2DCurves(compCurve,nType);
case AecHvac::eArcuateLead: // 内弧线导流
return MakeArcuateLead2DCurves(compCurve,nType);
case AecHvac::eAllOrtho: // 内外直角
return MakeAllOrtho2DCurves(compCurve,nType);
case AecHvac::eOrthoWrap: // 内外直角消声
return MakeOrthoWrap2DCurves(compCurve,nType);
case AecHvac::eOrthoLead: // 内外直角导流
return MakeOrthoLead2DCurves(compCurve,nType);
}
return FALSE;
}
Acad::ErrorStatus ImpHvacElbow::transformBy(const AcGeMatrix3d& xform)
{
if (NULL == m_pXDataMap)
return Acad::eNotApplicable;
// 取得位置点
AcGePoint3d ptStart, ptCorner, ptEnd;
m_pXDataMap->GetAt(HELB_StartPoint, ptStart);
m_pXDataMap->GetAt(HELB_CornerPoint, ptCorner);
m_pXDataMap->GetAt(HELB_EndPoint, ptEnd);
// 变换位置
ptStart.transformBy(xform);
ptCorner.transformBy(xform);
ptEnd.transformBy(xform);
// 更新点
m_pXDataMap->SetAt(HELB_StartPoint, ptStart);
m_pXDataMap->SetAt(HELB_CornerPoint, ptCorner);
m_pXDataMap->SetAt(HELB_EndPoint, ptEnd);
AcGePoint3d ptCornerSub; //辅助拐点
if (m_pXDataMap->GetAt(HELB_AssisCornerPoint, ptCornerSub))
{
ptCornerSub.transformBy(xform);
m_pXDataMap->SetAt(HELB_AssisCornerPoint, ptCornerSub);
}
double dScale = xform.scale();
double dStaWidth(0.0), dEndWidth(0.), dThick(0.0);
m_pXDataMap->GetAt(HELB_StartWidth, dStaWidth);
m_pXDataMap->GetAt(HELB_EndWidth, dEndWidth);
m_pXDataMap->GetAt(HELB_Thick, dThick);
dStaWidth *= dScale;
dEndWidth *= dScale;
dThick *= dScale;
m_pXDataMap->SetAt(HELB_StartWidth, dStaWidth);
m_pXDataMap->SetAt(HELB_EndWidth, dEndWidth);
m_pXDataMap->SetAt(HELB_Thick, dThick);
double dThickEnd = 0.0; //弯头尾部厚度
if (m_pXDataMap->GetAt(HELB_EndThick, dThickEnd))
{
dThickEnd *= dScale;
m_pXDataMap->SetAt(HELB_EndThick, dThickEnd);
}
return Acad::eOk;
}
AecEqui::Position ImpHvacElbow::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;
case 4:
ePos = AecEqui::eCommand2;
break;
}
return ePos;
}
void ImpHvacElbow::DrawAllArcuate3d(AcGiDraw &mode) const
{
ASSERT(NULL != m_pXDataMap);
int nSectType = 0;
m_pXDataMap->GetAt(HVAC_SectType,nSectType);
switch(nSectType)
{
case eRect:// 矩形
{
DrawAllArcuate3dRec(mode);
break;
}
case eCircle:// 圆形
{
DrawAllArcuate3dCir(mode);
break;
}
case eOblate: // 扁圆形
{
break;
}
}
}
//圆形3D
void ImpHvacElbow::DrawAllArcuate3dCir(AcGiDraw &mode) const
{
ASSERT(NULL != m_pXDataMap);
double dDiameter = MayAsMUnit(300.0);
double dPlusEdge = MayAsMUnit(50.0);
double dThick = MayAsMUnit(50.0);
double dStaWidth = MayAsMUnit(150.0);
double dEndWidth = MayAsMUnit(150.0);
AcGePoint3d ptStart, ptCorner, ptEnd;
AcDbObjectId idLayer;
int nBaseLine;
int nSectType = 2;
m_pXDataMap->GetAt(HVAC_SectType,nSectType);
m_pXDataMap->GetAt(HELB_Diameter,dStaWidth);
//BEGIN==========================================
if (!m_pXDataMap->GetAt(HELB_EndDiameter, dEndWidth))
{
dEndWidth = dStaWidth;
}
m_pXDataMap->GetAt(HELB_StartPoint,ptStart);
m_pXDataMap->GetAt(HELB_CornerPoint,ptCorner);
m_pXDataMap->GetAt(HELB_EndPoint,ptEnd);
m_pXDataMap->GetAt(HVAC_HasBaseLine,nBaseLine);
double dMaxWidth = dStaWidth > dEndWidth ? dStaWidth : dEndWidth;
if ((ptStart.distanceTo(ptCorner) - MayAsMUnit(50.0)) - dMaxWidth / 2 < -1e-6)
{
dPlusEdge = 0.1;
}
int nWrapType = 0;
m_pXDataMap->GetAt(HELB_Type,nWrapType);
double dWrap = 50;
if (2 == nWrapType)
{
if (dDiameter <= MayAsMUnit(100))
{
dWrap = dDiameter * 0.1;
}
dDiameter += dWrap * 2;
}
//以拐点为参照的矢量
AcGeVector3d vtStart = ptStart - ptCorner;
AcGeVector3d vtEnd = ptEnd - ptCorner;
vtStart.normalize();
vtEnd.normalize();
//求得中心线起点和终点
double dRadius = ptCorner.distanceTo(ptStart) -dPlusEdge;
AcGePoint3d ptStartArc = ptCorner + vtStart * dRadius;
AcGePoint3d ptEndArc = ptCorner + vtEnd * dRadius;
//求得平面法向量和中心线圆心
AcGeVector3d vtGNormal = this->normal();
vtGNormal.normalize();
AcGePoint3d ptGeCen;
AcGeVector3d vtStartTmp = vtStart;
AcGeVector3d vtEndTmp = vtEnd;
vtStartTmp.rotateBy(PI * 0.5,vtGNormal);
vtEndTmp.rotateBy(PI * 0.5,vtGNormal);
AcGeLine3d lineStart(ptStartArc, vtStartTmp);
AcGeLine3d lineEnd(ptEndArc, vtEndTmp);
Adesk::Boolean bRet = lineStart.intersectWith(lineEnd, ptGeCen);
if(!bRet) // 中心线圆心计算失败
{
return;
}
//求得中心线圆弧半径
dRadius = ptGeCen.distanceTo(ptStartArc);
//以中心线圆心为参照的矢量
AcGeVector3d vtGStart = ptStartArc - ptGeCen;
AcGeVector3d vtGEnd = ptEndArc - ptGeCen;
vtGStart.normalize();
vtGEnd.normalize();
AcDbCircle entCircle(ptGeCen, vtGNormal, dRadius);
//弯头的角度
double dAngle = vtGStart.angleTo(vtGEnd);
if (dAngle < 10e-9)
return;
//最小分角
double dMinDiffAng = GetMinDiffAngle();
//弧形截面数
int nRows = int(dAngle / dMinDiffAng);
// add by zh 2013-7-29 处理角度<最小分角的情况
if (nRows == 0)
nRows = 1;
//
dMinDiffAng = dAngle / nRows;
//各截面中的关键点数
int nColumns = int(2 * PI / dMinDiffAng);
//关键节点数组
AcGePoint3dArray arptKey;
//直线段(开始处前端)
AcGePoint3d pt = ptStart + vtGStart * dStaWidth / 2;
for(int i = 0; i < nColumns; i++)
{
arptKey.append(pt);
pt.rotateBy(dMinDiffAng, vtStart, ptStart);
}
pt = ptStart + vtGStart * dStaWidth / 2;
arptKey.append(pt);
//弧线段
AcDbEllipse entEll;
AcGePoint3d ptTemp;
AcGeVector3d vtRLong;
double dRLong = 0.0;
double dRShort = 0.0;
double dRatio = 0.0;
if(fabs(dAngle - PI/2) < 1e-6)
{
dRLong = dRadius + (dStaWidth > dEndWidth ? dStaWidth : dEndWidth) / 2;
dRShort = dRadius + (dStaWidth < dEndWidth ? dStaWidth : dEndWidth) / 2;
dRatio = dRShort / dRLong;
vtRLong = (dStaWidth > dEndWidth ? vtGStart * dRLong : vtGEnd * dRLong);
}
else
{
double dA = 0.0;
double dB = 0.0;
if(dStaWidth >= dEndWidth)
{
dA = dRadius + dStaWidth/2;
dRLong = dA;
vtRLong = vtGStart * dRLong;
double dEndToGOri = dRadius + dEndWidth / 2;
double dXEnd = fabs(dEndToGOri * sin(dAngle));
double dYEnd = fabs(dEndToGOri * cos(dAngle));
dB = dA * dXEnd / sqrt(dA * dA - dYEnd * dYEnd);
dRShort = dB;
dRatio = dRShort / dRLong;
}
else
{
dB = dRadius + dStaWidth/2;
dRShort = dB;
double dEndToGOri = dRadius + dEndWidth / 2;
double dXEnd = fabs(dEndToGOri * sin(dAngle));
double dYEnd = fabs(dEndToGOri * cos(dAngle));
dA = dB * dXEnd / sqrt(dB * dB - dYEnd * dYEnd);
dRLong = dA;
AcGeVector3d vtBuf = vtGStart;
vtRLong = vtBuf.rotateBy(-PI/2, vtGNormal) * dRLong;
dRatio = dRShort/dRLong;
}
}
//构建椭圆轨迹
entEll.set(ptGeCen, vtGNormal, vtRLong, dRatio);
double dStepC = -1.0;
double dStepE = -1.0;
entCircle.getParamAtPoint(ptStartArc, dStepC);
double dTemp = 0;
AcGePoint3d ptGArc;
entCircle.getStartParam(dTemp);
entCircle.getPointAtParam(dTemp, ptGArc);
AcGeVector3d vt = ptGArc - ptGeCen;
double dAngleCtoE = vt.angleTo(vtRLong, vtGNormal);
dStepE = dStepC - dAngleCtoE;
int nTemp = nRows;
AcGeVector3d vtNormal;
AcGeVector3d vtTest;
double dRet = 0.0;
for(; nTemp > 0; dStepC -= dMinDiffAng, dStepE -= dMinDiffAng, nTemp--)
{
if(fabs(dStepE - 0) < 1e-6)
{
dStepE += 2*PI;
}
if(fabs(dStepC - 0) < 1e-6)
{
dStepC += 2*PI;
}
entEll.getPointAtParam(dStepE, pt);
entCircle.getPointAtParam(dStepC, ptTemp);
entCircle.getFirstDeriv(ptTemp, vtNormal);
for(int i = 0; i < nColumns; i++)
{
arptKey.append(pt);
pt.rotateBy(dMinDiffAng, vtNormal, ptTemp);
}
entEll.getPointAtParam(dStepE, pt);
arptKey.append(pt);
}
//直线段(结束处前端和后端)
pt = ptEndArc + vtGEnd * dEndWidth / 2;
for(int m = 0; m < nColumns; m++)
{
arptKey.append(pt);
pt.rotateBy(dMinDiffAng, -vtEnd, ptEnd);
}
pt = ptEndArc + vtGEnd * dEndWidth / 2;
arptKey.append(pt);
pt = ptEnd + vtGEnd * dEndWidth / 2;
for(int n = 0; n < nColumns; n++)
{
arptKey.append(pt);
pt.rotateBy(dMinDiffAng, -vtEnd, ptEnd);
}
pt = ptEnd + vtGEnd * dEndWidth / 2;
arptKey.append(pt);
//绘制三维图形
DrawMesh(mode,nRows + 3, nColumns + 1, arptKey.asArrayPtr());
}
//方形3D
void ImpHvacElbow::DrawAllArcuate3dRec(AcGiDraw &mode) const
{
ASSERT(NULL != m_pXDataMap);
double dDiameter = MayAsMUnit(300.0);
double dPlusEdge = MayAsMUnit(50.0);
//========================================
double dStartThick = MayAsMUnit(50.0);
double dEndThick = MayAsMUnit(50.0);
double dStaWidth = MayAsMUnit(150.0);
double dEndWidth = MayAsMUnit(150.0);
AcGePoint3d ptStart, ptCorner, ptEnd;
AcGePoint3d ptCorStart, ptCorEnd;
AcDbObjectId idLayer;
int nBaseLine;
m_pXDataMap->GetAt(HELB_Thick,dStartThick);
BOOL bRet = m_pXDataMap->GetAt(HELB_EndThick, dEndThick);
if (!bRet)
{
dEndThick = dStartThick;
}
m_pXDataMap->GetAt(HELB_StartWidth,dStaWidth);
m_pXDataMap->GetAt(HELB_EndWidth,dEndWidth);
//m_pXDataMap->GetAt(HVAC_PlusEdge,dPlusEdge);
m_pXDataMap->GetAt(HELB_StartPoint,ptStart);
m_pXDataMap->GetAt(HELB_CornerPoint,ptCorStart);
if (!m_pXDataMap->GetAt(HELB_AssisCornerPoint, ptCorEnd))
{
ptCorEnd = ptCorStart;
}
double dMaxWidth = dStaWidth > dEndWidth ? dStaWidth : dEndWidth;
if ((ptStart.distanceTo(ptCorStart) - MayAsMUnit(50.0)) - dMaxWidth / 2 < -1e-6)
{
dPlusEdge = 0.1;
}
m_pXDataMap->GetAt(HELB_EndPoint,ptEnd);
m_pXDataMap->GetAt(HVAC_HasBaseLine,nBaseLine);
int nWrapType = 0;
m_pXDataMap->GetAt(HELB_Type,nWrapType);
AcGeVector3d vtCorStartCom = ptCorStart.asVector();
AcGeVector3d vtCorEndCom = ptCorEnd.asVector();
AcGeVector3d vtCornerCom = (vtCorStartCom + vtCorEndCom) / 2;
ptCorner = AcGePoint3d::kOrigin + vtCornerCom;
AcGeVector3d vtStart = ptStart - ptCorStart;
AcGeVector3d vtEnd = ptEnd - ptCorEnd;
vtStart.normalize();
vtEnd.normalize();
//求得中心线起点和终点
double dRadius = ptCorStart.distanceTo(ptStart) - dPlusEdge;
AcGePoint3d ptStartArc = ptCorStart + vtStart * dRadius;
AcGePoint3d ptEndArc = ptCorEnd + vtEnd * dRadius;
//求得平面法向量和中心线圆心
AcGeVector3d vtStartTmp = ptStartArc - ptCorner;
AcGeVector3d vtEndTmp = ptEndArc - ptCorner;
AcGeVector3d vtGNormal = vtStartTmp.crossProduct(vtEndTmp);
vtGNormal.normalize();
AcGePoint3d ptGeCen;
vtStartTmp.rotateBy(PI * 0.5, vtGNormal);
vtEndTmp.rotateBy(PI * 0.5, vtGNormal);
AcGeLine3d lineStart(ptStartArc, vtStartTmp);
AcGeLine3d lineEnd(ptEndArc, vtEndTmp);
if(!lineStart.intersectWith(lineEnd, ptGeCen)) // 中心线圆心计算失败
{
return;
}
//求得中心线圆弧半径
dRadius = ptGeCen.distanceTo(ptStartArc);
//弯头剖面内坐标向量
AcGeVector3d vtNormal = vtStart.crossProduct(vtEnd);
AcGeVector3d vtGStart = vtStart.rotateBy(-PI / 2, vtNormal);
AcGeVector3d vtGEnd = vtEnd.rotateBy(PI / 2, vtNormal);
vtGStart.normalize();
vtGEnd.normalize();
AcDbCircle entCircle(ptGeCen, vtGNormal, dRadius);
//弯头的角度
double dAngle = vtGStart.angleTo(vtGEnd);
//最小分角
double dMinDiffAng = GetMinDiffAngle();
int nRows = (int)(PI * 2 / dMinDiffAng);
AcGeVector3d vtCor = ptCorner - ptGeCen;
vtCor.normalize();
//求得中心线圆弧上点
AcGePoint3d ptOnArc = ptGeCen + vtCor * dRadius;
//关键节点数组
AcGePoint3dArray arptKey; //存储网格使用
AcGePoint3dArray arptArcHead; //存储边线弧形起点
AcGePoint3dArray arptArcTail; //存储边线弧形尾点
AcGePoint3dArray arptArcCor; //存储边线弧形中点
AcGePoint3dArray arptArcCenter; //存储边线弧形圆心
AcGeVector3dArray arvtArcNormal; //存储边线弧形平面法向量
AcGeVector3d vtGNormalTmp = vtGEnd.crossProduct(vtGStart); //弯头剖面法向量
vtGNormalTmp.normalize();
AcGePoint3d ptTemp[5];
//边线头端生成
ptTemp[0] = ptStartArc + vtGStart * (dStaWidth / 2) + vtGNormalTmp * (dStartThick / 2);
ptTemp[1] = ptStartArc + vtGStart * (dStaWidth / 2) - vtGNormalTmp * (dStartThick / 2);
ptTemp[2] = ptStartArc - vtGStart * (dStaWidth / 2) - vtGNormalTmp * (dStartThick / 2);
ptTemp[3] = ptStartArc - vtGStart * (dStaWidth / 2) + vtGNormalTmp * (dStartThick / 2);
for(int i = 0; i < 4; i++)
{
arptArcHead.append(ptTemp[i]);
}
//边线中段生成
ptTemp[0] = ptOnArc + vtCor * ((dStaWidth + dEndWidth) / 4) + vtGNormalTmp * ((dStartThick + dEndThick) / 4);
ptTemp[1] = ptOnArc + vtCor * ((dStaWidth + dEndWidth) / 4) - vtGNormalTmp * ((dStartThick + dEndThick) / 4);
ptTemp[2] = ptOnArc - vtCor * ((dStaWidth + dEndWidth) / 4) - vtGNormalTmp * ((dStartThick + dEndThick) / 4);
ptTemp[3] = ptOnArc - vtCor * ((dStaWidth + dEndWidth) / 4) + vtGNormalTmp * ((dStartThick + dEndThick) / 4);
for(int l = 0; l < 4; l++)
{
arptArcCor.append(ptTemp[l]);
}
//边线尾端生成
ptTemp[0] = ptEndArc + vtGEnd * (dEndWidth / 2) + vtGNormalTmp * (dEndThick / 2);
ptTemp[1] = ptEndArc + vtGEnd * (dEndWidth / 2) - vtGNormalTmp * (dEndThick / 2);
ptTemp[2] = ptEndArc - vtGEnd * (dEndWidth / 2) - vtGNormalTmp * (dEndThick / 2);
ptTemp[3] = ptEndArc - vtGEnd * (dEndWidth / 2) + vtGNormalTmp * (dEndThick / 2);
for(int m = 0; m < 4; m++)
{
arptArcTail.append(ptTemp[m]);
}
//边线弧形圆心和平面法向量生成
for(int n = 0; n < 4; n++)
{
AcGeCircArc3d arcTemp(arptArcHead.at(n), arptArcCor.at(n), arptArcTail.at(n));
arptArcCenter.append(arcTemp.center());
arvtArcNormal.append(arcTemp.normal());
}
//弯头头部生成
ptTemp[0] = ptStart + vtGStart * (dStaWidth / 2) + vtGNormalTmp * (dStartThick / 2);
ptTemp[1] = ptStart + vtGStart * (dStaWidth / 2) - vtGNormalTmp * (dStartThick / 2);
ptTemp[2] = ptStart - vtGStart * (dStaWidth / 2) - vtGNormalTmp * (dStartThick / 2);
ptTemp[3] = ptStart - vtGStart * (dStaWidth / 2) + vtGNormalTmp * (dStartThick / 2);
ptTemp[4] = ptStart + vtGStart * (dStaWidth / 2) + vtGNormalTmp * (dStartThick / 2);
for(int k = 0; k < 5; k++)
{
arptKey.append(ptTemp[k]);
}
ptTemp[0] = ptStartArc + vtGStart * (dStaWidth / 2) + vtGNormalTmp * (dStartThick / 2);
ptTemp[1] = ptStartArc + vtGStart * (dStaWidth / 2) - vtGNormalTmp * (dStartThick / 2);
ptTemp[2] = ptStartArc - vtGStart * (dStaWidth / 2) - vtGNormalTmp * (dStartThick / 2);
ptTemp[3] = ptStartArc - vtGStart * (dStaWidth / 2) + vtGNormalTmp * (dStartThick / 2);
ptTemp[4] = ptStartArc + vtGStart * (dStaWidth / 2) + vtGNormalTmp * (dStartThick / 2);
for(int c = 0; c < 5; c++)
{
arptKey.append(ptTemp[c]);
}
//弯头弧线段生成
for(int d = 1; d < nRows; d++)
{
for(int j = 0; j < 5; j++)
{
AcGePoint3d ptHeadTemp = arptArcHead.at(j%4);
AcGePoint3d ptTailTmp = arptArcTail.at(j%4);
AcGeVector3d vtNormalTemp = arvtArcNormal.at(j%4);
AcGePoint3d ptCenterTemp = arptArcCenter.at(j%4);
AcGeVector3d vtTest = ptTailTmp - ptCenterTemp;
AcGeVector3d vtStandard = ptHeadTemp - ptCenterTemp;
double dAngleTest = vtStandard.angleTo(vtTest, vtNormalTemp);
double dRoAngle = dMinDiffAng * d;
ptTemp[j] = ptHeadTemp.rotateBy(dRoAngle, vtNormalTemp, ptCenterTemp);
if(fabs(dRoAngle/dAngleTest - 1) < 1e-10 || dRoAngle > dAngleTest)
ptTemp[j] = ptTailTmp;
arptKey.append(ptTemp[j]);
}
}
//弯头尾部生成
ptTemp[0] = ptEndArc + vtGEnd * (dEndWidth / 2) + vtGNormalTmp * (dEndThick / 2);
ptTemp[1] = ptEndArc + vtGEnd * (dEndWidth / 2) - vtGNormalTmp * (dEndThick / 2);
ptTemp[2] = ptEndArc - vtGEnd * (dEndWidth / 2) - vtGNormalTmp * (dEndThick / 2);
ptTemp[3] = ptEndArc - vtGEnd * (dEndWidth / 2) + vtGNormalTmp * (dEndThick / 2);
ptTemp[4] = ptEndArc + vtGEnd * (dEndWidth / 2) + vtGNormalTmp * (dEndThick / 2);
for(int b = 0; b < 5; b++)
{
arptKey.append(ptTemp[b]);
}
ptTemp[0] = ptEnd + vtGEnd * (dEndWidth / 2) + vtGNormalTmp * (dEndThick / 2);
ptTemp[1] = ptEnd + vtGEnd * (dEndWidth / 2) - vtGNormalTmp * (dEndThick / 2);
ptTemp[2] = ptEnd - vtGEnd * (dEndWidth / 2) - vtGNormalTmp * (dEndThick / 2);
ptTemp[3] = ptEnd - vtGEnd * (dEndWidth / 2) + vtGNormalTmp * (dEndThick / 2);
ptTemp[4] = ptEnd + vtGEnd * (dEndWidth / 2) + vtGNormalTmp * (dEndThick / 2);
for(int a = 0; a < 5; a++)
{
arptKey.append(ptTemp[a]);
}
//添加关键点进行绘图
DrawMesh(mode, nRows + 3, 5, arptKey.asArrayPtr());
//======================================================================================
}
BOOL ImpHvacElbow::MakeAllArcuate2DCurves(AecComplexCurve& cplCurve,int &nType) const
{
ASSERT(NULL != m_pXDataMap);
if (IsHorzAlignment())
{
DrawAllArcuate2DHor(cplCurve,nType);
}
else if(IsVertAlignment())
{
DrawAllArcuate2DVer(cplCurve,nType);
}
else if (IsInclineAlignment())
{
DrawAllArcuate2DInc(cplCurve,nType);
}
return cplCurve.length() > 0;
}
// 绘制倾斜弯头2D线Lixl
BOOL ImpHvacElbow::DrawAllArcuate2DInc(AecComplexCurve& cplCurve,int &nType) const
{
double dDiameter = MayAsMUnit(300),dStartWidth = MayAsMUnit(300),dEndWidth = MayAsMUnit(100),dPlusEdge = MayAsMUnit(50.0);
int nWrapType = 1;
int nSectType = 2;
AcGePoint3d ptStart, ptCorner, ptEnd;
m_pXDataMap->GetAt(HVAC_SectType,nSectType);
m_pXDataMap->GetAt(HELB_Diameter,dDiameter);
m_pXDataMap->GetAt(HELB_StartWidth,dStartWidth);
m_pXDataMap->GetAt(HELB_EndWidth,dEndWidth);
m_pXDataMap->GetAt(HELB_StartPoint,ptStart);
m_pXDataMap->GetAt(HELB_CornerPoint,ptCorner);
m_pXDataMap->GetAt(HELB_EndPoint,ptEnd);
m_pXDataMap->GetAt(HELB_Type,nWrapType);
double dMaxWidth = dStartWidth > dEndWidth ? dStartWidth : dEndWidth;
if ((ptStart.distanceTo(ptCorner) - dPlusEdge) - dMaxWidth / 2 < -1e-6)
dPlusEdge = 0.1;
switch(nSectType)
{
case eRect: // 矩形
{
ptCorner.z = ptEnd.z = ptStart.z;
dStartWidth *= 0.5;
dEndWidth *= 0.5;
return GetAllArcuateCplCurveHor(cplCurve,nType,ptStart,
ptCorner,ptEnd,dPlusEdge,dStartWidth,dEndWidth,nWrapType);
break;
}
case eCircle: // 圆形
{
dStartWidth *= 0.5;
dEndWidth *= 0.5;
return GetAllArcuateCplCurveInc(cplCurve,nType,ptStart,
ptCorner,ptEnd,dPlusEdge,dStartWidth,dEndWidth,nWrapType);
break;
}
case eOblate: // 扁圆形
{
break;
}
}
return FALSE;
}
BOOL ImpHvacElbow::DrawAllArcuate2DHor(AecComplexCurve& cplCurve,int &nType) const
{
double dThick = MayAsMUnit(100.0),dDiameter = MayAsMUnit(300),dStartWidth = MayAsMUnit(300),dEndWidth = MayAsMUnit(100),dPlusEdge = MayAsMUnit(50.0);
int nWrapType = 1;
int nSectType = 2;
AcDbObjectId idLayer;
int nBaseLine = 1;
int nSingleLine = 0;
AcGePoint3d ptStart, ptCorner, ptEnd;
m_pXDataMap->GetAt(HVAC_SectType,nSectType);
m_pXDataMap->GetAt(HELB_Diameter,dDiameter);
m_pXDataMap->GetAt(HELB_StartWidth,dStartWidth);
m_pXDataMap->GetAt(HELB_EndWidth,dEndWidth);
m_pXDataMap->GetAt(HVAC_PlusEdge,dPlusEdge);
m_pXDataMap->GetAt(HELB_StartPoint,ptStart);
m_pXDataMap->GetAt(HELB_CornerPoint,ptCorner);
m_pXDataMap->GetAt(HELB_EndPoint,ptEnd);
m_pXDataMap->GetAt(HVAC_HasBaseLine,nBaseLine);
m_pXDataMap->GetAt(HVAC_IsSingleLine,nSingleLine);
//得到弯头类型,如果是内外消声弯头将多绘制两条弧线
m_pXDataMap->GetAt(HELB_Type,nWrapType);
ptCorner.z = ptEnd.z = ptStart.z;
double dMaxWidth = dStartWidth > dEndWidth ? dStartWidth : dEndWidth;
if ((ptStart.distanceTo(ptCorner) - MayAsMUnit(50.0)) - dMaxWidth / 2 < -1e-6)
{
dPlusEdge = 0.1;
}
switch(nSectType)
{
case eRect:// 矩形
{
dStartWidth *= 0.5;
dEndWidth *= 0.5;
return GetAllArcuateCplCurveHor(cplCurve,nType,ptStart,ptCorner,ptEnd,dPlusEdge,dStartWidth,dEndWidth,nWrapType);
break;
}
case eCircle:// 圆形
{
dStartWidth *= 0.5;
dEndWidth *= 0.5;
return GetAllArcuateCplCurveHor(cplCurve,nType,ptStart,ptCorner,ptEnd,dPlusEdge,dStartWidth,dEndWidth,nWrapType);
break;
}
case eOblate: // 扁圆形
{
break;
}
}
return FALSE;
}
//2d立管
BOOL ImpHvacElbow::DrawAllArcuate2DVer(AecComplexCurve& cplCurve,int &nType) const
{
double dThick = MayAsMUnit(100.0),dDiameter = MayAsMUnit(300),dStartWidth = MayAsMUnit(300),dEndWidth = MayAsMUnit(100),dPlusEdge = MayAsMUnit(50.0);
int nSectType = 2;
AcDbObjectId idLayer;
int nBaseLine = 1;
int nSingleLine = 0;
AcGePoint3d ptStart, ptCorner, ptEnd, ptCornerAssist;
m_pXDataMap->GetAt(HVAC_SectType,nSectType);
m_pXDataMap->GetAt(HELB_Diameter, dDiameter);
m_pXDataMap->GetAt(HELB_Thick, dThick);
m_pXDataMap->GetAt(HELB_StartWidth, dStartWidth);
m_pXDataMap->GetAt(HELB_EndWidth, dEndWidth);
////m_pXDataMap->GetAt(HVAC_PlusEdge,dPlusEdge);
m_pXDataMap->GetAt(HELB_StartPoint,ptStart);
m_pXDataMap->GetAt(HELB_CornerPoint,ptCorner);
if (!m_pXDataMap->GetAt(HELB_AssisCornerPoint, ptCornerAssist))
{
ptCornerAssist = ptCorner;
}
bool bIsCenterOffset = false;
if (ptCorner.distanceTo(ptCornerAssist) < 1e-3)
{
bIsCenterOffset = false;
}
else
{
bIsCenterOffset = true;
}
m_pXDataMap->GetAt(HELB_EndPoint,ptEnd);
m_pXDataMap->GetAt(HVAC_HasBaseLine,nBaseLine);
m_pXDataMap->GetAt(HVAC_IsSingleLine,nSingleLine);
double dDiameterEnd = MayAsMUnit(300);
if (!m_pXDataMap->GetAt(HELB_EndDiameter, dDiameterEnd))
{
dDiameterEnd = dDiameter;
}
double dEndThick = dThick;
m_pXDataMap->GetAt(HELB_EndThick, dEndThick);
int nWrapType = 0;
m_pXDataMap->GetAt(HELB_Type,nWrapType);
double dWrap = MayAsMUnit(50);
switch(nSectType)
{
case eRect:// 矩形
{
dStartWidth *= 0.5;
dEndWidth *= 0.5;
dThick *= 0.5;
dEndThick *= 0.5;
if (bIsCenterOffset)
{
return GetAllArcuateCplCurveVerRecForOffset(cplCurve, nType);
}
else
{
return GetAllArcuateCplCurveVerRec(cplCurve,nType,ptStart,ptCorner,ptEnd,dPlusEdge,dStartWidth,dEndWidth,dThick, dEndThick);
}
break;
}
case eCircle:// 圆形
{
dDiameter *= 0.5;
dDiameterEnd *= 0.5;
return GetAllArcuateCplCurveVerCir(cplCurve,nType,ptStart,ptCorner,ptEnd,dPlusEdge,dDiameter,dDiameterEnd);
break;
}
case eOblate: // 扁圆形
{
break;
}
}
return FALSE;
}
double ImpHvacElbow::GetEdgeLineWidth() const
{
ASSERT(NULL != m_pXDataMap);
double dWidth(0.0);
m_pXDataMap->GetAt(HVAC_EdgeWidth, dWidth);
return dWidth;
}
double ImpHvacElbow::GetCentLineWidth() const
{
ASSERT(NULL != m_pXDataMap);
double dWidth(0.0);
m_pXDataMap->GetAt(HVAC_CentWidth, dWidth);
return dWidth;
}
double ImpHvacElbow::GetEndLineWidth() const
{
ASSERT(NULL != m_pXDataMap);
double dWidth(0.0);
m_pXDataMap->GetAt(HVAC_EndWidth, dWidth);
return dWidth;
}
int GetEllipseFromCircle( AcGePoint3d ptCenter, double dDia, AcGeVector3d vtOrigNormal,
AcGeVector3d vtNewNormal, AcDbPolyline &polyLine, AcGeVector3d vtGet)
{
vtOrigNormal.normalize();
vtNewNormal.normalize();
double dRadius = dDia * 0.5;
AcGePlane planStd; // 椭圆投影所在标准面
planStd.set(ptCenter, vtNewNormal);
AcGePoint3d ptPrj = AcGePoint3d::kOrigin.orthoProject(planStd);
planStd.set(ptPrj, vtNewNormal);
double dEle = ptPrj.asVector().length();
if (!ptPrj.asVector().isCodirectionalTo(planStd.normal()))
{
dEle *= -1.0;
}
if (vtNewNormal.isParallelTo(vtOrigNormal)) // 平行,还是圆
{
AcGePoint3d ptStart, ptEnd;
if (vtGet.length() < 1e-6) // 整个圆
{
AcGeVector3d vtPerl = vtOrigNormal.perpVector();
ptStart = ptCenter + dRadius * vtPerl;
ptEnd = ptCenter - dRadius * vtPerl;
polyLine.addVertexAt(0, ptStart.convert2d(planStd), 1.0);
polyLine.addVertexAt(1, ptEnd.convert2d(planStd), 1.0);
polyLine.setClosed(Adesk::kTrue);
}
else // 半个圆
{
AcGeVector3d vtPerl = vtGet.orthoProject(vtNewNormal);
vtPerl.rotateBy(-PI / 2, vtNewNormal);
vtPerl.normalize();
ptStart = ptCenter + dRadius * vtPerl;
ptEnd = ptCenter - dRadius * vtPerl;
polyLine.addVertexAt(0, ptStart.convert2d(planStd), 1);
polyLine.addVertexAt(1, ptEnd.convert2d(planStd), 0);
}
polyLine.setElevation(dEle);
polyLine.setNormal(vtNewNormal);
return 0;
}
else if (vtNewNormal.isPerpendicularTo(vtOrigNormal)) // 垂直情况, 为直线
{
AcGeVector3d vtCrossPerl = vtOrigNormal.crossProduct(vtNewNormal);
AcGePoint3d ptStart, ptEnd;
ptStart = ptCenter + dRadius * vtCrossPerl;
ptEnd = ptCenter - dRadius * vtCrossPerl;
polyLine.addVertexAt(0, ptStart.convert2d(planStd));
polyLine.addVertexAt(1, ptEnd.convert2d(planStd));
polyLine.setElevation(dEle);
polyLine.setNormal(vtNewNormal);
return 1;
}
else // 普通投影为椭圆情况
{
// 长/短轴向量
AcGeVector3d vtLong = vtOrigNormal.crossProduct(vtNewNormal);
vtLong.normalize();
AcGeVector3d vtShort = vtLong;
vtShort.rotateBy(PI * 0.5, vtOrigNormal);
AcGeVector3d vtPerp = vtOrigNormal.crossProduct(vtNewNormal);
vtPerp.normalize();
double dMinAngle = GetMinDiffAngle();
// dMinAngle *= 0.5;
int nPart = (int)(PI / dMinAngle) +1;
dMinAngle = PI / nPart;
AcGePoint3d ptNow;
AcGePoint3dArray arptsEdge;
if (vtGet.length() < 1e-6)
{
ptNow = ptCenter + vtPerp * dDia * 0.5;
for(int i = 0; i <= nPart*2; i++)
{
polyLine.addVertexAt(i, ptNow.convert2d(planStd));
ptNow.rotateBy(dMinAngle, vtOrigNormal, ptCenter);
}
}
else
{
vtGet = vtGet.orthoProject(vtNewNormal);
if (vtGet.angleTo(vtShort) < PI*0.5) // C 端部分
{
ptNow = ptCenter + vtPerp * dDia * 0.5;
for(int i = 0; i <= nPart; i++)
{
polyLine.addVertexAt(i, ptNow.convert2d(planStd));
ptNow.rotateBy(dMinAngle, vtOrigNormal, ptCenter);
}
}
else // D 端部分
{
ptNow = ptCenter - vtPerp * dDia * 0.5;
for(int i = 0; i <= nPart; i++)
{
polyLine.addVertexAt(i, ptNow.convert2d(planStd));
ptNow.rotateBy(dMinAngle, vtOrigNormal, ptCenter);
}
}
}
}
polyLine.setElevation(dEle);
polyLine.setNormal(vtNewNormal);
return 2;
}
void GetArcPoint(AcDbPolyline &polyLine, AcGePoint3dArray &ptArcArr)
{
double dBugle(0.0);
polyLine.getBulgeAt(0, dBugle);
if (EQUAL_ZERO(dBugle - 1.0))// Polyline线是半个圆,或者圆
{
double dPar1, dPar2;
AcGePoint3d pt0, pt1, pt2, pt3, ptMid;
polyLine.getPointAt(0, pt0);
polyLine.getPointAt(1, pt1);
polyLine.getPointAt(2, pt2);
polyLine.getPointAt(3, pt3);
polyLine.getParamAtPoint(pt0, dPar1);
polyLine.getParamAtPoint(pt1, dPar2);
polyLine.getPointAtParam((dPar1 + dPar2)*0.5, ptMid);
ptArcArr.append(pt0);
ptArcArr.append(ptMid);
ptArcArr.append(pt1);
polyLine.getParamAtPoint(pt1, dPar1);
polyLine.getParamAtPoint(pt2, dPar2);
polyLine.getPointAtParam((dPar1 + dPar2)*0.5, ptMid);
ptArcArr.append(ptMid);
ptArcArr.append(pt2);
polyLine.getParamAtPoint(pt2, dPar1);
polyLine.getParamAtPoint(pt3, dPar2);
polyLine.getPointAtParam((dPar1 + dPar2)*0.5, ptMid);
ptArcArr.append(ptMid);
ptArcArr.append(pt3);
if (polyLine.isClosed())
{
polyLine.getParamAtPoint(pt3, dPar1);
polyLine.getEndParam(dPar2);
polyLine.getPointAtParam((dPar1 + dPar2)*0.5, ptMid);
ptArcArr.append(ptMid);
ptArcArr.append(pt0);
}
}
else
{
AcGePoint3d pt1;
for(int i = 0; i < polyLine.numVerts(); i++)
{
polyLine.getPointAt(i, pt1);
ptArcArr.append(pt1);
}
}
}
int GetEllipsePtsFromCircle(AcGePoint3dArray& arPtsOnCurve, AcGePoint3d ptCenter, double dDia, AcGeVector3d vtOrigNormal,
AcGeVector3d vtNewNormal, AcDbPolyline &polyLine, AcGeVector3d vtGet/* = AcGeVector3d::kIdentity*/)
{
int iRes = GetEllipseFromCircle(ptCenter, dDia, vtOrigNormal, vtNewNormal, polyLine, vtGet);
if (iRes != -1)
{
AcGePoint3d ptTemp, ptTemp1, ptTemp2;
double dPam1, dPam2;
AcGeVector3d vtDir;
AcGePlane plan;
switch (iRes)
{
default:
case 2:// 投影为椭圆
GetArcPoint(polyLine, arPtsOnCurve);
break;
case 1:// 投影为直线
polyLine.getPointAt(0, ptTemp);
arPtsOnCurve.append(ptTemp);
polyLine.getPointAt(1, ptTemp);
arPtsOnCurve.append(ptTemp);
arPtsOnCurve.append(ptTemp);
break;
case 0:// 投影为圆
if (polyLine.isClosed())// 整个圆
{
polyLine.getPointAt(0, ptTemp1);
polyLine.getPointAt(1, ptTemp2);
polyLine.getParamAtPoint(ptTemp1, dPam1);
polyLine.getParamAtPoint(ptTemp2, dPam2);
polyLine.getPointAtParam((dPam1+dPam2)*0.5, ptTemp);
arPtsOnCurve.append(ptTemp1);
arPtsOnCurve.append(ptTemp);
arPtsOnCurve.append(ptTemp2);
vtDir = ptTemp1 - ptTemp2;
plan.set(MidPoint(ptTemp1, ptTemp2), vtDir.rotateBy(PI * 0.5, vtNewNormal));
ptTemp.mirror(plan);
arPtsOnCurve.append(ptTemp);
arPtsOnCurve.append(ptTemp1);
}
else// 半个圆
{
polyLine.getPointAt(0, ptTemp1);
polyLine.getPointAt(1, ptTemp2);
polyLine.getParamAtPoint(ptTemp1, dPam1);
polyLine.getParamAtPoint(ptTemp2, dPam2);
polyLine.getPointAtParam((dPam1+dPam2)*0.5, ptTemp);
arPtsOnCurve.append(ptTemp1);
arPtsOnCurve.append(ptTemp);
arPtsOnCurve.append(ptTemp2);
}
break;
}
}
return iRes;
}
// Lixl 得到圆形截面的弯头两个外轮廓线上的点
BOOL ImpHvacElbow::GetPrjPts(AcGePoint3dArray &arPtsU, AcGePoint3dArray &arPtsD) const
{
// 每个分节面的圆上取三个点,放在此数组,用于确定分节圆,之后向平面投影得到投影点
AcGePoint3dArray arPtsOnCir;
double dDiameter = MayAsMUnit(300.0);
double dPlusEdge = MayAsMUnit(50.0);
double dStaWidth = MayAsMUnit(150.0);
double dEndWidth = MayAsMUnit(150.0);
int nSectType = 2;
AcGePoint3d ptStart, ptCorner, ptEnd;
m_pXDataMap->GetAt(HELB_StartPoint,ptStart);
m_pXDataMap->GetAt(HELB_CornerPoint,ptCorner);
m_pXDataMap->GetAt(HELB_EndPoint,ptEnd);
m_pXDataMap->GetAt(HVAC_SectType,nSectType);
m_pXDataMap->GetAt(HELB_Diameter,dStaWidth);
if (!m_pXDataMap->GetAt(HELB_EndDiameter, dEndWidth))
dEndWidth = dStaWidth;
double dMaxWidth = dStaWidth > dEndWidth ? dStaWidth : dEndWidth;
if ((ptStart.distanceTo(ptCorner) - 50.0) - dMaxWidth / 2 < -1e-6)
dPlusEdge = 0.1;
int nWrapType = 0;
m_pXDataMap->GetAt(HELB_Type,nWrapType);
double dWrap = MayAsMUnit(50);
if (2 == nWrapType)
{
if (dDiameter <= MayAsMUnit(100))
dWrap = dDiameter * 0.1;
dDiameter += dWrap * 2;
}
//以拐点为参照的矢量
AcGeVector3d vtStart = ptStart - ptCorner;
AcGeVector3d vtEnd = ptEnd - ptCorner;
vtStart.normalize();
vtEnd.normalize();
//求得中心线起点和终点
double dRadius = ptCorner.distanceTo(ptStart) -dPlusEdge;
AcGePoint3d ptStartArc = ptCorner + vtStart * dRadius;
AcGePoint3d ptEndArc = ptCorner + vtEnd * dRadius;
//求得平面法向量和中心线圆心
AcGeVector3d vtGNormal = this->normal();
vtGNormal.normalize();
AcGePoint3d ptGeCen;
AcGeVector3d vtStartTmp = vtStart;
AcGeVector3d vtEndTmp = vtEnd;
vtStartTmp.rotateBy(PI * 0.5,vtGNormal);
vtEndTmp.rotateBy(PI * 0.5,vtGNormal);
AcGeLine3d lineStart(ptStartArc, vtStartTmp);
AcGeLine3d lineEnd(ptEndArc, vtEndTmp);
Adesk::Boolean bRet = lineStart.intersectWith(lineEnd, ptGeCen);
if(!bRet) // 中心线圆心计算失败
return FALSE;
//求得中心线圆弧半径
dRadius = ptGeCen.distanceTo(ptStartArc);
//以中心线圆心为参照的矢量
AcGeVector3d vtGStart = ptStartArc - ptGeCen;
AcGeVector3d vtGEnd = ptEndArc - ptGeCen;
vtGStart.normalize();
vtGEnd.normalize();
AcDbCircle entCircle(ptGeCen, vtGNormal, dRadius);
//弯头的角度
double dAngle = vtGStart.angleTo(vtGEnd);
//最小分角
double dMinDiffAng = GetMinDiffAngle();
dMinDiffAng *= 0.5;
//弧形截面数,如果设置的虾米节数量,使用虾米节数量
int nRows = int(dAngle / dMinDiffAng);
AecHvac::HvacElbowType eElbowType = AecHvac::eAllArcuate;
m_pXDataMap->GetAt(HELB_Type, (int&)eElbowType);
if (AecHvac::eSegmental == eElbowType)
m_pXDataMap->GetAt(HELB_Segments, nRows);
dMinDiffAng = dAngle / nRows;
//各截面中的关键点数
int nColumns = int(2 * PI / dMinDiffAng);
//关键节点数组
AcGePoint3dArray arptKey;
//直线段(开始处前端)
AcGePoint3d pt = ptStart + vtGStart * dStaWidth / 2;
int i = 0;
for(i = 0; i < nColumns; i++)
{
arptKey.append(pt);
pt.rotateBy(dMinDiffAng, vtStart, ptStart);
}
pt = ptStart + vtGStart * dStaWidth / 2;
arptKey.append(pt);
//弧线段
AcDbEllipse entEll;
AcGePoint3d ptTemp;
AcGeVector3d vtRLong;
double dRLong = 0.0;
double dRShort = 0.0;
double dRatio = 0.0;
if(fabs(dAngle - PI/2) < 1e-6)
{
dRLong = dRadius + (dStaWidth > dEndWidth ? dStaWidth : dEndWidth) / 2;
dRShort = dRadius + (dStaWidth < dEndWidth ? dStaWidth : dEndWidth) / 2;
dRatio = dRShort / dRLong;
vtRLong = (dStaWidth > dEndWidth ? vtGStart * dRLong : vtGEnd * dRLong);
}
else
{
double dA = 0.0;
double dB = 0.0;
if(dStaWidth >= dEndWidth)
{
dA = dRadius + dStaWidth/2;
dRLong = dA;
vtRLong = vtGStart * dRLong;
double dEndToGOri = dRadius + dEndWidth / 2;
double dXEnd = fabs(dEndToGOri * sin(dAngle));
double dYEnd = fabs(dEndToGOri * cos(dAngle));
dB = dA * dXEnd / sqrt(dA * dA - dYEnd * dYEnd);
dRShort = dB;
dRatio = dRShort / dRLong;
}
else
{
dB = dRadius + dStaWidth/2;
dRShort = dB;
double dEndToGOri = dRadius + dEndWidth / 2;
double dXEnd = fabs(dEndToGOri * sin(dAngle));
double dYEnd = fabs(dEndToGOri * cos(dAngle));
dA = dB * dXEnd / sqrt(dB * dB - dYEnd * dYEnd);
dRLong = dA;
AcGeVector3d vtBuf = vtGStart;
vtRLong = vtBuf.rotateBy(-PI/2, vtGNormal) * dRLong;
dRatio = dRShort/dRLong;
}
}
//构建椭圆轨迹
entEll.set(ptGeCen, vtGNormal, vtRLong, dRatio);
double dStepC = -1.0;
double dStepE = -1.0;
entCircle.getParamAtPoint(ptStartArc, dStepC);
double dTemp = 0;
AcGePoint3d ptGArc;
entCircle.getStartParam(dTemp);
entCircle.getPointAtParam(dTemp, ptGArc);
AcGeVector3d vt = ptGArc - ptGeCen;
double dAngleCtoE = vt.angleTo(vtRLong, vtGNormal);
dStepE = dStepC - dAngleCtoE;
int nTemp = nRows;
AcGeVector3d vtNormal;
AcGeVector3d vtTest;
double dRet = 0.0;
for(; nTemp > 0; dStepC -= dMinDiffAng, dStepE -= dMinDiffAng, nTemp--)
{
if(fabs(dStepE - 0) < 1e-6)
{
dStepE += 2*PI;
}
if(fabs(dStepC - 0) < 1e-6)
{
dStepC += 2*PI;
}
entEll.getPointAtParam(dStepE, pt);
entCircle.getPointAtParam(dStepC, ptTemp);
entCircle.getFirstDeriv(ptTemp, vtNormal);
for(int i = 0; i < nColumns; i++)
{
arptKey.append(pt);
pt.rotateBy(dMinDiffAng, vtNormal, ptTemp);
}
entEll.getPointAtParam(dStepE, pt);
arptKey.append(pt);
}
//直线段(结束处前端和后端)
pt = ptEndArc + vtGEnd * dEndWidth / 2;
for(int m = 0; m < nColumns; m++)
{
arptKey.append(pt);
pt.rotateBy(dMinDiffAng, -vtEnd, ptEnd);
}
pt = ptEndArc + vtGEnd * dEndWidth / 2;
arptKey.append(pt);
pt = ptEnd + vtGEnd * dEndWidth / 2;
for(int n = 0; n < nColumns; n++)
{
arptKey.append(pt);
pt.rotateBy(dMinDiffAng, -vtEnd, ptEnd);
}
pt = ptEnd + vtGEnd * dEndWidth / 2;
arptKey.append(pt);
nTemp = arptKey.length();
arPtsOnCir.setLogicalLength(0);
for (int j = 0; j <= nTemp-3;)
{
arPtsOnCir.append(arptKey[j]);
arPtsOnCir.append(arptKey[j+1]);
arPtsOnCir.append(arptKey[j+2]);
j = j + (nColumns + 1);
}
AcGePlane plan(AcGePoint3d::kOrigin, GetUcsZvt());
AcGeCircArc3d cir; // 分节圆
AcGeVector3d vt1, vt2, vtcirNor;
AcDbPolyline *pLine = new AcDbPolyline;
if (NULL == pLine)
return FALSE;
int iRes = -1;
AcGePoint3d ptU, ptD;
for (i = 0; i < arPtsOnCir.length(); )// 几个圆
{
cir.set(arPtsOnCir[i], arPtsOnCir[i+1], arPtsOnCir[i+2]);
pt = cir.center();
vt1 = arPtsOnCir[i+1] - pt;
vt2 = arPtsOnCir[i+2] - pt;
vtcirNor = vt1.crossProduct(vt2); // 分节圆法向
vtTest = vtcirNor;
plan.set(pt, GetUcsZvt());
dTemp = vtcirNor.angleOnPlane(plan);
if (dTemp < PI)
vtTest.negate();
iRes = GetEllipseFromCircle(pt, cir.radius() * 2, vtcirNor, GetUcsZvt(), *pLine, vtcirNor);
ptGeCen = ptGeCen.orthoProject(plan);
if (2 == iRes || iRes == 1 || iRes == 0)
{
pLine->getPointAt(0, ptU);
nTemp = pLine->numVerts();
pLine->getPointAt(nTemp-1, ptD);
if (ptU.distanceTo(ptGeCen) >= ptD.distanceTo(ptGeCen))
{
arPtsU.append(ptU);
arPtsD.append(ptD);
}
else
{
arPtsU.append(ptD);
arPtsD.append(ptU);
}
pLine->reset(Adesk::kFalse, nTemp);
i = i+3;// 每3个点确定一个面
}
}
if (NULL != pLine)
delete pLine;
// 当分节面密集的时候,容易错误
for (i = 0; i < arPtsD.length(); i++)
{
arPtsD[i].z = ptCorner.z;
arPtsU[i].z = ptCorner.z;
}
// if (eElbowType != AecHvac::eSegmental)
// {
AcGeLineSeg3d line1, line2;
AcGePoint3d ptInter;
for(i = 0; i < arPtsD.length()-1; i++)
{
// 前面的线段
line1.set(arPtsD[i], arPtsD[i+1]);
for (int j = i+1; j < arPtsD.length()-1; j++)
{
line2.set(arPtsD[j], arPtsD[j+1]);
if (Adesk::kTrue == line1.intersectWith(line2, ptInter))
{
if (!ptInter.isEqualTo(arPtsD[j]))
{
// 前一个线段和后线段相交
for (int n = i+1; n<=j ; n++)
{
arPtsD[n] = ptInter;
}
}
}
}
}
// }
return TRUE;
}
BOOL ImpHvacElbow::GetAllArcuateCplCurveInc(AecComplexCurve& cplCurve,int &nType,AcGePoint3d& ptStart, AcGePoint3d& ptCorner,
AcGePoint3d& ptEnd,double& dPlusEdge,double& dDiameterS,double& dDiameterE,
int& nWrapType) const
{
if (nType != 0 && nType != 1)
{
return FALSE;
}
AcGeVector3d vtStr,vtEnd,vtCor,vtNor = AcGeVector3d::kZAxis, vtZAxis, vtX;
AcGePoint3d ptGeCen,ptStartU,ptStartD,ptCornerU,ptEndU,ptEndD,ptCornerD, ptOrgStart;
AcGePoint3d ptStartX,ptStartXU,ptStartXD,ptEndX,ptEndXU,ptEndXD,ptCorOnArc;
AcGePlane stdPlan(ptCorner, GetUcsZvt());
AcGePoint3dArray arPtsCen, arPtsU, arPtsD;
ptStartX = ptStart;
ptEndX = ptEnd;
vtStr = ptStart - ptCorner;
vtEnd = ptEnd - ptCorner;
vtStr.normalize();
vtEnd.normalize();
vtNor = vtStr.crossProduct(vtEnd);
//ptStart,ptEnd都改变了,去掉了直边段
ptStart = ptStart - vtStr * dPlusEdge;
ptEnd = ptEnd - vtEnd * dPlusEdge;
// 计算弯头截面的弧线(端线)
AcGePoint3dArray arPtS, arPtE;
vtZAxis = GetUcsZvt();
AcDbPolyline *pLine = new AcDbPolyline;
if (NULL == pLine)
return FALSE;
// 方向要从端点指向拐点
vtStr = - vtStr;
vtEnd = - vtEnd;
if (ptStartX.z > ptCorner.z)
;
else
vtStr = -vtStr;
int iRes = GetEllipsePtsFromCircle(arPtS, ptStartX, dDiameterS * 2, vtStr, vtZAxis, *pLine, vtStr); //Lixl add 2011-11-23
pLine->reset(Adesk::kFalse, iRes);
if (ptEndX.z > ptCorner.z)
;
else
vtEnd = -vtEnd;
iRes = GetEllipsePtsFromCircle(arPtE, ptEndX, dDiameterE * 2, vtEnd, vtZAxis, *pLine, vtEnd); //Lixl add 2011-11-23
if (NULL != pLine)
delete pLine;
vtStr = ptStart - ptCorner;
vtEnd = ptEnd - ptCorner;
vtStr.normalize();
vtEnd.normalize();
// 计算两外轮廓线的端点
ptStartX = ptStartX.orthoProject(stdPlan);
ptEndX = ptEndX.orthoProject(stdPlan);
vtStr = vtStr.orthoProject(vtZAxis);
vtEnd = vtEnd.orthoProject(vtZAxis);
vtStr.rotateBy(PI * 0.5, vtZAxis);
vtEnd.rotateBy(PI * 0.5, vtZAxis);
if (!GetIntersectWith(ptStartX, ptEndX, vtStr, vtEnd, ptGeCen))
return FALSE;
vtStr = ptStartX - ptGeCen;
vtEnd = ptEndX - ptGeCen;
ptStartXU = ptGeCen + vtStr.normalize() * dDiameterS;
ptStartXD = ptGeCen - vtStr.normalize() * dDiameterS;
ptEndXU = ptGeCen + vtEnd.normalize() * dDiameterE;
ptEndXD = ptGeCen - vtEnd.normalize() * dDiameterE;
// 计算两条外轮廓线
if (!GetPrjPts(arPtsU, arPtsD))
return FALSE;
int i = 0;
for (i = 0; i < arPtsU.length(); i++)
{
arPtsU[i] = arPtsU[i].orthoProject(stdPlan);
arPtsD[i] = arPtsD[i].orthoProject(stdPlan);
Midpoint(arPtsU[i], arPtsD[i], ptCorOnArc);
arPtsCen.append(ptCorOnArc);
}
AecEqui::AecCurveElement el;
memset(&el,0,sizeof(AecEqui::AecCurveElement));
//外轮廓
double dEdgeWidth = GetEdgeLineWidth();
double dCenWidth = GetCentLineWidth();
double dEndLineWidth = GetEndLineWidth();
AcDbObjectId idEndLayer(NULL),idSideLayer(NULL),idBaseLayer(NULL);
m_pXDataMap->GetAt(HVAC_EndLayer, idEndLayer);
if (IsInclineAlignment())
nWrapType = AecHvac::eAllArcuate;
//消声
if(AecHvac::eAllArcWrap == nWrapType)
{
//外轮廓
if (0 == nType)
{
AcGePoint3d ptWrapStrU,ptWrapStrD,ptWrapEndU,ptWrapEndD;
AcGePoint3d ptWrapStrXU,ptWrapStrXD,ptWrapEndXU,ptWrapEndXD;
AcGePoint3d ptWrapCorU,ptWrapCorD;
double dWrap = MayAsMUnit(50);
ptWrapStrU = ptStartU + vtStr * dWrap;
ptWrapStrD = ptStartD - vtStr * dWrap;
ptWrapStrXU = ptStartXU + vtStr * dWrap;
ptWrapStrXD = ptStartXD - vtStr * dWrap;
ptWrapEndU = ptEndU + vtEnd * dWrap;
ptWrapEndD = ptEndD - vtEnd * dWrap;
ptWrapEndXU = ptEndXU + vtEnd * dWrap;
ptWrapEndXD = ptEndXD - vtEnd * dWrap;
el.gsMark = 0;
el.dWidth = dEndLineWidth;
el.idSubLay = idEndLayer;
el.ptGe[0] = ptWrapStrXU;
el.ptGe[1] = ptWrapStrXD;
el.ptGe[2] = ptWrapStrXD;
cplCurve.append(el);
el.ptGe[0] = ptWrapEndXU;
el.ptGe[1] = ptWrapEndXD;
el.ptGe[2] = ptWrapEndXD;
cplCurve.append(el);
el.ptGe[0] = ptWrapStrD;
el.ptGe[1] = ptWrapCorD;
el.ptGe[2] = ptWrapEndD;
cplCurve.append(el);
el.ptGe[0] = ptWrapStrU;
el.ptGe[1] = ptWrapCorU;
el.ptGe[2] = ptWrapEndU;
cplCurve.append(el);
el.ptGe[0] = ptWrapStrXU;
el.ptGe[1] = ptWrapStrU;
el.ptGe[2] = ptWrapStrU;
cplCurve.append(el);
el.ptGe[0] = ptWrapEndU;
el.ptGe[1] = ptWrapEndXU;
el.ptGe[2] = ptWrapEndXU;
cplCurve.append(el);
el.ptGe[0] = ptWrapStrXD;
el.ptGe[1] = ptWrapStrD;
el.ptGe[2] = ptWrapStrD;
cplCurve.append(el);
el.ptGe[0] = ptWrapEndD;
el.ptGe[1] = ptWrapEndXD;
el.ptGe[2] = ptWrapEndXD;
cplCurve.append(el);
}
//内部线
else if (1 == nType)
{
if (!IsSingleLine())
{
//消声内弧
el.idSubLay = layerId();
el.dWidth = dEdgeWidth;
el.ptGe[0] = ptStartXU;
el.ptGe[1] = ptStartU;
el.ptGe[2] = ptStartU;
cplCurve.append(el);
el.ptGe[0] = ptStartU;
el.ptGe[1] = ptCornerU;
el.ptGe[2] = ptEndU;
cplCurve.append(el);
el.ptGe[0] = ptEndU;
el.ptGe[1] = ptEndXU;
el.ptGe[2] = ptEndXU;
cplCurve.append(el);
el.ptGe[0] = ptEndXD;
el.ptGe[1] = ptEndD;
el.ptGe[2] = ptEndD;
cplCurve.append(el);
el.ptGe[0] = ptStartD;
el.ptGe[1] = ptCornerD;
el.ptGe[2] = ptEndD;
cplCurve.append(el);
el.ptGe[0] = ptStartD;
el.ptGe[1] = ptStartXD;
el.ptGe[2] = ptStartXD;
cplCurve.append(el);
}
//中心线
if ((HasBaseLine() || IsSingleLine()))
{
el.gsMark = -1;
el.idSubLay = idBaseLayer;
if (IsSingleLine())
el.dWidth = dEdgeWidth;
else
el.dWidth = dCenWidth;
el.ptGe[0] = ptStartX;
el.ptGe[1] = ptStart;
el.ptGe[2] = ptStart;
cplCurve.append(el);
el.ptGe[0] = ptStart;
el.ptGe[1] = ptCorOnArc;
el.ptGe[2] = ptEnd;
cplCurve.append(el);
el.ptGe[0] = ptEnd;
el.ptGe[1] = ptEndX;
el.ptGe[2] = ptEndX;
cplCurve.append(el);
return TRUE;
}
}
}
//内外圆弧
else
{
if (0 == nType)
{
el.idSubLay = idSideLayer;
el.gsMark = 0;
el.dWidth = dEdgeWidth;
// 弯头外圆弧曲线
for (i = 0; i <= arPtsU.length()-2; i++)
{
el.ptGe[0] = arPtsU[i];
el.ptGe[1] = arPtsU[i+1];
el.ptGe[2] = arPtsU[i+1];
cplCurve.append(el);
}
// 弯头内圆弧曲线
for (i = 0; i <= arPtsD.length()-2; i++)
{
el.ptGe[0] = arPtsD[i];
el.ptGe[1] = arPtsD[i+1];
el.ptGe[2] = arPtsD[i+1];
cplCurve.append(el);
}
// 画端线
el.idSubLay = idEndLayer;
el.dWidth = dEndLineWidth;
for (i = 0; i < arPtS.length()-1; i++)//Lixl add 2011-11-23
{
el.ptGe[0] = arPtS[i];
el.ptGe[1] = arPtS[i+1];
el.ptGe[2] = arPtS[i+1];
cplCurve.append(el);
}
for (i = 0; i < arPtE.length()-1; i++)//Lixl add 2011-11-23
{
el.ptGe[0] = arPtE[i];
el.ptGe[1] = arPtE[i+1];
el.ptGe[2] = arPtE[i+1];
cplCurve.append(el);
}
}
//中心线
else if (1 == nType)
{
if (HasBaseLine() || IsSingleLine())
{
el.gsMark = -1;
el.idSubLay = idBaseLayer;
if (IsSingleLine())
el.dWidth = dEdgeWidth;
else
el.dWidth = dCenWidth;
for (i = 0; i <= arPtsCen.length()-2; i++)
{
// if (i > 1 && i%2 == 0)
// {
el.ptGe[0] = arPtsCen[i];
el.ptGe[1] = arPtsCen[i+1];
el.ptGe[2] = arPtsCen[i+1];
cplCurve.append(el);
// }
}
}
}
}
return cplCurve.length() > 0;
}
/////////////////////////////////////
// su
// sxu ─ ──────╮
// sx ─ ─────╮│
// sxd ─ ────╮││
// sd │││
// │││
// ed e eu
// │││
// exd ex exu
//////////////////////////////////////
BOOL ImpHvacElbow::GetAllArcuateCplCurveHor(AecComplexCurve& cplCurve,int &nType,
AcGePoint3d& ptStart, AcGePoint3d& ptCorner,
AcGePoint3d& ptEnd,double& dPlusEdge,
double& dDiameterS,double& dDiameterE,
int& nWrapType) const
{
if (nType != 0 && nType != 1)
{
return FALSE;
}
AcGeVector3d vtStr,vtEnd,vtCor,vtNor = AcGeVector3d::kZAxis;
AcGePoint3d ptGeCen,ptStartU,ptStartD,ptCornerU,ptEndU,ptEndD,ptCornerD;
AcGePoint3d ptStartX,ptStartXU,ptStartXD,ptEndX,ptEndXU,ptEndXD,ptCorOnArc;
ptStartX = ptStart;
ptEndX = ptEnd;
vtStr = ptStart - ptCorner;
vtEnd = ptEnd - ptCorner;
vtStr.normalize();
vtEnd.normalize();
vtNor = vtStr.crossProduct(vtEnd);
//ptStart,ptEnd都改变了,去掉了直边段
ptStart = ptStart - vtStr * dPlusEdge;
ptEnd = ptEnd - vtEnd * dPlusEdge;
vtStr.rotateBy(PI * 0.5,vtNor);
vtEnd.rotateBy(PI * 0.5,vtNor);
//求出圆心ptGeCen
if(!GetIntersectWith(ptStart,ptEnd,vtStr,vtEnd,ptGeCen))
return FALSE;
vtStr = ptStart - ptGeCen;
vtEnd = ptEnd - ptGeCen;
vtCor = ptCorner - ptGeCen;
vtStr.normalize();
vtEnd.normalize();
vtCor.normalize();
ptStartU = ptStart + vtStr * dDiameterS;
ptStartD = ptStart - vtStr * dDiameterS;
ptEndU = ptEnd + vtEnd * dDiameterE;
ptEndD = ptEnd - vtEnd * dDiameterE;
//曲率半径
double dRadRatio = ptStart.distanceTo(ptGeCen);
ptCorOnArc = ptGeCen + vtCor * dRadRatio;
ptCornerU = ptGeCen + vtCor * (dRadRatio + dDiameterS * 0.5 + dDiameterE * 0.5);
ptCornerD = ptGeCen + vtCor * (dRadRatio - dDiameterS * 0.5 - dDiameterE * 0.5);
//计算直边段的端点
AcGeVector3d vtStrT = ptStart - ptCorner;
AcGeVector3d vtEndT = ptEnd - ptCorner;
vtStrT.normalize();
vtEndT.normalize();
ptStartXU = ptStartU + vtStrT * dPlusEdge;
ptStartXD = ptStartD + vtStrT * dPlusEdge;
ptEndXU = ptEndU + vtEndT * dPlusEdge;
ptEndXD = ptEndD + vtEndT * dPlusEdge;
AecEqui::AecCurveElement el;
memset(&el,0,sizeof(AecEqui::AecCurveElement));
//外轮廓
double dEdgeWidth = GetEdgeLineWidth();
double dCenWidth = GetCentLineWidth();
double dEndLineWidth = GetEndLineWidth();
AcDbObjectId idEndLayer(NULL),idSideLayer(NULL),idBaseLayer(NULL);
m_pXDataMap->GetAt(HVAC_EndLayer, idEndLayer);
if(AecHvac::eAllArcWrap == nWrapType)
{
//外轮廓
if (0 == nType)
{
AcGePoint3d ptWrapStrU,ptWrapStrD,ptWrapEndU,ptWrapEndD;
AcGePoint3d ptWrapStrXU,ptWrapStrXD,ptWrapEndXU,ptWrapEndXD;
AcGePoint3d ptWrapCorU,ptWrapCorD;
double dWrap = MayAsMUnit(50);
ptWrapStrU = ptStartU + vtStr * dWrap;
ptWrapStrD = ptStartD - vtStr * dWrap;
ptWrapStrXU = ptStartXU + vtStr * dWrap;
ptWrapStrXD = ptStartXD - vtStr * dWrap;
ptWrapEndU = ptEndU + vtEnd * dWrap;
ptWrapEndD = ptEndD - vtEnd * dWrap;
ptWrapEndXU = ptEndXU + vtEnd * dWrap;
ptWrapEndXD = ptEndXD - vtEnd * dWrap;
ptWrapCorU = ptGeCen + vtCor * (dRadRatio + dDiameterS * 0.5 + dDiameterE * 0.5 + dWrap);
ptWrapCorD = ptGeCen + vtCor * (dRadRatio - dDiameterS * 0.5 - dDiameterE * 0.5 - dWrap);
el.gsMark = 0;
//el.dWidth = dEdgeWidth;
el.dWidth = dEndLineWidth;
el.idSubLay = idEndLayer;
el.ptGe[0] = ptWrapStrXU;
el.ptGe[1] = ptWrapStrXD;
el.ptGe[2] = ptWrapStrXD;
cplCurve.append(el);
el.ptGe[0] = ptWrapEndXU;
el.ptGe[1] = ptWrapEndXD;
el.ptGe[2] = ptWrapEndXD;
cplCurve.append(el);
el.ptGe[0] = ptWrapStrD;
el.ptGe[1] = ptWrapCorD;
el.ptGe[2] = ptWrapEndD;
cplCurve.append(el);
el.ptGe[0] = ptWrapStrU;
el.ptGe[1] = ptWrapCorU;
el.ptGe[2] = ptWrapEndU;
cplCurve.append(el);
el.ptGe[0] = ptWrapStrXU;
el.ptGe[1] = ptWrapStrU;
el.ptGe[2] = ptWrapStrU;
cplCurve.append(el);
el.ptGe[0] = ptWrapEndU;
el.ptGe[1] = ptWrapEndXU;
el.ptGe[2] = ptWrapEndXU;
cplCurve.append(el);
el.ptGe[0] = ptWrapStrXD;
el.ptGe[1] = ptWrapStrD;
el.ptGe[2] = ptWrapStrD;
cplCurve.append(el);
el.ptGe[0] = ptWrapEndD;
el.ptGe[1] = ptWrapEndXD;
el.ptGe[2] = ptWrapEndXD;
cplCurve.append(el);
}
//内部线
else if (1 == nType)
{
if (!IsSingleLine())
{
//消声内弧
el.idSubLay = layerId();
el.dWidth = dEdgeWidth;
el.ptGe[0] = ptStartXU;
el.ptGe[1] = ptStartU;
el.ptGe[2] = ptStartU;
cplCurve.append(el);
el.ptGe[0] = ptStartU;
el.ptGe[1] = ptCornerU;
el.ptGe[2] = ptEndU;
cplCurve.append(el);
el.ptGe[0] = ptEndU;
el.ptGe[1] = ptEndXU;
el.ptGe[2] = ptEndXU;
cplCurve.append(el);
el.ptGe[0] = ptEndXD;
el.ptGe[1] = ptEndD;
el.ptGe[2] = ptEndD;
cplCurve.append(el);
el.ptGe[0] = ptStartD;
el.ptGe[1] = ptCornerD;
el.ptGe[2] = ptEndD;
cplCurve.append(el);
el.ptGe[0] = ptStartD;
el.ptGe[1] = ptStartXD;
el.ptGe[2] = ptStartXD;
cplCurve.append(el);
}
//中心线
if ((HasBaseLine() || IsSingleLine()))
{
el.gsMark = -1;
el.idSubLay = idBaseLayer;
if (IsSingleLine())
el.dWidth = dEdgeWidth;
else
el.dWidth = dCenWidth;
el.ptGe[0] = ptStartX;
el.ptGe[1] = ptStart;
el.ptGe[2] = ptStart;
cplCurve.append(el);
el.ptGe[0] = ptStart;
el.ptGe[1] = ptCorOnArc;
el.ptGe[2] = ptEnd;
cplCurve.append(el);
el.ptGe[0] = ptEnd;
el.ptGe[1] = ptEndX;
el.ptGe[2] = ptEndX;
cplCurve.append(el);
return TRUE;
}
}
}
//内外圆弧
else
{
if (0 == nType)
{
el.idSubLay = idSideLayer;
el.gsMark = 0;
el.dWidth = dEdgeWidth;
el.ptGe[0] = ptStartXU;
el.ptGe[1] = ptStartU;
el.ptGe[2] = ptStartU;
cplCurve.append(el);
el.ptGe[0] = ptStartU;
el.ptGe[1] = ptCornerU;
el.ptGe[2] = ptEndU;
cplCurve.append(el);
el.ptGe[0] = ptEndU;
el.ptGe[1] = ptEndXU;
el.ptGe[2] = ptEndXU;
cplCurve.append(el);
el.ptGe[0] = ptEndXD;
el.ptGe[1] = ptEndD;
el.ptGe[2] = ptEndD;
cplCurve.append(el);
el.ptGe[0] = ptStartD;
el.ptGe[1] = ptCornerD;
el.ptGe[2] = ptEndD;
cplCurve.append(el);
el.ptGe[0] = ptStartD;
el.ptGe[1] = ptStartXD;
el.ptGe[2] = ptStartXD;
cplCurve.append(el);
el.idSubLay = idEndLayer;
el.dWidth = dEndLineWidth;
el.ptGe[0] = ptStartXU;
el.ptGe[1] = ptStartXD;
el.ptGe[2] = ptStartXD;
cplCurve.append(el);
el.ptGe[0] = ptEndXU;
el.ptGe[1] = ptEndXD;
el.ptGe[2] = ptEndXD;
cplCurve.append(el);
}
//中心线
else if (1 == nType)
{
if (HasBaseLine() || IsSingleLine())
{
el.gsMark = -1;
el.idSubLay = idBaseLayer;
if (IsSingleLine())
el.dWidth = dEdgeWidth;
else
el.dWidth = dCenWidth;
el.ptGe[0] = ptStartX;
el.ptGe[1] = ptStart;
el.ptGe[2] = ptStart;
cplCurve.append(el);
el.ptGe[0] = ptStart;
el.ptGe[1] = ptCorOnArc;
el.ptGe[2] = ptEnd;
cplCurve.append(el);
el.ptGe[0] = ptEnd;
el.ptGe[1] = ptEndX;
el.ptGe[2] = ptEndX;
cplCurve.append(el);
}
// 消声弯头
if(AecHvac::eAllArcInWrap == nWrapType)
{
// 计算内衬位置 宽度的1/10
double dWidth = 0;
m_pXDataMap->GetAt(HELB_StartWidth, dWidth);
double dLiningS = dWidth * 0.1;
m_pXDataMap->GetAt(HELB_EndWidth, dWidth);
double dLiningE = dWidth * 0.1;
double dLiningM = (dLiningS + dLiningE) / 2;
////////////////////////////////////////
// 2
// 1 ─ ──────╮3
// │
// 0 ─ ────╮ │
// 9 8 │ │
// │ │
// 7 4
// │ │
// 6 5
////////////////////////////////////////
// 计算关键点
AcGePoint3d ptL1 = ptStartXU - vtStr * dLiningS;
AcGePoint3d ptL2 = ptStartU - vtStr * dLiningS;
AcGePoint3d ptL3 = ptCornerU - vtCor * dLiningM;
AcGePoint3d ptL4 = ptEndU - vtEnd * dLiningE;
AcGePoint3d ptL5 = ptEndXU - vtEnd * dLiningE;
AcGePoint3d ptL6 = ptEndXD + vtEnd * dLiningE;
AcGePoint3d ptL7 = ptEndD + vtEnd * dLiningE;
AcGePoint3d ptL8 = ptCornerD + vtCor * dLiningM;
AcGePoint3d ptL9 = ptStartD + vtStr * dLiningS;
AcGePoint3d ptL0 = ptStartXD + vtStr * dLiningS;
el.idSubLay = idEndLayer;
el.idSubLty = KTSetting::InitLineStyle(_T("DASHED"));
el.ptGe[0] = ptL1;
el.ptGe[1] = ptL2;
el.ptGe[2] = ptL2;
cplCurve.append(el);
el.ptGe[0] = ptL2;
el.ptGe[1] = ptL3;
el.ptGe[2] = ptL4;
cplCurve.append(el);
el.ptGe[0] = ptL4;
el.ptGe[1] = ptL5;
el.ptGe[2] = ptL5;
cplCurve.append(el);
el.ptGe[0] = ptL0;
el.ptGe[1] = ptL9;
el.ptGe[2] = ptL9;
cplCurve.append(el);
el.ptGe[0] = ptL9;
el.ptGe[1] = ptL8;
el.ptGe[2] = ptL7;
cplCurve.append(el);
el.ptGe[0] = ptL7;
el.ptGe[1] = ptL6;
el.ptGe[2] = ptL6;
cplCurve.append(el);
}
}
}
return cplCurve.length() > 0;
}
////////////////////////////////////
// su
// sxu ─ ──────╮
// sx ─ ─────╮│
// sxd ─ ────╮││
// sd │││
// │││
// ed e eu
// │││
// exd ex exu
////////////////////////////////////
BOOL ImpHvacElbow::GetPtsSegmentalHor(AcGePoint3dArray& pts) const
{
double dDiameter = MayAsMUnit(300),dPlusEdge = MayAsMUnit(50.0);
int nSectType = 2;
AcDbObjectId idLayer;
int nBaseLine = 1;
int nSingleLine = 0;
int nSegments = 5;
AcGePoint3d ptStart, ptCorner, ptEnd;
//BEGIN======================================================
double dDiameterStart = MayAsMUnit(400.0);
double dDiameterEnd = MayAsMUnit(400.0);
m_pXDataMap->GetAt(HELB_Segments, nSegments);
m_pXDataMap->GetAt(HVAC_SectType,nSectType);
m_pXDataMap->GetAt(HELB_StartWidth, dDiameterStart);
if (!m_pXDataMap->GetAt(HELB_EndWidth, dDiameterEnd))
{
dDiameterEnd = dDiameterStart;
}
m_pXDataMap->GetAt(HELB_StartPoint,ptStart);
m_pXDataMap->GetAt(HELB_CornerPoint,ptCorner);
m_pXDataMap->GetAt(HELB_EndPoint,ptEnd);
m_pXDataMap->GetAt(HVAC_HasBaseLine,nBaseLine);
m_pXDataMap->GetAt(HVAC_IsSingleLine,nSingleLine);
//dPlusEdge = 50.0;
if (nSegments < 2)
nSegments = 2;
//dDiameter *= 0.5;
double dMaxWidth = dDiameterStart > dDiameterEnd ? dDiameterStart : dDiameterEnd;
if ((ptStart.distanceTo(ptCorner) - MayAsMUnit(50.0)) - dMaxWidth / 2 < -1e-6)
{
dPlusEdge = 0.1;
}
dDiameterStart *= 0.5;
dDiameterEnd *= 0.5;
AcGeVector3d vtStr,vtEnd,vtCor,vtNor = AcGeVector3d::kZAxis;
AcGePoint3d ptGeCen,ptStartU,ptStartD,ptCornerU,ptEndU,ptEndD,ptCornerD;
AcGePoint3d ptStartX,ptStartXU,ptStartXD,ptEndX,ptEndXU,ptEndXD,ptCorOnArc;
ptStartX = ptStart;
ptEndX = ptEnd;
vtStr = ptStart - ptCorner;
vtEnd = ptEnd - ptCorner;
vtStr.normalize();
vtEnd.normalize();
vtNor = vtStr.crossProduct(vtEnd);
//ptStart,ptEnd都改变了,去掉了直边段
ptStart = ptStart - vtStr * dPlusEdge;
ptEnd = ptEnd - vtEnd * dPlusEdge;
vtStr.rotateBy(PI * 0.5,vtNor);
vtEnd.rotateBy(PI * 0.5,vtNor);
//求出圆心ptGeCen
if(!GetIntersectWith(ptStart,ptEnd,vtStr,vtEnd,ptGeCen))
return FALSE;
vtStr = ptStart - ptGeCen;
vtEnd = ptEnd - ptGeCen;
vtCor = ptCorner - ptGeCen;
vtStr.normalize();
vtEnd.normalize();
vtCor.normalize();
ptStartU = ptStart + vtStr * dDiameterStart;
ptStartD = ptStart - vtStr * dDiameterStart;
ptEndU = ptEnd + vtEnd * dDiameterEnd;
ptEndD = ptEnd - vtEnd * dDiameterEnd;
//计算半径偏移量
double dDiameterOffset = dDiameterEnd - dDiameterStart;
ptCorOnArc = ptGeCen + vtCor * ptStart.distanceTo(ptGeCen);
//计算直边段的端点
AcGeVector3d vtStrT = ptStart - ptCorner;
AcGeVector3d vtEndT = ptEnd - ptCorner;
vtStrT.normalize();
vtEndT.normalize();
ptStartXU = ptStartU + vtStrT * dPlusEdge;
ptStartXD = ptStartD + vtStrT * dPlusEdge;
ptEndXU = ptEndU + vtEndT * dPlusEdge;
ptEndXD = ptEndD + vtEndT * dPlusEdge;
double dAngle = fabs(vtEnd.angleTo(vtStr,vtNor));
if (dAngle > PI)
{
dAngle = 2 * PI - dAngle;
}
double dSegAngle = dAngle / nSegments;
pts.append(ptStartXU);
AcGePoint3d pt;
pt = ptStartU;
pts.append(pt);
pt = ptStart;
int j(0);
int nOffsetRatioj(1);
for (j = 0, nOffsetRatioj = 1; j < nSegments - 1; j++, nOffsetRatioj += 1)
{
pt.rotateBy(dSegAngle,-vtNor,ptGeCen);
//BEGIN==========================================================================================
AcGePoint3d ptBuffer; //临时存放计算得到的点值
AcGeVector3d vtTemp = pt - ptGeCen;
vtTemp.normalize();
ptBuffer = pt + vtTemp * (dDiameterOffset * nOffsetRatioj / nSegments + dDiameterStart);
pts.append(ptBuffer);
}
pts.append(ptEndU);
pts.append(ptEndXU);
//下圆弧的点
pts.append(ptStartXD);
pt = ptStartD;
pts.append(pt);
pt = ptStart;
int i(0);
int nOffsetRatioi(1);
for (i = 0, nOffsetRatioi = 1; i < nSegments - 1; i++, nOffsetRatioi += 1)
{
pt.rotateBy(dSegAngle,-vtNor,ptGeCen);
AcGePoint3d ptBuffer; //临时存放计算得到的点值
AcGeVector3d vtTemp = pt - ptGeCen;
vtTemp.normalize();
ptBuffer = pt - vtTemp * (dDiameterOffset * nOffsetRatioi / nSegments + dDiameterStart);
pts.append(ptBuffer);
}
pts.append(ptEndD);
pts.append(ptEndXD);
//中心线的5个点
pts.append(ptStartX);
pts.append(ptStart);
pts.append(ptCorOnArc);
pts.append(ptEnd);
pts.append(ptEndX);
return pts.length() > 0;
}
////////////////////////////////////
// su
// sxu ─ ──────╮
// sx ─ ─────╮│
// sxd ─ \ ││
// sd \ ││
// \ ││
// \ ed e eu
// │││
// exd ex exu
/////////////////////////////////////
BOOL ImpHvacElbow::GetInclineCplCurveHor(AecComplexCurve& cplCurve,int &nType,AcGePoint3d& ptStart, AcGePoint3d& ptCorner,AcGePoint3d& ptEnd,double& dPlusEdge,double& dDiameterS,double& dDiameterE) const
{
if (nType != 0 && nType != 1)
{
return FALSE;
}
AcGeVector3d vtStr,vtEnd,vtCor,vtNor = AcGeVector3d::kZAxis;
AcGePoint3d ptGeCen,ptStartU,ptStartD,ptCornerU,ptEndU,ptEndD,ptCornerD;
AcGePoint3d ptStartX,ptStartXU,ptStartXD,ptEndX,ptEndXU,ptEndXD,ptCorOnArc;
//保证Star点永远在End前面,否则管线反向绘制隔板弯头会有问题
if (ptStart.x > ptEnd.x)
{
AcGePoint3d ptTemp(ptStart);
ptStart = ptEnd;
ptEnd = ptTemp;
//=========================================================
double dTemp = dDiameterS;
dDiameterS = dDiameterE;
dDiameterE =dTemp;
}
ptStartX = ptStart;
ptEndX = ptEnd;
vtStr = ptStart - ptCorner;
vtEnd = ptEnd - ptCorner;
vtStr.normalize();
vtEnd.normalize();
vtNor = vtStr.crossProduct(vtEnd);
//ptStart,ptEnd都改变了,去掉了直边段
ptStart = ptStart - vtStr * dPlusEdge;
ptEnd = ptEnd - vtEnd * dPlusEdge;
vtStr.rotateBy(PI * 0.5,vtNor);
vtEnd.rotateBy(PI * 0.5,vtNor);
//求出圆心ptGeCen
if(!GetIntersectWith(ptStart,ptEnd,vtStr,vtEnd,ptGeCen))
return FALSE;
vtStr = ptStart - ptGeCen;
vtEnd = ptEnd - ptGeCen;
vtCor = ptCorner - ptGeCen;
vtStr.normalize();
vtEnd.normalize();
vtCor.normalize();
ptStartU = ptStart + vtStr * dDiameterS;
ptStartD = ptStart - vtStr * dDiameterS;
ptEndU = ptEnd + vtEnd * dDiameterE;
ptEndD = ptEnd - vtEnd * dDiameterE;
//计算直边段的端点
ptStartXU = ptStartX + vtStr * dDiameterS;
ptStartXD = ptStartX - vtStr * dDiameterS;
ptEndXU = ptEndX + vtEnd * dDiameterE;
ptEndXD = ptEndX - vtEnd * dDiameterE;
vtStr = ptStart - ptCorner;
vtEnd = ptEnd - ptCorner;
vtStr.normalize();
vtEnd.normalize();
ptCornerU = (ptCorner - vtStr * dDiameterE) - vtEnd * dDiameterS;
AcDbObjectId idBaseLayer(NULL), idSideLayer(NULL), idEndLayer(NULL);
// //m_pXDataMap->GetAt(HVAC_BaseLayer, idBaseLayer);
m_pXDataMap->GetAt(HVAC_EndLayer, idSideLayer);
AecEqui::AecCurveElement el;
memset(&el,0,sizeof(AecEqui::AecCurveElement));
double dEdgeWidth = GetEdgeLineWidth();
double dCenWidth = GetCentLineWidth();
double dEndLineWidth = GetEndLineWidth();
// 弯头类型
AecHvac::HvacElbowType eElbowType = AecHvac::eIncline;
m_pXDataMap->GetAt(HELB_Type, (int&)eElbowType);
// 根据类型,是否绘制消声线
switch (eElbowType)
{
case AecHvac::eIncline: // 内斜线
{
//外轮廓
if (0 == nType)
{
el.dWidth = dEdgeWidth;
//el.idSubLay = idSideLayer;
el.ptGe[0] = ptStartXU;
el.ptGe[1] = ptCornerU;
el.ptGe[2] = ptCornerU;
cplCurve.append(el);
el.ptGe[0] = ptCornerU;
el.ptGe[1] = ptEndXU;
el.ptGe[2] = ptEndXU;
cplCurve.append(el);
el.ptGe[0] = ptEndXD;
el.ptGe[1] = ptEndD;
el.ptGe[2] = ptEndD;
cplCurve.append(el);
el.ptGe[0] = ptEndD;
el.ptGe[1] = ptStartD;
el.ptGe[2] = ptStartD;
cplCurve.append(el);
el.ptGe[0] = ptStartD;
el.ptGe[1] = ptStartXD;
el.ptGe[2] = ptStartXD;
cplCurve.append(el);
el.dWidth = dEndLineWidth;
el.idSubLay = idSideLayer;
el.ptGe[0] = ptEndXU;
el.ptGe[1] = ptEndXD;
el.ptGe[2] = ptEndXD;
cplCurve.append(el);
el.ptGe[0] = ptStartXD;
el.ptGe[1] = ptStartXU;
el.ptGe[2] = ptStartXU;
cplCurve.append(el);
}
//中心线
else if (1 == nType && (HasBaseLine() || IsSingleLine()))
{
el.gsMark = -1;
el.idSubLay = idBaseLayer;
if (IsSingleLine())
el.dWidth = dEdgeWidth;
else
el.dWidth = dCenWidth;
el.ptGe[0] = ptStartX;
el.ptGe[1] = ptCorner;
el.ptGe[2] = ptCorner;
cplCurve.append(el);
el.ptGe[0] = ptCorner;
el.ptGe[1] = ptEndX;
el.ptGe[2] = ptEndX;
cplCurve.append(el);
}
break;
}
case AecHvac::eInclineWrap: // 内斜线消声
{
//外轮廓
if (0 == nType)
{
AcGePoint3d ptWrapStrU,ptWrapStrD,ptWrapEndU,ptWrapEndD;
AcGePoint3d ptWrapStrXU,ptWrapStrXD,ptWrapEndXU,ptWrapEndXD;
AcGePoint3d ptWrapCorU,ptWrapCorD;
double dWrap = MayAsMUnit(50);
double dMaxWidth = dDiameterS > dDiameterE ? dDiameterS : dDiameterE;
if ((ptStart.distanceTo(ptCorner) - MayAsMUnit(50.0)) - dMaxWidth < -1e-6)
{
dWrap = 0.1;
}
vtStr = ptStart - ptGeCen;
vtEnd = ptEnd - ptGeCen;
vtStr.normalize();
vtEnd.normalize();
ptWrapStrU = ptStartU + vtStr * dWrap;
ptWrapStrXU = ptStartXU + vtStr * dWrap;
ptWrapStrXD = ptStartXD - vtStr * dWrap;
ptWrapEndU = ptEndU + vtEnd * dWrap;
ptWrapEndXU = ptEndXU + vtEnd * dWrap;
ptWrapEndXD = ptEndXD - vtEnd * dWrap;
//消声斜线与外轮廓的垂直距离是50.
double dWrapX = dWrap * tan(PI / 8);
ptWrapStrD = ptWrapStrXD + vtEnd * (dWrap - dWrapX);
ptWrapEndD = ptWrapEndXD + vtStr * (dWrap - dWrapX);
ptWrapCorU = (ptCorner + vtEnd * (dDiameterE + dWrap) + vtStr * (dDiameterS + dWrap));
//el.idSubLay = idSideLayer;
//el.dWidth = dEdgeWidth;
el.dWidth = dEndLineWidth;
el.idSubLay = idSideLayer;
el.ptGe[0] = ptWrapStrXU;
el.ptGe[1] = ptWrapStrXD;
el.ptGe[2] = ptWrapStrXD;
cplCurve.append(el);
el.ptGe[0] = ptWrapEndXU;
el.ptGe[1] = ptWrapEndXD;
el.ptGe[2] = ptWrapEndXD;
cplCurve.append(el);
el.ptGe[0] = ptWrapStrXU;
el.ptGe[1] = ptWrapCorU;
el.ptGe[2] = ptWrapCorU;
cplCurve.append(el);
el.ptGe[0] = ptWrapCorU;
el.ptGe[1] = ptWrapEndXU;
el.ptGe[2] = ptWrapEndXU;
cplCurve.append(el);
el.ptGe[0] = ptWrapEndXD;
el.ptGe[1] = ptWrapEndD;
el.ptGe[2] = ptWrapEndD;
cplCurve.append(el);
el.ptGe[0] = ptWrapEndD;
el.ptGe[1] = ptWrapStrD;
el.ptGe[2] = ptWrapStrD;
cplCurve.append(el);
el.ptGe[0] = ptWrapStrD;
el.ptGe[1] = ptWrapStrXD;
el.ptGe[2] = ptWrapStrXD;
cplCurve.append(el);
}
//内部线
else if (1 == nType)
{
//中心线
if ((HasBaseLine() || IsSingleLine()))
{
el.gsMark = -1;
el.idSubLay = idBaseLayer;
if (IsSingleLine())
el.dWidth = dEdgeWidth;
else
el.dWidth = dCenWidth;
el.ptGe[0] = ptStartX;
el.ptGe[1] = ptCorner;
el.ptGe[2] = ptCorner;
cplCurve.append(el);
el.ptGe[0] = ptCorner;
el.ptGe[1] = ptEndX;
el.ptGe[2] = ptEndX;
cplCurve.append(el);
}
if (!IsSingleLine())
{
el.dWidth = dEdgeWidth;
el.idSubLay = layerId();
//添加两条消声线
el.ptGe[0] = ptStartXU;
el.ptGe[1] = ptCornerU;
el.ptGe[2] = ptCornerU;
cplCurve.append(el);
el.ptGe[0] = ptCornerU;
el.ptGe[1] = ptEndXU;
el.ptGe[2] = ptEndXU;
cplCurve.append(el);
el.ptGe[0] = ptStartXD;
el.ptGe[1] = ptStartD;
el.ptGe[2] = ptStartD;
cplCurve.append(el);
el.ptGe[0] = ptStartD;
el.ptGe[1] = ptEndD;
el.ptGe[2] = ptEndD;
cplCurve.append(el);
el.ptGe[0] = ptEndD;
el.ptGe[1] = ptEndXD;
el.ptGe[2] = ptEndXD;
cplCurve.append(el);
}
}
break;
}
case AecHvac::eInclineBoard: // 内斜线隔板消声
{
//外轮廓
if (0 == nType)
{
el.dWidth = dEdgeWidth;
//el.idSubLay = idSideLayer;
el.ptGe[0] = ptStartXU;
el.ptGe[1] = ptCornerU;
el.ptGe[2] = ptCornerU;
cplCurve.append(el);
el.ptGe[0] = ptCornerU;
el.ptGe[1] = ptEndXU;
el.ptGe[2] = ptEndXU;
cplCurve.append(el);
el.ptGe[0] = ptEndXD;
el.ptGe[1] = ptEndD;
el.ptGe[2] = ptEndD;
cplCurve.append(el);
el.ptGe[0] = ptEndD;
el.ptGe[1] = ptStartD;
el.ptGe[2] = ptStartD;
cplCurve.append(el);
el.ptGe[0] = ptStartD;
el.ptGe[1] = ptStartXD;
el.ptGe[2] = ptStartXD;
cplCurve.append(el);
el.dWidth = dEndLineWidth;
el.idSubLay = idSideLayer;
el.ptGe[0] = ptStartXD;
el.ptGe[1] = ptStartXU;
el.ptGe[2] = ptStartXU;
cplCurve.append(el);
el.ptGe[0] = ptEndXU;
el.ptGe[1] = ptEndXD;
el.ptGe[2] = ptEndXD;
cplCurve.append(el);
}
//内部线
else if (1 == nType)
{
//添加两条消声线
AcGePoint3d ptWrapStrS,ptWrapStrE,ptWrapEndS,ptWrapEndE;
vtStr = ptStart - ptGeCen;
vtEnd = ptEnd - ptGeCen;
vtStr.normalize();
vtEnd.normalize();
ptWrapStrS = ptStartX + vtStr * dDiameterS / 3.0;
ptWrapStrE = ptWrapStrS + vtEnd * dDiameterS * 1.4;
ptWrapEndS = ptEndXU + vtStr * dDiameterS / 1.5;
ptWrapEndE = ptWrapEndS - vtEnd * dDiameterE * 1.4;
//中心线
if ((HasBaseLine() || IsSingleLine()))
{
el.gsMark = -1;
el.idSubLay = idBaseLayer;
if (IsSingleLine())
el.dWidth = dEdgeWidth;
else
el.dWidth = dCenWidth;
el.ptGe[0] = ptStartX;
el.ptGe[1] = ptCorner;
el.ptGe[2] = ptCorner;
cplCurve.append(el);
el.ptGe[0] = ptCorner;
el.ptGe[1] = ptEndX;
el.ptGe[2] = ptEndX;
cplCurve.append(el);
}
if (!IsSingleLine())
{
el.idSubLay = idSideLayer;
el.dWidth = dEndLineWidth;
el.ptGe[0] = ptWrapStrS;
el.ptGe[1] = ptWrapStrE;
el.ptGe[2] = ptWrapStrE;
cplCurve.append(el);
el.ptGe[0] = ptWrapEndS;
el.ptGe[1] = ptWrapEndE;
el.ptGe[2] = ptWrapEndE;
cplCurve.append(el);
}
}
break;
}
case AecHvac::eInclineLead: // 内斜线导流
{
//外轮廓
if (0 == nType)
{
el.dWidth = dEdgeWidth;
//el.idSubLay = idSideLayer;
el.ptGe[0] = ptStartXU;
el.ptGe[1] = ptCornerU;
el.ptGe[2] = ptCornerU;
cplCurve.append(el);
el.ptGe[0] = ptCornerU;
el.ptGe[1] = ptEndXU;
el.ptGe[2] = ptEndXU;
cplCurve.append(el);
el.ptGe[0] = ptEndXD;
el.ptGe[1] = ptEndD;
el.ptGe[2] = ptEndD;
cplCurve.append(el);
el.ptGe[0] = ptEndD;
el.ptGe[1] = ptStartD;
el.ptGe[2] = ptStartD;
cplCurve.append(el);
el.ptGe[0] = ptStartD;
el.ptGe[1] = ptStartXD;
el.ptGe[2] = ptStartXD;
cplCurve.append(el);
el.dWidth = dEndLineWidth;
el.idSubLay = idSideLayer;
el.ptGe[0] = ptStartXD;
el.ptGe[1] = ptStartXU;
el.ptGe[2] = ptStartXU;
cplCurve.append(el);
el.ptGe[0] = ptEndXU;
el.ptGe[1] = ptEndXD;
el.ptGe[2] = ptEndXD;
cplCurve.append(el);
}
//内部线
else if (1 == nType)
{
//添加导流线
AcGePoint3dArray arptLeaders;
AcGePoint3d ptWrap,ptWrapU,ptWrapD;
int nSize = sizeof(nLeader) / sizeof(nLeader[0]);
//取出第一个大于Dn的行数
for (int i = 0; i < nSize; i++)
{
if (nLeader[i][0] > dDiameterS * 2)
break;
}
//判断DN的最小差值
if (i > 0)
{
if (fabs((nLeader[i][0] - dDiameterS * 2)) > fabs((nLeader[i - 1][0] - dDiameterS * 2)))
{
i--;
}
}
ptWrap = ptGeCen + vtCor * (ptGeCen.distanceTo(ptStartD) + nLeader[i][2]);
ptWrapU = ptWrapD = ptWrap;
ptWrapU.rotateBy(PI / 10,vtNor,ptGeCen);
ptWrapD.rotateBy(PI / 10,-vtNor,ptGeCen);
if (!IsSingleLine() && dDiameterS > MayAsMUnit(249.0))
{
//添加第一导流线
el.idSubLay = idSideLayer;
el.dWidth = dEndLineWidth;
el.ptGe[0] = ptWrapU;
el.ptGe[1] = ptWrap;
el.ptGe[2] = ptWrapD;
cplCurve.append(el);
//根据数组的第二列,来添加多条导流线
int nCount = nLeader[i][1];
for (int j = 0; j < nCount - 1; j++)
{
ptWrapU += vtCor * nLeader[i][j + 3];
ptWrap += vtCor * nLeader[i][j + 3];
ptWrapD += vtCor * nLeader[i][j + 3];
el.ptGe[0] = ptWrapU;
el.ptGe[1] = ptWrap;
el.ptGe[2] = ptWrapD;
cplCurve.append(el);
}
}
//中心线
if ((HasBaseLine() || IsSingleLine()))
{
el.gsMark = -1;
el.idSubLay = idBaseLayer;
if (IsSingleLine())
el.dWidth = dEdgeWidth;
else
el.dWidth = dCenWidth;
el.ptGe[0] = ptStartX;
el.ptGe[1] = ptCorner;
el.ptGe[2] = ptCorner;
cplCurve.append(el);
el.ptGe[0] = ptCorner;
el.ptGe[1] = ptEndX;
el.ptGe[2] = ptEndX;
cplCurve.append(el);
}
}
break;
}
}
return cplCurve.length() > 0;
}
/////////////////////////////////////
// su corU
// sxu ─ ──────╮
// sx ─s─────╮│
// sxd ─ ────╮││
// sd corD│││
// │││
// ed e eu
// │││
// exd ex exu
/////////////////////////////////////
BOOL ImpHvacElbow::GetArcuateCplCurveHor(AecComplexCurve& cplCurve,int &nType,AcGePoint3d& ptStart, AcGePoint3d& ptCorner,AcGePoint3d& ptEnd,double& dPlusEdge,double& dDiameterS,double& dDiameterE) const
{
if (nType != 0 && nType != 1)
{
return FALSE;
}
AcGeVector3d vtStr,vtEnd,vtCor,vtNor = AcGeVector3d::kZAxis;
AcGePoint3d ptGeCen,ptStartU,ptStartD,ptCornerU,ptEndU,ptEndD,ptCornerD;
AcGePoint3d ptStartX,ptStartXU,ptStartXD,ptEndX,ptEndXU,ptEndXD,ptCorOnArc;
//保证Star点永远在End前面,否则管线反向绘制隔板弯头会有问题
if (ptStart.x > ptEnd.x)
{
AcGePoint3d ptTemp(ptStart);
ptStart = ptEnd;
ptEnd = ptTemp;
//=========================================================
double dTemp = dDiameterS;
dDiameterS = dDiameterE;
dDiameterE =dTemp;
}
ptStartX = ptStart;
ptEndX = ptEnd;
vtStr = ptStart - ptCorner;
vtEnd = ptEnd - ptCorner;
vtStr.normalize();
vtEnd.normalize();
vtNor = vtStr.crossProduct(vtEnd);
//ptStart,ptEnd都改变了,去掉了直边段
ptStart = ptStart - vtStr * dPlusEdge;
ptEnd = ptEnd - vtEnd * dPlusEdge;
vtStr.rotateBy(PI * 0.5,vtNor);
vtEnd.rotateBy(PI * 0.5,vtNor);
//求出圆心ptGeCen
if(!GetIntersectWith(ptStart,ptEnd,vtStr,vtEnd,ptGeCen))
return FALSE;
vtStr = ptStart - ptGeCen;
vtEnd = ptEnd - ptGeCen;
vtCor = ptCorner - ptGeCen;
vtStr.normalize();
vtEnd.normalize();
vtCor.normalize();
ptStartU = ptStart + vtStr * dDiameterS;
ptStartD = ptStart - vtStr * dDiameterS;
ptEndU = ptEnd + vtEnd * dDiameterE;
ptEndD = ptEnd - vtEnd * dDiameterE;
//计算直边段的端点
ptStartXU = ptStartX + vtStr * dDiameterS;
ptStartXD = ptStartX - vtStr * dDiameterS;
ptEndXU = ptEndX + vtEnd * dDiameterE;
ptEndXD = ptEndX - vtEnd * dDiameterE;
vtStr = ptStart - ptCorner;
vtEnd = ptEnd - ptCorner;
vtStr.normalize();
vtEnd.normalize();
ptCornerU = (ptCorner - vtStr * dDiameterE) - vtEnd * dDiameterS;
ptCorOnArc = ptGeCen + vtCor * (ptStart.distanceTo(ptGeCen));
ptCornerD = ptCorOnArc - vtCor * (dDiameterS + dDiameterE) * 0.5;
AcDbObjectId idBaseLayer(NULL), idSideLayer(NULL);
// //m_pXDataMap->GetAt(HVAC_BaseLayer, idBaseLayer);
m_pXDataMap->GetAt(HVAC_EndLayer, idSideLayer);
AecEqui::AecCurveElement el;
memset(&el,0,sizeof(AecEqui::AecCurveElement));
double dEdgeWidth = GetEdgeLineWidth();
double dCenWidth = GetCentLineWidth();
double dEndLineWidth = GetEndLineWidth();
// 弯头类型
AecHvac::HvacElbowType eElbowType = AecHvac::eArcuate;
m_pXDataMap->GetAt(HELB_Type, (int&)eElbowType);
// 根据类型,是否绘制消声线
switch (eElbowType)
{
case AecHvac::eArcuate: // 内弧线
{
//外轮廓
if (0 == nType)
{
//el.idSubLay = idSideLayer;
el.dWidth = dEdgeWidth;
el.ptGe[0] = ptStartXU;
el.ptGe[1] = ptCornerU;
el.ptGe[2] = ptCornerU;
cplCurve.append(el);
el.ptGe[0] = ptCornerU;
el.ptGe[1] = ptEndXU;
el.ptGe[2] = ptEndXU;
cplCurve.append(el);
el.ptGe[0] = ptEndXD;
el.ptGe[1] = ptEndD;
el.ptGe[2] = ptEndD;
cplCurve.append(el);
el.ptGe[0] = ptEndD;
el.ptGe[1] = ptCornerD;
el.ptGe[2] = ptStartD;
cplCurve.append(el);
el.ptGe[0] = ptStartD;
el.ptGe[1] = ptStartXD;
el.ptGe[2] = ptStartXD;
cplCurve.append(el);
el.dWidth = dEndLineWidth;
el.idSubLay = idSideLayer;
el.ptGe[0] = ptStartXD;
el.ptGe[1] = ptStartXU;
el.ptGe[2] = ptStartXU;
cplCurve.append(el);
el.ptGe[0] = ptEndXU;
el.ptGe[1] = ptEndXD;
el.ptGe[2] = ptEndXD;
cplCurve.append(el);
}
//中心线
else if (1 == nType && (HasBaseLine() || IsSingleLine()))
{
el.gsMark = -1;
el.idSubLay = idBaseLayer;
if (IsSingleLine())
el.dWidth = dEdgeWidth;
else
el.dWidth = dCenWidth;
el.ptGe[0] = ptStartX;
el.ptGe[1] = ptStart;
el.ptGe[2] = ptStart;
cplCurve.append(el);
el.ptGe[0] = ptStart;
el.ptGe[1] = ptCorOnArc;
el.ptGe[2] = ptEnd;
cplCurve.append(el);
el.ptGe[0] = ptEnd;
el.ptGe[1] = ptEndX;
el.ptGe[2] = ptEndX;
cplCurve.append(el);
}
break;
}
case AecHvac::eArcuateWrap: // 消声
{
//外轮廓
if (0 == nType)
{
AcGePoint3d ptWrapStrU,ptWrapStrD,ptWrapEndU,ptWrapEndD;
AcGePoint3d ptWrapStrXU,ptWrapStrXD,ptWrapEndXU,ptWrapEndXD;
AcGePoint3d ptWrapCorU,ptWrapCorD;
double dWrap = MayAsMUnit(50);
double dMaxWidth = dDiameterS > dDiameterE ? dDiameterS : dDiameterE;
if ((ptStart.distanceTo(ptCorner) - dWrap) - dMaxWidth < -1e-6)
{
dWrap = 0.1;
}
vtStr = ptStart - ptGeCen;
vtEnd = ptEnd - ptGeCen;
vtStr.normalize();
vtEnd.normalize();
ptWrapStrXU = ptStartXU + vtStr * dWrap;
ptWrapStrXD = ptStartXD - vtStr * dWrap;
ptWrapEndXU = ptEndXU + vtEnd * dWrap;
ptWrapEndXD = ptEndXD - vtEnd * dWrap;
ptWrapStrD = ptStart - vtStr * (dDiameterS + dWrap);
ptWrapEndD = ptEnd - vtEnd * (dDiameterE + dWrap);
ptWrapCorU = (ptCorner + vtEnd * (dDiameterE + dWrap) + vtStr * (dDiameterS + dWrap));
// = ptGeCen + vtCor * (ptWrapStrD.distanceTo(ptGeCen)); //ptWrapStrD
ptWrapCorD = ptGeCen + vtCor * (ptStart.distanceTo(ptGeCen) - dDiameterS * 0.5 - dDiameterE * 0.5 - dWrap);
//el.idSubLay = idSideLayer;
el.dWidth = dEndLineWidth;
el.idSubLay = idSideLayer;
el.ptGe[0] = ptWrapEndXU;
el.ptGe[1] = ptWrapEndXD;
el.ptGe[2] = ptWrapEndXD;
cplCurve.append(el);
el.ptGe[0] = ptWrapStrXU;
el.ptGe[1] = ptWrapStrXD;
el.ptGe[2] = ptWrapStrXD;
cplCurve.append(el);
el.ptGe[0] = ptWrapStrXU;
el.ptGe[1] = ptWrapCorU;
el.ptGe[2] = ptWrapCorU;
cplCurve.append(el);
el.ptGe[0] = ptWrapCorU;
el.ptGe[1] = ptWrapEndXU;
el.ptGe[2] = ptWrapEndXU;
cplCurve.append(el);
el.ptGe[0] = ptWrapEndXD;
el.ptGe[1] = ptWrapEndD;
el.ptGe[2] = ptWrapEndD;
cplCurve.append(el);
el.ptGe[0] = ptWrapEndD;
el.ptGe[1] = ptWrapCorD;
el.ptGe[2] = ptWrapStrD;
cplCurve.append(el);
el.ptGe[0] = ptWrapStrD;
el.ptGe[1] = ptWrapStrXD;
el.ptGe[2] = ptWrapStrXD;
cplCurve.append(el);
}
//内部线
else if (1 == nType)
{
//添加两条消声线
if (!IsSingleLine())
{
el.dWidth = dEdgeWidth;
el.idSubLay = layerId();
el.ptGe[0] = ptStartXU;
el.ptGe[1] = ptCornerU;
el.ptGe[2] = ptCornerU;
cplCurve.append(el);
el.ptGe[0] = ptCornerU;
el.ptGe[1] = ptEndXU;
el.ptGe[2] = ptEndXU;
cplCurve.append(el);
el.ptGe[0] = ptEndXD;
el.ptGe[1] = ptEndD;
el.ptGe[2] = ptEndD;
cplCurve.append(el);
el.ptGe[0] = ptEndD;
el.ptGe[1] = ptCornerD;
el.ptGe[2] = ptStartD;
cplCurve.append(el);
el.ptGe[0] = ptStartD;
el.ptGe[1] = ptStartXD;
el.ptGe[2] = ptStartXD;
cplCurve.append(el);
}
//中心线
if ((HasBaseLine() || IsSingleLine()))
{
el.gsMark = -1;
el.idSubLay = idBaseLayer;
if (IsSingleLine())
el.dWidth = dEdgeWidth;
else
el.dWidth = dCenWidth;
el.ptGe[0] = ptStartX;
el.ptGe[1] = ptStart;
el.ptGe[2] = ptStart;
cplCurve.append(el);
el.ptGe[0] = ptStart;
el.ptGe[1] = ptCorOnArc;
el.ptGe[2] = ptEnd;
cplCurve.append(el);
el.ptGe[0] = ptEnd;
el.ptGe[1] = ptEndX;
el.ptGe[2] = ptEndX;
cplCurve.append(el);
}
}
break;
}
case AecHvac::eArcuateBoard: // 隔板消声
{
//外轮廓
if (0 == nType)
{
//el.idSubLay = idSideLayer;
el.dWidth = dEdgeWidth;
el.ptGe[0] = ptStartXU;
el.ptGe[1] = ptCornerU;
el.ptGe[2] = ptCornerU;
cplCurve.append(el);
el.ptGe[0] = ptCornerU;
el.ptGe[1] = ptEndXU;
el.ptGe[2] = ptEndXU;
cplCurve.append(el);
el.ptGe[0] = ptEndXD;
el.ptGe[1] = ptEndD;
el.ptGe[2] = ptEndD;
cplCurve.append(el);
el.ptGe[0] = ptEndD;
el.ptGe[1] = ptCornerD;
el.ptGe[2] = ptStartD;
cplCurve.append(el);
el.ptGe[0] = ptStartD;
el.ptGe[1] = ptStartXD;
el.ptGe[2] = ptStartXD;
cplCurve.append(el);
el.dWidth = dEndLineWidth;
el.idSubLay = idSideLayer;
el.ptGe[0] = ptEndXU;
el.ptGe[1] = ptEndXD;
el.ptGe[2] = ptEndXD;
cplCurve.append(el);
el.ptGe[0] = ptStartXD;
el.ptGe[1] = ptStartXU;
el.ptGe[2] = ptStartXU;
cplCurve.append(el);
}
//内部线
else if (1 == nType)
{
//添加两条隔板线
AcGePoint3d ptWrapStrS,ptWrapStrE,ptWrapEndS,ptWrapEndE;
vtStr = ptStart - ptGeCen;
vtEnd = ptEnd - ptGeCen;
vtStr.normalize();
vtEnd.normalize();
ptWrapStrS = ptStartX + vtStr * dDiameterS / 3.0;
ptWrapStrE = ptWrapStrS + vtEnd * dDiameterS * 1.4;
ptWrapEndS = ptEndXU + vtStr * dDiameterS / 1.5;
ptWrapEndE = ptWrapEndS - vtEnd * dDiameterE * 1.4;
if (!IsSingleLine())
{
el.dWidth = dEndLineWidth;
el.idSubLay = idSideLayer;
el.ptGe[0] = ptWrapStrS;
el.ptGe[1] = ptWrapStrE;
el.ptGe[2] = ptWrapStrE;
cplCurve.append(el);
el.ptGe[0] = ptWrapEndS;
el.ptGe[1] = ptWrapEndE;
el.ptGe[2] = ptWrapEndE;
cplCurve.append(el);
}
//中心线
if ((HasBaseLine() || IsSingleLine()))
{
el.gsMark = -1;
el.idSubLay = idBaseLayer;
if (IsSingleLine())
el.dWidth = dEdgeWidth;
else
el.dWidth = dCenWidth;
el.ptGe[0] = ptStartX;
el.ptGe[1] = ptStart;
el.ptGe[2] = ptStart;
cplCurve.append(el);
el.ptGe[0] = ptStart;
el.ptGe[1] = ptCorOnArc;
el.ptGe[2] = ptEnd;
cplCurve.append(el);
el.ptGe[0] = ptEnd;
el.ptGe[1] = ptEndX;
el.ptGe[2] = ptEndX;
cplCurve.append(el);
}
}
break;
}
case AecHvac::eArcuateSieve: // 筛板消声
{
//外轮廓
if (0 == nType)
{
//el.idSubLay = idSideLayer;
el.dWidth = dEdgeWidth;
el.ptGe[0] = ptStartXU;
el.ptGe[1] = ptCornerU;
el.ptGe[2] = ptCornerU;
cplCurve.append(el);
el.ptGe[0] = ptCornerU;
el.ptGe[1] = ptEndXU;
el.ptGe[2] = ptEndXU;
cplCurve.append(el);
el.ptGe[0] = ptEndXD;
el.ptGe[1] = ptEndD;
el.ptGe[2] = ptEndD;
cplCurve.append(el);
el.ptGe[0] = ptEndD;
el.ptGe[1] = ptCornerD;
el.ptGe[2] = ptStartD;
cplCurve.append(el);
el.ptGe[0] = ptStartD;
el.ptGe[1] = ptStartXD;
el.ptGe[2] = ptStartXD;
cplCurve.append(el);
el.dWidth = dEndLineWidth;
el.idSubLay = idSideLayer;
el.ptGe[0] = ptStartXD;
el.ptGe[1] = ptStartXU;
el.ptGe[2] = ptStartXU;
cplCurve.append(el);
el.ptGe[0] = ptEndXU;
el.ptGe[1] = ptEndXD;
el.ptGe[2] = ptEndXD;
cplCurve.append(el);
}
//内部线
else if (1 == nType)
{
//添加两条筛板线
AcGePoint3d ptWrap1S,ptWrap1E,ptWrap2S,ptWrap2E;
//旋转9度
AcGeCircArc3d cirArc(ptStartD,ptCornerD,ptEndD);
AcGePoint3d ptGeCenD = cirArc.center();
ptWrap1S = ptCornerD;
ptWrap2S = ptCornerD;
ptWrap1S.rotateBy(PI * 0.02,vtNor,ptGeCenD);
ptWrap2S.rotateBy(PI * 0.02,-vtNor,ptGeCenD);
//求交
AcGeVector3d vtWrapCor = ptCornerD - ptCornerU;
GetIntersectWith(ptStartXU,ptWrap1S,vtStr,vtWrapCor,ptWrap1E);
GetIntersectWith(ptEndXU,ptWrap2S,vtEnd,vtWrapCor,ptWrap2E);
if (!IsSingleLine())
{
el.idSubLay = idSideLayer;
el.dWidth = dEndLineWidth;
el.ptGe[0] = ptWrap1S;
el.ptGe[1] = ptWrap1E;
el.ptGe[2] = ptWrap1E;
cplCurve.append(el);
el.ptGe[0] = ptWrap2S;
el.ptGe[1] = ptWrap2E;
el.ptGe[2] = ptWrap2E;
cplCurve.append(el);
}
//中心线
if ((HasBaseLine() || IsSingleLine()))
{
el.gsMark = -1;
el.idSubLay = idBaseLayer;
if (IsSingleLine())
el.dWidth = dEdgeWidth;
else
el.dWidth = dCenWidth;
el.ptGe[0] = ptStartX;
el.ptGe[1] = ptStart;
el.ptGe[2] = ptStart;
cplCurve.append(el);
el.ptGe[0] = ptStart;
el.ptGe[1] = ptCorOnArc;
el.ptGe[2] = ptEnd;
cplCurve.append(el);
el.ptGe[0] = ptEnd;
el.ptGe[1] = ptEndX;
el.ptGe[2] = ptEndX;
cplCurve.append(el);
}
}
break;
}
case AecHvac::eArcuateLead: // 导流
{
//外轮廓
if (0 == nType)
{
//el.idSubLay = idSideLayer;
el.dWidth = dEdgeWidth;
el.ptGe[0] = ptStartXU;
el.ptGe[1] = ptCornerU;
el.ptGe[2] = ptCornerU;
cplCurve.append(el);
el.ptGe[0] = ptCornerU;
el.ptGe[1] = ptEndXU;
el.ptGe[2] = ptEndXU;
cplCurve.append(el);
el.ptGe[0] = ptEndXD;
el.ptGe[1] = ptEndD;
el.ptGe[2] = ptEndD;
cplCurve.append(el);
el.ptGe[0] = ptEndD;
el.ptGe[1] = ptCornerD;
el.ptGe[2] = ptStartD;
cplCurve.append(el);
el.ptGe[0] = ptStartD;
el.ptGe[1] = ptStartXD;
el.ptGe[2] = ptStartXD;
cplCurve.append(el);
el.dWidth = dEndLineWidth;
el.idSubLay = idSideLayer;
el.ptGe[0] = ptStartXD;
el.ptGe[1] = ptStartXU;
el.ptGe[2] = ptStartXU;
cplCurve.append(el);
el.ptGe[0] = ptEndXU;
el.ptGe[1] = ptEndXD;
el.ptGe[2] = ptEndXD;
cplCurve.append(el);
}
//内部线
else if (1 == nType)
{
//添加导流线
AcGePoint3dArray arptLeaders;
AcGePoint3d ptWrap,ptWrapU,ptWrapD;
int nSize = sizeof(nLeader) / sizeof(nLeader[0]);
//取出第一个大于Dn的行数
for (int i = 0; i < nSize; i++)
{
if (nLeader[i][0] > dDiameterS * 2)
break;
}
//判断DN的最小差值
if (i > 0)
{
if (fabs((nLeader[i][0] - dDiameterS * 2)) > fabs((nLeader[i - 1][0] - dDiameterS * 2)))
{
i--;
}
}
ptWrap = ptGeCen + vtCor * (ptGeCen.distanceTo(ptStartD) + nLeader[i][2]);
ptWrapU = ptWrapD = ptWrap;
ptWrapU.rotateBy(PI / 10,vtNor,ptGeCen);
ptWrapD.rotateBy(PI / 10,-vtNor,ptGeCen);
if (!IsSingleLine() && dDiameterS > MayAsMUnit(249.0))
{
//添加第一导流线
el.dWidth = dEndLineWidth;
el.idSubLay = idSideLayer;
el.ptGe[0] = ptWrapU;
el.ptGe[1] = ptWrap;
el.ptGe[2] = ptWrapD;
cplCurve.append(el);
//根据数组的第二列,来添加多条导流线
int nCount = nLeader[i][1];
for (int j = 0; j < nCount - 1; j++)
{
ptWrapU += vtCor * nLeader[i][j + 3];
ptWrap += vtCor * nLeader[i][j + 3];
ptWrapD += vtCor * nLeader[i][j + 3];
el.ptGe[0] = ptWrapU;
el.ptGe[1] = ptWrap;
el.ptGe[2] = ptWrapD;
cplCurve.append(el);
}
}
//中心线
if ((HasBaseLine() || IsSingleLine()))
{
el.gsMark = -1;
el.idSubLay = idBaseLayer;
if (IsSingleLine())
el.dWidth = dEdgeWidth;
else
el.dWidth = dCenWidth;
el.ptGe[0] = ptStartX;
el.ptGe[1] = ptStart;
el.ptGe[2] = ptStart;
cplCurve.append(el);
el.ptGe[0] = ptStart;
el.ptGe[1] = ptCorOnArc;
el.ptGe[2] = ptEnd;
cplCurve.append(el);
el.ptGe[0] = ptEnd;
el.ptGe[1] = ptEndX;
el.ptGe[2] = ptEndX;
cplCurve.append(el);
}
}
break;
}
}
return cplCurve.length() > 0;
}
//////////////////////////////////////
// su corU
// sxu ─ ──────╮
// sx ─s─────╮│
// sxd ─ ────╮││
// sd corD│││
// │││
// ed e eu
// │││
// exd ex exu
/////////////////////////////////////
BOOL ImpHvacElbow::GetAllOrthoCplCurveHor(AecComplexCurve& cplCurve,int &nType,AcGePoint3d& ptStart, AcGePoint3d& ptCorner,AcGePoint3d& ptEnd,double& dPlusEdge,double& dDiameterS,double& dDiameterE) const
{
if (nType != 0 && nType != 1)
{
return FALSE;
}
AcGeVector3d vtStr,vtEnd,vtCor,vtNor = AcGeVector3d::kZAxis;
AcGePoint3d ptGeCen,ptStartU,ptStartD,ptCornerU,ptEndU,ptEndD,ptCornerD;
AcGePoint3d ptStartX,ptStartXU,ptStartXD,ptEndX,ptEndXU,ptEndXD,ptCorOnArc;
ptStartX = ptStart;
ptEndX = ptEnd;
vtStr = ptStart - ptCorner;
vtEnd = ptEnd - ptCorner;
vtStr.normalize();
vtEnd.normalize();
vtNor = vtStr.crossProduct(vtEnd);
//ptStart,ptEnd都改变了,去掉了直边段
ptStart = ptStart - vtStr * dPlusEdge;
ptEnd = ptEnd - vtEnd * dPlusEdge;
vtStr.rotateBy(PI * 0.5,vtNor);
vtEnd.rotateBy(PI * 0.5,vtNor);
//求出圆心ptGeCen
if(!GetIntersectWith(ptStart,ptEnd,vtStr,vtEnd,ptGeCen))
return FALSE;
vtStr = ptStart - ptGeCen;
vtEnd = ptEnd - ptGeCen;
vtCor = ptCorner - ptGeCen;
vtStr.normalize();
vtEnd.normalize();
vtCor.normalize();
ptStartU = ptStart + vtStr * dDiameterS;
ptStartD = ptStart - vtStr * dDiameterS;
ptEndU = ptEnd + vtEnd * dDiameterE;
ptEndD = ptEnd - vtEnd * dDiameterE;
//计算直边段的端点
ptStartXU = ptStartX + vtStr * dDiameterS;
ptStartXD = ptStartX - vtStr * dDiameterS;
ptEndXU = ptEndX + vtEnd * dDiameterE;
ptEndXD = ptEndX - vtEnd * dDiameterE;
vtStr = ptStart - ptCorner;
vtEnd = ptEnd - ptCorner;
vtStr.normalize();
vtEnd.normalize();
ptCornerU = (ptCorner - vtStr * dDiameterE) - vtEnd * dDiameterS;
ptCornerD = (ptCorner + vtStr * dDiameterE) + vtEnd * dDiameterS;
AcDbObjectId idBaseLayer(NULL), idSideLayer(NULL);
//m_pXDataMap->GetAt(HVAC_BaseLayer, idBaseLayer);
m_pXDataMap->GetAt(HVAC_EndLayer, idSideLayer);
AecEqui::AecCurveElement el;
memset(&el,0,sizeof(AecEqui::AecCurveElement));
double dEdgeWidth = GetEdgeLineWidth();
double dCenWidth = GetCentLineWidth();
double dEndLineWidth = GetEndLineWidth();
// 弯头类型
AecHvac::HvacElbowType eElbowType = AecHvac::eAllOrtho;
m_pXDataMap->GetAt(HELB_Type, (int&)eElbowType);
// 根据类型,是否绘制消声线
switch (eElbowType)
{
case AecHvac::eAllOrtho: // 内外直角
{
//外轮廓
if (0 == nType)
{
//el.idSubLay = idSideLayer;
el.dWidth = dEdgeWidth;
el.ptGe[0] = ptStartXU;
el.ptGe[1] = ptCornerU;
el.ptGe[2] = ptCornerU;
cplCurve.append(el);
el.ptGe[0] = ptCornerU;
el.ptGe[1] = ptEndXU;
el.ptGe[2] = ptEndXU;
cplCurve.append(el);
el.ptGe[0] = ptEndXD;
el.ptGe[1] = ptCornerD;
el.ptGe[2] = ptCornerD;
cplCurve.append(el);
el.ptGe[0] = ptCornerD;
el.ptGe[1] = ptStartXD;
el.ptGe[2] = ptStartXD;
cplCurve.append(el);
el.dWidth = dEndLineWidth;
el.idSubLay = idSideLayer;
el.ptGe[0] = ptStartXD;
el.ptGe[1] = ptStartXU;
el.ptGe[2] = ptStartXU;
cplCurve.append(el);
el.ptGe[0] = ptEndXU;
el.ptGe[1] = ptEndXD;
el.ptGe[2] = ptEndXD;
cplCurve.append(el);
}
//中心线
else if (1 == nType && (HasBaseLine() || IsSingleLine()))
{
el.gsMark = -1;
el.idSubLay = idBaseLayer;
if (IsSingleLine())
el.dWidth = dEdgeWidth;
else
el.dWidth = dCenWidth;
el.ptGe[0] = ptStartX;
el.ptGe[1] = ptCorner;
el.ptGe[2] = ptCorner;
cplCurve.append(el);
el.ptGe[0] = ptCorner;
el.ptGe[1] = ptEndX;
el.ptGe[2] = ptEndX;
cplCurve.append(el);
}
break;
}
case AecHvac::eOrthoWrap: // 直角消声
{
//外轮廓
if (0 == nType)
{
AcGePoint3d ptWrapStrU,ptWrapStrD,ptWrapEndU,ptWrapEndD;
AcGePoint3d ptWrapStrXU,ptWrapStrXD,ptWrapEndXU,ptWrapEndXD;
AcGePoint3d ptWrapCorU,ptWrapCorD;
double dWrap = MayAsMUnit(50);
double dMaxWidth = dDiameterS > dDiameterE ? dDiameterS : dDiameterE;
if ((ptStart.distanceTo(ptCorner) - dWrap) - dMaxWidth < -1e-6)
{
dWrap = 0.1;
}
vtStr = ptStart - ptGeCen;
vtEnd = ptEnd - ptGeCen;
vtStr.normalize();
vtEnd.normalize();
ptWrapStrXU = ptStartXU + vtStr * dWrap;
ptWrapStrXD = ptStartXD - vtStr * dWrap;
ptWrapEndXU = ptEndXU + vtEnd * dWrap;
ptWrapEndXD = ptEndXD - vtEnd * dWrap;
ptWrapCorU = (ptCorner + vtEnd * (dDiameterE + dWrap) + vtStr * (dDiameterS + dWrap));
ptWrapCorD = (ptCorner - vtEnd * (dDiameterE + dWrap) - vtStr * (dDiameterS + dWrap));
//el.idSubLay = idSideLayer;
//el.dWidth = dEdgeWidth;
el.dWidth = dEndLineWidth;
el.idSubLay = idSideLayer;
el.ptGe[0] = ptWrapStrXD;
el.ptGe[1] = ptWrapStrXU;
el.ptGe[2] = ptWrapStrXU;
cplCurve.append(el);
el.ptGe[0] = ptWrapEndXU;
el.ptGe[1] = ptWrapEndXD;
el.ptGe[2] = ptWrapEndXD;
cplCurve.append(el);
el.ptGe[0] = ptWrapStrXU;
el.ptGe[1] = ptWrapCorU;
el.ptGe[2] = ptWrapCorU;
cplCurve.append(el);
el.ptGe[0] = ptWrapCorU;
el.ptGe[1] = ptWrapEndXU;
el.ptGe[2] = ptWrapEndXU;
cplCurve.append(el);
el.ptGe[0] = ptWrapEndXD;
el.ptGe[1] = ptWrapCorD;
el.ptGe[2] = ptWrapCorD;
cplCurve.append(el);
el.ptGe[0] = ptWrapCorD;
el.ptGe[1] = ptWrapStrXD;
el.ptGe[2] = ptWrapStrXD;
cplCurve.append(el);
}
//内部线
else if (1 == nType)
{
//添加两条消声线
if (!IsSingleLine())
{
el.idSubLay = layerId();
el.dWidth = dEdgeWidth;
el.ptGe[0] = ptStartXU;
el.ptGe[1] = ptCornerU;
el.ptGe[2] = ptCornerU;
cplCurve.append(el);
el.ptGe[0] = ptCornerU;
el.ptGe[1] = ptEndXU;
el.ptGe[2] = ptEndXU;
cplCurve.append(el);
el.ptGe[0] = ptEndXD;
el.ptGe[1] = ptCornerD;
el.ptGe[2] = ptCornerD;
cplCurve.append(el);
el.ptGe[0] = ptCornerD;
el.ptGe[1] = ptStartXD;
el.ptGe[2] = ptStartXD;
cplCurve.append(el);
}
//中心线
if ((HasBaseLine() || IsSingleLine()))
{
el.gsMark = -1;
el.idSubLay = idBaseLayer;
if (IsSingleLine())
el.dWidth = dEdgeWidth;
else
el.dWidth = dCenWidth;
el.ptGe[0] = ptStartX;
el.ptGe[1] = ptCorner;
el.ptGe[2] = ptCorner;
cplCurve.append(el);
el.ptGe[0] = ptCorner;
el.ptGe[1] = ptEndX;
el.ptGe[2] = ptEndX;
cplCurve.append(el);
}
}
break;
}
case AecHvac::eOrthoLead: // 直角导流
{
//外轮廓
if (0 == nType)
{
el.dWidth = dEdgeWidth;
el.ptGe[0] = ptStartXU;
el.ptGe[1] = ptCornerU;
el.ptGe[2] = ptCornerU;
cplCurve.append(el);
el.ptGe[0] = ptCornerU;
el.ptGe[1] = ptEndXU;
el.ptGe[2] = ptEndXU;
cplCurve.append(el);
el.ptGe[0] = ptEndXD;
el.ptGe[1] = ptCornerD;
el.ptGe[2] = ptCornerD;
cplCurve.append(el);
el.ptGe[0] = ptCornerD;
el.ptGe[1] = ptStartXD;
el.ptGe[2] = ptStartXD;
cplCurve.append(el);
el.dWidth = dEndLineWidth;
el.idSubLay = idSideLayer;
el.ptGe[0] = ptStartXD;
el.ptGe[1] = ptStartXU;
el.ptGe[2] = ptStartXU;
cplCurve.append(el);
el.ptGe[0] = ptEndXU;
el.ptGe[1] = ptEndXD;
el.ptGe[2] = ptEndXD;
cplCurve.append(el);
}
//内部线
else if (1 == nType)
{
//添加导流线
AcGePoint3dArray arptLeaders;
AcGePoint3d ptWrap,ptWrapU,ptWrapD;
int nSize = sizeof(nLeader) / sizeof(nLeader[0]);
//取出第一个大于Dn的行数
for (int i = 0; i < nSize; i++)
{
if (nLeader[i][0] > dDiameterS * 2)
break;
}
//判断DN的最小差值
if (i > 0)
{
if (fabs((nLeader[i][0] - dDiameterS * 2)) > fabs((nLeader[i - 1][0] - dDiameterS * 2)))
{
i--;
}
}
ptWrap = ptGeCen + vtCor * (ptGeCen.distanceTo(ptStartD) + nLeader[i][2]);
ptWrapU = ptWrapD = ptWrap;
ptWrapU.rotateBy(PI / 10,vtNor,ptGeCen);
ptWrapD.rotateBy(PI / 10,-vtNor,ptGeCen);
if (!IsSingleLine() && dDiameterS > MayAsMUnit(249.0))
{
//添加第一导流线
el.idSubLay = idSideLayer;
el.dWidth = dEndLineWidth;
el.ptGe[0] = ptWrapU;
el.ptGe[1] = ptWrap;
el.ptGe[2] = ptWrapD;
cplCurve.append(el);
//根据数组的第二列,来添加多条导流线
int nCount = nLeader[i][1];
for (int j = 0; j < nCount - 1; j++)
{
ptWrapU += vtCor * nLeader[i][j + 3];
ptWrap += vtCor * nLeader[i][j + 3];
ptWrapD += vtCor * nLeader[i][j + 3];
el.ptGe[0] = ptWrapU;
el.ptGe[1] = ptWrap;
el.ptGe[2] = ptWrapD;
cplCurve.append(el);
}
}
//中心线
if ((HasBaseLine() || IsSingleLine()))
{
el.gsMark = -1;
el.idSubLay = idBaseLayer;
if (IsSingleLine())
el.dWidth = dEdgeWidth;
else
el.dWidth = dCenWidth;
el.ptGe[0] = ptStartX;
el.ptGe[1] = ptCorner;
el.ptGe[2] = ptCorner;
cplCurve.append(el);
el.ptGe[0] = ptCorner;
el.ptGe[1] = ptEndX;
el.ptGe[2] = ptEndX;
cplCurve.append(el);
}
}
break;
}
}
return cplCurve.length() > 0;
}
BOOL ImpHvacElbow::GetAllArcuateCplCurveVerRec(AecComplexCurve& cplCurve,int &nType,AcGePoint3d& ptStart, AcGePoint3d& ptCorner,AcGePoint3d& ptEnd,double& dPlusEdge,double& dDiameterS,double& dDiameterE,double& dThick, double& dEndThick) const
{
if (nType != 0 && nType != 1)
{
return FALSE;
}
AecHvac::HvacElbowType eElbowType = AecHvac::eIncline;
m_pXDataMap->GetAt(HELB_Type, (int&)eElbowType);
AcGeVector3d vtStr,vtEnd,vcCor,vtNor = AcGeVector3d::kZAxis;
AcGePoint3d ptGeCen,ptStartU,ptStartD,ptCornerU,ptEndU,ptEndD,ptCornerD,ptStartX,ptEndX;
ptStartX = ptStart;
ptEndX = ptEnd;
vtStr = ptStart - ptCorner;
vtEnd = ptEnd - ptCorner;
AcGeVector3d vtOrigEnd = vtEnd;
vtNor = vtStr.crossProduct(vtEnd);
vtStr.normalize();
vtEnd.normalize();
vtNor.normalize();
vtEnd.rotateBy(PI / 2, vtNor);
vtEnd.normalize();
//处理弯头开始点和末点互换
if (!vtStr.isPerpendicularTo(AcGeVector3d::kZAxis))
{
ptStartX = ptEnd;
ptEndX = ptStart;
vtEnd = ptCorner - ptEndX;
vtEnd.rotateBy(PI / 2, vtNor);
vtEnd.normalize();
//BEGIN===========================================
double dTemp = dThick;
dThick = dEndThick;
dEndThick = dTemp;
dTemp = dDiameterE;
dDiameterE = dDiameterS;
dDiameterS = dTemp;
}
ptEndX.z = ptStartX.z;// = (ptStart.z + ptEnd.z) * 0.5;
ptStartU = ptStartX + vtNor * dThick;
ptStartD = ptStartX - vtNor * dThick;
if (eElbowType != AecHvac::eAllArcuate && eElbowType != AecHvac::eAllArcWrap
&& eElbowType != AecHvac::eAllArcInWrap)
{
ptEndU = ptEndX + vtNor * (dEndThick + dThick) * 0.5;
ptEndD = ptEndX - vtNor * (dEndThick + dThick) * 0.5;
}
else
{
ptEndU = ptEndX + vtNor * dEndThick;
ptEndD = ptEndX - vtNor * dEndThick;
}
ptCornerU = ptEndU + vtEnd * dDiameterE;
ptCornerD = ptEndD + vtEnd * dDiameterE;
ptEndU = ptEndU - vtEnd * dDiameterE;
ptEndD = ptEndD - vtEnd * dDiameterE;
ptCornerU.z = ptStartX.z;
ptCornerD.z = ptStartX.z;
ptEndU.z = ptStartX.z;
ptEndD.z = ptStartX.z;
AecEqui::AecCurveElement el;
memset(&el,0,sizeof(AecEqui::AecCurveElement));
double dEdgeWidth = GetEdgeLineWidth();
double dCenWidth = GetCentLineWidth();
double dEndLineWidth = GetEndLineWidth();
AcDbObjectId idBaseLayer(NULL), idSideLayer(NULL);
//m_pXDataMap->GetAt(HVAC_BaseLayer, idBaseLayer);
m_pXDataMap->GetAt(HVAC_EndLayer, idSideLayer);
//el.idSubLay = idSideLayer;
if (0 == nType)
{
el.dWidth = dEdgeWidth;
el.ptGe[0] = ptStartU;
el.ptGe[1] = ptCornerU;
el.ptGe[2] = ptCornerU;
cplCurve.append(el);
el.ptGe[0] = ptStartD;
el.ptGe[1] = ptCornerD;
el.ptGe[2] = ptCornerD;
cplCurve.append(el);
el.ptGe[0] = ptCornerD;
el.ptGe[1] = ptCornerU;
el.ptGe[2] = ptCornerU;
cplCurve.append(el);
el.dWidth = dEndLineWidth;
el.idSubLay = idSideLayer;
el.ptGe[0] = ptStartU;
el.ptGe[1] = ptStartD;
el.ptGe[2] = ptStartD;
cplCurve.append(el);
}
if (1 == nType)
{
el.dWidth = dEdgeWidth;
AcGePoint3d ptMid = MidPoint(ptStart,ptEnd);
if ((HasBaseLine() || IsSingleLine()))
{
el.idSubLay = idBaseLayer;
el.gsMark = -1;
el.dWidth = dCenWidth;
el.ptGe[0] = ptStartX;
el.ptGe[1] = ptEndX;
el.ptGe[2] = ptEndX;
cplCurve.append(el);
}
int nDrawMode(0); // 是否填充线
m_pXDataMap->GetAt(HELB_VertDrawStyle, nDrawMode);
if (1 == nDrawMode)
{
AcGeVector3d vtUcsz = GetUcsZvt();
BOOL bStartToDown = vtStr.isCodirectionalTo(-vtUcsz);
BOOL bEndToDown = vtOrigEnd.isCodirectionalTo(-vtUcsz);
if (bStartToDown || bEndToDown) // 只有向下翻的弯头才绘制
{
el.idSubLay = idSideLayer;
el.dWidth = dEndLineWidth;
//BEGIN===============================================================
double dWidth(0.0);
double dWidthEnd = 0.0;
if (bStartToDown)
{
m_pXDataMap->GetAt(HELB_StartWidth, dWidth);
m_pXDataMap->GetAt(HELB_EndWidth, dWidthEnd);
}
else
{
m_pXDataMap->GetAt(HELB_EndWidth, dWidth);
m_pXDataMap->GetAt(HELB_StartWidth, dWidthEnd);
}
dWidth = dWidth > dWidthEnd ? dWidth : dWidthEnd;
AcGePoint3dArray ptUpArr;
AcGePoint3dArray ptDownArr;
AcGeVector3d vtOff = (ptStartU - ptCornerU).normalize();
ptUpArr.append(ptCornerU + vtOff * dWidth * 7.0/100.0); // 按照6.0比例
ptUpArr.append(ptCornerU + vtOff * dWidth * 17.0/100.0);
ptUpArr.append(ptCornerU + vtOff * dWidth * 32.0/100.0);
ptUpArr.append(ptCornerU + vtOff * dWidth * 47.0/100.0);
ptUpArr.append(ptCornerU + vtOff * dWidth * 68.0/100.0);
vtOff = (ptStartD - ptCornerD).normalize();
ptDownArr.append(ptCornerD + vtOff * dWidth * 7.0/100.0); // 按照6.0比例
ptDownArr.append(ptCornerD + vtOff * dWidth * 17.0/100.0);
ptDownArr.append(ptCornerD + vtOff * dWidth * 32.0/100.0);
ptDownArr.append(ptCornerD + vtOff * dWidth * 47.0/100.0);
ptDownArr.append(ptCornerD + vtOff * dWidth * 68.0/100.0);
int i(0);
//AcGePoint3d ptTemp;
for (i = 0; i < ptUpArr.length(); i++)
{
//ptTemp = ptUpArr[i] + vtPerl * dThick;
el.ptGe[0] = ptUpArr[i];
el.ptGe[1] = ptDownArr[i];
el.ptGe[2] = ptDownArr[i];
cplCurve.append(el);
}
}
}
}
return TRUE;
}
BOOL ImpHvacElbow::GetAllArcuateCplCurveVerRecForOffset(AecComplexCurve& cplCurve, int &nType) const
{
AcGePoint3d ptStart, ptCorner, ptCornerAssist, ptEnd;
m_pXDataMap->GetAt(HELB_StartPoint, ptStart);
m_pXDataMap->GetAt(HELB_EndPoint, ptEnd);
m_pXDataMap->GetAt(HELB_CornerPoint, ptCorner);
m_pXDataMap->GetAt(HELB_AssisCornerPoint, ptCornerAssist);
double dThickStart = 0.0, dThickEnd = 0.0, dWidth = 0.0;
m_pXDataMap->GetAt(HELB_Thick, dThickStart);
m_pXDataMap->GetAt(HELB_EndThick, dThickEnd);
dThickStart *= 0.5;
dThickEnd *= 0.5;
AcGeVector3d vtStart = ptStart - ptCorner;
vtStart.normalize();
AcGeVector3d vtEnd = ptEnd - ptCornerAssist;
vtStart.normalize();
// 获得UCS坐标Z向量
AcDbDatabase* pDb = acdbCurDwg();
AcGeVector3d vtZAxis(pDb->ucsxdir().crossProduct(pDb->ucsydir()));
AcGePlane planeStd;
AcGeVector3d vtHorOffset;
if (vtStart.isPerpendicularTo(vtZAxis))
{
planeStd.set(ptStart, vtZAxis);
ptEnd = ptEnd.orthoProject(planeStd);
m_pXDataMap->GetAt(HELB_EndWidth, dWidth);
dWidth *= 0.5;
vtHorOffset = ptCorner - ptStart;
vtHorOffset.normalize();
AcGePoint3d ptTemp = ptStart;
ptStart = ptEnd;
ptEnd = ptTemp;
double dTemp = dThickStart;
dThickStart = dThickEnd;
dThickEnd = dTemp;
}
else
{
planeStd.set(ptEnd, vtZAxis);
ptStart = ptStart.orthoProject(planeStd);
m_pXDataMap->GetAt(HELB_StartWidth, dWidth);
dWidth *= 0.5;
vtHorOffset = ptCornerAssist - ptEnd;
vtHorOffset.normalize();
}
AcGeVector3d vtNormalElbow = vtStart.crossProduct(vtEnd);
vtNormalElbow.normalize();
AcGePoint3d ptStartUpL = ptStart + vtNormalElbow * dThickStart + vtHorOffset * dWidth;
AcGePoint3d ptStartUpR = ptStart + vtNormalElbow * dThickStart - vtHorOffset * dWidth;
AcGePoint3d ptStartDownL = ptStart - vtNormalElbow * dThickStart + vtHorOffset * dWidth;
AcGePoint3d ptStartDownR = ptStart - vtNormalElbow * dThickStart - vtHorOffset * dWidth;
AcGePoint3d ptEndUp = ptEnd + vtNormalElbow * dThickEnd;
AcGePoint3d ptEndDown = ptEnd - vtNormalElbow * dThickEnd;
AecEqui::AecCurveElement el;
memset(&el,0,sizeof(AecEqui::AecCurveElement));
double dEdgeWidth = GetEdgeLineWidth();
double dCenWidth = GetCentLineWidth();
double dEndLineWidth = GetEndLineWidth();
AcDbObjectId idBaseLayer(NULL), idSideLayer(NULL);
m_pXDataMap->GetAt(HVAC_EndLayer, idSideLayer);
if (0 == nType)
{
el.dWidth = dEdgeWidth;
el.ptGe[0] = ptStartUpL;
el.ptGe[1] = ptStartUpR;
el.ptGe[2] = ptStartUpR;
cplCurve.append(el);
el.ptGe[0] = ptStartUpR;
el.ptGe[1] = ptEndUp;
el.ptGe[2] = ptEndUp;
cplCurve.append(el);
el.ptGe[0] = ptEndUp;
el.ptGe[1] = ptEndDown;
el.ptGe[2] = ptEndDown;
cplCurve.append(el);
el.ptGe[0] = ptEndDown;
el.ptGe[1] = ptStartDownR;
el.ptGe[2] = ptStartDownR;
cplCurve.append(el);
el.ptGe[0] = ptStartDownR;
el.ptGe[1] = ptStartDownL;
el.ptGe[2] = ptStartDownL;
cplCurve.append(el);
el.dWidth = dEndLineWidth;
el.idSubLay = idSideLayer;
el.ptGe[0] = ptStartDownL;
el.ptGe[1] = ptStartUpL;
el.ptGe[2] = ptStartUpL;
cplCurve.append(el);
}
if (1 == nType)
{
el.dWidth = dEdgeWidth;
AcGePoint3d ptMid = MidPoint(ptStart,ptEnd);
if ((HasBaseLine() || IsSingleLine()))
{
el.idSubLay = idBaseLayer;
el.gsMark = -1;
el.dWidth = dCenWidth;
el.ptGe[0] = ptStart;
el.ptGe[1] = ptEnd;
el.ptGe[2] = ptEnd;
cplCurve.append(el);
}
}
return TRUE;
}
BOOL ImpHvacElbow::GetAllArcuateCplCurveVerCir(AecComplexCurve& cplCurve,int &nType,AcGePoint3d& ptStart, AcGePoint3d& ptCorner,AcGePoint3d& ptEnd,double& dPlusEdge,double& dDiameterS,double& dDiameterE) const
{
if (nType != 0 && nType != 1)
{
return FALSE;
}
AcGeVector3d vtStr,vtEnd,vtDir,vtNor = AcGeVector3d::kZAxis, vtTemp;
AcGePoint3d ptStartU,ptStartD,ptCornerU,ptEndU,ptEndD,ptCornerD,ptStartArc,ptEndArc;
AcGePoint3d ptStartX,ptStartXU,ptStartXD,ptEndX,ptEndXU,ptEndXD,ptCorOnArc;
AcGePoint3d ptOrgStart, ptOrgEnd;
ptOrgStart = ptStart;
ptOrgEnd = ptEnd;
ptStartX = ptStart;
ptEndX = ptEnd;
vtStr = ptStart - ptCorner;
vtEnd = ptEnd - ptCorner;
vtNor = vtStr.crossProduct(vtEnd);
vtStr.normalize();
vtEnd.normalize();
vtNor.normalize();
ptStart -= vtStr * dPlusEdge;
ptEnd -= vtEnd * dPlusEdge;
// double dAngle = vtStr.angleTo(vtEnd,vtNor);
AcGeVector3d vtZAxis(GetUcsZvt());
ptEndX.z = ptStartX.z;
ptStartU = ptStartX + vtNor * dDiameterS;
ptStartD = ptStartX - vtNor * dDiameterS;
ptEndU = ptEndX + vtNor * dDiameterE;
ptEndD = ptEndX - vtNor * dDiameterE;
ptStartArc = ptStartX - vtEnd * dDiameterS;
ptEndArc = ptEndX - vtStr * dDiameterE;
AcDbObjectId idBaseLayer(NULL), idSideLayer(NULL);
int nHasBaseLine = 1;
//m_pXDataMap->GetAt(HVAC_BaseLayer, idBaseLayer);
m_pXDataMap->GetAt(HVAC_EndLayer, idSideLayer);
m_pXDataMap->GetAt(HVAC_HasBaseLine, nHasBaseLine);
AcDbObjectId idReal = layerId();
AcDbObjectId idDash = DashLayer();
AcDbObjectId idCent = CenterLayer();
AecEqui::AecCurveElement el;
memset(&el,0,sizeof(AecEqui::AecCurveElement));
double dEdgeWidth = GetEdgeLineWidth();
double dCenWidth = GetCentLineWidth();
double dEndLineWidth = GetEndLineWidth();
AcGePoint3dArray pts;
AcDbPolyline pPolyLine1, pPolyLine2;
int nRet = -1;
if (nType == 0)
{
vtDir = ptCorner - ptOrgStart;
if (vtDir.isParallelTo(vtZAxis))
// vtTemp = -vtStr.crossProduct(vtNor);// Lixl modify 2011-12-16
vtTemp = -vtEnd;
else
vtTemp = -vtDir;
nRet = GetEllipsePtsFromCircle(pts, ptOrgStart, dDiameterS*2.0, -vtDir, vtZAxis, pPolyLine1, vtTemp);
if (-1 != nRet)
{
if (1 == nRet)
{
el.dWidth = dEndLineWidth;
el.idSubLay = idSideLayer;
}
else
{
el.dWidth = dEdgeWidth;
el.idSubLay = AcDbObjectId::kNull;
}
if (0 == nRet && pts.length() == 3)// 半圆 Lixl add 2011-11-23
{
el.ptGe[0] = pts[0];
el.ptGe[1] = pts[1];
el.ptGe[2] = pts[2];
cplCurve.append(el);
}
else
{
for (int i = 0; i < pts.length()-1; i++)
{
el.ptGe[0] = pts[i];
el.ptGe[1] = pts[i+1];
el.ptGe[2] = pts[i+1];
cplCurve.append(el);
}
}
}
// 终点端线
vtDir = ptCorner - ptOrgEnd;
if (vtDir.isParallelTo(vtZAxis))
// vtTemp = -vtEnd.crossProduct(vtNor);// Lixl modify 2011-12-16
vtTemp = -vtStr;
else
vtTemp = -vtDir;
pts.setLogicalLength(0);
nRet = GetEllipsePtsFromCircle(pts, ptOrgEnd, dDiameterE*2, -vtDir, vtZAxis, pPolyLine2, vtTemp);
if (-1 != nRet)
{
if (1 == nRet)
{
el.dWidth = dEndLineWidth;
el.idSubLay = idSideLayer;
}
else
{
el.dWidth = dEdgeWidth;
el.idSubLay = AcDbObjectId::kNull;
}
if (0 == nRet && pts.length() == 3)// 半圆Lixl add 2011-11-23
{
el.ptGe[0] = pts[0];
el.ptGe[1] = pts[1];
el.ptGe[2] = pts[2];
cplCurve.append(el);
}
else
{
for (int i = 0; i < pts.length()-1; i++)
{
el.ptGe[0] = pts[i];
el.ptGe[1] = pts[i+1];
el.ptGe[2] = pts[i+1];
cplCurve.append(el);
}
}
}
el.idSubLay = idReal;
el.dWidth = dEdgeWidth;
el.ptGe[0] = ptStartU;
el.ptGe[1] = ptEndU;
el.ptGe[2] = ptEndU;
cplCurve.append(el);
el.ptGe[0] = ptStartD;
el.ptGe[1] = ptEndD;
el.ptGe[2] = ptEndD;
cplCurve.append(el);
}
else if (nType == 1)
{
if ((HasBaseLine() || IsSingleLine()))
{
el.idSubLay = idBaseLayer;
el.gsMark = -1;
el.dWidth = dCenWidth;
el.ptGe[0] = ptStartX;
el.ptGe[1] = ptEndX;
el.ptGe[2] = ptEndX;
cplCurve.append(el);
}
el.idSubLay = idReal;
el.dWidth = dEdgeWidth;
if (vtStr.angleTo(vtZAxis) < PI*0.25 || vtEnd.angleTo(vtZAxis) < PI*0.25)
{
ptStartArc = ptStartX + vtEnd * dDiameterS;
//BEGIN=====================================================
//ptEndArc = ptEndX + vtStr * dDiameterS;
ptEndArc = ptEndX + vtStr * dDiameterE;
el.gsMark = 0;
if (ptOrgStart.z > ptCorner.z)// 看看是否需要画内部半圆Lixl
{
vtDir = ptCorner - ptOrgStart;
if (vtDir.isParallelTo(vtZAxis))
vtTemp = vtStr.crossProduct(vtNor);
else
vtTemp = vtDir;
nRet = GetEllipsePtsFromCircle(pts, ptOrgStart, dDiameterS*2.0, vtDir, vtZAxis, pPolyLine1, vtTemp);
if (-1 != nRet)
{
if (1 == nRet)
{
el.dWidth = dEndLineWidth;
el.idSubLay = idSideLayer;
}
else
{
el.dWidth = dEdgeWidth;
el.idSubLay = AcDbObjectId::kNull;
}
if (0 == nRet && pts.length() == 3)// 半圆Lixl add 2011-11-23
{
el.ptGe[0] = pts[0];
el.ptGe[1] = pts[1];
el.ptGe[2] = pts[2];
cplCurve.append(el);
}
else
{
for (int i = 0; i < pts.length()-1; i++)
{
el.ptGe[0] = pts[i];
el.ptGe[1] = pts[i+1];
el.ptGe[2] = pts[i+1];
cplCurve.append(el);
}
}
}
}
if (ptOrgEnd.z > ptCorner.z)
{
vtDir = ptCorner - ptOrgEnd;
if (vtDir.isParallelTo(vtZAxis))
vtTemp = vtEnd.crossProduct(vtNor);
else
vtTemp = vtDir;
pts.setLogicalLength(0);
nRet = GetEllipsePtsFromCircle(pts, ptOrgEnd, dDiameterE*2, vtDir, vtZAxis, pPolyLine2, vtTemp);
if (-1 != nRet)
{
if (1 == nRet)
{
el.dWidth = dEndLineWidth;
el.idSubLay = idSideLayer;
}
else
{
el.dWidth = dEdgeWidth;
el.idSubLay = AcDbObjectId::kNull;
}
if (0 == nRet && pts.length() == 3)// 半圆Lixl add 2011-11-23
{
el.ptGe[0] = pts[0];
el.ptGe[1] = pts[1];
el.ptGe[2] = pts[2];
cplCurve.append(el);
}
else
{
for (int i = 0; i < pts.length()-1; i++)
{
el.ptGe[0] = pts[i];
el.ptGe[1] = pts[i+1];
el.ptGe[2] = pts[i+1];
cplCurve.append(el);
}
}
}
}
el.gsMark = -1;
}
else
{
int nDrawMode(0); // 是否填充线
m_pXDataMap->GetAt(HELB_VertDrawStyle, nDrawMode);
if (1 == nDrawMode)
{
BOOL bStartToDown = vtStr.isCodirectionalTo(-vtZAxis);
BOOL bEndToDown = vtEnd.isCodirectionalTo(-vtZAxis);
if (bStartToDown || bEndToDown) // 只有向下翻的弯头才绘制
{
el.idSubLay = idSideLayer;
el.dWidth = dEndLineWidth;
AcGePoint3d ptStartMoveUp, ptEndMoveUp, ptStartMoveArc, ptEndMoveArc;
AcGePoint3d ptStartMoveDown, ptEndMoveDown;
if (bStartToDown)
{
ptStartMoveUp = ptStartU;
ptEndMoveUp = ptEndU;
ptStartMoveArc = ptStartArc;
ptEndMoveArc = ptEndArc;
ptStartMoveDown = ptStartD;
ptEndMoveDown = ptEndD;
//m_pXDataMap->GetAt(HELB_Diameter, dWidth);
}
else
{
ptStartMoveUp = ptEndU;
ptEndMoveUp = ptStartU;
ptStartMoveArc = ptEndArc;
ptEndMoveArc = ptStartArc;
ptStartMoveDown = ptEndD;
ptEndMoveDown = ptStartD;
//m_pXDataMap->GetAt(HELB_EndWidth, dWidth);
}
double dMaxDiameter = dDiameterS > dDiameterE ? dDiameterS : dDiameterE;
double dHalfWidth = dMaxDiameter;
AcGePoint3dArray ptUpArr, ptArcArr, ptDownArr;
AcGeVector3d vtOff = (ptEndMoveUp - ptStartMoveUp).normalize();
ptUpArr.append(ptStartMoveUp + vtOff * dHalfWidth * 1.0/8.5); // 按照6.0比例
ptUpArr.append(ptStartMoveUp + vtOff * dHalfWidth * 1.0/3.1);
ptUpArr.append(ptStartMoveUp + vtOff * dHalfWidth * 1.0/1.62);
ptUpArr.append(ptStartMoveUp + vtOff * dHalfWidth);
vtOff = (ptEndMoveArc - ptStartMoveArc).normalize();
ptStartMoveArc.z = ptStartMoveUp.z;
ptArcArr.append(ptStartMoveArc + vtOff * dHalfWidth * 1.0/8.5);
ptArcArr.append(ptStartMoveArc + vtOff * dHalfWidth * 1.0/3.1);
ptArcArr.append(ptStartMoveArc + vtOff * dHalfWidth * 1.0/1.62);
ptArcArr.append(ptStartMoveArc + vtOff * dHalfWidth);
//AcGeVector3d vtPerl = (ptStartD - ptStartU).normalize();
vtOff = (ptEndMoveDown - ptStartMoveDown).normalize();
ptStartMoveDown.z = ptStartMoveUp.z;
ptDownArr.append(ptStartMoveDown + vtOff * dHalfWidth * 1.0/8.5);
ptDownArr.append(ptStartMoveDown + vtOff * dHalfWidth * 1.0/3.1);
ptDownArr.append(ptStartMoveDown + vtOff * dHalfWidth * 1.0/1.62);
ptDownArr.append(ptStartMoveDown + vtOff * dHalfWidth);
int i(0);
AcGePoint3d ptTemp;
for (i = 0; i < ptUpArr.length() && i < ptArcArr.length(); i++)
{
//ptTemp = ptUpArr[i] + vtPerl * dWidth;
el.ptGe[0] = ptUpArr[i];
el.ptGe[1] = ptArcArr[i];
el.ptGe[2] = ptDownArr[i];
cplCurve.append(el);
}
}
}
}
}
return TRUE;
}
void ImpHvacElbow::DrawAllArcInWrap3d(AcGiDraw &mode) const
{
ASSERT(NULL != m_pXDataMap);
DrawAllArcuate3d(mode);
}
BOOL ImpHvacElbow::MakeAllArcInWrap2DCurves(AecComplexCurve& cplCurve,int &nType) const
{
ASSERT(NULL != m_pXDataMap);
if (IsHorzAlignment())
{
return DrawAllArcuate2DHor(cplCurve,nType);
}
else if(IsVertAlignment())
{
return DrawAllArcuate2DVer(cplCurve,nType);
}
else if (IsInclineAlignment())
{
return MakeAllArcuate2DCurves(cplCurve,nType);
}
return FALSE;
}
void ImpHvacElbow::DrawAllArcWrap3d(AcGiDraw &mode) const
{
ASSERT(NULL != m_pXDataMap);
DrawAllArcuate3d(mode);
}
BOOL ImpHvacElbow::MakeAllArcWrap2DCurves(AecComplexCurve& cplCurve,int &nType) const
{
ASSERT(NULL != m_pXDataMap);
if (IsHorzAlignment())
{
return DrawAllArcuate2DHor(cplCurve,nType);
}
else if(IsVertAlignment())
{
return DrawAllArcuate2DVer(cplCurve,nType);
}
else if (IsInclineAlignment())
{
return MakeAllArcuate2DCurves(cplCurve,nType);
}
return FALSE;
}
//多节弯头圆形3D
void ImpHvacElbow::DrawSegmental3d(AcGiDraw &mode) const
{
ASSERT(NULL != m_pXDataMap);
double dDiameter = MayAsMUnit(300),dPlusEdge = MayAsMUnit(50.0);
int nSectType = 2;
AcDbObjectId idLayer;
int nBaseLine = 1;
int nSingleLine = 0;
int nSegments = 4;
AcGePoint3d ptStart, ptCorner, ptEnd;
m_pXDataMap->GetAt(HELB_Segments, nSegments);
m_pXDataMap->GetAt(HVAC_SectType,nSectType);
double dDiameterStart = MayAsMUnit(400.0);
double dDiameterEnd = MayAsMUnit(400.0);
m_pXDataMap->GetAt(HELB_StartPoint,ptStart);
m_pXDataMap->GetAt(HELB_CornerPoint,ptCorner);
m_pXDataMap->GetAt(HELB_EndPoint,ptEnd);
m_pXDataMap->GetAt(HVAC_HasBaseLine,nBaseLine);
m_pXDataMap->GetAt(HVAC_IsSingleLine,nSingleLine);
m_pXDataMap->GetAt(HELB_Diameter, dDiameterStart);
if (!m_pXDataMap->GetAt(HELB_EndDiameter, dDiameterEnd))
{
dDiameterEnd = dDiameterStart;
}
double dMaxWidth = dDiameterStart > dDiameterEnd ? dDiameterStart : dDiameterEnd;
if ((ptStart.distanceTo(ptCorner) - MayAsMUnit(50.0)) - dMaxWidth / 2 < -1e-6)
{
dPlusEdge = 0.1;
}
dDiameterStart *= 0.5;
dDiameterEnd *= 0.5;
if (nSegments < 2)
nSegments = 2;
double dMinDiffAng = GetMinDiffAngle();
int nColumns = (int)(PI * 2 / dMinDiffAng);
//计算半径偏移量
double dDiameterOffset = dDiameterEnd - dDiameterStart;
AcGePoint3d ptOnArc = ptCorner;
AcGePoint3d ptStartArc = ptStart;
AcGePoint3d ptEndArc = ptEnd;
if (!GetPtOnArcExt(ptStartArc, ptCorner, ptEndArc, ptCorner, ptOnArc, dPlusEdge))
{
//输出错误信息
acutPrintf(_T("\n无法生成弯头!"));
return;
}
AcGeCircArc3d circleArc;
circleArc.set(ptStartArc, ptOnArc, ptEndArc);
AcGePoint3d ptCenterArc = circleArc.center();
AcGeVector3d vtStartArc = ptStartArc - ptCenterArc;
AcGeVector3d vtEndArc = ptEndArc - ptCenterArc;
AcGeVector3d vtNormalArc = vtEndArc.crossProduct(vtStartArc);
vtStartArc.normalize();
vtEndArc.normalize();
vtNormalArc.normalize();
double dAngle = vtStartArc.angleTo(vtEndArc);
double dSegAngle = dAngle / nSegments;
//关键节点数组
AcGePoint3dArray arptKeys;
AcGePoint3d ptTemp;
double dDiameterTemp = MayAsMUnit(300.0);
//起始段
AcGeVector3d vtAxisStart = ptStart - ptStartArc;
// Lixl add 2011-2-12-02
vtStartArc = vtAxisStart.crossProduct(vtNormalArc);
vtStartArc.normalize();
//起始段前端
for (int iStart = 0; iStart < nColumns; iStart++)
{
ptTemp = ptStart + dDiameterStart * vtStartArc;
ptTemp.rotateBy(dMinDiffAng * iStart, vtAxisStart, ptStart);
arptKeys.append(ptTemp);
}
ptTemp = ptStart + dDiameterStart * vtStartArc;
arptKeys.append(ptTemp);
//起始段后端
for (int iStartArc = 0; iStartArc < nColumns; iStartArc++)
{
ptTemp = ptStartArc + dDiameterStart * vtStartArc;
ptTemp.rotateBy(dMinDiffAng * iStartArc, vtAxisStart, ptStartArc);
arptKeys.append(ptTemp);
}
ptTemp = ptStartArc + dDiameterStart * vtStartArc;
arptKeys.append(ptTemp);
//中间圆弧段
for (int iArc = 1; iArc < nSegments; iArc++)
{
dDiameterTemp = dDiameterStart + dDiameterOffset * iArc / nSegments;
AcGePoint3d ptStartArcTemp = ptStartArc;
AcGePoint3d ptOnArcTemp = ptStartArcTemp.rotateBy(-dSegAngle * iArc, vtNormalArc, ptCenterArc);
AcGeVector3d vtOnArcTemp = ptOnArcTemp - ptCenterArc;
AcGeVector3d vtOnArcAxis = vtOnArcTemp;
vtOnArcAxis.rotateBy(PI / 2, vtNormalArc);
vtOnArcTemp.normalize();
for (int i = 0; i < nColumns; i++)
{
ptTemp = ptOnArcTemp + dDiameterTemp * vtOnArcTemp;
ptTemp.rotateBy(dMinDiffAng * i, vtOnArcAxis, ptOnArcTemp);
arptKeys.append(ptTemp);
}
ptTemp = ptOnArcTemp + dDiameterTemp * vtOnArcTemp;
arptKeys.append(ptTemp);
}
//末尾段
AcGeVector3d vtAxisEnd = ptEndArc - ptEnd;
// Lixl add 2011-2-12-02
vtEndArc = vtAxisEnd.crossProduct(vtNormalArc);
vtEndArc.normalize();
//末尾段前端
for (int iEndArc = 0; iEndArc < nColumns; iEndArc++)
{
ptTemp = ptEndArc + dDiameterEnd * vtEndArc;
ptTemp.rotateBy(dMinDiffAng * iEndArc, vtAxisEnd, ptEndArc);
arptKeys.append(ptTemp);
}
ptTemp = ptEndArc + dDiameterEnd * vtEndArc;
arptKeys.append(ptTemp);
//末尾段后端
for (int iEnd = 0; iEnd < nColumns; iEnd++)
{
ptTemp = ptEnd + dDiameterEnd * vtEndArc;
ptTemp.rotateBy(dMinDiffAng * iEnd, vtAxisEnd, ptEnd);
arptKeys.append(ptTemp);
}
ptTemp = ptEnd + dDiameterEnd * vtEndArc;
arptKeys.append(ptTemp);
//生成三维网格
DrawMesh(mode,nSegments + 3, nColumns + 1, arptKeys.asArrayPtr());
}
BOOL ImpHvacElbow::MakeSegmental2DCurves(AecComplexCurve& cplCurve,int &nType) const
{
ASSERT(NULL != m_pXDataMap);
double dEdgeWidth = GetEdgeLineWidth();
double dCenWidth = GetCentLineWidth();
if (IsHorzAlignment())
{
AcGePoint3dArray pts;
if (GetPtsSegmentalHor(pts))
{
int nLength = pts.length() - 5;
nLength = nLength / 2;
int i = 0;
AcDbObjectId idBaseLayer(NULL), idSideLayer(NULL);
int nHasBaseLine = 1;
double dEndLineWidth = GetEndLineWidth();
//m_pXDataMap->GetAt(HVAC_BaseLayer, idBaseLayer);
m_pXDataMap->GetAt(HVAC_EndLayer, idSideLayer);
m_pXDataMap->GetAt(HVAC_HasBaseLine, nHasBaseLine);
AecEqui::AecCurveElement el;
memset(&el,0,sizeof(AecEqui::AecCurveElement));
if (0 == nType)
{
el.dWidth = dEdgeWidth;
//上弧
for (i = 0; i < nLength - 1; i++)
{
el.ptGe[0] = pts.at(i);
el.ptGe[1] = pts.at(i + 1);
el.ptGe[2] = pts.at(i + 1);
cplCurve.append(el);
}
//下弧
for (i = nLength; i < nLength * 2 - 1; i++)
{
el.ptGe[0] = pts.at(i);
el.ptGe[1] = pts.at(i + 1);
el.ptGe[2] = pts.at(i + 1);
cplCurve.append(el);
}
//两端直线
el.idSubLay = idSideLayer;
el.dWidth = dEndLineWidth;
el.ptGe[0] = pts.at(0);
el.ptGe[1] = pts.at(nLength);
el.ptGe[2] = pts.at(nLength);
cplCurve.append(el);
el.ptGe[0] = pts.at(nLength - 1);
el.ptGe[1] = pts.at(nLength * 2 - 1);
el.ptGe[2] = pts.at(nLength * 2 - 1);
cplCurve.append(el);
}
//中心线
if (1 == nType)
{
//中间的间隔线
if (!IsSingleLine())
{
for (i = 2; i <= nLength - 3; i ++)
{
el.idSubLay = idSideLayer;
el.dWidth = dEndLineWidth;
el.ptGe[0] = pts.at(i);
el.ptGe[1] = pts.at(nLength + i);
el.ptGe[2] = pts.at(nLength + i);
cplCurve.append(el);
}
}
if ((HasBaseLine() || IsSingleLine()))
{
el.idSubLay = idBaseLayer;
el.gsMark = -1;
if (IsSingleLine())
el.dWidth = dEdgeWidth;
else
el.dWidth = dCenWidth;
el.ptGe[0] = pts.at(nLength * 2);
el.ptGe[1] = pts.at(nLength * 2 + 1);
el.ptGe[2] = pts.at(nLength * 2 + 1);
cplCurve.append(el);
el.ptGe[0] = pts.at(nLength * 2 + 1);
el.ptGe[1] = pts.at(nLength * 2 + 2);
el.ptGe[2] = pts.at(nLength * 2 + 3);
cplCurve.append(el);
el.ptGe[0] = pts.at(nLength * 2 + 3);
el.ptGe[1] = pts.at(nLength * 2 + 4);
el.ptGe[2] = pts.at(nLength * 2 + 4);
cplCurve.append(el);
return TRUE;
}
}
}
}
else if(IsVertAlignment())
{
DrawAllArcuate2DVer(cplCurve,nType);
}
else if(IsInclineAlignment())
{
return MakeSegmental2DInc(cplCurve,nType);
}
return cplCurve.length() > 0;
}
// 分段拟合弯头,圆形,倾斜二维绘制
// 待完成
BOOL ImpHvacElbow::MakeSegmental2DInc( AecComplexCurve& cplCurve,int &nType ) const
{
ASSERT(NULL != m_pXDataMap);
ESection eSectType = eRect;
m_pXDataMap->GetAt(HVAC_SectType,(int&)eSectType);
if (eCircle != eSectType)
return FALSE;
// 点
AcGePoint3d ptStart, ptCorner, ptEnd;
m_pXDataMap->GetAt(HELB_StartPoint,ptStart);
m_pXDataMap->GetAt(HELB_CornerPoint,ptCorner);
m_pXDataMap->GetAt(HELB_EndPoint,ptEnd);
// 端口宽
double dDiameter = MayAsMUnit(300),dStartWidth = MayAsMUnit(300),dEndWidth = MayAsMUnit(100),dPlusEdge = MayAsMUnit(50.0);
m_pXDataMap->GetAt(HELB_Diameter,dDiameter);
m_pXDataMap->GetAt(HELB_StartWidth,dStartWidth);
m_pXDataMap->GetAt(HELB_EndWidth,dEndWidth);
m_pXDataMap->GetAt(HVAC_PlusEdge, dPlusEdge);
BOOL bSingleLine(FALSE);
BOOL bHasBaseLine(FALSE);
m_pXDataMap->GetAt(HVAC_IsSingleLine, bSingleLine);
m_pXDataMap->GetAt(HVAC_HasBaseLine, bHasBaseLine);
// 线宽
double dEdgeLineWidth(0), dCenLineWidth(0), dEndLineWidth(0);
dEdgeLineWidth = GetEdgeLineWidth();
dEndLineWidth = GetEndLineWidth();
dCenLineWidth = GetCentLineWidth();
AcDbObjectId idEndLayer;
m_pXDataMap->GetAt(HVAC_EndLayer, idEndLayer);
AcGePoint3dArray arptu,arptd;
if (!GetPrjPts(arptu, arptd))
return FALSE;
// 中心线上的点数组
AcGePoint3dArray arCen;
AcGePoint3d ptCen;
arCen.append(ptStart);
for (int i = 1; i <= arptu.length()-2; i++)
{
Midpoint(arptu[i], arptd[i], ptCen);
arCen.append(ptCen);
}
arCen.append(ptEnd);
AecEqui::AecCurveElement el;
memset(&el, 0, sizeof(AecEqui::AecCurveElement));
// 外轮廓
if (0 == nType)
{
el.dWidth = dEdgeLineWidth;
// 单线模式
if (bSingleLine)
{
for (int i = 0; i < arCen.length()-1; i++)
{
el.ptGe[0] = arptu[i];
el.ptGe[1] = arptu[i+1];
el.ptGe[2] = arptu[i+1];
cplCurve.append(el);
}
return TRUE;
}
int i(0);
for (; i < arptu.length()-1; i++)
{
el.ptGe[0] = arptu[i];
el.ptGe[1] = arptu[i+1];
el.ptGe[2] = arptu[i+1];
cplCurve.append(el);
}
for (i = 0; i < arptd.length()-1; i++)
{
el.ptGe[0] = arptd[i];
el.ptGe[1] = arptd[i+1];
el.ptGe[2] = arptd[i+1];
cplCurve.append(el);
}
AcGeVector3d vtStr, vtEnd, vtNor, vtZAxis;
vtStr = ptStart - ptCorner;
vtEnd = ptEnd - ptCorner;
vtStr.normalize();
vtEnd.normalize();
vtNor = vtStr.crossProduct(vtEnd);
// 计算弯头截面的弧线(端线)
AcGePoint3dArray arPtS, arPtE;
vtZAxis = GetUcsZvt();
AcDbPolyline DbLine;
// 方向要从端点指向拐点
vtStr = - vtStr;
vtEnd = - vtEnd;
if (ptStart.z > ptCorner.z)
;
else
vtStr = -vtStr;
int iRes = GetEllipsePtsFromCircle(arPtS, ptStart, dStartWidth, vtStr, vtZAxis, DbLine, vtStr); //Lixl add 2011-11-23
DbLine.reset(Adesk::kFalse, iRes);
if (ptEnd.z > ptCorner.z)
;
else
vtEnd = -vtEnd;
iRes = GetEllipsePtsFromCircle(arPtE, ptEnd, dEndWidth, vtEnd, vtZAxis, DbLine, vtEnd); //Lixl add 2011-11-23
// 边线
el.idSubLay = idEndLayer;
el.dWidth = dEndLineWidth;
for (i = 0; i < arPtS.length()-1; i++)
{
el.ptGe[0] = arPtS[i];
el.ptGe[1] = arPtS[i+1];
el.ptGe[2] = arPtS[i+1];
cplCurve.append(el);
}
for (i = 0; i < arPtE.length()-1; i++)
{
el.ptGe[0] = arPtE[i];
el.ptGe[1] = arPtE[i+1];
el.ptGe[2] = arPtE[i+1];
cplCurve.append(el);
}
}
// 中心线
else if (1 == nType)
{
if (bHasBaseLine)
{
el.gsMark = -1;
el.dWidth = dCenLineWidth;
for (i = 0; i <= arCen.length()-2; i++)
{
el.ptGe[0] = arCen[i];
el.ptGe[1] = arCen[i+1];
el.ptGe[2] = arCen[i+1];
cplCurve.append(el);
}
}
}
return TRUE;
}
void ImpHvacElbow::DrawIncline3d(AcGiDraw &mode) const
{
ASSERT(NULL != m_pXDataMap);
double dDiameter = MayAsMUnit(300.0);
double dPlusEdge = MayAsMUnit(50.0);
//==========================================
double dThickA = MayAsMUnit(50.0);
double dThickB = MayAsMUnit(50.0);
AcGePoint3d ptCorStart;
AcGePoint3d ptCorEnd;
double dStaWidth = MayAsMUnit(150.0);
double dEndWidth = MayAsMUnit(150.0);
AcGePoint3d ptStart, ptCorner, ptEnd;
AcDbObjectId idLayer;
int nBaseLine;
//=====================================================
m_pXDataMap->GetAt(HELB_Thick,dThickA);
if (!m_pXDataMap->GetAt(HELB_EndThick, dThickB))
{
dThickB = dThickA;
}
m_pXDataMap->GetAt(HELB_StartWidth,dStaWidth);
m_pXDataMap->GetAt(HELB_EndWidth,dEndWidth);
//m_pXDataMap->GetAt(HVAC_PlusEdge,dPlusEdge);
m_pXDataMap->GetAt(HELB_StartPoint,ptStart);
//BEGIN==========================================
m_pXDataMap->GetAt(HELB_CornerPoint,ptCorStart);
if (!m_pXDataMap->GetAt(HELB_AssisCornerPoint, ptCorEnd))
{
ptCorEnd = ptCorStart;
}
double dMaxWidth = dStaWidth > dEndWidth ? dStaWidth : dEndWidth;
if ((ptStart.distanceTo(ptCorStart) - MayAsMUnit(50.0)) - dMaxWidth / 2 < -1e-6)
{
dPlusEdge = 0.1;
}
m_pXDataMap->GetAt(HELB_EndPoint,ptEnd);
m_pXDataMap->GetAt(HVAC_HasBaseLine,nBaseLine);
AecHvac::HvacElbowType eElbowType = AecHvac::eIncline;
m_pXDataMap->GetAt(HELB_Type, (int&)eElbowType);
//内斜线弯头弯曲角度为90度
const double dAngle = PI / 2;
AcGeVector3d vtCorStartCom = ptCorStart.asVector();
AcGeVector3d vtCorEndCom = ptCorEnd.asVector();
AcGeVector3d vtCornerCom = (vtCorStartCom + vtCorEndCom) / 2;
ptCorner = AcGePoint3d::kOrigin + vtCornerCom;
AcGePoint3d ptOnArc = ptCorner;
AcGePoint3d ptStartArc = ptStart;
AcGePoint3d ptEndArc = ptEnd;
//计算出中心线弧线段的起点、中点和终点
//GetPtOnArc(ptStartArc, ptOnArc, ptEndArc, dPlusEdge);
GetPtOnArcExt(ptStartArc, ptCorStart, ptEndArc, ptCorEnd, ptOnArc, dPlusEdge);
//构建中心圆弧并求得圆心
AcGeCircArc3d cirArc(ptStartArc, ptOnArc, ptEndArc);
AcGePoint3d ptCen = cirArc.center();
//计算弯头平面矢量和弧线平面矢量
AcGeVector3d vtStart = ptStart - ptCorStart;
AcGeVector3d vtEnd = ptEnd - ptCorEnd;
AcGeVector3d vtNormal = vtStart.crossProduct(vtEnd);
vtStart.normalize();
vtEnd.normalize();
vtNormal.normalize();
AcGeVector3d vtStartArc = ptStartArc - ptCen;
AcGeVector3d vtEndArc = ptEndArc - ptCen;
AcGeVector3d vtNormalArc = vtEndArc.crossProduct(vtStartArc);
vtStartArc.normalize();
vtEndArc.normalize();
vtNormalArc.normalize();
//求得弯头头部和尾部的径向向量
vtStart.rotateBy(-PI / 2, vtNormal);
vtStart.normalize();
vtEnd.rotateBy(PI / 2, vtNormal);
vtEnd.normalize();
//生成中部拐点
AcGePoint3d ptCorU = ptCorner + vtNormal * (dThickA + dThickB) / 4 + vtStart * dStaWidth / 2 + vtEnd * dEndWidth / 2;
AcGePoint3d ptCorD = ptCorner - vtNormal * (dThickA + dThickB) / 4 + vtStart * dStaWidth / 2 + vtEnd * dEndWidth / 2;
//关键节点数组
AcGePoint3dArray arptKeys;
AcGePoint3d ptTemp[5];
//生成弯头头部
ptTemp[0] = ptStart + vtNormal * dThickA / 2 + vtStart * dStaWidth / 2;
ptTemp[1] = ptStart - vtNormal * dThickA / 2 + vtStart * dStaWidth / 2;
ptTemp[2] = ptStart - vtNormal * dThickA / 2 - vtStart * dStaWidth / 2;
ptTemp[3] = ptStart + vtNormal * dThickA / 2 - vtStart * dStaWidth / 2;
ptTemp[4] = ptStart + vtNormal * dThickA / 2 + vtStart * dStaWidth / 2;
for(int i = 0; i < 5; i++)
{
arptKeys.append(ptTemp[i]);
}
ptTemp[0] = ptStartArc + vtNormal * dThickA / 2 + vtStart * dStaWidth / 2;
ptTemp[1] = ptStartArc - vtNormal * dThickA / 2 + vtStart * dStaWidth / 2;
ptTemp[2] = ptStartArc - vtNormal * dThickA / 2 - vtStart * dStaWidth / 2;
ptTemp[3] = ptStartArc + vtNormal * dThickA / 2 - vtStart * dStaWidth / 2;
ptTemp[4] = ptStartArc + vtNormal * dThickA / 2 + vtStart * dStaWidth / 2;
for(int j = 0; j < 5; j++)
{
arptKeys.append(ptTemp[j]);
}
//生成弯头中部
ptTemp[0] = ptCorU;
ptTemp[1] = ptCorD;
ptTemp[4] = ptCorU;
for(int u = 0; u < 5; u++)
{
arptKeys.append(ptTemp[u]);
}
ptTemp[2] = ptEndArc - vtNormal * dThickB / 2 - vtEnd * dEndWidth / 2;
ptTemp[3] = ptEndArc + vtNormal * dThickB / 2 - vtEnd * dEndWidth / 2;
for(int d = 0; d < 5; d++)
{
arptKeys.append(ptTemp[d]);
}
//生成弯头尾部
ptTemp[0] = ptEndArc + vtNormal * dThickB / 2 + vtEnd * dEndWidth / 2;
ptTemp[1] = ptEndArc - vtNormal * dThickB / 2 + vtEnd * dEndWidth / 2;
ptTemp[2] = ptEndArc - vtNormal * dThickB / 2 - vtEnd * dEndWidth / 2;
ptTemp[3] = ptEndArc + vtNormal * dThickB / 2 - vtEnd * dEndWidth / 2;
ptTemp[4] = ptEndArc + vtNormal * dThickB / 2 + vtEnd * dEndWidth / 2;
for(int k = 0; k < 5; k++)
{
arptKeys.append(ptTemp[k]);
}
ptTemp[0] = ptEnd + vtNormal * dThickB / 2 + vtEnd * dEndWidth / 2;
ptTemp[1] = ptEnd - vtNormal * dThickB / 2 + vtEnd * dEndWidth / 2;
ptTemp[2] = ptEnd - vtNormal * dThickB / 2 - vtEnd * dEndWidth / 2;
ptTemp[3] = ptEnd + vtNormal * dThickB / 2 - vtEnd * dEndWidth / 2;
ptTemp[4] = ptEnd + vtNormal * dThickB / 2 + vtEnd * dEndWidth / 2;
for(int l = 0; l < 5; l++)
{
arptKeys.append(ptTemp[l]);
}
//添加关键节点并绘图
DrawMesh(mode,6, 5, arptKeys.asArrayPtr());
//====================================================================================
}
BOOL ImpHvacElbow::MakeIncline2DCurves(AecComplexCurve& cplCurve,int &nType) const
{
ASSERT(NULL != m_pXDataMap);
double dThick = MayAsMUnit(100.0),dDiameter = MayAsMUnit(300),dStartWidth = MayAsMUnit(300),dEndWidth = MayAsMUnit(100),dPlusEdge = MayAsMUnit(50.0);
AcDbObjectId idLayer;
int nBaseLine = 1;
int nSingleLine = 0;
AcGePoint3d ptStart, ptCorner, ptEnd;
m_pXDataMap->GetAt(HELB_Diameter, dDiameter);
m_pXDataMap->GetAt(HELB_Thick, dThick);
m_pXDataMap->GetAt(HELB_StartWidth, dStartWidth);
m_pXDataMap->GetAt(HELB_EndWidth, dEndWidth);
//m_pXDataMap->GetAt(HVAC_PlusEdge,dPlusEdge);
m_pXDataMap->GetAt(HELB_StartPoint,ptStart);
m_pXDataMap->GetAt(HELB_CornerPoint,ptCorner);
m_pXDataMap->GetAt(HELB_EndPoint,ptEnd);
m_pXDataMap->GetAt(HVAC_HasBaseLine,nBaseLine);
m_pXDataMap->GetAt(HVAC_IsSingleLine,nSingleLine);
double dEndThick = dThick;
m_pXDataMap->GetAt(HELB_EndThick, dEndThick);
if (IsHorzAlignment())
{
ptCorner.z = ptEnd.z = ptStart.z;
double dMaxWidth = dStartWidth > dEndWidth ? dStartWidth : dEndWidth;
if ((ptStart.distanceTo(ptCorner) - 50.0) - dMaxWidth / 2 < -1e-6)
{
dPlusEdge = 0.1;
}
dStartWidth *= 0.5;
dEndWidth *= 0.5;
dThick *= 0.5;
dEndThick *= 0.5;
return GetInclineCplCurveHor(cplCurve,nType,ptStart,ptCorner,ptEnd,dPlusEdge,dStartWidth,dEndWidth);
}
else if(IsVertAlignment())
{
dStartWidth *= 0.5;
dEndWidth *= 0.5;
dThick *= 0.5;
dEndThick *= 0.5;
//return GetAllArcuateCplCurveVerRec(cplCurve,nType,ptStart,ptCorner,ptEnd,dPlusEdge,dStartWidth,dEndWidth,dThick);
return GetAllArcuateCplCurveVerRec(cplCurve, nType, ptStart, ptCorner, ptEnd, dPlusEdge, dStartWidth, dEndWidth, dThick, dEndThick);
}
return FALSE;
}
void ImpHvacElbow::DrawInclineWrap3d(AcGiDraw &mode) const
{
ASSERT(NULL != m_pXDataMap);
DrawIncline3d(mode);
}
BOOL ImpHvacElbow::MakeInclineWrap2DCurves(AecComplexCurve& cplCurve,int &nType) const
{
ASSERT(NULL != m_pXDataMap);
MakeIncline2DCurves(cplCurve,nType);
return cplCurve.length() > 0;
}
void ImpHvacElbow::DrawInclineBoard3d(AcGiDraw &mode) const
{
ASSERT(NULL != m_pXDataMap);
DrawIncline3d(mode);
}
BOOL ImpHvacElbow::MakeInclineBoard2DCurves(AecComplexCurve& cplCurve,int &nType) const
{
ASSERT(NULL != m_pXDataMap);
return MakeIncline2DCurves(cplCurve,nType);
}
void ImpHvacElbow::DrawInclineLead3d(AcGiDraw &mode) const
{
ASSERT(NULL != m_pXDataMap);
DrawIncline3d(mode);
}
BOOL ImpHvacElbow::MakeInclineLead2DCurves(AecComplexCurve& cplCurve,int &nType) const
{
ASSERT(NULL != m_pXDataMap);
MakeIncline2DCurves(cplCurve,nType);
return cplCurve.length() > 0;
}
void ImpHvacElbow::DrawArcuate3d(AcGiDraw &mode) const
{
ASSERT(NULL != m_pXDataMap);
double dDiameter = MayAsMUnit(300.0);
double dPlusEdge = MayAsMUnit(50.0);
double dThickA = MayAsMUnit(50.0);
double dThickB = MayAsMUnit(50.0);
AcGePoint3d ptCorStart;
AcGePoint3d ptCorEnd;
double dStaWidth = MayAsMUnit(150.0);
double dEndWidth = MayAsMUnit(150.0);
AcGePoint3d ptStart, ptCorner, ptEnd;
AcDbObjectId idLayer;
int nBaseLine;
m_pXDataMap->GetAt(HELB_Thick, dThickA);
if (!m_pXDataMap->GetAt(HELB_EndThick, dThickB))
{
dThickB = dThickA;
}
m_pXDataMap->GetAt(HELB_StartWidth,dStaWidth);
m_pXDataMap->GetAt(HELB_EndWidth,dEndWidth);
//m_pXDataMap->GetAt(HVAC_PlusEdge,dPlusEdge);
m_pXDataMap->GetAt(HELB_StartPoint,ptStart);
m_pXDataMap->GetAt(HELB_CornerPoint,ptCorStart);
if (!m_pXDataMap->GetAt(HELB_AssisCornerPoint, ptCorEnd))
{
ptCorEnd = ptCorStart;
}
double dMaxWidth = dStaWidth > dEndWidth ? dStaWidth : dEndWidth;
if ((ptStart.distanceTo(ptCorStart) - MayAsMUnit(50.0) ) - dMaxWidth / 2 < -1e-6)
{
dPlusEdge = 0.1;
}
m_pXDataMap->GetAt(HELB_EndPoint,ptEnd);
m_pXDataMap->GetAt(HVAC_HasBaseLine,nBaseLine);
AecHvac::HvacElbowType eElbowType = AecHvac::eArcuate;
m_pXDataMap->GetAt(HELB_Type, (int&)eElbowType);
//内圆弧弯头弯曲角度为90度
const double dAngle = PI / 2;
double dMinDiffAng = GetMinDiffAngle();
int nRows = (int)(PI * 2 / dMinDiffAng);
//生成拐点
AcGeVector3d vtCorStartCom = ptCorStart.asVector();
AcGeVector3d vtCorEndCom = ptCorEnd.asVector();
AcGeVector3d vtCornerCom = (vtCorStartCom + vtCorEndCom) / 2;
ptCorner = AcGePoint3d::kOrigin + vtCornerCom;
AcGePoint3d ptOnArc = ptCorner;
AcGePoint3d ptStartArc = ptStart;
AcGePoint3d ptEndArc = ptEnd;
//计算出中心线弧线段的起点、中点和终点
//GetPtOnArc(ptStartArc, ptOnArc, ptEndArc, dPlusEdge);
GetPtOnArcExt(ptStartArc, ptCorStart, ptEndArc, ptCorEnd, ptOnArc, dPlusEdge);
//构建中心圆弧并求得圆心
AcGeCircArc3d cirArc(ptStartArc, ptOnArc, ptEndArc);
AcGePoint3d ptCen = cirArc.center();
//计算弯头平面矢量和弧线平面矢量
AcGeVector3d vtStart = ptStart - ptCorStart;
AcGeVector3d vtEnd = ptEnd - ptCorEnd;
AcGeVector3d vtNormal = vtStart.crossProduct(vtEnd);
vtStart.normalize();
vtEnd.normalize();
vtNormal.normalize();
AcGeVector3d vtStartArc = ptStartArc - ptCen;
AcGeVector3d vtEndArc = ptEndArc - ptCen;
AcGeVector3d vtNormalArc = vtEndArc.crossProduct(vtStartArc);
vtStartArc.normalize();
vtEndArc.normalize();
vtNormalArc.normalize();
vtStart.rotateBy(-PI / 2, vtNormal);
vtStart.normalize();
vtEnd.rotateBy(PI / 2, vtNormal);
vtEnd.normalize();
//生成中部拐点
AcGePoint3d ptCorU = ptCorner + vtNormal * (dThickA + dThickB) / 4 + vtStart * dStaWidth / 2 + vtEnd * dEndWidth / 2;
AcGePoint3d ptCorD = ptCorner - vtNormal * (dThickA + dThickB) / 4 + vtStart * dStaWidth / 2 + vtEnd * dEndWidth / 2;
//构建弧线段
AcGeVector3d vtCor = ptOnArc - ptCen;
vtCor.normalize();
//计算边线圆弧起点、圆上点、终点、圆心和平面法向量
AcGePoint3d ptStartArcU = ptStartArc + vtNormal * dThickA / 2 - vtStart * dStaWidth / 2;
AcGePoint3d ptStartArcD = ptStartArc - vtNormal * dThickA / 2 - vtStart * dStaWidth / 2;
AcGePoint3d ptEndArcU = ptEndArc + vtNormal * dThickB / 2 - vtEnd * dEndWidth / 2;
AcGePoint3d ptEndArcD = ptEndArc - vtNormal * dThickB / 2 - vtEnd * dEndWidth / 2;
AcGePoint3d ptOnArcU = ptOnArc + vtNormal * (dThickA + dThickB) / 4 - vtCor * (dStaWidth + dEndWidth) / 4;
AcGePoint3d ptOnArcD = ptOnArc - vtNormal * (dThickA + dThickB) / 4 - vtCor * (dStaWidth + dEndWidth) / 4;
AcGeCircArc3d cirU(ptStartArcU, ptOnArcU, ptEndArcU);
AcGePoint3d ptCenU = cirU.center();
AcGeVector3d vtNormalU = cirU.normal();
AcGeCircArc3d cirD(ptStartArcD, ptOnArcD, ptEndArcD);
AcGePoint3d ptCenD = cirD.center();
AcGeVector3d vtNormalD = cirD.normal();
//关键节点数组
AcGePoint3dArray arptKeys;
AcGePoint3d ptTemp[5];
//生成弯头头部
ptTemp[0] = ptStart + vtNormal * dThickA / 2 + vtStart * dStaWidth / 2;
ptTemp[1] = ptStart - vtNormal * dThickA / 2 + vtStart * dStaWidth / 2;
ptTemp[2] = ptStart - vtNormal * dThickA / 2 - vtStart * dStaWidth / 2;
ptTemp[3] = ptStart + vtNormal * dThickA / 2 - vtStart * dStaWidth / 2;
ptTemp[4] = ptStart + vtNormal * dThickA / 2 + vtStart * dStaWidth / 2;
for(int i = 0; i < 5; i++)
{
arptKeys.append(ptTemp[i]);
}
ptTemp[0] = ptStartArc + vtNormal * dThickA / 2 + vtStart * dStaWidth / 2;
ptTemp[1] = ptStartArc - vtNormal * dThickA / 2 + vtStart * dStaWidth / 2;
ptTemp[2] = ptStartArc - vtNormal * dThickA / 2 - vtStart * dStaWidth / 2;
ptTemp[3] = ptStartArc + vtNormal * dThickA / 2 - vtStart * dStaWidth / 2;
ptTemp[4] = ptStartArc + vtNormal * dThickA / 2 + vtStart * dStaWidth / 2;
for(int j = 0; j < 5; j++)
{
arptKeys.append(ptTemp[j]);
}
//生成弯头中部
for(int m = 1; m < nRows; m++)
{
AcGePoint3d ptBufU = ptStartArcU;
AcGePoint3d ptBufD = ptStartArcD;
arptKeys.append(ptCorU);
arptKeys.append(ptCorD);
AcGeVector3d vtHead = ptEndArcD - ptCenD;
AcGeVector3d vtTail = ptStartArcD - ptCenD;
double dAngleFlag = vtTail.angleTo(vtHead, vtNormalD);
BOOL bBreak = (dMinDiffAng * m > dAngleFlag) || (fabs(dMinDiffAng * m / dAngleFlag - 1) < 1e-10);
arptKeys.append(bBreak ? ptEndArcD : ptBufD.rotateBy(dMinDiffAng * m, vtNormalD, ptCenD));
vtHead = ptEndArcU - ptCenU;
vtTail = ptStartArcU - ptCenU;
dAngleFlag = vtTail.angleTo(vtHead, vtNormalU);
bBreak = (dMinDiffAng * m > dAngleFlag) || (fabs(dMinDiffAng * m /dAngleFlag - 1) < 1e-10);
arptKeys.append(bBreak ? ptEndArcU : ptBufU.rotateBy(dMinDiffAng * m, vtNormalU, ptCenU));
arptKeys.append(ptCorU);
}
//生成弯头尾部
ptTemp[0] = ptEndArc + vtNormal * dThickB / 2 + vtEnd * dEndWidth / 2;
ptTemp[1] = ptEndArc - vtNormal * dThickB / 2 + vtEnd * dEndWidth / 2;
ptTemp[2] = ptEndArc - vtNormal * dThickB / 2 - vtEnd * dEndWidth / 2;
ptTemp[3] = ptEndArc + vtNormal * dThickB / 2 - vtEnd * dEndWidth / 2;
ptTemp[4] = ptEndArc + vtNormal * dThickB / 2 + vtEnd * dEndWidth / 2;
for(int k = 0; k < 5; k++)
{
arptKeys.append(ptTemp[k]);
}
ptTemp[0] = ptEnd + vtNormal * dThickB / 2 + vtEnd * dEndWidth / 2;
ptTemp[1] = ptEnd - vtNormal * dThickB / 2 + vtEnd * dEndWidth / 2;
ptTemp[2] = ptEnd - vtNormal * dThickB / 2 - vtEnd * dEndWidth / 2;
ptTemp[3] = ptEnd + vtNormal * dThickB / 2 - vtEnd * dEndWidth / 2;
ptTemp[4] = ptEnd + vtNormal * dThickB / 2 + vtEnd * dEndWidth / 2;
for(int l = 0; l < 5; l++)
{
arptKeys.append(ptTemp[l]);
}
DrawMesh(mode,nRows + 3, 5, arptKeys.asArrayPtr());
//===========================================================================================
}
BOOL ImpHvacElbow::MakeArcuate2DCurves(AecComplexCurve& cplCurve,int &nType) const
{
ASSERT(NULL != m_pXDataMap);
double dThick = MayAsMUnit(100.0),dDiameter = MayAsMUnit(300),dStartWidth = MayAsMUnit(300),dEndWidth = MayAsMUnit(100),dPlusEdge = MayAsMUnit(50.0);
AcDbObjectId idLayer;
int nBaseLine = 1;
int nSingleLine = 0;
AcGePoint3d ptStart, ptCorner, ptEnd;
m_pXDataMap->GetAt(HELB_Diameter, dDiameter);
m_pXDataMap->GetAt(HELB_Thick, dThick);
m_pXDataMap->GetAt(HELB_StartWidth, dStartWidth);
m_pXDataMap->GetAt(HELB_EndWidth, dEndWidth);
m_pXDataMap->GetAt(HELB_StartPoint,ptStart);
m_pXDataMap->GetAt(HELB_CornerPoint,ptCorner);
m_pXDataMap->GetAt(HELB_EndPoint,ptEnd);
m_pXDataMap->GetAt(HVAC_HasBaseLine,nBaseLine);
m_pXDataMap->GetAt(HVAC_IsSingleLine,nSingleLine);
double dEndThick =dThick;
m_pXDataMap->GetAt(HELB_EndThick, dEndThick);
if (IsHorzAlignment())
{
ptCorner.z = ptEnd.z = ptStart.z;
double dMaxWidth = dStartWidth > dEndWidth ? dStartWidth : dEndWidth;
if ((ptStart.distanceTo(ptCorner) - MayAsMUnit(50.0)) - dMaxWidth / 2 < -1e-6)
{
dPlusEdge = 0.1;
}
dStartWidth *= 0.5;
dEndWidth *= 0.5;
dThick *= 0.5;
dEndThick *= 0.5;
return GetArcuateCplCurveHor(cplCurve,nType,ptStart,ptCorner,ptEnd,dPlusEdge,dStartWidth,dEndWidth);
}
else if(IsVertAlignment())
{
dStartWidth *= 0.5;
dEndWidth *= 0.5;
dThick *= 0.5;
dEndThick *= 0.5;
return GetAllArcuateCplCurveVerRec(cplCurve, nType, ptStart, ptCorner, ptEnd, dPlusEdge, dStartWidth, dEndWidth, dThick, dEndThick);
}
return FALSE;
}
void ImpHvacElbow::DrawArcuateWrap3d(AcGiDraw &mode) const
{
ASSERT(NULL != m_pXDataMap);
DrawArcuate3d(mode);
}
BOOL ImpHvacElbow::MakeArcuateWrap2DCurves(AecComplexCurve& cplCurve,int &nType) const
{
ASSERT(NULL != m_pXDataMap);
return MakeArcuate2DCurves(cplCurve, nType);
}
void ImpHvacElbow::DrawArcuateBoard3d(AcGiDraw &mode) const
{
ASSERT(NULL != m_pXDataMap);
DrawArcuate3d(mode);
}
BOOL ImpHvacElbow::MakeArcuateBoard2DCurves(AecComplexCurve& cplCurve,int &nType) const
{
ASSERT(NULL != m_pXDataMap);
return MakeArcuate2DCurves(cplCurve, nType);
}
void ImpHvacElbow::DrawArcuateSieve3d(AcGiDraw &mode) const
{
ASSERT(NULL != m_pXDataMap);
DrawArcuate3d(mode);
}
BOOL ImpHvacElbow::MakeArcuateSieve2DCurves(AecComplexCurve& cplCurve,int &nType) const
{
ASSERT(NULL != m_pXDataMap);
return MakeArcuate2DCurves(cplCurve, nType);
}
void ImpHvacElbow::DrawArcuateLead3d(AcGiDraw &mode) const
{
ASSERT(NULL != m_pXDataMap);
DrawArcuate3d(mode);
}
BOOL ImpHvacElbow::MakeArcuateLead2DCurves(AecComplexCurve& cplCurve,int &nType) const
{
ASSERT(NULL != m_pXDataMap);
return MakeArcuate2DCurves(cplCurve, nType);
}
void ImpHvacElbow::DrawAllOrtho3d(AcGiDraw &mode) const
{
ASSERT(NULL != m_pXDataMap);
double dDiameter = MayAsMUnit(300.0);
double dPlusEdge = MayAsMUnit(50);
double dThickA = MayAsMUnit(50.0);
double dThickB = MayAsMUnit(50.0);
AcGePoint3d ptCorStart;
AcGePoint3d ptCorEnd;
double dStaWidth = MayAsMUnit(150.0);
double dEndWidth = MayAsMUnit(150.0);
AcGePoint3d ptStart, ptCorner, ptEnd;
AcDbObjectId idLayer;
int nBaseLine;
m_pXDataMap->GetAt(HELB_Thick,dThickA);
if (!m_pXDataMap->GetAt(HELB_EndThick, dThickB))
{
dThickB = dThickA;
}
m_pXDataMap->GetAt(HELB_StartWidth,dStaWidth);
m_pXDataMap->GetAt(HELB_EndWidth,dEndWidth);
//m_pXDataMap->GetAt(HVAC_PlusEdge,dPlusEdge);
m_pXDataMap->GetAt(HELB_StartPoint,ptStart);
m_pXDataMap->GetAt(HELB_CornerPoint,ptCorStart);
if(!m_pXDataMap->GetAt(HELB_AssisCornerPoint, ptCorEnd))
{
ptCorEnd = ptCorStart;
}
double dMaxWidth = dStaWidth > dEndWidth ? dStaWidth : dEndWidth;
if ((ptStart.distanceTo(ptCorStart) - dPlusEdge) - dMaxWidth / 2 < -1e-6)
{
dPlusEdge = 0.1;
}
m_pXDataMap->GetAt(HELB_EndPoint,ptEnd);
m_pXDataMap->GetAt(HVAC_HasBaseLine,nBaseLine);
AecHvac::HvacElbowType eElbowType = AecHvac::eIncline;
m_pXDataMap->GetAt(HELB_Type, (int&)eElbowType);
//双直角弯头弯曲角度固定为90度
const double dAngle = PI / 2;
AcGeVector3d vtCorStartCom = ptCorStart.asVector();
AcGeVector3d vtCorEndCom = ptCorEnd.asVector();
AcGeVector3d vtCornerCom = (vtCorStartCom + vtCorEndCom) / 2;
ptCorner = AcGePoint3d::kOrigin + vtCornerCom;
AcGePoint3d ptOnArc = ptCorner;
AcGePoint3d ptStartArc = ptStart;
AcGePoint3d ptEndArc = ptEnd;
//计算出中心线弧线段的起点、中点和终点
//GetPtOnArc(ptStartArc, ptOnArc, ptEndArc, dPlusEdge);
GetPtOnArcExt(ptStartArc, ptCorStart, ptEndArc, ptCorEnd, ptOnArc, dPlusEdge);
//构建中心圆弧并求得圆心
AcGeCircArc3d cirArc(ptStartArc, ptOnArc, ptEndArc);
AcGePoint3d ptCen = cirArc.center();
//计算弯头平面矢量和弧线平面矢量
AcGeVector3d vtStart = ptStart - ptCorStart;
AcGeVector3d vtEnd = ptEnd - ptCorEnd;
AcGeVector3d vtNormal = vtStart.crossProduct(vtEnd);
vtStart.normalize();
vtEnd.normalize();
vtNormal.normalize();
AcGeVector3d vtStartArc = ptStartArc - ptCen;
AcGeVector3d vtEndArc = ptEndArc - ptCen;
AcGeVector3d vtNormalArc = vtEndArc.crossProduct(vtStartArc);
vtStartArc.normalize();
vtEndArc.normalize();
vtNormalArc.normalize();
vtStart.rotateBy(-PI / 2, vtNormal);
vtStart.normalize();
vtEnd.rotateBy(PI / 2, vtNormal);
vtEnd.normalize();
//计算中部四个拐点
AcGePoint3d ptCorU = ptCorner + vtNormal * (dThickA + dThickB) / 4 + vtStart * dStaWidth / 2 + vtEnd * dEndWidth / 2;
AcGePoint3d ptCorD = ptCorner - vtNormal * (dThickA + dThickB) / 4 + vtStart * dStaWidth / 2 + vtEnd * dEndWidth / 2;
AcGePoint3d ptCorUL = ptCorner + vtNormal * (dThickA + dThickB) / 4 - vtStart * dStaWidth / 2 - vtEnd * dEndWidth / 2;
AcGePoint3d ptCorDL = ptCorner - vtNormal * (dThickA + dThickB) / 4 - vtStart * dStaWidth / 2 - vtEnd * dEndWidth / 2;
//关键节点数组
AcGePoint3dArray arptKeys;
AcGePoint3d ptTemp[5];
//生成弯头头部
ptTemp[0] = ptStart + vtNormal * dThickA / 2 + vtStart * dStaWidth / 2;
ptTemp[1] = ptStart - vtNormal * dThickA / 2 + vtStart * dStaWidth / 2;
ptTemp[2] = ptStart - vtNormal * dThickA / 2 - vtStart * dStaWidth / 2;
ptTemp[3] = ptStart + vtNormal * dThickA / 2 - vtStart * dStaWidth / 2;
ptTemp[4] = ptStart + vtNormal * dThickA / 2 + vtStart * dStaWidth / 2;
for(int i = 0; i < 5; i++)
{
arptKeys.append(ptTemp[i]);
}
ptTemp[0] = ptStartArc + vtNormal * dThickA / 2 + vtStart * dStaWidth / 2;
ptTemp[1] = ptStartArc - vtNormal * dThickA / 2 + vtStart * dStaWidth / 2;
ptTemp[2] = ptStartArc - vtNormal * dThickA / 2 - vtStart * dStaWidth / 2;
ptTemp[3] = ptStartArc + vtNormal * dThickA / 2 - vtStart * dStaWidth / 2;
ptTemp[4] = ptStartArc + vtNormal * dThickA / 2 + vtStart * dStaWidth / 2;
for(int j = 0; j < 5; j++)
{
arptKeys.append(ptTemp[j]);
}
//生成弯头中部
ptTemp[0] = ptCorU;
ptTemp[1] = ptCorD;
ptTemp[2] = ptCorDL;
ptTemp[3] = ptCorUL;
ptTemp[4] = ptCorU;
for(int u = 0; u < 5; u++)
{
arptKeys.append(ptTemp[u]);
}
//生成弯头尾部
ptTemp[0] = ptEndArc + vtNormal * dThickB / 2 + vtEnd * dEndWidth / 2;
ptTemp[1] = ptEndArc - vtNormal * dThickB / 2 + vtEnd * dEndWidth / 2;
ptTemp[2] = ptEndArc - vtNormal * dThickB / 2 - vtEnd * dEndWidth / 2;
ptTemp[3] = ptEndArc + vtNormal * dThickB / 2 - vtEnd * dEndWidth / 2;
ptTemp[4] = ptEndArc + vtNormal * dThickB / 2 + vtEnd * dEndWidth / 2;
for(int k = 0; k < 5; k++)
{
arptKeys.append(ptTemp[k]);
}
ptTemp[0] = ptEnd + vtNormal * dThickB / 2 + vtEnd * dEndWidth / 2;
ptTemp[1] = ptEnd - vtNormal * dThickB / 2 + vtEnd * dEndWidth / 2;
ptTemp[2] = ptEnd - vtNormal * dThickB / 2 - vtEnd * dEndWidth / 2;
ptTemp[3] = ptEnd + vtNormal * dThickB / 2 - vtEnd * dEndWidth / 2;
ptTemp[4] = ptEnd + vtNormal * dThickB / 2 + vtEnd * dEndWidth / 2;
for(int l = 0; l < 5; l++)
{
arptKeys.append(ptTemp[l]);
}
DrawMesh(mode,5, 5, arptKeys.asArrayPtr());
}
BOOL ImpHvacElbow::MakeAllOrtho2DCurves(AecComplexCurve& cplCurve,int &nType) const
{
ASSERT(NULL != m_pXDataMap);
double dThick = MayAsMUnit(100.0),dDiameter = MayAsMUnit(300),dStartWidth = (300),dEndWidth = MayAsMUnit(100),dPlusEdge = MayAsMUnit(50.0);
AcDbObjectId idLayer;
int nBaseLine = 1;
int nSingleLine = 0;
AcGePoint3d ptStart, ptCorner, ptEnd;
m_pXDataMap->GetAt(HELB_Diameter, dDiameter);
m_pXDataMap->GetAt(HELB_Thick, dThick);
m_pXDataMap->GetAt(HELB_StartWidth, dStartWidth);
m_pXDataMap->GetAt(HELB_EndWidth, dEndWidth);
m_pXDataMap->GetAt(HELB_StartPoint,ptStart);
m_pXDataMap->GetAt(HELB_CornerPoint,ptCorner);
m_pXDataMap->GetAt(HELB_EndPoint,ptEnd);
m_pXDataMap->GetAt(HVAC_HasBaseLine,nBaseLine);
m_pXDataMap->GetAt(HVAC_IsSingleLine,nSingleLine);
double dEndThick = dThick;
m_pXDataMap->GetAt(HELB_EndThick, dEndThick);
if (IsHorzAlignment())
{
ptCorner.z = ptEnd.z = ptStart.z;
double dMaxWidth = dStartWidth > dEndWidth ? dStartWidth : dEndWidth;
if ((ptStart.distanceTo(ptCorner) - dPlusEdge) - dMaxWidth / 2 < -1e-6)
{
dPlusEdge = 0.1;
}
dStartWidth *= 0.5;
dEndWidth *= 0.5;
dThick *= 0.5;
dEndThick *= 0.5;
return GetAllOrthoCplCurveHor(cplCurve,nType,ptStart,ptCorner,ptEnd,dPlusEdge,dStartWidth,dEndWidth);
}
else if(IsVertAlignment())
{
dStartWidth *= 0.5;
dEndWidth *= 0.5;
dThick *= 0.5;
dEndThick *= 0.5;
return GetAllArcuateCplCurveVerRec(cplCurve, nType, ptStart, ptCorner, ptEnd, dPlusEdge, dStartWidth, dEndWidth, dThick, dEndThick);
}
return FALSE;
}
void ImpHvacElbow::DrawOrthoWrap3d(AcGiDraw &mode) const
{
ASSERT(NULL != m_pXDataMap);
DrawAllOrtho3d(mode);
}
BOOL ImpHvacElbow::MakeOrthoWrap2DCurves(AecComplexCurve& cplCurve,int &nType) const
{
ASSERT(NULL != m_pXDataMap);
return MakeAllOrtho2DCurves(cplCurve,nType);
}
void ImpHvacElbow::DrawOrthoLead3d(AcGiDraw &mode) const
{
ASSERT(NULL != m_pXDataMap);
DrawAllOrtho3d(mode);
}
BOOL ImpHvacElbow::MakeOrthoLead2DCurves(AecComplexCurve& cplCurve,int &nType) const
{
ASSERT(NULL != m_pXDataMap);
return MakeAllOrtho2DCurves(cplCurve,nType);
}
BOOL ImpHvacElbow::GetIntersectWith(AcGePoint3d &pt1,AcGePoint3d &pt2,AcGeVector3d &vt1,AcGeVector3d &vt2,AcGePoint3d &ptIntersect) const
{
AcGeLine3d line1,line2;
line1.set(pt1,vt1);
line2.set(pt2,vt2);
return line1.intersectWith(line2, ptIntersect);
}
BOOL ImpHvacElbow::GetPtOnArc(AcGePoint3d &ptStart,AcGePoint3d &ptCorner,AcGePoint3d &ptEnd,double &dPlusEdge) const
{
AcGeVector3d vtStr,vtEnd,vtCor,vtNor;
AcGePoint3d ptGeCen;
AcGePoint3d ptCorStart = ptCorner;
ptCorStart.z = ptStart.z;
vtStr = ptStart - ptCorStart;
AcGePoint3d ptCorEnd = ptCorner;
ptCorEnd.z = ptEnd.z;
vtEnd = ptEnd - ptCorEnd;
vtStr.normalize();
vtEnd.normalize();
vtNor = vtStr.crossProduct(vtEnd);
ptStart = ptStart - vtStr * dPlusEdge;
ptEnd = ptEnd - vtEnd * dPlusEdge;
vtStr.rotateBy(PI * 0.5,vtNor);
vtEnd.rotateBy(PI * 0.5,vtNor);
//================================================================
AcGePoint3d ptStartTemp = ptStart;
ptStartTemp.z = ptCorner.z;
AcGePoint3d ptEndTemp = ptEnd;
ptEndTemp.z = ptCorner.z;
if(!GetIntersectWith(ptStartTemp,ptEndTemp,vtStr,vtEnd,ptGeCen))
return FALSE;
vtCor = ptCorner - ptGeCen;
vtCor.normalize();
ptCorner = ptGeCen + vtCor * (ptStart.distanceTo(ptGeCen));
return TRUE;
}
AcGeVector3d ImpHvacElbow::normal() const
{
ASSERT(NULL != m_pXDataMap);
AcGePoint3d ptStart,ptCorner,ptEnd;
AcGeVector3d vts,vte;
m_pXDataMap->GetAt(HELB_StartPoint, ptStart);
m_pXDataMap->GetAt(HELB_CornerPoint, ptCorner);
m_pXDataMap->GetAt(HELB_EndPoint, ptEnd);
vts = ptCorner - ptStart;
vte = ptCorner - ptEnd;
return vts.crossProduct(vte);
}
BOOL ImpHvacElbow::GetPtOnArcExt(AcGePoint3d &ptStartArc, const AcGePoint3d &ptCorStart, AcGePoint3d &ptEndArc, const AcGePoint3d &ptCorEnd, AcGePoint3d &ptOnArcOut, double &dPlusEdge) const
{
AcGeVector3d vtStr,vtEnd,vtCor,vtNor;
AcGeVector3d vtStartArc;
AcGeVector3d vtEndArc;
AcGePoint3d ptGeCen;
AcGePoint3d ptCorner;
AcGeVector3d vtCorStartCom = ptCorStart.asVector();
AcGeVector3d vtCorEndCom = ptCorEnd.asVector();
AcGeVector3d vtCornerCom = (vtCorStartCom + vtCorEndCom) / 2;
ptCorner = AcGePoint3d::kOrigin + vtCornerCom;
vtStr = ptStartArc - ptCorStart;
vtEnd = ptEndArc - ptCorEnd;
vtStr.normalize();
vtEnd.normalize();
ptStartArc = ptStartArc - vtStr * dPlusEdge;
ptEndArc = ptEndArc - vtEnd * dPlusEdge;
vtStartArc = ptStartArc - ptCorner;
vtEndArc = ptEndArc - ptCorner;
vtNor = vtStartArc.crossProduct(vtEndArc);
vtStartArc.rotateBy(PI * 0.5, vtNor);
vtEndArc.rotateBy(PI * 0.5, vtNor);
if(!GetIntersectWith(ptStartArc,ptEndArc,vtStartArc,vtEndArc,ptGeCen))
return FALSE;
vtCor = ptCorner - ptGeCen;
vtCor.normalize();
ptOnArcOut = ptGeCen + vtCor * (ptStartArc.distanceTo(ptGeCen));
return TRUE;
}
BOOL ImpHvacElbow::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;
}
void ImpHvacElbow::Move3DBuffer(AcDbVoidPtrArray& ar3DBuffer) const
{
if (!m_ar3DDrableBufPtrs_.isEmpty())
{
ar3DBuffer.append(m_ar3DDrableBufPtrs_);
m_ar3DDrableBufPtrs_.removeAll();
}
}
bool ImpHvacElbow::Has3DBuffer() const
{
return !m_ar3DDrableBufPtrs_.isEmpty();
}
bool ImpHvacElbow::GetInterface(AcArray<AecInterface>& arInfs) const
{
if (NULL == m_pXDataMap)
return false;
// 获取弯头各点位置
AcGePoint3d ptStart, ptCorner, ptEnd;
m_pXDataMap->GetAt(HELB_StartPoint, ptStart);
m_pXDataMap->GetAt(HELB_CornerPoint, ptCorner);
m_pXDataMap->GetAt(HELB_EndPoint, ptEnd);
// 求两端方向
AcGeVector3d vtStart, vtEnd;
vtStart = ptStart - ptCorner;
vtEnd = ptEnd - ptCorner;
AecInterface inf;
inf.ptPos = ptStart;
inf.vtDir = vtStart;
ESection eSectType = eRect;
m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType);
LPCTSTR pszWidthKey, pszThickKey;
pszWidthKey = ((eCircle == eSectType) ? HELB_Diameter : HELB_StartWidth);
pszThickKey = HELB_Thick;
double dWidth = 0.0, dThick = 0.0;
m_pXDataMap->GetAt(pszWidthKey, dWidth);
m_pXDataMap->GetAt(pszThickKey, dThick);
// 设置接口数据
inf.nType = eSectType;
inf.dSize1 = dWidth;
inf.dSize2 = dThick;
inf.idOwner = m_pOwnerEnt->objectId();
arInfs.append(inf);
pszWidthKey = ((eCircle == eSectType) ? HELB_EndDiameter : HELB_EndWidth);
pszThickKey = HELB_EndThick;
m_pXDataMap->GetAt(pszWidthKey, dWidth);
m_pXDataMap->GetAt(pszThickKey, dThick);
inf.dSize1 = dWidth;
inf.dSize2 = dThick;
inf.ptPos = ptEnd;
inf.vtDir = vtEnd;
arInfs.append(inf);
return true;
}
BOOL ImpHvacElbow::IsArcuate() const
{
ASSERT(NULL != m_pXDataMap);
// 弯头类型
AecHvac::HvacElbowType eElbowType = AecHvac::eAllArcuate;
m_pXDataMap->GetAt(HELB_Type, (int&)eElbowType);
switch (eElbowType)
{
case AecHvac::eAllArcuate: // 内外圆弧
case AecHvac::eAllArcWrap: // 内外圆弧消声
case AecHvac::eAllArcInWrap: // 消声弯头
case AecHvac::eSegmental: // 分段拟合
return TRUE;
case AecHvac::eArcuate: // 内弧线
case AecHvac::eArcuateWrap: // 内弧线消声
case AecHvac::eArcuateBoard: // 内弧线隔板消声
case AecHvac::eArcuateSieve: // 内弧线筛板消声
case AecHvac::eArcuateLead: // 内弧线导流
case AecHvac::eIncline: // 内斜线
case AecHvac::eInclineWrap: // 内斜线消声
case AecHvac::eInclineBoard: // 内斜线隔板消声
case AecHvac::eInclineLead: // 内斜线导流
case AecHvac::eAllOrtho: // 内外直角
case AecHvac::eOrthoWrap: // 内外直角消声
case AecHvac::eOrthoLead: // 内外直角导流
return FALSE;
}
return FALSE;
}
void ImpHvacElbow::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(HELB_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(HELB_StartWidth, dStartWidth);
m_pXDataMap->GetAt(HELB_EndWidth, dEndWidth);
m_pXDataMap->GetAt(HELB_Thick, dThick);
acutPrintf(_T("\n\t\t\t\t\t\t\t\t始端宽度:%.2f 末端宽度:%.2f 厚度:%.2f"), dStartWidth, dEndWidth, dThick);
}
// 起点
AcGePoint3d pt;
m_pXDataMap->GetAt(HELB_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(HELB_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);
}