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

3059 lines
83 KiB
C++

#include "stdafx.h"
#include "TAPI.h"
#include "TelDef.h"
#include "XBlock.h"
#include "wire.h"
//#include <arxtools.h>
#include <dbrect.h>
#include <actrans.h>
Entity GetWireByPoint(XPoint pt)
{
PickSet ss(SS_FREE);
RBList rbMask = ads_buildlist(RTDXF0, _T("ARC,LINE"), 8, GetLayerNames(_T("导线")), NULL);
GetPointPickSet(pt, ss, rbMask, 1);
int len = ss.Length();
if(ss.Length() != 1)
return Entity();
else
return ss[0L];
}
Entity GetPWireByPoint(XPoint pt)
{
PickSet ss(SS_FREE);
RBList rbMask = ads_buildlist( -4, _T("<or"),
-4, _T("<and"), RTDXF0, _T("LWPOLYLINE"), 8, GetLayerNames(_T("导线")), -4, _T("and>"),
-4, _T("<and"), RTDXF0, _T("LINE"), 8, GetLayerNames(_T("导线")), -4, _T("and>"),
-4, _T("<and"), RTDXF0, _T("ARC"), 8, GetLayerNames(_T("导线")), -4, _T("and>"),
-4, _T("or>"), NULL);
XPoint ptUcs = Wcs2Ucs(pt);
GetPointPickSet(ptUcs, ss, rbMask, 30);
int len = ss.Length();
if(ss.Length() != 1)
return Entity();
else
return ss[0L];
}
resbuf *GetWireMask()//注意RB没有释放,需要调用者自己释放
{
resbuf *rbRet = ads_buildlist(RTDXF0, _T("ARC,LINE"), 8, GetLayerNames(_T("导线")), NULL);
return rbRet;
}
resbuf *GetThickWireMask()//注意RB没有释放,需要调用者自己释放
{
resbuf *rbRet = ads_buildlist(RTDXF0, _T("LWPOLYLINE"), 8, GetLayerNames(_T("导线")), NULL);
return rbRet;
}
void GetBlkExplodeCurves(AcDbEntity *pEnt, AcArray<XCurveSegment, AcArrayObjectCopyReallocator<XCurveSegment> > &arCurves)
{
if(pEnt == NULL)
return;
AcDbVoidPtrArray arEnts;
pEnt->explode(arEnts);
for (int j = 0; j < arEnts.length(); ++j)
{
AcDbEntity *pEnt = (AcDbEntity*)arEnts[j];
AcDbLine *pLine = NULL;
AcDbPolyline *pPLine = NULL;
AcDbArc *pArc = NULL;
AcDbCircle *pCir = NULL;
AcDbBlockReference *pBlock = NULL;
XCurveSegment seg;
if(pLine = AcDbLine::cast(pEnt)){
XLine line(XPoint(pLine->startPoint()), XPoint(pLine->endPoint()));
seg = line;
arCurves.append(seg);
}
else if(pArc = AcDbArc::cast(pEnt)){
AcGePoint3d ptStart, ptEnd;
pArc->getStartPoint(ptStart);
pArc->getEndPoint(ptEnd);
double dAng(0), dLen(0);
pArc->getDistAtPoint(ptEnd, dLen);
dAng = dLen / pArc->radius();
XArc arc(XPoint(ptStart), XPoint(ptEnd), dAng);
seg = arc;
arCurves.append(seg);
}
else if(pCir = AcDbCircle::cast(pEnt)){
AcGePoint3d ptCen = pCir->center();
XCircle cir(XPoint(ptCen), pCir->radius());
seg = cir;
arCurves.append(seg);
}
else if(pPLine = AcDbPolyline::cast(pEnt)){
XPoly2D poly;
PolyConvert(*pPLine, poly);
for(int n=0; n<poly.TotalSegments(); n++) {
XCurveSegment seg;
poly.Nth(n, seg);
arCurves.append(seg);
}
}
else if(pBlock = AcDbBlockReference::cast(pEnt)){
GetBlkExplodeCurves(pEnt, arCurves);
}
}
ReleaseEntSet(arEnts);
}
//判断一个线段是否接在一组线段上
BOOL IsSegLinkSegs(XCurveSegment segMain, AcArray<XCurveSegment, AcArrayObjectCopyReallocator<XCurveSegment> > &arSegs, XPoint &ptConnect)
{
BOOL bRet = FALSE;
XPoint ptStart, ptEnd;
ptStart = segMain.StartPoint();
ptEnd = segMain.EndPoint();
XPoint pt1,pt2;
//找到管线与实体交点,并判断交点是否在实体表面
for (int i = 0; i < arSegs.length(); ++i)
{
XCurveSegment seg = arSegs[i];
if (seg.Intersection(segMain, pt1, pt2) > 0)
{
if (pt1.Distance2d(ptStart) < 1E-3)
{
bRet = TRUE;
ptConnect = ptStart;
break;
}
else if (pt1.Distance2d(ptEnd) < 1E-3)
{
bRet = TRUE;
ptConnect = ptEnd;
break;
}
}
else if(seg.Is(CURVE_LINE))//如果没有交点(平行),但导线的端点在线段上,也算连接
{
XLine line = seg.GetLine();
int ret1 = ptStart&line;
if(ret1 == PR_ONPT1 || ret1 == PR_ONPT2 || ret1 == PR_INSIDE)
{
bRet = TRUE;
ptConnect = ptStart;
break;
}
int ret2 = ptEnd&line;
if(ret2 == PR_ONPT1 || ret2 == PR_ONPT2 || ret2 == PR_INSIDE)
{
bRet = TRUE;
ptConnect = ptEnd;
break;
}
}
}
return bRet;
}
//判断一根导线是否接在一个设备上
BOOL IsWireInEnt(Entity ent, Entity entEq, XPoint &ptConnect)
{
BOOL bTrue = FALSE;
AcArray<XCurveSegment, AcArrayObjectCopyReallocator<XCurveSegment> > arSegs;
AcDbObjectId eId1;
AcDbEntity *pEnt1 = NULL;
acdbGetObjectId(eId1, entEq);
acdbOpenObject(pEnt1, eId1, AcDb::kForRead);
GetBlkExplodeCurves(pEnt1, arSegs);
pEnt1->close();
if(ent.Is(_T("LINE")) || ent.Is(_T("ARC")))
{
XCurveSegment segMain(ent);
bTrue = IsSegLinkSegs(segMain, arSegs, ptConnect);
}
else if(ent.Is(_T("LWPOLYLINE")))
{
//对于pline,把首尾2根线段取出来,和arSegs判断是否连接
XPoly2D poly(ent);
XCurveSegment seg;
poly.Nth(0, seg);
bTrue = IsSegLinkSegs(seg, arSegs, ptConnect);
if(!bTrue && poly.TotalSegments() > 1)
{
int num = poly.TotalSegments();
poly.Nth(num-1, seg);
bTrue = IsSegLinkSegs(seg, arSegs, ptConnect);
}
}
return bTrue;
}
//老函数暂时取消,因为在弧线不圆的情况下,SS.GET是得不到正确结果的 sr 091109
BOOL IsWireInEnt2(Entity ent, Entity entEq, XPoint &ptConnect)
{
RBList rbMask = ads_buildlist(RTDXF0, _T("INSERT"), NULL);
XPoint ptStart, ptEnd;
GetWire2Point(ent, ptStart, ptEnd);
PickSet ss(SS_FREE);
XPoint ptTemp1, ptTemp2;
ptTemp1.x = ptStart.x - MM;
ptTemp1.y = ptStart.y + MM;
ptTemp2.x = ptStart.x + MM;
ptTemp2.y = ptStart.y - MM;
XPoint ptUcs1, ptUcs2;
XLine line(ptTemp1, ptTemp2);
line.Make();
ptUcs1 = Wcs2Ucs(ptTemp1);
ptUcs2 = Wcs2Ucs(ptTemp2);
XRectAngle rect(ptUcs1, ptUcs2);
struct resbuf *list = ads_buildlist( RTPOINT, &rect.GetLowLeft(), RTPOINT, &rect.GetLowRight(),
RTPOINT, &rect.GetUpRight(), RTPOINT, &rect.GetUpLeft(),
RTPOINT, &rect.GetLowLeft(), NULL);
//2009-11-9 沈睿 把c选改为cp选, 在某些图上,明明没有接触, 程序也选到了
ss.Get(_T("CP"), list, NULL, rbMask);// ss.Get(_T("C"), ptUcs1, ptUcs2, rbMask);
ads_relrb(list);
ptConnect = ptStart;
long len = ss.Length();
for(long i=0;i<len;i++)
{
Entity entTemp = ss[i];
if(entTemp == entEq)
{
return TRUE;
}
}
ptConnect = ptEnd;
ptTemp1.x = ptEnd.x - MM;
ptTemp1.y = ptEnd.y + MM;
ptTemp2.x = ptEnd.x + MM;
ptTemp2.y = ptEnd.y - MM;
XLine line2(ptTemp1, ptTemp2);
line2.Make();
PickSet ss2(SS_FREE);
ptUcs1 = Wcs2Ucs(ptTemp1);
ptUcs2 = Wcs2Ucs(ptTemp2);
XRectAngle rect2(ptUcs1, ptUcs2);
struct resbuf *list2 = ads_buildlist( RTPOINT, &rect2.GetLowLeft(), RTPOINT, &rect2.GetLowRight(),
RTPOINT, &rect2.GetUpRight(), RTPOINT, &rect2.GetUpLeft(),
RTPOINT, &rect2.GetLowLeft(), NULL);
ss2.Get(_T("CP"), list2, NULL, rbMask);// ss2.Get(_T("C"), ptUcs1, ptUcs2, rbMask);
ads_relrb(list2);
len = ss2.Length();
for(i=0;i<len;i++)
{
Entity entTemp = ss2[i];
if(entTemp == entEq)
{
return TRUE;
}
}
return FALSE;
}
//得到图块所引出的所有的导线
BOOL GetAllWireInEq(PickSet &ssSel, Entity entEq, BOOL bIsTouch, RBList &rbMask)
{
ads_point lowPt, upPt;
entEq.GetExtend(lowPt, upPt);
XRectAngle box(lowPt, upPt);
XPoly2D poly2d(1);
box.AsPoly2D(poly2d);
poly2d.TransUCS(Groups(0), Groups(1));
RBList rbFence=poly2d.Fence();
ssSel.Get(_T("F"), rbFence, NULL, rbMask);
ssSel -= entEq;
XPoint ptConnect;
long ssLen = ssSel.Length();
for(long i=0;i<ssLen;i++){
Entity entTemp = ssSel[i];
if(!IsWireInEnt(entTemp, entEq, ptConnect) && bIsTouch){
ssSel -= entTemp;
i--;
ssLen--;
}
if(IsWireInEnt(entTemp, entEq, ptConnect) && !bIsTouch){
ssSel -= entTemp;
i--;
ssLen--;
}
}
return TRUE;
}
void GetAllEqByWire(Entity entwire, Entity &ent1, Entity &ent2)
{
Entity entEq;
PickSet ssStart(SS_FREE);
PickSet ssEnd(SS_FREE);
RBList rbMask(RTDXF0, _T("INSERT"), 8, GetLayerNames(_T("设备")), NULL);
XPoint ptStart, ptEnd, ptConnect;
GetWire2Point(entwire, ptStart, ptEnd);
XPoint ptTemp1, ptTemp2;
ptTemp1.x = ptStart.x - MM*20;
ptTemp1.y = ptStart.y + MM*20;
ptTemp2.x = ptStart.x + MM*20;
ptTemp2.y = ptStart.y - MM*20;
ssStart.Get(_T("C"), ptTemp1, ptTemp2, rbMask);
int lenS = ssStart.Length();
if(ssStart.Length() > 0)
{
int idx = 0;
Entity entTmp;
for(long i=0;i<lenS;i++){
Entity entEq = ssStart[i];
if(IsWireInEnt(entwire, entEq, ptConnect))
{
idx++;
entTmp = entEq;
}
}
if(idx == 1)
ent1 = entTmp;
}
ptTemp1.x = ptEnd.x - MM*20;
ptTemp1.y = ptEnd.y + MM*20;
ptTemp2.x = ptEnd.x + MM*20;
ptTemp2.y = ptEnd.y - MM*20;
ssEnd.Get(_T("C"), ptTemp1, ptTemp2, rbMask);
int lenE = ssEnd.Length();
if(ssEnd.Length() > 0)
{
int idx = 0;
Entity entTmp;
for(long i=0;i<lenE;i++){
Entity entEq = ssEnd[i];
if(IsWireInEnt(entwire, entEq, ptConnect))
{
idx++;
entTmp = entEq;
}
}
if(idx == 1)
ent2 = entTmp;
}
return;
}
//得到图块所引出的所有的导线, 及接线点
BOOL GetAllWireInEq(PickSet &ssSel, Entity entEq, XPointList &lstPt, RBList &rbMask)
{
XPoint lowPt, upPt;
entEq.GetExtend(lowPt, upPt);
lowPt.x = lowPt.x - MM/2;
lowPt.y = lowPt.y - MM/2;
upPt.x = upPt.x + MM/2;
upPt.y = upPt.y + MM/2;
XRectAngle box(lowPt, upPt);
XPoly2D poly2d(1);
box.AsPoly2D(poly2d);
poly2d.TransUCS(Groups(0), Groups(1));
RBList rbFence=poly2d.Fence();
PickSet ssTmp(SS_FREE);
ssTmp.Get(_T("F"), rbFence, NULL, rbMask);
ssTmp -= entEq;
XPoint ptConnect;
long ssLen = ssTmp.Length();
for(long i=0;i<ssLen;i++){
Entity entTemp = ssTmp[i];
if(IsWireInEnt(entTemp, entEq, ptConnect))
{
ssSel += entTemp;
XPoint *ptNew = new XPoint();
*ptNew = ptConnect;
lstPt.Append(ptNew);
}
}
return TRUE;
}
//得到设备块上的接线点, 如果是圆设备,返回圆心和半径
BOOL GetEquipPoint(Entity entBlk, XPointList &lstPt, double &nRadius)
{
if(!entBlk)
return FALSE;
BOOL bIsCircle = FALSE;
AcGePoint3d ptCen;
XBlock myBlock(entBlk);
if(!myBlock.m_bInitSuccess)
return FALSE;
nRadius = -1;
AcDbBlockTableRecordIterator *pIterator;
pIterator = myBlock.GetIterator();
for(pIterator->start(); !pIterator->done(); pIterator->step()){
AcDbEntity *pEnt;
pIterator->getEntity(pEnt, AcDb::kForRead);
AcDbBlockReference *pBlk = NULL;
AcDbCircle *pCir = NULL;
AcDbPoint *pPoint = NULL;
if(pBlk = AcDbBlockReference::cast(pEnt)){
AcGePoint3d ptIns = pBlk->position();
ptIns = ptIns.transformBy(myBlock.GetMatrix3d());
lstPt.NewAppend(ptIns);
}
else if(pPoint = AcDbPoint::cast(pEnt)){
AcGePoint3d ptIns = pPoint->position();
ptIns = ptIns.transformBy(myBlock.GetMatrix3d());
lstPt.NewAppend(ptIns);
}
else if(pCir = AcDbCircle::cast(pEnt)){
double jj = pCir->radius();
if(((pCir->radius() > 0.3) && (pCir->radius() > nRadius)) || ((pCir->radius() > 0.3) && (nRadius < 0))){
nRadius = pCir->radius();
ptCen = pCir->center();
ptCen = ptCen.transformBy(myBlock.GetMatrix3d());
}
}
pEnt->close();
}
if(nRadius > 0){
bIsCircle = TRUE;
lstPt.Reset();
lstPt.NewAppend(ptCen);
}
return bIsCircle;
}
//李盛达 2013-12-31 重新写
BOOL DrawPLineWireBy2Equip(Entity oldent, Entity ent1, Entity ent2)
{
BOOL bRet(FALSE);
CWire wire1(oldent);
CString csLayer = wire1.GetWireLayer();
CString csLineType = wire1.GetLineType();
double nLineThick = wire1.GetLineThick();
CString csName = ReadXdata(oldent, _T("linenum"));
CString csType = ReadXdata(oldent, _T("ltype"));
CString csRadius = ReadXdata(oldent, _T("ldm"));
CString csMode = ReadXdata(oldent, _T("lmeth"));
CString csPlace = ReadXdata(oldent, _T("linst"));
CString csArea = ReadXdata(oldent, _T("lnoar"));
CString csNorm = ReadXdata(oldent, _T("lnorm"));
XPoint ptCen1, ptCen2;
XPointList lst111, lst222;
BOOL flag1(FALSE), flag2(FALSE), bIsLamp1(FALSE), bIsLamp2(FALSE);
double nRadius1(0.0), nRadius2(0.0);
CString csAttribText1 = GetAttrib(ent1, _T("A"));
CString csAttribText2 = GetAttrib(ent2, _T("A"));
// if(csAttribText1.Find(_T("荧光灯")) > -1 && csAttribText2.Find(_T("荧光灯")) < 0){
// ent1.GetData(10, ptCen1);
// bIsLamp1 = TRUE;
// }
// else if(csAttribText2.Find(_T("荧光灯")) > -1 && csAttribText1.Find(_T("荧光灯")) < 0){
// bIsLamp2 = TRUE;
// ent2.GetData(10, ptCen2);
// }
flag1 = GetEquipPoint(ent1, lst111, nRadius1);
flag2 = GetEquipPoint(ent2, lst222, nRadius2);
//2008-4-9 sr 增加以下40行. 解决,开关连接荧光灯的时候, 希望连接在荧光灯的中间, 而不是根据就近原则连接到荧光灯的边上
//if(csAttribText1.Find(_T("开关")) > -1 && csAttribText2.Find(_T("荧光灯")) > -1){
// XPointList lstPtTrue;
// double dLampAng(0);
// ent2.GetData(50, &dLampAng);
// XPoint ptLampTmp, ptLampIns;
// ent2.GetData(10, ptLampIns);
// ads_polar(ptLampIns, dLampAng, 50, ptLampTmp);
// // 得到荧光灯图块的向量
// AcGeVector3d vt1 = ptLampTmp - ptLampIns;
// int len2 = lst222.Length();
// for(int m=0;m<len2;m++){
// XPoint pt1 = *lst222[m];
// AcGeVector3d vt2 = pt1 - ptLampIns;
// if(vt1.isParallelTo(vt2)!=Adesk::kTrue){
// lstPtTrue.NewAppend(pt1);
// }
// }
// lst222.Reset();
// lst222 = lstPtTrue;
//}
//else if(csAttribText2.Find(_T("开关")) > -1 && csAttribText1.Find(_T("荧光灯")) > -1){
// XPointList lstPtTrue;
// double dLampAng(0);
// ent1.GetData(50, &dLampAng);
// XPoint ptLampTmp, ptLampIns;
// ent1.GetData(10, ptLampIns);
// ads_polar(ptLampIns, dLampAng, 50, ptLampTmp);
// // 得到荧光灯图块的向量
// AcGeVector3d vt1 = ptLampTmp - ptLampIns;
// int len2 = lst111.Length();
// for(int m=0;m<len2;m++){
// XPoint pt1 = *lst111[m];
// AcGeVector3d vt2 = pt1 - ptLampIns;
// if(vt1.isParallelTo(vt2)!=Adesk::kTrue){
// lstPtTrue.NewAppend(pt1);
// }
// }
// lst111.Reset();
// lst111 = lstPtTrue;
//}
//lsd add 2013-12-30
//开关连灯的时候如果开关在灯两端垂直延长线内,连中点,否则取最近点
//如果是开关连灯,求出灯的两端点备用并设置标记值
XPoint ptLampIns,ptS,ptE;//中点,起始接线点
double dMaxDist = 0.0;
Entity entLamp;
XPointList lstPts;
if(csAttribText2.Find(_T("开关")) > -1 && csAttribText1.Find(_T("荧光灯")) > -1)
{
bIsLamp1 = TRUE;
entLamp = ent1;
lstPts = lst111;
}
else if(csAttribText1.Find(_T("开关")) > -1 && csAttribText2.Find(_T("荧光灯")) > -1)
{
bIsLamp2 = TRUE;
entLamp = ent2;
lstPts = lst222;
}
if(bIsLamp1 || bIsLamp2)
{
double dLampAng(0);
entLamp.GetData(50, &dLampAng);
XPoint ptLampTmp;
entLamp.GetData(10, ptLampIns);
ads_polar(ptLampIns, dLampAng, 50, ptLampTmp);
// 得到荧光灯图块的向量
AcGeVector3d vt1 = ptLampTmp - ptLampIns;
//求得灯的两端接线点(按图块向量上的最远点算)
int iLen = lstPts.Length();
for(int k = 0;k < iLen;k++)
{
XPoint pt1 = *lstPts[k];
if(AcGeVector3d(pt1 - ptLampIns).isParallelTo(vt1) != Adesk::kTrue)
continue;
for(int kk = k;kk < iLen;kk++)
{
XPoint pt2 = *lstPts[kk];
if(AcGeVector3d(pt2 - ptLampIns).isParallelTo(vt1) != Adesk::kTrue)
continue;
if(dMaxDist < pt1.Distance2d(pt2))
{
dMaxDist = pt1.Distance2d(pt2);
ptS = pt1;
ptE = pt2;
}
}
}
}
AcDbLine lineLamp(ptS,ptE);//灯管中线
//add end
double xscale;
ent1.GetData(41, &xscale);
nRadius1 *= fabs(xscale);
ent2.GetData(41, &xscale);
nRadius2 *= fabs(xscale);
int len1 = lst111.Length();
int len2 = lst222.Length();
double nMinDist = -1;
//lsd modified 2013-12-30
for(int i=0;i<len1;i++){
XPoint pti = *lst111[i];
//if(bIsLamp1)
// pti = ptCen1;
for(int j=0;j<len2;j++){
XPoint ptj = *lst222[j];
//if(bIsLamp2)
// ptj = ptCen2;
if(bIsLamp1)
{
AcGePoint3d ptOnLine;
lineLamp.getClosestPointTo(ptj,ptOnLine);
if(!ptOnLine.isEqualTo(ptS, g_globalTol) && !ptOnLine.isEqualTo(ptE, g_globalTol))
pti = ptLampIns;
}
if(bIsLamp2)
{
AcGePoint3d ptOnLine;
lineLamp.getClosestPointTo(pti,ptOnLine);
if(!ptOnLine.isEqualTo(ptS, g_globalTol) && !ptOnLine.isEqualTo(ptE, g_globalTol))
ptj = ptLampIns;
}
// modifiy end
if((nMinDist > 0 && pti.Distance(ptj) < nMinDist) || (nMinDist < 0)){
nMinDist = pti.Distance(ptj); //找最近连接点
ptCen2 = ptj;
ptCen1 = pti;
double angle = ads_angle(ptCen1, ptCen2);
if(flag1){ //如果是圆块, 找延长线为圆心的点
ads_polar(ptCen1, angle, nRadius1, ptCen1);
}
angle = ads_angle(ptCen2, ptCen1);
if(flag2){
ads_polar(ptCen2, angle, nRadius2, ptCen2);
}
}
}
}
if(!!ptCen1 && !!ptCen2){
CWire::DrawLineWire(ptCen1, ptCen2, csLayer, csLineType, nLineThick);
Entity ent;
ent.GetLast();
WriteXdata(ent, _T("linenum"), (const TCHAR*)csName);
WriteXdata(ent, _T("ltype"), csType); //导线型号
WriteXdata(ent, _T("ldm"), csRadius); //穿管直径
WriteXdata(ent, _T("lmeth"), csMode); //配线方式
WriteXdata(ent, _T("linst"), csPlace); //敷设部位
WriteXdata(ent, _T("lnoar"), csArea); //规格
WriteXdata(ent, _T("lnorm"), csNorm); //
bRet = TRUE;
}
return bRet;
}
//(通用布线) 画直导线时, 得到最佳两点
BOOL DrawPLineWireBy2Equip_OLD(Entity oldent, Entity ent1, Entity ent2)
{
BOOL bRet(FALSE);
CWire wire1(oldent);
CString csLayer = wire1.GetWireLayer();
CString csLineType = wire1.GetLineType();
double nLineThick = wire1.GetLineThick();
CString csName = ReadXdata(oldent, _T("linenum"));
CString csType = ReadXdata(oldent, _T("ltype"));
CString csRadius = ReadXdata(oldent, _T("ldm"));
CString csMode = ReadXdata(oldent, _T("lmeth"));
CString csPlace = ReadXdata(oldent, _T("linst"));
CString csArea = ReadXdata(oldent, _T("lnoar"));
CString csNorm = ReadXdata(oldent, _T("lnorm"));
XPoint ptCen1, ptCen2;
XPointList lst111, lst222;
BOOL flag1(FALSE), flag2(FALSE), bIsLamp1(FALSE), bIsLamp2(FALSE);
double nRadius1(0.0), nRadius2(0.0);
CString csAttribText1 = GetAttrib(ent1, _T("A"));
CString csAttribText2 = GetAttrib(ent2, _T("A"));
// if(csAttribText1.Find(_T("荧光灯")) > -1 && csAttribText2.Find(_T("荧光灯")) < 0){
// ent1.GetData(10, ptCen1);
// bIsLamp1 = TRUE;
// }
// else if(csAttribText2.Find(_T("荧光灯")) > -1 && csAttribText1.Find(_T("荧光灯")) < 0){
// bIsLamp2 = TRUE;
// ent2.GetData(10, ptCen2);
// }
flag1 = GetEquipPoint(ent1, lst111, nRadius1);
flag2 = GetEquipPoint(ent2, lst222, nRadius2);
//2008-4-9 sr 增加以下40行. 解决,开关连接荧光灯的时候, 希望连接在荧光灯的中间, 而不是根据就近原则连接到荧光灯的边上
if(csAttribText1.Find(_T("开关")) > -1 && csAttribText2.Find(_T("荧光灯")) > -1){
XPointList lstPtTrue;
double dLampAng(0);
ent2.GetData(50, &dLampAng);
XPoint ptLampTmp, ptLampIns;
ent2.GetData(10, ptLampIns);
ads_polar(ptLampIns, dLampAng, 50, ptLampTmp);
// 得到荧光灯图块的向量
AcGeVector3d vt1 = ptLampTmp - ptLampIns;
int len2 = lst222.Length();
for(int m=0;m<len2;m++){
XPoint pt1 = *lst222[m];
AcGeVector3d vt2 = pt1 - ptLampIns;
if(vt1.isParallelTo(vt2)!=Adesk::kTrue){
lstPtTrue.NewAppend(pt1);
}
}
lst222.Reset();
lst222 = lstPtTrue;
}
else if(csAttribText2.Find(_T("开关")) > -1 && csAttribText1.Find(_T("荧光灯")) > -1){
XPointList lstPtTrue;
double dLampAng(0);
ent1.GetData(50, &dLampAng);
XPoint ptLampTmp, ptLampIns;
ent1.GetData(10, ptLampIns);
ads_polar(ptLampIns, dLampAng, 50, ptLampTmp);
// 得到荧光灯图块的向量
AcGeVector3d vt1 = ptLampTmp - ptLampIns;
int len2 = lst111.Length();
for(int m=0;m<len2;m++){
XPoint pt1 = *lst111[m];
AcGeVector3d vt2 = pt1 - ptLampIns;
if(vt1.isParallelTo(vt2)!=Adesk::kTrue){
lstPtTrue.NewAppend(pt1);
}
}
lst111.Reset();
lst111 = lstPtTrue;
}
double xscale;
ent1.GetData(41, &xscale);
nRadius1 *= fabs(xscale);
ent2.GetData(41, &xscale);
nRadius2 *= fabs(xscale);
int len1 = lst111.Length();
int len2 = lst222.Length();
double nMinDist = -1;
for(int i=0;i<len1;i++){
XPoint pti = *lst111[i];
if(bIsLamp1)
pti = ptCen1;
for(int j=0;j<len2;j++){
XPoint ptj = *lst222[j];
if(bIsLamp2)
ptj = ptCen2;
if((nMinDist > 0 && pti.Distance(ptj) < nMinDist) || (nMinDist < 0)){
nMinDist = pti.Distance(ptj); //找最近连接点
ptCen2 = ptj;
ptCen1 = pti;
double angle = ads_angle(ptCen1, ptCen2);
if(flag1){ //如果是圆块, 找延长线为圆心的点
ads_polar(ptCen1, angle, nRadius1, ptCen1);
}
angle = ads_angle(ptCen2, ptCen1);
if(flag2){
ads_polar(ptCen2, angle, nRadius2, ptCen2);
}
}
}
}
if(!!ptCen1 && !!ptCen2){
CWire::DrawLineWire(ptCen1, ptCen2, csLayer, csLineType, nLineThick);
Entity ent;
ent.GetLast();
WriteXdata(ent, _T("linenum"), (const TCHAR*)csName);
WriteXdata(ent, _T("ltype"), csType); //导线型号
WriteXdata(ent, _T("ldm"), csRadius); //穿管直径
WriteXdata(ent, _T("lmeth"), csMode); //配线方式
WriteXdata(ent, _T("linst"), csPlace); //敷设部位
WriteXdata(ent, _T("lnoar"), csArea); //规格
WriteXdata(ent, _T("lnorm"), csNorm); //
bRet = TRUE;
}
return bRet;
}
void GetBlkBreakPtByPoly(XCircle cir, Entity entBreak, XPoint &ptBr1, XPoint &ptBr2)
{
XPoint ptFirst, ptEnd;
BOOL bFlag = FALSE;
if(entBreak.Is(_T("LINE"))){
XCurveSegment seg(entBreak);
ptFirst = seg.StartPoint();
ptEnd = seg.EndPoint();
XPoint ptInters, ptInters2, ptBreak1, ptBreak2;
int ret;
if(seg.Is(CURVE_LINE))
{
XLine lineTmp = seg.GetLine();
ret = cir.Intersection(&lineTmp, ptInters, ptInters2);
}
else if(seg.Is(CURVE_ARC))
{
XArc arcTmp = seg.GetArc();
ret = cir.Intersection(&arcTmp, ptInters, ptInters2);
}
if(ret == 2){
ptBr1 = ptInters;
ptBr2 = ptInters2;
return;
}
if(ret == 1){
if(bFlag)
ptBr2 = ptInters;
else{
ptBr1 = ptInters;
bFlag = TRUE;
}
}
if(!!ptBr1 && !!ptBr2)
return;
}
else{
XPoly2D xpoly(entBreak);
ptFirst = *xpoly[0];
ptEnd = *xpoly[xpoly.Length()-1];
for(int n=0; n<xpoly.TotalSegments(); n++) {
XCurveSegment seg;
xpoly.Nth(n, seg);
XPoint ptInters, ptInters2, ptBreak1, ptBreak2;
int ret;
if(seg.Is(CURVE_LINE))
{
XLine lineTmp = seg.GetLine();
ret = cir.Intersection(&lineTmp, ptInters, ptInters2);
}
else if(seg.Is(CURVE_ARC))
{
XArc arcTmp = seg.GetArc();
ret = cir.Intersection(&arcTmp,ptInters, ptInters2);
}
if(ret == 2){
ptBr1 = ptInters;
ptBr2 = ptInters2;
return;
}
if(ret == 1){
if(bFlag)
ptBr2 = ptInters;
else{
ptBr1 = ptInters;
bFlag = TRUE;
}
}
if(!!ptBr1 && !!ptBr2)
return;
}
}
if(ads_distance(cir.GetCenterPt(), ptEnd) < ads_distance(cir.GetCenterPt(), ptFirst))
ptBr2 = ptEnd;
else
ptBr2 = ptFirst;
}
double GetWireWidth(Entity ent)
{
double nLineThick(0);
if(ent.Is(_T("LWPOLYLINE"))){
ent.GetData(40, &nLineThick);
}
else if(ent.Is(_T("ATS_RECT"))){
OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbRect, pEnt);
if(pEnt){
double x = pEnt->GetSizeX();
double y = pEnt->GetSizeY();
nLineThick = x < y ? x : y;
}
OPENOBJ_END();
}
return nLineThick;
}
Entity GetCulBreakPWire(PickSet &ssAllBreak, PickSet &ssff)
{
for(long m=0;m<ssAllBreak.Length();m++){
for(long n=0;n<ssff.Length();n++){
if(ssAllBreak[m] == ssff[n]){
return ssAllBreak[m];
}
}
}
return Entity();
}
void GetMWire2Line(Entity ent, XLine &line1, XLine &line2)
{
if(!ent.Is(_T("ATS_RECT")))
return;
OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbRect, pEnt);
if(pEnt){
double x = pEnt->GetSizeX();
double y = pEnt->GetSizeY();
double width = x < y ? x : y;
double ang = pEnt->GetRotation();
if(ang >= PI)
ang -= PI;
XPoint pt1, pt2, pt3, pt4;
if(pEnt->GetRotation() >= PI){
pt1 = pEnt->GetUpLeft();
pt2 = pEnt->GetUpRight();
pt3 = pEnt->GetLowLeft();
pt4 = pEnt->GetLowRight();
}
else{
pt1 = pEnt->GetLowLeft();
pt2 = pEnt->GetLowRight();
pt3 = pEnt->GetUpLeft();
pt4 = pEnt->GetUpRight();
}
XLine line3(pt1, pt2, 1);
line1 = line3;
XLine line4(pt3, pt4, 1);
line2 = line4;
}
OPENOBJ_END();
}
void BreakMWire(Entity entSel, XPoint ptPick, XPoint ptPick2)
{
XPoint ptCen, ptCen1, ptCen2, ptInter1, ptInter2, ptInter3, ptInter4, ptLowLeft, ptLowRight, ptUpRight, ptUpLeft;
XLine line3(1), line4(1);
GetMWire2Line(entSel, line3, line4);
double width(0), length(0), ang(0);
OPENOBJ_BEGIN(entSel, AcDb::kForWrite, TDbRect, pEnt);
if(pEnt){
ptUpLeft = pEnt->GetUpLeft();
ptCen = pEnt->GetCenter();
double x = pEnt->GetSizeX();
double y = pEnt->GetSizeY();
width = x < y ? x : y;
ang = pEnt->GetRotation();
if(ang >= PI){
ang -= PI;
}
XPoint ptTmp1, ptTmp2;
ads_polar(ptPick, ang-PI/2, width, ptTmp1);
ads_polar(ptPick, ang+PI/2, width, ptTmp2);
XLine line1(ptTmp1, ptTmp2, 1);
ads_polar(ptPick2, ang-PI/2, width*2, ptTmp1);
ads_polar(ptPick2, ang+PI/2, width*2, ptTmp2);
XLine line2(ptTmp1, ptTmp2, 1);
line3.Intersection(&line1, ptInter1);
line3.Intersection(&line2, ptInter2);
line4.Intersection(&line1, ptInter3);
line4.Intersection(&line2, ptInter4);
double n1 = ads_distance(ptInter1, ptUpLeft);
double n2 = ads_distance(ptInter2, ptUpLeft);
double n3 = ads_distance(ptInter1, ptInter2);
double nX = n1 < n2 ? n1 : n2;
ads_polar(ptCen, ang+PI, (x-nX)/2, ptCen1);
pEnt->SetSizeX(nX);
pEnt->SetCenter(ptCen1);
length = x - nX - n3;
ads_polar(ptCen, ang, x/2-length/2, ptCen2);
}
OPENOBJ_END();
if(length > 0 && width > 0 && !!ptCen2){
TDbRect *pRect = new TDbRect;
pRect->setLayer(LAY_WIRE_BUS);
pRect->SetSizeX(length);
pRect->SetRotation(ang);
pRect->SetSizeY(width);
pRect->SetCenter(ptCen2) ;
pRect->AddToCSpace(Adesk::kTrue);
}
}
void DoBreakPLineOld(Entity ent, DList<CBreakPtList> &lstPt)
{
int len = lstPt.Length();
if(len < 1)
return;
PickSet ssAllBreak(SS_FREE);
ssAllBreak += ent;
double m = GetWireWidth(ent);
RBList rbMask = ads_buildlist( -4, _T("<or"),
-4, _T("<and"), RTDXF0, _T("LWPOLYLINE"), 8, GetLayerNames(_T("导线")), -4, _T("and>"),
-4, _T("<and"), RTDXF0, _T("LINE"), 8, GetLayerNames(_T("导线")), -4, _T("and>"),
-4, _T("<and"), RTDXF0, _T("ARC"), 8, GetLayerNames(_T("导线")), -4, _T("and>"),
-4, _T("<and"), RTDXF0, _T("ATS_RECT"), 8, LAY_WIRE_BUS, -4, _T("and>"),
-4, _T("or>"), NULL);
for(int i=0;i<len;i++){
XPoint ptBreak1, ptBreak2;
ptBreak1 = lstPt[i]->m_ptFirst;
ptBreak2 = lstPt[i]->m_ptEnd;
Entity entSel;
PickSet ssff(SS_FREE);
GetPointPickSet(ptBreak1, ssff, rbMask, (int)m);
long ff = ssff.Length();
entSel = GetCulBreakPWire(ssAllBreak, ssff);
if(!entSel){
continue;
}
if(entSel.Is(_T("LWPOLYLINE"))){
ads_command(RTSTR, _T(".BREAK"), RTLB, RTENAME, (TLong_ptr*)entSel, RT3DPOINT, &ptBreak1, RTLE, RTSTR, _T("F"), RT3DPOINT, &ptBreak1, RT3DPOINT, &ptBreak2, RTNONE);
}
if(entSel.Is(_T("LINE"))){
ads_command(RTSTR, _T(".BREAK"), RTLB, RTENAME, (TLong_ptr*)entSel, RT3DPOINT, &ptBreak1, RTLE, RTSTR, _T("F"), RT3DPOINT, &ptBreak1, RT3DPOINT, &ptBreak2, RTNONE);
}
if(entSel.Is(_T("ARC"))){
ads_command(RTSTR, _T(".BREAK"), RTLB, RTENAME, (TLong_ptr*)entSel, RT3DPOINT, &ptBreak1, RTLE, RTSTR, _T("F"), RT3DPOINT, &ptBreak1, RT3DPOINT, &ptBreak2, RTNONE);
}
else if(_T("ATS_RECT")){
BreakMWire(entSel, ptBreak1, ptBreak2);
ads_command(RTSTR, _T("REDRAW"), RTNONE);
}
Entity entTmp;
entTmp.GetLast();
ssAllBreak += entTmp;
}
}
bool PtIsOnLine(const XPoint &pt1, const XPoint &pt2, DList<CBreakPtList> &lstPt)
{
int nLen = lstPt.Length();
XPoint ptFirst, ptSecond;
double dDist = 0.001;
for(int i = 0; i < nLen; ++i)
{
ptFirst = lstPt[i]->m_ptFirst;
ptSecond = lstPt[i]->m_ptEnd;
if (((ptFirst.Distance(pt1) < dDist) && (ptSecond.Distance(pt2) < dDist)) || ((ptFirst.Distance(pt2) < dDist) && (ptSecond.Distance(pt1) < dDist)))
{
return true;
}
}
return false;
}
// 打断点组
struct SBreakPts
{
SBreakPts(XPoint pS, double dS, XPoint pE, double dE)
:ptS(pS), dDistS(dS), ptE(pE), dDistE(dE)
{}
XPoint ptS, ptE;
double dDistS, dDistE;
};
void AdjustBreakPt(Entity ent, DList<CBreakPtList> &lstPt)
{
int nLen = lstPt.Length();
if (nLen < 1)
return;
int i = 0;
int j = 0;
std::vector<SBreakPts> vecPts;
AcGePoint3d ptS, ptE, ptTemp;
double dDistS = 0.0, dDistE = 0.0, dTemp = 0.0;
BOOL bSerch = FALSE;
BOOL bStartIn = FALSE;
BOOL bEndIn = FALSE;
XPoly2D polyMain(ent);
OPENOBJ_BEGIN(ent, AcDb::kForRead, AcDbCurve, pCurve);
if (pCurve != NULL)
{
for(i = 0; i < nLen; ++i)
{
ptS = lstPt[i]->m_ptFirst;
ptE = lstPt[i]->m_ptEnd;
//modify liaoy 2016-7-11 lstPt全部为wcs坐标,无需再转换
//add liaoy 2015-12-30
//UCS2WCS(ptS);
//UCS2WCS(ptE);
//add end
//modify end
//axc add 2016-12-05 保证点落在导线上
AcGePoint3d ptSTemp,ptETemp;
pCurve->getClosestPointTo(ptS,ptSTemp);
pCurve->getClosestPointTo(ptE,ptETemp);
if (ptSTemp.distanceTo(ptS) < 1E-3 &&
ptETemp.distanceTo(ptE) < 1E-3)
{
ptS = ptSTemp;
ptE = ptETemp;
}
if (pCurve->getDistAtPoint(ptS, dDistS) == Acad::eOk &&
pCurve->getDistAtPoint(ptE, dDistE) == Acad::eOk)
{
if (dDistS > dDistE)
{
dTemp = dDistS;
dDistS = dDistE;
dDistE = dTemp;
ptTemp = ptS;
ptS = ptE;
ptE = ptTemp;
}
int nCurLen = vecPts.size();
bSerch = FALSE;
for (j = 0; j < nCurLen; j++)
{
bStartIn = dDistS >= vecPts[j].dDistS && dDistS <= vecPts[j].dDistE;
bEndIn = dDistE >= vecPts[j].dDistS && dDistE <= vecPts[j].dDistE;
bSerch = bStartIn || bEndIn;
if (bStartIn && !bEndIn)
{
vecPts[j].dDistE = dDistE;
vecPts[j].ptE = ptE;
break;
}
else if (!bStartIn && bEndIn)
{
vecPts[j].dDistS = dDistS;
vecPts[j].ptS = ptS;
break;
}
}
if (FALSE == bSerch)
vecPts.push_back(SBreakPts(ptS, dDistS, ptE, dDistE));
}
}
}
OPENOBJ_END();
lstPt.Reset();
nLen = vecPts.size();
for (i = 0; i < nLen; i++)
{
lstPt.Append(new CBreakPtList(vecPts[i].ptS, vecPts[i].ptE));
}
}
// add by sps 2013.4.18
// 功能:对打断点组交叉的状况 做出融合
void AdjustBreakPt_old(Entity ent, DList<CBreakPtList> &lstPt)
{
int nLen = lstPt.Length();
if (nLen < 1)
return;
int i = 0;
int j = 0;
std::vector<SBreakPts> vecPts;
AcGePoint3d ptS, ptE, ptTemp;
double dDistS = 0.0, dDistE = 0.0, dTemp = 0.0;
BOOL bSerch = FALSE;
BOOL bStartIn = FALSE;
BOOL bEndIn = FALSE;
OPENOBJ_BEGIN(ent, AcDb::kForRead, AcDbCurve, pCurve);
if (pCurve != NULL)
{
for(i = 0; i < nLen; ++i)
{
ptS = lstPt[i]->m_ptFirst;
ptE = lstPt[i]->m_ptEnd;
if (pCurve->getDistAtPoint(ptS, dDistS) == Acad::eOk &&
pCurve->getDistAtPoint(ptE, dDistE) == Acad::eOk)
{
if (dDistS > dDistE)
{
dTemp = dDistS;
dDistS = dDistE;
dDistE = dTemp;
ptTemp = ptS;
ptS = ptE;
ptE = ptTemp;
}
int nCurLen = vecPts.size();
bSerch = FALSE;
for (j = 0; j < nCurLen; j++)
{
bStartIn = dDistS >= vecPts[j].dDistS && dDistS <= vecPts[j].dDistE;
bEndIn = dDistE >= vecPts[j].dDistS && dDistE <= vecPts[j].dDistE;
bSerch = bStartIn || bEndIn;
if (bStartIn && !bEndIn)
{
vecPts[j].dDistE = dDistE;
vecPts[j].ptE = ptE;
break;
}
else if (!bStartIn && bEndIn)
{
vecPts[j].dDistS = dDistS;
vecPts[j].ptS = ptS;
break;
}
}
if (FALSE == bSerch)
vecPts.push_back(SBreakPts(ptS, dDistS, ptE, dDistE));
}
}
}
OPENOBJ_END();
lstPt.Reset();
nLen = vecPts.size();
for (i = 0; i < nLen; i++)
{
lstPt.Append(new CBreakPtList(vecPts[i].ptS, vecPts[i].ptE));
}
}
void DoBreakPLine(Entity ent, DList<CBreakPtList> &lstPt)
{
AdjustBreakPt(ent, lstPt);
int nLen = lstPt.Length();
if (nLen < 1)
{
return;
}
bool bFlag = false;
OPENOBJ_BEGIN(ent, AcDb::kForRead, AcDbCurve, pCurve);
if (pCurve != NULL)
{
// 对打断点排序
AcGePoint3d ptFirst, ptSecond;
std::multimap<double, AcGePoint3d> mapPts;
for(int i = 0; i < nLen; ++i)
{
ptFirst = lstPt[i]->m_ptFirst;
ptSecond = lstPt[i]->m_ptEnd;
double dDist1 = 0.0, dDist2 = 0.0;
if (pCurve->getDistAtPoint(ptFirst, dDist1) != Acad::eOk || pCurve->getDistAtPoint(ptSecond, dDist2) != Acad::eOk)
{
return;
}
mapPts.insert(std::make_pair(dDist1, ptFirst));
mapPts.insert(std::make_pair(dDist2, ptSecond));
}
AcGePoint3dArray arrBreakPt;
std::multimap<double, AcGePoint3d>::iterator it, itEnd = mapPts.end();
for (it = mapPts.begin(); it != itEnd; ++it)
{
arrBreakPt.append(it->second);
}
AcDbVoidPtrArray arrPtr;
if (pCurve->getSplitCurves(arrBreakPt, arrPtr) == Acad::eOk)
{
int nSize = arrPtr.length();
AcDbCurve *pCve = NULL;
AcGePoint2d pt;
AcGePoint3d ptS, ptE;
for (int j = 0; j < nSize; ++j)
{
pCve = (AcDbCurve*)arrPtr[j];
if (pCve == NULL)
{
delete arrPtr[j];
continue;
}
pCve->getStartPoint(ptS);
pCve->getEndPoint(ptE);
if (!PtIsOnLine(XPoint(ptS), XPoint(ptE), lstPt)) // 两点不在分割点集中
{
AcDbCurve *pCurveNew = (AcDbCurve*)pCurve->clone();
AcDbLine *pLine = AcDbLine::cast(pCurveNew);
AcDbArc *pArc = AcDbArc::cast(pCurveNew);
AcDbPolyline *pPLine = AcDbPolyline::cast(pCurveNew);
if (pLine != NULL)
{
pLine->setStartPoint(ptS);
pLine->setEndPoint(ptE);
}
else if (pArc != NULL)
{
AcDbArc *pArc2 = (AcDbArc*)pCve;
if (pArc2 == NULL)
{
delete pCve;
delete pCurveNew;
continue;
}
pArc->setStartAngle(pArc2->startAngle());
pArc->setEndAngle(pArc2->endAngle());
pArc->setCenter(pArc2->center());
pArc->setRadius(pArc2->radius());
}
else if (pPLine != NULL)
{
int nNum = pPLine->numVerts();
while(nNum > 0)
{
pPLine->removeVertexAt(nNum - 1);
--nNum;
}
int nLineLen = pPLine->numVerts();
AcDbPolyline *pTemp = (AcDbPolyline*)pCve;
if (pTemp == NULL)
{
delete pCve;
delete pCurveNew;
continue;
}
nNum = pTemp->numVerts();
double dBulge = 0.0, dWidthS = 0.0, dWidthE = 0.0;
for (int k = 0; k < nNum; ++k)
{
pTemp->getPointAt(k, pt);
pTemp->getBulgeAt(k, dBulge);
pTemp->getWidthsAt(k, dWidthS, dWidthE);
if (k == 0 && nLineLen == 1) // 最后一点无法删除
{
pPLine->setPointAt(k, pt);
pPLine->setBulgeAt(k, dBulge);
pPLine->setWidthsAt(k, dWidthS, dWidthE);
}
else
{
pPLine->addVertexAt(k, pt, dBulge, dWidthS, dWidthE);
}
}
}
else
{
delete pCve;
delete pCurveNew;
continue;
}
AddToCurrentSpace(pCurveNew, Adesk::kTrue);
bFlag = true;
}
delete pCve;
}
}
}
OPENOBJ_END();
if (bFlag)
{
ent.Erase();
}
}
//////////////////////////////////////////////////////////////////////////
//add liaoy 170725
XCurveSegment GetBlkSel(AcDbEntity *pEnt, XPoint ptPick,const double& xscale = 1,const AcGeMatrix3d& mat = AcGeMatrix3d::kIdentity)
{
XCurveSegment seg;
const double dTol = g_nEqBlkLength/20;
if (!pEnt)
return seg;
AcDbCircle *pCir = NULL;
AcDbPolyline *pPoly = NULL;
AcDbLine *pLine = NULL;
AcDbArc *pArc = NULL;
if(pCir = AcDbCircle::cast(pEnt))
{
AcGePoint3d ptIns = pCir->center();
ptIns = ptIns.transformBy(mat);
XCircle cir(asDblArray(ptIns), pCir->radius()*xscale);
seg = cir;
if(IsPtOnCircle(ptPick, cir, dTol))
{
return seg;
}
}
else if(pPoly = AcDbPolyline::cast(pEnt))
{
/*
XPoly2D poly;
PolyConvert(*pPoly, poly);
poly.TransformBy(mat);//多段线TransformBy时若为非均匀缩放矩阵或非正交矩阵则不一定成功
double n;
seg = GetSegByPt(poly, ptPick, n);
if(!!seg)
return seg;
*/
AcGePoint3d ptS,ptE;
double dBulge(0);
int nNumVer = pPoly->numVerts();
for (int m = 0;m < nNumVer;m++)
{
if (m == nNumVer - 1 && !pPoly->isClosed())
break;
if ( Acad::eOk == pPoly->getPointAt(m,ptS) &&
Acad::eOk == pPoly->getPointAt( (m + 1) % nNumVer,ptE) &&
Acad::eOk == pPoly->getBulgeAt(m,dBulge))
{
ptS = ptS.transformBy(mat);
ptE = ptE.transformBy(mat);
if (fabs(dBulge) <= TOL)//直线
{
XLine line(asDblArray(ptS), asDblArray(ptE), LS_FINITE);
seg = line;
if(IsPtOnLine(ptPick, line, dTol))
{
return seg;
}
}
else//弧线
{
XArc arc(asDblArray(ptS), asDblArray(ptE), atan(dBulge) * 4);
seg = arc;
if(IsPtOnArc(ptPick, arc, dTol))
{
return seg;
}
}
}
}
}
else if(pLine = AcDbLine::cast(pEnt))
{
AcGePoint3d ptStart = pLine->startPoint();
ptStart = ptStart.transformBy(mat);
AcGePoint3d ptEnd = pLine->endPoint();
ptEnd = ptEnd.transformBy(mat);
XLine line(asDblArray(ptStart), asDblArray(ptEnd), 1);
seg = line;
if(IsPtOnLine(ptPick, line, dTol))
{
return seg;
}
}
else if(pArc = AcDbArc::cast(pEnt))
{
AcGePoint3d ptIns = pArc->center();
ptIns = ptIns.transformBy(mat);
XArc arc(asDblArray(ptIns), pArc->radius()*xscale, pArc->startAngle(), pArc->endAngle());
seg = arc;
if(IsPtOnArc(ptPick, arc, dTol))
{
return seg;
}
}
return XCurveSegment();
}
//广度优先获取块实体和Matrix,外部不能释放arpNewSet
BOOL GetWidthBlkEntity(AcDbBlockReference* pRef,AcArray<AcArray<std::pair<AcDbEntity*,AcGeMatrix3d>>>& arpNewSet)
{
if(!pRef)
return FALSE;
AcDbBlockTableRecordIterator *pIterator = NULL;
OPENOBJ_BEGIN(pRef->blockTableRecord(), AcDb::kForRead, AcDbBlockTableRecord , pRec);
if(pRec)
pRec->newIterator(pIterator);
OPENOBJ_END();
AcArray<std::pair<AcDbEntity*,AcGeMatrix3d>> entSet;
AcGeMatrix3d mat = pRef->blockTransform();
if (pIterator)
{
for(pIterator->start(); !pIterator->done(); pIterator->step())
{
AcDbEntity *pEnt = NULL;
pIterator->getEntity(pEnt, AcDb::kForRead);
if(pEnt)
{
entSet.append(std::make_pair(pEnt,mat));
pEnt->close();
}
}
delete pIterator;
pIterator = NULL;
}
if (entSet.length() <= 0)
return FALSE;
arpNewSet.append(entSet);
while(TRUE)
{
int nLayerSize = arpNewSet.length();
if (nLayerSize <= 0)
break;
int nLastLayerSize = arpNewSet[nLayerSize - 1].length();
if (nLastLayerSize <= 0)
break;
entSet.removeAll();
for(int n=0; n<nLastLayerSize; n++)
{
AcDbEntity *pNewEnt=(arpNewSet[nLayerSize - 1][n]).first;
AcGeMatrix3d matNew = (arpNewSet[nLayerSize - 1][n]).second;
if(pNewEnt == NULL)
continue;
AcDbBlockReference* pRefNew = AcDbBlockReference::cast(pNewEnt);
if (pRefNew)
{
pIterator = NULL;
OPENOBJ_BEGIN(pRefNew->blockTableRecord(), AcDb::kForRead, AcDbBlockTableRecord , pRecNew);
if(pRecNew)
pRecNew->newIterator(pIterator);
OPENOBJ_END();
if (pIterator)
{
mat = pRefNew->blockTransform();
for(pIterator->start(); !pIterator->done(); pIterator->step())
{
AcDbEntity *pEnt = NULL;
pIterator->getEntity(pEnt, AcDb::kForRead);
if(pEnt)
{
entSet.append(std::make_pair(pEnt,matNew * mat));
pEnt->close();
}
}
delete pIterator;
pIterator = NULL;
}
}
}
if (entSet.length() <= 0)
break;
arpNewSet.append(entSet);
}
return TRUE;
}
bool SetLayerLockedTel(const CString& sLayerName, bool bLock)
{
XStringList lstLayerName;
lstLayerName.Append(tstrnew(sLayerName));
return SetLayerLockedTel(lstLayerName,bLock);
}
bool SetLayerLockedTel(XStringList& lstLayerName, bool bLock)
{
//
AcDbLayerTable *pLayertable = NULL;
Acad::ErrorStatus es = acdbCurDwg()->getLayerTable(pLayertable, AcDb::kForRead);
if (pLayertable)
{
AcAxDocLock docLock(acdbCurDwg());
for(int i = 0;i < lstLayerName.Length();i++)
{
CString sCurLayerName = lstLayerName[i];
AcDbLayerTableRecord *pLayerRec = NULL;
es = pLayertable->getAt(sCurLayerName, pLayerRec, AcDb::kForWrite);
if (pLayerRec)
{
if (bLock != pLayerRec->isLocked())
{
pLayerRec->setIsLocked(bLock);
}
pLayerRec->close();
}
}
pLayertable->close();
return true;
}
return false;
//
//ads_command(RTSTR, _T("-layer"), RTSTR, bLock ? _T("LO") : _T("U"), RTSTR,_T("layer1,layer2,...") , RTSTR, _T(""), RTNONE);
//上述方法也能锁定/解锁图层,并更新淡显效果,无需re;但对图层名带'#'的不能锁定/解锁
/*
XStringList lstNeedDeal;
AcDbLayerTable *pLayertable = NULL;
Acad::ErrorStatus es = acdbCurDwg()->getLayerTable(pLayertable, AcDb::kForRead);
if (pLayertable)
{
AcAxDocLock docLock(acdbCurDwg());
for(int i = 0;i < lstLayerName.Length();i++)
{
CString sCurLayerName = lstLayerName[i];
AcDbLayerTableRecord *pLayerRec = NULL;
es = pLayertable->getAt(sCurLayerName, pLayerRec, AcDb::kForRead);
if (pLayerRec)
{
if (lstNeedDeal.Index(sCurLayerName) < 0 && bLock != pLayerRec->isLocked())
{
lstNeedDeal.Append(tstrnew(sCurLayerName));
}
pLayerRec->close();
}
}
pLayertable->close();
}
bool bRet = false;
int nLength = lstNeedDeal.Length();
if (nLength > 0)
{
CString csAll = lstNeedDeal[0];
for (int i=1; i<nLength; i++)
{
csAll += _T(",");
csAll += lstNeedDeal[i];
}
if (!csAll.IsEmpty())
{
ads_command(RTSTR, _T("-layer"), RTSTR, bLock ? _T("LO") : _T("U"), RTSTR, csAll, RTSTR, _T(""), RTNONE);
bRet = true;
}
}
return bRet;
*/
}
//更新淡显效果
void UpdateLayerLockFade(BOOL bRegen)
{
ads_command(RTSTR, _T("-layer"),RTSTR, _T(""), RTNONE);
if (bRegen)
ads_command(RTSTR, _T("regen"), RTNONE);
else
adsout << _T("需要手工REGEN才能更新锁定图层透明效果\n");
}
//////////////////////////////////////////////////////////////////////////
XCurveSegment GetBlkSel(Entity entBlk, XPoint ptPick)
{
double xscale;
entBlk.GetData(41, &xscale);
XBlock myBlock(entBlk);
if(!myBlock.m_bInitSuccess)
return XCurveSegment();
//mod liaoy 170712修改为广度优先循环查找方法
/*
AcGeMatrix3d mat = myBlock.GetMatrix3d();
AcDbBlockTableRecordIterator *pIterator = NULL;
pIterator = myBlock.GetIterator();
if (pIterator)
{
for(pIterator->start(); !pIterator->done(); pIterator->step())
{
AcDbEntity *pEnt = NULL;
pIterator->getEntity(pEnt, AcDb::kForRead);
if (pEnt)
{
XCurveSegment seg = GetBlkSel(pEnt,ptPick,xscale,mat);
pEnt->close();
if (!!seg)
return seg;
}
}
}
*/
//mod liaoy 170712
/*修改为GetBlkSel()方法
AcDbCircle *pCir = NULL;
AcDbPolyline *pPoly = NULL;
AcDbLine *pLine = NULL;
AcDbArc *pArc = NULL;
XCurveSegment seg;
if(pCir = AcDbCircle::cast(pEnt)){
AcGePoint3d ptIns = pCir->center();
ptIns = ptIns.transformBy(myBlock.GetMatrix3d());
XCircle cir(asDblArray(ptIns), pCir->radius()*xscale);
seg = cir;
if(IsPtOnCircle(ptPick, cir, g_nEqBlkLength/20)){
pEnt->close();
return seg;
}
}
else if(pPoly = AcDbPolyline::cast(pEnt)){
XPoly2D poly;
PolyConvert(*pPoly, poly);
poly.TransformBy(myBlock.GetMatrix3d());
double n;
seg = GetSegByPt(poly, ptPick, n);
if(!!seg)
return seg;
}
else if(pLine = AcDbLine::cast(pEnt)){
AcGePoint3d ptStart = pLine->startPoint();
ptStart = ptStart.transformBy(myBlock.GetMatrix3d());
AcGePoint3d ptEnd = pLine->endPoint();
ptEnd = ptEnd.transformBy(myBlock.GetMatrix3d());
XLine line(asDblArray(ptStart), asDblArray(ptEnd), 1);
seg = line;
if(IsPtOnLine(ptPick, line, g_nEqBlkLength/20)){
pEnt->close();
return seg;
}
}
else if(pArc = AcDbArc::cast(pEnt)){
AcGePoint3d ptIns = pArc->center();
ptIns = ptIns.transformBy(myBlock.GetMatrix3d());
XArc arc(asDblArray(ptIns), pArc->radius()*xscale, pArc->startAngle(), pArc->endAngle());
seg = arc;
if(IsPtOnArc(ptPick, arc, g_nEqBlkLength/20)){
pEnt->close();
return seg;
}
}
pEnt->close();
*/
//若没找到,则可能存在块嵌套,广度优先再次寻找
XCurveSegment seg;
BOOL bFind = FALSE;
AcArray<AcArray<std::pair<AcDbEntity*,AcGeMatrix3d>>> arpNewSet;
GetWidthBlkEntity(myBlock.GetBlockReference(),arpNewSet);
for (int i = 0;i < arpNewSet.length();i++)
{
for (int j = 0;j < arpNewSet[i].length();j++)
{
AcDbEntity *pEnt = arpNewSet[i][j].first;
AcGeMatrix3d matCur = arpNewSet[i][j].second;
if (pEnt)
{
seg = GetBlkSel(pEnt,ptPick,xscale,matCur);
if (!!seg)
{
bFind = TRUE;
break;
}
}
}
if(bFind)
break;
}
return seg;
//return RTNORM;
//mod end
}
Entity GetNearestEnt(PickSet &ssSel, XPoint pt)
{
double nDist = -1;
Entity entRet;
long len = ssSel.Length();
for(long i=0;i<len;i++){
Entity ent = ssSel[i];
XPoint ptIns;
ent.GetData(10, ptIns);
if(nDist < 0 || nDist > ads_distance(ptIns, pt)){
entRet = ent;
nDist = ads_distance(ptIns, pt);
}
}
return entRet;
}
BOOL IsBlkLight(Entity ent)
{
if(ReadXdata(ent, _T("light")) == _T("T"))
return TRUE;
else
return FALSE;
}
BOOL IsBlkPowerEquip(Entity ent)
{
if(ReadXdata(ent, _T("powerequip")) == _T("T"))
return TRUE;
else
return FALSE;
}
BOOL IsBlkWeakEquip(Entity ent)
{
if(ReadXdata(ent, _T("weakequip")) == _T("T"))
return TRUE;
else
return FALSE;
}
BOOL IsBlkFireEquip(Entity ent)
{
if(ReadXdata(ent, _T("fireequip")) == _T("T"))
return TRUE;
else
return FALSE;
}
BOOL IsBlkSwitch(Entity ent)
{
if(ReadXdata(ent, _T("switch")) == _T("T"))
return TRUE;
else
return FALSE;
}
BOOL IsBlkSwitchBoard(Entity ent)
{
if(ReadXdata(ent, _T("switchboard")) == _T("T"))
return TRUE;
else
return FALSE;
}
BOOL IsBlkSocket(Entity ent)
{
if(ReadXdata(ent, _T("socket")) == _T("T"))
return TRUE;
else
return FALSE;
}
BOOL IsWireCable(Entity ent)
{
if(ReadXdata(ent, _T("cable")) == _T("T"))
return TRUE;
else
return FALSE;
}
void GetWire2Point(Entity ent, XPoint &ptStart, XPoint &ptEnd)
{
if(ent.Is(_T("LINE"))){
ent.GetData(10, ptStart);
ent.GetData(11, ptEnd);
}
else if(ent.Is(_T("ARC"))){
XPoint ptCen;
double nRadius, rStart, rEnd;
ent.GetData(10, ptCen);
ent.GetData(40, &nRadius);
ent.GetData(50, &rStart);
ent.GetData(51, &rEnd);
ads_polar(ptCen, rStart, nRadius, ptStart);
ads_polar(ptCen, rEnd, nRadius, ptEnd);
}
else{
XPoly2D poly(ent);
ptStart = *poly[0];
int len = poly.Length();
ptEnd = *poly[len-1];
}
return;
}
Entity DrawLineWire(XPoint pt1, XPoint pt2, const TCHAR* szLayer)
{
PickSet ss(SS_FREE);
XLine line(pt1, pt2, 1);
RBList rbMask = ads_buildlist(RTDXF0, _T("LINE"), 8, GetLayerNames(_T("导线")), NULL);
BOOL flag = FALSE;
GetPointPickSet(pt1, ss, rbMask);
for(long i=0;i<ss.Length();i++){
Entity ent = ss[i];
XLine lineEnt(ent, 1);
double ang1 = ads_angle(pt1, pt2);
double ang2 = ads_angle(lineEnt.StartPoint(), lineEnt.EndPoint());
if(fabs(ang1 - ang2) < 0.01 || fabs(fabs(ang1 - ang2) - PI) < 0.01){
int ret1 = pt1&lineEnt;
int ret2 = pt2&lineEnt;
if((ret1 == PR_INSIDE || ret1 == PR_ONPT1 || ret1 == PR_ONPT2)
&& (ret2 == PR_INSIDE || ret2 == PR_ONPT1 || ret2 == PR_ONPT2))
flag = TRUE;
}
}
if(!flag){
InitLayer(szLayer);
XPushVarStr clayer(_T("LAYER"), szLayer);
line.Make();
Entity ent;
ent.GetLast();
return ent;
}
return Entity();
}
void DrawPWire(XPoly2D poly, const TCHAR* szLayer)
{
InitLayer(szLayer);
XPushVarStr clayer(_T("CLAYER"), szLayer);
AcDbPolyline *pLine = new AcDbPolyline;
PolyConvert(poly, *pLine);
PostToDb(pLine);
pLine->close();
}
// pt3 1 pt1
// |-----------------------|
// | 2 4 |
// |-----------------------|
// pt2 3 pt4
void GetBlkBreakPt(Entity entBlk, Entity entBreak, double nBreLen, XPoint &ptBr1, XPoint &ptBr2)
{
XPoint ptStart, ptEnd;
GetWire2Point(entBreak, ptStart, ptEnd);
XPoint ptMax, ptMin, pt1, pt2, pt3, pt4;
entBlk.GetExtend(ptMax, ptMin);
ptMax.z = 0; ptMin.z = 0;
ads_polar(ptMax, (PI * 0.25), nBreLen / 2, pt1);
ads_polar(ptMin, (PI * 1.25), nBreLen / 2, pt2);
XRectAngle rect(pt1, pt2);
if(entBreak.Is(_T("LINE"))){
XLine l(ptStart, ptEnd, LS_FINITE);
int ret = rect.Intersection(l,ptBr1, ptBr2);
if(ret == 2 || ret == 0)
return;
if(ptStart.x > rect.lowLeft.x && ptStart.x < rect.upRight.x
&& ptStart.y > rect.lowLeft.y && ptStart.y < rect.upRight.y )
ptBr2 = ptStart;
else
ptBr2 = ptEnd;
}
else if(entBreak.Is(_T("ARC"))){
XArc xarc(entBreak);
pt3.x = pt2.x;
pt3.y = pt1.y;
pt4.x = pt1.x;
pt4.y = pt2.y;
XLine l1(pt1, pt3, LS_FINITE);
XLine l2(pt3, pt2, LS_FINITE);
XLine l3(pt2, pt4, LS_FINITE);
XLine l4(pt4, pt1, LS_FINITE);
if(xarc.Intersection(&l1, ptBr1, ptBr2) == 1){
if(xarc.Intersection(&l2, ptBr2, ptBr1) == 1)
return;
if(xarc.Intersection(&l3, ptBr2, ptBr1) == 1)
return;
if(xarc.Intersection(&l4, ptBr2, ptBr1) == 1)
return;
}
if(xarc.Intersection(&l2, ptBr1, ptBr2) == 1){
if(xarc.Intersection(&l1, ptBr2, ptBr1) == 1)
return;
if(xarc.Intersection(&l3, ptBr2, ptBr1) == 1)
return;
if(xarc.Intersection(&l4, ptBr2, ptBr1) == 1)
return;
}
if(xarc.Intersection(&l3, ptBr1, ptBr2) == 1){
if(xarc.Intersection(&l1, ptBr2, ptBr1) == 1)
return;
if(xarc.Intersection(&l2, ptBr2, ptBr1) == 1)
return;
if(xarc.Intersection(&l4, ptBr2, ptBr1) == 1)
return;
}
if(xarc.Intersection(&l4, ptBr1, ptBr2) == 1){
if(xarc.Intersection(&l1, ptBr2, ptBr1) == 1)
return;
if(xarc.Intersection(&l2, ptBr2, ptBr1) == 1)
return;
if(xarc.Intersection(&l3, ptBr2, ptBr1) == 1)
return;
}
if(ptStart.x > rect.lowLeft.x && ptStart.x < rect.upRight.x
&& ptStart.y > rect.lowLeft.y && ptStart.y < rect.upRight.y )
ptBr2 = ptStart;
else
ptBr2 = ptEnd;
}
}
BOOL IsBusLine(Entity ent) //是否是干线?
{
if(!ent.Is(_T("LINE")))
return FALSE;
AcDbObjectId eId;
AcDbEntity *pEnt;
acdbGetObjectId(eId, ent);
acdbOpenObject(pEnt, eId, AcDb::kForRead);
resbuf *pxData = pEnt->xData(XD_BUSDATA);
if(pxData){
ads_relrb(pxData);
pEnt->close();
return TRUE;
}
pEnt->close();
return FALSE;
}
BOOL IsBraLine(Entity ent) //是否是干线?
{
if(!ent.Is(_T("LWPOLYLINE")) && !ent.Is(_T("LINE")))
return FALSE;
AcDbObjectId eId;
AcDbEntity *pEnt;
acdbGetObjectId(eId, ent);
acdbOpenObject(pEnt, eId, AcDb::kForRead);
resbuf *pxData = pEnt->xData(XD_BRADATA);
if(pxData){
ads_relrb(pxData);
pEnt->close();
return TRUE;
}
pEnt->close();
return FALSE;
}
void ChangeColor(Entity ent)
{
int col=1;
ent.GetData(62, &col);
ent.SetData(62, 3);
ent.Modify();
}
void Join2PLine(AcDbObjectId id, LPCTSTR lpLayName)
{
XPoint ptStart, ptEnd;
AcDbPolyline *pll;
acdbOpenObject(pll, id, AcDb::kForRead);
if(!pll)
return;
pll->getStartPoint(ptStart);
pll->getEndPoint(ptEnd);
pll->close();
PickSet ssAllPoly(SS_FREE);
ssAllPoly += id;
RBList rbMask(RTDXF0, _T("LWPOLYLINE"), 8, lpLayName, NULL);
PickSet ssPoly(SS_FREE);
XPoint ptTemp1, ptTemp2;
ptTemp1.x = ptStart.x - MM;
ptTemp1.y = ptStart.y + MM;
ptTemp2.x = ptStart.x + MM;
ptTemp2.y = ptStart.y - MM;
ssPoly.Get(_T("C"), ptTemp1, ptTemp2, rbMask);
ssAllPoly += ssPoly;
ssPoly.Free();
ptTemp1.x = ptEnd.x - MM;
ptTemp1.y = ptEnd.y + MM;
ptTemp2.x = ptEnd.x + MM;
ptTemp2.y = ptEnd.y - MM;
ssPoly.Get(_T("C"), ptTemp1, ptTemp2, rbMask);
ssAllPoly += ssPoly;
ads_name entName;
int k = ssAllPoly.Length();
acdbGetAdsName(entName, id);
Entity entPoly(entName);
PickSet ssTmp(SS_FREE);
ssTmp += ssAllPoly;
ssTmp -= entPoly;
long len = ssTmp.Length();
ChangeColor(entPoly);
if(len < 1)
return;
ads_command(RTSTR, _T(".PEDIT"), RTENAME, (TLong_ptr*)ssAllPoly[0L], RTSTR, _T("J"), RTPICKS, (TLong_ptr *)ssAllPoly, RTSTR, _T(""), RTSTR, _T(""), RTNONE);
entPoly.GetLast();
}
void DrawArcPoly(XArc arc, const TCHAR* szLayer)
{
XCurveSegment seg;
seg = arc;
XPoly2D poly2d;
seg.AsPoly2D(poly2d);
InitLayer(szLayer);
XPushVarStr clayer(_T("CLAYER"), szLayer);
AcDbPolyline *pline = new AcDbPolyline;
PolyConvert(poly2d, *pline);
PostToDb(pline);
pline->close();
Join2PLine(pline->objectId(), szLayer);
}
BOOL LstDemoDisplayPoint(XPointList &lstPtIn, XPointList &lstPtOut, double dAngle)
{
int itype;
double dAng, dOAng, dDis;
XPoint ptStart, ptEnd, ptTurn, ptstart, ptend;
XPointList lstStart, lstEnd;
int iNum = lstPtIn.Length();
ptstart = *lstPtIn[0];
ptend = *lstPtIn[iNum - 1];
if(dAngle < 0){
XLine line(ptstart, ptend, 1);
dAngle = line.Direction();
}
BOOL bFisrt = TRUE;
while(1){
struct resbuf pointbuf;
int iRet = ads_grread(5, &itype, &pointbuf);//得到动态点pointbuf
ads_point_set(pointbuf.resval.rpoint, ptEnd);//ptTurn动态点,也就是引出支线的结束点
ptEnd = Ucs2Wcs(ptEnd);
if(itype != 5 && bFisrt)
continue;
ads_redraw(NULL, 1); //不画线演示
if(itype == 11 || itype == 2) // 11右键取消 2:空格,回车
return FALSE;
else if(itype == 5){
lstStart.Reset();
lstEnd.Reset();
bFisrt = FALSE;
for(int i=0; i<iNum; i++){
ptTurn = *lstPtIn[i];//ptTurn引出线起点
dOAng = ads_angle(ptTurn, ptEnd) - dAngle;
dDis = fabs(ads_distance(ptTurn, ptEnd)*sin(dOAng));
//指出标注的引出方向
if(dOAng < 0)
dOAng += 2*PI;
if(dOAng>=PI && dOAng<2*PI)
dAng = dAngle - PI/2;
else if(dOAng>=0 && dOAng<PI)
dAng = dAngle + PI/2;
ads_polar(ptTurn, dAng, dDis, ptEnd);
ads_grdraw(Wcs2Ucs(ptTurn), Wcs2Ucs(ptEnd), -1, 0); //演示
}
}
else{
bFisrt = FALSE;
for(int i=0; i<iNum; i++){
ptTurn = *lstPtIn[i];//ptTurn引出线起点
dOAng = ads_angle(ptTurn, ptEnd) - dAngle;
dDis = fabs(ads_distance(ptTurn, ptEnd)*sin(dOAng));
//指出标注的引出方向
if(dOAng < 0)
dOAng += 2*PI;
if(dOAng>=PI && dOAng<2*PI)
dAng = dAngle - PI/2;
else if(dOAng>=0 && dOAng<PI)
dAng = dAngle + PI/2;
ads_polar(ptTurn, dAng, dDis, ptEnd);
lstPtOut.NewAppend(ptEnd);
}
return TRUE;
}
}
return FALSE;
}
//加粗元件中的PLINE
void ThickBlkPLine(Entity entBlk, double dWidth)
{
if(dWidth < 0)
dWidth = 0.35;
TCHAR szBlkName[256];
entBlk.GetData(2, szBlkName);
AcDbBlockTableRecord *pRecord = NULL;
AcDbBlockTable* pBlockTable = NULL;
acdbCurDwg()->getBlockTable(pBlockTable, AcDb::kForRead);
if(!pBlockTable)
return;
if(Acad::eOk != pBlockTable->getAt(szBlkName, pRecord, AcDb::kForRead)){
pBlockTable->close();
return;
}
pBlockTable->close();
if(!pRecord)
return;
AcDbBlockTableRecordIterator *pIterator;
pRecord->newIterator(pIterator);
pRecord->close();
if(!pIterator)
return;
for(pIterator->start(); !pIterator->done(); pIterator->step()){
AcDbEntity *pEnt = NULL;
pIterator->getEntity(pEnt, AcDb::kForWrite);
if(pEnt){
AcDbPolyline *pll = NULL;
if(pll = AcDbPolyline::cast(pEnt)){
pll->setConstantWidth(dWidth*DocGetPScale()/1500);
}
pEnt->close();
}
}
delete pIterator;
VERIFY(entBlk.GetData(2, szBlkName)==RTNORM);
}
//加粗元件中的PLINE
void ThickBlkPLine(const TCHAR* szBlkName)
{
double dWidth = g_dSysLineWidth;
AcDbBlockTableRecord *pRecord = NULL;
AcDbBlockTable* pBlockTable = NULL;
acdbCurDwg()->getBlockTable(pBlockTable, AcDb::kForRead);
if(!pBlockTable)
return;
if(Acad::eOk != pBlockTable->getAt(szBlkName, pRecord, AcDb::kForRead)){
pBlockTable->close();
return;
}
pBlockTable->close();
if(!pRecord)
return;
AcDbBlockTableRecordIterator *pIterator;
pRecord->newIterator(pIterator);
pRecord->close();
if(!pIterator)
return;
for(pIterator->start(); !pIterator->done(); pIterator->step()){
AcDbEntity *pEnt = NULL;
pIterator->getEntity(pEnt, AcDb::kForWrite);
if(pEnt){
AcDbPolyline *pll = NULL;
if(pll = AcDbPolyline::cast(pEnt)){
pll->setConstantWidth(g_dSysLineWidth*DocGetPScale()/1500);
}
pEnt->close();
}
}
delete pIterator;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
// 绘制导线
//////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL IsExistLayer(const TCHAR* szLayer)
{
BOOL bHasIt;
AcDbLayerTable *pLayerTable = NULL;
acdbCurDwg()->getLayerTable(pLayerTable, AcDb::kForRead);
bHasIt = pLayerTable->has(szLayer);
pLayerTable->close();
return bHasIt;
}
void DrawSysWire(XPoint ptStart, XPoint ptEnd, BOOL bBusLine)
{
double dWidth(0);
if(bBusLine)
dWidth = g_dBusLineWidth;
else
dWidth = g_dSysLineWidth;
CString csLay;
if(bBusLine)
csLay = LAY_WIRE_BUS;
else
csLay = LAY_WIRE_SYSTEM;
InitLayer(csLay);
XPushVarStr clayer(_T("CLAYER"), csLay);
AcDbObjectId id = NULL;
if(dWidth < 0.001){
AcDbLine *pline = new AcDbLine;
pline->setStartPoint(ptStart);
pline->setEndPoint(ptEnd);
PostToDb(pline);
pline->close();
}
else{
AcDbPolyline *pline = new AcDbPolyline;
pline->addVertexAt(0, ptStart);
pline->addVertexAt(1, ptEnd);
pline->setConstantWidth(dWidth*DocGetPScale());
PostToDb(pline);
pline->close();
id = pline->objectId();
}
}
void DrawPLineWire(XPoly2D &xpoly, int iLayerIndex, BOOL bJoin)
{
CString csLay = GetWireLayer(iLayerIndex);
if(!IsExistLayer(csLay)){
InitLayer(csLay);
SetLayerLineType(csLay, g_csLineType[iLayerIndex]);
}
else
InitLayer(csLay);
XPushVarStr clayer(_T("CLAYER"), GetWireLayer(iLayerIndex));
double dWidth = g_nWireWidth[iLayerIndex];
AcDbObjectId id = NULL;
AcDbPolyline *pline = new AcDbPolyline;
PolyConvert(xpoly, *pline);
pline->setConstantWidth(dWidth*DocGetPScale());
pline->setLinetype(GetPipeWireLayLineType(GetWireLayer(iLayerIndex)));
PostToDb(pline);
pline->close();
id = pline->objectId();
int index = iLayerIndex;
if(index == 4) //应急
index = 0;
else if(index > 4 && index < 9)//消防
index = 2;
else if(index > 8) //弱电
index = 3;
if(index >= 0 && index < 4){
Entity ent;
ent.GetLast();
WriteXdata(ent, _T("linenum"), (const TCHAR*)g_csWireLoop[index]); //回路编号//add liaoy 2016-9-23
WriteXdata(ent, _T("ltype"), (const TCHAR*)g_csWireDimType[index]); //导线型号
WriteXdata(ent, _T("ldm"), (const TCHAR*)g_csWireDimRadius[index]); //穿管直径
WriteXdata(ent, _T("lmeth"), (const TCHAR*)g_csWireDimMode[index]); //配线方式
WriteXdata(ent, _T("linst"), (const TCHAR*)g_csWireDimPlace[index]); //敷设部位
WriteXdata(ent, _T("lnoar"), (const TCHAR*)g_csWireDimArea[index]); //规格
WriteXdata(ent, _T("lnorm"), (const TCHAR*)Itoa(g_iWireDimNorm[index])); //普通、阻燃、耐火
}
if(bJoin && dWidth > 0.001)
Join2PLine(id, GetWireLayer(iLayerIndex));
}
void DrawPLineWire(XPoint ptStart, XPoint ptEnd, int iLayerIndex, BOOL bJoin)
{
CString csLay = GetWireLayer(iLayerIndex);
if(!IsExistLayer(csLay)){
InitLayer(csLay);
SetLayerLineType(csLay, g_csLineType[iLayerIndex]);
}
else
InitLayer(csLay);
XPushVarStr clayer(_T("CLAYER"), GetWireLayer(iLayerIndex));
double dWidth = g_nWireWidth[iLayerIndex];
AcDbObjectId id = NULL;
if(dWidth < 0.001){
AcDbLine *pline = new AcDbLine;
pline->setStartPoint(ptStart);
pline->setEndPoint(ptEnd);
pline->setLinetype(GetPipeWireLayLineType(GetWireLayer(iLayerIndex)));
PostToDb(pline);
pline->close();
}
else{
AcDbPolyline *pline = new AcDbPolyline;
pline->addVertexAt(0, ptStart);
pline->addVertexAt(1, ptEnd);
pline->setConstantWidth(dWidth*DocGetPScale());
pline->setLinetype(GetPipeWireLayLineType(GetWireLayer(iLayerIndex)));
pline->setElevation(ptStart.z);
PostToDb(pline);
pline->close();
id = pline->objectId();
}
//modify liaoy 2016-2-25
//插座、电话等设备,用任意布置、矩形布置等自动生成对应导线时生成的导线
//与 【平面布线】所生成的导线的标注信息不统一
int index = iLayerIndex;
//if(index == 4) //应急
// index = 0;
//else if(index > 4 && index < 9)//消防
// index = 2;
//else if(index > 8) //弱电
// index = 3;
//if(index >= 0 && index < 4){
//modify end
if(index >= 0 && index < MAX_WIRE_LEN){
Entity ent;
ent.GetLast();
WriteXdata(ent, _T("linenum"), (const TCHAR*)g_csWireLoop[index]); //回路编号//add liaoy 2016-9-23
WriteXdata(ent, _T("ltype"), (const TCHAR*)g_csWireDimType[index]); //导线型号
WriteXdata(ent, _T("ldm"), (const TCHAR*)g_csWireDimRadius[index]); //穿管直径
WriteXdata(ent, _T("lmeth"), (const TCHAR*)g_csWireDimMode[index]); //配线方式
WriteXdata(ent, _T("linst"), (const TCHAR*)g_csWireDimPlace[index]); //敷设部位
WriteXdata(ent, _T("lnoar"), (const TCHAR*)g_csWireDimArea[index]); //规格
WriteXdata(ent, _T("lnorm"), (const TCHAR*)Itoa(g_iWireDimNorm[index])); //普通、阻燃、耐火
WriteXdata(ent, _T("weakwirenum"),g_csWireLineNum[iLayerIndex]); //弱电缆根数//add liaoy 2016-2-25
}
if(bJoin && dWidth > 0.001)
Join2PLine(id, GetWireLayer(iLayerIndex));
}
void DrawPArcWire(XPoint ptStart, XPoint ptMid, XPoint ptEnd, int iLayerIndex, BOOL bJoin)
{
CString csLay = GetWireLayer(iLayerIndex);
if(!IsExistLayer(csLay)){
InitLayer(csLay);
SetLayerLineType(csLay, g_csLineType[iLayerIndex]);
}
else
InitLayer(csLay);
XArc arc(ptStart, ptMid, ptEnd);
XCurveSegment seg;
seg = arc;
XPoly2D poly2d;
seg.AsPoly2D(poly2d);
XPushVarStr clayer(_T("CLAYER"), GetWireLayer(iLayerIndex));
double dWidth = g_nWireWidth[iLayerIndex];
AcDbObjectId id = NULL;
if(dWidth < 0.001){
AcDbArc *pArc = new AcDbArc;
XArc arc(ptStart, ptMid, ptEnd);
pArc->setCenter(arc.GetCenterPt());
pArc->setRadius(arc.GetRadius());
pArc->setStartAngle(arc.GetStarAngle());
pArc->setEndAngle(arc.GetEndAngle());
pArc->setLinetype(GetPipeWireLayLineType(GetWireLayer(iLayerIndex)));
PostToDb(pArc);
pArc->close();
}
else{
AcDbPolyline *pline = new AcDbPolyline;
PolyConvert(poly2d, *pline);
pline->setConstantWidth(dWidth*DocGetPScale());
pline->setLinetype(GetPipeWireLayLineType(GetWireLayer(iLayerIndex)));
PostToDb(pline);
pline->close();
id = pline->objectId();
}
//modify liaoy 2016-6-2
//插座、电话等设备,用任意布置、矩形布置等自动生成对应导线时生成的导线
//与 【平面布线】所生成的导线的标注信息不统一
int index = iLayerIndex;
//if(index == 4) //应急
// index = 0;
//else if(index > 4 && index < 9)//消防
// index = 2;
//else if(index > 8) //弱电
// index = 3;
//if(index >= 0 && index < 4){
if(index >= 0 && index < MAX_WIRE_LEN){
//modify end
Entity ent;
ent.GetLast();
WriteXdata(ent, _T("ltype"), (const TCHAR*)g_csWireDimType[index]); //导线型号
WriteXdata(ent, _T("ldm"), (const TCHAR*)g_csWireDimRadius[index]); //穿管直径
WriteXdata(ent, _T("lmeth"), (const TCHAR*)g_csWireDimMode[index]); //配线方式
WriteXdata(ent, _T("linst"), (const TCHAR*)g_csWireDimPlace[index]); //敷设部位
WriteXdata(ent, _T("lnoar"), (const TCHAR*)g_csWireDimArea[index]); //规格
WriteXdata(ent, _T("lnorm"), (const TCHAR*)Itoa(g_iWireDimNorm[index])); //普通、阻燃、耐火
WriteXdata(ent, _T("weakwirenum"),g_csWireLineNum[index]); //弱电缆根数//add liaoy 2016-6-2
}
if(bJoin && dWidth > 0.001)
Join2PLine(id, GetWireLayer(iLayerIndex));
}
void DrawPArcWire(XArc arc, int iLayerIndex)
{
CString csLay = GetWireLayer(iLayerIndex);
if(!IsExistLayer(csLay)){
InitLayer(csLay);
SetLayerLineType(csLay, g_csLineType[iLayerIndex]);
}
else
InitLayer(csLay);
XCurveSegment seg;
seg = arc;
XPoly2D poly2d;
seg.AsPoly2D(poly2d);
XPushVarStr clayer(_T("CLAYER"), GetWireLayer(iLayerIndex));
double dWidth = g_nWireWidth[iLayerIndex];
AcDbObjectId id = NULL;
if(dWidth < 0.001){
AcDbArc *pArc = new AcDbArc;
pArc->setCenter(arc.GetCenterPt());
pArc->setRadius(arc.GetRadius());
pArc->setStartAngle(arc.GetStarAngle());
pArc->setEndAngle(arc.GetEndAngle());
pArc->setLinetype(GetPipeWireLayLineType(GetWireLayer(iLayerIndex)));
PostToDb(pArc);
pArc->close();
}
else{
AcDbPolyline *pline = new AcDbPolyline;
PolyConvert(poly2d, *pline);
pline->setConstantWidth(dWidth*DocGetPScale());
pline->setLinetype(GetPipeWireLayLineType(GetWireLayer(iLayerIndex)));
PostToDb(pline);
pline->close();
id = pline->objectId();
}
//modify liaoy 2016-6-2
//插座、电话等设备,用任意布置、矩形布置等自动生成对应导线时生成的导线
//与 【平面布线】所生成的导线的标注信息不统一
int index = iLayerIndex;
//if(index == 4) //应急
// index = 0;
//else if(index > 4 && index < 9)//消防
// index = 2;
//else if(index > 8) //弱电
// index = 3;
//if(index >= 0 && index < 4){
if(index >= 0 && index < MAX_WIRE_LEN){
//modify end
Entity ent;
ent.GetLast();
WriteXdata(ent, _T("ltype"), (const TCHAR*)g_csWireDimType[index]); //导线型号
WriteXdata(ent, _T("ldm"), (const TCHAR*)g_csWireDimRadius[index]); //穿管直径
WriteXdata(ent, _T("lmeth"), (const TCHAR*)g_csWireDimMode[index]); //配线方式
WriteXdata(ent, _T("linst"), (const TCHAR*)g_csWireDimPlace[index]); //敷设部位
WriteXdata(ent, _T("lnoar"), (const TCHAR*)g_csWireDimArea[index]); //规格
WriteXdata(ent, _T("lnorm"), (const TCHAR*)Itoa(g_iWireDimNorm[index])); //普通、阻燃、耐火
WriteXdata(ent, _T("weakwirenum"),g_csWireLineNum[index]); //弱电缆根数//add liaoy 2016-6-2
}
if(g_bJoin2Wire && dWidth > 0.001)
Join2PLine(id, GetWireLayer(iLayerIndex));
}
void DrawDivWire(XPoint ptStart, XPoint ptEnd, BOOL bIsBusWire, BOOL bNeed, BOOL bIsEmptyMWire)
{
double dWidth(0);
if(bIsBusWire)
dWidth = g_dBusLineWidth;
else
dWidth = g_dSysLineWidth;
int dist = g_nBlkLength / 2;
double angle = ads_angle(ptStart, ptEnd);
ads_point pt;
pt[0] = ptStart.x;
pt[1] = ptStart.y;
pt[2] = ptStart.z;
CString csDwb = g_csDwbPath + _T("TelecSys");
XString xsTmp;
if(LoadDwbBlock(csDwb, _T("00000007"), xsTmp) != RTNORM) // _sgrid分隔
return;
int n = 1;
while(ads_distance(ptStart, ptEnd) >= ads_distance(ptStart, pt)){
if(bNeed)
InsertBlock((const TCHAR*)xsTmp, asPnt3d(pt), dist/5, dist/5, angle, LAY_TEL_GRID);
ads_polar(ptStart, angle, dist*n, pt);
n++;
}
dist = dist*(n-2);
if(bIsEmptyMWire){
InitLayer(LAY_WIRE_BUS);
XLine line(ptStart, ptEnd, 1);
double ang = line.Direction();
if(ang >= PI)
ang -= PI;
XPoint ptcen;
line.MidPoint(ptcen);
TDbRect *pRect = new TDbRect;
pRect->setLayer(LAY_WIRE_BUS);
pRect->SetSizeX(line.GetLength());
pRect->SetRotation(ang);
pRect->SetSizeY(g_dBusLineWidth*DocGetPScale());
pRect->SetCenter(ptcen) ;
pRect->AddToCSpace(Adesk::kTrue);
}
else
DrawSysWire(ptStart, ptEnd, bIsBusWire);
}
CString GetAttrib(Entity entTemp, const TCHAR*szTag, BOOL bIsVisable)
{
CString csRet;
AcDbBlockReference *pBlockRef = NULL;// 定义块表指针
AcDbObjectId eId;
acdbGetObjectId(eId, entTemp);
acdbOpenObject(pBlockRef, eId, AcDb::kForRead);
if(!pBlockRef)
return CString();
AcDbObjectIterator *pIterator;
pIterator = pBlockRef->attributeIterator();
AcDbEntity *pEnt;
AcDbAttribute *pAtt;
for (pIterator->start(); !pIterator->done(); pIterator->step())
{
//遍历块中实体
AcDbObjectId att_id;
att_id = pIterator->objectId();
acdbOpenAcDbEntity(pEnt, att_id, AcDb::kForRead);
pAtt = AcDbAttribute::cast(pEnt);
if(pAtt != NULL)
{
TCHAR *cname = pAtt->tag();//得到标记
if(_tcsicmp(cname, szTag) == 0) {
if(pAtt->isInvisible() == Adesk::kFalse || bIsVisable){
TCHAR *cval = pAtt->textString();//得到值
csRet.Format(_T("%s"), cval);
delete[] cval;
}
pAtt->close();
break;
}
delete[] cname;
}
pEnt->close();
}
delete pIterator;
pBlockRef->close();
return csRet;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
void GetBlockCurves(Entity &ent, DList<XCurveSegment> &lstCurves)
{
AcDbObjectId id;
acdbGetObjectId(id, ent);
//炸开图块
AcDbVoidPtrArray arBlocks;
AcDbBlockReference *pBlock = NULL;
acdbOpenObject(pBlock, id, AcDb::kForRead);
if (pBlock != NULL)
{
pBlock->explode(arBlocks);
AcDbLine *pLine = NULL;
AcDbArc *pArc = NULL;
AcDbCircle *pCir = NULL;
XCurveSegment seg;
for (int i =0; i < arBlocks.length(); ++i)
{
AcDbEntity *pEnt = (AcDbEntity*)arBlocks[i];
if (pEnt != NULL)
{
if(pLine = AcDbLine::cast(pEnt))
{
XLine line(XPoint(pLine->startPoint()), XPoint(pLine->endPoint()));
seg = line;
lstCurves.Append(new XCurveSegment(seg));
}
else if(pArc = AcDbArc::cast(pEnt))
{
AcGePoint3d ptStart, ptEnd;
pArc->getStartPoint(ptStart);
pArc->getEndPoint(ptEnd);
double dAng(0), dLen(0);
pArc->getDistAtPoint(ptEnd, dLen);
dAng = dLen / pArc->radius();
XArc arc(XPoint(ptStart), XPoint(ptEnd), dAng);
seg = arc;
lstCurves.Append(new XCurveSegment(seg));
}
else if(pCir = AcDbCircle::cast(pEnt))
{
AcGePoint3d ptCen = pCir->center();
XCircle cir(XPoint(ptCen), pCir->radius());
seg = cir;
lstCurves.Append(new XCurveSegment(seg));
}
}
}
pBlock->close();
}
ReleaseEntSet(arBlocks);
}
// 直线是否被曲线穿过(不包含直线端点)
bool IsLineThreadCurves(XLine &line, DList<XCurveSegment> &lstCurves)
{
line.SetLineFlag(LS_FINITE);
XPoint ptS = line.StartPoint();
XPoint ptE = line.EndPoint();
XPoint pt1, pt2;
int nLen = lstCurves.Length();
for (int i = 0; i < nLen; ++i)
{
XCurveSegment &seg = *lstCurves[i];
seg.SetLineFlag(LS_FINITE);
int nNum = seg.Intersection(line, pt1, pt2);
if (nNum == 0)
{
continue;
}
// 两个交点,曲线穿过直线
if (nNum == 2)
{
return true;
}
// 一个交点,交点不在直线端点时,穿过直线
if (nNum == 1)
{
double dDist1 = ptS.Distance2d(pt1);
double dDist2 = ptE.Distance2d(pt1);
if (fabs(dDist1) > 0.001 && fabs(dDist2) > 0.001)
{
return true;
}
}
}
return false;
}
// 点是否在直线上
bool IsOnLine(XPoint &pt, XLine &line)
{
XPoint ptS = line.StartPoint();
XPoint ptE = line.EndPoint();
double dLen = ptS.Distance(ptE);
double dDist1 = ptS.Distance(pt);
double dDist2 = ptE.Distance(pt);
if (fabs(dDist2 + dDist1 - dLen) < 0.001)
{
return true;
}
return false;
}
// 直线是否与曲线共线
bool IsCollinear(XLine &line, DList<XCurveSegment> &lstCurves)
{
XPoint ptS = line.StartPoint();
XPoint ptE = line.EndPoint();
AcGeVector3d vt = ptS - ptE;
AcGeVector3d vtTemp;
AcGeTol tol;
tol.setEqualVector(0.001);
XLine lineTemp;
int nLen = lstCurves.Length();
for (int i = 0; i < nLen; ++i)
{
XCurveSegment &seg = *lstCurves[i];
if (!seg.Is(CURVE_LINE))
{
continue;
}
vtTemp = seg.StartPoint() - seg.EndPoint();
if (!vtTemp.isParallelTo(vt, tol))
{
continue;
}
lineTemp.SetPoints(seg.StartPoint(), seg.EndPoint());
if (IsOnLine(seg.StartPoint(), line) || IsOnLine(seg.EndPoint(), line)
|| IsOnLine(ptS, lineTemp) || IsOnLine(ptE, lineTemp))
{
return true;
}
}
return false;
}
// 直线是否平行x轴或y轴
bool IsParallelXorYAxis(XLine &line)
{
AcGeVector3d vtLine = line.StartPoint() - line.EndPoint();
vtLine.rotateBy(Wcs2Ucs(0.0), AcGeVector3d::kZAxis);
vtLine.z = 0.0;
AcGeTol tol;
tol.setEqualVector(0.001);
if (vtLine.isParallelTo(AcGeVector3d::kXAxis, tol) || vtLine.isParallelTo(AcGeVector3d::kYAxis, tol))
{
return true;
}
return false;
}
// 删除连接线中与图块直线重叠的部分以及圆内部分(假设直线重叠部分在起点位置)
void ModifyLinkPath(Entity &ent, XLine &line)
{
// 获得图块中的曲线
DList<XCurveSegment> lstCurves;
GetBlockCurves(ent, lstCurves);
AcGeVector3d vtLine = line.StartPoint() - line.EndPoint();
vtLine.z = 0.0;
AcGeTol tol;
tol.setEqualVector(0.001);
int nNum = 0;
XPoint pt1, pt2;
XCircle cir;
line.SetLineFlag(LS_FINITE);
int nLen = lstCurves.Length();
AcGeVector3d vtTemp;
for (int i = 0; i < nLen; ++i)
{
XCurveSegment &seg = *lstCurves[i];
seg.SetLineFlag(LS_FINITE);
if (seg.Is(CURVE_LINE)) // 直线
{
vtTemp = seg.StartPoint() - seg.EndPoint();
vtTemp.z = 0.0;
if (!vtTemp.isParallelTo(vtLine, tol))
{
continue;
}
// 如果line在seg内
double dLen = seg.StartPoint().Distance2d(seg.EndPoint());
double dDist1 = line.StartPoint().Distance2d(seg.StartPoint()) + line.StartPoint().Distance2d(seg.EndPoint());
double dDist2 = line.EndPoint().Distance2d(seg.StartPoint()) + line.EndPoint().Distance2d(seg.EndPoint());
if (fabs(dDist1 - dLen) < 0.001 && fabs(dDist2 - dLen) < 0.001)
{
pt1 = line.EndPoint();
line.StartPoint() = pt1;
break;
}
// line与seg部分重叠
dLen = line.StartPoint().Distance2d(line.EndPoint());
dDist1 = line.StartPoint().Distance2d(seg.StartPoint()) + line.EndPoint().Distance2d(seg.StartPoint());
dDist2 = line.StartPoint().Distance2d(seg.EndPoint()) + line.EndPoint().Distance2d(seg.EndPoint());
if (fabs(dLen - dDist1) > 0.001 && fabs(dLen - dDist2) > 0.001)
{
continue;
}
if (dDist1 < dDist2)
{
line.SetStartPoint(seg.StartPoint());
}
else
{
line.SetStartPoint(seg.EndPoint());
}
}
else if (seg.Is(CURVE_CIRCLE)) // 园
{
nNum = seg.Intersection(line, pt1, pt2);
if (nNum == 1)
{
line.SetStartPoint(pt1);
}
}
}
}
void ModifyLinkPath(Entity &ent1, Entity &ent2, DList<XPoint> &lstPts)
{
// 修剪连接线,删除重叠的部分和圆内部分
XLine line;
XPoint ptS, ptE, ptTemp;
int nLen = lstPts.Length();
if (nLen == 2)
{
line.SetStartPoint(*lstPts[0]);
line.SetEndPoint(*lstPts[1]);
ModifyLinkPath(ent1, line);
line.SetStartPoint(*lstPts[1]);
line.SetEndPoint(*lstPts[0]);
ModifyLinkPath(ent2, line);
*lstPts[0] = line.StartPoint();
*lstPts[1] = line.EndPoint();
}
else
{
ptS = *lstPts[0];
ptTemp = *lstPts[1];
ptE = *lstPts[2];
lstPts.Reset();
XLine line1(ptS, ptTemp);
ModifyLinkPath(ent1, line1);
double dLen1 = line1.GetLength();
if (dLen1 > 0.1)
{
lstPts.Append(new XPoint(line1.StartPoint()));
lstPts.Append(new XPoint(line1.EndPoint()));
}
XLine line2(ptE, ptTemp);
ModifyLinkPath(ent2, line2);
if (line2.GetLength() > 0.1)
{
if (dLen1 < 0.1)
{
lstPts.Append(new XPoint(line2.EndPoint()));
}
lstPts.Append(new XPoint(line2.StartPoint()));
}
}
}
// 获得连接两设备图块的最佳垂直路径
// 2013-3-12 CET ADD
void GetEquipLinkPath(Entity &ent1, Entity &ent2, const XPoint &ptPick, DList<XPoint> &lstPts)
{
lstPts.Reset();
// 获取连接点
XPointList lstPt1, lstPt2;
double dRadius1 = 0.0, dRadius2 = 0.0;
GetEquipPoint(ent1, lstPt1, dRadius1);
GetEquipPoint(ent2, lstPt2, dRadius2);
if (lstPt1.Length() == 0 || lstPt2.Length() == 0)
{
return;
}
// 找出ent2中距离pt最近的点
XPoint pt = ptPick;
std::multimap<double, XPoint> mapDistPt;
for (int i = 0; i < lstPt2.Length(); ++i)
{
double dDist = pt.Distance2d(*lstPt2[i]);
mapDistPt.insert(std::make_pair(dDist, *lstPt2[i]));
}
pt = mapDistPt.begin()->second;
// 获得图块中的曲线
DList<XCurveSegment> lstCurves;
GetBlockCurves(ent1, lstCurves);
GetBlockCurves(ent2, lstCurves);
// 根据距pt的远近对lst1排序
mapDistPt.clear();
for (i = 0; i < lstPt1.Length(); ++i)
{
double dDist = pt.Distance2d(*lstPt1[i]);
mapDistPt.insert(std::make_pair(dDist, *lstPt1[i]));
}
// 找出pt与ent1上的点连线未被两图块穿过的直线
XLine line, line1, line2;
XPoint ptS, ptE, ptTemp;
std::multimap<double, XPoint>::iterator it, itEnd = mapDistPt.end();
for(it = mapDistPt.begin(); it != itEnd; ++it)
{
line.SetPoints(it->second, pt);
// 直线与X轴或Y轴不平行
if (!IsParallelXorYAxis(line))
{
ptS = line.StartPoint();
ptE = line.EndPoint();
ptS = Wcs2Ucs(ptS);
ptE = Wcs2Ucs(ptE);
ptTemp.x = ptS.x;
ptTemp.y = ptE.y;
ptTemp.z = ptE.z;
ptTemp = Ucs2Wcs(ptTemp);
XLine line1(ptS, ptTemp);
XLine line2(ptE, ptTemp);
if (!IsLineThreadCurves(line1, lstCurves) && !IsLineThreadCurves(line2, lstCurves))
{
ptS = Ucs2Wcs(ptS);
ptE = Ucs2Wcs(ptE);
lstPts.Append(new XPoint(ptS));
lstPts.Append(new XPoint(ptTemp));
lstPts.Append(new XPoint(ptE));
break;
}
else
{
ptTemp.x = ptE.x;
ptTemp.y = ptS.y;
ptS = Ucs2Wcs(ptS);
ptE = Ucs2Wcs(ptE);
ptTemp = Ucs2Wcs(ptTemp);
line1.SetPoints(ptS, ptTemp);
line2.SetPoints(ptE, ptTemp);
if (!IsLineThreadCurves(line1, lstCurves) && !IsLineThreadCurves(line2, lstCurves))
{
lstPts.Append(new XPoint(ptS));
lstPts.Append(new XPoint(ptTemp));
lstPts.Append(new XPoint(ptE));
break;
}
}
}
else if (!IsLineThreadCurves(line, lstCurves) || IsCollinear(line, lstCurves)) // 直线与X轴或Y轴平行并且未被曲线穿过或与曲线平行相交
{
lstPts.Append(new XPoint(line.StartPoint()));
lstPts.Append(new XPoint(line.EndPoint()));
}
}
// 已经找到连接线
if (lstPts.Length() != 0)
{
ModifyLinkPath(ent1, ent2, lstPts);
return;
}
// 未找到连接线,直接找出两图块最近的两点连接
std::multimap<double, std::pair<XPoint,XPoint> > mapPts;
int nLen1 = lstPt1.Length();
int nLen2 = lstPt2.Length();
for (int k = 0; k < nLen1; ++k)
{
for (int j = 0; j < nLen2; ++j)
{
double dDist = (*lstPt1[k]).Distance2d(*lstPt2[j]);
mapPts.insert(std::make_pair(dDist, std::make_pair(*lstPt1[k], *lstPt2[j])));
}
}
std::multimap<double, std::pair<XPoint,XPoint> >::iterator itTemp = mapPts.begin();
ptS = itTemp->second.first;
ptE = itTemp->second.second;
XLine lineTemp(ptS, ptE);
if (!IsParallelXorYAxis(lineTemp))
{
ptS = Ucs2Wcs(ptS);
ptE = Ucs2Wcs(ptE);
ptTemp.x = ptS.x;
ptTemp.y = ptE.y;
ptTemp.z = ptE.z;
ptS = Ucs2Wcs(ptS);
ptE = Ucs2Wcs(ptE);
ptTemp = Ucs2Wcs(ptTemp);
lstPts.Append(new XPoint(ptS));
lstPts.Append(new XPoint(ptTemp));
lstPts.Append(new XPoint(ptE));
XLine line1(ptS, ptTemp);
XLine line2(ptE, ptTemp);
}
else
{
lstPts.Append(new XPoint(ptS));
lstPts.Append(new XPoint(ptE));
}
ModifyLinkPath(ent1, ent2, lstPts);
}
void testBlock()
{
RBList rbMask(RTDXF0, _T("INSERT"), NULL);
Entity ent1;
XPoint pt1;
if (SelectEntity1(_T("\n选择第一个图块:"), ent1, pt1, rbMask) != RTNORM)
{
return;
}
Entity ent2;
XPoint pt2;
if (SelectEntity1(_T("\n选择第二个图块:"), ent2, pt2, rbMask) != RTNORM)
{
return;
}
XPoint pt;
if (acedGetPoint(NULL, _T("\n在第二个图块选择连接点"), pt) != RTNORM)
{
return;
}
DList<XPoint> lstPts;
GetEquipLinkPath(ent1, ent2, pt, lstPts);
int nLen = lstPts.Length();
for (int i = 0; i < nLen - 1; ++i)
{
XLine line(*lstPts[i], *lstPts[i+1]);
line.Make();
}
}
void AdjustWndToViewport(CWnd* pWnd,int nXOff,int nYOff)
{
if (pWnd != NULL)
{
CRect rect,rectWnd;
acedGetAcadFrame()->GetWindowRect(rect);
pWnd->GetWindowRect(&rectWnd);
if (!PtInRect(rect, rectWnd.TopLeft()) &&
!PtInRect(rect, rectWnd.BottomRight()))
{
int nX = rect.TopLeft().x + nXOff;
int nY = rect.TopLeft().y = nYOff;
pWnd->MoveWindow(nX,nY,rectWnd.Width(),rectWnd.Height());
}
}
}