// RemoveDupDlg.cpp : implementation file // #include "stdafx.h" #include "RemoveDupDlg.h" #include #include #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif //*************************************************************************************************** // 消重图块 //*************************************************************************************************** enum TYPE { kNull = -1, //不处理 kOther = 0, //线,弧,圆 kText = 1, //文本 kBlock = 2, //图块 kWall = 3, //墙 kColumn = 4, //柱子 kOpenning = 5, //门窗 kTSpace = 6, //房间 kEquipment = 7, //设备 kPipeBase = 8, //管道 }; class TEntityTmp { public: TEntityTmp(){}; TEntityTmp(Entity en) { m_nType = kNull; AcDbObjectId objId; Acad::ErrorStatus es = acdbGetObjectId(objId, en); if(es != Acad::eOk) return; AcDbObject* obj=NULL; es = acdbOpenObject(obj, objId, AcDb::kForRead); if(es != Acad::eOk) return; CString strClassName = obj->isA()->name(); obj->close(); if((_tcsicmp(strClassName,_T("AcDbLine")) == 0) ||(_tcsicmp(strClassName,_T("AcDbArc")) == 0) ||(_tcsicmp(strClassName,_T("AcDbCircle")) == 0)) //直线,弧,圆 { m_nType = kOther; } else if(_tcsicmp(strClassName,_T("TDbWall")) == 0 ||_tcsicmp(strClassName,_T("TDbCurtainWall")) == 0) //墙体和幕墙 { m_nType = kWall; } else if(_tcsicmp(strClassName,_T("TDbColumn")) == 0) //柱子 { m_nType = kColumn; } else if(_tcsicmp(strClassName,_T("TDbOpening")) == 0 ||_tcsicmp(strClassName,_T("TDbGroupOpening")) == 0)//门窗,组合门窗 { m_nType = kOpenning; } else if(_tcsicmp(strClassName,_T("TDbSpace")) == 0) //房间 { m_nType = kTSpace; } else if((_tcsicmp(strClassName,_T("TDbText")) == 0) ||(_tcsicmp(strClassName,_T("TDbMText")) == 0) ||(_tcsicmp(strClassName,_T("AcDbText")) == 0) ||(_tcsicmp(strClassName,_T("AcDbMText")) == 0)) //文本 { m_nType = kText; } else if((_tcsicmp(strClassName,_T("TDbBlockInsert")) == 0) ||(_tcsicmp(strClassName,_T("AcDbBlockReference")) == 0))//图块 { m_nType = kBlock; } else if((_tcsicmp(strClassName,_T("TDbEquipment")) == 0) ||(_tcsicmp(strClassName,_T("TDbWell")) == 0)) //设备 { m_nType = kEquipment; } else if((_tcsicmp(strClassName,_T("TDbECabletry")) == 0) ||(_tcsicmp(strClassName,_T("TDbEFitting")) == 0)) //管道 { m_nType = kPipeBase; } else { return; } m_eName = en; //获得2D下的包围盒 int nOldMode=DocGetDrawMode(); DocSetDrawMode(DRAW_2D); ads_point ptLow,ptUp; en.GetExtend(ptLow,ptUp); DocSetDrawMode(nOldMode); ptLow[2]=ptUp[2]=0; m_ptMin = ptLow; m_ptMax = ptUp; } int m_nType; Entity m_eName; XPoint m_ptMin,m_ptMax; bool operator >(const TEntityTmp& ent)const { if(m_nType == ent.m_nType) { if(m_ptMin == ent.m_ptMin) { if(m_ptMax == ent.m_ptMax) { return false; } return m_ptMax > ent.m_ptMax; } return m_ptMin > ent.m_ptMin; } return m_nType > ent.m_nType; } bool operator <(const TEntityTmp& ent)const{return ent>(*this);} bool operator==(const TEntityTmp& ent) { if((m_nType == ent.m_nType)) { switch(m_nType) { case kText: return CompareText(ent); break; case kBlock: return CompareBlock(ent); break; case kWall: return CompareWall(ent); break; case kColumn: return CompareColumn(ent); break; case kOpenning: return CompareOpening(ent); break; case kTSpace: return CompareSpace(ent); break; case kEquipment: return CompareBlock(ent); break; case kPipeBase: return ComparePipeBase(ent); break; } return true; } return false; } //两段XPoly2D线是否相交 bool IsIntersect(XPoly2D &poly1,XPoly2D &poly2) { DList lstDest; if(Intersect(poly1,poly2,lstDest) == RTNORM) { if(lstDest.Length()!= 0) // 有交点 { double area=0.0; // 相交区域面积 for(int i=0;iPathArea()); } if(area > _DIST_SNAP*_DIST_SNAP)//相交精度控制 { return true; } } } return false; } //由点ptMin,ptMax构成的XPoly2D和由点ptMin2,ptMax2构成的XPoly2D是否相交 bool IsIntersect(XPoint ptMin,XPoint ptMax,XPoint ptMin2,XPoint ptMax2) { XPoly2D poly1(1),poly2(1); poly1.AppendNode(ptMin); poly1.AppendNode(XPoint(ptMin[0],ptMax[1])); poly1.AppendNode(ptMax); poly1.AppendNode(XPoint(ptMax[0],ptMin[1])); poly2.AppendNode(ptMin2); poly2.AppendNode(XPoint(ptMin2[0],ptMax2[1])); poly2.AppendNode(ptMax2); poly2.AppendNode(XPoint(ptMax2[0],ptMin2[1])); return IsIntersect(poly1,poly2); } //是否在控制精度范围内存在相同点 bool IsPointEqual(AcGePoint3d ptStart1,AcGePoint3d ptEnd1,AcGePoint3d ptStart2,AcGePoint3d ptEnd2) { ptStart1.z=0; ptEnd1.z=0; ptStart2.z=0; ptEnd2.z=0; if((ptStart1.distanceTo(ptStart2)StartPoint(); ptEnd1=pWall->EndPoint(); bIsArc1 = pWall->Is(CURVE_ARC); if(bIsArc1) { ptCenter1=pWall->GetArc().GetCenterPt(); } else { vect1=pWall->Direction3d(); } } OPENOBJ_END(); OPENOBJ_BEGIN(ent.m_eName,AcDb::kForRead,TDbWall,pWall); if(pWall) { ptStart2=pWall->StartPoint(); ptEnd2=pWall->EndPoint(); bIsArc2 = pWall->Is(CURVE_ARC); if(bIsArc2) { ptCenter2=pWall->GetArc().GetCenterPt(); } else { vect2=pWall->GetLine().Direction3d(); } } OPENOBJ_END(); BOOL bParallel=FALSE; if(!bIsArc1&&!bIsArc2) { if(vect1.isParallelTo(vect2)) bParallel=TRUE; } else if(bIsArc1&&bIsArc2) { if(ptCenter1.Distance2d(ptCenter2)<_DIST_SNAP) bParallel=TRUE; } if(bParallel) { XLine line1(ptStart1,ptEnd1,LS_FINITE),line2(ptStart2,ptEnd2,LS_FINITE); ads_point pts; int num=line1.Intersection(&line2,pts); if((line1.HitTest2d(XPoint(ptStart2))==3&&line1.HitTest2d(XPoint(ptEnd2))==4) ||(line1.HitTest2d(XPoint(ptStart2))==4&&line1.HitTest2d(XPoint(ptEnd2))==3))//完全重合 { return true; } else if(line1.HitTest2d(XPoint(ptStart2))==3 ||line1.HitTest2d(XPoint(ptEnd2))==4 ||line1.HitTest2d(XPoint(ptStart2))==4 ||line1.HitTest2d(XPoint(ptEnd2))==3) //基线有唯一一个相同顶点 { return false; } else if(line1.HitTest2d(XPoint(ptStart2))==5 ||line1.HitTest2d(XPoint(ptEnd2))==5 ||line2.HitTest2d(XPoint(ptStart1))==5 ||line2.HitTest2d(XPoint(ptEnd1))==5)//基线有部分重合 return true; else if(num!=NULL)//弧墙基线有重合 { return true; } } } //if(IsIntersect(m_ptMin,m_ptMax,ent.m_ptMin,ent.m_ptMax)) // 两段墙包围盒是否相交 if(bIntersect) { AcDbCurve *pCurve1=NULL,*pCurve2=NULL; // 墙体的基线 XPoly2D poly1,poly2; // 墙体截面 double elev1(0),elev2(0),height1(0),height2(0); // 墙体标高,高度 AcGePoint3d ptStart1,ptEnd1,ptStart2,ptEnd2; // 墙体起始点 BOOL bIsArc1,bIsArc2; //是否弧墙 XPoint ptCenter1,ptCenter2; AcGeVector3d vect1,vect2; AcDbObjectId idS1,idE1,idS2,idE2; OPENOBJ_BEGIN(m_eName,AcDb::kForRead,TDbWall,pWall); if(pWall) { pWall->GetOutlinePoly(0,poly1,TRUE); elev1 = pWall->GetElevation(); height1=pWall->GetHeight(); pCurve1=pWall->GetAcDbCurve(0); pWall->getStartPoint(ptStart1); pWall->getEndPoint(ptEnd1); bIsArc1 = pWall->Is(CURVE_ARC); if(bIsArc1) { ptCenter1=pWall->GetArc().GetCenterPt(); } else { vect1=pWall->Direction3d(); } } OPENOBJ_END(); OPENOBJ_BEGIN(ent.m_eName,AcDb::kForRead,TDbWall,pWall); if(pWall) { pWall->GetOutlinePoly(0,poly2,TRUE); elev2 = pWall->GetElevation(); height2=pWall->GetHeight(); pCurve2=pWall->GetAcDbCurve(0); pWall->getStartPoint(ptStart2); pWall->getEndPoint(ptEnd2); bIsArc2 = pWall->Is(CURVE_ARC); if(bIsArc2) { ptCenter2=pWall->GetArc().GetCenterPt(); } else { vect2=pWall->Direction3d(); } } OPENOBJ_END(); BOOL flag=FALSE; //基线是否相交标志 if(pCurve1 && pCurve2) { AcGePoint3dArray points; pCurve1->intersectWith(pCurve2,AcDb::kOnBothOperands,AcGePlane(AcGePoint3d(0,0,0),AcGeVector3d::kZAxis),points); if(points.length() == 1) { flag=TRUE; } } if(pCurve1) { delete pCurve1; } if(pCurve2) { delete pCurve2; } if(IsIntersect(poly1,poly2)) //墙体截面是否相交 { if(flag && IsPointEqual(ptStart1,ptEnd1,ptStart2,ptEnd2)) return false; //add by xlc on 090424 else { XLine line1((XPoint)ptStart1,(XPoint)ptEnd1,LS_FINITE),line2((XPoint)ptStart2,(XPoint)ptEnd2,LS_FINITE); ads_point pts; int num=line1.Intersection(&line2,pts); if((line1.HitTest2d(XPoint(ptStart2))==3&&line1.HitTest2d(XPoint(ptEnd2))==4) ||(line1.HitTest2d(XPoint(ptStart2))==4&&line1.HitTest2d(XPoint(ptEnd2))==3))//完全重合 { return true; } else if((line1.HitTest2d(XPoint(ptStart2))==3 ||line1.HitTest2d(XPoint(ptEnd2))==4 ||line1.HitTest2d(XPoint(ptStart2))==4 ||line1.HitTest2d(XPoint(ptEnd2))==3) &&(!(line1.HitTest2d(XPoint(ptStart2))==5 ||line1.HitTest2d(XPoint(ptEnd2))==5 ||line2.HitTest2d(XPoint(ptStart1))==5 ||line2.HitTest2d(XPoint(ptEnd1))==5))) //基线有唯一一个相同顶点 { return false; } } } else { BOOL bParallel=FALSE; if(!bIsArc1&&!bIsArc2) { if(vect1.isParallelTo(vect2)) bParallel=TRUE; } else if(bIsArc1&&bIsArc2) { if(ptCenter1.Distance2d(ptCenter2)<_DIST_SNAP) bParallel=TRUE; } if(bParallel) { XLine line1(XPoint(ptStart1.x,ptStart1.y,ptStart1.z),XPoint(ptEnd1.x,ptEnd1.y,ptEnd1.z),LS_FINITE); XLine line2(XPoint(ptStart2.x,ptStart2.y,ptStart2.z),XPoint(ptEnd2.x,ptEnd2.y,ptEnd2.z),LS_FINITE); ads_point pts; int num=line1.Intersection(&line2,pts); //modify by xlc on 090120 消除弧墙有唯一顶点相同时的影响 // if(num!=NULL)//弧墙基线有重合 // { // return true; // } // else // { // if(line1.HitTest2d(XPoint(ptStart2))==5 // ||line1.HitTest2d(XPoint(ptEnd2))==5 // ||line2.HitTest2d(XPoint(ptStart1))==5 // ||line2.HitTest2d(XPoint(ptEnd1))==5)//基线有部分重合 // return true; // else if((line1.HitTest2d(XPoint(ptStart2))==3&&line1.HitTest2d(XPoint(ptEnd2))==4) // ||(line1.HitTest2d(XPoint(ptStart2))==4&&line1.HitTest2d(XPoint(ptEnd2))==3))//完全重合 // { // return true; // } // } if((line1.HitTest2d(XPoint(ptStart2))==3&&line1.HitTest2d(XPoint(ptEnd2))==4) ||(line1.HitTest2d(XPoint(ptStart2))==4&&line1.HitTest2d(XPoint(ptEnd2))==3))//完全重合 { return true; } else if(line1.HitTest2d(XPoint(ptStart2))==3 ||line1.HitTest2d(XPoint(ptEnd2))==4 ||line1.HitTest2d(XPoint(ptStart2))==4 ||line1.HitTest2d(XPoint(ptEnd2))==3) //基线有唯一一个相同顶点 { return false; } else if(line1.HitTest2d(XPoint(ptStart2))==5 ||line1.HitTest2d(XPoint(ptEnd2))==5 ||line2.HitTest2d(XPoint(ptStart1))==5 ||line2.HitTest2d(XPoint(ptEnd1))==5)//基线有部分重合 return true; else if(num!=NULL)//弧墙基线有重合 { return true; } } } } return false; } // 比较文本是否重合 bool CompareText(const TEntityTmp &ent) { if(m_ptMin == ent.m_ptMin) { if(m_ptMax == ent.m_ptMax) { CString strText=GetTextContent(m_eName), strTextEnt=GetTextContent(ent.m_eName); //if(_tcsicmp(strText,strTextEnt) == 0) if(strText==strTextEnt) { return true; } } } return false; } // 获得文本内容 CString GetTextContent(Entity en) { CString strText(_T("")); OPENOBJ_BEGIN(en, AcDb::kForRead, AcDbEntity, pText); if(pText) { if(pText->isKindOf(AcDbText::desc())) { TCHAR *str=((AcDbText *)pText)->textString(); strText.Format(_T("%s"),((AcDbText *)pText)->textString()); free(str); } else if(pText->isKindOf(AcDbMText::desc())) { TCHAR *str=((AcDbMText *)pText)->contents(); strText.Format(_T("%s"),str); free(str); } else strText.Format(_T("%s"),((TDbText *)pText)->GetText()); } OPENOBJ_END(); return strText; } // 比较桥架是否重合 bool ComparePipeBase(TEntityTmp ent) { if(m_ptMin == ent.m_ptMin) { if(m_ptMax == ent.m_ptMax) { return true; } } return false; } // 比较图块是否重合 bool CompareBlock(TEntityTmp ent) { if(m_ptMin == ent.m_ptMin) { if(m_ptMax == ent.m_ptMax) { CString strName=GetBlockName(m_eName), strNameEnt=GetBlockName(ent.m_eName); if(strName.CompareNoCase(strNameEnt) == 0) { return true; } } } return false; } // 获得图块名 CString GetBlockName(Entity ent) { CString strText(_T("")); AcDbObjectId id = NULL; if(ent.Is(_T("INSERT"))) { OPENOBJ_BEGIN(ent,AcDb::kForRead, AcDbBlockReference, pBlk); if (pBlk) { id = pBlk->blockTableRecord(); } OPENOBJ_END(); } else if(ent.Is(_T("ATS_EQUIPMENT"))) { OPENOBJ_BEGIN(ent,AcDb::kForRead, TDbEquipment, pBlk); if (pBlk) { id = pBlk->GetBlock2d(); } OPENOBJ_END(); } else if(ent.Is(_T("ATS_WELL"))) { OPENOBJ_BEGIN(ent,AcDb::kForRead, TDbWell, pBlk); if (pBlk) { id = pBlk->GetBlock2d(); } OPENOBJ_END(); } strText = (const TCHAR*)GetSymbolName(id); // OPENOBJ_BEGIN(ent,AcDb::kForRead,AcDbBlockTableRecord,pBlkTblRec); // if (pBlkTblRec) // { // TCHAR *pchName=NULL; // 块名 // pBlkTblRec->getName(pchName); // 得到块名 // strText.Format(_T("%s"),pchName); // acutDelString(pchName); // } // OPENOBJ_END(); return strText; } // 比较房间是否重叠 bool CompareSpace(TEntityTmp ent) { //add by xlc on 090526 BOOL bSpace=FALSE; //是否房间类型 XPoly2D poly1,poly2; OPENOBJ_BEGIN(m_eName,AcDb::kForRead,TDbSpace,pSpace); if(pSpace) { AcGeVector3d normal; pSpace->GetPathPoly(poly1,normal); //add by xlc on 090526 if(!(pSpace->m_nType==TDbSpace::kHouseArea ||pSpace->m_nType==TDbSpace::kTotalArea) ) { bSpace=TRUE; } } OPENOBJ_END(); OPENOBJ_BEGIN(ent.m_eName,AcDb::kForRead,TDbSpace,pSpace); if(pSpace) { AcGeVector3d normal; pSpace->GetPathPoly(poly2,normal); //add by xlc on 090526 if(bSpace &&(pSpace->m_nType==TDbSpace::kHouseArea ||pSpace->m_nType==TDbSpace::kTotalArea) ) { bSpace=FALSE; } } OPENOBJ_END(); if(bSpace) return IsIntersect(poly1,poly2); else return false; } // 比较柱子是否重叠 bool CompareColumn(TEntityTmp ent) { if(IsIntersect(m_ptMin,m_ptMax,ent.m_ptMin,ent.m_ptMax)) { XPoly2D poly1,poly2; OPENOBJ_BEGIN(m_eName,AcDb::kForRead,TDbColumn,pColumn); if(pColumn) { pColumn->GetOutline(poly1); } OPENOBJ_END(); OPENOBJ_BEGIN(ent.m_eName,AcDb::kForRead,TDbColumn,pColumn); if(pColumn) { pColumn->GetOutline(poly2); } OPENOBJ_END(); return IsIntersect(poly1,poly2); } return false; } // 比较门窗是否重叠 bool CompareOpening(TEntityTmp ent) { if(IsIntersect(m_ptMin,m_ptMax,ent.m_ptMin,ent.m_ptMax)) { XPoly2D poly1,poly2; double elev1(0),elev2(0),height1(0),height2(0); OPENOBJ_BEGIN(m_eName,AcDb::kForRead,TDbOpening,pOpening); if(pOpening) { pOpening->GetOutlinePoly(0,poly1); elev1 = pOpening->GetSill(); height1=pOpening->GetHeight(); } OPENOBJ_END(); OPENOBJ_BEGIN(ent.m_eName,AcDb::kForRead,TDbOpening,pOpening1); if(pOpening1) { pOpening1->GetOutlinePoly(0,poly2); elev2 = pOpening1->GetSill(); height2=pOpening1->GetHeight(); } OPENOBJ_END(); if(IsIntersect(poly1,poly2)) { // 考虑高窗 if(elev1elev2) { return true; } } else if(elev1>elev2) { if(elev1SetFocus(); PickSet ss(SS_FREE); CString strType = dlg.GetEntType(); RBList rbMask(RTDXF0, strType, NULL); if(SelectEntities(_T("\n请选择要消除重复的图块<整张图>:"), ss, rbMask) != RTNORM) { ss.Get(_T("X"), NULL, NULL, rbMask); } dlg.UpdateData(); CArray m_blockArray; //图块数组 CArray m_textArray; //文本数组 CArray m_equipmentArray; //设备数组 CArray m_pipeArray; //桥架数组 PickSet ssOther(SS_FREE); for(long i=0L;ierase(); m_textArray.RemoveAt(j); j--; nCount++; } OPENOBJ_END(); } } } if(nCount==0) { adsout<<_T("\n没有发现重合的文本对象!"); } else { adsout<<_T("\n删除")<erase(); m_blockArray.RemoveAt(j); j--; nCount++; } OPENOBJ_END(); } } } if(nCount==0) { adsout<<_T("\n没有发现重合的图块!"); } else { adsout<<_T("\n删除")<erase(); m_equipmentArray.RemoveAt(j); j--; nCount++; } OPENOBJ_END(); } } } if(nCount==0) { adsout<<_T("\n没有发现重合的设备!"); } else { adsout<<_T("\n删除")<erase(); m_pipeArray.RemoveAt(j); j--; nCount++; } OPENOBJ_END(); } } } if(nCount==0) { adsout<<_T("\n没有发现重合的桥架!"); } else { adsout<<_T("\n删除")<