3059 lines
83 KiB
C++
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());
|
|
}
|
|
}
|
|
} |