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

2409 lines
63 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 "TAuxTools.h"
#include "math.h"
#include "TImpSpecFitting.h"
#include "TImpSpecEquipment.h"
using namespace std;
#define ZERO_AIR 1.0e-6
// 取得接口记录指针 外部使用
DLLIMPEXP TDbInterfaceRecord* GetInterfacePtr()
{
return TAuxTools::GetIntfPtrFromDB();
}
// 写入暖通动态扩展数据到图纸中
DLLIMPEXP void SetTHvacParamToDwg(LPCTSTR pszKey = NULL)
{
if(NULL == pszKey)
{
BOOL bShowCover = FALSE; // 显示遮挡
GetGlobalContext()->GetAt(KEY_HIDEDRAW, bShowCover);
TAuxTools::SetTHvacDataToDwg(KEY_HIDEDRAW, bShowCover);
double dHideWidth = 0; // 打断间隙
GetGlobalContext()->GetAt(HVAC_HIDEEXTENT, dHideWidth);
TAuxTools::SetTHvacDataToDwg(HVAC_HIDEEXTENT, dHideWidth);
BOOL bShowWidth = FALSE; // 是否加粗
GetGlobalContext()->GetAt(HVAC_SHOWWIDTH, bShowWidth);
TAuxTools::SetTHvacDataToDwg(HVAC_SHOWWIDTH, bShowWidth);
double dBrWidth = 0; // 水管风管打断间隙
GetGlobalContext()->GetAt(HVAC_PIPEHIDEWIDTH, dBrWidth);
TAuxTools::SetTHvacDataToDwg(HVAC_PIPEHIDEWIDTH, dBrWidth);
BOOL bPipeDuctBreak = FALSE; // 风管与水管打断
GetGlobalContext()->GetAt(HVAC_PIPEDUCTBREAK, bPipeDuctBreak);
TAuxTools::SetTHvacDataToDwg(HVAC_PIPEDUCTBREAK, bPipeDuctBreak);
}
else
{
if(0 == _tcscmp(pszKey, KEY_HIDEDRAW)
|| 0 == _tcscmp(pszKey, HVAC_SHOWWIDTH)
|| 0 == _tcscmp(pszKey, HVAC_PIPEDUCTBREAK))
{
BOOL bValue = FALSE;
if(GetGlobalContext()->GetAt(pszKey, bValue))
{
TAuxTools::SetTHvacDataToDwg(pszKey, bValue);
}
}
else if(0 == _tcscmp(pszKey, HVAC_HIDEEXTENT)
|| 0 == _tcscmp(pszKey, HVAC_PIPEHIDEWIDTH))
{
double dValue = 0;
if(GetGlobalContext()->GetAt(pszKey, dValue))
{
TAuxTools::SetTHvacDataToDwg(pszKey, dValue);
}
}
}
}
// 从图纸中读取暖通风管遮挡参数
DLLIMPEXP void GetTHvacParamFromDwg()
{
BOOL bShowCover = FALSE; // 显示遮挡
if(TAuxTools::GetTHvacDataFromDwg(KEY_HIDEDRAW, bShowCover))
{
GetGlobalContext()->SetAt(KEY_HIDEDRAW, bShowCover);
}
double dHideWidth = 0; // 打断间隙
if(TAuxTools::GetTHvacDataFromDwg(HVAC_HIDEEXTENT, dHideWidth))
{
// add by hh 2011-10-11 支持遮挡宽度随比例变化
if(10 < dHideWidth)
{
// 兼容旧版图纸,宽度大于10时,认为是旧版数据,转换为新版的
dHideWidth /= DocGetPScale();
TAuxTools::SetTHvacDataToDwg(HVAC_HIDEEXTENT, dHideWidth);
}
GetGlobalContext()->SetAt(HVAC_HIDEEXTENT, dHideWidth);
}
BOOL bShowWidth = FALSE; // 是否加粗
if(TAuxTools::GetTHvacDataFromDwg(HVAC_SHOWWIDTH, bShowWidth))
{
GetGlobalContext()->SetAt(HVAC_SHOWWIDTH, bShowWidth);
}
// add by hh 2011-01-05 兼容8.2版图纸
else
{
AcDbBlockTable* pBlockTable = NULL;
AcDbBlockTableRecord* pTableRecord = NULL;
if(acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable, AcDb::kForRead) != Acad::eOk)
return;
pBlockTable->close();
if(pBlockTable->getAt(ACDB_MODEL_SPACE, pTableRecord, AcDb::kForRead) != Acad::eOk)
return;
pTableRecord->close();
bShowWidth = (BOOL)_ttoi(TAuxTools::ReadXdata(pTableRecord->id(), HVAC_SHOWWIDTH));
GetGlobalContext()->SetAt(HVAC_SHOWWIDTH, bShowWidth);
// 将是否加粗标识写入动态扩展数据中 转换为8.5版图纸
//bsl 2011.10.26 增加暖通判断
// change by hh 2013-03-25 暖通标准版ID从6改成15
// if (g_nProductId == 6 || g_nProductId == 5)
if (g_nProductId == 15 || g_nProductId == 5)
TAuxTools::SetTHvacDataToDwg(HVAC_SHOWWIDTH, bShowWidth);
}
double dBrWidth = 0; // 水管风管打断间隙
if(TAuxTools::GetTHvacDataFromDwg(HVAC_PIPEHIDEWIDTH, dBrWidth))
{
GetGlobalContext()->SetAt(HVAC_PIPEHIDEWIDTH, dBrWidth);
}
BOOL bPipeDuctBreak = FALSE; // 风管与水管打断
if(TAuxTools::GetTHvacDataFromDwg(HVAC_PIPEDUCTBREAK, bPipeDuctBreak))
{
GetGlobalContext()->SetAt(HVAC_PIPEDUCTBREAK, bPipeDuctBreak);
}
}
AcGePoint3d TAuxTools::Mid(AcGePoint3d ptGe1, AcGePoint3d ptGe2)
{
return AcGePoint3d((ptGe1.x + ptGe2.x) / 2.0,(ptGe1.y + ptGe2.y) / 2.0,(ptGe1.z + ptGe2.z) / 2.0);
}
/*
两圆相交法求椭圆法点图
O2
D
|
|
A--O1--------O-----------B
|
F |
C
*/
// int TAuxTools::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);
//
// // 把向量投影到所给面上
// vtLong = vtLong.orthoProject(vtNewNormal);
// vtShort = vtShort.orthoProject(vtNewNormal);
//
// AcGePoint3d ptO = ptCenter.orthoProject(planStd); // 中心点
// AcGePoint3d ptA = ptO + dDia * 0.5 * vtLong; // A
// AcGePoint3d ptB = ptA - dDia * vtLong; // B
// AcGePoint3d ptC = ptO + dDia * 0.5 * vtShort; // C
// AcGePoint3d ptD = ptC - dDia * vtShort; // D
//
// double CF = dDia / 2 - ptC.distanceTo(ptD) / 2;
// AcGeVector3d vtCF = ptA - ptC;
// vtCF.normalize();
// AcGePoint3d ptF = ptC + CF * vtCF;
//
// AcGeLine3d lineAB(ptA, ptB);
// AcGeLine3d lineCD(ptC, ptD);
// AcGeLine3d lineAF(ptA, ptF);
//
// // 求线AF的中垂线
// AcGeVector3d vtAFPerl = ptF - ptA;
// vtAFPerl.rotateBy(PI * 0.5, vtNewNormal);
// AcGePoint3d ptAFMid = Mid(ptA, ptF);
// AcGeLine3d lineAFPerl(ptAFMid, ptAFMid + 100 * vtAFPerl);
//
// AcGePoint3d ptO1, ptO2; // 两个辅助圆圆心O1 O2
// lineAFPerl.intersectWith(lineAB, ptO1);
// lineAFPerl.intersectWith(lineCD, ptO2);
//
// double dRad1 = ptO1.distanceTo(ptA); // 两圆对应半径
// double dRad2 = ptO2.distanceTo(ptC);
//
// // 构造两个圆,求交点,为两弧邻接点
// AcGeCircArc3d cir1(ptO1, vtNewNormal, dRad1);
// AcGeCircArc3d cir2(ptO2, vtNewNormal, dRad2);
// AcGePoint3d ptCross, ptCross2;
// int nSucsId(0);
// cir1.intersectWith(cir2, nSucsId, ptCross, AcGePoint3d());
//
// if (nSucsId < 1)
// return -1;
//
// // 镜像后得到其他3个邻接点
// AcGePoint3d ptCrossLongMir(ptCross), ptCrossShortMir(ptCross), ptCrossInclinMir;
// AcGePlane planAB(ptO, ptC - ptD);
// AcGePlane planCD(ptO, ptA - ptB);
// ptCrossLongMir.mirror(planAB);
// ptCrossShortMir.mirror(planCD);
// ptCrossInclinMir = ptCrossShortMir;
// ptCrossInclinMir.mirror(planAB);
//
// // 求两种弧bulge值
// AcGePoint3d ptMidCorss1 = Mid(ptCross, ptCrossLongMir);
// AcGePoint3d ptMidCorss2 = Mid(ptCross, ptCrossShortMir);
// double dBulge1 = ptMidCorss1.distanceTo(ptA) / ptMidCorss1.distanceTo(ptCross);
// double dBulge2 = ptMidCorss2.distanceTo(ptC) / ptMidCorss2.distanceTo(ptCross);
//
// // 矫正Bulge正负值
// AcGeVector3d vtClockSta = ptCrossShortMir - ptCross;
// AcGeVector3d vtClockEnd = ptCrossLongMir - ptCross;
// AcGeVector3d vtClockPerl = vtClockSta.crossProduct(vtClockEnd);
// if (!vtClockPerl.isCodirectionalTo(vtNewNormal))
// {
// dBulge1 *= -1;
// dBulge2 *= -1;
// }
//
// if (vtGet.length() < 1e-6)
// {
// polyLine.addVertexAt(0, ptCross.convert2d(planStd), dBulge2);
// polyLine.addVertexAt(1, ptCrossShortMir.convert2d(planStd), dBulge1);
// polyLine.addVertexAt(2, ptCrossInclinMir.convert2d(planStd), dBulge2);
// polyLine.addVertexAt(3, ptCrossLongMir.convert2d(planStd), dBulge1);
// polyLine.setClosed(Adesk::kTrue);
// }
// else
// {
// vtGet = vtGet.orthoProject(vtNewNormal);
// if (vtGet.angleTo(vtShort) < PI*0.5) // C 端部分
// {
// polyLine.addVertexAt(0, ptA.convert2d(planStd), dBulge1*0.5);
// polyLine.addVertexAt(1, ptCross.convert2d(planStd), dBulge2);
// polyLine.addVertexAt(2, ptCrossShortMir.convert2d(planStd), dBulge1*0.5);
// polyLine.addVertexAt(3, ptB.convert2d(planStd));
// }
// else // D 端部分
// {
// polyLine.addVertexAt(0, ptB.convert2d(planStd), dBulge1*0.5);
// polyLine.addVertexAt(1, ptCrossInclinMir.convert2d(planStd), dBulge2);
// polyLine.addVertexAt(2, ptCrossLongMir.convert2d(planStd), dBulge1*0.5);
// polyLine.addVertexAt(3, ptA.convert2d(planStd));
// }
// }
// }
//
// polyLine.setElevation(dEle);
// polyLine.setNormal(vtNewNormal);
//
// return 2;
// }
int TAuxTools::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 TAuxTools::GetArcPoint(AcDbPolyline &polyLine, AcGePoint3dArray &ptArcArr)
{
// if (polyLine.numVerts() != 4)
// return;
//
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 TAuxTools::GetEllipsePtsFromCircle(AcGePoint3dArray& arPtsOnCurve, AcGePoint3d ptCenter, double dDia, AcGeVector3d vtOrigNormal,
AcGeVector3d vtNewNormal, AcDbPolyline &polyLine, AcGeVector3d vtGet/* = AcGeVector3d::kIdentity*/)
{
int iRes = TAuxTools::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:// 投影为椭圆
TAuxTools::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(TAuxTools::Mid(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;
}
BOOL TAuxTools::GetPrjPtsFromCircle(AcGePoint3dArray& ptArr, AcGePoint3dArray& arPtJudge)
{
XCircle cir;
AcGeVector3d vtTmp1, vtTmp2, vtCirNor;
AcGePoint3d ptCirCen, ptIn, ptU, ptD;
AcGePoint3dArray arPtSides;
AcGePlane plan;
int iRes(-1);
AcDbPolyline* pLine = new AcDbPolyline;
if (NULL == pLine)
return TRUE;
for (int i = 0; i < ptArr.length(); )
{
cir.Set(ptArr[i], ptArr[i+1], ptArr[i+2]);
ptCirCen = cir.m_ptCenter.AsAcGePoint3d();
vtTmp1 = ptArr[i+1] - ptCirCen;
vtTmp2 = ptArr[i+2] - ptCirCen;
// 分节圆法向
vtCirNor = vtTmp1.crossProduct(vtTmp2);
plan.set(ptCirCen, TAuxTools::GetUcsZvt());
iRes = TAuxTools::GetEllipseFromCircle(ptCirCen, cir.m_dRadius * 2, vtCirNor, TAuxTools::GetUcsZvt(), *pLine, vtCirNor);
if (-1 == iRes)
{
if (NULL != pLine)
delete pLine;
return FALSE;
}
pLine->getPointAt(0, ptU);
pLine->getPointAt(pLine->numVerts()-1, ptD);
plan.set(arPtJudge[i / 3], TAuxTools::GetUcsZvt());
ptU = ptU.orthoProject(plan);
ptD = ptD.orthoProject(plan);
if (ptD.distanceTo(arPtJudge[ i / 3]) <= ptU.distanceTo(arPtJudge[ i / 3]))
{
// 总是先添加距离ptArrCen[ i / 3]近的点
arPtSides.append(ptD);
arPtSides.append(ptU);
}
else
{
arPtSides.append(ptU);
arPtSides.append(ptD);
}
pLine->reset(Adesk::kFalse, iRes);
i = i+3;// 每3个点确定一个面
}
if (NULL == pLine)
delete pLine;
arPtJudge.setLogicalLength(0);
arPtJudge.append(arPtSides);
return TRUE;
}
BOOL TAuxTools::MergerPline(AcDbPolyline* pPl,AcDbPolyline* pSrc)
{
AcGePoint3d ptStart,ptStart2;
AcGePoint3d ptEnd,ptEnd2;
pPl->getStartPoint(ptStart);
pPl->getEndPoint(ptEnd);
pSrc->getStartPoint(ptStart2);
pSrc->getEndPoint(ptEnd2);
AcGePoint2d pt2d;
double dBulge = -1;
if (ptStart.distanceTo(ptStart2) < 1.e-3) //sta 重合
{
int nVerts = pSrc->numVerts();
for (int i = 1;i < nVerts; i++)
{
pSrc->getPointAt(i, pt2d);
pSrc->getBulgeAt(i - 1, dBulge);
pPl->addVertexAt(0, pt2d, -dBulge);
}
}
else if (ptStart.distanceTo(ptEnd2) < 1.e-3) //end
{
int nVerts = pSrc->numVerts() - 1;
for (int i = nVerts; i > 0; i--)
{
pSrc->getPointAt(i - 1, pt2d);
pSrc->getBulgeAt(i - 1, dBulge);
pPl->addVertexAt(0, pt2d, dBulge);
}
}
else if (ptEnd.distanceTo(ptStart2) < 1.e-3) //sta 重合
{
int nVerts = pPl->numVerts();
for (int i = 1; i < (int)pSrc->numVerts(); i++)
{
pSrc->getPointAt(i, pt2d);
pSrc->getBulgeAt(i - 1, dBulge);
if (1 == i)
{
pPl->setBulgeAt(nVerts - 1, dBulge);
}
pPl->addVertexAt(nVerts, pt2d, dBulge);
nVerts++;
}
}
else if (ptEnd.distanceTo(ptEnd2) < 1.e-3) //end
{
int nVerts = pPl->numVerts();
for (int i = pSrc->numVerts() - 1; i > -1; i--)
{
pSrc->getPointAt(i, pt2d);
pSrc->getBulgeAt(i - 1, dBulge);
pPl->addVertexAt(nVerts, pt2d, -dBulge);
nVerts++;
}
}
// Lixl处理两条PLine线不同高度的情况
else
{
ptStart2.z = ptStart.z;
ptEnd2.z = ptEnd.z;
int nVerts = pPl->numVerts();
int nPlVerts = nVerts - 1;
if (ptEnd.distanceTo(ptStart2) < 1.e-3)
{
for (int i = 0; i < (int)pSrc->numVerts(); i++)
{
pSrc->getPointAt(i, pt2d);
pSrc->getBulgeAt(i, dBulge);
pPl->addVertexAt(nVerts, pt2d, dBulge);
nVerts++;
}
pPl->setBulgeAt(nPlVerts, 0);
}
else if (ptEnd.distanceTo(ptEnd2) < 1.e-3)
{
for (int i = pSrc->numVerts()-1; i >= 0; i--)
{
pSrc->getPointAt(i, pt2d);
pSrc->getBulgeAt(i-1, dBulge);
if (0 == i)
dBulge = 0.0;
pPl->addVertexAt(nVerts, pt2d, -dBulge);
nVerts++;
}
pPl->setBulgeAt(nPlVerts, 0);
}
}
return TRUE;
}
int TAuxTools::PositionOnLine(AcGePoint3d ptSta, AcGePoint3d ptEnd, AcGePoint3d ptBase)
{
AcGeVector3d vt = ptSta - ptEnd;
vt.normalize();
double dBS = ptBase.distanceTo(ptSta);
double dBE = ptBase.distanceTo(ptEnd);
double dSE = ptEnd.distanceTo(ptSta);
//在两个点中间位置
if (((dBS + dBE) - dSE) < 1.e-3 )
{
return 0;
}
else
{
//在S端左侧
if (dBS < dBE)
{
return 1;
}
//在E端右侧
else
{
return 2;
}
}
return -1;
}
BOOL TAuxTools::isCodirectionalPt(AcGePoint3d ptSta, AcGePoint3d ptEnd, AcGeVector3d vtBase)
{
AcGeVector3d vt = ptSta - ptEnd;
return vt.isCodirectionalTo(vtBase);
}
AcGePlane TAuxTools::GetHidePlane(AcGePoint3d pt1, AcGePoint3d pt2, AcGePoint3d pt3,
AcGeVector3d vtNormal, double &dEle)
{
AcGePlane plan(pt1, pt2, pt3);
AcGePoint3d ptOrth = AcGePoint3d::kOrigin.orthoProject(plan);
plan.set(ptOrth, vtNormal);
dEle = ptOrth.asVector().length();
if (!ptOrth.asVector().isCodirectionalTo(vtNormal))
dEle *= -1.0;
return plan;
}
BOOL TAuxTools::InsertBlock(AcDbVoidPtrArray& entitySet,AcDbObjectId idBlock, AcGePoint3d ptBase, AcGeScale3d ScaleFactor,double dAngle)
{
AcDbBlockReference blcRfr;
blcRfr.setNormal(AcGeVector3d::kZAxis);
blcRfr.setBlockTableRecord(idBlock);
blcRfr.setPosition(ptBase);
blcRfr.setRotation(dAngle);
blcRfr.setScaleFactors(ScaleFactor);
blcRfr.explode(entitySet);
return TRUE;
}
BOOL TAuxTools::GetIntersectWith(AcGePoint3d pt1,AcGePoint3d pt2,AcGePoint3d pt3,AcGePoint3d pt4,AcGePoint3d& ptIntersect)
{
AcGeLine3d line1,line2;
line1.set(pt1,pt2);
line2.set(pt3,pt4);
return line1.intersectWith(line2, ptIntersect);
}
int TAuxTools::Getquadrant(AcGePoint3d ptCenter, AcGePoint3d pt, AcGeVector3d vtMain, AcGeVector3d vtNormal)
{
AcGeVector3d vtBr = pt - ptCenter;
double dAngle = vtMain.angleTo(vtBr, vtNormal);
if (dAngle >= PI * 0.5 && dAngle < PI)
{
return 2;
}
else if (dAngle >= PI && dAngle < PI * 1.5)
{
return 3;
}
else if (dAngle >= PI * 1.5 && dAngle < PI * 2 )
{
return 4;
}
return 1;
}
// 用户X坐标向量
AcGeVector3d TAuxTools::GetUcsXvt()
{
AcGeVector3d vtX = AcGeVector3d::kXAxis;
AcDbDatabase* pDb = acdbCurDwg();
if (NULL != pDb)
vtX = pDb->ucsxdir();
return vtX;
}
AcGeVector3d TAuxTools::GetUcsYvt()
{
AcGeVector3d vtY = AcGeVector3d::kYAxis;
AcDbDatabase* pDb = acdbCurDwg();
if (NULL != pDb)
vtY = pDb->ucsydir();
return vtY;
}
AcGeVector3d TAuxTools::GetUcsZvt()
{
AcGeVector3d vtZ = AcGeVector3d::kZAxis;
AcDbDatabase* pDb = acdbCurDwg();
if (NULL != pDb)
vtZ = pDb->ucsxdir().crossProduct(pDb->ucsydir());
return vtZ;
}
//////////////////////////////////////////////////////////////////////////
// 风管沿程阻力水力计算
double TAuxTools::CalFricLoss( double dTemp, double dRough, double dDia, double dLength, double dVelocity )
{
//double dDensity = CalDesity(dTemp); // 密度
double dDensity = TDbHvacDimension::m_dDensity; // 密度
//double dMoveVis = CalMoveVis(dTemp); // 运动黏度(m^2/s);范围:>0
double dMoveVis = TDbHvacDimension::m_dMoveVis * 1.e-6;
double dRe = CalRe(dVelocity, dDia, dMoveVis); // 计算Re
double dFricCoef = CalFricCoef(dRough, dDia, dRe); // 计算摩擦系数
return CalCircleFricLoss(dFricCoef, dDia, dLength, dDensity, dVelocity);
}
double TAuxTools::CalFricLoss( double dTemp, double dRough, double dWidth, double dHeight,
double dLength, double dVelocity )
{
double dDia = CalVelDia(dWidth, dHeight);
return CalFricLoss(dTemp, dRough, dDia, dLength, dVelocity);
}
// 圆管沿程阻力 dFricCoef摩擦系数 管径(mm)、管长(m)、密度(kg/m^3)和流速(m/s)计算沿程阻力(Pa)
double TAuxTools::CalCircleFricLoss(double dFricCoef, double dDia, double dLength,
double dDensity, double dVelocity)
{
if ((dFricCoef < ZERO_AIR) || (dDia < ZERO_AIR) || (dLength < 0)
|| (dDensity < ZERO_AIR) || (dVelocity < 0))
return 0.0;
return dFricCoef * dLength * dDensity * pow(dVelocity, 2) / (0.002 * dDia);
}
// 根据粗糙度(mm)、流速当量直径(mm)和雷诺数计算摩擦系数, 用柯列勃洛克-怀特公式计算
double TAuxTools::CalFricCoef(double dRough, double dCalDia, double dRe)
{
if ((dRough < 0.0) || (dCalDia < ZERO_AIR) || (dRe < ZERO_AIR))
return ZERO_AIR;
if (dRe < 2000)
return 64 / dRe;
double dA, dB; // 系数a, b
dA = dRough / (3.7 * dCalDia);
dB = 2.51 / dRe;
double dNewX, dOldX; // 用于迭代计算的新旧数据 =1/(FricCoef)^0.5
dNewX = 5.0; // 初始值为5
double e = 1.0; // 两次迭代之差
double t = 0.0;
int nFlag = 0; // 控制最大迭代次数
while ((e > 0.0001) && (nFlag < 100))
{
dOldX = dNewX;
t = dA + dB * dOldX;
if (t < ZERO_AIR)
return 0.0; // 认为无解
dNewX = dOldX - (dOldX + 2 * log10(t)) * (t) * log(10.0) / ((t) * log(10.0) + 2 * dB);
e = fabs(dNewX - dOldX);
nFlag++;
}
if (nFlag >= 100)
return 0.0; // 认为无解
return 1 / pow(dNewX, 2);
}
// 根据管宽(mm)和管高(mm)计算流速当量直径(mm)
double TAuxTools::CalVelDia(double dWidth, double dHeight)
{
if ((dWidth < ZERO_AIR) || (dHeight < ZERO_AIR))
return 0.0;
return 2 * dWidth * dHeight / (dWidth + dHeight);
}
// 流速(m/s)、流速当量直径(mm)和黏度(m^2/s)计算雷诺数
double TAuxTools::CalRe(double dVelocity, double dVelDia, double dMoveVis)
{
if ((dVelocity < 0.0) || (dVelDia < ZERO_AIR) || (dMoveVis < 1.0e-10))
return ZERO_AIR;
return dVelocity * 0.001 * dVelDia / dMoveVis;
}
double TAuxTools::CalDesity(double dTemperature)
{
double dDensity[15] = {1.293, 1.270, 1.248, 1.226, 1.205,
1.185, 1.165, 1.146, 1.128, 1.093,
1.060, 1.029, 1.000, 0.973, 0.947};
double dTem[15] = {0, 5, 10, 15, 20,
25, 30, 35, 40, 50,
60, 70, 80, 90, 100};
return CalTable(dTem, (double*)dDensity, dTemperature, 15);
}
double TAuxTools::CalMoveVis(double dTemperature)
{
double dMovVis[18] = {13.7, 14.7, 15.7, 16.6, 17.6,
18.6, 19.6, 20.5, 21.7, 22.9,
23.6, 26.2, 28.5, 30.6, 33.2,
35.8, 42.8, 49.9};
double dTem[18] = {0, 10, 20, 30, 40,
50, 60, 70, 80, 90,
100, 120, 140, 160, 180,
200, 250, 300};
return CalTable(dTem, (double*)dMovVis, dTemperature, 18) * 1.0e-6;
}
/*----------------------------------------------------------------------------*
* 功能描述: 用插值法从一维表格中取值
* 备 注: dAbscissa为表头;共m列数据;dX表示列值;表头升序
-----------------------------------------------------------------------------*/
double TAuxTools::CalTable(double dAbscissa[], double *pTable, double dX, int m)
{
if (dX < dAbscissa[0])
dX = dAbscissa[0];
else if (dX > dAbscissa[m - 1])
dX = dAbscissa[m - 1];
for(int i = 0; i < m; i++)
{
if (dAbscissa[i] == dAbscissa[i - 1]) // 与前一个表头相等
continue;
if (dX == dAbscissa[i]) // 等于某个表头
return pTable[i];
else if (dX < dAbscissa[i]) // 小于某个表头,用查值
return (pTable[i] - pTable[i - 1])*(dX - dAbscissa[i - 1])
/ (dAbscissa[i] - dAbscissa[i - 1]) + pTable[i - 1];
}
return 0.0;
}
//////////////////////////////////////////////////////////////////////////
// 用于特性表修改某些参数后,更新遮挡关系
void TAuxTools::SetAndUpdateCover(TDbInterfacesObj* pObj, LPCTSTR pszName, TDb::OPMInfo* pInfo)
{
// 设置数据时,更新遮挡
if (NULL != pObj && NULL != pInfo->pXData && 0 != pInfo->pXData->nVt)
{
// 设置数据
TDbXDataMap* pMap = pObj->GetSpecialtyData();
if (NULL != pMap)
{
pMap->SetAt(pszName, *pInfo->pXData);
pInfo->pXData->nVt = 0; // 设置处理完成标识
pObj->FlashCoverDisplay();
}
}
}
// 获得字体样式表
void TAuxTools::GetAllTextStyleNameArray(CStringArray& arTextStyle)
{
AcDbTextStyleTable* pTextStyleTbl = NULL;
AcDbTextStyleTableRecord* pTextStyleTblRec = NULL;
if (acdbHostApplicationServices()->workingDatabase() \
->getTextStyleTable(pTextStyleTbl, AcDb::kForRead) == Acad::eOk)
{
// 文字样式表记录
AcDbTextStyleTableIterator* pIterator = NULL;
if (pTextStyleTbl->newIterator(pIterator) == Acad::eOk)
{
for (pIterator->start(); !pIterator->done(); pIterator->step())
{
if (pIterator->getRecord(pTextStyleTblRec, AcDb::kForRead) == Acad::eOk)
{
LPCTSTR pszName = NULL;
pTextStyleTblRec->getName(pszName);
arTextStyle.Add(pszName);
pTextStyleTblRec->close();
}
}
delete pIterator;
}
pTextStyleTbl->close();
}
}
// 获取最小分度角(曲面分化成小平面,相邻平面法向量间最小夹角)
double TAuxTools::GetMinDiffAngle()
{
double dMinDiffAng = PI/12;
GetGlobalContext()->GetAt(KEY_MINDIFFANG, dMinDiffAng);
if (dMinDiffAng < 1e-3)
return PI/12;
return dMinDiffAng;
}
void TAuxTools::BuildRectDuct(const AcGePoint3d& ptStart, const AcGePoint3d& ptEnd,
const AcGeVector3d& vtNormal, const double dSWidth,
const double dSThick, const double dEWidth, const double dEThick,
TXShell& xShell, const AcGeVector3d* pvtSSide/* = NULL*/,
const AcGeVector3d* pvtESide/* = NULL*/)
{
// 计算参数
double dHalfSWidth = dSWidth / 2.0;
double dHalfSThick = dSThick / 2.0;
double dHalfEWidth = dEWidth / 2.0;
double dHalfEThick = dEThick / 2.0;
AcGeVector3d vtSSide;
if (NULL == pvtSSide)
{
vtSSide = ptEnd - ptStart;
vtSSide.rotateBy(PI / 2.0, vtNormal);
}
else
{
vtSSide = *pvtSSide;
}
vtSSide.normalize();
AcGeVector3d vtESide;
if (NULL == pvtESide)
{
vtESide = ptEnd - ptStart;
vtESide.rotateBy(PI / 2.0, vtNormal);
}
else
{
vtESide = *pvtESide;
}
vtESide.normalize();
// 计算端点
AcGePoint3d arpt[8];
arpt[0] = ptStart + vtSSide * dHalfSWidth + vtNormal * dHalfSThick;
arpt[1] = ptStart + vtSSide * dHalfSWidth - vtNormal * dHalfSThick;
arpt[2] = ptStart - vtSSide * dHalfSWidth - vtNormal * dHalfSThick;
arpt[3] = ptStart - vtSSide * dHalfSWidth + vtNormal * dHalfSThick;
arpt[4] = ptEnd + vtESide * dHalfEWidth + vtNormal * dHalfEThick;
arpt[5] = ptEnd + vtESide * dHalfEWidth - vtNormal * dHalfEThick;
arpt[6] = ptEnd - vtESide * dHalfEWidth - vtNormal * dHalfEThick;
arpt[7] = ptEnd - vtESide * dHalfEWidth + vtNormal * dHalfEThick;
// 添加碰撞面
xShell.AppendFace(new AcDbFace(arpt[0], arpt[1], arpt[2], arpt[3]));
xShell.AppendFace(new AcDbFace(arpt[4], arpt[5], arpt[6], arpt[7]));
xShell.AppendFace(new AcDbFace(arpt[0], arpt[1], arpt[5], arpt[4]));
xShell.AppendFace(new AcDbFace(arpt[1], arpt[2], arpt[6], arpt[5]));
xShell.AppendFace(new AcDbFace(arpt[2], arpt[3], arpt[7], arpt[6]));
xShell.AppendFace(new AcDbFace(arpt[3], arpt[0], arpt[4], arpt[7]));
}
void TAuxTools::BuildCirDuct(const AcGePoint3d& ptStart, const AcGePoint3d& ptEnd,
const double dSDiameter, const double dEDiameter, TXShell& xShell,
const AcGeVector3d* pvtSRot/* = NULL*/, const AcGeVector3d* pvtERot/* = NULL*/,
const AcGeVector3d* pvtSRotAxis/* = NULL*/, const AcGeVector3d* pvtERotAxis/* = NULL*/)
{
// 计算参数
double dSRadius = dSDiameter / 2.0;
double dERadius = dEDiameter / 2.0;
AcGeVector3d vtRotNormal = ptEnd - ptStart;
AcGeVector3d vtSRot;
if (NULL != pvtSRot && NULL != pvtSRotAxis)
{
vtSRot = *pvtSRot;
}
else
{
vtSRot = vtRotNormal.perpVector();
}
vtSRot.normalize();
AcGeVector3d vtERot;
if (NULL != pvtERot && NULL != pvtERotAxis)
{
vtERot = *pvtERot;
}
else
{
vtERot = vtRotNormal.perpVector();
}
vtERot.normalize();
// 计算端点
AcGePoint3d arpt[12];
if (NULL != pvtSRotAxis && NULL != pvtERotAxis)
{
for (int i = 0; i < 6; ++i)
{
arpt[0 + i] = ptStart + vtSRot * dSRadius;
arpt[6 + i] = ptEnd + vtERot * dERadius;
vtSRot.rotateBy(PI / 3.0, *pvtSRotAxis);
vtERot.rotateBy(-PI / 3.0, *pvtERotAxis);
}
}
else
{
for (int i = 0; i < 6; ++i)
{
arpt[0 + i] = ptStart + vtSRot * dSRadius;
arpt[6 + i] = ptEnd + vtERot * dERadius;
vtSRot.rotateBy(PI / 3.0, vtRotNormal);
vtERot.rotateBy(PI / 3.0, vtRotNormal);
}
}
// 添加碰撞面
for (int j = 0; j < 5; ++j)
{
xShell.AppendFace(new AcDbFace(arpt[j], arpt[j + 1], arpt[j + 7], arpt[j + 6]));
}
xShell.AppendFace(new AcDbFace(arpt[5], arpt[0], arpt[6], arpt[11]));
xShell.AppendFace(new AcDbFace(arpt[0], arpt[1], arpt[2], arpt[5]));
xShell.AppendFace(new AcDbFace(arpt[2], arpt[3], arpt[4], arpt[5]));
xShell.AppendFace(new AcDbFace(arpt[6], arpt[7], arpt[8], arpt[11]));
xShell.AppendFace(new AcDbFace(arpt[8], arpt[9], arpt[10], arpt[11]));
}
void TAuxTools::BuildMinRectangle(const AcGePoint3dArray& arpt, AcDbExtents& ext)
{
int iLen = arpt.length();
if (0 == iLen)
{
return;
}
double dMaxX = arpt[0].x;
double dMaxY = arpt[0].y;
double dMaxZ = arpt[0].z;
double dMinX = dMaxX;
double dMinY = dMaxY;
double dMinZ = dMaxZ;
for (int i = 0; i < iLen; ++i)
{
if (dMaxX < arpt[i].x)
{
dMaxX = arpt[i].x;
}
if (dMaxY < arpt[i].y)
{
dMaxY = arpt[i].y;
}
if (dMaxZ < arpt[i].z)
{
dMaxZ = arpt[i].z;
}
if (dMinX > arpt[i].x)
{
dMinX = arpt[i].x;
}
if (dMinY > arpt[i].y)
{
dMinY = arpt[i].y;
}
if (dMinZ > arpt[i].z)
{
dMinZ = arpt[i].z;
}
}
AcGePoint3d ptMax(dMaxX,dMaxY,dMaxZ);
AcGePoint3d ptMin(dMinX,dMinY,dMinZ);
ext.set(ptMin,ptMax);
}
BOOL TAuxTools::IsAutoWorkOffset()
{
BOOL bAuto(FALSE);
GetGlobalContext(HVAC_AUTOOFFSET, bAuto);
return bAuto;
}
BOOL TAuxTools::IsAutoWorkConnect()
{
BOOL bAuto(FALSE);
GetGlobalContext(HVAC_AUTOCONNECT, bAuto);
return bAuto;
}
BOOL TAuxTools::IsAutoWorkSize()
{
BOOL bAuto(FALSE);
GetGlobalContext(HVAC_AUTOSIZE, bAuto);
return bAuto;
}
void TAuxTools::BuildCir2RectDuct(const AcGePoint3d& ptCir, const AcGePoint3d& ptRec,
const AcGeVector3d& vtNormal, const double dDiameter,
const double dWidth, const double dThick, TXShell& xShell,
const AcGeVector3d* pvtRot/* = NULL*/, const AcGeVector3d* pvtCirOut/* = NULL*/)
{
// 计算侧方向
AcGeVector3d vtRot;
AcGeVector3d vtRotNormal;
if (NULL != pvtRot && NULL != pvtCirOut)
{
vtRot = *pvtRot;
vtRotNormal = *pvtCirOut;
}
else
{
vtRot = ptCir - ptRec;
vtRot.rotateBy(PI / 2.0, vtNormal);
}
vtRot.normalize();
// 计算方口端点
double dHalfWidth = dWidth / 2.0;
double dHalfThick = dThick / 2.0;
AcGeVector3d vtSide = vtRot;
AcGePoint3d arptRec[4];
arptRec[0] = ptRec + vtSide * dHalfWidth + vtNormal * dHalfThick;
arptRec[1] = ptRec - vtSide * dHalfWidth + vtNormal * dHalfThick;
arptRec[2] = ptRec - vtSide * dHalfWidth - vtNormal * dHalfThick;
arptRec[3] = ptRec + vtSide * dHalfWidth - vtNormal * dHalfThick;
// 计算圆口端点
double dRadius = dDiameter / 2.0;
AcGePoint3d arptCir[8];
for (int i = 0; i < 8; ++i)
{
arptCir[i] = ptCir + vtRot * dRadius;
vtRot.rotateBy(PI / 4.0, vtRotNormal);
}
// 添加碰撞面
xShell.AppendFace(new AcDbFace(arptCir[0], arptCir[1], arptRec[0], arptRec[0]));
xShell.AppendFace(new AcDbFace(arptCir[1], arptCir[2], arptRec[0], arptRec[0]));
xShell.AppendFace(new AcDbFace(arptCir[2], arptCir[3], arptRec[1], arptRec[1]));
xShell.AppendFace(new AcDbFace(arptCir[3], arptCir[4], arptRec[1], arptRec[1]));
xShell.AppendFace(new AcDbFace(arptCir[4], arptCir[5], arptRec[2], arptRec[2]));
xShell.AppendFace(new AcDbFace(arptCir[5], arptCir[6], arptRec[2], arptRec[2]));
xShell.AppendFace(new AcDbFace(arptCir[6], arptCir[7], arptRec[3], arptRec[3]));
xShell.AppendFace(new AcDbFace(arptCir[7], arptCir[0], arptRec[3], arptRec[3]));
xShell.AppendFace(new AcDbFace(arptRec[0], arptRec[1], arptCir[2], arptCir[2]));
xShell.AppendFace(new AcDbFace(arptRec[1], arptRec[2], arptCir[4], arptCir[4]));
xShell.AppendFace(new AcDbFace(arptRec[2], arptRec[3], arptCir[6], arptCir[6]));
xShell.AppendFace(new AcDbFace(arptRec[3], arptRec[0], arptCir[0], arptCir[0]));
xShell.AppendFace(new AcDbFace(arptCir[0], arptCir[1], arptCir[2], ptCir));
xShell.AppendFace(new AcDbFace(arptCir[2], arptCir[3], arptCir[4], ptCir));
xShell.AppendFace(new AcDbFace(arptCir[4], arptCir[5], arptCir[6], ptCir));
xShell.AppendFace(new AcDbFace(arptCir[6], arptCir[7], arptCir[0], ptCir));
xShell.AppendFace(new AcDbFace(arptRec[0], arptRec[1], arptRec[2], arptRec[3]));
}
void TAuxTools::BuildRecFace(const AcGePoint3d& pt, const double dWidth, const double dThick,
const AcGeVector3d& vtNormal, const AcGeVector3d& vtFaceNormal, TXShell& xShell)
{
// 获得侧方向
AcGeVector3d vtSide = vtFaceNormal;
vtSide.rotateBy(PI / 2.0, vtNormal);
vtSide.normalize();
// 添加面
double dHalfWidth = dWidth / 2.0;
double dHalfThick = dThick / 2.0;
AcGePoint3d arpt[4];
arpt[0] = pt + vtSide * dHalfWidth + vtNormal * dHalfThick;
arpt[1] = pt + vtSide * dHalfWidth - vtNormal * dHalfThick;
arpt[2] = pt - vtSide * dHalfWidth - vtNormal * dHalfThick;
arpt[3] = pt - vtSide * dHalfWidth + vtNormal * dHalfThick;
xShell.AppendFace(new AcDbFace(arpt[0], arpt[1], arpt[2], arpt[3]));
}
void TAuxTools::BuildRecFace(const AcGePoint3d& pt, const double dWidth, const double dThick,
const AcGeVector3d& vtNormal, const AcGeVector3d& vtFaceNormal, AcDbVoidPtrArray& dbPtArr)
{
// 获得侧方向
AcGeVector3d vtSide = vtFaceNormal;
vtSide.rotateBy(PI / 2.0, vtNormal);
vtSide.normalize();
// 添加面
double dHalfWidth = dWidth / 2.0;
double dHalfThick = dThick / 2.0;
AcGePoint3d arpt[4];
arpt[0] = pt + vtSide * dHalfWidth + vtNormal * dHalfThick;
arpt[1] = pt + vtSide * dHalfWidth - vtNormal * dHalfThick;
arpt[2] = pt - vtSide * dHalfWidth - vtNormal * dHalfThick;
arpt[3] = pt - vtSide * dHalfWidth + vtNormal * dHalfThick;
dbPtArr.append(new AcDbFace(arpt[0], arpt[1], arpt[2], arpt[3]));
}
void TAuxTools::BuildCirFace(const AcGePoint3d& pt, const double dDiameter, const AcGeVector3d& vtNormal,
const AcGeVector3d& vtFaceNormal, TXShell& xShell)
{
// 获得侧方向
AcGeVector3d vtRot = vtNormal;
vtRot.normalize();
double dRadius = dDiameter / 2.0;
AcGePoint3d arpt[6];
for (int i = 0; i < 6; ++i)
{
arpt[i] = pt + vtRot * dRadius;
vtRot.rotateBy(PI / 3.0, vtFaceNormal);
}
xShell.AppendFace(new AcDbFace(arpt[0], arpt[1], arpt[2], arpt[3]));
xShell.AppendFace(new AcDbFace(arpt[3], arpt[4], arpt[5], arpt[0]));
}
void TAuxTools::BuildCirFace(const AcGePoint3d& pt, const double dDiameter, const AcGeVector3d& vtNormal,
const AcGeVector3d& vtFaceNormal, AcDbVoidPtrArray& dbPtArr)
{
// 获得侧方向
AcGeVector3d vtRot = vtNormal;
vtRot.normalize();
double dRadius = dDiameter / 2.0;
AcGePoint3d arpt[6];
for (int i = 0; i < 6; ++i)
{
arpt[i] = pt + vtRot * dRadius;
vtRot.rotateBy(PI / 3.0, vtFaceNormal);
}
dbPtArr.append(new AcDbFace(arpt[0], arpt[1], arpt[2], arpt[3]));
dbPtArr.append(new AcDbFace(arpt[3], arpt[4], arpt[5], arpt[0]));
}
void TAuxTools::DealWithConEnt(AcDbObjectId idToDeal, const AcGeVector3d& vtOff,
AcDbObjectId idFrom, AcGePoint3d ptFrom)
{
TDbXDataMap* pMap = NULL;
ObjectKind eKind(TDb::eCabletry);
OPENOBJ_BEGIN(idToDeal, AcDb::kForWrite, TDbInterfacesObj, pIfObj);
if (NULL != pIfObj)
{
pMap = pIfObj->GetSpecialtyData();
if (NULL != pMap)
{
pMap->GetAt(KEY_RUNTIME, (int&)eKind);
if (eKind == TDb::ePipe)
{
TDbHvacDuct* pDuct = TDbHvacDuct::cast(pIfObj);
if (NULL != pDuct)
{
AcGePoint3d ptStart = pDuct->StartPoint();
AcGePoint3d ptEnd = pDuct->EndPoint();
AcGeVector3d vtDirect = ptEnd - ptStart;
if (vtOff.isParallelTo(vtDirect))
{
if (ptStart.distanceTo(ptFrom) < 1e-6)
{
AcGePoint3d ptNewStart = ptStart + vtOff;
pDuct->SetStartPoint(ptNewStart);
pDuct->UpdateInterfaceRec(ptStart, ptNewStart);
}
else if (ptEnd.distanceTo(ptFrom) < 1e-6)
{
AcGePoint3d ptNewEnd = ptEnd + vtOff;
pDuct->SetEndPoint(ptNewEnd);
pDuct->UpdateInterfaceRec(ptEnd, ptNewEnd);
}
}
}
}
else
{
if (!pIfObj->GetInterface(ptFrom, TInterface())) // 没有实际连接
return;
int nIfNum = pIfObj->GetInterfaceCount();
int i(0);
TInterface tIf;
AcDbObjectId id(AcDbObjectId::kNull);
for (i = 0; i < nIfNum; i++)
{
tIf.Reset();
if (!pIfObj->GetInterface(i, tIf))
continue;
id = tIf.GetConnectObject();
if (id != idFrom && id.isValid())
{
DealWithConEnt(id, vtOff, idToDeal, tIf.GetPosition());
}
}
pIfObj->transformBy(vtOff);
}
}
}
OPENOBJ_END();
}
void TAuxTools::DealWithConEnt( AcDbObjectIdArray idArrToDeal, const AcGePoint3dArray& ptArrOrig,
const AcGePoint3dArray& ptArrNew, AcDbObjectId idFrom )
{
int nSize = idArrToDeal.length();
if (nSize != ptArrOrig.length() || nSize != ptArrNew.length())
return;
AcGeVector3d vtOff;
int i(0);
for (i = 0; i < nSize; i++)
{
if (idArrToDeal[i].isValid() && idFrom.isValid())
{
vtOff = ptArrNew[i] - ptArrOrig[i];
if (vtOff.length() > 1e-6)
{
DealWithConEnt(idArrToDeal[i], vtOff, idFrom, ptArrOrig[i]);
}
}
}
}
BOOL TAuxTools::GetInterfacePoint(const TImpSpecFitting* pFit, AcGePoint3dArray &ptArr )
{
if (NULL == pFit)
return FALSE;
TInterface tIf;
int i(0), nNum = pFit->GetInterfaceCount();
for (i = 0; i < nNum; i++)
{
tIf.Reset();
pFit->GetInterface(i, tIf);
ptArr.append(tIf.GetPosition());
}
return ptArr.length() > 0;
}
BOOL TAuxTools::GetInterfaceId( const TImpSpecFitting* pFit, AcDbObjectIdArray &idArr )
{
if (NULL == pFit)
return FALSE;
TInterface tIf;
AcDbObjectId id(AcDbObjectId::kNull);
int i(0), nNum = pFit->GetInterfaceCount();
for (i = 0; i < nNum; i++)
{
tIf.Reset();
pFit->GetInterface(i, tIf);
id = tIf.GetConnectObject();
if (id.isValid())
idArr.append(id);
}
return idArr.length() > 0;
}
// 获取面标高, 零点距到零点投影到该面的垂点的长度
double TAuxTools::GetPlaneEle( const AcGePlane &plan )
{
AcGePoint3d ptOrth = AcGePoint3d::kOrigin.orthoProject(plan);
double dEle = ptOrth.asVector().length();
AcGeVector3d vtZAxis(TAuxTools::GetUcsZvt());
if (!ptOrth.asVector().isCodirectionalTo(plan.normal()))
dEle *= -1.0;
return dEle;
}
//读扩展数据
CString TAuxTools::ReadXdata( ads_name name, const TCHAR*szName )
{
AcDbObjectId idEnt;
acdbGetObjectId(idEnt, name);
return ReadXdata(idEnt, szName);
}
//读扩展数据
CString TAuxTools::ReadXdata( AcDbObjectId idEnt, const TCHAR*szName )
{
AcDbObject *pObj = NULL;
acdbOpenObject(pObj, idEnt, AcDb::kForRead);
if(!pObj)
return _T("");
resbuf *pRb = pObj->xData(szName);
CString csRet;
if (pRb != NULL)
{
resbuf *pTemp = pRb;
if (pTemp->rbnext != NULL)
{
pTemp = pTemp->rbnext;
if (pTemp->restype == 1000)
csRet = pTemp->resval.rstring;
}
}
ads_relrb(pRb);
pObj->close();
return csRet;
}
//写扩展数据
BOOL TAuxTools::WriteXdata(ads_name name, const TCHAR*szName, const TCHAR*szValue)
{
AcDbObjectId idEnt;
acdbGetObjectId(idEnt, name);
return WriteXdata(idEnt, szName, szValue);
}
//写扩展数据
BOOL TAuxTools::WriteXdata(AcDbObjectId idEnt, const TCHAR*szName, const TCHAR*szValue)
{
AcDbObject *pObj = NULL;
if(!XSymbolTable(_T("APPID"), szName))
ads_regapp(szName);
acdbOpenObject(pObj, idEnt, AcDb::kForWrite);
if(!pObj)
return FALSE;
resbuf *pXData = ads_buildlist(1001, szName, 1000, szValue, NULL);
pObj->setXData(pXData);
ads_relrb(pXData);
pObj->close();
return TRUE;
}
// 通过id获取文字样式名
TCHAR* TAuxTools::GetFontStyle(AcDbObjectId idTextStyle)
{
AcDbTextStyleTableRecord* pTTR;
if (acdbOpenObject(pTTR, idTextStyle, AcDb::kForRead) != Acad::eOk)
return NULL;
TCHAR* pName = NULL;
if (pTTR->getName(pName) != Acad::eOk)
{
pTTR->close();
return NULL;
}
pTTR->close();
return pName;
}
BOOL TAuxTools::IsEquipAutoMove( TImpSpecEquipment* pImpEquip, AcGeVector3d vtOffset )
{
if (NULL == pImpEquip)
return FALSE;
TInterface tIf;
AcGeVector3d vtIf;
int i(0), nIfNum(pImpEquip->GetInterfaceCount());
for (i = 0; i < nIfNum; i++)
{
tIf.Reset();
if (!pImpEquip->GetInterface(i, tIf))
continue;
vtIf = tIf.GetOutDir();
if (!(vtOffset.isPerpendicularTo(vtIf) || vtOffset.isParallelTo(vtIf)))
return FALSE;
}
return TRUE;
}
void TAuxTools::GetAirLetByDuct( const TDbHvacDuct* pDuct, AcDbObjectIdArray &idArrAir )
{
AcDbObjectIdArray idArrAllEnt;
GetAllAirFromModel(idArrAllEnt);
int nPos(0);
AcGeVector3d vtFlur;
int i(0);
for (i = 0; i < idArrAllEnt.length(); i++)
{
if (AirIsOnDuct(idArrAllEnt[i], pDuct, nPos, vtFlur))
idArrAir.append(idArrAllEnt[i]);
}
}
// 从模型空间块表中获取所有的风口,性能有待改善
void TAuxTools::GetAllAirFromModel(AcDbObjectIdArray& arAirId)
{
// 需要非写方式打开实体时调用
// RBList rbMask = ads_buildlist( -4, _T("<or"),
// -4, _T("<and"), RTDXF0, _T("ATS_DBHEQUIPMENT"), -4, _T("and>"),
// -4, _T("or>"), NULL);
//
//
// PickSet ssEquip(SS_FREE);
// ssEquip.Get(_T("X"), NULL, NULL, rbMask);
// long lIndex(0), lLen(ssEquip.Length());
// TInterface tIf;
// TDb::ObjectKind eKind = TDb::eCabletry;
//
// for (lIndex = 0; lIndex < lLen; lIndex++)
// {
// OPENOBJ_BEGIN(ssEquip[lIndex], AcDb::kForRead, TDbHvacEquipment, pEqu);
// if (pEqu != NULL)
// {
// pEqu->GetSpecialtyDataReadOnly()->GetAt(KEY_RUNTIME, (int&)eKind);
// if (eKind == TDb::eAirlets)
// {
// tIf.Reset();
// pEqu->GetInterface(0, tIf);
// if (tIf.GetConnectObject().isValid())
// continue;
//
// arAirId.append(pEqu->objectId());
// }
// }
// OPENOBJ_END();
// }
AcDbBlockTable* pBlockTable = NULL;
if(Acad::eOk != acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable, AcDb::kForRead))
return;
AcDbBlockTableRecord* pBlockTableRecord = NULL;
if(Acad::eOk != pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite))
{
pBlockTable->close();
return;
}
pBlockTable->close();
AcDbObjectId idPre;
AcDbBlockTableRecordIterator* pRecIter;
pBlockTableRecord->newIterator(pRecIter);
TDb::ObjectKind eKind;
TInterface tIf;
AcDbObjectId idCon = NULL;
BOOL bConOk(FALSE); // 连接完好的不用统计,会自动联动
for (pRecIter->start(); !pRecIter->done(); pRecIter->step())
{
pRecIter->getEntityId(idPre);
OPENOBJ_BEGIN(idPre, AcDb::kForRead, TDbHvacEquipment, pEqu);
if (pEqu != NULL)
{
pEqu->GetSpecialtyDataReadOnly()->GetAt(KEY_RUNTIME, (int&)eKind);
if (eKind == TDb::eAirlets)
{
tIf.Reset();
pEqu->GetInterface(0, tIf);
if (tIf.GetConnectObject().isValid())
continue;
arAirId.append(idPre);
}
}
OPENOBJ_END();
}
pBlockTableRecord->close();
}
// 判断风口是否在风管上
BOOL TAuxTools::AirIsOnDuct( const AcDbObjectId& idAir, const TDbHvacDuct* pDuct, int& nPos, AcGeVector3d& vtFlux )
{
if (pDuct == NULL)
return FALSE;
OPENOBJ_BEGIN(idAir, AcDb::kForRead, TDbHvacEquipment, pEqu);
if (pEqu == NULL)
return FALSE;
TDbXDataMap* pXMap = pEqu->GetSpecialtyDataReadOnly();
TDb::ObjectKind eKind;
pXMap->GetAt(KEY_RUNTIME, (int&)eKind);
if (eKind != TDb::eAirlets)
return FALSE;
AcGePoint3d ptStart, ptEnd, ptCenter;
AcGeVector3d vtNorDuct, vtSect, vtNorAir, vtMain;
double dWidthDt, dThickDt, dThickAir;
pXMap->GetAt(HALT_CenterPoint, ptCenter);
pXMap->GetAt(HALT_MainDir, vtMain);
pXMap->GetAt(HVAC_Normal, vtNorAir);
pXMap->GetAt(HALT_Thick, dThickAir);
pDuct->getStartPoint(ptStart);
pDuct->getEndPoint(ptEnd);
vtNorDuct = pDuct->normal();
pXMap = pDuct->GetSpecialtyDataReadOnly();
pXMap->GetAt(HDCT_Width, dWidthDt);
pXMap->GetAt(HDCT_Thick, dThickDt);
TDb::HvacSectType eSectType;
pXMap->GetAt(HVAC_SectType, (int&)eSectType);
if (eSectType == TDb::eCircular)
dThickDt = dWidthDt;
vtSect = ptEnd - ptStart;
nPos = CalPosBy3Point(ptStart, ptEnd, ptCenter);
if (nPos == 0) // 不共线
{
// 求风口在管上的投影点
AcGePlane plan(ptCenter, vtSect);
AcGePoint3d ptConer = ptStart.orthoProject(plan);
if (CalPosBy3Point(ptStart, ptEnd, ptConer) == 3)
{
double dLength = ptCenter.distanceTo(ptConer);
dThickAir += 1.0;
if (vtNorAir.isParallelTo(vtNorDuct))
{
if (fabs(dLength - dThickDt / 2.0) < dThickAir)
{
nPos = 2;
vtFlux = ptCenter - ptConer;
vtFlux.normalize();
return TRUE;
}
}
else if (vtNorAir.isPerpendicularTo(vtNorDuct))
{
if (fabs(dLength - dWidthDt / 2.0) < dThickAir)
{
nPos = 3;
vtFlux = ptCenter - ptConer;
vtFlux.normalize();
return TRUE;
}
}
}
}
else // 共线
{
if (vtNorAir.isParallelTo(vtSect)) // 平行
{
dThickAir += 1.0;
if ((ptCenter.distanceTo(ptStart) < dThickAir) || (ptCenter.distanceTo(ptEnd) < dThickAir)) // 范围
{
nPos = 1;
vtFlux = vtNorAir;
return TRUE;
}
}
}
OPENOBJ_END();
return FALSE;
}
// 判断点pt3与pt1和pt2的位置关系。0-不共线;1--在pt1外;2--同pt1;3--在pt1和pt2之间;4--同pt2;5--在pt2外
int TAuxTools::CalPosBy3Point(const AcGePoint3d& pt1, const AcGePoint3d& pt2, const AcGePoint3d& pt3)
{
if (pt3 == pt1)
return 2;
if (pt3 == pt2)
return 4;
AcGeVector3d vt13, vt23;
vt13 = pt3 - pt1;
vt23 = pt3 - pt2;
if (!vt13.isParallelTo(vt23)) // 不共线
return 0;
if (vt13.isCodirectionalTo(vt23))
{
if (pt3.distanceTo(pt1) < pt3.distanceTo(pt2))
return 1;
else
return 5;
}
else
{
return 3;
}
return -1;
}
BOOL TAuxTools::Is2DView()
{
BOOL b2D(FALSE);
struct resbuf rb = {NULL, RT3DPOINT, 0};
acedGetVar(_T("VIEWDIR"), &rb);
AcGeVector3d vtDir = asVec3d(rb.resval.rpoint);
if ((vtDir.isCodirectionalTo(AcGeVector3d::kZAxis)
&& TAuxTools::GetUcsZvt().isCodirectionalTo(AcGeVector3d::kZAxis)))
{
b2D = TRUE;
}
return b2D;
}
void TAuxTools::DoubleToString( double dValue, int nPreci, CString &csValue )
{
CString csPreci;
csPreci.Format(_T("%d"), nPreci);
csValue.Format(_T("%.") + csPreci + _T("f"), dValue);
}
AcDbObjectId TAuxTools::GetProjBlockId(const AcDbObjectId& idSrc, AcGeVector3d vtNor,
AcGeVector3d vtMain, AcGeVector3d vtPlaneSec,
AcGeScale3d& scale, AcDbExtents* pExt)
{
// 图块正方向
AcGeVector3d vtFront = vtNor.crossProduct(vtMain);
// 正方向与投影方向的角度
double dProjAng = vtFront.angleTo(vtPlaneSec, vtNor);
// 是否镜像
BOOL bMirror = (PI / 2 < dProjAng && PI * 1.5 > dProjAng);
// 旋转轴
AcGeVector3d vtAxis = vtPlaneSec.crossProduct(vtNor);
// 旋转角度
double dAngle = vtNor.angleTo(vtPlaneSec, bMirror ? -vtAxis : vtAxis);
// 矩阵
AcGeMatrix3d matNor, matHorz, matMirr;
matNor.setToRotation(dAngle, vtAxis, AcGePoint3d::kOrigin);
matHorz.setToRotation(-dProjAng, AcGeVector3d::kZAxis, AcGePoint3d::kOrigin);
matMirr.setToRotation(PI, AcGeVector3d::kXAxis, AcGePoint3d::kOrigin);
// 新图块ID
AcDbObjectId idNew = AcDbObjectId::kNull;
// 原始图块旋转之后的尺寸
AcGeScale3d scaOrg(1, 1, 1);
// 生成图块名
CString csBlkName;
OPENOBJ_BEGIN(idSrc, AcDb::kForRead, AcDbBlockTableRecord, pBlkRec);
if(NULL != pBlkRec)
{
TCHAR* pName = NULL;
pBlkRec->getName(pName);
csBlkName.Format(_T("%s_%d%d%d%.6f%.6f%.6f"), pName, bMirror, (int)(dAngle * 180 / PI),
(int)(dProjAng * 180 / PI), vtAxis.x, vtAxis.y, vtAxis.z);
}
else
{
return AcDbObjectId::kNull;
}
OPENOBJ_END();
AcDbBlockTable* pBlkTbl = NULL;
acdbCurDwg()->getBlockTable(pBlkTbl, AcDb::kForWrite);
if(NULL == pBlkTbl)
return AcDbObjectId::kNull;
AcGePoint3d ptMax, ptMin;
if(pBlkTbl->has(csBlkName)) // 块存在
{
pBlkTbl->getAt(csBlkName, idNew);
OPENOBJ_BEGIN(idNew, AcDb::kForRead, AcDbBlockTableRecord, pBlkOld);
if(NULL != pBlkOld)
{
AcDbExtents ext;
ext.addBlockExt(pBlkOld);
ptMax = ext.maxPoint();
ptMin = ext.minPoint();
scaOrg.set(ptMax.x - ptMin.x, ptMax.y - ptMin.y, ptMax.z - ptMin.z);
}
OPENOBJ_END();
}
else
{
// 插入新图块
AcDbBlockTableRecord* pBlkNew = new AcDbBlockTableRecord;
pBlkTbl->add(idNew, pBlkNew);
pBlkNew->setName(csBlkName);
AcDbBlockReference* pBlkRef = new AcDbBlockReference(AcGePoint3d::kOrigin , idSrc);
pBlkRef->transformBy(matNor);
pBlkRef->transformBy(matHorz);
if(bMirror)
pBlkRef->transformBy(matMirr);
AcDbVoidPtrArray ptrArr;
pBlkRef->explode(ptrArr);
for(int i = 0; i < ptrArr.length(); i++)
{
AcDbEntity* pEnt = AcDbEntity::cast((AcDbEntity*)ptrArr[i]);
if(NULL != pEnt)
{
pBlkNew->appendAcDbEntity(pEnt);
pEnt->close();
}
}
delete pBlkRef;
// 取得图块尺寸
AcDbExtents ext;
ext.addBlockExt(pBlkNew);
ptMax = ext.maxPoint();
ptMin = ext.minPoint();
scaOrg.set(ptMax.x - ptMin.x, ptMax.y - ptMin.y, ptMax.z - ptMin.z);
// 设置图块插入点
//AcGePoint3d ptOrigin = Mid(ptMax, ptMin);
//ptOrigin.y = ptMin.y;
//pBlkNew->setOrigin(ptOrigin);
pBlkNew->close();
}
// 计算新图块比例
AcDbObjectId idTemp;
AcDbBlockTableRecord* pBlkSca = new AcDbBlockTableRecord;
pBlkTbl->add(idTemp, pBlkSca);
pBlkTbl->close();
AcDbBlockReference* pBlkRefSca = new AcDbBlockReference(AcGePoint3d::kOrigin , idSrc);
pBlkRefSca->setScaleFactors(scale);
pBlkRefSca->transformBy(matNor);
pBlkRefSca->transformBy(matHorz);
if(bMirror)
pBlkRefSca->transformBy(matMirr);
AcDbVoidPtrArray ptrArr;
pBlkRefSca->explode(ptrArr);
for(int i = 0; i < ptrArr.length(); i++)
{
AcDbEntity* pEnt = AcDbEntity::cast((AcDbEntity*)ptrArr[i]);
if(NULL != pEnt)
{
pBlkSca->appendAcDbEntity(pEnt);
pEnt->close();
}
}
delete pBlkRefSca;
// 取得新图块尺寸
AcDbExtents extSca;
extSca.addBlockExt(pBlkSca);
ptMax = extSca.maxPoint();
ptMin = extSca.minPoint();
if(NULL != pExt)
pExt->addExt(extSca);
scale.set((ptMax.x - ptMin.x) / scaOrg[X],
(ptMax.y - ptMin.y) / scaOrg[Y],
(ptMax.z - ptMin.z) / scaOrg[Z]);
pBlkSca->erase();
pBlkSca->close();
return idNew;
}
extern TDbRelInterfaceReactor* g_pRelInterfaceReactor;
TDbInterfaceRecord* TAuxTools::GetIntfPtrFromDB()
{
AcDbDatabase* pDb = acdbCurDwg();
if(NULL == pDb)
return NULL;
TDbInterfaceRecord* pIRec = NULL;
g_pRelInterfaceReactor->m_mapDbToIRecPtr.Lookup(pDb,(void *&)pIRec);
if (pIRec != NULL)
{
pIRec->m_bIsCatchBuf = true;
return pIRec;
}
else //
{
}
return NULL;
}
// pLine转换为TGGeCurveSegment,并添加到TDPtrList中
void TAuxTools::Poly2CurveSeg(AcDbPolyline* pLine, TDPtrList<TGGeCurveSegment>& segComs)
{
if (NULL == pLine)
return ;
AcGePoint3d pt1, pt2;
double dBugle(0.0), dAng(0.0);
TGGeCurveSegment tGetSeg;
for(int i = 0; i <= (int)pLine->numVerts()-2; i++)
{
pLine->getPointAt(i, pt1);
pLine->getBulgeAt(i, dBugle);
pLine->getPointAt(i+1, pt2);
// 直线
if (EQUAL_ZERO(dBugle))
{
tGetSeg.SetLine(pt1, pt2);
}
// 此段为弧线
else
{
// 计算角度
dAng = atan(dBugle) * 4;
tGetSeg.SetArc(pt1, pt2, dAng);
}
segComs.Append(new TGGeCurveSegment(tGetSeg));
}
if (pLine->isClosed())
{
dBugle = 0.0;
pLine->getPointAt(pLine->numVerts()-1, pt1);
pLine->getPointAt(0, pt2);
pLine->getBulgeAt(pLine->numVerts()-1, dBugle);
if (EQUAL_ZERO(dBugle))
tGetSeg.SetLine(pt1, pt2);
else
{
dAng = atan(dBugle) * 4;
tGetSeg.SetArc(pt1, pt2, dAng);
}
segComs.Append(new TGGeCurveSegment(tGetSeg));
}
}
BOOL TAuxTools::IsIncline(AcGeVector3d& vt)
{
AcDbDatabase* pDb = acdbCurDwg();
if (NULL == pDb)
return FALSE;
AcGeVector3d vtZAxis(pDb->ucsxdir().crossProduct(pDb->ucsydir()));
return !vt.isParallelTo(vtZAxis) && !vt.isPerpendicularTo(vtZAxis);
}
void TAuxTools::Matrix3D2String( const AcGeMatrix3d &mat, CString &str )
{
#if ADS <= 15
std::ostringstream stream;
#else
std::wostringstream stream;
#endif
for (int ln = 0; ln < 4; ++ln)
{
for (int col = 0; col < 4; ++col)
{
stream<<mat.entry[ln][col];
#if ADS <= 15
stream << " ";
#else
stream << L" ";
#endif
}
}
str = stream.str().c_str();
}
double TAuxTools::CalCurvature(const AcGePoint3d& pt1, const AcGePoint3d& pt2,
const AcGePoint3d& pt3, const AcGeVector3d* pVtNor)
{
AcGeVector3d vtUseZAixs = AcGeVector3d::kIdentity;
if(NULL == pVtNor)
{
AcDbDatabase* pDb = acdbCurDwg();
if (NULL != pDb)
vtUseZAixs = pDb->ucsxdir().crossProduct(pDb->ucsydir());
}
else
{
vtUseZAixs = *pVtNor;
}
AcGeCircArc3d arc(pt1, pt2, pt3);
double dBulge = tan((arc.endAng() - arc.startAng()) * 0.25);
AcGeVector3d vtMid = pt2 - pt1;
AcGeVector3d vtEnd = pt3 - pt1;
AcGeVector3d vtCross = vtMid.crossProduct(vtEnd);
if (!vtCross.isCodirectionalTo(vtUseZAixs))
dBulge *= -1;
return dBulge;
}
LPCTSTR TAuxTools::GetBlkNameById (AcDbObjectId id)
{
AcDbObject* pObj = NULL;
if (Acad::eOk != acdbOpenObject(pObj, id, AcDb::kForRead))
{
return NULL;
}
if (!pObj->isKindOf(AcDbBlockTableRecord::desc()))
{
pObj->close();
return NULL;
}
AcDbBlockTableRecord* pRec = AcDbBlockTableRecord::cast(pObj);
ACHAR* pCh = NULL;
pRec->getName(pCh);
pRec->close();
pObj->close();
return pCh;
}
// add by dyc on 2014-01-21 解决Y型三通在比较大坐标值情况下以后后变成T型问题,求两圆交点
BOOL TAuxTools::CircleInsertWith(const AcGeCircArc3d& circleS, const AcGeCircArc3d& circleE,
AcGePoint3d& ptInter1, AcGePoint3d& ptInter2)
{
AcGePoint3d ptCentS = circleS.center();
AcGePoint3d ptCentE = circleE.center();
double dRS = circleS.radius();
double dRE = circleE.radius();
double dSumR = dRS + dRE;
double dDistanceES = ptCentS.distanceTo(ptCentE);
AcGeVector3d vtES = ptCentE - ptCentS;
BOOL bInsert = FALSE;
vtES.normalize();
AcGePoint3d ptInsert;
if(dDistanceES > dSumR)
return bInsert;
else if(fabs(dDistanceES - dSumR) <= 1e-6)
{
ptInsert = ptCentS + vtES * dRS;
ptInter1 = ptInter2 = ptInsert;
bInsert = TRUE;
}
else
{
double dLeftLength = (pow(dRS, 2) - pow(dRE, 2) + pow(dDistanceES, 2)) / (2 * dDistanceES);
double dUpLength = sqrt(pow(dRS, 2) - pow(dLeftLength, 2));
double dDownLength = dUpLength;
ptInsert = ptCentS + vtES * dLeftLength;
vtES.rotateBy(PI * 0.5, AcGeVector3d::kZAxis);
ptInter1 = ptInsert + vtES * dUpLength;
ptInter2 = ptInsert - vtES * dDownLength;
bInsert = TRUE;
}
return bInsert;
}
int TAuxTools::StrTokenize(LPCTSTR pszSrc, LPCTSTR pszDelimit, CStringArray& arSubs)
{
if(NULL == pszSrc || NULL == pszDelimit)
return 0;
CString sText = pszSrc;
LPTSTR pszSub = _tcstok(sText.GetBuffer(0), pszDelimit);
while(NULL != pszSub)
{
arSubs.Add(pszSub);
pszSub = _tcstok(NULL, pszDelimit);
}
sText.ReleaseBuffer();
return (int)arSubs.GetSize();
}
BOOL TAuxTools::IsVerticalLine(AcGePoint3d pt1, AcGePoint3d pt2)
{
AcGeVector3d vt = pt2 - pt1;
return fabs(vt.x) < 1.0E-6 && fabs(vt.y) < 1.0E-6;
}
// 计算曲线遮挡 用于水管遮挡风管的情况
void TAuxTools::GetCurveGeomExtentsEdge(AcDbEntity* pEnt, TComplexCurve& crLoop)
{
if(NULL == pEnt)
return;
if(!pEnt->isKindOf(AcDbCurve::desc()))
return;
// 起点终点
AcDbCurve* pCurve = (AcDbCurve*)pEnt;
AcGePoint3d ptStart, ptEnd;
pCurve->getStartPoint(ptStart);
pCurve->getEndPoint(ptEnd);
// 立管不处理
if(IsVerticalLine(ptStart, ptEnd))
return;
// 中点
double dPar1 = 0, dPar2 = 0;
pCurve->getStartParam(dPar1);
pCurve->getEndParam(dPar2);
AcGePoint3d ptMid;
pCurve->getPointAtParam((dPar1 + dPar2) / 2, ptMid);
// 判断是否弧形
BOOL bArc = FALSE;
AcGeVector3d vtSE = ptEnd - ptStart;
AcGeVector3d ptSM = ptMid - ptStart;
if(!vtSE.isParallelTo(ptSM))
{
bArc = TRUE;
}
// 计算边界
double dBrWidth = 0;
if(!TAuxTools::GetTHvacDataFromDwg(HVAC_PIPEHIDEWIDTH, dBrWidth))
GetGlobalContext()->GetAt(HVAC_PIPEHIDEWIDTH, dBrWidth);
if(!DOWNEQUAL_ZERO(dBrWidth))
{
AcGePoint3d ptS1, ptS2, ptE1, ptE2, ptM1, ptM2;
if(bArc)
{
// 取得圆心
AcGeCircArc3d arc(ptStart, ptMid, ptEnd);
AcGePoint3d ptCenter = arc.center();
AcGeVector3d vtDir;
// start
vtDir = ptStart - ptCenter;
vtDir.normalize();
ptS1 = ptStart + vtDir * dBrWidth;
ptS2 = ptStart - vtDir * dBrWidth;
// end
vtDir = ptEnd - ptCenter;
vtDir.normalize();
ptE1 = ptEnd + vtDir * dBrWidth;
ptE2 = ptEnd - vtDir * dBrWidth;
// mid
vtDir = ptMid - ptCenter;
vtDir.normalize();
ptM1 = ptMid + vtDir * dBrWidth;
ptM2 = ptMid - vtDir * dBrWidth;
}
else
{
// 方向
AcGeVector3d vtDir = ptEnd - ptStart;
vtDir.rotateBy(0.5 * PI, AcGeVector3d::kZAxis);
vtDir.normalize();
ptS1 = ptStart + vtDir * dBrWidth;
ptS2 = ptStart - vtDir * dBrWidth;
ptE1 = ptEnd + vtDir * dBrWidth;
ptE2 = ptEnd - vtDir * dBrWidth;
}
TCurveElement tCurveEle;
memset(&tCurveEle, 0, sizeof(TCurveElement));
tCurveEle.bHided = FALSE;
tCurveEle.dWidth = 0.0;
tCurveEle.gsMark = 0;
tCurveEle.ptGe[0] = ptS1;
tCurveEle.ptGe[1] = bArc ? ptM1 : ptE1;
tCurveEle.ptGe[2] = ptE1;
crLoop.append(tCurveEle);
tCurveEle.ptGe[0] = ptE1;
tCurveEle.ptGe[1] = ptE2;
tCurveEle.ptGe[2] = ptE2;
crLoop.append(tCurveEle);
tCurveEle.ptGe[0] = ptE2;
tCurveEle.ptGe[1] = bArc ? ptM2 : ptS2;
tCurveEle.ptGe[2] = ptS2;
crLoop.append(tCurveEle);
tCurveEle.ptGe[0] = ptS2;
tCurveEle.ptGe[1] = ptS1;
tCurveEle.ptGe[2] = ptS1;
crLoop.append(tCurveEle);
}
}
void TAuxTools::MakeCurvePolyFaces(AcDbEntity* pEnt, AcDbVoidPtrArray& arFaces)
{
if(NULL == pEnt)
return;
if(!pEnt->isKindOf(AcDbCurve::desc()))
return;
// 起点终点
AcDbCurve* pCurve = (AcDbCurve*)pEnt;
AcGePoint3d ptStart, ptEnd;
pCurve->getStartPoint(ptStart);
pCurve->getEndPoint(ptEnd);
// 立管不处理
if(IsVerticalLine(ptStart, ptEnd))
return;
// 中点
double dPar1 = 0, dPar2 = 0;
pCurve->getStartParam(dPar1);
pCurve->getEndParam(dPar2);
AcGePoint3d ptMid;
pCurve->getPointAtParam((dPar1 + dPar2) / 2, ptMid);
// 投影到中点上
AcGePlane plane(Mid(ptStart, ptEnd), AcGeVector3d::kZAxis);
ptStart = ptStart.orthoProject(plane);
ptEnd = ptEnd.orthoProject(plane);
ptMid = ptMid.orthoProject(plane);
// 判断是否弧形
BOOL bArc = FALSE;
AcGeVector3d vtSE = ptEnd - ptStart;
AcGeVector3d ptSM = ptMid - ptStart;
if(!vtSE.isParallelTo(ptSM))
{
bArc = TRUE;
}
// 计算边界
double dBrWidth = 0;
if(!TAuxTools::GetTHvacDataFromDwg(HVAC_PIPEHIDEWIDTH, dBrWidth))
GetGlobalContext()->GetAt(HVAC_PIPEHIDEWIDTH, dBrWidth);
if(!DOWNEQUAL_ZERO(dBrWidth))
{
if(!bArc)
{
// 方向
AcGeVector3d vtDir = ptEnd - ptStart;
vtDir.normalize();
ptStart += vtDir * 0.1;
ptEnd -= vtDir * 0.1;
vtDir.rotateBy(0.5 * PI, AcGeVector3d::kZAxis);
vtDir.normalize();
AcGePoint3d ptS1 = ptStart + vtDir * dBrWidth;
AcGePoint3d ptS2 = ptStart - vtDir * dBrWidth;
AcGePoint3d ptE1 = ptEnd + vtDir * dBrWidth;
AcGePoint3d ptE2 = ptEnd - vtDir * dBrWidth;
AcDbFace* pFace = new AcDbFace;
pFace->setVertexAt(0, ptS1);
pFace->setVertexAt(1, ptE1);
pFace->setVertexAt(2, ptE2);
pFace->setVertexAt(3, ptS2);
arFaces.append(pFace);
}
else // 弧形以直线进行拟合
{
double dAngle = GetMinDiffAngle();
// 取得圆心 圆心角
AcGeCircArc3d arc(ptStart, ptMid, ptEnd);
double dRadius = arc.radius();
AcGePoint3d ptCent = arc.center();
AcGeVector3d vtMid = ptMid - ptCent;
vtMid.normalize();
// 生成点
AcGePoint3dArray arPtUp, arPtDn;
AcGePoint3d ptOn;
AcGeVector3d vtLeft = vtMid;
AcGeVector3d vtRight = vtMid;
double dArcAngle = arc.endAng() - arc.startAng();
int nLoop = (int)(dArcAngle / dAngle / 2) + 1;
for(int i = 0; i < nLoop; i++)
{
if(0 == i)
{
ptOn = ptCent + vtMid * (dRadius + dBrWidth);
arPtUp.append(ptOn);
ptOn = ptCent + vtMid * (dRadius - dBrWidth);
arPtDn.append(ptOn);
}
else
{
// 左侧
vtLeft.rotateBy(dAngle, AcGeVector3d::kZAxis);
ptOn = ptCent + vtLeft * (dRadius + dBrWidth);
arPtUp.insertAt(0, ptOn);
ptOn = ptCent + vtLeft * (dRadius - dBrWidth);
arPtDn.insertAt(0, ptOn);
// 右侧
vtRight.rotateBy(-dAngle, AcGeVector3d::kZAxis);
ptOn = ptCent + vtRight * (dRadius + dBrWidth);
arPtUp.append(ptOn);
ptOn = ptCent + vtRight * (dRadius - dBrWidth);
arPtDn.append(ptOn);
}
}
// 起点终点
vtMid = ptEnd - ptCent;
vtMid.normalize();
arPtUp.insertAt(0, ptCent + vtMid * (dRadius + dBrWidth));
arPtDn.insertAt(0, ptCent + vtMid * (dRadius - dBrWidth));
vtMid = ptStart - ptCent;
vtMid.normalize();
arPtUp.append(ptCent + vtMid * (dRadius + dBrWidth));
arPtDn.append(ptCent + vtMid * (dRadius - dBrWidth));
// 生成遮挡面
AcDbFace* pFace = NULL;
for(int i = 0; i < arPtUp.length() - 1; i++)
{
pFace = new AcDbFace;
pFace->setVertexAt(0, arPtUp[i]);
pFace->setVertexAt(1, arPtUp[i + 1]);
pFace->setVertexAt(2, arPtDn[i + 1]);
pFace->setVertexAt(3, arPtDn[i]);
arFaces.append(pFace);
}
}
}
}