2409 lines
63 KiB
C++
2409 lines
63 KiB
C++
#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);
|
||
}
|
||
}
|
||
}
|
||
}
|