Files
envi-code/SourceCode/Code2026/ThunderProof/FoldPinRelation.cpp
T
2026-09-28 15:28:50 +08:00

2768 lines
64 KiB
C++

#include "stdafx.h"
#include "FoldPinRelation.h"
#include "ThunderXData.h"
#include "ThunderCmdGroup.h"
#include "FoldProTool.h"
#include "dbgroup.h "
#include "ktsetting.h"
CFoldPinRelation* CFoldPinRelation::m_pInstance = NULL;
CFoldPinRelation::CFoldPinRelation(void)
{
m_pProTool = new CFoldProTool;
}
CFoldPinRelation::~CFoldPinRelation(void)
{
if(m_pProTool)
delete m_pProTool;
}
CFoldPinRelation* CFoldPinRelation::Instance()
{
if (m_pInstance == NULL)
{
m_pInstance = new CFoldPinRelation;
}
return m_pInstance;
}
void CFoldPinRelation::DisInstance()
{
delete m_pInstance;
}
void CFoldPinRelation::GetAllFoldThunder(FOLDPINGROUP& FoldLst)
{
FoldLst.clear();
FoldLst = m_arAllPoldPin;
}
//由ID建立到数据结构的映射
void CFoldPinRelation::ReadDataFromID(const AcDbObjectId& oid,XFoldThunder& FoldThunder)
{
if (oid.isValid())
{
AcGePoint3d ptPos;
memset(&FoldThunder,0,sizeof(XFoldThunder));
ads_name entName;
acdbGetAdsName(entName,oid);
Entity ent(entName);
ent.GetData(10,&ptPos);
// 编号,高度,图块系数, 字体高度
CThunderXData thundXData;
CStringArray arXData;
CString sTemp;
thundXData.GetBaseInformationExData(oid,arXData,TEL_THUNDER_BASEINFOR);
if (arXData.GetCount() == 0)
return;
int nGroup = thundXData.GetFoldGroupNO(oid);
sTemp = arXData.GetAt(CThunderXData::eXFoldPinNum);
int nNO = _ttoi(sTemp);
sTemp = arXData.GetAt(CThunderXData::eXFoldPinHeight);
double dHeight = _tstof(sTemp);
//保护高度
AcGeDoubleArray arProHeights;
thundXData.GetFoldProHeightFromObjEx(oid,arProHeights);
FoldThunder.m_nNo = nNO;
FoldThunder.m_nGroup = nGroup;
FoldThunder.m_dHeight = dHeight;
FoldThunder.m_arProHeight = arProHeights;
FoldThunder.m_ptPos = ptPos;
FoldThunder.m_Id = oid;
}
}
void CFoldPinRelation::ReadDataFromID(AcDbEntity* pEnt,XFoldThunder& FoldThunder)
{
if (pEnt == NULL)
{
return;
}
AcDbBlockReference* pRef = AcDbBlockReference::cast(pEnt);
if (pRef == NULL)
{
return;
}
AcGePoint3d ptPos;
memset(&FoldThunder,0,sizeof(XFoldThunder));
ptPos = pRef->position();
// 编号,高度,图块系数, 字体高度
CThunderXData thundXData;
CStringArray arXData;
CString sTemp;
thundXData.GetBaseInformationExData(pEnt,arXData,TEL_THUNDER_BASEINFOR);
if (arXData.GetCount() == 0)
return;
int nGroup = thundXData.GetFoldGroupNO(pEnt);
sTemp = arXData.GetAt(CThunderXData::eXFoldPinNum);
int nNO = _ttoi(sTemp);
sTemp = arXData.GetAt(CThunderXData::eXFoldPinHeight);
double dHeight = _tstof(sTemp);
//保护高度
AcGeDoubleArray arProHeights;
thundXData.GetFoldProHeightFromObjEx(pEnt,arProHeights);
FoldThunder.m_nNo = nNO;
FoldThunder.m_nGroup = nGroup;
FoldThunder.m_dHeight = dHeight;
FoldThunder.m_arProHeight = arProHeights;
FoldThunder.m_ptPos = ptPos;
FoldThunder.m_Id = pEnt->objectId();
}
//过滤所有避雷针
void CFoldPinRelation::FilterAllFoldPin()
{
//过滤器
if (m_arAllPoldPin.size() > 0)
{
m_arAllPoldPin.erase(m_arAllPoldPin.begin(),m_arAllPoldPin.end());
}
RBList rb = ads_buildlist(RTDXF0,_T("INSERT"),2,_T("$Ectrical$00000112"),NULL);
PickSet ss(SS_FREE);
ss.Get(_T("X"),NULL,NULL,rb);
CThunderXData thundXData;
CStringArray arXData;
AcDbObjectId oid;
int nGroup = 0;
int nNO = 0;
double dHeight = 0.0;
AcGeDoubleArray arProHeights;
CString sTemp = _T("");
AcGePoint3d ptPos;
for (long i = 0;i < ss.Length();++i)
{
acdbGetObjectId(oid,ss[i]);
if (oid.isValid())
{
ss[i].GetData(10,&ptPos);
// 编号,高度,图块系数, 字体高度
arXData.RemoveAll();
thundXData.GetBaseInformationExData(oid,arXData,TEL_THUNDER_BASEINFOR);
if (arXData.GetCount() == 0)
{
continue;
}
nGroup = thundXData.GetFoldGroupNO(oid);
sTemp = arXData.GetAt(CThunderXData::eXFoldPinNum);
nNO = _ttoi(sTemp);
sTemp = arXData.GetAt(CThunderXData::eXFoldPinHeight);
dHeight = _tstof(sTemp);
//保护高度
thundXData.GetFoldProHeightFromObjEx(oid,arProHeights);
XFoldThunder FoldThunder;
FoldThunder.m_nNo = nNO;
FoldThunder.m_nGroup = nGroup;
FoldThunder.m_dHeight = dHeight;
FoldThunder.m_arProHeight = arProHeights;
FoldThunder.m_ptPos = ptPos;
FoldThunder.m_Id = oid;
AddFoldPinToMap(FoldThunder);
}
}
}
//添加避雷针
void CFoldPinRelation::AddFoldPinToMap(const XFoldThunder& FoldThunder)
{
int nGroup = FoldThunder.m_nGroup;
int nNo = FoldThunder.m_nNo;
XFoldThunder thunder;
memset(&thunder,0,sizeof(XFoldThunder));
thunder = FoldThunder;
if (m_arAllPoldPin.find(nGroup) == m_arAllPoldPin.end())
{
FOLDPINLST PinList;
PinList.push_back(thunder);
m_arAllPoldPin.insert(std::make_pair(nGroup,PinList));
}
else
{
int nPos = 0;
FOLDPINLST& PinList = m_arAllPoldPin[nGroup];
if (!IsExist(thunder,PinList,nPos))
{
PinList.push_back(thunder);
}
else
{
PinList[nPos] = thunder;
}
}
}
//添加避雷针
void CFoldPinRelation::AddFoldPinToMap(const AcDbObjectId& oid)
{
XFoldThunder FoldThunder;
memset(&FoldThunder,0,sizeof(XFoldThunder));
if (oid.isValid())
{
ads_name ent_name;
AcGePoint3d ptPos;
int nGroup,nNO;
CString sTemp;
double dHeight;
CThunderXData thundXData;
AcGeDoubleArray arProHeights;
CStringArray arXData;
acdbGetAdsName(ent_name,oid);
Entity ent(ent_name);
ent.GetData(10,&ptPos);
// 编号,高度,图块系数, 字体高度
thundXData.GetBaseInformationExData(oid,arXData,TEL_THUNDER_BASEINFOR);
if (arXData.GetCount() == 0)
{
return;
}
nGroup = thundXData.GetFoldGroupNO(oid);
sTemp = arXData.GetAt(CThunderXData::eXFoldPinNum);
nNO = _ttoi(sTemp);
sTemp = arXData.GetAt(CThunderXData::eXFoldPinHeight);
dHeight = _tstof(sTemp);
//保护高度
thundXData.GetFoldProHeightFromObjEx(oid,arProHeights);
FoldThunder.m_nNo = nNO;
FoldThunder.m_nGroup = nGroup;
FoldThunder.m_dHeight = dHeight;
FoldThunder.m_arProHeight = arProHeights;
FoldThunder.m_ptPos = ptPos;
FoldThunder.m_Id = oid;
AddFoldPinToMap(FoldThunder);
}
}
//删除避雷针更新映射
void CFoldPinRelation::DelFoldPinFromMap(const CString& sGroup,const AcDbObjectId& oid)
{
int nGroup = _ttoi(sGroup);
if (m_arAllPoldPin.find(nGroup) != m_arAllPoldPin.end())
{
FOLDPINLST& PinLst = m_arAllPoldPin[nGroup];
FOLDPINLST::iterator itor;
for (itor = PinLst.begin();itor != PinLst.end();++itor)
{
if (oid == itor->m_Id)
{
PinLst.erase(itor);
break;
}
}
if (PinLst.size() == 0)
{
m_arAllPoldPin.erase(nGroup);
}
}
}
//删除避雷针更新映射
void CFoldPinRelation::DelFoldPinFromMap(const XFoldThunder& FoldThunder)
{
int nGroup = FoldThunder.m_nGroup;
int nNo = FoldThunder.m_nNo;
if (m_arAllPoldPin.find(nGroup) == m_arAllPoldPin.end())
{
return;
}
else
{
FOLDPINLST& PinList = m_arAllPoldPin[nGroup];
FOLDPINLST::iterator itor;
for (itor = PinList.begin();itor != PinList.end();++itor)
{
if (FoldThunder.m_Id == itor->m_Id)
{
PinList.erase(itor);
break;
}
}
if (PinList.size() == 0)
{
m_arAllPoldPin.erase(nGroup);
}
}
}
void CFoldPinRelation::DelFoldPinFromMap(const AcDbObjectId& oid)
{
FOLDPINGROUP::iterator itorGroup;
FOLDPINLST::iterator itorPins;
for (itorGroup = m_arAllPoldPin.begin();itorGroup != m_arAllPoldPin.end();++itorGroup)
{
FOLDPINLST& LstTemp = itorGroup->second;
for (itorPins = LstTemp.begin();itorPins != LstTemp.end();++itorPins)
{
if ((*itorPins).m_Id == oid)
{
LstTemp.erase(itorPins);
break;
}
}
if (LstTemp.size() == 0)
{
m_arAllPoldPin.erase(itorGroup);
break;
}
}
}
//更新避雷针
void CFoldPinRelation::UpdateFoldPinInMap(int nOldGroup,const AcDbObjectId& oid)
{
XFoldThunder thunder;
ReadDataFromID(oid,thunder);
UpdateFoldPinInMap(nOldGroup,thunder);
}
//更新避雷针
void CFoldPinRelation::UpdateFoldPinInMap(int nOldGroup,const XFoldThunder& FoldThunder)
{
int nGroup = FoldThunder.m_nGroup;
XFoldThunder thunder;
memset(&thunder,0,sizeof(XFoldThunder));
thunder = FoldThunder;
FOLDPINGROUP::iterator GroupItor = m_arAllPoldPin.find(nOldGroup);
if (GroupItor == m_arAllPoldPin.end())
{
//未找到原组号
return;
}
else
{
FOLDPINLST& OldPinList = m_arAllPoldPin[nOldGroup];
FOLDPINLST::iterator OldItor;
if (nGroup != nOldGroup)
{
//找到原数据,删除
for (OldItor = OldPinList.begin();OldItor != OldPinList.end();++OldItor)
{
if ((*OldItor).m_Id == thunder.m_Id)
{
OldPinList.erase(OldItor);
break;
}
}
GroupItor = m_arAllPoldPin.find(nGroup);
if (GroupItor == m_arAllPoldPin.end())
{
//没有对应组号
FOLDPINLST PinData;
PinData.push_back(thunder);
m_arAllPoldPin.insert(std::make_pair(nGroup,PinData));
}
else
{
//组号已经存在
FOLDPINLST& NewPinList = GroupItor->second;
//没有增加,有则替换
int nPos = 0;
if (IsExist(thunder,NewPinList,nPos))
{
NewPinList[nPos] = thunder;
}
else
NewPinList.push_back(thunder);
}
}
else
{
//组号已经存在
FOLDPINLST& NewPinList = GroupItor->second;
//没有增加,有则替换
int nPos = 0;
if (IsExist(thunder,NewPinList,nPos))
{
NewPinList[nPos] = thunder;
}
else
NewPinList.push_back(thunder);
}
}
}
void CFoldPinRelation::GetNumArrayBySpecGroup(int nGroup,AcGeIntArray& arNo)
{
if (m_arAllPoldPin.size() == 0)
{
return;
}
if (m_arAllPoldPin.find(nGroup) == m_arAllPoldPin.end())
{
return;
}
else
{
std::list<int> arNos;
FOLDPINLST& arPinLst = m_arAllPoldPin[nGroup];
unsigned i = 0;
for (i = 0;i < arPinLst.size();++i)
{
arNos.push_back(arPinLst[i].m_nNo);
}
arNos.sort();
std::list<int>::iterator itor;
for (itor = arNos.begin();itor != arNos.end();++itor)
{
arNo.append(*itor);
}
}
}
//获取所有可与Src联合的针
void CFoldPinRelation::GetFoldUnionPin(const XFoldThunder& Src,double dHx,const FOLDPINLST& arFrom,FOLDPINLST& arConnectPins)
{
if (!IsExist(Src,arConnectPins))
{
arConnectPins.push_back(Src);
}
//取相邻针
FOLDPINLST lstTemp;
FOLDPINLST lstTemp1;
GetFoldPinCloseBy(Src,dHx,arFrom,lstTemp);
for (unsigned int i = 0;i < lstTemp.size();i++)
{
if (!IsExist(lstTemp[i],arConnectPins))
{
arConnectPins.push_back(lstTemp[i]);
lstTemp1.push_back(lstTemp[i]);
}
}
if (lstTemp1.size() == 0)
{
return;
}
for (unsigned int k = 0;k < lstTemp1.size();k++)
{
//递归
GetFoldUnionPin(lstTemp1[k],dHx,arFrom,arConnectPins);
}
}
//获取与Src相邻且有联合保护的避雷针
void CFoldPinRelation::GetFoldPinCloseBy(const XFoldThunder& Src,double dHx,FOLDPINLST& arPoldPin)
{
arPoldPin.clear();
int nCount = m_arAllPoldPin.size();
int nGroup = Src.m_nGroup;
if (nCount == 0)
{
return;
}
FOLDPINLST& pinList = m_arAllPoldPin[nGroup];
FOLDPINLST::iterator itor;
CFoldToolKit* pToolKit = CFoldToolKit::Instance();
double dBx = 0.0;
for (unsigned int i = 0;i < pinList.size();i++)
{
if (Src.m_Id == pinList[i].m_Id)
{
continue;
}
if(m_pProTool->HasUnionPro(Src,pinList[i],dHx))
{
//可联合
int nPos = 0;
if (!IsExist(pinList[i],arPoldPin))
{
arPoldPin.push_back(pinList[i]);
}
}
}
}
//获取与Src相邻且有联合保护的避雷针
void CFoldPinRelation::GetFoldPinCloseBy(const XFoldThunder& Src,double dHx,const FOLDPINLST& arPins,FOLDPINLST& arPoldPin)
{
arPoldPin.clear();
int nCount = arPins.size();
if (nCount == 0)
{
return;
}
CFoldToolKit* pToolKit = CFoldToolKit::Instance();
for (unsigned int i = 0;i < arPins.size();i++)
{
if (arPins[i].m_Id == Src.m_Id)
{
continue;
}
if(m_pProTool->HasUnionPro(Src,arPins[i],dHx))
{
//可联合
int nPos = 0;
if (!IsExist(arPins[i],arPoldPin))
{
arPoldPin.push_back(arPins[i]);
}
}
}
}
//获取指定3针的保护线
void CFoldPinRelation::GetProLineByThree(std::list<PFoldProLine>& arEdges,const AcGeIntArray& arNos,std::list<PFoldProLine>& arProLines)
{
if (arNos.length() == 0)
{
return;
}
std::list<PFoldProLine>::iterator itor;
int nPos = 0;
for (itor = arEdges.begin();itor != arEdges.end();++itor)
{
if (!(*itor)->m_bValid)
{
//continue;
}
if (arNos.find((*itor)->m_LinePart1.m_nNo,nPos) &&
arNos.find((*itor)->m_LinePart2.m_nNo,nPos))
{
PFoldProLine ProLine = (*itor);
arProLines.push_back(ProLine);
}
}
}
//根据3针过滤无效边(公共处理)
void CFoldPinRelation::FilterInvalidEdge2(const XFoldThunder& thunder1,const XFoldThunder& thunder2,const XFoldThunder& thunder3,double dHx,std::list<PFoldProLine>& arEdges)
{
AcGePoint3d pt1,pt2,pt3,ptTemp;
pt1 = thunder1.m_ptPos;
pt2 = thunder2.m_ptPos;
pt3 = thunder3.m_ptPos;
double dTemp12 = 0.0,dTemp23 = 0.0,dTemp13 = 0.0;
int nNo1 = thunder1.m_nNo;
int nNo2 = thunder2.m_nNo;
int nNo3 = thunder3.m_nNo;
AcGeIntArray arNos;
arNos.append(nNo1);
arNos.append(nNo2);
arNos.append(nNo3);
XFoldThunder thunder;
std::list<PFoldProLine> arProLines;
GetProLineByThree(arEdges,arNos,arProLines);
dTemp12 = pt1.distanceTo(pt2);
dTemp13 = pt1.distanceTo(pt3);
dTemp23 = pt2.distanceTo(pt3);
//按距离排序 1 3 为最远
if (dTemp12 - dTemp13 > 1e-3)
{
//1 2 远过 1 3
ptTemp = pt3;
pt3 = pt2;
pt2 = ptTemp;
if (dTemp23 - dTemp12 > 1e-3)
{
//2 3 最远
ptTemp = pt1;
pt1 = pt2;
pt2 = ptTemp;
arNos.remove(nNo1);
thunder = thunder1;
}
else
{
arNos.remove(nNo3);
thunder = thunder3;
}
}
else
{
//1 3 远过 1 2
if (dTemp23 - dTemp13 > 1e-3)
{
// 2 3 最远
ptTemp = pt1;
pt1 = pt2;
pt2 = ptTemp;
arNos.remove(nNo1);
thunder = thunder1;
}
else
{
arNos.remove(nNo2);
thunder = thunder2;
}
}
AcGeLine3d lineBase;
lineBase.set(pt1,pt3);
//将剩余有效边,按基准线分边
std::list<PFoldProLine> arProUp,arProDown;
SortProLineByLine(lineBase,arProLines,arProUp,arProDown);
if (arProUp.size() > 0 && arProDown.size() > 0)
{
//与基准相交的线置无效
FilterProLineByLine(lineBase,arProDown);
FilterProLineByLine(lineBase,arProUp);
//去除重复保护线(关联相同2针)
FilterReProLineByBase(lineBase,arProUp);
FilterReProLineByBase(lineBase,arProDown);
if (arProDown.size() > 3)
{
FilterInvalidEdge(thunder1,thunder2,thunder3,arProDown);
}
if (arProUp.size() > 3)
{
FilterInvalidEdge(thunder1,thunder2,thunder3,arProUp);
}
}
FixProLineByLine(lineBase,thunder,dHx,arNos,arProDown);
FixProLineByLine(lineBase,thunder,dHx,arNos,arProUp);
}
//根据3针过滤无效边
void CFoldPinRelation::FilterInvalidEdge(const XFoldThunder& thunder1,const XFoldThunder& thunder2,const XFoldThunder& thunder3,std::list<PFoldProLine>& arEdges)
{
AcGePoint3d pt1,pt2,pt3,ptTemp;
pt1 = thunder1.m_ptPos;
pt2 = thunder2.m_ptPos;
pt3 = thunder3.m_ptPos;
int nNo1 = thunder1.m_nNo;
int nNo2 = thunder2.m_nNo;
int nNo3 = thunder3.m_nNo;
AcGeIntArray arNos;
arNos.append(nNo1);
arNos.append(nNo2);
arNos.append(nNo3);
//忽略基准保护线过滤
double dTemp12 = 0.0,dTemp13 = 0.0,dTemp23 = 0.0;
AcGeIntArray arNoBase = arNos;
dTemp12 = pt1.distanceTo(pt2);
dTemp13 = pt1.distanceTo(pt3);
dTemp23 = pt2.distanceTo(pt3);
//按距离排序 1 3 为最远
if (dTemp12 - dTemp13 > 1e-3)
{
//1 2 远过 1 3
ptTemp = pt3;
pt3 = pt2;
pt2 = ptTemp;
if (dTemp23 - dTemp12 > 1e-3)
{
//2 3 最远
ptTemp = pt1;
pt1 = pt2;
pt2 = ptTemp;
arNoBase.remove(nNo1);
}
else
{
arNoBase.remove(nNo3);
}
}
else
{
//1 3 远过 1 2
if (dTemp23 - dTemp13 > 1e-3)
{
// 2 3 最远
ptTemp = pt1;
pt1 = pt2;
pt2 = ptTemp;
arNos.remove(nNo1);
}
else
{
arNos.remove(nNo2);
}
}
std::list<PFoldProLine> arTemp;
arTemp = arEdges;
arEdges.clear();
AcGeLine3d line1,line2,line3,line;
line1.set(pt1,pt2);
line2.set(pt1,pt3);
line3.set(pt2,pt3);
int nPos = 0;
std::list<PFoldProLine>::iterator itor;
for (itor = arTemp.begin();itor != arTemp.end();++itor)
{
if (!(*itor)->m_bValid)
{
continue;
}
if (!arNos.find((*itor)->m_LinePart1.m_nNo,nPos) ||
!arNos.find((*itor)->m_LinePart2.m_nNo,nPos))
{
arEdges.push_back((*itor));
continue;
}
//如果是基准保护线,忽略过滤
if (arNoBase.find((*itor)->m_LinePart1.m_nNo,nPos) &&
arNoBase.find((*itor)->m_LinePart2.m_nNo,nPos))
{
arEdges.push_back((*itor));
continue;
}
if (m_pProTool->IsCrossBy(line1,*itor) ||
m_pProTool->IsCrossBy(line2,*itor) ||
m_pProTool->IsCrossBy(line3,*itor))
{
//无效边
(*itor)->m_bValid = FALSE;
}
else
arEdges.push_back((*itor));
}
}
//由边集生成2d联合保护范围
void CFoldPinRelation::ShowUnionPro2d(std::list<PFoldProLine>& arEdges,AcDbObjectIdArray& arProIds)
{
DList<XCurveSegment> lstSegs;
std::list<PFoldProLine>::iterator itor;
XPoint ptS1,ptS2,ptTurn;
std::list<XFoldProArc> arArcs;
std::list<XFoldProArc>::iterator itorArc;
//整合保护线
UnionProLine(arEdges);
//获取所有保护弧线
GetAllProArc(arEdges,arArcs);
for (itor = arEdges.begin();itor != arEdges.end();++itor)
{
if ((*itor)->m_bValid == TRUE)
{
ptTurn = (*itor)->m_ptTurn;
if ((*itor)->m_LinePart1.m_bValid)
{
XCurveSegment* segLine = new XCurveSegment;
ptS1 = (*itor)->m_LinePart1.m_ptS;
XLine line;
line.SetPoints(ptS1,ptTurn);
*segLine = line;
lstSegs.Append(segLine);
}
if ((*itor)->m_LinePart2.m_bValid)
{
XCurveSegment* segLine = new XCurveSegment;
ptS2 = (*itor)->m_LinePart2.m_ptS;
XLine line;
line.SetPoints(ptS2,ptTurn);
*segLine = line;
lstSegs.Append(segLine);
}
}
}
for (itorArc = arArcs.begin();itorArc != arArcs.end();++itorArc)
{
XArc arc;
(*itorArc).ConverToArc(arc);
XCurveSegment* segArc = new XCurveSegment;
*segArc = arc;
lstSegs.Append(segArc);
}
// RemoveDupCurves(lstSegs);
IntersectCurves(lstSegs,0.0);
DList<XPoly2D> lstPoly;
//得到外框闭合poly
//SearchOutRegions(lstSegs, lstPoly);
SearchRegions(lstSegs, lstPoly);
//过滤有重叠部分的多段线。保留范围大的。
FilterBigUnion(lstPoly);
KTSetting::InitLayer(LAY_EL_THUNDER_2D);
XPushVarStr cLayer(_T("CLAYER"), LAY_EL_THUNDER_2D);
PickSet ss(SS_FREE);
CRegProperty regProp(GetRegLocation(), TEL_OBJECTKEY);
regProp.SetTopRootKey(HKEY_CURRENT_USER);
int nIndex = 0;
regProp.GetValue(KEY_FOLD_UNIONPRO_COLOR, nIndex);
XPoly2D poly2d;
for (int i = 0;i < lstPoly.Length();++i)
{
Entity ent;
//XPoly2D* pPoly = new XPoly2D;
AcDbPolyline* pPoly = new AcDbPolyline;
pPoly->copyFrom(lstPoly[i]->AsAcDbCurve());
//pPoly->CopyFrom(lstPoly[i]);
// pPoly->Make();
pPoly->setColorIndex(nIndex);
AddToCurrentSpace(pPoly,TRUE);
ent.GetLast();
ss += ent;
}
AcDbObjectId oid;
for (long j = 0;j < ss.Length();++j)
{
acdbGetObjectId(oid,ss[j]);
if (oid.isValid())
{
arProIds.append(oid);
}
}
// if (lstPoly.Length() == 0)
// {
// for (int i = 0;i < lstSegs.Length();++i)
// {
//if(lstSegs[i]->Is(CURVE_ARC))
// lstSegs[i]->Make();
// }
// }
}
//用于重新绘制联合保护范围
void CFoldPinRelation::ShowUnionPro2d(const CString& sGroup)
{
int nGroup = _ttoi(sGroup);
//清除同组所有联合保护范围和保护圆
DelFoldUnionPro(nGroup);
//获取同组所有避雷针
FOLDPINLST arGroupPins= m_arAllPoldPin[nGroup];
if (arGroupPins.size() == 0)
{
return;
}
AcGeDoubleArray arHeight;
arHeight = arGroupPins[0].m_arProHeight;
FOLDPINLST PinLst,PinLstTemp;
std::list<PFoldProLine> arEages;
int i = 0;
AcDbObjectIdArray arCircleIds;
for (i = 0;i < arGroupPins.size();++i)
{
ShowProCircle(arGroupPins[i],arCircleIds);
RecordFoldPro(arCircleIds,nGroup);
}
std::vector<FOLDPINLST> arBlocks;
for (i = 0;i < arHeight.length();++i)
{
//将避雷针进行关系分块
BlockingFoldPin(arGroupPins,arBlocks,arHeight[i]);
for(unsigned j = 0;j < arBlocks.size();++j)
{
//过滤在同一保护高度 相联合的所有避雷针
PinLst.clear();
//GetFoldUnionPin(thunder,arHeight[i],PinLst);
//由这些避雷针生成联合边线
PinLst = arBlocks[j];
ProductUnionPro2d(PinLst,arHeight[i],arEages);
//过滤无效边线
PinLst = arBlocks[j];
FilerUnionPro2d(PinLst,arHeight[i],arEages);
PinLstTemp.clear();
AcDbObjectIdArray arProIds;
//由边线计算,生成联合保护范围
ShowUnionPro2d(arEages,arProIds);
//清空边线
EraseProLine(arEages);
//将组号和保护高度记录到联合保护范围
RecordFoldPro(arProIds,nGroup,arHeight[i]);
//将同高度联合保护线,做成组
GroupFoldPro(arProIds);
}
}
acedUpdateDisplay();
actrTransactionManager->flushGraphics();
}
void CFoldPinRelation::ShowUnionPro2d(const AcDbObjectId& oid,BOOL bRemove)
{
//生成对应避雷针的联合范围
XFoldThunder thunder;
memset(&thunder,0,sizeof(XFoldThunder));
//获取避雷针数据
AcGeDoubleArray arHeight;
FOLDPINLST PinLst,PinLstTemp;
std::list<PFoldProLine> arEages;
if(GetThunderById(oid,thunder))
{
//存在避雷针
arHeight = thunder.m_arProHeight;
int nGroup = thunder.m_nGroup;
//获取同组所有避雷针
FOLDPINLST arGroupPins= m_arAllPoldPin[nGroup];
//清除同组所有联合保护范围和保护圆
DelFoldUnionPro(nGroup);
//显示保护圆
//如果是删除
if (bRemove)
{
FOLDPINLST::iterator itor;
for (itor = arGroupPins.begin();itor != arGroupPins.end();++itor)
{
if (itor->m_Id == oid)
{
arGroupPins.erase(itor);
break;
}
}
}
else
{
//更新保护高度
CThunderCmdGroup::bReDrawFold = FALSE;
UpdateGroupHeight(arGroupPins,arHeight);
CThunderCmdGroup::bReDrawFold = TRUE;
}
int i = 0;
AcDbObjectIdArray arCircleIds;
for (i = 0;i < arGroupPins.size();++i)
{
ShowProCircle(arGroupPins[i],arCircleIds);
RecordFoldPro(arCircleIds,nGroup);
}
std::vector<FOLDPINLST> arBlocks;
for (i = 0;i < arHeight.length();++i)
{
//将避雷针进行关系分块
BlockingFoldPin(arGroupPins,arBlocks,arHeight[i]);
for(unsigned j = 0;j < arBlocks.size();++j)
{
//过滤在同一保护高度 相联合的所有避雷针
PinLst.clear();
//GetFoldUnionPin(thunder,arHeight[i],PinLst);
//由这些避雷针生成联合边线
PinLst = arBlocks[j];
ProductUnionPro2d(PinLst,arHeight[i],arEages);
//过滤无效边线
PinLst = arBlocks[j];
FilerUnionPro2d(PinLst,arHeight[i],arEages);
PinLstTemp.clear();
AcDbObjectIdArray arProIds;
//由边线计算,生成联合保护范围
ShowUnionPro2d(arEages,arProIds);
//清空边线
EraseProLine(arEages);
//将组号记录到联合保护范围
RecordFoldPro(arProIds,nGroup);
//将同高度联合保护线,做成组
GroupFoldPro(arProIds);
}
}
}
acedUpdateDisplay();
actrTransactionManager->flushGraphics();
}
//计算2针联合保护边线
void CFoldPinRelation::ProductUnionPro2d(const XFoldThunder& thunder1,const XFoldThunder& thunder2,double dHx,std::list<PFoldProLine>& arEdges)
{
arEdges.clear();
double dHmin = thunder1.m_dHeight;
double dHmax = thunder2.m_dHeight;
AcGePoint3d ptMin,ptMax;
ptMin = thunder1.m_ptPos;
ptMax = thunder2.m_ptPos;
if (dHmin - dHmax > 1e-3)
{
dHmin = thunder2.m_dHeight;
dHmax = thunder1.m_dHeight;
ptMin = thunder2.m_ptPos;
ptMax = thunder1.m_ptPos;
}
double dDist = ptMin.distanceTo(ptMax);
dDist *= 1e-3;
double dR1 = 0.0,dR2 = 0.0;
CFoldToolKit* pToolKit = CFoldToolKit::Instance();
if (pToolKit)
{
AcGePoint3d ptTurn1,ptTurn2;
AcGeVector3d vtDir = ptMax - ptMin;
vtDir.normalize();
AcGeVector3d vtVor = vtDir;
vtVor.rotateBy(PI/2,AcGeVector3d::kZAxis);
vtVor.normalize();
double dBx = 0.0;
if (pToolKit->CalcFoldBx(dHmin,dHmax,dDist,dHx,dBx))
{
dDist = pToolKit->CalcEffectDist(dHmin,dHmax,dDist,dHx);
XPoint ptMid = ptMin + vtDir * dDist * 0.5 * 1000;
//求2折点
ptTurn1 = ptMid + vtVor * dBx * 1000;
ptTurn2 = ptMid - vtVor *dBx * 1000;
AcGePoint3d ptRef1,ptRef2;
if (dBx < 1e-3)
{
ptRef1 = ptMid + vtVor * 5;
ptRef2 = ptMid - vtVor * 5;
}
else
{
ptRef1 = ptMid + vtVor * dBx * 0.5 * 1000;
ptRef2 = ptMid - vtVor * dBx * 0.5 * 1000;
}
//求切点1
AcGePoint3d ptTang11,ptTang21;
AcGePoint3d ptTang12,ptTang22;
BOOL bPt11 = TRUE,bPt12 = TRUE,bPt21 = TRUE,bPt22 = TRUE;
// bPt11 = GetTangencyPoint(thunder1,dHx,ptTurn1,ptRef1,ptTang11);
// bPt12 = GetTangencyPoint(thunder1,dHx,ptTurn2,ptRef2,ptTang12);
// bPt21 = GetTangencyPoint(thunder2,dHx,ptTurn1,ptRef1,ptTang21);
// bPt22 = GetTangencyPoint(thunder2,dHx,ptTurn2,ptRef2,ptTang22);
bPt11 = GetTangencyPoint(thunder1,dHx,ptTurn1,thunder2.m_ptPos,vtVor,ptTang11);
bPt12 = GetTangencyPoint(thunder1,dHx,ptTurn2,thunder2.m_ptPos,-1 * vtVor,ptTang12);
bPt21 = GetTangencyPoint(thunder2,dHx,ptTurn1,thunder1.m_ptPos,vtVor,ptTang21);
bPt22 = GetTangencyPoint(thunder2,dHx,ptTurn2,thunder1.m_ptPos,-1 * vtVor,ptTang22);
if (bPt11 == FALSE && bPt12 == FALSE &&
bPt21 == FALSE && bPt22 == FALSE)
{
//如果折点在圆内
return;
}
if (bPt11 != bPt12 || bPt21 != bPt22)
{
return;
}
if (bPt11 == FALSE && bPt21)
{
//针1无切点,针2有切点,重新计算折点
dR1 = pToolKit->CalcFoldRx(thunder1.m_dHeight,dHx);
AcDbLine line(ptTurn1,ptTang21);
AcDbCircle cir(thunder1.m_ptPos,AcGeVector3d::kZAxis,dR1 * 1000);
AcGePoint3dArray arCross;
line.intersectWith(&cir,AcDb::kOnBothOperands,arCross);
if (arCross.length() == 0)
{
return;
}
ptTurn1 = arCross[0];
arCross.setLogicalLength(0);
line.setStartPoint(ptTurn2);
line.setEndPoint(ptTang22);
line.intersectWith(&cir,AcDb::kOnBothOperands,arCross);
if (arCross.length() == 0)
{
return;
}
ptTurn2 = arCross[0];
ptTang11 = ptTurn1;
ptTang12 = ptTurn2;
}
else if (bPt11 && bPt21 == FALSE)
{
//针2无切点,针1有切点,重新计算折点
dR2 = pToolKit->CalcFoldRx(thunder2.m_dHeight,dHx);
AcDbLine line(ptTurn1,ptTang11);
AcDbCircle cir(thunder2.m_ptPos,AcGeVector3d::kZAxis,dR2 * 1000);
AcGePoint3dArray arCross;
line.intersectWith(&cir,AcDb::kOnBothOperands,arCross);
if (arCross.length() == 0)
{
return;
}
ptTurn1 = arCross[0];
arCross.setLogicalLength(0);
line.setStartPoint(ptTurn2);
line.setEndPoint(ptTang12);
line.intersectWith(&cir,AcDb::kOnBothOperands,arCross);
if (arCross.length() == 0)
{
return;
}
ptTurn2 = arCross[0];
ptTang21 = ptTurn1;
ptTang22 = ptTurn2;
}
//半折线
XHalfFoldLine ProL11,ProL12,ProL21,ProL22;
AcGePoint3dArray arPts;
ProL11.m_nNo = thunder1.m_nNo;
ProL11.m_ptS = ptTang11;
ProL11.m_bValid = TRUE;
arPts.append(ptTang11);
arPts.append(ptTang12);
GetArcOnCircle(thunder1,dHx,arPts,ptTurn1,ProL11.m_ArcS);
ProL12.m_nNo = thunder2.m_nNo;
ProL12.m_ptS = ptTang21;
ProL12.m_bValid = TRUE;
arPts[0] = ptTang21;
arPts[1] = ptTang22;
GetArcOnCircle(thunder2,dHx,arPts,ptTurn1,ProL12.m_ArcS);
ProL21.m_nNo = thunder1.m_nNo;
ProL21.m_ptS = ptTang12;
ProL21.m_ArcS = ProL11.m_ArcS;
//修改起点
ProL21.m_ArcS.m_ptS = ptTang12;
ProL21.m_bValid = TRUE;
ProL22.m_nNo = thunder2.m_nNo;
ProL22.m_ptS = ptTang22;
ProL22.m_ArcS = ProL12.m_ArcS;
ProL22.m_ArcS.m_ptS = ptTang22;
ProL22.m_bValid = TRUE;
//折线
PFoldProLine ProLine1 = NULL,ProLine2 = NULL;
ProLine1 = new TGFoldProLine;
ProLine2 = new TGFoldProLine;
ProLine1->m_bValid = TRUE;
ProLine1->m_LinePart1 = ProL11;
ProLine1->m_LinePart2 = ProL12;
ProLine1->m_ptTurn = ptTurn1;
ProLine2->m_bValid = TRUE;
ProLine2->m_LinePart1 = ProL21;
ProLine2->m_LinePart2 = ProL22;
ProLine2->m_ptTurn = ptTurn2;
arEdges.push_back(ProLine1);
arEdges.push_back(ProLine2);
}
}
}
//求切点
BOOL CFoldPinRelation::GetTangencyPoint(const XFoldThunder& thunder,double dHx,const AcGePoint3d& ptBase,const AcGePoint3d& ptRef,const AcGeVector3d & vtOffset,AcGePoint3d& ptTang)
{
CFoldToolKit* pToolKit = CFoldToolKit::Instance();
if (pToolKit)
{
AcGePoint3d ptTang1,ptTang2;
double dH = thunder.m_dHeight;
double dR = 0.0,dAngle = 0.0;
AcGePoint3d ptCenter = thunder.m_ptPos;
double dDist = ptCenter.distanceTo(ptBase);
AcGeVector3d vtDir = ptBase - ptCenter;
vtDir.normalize();
AcGeVector3d vtTemp;
AcGePoint3d ptTemp;
vtTemp = ptRef - ptCenter;
vtTemp.normalize();
ptTemp = ptCenter + vtTemp * dDist;
AcGePoint3dArray arTemp;
dR = pToolKit->CalcFoldRx(dH,dHx);
if (ptBase.distanceTo(ptCenter) - dR * 1000 < 1e-3)
{
return FALSE;
}
dAngle = acos(dR * 1000 / dDist);
//切点1
vtTemp = vtDir;
vtTemp.rotateBy(dAngle,AcGeVector3d::kZAxis);
vtTemp.normalize();
ptTang1 = ptCenter + vtTemp * dR * 1000;
//切点2
vtTemp = vtDir;
vtTemp.rotateBy(-1*dAngle,AcGeVector3d::kZAxis);
vtTemp.normalize();
ptTang2 = ptCenter + vtTemp * dR * 1000;
AcGeLine3d line;
line.set(ptCenter + vtOffset * 5,ptRef + vtOffset * 5);
if (line.distanceTo(ptTang1) - line.distanceTo(ptTang2) > 1e-3)
{
ptTang = ptTang1;
}
else
ptTang = ptTang2;
return TRUE;
}
return FALSE;
}
//指定2点得到避雷针保护员圆上的弧线
void CFoldPinRelation::GetArcOnCircle(const XFoldThunder& thunder,double dHx,const AcGePoint3dArray& arPts,const AcGePoint3d& ptBase,XFoldProArc& arc)
{
if (arPts.length() != 2)
{
return;
}
CFoldToolKit* pToolKit = CFoldToolKit::Instance();
if (pToolKit)
{
memset(&arc,0,sizeof(XFoldProArc));
double dH = thunder.m_dHeight;
double dR = 0.0,dAngle = 0.0;
AcGePoint3d pt1,pt2,pt3,ptMid,ptCenter;
AcGeVector3d vtDir;
ptCenter = thunder.m_ptPos;
vtDir = ptBase - ptCenter;
vtDir.normalize();
pt1 = arPts[0];
pt2 = arPts[1];
ptMid = Mid(pt1,pt2);
AcDbLine line(ptBase,ptMid);
dR = pToolKit->CalcFoldRx(dH,dHx);
AcDbCircle circle(ptCenter,AcGeVector3d::kZAxis,dR * 1000);
AcGePoint3dArray arCross;
line.intersectWith(&circle,AcDb::kExtendThis,arCross);
if (arCross.length() == 0)
{
return;
}
if (arCross.length() == 1)
{
pt3 = arCross[0];
}
if (arCross.length() == 2)
{
if (ptBase.distanceTo(arCross[0]) - ptBase.distanceTo(arCross[1]) > 1e-3)
{
pt3 = arCross[0];
}
else
pt3 = arCross[1];
}
// pt3 = ptCenter - vtDir * dR * 1000;
XArc arcTemp(pt1,pt3,pt2);
arc.m_dR = dR * 1000;
arc.m_ptCenter = thunder.m_ptPos;
arc.m_ptS = pt1;
arc.m_dAngleS = arcTemp.GetStarAngle();
arc.m_dAngleE = arcTemp.GetEndAngle();
}
}
//指定3点得圆上圆弧
void CFoldPinRelation::GetArcOnCircle(const XFoldThunder& thunder,double dHx,const AcGePoint3dArray& arPts,XFoldProArc& arc)
{
if (arPts.length() != 3)
{
return;
}
CFoldToolKit* pToolKit = CFoldToolKit::Instance();
if (pToolKit)
{
memset(&arc,0,sizeof(XFoldProArc));
double dH = thunder.m_dHeight;
double dR = 0.0;
AcGePoint3d pt1,pt2,pt3;
pt1 = arPts[0];
pt2 = arPts[1];
pt3 = arPts[2];
dR = pToolKit->CalcFoldRx(dH,dHx);
XArc arcTemp(pt1,pt3,pt2);
arc.m_dR = dR * 1000;
arc.m_ptCenter = thunder.m_ptPos;
arc.m_ptS = pt1;
arc.m_dAngleS = arcTemp.GetStarAngle();
arc.m_dAngleE = arcTemp.GetEndAngle();
}
}
//计算联合保护边线
void CFoldPinRelation::ProductUnionPro2d(FOLDPINLST& arPoldPin,double dHx,std::list<PFoldProLine>& arEdges)
{
if (arPoldPin.size() < 2)
{
return;
}
//取任一针做起始
XFoldThunder src = arPoldPin[0];
FOLDPINLST arClose;
std::list<PFoldProLine> arTemp;
GetFoldPinCloseBy(src,dHx,arPoldPin,arClose);
for (unsigned int i = 0;i < arClose.size();++i)
{
ProductUnionPro2d(src,arClose[i],dHx,arTemp);
if (arTemp.size() > 0)
{
arEdges.insert(arEdges.end(),arTemp.begin(),arTemp.end());
}
}
arPoldPin.erase(arPoldPin.begin());
ProductUnionPro2d(arPoldPin,dHx,arEdges);
}
//过滤无效边线
void CFoldPinRelation::FilerUnionPro2d(FOLDPINLST& arPoldPin,double dHx,std::list<PFoldProLine>& arEdges)
{
if (arPoldPin.size() < 2)
{
return;
}
//取任一针做起始
FOLDPINLST arClose;
XFoldThunder src = arPoldPin[0];
XFoldThunder thunder1,thunder2;
GetFoldPinCloseBy(src,dHx,arPoldPin,arClose);
if (arClose.size() > 1)
{
for (unsigned int i = 0;i < arClose.size() - 1;++i)
{
thunder1 = arClose[i];
for (unsigned int j = i + 1;j < arClose.size();++j)
{
thunder2 = arClose[j];
if (m_pProTool->HasUnionPro(thunder1,thunder2,dHx))
{
FilterInvalidEdge2(src,thunder1,thunder2,dHx,arEdges);
}
// FilterInvalidEdge2(src,thunder1,thunder2,dHx,arEdges);
}
}
}
arPoldPin.erase(arPoldPin.begin());
//递归
FilerUnionPro2d(arPoldPin,dHx,arEdges);
}
BOOL CFoldPinRelation::GetThunderById(const AcDbObjectId& oid,XFoldThunder& FoldThunder)
{
//有ID获取thunder数据
//获取避雷针组号
CThunderXData thundXData;
// int nGroup = thundXData.GetFoldGroupNO(oid);
int nGroup = 0;
CString sNO = _T("");
AcDbEntity* pEnt = NULL;
acdbOpenAcDbEntity(pEnt,oid,AcDb::kForRead,true);
if (pEnt)
{
thundXData.GetXData(pEnt,KEY_FOLD_GROUP_NO,sNO);
pEnt->close();
}
nGroup = _ttoi(sNO);
if (m_arAllPoldPin.find(nGroup) != m_arAllPoldPin.end())
{
FOLDPINLST& PinLst = m_arAllPoldPin[nGroup];
for (unsigned int i = 0;i < PinLst.size();++i)
{
if (PinLst[i].m_Id == oid)
{
FoldThunder = PinLst[i];
return TRUE;
}
}
}
return FALSE;
}
void CFoldPinRelation::ShowProCircle(const AcDbObjectId& oid,AcDbObjectIdArray& arIds)
{
//绘制保护圆
XFoldThunder FoldThunder;
if(GetThunderById(oid,FoldThunder))
ShowProCircle(FoldThunder,arIds);
}
void CFoldPinRelation::ShowProCircle(const XFoldThunder& FoldThunder,AcDbObjectIdArray& arIds)
{
//绘制保护圆
CFoldToolKit* pToolKit = CFoldToolKit::Instance();
if (pToolKit)
{
//计算Rx
double dRx = 0.0;
AcDbObjectId oid;
int nIndex = 0;
CRegProperty regProp(GetRegLocation(), TEL_OBJECTKEY);
regProp.SetTopRootKey(HKEY_CURRENT_USER);
regProp.GetValue(KEY_FOLD_SINGLEPRO_COLOR, nIndex);
CThunderXData thunderXData;
for (int i = 0;i < FoldThunder.m_arProHeight.length();++i)
{
dRx = pToolKit->CalcFoldRx(FoldThunder.m_dHeight,FoldThunder.m_arProHeight[i]);
//绘制各保护高度的保护员
AcDbCircle* pCircle = new AcDbCircle;
pCircle->setCenter(FoldThunder.m_ptPos);
pCircle->setRadius(dRx * 1000);
pCircle->setNormal(AcGeVector3d::kZAxis);
pCircle->setLayer(LAY_EL_THUNDER);
pCircle->setColorIndex(nIndex);
oid = AddToCurrentSpace(pCircle,TRUE);
//将保护高度和避雷针ID写入保护圆
CString sProH;
sProH.Format(_T("%f"),FoldThunder.m_arProHeight[i]);
thunderXData.SetXData(oid,KEY_FOLD_CURRENT_PROHEIGHT,sProH);
//将避雷针ID写入保护圆
thunderXData.SetXData(oid,KEY_FOLD_THUNDER_ID,FoldThunder.m_Id);
arIds.append(oid);
}
}
}
void CFoldPinRelation::EraseProLine(std::list<PFoldProLine>& arEdges)
{
std::list<PFoldProLine>::iterator itor;
PFoldProLine pTemp = NULL;
for (itor = arEdges.begin();itor != arEdges.end();++itor)
{
pTemp = *itor;
*itor = NULL;
delete pTemp;
}
arEdges.clear();
}
//由基准线将边分类
void CFoldPinRelation::SortProLineByLine(AcGeLine3d& line,std::list<PFoldProLine>& arEdges,std::list<PFoldProLine>& arUp,std::list<PFoldProLine>& arDown)
{
AcGeVector3d vtDir,vtTemp;
AcGePoint3d ptClose,ptS,ptE;
std::list<PFoldProLine>::iterator itor;
PFoldProLine pProLine = NULL;
ptS = line.evalPoint(0.0);
ptE = line.evalPoint(1.0);
vtDir = ptS - ptE;
vtDir.rotateBy(PI/2,AcGeVector3d::kZAxis);
for (itor = arEdges.begin();itor != arEdges.end();++itor)
{
pProLine = *itor;
ptClose = line.closestPointTo(pProLine->m_ptTurn);
vtTemp = pProLine->m_ptTurn - ptClose;
if (vtTemp.isCodirectionalTo(vtDir))
{
//up
arUp.push_back(pProLine);
}
else
arDown.push_back(pProLine);
}
}
void CFoldPinRelation::FixProLineByLine(const AcGeLine3d& line,const XFoldThunder& thunder,double dHx,const AcGeIntArray& arNoBase,std::list<PFoldProLine>& arEdges)
{
if (arEdges.size() < 2)
{
return;
}
//如果只有2条边线,取最外边框
if (arEdges.size() == 2)
{
AcGePoint3d ptTurn1,ptTurn2;
double dDist1 = 0.0,dDist2 = 0.0;
PFoldProLine Proline1 = NULL,Proline2 = NULL;
std::list<PFoldProLine>::iterator itor = arEdges.begin();
Proline1 = *itor;
++itor;
Proline2 = *itor;
if(m_pProTool->SortBaseLine(arNoBase,Proline1,Proline2))
{
//如果有基准保护线
if (!m_pProTool->IsCrossBy(Proline1,Proline2))
{
//如果2边框不相交
if(!m_pProTool->IsCloserByLine(line,Proline1,Proline2))
{
//如果基准保护线在外层
Proline2->m_bValid = FALSE;
}
else
{
//如果基准保护线在内层,则必定和thunder的保护圆相交
FixProLineByThunder(Proline1,Proline2,dHx,thunder);
}
}
else
{
//2线相交,修正两线
FixProLineByLine(line,Proline1,Proline2);
}
}
}
if (arEdges.size() == 3)
{
AcGePoint3d ptTurn1,ptTurn2;
double dDist1 = 0.0,dDist2 = 0.0;
PFoldProLine Proline1 = NULL,Proline2 = NULL,Proline3 = NULL;
std::list<PFoldProLine>::iterator itor = arEdges.begin();
Proline1 = *itor;
++itor;
Proline2 = *itor;
++itor;
Proline3 = *itor;
int nPos = 0;
m_pProTool->SortBaseLine(arNoBase,Proline1,Proline2,Proline3);
if (!m_pProTool->IsCrossBy(Proline1,Proline2) && !m_pProTool->IsCrossBy(Proline1,Proline3))
{
//3条线相互不相交
if (!m_pProTool->IsCloserByLine(line,Proline1,Proline2) && !m_pProTool->IsCloserByLine(line,Proline1,Proline3))
{
Proline2->m_bValid = FALSE;
Proline3->m_bValid = FALSE;
if (m_pProTool->IsCrossBy(Proline1,thunder,dHx))
{
//如果与圆有交点
Proline2->m_bValid = TRUE;
Proline3->m_bValid = TRUE;
AcGePoint3dArray arCross;
m_pProTool->GetCrossPoint(Proline1,thunder,dHx,arCross);
if (arCross.length() == 2)
{
double dR = 0.0;
CFoldToolKit* pToolKit = CFoldToolKit::Instance();
if (pToolKit)
{
dR = pToolKit->CalcFoldRx(thunder.m_dHeight,dHx);
dR *= 1000;
}
AcGePoint3d ptS1,ptS2,ptTurn,ptCenter,ptTemp;
ptTurn = Proline1->m_ptTurn;
ptCenter = thunder.m_ptPos;
AcGeVector3d vtTemp = ptTurn - ptCenter;
vtTemp.normalize();
ptTemp = ptCenter + vtTemp*dR;
arCross.append(ptTemp);
int nNo1 = GetSameNo(Proline1,Proline2);
int nNo2 = GetSameNo(Proline1,Proline3);
Proline1->GetStartPtByNo(nNo1,ptS1);
Proline1->GetStartPtByNo(nNo2,ptS2);
{
//构造折线1
Proline2->SetStartPtByNo(nNo1,ptS1);
if (arCross[0].distanceTo(ptS1) - arCross[1].distanceTo(ptS1) > 1e-3)
{
Proline2->m_ptTurn = arCross[1];
Proline2->SetAnotherPt(nNo1,arCross[1]);
}
else
{
Proline2->m_ptTurn = arCross[0];
Proline2->SetAnotherPt(nNo1,arCross[0]);
}
GetArcOnCircle(thunder,dHx,arCross,Proline2->m_LinePart2.m_ArcS);
}
{
//构造折线2
Proline3->SetStartPtByNo(nNo2,ptS2);
if (arCross[0].distanceTo(ptS2) - arCross[1].distanceTo(ptS2) > 1e-3)
{
Proline3->m_ptTurn = arCross[1];
Proline3->SetAnotherPt(nNo2,arCross[1]);
}
else
{
Proline3->m_ptTurn = arCross[0];
Proline3->SetAnotherPt(nNo2,arCross[0]);
}
GetArcOnCircle(thunder,dHx,arCross,Proline3->m_LinePart2.m_ArcS);
}
Proline1->m_bValid = FALSE;
}
}
}
else
Proline1->m_bValid = FALSE;
}
if (!m_pProTool->IsCrossBy(Proline1,Proline2) && m_pProTool->IsCrossBy(Proline1,Proline3))
{
//基准保护线和一个相交
if (!m_pProTool->IsCloserByLine(line,Proline1,Proline2))
{
//基准保护线在未相交的保护线外
Proline2->m_bValid = FALSE;
FixProLineByLine(line,Proline1,Proline3);
}
else
{
//基准保护线在未相交的保护线内
FixProLineByLine(line,Proline1,Proline3);
}
}
if (!m_pProTool->IsCrossBy(Proline1,Proline3) && m_pProTool->IsCrossBy(Proline1,Proline2))
{
//基准保护线和一个相交
if (!m_pProTool->IsCloserByLine(line,Proline1,Proline3))
{
//基准保护线在未相交的保护线外
Proline3->m_bValid = FALSE;
FixProLineByLine(line,Proline1,Proline2);
}
else
{
//基准保护线在未相交的保护线内
FixProLineByLine(line,Proline1,Proline2);
}
}
if (m_pProTool->IsCrossBy(Proline1,Proline3) && m_pProTool->IsCrossBy(Proline1,Proline2))
{
//基准线和2个相交
AcGePoint3dArray arCross;
m_pProTool->GetCrossPoint(Proline1,Proline3,arCross);
AcGePoint3d ptBaseS;
if (!m_pProTool->IsCloserByLine(line,Proline1,Proline3))
{
//基准保护线较远
int nNoBase = GetSameNo(Proline1,Proline3);
Proline1->GetStartPtByNo(nNoBase,ptBaseS);
Proline3->SetStartPtByNo(nNoBase,ptBaseS);
XFoldProArc arc;
Proline1->GetArcByNo(nNoBase,arc);
Proline3->SetArcByNo(nNoBase,arc);
Proline3->m_ptTurn = arCross[0];
}
arCross.setLogicalLength(0);
m_pProTool->GetCrossPoint(Proline1,Proline2,arCross);
if (!m_pProTool->IsCloserByLine(line,Proline1,Proline2))
{
//基准保护线较远
int nNoBase = GetSameNo(Proline1,Proline2);
Proline1->GetStartPtByNo(nNoBase,ptBaseS);
Proline2->SetStartPtByNo(nNoBase,ptBaseS);
XFoldProArc arc;
Proline1->GetArcByNo(nNoBase,arc);
Proline2->SetArcByNo(nNoBase,arc);
Proline2->m_ptTurn = arCross[0];
}
Proline1->m_bValid = FALSE;
}
}
}
void CFoldPinRelation::FixProLineByLine(const AcGeLine3d& line,PFoldProLine& pProLine1,PFoldProLine& pProLine2)
{
if (pProLine1 == NULL || pProLine2 == NULL)
{
return;
}
AcGePoint3dArray arCross;
AcGePoint3d ptCross,pt1,pt2;
if (m_pProTool->GetCrossPoint(pProLine1,pProLine2,arCross))
{
if (arCross.length() == 1)
{
//1个交点
ptCross = arCross[0];
//交点为折点
if (ptCross == pProLine1->m_ptTurn)
{
if (pProLine1->m_LinePart1.m_ptS == pProLine2->m_LinePart1.m_ptS)
{
pt1 = pProLine1->m_LinePart2.m_ptS;
pt2 = pProLine2->m_LinePart2.m_ptS;
}
else if (pProLine1->m_LinePart1.m_ptS == pProLine2->m_LinePart2.m_ptS)
{
pt1 = pProLine1->m_LinePart2.m_ptS;
pt2 = pProLine2->m_LinePart1.m_ptS;
}
else if (pProLine1->m_LinePart2.m_ptS == pProLine2->m_LinePart1.m_ptS)
{
pt1 = pProLine1->m_LinePart1.m_ptS;
pt2 = pProLine2->m_LinePart2.m_ptS;
}
else if (pProLine1->m_LinePart2.m_ptS == pProLine2->m_LinePart2.m_ptS)
{
pt1 = pProLine1->m_LinePart1.m_ptS;
pt2 = pProLine2->m_LinePart1.m_ptS;
}
if (line.distanceTo(pt1) - line.distanceTo(pt2) > 1e-3)
pProLine2->m_bValid = FALSE;
else
pProLine1->m_bValid = FALSE;
}
else
{
//一般相交情况
int nNoBase = GetSameNo(pProLine1,pProLine2);
int nNoCross1 = GetNoByPt(pProLine1,ptCross);
int nNoCross2 = GetNoByPt(pProLine2,ptCross);
if (m_pProTool->IsCloserByLine(line,pProLine1,pProLine2))
{
if ((nNoCross2 != nNoBase && nNoCross1 == nNoBase) ||
(nNoCross2 == nNoBase && nNoCross1 != nNoBase))
{
FixProLineByPt(pProLine1,ptCross,FALSE,FALSE);
FixProLineByPt(pProLine2,ptCross,FALSE,FALSE);
}
else
{
FixProLineByPt(pProLine1,ptCross,FALSE,TRUE);
FixProLineByPt(pProLine2,ptCross,FALSE,FALSE);
}
}
else
{
if ((nNoCross2 != nNoBase && nNoCross1 == nNoBase) ||
(nNoCross2 == nNoBase && nNoCross1 != nNoBase))
{
FixProLineByPt(pProLine1,ptCross,FALSE,FALSE);
FixProLineByPt(pProLine2,ptCross,FALSE,FALSE);
}
else
{
FixProLineByPt(pProLine1,ptCross,FALSE,FALSE);
FixProLineByPt(pProLine2,ptCross,FALSE,TRUE);
}
}
}
}
else if (arCross.length() == 2)
{
//2个交点
int nNoBase = -1;
AcGePoint3d ptBaseS,ptClose,ptFar;
nNoBase = GetSameNo(pProLine1,pProLine2);
pProLine1->GetStartPtByNo(nNoBase,ptBaseS);
if (ptBaseS.distanceTo(arCross[0]) - ptBaseS.distanceTo(arCross[1]) > 1e-3)
{
ptClose = arCross[1];
ptFar = arCross[0];
}
else
{
ptClose = arCross[0];
ptFar = arCross[1];
}
int nNo1,nNo2;
pProLine2->GetProLineNo(nNo1,nNo2);
if (nNo1 == nNoBase)
{
nNo1 = nNo2;
}
if (GetNoByPt(pProLine1,ptClose) == GetNoByPt(pProLine1,ptFar) ||
GetNoByPt(pProLine2,ptClose) == GetNoByPt(pProLine2,ptFar))
{
//一条边交2条边
//构造新折线1
if (!m_pProTool->IsCloserByLine(line,pProLine1,pProLine2))
{
//基准保护线较远
pProLine2->SetStartPtByNo(nNoBase,ptBaseS);
//重置绑定圆弧
XFoldProArc arc;
pProLine1->GetArcByNo(nNoBase,arc);
pProLine2->SetArcByNo(nNoBase,arc);
}
pProLine2->m_ptTurn = ptClose;
pProLine2->SetStartPtByNo(nNo1,ptFar);
//将绑定圆弧置无效
pProLine2->InvalidArcByNo(nNo1);
//构造新折线2
pProLine1->InvalidHalfByNo(nNoBase);
pProLine1->m_ptTurn = ptFar;
}
else
{
//分别交与2条边
AcGePoint3d ptS2;
//构造新折线1
if (!m_pProTool->IsCloserByLine(line,pProLine1,pProLine2))
{
//基准保护线较远
pProLine2->SetStartPtByNo(nNoBase,ptBaseS);
//重置绑定圆弧
XFoldProArc arc;
pProLine1->GetArcByNo(nNoBase,arc);
pProLine2->SetArcByNo(nNoBase,arc);
ptS2 = pProLine1->m_ptTurn;
}
else
ptS2 = pProLine2->m_ptTurn;
pProLine2->m_ptTurn = ptClose;
pProLine2->SetStartPtByNo(nNo1,ptS2);
//将绑定圆弧置无效
pProLine2->InvalidArcByNo(nNo1);
//构造新折线2
pProLine1->SetStartPtByNo(nNoBase,ptS2);
pProLine1->m_ptTurn = ptFar;
pProLine1->InvalidArcByNo(nNoBase);
}
}
}
}
void CFoldPinRelation::FixProLineByPt(PFoldProLine pProline,const AcGePoint3d& ptNew,BOOL bUnion,BOOL bHalfValid)
{
if (pProline == NULL)
{
return;
}
AcGeLine3d line1,line2;
double dParam = 0.0;
line1.set(pProline->m_ptTurn,pProline->m_LinePart1.m_ptS);
if (line1.isOn(ptNew) && (dParam > -1e-3 && dParam - 1 < 1e-3))
{
if (pProline->m_LinePart1.m_bValid)
{
//如果双半边有效,重置对应边起点,如果其中1边无效,则重置折点
if (pProline->m_LinePart2.m_bValid)
{
if (bHalfValid)
{
pProline->m_LinePart1.m_ptS = ptNew;
//将绑定圆弧置无效
pProline->InvalidArcByNo(pProline->m_LinePart1.m_nNo);
}
else
{
pProline->m_LinePart2.m_bValid = FALSE;
pProline->m_ptTurn = ptNew;
}
}
else
{
if (bUnion)
{
pProline->m_LinePart1.m_ptS = ptNew;
}
else
pProline->m_ptTurn = ptNew;
}
}
return;
}
line1.set(pProline->m_ptTurn,pProline->m_LinePart2.m_ptS);
if (line1.isOn(ptNew) && (dParam > -1e-3 && dParam - 1 < 1e-3))
{
if (pProline->m_LinePart2.m_bValid)
{
//如果双半边有效,重置对应边起点,如果其中1边无效,则重置折点
if (pProline->m_LinePart1.m_bValid)
{
if (bHalfValid)
{
pProline->m_LinePart2.m_ptS = ptNew;
//绑定圆弧置无效
pProline->InvalidArcByNo(pProline->m_LinePart2.m_nNo);
}
else
{
pProline->m_LinePart1.m_bValid = FALSE;
pProline->m_ptTurn = ptNew;
}
}
else
if (bUnion)
{
pProline->m_LinePart2.m_ptS = ptNew;
}
else
pProline->m_ptTurn = ptNew;
}
return;
}
}
void CFoldPinRelation::FilterProLineByLine(const AcGeLine3d& line,std::list<PFoldProLine>& arEdges)
{
std::list<PFoldProLine> arTemp;
arTemp = arEdges;
arEdges.clear();
std::list<PFoldProLine>::iterator itor,itorPre;
for (itor = arTemp.begin();itor != arTemp.end();++itor)
{
if (m_pProTool->IsCrossBy(line,(*itor)))
{
(*itor)->m_bValid = FALSE;
}
else
arEdges.push_back(*itor);
}
}
void CFoldPinRelation::FilterReProLineByBase(const AcGeLine3d& line,std::list<PFoldProLine>& arEdges)
{
//将编号相同的保护线(关联相同避雷针),进行过滤
std::map<TGFOLDNO,std::vector<PFoldProLine> > arPre;
std::list<PFoldProLine>::iterator itor;
for (itor = arEdges.begin();itor != arEdges.end();++itor)
{
TGFOLDNO FoldNo;
FoldNo.m_nNo1 = (*itor)->m_LinePart1.m_nNo;
FoldNo.m_nNo2 = (*itor)->m_LinePart2.m_nNo;
if (IsExist(arPre,FoldNo))
{
arPre[FoldNo].push_back((*itor));
}
else
{
std::vector<PFoldProLine> arProLine;
arProLine.push_back((*itor));
arPre.insert(std::make_pair(FoldNo,arProLine));
}
}
arEdges.clear();
std::map<TGFOLDNO,std::vector<PFoldProLine> >::iterator MapItor;
for (MapItor = arPre.begin();MapItor != arPre.end();++MapItor)
{
int nMin = 0;
std::vector<PFoldProLine>& arLines = MapItor->second;
if (arLines.size() > 1)
{
for (unsigned int i = 0;i < arLines.size() - 1;++i)
{
if (m_pProTool->IsCloserByLine(line,arLines[nMin],arLines[i + 1]))
{
arLines[nMin]->m_bValid = FALSE;
nMin = i + 1;
}
else
arLines[i + 1]->m_bValid = FALSE;
}
}
arEdges.push_back(arLines[nMin]);
}
}
void CFoldPinRelation::FixProLineByThunder(PFoldProLine& ProLine,PFoldProLine ProLineRef,double dHx,const XFoldThunder& thunder)
{
//处理保护线与 避雷针保护圆相交的情况,默认 ProLine在ProLineRef内侧
CFoldToolKit* pToolKit = CFoldToolKit::Instance();
if (pToolKit)
{
double dR = 0.0;
dR = pToolKit->CalcFoldRx(thunder.m_dHeight,dHx);
AcGePoint3d ptS1,ptS2,ptTurn;
ptTurn = ProLine->m_ptTurn;
int nPart = 0;
if (ProLine->m_LinePart1.m_nNo == ProLineRef->m_LinePart1.m_nNo ||
ProLine->m_LinePart1.m_nNo == ProLineRef->m_LinePart2.m_nNo)
{
ptS1 = ProLine->m_LinePart1.m_ptS;
ptS2 = ProLine->m_LinePart2.m_ptS;
nPart = 1;
}
if (ProLine->m_LinePart2.m_nNo == ProLineRef->m_LinePart1.m_nNo ||
ProLine->m_LinePart2.m_nNo == ProLineRef->m_LinePart2.m_nNo)
{
ptS1 = ProLine->m_LinePart2.m_ptS;
ptS2 = ProLine->m_LinePart1.m_ptS;
nPart = 2;
}
AcGePoint3d ptTangent;
ptTangent = ProLineRef->GetTangentPoint(thunder.m_nNo);
AcDbCircle cir(thunder.m_ptPos,AcGeVector3d::kZAxis,dR * 1000);
AcDbLine line1(ptTurn,ptS1),line2(ptTurn,ptS2);
AcGePoint3dArray arCross1,arCross2;
line1.intersectWith(&cir,AcDb::kOnBothOperands,arCross1);
line2.intersectWith(&cir,AcDb::kOnBothOperands,arCross2);
if (arCross1.length() + arCross2.length() < 2)
{
ProLine->m_bValid = FALSE;
return;
}
else
{
AcGePoint3d ptClose,ptFar;
//如果2交点分别交于2条半边
if (arCross1.length() == 1 && arCross2.length() == 1)
{
if (nPart == 1)
{
ptClose = arCross2[0];
ptFar = arCross1[0];
}
else
{
ptClose = arCross1[0];
ptFar = arCross2[0];
}
}
//取最近点
if (arCross1.length() == 2)
{
if (ptTurn.distanceTo(arCross1[0]) - ptTurn.distanceTo(arCross1[1]) > 1e-3)
{
ptClose = arCross1[1];
}
else
ptClose = arCross1[0];
}
else if (arCross2.length() == 2)
{
if (ptTurn.distanceTo(arCross2[0]) - ptTurn.distanceTo(arCross2[1]) > 1e-3)
{
ptClose = arCross2[0];
}
else
ptClose = arCross2[1];
}
ProLine->GetHalfFoldLine(nPart).m_ptS = ptClose;
ProLine->m_ptTurn = ptClose;
AcGePoint3dArray arPts;
arPts.append(ptClose);
arPts.append(ptFar);
arPts.append(ptTangent);
GetArcOnCircle(thunder,dHx,arPts,ProLine->m_LinePart1.m_ArcS);
}
}
}
//获取2折线的公共针编号
int CFoldPinRelation::GetSameNo(PFoldProLine ProLine1,PFoldProLine ProLine2,int& nNo1,int& nNo2)
{
int nCount = 0;
//初始化返回值
nNo1 = -1,nNo2 = -1;
if (ProLine1->m_LinePart1.m_nNo == ProLine2->m_LinePart1.m_nNo ||
ProLine1->m_LinePart1.m_nNo == ProLine2->m_LinePart2.m_nNo)
{
nNo1 = ProLine1->m_LinePart1.m_nNo;
++nCount;
}
if (ProLine1->m_LinePart2.m_nNo == ProLine2->m_LinePart1.m_nNo ||
ProLine1->m_LinePart2.m_nNo == ProLine2->m_LinePart2.m_nNo)
{
if (nCount == 0)
{
nNo1 = ProLine1->m_LinePart2.m_nNo;
}
else
nNo2 = ProLine1->m_LinePart2.m_nNo;
++nCount;
}
return nCount;
}
int CFoldPinRelation::GetSameNo(PFoldProLine ProLine1,PFoldProLine ProLine2)
{
int nNo = -1;
if (ProLine1->m_LinePart1.m_nNo == ProLine2->m_LinePart1.m_nNo ||
ProLine1->m_LinePart1.m_nNo == ProLine2->m_LinePart2.m_nNo)
{
nNo = ProLine1->m_LinePart1.m_nNo;
}
else if (ProLine1->m_LinePart2.m_nNo == ProLine2->m_LinePart1.m_nNo ||
ProLine1->m_LinePart2.m_nNo == ProLine2->m_LinePart2.m_nNo)
{
nNo = ProLine1->m_LinePart2.m_nNo;
}
return nNo;
}
int CFoldPinRelation::GetNoByPt(PFoldProLine ProLine,const AcGePoint3d& ptOn)
{
AcGePoint3d ptS1,ptS2,ptTurn;
ptS1 = ProLine->m_LinePart1.m_ptS;
ptS2 = ProLine->m_LinePart2.m_ptS;
ptTurn = ProLine->m_ptTurn;
double dHalfLen = 0.0,dDist = 0.0;
dHalfLen = ptS1.distanceTo(ptTurn);
dDist = ptOn.distanceTo(ptTurn) + ptOn.distanceTo(ptS1);
if (fabs(dDist - dHalfLen) < 1e-3)
{
return ProLine->m_LinePart1.m_nNo;
}
dHalfLen = ptS2.distanceTo(ptTurn);
dDist = ptOn.distanceTo(ptTurn) + ptOn.distanceTo(ptS2);
if (fabs(dDist - dHalfLen) < 1e-3)
{
return ProLine->m_LinePart2.m_nNo;
}
return -1;
}
void CFoldPinRelation::FixProLineByLine(const AcGeLine3d& line,PFoldProLine& pProLine1,PFoldProLine& pProLine2,PFoldProLine& pProLine3)
{
//3边相交
}
//获取所有弧线
void CFoldPinRelation::GetAllProArc(std::list<PFoldProLine>& arEdges,std::list<XFoldProArc>& arArcs)
{
std::list<PFoldProLine>::iterator itor;
std::map<int,std::vector<XFoldProArc> > arArcPre;
int nNo;
//按避雷针进行分类
for(itor = arEdges.begin();itor != arEdges.end();++itor)
{
if ((*itor)->m_bValid == TRUE)
{
if ((*itor)->m_LinePart1.m_bValid == TRUE)
{
XFoldProArc arc;
nNo = (*itor)->m_LinePart1.m_nNo;
arc = (*itor)->m_LinePart1.m_ArcS;
if (arc.m_dR > 1e-3)
{
if (arArcPre.find(nNo) == arArcPre.end())
{
//未找到
std::vector<XFoldProArc> arArc;
arArc.push_back(arc);
arArcPre.insert(std::make_pair(nNo,arArc));
}
else
{
arArcPre[nNo].push_back(arc);
}
}
}
if ((*itor)->m_LinePart2.m_bValid == TRUE)
{
XFoldProArc arc;
nNo = (*itor)->m_LinePart2.m_nNo;
arc = (*itor)->m_LinePart2.m_ArcS;
if (arc.m_dR > 1e-3)
{
if (arArcPre.find(nNo) == arArcPre.end())
{
//未找到
std::vector<XFoldProArc> arArc;
arArc.push_back(arc);
arArcPre.insert(std::make_pair(nNo,arArc));
}
else
{
arArcPre[nNo].push_back(arc);
}
}
}
}
}
std::map<int,std::vector<XFoldProArc> >::iterator MapItor;
std::vector<XFoldProArc> ArcRet;
for (MapItor = arArcPre.begin();MapItor != arArcPre.end();++MapItor)
{
if ((*MapItor).first == 1)
{
XArc xarc;
ArcRet = (*MapItor).second;
for (unsigned i = 0;i < ArcRet.size();++i)
{
ArcRet[i].ConverToArc(xarc);
// xarc.Make();
}
}
ArcRet.clear();
if (UnionProArc(MapItor->second,ArcRet))
{
arArcs.insert(arArcs.end(),ArcRet.begin(),ArcRet.end());
}
}
}
BOOL CFoldPinRelation::UnionProArc(std::vector<XFoldProArc>& arArc,std::vector<XFoldProArc>& ArcRet)
{
//std::vector<XFoldProArc> ArcRet;
if (arArc.size() == 0)
{
return FALSE;
}
XFoldProArc arcTemp,arcTemp1;
SortProArc(arArc);
if (arArc.size() == 1)
{
ArcRet.push_back(arArc[0]);
return TRUE;
}
// BOOL bReBegion = TRUE;
// for (unsigned int i = 0;i < arArc.size();++i)
// {
// if (bReBegion)
// {
// arcTemp = arArc[i];
// bReBegion = FALSE;
// continue;
// }
// bReBegion = FALSE;
// arcTemp1 = arcTemp;
// if(!UnionProArc(arcTemp1,arArc[i],arcTemp))
// return FALSE;
// }
BOOL bReCount = FALSE;
for (unsigned i = 0;i < arArc.size() - 1;++i)
{
arcTemp = arArc[i];
for (unsigned j = i + 1; j < arArc.size();++j)
{
arcTemp1 = arcTemp;
if(!UnionProArc(arcTemp1,arArc[j],arcTemp))
{
continue;
}
}
bReCount = FALSE;
for (unsigned k = 0;k < ArcRet.size();++k)
{
if (UnionProArc(arcTemp,ArcRet[k],arcTemp1))
{
bReCount = TRUE;
break;
}
}
if (!bReCount)
{
ArcRet.push_back(arcTemp);
}
}
return TRUE;
}
BOOL CFoldPinRelation::UnionProArc(const XFoldProArc& arc1,const XFoldProArc& arc2,XFoldProArc& arc)
{
if (arc1.m_ptCenter != arc2.m_ptCenter)
{
return FALSE;
}
if (arc1.m_dR != arc2.m_dR)
{
return FALSE;
}
AcGePoint3d ptRef = arc1.m_ptS;
arc.m_dR = arc1.m_dR;
arc.m_ptCenter = arc1.m_ptCenter;
arc.m_ptS = ptRef;
double dAngleS1 = 0.0,dAngleE1 = 0.0,dAngleS2 = 0.0,dAngleE2 = 0.0,dAngleS = 0.0,dAngleE = 0.0;
BOOL bOver1 = FALSE,bOver2 = FALSE;
dAngleS1 = arc1.m_dAngleS;
dAngleE1 = arc1.m_dAngleE;
if (dAngleS1 - dAngleE1 > 1e-3)
{
bOver1 = TRUE;
// dE1 += 2 * PI;
}
dAngleS2 = arc2.m_dAngleS;
dAngleE2 = arc2.m_dAngleE;
if (dAngleS2 - dAngleE2 > 1e-3)
{
bOver2 = TRUE;
// dE2 += 2 * PI;
}
if (!bOver1 && !bOver2)
{
//如果2弧都不跨1 4 象限
if (dAngleS2 > dAngleE1 || dAngleS1 > dAngleE2)
{
return FALSE;
}
arc.m_dAngleS = max(dAngleS1,dAngleS2);
arc.m_dAngleE = min(dAngleE1,dAngleE2);
}
else if ((bOver1 && !bOver2) || (!bOver1 && bOver2))
{
//其中1个跨 1 4象限
if (bOver2)
{
//交换变量,始终保持 S1 E1 为跨界弧
double dTemp = 0.0;
dTemp = dAngleS1;
dAngleS1 = dAngleS2;
dAngleS2 = dTemp;
dTemp = dAngleE1;
dAngleE1 = dAngleE2;
dAngleE2 = dTemp;
}
if(dAngleS1 < dAngleE2 && dAngleE1 > dAngleS2)
{
//2段重叠,首尾相交
XArc ArcTemp1,ArcTemp2;
ArcTemp1.SetRadius(arc1.m_dR);
ArcTemp1.SetCenterPt(arc1.m_ptCenter);
ArcTemp1.SetStarAngle(dAngleS2);
ArcTemp1.SetEndAngle(dAngleE1);
ArcTemp2.SetRadius(arc1.m_dR);
ArcTemp2.SetCenterPt(arc1.m_ptCenter);
ArcTemp2.SetStarAngle(dAngleS1);
ArcTemp2.SetEndAngle(dAngleE2);
if (ArcTemp1.PtOnArc(ptRef))
{
arc.m_dAngleS = ArcTemp1.GetStarAngle();
arc.m_dAngleE = ArcTemp1.GetEndAngle();
}
else if (ArcTemp2.PtOnArc(ptRef))
{
arc.m_dAngleS = ArcTemp2.GetStarAngle();
arc.m_dAngleE = ArcTemp2.GetEndAngle();
}
}
else
{
//1段重叠
if (dAngleE2 > dAngleS1 && dAngleS2 > dAngleE1)
{
//arc2 起点相交
arc.m_dAngleS = dAngleS1;
arc.m_dAngleE = dAngleE2;
}
else if (dAngleS2 < dAngleE1 && dAngleE2 < dAngleS1)
{
//arc2 终点相交
arc.m_dAngleS = dAngleS2;
arc.m_dAngleE = dAngleE1;
}
else if ((dAngleS2 < dAngleE1 && dAngleE2 < dAngleE1) ||
(dAngleS2 > dAngleS1 && dAngleE2 > dAngleS1))
{
//arc2 被包含
arc.m_dAngleS = dAngleS2;
arc.m_dAngleE = dAngleE2;
}
else
return FALSE;
}
}
else if (bOver1 && bOver2)
{
//2弧都跨界
if ((dAngleS1 < dAngleS2 && dAngleS1 < dAngleE2) ||
(dAngleS2 < dAngleS1 && dAngleS2 < dAngleE1))
{
//2段重叠,首尾相交
XArc ArcTemp1,ArcTemp2;
ArcTemp1.SetRadius(arc1.m_dR);
ArcTemp1.SetCenterPt(arc1.m_ptCenter);
ArcTemp1.SetStarAngle(dAngleS2);
ArcTemp1.SetEndAngle(dAngleE1);
ArcTemp2.SetRadius(arc1.m_dR);
ArcTemp2.SetCenterPt(arc1.m_ptCenter);
ArcTemp2.SetStarAngle(dAngleS1);
ArcTemp2.SetEndAngle(dAngleE2);
if (ArcTemp1.PtOnArc(ptRef))
{
arc.m_dAngleS = ArcTemp1.GetStarAngle();
arc.m_dAngleE = ArcTemp1.GetEndAngle();
}
else if (ArcTemp2.PtOnArc(ptRef))
{
arc.m_dAngleS = ArcTemp2.GetStarAngle();
arc.m_dAngleE = ArcTemp2.GetEndAngle();
}
}
else
{
arc.m_dAngleS = max(dAngleS1,dAngleS2);
arc.m_dAngleE = min(dAngleE1,dAngleE2);
}
}
return TRUE;
}
//按起始角度进行排序
bool ArcGreater(XFoldProArc arc1,XFoldProArc arc2)
{
return arc1.m_dAngleS < arc2.m_dAngleS;
}
void CFoldPinRelation::SortProArc(std::vector<XFoldProArc>& arArc)
{
std::sort(arArc.begin(),arArc.end(),ArcGreater);
}
void CFoldPinRelation::UnionProLine(std::list<PFoldProLine>& arEdges)
{
//处理最后的保护线
std::map<int,std::vector<PFoldProLine> > arEdgesPre;
std::list<PFoldProLine>::iterator itor,itorTemp;
int nNo;
//将保护线,按连接的针分类
for (itor = arEdges.begin();itor != arEdges.end();++itor)
{
if ((*itor)->m_bValid == TRUE)
{
if ((*itor)->m_LinePart1.m_bValid == TRUE)
{
nNo = (*itor)->m_LinePart1.m_nNo;
if (arEdgesPre.find(nNo) == arEdgesPre.end())
{
//未找到
std::vector<PFoldProLine> arTemp;
arTemp.push_back(*itor);
arEdgesPre.insert(std::make_pair(nNo,arTemp));
}
else
{
//std::list<PFoldProLine>& arTemp = arEdgesPre[nNo];
arEdgesPre[nNo].push_back(*itor);
//arTemp.push_back(*itor);
}
}
if ((*itor)->m_LinePart2.m_bValid == TRUE)
{
nNo = (*itor)->m_LinePart2.m_nNo;
if (arEdgesPre.find(nNo) == arEdgesPre.end())
{
//未找到
std::vector<PFoldProLine> arTemp;
arTemp.push_back(*itor);
arEdgesPre.insert(std::make_pair(nNo,arTemp));
}
else
{
arEdgesPre[nNo].push_back(*itor);
}
}
}
}
//处理相交保护线
std::map<int,std::vector<PFoldProLine> >::iterator MapItor;
PFoldProLine Proline1,Proline2;
for (MapItor = arEdgesPre.begin();MapItor != arEdgesPre.end();++MapItor)
{
std::vector<PFoldProLine>& arPro = MapItor->second;
for (unsigned i = 0;i < arPro.size() - 1;++i)
{
//两两判断是否相交
Proline1 = arPro[i];
for (unsigned j = i + 1;j < arPro.size();++j)
{
Proline2 = arPro[j];
if (m_pProTool->IsCrossBy(Proline1,Proline2))
{
UnionProLine(Proline1,Proline2);
}
}
}
}
}
void CFoldPinRelation::UnionProLine(PFoldProLine& ProLine1,PFoldProLine& ProLine2)
{
AcGePoint3dArray arCross;
AcGePoint3d ptCross;
m_pProTool->GetCrossPoint(ProLine1,ProLine2,arCross);
if (arCross.length() == 0)
{
return;
}
ptCross = arCross[0];
int nNo1 = GetNoByPt(ProLine1,ptCross);
int nNo2 = GetNoByPt(ProLine2,ptCross);
if (nNo1 == nNo2)
{
FixProLineByPt(ProLine1,ptCross,TRUE);
FixProLineByPt(ProLine2,ptCross,TRUE);
}
}
void CFoldPinRelation::GroupFoldPro(const AcDbObjectIdArray& arPros)
{
//生成Group
// 添加到组
AcDbGroup* pGroup = new AcDbGroup;
for (int i = 0;i < arPros.length();++i)
{
pGroup->append(arPros[i]);
}
// 将组添加到有名对象字典的组字典中
AcDbDictionary* pGroupDict = NULL;
acdbHostApplicationServices()->workingDatabase()
->getGroupDictionary(pGroupDict, AcDb::kForWrite);
AcDbObjectId idGoup;
pGroupDict->setAt(_T("*A"),pGroup,idGoup);
pGroupDict->close();
pGroup->close();
}
//删除联合保护范围
void CFoldPinRelation::DelFoldUnionPro(int nGroup)
{
RBList rb = ads_buildlist(-4,_T("<or"),
-4,_T("<and"),RTDXF0,_T("LWPOLYLINE"),8,LAY_EL_THUNDER_2D,-4,_T("and>"),
-4,_T("<and"),RTDXF0,_T("CIRCLE"),8,LAY_EL_THUNDER,-4,_T("and>"),
-4,_T("or>"),RTNONE);
PickSet ss(SS_FREE);
ss.Get(_T("X"),NULL,NULL,rb);
CString sFoldSign = _T("");
CThunderXData thunderData;
for (long i = 0;i < ss.Length();++i)
{
OPENOBJ_BEGIN(ss[i],AcDb::kForWrite,AcDbEntity,pEnt);
if (pEnt)
{
thunderData.GetXData(pEnt,KEY_FOLD_PRO_GROUP,sFoldSign);
if (!sFoldSign.IsEmpty())
{
if (nGroup == _ttoi(sFoldSign))
{
pEnt->erase();
}
}
}
OPENOBJ_END();
}
}
//获取联合保护范围
void CFoldPinRelation::GetFoldUnionPro(const AcDbObjectIdArray& arPins,double dHx,std::vector<AcDbObjectIdArray>& arPros)
{
CString sKey = _T("");
sKey.Format(_T("%s_%.0f"),KEY_FOLD_HORPRO_RANGE,dHx);
CThunderXData thunderData;
AcDbObjectIdArray arIds;
for (int i = 0;i < arPins.length();++i)
{
thunderData.GetEntityIdFromExData(arPins[i],arIds,sKey);
if (!IsExist(arPros,arIds))
{
arPros.push_back(arIds);
}
}
}
//记录联合保护范围
void CFoldPinRelation::RecordFoldPro(AcDbObjectIdArray& arPros,int nGroup,double dHx)
{
CString sGroup = _T("");
sGroup.Format(_T("%d"),nGroup);
CThunderXData thunderData;
CString sProH;
sProH.Format(_T("%f"),dHx);
for (int i = 0;i < arPros.length();++i)
{
thunderData.SetXData(arPros[i],KEY_FOLD_PRO_GROUP,sGroup);
thunderData.SetXData(arPros[i],KEY_FOLD_CURRENT_PROHEIGHT,sProH);
}
}
void CFoldPinRelation::RecordFoldPro(AcDbObjectIdArray& arPros,int nGroup)
{
CString sGroup = _T("");
sGroup.Format(_T("%d"),nGroup);
CThunderXData thunderData;
for (int i = 0;i < arPros.length();++i)
{
thunderData.SetXData(arPros[i],KEY_FOLD_PRO_GROUP,sGroup);
}
}
void CFoldPinRelation::BlockingFoldPin(FOLDPINLST& arPins,std::vector<FOLDPINLST>& arBlocks,double dHx)
{
if (arPins.size() == 0)
{
return;
}
XFoldThunder thunder;
thunder = arPins[0];
FOLDPINLST arBlock;
//指定基准,获取所有可以关联避雷针
GetFoldUnionPin(thunder,dHx,arPins,arBlock);
if (arBlock.size() > 0)
{
arBlocks.push_back(arBlock);
}
FOLDPINLST::iterator itor;
for (unsigned i = 0;i < arBlock.size();++i)
{
for (itor = arPins.begin();itor != arPins.end();++itor)
{
if ((*itor).m_Id == arBlock[i].m_Id)
{
arPins.erase(itor);
break;
}
}
}
//递归
BlockingFoldPin(arPins,arBlocks,dHx);
}
void CFoldPinRelation::UpdateGroupHeight(FOLDPINLST& arPins,const AcGeDoubleArray& arHeights)
{
CThunderXData thunderXData;
for (unsigned i = 0;i < arPins.size();++i)
{
thunderXData.SetFoldProHeightToObjEx(arPins[i].m_Id,arHeights);
arPins[i].m_arProHeight = arHeights;
}
}
//筛选较大的联合保护范围(有部分重叠的)
void CFoldPinRelation::FilterBigUnion(DList<XPoly2D>& lstUnions)
{
XPoly2D poly1,poly2;
XPointList lstPnt,lstPnt2;
BOOL bFind = FALSE,bRemovePre = FALSE;
XPoint ptPos,ptPos2;
for (int i = 0;i < lstUnions.Length();)
{
poly1 = *lstUnions[i];
lstPnt.Reset();
poly1.AsPoly2D(lstPnt);
for (int j = i + 1;j < lstUnions.Length();)
{
lstPnt2.Reset();
poly2 = *lstUnions[j];
poly2.AsPoly2D(lstPnt2);
for (int k = 0;k < lstPnt.Length();++k)
{
ptPos = *lstPnt[k];
for (int t = 0;t < lstPnt2.Length();++t)
{
ptPos2 = *lstPnt2[t];
if (ptPos2 == ptPos)
{
bFind = TRUE;
break;
}
}
if (bFind)
{
break;
}
}
if (bFind)
{
bFind = FALSE;
if (poly1.Area() - poly2.Area() > 1e-3)
{
//判断2区域大小,删除小的。
lstUnions.Remove(j);
continue;
}
else
{
bRemovePre = TRUE;
break;
}
}
++j;
}
if (bRemovePre)
{
bRemovePre = FALSE;
lstUnions.Remove(i);
continue;
}
++i;
}
}