#include "stdafx.h" #include "TAPI.h" #include "TelDef.h" #include "XBlock.h" #include "wire.h" //#include #include #include 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(""), -4, _T(""), -4, _T(""), -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 > &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 > &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 > 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 0) { int idx = 0; Entity entTmp; for(long i=0;i 0) { int idx = 0; Entity entTmp; for(long i=0;istart(); !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 -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 -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 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 -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 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; nGetSizeX(); double y = pEnt->GetSizeY(); nLineThick = x < y ? x : y; } OPENOBJ_END(); } return nLineThick; } Entity GetCulBreakPWire(PickSet &ssAllBreak, PickSet &ssff) { for(long m=0;mGetSizeX(); 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 &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(""), -4, _T(""), -4, _T(""), -4, _T(""), -4, _T("or>"), NULL); for(int i=0;im_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 &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 &lstPt) { int nLen = lstPt.Length(); if (nLen < 1) return; int i = 0; int j = 0; std::vector 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 &lstPt) { int nLen = lstPt.Length(); if (nLen < 1) return; int i = 0; int j = 0; std::vector 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 &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 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::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>>& arpNewSet) { if(!pRef) return FALSE; AcDbBlockTableRecordIterator *pIterator = NULL; OPENOBJ_BEGIN(pRef->blockTableRecord(), AcDb::kForRead, AcDbBlockTableRecord , pRec); if(pRec) pRec->newIterator(pIterator); OPENOBJ_END(); AcArray> 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; nblockTableRecord(), 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; istart(); !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>> 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 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;iclose(); } // 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=PI && dOAng<2*PI) dAng = dAngle - PI/2; else if(dOAng>=0 && dOAng=PI && dOAng<2*PI) dAng = dAngle - PI/2; else if(dOAng>=0 && dOAnggetBlockTable(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 &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 &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 &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 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 &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 &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 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 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::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 > 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 >::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 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()); } } }