Files
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

3751 lines
89 KiB
C++

#include "stdafx.h"
#include "resource.h"
#include "DrawThunder3D.h"
#include "CaculateResult.h"
#include "ThunderXData.h"
#include "dbgroup.h"
#include "ThunderCmdGroup.h"
#include "LightningRodData.h"
#include "ktsetting.h"
#include "ThunderCaculate.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define DSPACE 0.05
#define GRADUALLY_COUNT 10
TGDrawThunder::TGDrawThunder()
{
m_strLayer2d = LAY_EL_THUNDER_2D;
m_strLayer3d = LAY_EL_THUNDER_3D;
m_nSinglePinColorIndex = 256;
m_nMultiPinColorIndex = 256;
}
TGDrawThunder::~TGDrawThunder()
{
}
AcGePoint3d TGDrawThunder::Mid2Point(const AcGePoint3d& pt1, const AcGePoint3d& pt2)
{
return AcGePoint3d((pt1.x+pt2.x)/2,(pt1.y+pt2.y)/2,(pt1.z+pt2.z)/2);
}
//画3D避雷区域
void TGDrawThunder::DrawThunder3DArea(LPCTSTR pszGroupNo, lstCltResult& lstData, BOOL bPreview)
{
//生成新的实体
MakeThunderEntity(pszGroupNo,lstData, bPreview);
CThunderXData xd;
AcDbObjectId id;
if (bPreview)
{
for (int i = 0;i < m_arPreview.length();++i)
{
id = AddToCurrentSpace((AcDbEntity*)m_arPreview[i],Adesk::kTrue);
xd.SetXData(id, TEL_GROUP_NO, pszGroupNo);
ThunderContainer->AppendPreview3DSolid(pszGroupNo, id);
}
m_arPreview.setLogicalLength(0);
}
else
{
for (int i = 0; i < m_arRegSolid.length(); ++i)
{
id = AddToCurrentSpace((AcDbEntity*)m_arRegSolid[i],Adesk::kTrue);
xd.SetXData(id, TEL_GROUP_NO, pszGroupNo);
ThunderContainer->Append3DSolid(pszGroupNo, id);
}
}
}
bool TGDrawThunder::DocGetMeterUnitDraw()
{
struct resbuf rb;
acedGetVar(_T("INSUNITS"),&rb);
if (rb.resval.rint == AcDb::kUnitsMeters)
{
return true;
}
return false;
}
//画2D保护区域
void TGDrawThunder::DrawThunder2DArea(const AcGeDoubleArray& arHeight, LPCTSTR pszGroupNo)
{
if (pszGroupNo == NULL)
{
return;
}
// 清理旧的实体
DeleteAllEntities(pszGroupNo);
AcDbObjectIdArray arID;
if (ThunderContainer->GetGroupThunder(pszGroupNo, arID) < 1)
{
return;
}
KTSetting::InitLayer(LAY_EL_THUNDER_2D);
KTSetting::InitLayer(LAY_EL_THUNDER_3D);
CRegProperty regProp(GetRegLocation(), TEL_OBJECTKEY);
regProp.SetTopRootKey(HKEY_CURRENT_USER);
regProp.GetValue(KEY_SINGLEPRO_COLOR,m_nSinglePinColorIndex);
regProp.GetValue(KEY_UNIONPRO_COLOR,m_nMultiPinColorIndex);
if (arHeight.length() < 1)
{
return;
}
CTGTempTol locTol(0.1, 0.1);
// 绘制保护圆
DrawThunderCircle(arHeight, pszGroupNo, arID);
// 计算避雷针数据
lstCltResult lstData;
CalcThunderData(pszGroupNo, arHeight, arID, lstData);
// 绘制三维
DrawThunder3DArea(pszGroupNo, lstData);
// 根据三维绘制二维
double dScale = 1.0;
if (!DocGetMeterUnitDraw())
dScale = 1000.0;
AcDbObjectId id;
AcGePoint3d ptOrg;
AcGePlane plan;
AcGeDoubleArray arTemp;
CThunderXData thunderXData;
AcDbRegion *pFirstReg = NULL;
AcDbRegion *pReg = NULL;
CString sTemp;
for (int j = 0; j < arHeight.length(); ++j)
{
ptOrg.set(0,0,arHeight[j]*dScale);
plan.set(ptOrg,AcGeVector3d::kXAxis,AcGeVector3d::kYAxis);
if (m_arRegSolid.length() > 0)
{
((AcDb3dSolid*)m_arRegSolid[0])->getSection(plan,pFirstReg);
}
if (pFirstReg != NULL)
{
for (int i = 1;i < m_arRegSolid.length();++i)
{
((AcDb3dSolid*)m_arRegSolid[i])->getSection(plan,pReg);
if (pReg != NULL)
{
pFirstReg->booleanOper(AcDb::kBoolUnite,pReg);
delete pReg;
pReg = NULL;
}
}
pFirstReg->setLayer(m_strLayer2d);
pFirstReg->setColorIndex(m_nMultiPinColorIndex);
id = AddToCurrentSpace(pFirstReg,Adesk::kTrue);
pFirstReg = NULL;
// 二维区域写入保护高度扩展数据
arTemp.setLogicalLength(0);
arTemp.append(arHeight[j]);
sTemp.Format(_T("%g"),arHeight[j]);
thunderXData.SetXData(id,TEL_GROUP_NO,pszGroupNo);
thunderXData.SetXData(id,TEL_CURRENT_PROHEIGHT,sTemp);
thunderXData.SetProtectHeightToObjEx(id, arHeight);
ThunderContainer->AppendRegion(pszGroupNo, id);
}
}
}
void TGDrawThunder::DrawThunderLine(LPCTSTR pszGroupNo, const AcGeDoubleArray& arHeight)
{
// 清理旧的实体
DeleteThunLineEntities(pszGroupNo);
if (pszGroupNo != NULL && arHeight.length() > 0)
{
KTSetting::InitLayer(LAY_EL_THUNDER_2D);
KTSetting::InitLayer(LAY_EL_THUNDER_3D);
CRegProperty regProp(GetRegLocation(), TEL_OBJECTKEY);
regProp.SetTopRootKey(HKEY_CURRENT_USER);
regProp.GetValue(KEY_SINGLEPRO_COLOR,m_nSinglePinColorIndex);
regProp.GetValue(KEY_UNIONPRO_COLOR,m_nMultiPinColorIndex);
AcDbObjectIdArray arID;
ThunderContainer->GetGroupThunderLine(pszGroupNo, arID);
if (arHeight.length() < 1 ||
arID.length() < 1)
{
return;
}
CTGTempTol locTol(0.1, 0.1);
// 计算数据
MapThunderLineCltResult mapData;
CalcThunLineData(pszGroupNo, arHeight, arID, mapData);
// 绘制避雷线三维
DrawThunLine3D(pszGroupNo, mapData);
// 添加到模型空间
AcDbObjectId id;
AcDbEntity* p3dEnt = NULL;
MapThunderLinePtr::iterator itT;
for (itT = m_mapThunLinePtr.begin();itT != m_mapThunLinePtr.end();++itT)
{
m_arCollector.append(itT->second);
}
for (int i = 0; i < m_arCollector.length(); ++i)
{
p3dEnt = (AcDbEntity*)m_arCollector[i];
if (p3dEnt != NULL)
{
p3dEnt->setLayer(LAY_EL_THUNDER_3D);
p3dEnt->setColorIndex(m_nMultiPinColorIndex);
id = AddToCurrentSpace(p3dEnt,Adesk::kTrue);
ThunderContainer->AppendLine3DSolid(pszGroupNo, id);
}
}
// 根据三维实体生成二维区域
double dScale = 1.0;
if (!DocGetMeterUnitDraw())
dScale = 1000.0;
AcGePoint3d ptOrg;
AcGePlane plan;
AcGeDoubleArray arTemp;
CThunderXData thunderXData;
AcDbRegion *pFirstReg = NULL;
AcDbRegion *pReg = NULL;
CString sTemp;
MapUnionLine::iterator itUnion;
AcDbVoidPtrArray arPtrTemp;
for (int j = 0; j < arHeight.length(); ++j)
{
arPtrTemp.setLogicalLength(0);
ptOrg.set(0,0,arHeight[j]*dScale);
plan.set(ptOrg,AcGeVector3d::kXAxis,AcGeVector3d::kYAxis);
//1.单个避雷线reg
for (itT = m_mapThunLinePtr.begin();itT != m_mapThunLinePtr.end();++itT)
{
arPtrTemp = itT->second;
if (arPtrTemp.length() > 0)
{
((AcDb3dSolid*)arPtrTemp[0])->getSection(plan,pFirstReg);
if (pFirstReg != NULL)
{
for (int i = 1;i < arPtrTemp.length();++i)
{
((AcDb3dSolid*)arPtrTemp[i])->getSection(plan,pReg);
if (pReg != NULL)
{
pFirstReg->booleanOper(AcDb::kBoolUnite,pReg);
delete pReg;
pReg = NULL;
}
}
pFirstReg->setLayer(m_strLayer2d);
pFirstReg->setColorIndex(m_nSinglePinColorIndex);
id = AddToCurrentSpace(pFirstReg,Adesk::kTrue);
pFirstReg = NULL;
// 二维区域写入保护高度扩展数据
arTemp.setLogicalLength(0);
arTemp.append(arHeight[j]);
sTemp.Format(_T("%g"),arHeight[j]);
thunderXData.SetXData(id,KEY_LINE_GROUP_NO,pszGroupNo);
thunderXData.SetXData(id,TEL_CURRENT_PROHEIGHT,sTemp);
thunderXData.SetProtectHeightToObjEx(id, arHeight);
ThunderContainer->AppendLineRegion(pszGroupNo, id);
}
}
}
//1.联合避雷线reg
for (itUnion = m_mapLineUnRegSolid.begin();itUnion != m_mapLineUnRegSolid.end();++itUnion)
{
arPtrTemp = itUnion->second;
if (arPtrTemp.length() > 0)
{
((AcDb3dSolid*)arPtrTemp[0])->getSection(plan,pFirstReg);
if (pFirstReg != NULL)
{
for (int i = 1;i < arPtrTemp.length();++i)
{
((AcDb3dSolid*)arPtrTemp[i])->getSection(plan,pReg);
if (pReg != NULL)
{
pFirstReg->booleanOper(AcDb::kBoolUnite,pReg);
delete pReg;
pReg = NULL;
}
}
pFirstReg->setLayer(m_strLayer2d);
pFirstReg->setColorIndex(m_nMultiPinColorIndex);
id = AddToCurrentSpace(pFirstReg,Adesk::kTrue);
pFirstReg = NULL;
// 二维区域写入保护高度扩展数据
arTemp.setLogicalLength(0);
arTemp.append(arHeight[j]);
sTemp.Format(_T("%g"),arHeight[j]);
thunderXData.SetXData(id,KEY_LINE_GROUP_NO,pszGroupNo);
thunderXData.SetXData(id,TEL_CURRENT_PROHEIGHT,sTemp);
thunderXData.SetProtectHeightToObjEx(id, arHeight);
ThunderContainer->AppendLineRegion(pszGroupNo, id);
}
}
}
}
m_arCollector.setLogicalLength(0);
m_mapThunLinePtr.clear();
m_mapLineUnRegSolid.clear();
}
}
void TGDrawThunder::DeleteThunLineEntities(LPCTSTR pszGNo)
{
ThunderContainer->EreaseSpecGNoLineRegion(pszGNo);
ThunderContainer->EreaseSpecGNoLine3dSolid(pszGNo);
}
void TGDrawThunder::ClassifyThunderLines(const AcDbObjectIdArray& arID, LstParallelTLine& lstID)
{
lstID.clear();
int nPos = -1;
AcDbObjectIdArray arLoc,arTmp;
arLoc.append(arID);
while (arLoc.length() > 0)
{
arTmp.append(arLoc[0]);
for (int i = 1;i < arLoc.length();++i)
{
if (CheckIsEqualLineTLine(arLoc[0], arLoc[i]))
{
arTmp.append(arLoc[i]);
}
}
lstID.push_back(arTmp);
for (int j = 0;j < arTmp.length();++j)
{
arLoc.find(arTmp[j],nPos);
if (nPos >= 0 && nPos < arLoc.length())
{
arLoc.removeAt(nPos);
}
}
arTmp.setLogicalLength(0);
}
}
BOOL TGDrawThunder::CheckIsEqualLineTLine(const AcDbObjectId& id1,const AcDbObjectId& id2)
{
BOOL bSuc = FALSE;
if (id1.isValid() && id2.isValid())
{
CString sGRadius,sGRadius2,sHeight,sHeight2;
CThunderXData xd;
OPENOBJ_BEGIN(id1,AcDb::kForRead,AcDbPolyline,pLine);
if (pLine != NULL)
{
OPENOBJ_BEGIN(id2,AcDb::kForRead,AcDbPolyline,pLine2);
if (pLine2 != NULL)
{
// 比较扩展数据
xd.GetXData(pLine,KEY_LINE_PRO_RADIUS,sGRadius);
xd.GetXData(pLine,KEY_LINE_HEIGHT,sHeight);
xd.GetXData(pLine2,KEY_LINE_PRO_RADIUS,sGRadius2);
xd.GetXData(pLine2,KEY_LINE_HEIGHT,sHeight2);
if (fabs(_tstof(sGRadius)-_tstof(sGRadius2)) < 1e-3 &&
fabs(_tstof(sHeight)-_tstof(sHeight2)) < 1e-3 )
{
AcGePoint3d ptS,ptE,ptS2,ptE2;
pLine->getStartPoint(ptS);
pLine->getEndPoint(ptE);
pLine2->getStartPoint(ptS2);
pLine2->getEndPoint(ptE2);
AcGeVector3d vt1 = ptE - ptS;
AcGeVector3d vt2 = ptE2 - ptS2;
if (vt1.isParallelTo(vt2)) // 平行
{
// 共线
if (CheckPtIsOnLine(ptS,pLine2) ||
CheckPtIsOnLine(ptE,pLine2) ||
CheckPtIsOnLine(ptS2,pLine) ||
CheckPtIsOnLine(ptE2,pLine) )
{
bSuc = TRUE;
}
}
}
}
OPENOBJ_END();
}
OPENOBJ_END();
}
return bSuc;
}
BOOL TGDrawThunder::CheckPtIsOnLine(const AcGePoint3d& pt, AcDbPolyline* pLine)
{
if (pLine != NULL)
{
AcGePoint3d ptOn;
pLine->getClosestPointTo(pt, ptOn);
if (pt.distanceTo(ptOn) < 1e-3)
{
return TRUE;
}
}
return FALSE;
}
void TGDrawThunder::GetThunderLineMaxPort(const AcDbObjectIdArray& arID, AcGePoint3d& ptS,AcGePoint3d& ptE)
{
// 前提:所有Pl平行且共线
AcGePoint3d ptT;
std::list<double> lstX,lstY,lstZ;
for (int i = 0;i < arID.length();++i)
{
OPENOBJ_BEGIN(arID[i],AcDb::kForRead,AcDbPolyline,pLine);
if (pLine != NULL)
{
pLine->getStartPoint(ptT);
lstX.push_back(ptT.x);
lstY.push_back(ptT.y);
lstZ.push_back(ptT.z);
pLine->getEndPoint(ptT);
lstX.push_back(ptT.x);
lstY.push_back(ptT.y);
lstZ.push_back(ptT.z);
}
OPENOBJ_END();
}
if (lstX.size() > 0 &&
lstY.size() > 0 &&
lstZ.size() > 0)
{
lstX.sort();
lstY.sort();
lstZ.sort();
ptS.x = lstX.front();
ptS.y = lstY.front();
ptS.z = lstZ.front();
ptE.x = lstX.back();
ptE.y = lstY.back();
ptE.z = lstZ.back();
}
}
int TGDrawThunder::CalcThunLineData(LPCTSTR pszGNo, const AcGeDoubleArray& arProHeight, const AcDbObjectIdArray& arID, MapThunderLineCltResult& mapData)
{
mapData.clear();
if (pszGNo != NULL && arID.length() > 0)
{
CThunderXData thundXData;
for (int p = 0;p < arID.length();++p)
{
thundXData.SetProtectHeightToObjEx(arID[p], arProHeight);
}
AcDbObjectIdArray arLoc(arID);
// 检查是否存在避雷针编号重复
AcDbObjectIdArray arRepeate;
if (CheckHasRepeatNum(arLoc,arRepeate))
{
acutPrintf(_T("\n 存在重复的避雷线编号,请修改编号。"));
}
// LstParallelTLine lstID;
// LstParallelTLine::iterator it;
// ClassifyThunderLines(arLoc, lstID);
CStringArray arsXData;
TGLightningRodData ltnData;
TGThunderCaculate caculate;
AcGePoint3d ptStart,ptEnd;
lstCltResult lstTemp;
CString sGRadius,sHeight,sNum,sGNo;
for (int i = 0;i < arLoc.length();++i)
{
if (!arLoc[i].isValid())
{
continue;
}
// GetThunderLineMaxPort(arIDTemp, ptStart, ptEnd);
// ptStart.z = 0;
// ptEnd.z = 0;
lstTemp.clear();
OPENOBJ_BEGIN(arLoc[i],AcDb::kForRead,AcDbPolyline,pLine);
if (pLine != NULL)
{
pLine->getStartPoint(ptStart);
pLine->getEndPoint(ptEnd);
ptStart.z = 0;
ptEnd.z = 0;
thundXData.GetXData(pLine,KEY_LINE_PRO_RADIUS,sGRadius);
thundXData.GetXData(pLine,KEY_LINE_HEIGHT,sHeight);
thundXData.GetXData(pLine,KEY_LINE_GROUP_NO,sGNo);
thundXData.GetXData(pLine,TEL_ORDER_NUMBER,sNum);
ltnData.SetGroundRadius(_tstof(sGRadius));
ltnData.SetHeight(_tstof(sHeight));
ltnData.SetNumber(_ttoi(sNum));
ltnData.SetGroupNO(_ttoi(sGNo));
ltnData.SetInsertPoint(ptStart);
ltnData.m_arProtecedHeight.setLogicalLength(0);
ltnData.m_arProtecedHeight.append(arProHeight);
caculate.CaculateThunderData(&ltnData);
lstTemp.push_back(caculate.m_result);
ltnData.SetGroundRadius(_tstof(sGRadius));
ltnData.SetHeight(_tstof(sHeight));
ltnData.SetNumber(_ttoi(sNum));
ltnData.SetGroupNO(_ttoi(sGNo));
ltnData.SetInsertPoint(ptEnd);
ltnData.m_arProtecedHeight.setLogicalLength(0);
ltnData.m_arProtecedHeight.append(arProHeight);
caculate.CaculateThunderData(&ltnData);
lstTemp.push_back(caculate.m_result);
}
OPENOBJ_END();
mapData.insert(std::make_pair(arLoc[i],lstTemp));
}
}
return (mapData.size() > 0);
}
void TGDrawThunder::DrawThunLine3D(LPCTSTR pszGNo,MapThunderLineCltResult& mapData, BOOL bPreview)
{
AcDb3dSolid *pSolid = NULL;
CThunderXData thundXData;
lstCltResult::iterator it;
MapThunderLineCltResult::iterator itMap;
lstCltResult lstData;
AcDbRegion* pSecReg = NULL;
AcGePlane plan;
AcGePoint3d ptPos;
AcGeVector3d vtHor = AcGeVector3d::kZAxis,vtVer,vtNor;
AcDbVoidPtrArray arPtr;
// 绘制单个避雷线
for (itMap = mapData.begin();itMap != mapData.end();++itMap)
{
lstData = itMap->second;
if (lstData.size() != 2)
continue;
ptPos = lstData.front().m_ptInsert;
ptPos.z = 0.0;
vtNor = lstData.back().m_ptInsert - lstData.front().m_ptInsert;
vtVer = vtHor;
vtVer.rotateBy(PI/2,vtNor);
plan.set(ptPos,vtHor,vtVer);
pSolid = Create3DSolid(lstData.front());
if (pSolid == NULL)
{
continue;
}
arPtr.setLogicalLength(0);
arPtr.append(pSolid);
// 实体截面
pSolid->getSection(plan, pSecReg);
if (pSecReg != NULL)
{
pSolid = ExtrudeSolid(pSecReg, vtNor.normal(), vtNor.length());
if (pSolid != NULL)
{
arPtr.append(pSolid);
}
delete pSecReg;
}
pSolid = Create3DSolid(lstData.back());
if (pSolid != NULL)
{
arPtr.append(pSolid);
for (int t = 0;t < arPtr.length();++t)
{
thundXData.SetXData((AcDbEntity*)arPtr[t], KEY_LINE_GROUP_NO, pszGNo);
}
// 添加预览
if (bPreview)
{
m_arLinePreview.append(arPtr);
}
else
{
m_mapThunLinePtr.insert(std::make_pair(itMap->first,arPtr));
}
}
else
{
for (int t = 0;t < arPtr.length();++t)
{
delete (AcDbEntity*)arPtr[t];
}
}
}
// 生成联合保护区域
AcDbVoidPtrArray arTemp;
AcDbVoidPtrArray arUnions;
MapThunderLinePtr::iterator itFind;
MapUnionLine::iterator itApFind;
MapThunderLineCltResult::iterator itSub;
AcDbObjectIdArray arSubGroup;
MapGrouping mapGroup;
MapGrouping::iterator itGroup;
int nIndex = 0;
for (itMap = mapData.begin();itMap != mapData.end();++itMap)
{
arTemp.setLogicalLength(0);
arSubGroup.setLogicalLength(0);
itSub = itMap;
itSub++;
for (itSub;itSub != mapData.end();++itSub)
{
if (CheckIsSuitToCreate(itMap->first,itMap->second,itSub->first,itSub->second))
{
CreateUnionRegion(itMap->first,itMap->second,itSub->first,itSub->second,arUnions);
if (arUnions.length() > 0)
{
if (bPreview)
{
m_arLinePreview.append(arUnions);
arSubGroup.append(itSub->first);
}
else
{
m_arCollector.append(arUnions);
arTemp.append(arUnions);
arSubGroup.append(itSub->first);
}
arUnions.setLogicalLength(0);
}
}
}
if (arSubGroup.length() > 0)
{
arSubGroup.append(itMap->first);
BOOL bAppend = FALSE;
for (itGroup = mapGroup.begin();itGroup != mapGroup.end();++itGroup)
{
if (FindSubArray(itGroup->second, arSubGroup)) // 已经存在
{
if ((itApFind = m_mapLineUnRegSolid.find(itGroup->first)) != m_mapLineUnRegSolid.end())
{
itApFind->second.append(arTemp);
bAppend = TRUE;
break;
}
}
}
if (!bAppend)
{
for (int t = 0;t < arSubGroup.length();++t)
{
if ((itFind = m_mapThunLinePtr.find(arSubGroup[t])) != m_mapThunLinePtr.end())
{
arTemp.append(itFind->second);
}
}
nIndex++;
if (arTemp.length() > 0)
{
m_mapLineUnRegSolid.insert(std::make_pair(nIndex,arTemp));
}
// m_mapLineUnRegSolid.insert(std::make_pair(nIndex,arTempty));
mapGroup.insert(std::make_pair(nIndex,arSubGroup));
}
}
}
// 端点处生成避雷针联合保护区域
AcDbVoidPtrArray arPtrs;
for (itGroup = mapGroup.begin();itGroup != mapGroup.end();++itGroup)
{
Create2PortsUnionSolids(pszGNo, itGroup->second, mapData, arPtrs);
if (arPtrs.length() > 0)
{
if (bPreview)
{
m_arLinePreview.append(arPtrs);
}
else
{
if ((itApFind = m_mapLineUnRegSolid.find(itGroup->first)) != m_mapLineUnRegSolid.end())
{
m_arCollector.append(arPtrs); // 添加到模型空间
itApFind->second.append(arPtrs); // 添加到联合保护区域实体集
}
else
{
ReleasePtrArray(arPtrs);
}
}
arPtrs.setLogicalLength(0);
}
}
if (bPreview)
{
AcDbEntity* pEnt = NULL;
AcDbObjectId id;
for (int i = 0;i < m_arLinePreview.length();++i)
{
pEnt = (AcDbEntity*)m_arLinePreview[i];
if (pEnt != NULL)
{
pEnt->setLayer(LAY_PREVIEW_THUNDER);
pEnt->setColorIndex(m_nMultiPinColorIndex);
id = AddToCurrentSpace(pEnt,Adesk::kTrue);
thundXData.SetXData(id, KEY_LINE_GROUP_NO, pszGNo);
ThunderContainer->AppendPreview3DSolid(pszGNo, id);
}
}
m_arLinePreview.setLogicalLength(0);
}
}
void TGDrawThunder::Create2PortsUnionSolids(LPCTSTR pszGNO, const AcDbObjectIdArray& arLine, MapThunderLineCltResult& mapData, AcDbVoidPtrArray& arSolids)
{
if (arLine.length() < 3 ||
mapData.size() < 1 ||
pszGNO == NULL )
{
return;
}
AcGePoint3dArray arPtPort1,arPtPort2;
AcGeVector3d vtDir;
AcGePoint3d ptS,ptE;
CCaculateResult rstTmp,rstTmp2;
lstCltResult lstData1,lstData2;
MapThunderLineCltResult::iterator it;
OPENOBJ_BEGIN(arLine[0],AcDb::kForRead,AcDbPolyline,pLine);
if (pLine != NULL)
{
pLine->getStartPoint(ptS);
pLine->getEndPoint(ptE);
if ((it = mapData.find(arLine[0])) != mapData.end())
{
arPtPort1.append(ptS);
GetCltResultByPosition(it->second, ptS, rstTmp);
lstData1.push_back(rstTmp);
arPtPort2.append(ptE);
GetCltResultByPosition(it->second, ptE, rstTmp);
lstData2.push_back(rstTmp);
}
vtDir = ptS - ptE;
vtDir.normalize();
}
OPENOBJ_END();
for (int i = 1;i < arLine.length();++i)
{
OPENOBJ_BEGIN(arLine[i],AcDb::kForRead,AcDbPolyline,pLine);
if (pLine != NULL)
{
pLine->getStartPoint(ptS);
pLine->getEndPoint(ptE);
if ((it = mapData.find(arLine[i])) != mapData.end())
{
GetCltResultByPosition(it->second, ptS, rstTmp);
GetCltResultByPosition(it->second, ptE, rstTmp2);
if (vtDir.isCodirectionalTo(ptS - ptE)) // 同向
{
arPtPort1.append(ptS);
lstData1.push_back(rstTmp);
arPtPort2.append(ptE);
lstData2.push_back(rstTmp2);
}
else
{
arPtPort1.append(ptE);
lstData1.push_back(rstTmp2);
arPtPort2.append(ptS);
lstData2.push_back(rstTmp);
}
}
}
OPENOBJ_END();
}
// 生成避雷针联合实体
Make3CenThunderEntity(pszGNO, lstData1,FALSE,&arSolids);
Make3CenThunderEntity(pszGNO, lstData2,FALSE,&arSolids);
}
BOOL TGDrawThunder::FindSubArray(const AcDbObjectIdArray& arSrc, const AcDbObjectIdArray& arSub)
{
if (arSrc.length() < 1|| arSub.length() < 1)
{
return FALSE;
}
int nIndex = 0;
for (int i = 0;i < arSub.length();++i)
{
if (!arSrc.find(arSub[i], nIndex))
{
return FALSE;
}
}
return TRUE;
}
AcDb3dSolid* TGDrawThunder::ExtrudeSolid(AcDbRegion* pDepReg, const AcGeVector3d& vtDirTo, double dLength)
{
AcDb3dSolid* pSolid = NULL;
if (pDepReg != NULL)
{
AcGeVector3d vtDir(vtDirTo);
int nScale = 1;
if (!DocGetMeterUnitDraw())
{
nScale *= 1000;
}
AcGeVector3d vtNor;
pDepReg->getNormal(vtNor);
int nDir = 1;
if (!vtNor.isCodirectionalTo(vtDir))
{
nDir = -1;
}
pSolid = new AcDb3dSolid;
AcGeVector3d vtOff;
AcGeMatrix3d mat;
AcDb3dSolid* pTemp = new AcDb3dSolid;
AcDb3dSolid* pTemp2 = new AcDb3dSolid;
int nCount = (int)dLength / (EXTRUDE_MAX_SIZE*nScale);
double dSpare = dLength - (nCount * EXTRUDE_MAX_SIZE*nScale);
if (nCount > 0)
{
pSolid->extrude(pDepReg, EXTRUDE_MAX_SIZE*nScale*nDir, 0);
pTemp2->copyFrom(pSolid);
}
for (int t = 1;t < nCount;++t)
{
vtOff = vtDir.normal() * t * EXTRUDE_MAX_SIZE*nScale;
mat.setToTranslation(vtOff);
pTemp->cleanBody();
pTemp->copyFrom(pTemp2);
pTemp->transformBy(mat);
pSolid->booleanOper(AcDb::kBoolUnite, pTemp);
}
if (dSpare > 0)
{
vtOff = vtDir.normal() * nCount * EXTRUDE_MAX_SIZE*nScale;
mat.setToTranslation(vtOff);
pDepReg->transformBy(mat);
pTemp->cleanBody();
pTemp->extrude(pDepReg,dSpare*nDir,0);
pSolid->booleanOper(AcDb::kBoolUnite, pTemp);
}
delete pTemp;
delete pTemp2;
}
return pSolid;
}
AcDb3dSolid* TGDrawThunder::ExtrudeSolidAlongPath(AcDbRegion* pDepReg, AcDbCurve* pCve)
{
AcDb3dSolid* pSolid = NULL;
if (pDepReg != NULL && pCve != NULL)
{
int nScale = 1;
if (!DocGetMeterUnitDraw())
{
nScale *= 1000;
}
pSolid = new AcDb3dSolid;
AcGePoint3d ptS,ptE;
CalcLinePorts(pDepReg, pCve, ptS, ptE);
double dLength = ptS.distanceTo(ptE);
AcGeVector3d vtDir = ptE - ptS;
vtDir.normalize();
AcGeVector3d vtOff;
AcGeMatrix3d mat;
AcDb3dSolid* pTemp = new AcDb3dSolid;
AcDb3dSolid* pTemp2 = new AcDb3dSolid;
AcDbLine* pLine = NULL;
AcDbObjectId idTmp;
Acad::ErrorStatus es;
int nCount = (int)dLength / (EXTRUDE_ALONGPATH_MAX_SIZE*nScale);
double dSpare = dLength - (nCount * EXTRUDE_ALONGPATH_MAX_SIZE*nScale);
if (nCount > 0)
{
ptE = ptS + vtDir * EXTRUDE_ALONGPATH_MAX_SIZE*nScale;
pLine = new AcDbLine(ptS,ptE);
idTmp = AddToCurrentSpace(pLine,Adesk::kTrue);
es = pSolid->extrudeAlongPath(pDepReg, pLine);
pTemp2->copyFrom(pSolid);
EreaseObj(idTmp);
}
// 由于端点处截取的reg是不规则的
// 因此需要重新截取新的reg
for (int t = 1;t < nCount;++t)
{
vtOff = vtDir.normal() * t * EXTRUDE_ALONGPATH_MAX_SIZE*nScale;
mat.setToTranslation(vtOff);
pTemp->cleanBody();
pTemp->copyFrom(pTemp2);
pTemp->transformBy(mat);
pSolid->booleanOper(AcDb::kBoolUnite, pTemp);
}
if (dSpare > 0)
{
ptS += vtDir.normal() * nCount * EXTRUDE_ALONGPATH_MAX_SIZE*nScale;
ptE = ptS + vtDir * dSpare;
pLine = new AcDbLine(ptS, ptE);
idTmp = AddToCurrentSpace(pLine,Adesk::kTrue);
if (nCount < 1)
{
pTemp->cleanBody();
es = pTemp->extrudeAlongPath(pDepReg, pLine);
pSolid->booleanOper(AcDb::kBoolUnite, pTemp);
}
else
{
AcGePoint3d ptTmp = ptS - vtDir.normal() * nScale;
AcGeVector3d vtT = vtDir.crossProduct(AcGeVector3d::kZAxis);
AcGePlane plan;
plan.set(ptTmp,vtT,AcGeVector3d::kZAxis);
AcDbRegion* pReg = NULL;
pSolid->getSection(plan,pReg);
if (pReg != NULL)
{
pTemp->cleanBody();
es = pTemp->extrudeAlongPath(pReg, pLine);
delete pReg;
pSolid->booleanOper(AcDb::kBoolUnite, pTemp);
}
}
EreaseObj(idTmp);
}
delete pTemp;
delete pTemp2;
}
return pSolid;
}
void TGDrawThunder::CalcLinePorts(AcDbRegion* pReg, AcDbCurve* pCve, AcGePoint3d& ptS, AcGePoint3d& ptE)
{
if (pReg != NULL && pCve != NULL)
{
pCve->getStartPoint(ptS);
pCve->getEndPoint(ptE);
AcDbVoidPtrArray arPtr;
pReg->explode(arPtr);
AcGePoint3d ptOn;
AcDbCurve* pL = NULL;
for (int i = 0;i < arPtr.length();++i)
{
pL = AcDbCurve::cast((AcDbEntity*)arPtr[i]);
if (pL != NULL)
{
pL->getClosestPointTo(ptS, ptOn);
if (ptS.distanceTo(ptOn) < 1e-3)
{
break;
}
pL->getClosestPointTo(ptE, ptOn);
if (ptE.distanceTo(ptOn) < 1e-3)
{
ptOn = ptE;
ptE = ptS;
ptS = ptOn;
break;
}
}
}
for (int j = 0;j < arPtr.length();++j)
{
delete (AcDbEntity*)arPtr[j];
}
}
}
AcGeVector3d TGDrawThunder::CalcRegionNormal(const AcGePoint3d& pt, AcDbRegion* pReg)
{
AcGeVector3d vtNor;
if (pReg != NULL)
{
AcGePlane plan;
pReg->getPlane(plan);
AcGePoint3d ptOn = pt.orthoProject(plan);
vtNor = pt - ptOn;
}
return vtNor;
}
BOOL TGDrawThunder::CheckIsSuitToCreate(const AcDbObjectId& id1, lstCltResult& lstData1, const AcDbObjectId& id2, lstCltResult& lstData2)
{
BOOL bSuit = FALSE;
// 只处理0< h <= hr的情况
if (lstData1.size() < 1 ||
lstData2.size() < 1)
{
return bSuit;
}
double dGRadius = lstData1.begin()->m_dGroundRadius;
double dHeight = lstData1.begin()->m_dHeight;
if (dHeight < 0 ||
dHeight > dGRadius)
{
return bSuit;
}
dGRadius = lstData2.begin()->m_dGroundRadius;
dHeight = lstData2.begin()->m_dHeight;
if (dHeight < 0 ||
dHeight > dGRadius)
{
return bSuit;
}
if (id1.isValid() && id2.isValid())
{
OPENOBJ_BEGIN(id1,AcDb::kForRead,AcDbPolyline,pLine);
if (pLine != NULL)
{
OPENOBJ_BEGIN(id2,AcDb::kForRead,AcDbPolyline,pLine2);
if (pLine2 != NULL)
{
AcGePoint3d ptS,ptE,ptS2,ptE2;
AcGeVector3d vt1,vt2;
pLine->getStartPoint(ptS);
pLine->getEndPoint(ptE);
ptS.z = 0;
ptE.z = 0;
vt1 = ptS - ptE;
pLine2->getStartPoint(ptS2);
pLine2->getEndPoint(ptE2);
ptS2.z = 0;
ptE2.z = 0;
vt2 = ptS2 - ptE2;
if (vt1.isParallelTo(vt2)) // 平行
{
AcDbLine ln(ptS,ptE);
AcGePoint3d ptOn;
ln.getClosestPointTo(ptS2, ptOn, Adesk::kTrue);
double dDist = ptS2.distanceTo(ptOn);
if (dDist > 1e-3) //不共线
{
CString sGroundRadius,sHeight;
CThunderXData xd;
xd.GetXData(pLine, KEY_LINE_PRO_RADIUS, sGroundRadius);
xd.GetXData(pLine, KEY_LINE_HEIGHT, sHeight);
double dScale = 1.0;
if (!DocGetMeterUnitDraw())
dScale *= 1000;
double dD = 2*pow(_tstof(sHeight)*dScale*(2*_tstof(sGroundRadius)*dScale-_tstof(sHeight)*dScale),0.5);
if (dDist < dD)
{
bSuit = TRUE;
}
}
}
}
OPENOBJ_END();
}
OPENOBJ_END();
}
return bSuit;
}
static AcDbObjectId ShowPoint(const AcGePoint3d& pt, Adesk::UInt16 nColorIndex)
{
AcDbCircle* pCir = new AcDbCircle(pt, AcGeVector3d::kZAxis, 1000);
pCir->setColorIndex(nColorIndex);
return AddToCurrentSpace(pCir, Adesk::kTrue);
}
BOOL TGDrawThunder::CreatePortUnionSolid(const AcDbObjectId& id1,lstCltResult& lstData1,const AcDbObjectId& id2,lstCltResult& lstData2,AcDbVoidPtrArray& arSolids)
{
if (id1.isValid() && id2.isValid())
{
CCaculateResult data1,data2;
OPENOBJ_BEGIN(id1,AcDb::kForRead,AcDbPolyline,pLine);
if (pLine != NULL)
{
OPENOBJ_BEGIN(id2,AcDb::kForRead,AcDbPolyline,pLine2);
if (pLine2 != NULL)
{
AcGePoint3d ptS,ptE,ptS2,ptE2;
pLine->getStartPoint(ptS);
pLine->getEndPoint(ptE);
pLine2->getStartPoint(ptS2);
pLine2->getEndPoint(ptE2);
double dDist = 0.0;
std::map<double,LinePtPair> mapPt;
LinePtPair ptPair;
dDist = ptS.distanceTo(ptS2);
ptPair.pt1 = ptS;
ptPair.pt2 = ptS2;
mapPt.insert(std::make_pair(dDist,ptPair));
dDist = ptS.distanceTo(ptE2);
ptPair.pt1 = ptS;
ptPair.pt2 = ptE2;
mapPt.insert(std::make_pair(dDist,ptPair));
dDist = ptE.distanceTo(ptS2);
ptPair.pt1 = ptE;
ptPair.pt2 = ptS2;
mapPt.insert(std::make_pair(dDist,ptPair));
dDist = ptE.distanceTo(ptE2);
ptPair.pt1 = ptE;
ptPair.pt2 = ptE2;
mapPt.insert(std::make_pair(dDist,ptPair));
lstCltResult lstLoc;
lstLoc.insert(lstLoc.end(),lstData1.begin(),lstData1.end());
lstLoc.insert(lstLoc.end(),lstData2.begin(),lstData2.end());
ptS = mapPt.begin()->second.pt1;
ptE = mapPt.begin()->second.pt2;
GetCltResultByPosition(lstLoc, ptS, data1);
GetCltResultByPosition(lstLoc, ptE, data2);
}
OPENOBJ_END();
}
OPENOBJ_END();
AcDb3dSolid* pSolid = GetThunderAreaBy2Pin(data1, data2, TRUE);
if (pSolid != NULL)
{
arSolids.append(pSolid);
}
}
return (arSolids.length() > 0);
}
BOOL TGDrawThunder::CreateUnionRegion(const AcDbObjectId& id1,lstCltResult& lstData1,const AcDbObjectId& id2,lstCltResult& lstData2,AcDbVoidPtrArray& arSolids)
{
if (id1.isValid() && id2.isValid() &&
lstData1.size() == 2 &&
lstData2.size() == 2 )
{
int nScale = 1;
if (!DocGetMeterUnitDraw())
nScale *= 1000;
// 计算两线共线部分
T3DNODE node1,node2;
if (!Get2LinePublicSegment(id1, id2, node1, node2))
{
// 两避雷线不存在共线时单独处理距离较近的一端
return CreatePortUnionSolid(id1, lstData1, id2, lstData2, arSolids);
}
// 绑定数据
T3DCALCNODE data1,data2;
AttachThunderData(lstData1, lstData2, node1, node2, data1, data2);
// 创建两端端点避雷针联合保护区域
AcDb3dSolid* pInt1 = GetThunderAreaBy2Pin(data1.rstPort, data1.rstPro, FALSE);
AcDb3dSolid* pInt2 = GetThunderAreaBy2Pin(data2.rstPort, data2.rstPro, FALSE);
if (pInt1 != NULL && pInt2 != NULL)
{
// 创建共线部分实体
// 共线实体拉伸方向(以data1为拉伸起始点)
AcGeVector3d vtDir = GetPubleSolidExDir(id1, data1, data2);
// 生成共线实体的实体
AcDb3dSolid* pIntPubSolid = GetThunderAreaBy2Pin(data1.rstPro, data1.rstVF, FALSE);
AcDb3dSolid* pIntPubSolid2 = GetThunderAreaBy2Pin(data2.rstPro, data2.rstVF, FALSE);
if (pIntPubSolid != NULL && pIntPubSolid2 != NULL)
{
AcDb3dSolid* pRetSolid = CreatePublicSolid(pIntPubSolid, data1.rstPro, data1.rstVF, vtDir);
if (pRetSolid != NULL)
{
double dHeight = lstData1.front().m_dHeight;
if (dHeight < lstData2.front().m_dHeight)
{
dHeight = lstData2.front().m_dHeight;
}
AcDb3dSolid* pPortSolid = CreateScissorSolid(data1, pIntPubSolid, pInt1, AcGeVector3d::kZAxis, dHeight*nScale);
if (pPortSolid != NULL)
{
arSolids.append(pPortSolid);
}
pPortSolid = CreateScissorSolid(data2, pIntPubSolid2, pInt2, AcGeVector3d::kZAxis, dHeight*nScale);
if (pPortSolid != NULL)
{
arSolids.append(pPortSolid);
}
arSolids.append(pRetSolid);
}
}
if (pIntPubSolid != NULL)
delete pIntPubSolid;
if (pIntPubSolid2 != NULL)
delete pIntPubSolid2;
arSolids.append(pInt1);
arSolids.append(pInt2);
}
else
{
if (pInt1 != NULL)
delete pInt1;
if (pInt2 != NULL)
delete pInt2;
}
}
return (arSolids.length() > 0);
}
AcDb3dSolid* TGDrawThunder::CreateScissorSolid(T3DCALCNODE& data, AcDb3dSolid* pPub, AcDb3dSolid* pPort, const AcGeVector3d& vtDir, double dLength)
{
AcDb3dSolid* pRetSolid = NULL;
if (pPub != NULL && pPort != NULL)
{
if (data.rstPort.m_ptInsert.distanceTo(data.rstVF.m_ptInsert) < 1e-3)
{
return pRetSolid;
}
// 创建三点实体
AcGePoint3dArray arPts;
arPts.append(data.rstPort.m_ptInsert);
arPts.append(data.rstPro.m_ptInsert);
arPts.append(data.rstVF.m_ptInsert);
// 整体
pRetSolid = CreateExtendSolid(arPts, vtDir, dLength);
if (pRetSolid != NULL)
{
// 被削减体
AcDbArc* pArc1 = GetSolidTopArc(pPub, data.rstPro, data.rstVF);
AcDbArc* pArc2 = GetSolidTopArc(pPort, data.rstPro, data.rstPort);
if (pArc1 != NULL && pArc2 != NULL)
{
AcGePoint3d ptTmp = data.rstPro.m_ptInsert;
ptTmp.z += data.rstPro.m_dHeight;
if (!DocGetMeterUnitDraw())
{
ptTmp.z *= 1000;
}
AcDbVoidPtrArray arFace;
CreateSliceFace(pArc1,ptTmp, pArc2, ptTmp, arFace);
AcDb3dSolid* pRemoveSolid = CreateRemovedSolid(pRetSolid, arFace, pArc1->center());
ReleasePtrArray(arFace);
CreateSliceFace(pArc2,ptTmp, pArc1, ptTmp, arFace);
AcDb3dSolid* pRemoveSolid2 = CreateRemovedSolid(pRetSolid, arFace, pArc2->center());
ReleasePtrArray(arFace);
AcDb3dSolid* pBackUp = new AcDb3dSolid;
pBackUp->copyFrom(pRetSolid);
if (pRemoveSolid != NULL)
{
if (pRetSolid->booleanOper(AcDb::kBoolSubtract, pRemoveSolid) != Acad::eOk)
{
pRetSolid->copyFrom(pBackUp);
}
else
{
pBackUp->copyFrom(pRetSolid);
}
delete pRemoveSolid;
}
if (pRemoveSolid2 != NULL)
{
if (pRetSolid->booleanOper(AcDb::kBoolSubtract, pRemoveSolid2) != Acad::eOk)
{
pRetSolid->copyFrom(pBackUp);
}
delete pRemoveSolid2;
}
delete pBackUp;
}
if (pArc1 != NULL)
delete pArc1;
if (pArc2 != NULL)
delete pArc2;
}
}
return pRetSolid;
}
AcDb3dSolid* TGDrawThunder::CreatePublicSolid(AcDb3dSolid* pIntPubSolid, CCaculateResult& rst1, CCaculateResult& rst2, const AcGeVector3d& vtDir)
{
AcDb3dSolid* pRetSolid = NULL;
if (pIntPubSolid != NULL)
{
AcGePlane plan;
AcGeVector3d vtPlan = rst1.m_ptInsert - rst2.m_ptInsert;
plan.set(rst1.m_ptInsert, vtPlan, AcGeVector3d::kZAxis);
AcDbRegion* pReg = NULL;
pIntPubSolid->getSection(plan, pReg);
if (pReg != NULL)
{
pRetSolid = ExtrudeSolid(pReg, vtDir, vtDir.length());
delete pReg;
}
}
return pRetSolid;
}
AcGeVector3d TGDrawThunder::GetPubleSolidExDir(const AcDbObjectId& id, T3DCALCNODE& data1, T3DCALCNODE& data2)
{
AcGeVector3d vtDir;
if (id.isValid())
{
OPENOBJ_BEGIN(id, AcDb::kForRead, AcDbPolyline, pLine);
if (pLine != NULL)
{
AcGePoint3d ptS, ptE;
pLine->getClosestPointTo(data2.rstPro.m_ptInsert, ptS);
pLine->getClosestPointTo(data1.rstPro.m_ptInsert, ptE);
vtDir = ptS - ptE;
}
OPENOBJ_END();
}
return vtDir;
}
void TGDrawThunder::AttachThunderData(lstCltResult& lstData1, lstCltResult& lstData2, T3DNODE& node1, T3DNODE& node2, T3DCALCNODE& data1, T3DCALCNODE& data2)
{
lstCltResult lstFind;
lstFind.insert(lstFind.end(), lstData1.begin(), lstData1.end());
lstFind.insert(lstFind.end(), lstData2.begin(), lstData2.end());
GetCltResultByPosition(lstFind, node1.ptPort, data1.rstPort);
GetCltResultByPosition(lstFind, node1.ptPro, data1.rstPro);
GetCltResultByPosition(lstFind, node2.ptPort, data2.rstPort);
GetCltResultByPosition(lstFind, node2.ptPro, data2.rstPro);
data1.rstVF = data1.rstPort;
data1.rstVF.m_ptInsert = node1.ptVF;
data1.rstVF.m_ptInsert.z = 0.0;
data2.rstVF = data2.rstPort;
data2.rstVF.m_ptInsert = node2.ptVF;
data2.rstVF.m_ptInsert.z = 0.0;
}
BOOL TGDrawThunder::GetCltResultByPosition(lstCltResult& lstSrc, const AcGePoint3d& ptPos, CCaculateResult& data)
{
int nScale = 1;
if (!DocGetMeterUnitDraw())
nScale *= 1000;
AcGePoint3d ptT;
lstCltResult::const_iterator it;
for (it = lstSrc.begin();it != lstSrc.end();++it)
{
ptT = it->m_ptInsert;
ptT.z += it->m_dHeight * nScale;
if (ptPos.distanceTo(ptT) < 1e-3)
{
data = *it;
return TRUE;
}
}
return FALSE;
}
BOOL TGDrawThunder::Get2LinePublicSegment(const AcDbObjectId& idLine, const AcDbObjectId& idLine2, T3DNODE& node1, T3DNODE& node2)
{
/************************************************************************
ptPro ptVF ptPort
+------+------+
| |
+----+------+
ptPort ptVF ptPro
************************************************************************/
BOOL bSuc = FALSE;
if (idLine.isValid() && idLine2.isValid())
{
OPENOBJ_BEGIN(idLine,AcDb::kForRead,AcDbPolyline,pCve1);
if (pCve1 != NULL)
{
OPENOBJ_BEGIN(idLine2,AcDb::kForRead,AcDbPolyline,pCve2);
if (pCve2 != NULL)
{
AcGePoint3d ptS,ptE,ptS2,ptE2;
pCve1->getStartPoint(ptS);
pCve1->getEndPoint(ptE);
pCve2->getStartPoint(ptS2);
pCve2->getEndPoint(ptE2);
AcGePoint3d ptVF,ptVF2;
AcDbLine ln(ptS,ptE);
AcDbLine ln2(ptS2,ptE2);
if ( CheckPoint2LineVerFootPoint(&ln, ptS2, ptVF) &&
!CheckPoint2LineVerFootPoint(&ln, ptE2, ptVF2) )
{
node1.ptPro = ptS2;
node1.ptVF = ptVF;
node1.ptPort = GetVFootLinePort(ptS2 - ptE2, &ln);
if ( CheckPoint2LineVerFootPoint(&ln2, ptS, ptVF) &&
!CheckPoint2LineVerFootPoint(&ln2, ptE, ptVF2))
{
node2.ptVF = ptVF;
node2.ptPro = ptS;
node2.ptPort = GetVFootLinePort(ptS - ptE, &ln2);
bSuc = TRUE;
}
else if ( CheckPoint2LineVerFootPoint(&ln2, ptE, ptVF) &&
!CheckPoint2LineVerFootPoint(&ln2, ptS, ptVF2))
{
node2.ptVF = ptVF;
node2.ptPro = ptE;
node2.ptPort = GetVFootLinePort(ptE - ptS, &ln2);
bSuc = TRUE;
}
else if (CheckPoint2LineVerFootPoint(&ln2, ptS, ptVF) &&
CheckPoint2LineVerFootPoint(&ln2, ptE, ptVF2))
{
node1.ptPro = ptS;
node1.ptVF = ptVF;
node1.ptPort = GetVFootLinePort(ptS - ptE, &ln2);
node2.ptPro = ptE;
node2.ptVF = ptVF2;
node2.ptPort = GetVFootLinePort(ptE - ptS, &ln2);
bSuc = TRUE;
}
}
else if ( CheckPoint2LineVerFootPoint(&ln, ptE2, ptVF) &&
!CheckPoint2LineVerFootPoint(&ln, ptS2, ptVF2))
{
node1.ptVF = ptVF;
node1.ptPro = ptE2;
node1.ptPort = GetVFootLinePort(ptE2 - ptS2, &ln);
if ( CheckPoint2LineVerFootPoint(&ln2, ptS, ptVF) &&
!CheckPoint2LineVerFootPoint(&ln2, ptE, ptVF2))
{
node2.ptVF = ptVF;
node2.ptPro = ptS;
node2.ptPort = GetVFootLinePort(ptS - ptE, &ln2);
bSuc = TRUE;
}
else if ( CheckPoint2LineVerFootPoint(&ln2, ptE, ptVF) &&
!CheckPoint2LineVerFootPoint(&ln2, ptS, ptVF2))
{
node2.ptVF = ptVF;
node2.ptPro = ptE;
node2.ptPort = GetVFootLinePort(ptE - ptS, &ln2);
bSuc = TRUE;
}
else if (CheckPoint2LineVerFootPoint(&ln2, ptS, ptVF) &&
CheckPoint2LineVerFootPoint(&ln2, ptE, ptVF2))
{
node1.ptPro = ptS;
node1.ptVF = ptVF;
node1.ptPort = GetVFootLinePort(ptS - ptE, &ln2);
node2.ptPro = ptE;
node2.ptVF = ptVF2;
node2.ptPort = GetVFootLinePort(ptE - ptS, &ln2);
bSuc = TRUE;
}
}
else if (CheckPoint2LineVerFootPoint(&ln, ptS2, ptVF) &&
CheckPoint2LineVerFootPoint(&ln, ptE2, ptVF2))
{
node1.ptPro = ptS2;
node1.ptVF = ptVF;
node1.ptPort = GetVFootLinePort(ptS2 - ptE2, &ln);
node2.ptPro = ptE2;
node2.ptVF = ptVF2;
node2.ptPort = GetVFootLinePort(ptE2 - ptS2, &ln);
bSuc = TRUE;
}
else if (!CheckPoint2LineVerFootPoint(&ln, ptS2, ptVF) &&
!CheckPoint2LineVerFootPoint(&ln, ptE2, ptVF2))
{
if (CheckPoint2LineVerFootPoint(&ln2, ptS, ptVF) &&
CheckPoint2LineVerFootPoint(&ln2, ptE, ptVF2))
{
node1.ptPro = ptS;
node1.ptVF = ptVF;
node1.ptPort = GetVFootLinePort(ptS - ptE, &ln2);
node2.ptPro = ptE;
node2.ptVF = ptVF2;
node2.ptPort = GetVFootLinePort(ptE - ptS, &ln2);
bSuc = TRUE;
}
}
}
OPENOBJ_END();
}
OPENOBJ_END();
}
return bSuc;
}
AcGePoint3d TGDrawThunder::GetVFootLinePort(const AcGeVector3d& vtDir, AcDbLine* pLine)
{
AcGePoint3d ptPort;
if (pLine != NULL)
{
AcGeVector3d vt = pLine->startPoint() - pLine->endPoint();
if (vt.isCodirectionalTo(vtDir))
{
ptPort = pLine->startPoint();
}
else
{
ptPort = pLine->endPoint();
}
}
return ptPort;
}
BOOL TGDrawThunder::CheckPoint2LineVerFootPoint(AcDbLine* pLine, const AcGePoint3d& pt, AcGePoint3d& ptVF)
{
BOOL bSuc = FALSE;
if (pLine != NULL)
{
pLine->getClosestPointTo(pt, ptVF, Adesk::kTrue);
AcGePoint3d ptT;
pLine->getClosestPointTo(ptVF, ptT, Adesk::kFalse);
if (ptVF.distanceTo(ptT) < 1e-3)
{
bSuc = TRUE;
}
}
return bSuc;
}
BOOL TGDrawThunder::BooleanOperSolid(AcDb3dSolid* pMainSolid, AcDb3dSolid* pSubSolid, AcDb::BoolOperType nType, const AcGeVector3d& vtDir, double dDist)
{
BOOL bSuc = FALSE;
if (pMainSolid != NULL &&
pSubSolid != NULL )
{
AcDb3dSolid* pNewMain = new AcDb3dSolid;
pNewMain->copyFrom(pMainSolid);
AcDb3dSolid* pNewSub = new AcDb3dSolid;
pNewSub->copyFrom(pSubSolid);
AcGeVector3d vtOff = vtDir.normal() * dDist;
AcGeMatrix3d mat;
mat.setToTranslation(vtOff);
pNewSub->transformBy(mat);
if (pNewMain->booleanOper(nType, pNewSub) == Acad::eOk)
{
pMainSolid->copyFrom(pNewMain);
bSuc = TRUE;
}
delete pNewMain;
delete pNewSub;
}
return bSuc;
}
AcDb3dSolid* TGDrawThunder::CreateRemovedSolid(AcDb3dSolid* pSolid, const AcDbVoidPtrArray& arFace, const AcGePoint3d& ptOr)
{
AcDb3dSolid* pRetSolid = NULL;
if (pSolid != NULL && arFace.length() > 0)
{
pRetSolid = new AcDb3dSolid;
pRetSolid->copyFrom(pSolid);
// 分割整个实体
AcDb3dSolid* pTmpSolid = NULL;
AcDbFace* pFace = NULL;
AcGePlane SlicePlan;
for (int i = 0;i < arFace.length();++i)
{
pFace = AcDbFace::cast((AcRxObject*)arFace[i]);
if (pFace != NULL)
{
GetPlaneFromSpecFace(pFace, ptOr, SlicePlan);
pRetSolid->getSlice(SlicePlan, Adesk::kFalse, pTmpSolid);
}
}
}
return pRetSolid;
}
AcDb3dSolid* TGDrawThunder::GetSolidFromFace(AcDbFace* pFace, double dHeight)
{
AcDb3dSolid* pSolid = NULL;
if (pFace != NULL)
{
AcGePoint3d arPt[4];
pFace->getVertexAt(0, arPt[0]);
pFace->getVertexAt(1, arPt[1]);
pFace->getVertexAt(2, arPt[2]);
arPt[3] = arPt[0];
AcDbLine* pLine = NULL;
AcDbVoidPtrArray arLines;
for (int i = 0;i < 3;++i)
{
pLine = new AcDbLine(arPt[i],arPt[i+1]);
arLines.append(pLine);
}
AcDbVoidPtrArray arRegs;
AcDbRegion::createFromCurves(arLines, arRegs);
if (arRegs.length() > 0)
{
AcDbRegion* pReg = AcDbRegion::cast((AcRxObject*)arRegs[0]);
if (pReg != NULL)
{
pSolid = new AcDb3dSolid;
pSolid->extrude(pReg, dHeight, 0.0);
}
}
ReleasePtrArray(arLines);
ReleasePtrArray(arRegs);
}
return pSolid;
}
void TGDrawThunder::GetPlaneFromSpecFace(AcDbFace* pFace, const AcGePoint3d& ptOr, AcGePlane& plan)
{
if (pFace != NULL)
{
AcGePoint3d pt1,pt2,pt3;
pFace->getVertexAt(0, pt1);
pFace->getVertexAt(1, pt2);
pFace->getVertexAt(2, pt3);
plan.set(pt1, pt2, pt3);
AcGePoint3d ptOn;
ptOn = ptOr.orthoProject(plan);
AcGeVector3d vtNor = ptOr - ptOn;
plan.set(ptOn, vtNor);
}
}
void TGDrawThunder::CreateSliceFace(AcDbArc* pMainArc, const AcGePoint3d& ptS1, AcDbArc* pSubArc, const AcGePoint3d& ptS2, AcDbVoidPtrArray& arFace)
{
if (pMainArc != NULL && pSubArc != NULL)
{
// 收集点
int i,j;
double dParaS,dParaE,dT;
AcGePoint3d ptOn;
AcGePoint3dArray arPt1,arPt2;
AcGeDoubleArray arDPara;
// 弧线1
pMainArc->getStartParam(dParaS);
pMainArc->getEndParam(dParaE);
int nCount = (int)((dParaE - dParaS)/DSPACE);
arDPara.append(dParaS);
for (i = 1;i <= nCount;++i)
{
dT = dParaS + DSPACE * i;
arDPara.append(dT);
}
arDPara.append(dParaE);
for (j = 0;j < arDPara.length();++j)
{
dT = arDPara[j];
pMainArc->getPointAtParam(dT, ptOn);
arPt1.append(ptOn);
}
if (arPt1.length() < 2) return;
// 弧线2
arDPara.setLogicalLength(0);
pSubArc->getStartParam(dParaS);
pSubArc->getEndParam(dParaE);
nCount = (int)((dParaE - dParaS)/DSPACE);
arDPara.append(dParaS);
for (i = 1;i < nCount;++i)
{
dT = dParaS + DSPACE * i;
arDPara.append(dT);
}
arDPara.append(dParaE);
for (j = 0;j < arDPara.length();++j)
{
dT = arDPara[j];
pSubArc->getPointAtParam(dT, ptOn);
arPt2.append(ptOn);
}
if (arPt2.length() < 2) return;
AcGePoint3d ptTmp;
pMainArc->getStartPoint(ptTmp);
if (ptTmp.distanceTo(ptS1) > 1e-3)
{
arPt1.reverse();
}
pSubArc->getStartPoint(ptTmp);
if (ptTmp.distanceTo(ptS2) > 1e-3)
{
arPt2.reverse();
}
if (ptS1.distanceTo(ptS2) < 1e-3)
{
arPt2.removeFirst();
}
// 创建face
AcDbFace* pFace = NULL;
if (arPt1.length() > arPt2.length())
{
for (i = 0;i < arPt1.length()-1;++i)
{
if (i >= arPt2.length())
{
pFace = new AcDbFace(arPt2.last(),arPt1[i],arPt1[i+1]);
arFace.append(pFace);
}
else
{
pFace = new AcDbFace(arPt2[i],arPt1[i],arPt1[i+1]);
arFace.append(pFace);
}
}
}
else
{
for (i = 0;i < arPt1.length()-1;++i)
{
pFace = new AcDbFace(arPt2[i],arPt1[i],arPt1[i+1]);
arFace.append(pFace);
}
for (i;i < arPt2.length()-1;++i)
{
pFace = new AcDbFace(arPt1.last(),arPt2[i],arPt2[i+1]);
arFace.append(pFace);
}
}
}
}
AcDbArc* TGDrawThunder::GetSolidTopArc(AcDb3dSolid* pSolid1,const CCaculateResult& result1,const CCaculateResult& result2)
{
AcDbArc* pArc = NULL;
if (pSolid1 != NULL)
{
std::list<LINEPTPAIR> lstPtPair;
LINEPTPAIR ptPair;
AcGePoint3d ptS,ptE;
int nScale = 1;
if (!DocGetMeterUnitDraw())
{
nScale *= 1000;
}
ptPair.pt1 = result1.m_ptInsert;
ptPair.pt1.z += result1.m_dHeight * nScale;
ptPair.pt2 = result2.m_ptInsert;
ptPair.pt2.z += result2.m_dHeight * nScale;
lstPtPair.push_back(ptPair);
pArc = GetSolidTopArcByLoop(pSolid1, lstPtPair);
}
return pArc;
}
AcDbArc* TGDrawThunder::GetSolidTopArcByLoop(AcDbEntity* pEnt, std::list<LINEPTPAIR>& lstPtPair)
{
AcDbArc* pRetArc = NULL;
if (pEnt != NULL)
{
AcDbVoidPtrArray arPtr;
pEnt->explode(arPtr);
AcGePoint3d ptS,ptE;
AcGePoint3d ptT,ptT2;
AcDbArc* pArc = NULL;
for (int i = 0;i < arPtr.length();++i)
{
pArc = AcDbArc::cast((AcDbEntity*)arPtr[i]);
if (pArc != NULL)
{
pArc->getStartPoint(ptS);
pArc->getEndPoint(ptE);
std::list<LINEPTPAIR>::iterator it;
for (it = lstPtPair.begin();it != lstPtPair.end();++it)
{
ptT = it->pt1;
ptT2 = it->pt2;
if ((ptS.distanceTo(it->pt1) < 1e-3 &&
ptE.distanceTo(it->pt2) < 1e-3 ) ||
(ptS.distanceTo(it->pt2) < 1e-3 &&
ptE.distanceTo(it->pt1) < 1e-3 ) )
{
pRetArc = new AcDbArc;
pRetArc->copyFrom(pArc);
break;
}
}
if (pRetArc != NULL) break;
}
else
{
pRetArc = GetSolidTopArcByLoop((AcDbEntity*)arPtr[i], lstPtPair);
if (pRetArc != NULL)
{
break;
}
}
}
ReleasePtrArray(arPtr);
}
return pRetArc;
}
AcDb3dSolid* TGDrawThunder::CreateExtendSolid(const AcGePoint3dArray& arPts, const AcGeVector3d& vtDir, double dLength)
{
AcDb3dSolid* pRetSolid = NULL;
if (arPts.length() > 2)
{
AcGePoint3dArray arLoc;
arLoc.append(arPts);
arLoc.append(arPts.first());
AcDbLine* pLine = NULL;
AcDbVoidPtrArray arLines,arRegs;
int nCount = arLoc.length() - 1;
for (int i = 0;i < nCount;++i)
{
pLine = new AcDbLine(arLoc[i], arLoc[i+1]);
arLines.append(pLine);
}
AcDbRegion::createFromCurves(arLines, arRegs);
if (arRegs.length() > 0)
{
AcDbRegion* pReg = AcDbRegion::cast((AcRxObject*)arRegs[0]);
if (pReg != NULL)
{
pRetSolid = ExtrudeSolid(pReg, vtDir, dLength);
}
}
ReleasePtrArray(arLines);
ReleasePtrArray(arRegs);
}
return pRetSolid;
}
void TGDrawThunder::ReleasePtrArray(AcDbVoidPtrArray& arPtr)
{
for (int i = 0;i < arPtr.length();++i)
{
delete (AcDbEntity*)arPtr[i];
}
arPtr.setLogicalLength(0);
}
void TGDrawThunder::ShowPtrArray(AcDbVoidPtrArray& arPtr)
{
AcDbGroup* pGroup = new AcDbGroup;
for (int i = 0;i < arPtr.length();++i)
{
pGroup->append(AddToCurrentSpace((AcDbEntity*)arPtr[i], Adesk::kTrue));
}
AcDbDictionary* pGroupDict = NULL;
acdbHostApplicationServices()->workingDatabase()
->getGroupDictionary(pGroupDict, AcDb::kForWrite);
if (pGroupDict != NULL)
{
AcDbObjectId id;
pGroupDict->setAt(_T("*A"),pGroup,id);
pGroupDict->close();
pGroup->close();
}
else
{
delete pGroup;
}
arPtr.setLogicalLength(0);
}
AcDbLine* TGDrawThunder::GetSolidExtrudePath(AcDb3dSolid* pSolid1, AcDb3dSolid* pSolid2, std::list<LINEPTPAIR>& lstPtPair)
{
AcDbLine* pLine = NULL;
if (pSolid1 != NULL &&
pSolid2 != NULL &&
lstPtPair.size() > 0)
{
AcGePoint3d ptS,ptE;
if (GetSolidCopingLowPoint(pSolid1, lstPtPair, ptS) &&
GetSolidCopingLowPoint(pSolid2, lstPtPair, ptE) )
{
pLine = new AcDbLine(ptS, ptE);
}
}
return pLine;
}
BOOL TGDrawThunder::GetSolidCopingLowPoint(AcDbEntity* pEnt, std::list<LINEPTPAIR>& lstPtPair, AcGePoint3d& ptOut)
{
BOOL bSuc = FALSE;
if (pEnt != NULL)
{
AcDbVoidPtrArray arPtr;
pEnt->explode(arPtr);
AcGePoint3d ptS,ptE;
AcDbArc* pArc = NULL;
for (int i = 0;i < arPtr.length();++i)
{
pArc = AcDbArc::cast((AcDbEntity*)arPtr[i]);
if (pArc != NULL)
{
pArc->getStartPoint(ptS);
pArc->getEndPoint(ptE);
std::list<LINEPTPAIR>::iterator it;
for (it = lstPtPair.begin();it != lstPtPair.end();++it)
{
if ((ptS.distanceTo(it->pt1) < 1e-3 &&
ptE.distanceTo(it->pt2) < 1e-3 ) ||
(ptS.distanceTo(it->pt2) < 1e-3 &&
ptE.distanceTo(it->pt1) < 1e-3 ) )
{
ptOut = GetArcMidPiont(pArc, it->pt1, it->pt2);
bSuc = TRUE;
break;
}
}
if (bSuc) break;
}
else
{
if (GetSolidCopingLowPoint((AcDbEntity*)arPtr[i], lstPtPair, ptOut))
{
bSuc = TRUE;
break;
}
}
}
for (int j = 0;j < arPtr.length();++j)
{
delete (AcDbEntity*)arPtr[j];
}
}
return bSuc;
}
AcGePoint3d TGDrawThunder::GetArcMidPiont(AcDbArc* pArc, const AcGePoint3d& ptS, const AcGePoint3d& ptE)
{
if (pArc != NULL)
{
AcDbLine ln(ptS, ptE);
AcGePoint3d ptOn;
AcGePoint3d ptCent = pArc->center();
ln.getClosestPointTo(ptCent, ptOn);
ln.setStartPoint(ptOn);
ln.setEndPoint(ptCent);
AcGePoint3dArray arPt;
ln.intersectWith(pArc, AcDb::kExtendThis, arPt);
if (arPt.length() > 0)
{
return arPt.first();
}
}
return AcGePoint3d::kOrigin;
}
AcDb3dSolid* TGDrawThunder::CreateUnion3DRegion(const AcDb3dSolid* pBaseSolid,CCaculateResult& data1,CCaculateResult& data2,AcDbCurve* pCve)
{
if (pBaseSolid == NULL || pCve == NULL)
{
return NULL;
}
AcDb3dSolid* pSolid = NULL;
// 截取面reg
AcGeVector3d vt = data2.m_ptInsert - data1.m_ptInsert;
AcGePlane plan;
plan.set(data1.m_ptInsert,vt,AcGeVector3d::kZAxis);
AcDbRegion* pReg = NULL;
Acad::ErrorStatus es = pBaseSolid->getSection(plan, pReg);
if (pReg != NULL)
{
pSolid = ExtrudeSolidAlongPath(pReg, pCve);
delete pReg;
}
return pSolid;
}
AcDb3dSolid* TGDrawThunder::CreateBoolSubtractSolid(const AcDb3dSolid* pBaseSolid,CCaculateResult& data1,CCaculateResult& data2,AcDbCurve* pCve)
{
if (pBaseSolid == NULL || pCve == NULL)
{
return NULL;
}
AcDb3dSolid* pSolid = NULL;
// 创建reg
AcGePoint3d pt1 = data1.m_ptInsert;
AcGePoint3d pt2 = data2.m_ptInsert;
AcGePoint3d pt3 = pt2;
AcGePoint3d pt4 = pt1;
int nScale = 1;
if (!DocGetMeterUnitDraw())
{
nScale *= 1000;
}
double dH = data1.m_dHeight;
if (dH < data2.m_dHeight)
dH = data2.m_dHeight;
pt1.z += dH * nScale;
pt2.z += dH * nScale;
AcDbVoidPtrArray arPtr;
AcDbLine* pLine = NULL;
pLine = new AcDbLine(pt1, pt2);
arPtr.append(pLine);
pLine = new AcDbLine(pt2, pt3);
arPtr.append(pLine);
pLine = new AcDbLine(pt3, pt4);
arPtr.append(pLine);
pLine = new AcDbLine(pt4, pt1);
arPtr.append(pLine);
AcDbVoidPtrArray arRegions;
AcDbRegion::createFromCurves(arPtr, arRegions);
ReleasePtrArray(arPtr);
if (arRegions.length() < 1)
{
return NULL;
}
AcDbRegion* pReg = (AcDbRegion*)arRegions[0];
if (pReg != NULL)
{
AcGePoint3d ptS,ptE;
CalcLinePorts(pReg, pCve, ptS, ptE);
AcGeVector3d vt = ptS - ptE;
ptE = ptS + vt;
AcGeVector3d vtNor = CalcRegionNormal(ptE, pReg);
pSolid = ExtrudeSolid(pReg, vtNor, vt.length());
}
ReleasePtrArray(arRegions);
return pSolid;
}
void TGDrawThunder::DrawThunder2DArea(LPCTSTR pszGroupNo, const AcDbObjectIdArray& arID)
{
if (pszGroupNo == NULL ||
arID.length() < 1)
{
return;
}
CTGTempTol locTol(0.1, 0.1);
// 计算避雷针数据
AcGeDoubleArray arProHeight;
CThunderXData xd;
xd.GetProtectHeightFromObjEx(arID[0], arProHeight);
lstCltResult lstData;
CalcThunderData(pszGroupNo, arProHeight, arID, lstData);
// 绘制三维
DrawThunder3DArea(pszGroupNo, lstData, TRUE);
}
void TGDrawThunder::DrawThunderLine(LPCTSTR pszGroupNo, const AcDbObjectIdArray& arID)
{
if (pszGroupNo == NULL ||
arID.length() < 1)
{
return;
}
CTGTempTol locTol(0.1, 0.1);
// 计算避雷针数据
AcGeDoubleArray arProHeight;
CThunderXData xd;
xd.GetProtectHeightFromObjEx(arID[0], arProHeight);
MapThunderLineCltResult mapData;
CalcThunLineData(pszGroupNo, arProHeight, arID, mapData);
// 绘制避雷线三维
DrawThunLine3D(pszGroupNo, mapData, TRUE);
}
AcGePoint3d TGDrawThunder::CalcSolidTopPoint(const CCaculateResult& result)
{
int nScale = 1;
if (!DocGetMeterUnitDraw())
nScale *= 1000;
AcGePoint3d ptTop;
if (result.m_dHeight < result.m_dGroundRadius)
{
ptTop = result.m_ptInsert;
ptTop.z += result.m_dHeight*nScale;
}
else
{
AcGePoint3d ptS = result.m_ptInsert;
AcGePoint3d ptE = ptS;
ptE.z += result.m_dHeight*nScale;
AcDbLine ln(ptS,ptE);
AcDbCircle cir(result.m_ptGroundCenter,AcGeVector3d::kXAxis,result.m_dGroundRadius*nScale);
AcGePoint3dArray arPt;
ln.intersectWith(&cir,AcDb::kOnBothOperands,arPt);
if (arPt.length() == 1)
{
ptTop = arPt.first();
}
else if (arPt.length() == 2)
{
double dDist1 = ptS.distanceTo(arPt.first());
double dDist2 = ptS.distanceTo(arPt.last());
if (dDist1 > dDist2)
{
ptTop = arPt.last();
}
else
{
ptTop = arPt.first();
}
}
}
return ptTop;
}
//生成单针的避雷区域实体
AcDb3dSolid* TGDrawThunder::Create3DSolid(const CCaculateResult& result)
{
int nScale = 1;
if (!DocGetMeterUnitDraw())
nScale *= 1000;
AcGePoint3d ptStart = result.m_ptInsert;
AcGePoint3d ptEnd = CalcSolidTopPoint(result);
AcDbLine* pLine = new AcDbLine;
pLine->setStartPoint(ptStart);
pLine->setEndPoint(ptEnd);
pLine->setNormal(AcGeVector3d::kXAxis);
// CopyEnt(pLine);
//得到需要旋转的REG
AcGePoint3d ptReg = result.m_ptGroundCenter;
ptReg.z = 0.0;
AcDbLine* pLine2 = new AcDbLine;
pLine2->setStartPoint(ptReg);
pLine2->setEndPoint(ptStart);
pLine2->setNormal(AcGeVector3d::kXAxis);
// CopyEnt(pLine2);
AcDbCircle cir(result.m_ptGroundCenter,AcGeVector3d::kXAxis,result.m_dGroundRadius*nScale);
AcDbArc* pArc = GetArcSegmentFromCircle(&cir, ptEnd, ptReg);
// CopyEnt(pArc);
AcDbVoidPtrArray arPtrs;
arPtrs.append(pArc);
arPtrs.append(pLine);
arPtrs.append(pLine2);
//生成3D实体
AcDb3dSolid *pSolid = NULL;
AcDbVoidPtrArray arRegions;
AcDbRegion::createFromCurves(arPtrs, arRegions);
if (arRegions.length() > 0)
{
AcDbRegion* pRegion = AcDbRegion::cast((AcDbEntity*)arRegions[0]);
if (pRegion != NULL)
{
AcGeVector3d vtAxis = ptEnd - ptStart;
AcDbRevolveOptions rev;
pSolid = new AcDb3dSolid;
Acad::ErrorStatus es = pSolid->revolve(pRegion,result.m_ptInsert,vtAxis,2 * PI);
//acutPrintf(_T("\nrevolve %d!"),es);
//ZWCAD 不支持,改为微分方式
//acedAlert(_T("ZRX 开发包目前没有实现AcDb3dSolid 接口!"));
}
}
ReleasePtrArray(arPtrs);
ReleasePtrArray(arRegions);
return pSolid;
}
AcDbArc* TGDrawThunder::GetArcSegmentFromCircle(AcDbCircle* pCir, const AcGePoint3d& ptS, const AcGePoint3d& ptE, BOOL bInferior)
{
AcDbArc* pArc = NULL;
if (pCir != NULL)
{
double dPara,dPara2;
pCir->getParamAtPoint(ptS,dPara);
pCir->getParamAtPoint(ptE,dPara2);
if (fabs(dPara-0.0) < 1e-3 &&
dPara2 > PI )
{
dPara = 2*PI;
}
else if (fabs(dPara2-0.0) < 1e-3 &&
dPara > PI)
{
dPara2 = 2*PI;
}
if (bInferior) // 劣弧
{
if (dPara > dPara2)
{
double dT = dPara;
dPara = dPara2;
dPara2 = dT;
}
}
else // 优弧
{
if (dPara < dPara2)
{
double dT = dPara;
dPara = dPara2;
dPara2 = dT;
}
}
pArc = new AcDbArc(pCir->center(), pCir->normal(), pCir->radius(), dPara, dPara2);
}
return pArc;
}
//得到2针的避雷区域
AcDb3dSolid* TGDrawThunder::GetThunderAreaBy2Pin(const CCaculateResult& result1,const CCaculateResult& result2,BOOL bCheck)
{
AcDb3dSolid* pRetInt = NULL;
double dHeight1 = 0.0,dHeight2 = 0.0,dGroundRadius = 0.0,dProRadius1 = 0.0,dProRadius2 = 0.0;
double dScale = 1.0;
if (!DocGetMeterUnitDraw())
dScale *= 1000;
dHeight1 = result1.m_dHeight*dScale;
dHeight2 = result2.m_dHeight*dScale;
dGroundRadius = result1.m_dGroundRadius*dScale;
dProRadius1 = result1.m_dProRadius*dScale;
dProRadius2 = result2.m_dProRadius*dScale;
//判断两针之间是否有影响
if (bCheck)
{
double dDis = result1.m_ptInsert.distanceTo(result2.m_ptInsert);
if (fabs(dHeight1 - dHeight2) < 0.01)
{
if (dDis >= 2*pow(dHeight2*(2*dGroundRadius-dHeight2),0.5))
{
return pRetInt;
}
}
else
{
if (dDis >= pow(dHeight1*(2*dGroundRadius-dHeight1),0.5) + pow(dHeight2*(2*dGroundRadius-dHeight2),0.5))
{
return pRetInt;
}
}
}
AcDb3dSolid *pCircleSolid1 = NULL;
AcDb3dSolid *pCircleSolid2 = NULL;
AcDb3dSolid *pTopSolid = NULL;
//生成滚球实体
GetSphereSolids(result1.m_ptInsert,result2.m_ptInsert,dProRadius1,dProRadius2,dGroundRadius,pCircleSolid1,pCircleSolid2);
if (pCircleSolid1 != NULL && pCircleSolid2 != NULL)
{
pTopSolid = GetTopSphereSolid(result1,result2,dGroundRadius);
pRetInt = Get2DIntersectionArea(result1,result2);
if (pRetInt != NULL && pTopSolid != NULL)
{
// 如果布尔运算失败则会删除两实体的内部对象
// 此处要做保留操作
AcDb3dSolid* pTmpInt = new AcDb3dSolid;
pTmpInt->copyFrom(pRetInt);
if (pRetInt->booleanOper(AcDb::kBoolSubtract,pCircleSolid1) != Acad::eOk)
{
pRetInt->copyFrom(pTmpInt);
}
else
{
pTmpInt->copyFrom(pRetInt);
};
if (pRetInt->booleanOper(AcDb::kBoolSubtract,pCircleSolid2) != Acad::eOk)
{
pRetInt->copyFrom(pTmpInt);
}
else
{
pTmpInt->copyFrom(pRetInt);
}
if (fabs(result1.m_dHeight-result2.m_dHeight) < 1e-3)
{
if (pRetInt->booleanOper(AcDb::kBoolSubtract,pTopSolid) != Acad::eOk)
{
pRetInt->copyFrom(pTmpInt);
}
}
delete pTmpInt;
}
}
if (pCircleSolid1 != NULL)
delete pCircleSolid1;
if (pCircleSolid2 != NULL)
delete pCircleSolid2;
if (pTopSolid != NULL)
delete pTopSolid;
return pRetInt;
}
//生成滚球实体
void TGDrawThunder::GetSphereSolids(const AcGePoint3d& ptInsert1,const AcGePoint3d& ptInsert2,double dProRadius1,double dProRadius2,double dGroundRadius,AcDb3dSolid*& pCircleSolid1,AcDb3dSolid*& pCircleSolid2)
{
AcDbCircle circle1(ptInsert1,AcGeVector3d::kZAxis,dProRadius1);
AcDbCircle circle2(ptInsert2,AcGeVector3d::kZAxis,dProRadius2);
AcGePoint3dArray arPt;
IntersectWith2Circle(&circle1, &circle2, arPt);
if (arPt.length() != 2)
{
return;
}
//得到最大保护半径的交点
AcGeMatrix3d matrix;
AcGePoint3d ptCen1 = arPt[0];
AcGePoint3d ptCen2 = arPt[1];
ptCen1.z += dGroundRadius;
ptCen2.z += dGroundRadius;
pCircleSolid1 = new AcDb3dSolid;
if (pCircleSolid1 != NULL)
{
pCircleSolid1->createSphere(dGroundRadius);
matrix.setToTranslation(ptCen1.asVector());
pCircleSolid1->transformBy(matrix);
}
pCircleSolid2 = new AcDb3dSolid;
if (pCircleSolid2 != NULL)
{
pCircleSolid2->createSphere(dGroundRadius);
matrix.setToTranslation(ptCen2.asVector());
pCircleSolid2->transformBy(matrix);
}
}
//生成2避雷针中间一块区域
AcDb3dSolid* TGDrawThunder::Get2DIntersectionArea(const CCaculateResult& result1,const CCaculateResult& result2)
{
AcDb3dSolid* pSolid = new AcDb3dSolid;
if (pSolid == NULL)
return NULL;
double dHeight1 = result1.m_dHeight;
double dHeight2 = result2.m_dHeight;
if (!DocGetMeterUnitDraw())
{
dHeight1 *= 1000;
dHeight2 *= 1000;
}
AcDbRegion *pRegion = GetRegionByCircle(result1,result2);
if (pRegion == NULL)
{
delete pSolid;
return NULL;
}
Acad::ErrorStatus es;
if (dHeight2 > dHeight1)
es = pSolid->extrude(pRegion,dHeight2,0);
else
es = pSolid->extrude(pRegion,dHeight1,0);
delete pRegion;
return pSolid;
}
//生成顶部球实体
AcDb3dSolid* TGDrawThunder::GetTopSphereSolid(const CCaculateResult& result1,const CCaculateResult& result2,double dGroundRadius,AcGePoint3d* pt)
{
AcGePoint3d ptCen,ptThunderCen1,ptThunderCen2;
ptThunderCen1 = result1.m_ptInsert;
ptThunderCen2 = result2.m_ptInsert;
double dHeight1 = 0.0,dHeight2 = 0.0;
if (!DocGetMeterUnitDraw())
{
dHeight1 = result1.m_dHeight*1000;
dHeight2 = result2.m_dHeight*1000;
}
else
{
dHeight1 = result1.m_dHeight;
dHeight2 = result2.m_dHeight;
}
double dDis = result1.m_ptInsert.distanceTo(result2.m_ptInsert);
double dDisLeft = (pow(dGroundRadius-dHeight2,2) - pow(dGroundRadius-dHeight1,2) + pow(dDis,2))/(2*dDis);
AcDbLine line(result1.m_ptInsert,result2.m_ptInsert);
line.getPointAtDist(dDisLeft,ptCen);
ptCen.z += dGroundRadius;
ptThunderCen1.z += dHeight1;
ptThunderCen2.z += dHeight2;
double dRadius = ptThunderCen1.distanceTo(ptCen);
Acad::ErrorStatus es;
AcDb3dSolid *pSolid = new AcDb3dSolid;
if (pSolid == NULL)
return NULL;
es = pSolid->createSphere(dRadius);
AcGeMatrix3d matrix;
matrix.setCoordSystem(ptCen,AcGeVector3d::kXAxis,AcGeVector3d::kYAxis,AcGeVector3d::kZAxis);
pSolid->transformBy(matrix);
if (pt != NULL)
{
*pt = ptCen;
}
return pSolid;
}
//生成3维实体对象
void TGDrawThunder::MakeThunderEntity(LPCTSTR pszGroupNo, lstCltResult& lstData, BOOL bPreview)
{
AcDb3dSolid *pSolid = NULL;
CThunderXData thundXData;
//单针实体
lstCltResult::iterator it;
for (it = lstData.begin();it != lstData.end();++it)
{
pSolid = Create3DSolid(*it);
if (pSolid != NULL)
{
pSolid->setLayer(m_strLayer3d);
pSolid->setColorIndex(m_nMultiPinColorIndex);
thundXData.SetXData(pSolid, TEL_GROUP_NO, pszGroupNo);
if (bPreview)
{
pSolid->setLayer(LAY_PREVIEW_THUNDER);
m_arPreview.append(pSolid);
}
else
{
m_arRegSolid.append(pSolid);
}
}
}
//生成2避雷针的区域
lstCltResult::iterator itSub;
for (it = lstData.begin();it != lstData.end();++it)
{
itSub = it;
itSub++;
for (itSub;itSub != lstData.end();++itSub)
{
pSolid = GetThunderAreaBy2Pin(*it,*itSub);
if (pSolid != NULL)
{
pSolid->setLayer(m_strLayer3d);
pSolid->setColorIndex(m_nMultiPinColorIndex);
thundXData.SetXData(pSolid, TEL_GROUP_NO, pszGroupNo);
if (bPreview)
{
pSolid->setLayer(LAY_PREVIEW_THUNDER);
m_arPreview.append(pSolid);
}
else
{
m_arRegSolid.append(pSolid);
}
}
}
}
//生成3避雷针的区域
if (lstData.size() >= 3)
Make3CenThunderEntity(pszGroupNo, lstData, bPreview);
}
//显示层
void TGDrawThunder::ShowLayer(LPCTSTR lpLayerName,BOOL bShow)
{
if (lpLayerName == NULL)
return;
AcDbLayerTable *pLayerTable = NULL;
acdbHostApplicationServices()->workingDatabase()
->getSymbolTable(pLayerTable, AcDb::kForRead);
AcDbLayerTableRecord *pRecord = NULL;
AcDbObjectId id;
pLayerTable->getAt(lpLayerName,pRecord,AcDb::kForWrite);
pLayerTable->close();
if (pRecord == NULL)
return;
if (_tcsicmp(lpLayerName,LAY_PREVIEW_THUNDER) == 0)
{
AcCmColor color;
color.setColorIndex(4);
pRecord->setColor(color);
}
if (bShow)
pRecord->setIsOff(FALSE);
else
pRecord->setIsOff(TRUE);
pRecord->close();
}
//生成3针形成中间的避雷区域
void TGDrawThunder::Make3CenThunderEntity(LPCTSTR pszGroupNo, lstCltResult& lstData,BOOL bPreview, AcDbVoidPtrArray* pArPtr)
{
if (lstData.size() == 0)
{
return;
}
AcArray<AcGePoint3d> arPtInsert;
AcGeDoubleArray arRadius;
lstCltResult::iterator it;
double dScale = 1.0;
if (!DocGetMeterUnitDraw())
dScale *= 1000;
for (it = lstData.begin();it != lstData.end();++it)
{
arPtInsert.append(it->m_ptInsert);
arRadius.append(it->m_dProRadius*dScale);
}
Acad::ErrorStatus es;
AcArray<AcDb3dSolid*> arSolid;
AcArray<AcGePoint3d> arPt;
//得到联合区域的边部滚球
GetSphereSolids(arPtInsert,arRadius,lstData.front().m_dGroundRadius*dScale,arSolid,arPt);
AcArray<AcDb3dSolid*> arInterSolid;
//得到中间区域
Get3DIntersectionArea(lstData,arPt,arInterSolid);
if (arInterSolid.length() == 0)
return;
CThunderXData thundXData;
AcDbVoidPtrArray arTop;
for (int m = 0; m < arInterSolid.length(); ++m)
{
if (m > 0)
{
GetSphereSolids(arPtInsert,arRadius,lstData.front().m_dGroundRadius*dScale,arSolid,arPt);
}
for (int k = 0; k < arSolid.length(); k++)
{
es = arInterSolid[m]->booleanOper(AcDb::kBoolSubtract,arSolid[k]);
}
GetTopSphereSolid(lstData,arTop);
if (arTop.length() < 1)
{
arSolid.setLogicalLength(0);
arPt.setLogicalLength(0);
delete arInterSolid[m];
continue;
}
for (int j = 0; j < arTop.length(); j++)
{
es = arInterSolid[m]->booleanOper(AcDb::kBoolSubtract,(AcDb3dSolid*)arTop[j]);
delete (AcDb3dSolid*)arTop[j];
}
arTop.setLogicalLength(0);
if (arInterSolid[m] != NULL)
{
arInterSolid[m]->setLayer(m_strLayer3d);
arInterSolid[m]->setColorIndex(m_nMultiPinColorIndex);
thundXData.SetXData(arInterSolid[m], TEL_GROUP_NO, pszGroupNo);
if (bPreview)
{
arInterSolid[m]->setLayer(LAY_PREVIEW_THUNDER);
m_arPreview.append(arInterSolid[m]);
if (pArPtr != NULL)
{
AcDb3dSolid* pSolid = new AcDb3dSolid;
pSolid->copyFrom(arInterSolid[m]);
pArPtr->append(pSolid);
}
}
else
{
m_arRegSolid.append(arInterSolid[m]);
if (pArPtr != NULL)
{
AcDb3dSolid* pSolid = new AcDb3dSolid;
pSolid->copyFrom(arInterSolid[m]);
pArPtr->append(pSolid);
}
}
}
arPt.setLogicalLength(0);
}
}
//得到3针滚球球心
BOOL TGDrawThunder::Get3PinSphereCen(const AcGePoint3d& pt1,const AcGePoint3d& pt2,const AcGePoint3d& pt3,double dGroundRadius,const AcGeVector3d& vecParal,AcGePoint3d& ptCenter,double dProRadius)
{
AcGePlane plan(pt1,pt2,pt3);
AcGeVector3d vecNormal = plan.normal();
AcGeVector3d vec12,vec23,vec31;
vec12 = pt1 - pt2;
vec23 = pt2 - pt3;
vec31 = pt3 - pt1;
AcGeVector3d vecNormal12,vecNormal23,vecNormal31;
AcGePlane plan12(pt1,vec12,vecNormal);
AcGePlane plan23(pt2,vec23,vecNormal);
AcGePlane plan31(pt3,vec31,vecNormal);
vecNormal12 = plan12.normal();
vecNormal23 = plan23.normal();
vecNormal31 = plan31.normal();
vecNormal12.normalize();
vecNormal23.normalize();
vecNormal31.normalize();
//得到各边中点
AcGePoint3d ptCen12,ptCen23,ptCen31;
ptCen12.x = (pt1.x + pt2.x)/2;
ptCen12.y = (pt1.y + pt2.y)/2;
ptCen12.z = (pt1.z + pt2.z)/2;
ptCen23.x = (pt3.x + pt2.x)/2;
ptCen23.y = (pt3.y + pt2.y)/2;
ptCen23.z = (pt3.z + pt2.z)/2;
ptCen31.x = (pt1.x + pt3.x)/2;
ptCen31.y = (pt1.y + pt3.y)/2;
ptCen31.z = (pt1.z + pt3.z)/2;
AcGePoint3d ptEnd12,ptEnd23,ptEnd31;
AcGePoint3d ptStart12,ptStart23,ptStart31;
ptEnd12 = ptCen12 + vecNormal12*dGroundRadius;
ptEnd23 = ptCen23 + vecNormal23*dGroundRadius;
ptEnd31 = ptCen31 + vecNormal31*dGroundRadius;
ptStart12 = ptCen12 - vecNormal12*dGroundRadius;
ptStart23 = ptCen23 - vecNormal23*dGroundRadius;
ptStart31 = ptCen31 - vecNormal31*dGroundRadius;
AcDbLine line12(ptStart12,ptEnd12);
AcDbLine line23(ptStart23,ptEnd23);
AcGePoint3dArray arPts;
line12.intersectWith(&line23,AcDb::kExtendBoth,arPts);
if (arPts.length() != 1)
return FALSE;
//中垂线交点到点距离
double dDis = arPts[0].distanceTo(pt1);
if (dDis > dProRadius)
return FALSE;
//球心到面的投影距离
double dDisPer = pow(pow(dGroundRadius,2) - pow(dDis,2),0.5);
vecNormal.normalize();
if (vecNormal.angleTo(vecParal) < PI/2)
ptCenter = arPts[0] + vecNormal*dDisPer;
else
ptCenter = arPts[0] - vecNormal*dDisPer;
return TRUE;
}
//生成3避雷针中间一块区域
AcDb3dSolid* TGDrawThunder::Get3DIntersectionArea(const CCaculateResult& result1,const CCaculateResult& result2,const CCaculateResult& result3 )
{
AcArray<AcGePoint3d> arPtInter;
double dRadius1 = result1.m_dProRadius;
double dRadius2 = result2.m_dProRadius;
double dRadius3 = result3.m_dProRadius;
if (!DocGetMeterUnitDraw()) //毫米单位
{
dRadius1 *= 1000;
dRadius2 *= 1000;
dRadius3 *= 1000;
}
Get3PeripheryPoints(result1.m_ptInsert,result2.m_ptInsert,result3.m_ptInsert,dRadius1,dRadius2,dRadius3,arPtInter);
AcDbVoidPtrArray arRegs;
AcDbLine line;
for (int i = 0; i < arPtInter.length(); ++i)
{
if (result1.m_ptInsert.distanceTo(arPtInter[i]) - dRadius1 < 0.01)
{
AcDbLine *pLine = new AcDbLine(result1.m_ptInsert,arPtInter[i]);
arRegs.append(pLine);
}
if (result2.m_ptInsert.distanceTo(arPtInter[i]) - dRadius2 < 0.01)
{
AcDbLine *pLine = new AcDbLine(result2.m_ptInsert,arPtInter[i]);
arRegs.append(pLine);
}
if (result3.m_ptInsert.distanceTo(arPtInter[i]) - dRadius3 < 0.01)
{
AcDbLine *pLine = new AcDbLine(result3.m_ptInsert,arPtInter[i]);
pLine->setColorIndex(1);
arRegs.append(pLine);
}
}
AcDbVoidPtrArray arRegions;
arRegions.setPhysicalLength(10);
arRegions.setGrowLength(1);
AcDbRegion::createFromCurves(arRegs, arRegions);
ReleasePtrArray(arRegs);
if (arRegions.length() != 1)
return NULL;
AcDbRegion *pReg = AcDbRegion::cast((AcRxObject*)arRegions[0]);
if (pReg == NULL)
return NULL;
double dHeight1 = result1.m_dHeight;
double dHeight2 = result2.m_dHeight;
double dHeight3 = result3.m_dHeight;
double dGroundRadius = result3.m_dGroundRadius;
if (!DocGetMeterUnitDraw())
{
dHeight1 *= 1000;
dHeight2 *= 1000;
dHeight3 *= 1000;
dGroundRadius *= 1000;
}
Acad::ErrorStatus es;
AcDb3dSolid *pSolid = new AcDb3dSolid;
if (dHeight1 >= dHeight2 && dHeight1 >= dHeight3)
es = pSolid->extrude(pReg,dHeight1,0);
else if (dHeight2 >= dHeight3 && dHeight2 >= dHeight1)
es = pSolid->extrude(pReg,dHeight2,0);
else if (dHeight3 >= dHeight2 && dHeight3 >= dHeight1)
es = pSolid->extrude(pReg,dHeight3,0);
ReleasePtrArray(arRegions);
return pSolid;
}
//得到两圆圆心到交点连成的REG
AcDbRegion *TGDrawThunder::GetRegionByCircle(const CCaculateResult& result1,const CCaculateResult& result2)
{
AcGePoint3d ptStart,ptEnd;
ptStart = result1.m_ptInsert;
ptEnd = result2.m_ptInsert;
double dProRadius1 = result1.m_dProRadius;
double dProRadius2 = result2.m_dProRadius;
if (!DocGetMeterUnitDraw())
{
dProRadius1 *= 1000;
dProRadius2 *= 1000;
}
AcDbCircle circle1(ptStart,AcGeVector3d::kZAxis,dProRadius1);
AcDbCircle circle2(ptEnd,AcGeVector3d::kZAxis,dProRadius2);
AcGePoint3dArray arPt;
IntersectWith2Circle(&circle1, &circle2, arPt);
if (arPt.length() != 2)
return NULL;
//构造3维体
AcDbLine line1(arPt[0],result1.m_ptInsert);
AcDbLine line2(result1.m_ptInsert,arPt[1]);
AcDbLine line3(arPt[1],result2.m_ptInsert);
AcDbLine line4(result2.m_ptInsert,arPt[0]);
AcDbVoidPtrArray arRegs;
arRegs.append(&line1);
arRegs.append(&line2);
arRegs.append(&line3);
arRegs.append(&line4);
AcDbVoidPtrArray arRegions;
AcDbRegion::createFromCurves(arRegs, arRegions);
if (arRegions.length() != 1)
{
ReleasePtrArray(arRegions);
return NULL;
}
AcDbRegion *pRegion= AcDbRegion::cast((AcRxObject*)arRegions[0]);
return pRegion;
}
void TGDrawThunder::Get3PeripheryPoints(const AcGePoint3d& ptInsert1,const AcGePoint3d& ptInsert2,const AcGePoint3d& ptInsert3,double dProRadius1,double dProRadius2,double dProRadius3,AcArray<AcGePoint3d>& arPtInter)
{
AcGePoint3d ptSphere1,ptSphere2,ptSphere3;
AcDbCircle circle1(ptInsert1,AcGeVector3d::kZAxis,dProRadius1);
AcDbCircle circle2(ptInsert2,AcGeVector3d::kZAxis,dProRadius2);
AcGePoint3dArray arPt1;
IntersectWith2Circle(&circle1, &circle2, arPt1);
if (arPt1.length() != 2)
return;
if (arPt1[0].distanceTo(ptInsert3) > arPt1[1].distanceTo(ptInsert3))
ptSphere1 = arPt1[0];
else
ptSphere1 = arPt1[1];
AcDbCircle circle3(ptInsert2,AcGeVector3d::kZAxis,dProRadius2);
AcDbCircle circle4(ptInsert3,AcGeVector3d::kZAxis,dProRadius3);
AcGePoint3dArray arPt2;
IntersectWith2Circle(&circle3, &circle4, arPt2);
if (arPt2.length() != 2)
return;
if (arPt2[0].distanceTo(ptInsert1) > arPt2[1].distanceTo(ptInsert1))
ptSphere2 = arPt2[0];
else
ptSphere2 = arPt2[1];
AcDbCircle circle5(ptInsert3,AcGeVector3d::kZAxis,dProRadius3);
AcDbCircle circle6(ptInsert1,AcGeVector3d::kZAxis,dProRadius1);
AcGePoint3dArray arPt3;
IntersectWith2Circle(&circle5, &circle6, arPt3);
if (arPt3.length() != 2)
return;
if (arPt3[0].distanceTo(ptInsert2) > arPt3[1].distanceTo(ptInsert2))
ptSphere3 = arPt3[0];
else
ptSphere3 = arPt3[1];
arPtInter.append(ptSphere1);
arPtInter.append(ptSphere2);
arPtInter.append(ptSphere3);
}
void TGDrawThunder::GetSphereSolids(const AcArray<AcGePoint3d>& arPt,const AcGeDoubleArray& arRadius,double dGroundRadius,AcArray<AcDb3dSolid*>& arSolid,AcArray<AcGePoint3d>& arPtSec)
{
if (arPt.length() != arRadius.length())
return;
BOOL bHasResult = TRUE;
for (int i = 0; i < arPt.length(); ++i)
{
for (int j = i + 1; j < arPt.length(); ++j)
{
AcDbCircle circle1(arPt[i],AcGeVector3d::kZAxis,arRadius[i]);
AcDbCircle circle2(arPt[j],AcGeVector3d::kZAxis,arRadius[j]);
AcGePoint3dArray arPtInter;
IntersectWith2Circle(&circle1, &circle2, arPtInter);
if (arPtInter.length() != 2)
continue;
for (int k = 0; k < arPt.length(); ++k)
{
if (k == i || k == j)
continue;
if (arPtInter[0].distanceTo(arPt[k]) < arRadius[k])
bHasResult = FALSE;
}
if (bHasResult)
arPtSec.append(arPtInter[0]);
bHasResult = TRUE;
for (int l = 0; l < arPt.length(); ++l)
{
if (l == i || l == j)
continue;
if (arPtInter[1].distanceTo(arPt[l]) < arRadius[l])
bHasResult = FALSE;
}
if (bHasResult)
arPtSec.append(arPtInter[1]);
bHasResult = TRUE;
}
}
AcGePoint3d ptResult;
for (int m = 0; m < arPtSec.length(); ++m)
{
ptResult = arPtSec[m];
ptResult.z += dGroundRadius;
AcDb3dSolid *pSolid = new AcDb3dSolid;
pSolid->createSphere(dGroundRadius);
AcGeMatrix3d matrix;
matrix.setCoordSystem(ptResult,AcGeVector3d::kXAxis,AcGeVector3d::kYAxis,AcGeVector3d::kZAxis);
pSolid->transformBy(matrix);
arSolid.append(pSolid);
}
}
//生成顶部球体和中间区域
void TGDrawThunder::GetTopSphereSolid(lstCltResult& arResult, AcDbVoidPtrArray& arTopPtr)
{
AcGePoint3dArray arPt;
if (arResult.size() <= 0)
return;
double dGroundRadius = arResult.front().m_dGroundRadius;
double dProRadius = 0.0;
double dScale = 1.0;
if (!DocGetMeterUnitDraw())
{
dGroundRadius *= 1000;
dProRadius *= 1000;
dScale *= 1000;
}
lstCltResult::iterator it,itSub,itThird;
for (it = arResult.begin();it != arResult.end();++it)
{
itSub = it;
itSub++;
for (itSub;itSub != arResult.end(); ++itSub)
{
itThird = itSub;
itThird++;
for (itThird;itThird != arResult.end();++itThird)
{
double dHeight1 = it->m_dHeight;
double dHeight2 = itSub->m_dHeight;
double dHeight3 = itThird->m_dHeight;
if (!DocGetMeterUnitDraw())
{
dHeight1 *= 1000;
dHeight2 *= 1000;
dHeight3 *= 1000;
}
AcGePoint3d ptTop1 = it->m_ptInsert;
AcGePoint3d ptTop2 = itSub->m_ptInsert;
AcGePoint3d ptTop3 = itThird->m_ptInsert;
ptTop1.z += dHeight1;
ptTop2.z += dHeight2;
ptTop3.z += dHeight3;
AcGeVector3d vecParal = ptTop1 - it->m_ptInsert;
AcGePoint3d ptCen;
double dDis = 0.0;
dProRadius = it->m_dProRadius*dScale;
if (Get3PinSphereCen(ptTop1,ptTop2,ptTop3,dGroundRadius,vecParal,ptCen,dProRadius))
{
BOOL bNeedSphere = TRUE;
AcGePoint3d ptTemp;
lstCltResult::iterator itL;
for (itL = arResult.begin();itL != arResult.end();++itL)
{
if (itL == it || itL == itThird || itL == itSub)
{
continue;
}
ptTemp = itL->m_ptInsert;
if (!DocGetMeterUnitDraw())
ptTemp.z += 1000*itL->m_dHeight;
else
ptTemp.z += itL->m_dHeight;
double dDisdis = ptCen.distanceTo(ptTemp);
if (dGroundRadius - dDisdis > 0.00001)
{
bNeedSphere = FALSE;
break;
}
}
if (bNeedSphere)
arPt.append(ptCen);
else
bNeedSphere = TRUE;
}
}
}
}
for (int m = 0; m < arPt.length(); ++m)
{
AcDb3dSolid *pSolid = new AcDb3dSolid;
pSolid->createSphere(dGroundRadius);
AcGeMatrix3d matrix;
matrix.setCoordSystem(arPt[m],AcGeVector3d::kXAxis,AcGeVector3d::kYAxis,AcGeVector3d::kZAxis);
pSolid->transformBy(matrix);
arTopPtr.append(pSolid);
}
}
//得到中间区域
void TGDrawThunder::Get3DIntersectionArea(lstCltResult& arResult,const AcArray<AcGePoint3d>& arPtInter,AcArray<AcDb3dSolid*>& arSolid)
{
if (arResult.size() <= 0)
return;
AcDbVoidPtrArray arRegs;
double dRadius = 0.0;
AcGePoint3d ptT,ptInterT;
lstCltResult::iterator it;
for (int i = 0; i < arPtInter.length(); ++i)
{
for (it = arResult.begin();it != arResult.end();++it)
{
if (!DocGetMeterUnitDraw())
dRadius = it->m_dProRadius*1000;
else
dRadius = it->m_dProRadius;
if (it->m_ptInsert.distanceTo(arPtInter[i]) - dRadius < 0.01)
{
AcDbLine *pLine = new AcDbLine(it->m_ptInsert,arPtInter[i]);
arRegs.append(pLine);
}
}
}
Acad::ErrorStatus es;
AcDbVoidPtrArray arRegions;
es = AcDbRegion::createFromCurves(arRegs, arRegions);
ReleasePtrArray(arRegs);
if (arRegions.length() < 1)
return;
double dGroundRadius = arResult.front().m_dGroundRadius;
if (!DocGetMeterUnitDraw())
{
dGroundRadius *= 1000;
}
double dArea = 0.0;
for (int l = 0; l < arRegions.length(); ++l)
{
AcDbRegion *pRegTemp = AcDbRegion::cast((AcRxObject*)arRegions[l]);
AcDb3dSolid *pSolid = new AcDb3dSolid;
es = pSolid->extrude(pRegTemp,dGroundRadius,0);
arSolid.append(pSolid);
}
ReleasePtrArray(arRegions);
}
void TGDrawThunder::DeleteAllEntities(LPCTSTR pszGroupNo)
{
ThunderContainer->EreaseSpecGNoCircl(pszGroupNo);
ThunderContainer->EreaseSpecGNoRegion(pszGroupNo);
ThunderContainer->EreaseSpecGNo3dSolid(pszGroupNo);
m_arRegSolid.setLogicalLength(0);
}
// 更改图层
void TGDrawThunder::Set2dLayer(const CString& strLayer2d)
{
m_strLayer2d = strLayer2d;
}
void TGDrawThunder::Set3dLayer(const CString& strLayer3d)
{
m_strLayer3d = strLayer3d;
}
int TGDrawThunder::GetNowCaculateResult(lstCltResult& lstData)
{
lstData.clear();
TContainerSingleton::LstGroupIDMap mapData;
TContainerSingleton::LstGroupIDMap::iterator it;
ThunderContainer->GetThunderMap(mapData);
CStringArray arsXData;
CThunderXData thundXData;
TGLightningRodData ltnData;
TGThunderCaculate caculate;
AcGePoint3d ptInsert;
TContainerSingleton::LstIDData lstID;
TContainerSingleton::LstIDData::iterator itLst;
AcGeDoubleArray arProHeight;
int nMaxProSize = 0;
for (it = mapData.begin();it != mapData.end();++it)
{
lstID = it->second;
if (lstID.size() < 1) continue;
thundXData.GetProtectHeightFromObjEx(lstID.front(), arProHeight);
if (arProHeight.length() > nMaxProSize)
{
nMaxProSize = arProHeight.length();
}
for (itLst = lstID.begin();itLst != lstID.end();++itLst)
{
ptInsert = ThunderContainer->GetThunderInsertPosition(*itLst);
if (thundXData.GetBaseInformationExData(*itLst, arsXData, TEL_THUNDER_BASEINFOR) )
{
ltnData.SetGroundRadius(_tstof(arsXData.GetAt(CThunderXData::eXDataPinRadius)));
ltnData.SetHeight(_tstof(arsXData.GetAt(CThunderXData::eXDataPinHeight)));
ltnData.SetNumber(_ttoi(arsXData.GetAt(CThunderXData::eXDataPinNum)));
ltnData.SetInsertPoint(ptInsert);
ltnData.SetObjectID(*itLst);
ltnData.SetGroupNO(_ttoi(it->first));
ltnData.m_arProtecedHeight.setLogicalLength(0);
ltnData.m_arProtecedHeight.append(arProHeight);
caculate.CaculateThunderData(&ltnData);
lstData.push_back(caculate.m_result);
}
}
}
return nMaxProSize;
}
BOOL TGDrawThunder::CheckHasRepeatNum(AcDbObjectIdArray& arID, AcDbObjectIdArray& arIDRepeated)
{
arIDRepeated.setLogicalLength(0);
if (arID.length() < 1)
{
return FALSE;
}
std::list<int> lstNum;
std::list<int>::iterator it;
CString sNum;
CThunderXData xd;
AcDbObjectIdArray arLoc;
for (int i = 0;i < arID.length();++i)
{
if (arID[i].isValid())
{
xd.GetXData(arID[i], TEL_ORDER_NUMBER, sNum);
if ((it = std::find(lstNum.begin(),lstNum.end(),_ttoi(sNum))) != lstNum.end())
{
arIDRepeated.append(arID[i]);
}
else
{
lstNum.push_back(_ttoi(sNum));
arLoc.append(arID[i]);
}
}
}
arID.setLogicalLength(0);
arID.append(arLoc);
return arIDRepeated.length() > 0;
}
void TGDrawThunder::DrawThunderCircle(const AcGeDoubleArray& arProHeight, LPCTSTR pszGroupNo, const AcDbObjectIdArray& arID)
{
if (pszGroupNo == NULL || arID.length() < 1)
{
return;
}
// 绘制圆
CThunderXData thunderXData;
AcDbObjectId idCir;
AcDbObjectIdArray arThun,arCir;
CStringArray arXData;
CString sTemp;
AcGePoint3d ptInsert;
for (int i = 0;i < arID.length();++i)
{
ptInsert = ThunderContainer->GetThunderInsertPosition(arID[i]);
thunderXData.SetProtectHeightToObjEx(arID[i], arProHeight);
thunderXData.GetBaseInformationExData(arID[i], arXData, TEL_THUNDER_BASEINFOR);
for (int j = 0;j < arProHeight.length();++j)
{
idCir = DrawCircleRingThunder(arXData, ptInsert, arProHeight[j]);
if (idCir.isValid())
{
sTemp.Format(_T("%g"),arProHeight[j]);
thunderXData.SetXData(idCir,TEL_CURRENT_PROHEIGHT,sTemp);
thunderXData.SetXData(idCir, TEL_GROUP_NO, pszGroupNo);
thunderXData.SetProtectHeightToObjEx(idCir, arProHeight);
arCir.append(idCir);
}
}
// 将避雷针id存入多个圆的扩展数据
arThun.append(arID[i]);
for (int k = 0;k < arCir.length();++k)
{
thunderXData.SetEntityIdToExData(arThun, arCir[k], TEL_THUNDER_ID);
}
// 将多个圆存入避雷针的扩展数据
thunderXData.SetEntityIdToExData(arCir, arID[i], TEL_THUNDER_ID);
ThunderContainer->AppendCircle(pszGroupNo, arCir);
arCir.setLogicalLength(0);
arThun.setLogicalLength(0);
}
}
// 在避雷针的周围画圆
AcDbObjectId TGDrawThunder::DrawCircleRingThunder(const CStringArray& arXData, AcGePoint3d& ptInsert, double dProHt)
{
AcDbObjectId idCir = AcDbObjectId::kNull;
if (arXData.GetSize() < 3)
{
return idCir;
}
AcDbCircle* pCircle = NULL;
double dRadius = 0.0;
double dScale = 1.0;
if (!DocGetMeterUnitDraw())
dScale = 1000.0;
else
dScale = 1.0;
dRadius = pow((_tstof(arXData.GetAt(CThunderXData::eXDataPinHeight))) *
(2 * (_tstof(arXData.GetAt(CThunderXData::eXDataPinRadius))) -
(_tstof(arXData.GetAt(CThunderXData::eXDataPinHeight)))), 0.5) -
pow((dProHt) *
(2 * (_tstof(arXData.GetAt(CThunderXData::eXDataPinRadius))) - dProHt), 0.5);
double dValue = 0.0;
dValue = dProHt * dScale;
ptInsert[Z] = dValue;
pCircle = new AcDbCircle(ptInsert, AcGeVector3d::kZAxis, dRadius * dScale);
if (pCircle == NULL)
{
return idCir;
}
pCircle->setLayer(LAY_EL_THUNDER_2D);
pCircle->setColorIndex(m_nSinglePinColorIndex);
idCir = AddToCurrentSpace(pCircle, Adesk::kTrue);
return idCir;
}
BOOL TGDrawThunder::CalcThunderData(LPCTSTR pszGNo, const AcGeDoubleArray& arProHeight, const AcDbObjectIdArray& arID, lstCltResult& lstData)
{
lstData.clear();
if (pszGNo != NULL && arID.length() > 0)
{
AcDbObjectIdArray arLoc(arID);
// 检查是否存在避雷针编号重复
AcDbObjectIdArray arRepeate;
if (CheckHasRepeatNum(arLoc,arRepeate))
{
acutPrintf(_T("\n 存在重复的避雷针编号,请修改编号。"));
}
CStringArray arsXData;
CThunderXData thundXData;
TGLightningRodData ltnData;
TGThunderCaculate caculate;
AcGePoint3d ptInsert;
for (int i = 0;i < arLoc.length();++i)
{
ptInsert = ThunderContainer->GetThunderInsertPosition(arLoc[i]);
if (thundXData.GetBaseInformationExData(arLoc[i], arsXData, TEL_THUNDER_BASEINFOR) )
{
ltnData.SetGroundRadius(_tstof(arsXData.GetAt(CThunderXData::eXDataPinRadius)));
ltnData.SetHeight(_tstof(arsXData.GetAt(CThunderXData::eXDataPinHeight)));
ltnData.SetNumber(_ttoi(arsXData.GetAt(CThunderXData::eXDataPinNum)));
ltnData.SetInsertPoint(ptInsert);
ltnData.SetObjectID(arLoc[i]);
ltnData.SetGroupNO(_ttoi(pszGNo));
ltnData.m_arProtecedHeight.setLogicalLength(0);
ltnData.m_arProtecedHeight.append(arProHeight);
caculate.CaculateThunderData(&ltnData);
lstData.push_back(caculate.m_result);
}
}
}
return (lstData.size() > 0);
}
void TGDrawThunder::PickupSymbolBySpecGroupNO(PickSet& ssSymbol, LPCTSTR pszGroupNo)
{
if (pszGroupNo != NULL && _ttoi(pszGroupNo) > 0)
{
PickSet ssTmp(SS_FREE);
CThunderXData thundXData;
CString sGroupNo;
for (long i = 0;i < ssSymbol.Length();++i)
{
OPENOBJ_BEGIN(ssSymbol[i],AcDb::kForRead,AcDbEntity,pEnt);
if (pEnt != NULL)
{
thundXData.GetXData(pEnt, TEL_GROUP_NO, sGroupNo);
}
OPENOBJ_END();
if (sGroupNo.CompareNoCase(pszGroupNo) == 0)
{
ssTmp += ssSymbol[i];
sGroupNo.Empty();
}
}
ssSymbol.Free();
ssSymbol += ssTmp;
}
}
AcDbObjectId TGDrawThunder::CopyEnt(AcDbEntity* pEnt)
{
AcDbObjectId id;
if (pEnt)
{
AcDbEntity* pNew = CopyEntPtr(pEnt);
if (pNew)
{
id = AddToCurrentSpace(pNew,Adesk::kTrue);
}
}
return id;
}
AcDbEntity* TGDrawThunder::CopyEntPtr(AcDbEntity* pEnt)
{
AcDbEntity* pLoc = NULL;
if (pEnt)
{
AcDb3dSolid* pp = AcDb3dSolid::cast(pEnt);
if (pp)
{
pLoc = new AcDb3dSolid;
pLoc->copyFrom(pEnt);
}
AcDbLine* p2 = AcDbLine::cast(pEnt);
if (p2)
{
pLoc = new AcDbLine;
pLoc->copyFrom(pEnt);
}
AcDbArc* p3 = AcDbArc::cast(pEnt);
if (p3)
{
pLoc = new AcDbArc;
pLoc->copyFrom(pEnt);
}
AcDbRegion* pReg = AcDbRegion::cast(pEnt);
if (pReg)
{
pLoc = new AcDbRegion;
pLoc->copyFrom(pEnt);
}
}
return pLoc;
}
void TGDrawThunder::EreaseObj(const AcDbObjectId& id)
{
if (id.isValid())
{
OPENOBJ_BEGIN(id,AcDb::kForWrite,AcDbEntity,pEnt);
if (pEnt != NULL)
{
pEnt->erase();
}
OPENOBJ_END();
}
}
BOOL TGDrawThunder::IntersectWith2Circle(AcDbCircle* pCir1, AcDbCircle* pCir2, AcGePoint3dArray& arPt)
{
if (pCir1 != NULL && pCir2 != NULL)
{
pCir1->intersectWith(pCir2, AcDb::kOnBothOperands, arPt);
if (arPt.length() < 1)
{
double dRadius1 = pCir1->radius();
double dRadius2 = pCir2->radius();
double dDist = pCir1->center().distanceTo(pCir2->center());
if (fabs(dDist - (dRadius1+dRadius2)) < 1e-3) // 相切
{
AcDbLine ln(pCir1->center(), pCir2->center());
ln.intersectWith(pCir1, AcDb::kOnBothOperands, arPt);
}
else if (dDist < (dRadius1+dRadius2)) // 相交
{
AcDbVoidPtrArray arPtr,arReg1,arReg2;
AcDbCircle* pC1 = new AcDbCircle(pCir1->center(), pCir1->normal(), pCir1->radius());
arPtr.append(pC1);
AcDbRegion::createFromCurves(arPtr, arReg1);
ReleasePtrArray(arPtr);
AcDbCircle* pC2 = new AcDbCircle(pCir2->center(), pCir2->normal(), pCir2->radius());
arPtr.append(pC2);
AcDbRegion::createFromCurves(arPtr, arReg2);
ReleasePtrArray(arPtr);
if (arReg1.length() > 0 && arReg2.length() > 0)
{
AcDbRegion* pReg1 = (AcDbRegion*)arReg1.first();
AcDbRegion* pReg2 = (AcDbRegion*)arReg2.first();
if (pReg1 != NULL && pReg2 != NULL)
{
pReg1->booleanOper(AcDb::kBoolIntersect, pReg2);
AcGePoint3d ptT;
AcDbVoidPtrArray arExplode;
pReg1->explode(arExplode);
AcDbArc* pArc = NULL;
for (int i = 0;i < arExplode.length();++i)
{
pArc = (AcDbArc*)arExplode[i];
if (pArc != NULL)
{
pArc->getStartPoint(ptT);
arPt.append(ptT);
pArc->getEndPoint(ptT);
arPt.append(ptT);
break;
}
}
ReleasePtrArray(arExplode);
}
}
ReleasePtrArray(arReg1);
ReleasePtrArray(arReg2);
}
}
}
return arPt.length() > 0;
}
AcDb3dSolid* TGDrawThunder::CreateRepair3DSolid(AcDb3dSolid* pInt1,const CCaculateResult& pInt1Data1,const CCaculateResult& pInt1Data2,
AcDb3dSolid* pInt2,const CCaculateResult& pInt2Data1,const CCaculateResult& pInt2Data2)
{
AcDb3dSolid* pRetSolid = NULL;
if (pInt1 == NULL || pInt2 == NULL)
{
return pRetSolid;
}
// 截取面reg
AcGeVector3d vt = pInt1Data1.m_ptInsert - pInt1Data2.m_ptInsert;
AcGePlane plan;
plan.set(pInt1Data1.m_ptInsert,vt,AcGeVector3d::kZAxis);
AcDbRegion* pReg = NULL;
pInt1->getSection(plan, pReg);
if (pReg == NULL) return pRetSolid;
vt = pInt2Data1.m_ptInsert - pInt2Data2.m_ptInsert;
plan.set(pInt2Data1.m_ptInsert,vt,AcGeVector3d::kZAxis);
AcDbRegion* pReg2 = NULL;
pInt2->getSection(plan, pReg2);
if (pReg2 == NULL)
{
delete pReg;
return pRetSolid;
}
// 计算延伸路径
AcDbLine path;
CalcStretchPaht(pReg,pInt1Data1,pInt1Data2,pReg2,pInt2Data1,pInt2Data2,&path);
// 取需要延伸实体的reg
double dDist1 = pInt1Data1.m_ptInsert.distanceTo(pInt1Data2.m_ptInsert);
double dDist2 = pInt2Data1.m_ptInsert.distanceTo(pInt2Data2.m_ptInsert);
if (dDist1 > dDist2)
{
pRetSolid = ExtrudeSolidAlongPath(pReg2, &path);
}
else
{
pRetSolid = ExtrudeSolidAlongPath(pReg, &path);
}
delete pReg;
delete pReg2;
return pRetSolid;
}
BOOL TGDrawThunder::CalcStretchPaht(AcDbEntity* pEnt1,const CCaculateResult& pInt1Data1,const CCaculateResult& pInt1Data2,
AcDbEntity* pEnt2,const CCaculateResult& pInt2Data1,const CCaculateResult& pInt2Data2,
AcDbLine* pPath)
{
if (pEnt1 != NULL &&
pEnt2 != NULL &&
pPath != NULL )
{
std::list<LINEPTPAIR> lstPtPair;
LINEPTPAIR ptPair;
AcGePoint3d ptS,ptE;
int nScale = 1;
if (!DocGetMeterUnitDraw())
{
nScale *= 1000;
}
ptPair.pt1 = pInt1Data1.m_ptInsert;
ptPair.pt1.z += pInt1Data1.m_dHeight * nScale;
ptPair.pt2 = pInt1Data2.m_ptInsert;
ptPair.pt2.z += pInt1Data2.m_dHeight * nScale;
lstPtPair.push_back(ptPair);
ptPair.pt1 = pInt2Data1.m_ptInsert;
ptPair.pt1.z += pInt2Data1.m_dHeight * nScale;
ptPair.pt2 = pInt2Data2.m_ptInsert;
ptPair.pt2.z += pInt2Data2.m_dHeight * nScale;
lstPtPair.push_back(ptPair);
if (GetSolidCopingLowPoint(pEnt1, lstPtPair, ptS) &&
GetSolidCopingLowPoint(pEnt2, lstPtPair, ptE) )
{
pPath->setStartPoint(ptS);
pPath->setEndPoint(ptE);
return TRUE;
}
}
return FALSE;
}