3751 lines
89 KiB
C++
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(<nData);
|
|
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(<nData);
|
|
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(<nData);
|
|
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(<nData);
|
|
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;
|
|
}
|