#include "stdafx.h" //#include //#include #include //#include #include //#include #include #include #include #include #include "tapi.h" #include "TelDef.h" #include "XBlock.h" #define TPI 6.283185307 #define MINL 1.0E-6 #define FEQU(a,b) (fabs((a) - (b)) < MINL) #define E6TOL 1.e-6 //CTemporaryResourceOverride const char *GetRegLocation1() { #if (ADS>14) return "SoftWare\\Tangent\\Tel2k"; #else return "SoftWare\\Tangent\\Tel14"; #endif } // cet 2016.7.20 add 获得外部参照实体转换矩阵 AcGeMatrix3d GetExternalEntityTransform(Entity ent) { AcDbObjectId idTemp; acdbGetObjectId(idTemp, ent.name); AcGeMatrix3d matRet = AcGeMatrix3d::kIdentity; AcDbBlockTable *pTbl = NULL; acdbCurDwg()->getBlockTable(pTbl, AcDb::kForRead); if (pTbl != NULL) { bool bFlag = false; AcDbBlockTableIterator *it = NULL; pTbl->newIterator(it); for (it->start(); !it->done() && !bFlag; it->step()) { AcDbBlockTableRecord *pRcd = NULL; it->getRecord(pRcd, AcDb::kForRead); if (pRcd != NULL && pRcd->isFromExternalReference()) { AcGeMatrix3d mat = AcGeMatrix3d::kIdentity; AcDbObjectIdArray arrId; pRcd->getBlockReferenceIds(arrId); if (arrId.length() != 1) { pRcd->close(); continue; } AcDbBlockReference *pRef = NULL; acdbOpenObject(pRef, arrId[0], AcDb::kForRead); if (pRef != NULL) { mat = pRef->blockTransform(); pRef->close(); } else { pRcd->close(); continue; } AcDbBlockTableRecordIterator *itRec = NULL; pRcd->newIterator(itRec); for (itRec->start(); !itRec->done() && !bFlag; itRec->step()) { AcDbObjectId id; itRec->getEntityId(id); if (id = idTemp) { matRet = mat; bFlag = true; break; } } delete itRec; } pRcd->close(); } delete it; pTbl->close(); } return matRet; } static XPoint g_ptDragCenter; static int DragRotationAction(ads_point pt, ads_matrix mt) { ads_real nRot=ads_angle(g_ptDragCenter, pt); Ucs2Wcs(g_ptDragCenter).GetRotationMatrix(nRot, mt); return RTNORM; } int DragRotate(PickSet &ss, XPoint Pt, const TCHAR* szPmt) { ss.Redraw(3); // 将实体隐藏 // DragPickSet ssDrag(Pt, ss); XPoint ptDrag; g_ptDragCenter = Pt; ads_initget(RSG_OTHER, NULL); int rc = ads_draggen(ss, szPmt, 0, DragRotationAction, ptDrag); if(rc==RTNORM) { ads_real nRot=CT_std_angle(ads_angle(Ucs2Wcs(g_ptDragCenter), Ucs2Wcs(ptDrag)))*180/PI; XPushVar vOsMode(_T("OSMODE"), 0); return ads_command(RTSTR, _T(".ROTATE"), RTPICKS, (TLong_ptr *)ss, RTSTR, _T(""), RT3DPOINT, &g_ptDragCenter, RTREAL, nRot, RTNONE); } else if(rc==RTSTR) { TCHAR sInput[80]=_T(""); ads_getinput(sInput); if(!sInput[0]) return RTERROR; ads_real nRot=_tstof(sInput); if(fabs(nRot)<_angSnap) return RTERROR; XPushVar vOsMode(_T("OSMODE"), 0); return ads_command(RTSTR, _T(".ROTATE"), RTPICKS, (TLong_ptr *)ss, RTSTR, _T(""), RT3DPOINT, &g_ptDragCenter, RTREAL, nRot, RTNONE); } else ss.Redraw(4);// 将实体恢复 return RTNORM; } static int DragMoveAction(ads_point pt, ads_matrix mt) { ads_real nRot=ads_angle(g_ptDragCenter, pt); Ucs2Wcs(g_ptDragCenter).GetMoveMatrix(pt, mt); return RTNORM; } int DragMove(PickSet &ss, XPoint Pt, const TCHAR* szPmt) { ss.Redraw(2); // 将实体隐藏 XPoint ptDrag; g_ptDragCenter = Pt; ads_initget(RSG_OTHER, NULL); int rc = ads_draggen(ss, szPmt, 0, DragMoveAction, ptDrag); acedGetAcadDwgView()->RedrawWindow(); if(rc==RTNORM) { XPushVar vOsMode(_T("OSMODE"), 0); return ads_command(RTSTR, _T(".MOVE"), RTPICKS, (TLong_ptr *)ss, RTSTR, _T(""), RT3DPOINT, &g_ptDragCenter, RT3DPOINT, &ptDrag, RTNONE); } else ss.Redraw(4);// 将实体恢复 return rc; } // 给定1点, 得到该点上的墙 Entity GetPtOnWall(XPoint pt) { RBList rbMask = ads_buildlist( -4, _T(""), -4, _T(""), -4, _T("or>"), NULL); PickSet ss(SS_FREE); XPoint ptTemp1, ptTemp2; ptTemp1.x = pt.x - 5; ptTemp1.y = pt.y + 5; ptTemp2.x = pt.x + 5; ptTemp2.y = pt.y - 5; ss.Get(_T("C"), ptTemp1, ptTemp2, rbMask); int len2 = ss.Length(); if(ss.Length() != 1) return Entity(); return ss[0L]; } // 给定1点, 得到该点上的窗, 柱 Entity GetPtOnWindow(XPoint pt) { RBList rbMask = ads_buildlist( -4, _T(""), -4, _T(""), -4, _T("or>"), NULL); PickSet ss(SS_FREE); XPoint ptTemp1, ptTemp2; ptTemp1.x = pt.x - 5; ptTemp1.y = pt.y + 5; ptTemp2.x = pt.x + 5; ptTemp2.y = pt.y - 5; ss.Get(_T("C"), ptTemp1, ptTemp2, rbMask); int len2 = ss.Length(); if(ss.Length() != 1) return Entity(); return ss[0L]; } BOOL IsPtOnSegment(XPoint pt, XCurveSegment seg, double nSnap) { if(seg.Is(CURVE_LINE)){ XLine line(1); line = seg.GetLine(); return IsPtOnLine(pt, line, nSnap); } else if(seg.Is(CURVE_ARC)){ XArc arc = seg.GetArc(); return IsPtOnArc(pt, arc, nSnap); } else if(seg.Is(CURVE_CIRCLE)){ XCircle cir = seg.GetCircle(); return IsPtOnCircle(pt, cir, nSnap); } else return FALSE; } BOOL IsPtOnLine(XPoint pt, XLine line, double nSnap) { ads_real l1,l2,l12; double dd = pt.Distance(&line); if(fabs(pt.Distance(&line)) > nSnap) return FALSE; l1=ads_distance(pt, line.StartPoint()); l2=ads_distance(pt, line.EndPoint()); l12=line.GetLength(); if(fabs(l1 + l2 - l12) <= nSnap) return TRUE; return FALSE; } BOOL IsPtOnCircle(XPoint pt, XCircle circle, double nSnap) { double r=pt.Distance(circle.GetCenterPt()) - circle.GetRadius(); if(fabs(r) < nSnap) return TRUE; else return FALSE; } BOOL IsPtOnArc(XPoint pt, XArc arc, double nSnap) { double ang = ads_angle(arc.GetCenterPt(), pt); double rad = arc.GetRadius(); double ff = ads_distance(arc.GetCenterPt(), pt); if(fabs(ads_distance(arc.GetCenterPt(), pt) - rad) > nSnap) return FALSE; if( arc.GetStarAngle() < arc.GetEndAngle() ) { if(ang>arc.GetStarAngle() && angarc.GetStarAngle() || angsetVisibility(bTrue? AcDb::kVisible : AcDb::kInvisible); // OPENOBJ_END(); // } //} //*************************************************************** // arx 函数 //**************************************************************** BOOL IsLayerOn(const TCHAR*szLayerName) { // 判断图层是开是关 AcDbLayerTable *pLayertable; AcDbLayerTableRecord *pLayerRec; acdbCurDwg()->getLayerTable(pLayertable, AcDb::kForRead); if(!pLayertable) return FALSE; if((pLayertable->getAt(szLayerName, pLayerRec, AcDb::kForRead)) == Acad::eOk) { pLayertable->close(); if (pLayerRec->isOff() == Adesk::kTrue){ pLayerRec->close(); return FALSE; } else{ pLayerRec->close(); return TRUE; } pLayerRec->close(); } else pLayertable->close(); return TRUE; } BOOL SetLayerOnOff(const TCHAR*szLayerName, BOOL bOpen) { AcDbLayerTable *pLayertable = NULL; AcDbLayerTableRecord *pLayerRec = NULL; acdbCurDwg()->getLayerTable(pLayertable, AcDb::kForRead); if(!pLayertable) return FALSE; if((pLayertable->getAt(szLayerName, pLayerRec, AcDb::kForWrite)) == Acad::eOk) { if(bOpen) pLayerRec->setIsOff(Adesk::kFalse); // 打开 else pLayerRec->setIsOff(Adesk::kTrue); // 关 pLayerRec->close(); pLayertable->close(); } else pLayertable->close(); return TRUE; } BOOL AddLayer(const TCHAR* szLayer, int iColor) { BOOL bHasIt; AcDbLayerTable *pLayerTable; AcDbLayerTableRecord *pLayerTableRecord = new AcDbLayerTableRecord; AcCmColor color; color.setColorIndex(iColor); acdbCurDwg()->getLayerTable(pLayerTable, AcDb::kForWrite); bHasIt = pLayerTable->has(szLayer); if(!bHasIt){ pLayerTableRecord->setName(szLayer); pLayerTableRecord->setColor(color); pLayerTable->add(pLayerTableRecord); } else{ pLayerTable->getAt(szLayer, pLayerTableRecord, AcDb::kForWrite); pLayerTableRecord->setColor(color); } pLayerTable->close(); pLayerTableRecord->close(); return TRUE; } Acad::ErrorStatus PostToDb(AcDbEntity* ent, BOOL bClose) { Adesk::Boolean flag; if(bClose) flag = Adesk::kTrue; else flag = Adesk::kFalse; AcDbObjectId objId = AddToCurrentSpace(ent, flag); return Acad::eOk; } BOOL CreateTextStyle(const TCHAR*szTextStyle, const TCHAR*szEngShape, const TCHAR*szChnShape) { CString csTextStyle(szTextStyle), csEngShape(szEngShape), csChnShape(szChnShape); AcDbDatabase *pCurDwg=acdbCurDwg(); AcDbTextStyleTable* pTT = NULL; VERIFY(pCurDwg->getTextStyleTable(pTT, AcDb::kForWrite) == Acad::eOk); AcDbTextStyleTableRecord* pTTR = new AcDbTextStyleTableRecord; if(pTTR->setName(csTextStyle) != Acad::eOk) { AfxMessageBox(_T("文字样式名称不合法!请重新输入。")); delete pTTR; pTT->close(); return FALSE; } if(csEngShape != _T("")) pTTR->setFileName((const TCHAR*)csEngShape); if(csChnShape != _T("")) pTTR->setBigFontFileName((const TCHAR*)csChnShape); else pTTR->setBigFontFileName(NULL); if(pTT->add(pTTR) != Acad::eOk ) { pTT->close(); delete pTTR; return FALSE; } pTT->close(); pTTR->close(); return TRUE; } BOOL ModifyTextStyle(const TCHAR*szTextStyle, const TCHAR*szEngShape, const TCHAR*szChnShape) { CString csTextStyle(szTextStyle), csEngShape(szEngShape), csChnShape(szChnShape); AcDbTextStyleTableRecord *pRec=NULL; AcDbObjectId idTextStyle = GetTextStyleId(csTextStyle); if(!idTextStyle) return FALSE; OPENOBJ_BEGIN(idTextStyle, AcDb::kForWrite, AcDbTextStyleTableRecord, pRec); if(csEngShape != _T("")) pRec->setFileName((const TCHAR*)csEngShape); if(csChnShape != _T("")) pRec->setBigFontFileName((const TCHAR*)csChnShape); else pRec->setBigFontFileName(NULL); OPENOBJ_END(); return TRUE; } int DoubleCmp(const double *i, const double *j) { if(*i < *j) return -1; else if(*i > *j) return 1; else return 0; } int DoubleCmp2(const double *i, const double *j) { if(*i > *j) return -1; else if(*i < *j) return 1; else return 0; } //读扩展数据 CString ReadXdata(Entity ent, const TCHAR*szName) { AcDbObjectId eId; AcDbEntity *pEnt = NULL; acdbGetObjectId(eId, ent); acdbOpenObject(pEnt, eId, AcDb::kForRead); if(!pEnt) return _T(""); resbuf *pRb = pEnt->xData(szName); CString csRet; if (pRb != NULL) { resbuf *pTemp = pRb; if (pTemp->rbnext != NULL) { pTemp = pTemp->rbnext; if (pTemp->restype == 1000) csRet = pTemp->resval.rstring; } } ads_relrb(pRb); pEnt->close(); return csRet; } //写扩展数据 BOOL WriteXdata(Entity ent, const TCHAR*szName, const TCHAR*szValue) { AcDbObjectId eId; AcDbEntity *pEnt = NULL; acdbGetObjectId(eId, ent); if(!XSymbolTable(_T("APPID"), szName)) ads_regapp(szName); acdbOpenObject(pEnt, eId, AcDb::kForWrite); if(!pEnt) return FALSE; resbuf *pXData = ads_buildlist(1001, szName, 1000, szValue, NULL); pEnt->setXData(pXData); ads_relrb(pXData); pEnt->close(); return TRUE; } double GetLineAngle(Entity ent) { double ang; if(ent.Is(_T("LINE"))){ Callme(); return -1; } XPoint pt1, pt2; GetWire2Point(ent, pt1, pt2); ang = ads_angle(pt1, pt2); return ang; } //注意,调用者自己考虑len比例的问题 void GetPointPickSet(XPoint pt, PickSet &ss, RBList &rbMask, int len)//注意:pt是UCS点 { double dLen = len; // if(DocGetMeterUnitDraw()) // dLen = dLen / 100.0; XPoint ptTemp1, ptTemp2; ptTemp1.x = pt.x - dLen; ptTemp1.y = pt.y + dLen; ptTemp2.x = pt.x + dLen; ptTemp2.y = pt.y - dLen; //sr add 2006-4-28 支持三维上插入阀门 ptTemp1.z = pt.z; ptTemp2.z = pt.z; XLine line(ptTemp1, ptTemp2, 1); // line.Make(); ss.Get(_T("C"), ptTemp1, ptTemp2, rbMask); long len1 = ss.Length(); for(long i=0;i 1) return FALSE; else return TRUE; } void Get2PtFLinePick(PickSet &ss, XPoint ptStart, XPoint ptEnd, RBList &rbMask, int n) { XPoint p1, p2, p3, p4; double angle = ads_angle(ptStart, ptEnd); ads_polar(ptStart, (angle + PI/2), n, p1); // p1 ads_polar(ptStart, (angle - PI/2), n, p2); // p2 ads_polar(ptEnd, (angle + PI/2), n, p3); // p3 ads_polar(ptEnd, (angle - PI/2), n, p4); // p4 struct resbuf *list = ads_buildlist( RTPOINT, &p1, RTPOINT, &p2, RTPOINT, &p4, RTPOINT, &p3, RTPOINT, &p1, NULL); ss.Get(_T("F"), list, NULL, rbMask); ads_relrb(list); } //mode == 0 居中对齐,两端留一定距离 //mode == 1 两端对齐 //将一段线均分N个点 void GetPointList(XCurveSegment seg, int iNum, XPointList &lstPt, int mode) { double dDist2Wall(0); if(mode == 0) dDist2Wall = 0.5; else if(mode == 1) dDist2Wall = 0; else if(mode == 2) dDist2Wall = 0.25; double dDistEven(0); dDistEven = seg.GetLength() / (2*dDist2Wall+iNum-1); AcGePoint3d ptTmp; AcDbCurve *pCurve = seg.AsAcDbCurve(); if(seg.Is(CURVE_CIRCLE)){ XCircle ar = seg.GetCircle(); pCurve = new AcDbCircle(ar.GetCenterPt(), AcGeVector3d(0,0,1), ar.GetRadius()); } if(pCurve == NULL) return; int n = 0; while(n < iNum){ //mod liaoy 避免出现除以0的导致dDistEven无效 double dDist = 0; if(mode == 1 && iNum == 1) dDist = seg.GetLength() / 2; else dDist = dDist2Wall*dDistEven+n*dDistEven; //double dDist = dDist2Wall*dDistEven+n*dDistEven; //mod end pCurve->getPointAtDist(dDist, ptTmp); lstPt.NewAppend(ptTmp); n++; } delete pCurve; return; } //将一段线以间距nDist均分N个点 void GetPointList(XCurveSegment seg, double dDist, XPointList &lstPt) { double dLen = seg.GetLength(); AcGePoint3d ptTmp; AcDbCurve *pCurve = seg.AsAcDbCurve(); if(seg.Is(CURVE_CIRCLE)){ XCircle ar = seg.GetCircle(); pCurve = new AcDbCircle(ar.GetCenterPt(), AcGeVector3d(0,0,1), ar.GetRadius()); } if(pCurve == NULL) return; if(dDist < 0){//反向 dDist = fabs(dDist); double dAllDist = 1; int n = 0; while(dAllDist > 0){ dAllDist = dLen - n*dDist; pCurve->getPointAtDist(dAllDist, ptTmp); lstPt.NewAppend(ptTmp); n++; } } else{ //正向 double dAllDist = 0; int n = 0; while(dLen > dAllDist){ dAllDist = n*dDist; pCurve->getPointAtDist(dAllDist, ptTmp); lstPt.NewAppend(ptTmp); n++; } } delete pCurve; return; } double GetArcLenByChord(XArc &arc, double nChord) { double nRadius = arc.GetRadius(); double nTmp = nChord / (2.0*nRadius); nTmp = asin(nTmp) * 2.0 * nRadius; return nTmp; } //将一段线均分N个点, 但间距是50倍数(喷淋系统) void GetPointList(XCurveSegment seg, int iNum, XPointList &lstPt, double nShortDist, double nDist2Wall) { if(seg.Is(CURVE_LINE)){ XLine line = seg.GetLine(); double angLine = ads_angle(line.StartPoint(), line.EndPoint()); double distLine = line.GetLength() / iNum / 2; if(distLine < nShortDist && nShortDist > 0) distLine = nShortDist; double nTmp1 = distLine / 100; double nTmp2 = distLine - ((int)nTmp1)*100; double nTmp3 = nTmp2 / 25 + 0.5; int iTmp1 = (int)nTmp3; distLine = (int)nTmp1 * 100 + iTmp1 * 25; int n = 1; XPoint ptTemp; double nFisrtDist = (line.GetLength() - distLine * (iNum-1) * 2) / 2; while(nFisrtDist > nDist2Wall){ distLine += 25; nFisrtDist = nFisrtDist - iNum*25; } nTmp1 = nFisrtDist / 100; nTmp2 = nFisrtDist - ((int)nTmp1)*100; nTmp3 = nTmp2 / 50 + 0.5; iTmp1 = (int)nTmp3; nFisrtDist = (int)nTmp1 * 100 + iTmp1 * 50; ads_polar(line.StartPoint(), angLine, nFisrtDist, ptTemp); lstPt.NewAppend(ptTemp); while(n < iNum){ ads_polar(line.StartPoint(), angLine, (2*n)*distLine + nFisrtDist, ptTemp); lstPt.NewAppend(ptTemp); n++; } } else if(seg.Is(CURVE_ARC)){ XArc arc = seg.GetArc(); nShortDist = nShortDist*2; XPoint ptStart, ptEnd; arc.GetStartPoint(ptStart); arc.GetEndPoint(ptEnd); // arc.GetPoints(ptStart, ptEnd); double distLine = arc.GetLength() / iNum; double nTmp1 = distLine / 100; double nTmp2 = distLine - ((int)nTmp1)*100; double nTmp3 = nTmp2 / 50 + 0.5; int iTmp1 = (int)nTmp3; distLine = (int)nTmp1 * 100 + iTmp1 * 50; int n = 1; XPoint ptTemp; double nFisrtDist = (arc.GetLength() - distLine * (iNum-1)) / 2; while(nFisrtDist > nDist2Wall){ distLine += 50; nFisrtDist = nFisrtDist - iNum*25; } nTmp1 = nFisrtDist / 100; nTmp2 = nFisrtDist - ((int)nTmp1)*100; nTmp3 = nTmp2 / 50 + 0.5; iTmp1 = (int)nTmp3; nFisrtDist = (int)nTmp1 * 100 + iTmp1 * 50; nFisrtDist = GetArcLenByChord(arc, nFisrtDist); AcDbArc *pArc=new AcDbArc; pArc->setCenter(arc.GetCenterPt()); pArc->setRadius(arc.GetRadius()); pArc->setStartAngle(arc.GetStarAngle()); pArc->setEndAngle(arc.GetEndAngle()); pArc->getPointAtDist(nFisrtDist, ptTemp); lstPt.NewAppend(ptTemp); distLine = GetArcLenByChord(arc, distLine); if(distLine > 0.001){ while(distLine > 0.001 && n < iNum){ pArc->getPointAtDist(n*distLine + nFisrtDist, ptTemp); lstPt.NewAppend(ptTemp); n++; } } delete pArc; } } BOOL Is2LineOnLine(XLine line1, XLine line2) { XPoint ptStart, ptEnd; ptStart = line1.StartPoint(); ptEnd = line1.EndPoint(); double len1 = fabs(ptStart.Distance(&line2)); double len2 = fabs(ptEnd.Distance(&line2)); if(fabs(ptStart.Distance(&line2)) < 2.0 && fabs(ptEnd.Distance(&line2)) < 2.0) return TRUE; else return FALSE; } BOOL Is2ArcOnArc(XArc arc1, XArc arc2) { XPoint ptCen1, ptCen2; ptCen1 = arc1.GetCenterPt(); ptCen2 = arc2.GetCenterPt(); double nRadius1, nRadius2; nRadius1 = arc1.GetRadius(); nRadius2 = arc2.GetRadius(); if(ptCen1 == ptCen2 && (fabs(nRadius1 - nRadius2) < 0.1)) return TRUE; else return FALSE; } void GetLineMax2Pt(XPoint pt1, XPoint pt2, XPoint &pt3, XPoint &pt4) { XLine l1(pt1, pt3, LS_FINITE); XLine l2(pt2, pt3, LS_FINITE); XLine l3(pt1, pt4, LS_FINITE); XLine l4(pt2, pt4, LS_FINITE); double nMaxLen = 0.0; XPoint ptStart, ptEnd; nMaxLen = l1.GetLength() > nMaxLen ? l1.GetLength() : nMaxLen; nMaxLen = l2.GetLength() > nMaxLen ? l2.GetLength() : nMaxLen; nMaxLen = l3.GetLength() > nMaxLen ? l3.GetLength() : nMaxLen; nMaxLen = l4.GetLength() > nMaxLen ? l4.GetLength() : nMaxLen; if(nMaxLen == l1.GetLength()){ pt3 = l1.StartPoint(); pt4 = l1.EndPoint(); return; } if(nMaxLen == l2.GetLength()){ pt3 = l2.StartPoint(); pt4 = l2.EndPoint(); return; } if(nMaxLen == l3.GetLength()){ pt3 = l3.StartPoint(); pt4 = l3.EndPoint(); return; } if(nMaxLen == l4.GetLength()){ pt3 = l4.StartPoint(); pt4 = l4.EndPoint(); return; } } void DrawSlide(const TCHAR*szPath, CWnd* pWnd) { CImageDC img; CDC *pDC = pWnd->GetDC(); CRect rc; pWnd->GetClientRect(&rc); img.InitDC(pDC, rc, GetAcadBackColor()); img.PaintSlide(szPath); img.SetDC(NULL); pWnd->ReleaseDC(pDC); } void DrawSlide(const TCHAR*szPath, CDC* pDC, CRect rc) { CImageDC img; img.InitDC(pDC, rc, GetAcadBackColor()); img.PaintSlide(szPath); img.SetDC(NULL); } XCurveSegment GetSegByPt(XPoly2D poly, XPoint pt, double &dAngle) { XCurveSegment seg; int m = poly.HitTestOnCurve(pt); if(m > 0) m = m - 2; else if(m < 0) m = abs(m) -1; else if(m == 0) return XCurveSegment(); if(m < 0) m = 0; poly.Nth(m, seg); if(seg.Is(CURVE_LINE)) dAngle= seg.GetLine().Direction(); else if(seg.Is(CURVE_ARC)){ XPoint ptCenter; seg.GetArc().Center(ptCenter); dAngle = ads_angle(ptCenter, pt) + PI/2; } return seg; } XArc GetArcByCir(XPoint ptCen, double nRadius, XPoint ptStart, XPoint ptEnd, BOOL bIsLongArc = TRUE) { double startAngle = ads_angle(ptCen, ptStart); double endAngle = ads_angle(ptCen, ptEnd); XArc arc1(ptCen, nRadius, startAngle, endAngle); XArc arc2(ptCen, nRadius, endAngle, startAngle); if(bIsLongArc){ if(arc1.GetLength() > arc2.GetLength()) return arc1; else return arc2; } else{ if(arc1.GetLength() > arc2.GetLength()) return arc2; else return arc1; } } CString PlusString(const TCHAR* szRes, int step, BOOL bIsPlus) { if(_tcsicmp(szRes, _T("")) == 0) return CString(); XString xsText; int num, numWith; StringAnalysis(szRes, xsText, &num, &numWith); CString csRes = szRes; CString csRet = csRes; if(numWith != 0){ if(bIsPlus) num += step; else if(num > 1) num -= step; if(num < 0) num = 0; if(numWith == -1) csRet.Format(_T("%s%d"), xsText, num); else{ //需要补0 XString sText; sText << xsText; TCHAR szNext[256]=_T(""); _itot(num, szNext, 10); if(numWith > 0) { int iZeroNum = numWith - (int)_tcslen(szNext); for(int kk=0; kk 0) // { // CString csTmp; // csTmp = csInput.Right(csInput.GetLength() - idx); // SplitBlkStr(csTmp, csTK, csRecord); // return; // }//以上几句 沈睿 2011-6-24加,有的图块名是有前缀的。一般都是从$开头 int len = (int)_tcslen(szInput); TCHAR szTemp[256]=_T(""); int j =0; BOOL bfisrt = TRUE; szTemp[0] = _T('\0'); for(int i=0; i<=len; i++) { if(szInput[i] != _T('\0') && szInput[i] != _T('$')) szTemp[j] = szInput[i]; else { szTemp[j] = _T('\0'); if(szTemp[0] != _T('\0') && bfisrt){ csTK = szTemp; bfisrt = FALSE; } else if(szTemp[0] != _T('\0') && !bfisrt){ csRecord = szTemp; } j =-1; } j++; } } XCurveSegment GetBlkPickSeg(Entity entBlk, XPoint ptPick) { double xscale; entBlk.GetData(41, &xscale); xscale = fabs(xscale); XBlock myBlock(entBlk); if(!myBlock.m_bInitSuccess) return XCurveSegment(); AcDbBlockTableRecordIterator *pIterator; pIterator = myBlock.GetIterator(); for(pIterator->start(); !pIterator->done(); pIterator->step()){ AcDbEntity *pEnt; pIterator->getEntity(pEnt, AcDb::kForRead); AcDbCircle *pCir = NULL; AcDbLine *pLine = NULL; AcDbPolyline *pPoly = NULL; AcDbArc *pArc = NULL; AcDbSolid *pSolid = NULL; TDbWall *pWall = 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, 25)){ pEnt->close(); return seg; } } else if(pSolid = AcDbSolid::cast(pEnt)){ AcGePoint3d p1, p2, p3, p4; pSolid->getPointAt(0, p1); pSolid->getPointAt(1, p2); pSolid->getPointAt(2, p3); pSolid->getPointAt(3, p4); p1 = p1.transformBy(myBlock.GetMatrix3d()); p2 = p2.transformBy(myBlock.GetMatrix3d()); p3 = p3.transformBy(myBlock.GetMatrix3d()); p4 = p4.transformBy(myBlock.GetMatrix3d()); XLine l1(asDblArray(p1), asDblArray(p2), 1); XLine l2(asDblArray(p2), asDblArray(p4), 1); XLine l3(asDblArray(p3), asDblArray(p4), 1); XLine l4(asDblArray(p3), asDblArray(p1), 1); if(IsPtOnLine(ptPick, l1, 25)){ pEnt->close(); seg = l1; return seg; } if(IsPtOnLine(ptPick, l2, 25)){ pEnt->close(); seg = l2; return seg; } if(IsPtOnLine(ptPick, l3, 25)){ pEnt->close(); seg = l3; return seg; } if(IsPtOnLine(ptPick, l4, 25)){ pEnt->close(); seg = l4; 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, 25)){ 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, 25)){ pEnt->close(); return seg; } } else if(pWall = TDbWall::cast(pEnt)){ //特别支持5。0墙体 XCurveSegment lCurve, rCurve; pWall->GetSideCurve(lCurve, rCurve); if(lCurve.Is(CURVE_LINE)){ AcGePoint3d ptStart = lCurve.StartPoint(); ptStart = ptStart.transformBy(myBlock.GetMatrix3d()); AcGePoint3d ptEnd = lCurve.EndPoint(); ptEnd = ptEnd.transformBy(myBlock.GetMatrix3d()); XLine line(asDblArray(ptStart), asDblArray(ptEnd), 1); seg = line; if(IsPtOnLine(ptPick, line, 25)){ pEnt->close(); return seg; } } if(rCurve.Is(CURVE_LINE)){ AcGePoint3d ptStart = rCurve.StartPoint(); ptStart = ptStart.transformBy(myBlock.GetMatrix3d()); AcGePoint3d ptEnd = rCurve.EndPoint(); ptEnd = ptEnd.transformBy(myBlock.GetMatrix3d()); XLine line(asDblArray(ptStart), asDblArray(ptEnd), 1); seg = line; if(IsPtOnLine(ptPick, line, 25)){ pEnt->close(); return seg; } } if(lCurve.Is(CURVE_ARC)){ XArc arcTmp = lCurve.GetArc(); AcGePoint3d ptIns = arcTmp.GetCenterPt(); ptIns = ptIns.transformBy(myBlock.GetMatrix3d()); XArc arc(asDblArray(ptIns), arcTmp.GetRadius()*xscale, arcTmp.GetStarAngle(), arcTmp.GetEndAngle()); seg = arc; if(IsPtOnArc(ptPick, arc, 25)){ pEnt->close(); return seg; } } if(rCurve.Is(CURVE_ARC)){ XArc arcTmp = rCurve.GetArc(); AcGePoint3d ptIns = arcTmp.GetCenterPt(); ptIns = ptIns.transformBy(myBlock.GetMatrix3d()); XArc arc(asDblArray(ptIns), arcTmp.GetRadius()*xscale, arcTmp.GetStarAngle(), arcTmp.GetEndAngle()); seg = arc; if(IsPtOnArc(ptPick, arc, 25)){ pEnt->close(); return seg; } } } pEnt->close(); } return XCurveSegment(); } BOOL SetLayerLocked(const TCHAR* szLayerName, BOOL bLock) { AcDbLayerTable *pLayertable = NULL; AcDbLayerTableRecord *pLayerRec = NULL; acdbCurDwg()->getLayerTable(pLayertable, AcDb::kForRead); if(!pLayertable) return FALSE; if((pLayertable->getAt(szLayerName, pLayerRec, AcDb::kForWrite)) == Acad::eOk) { if(bLock) pLayerRec->setIsLocked(true); // 打开 else pLayerRec->setIsLocked(false); // 关 pLayerRec->close(); pLayertable->close(); } else pLayertable->close(); return TRUE; } BOOL SetLayer0UnLocked() { AcDbLayerTable *pLayertable = NULL; AcDbLayerTableRecord *pLayerRec = NULL; acdbCurDwg()->getLayerTable(pLayertable, AcDb::kForRead); if(!pLayertable) return FALSE; if((pLayertable->getAt(_T("0"), pLayerRec, AcDb::kForRead)) == Acad::eOk) { if(pLayerRec->isLocked() && pLayerRec->upgradeOpen()==Acad::eOk) { pLayerRec->setIsLocked(false); // 关 pLayerRec->downgradeOpen(); } pLayerRec->close(); } pLayertable->close(); return TRUE; } void SetBlkAttrText(Entity entBlk, const TCHAR*szText, const TCHAR*szTag, double nHeight, BOOL bVisible, BOOL bDown) { SetLayer0UnLocked(); AcDbBlockReference *pBlockRef = NULL;// 定义块表指针 AcDbObjectId eId; acdbGetObjectId(eId, entBlk); acdbOpenObject(pBlockRef, eId, AcDb::kForRead); if(!pBlockRef) return; AcDbObjectIterator *pIterator; pIterator = pBlockRef -> attributeIterator(); for (pIterator -> start(); !pIterator -> done(); pIterator -> step()) { //遍历块中实体 AcDbObjectId att_id; att_id = pIterator -> objectId(); AcDbEntity *pEnt; AcDbAttribute *pAtt; acdbOpenAcDbEntity(pEnt, att_id, AcDb::kForWrite); pAtt = AcDbAttribute::cast(pEnt); if(pAtt != NULL) { TCHAR *cname = pAtt->tag();//得到标记 if(_tcsicmp(cname, szTag) == 0){ if(!bVisible) pAtt->setInvisible(Adesk::kTrue); else{ pAtt->setTextString(szText); pAtt->setHeight(nHeight*DocGetPScale()); pAtt->setInvisible(Adesk::kFalse); if(bDown){ pAtt->setHorizontalMode(AcDb::kTextLeft); pAtt->setVerticalMode(AcDb::kTextTop); } } } delete[] cname; } pEnt->close(); } delete pIterator; pBlockRef->close(); } int GetLayerColorByDwg(const TCHAR*szLayer) { int iRet = -1; AcDbObjectId idLayer = GetLayerIdFromString(szLayer); OPENOBJ_BEGIN(idLayer, AcDb::kForRead, AcDbLayerTableRecord, pLayer); if(pLayer) { AcCmColor color = pLayer->color(); iRet = color.colorIndex(); } OPENOBJ_END(); return iRet; } void FilletEntity(Entity ent1, Entity ent2, double nRad) { XPushVar FilletRad(_T("FilletRad"), (int)nRad); XLine l1(ent1, 1); XLine l2(ent2, 1); XPoint ptMid1, ptMid2; l1.MidPoint(ptMid1); l2.MidPoint(ptMid2); ptMid1 = Wcs2Ucs(ptMid1); ptMid2 = Wcs2Ucs(ptMid2); ads_command(RTSTR,_T("FILLET"), RTLB,RTENAME,(TLong_ptr *)ent1, RT3DPOINT, &ptMid1, RTLE, RTLB,RTENAME,(TLong_ptr *)ent2, RT3DPOINT, &ptMid2, RTLE, RTNONE); } // 2008-6-27 sr 改采用acedNEntSelP的方法,支持嵌套参考 XCurveSegment GetBlkPickSegment(Entity entBlk, XPoint ptPick) { XCurveSegment seg; ads_name ename; ads_matrix adsmat; struct resbuf *insStack; if (acedNEntSelP(NULL, ename, ptPick, TRUE, adsmat, &insStack) != RTNORM) { ads_printf(_T("\nFailure in ads_nentselp")); return seg; } ads_relrb(insStack); Entity entTemp = ename; if(entTemp.Is(_T("LINE")) || entTemp.Is(_T("ARC"))){ XCurveSegment seg1(entTemp); seg1.TransformBy(adsmat); seg = seg1; } else if(entTemp.Is(_T("LWPOLYLINE"))){ double dAngle; XPoly2D poly(entTemp); poly.TransformBy(AsAcGeMatrix3d(adsmat)); //poly.Make(); seg = GetSegByPt(poly, ptPick, dAngle); } else if(entTemp.Is(_T("ATS_WALL"))){ OPENOBJ_BEGIN(entTemp, AcDb::kForRead, TDbWall, pWall); XCurveSegment lCurve, rCurve; XPoint ptNew1, ptNew2; if(pWall) { pWall->GetSideCurve(lCurve, rCurve); lCurve.TransformBy(adsmat); rCurve.TransformBy(adsmat); seg = lCurve; } OPENOBJ_END(); } else{ OPENOBJ_BEGIN(ename, AcDb::kForRead, AcDbEntity, pEnt); if(pEnt != NULL){ ads_printf(_T("\n无法识别: %s"), pEnt->isA()->name()); } OPENOBJ_END(); } return seg; } /* XCurveSegment GetBlkPickSegment(Entity entBlk, XPoint ptPick) { //第一步,得到块参考矩阵 AcDbBlockReference *pBlkRef = NULL; AcDbObjectId id = NULL; acdbGetObjectId(id, entBlk); acdbOpenObject(pBlkRef, id, AcDb::kForRead); if(!pBlkRef) return XCurveSegment(); AcGeMatrix3d mat = pBlkRef->blockTransform(); if(pBlkRef) pBlkRef->close(); double xscale; entBlk.GetData(41, &xscale); xscale = fabs(xscale); //第二步,得到块记录遍历器 TCHAR szBlkName[256]; entBlk.GetData(2, szBlkName); AcDbBlockTable* pBlockTable = NULL; AcDbBlockTableRecord *pRecord = NULL; acdbCurDwg()->getBlockTable(pBlockTable, AcDb::kForRead); if(Acad::eOk != pBlockTable->getAt(szBlkName, pRecord, AcDb::kForRead)) return XCurveSegment(); pBlockTable->close(); if(pRecord->isFromExternalReference() == true){ XPoint ptOrigin = pRecord->origin(); AcGeMatrix3d mat2; mat2.setToTranslation(AcGeVector3d(-ptOrigin[0], -ptOrigin[1], -ptOrigin[2])); mat *= mat2; } AcDbBlockTableRecordIterator *pIterator = NULL; pRecord->newIterator(pIterator); if(pRecord) pRecord->close(); for(pIterator->start(); !pIterator->done(); pIterator->step()){ AcDbEntity *pEnt; pIterator->getEntity(pEnt, AcDb::kForRead); AcDbCircle *pCir = NULL; AcDbLine *pLine = NULL; AcDbPolyline *pPoly = NULL; AcDbArc *pArc = NULL; AcDbSolid *pSolid = NULL; TDbWall *pWall = NULL; XCurveSegment seg; 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, 500/20)){ pEnt->close(); return seg; } } else if(pSolid = AcDbSolid::cast(pEnt)){ AcGePoint3d p1, p2, p3, p4; pSolid->getPointAt(0, p1); pSolid->getPointAt(1, p2); pSolid->getPointAt(2, p3); pSolid->getPointAt(3, p4); p1 = p1.transformBy(mat); p2 = p2.transformBy(mat); p3 = p3.transformBy(mat); p4 = p4.transformBy(mat); XLine l1(asDblArray(p1), asDblArray(p2), 1); XLine l2(asDblArray(p2), asDblArray(p4), 1); XLine l3(asDblArray(p3), asDblArray(p4), 1); XLine l4(asDblArray(p3), asDblArray(p1), 1); if(IsPtOnLine(ptPick, l1, 25)){ pEnt->close(); seg = l1; return seg; } if(IsPtOnLine(ptPick, l2, 25)){ pEnt->close(); seg = l2; return seg; } if(IsPtOnLine(ptPick, l3, 25)){ pEnt->close(); seg = l3; return seg; } if(IsPtOnLine(ptPick, l4, 25)){ pEnt->close(); seg = l4; return seg; } } else if(pPoly = AcDbPolyline::cast(pEnt)){ XPoly2D poly; PolyConvert(*pPoly, poly); poly.TransformBy(mat); double n; seg = GetSegByPt(poly, ptPick, n); if(!!seg) 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, 500/20)){ pEnt->close(); 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, 500/20)){ pEnt->close(); return seg; } } else if(pWall = TDbWall::cast(pEnt)){ //特别支持5。0墙体 XCurveSegment lCurve, rCurve; pWall->GetSideCurve(lCurve, rCurve); if(lCurve.Is(CURVE_LINE)){ AcGePoint3d ptStart = lCurve.StartPoint(); ptStart = ptStart.transformBy(mat); AcGePoint3d ptEnd = lCurve.EndPoint(); ptEnd = ptEnd.transformBy(mat); XLine line(asDblArray(ptStart), asDblArray(ptEnd), 1); seg = line; if(IsPtOnLine(ptPick, line, 500/20)){ pEnt->close(); return seg; } } if(rCurve.Is(CURVE_LINE)){ AcGePoint3d ptStart = rCurve.StartPoint(); ptStart = ptStart.transformBy(mat); AcGePoint3d ptEnd = rCurve.EndPoint(); ptEnd = ptEnd.transformBy(mat); XLine line(asDblArray(ptStart), asDblArray(ptEnd), 1); seg = line; if(IsPtOnLine(ptPick, line, 500/20)){ pEnt->close(); return seg; } } if(lCurve.Is(CURVE_ARC)){ XArc arcTmp = lCurve.GetArc(); AcGePoint3d ptIns = arcTmp.center; ptIns = ptIns.transformBy(mat); XArc arc(asDblArray(ptIns), arcTmp.radius*xscale, arcTmp.startAngle, arcTmp.endAngle); seg = arc; if(IsPtOnArc(ptPick, arc, 500/20)){ pEnt->close(); return seg; } } if(rCurve.Is(CURVE_ARC)){ XArc arcTmp = rCurve.GetArc(); AcGePoint3d ptIns = arcTmp.center; ptIns = ptIns.transformBy(mat); XArc arc(asDblArray(ptIns), arcTmp.radius*xscale, arcTmp.startAngle, arcTmp.endAngle); seg = arc; if(IsPtOnArc(ptPick, arc, 500/20)){ pEnt->close(); return seg; } } } pEnt->close(); } if(pIterator) delete pIterator; return XCurveSegment(); } */ int get_line_angle(ads_real& line_angle)//得到直线的角度 { int iLineType = 0; RBList rbMask = ads_buildlist( -4, _T(""), -4, _T(""), -4, _T(""), -4, _T(""), -4, _T("or>"), NULL); XPoint ptPick; Entity entWall; if(SelectEntity1(_T("\n从当前图中选取行向线<不选取>:"), entWall, ptPick, rbMask) != RTNORM) return RTNORM; XCurveSegment lCurve, rCurve, SelCurve; BOOL bIsLeft = TRUE; if(entWall.Is(_T("INSERT"))){ SelCurve = GetBlkPickSegment(entWall, ptPick); if(!SelCurve) return 0; iLineType = 0; } else if(entWall.Is(_T("LWPOLYLINE"))){ double dAngle; XPoint ptWcs = Ucs2Wcs(ptPick); SelCurve = GetSegByPt(XPoly2D(entWall), ptWcs, dAngle); if(!SelCurve) return 0; iLineType = 0; } else if(entWall.Is(_T("ATS_WALL"))){ OPENOBJ_BEGIN(entWall, AcDb::kForRead, TDbWall, pWall); XPoint ptNew1, ptNew2; if(pWall) { pWall->GetSideCurve(lCurve, rCurve); lCurve.ProjectToMe(ptPick, ptNew1); rCurve.ProjectToMe(ptPick, ptNew2); if(ads_distance(ptPick, ptNew1) < ads_distance(ptPick, ptNew2)){ SelCurve = lCurve; bIsLeft = TRUE; } else{ SelCurve = rCurve; bIsLeft = FALSE; } } OPENOBJ_END(); } else iLineType = 1; if(!SelCurve.Is(CURVE_LINE)) return RTCAN; if(iLineType == 0){ XLine line = SelCurve.GetLine(); //得到直线的角度 line_angle=ads_angle(line.StartPoint(),line.EndPoint()); if(line_angle > PI) line_angle = line_angle - PI; } else if(iLineType == 1){ XPoint ptStart, ptEnd; entWall.GetData(10, ptStart); entWall.GetData(11, ptEnd); line_angle=ads_angle(ptStart, ptEnd); if(line_angle > PI) line_angle = line_angle - PI; } return RTNORM; } AcDbObjectId InitDoteLayer(const TCHAR* szLay) { AcDbObjectId idLay=GetLayerIdFromString(szLay); if(!!idLay) return idLay; AcDbObjectId id = InitLayer(szLay); AddLineType(_T("CENTER2")); AcDbLinetypeTable *pLinetypeTbl; AcDbObjectId ltId; Acad::ErrorStatus es = acdbCurDwg()->getLinetypeTable(pLinetypeTbl, AcDb::kForRead); if(es != Acad::eOk) { return NULL; } if((pLinetypeTbl->getAt(_T("CENTER2"), ltId)) != Acad::eOk){ pLinetypeTbl->close(); return NULL; } pLinetypeTbl->close(); OPENOBJ_BEGIN(id, AcDb::kForWrite, AcDbLayerTableRecord, pRec); if(pRec){ pRec->setLinetypeObjectId(ltId); } OPENOBJ_END(); return id; } AcDbObjectId InitGridLayer(const TCHAR* szLay) { AcDbObjectId idLay=GetLayerIdFromString(szLay); if(!!idLay) return idLay; AcDbObjectId id = InitLayer(szLay); AddLineType(_T("DOT")); AcDbLinetypeTable *pLinetypeTbl; AcDbObjectId ltId; Acad::ErrorStatus es = acdbCurDwg()->getLinetypeTable(pLinetypeTbl, AcDb::kForRead); if(es != Acad::eOk) { return NULL; } if((pLinetypeTbl->getAt(_T("DOT"), ltId)) != Acad::eOk){ pLinetypeTbl->close(); return NULL; } pLinetypeTbl->close(); OPENOBJ_BEGIN(id, AcDb::kForWrite, AcDbLayerTableRecord, pRec); if(pRec){ pRec->setLinetypeObjectId(ltId); } OPENOBJ_END(); return id; } AcDbObjectId InitDashLayer(const TCHAR* szLay) { AcDbObjectId idLay=GetLayerIdFromString(szLay); if(!!idLay) return idLay; AcDbObjectId id = InitLayer(szLay); AddLineType(_T("DASH")); AcDbLinetypeTable *pLinetypeTbl; AcDbObjectId ltId; Acad::ErrorStatus es = acdbCurDwg()->getLinetypeTable(pLinetypeTbl, AcDb::kForRead); if(es != Acad::eOk) { return NULL; } if((pLinetypeTbl->getAt(_T("DASH"), ltId)) != Acad::eOk){ pLinetypeTbl->close(); return NULL; } pLinetypeTbl->close(); OPENOBJ_BEGIN(id, AcDb::kForWrite, AcDbLayerTableRecord, pRec); if(pRec){ pRec->setLinetypeObjectId(ltId); } OPENOBJ_END(); return id; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// //以下是李夫银的AcGePoint3dArray排序函数 typedef struct PtOnCrItem { AcGePoint3d m_ptGeOld; AcGePoint3d m_ptGeOn; AcDbCurve * m_pCurve; AcDbObjectId m_ID; } PTONCRITEM,* PPTONCRITEM; //回调函数 static bool GreaterCoord(PTONCRITEM item1,PTONCRITEM item2) { AcDbCurve * pCurve = item1.m_pCurve; AcGePoint3d ptGe1 = item1.m_ptGeOn; AcGePoint3d ptGe2 = item2.m_ptGeOn; double dDis1 = 0.0,dDis2 = 0.0; pCurve->getParamAtPoint(ptGe1,dDis1); pCurve->getParamAtPoint(ptGe2,dDis2); if(dDis1 - dDis2 > 0.000001) { return false;//up sort } return true;//down sort } void SortPoints(AcGePoint3dArray& points, AcDbCurve * pCurve, BOOL bModifyArray) { PTONCRITEM ptOnCrItem; typedef std::vector PtOnCrItemVector; // PtOnCrItemVector::_Tptr p_ptr = (PTONCRITEM *)0; // PtOnCrItemVector::_Ctptr p_cptr = (const PTONCRITEM *)0; PtOnCrItemVector::reference p_ref = ptOnCrItem; PtOnCrItemVector::const_reference p_cref = (const PTONCRITEM&) ptOnCrItem; PtOnCrItemVector::value_type * p_val = (PTONCRITEM *)0; PtOnCrItemVector::size_type * p_size = (size_t *)0; PtOnCrItemVector::difference_type * p_diff = (ptrdiff_t *)0; PtOnCrItemVector vectorItems; ptOnCrItem.m_pCurve = pCurve; AcGePoint3d ptGeT; int nLength = points.length(); for(int i = 0;i < nLength;i++) { ptGeT = points.at(i); ptOnCrItem.m_ptGeOld = ptGeT; pCurve->getClosestPointTo(ptGeT,ptGeT); ptOnCrItem.m_ptGeOn = ptGeT; vectorItems.push_back(ptOnCrItem); } PtOnCrItemVector::iterator itHead = vectorItems.begin(); PtOnCrItemVector::iterator itTail = vectorItems.end(); std::sort(itHead,itTail,GreaterCoord); itHead = vectorItems.begin(); itTail = vectorItems.end(); points.removeSubArray(0,nLength - 1); AcGePoint3d ptGe; for(;itHead != itTail;++itHead) { if(bModifyArray) ptGe = (*itHead).m_ptGeOn; else ptGe = (*itHead).m_ptGeOld; points.append(ptGe); } } void DeleteRepeateWall(AcDbObjectIdArray * pIDWalls) { AcDbObjectIdArray idWalls; AcDbObjectIdArray idErases; AcDbObjectId id1,id2; AcDbEntity * pEnt1 = NULL; AcDbEntity * pEnt2 = NULL; double dDis1 = 0.0,dDis2 = 0.0; int nLen = pIDWalls->length(); for(int i = 0;i < nLen;i++) { id1 = pIDWalls->at(i); if (Acad::eOk == acdbOpenAcDbEntity(pEnt1,id1,AcDb::kForRead)) { for(int j = 0;j < nLen;j++) { id2 = pIDWalls->at(j); if (id1 != id2) { if (Acad::eOk == acdbOpenAcDbEntity(pEnt2,id2,AcDb::kForRead)) { if (pEnt1->isKindOf(pEnt2->desc())) { AcDbLine * pLine1 = AcDbLine::cast(pEnt1); AcDbLine * pLine2 = AcDbLine::cast(pEnt2); if (pLine1 != NULL && pLine2 != NULL) { AcGePoint3d ptGeSta1 = pLine1->startPoint(); AcGePoint3d ptGeEnd1 = pLine1->endPoint(); AcGePoint3d ptGeSta2 = pLine2->startPoint(); AcGePoint3d ptGeEnd2 = pLine2->endPoint(); AcGeVector3d vc1 = ptGeEnd1 - ptGeSta1; AcGeVector3d vc2 = ptGeEnd2 - ptGeSta2; if (vc1.isParallelTo(vc2)) { AcDbXline xline; xline.setUnitDir(vc1); xline.setBasePoint(ptGeEnd1); AcGePoint3d ptGe; xline.getClosestPointTo(ptGeEnd2,ptGe); double dDis1 = ptGe.distanceTo(ptGeEnd2); if (dDis1 < E6TOL) { dDis1 = ptGeEnd1.distanceTo(ptGeSta1); dDis2 = ptGeEnd2.distanceTo(ptGeSta2); AcGePoint3dArray ptS; ptS.append(ptGeSta1); ptS.append(ptGeEnd1); ptS.append(ptGeSta2); ptS.append(ptGeEnd2); SortPoints(ptS,&xline,TRUE); double dDis3 = ptS.first().distanceTo(ptS.last()); if (dDis1 + dDis2 - dDis3 > E6TOL) { if (dDis1 - dDis2 < E6TOL) { pLine1->upgradeOpen(); pLine1->erase(); pLine1->downgradeOpen(); idErases.append(id1); } else { pLine2->upgradeOpen(); pLine2->erase(); pLine2->downgradeOpen(); idErases.append(id2); } } } } } AcDbBlockReference * pBlk1 = AcDbBlockReference::cast(pEnt1); AcDbBlockReference * pBlk2 = AcDbBlockReference::cast(pEnt2); if (pBlk1 != NULL && pBlk2 != NULL) { AcGePoint3d ptLoc1 = pBlk1->position(); AcGePoint3d ptLoc2 = pBlk2->position(); AcDbObjectId id1 = pBlk1->blockTableRecord(); AcDbObjectId id2 = pBlk2->blockTableRecord(); double dDis1 = ptLoc1.distanceTo(ptLoc2); if (dDis1 < E6TOL) { pBlk1->upgradeOpen(); pBlk1->erase(); pBlk1->downgradeOpen(); idErases.append(id1); } } } pEnt2->close(); } } } pEnt1->close(); } } nLen = idErases.length(); for(i = 0;i < nLen;i++) { pIDWalls->remove(idErases.at(i)); } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// // OFFSET 2008-1-28 沈睿 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// //已知1线段,和偏移距离,和线上1点, 返回偏移后的线段 // 注意:调用者自己必须释放返回的AcDbCurve AcDbCurve* GetOffsetCurve(AcDbCurve *pCurve, double dOffsetDist, XPoint ptPick) { if(pCurve == NULL) return NULL; //先OFFSET一根曲线过来 AcDbVoidPtrArray arCurves; pCurve->getOffsetCurves(dOffsetDist, arCurves); int len = arCurves.length(); if(arCurves.length() > 0){ AcDbCurve *pCurve2; pCurve2 = (AcDbCurve *)arCurves.first(); XPoint ptOnCurve; pCurve2->getClosestPointTo(ptPick, ptOnCurve); double dDist = ads_distance(ptPick, ptOnCurve); long lNum=arCurves.length(); for(long j=1L; jgetOffsetCurves(-dOffsetDist, arCurves2); if(arCurves2.length() > 0){ AcDbCurve *pCurve3; pCurve3 = (AcDbCurve *)arCurves2.first(); long lNum2=arCurves2.length(); for(j=1L; j vecPt; typedef std::vector::iterator iter; XPoint ptTemp1,ptTemp2;//取两点十字集范围内实体的两个点 XPoint ptPLineStart, ptPLineEnd, ptPLineTurn;//相邻线的起点 拐点 终点 ptPLineStart = ptPick; Entity entFirst = ent, entNext; //相邻两个实体 //不断的循环查找下一相邻实体 //seg变化 seg2不变化 ptPLineTurn = ptFrom; // cet 2016.7.20 add 支持外部参照 #if ADS > 17 struct CurveNode { XCurveSegment seg; Entity ent; AcGeMatrix3d mat; }; #endif std::vector vecCurve; AcDbBlockTable *pTbl = NULL; acdbCurDwg()->getBlockTable(pTbl, AcDb::kForRead); if (pTbl != NULL) { AcDbBlockTableIterator *it = NULL; pTbl->newIterator(it); for (it->start(); !it->done(); it->step()) { AcDbBlockTableRecord *pRcd = NULL; it->getRecord(pRcd, AcDb::kForRead); if (pRcd != NULL && pRcd->isFromExternalReference()) { AcGeMatrix3d mat = AcGeMatrix3d::kIdentity; AcDbObjectIdArray arrId; pRcd->getBlockReferenceIds(arrId); if (arrId.length() != 1) { pRcd->close(); continue; } AcDbBlockReference *pRef = NULL; acdbOpenObject(pRef, arrId[0], AcDb::kForRead); if (pRef != NULL) { mat = pRef->blockTransform(); pRef->close(); } else { pRcd->close(); continue; } ads_matrix matTemp; memcpy(matTemp, &mat, sizeof(AcGeMatrix3d)); AcDbBlockTableRecordIterator *itRec = NULL; pRcd->newIterator(itRec); for (itRec->start(); !itRec->done(); itRec->step()) { AcDbEntity *pEnt = NULL; itRec->getEntity(pEnt, AcDb::kForRead); if (pEnt != NULL) { if (pEnt->isKindOf(AcDbLine::desc())) { AcDbLine *pLine = (AcDbLine*)pEnt; AcGePoint3d pt1, pt2; pLine->getStartPoint(pt1); pLine->getEndPoint(pt2); XCurveSegment seg; seg.SetLine(pt1, pt2); seg.TransformBy(matTemp); ads_name name; acdbGetAdsName(name, pEnt->objectId()); CurveNode node; node.seg = seg; node.ent = Entity(name); node.mat = mat; vecCurve.push_back(node); } else if (pEnt->isKindOf(AcDbArc::desc())) { AcDbArc *pArc = (AcDbArc*)pEnt; XArc arc(XPoint(pArc->center()), pArc->radius(), pArc->startAngle(), pArc->endAngle()); arc.TransformBy(matTemp); ads_name name; acdbGetAdsName(name, pEnt->objectId()); CurveNode node; node.seg = arc; node.ent = Entity(name); node.mat = mat; vecCurve.push_back(node); } } pEnt->close(); } delete itRec; } pRcd->close(); } delete it; // 模型空间中的墙体 AcDbBlockTableRecord *pRcd = NULL; pTbl->getAt(ACDB_MODEL_SPACE, pRcd, AcDb::kForRead); if (pTbl != NULL) { AcGeMatrix3d mat = AcGeMatrix3d::kIdentity; ads_matrix matTemp; memcpy(matTemp, &mat, sizeof(AcGeMatrix3d)); AcDbBlockTableRecordIterator *itRec = NULL; pRcd->newIterator(itRec); for (itRec->start(); !itRec->done(); itRec->step()) { AcDbEntity *pEnt = NULL; itRec->getEntity(pEnt, AcDb::kForRead); if (pEnt != NULL) { if (pEnt->isKindOf(AcDbLine::desc())) { AcDbLine *pLine = (AcDbLine*)pEnt; AcGePoint3d pt1, pt2; pLine->getStartPoint(pt1); pLine->getEndPoint(pt2); XCurveSegment seg; seg.SetLine(pt1, pt2); seg.TransformBy(matTemp); ads_name name; acdbGetAdsName(name, pEnt->objectId()); CurveNode node; node.seg = seg; node.ent = Entity(name); node.mat = mat; vecCurve.push_back(node); } else if (pEnt->isKindOf(AcDbArc::desc())) { AcDbArc *pArc = (AcDbArc*)pEnt; XArc arc(XPoint(pArc->center()), pArc->radius(), pArc->startAngle(), pArc->endAngle()); arc.TransformBy(matTemp); ads_name name; acdbGetAdsName(name, pEnt->objectId()); CurveNode node; node.seg = arc; node.ent = Entity(name); node.mat = mat; vecCurve.push_back(node); } } pEnt->close(); } delete itRec; pRcd->close(); } pTbl->close(); } //两个实体相邻则退出 while(seg.EndPoint().Distance(seg2.StartPoint()) > 0.001 && seg.StartPoint().Distance(seg2.EndPoint()) > 0.001 && seg.EndPoint().Distance(seg2.EndPoint()) > 0.001 && seg.StartPoint().Distance(seg2.StartPoint()) > 0.001) { // cet 2016.7.20 modify 支持外部参照 // ptTemp1 = ptPLineTurn; // ptTemp2 = ptPLineTurn; // ptTemp1.x += 2; // ptTemp1.y += 2; // ptTemp2.x -= 2; // ptTemp2.y -= 2; // AssureInCurrentView(ptTemp1, ptTemp2); // PickSet ssPoint(SS_FREE); // ssPoint.Get(_T("C"),ptTemp1,ptTemp2, RBList(RTDXF0, _T("LINE,ARC"), NULL)); PickSet ssPoint(SS_FREE); for (int i = 0; i < vecCurve.size(); ++i) { XCurveSegment &segTmp = vecCurve[i].seg; XPoint pt; ptPLineTurn.Project(&segTmp, pt); if (pt.Distance2d(ptPLineTurn) < 0.001) { ssPoint += vecCurve[i].ent; } } ssPoint -= entFirst; if(ssPoint.Length() != 1) return FALSE; entNext = ssPoint[0L]; // if(ssPoint.Length() != 2) // return FALSE; // //去掉旧的实体 entNext 是循环的下1段线 // Entity entPointTemp1, entPointTemp2; // entPointTemp1 = ssPoint[0L]; // entPointTemp2 = ssPoint[1L]; // // if(entPointTemp1 == entFirst) // entNext = entPointTemp2; // else if(entPointTemp2 == entFirst) // entNext = entPointTemp1; XCurveSegment segNext(entNext); // cet 2016.7.20 add 支持外部参照 AcGeMatrix3d mat = AcGeMatrix3d::kIdentity; for (int i = 0; i < vecCurve.size(); ++i) { if (vecCurve[i].ent == entNext) { mat = vecCurve[i].mat; break; } } ads_matrix matTemp; memcpy(matTemp, &mat, sizeof(AcGeMatrix3d)); segNext.TransformBy(matTemp); seg = segNext; //下一个 if(segNext.StartPoint() == seg.StartPoint() || segNext.StartPoint() == seg.EndPoint()) ptPLineEnd = segNext.EndPoint(); else if(segNext.EndPoint() == seg.StartPoint() || segNext.EndPoint() == seg.EndPoint()) ptPLineEnd = segNext.StartPoint(); else return FALSE;//确保前后2段线一定首尾相连 MakeSimplePloyLine(entFirst,entNext,ptPLineStart,ptPLineEnd,linePt1,linePt2,linePt3,ptPLineTurn); //取下1段PLINE的拐点 if (segNext.StartPoint() != ptPLineTurn) ptPLineTurn = segNext.StartPoint(); else ptPLineTurn = segNext.EndPoint(); entFirst = entNext; ptPLineStart = ptPLineEnd; if (entFirst == ent)//找到自己则退出 return FALSE; vecPt.push_back(linePt1); vecPt.push_back(linePt2); vecPt.push_back(linePt3); } MakeSimplePloyLine(entFirst,ent2,ptPLineStart,ptPick2,linePt1,linePt2,linePt3,ptPLineTurn); vecPt.push_back(linePt1); vecPt.push_back(linePt2); vecPt.push_back(linePt3); //生成PLINE线 for (int it = 0; it < vecPt.size(); ++it) { pLine->addVertexAt(it,vecPt[it].pt,vecPt[it].dBulge); } return TRUE; } // 已知一个曲线,并知道曲线上2点,求这2点围成的中间曲线 // 注意:返回的曲线必须调用者自己释放 AcDbCurve* GetCurveBy2Pt(AcDbCurve *pCurve, XPoint ptOnCurve1, XPoint ptOnCurve2) { AcDbVoidPtrArray arSeg;//裁剪后的曲线段 AcGePoint3dArray arPoint(2);//裁剪的点 double dDist1, dDist2; pCurve->getDistAtPoint(ptOnCurve1, dDist1); pCurve->getDistAtPoint(ptOnCurve2, dDist2); if(dDist1 < dDist2){ arPoint.append(ptOnCurve1); arPoint.append(ptOnCurve2); } else{ arPoint.append(ptOnCurve2); arPoint.append(ptOnCurve1); } pCurve->getSplitCurves(arPoint,arSeg);//剪切PLINE线 int nLen = arSeg.length(); // cet 2014.12.1 modify 当点在曲线起始点时结果错误 // if(nLen != 3) // { // ReleaseEntSet(arSeg); // return NULL; // } // AcDbCurve *pCurveRet = NULL; // for (int i = 0; i < nLen; ++i) // { // AcDbCurve *pCurve3 = (AcDbCurve*)arSeg[i]; // if (pCurve3 != NULL) // { // if(i == 1) // pCurveRet = pCurve3; // else // delete pCurve3; // } // } AcGePoint3d ptS, ptE; AcDbCurve *pCurveRet = NULL; for (int i = 0; i < nLen; ++i) { AcDbCurve *pCurve3 = (AcDbCurve*)arSeg[i]; if (pCurve3 != NULL) { pCurve3->getStartPoint(ptS); pCurve3->getEndPoint(ptE); if (ptS.distanceTo(ptOnCurve1) < 0.001 && ptE.distanceTo(ptOnCurve2) < 0.001 || ptS.distanceTo(ptOnCurve2) < 0.001 && ptE.distanceTo(ptOnCurve1) < 0.001) { arSeg.removeAt(i); pCurveRet = pCurve3; break; } } } ReleaseEntSet(arSeg); return pCurveRet; } //已知一个曲线XCurveSegment,以及曲线上2点,返回这2点连成的AcDbPolyline void GetPLineBySeg(AcDbPolyline *pLine, XCurveSegment seg, XPoint ptPick, XPoint ptPick2) { if(seg.Is(CURVE_LINE)){ pLine->addVertexAt(0, ptPick); pLine->addVertexAt(1, ptPick2); } else if(seg.Is(CURVE_ARC)){ //圆弧 XArc arc = seg.GetArc(); AcGeVector3d vt1(ptPick2-arc.GetCenterPt()); AcGeVector3d vt2(ptPick-arc.GetCenterPt()); double dAngle = vt1.angleTo(vt2); double dBulge = tan(0.25 * dAngle); // 要确定Bulge的正,负。 如果PLINE起点离弧起点近,Bulge为正 AcDbCurve *pCurve = seg.AsAcDbCurve(); double dDist1(0), dDist2(0); pCurve->getDistAtPoint(ptPick, dDist1); pCurve->getDistAtPoint(ptPick2, dDist2); if(dDist1 < dDist2) dBulge = fabs(dBulge); else dBulge = -fabs(dBulge); delete pCurve; pLine->addVertexAt(0, ptPick, dBulge); pLine->addVertexAt(1, ptPick2); } } //通过在墙上两点得到PLINE线 BOOL MakePolyLineByWall(AcDbPolyline *pLine,Entity ent, Entity ent2, XPoint ptPick, XPoint ptPick2) { XCurveSegment lCurve, rCurve,firstSeg,secondSeg; BOOL bIsLeft = TRUE; XPoint ptTurn; //得到墙实体1 OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbWall, pWall); XPoint ptNew1, ptNew2; if(pWall) { pWall->GetSideCurve(lCurve, rCurve); lCurve.ProjectToMe(ptPick, ptNew1); rCurve.ProjectToMe(ptPick, ptNew2); if(ads_distance(ptPick, ptNew1) < ads_distance(ptPick, ptNew2)){ firstSeg = lCurve; bIsLeft = TRUE; ptPick = ptNew1; } else{ firstSeg = rCurve; bIsLeft = FALSE; ptPick = ptNew2; } } OPENOBJ_END(); XPoint ptNew3, ptNew4; //得到墙实体2 OPENOBJ_BEGIN(ent2, AcDb::kForRead, TDbWall, pWall2); if(pWall2) { pWall2->GetSideCurve(lCurve, rCurve); lCurve.ProjectToMe(ptPick2, ptNew3); rCurve.ProjectToMe(ptPick2, ptNew4); //找到相临的CURVE if(firstSeg.StartPoint() == lCurve.StartPoint() || firstSeg.StartPoint() == lCurve.EndPoint()||firstSeg.EndPoint() == lCurve.StartPoint() || firstSeg.EndPoint() == lCurve.EndPoint()) { ptPick2 = ptNew3; secondSeg = lCurve; } else { ptPick2 = ptNew4; secondSeg = rCurve; } } OPENOBJ_END(); //得到拐点 if(firstSeg.StartPoint() == secondSeg.StartPoint() || firstSeg.StartPoint() == secondSeg.EndPoint()) ptTurn = firstSeg.StartPoint(); else if(firstSeg.EndPoint() == secondSeg.StartPoint() || firstSeg.EndPoint() == secondSeg.EndPoint()) ptTurn = firstSeg.EndPoint(); else return FALSE; XLinePointAndBulge linePoint1,linePoint2,linePoint3; //得到构成PLINE线的3点 MakeSimplePloyLine(firstSeg,secondSeg,ptPick,ptPick2,linePoint1,linePoint2,linePoint3,ptTurn); if (pLine != NULL) { pLine->addVertexAt(0,linePoint1.pt,linePoint1.dBulge); pLine->addVertexAt(1,linePoint2.pt,linePoint2.dBulge); pLine->addVertexAt(2,linePoint3.pt,linePoint3.dBulge); AssureInCurrentView(ptPick2, ptPick2); } return TRUE; } // 主函数 // 已知2根相邻的线段,给定2个点,返回一个POLYLINE // 注意:调用者必须自己delete PLINE AcDbPolyline* GetNextPloyLine(Entity ent, Entity ent2, XPoint ptPick, XPoint ptPick2) { XPoint ptTurn; XCurveSegment seg(ent); XCurveSegment seg2(ent2); // cet 2016.7.20 add 支持外部参照 AcGeMatrix3d mat1 = GetExternalEntityTransform(ent); AcGeMatrix3d mat2 = GetExternalEntityTransform(ent2); ads_matrix matTemp; memcpy(matTemp, &mat1, sizeof(AcGeMatrix3d)); seg.TransformBy(matTemp); memcpy(matTemp, &mat2, sizeof(AcGeMatrix3d)); seg2.TransformBy(matTemp); //如果是相邻或同一线段求得转折点 if(seg.StartPoint() == seg2.StartPoint() || seg.StartPoint() == seg2.EndPoint()) ptTurn = seg.StartPoint(); else if(seg.EndPoint() == seg2.StartPoint() || seg.EndPoint() == seg2.EndPoint()) ptTurn = seg.EndPoint(); AcDbPolyline *pLine = new AcDbPolyline; if(ent == ent2) { // 如果用户点在本线段 if(ent.Is(_T("LINE")) || ent.Is(_T("ARC"))) { GetPLineBySeg(pLine, seg, ptPick, ptPick2); } else if (ent.Is(_T("ATS_WALL"))) { OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbWall, pWall); if(pWall){ XCurveSegment lCurve, rCurve, seg; XPoint ptNew1, ptNew2; pWall->GetSideCurve(lCurve, rCurve); // cet 2016.7.20 add 支持外部参照 ads_matrix matTemp; memcpy(matTemp, &mat1, sizeof(AcGeMatrix3d)); lCurve.TransformBy(matTemp); rCurve.TransformBy(matTemp); lCurve.ProjectToMe(ptPick, ptNew1); rCurve.ProjectToMe(ptPick, ptNew2); if(ads_distance(ptPick, ptNew1) < ads_distance(ptPick, ptNew2)) seg = lCurve; else seg = rCurve; GetPLineBySeg(pLine, seg, ptPick, ptPick2); } OPENOBJ_END(); } else if (ent.Is(_T("LWPOLYLINE"))) { delete pLine; AcDbPolyline *pLine2 = NULL; OPENOBJ_BEGIN(ent, AcDb::kForRead, AcDbPolyline, pCurve); if(pCurve) { AcDbCurve *pNewCurve = (AcDbCurve*)pCurve->clone(); pNewCurve->transformBy(mat1); AcDbCurve *pCurve3 = GetCurveBy2Pt(pNewCurve, ptPick, ptPick2); if(pCurve3 != NULL) pLine2 = AcDbPolyline::cast(pCurve3); if(pLine2 == NULL) delete pCurve3; delete pNewCurve; } OPENOBJ_END(); AssureInCurrentView(ptPick2, ptPick2); return pLine2; } else { delete pLine; return NULL; } } else{ // 如果用户点在不同并且不相邻线段 //不支持2个相邻的线段,有1个是PLINE if (ent.Is(_T("LWPOLYLINE")) || ent2.Is(_T("LWPOLYLINE"))){ delete pLine; return NULL; } if (ptTurn != seg.StartPoint() && ptTurn != seg.EndPoint()) { //如果是封闭曲线则不画 BOOL bTrue1 = MakeRightPloyLine(pLine,ent,ent2,ptPick,ptPick2,seg.StartPoint()); BOOL bTrue2 = MakeRightPloyLine(pLine,ent,ent2,ptPick,ptPick2,seg.EndPoint()); if (bTrue1 && bTrue2) { adsout << _T("所选线段在封闭的环中\n"); delete pLine; return NULL; } if (!bTrue1 && !bTrue2) { delete pLine; XPoint ptInter1,ptInter2; if (seg.Intersection(seg2,ptInter1,ptInter2) != 1) { adsout << _T("所选线段与当前线段没有相连\n"); return NULL; } else { //实体相邻且只有一个交点 pLine = new AcDbPolyline; XLinePointAndBulge linePoint1,linePoint2,linePoint3; //通过给定的实体和点得到构成PLINE线的3点 //ent ent2 ptPick ptPick2 为选中的实体和点 ptInter1 为两实体交点 MakeSimplePloyLine(ent,ent2,ptPick,ptPick2,linePoint1,linePoint2,linePoint3,ptInter1); if (pLine != NULL) { pLine->addVertexAt(0,linePoint1.pt,linePoint1.dBulge); pLine->addVertexAt(1,linePoint2.pt,linePoint2.dBulge); pLine->addVertexAt(2,linePoint3.pt,linePoint3.dBulge); AssureInCurrentView(ptPick2, ptPick2); } return pLine; } } } else { if (ent.Is(_T("ATS_WALL")) && ent2.Is(_T("ATS_WALL"))) { if(!MakePolyLineByWall(pLine,ent,ent2,ptPick,ptPick2)){ delete pLine; return NULL; } return pLine; } else { BOOL bTrue3 = MakeRightPloyLine(pLine,ent,ent2,ptPick,ptPick2,ptTurn); if (!bTrue3) { delete pLine; return NULL; } } } } AssureInCurrentView(ptPick2, ptPick2); return pLine; } ///////////////////////////////////////////////////////////////////////////////////////////////////////// // 2008-2-25 谢真 ///////////////////////////////////////////////////////////////////////////////////////////////////////// //通过选中的一点和选中的实体生成PLINE线 BOOL GetOneSidePolyLine(Entity ent,XPoint ptPick,AcDbPolyline *pPolyLine,std::vector &vecPt,BOOL bFirst,BOOL &bHasNext) { if (pPolyLine == NULL) return FALSE; bHasNext = TRUE; BOOL bClosed = TRUE; //判断是否是闭合的 BOOL bFirstExt = TRUE; //是否是起点 XCurveSegment seg(ent); XPoint ptTemp1,ptTemp2;//取两点十字集范围内实体的两个点 XPoint ptFirst,ptNext,ptEnd,ptTurn; Entity entPointTemp1, entPointTemp2,entNext,entFirst; ptNext = ptPick; ptTurn = ptPick; entFirst = ent; if (ptPick == seg.StartPoint()) ptEnd = seg.EndPoint(); else ptEnd = seg.StartPoint(); ptFirst = ptEnd; AcDbObjectIdArray arIDFirst,arIDNext; AcDbObjectId idTemp; XLinePointAndBulge linePoint1,linePoint2,linePoint3; while (ptNext != ptEnd)//不断寻找下一段 { ptTemp1 = ptTurn; ptTemp2 = ptTurn; ptTemp1.x += 2; ptTemp1.y += 2; ptTemp2.x -= 2; ptTemp2.y -= 2; AssureInCurrentView(ptTemp1, ptTemp2); PickSet ssPoint(SS_FREE); ssPoint.Get(_T("C"),ptTemp1,ptTemp2, RBList(RTDXF0, _T("LINE,ARC"), NULL)); if(ssPoint.Length() != 2) { bClosed = FALSE; if (bFirstExt) bHasNext = FALSE; break; } entPointTemp1 = ssPoint[0L]; entPointTemp2 = ssPoint[1L]; //得到相邻下一段实体 if(entPointTemp1 == entFirst) entNext = entPointTemp2; else if(entPointTemp2 == entFirst) entNext = entPointTemp1; XCurveSegment segNext(entNext); if (segNext.StartPoint() == ptNext) ptNext = segNext.EndPoint(); else if (segNext.EndPoint() == ptNext) ptNext = segNext.StartPoint(); else { bClosed = FALSE; break; } if (bFirst) { //第一次寻找则存放实体 acdbGetObjectId(idTemp,entFirst.name); arIDFirst.append(idTemp); acdbGetObjectId(idTemp,entNext.name); arIDNext.append(idTemp); } else { //第二次则得到寻找的所有点 MakeSimplePloyLine(entFirst,entNext,ptFirst,ptNext,linePoint1,linePoint2,linePoint3,ptTurn); if (bFirstExt) { vecPt.push_back(linePoint1); bFirstExt = FALSE; } //存放拐点 vecPt.push_back(linePoint2); } entFirst = entNext; ptFirst = ptTurn; ptTurn = ptNext; } if (bFirst) { // 第一次执行 则将实体排序 int nSize = arIDFirst.length(); ads_name adTempName; Entity ent1,ent2; XPoint ptPick1,ptPick2,ptTurn; for (int i = nSize-1; i >= 0; --i) { acdbGetAdsName(adTempName,arIDFirst[i]); ent2 = adTempName; acdbGetAdsName(adTempName,arIDNext[i]); ent1 = adTempName; XCurveSegment seg(ent1); XCurveSegment seg2(ent2); //如果是相邻或同一线段求得转折点 if(seg.StartPoint() == seg2.StartPoint() || seg.StartPoint() == seg2.EndPoint()) { ptTurn = seg.StartPoint(); ptPick1 = seg.EndPoint(); if (ptTurn == seg2.StartPoint()) ptPick2 = seg2.EndPoint(); else ptPick2 = seg2.StartPoint(); } else if(seg.EndPoint() == seg2.StartPoint() || seg.EndPoint() == seg2.EndPoint()) { ptTurn = seg.EndPoint(); ptPick1 = seg.StartPoint(); if (ptTurn == seg2.StartPoint()) ptPick2 = seg2.EndPoint(); else ptPick2 = seg2.StartPoint(); } else return FALSE; MakeSimplePloyLine(ent1,ent2,ptPick1,ptPick2,linePoint1,linePoint2,linePoint3,ptTurn); //存放起点 if (bFirstExt) { vecPt.push_back(linePoint1); bFirstExt = FALSE; } //存放拐点 vecPt.push_back(linePoint2); } } else { //存放终点 if (bHasNext) vecPt.push_back(linePoint3); } //封闭的则需加入起点 if (bClosed) vecPt.push_back(vecPt[0]); return bClosed; } // 主函数 // 已知1段LINE或ARC, 返回它所连接所有的线段所组成的PLINE,可能是封闭,也可能不封闭。 // 所有线段必须首尾相连,且不分叉 // 传入:ent 所选取的LINE或ARC 返回:pPolyLine // 注意:PLINE指针由调用者自己在外面分配空间 void GetLoopPLineBySeg(Entity ent, AcDbPolyline *pPolyLine) { if (pPolyLine == NULL) return; std::vector vecPt; typedef std::vector::iterator iter; XCurveSegment seg(ent); BOOL bHasNext1,bHasNext2; if (!GetOneSidePolyLine(ent,seg.StartPoint(),pPolyLine,vecPt,TRUE,bHasNext1))//不是闭合的则需找另外一个方向 { GetOneSidePolyLine(ent,seg.EndPoint(),pPolyLine,vecPt,FALSE,bHasNext2); if (!bHasNext1 && !bHasNext2)//实体不连续 { if (ent.Is(_T("LINE"))) { pPolyLine->addVertexAt(0, seg.StartPoint()); pPolyLine->addVertexAt(1, seg.EndPoint()); } else { //圆弧 XArc arc(ent); AcGeVector3d vt1(seg.EndPoint()-arc.GetCenterPt()); AcGeVector3d vt2(seg.StartPoint()-arc.GetCenterPt()); double dAngle = vt1.angleTo(vt2); double dBulge = tan(0.25 * dAngle); // 要确定Bulge的正,负。 如果PLINE起点离弧起点近,Bulge为正 OPENOBJ_BEGIN(ent, AcDb::kForRead, AcDbCurve, pCurve); if(pCurve) { double dDist1(0), dDist2(0); pCurve->getDistAtPoint(seg.StartPoint(), dDist1); pCurve->getDistAtPoint(seg.EndPoint(), dDist2); if(dDist1 < dDist2) dBulge = fabs(dBulge); else dBulge = -fabs(dBulge); } OPENOBJ_END(); pPolyLine->addVertexAt(0, seg.StartPoint(), dBulge); pPolyLine->addVertexAt(1, seg.EndPoint()); } } } //生成PLINE线 for (int it = 0; it < vecPt.size(); ++it) { pPolyLine->addVertexAt(it,vecPt[it].pt,vecPt[it].dBulge); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 获得当前视口的左下角点右上角点 (UCS点) void GetCurrentViewExtent(XPoint &ptMin, XPoint &ptMax) { struct resbuf rb = {NULL, RT3DPOINT, 0}; acedGetVar(_T("VIEWCTR"), &rb); AcGePoint3d ptView = asPnt3d(rb.resval.rpoint); acedGetVar(_T("SCREENSIZE"), &rb); AcGePoint3d ptSize = asPnt3d(rb.resval.rpoint); double dXSize = ptSize.x; double dYSize = ptSize.y; dXSize = PixelToWcs(dXSize); dYSize = PixelToWcs(dYSize); ptMin.x = ptView.x - dXSize / 2; ptMin.y = ptView.y - dYSize / 2; ptMin.z = ptView.z; ptMax.x = ptView.x + dXSize / 2; ptMax.y = ptView.y + dYSize / 2; ptMax.z = ptView.z; } // 根据wcs下外包框的左下角点和右上角点,求得ucs下次外包框的左下角点和右上角点(返回值为ucs点) void GetUcsExtent(const XPoint &ptLow, const XPoint &ptUp, XPoint &ptNewLow, XPoint &ptNewUp) { XPoint pt1; // wcs下外包框的左上点 XPoint pt2; // wcs下外包框的右下点 pt1.x = ptLow.x; pt1.y = ptUp.y; pt1.z = ptLow.z; pt2.x = ptUp.x; pt2.y = ptLow.y; pt2.z = ptLow.z; AcDbExtents ext; ext.addPoint(Wcs2Ucs(pt1)); ext.addPoint(Wcs2Ucs(pt2)); ext.addPoint(Wcs2Ucs(ptLow)); ext.addPoint(Wcs2Ucs(ptUp)); ptNewLow = ext.minPoint(); ptNewUp = ext.maxPoint(); } Acad::ErrorStatus AssureInCurrentView_New(const XPoint &ptLow, const XPoint &ptUp) { // 当前视口的左下角点右上角点 XPoint lowCorner, upCorner; GetCurrentViewExtent(lowCorner, upCorner); // 根据ptLow, ptUp获得ucs下外包框的左下角点和右上角点 XPoint ptUcsLow, ptUcsUp; GetUcsExtent(ptLow, ptUp, ptUcsLow, ptUcsUp); ptUcsLow.z = ptUcsUp.z = lowCorner.z; // 求最大值点,最小值点 XPoint ptMin = Min(ptUcsLow, lowCorner); XPoint ptMax = Max(ptUcsUp, upCorner); if (ptMin != lowCorner || ptMax != upCorner) //点不在屏幕当前视图之内 { //2004下UCS, AssureInCurrentView运行特别慢 2009-8-12 sr BOOL bIsUcs = FALSE; XPoint ptUcsLow = Wcs2Ucs(ptLow); XPoint ptUcsUp = Wcs2Ucs(ptUp); if(ptUcsLow != ptLow && ptUcsUp != ptUp) bIsUcs = TRUE; double dd = g_nAcadVer; if(g_nAcadVer>15.1 && g_nAcadVer<16.01 && bIsUcs) // sr 2010-2-26 >15.0001 改为 >15.1 (ACAD2002是15.006) ads_command(RTSTR, _T("ZOOM"), RTSTR, _T("W"), RT3DPOINT, &ptUcsLow, RT3DPOINT, &ptUcsUp, RTNONE); else AssureInCurrentView(Ucs2Wcs(ptMin), Ucs2Wcs(ptMax)); } return Acad::eOk; }