// XdRdupCurve.cpp: implementation of the XdRdupCurve class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" //#include "xdrx_lib.h" #include "XdRdupCurve.h" //extern "C" const char* acadErrorStatusText(Acad::ErrorStatus); ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// XdRdupCurve::XdRdupCurve() { m_tol.setEqualPoint(_DIST_SNAP); m_tol.setEqualVector(_DIST_SNAP); m_slength=_DIST_SNAP; //100; m_shortLineNum=0; m_shortArcNum=0; m_delLineNum=0; m_delArcNum=0; m_delCirNum=0; m_pbarinterval=0; } XdRdupCurve::~XdRdupCurve() { } int XdRdupCurve::FindNode(double key,DList &lstNewCurves) { int len=lstNewCurves.Length(); if (!len) return -1; for (int i=0;ikey-key)<1e-5) { return i; } } return -1; } int compareDList(const XdRdupLineNode *p1, const XdRdupLineNode *p2) { ads_real v1, v2; int no=0; v1=p1->key; v2=p2->key; if (fabs(v1-v2)<1e-5) no=0; else if (v1>v2) no=1; else no=-1; return(no); } double XdRdupCurve::distanceOfPtToLine(AcGePoint3d pt,AcGePoint3d sPt,AcGePoint3d ePt) { double c1,c2,c3; c1=ePt.y-sPt.y; c2=sPt.x-ePt.x; c3=sqrt(c1*c1+c2*c2); c1=c1/c3; c2=c2/c3; c3=(ePt.x*sPt.y-sPt.x*ePt.y)/c3; return ((c1*pt[X])+(c2*pt[Y])+c3); } void XdRdupCurve::getMinPoint(AcDbObjectIdArray *ids,AcGePoint3d &minPt) { AcGePoint3d temp1; minPt.set(1e100,1e100,0); AcDbLine *pEnt; for (int i=0;ilength();i++) { if (Acad::eOk!=acdbOpenObject(pEnt,ids->at(i),AcDb::kForRead)) continue; temp1=pEnt->startPoint(); if (temp1.xendPoint(); if (temp1.xclose(); } return; } BOOL XdRdupCurve::makeArrayByAngle(PickSet &ss,DList &lstNewCurves,PickSet &ssArc,PickSet &ssCir) { AcGePoint3d sPt,ePt; AcDbObjectId entId; AcDbEntity *pEnt; AcDbLine * pLine; double angle; long len=ss.Length(); if (!len) return FALSE; int nBar=0; if (m_pbarinterval) acedSetStatusBarProgressMeter(_T("搜索曲线中..."),0,(int)len/m_pbarinterval); for (long i=0;iclose(); continue; } sPt=pLine->startPoint(); ePt=pLine->endPoint(); if (sPt.distanceTo(ePt)<=m_slength)//超短线,删除 { m_shortLineNum++; if (Acad::eOk==pLine->upgradeOpen()) { pLine->erase(); } pLine->close(); continue; } pLine->close(); angle=ads_angle(asDblArray(sPt),asDblArray(ePt)); angle=(angle=0) { (*lstNewCurves[pos]).entArray.append(entId); } else { node->key=key; node->entArray.append(entId); lstNewCurves.Append(node); } }//循环后,将角度相同的实体放入同一个表中 if (m_pbarinterval) acedRestoreStatusBar(); return (lstNewCurves.Length())?TRUE:FALSE; } void XdRdupCurve::setEqualPoint(double tol) { m_tol.setEqualPoint(fabs(tol)); return; } void XdRdupCurve::setEqualVector(double tol) { m_tol.setEqualVector(fabs(tol)); return; } void XdRdupCurve::setShortLineLength(double shortLine) { m_slength=fabs(shortLine); return; } void XdRdupCurve::setProgressBarInterval(int interval) { m_pbarinterval=abs(interval); return; } /* 消除重线 1:对于一条直线包含很多重线,则删除这些重线,保留最长的线 2:若连接两条线,修改前一线的终点,任何时候本程序都不新生成LINE 3:没有重线,不修改LINE的属性,保留原来的LINE */ void XdRdupCurve::removeDupCurve(PickSet &ss) { long len = ss.Length(); if (!len) return ; DList lstNewCurves; m_shortLineNum=m_delLineNum=0; PickSet ssArc(SS_FREE),ssCir(SS_FREE); makeArrayByAngle(ss,lstNewCurves,ssArc,ssCir); XdRdupLineNode * trval; AcGePoint3d sPt,ePt,sPt1,ePt1; double dist,dist1,dist2; TCHAR dis[200]; AcDbLine *pLine; AcDbObjectId entId,entId1; AcDbObjectIdArray *pId; int nMaxLen=lstNewCurves.Length(); int nBar=0; if (m_pbarinterval) acedSetStatusBarProgressMeter(_T("处理中..."),0,nMaxLen); for (int i=0;ientArray); len=pId->length(); if (len<2) continue;//ID数目小于2,没有重线,略过... entId=pId->at(0); if (Acad::eOk!=acdbOpenObject(pLine,entId,AcDb::kForRead)) continue; sPt=pLine->startPoint(); ePt=pLine->endPoint(); pLine->close(); DList lstNewCurves1; for (int j=0;jat(j); if (Acad::eOk!=acdbOpenObject(pLine,entId,AcDb::kForRead)) continue; dist=distanceOfPtToLine(pLine->startPoint(),sPt,ePt); pLine->close(); ads_rtos(dist,2,3,dis); dist=_tstof(dis); XdRdupLineNode * node=new XdRdupLineNode; int pos=FindNode(dist,lstNewCurves1); if (pos>=0) { (*lstNewCurves1[pos]).entArray.append(entId); } else { node->key=dist; node->entArray.append(entId); lstNewCurves1.Append(node); } }//循环后,将同角度表中实体距离第一条直线距离相同的的实体放入相同的表中 for (j=0;jentArray); double angle=trval->key; len=pId->length(); AcGePoint3d minPt; getMinPoint(pId,minPt); DList lstNewCurves2; for (int k=0;kat(k); if (Acad::eOk!=acdbOpenObject(pLine,entId,AcDb::kForRead)) continue; AcGePoint3d sPt1(pLine->startPoint()), ePt1(pLine->endPoint()); pLine->close(); dist1=sPt1.distanceTo(minPt); dist2=ePt1.distanceTo(minPt); dist=(dist2key=dist; node->entArray.append(entId); lstNewCurves2.Append(node); }//循环后,将距离相同的线的起始点到垂直于第一条线的起始点的线的距离构建表 //对上表按距离排升序 lstNewCurves2.QuickSort(compareDList); int length=lstNewCurves2.Length(); AcDbObjectIdArray delArray; AcDbVoidPtrArray newLineArray; for (k=0;kentArray); entId=pId->at(0); if (Acad::eOk!=acdbOpenObject(pLine,entId,AcDb::kForRead)) continue; sPt=pLine->startPoint(); ePt=pLine->endPoint(); AcGeLineSeg3d gFirst(sPt,ePt); dist1=sPt.distanceTo(minPt); dist2=ePt.distanceTo(minPt); if (dist2entArray); entId1=pId->at(0); AcDbLine *pLine1; if (Acad::eOk!=acdbOpenObject(pLine1,entId1,AcDb::kForRead)) continue; sPt1=pLine1->startPoint(); ePt1=pLine1->endPoint(); pLine1->close(); dist1=sPt1.distanceTo(minPt); dist2=ePt1.distanceTo(minPt); if (dist2upgradeOpen()==Acad::eOk) { if (pLine->startPoint()==sPt) { pLine->setEndPoint(ePt); } else if (pLine->endPoint()==sPt) pLine->setStartPoint(ePt); } else ASSERT(0); } pLine->close(); } if (!delArray.isEmpty()) { for (int i=0;ierase(); pLine->close(); } } }//循环后,角度相同距离相同的线,重线处理完闭 } if (m_pbarinterval) acedRestoreStatusBar(); removeDupArc(ssArc); removeDupCircle(ssCir); //ssArc.Free(); //ssCir.Free(); return; } void XdRdupCurve::removeDupCircle(PickSet &ss) { AcDbObjectId entId; AcDbCircle * pCir; long nMaxLen=ss.Length(); if (!nMaxLen) return; DList lstCircle; AcGePoint3d center; double radius; AcGeCircArc3d gCircle; int nBar=0; if (m_pbarinterval) acedSetStatusBarProgressMeter(_T("搜索圆中..."),0,(int)nMaxLen/m_pbarinterval); m_delCirNum=0; for (long i=0;icenter(); radius=pCir->radius(); if (FindNode(lstCircle,center,radius)>=0) { if (pCir->upgradeOpen()==Acad::eOk) { m_delCirNum++; pCir->erase(); } } else { XdRdupCircArcNode *node=new XdRdupCircArcNode; node->center=center; node->radius=radius; lstCircle.Append(node); } pCir->close(); } if (m_pbarinterval) acedRestoreStatusBar(); return; } int XdRdupCurve::FindNode(DList &lstCircle,AcGePoint3d center,double radius) { int len=lstCircle.Length(); if (!len) return -1; for (int i=0;icenter,m_tol))&& (fabs(radius-lstCircle[i]->radius) &lstArc) { long nMaxLen=ss.Length(); if (!nMaxLen) return FALSE; AcDbObjectId entId; AcDbArc * pArc; int nBar=0; if (m_pbarinterval) acedSetStatusBarProgressMeter(_T("搜索圆弧..."),0,(int)nMaxLen/m_pbarinterval); AcGePoint3d center; double radius,sAng,eAng; m_delArcNum=m_shortArcNum=0; AcGePoint3d sPt,ePt; for (long i=0;igetEndParam(eParam); if (pArc->getDistAtParam(eParam,len)==Acad::eOk) { if (lenupgradeOpen()==Acad::eOk) { pArc->erase(); m_shortArcNum++; } pArc->close(); continue; } } center=pArc->center(); radius=pArc->radius(); sAng=pArc->startAngle(); eAng=pArc->endAngle(); pArc->close(); int pos=FindNode(lstArc,center,radius); if (pos>=0) { (*lstArc[pos]).arcIdArray.append(entId); } else { XdRdupCircArcNode *node=new XdRdupCircArcNode; node->center=center; node->radius=radius; node->arcIdArray.append(entId); lstArc.Append(node); } } if (m_pbarinterval) acedRestoreStatusBar(); return (lstArc.Length())?TRUE:FALSE; } void XdRdupCurve::removeDupArc(PickSet &ss) { if (!ss.Length()) return; DList lstArc; m_delArcNum=m_shortArcNum=0; if (!makeArrayByCenterRadius(ss,lstArc)) return; int len=lstArc.Length(); AcDbObjectIdArray *pId; XdRdupCircArcNode * trval; AcDbObjectId entId1,entId2; AcDbArc *pArc1,*pArc2; int nBar=0; if (m_pbarinterval) acedSetStatusBarProgressMeter(_T("处理圆弧中..."),0,len); for (int i=0;iarcIdArray; DList lstSortArc; for (int j=0;jlength();j++) { entId1=pId->at(j); if (Acad::eOk!=acdbOpenObject(pArc1,entId1,AcDb::kForRead)) continue; double key=pArc1->startAngle(); pArc1->close(); XdRdupLineNode *node=new XdRdupLineNode; node->key=key; node->entArray.append(entId1); lstSortArc.Append(node); } lstSortArc.QuickSort(compareDList); AcDbObjectIdArray delArray; int len1=lstSortArc.Length(); AcDbObjectId lastId,firstId; for (j=0;jentArray; AcDbObjectId entId1=pId->at(0); if (!j) firstId=entId1; lastId=entId1; AcDbArc *pArc1; if (acdbOpenObject(pArc1,entId1,AcDb::kForRead)!=Acad::eOk) continue; double sParam1,eParam1; AcGeCircArc3d gArc1; pArc1->getStartParam(sParam1); gArc1.setAngles(pArc1->startAngle(),pArc1->endAngle()); gArc1.setCenter(pArc1->center()); gArc1.setRadius(pArc1->radius()); double lenArc1; pArc1->getEndParam(eParam1); pArc1->getDistAtParam(eParam1,lenArc1); double eAng1=pArc1->endAngle(), sAng1=pArc1->startAngle(); BOOL modifyFlag=FALSE; for (int k=j+1;kentArray; AcDbObjectId entId2=pId->at(0); AcDbArc *pArc2; if (acdbOpenObject(pArc2,entId2,AcDb::kForRead)!=Acad::eOk) continue; AcGePoint3d sPt,ePt; pArc2->getStartPoint(sPt); pArc2->getEndPoint(ePt); double eParam2,lenArc2; pArc2->getEndParam(eParam2); pArc2->getDistAtParam(eParam2,lenArc2); double sAng2,eAng2; sAng2=pArc2->startAngle(); eAng2=pArc2->endAngle(); pArc2->close(); if ((gArc1.startPoint()==sPt)&&(gArc1.endPoint()==ePt)) //完全重合 { delArray.append(entId2); j=k; } else if (gArc1.isOn(sPt,m_tol)) //起点在,头链接 { j=k; delArray.append(entId2); if (gArc1.isOn(ePt,m_tol))// 组成园 { double sParam=gArc1.paramOf(sPt,m_tol), eParam=gArc1.paramOf(ePt,m_tol); if (eParamupgradeOpen()==Acad::eOk) { if (fabs(eAng1-sAng1-2*PI)<1e-5) eAng1=eAng1-PI/1800; pArc1->setStartAngle(sAng1); pArc1->setEndAngle(eAng1); } } pArc1->close(); } if (!delArray.isEmpty()) { m_delArcNum+=delArray.length(); //计数器增加 //XdDbUtils::deleteArray(&delArray); int nDelNum=delArray.length(); for(int nIdx=0; nIdxerase(); OPENOBJ_END(); } } if (lastId!=firstId) { if (acdbOpenObject(pArc1,lastId,AcDb::kForRead)==Acad::eOk) { if (acdbOpenObject(pArc2,firstId,AcDb::kForRead)==Acad::eOk) { AcGePoint3d sPt,ePt; pArc1->getEndPoint(ePt); AcGeCircArc3d gArc; gArc.setAngles(pArc2->startAngle(),pArc2->endAngle()); gArc.setRadius(pArc2->radius()); gArc.setCenter(pArc2->center()); if (gArc.isOn(ePt,m_tol)) { if (pArc2->upgradeOpen()==Acad::eOk) { pArc2->setStartAngle(pArc1->startAngle()); pArc2->downgradeOpen(); if (pArc1->upgradeOpen()==Acad::eOk) { m_delArcNum++; pArc1->erase(); } } } pArc2->close(); } pArc1->close(); } } } if (m_pbarinterval) acedRestoreStatusBar(); return; } // 2010-3-15 17:55 wubo // 和Geo库的类重名 //class XRemoveDupEntByLayer { //public: // XString m_sLayer; // PickSet m_ss; //public: // XRemoveDupEntByLayer(const TCHAR *pLayer):m_sLayer(pLayer), m_ss(SS_FREE) // {} // static int CompareForFindByLayer(const XRemoveDupEntByLayer *p1, const void *p2); //}; // //int XRemoveDupEntByLayer::CompareForFindByLayer(const XRemoveDupEntByLayer *p1, const void *p2) //{ // const TCHAR *pp2=(const TCHAR *)p2; // return _tcsicmp(p1->m_sLayer, pp2); //} void xdRemoveDup() { DList lstRemoveDup; PickSet ss(SS_FREE); if (ss.Get(NULL, NULL, NULL, RBList(RTDXF0, _T("LINE,ARC,CIRCLE"), NULL))==RTNORM) { long lCount=ss.Length(); for(long i=0L;im_ss += ent; } else { pData=new XRemoveDupEntByLayer(sLayer); pData->m_ss += ent; lstRemoveDup.Append(pData); } } for(int n=0; nm_sLayer << _T("消除重线: "); long nOldNum=pData->m_ss.Length(); XdRdupCurve rmdup; rmdup.removeDupCurve(pData->m_ss); adsout << _T("由") << int(nOldNum) << _T("变为") << (int)(nOldNum-rmdup.m_delArcNum-rmdup.m_delCirNum-rmdup.m_delLineNum -rmdup.m_shortArcNum-rmdup.m_shortLineNum) << _T("; 包括删除其中") << int(rmdup.m_shortArcNum+rmdup.m_shortLineNum) << _T("根短线!"); } } }