#include "StdAfx.h" #include "frame.h" #include "OpeningLabelData.h" #include "OpeningCheck.h" //#include "SetWinLab.h" namespace NDoorWinCheck { extern CDoorWinFrame *pFrame; static CString strDoorTypeName[eDoorTypeNum] = { _T("门"), _T("门连窗"), _T("子母门"), _T("组合门窗"), _T("窗"), _T("弧窗"), _T("凸窗"), _T("转角窗"), _T("带形窗"), _T("老虎窗"), _T("洞口") }; static CString strDoorTyeHead[eDoorTypeNum] = { _T("M"), _T("MC"), _T("ZM"), _T("ZM"), _T("C"), _T("HC"), _T("TC"), _T("ZJC"), _T("DC"), _T("LHC"), _T("DK") }; static CString s_strParaName[eDoorWinParmNum] = { _T("编号"), _T("新编号"), _T("类型"), _T("宽度"), _T("高度"), _T("底高"), _T("型式"), _T("出挑长"), _T("梯形宽") }; static EShowItem s_showItem[eDoorWinParmNum] = { eLabelProp, eNewLabelProp, eTypeProp, eWidProp, eHeiProp, eEle, eGeoTypeProp, eChutiaoProp, eTixingkuanProp }; #ifndef NDEBUG static DWORD dwtime = 0; static DWORD dwRead = 0; static DWORD dwRead1 = 0; static DWORD dwRead2 = 0; static DWORD dwRead3 = 0; #endif EShowItem GetShowItem(EShowItem eShowIndex) { ASSERT(eShowIndex < eDoorWinParmNum); return s_showItem[eShowIndex]; } EShowItem ShowItem2Index(EShowItem eShowItem) { for (int i = 0; i < eDoorWinParmNum; i++) { if (GetShowItem(EShowItem(i)) == eShowItem) return EShowItem(i); } return eLabelIndex;// 这里不能走到 } CString ParamTypeToString(EShowItem eShowItem) { return s_strParaName[ShowItem2Index(eShowItem)]; } BOOL IsTextShowItem(EShowItem eItem) { return eItem == eLabelProp || eItem == eNewLabelProp || eItem == eWidProp || eItem == eHeiProp; } // 更新显示,不管ID对应的是普通实体,块参照实体,或者外部参照实体 void UpdateGraphicAny(const TDPtrList &ss) { AcDbBlockTable *pTable; AcDbObjectId modelId; if (curDoc()->database()->getBlockTable(pTable, AcDb::kForRead) == Acad::eOk) { pTable->getAt(ACDB_MODEL_SPACE, modelId, AcDb::kForRead); pTable->close(); } bool bHasBolck = false; for (int i = 0; i < (int)ss.Length(); i++) { OPENOBJ_BEGIN((ss[i]), AcDb::kForRead, AcDbEntity, pEnt) if (pEnt != NULL && pEnt->ownerId() != modelId) { bHasBolck = true; break; } OPENOBJ_END() } if (bHasBolck) { PickSet ssp(SS_FREE); ssp.Get(_T("X"), NULL, NULL, RBList(RTDXF0, _T("INSERT"), NULL)); UpdateGraphic(ssp); } UpdateGraphic(ss); } void LockDocumentChange() { if (acDocManager->isDocumentActivationEnabled()) { Acad::ErrorStatus error = acDocManager->disableDocumentActivation(); // acDocManager->enableDocumentActivation(); if (error == Acad::eOk) { } } } void UnLockDocumentChange() { if (!acDocManager->isDocumentActivationEnabled()) { Acad::ErrorStatus error = acDocManager->enableDocumentActivation(); if (error == Acad::eOk) { } } } BOOL IsSlideType(EEntType eEntType) { if (eEntType == eM || eEntType == eC || eEntType == eMLC || eEntType == eZMM) return TRUE; else return FALSE; } BOOL IsEmptyProject() { CString strProj = _T(""); BOOL bEmpty = !g_project.GetProjectName(strProj); return bEmpty; } CString ProjectName() { CString strProj = _T(""); BOOL bEmpty = !g_project.GetProjectName(strProj); if (strProj.GetLength() > 4) { // 去掉工程名字的后缀,.tpr strProj = strProj.Left(strProj.GetLength() - 4); } return strProj; } CString ProjectFullName() { CString strProj = _T(""); BOOL bEmpty = !g_project.GetFileFullName(); return strProj; } CString Type2Name(EEntType eEntType) { return strDoorTypeName[eEntType]; } CWidItem* FindWidItem(const AryWidItemPtr &aryWidItem, CString strLabel) { for (int i = 0; i < (int)aryWidItem.GetSize(); i++) { if (aryWidItem[i]->strLabel.CompareNoCase(strLabel) == 0) return aryWidItem[i]; } return NULL; } int FindIdArry(const DList &lstId, const AcDbObjectId &id) { for (int i = 0; i < (int)lstId.Length(); i++) { const AcDbObjectId &tempId = lstId[i]; // CAD的老版本中,如果某ID所在的图形当前没有打开,直接进行的ID相等比较会导致程序崩溃 if (id.asOldId() == tempId.asOldId()) return i; } return -1; } int FindIdArry(const AcDbObjectIdArray &idArry, const AcDbObjectId &id) { for (int i = 0; i < (int)idArry.length(); i++) { // CAD的老版本中,如果某ID所在的图形当前没有打开,直接进行的ID相等比较会导致程序崩溃 if (id.asOldId() == idArry[i].asOldId()) return i; } return -1; } // 向widItem数组中添加pItem void AddItemToWidItemAry(AryWidItemPtr &aryWidItem, CItem *pItem) { if (pItem == NULL) return; CWidItem *pWidItem = FindWidItem(aryWidItem, pItem->strLabel); if (pWidItem == NULL) { pWidItem = new CWidItem; aryWidItem.Add(pWidItem); } pWidItem->AddItem(pItem); } void ClearAryWidItemPtr(AryWidItemPtr &aryWidItemPtr) { for (int i = 0; i < (int)aryWidItemPtr.GetSize(); i++) { delete aryWidItemPtr[i]; aryWidItemPtr[i] = NULL; } aryWidItemPtr.RemoveAll(); } void ItemPtrAry2Wid(const AryItemPtr &aryItemPtr, AryWidItemPtr &aryWidItem) { for (int i = 0; i < (int)aryItemPtr.GetSize(); i++) { CWidItem *pWidItem = new CWidItem(aryItemPtr[i]); aryWidItem.Add(pWidItem); } } // 将当前的属性数据覆盖DWG图纸中的数据,需要pEnt是门窗类型。 void UpdateProp2DWG(AcDbEntity* pEnt, EEntType eEntType, AryEShowItem &aryEShowItem, CStringArray &aryProp) { if (pEnt == NULL) return; pEnt->assertWriteEnabled(); pEnt->recordGraphicsModified(); if (pEnt->isKindOf(AcDbText::desc())) { AcDbText *pText = AcDbText::cast(pEnt); for (int i = 0; i < (int)aryProp.GetSize(); i++) { if (aryEShowItem[i] == eNewLabelProp) { pText->setTextString(aryProp[i]); } } return; } else if (pEnt->isKindOf(TDbText::desc())) { TDbText *pText = TDbText::cast(pEnt); for (int i = 0; i < (int)aryProp.GetSize(); i++) { if (aryEShowItem[i] == eNewLabelProp) { pText->SetText(aryProp[i]); } } return; } switch(eEntType) { case eM: // 门 case eC: // 窗 case eHC: // 弧窗 case eMLC: // 门连窗 case eZMM: // 子母门 case eZHMC: // 组合门窗 case eDK: // 洞口 case eTC:// 凸窗 { TDbOpening *pOpening = TDbOpening::cast(pEnt); if (pOpening == NULL) break; for (int i = 0; i < (int)aryEShowItem.GetSize(); i++) { if (aryEShowItem[i] == eTypeProp) { if (eEntType == eTC) { XBayWindow::XBayWinStyle style = GeoType2Style(aryProp[i]); if (style != XBayWindow::BWS_UNKNOWN) { pOpening->m_pBayWin->m_nStyle = style; } } else if (eEntType == eM || eEntType == eC || eEntType == eHC) { pOpening->SetSubKind(aryProp[i]); } } else if (aryEShowItem[i] == eNewLabelProp) { pOpening->SetLabel(aryProp[i]); } else if (aryEShowItem[i] == eWidProp) { double iWid = _tstof(aryProp[i]); if (iWid > 0) pOpening->SetWidth(iWid); } else if (aryEShowItem[i] == eHeiProp) { double iHei = _tstof(aryProp[i]); if (iHei > 0) { pOpening->SetHeight(iHei); } } else if (aryEShowItem[i] == eEle) { double iEle = _tstof(aryProp[i]); if (iEle > -1e-6) { //modify by lgy 20120301 标高无法设置到门窗实体中的主要原因是 //不知道谁出于什么原因把下面这句代码给注释了故无法设置标高 //pOpening->SetElevation(iEle); pOpening->SetSill(iEle); } } else if (aryEShowItem[i] == eGeoTypeProp) { if (eEntType == eTC) { XBayWindow::XBayWinStyle style = GeoType2Style(aryProp[i]); if (style != XBayWindow::BWS_UNKNOWN) { pOpening->m_pBayWin->m_nStyle = style; } } // 其他的不用修改 } else if (aryEShowItem[i] == eChutiaoProp) { double iChuTiao = _tstof(aryProp[i]); pOpening->m_pBayWin->m_nProtrude = iChuTiao; } else if (aryEShowItem[i] == eTixingkuanProp) { if (eEntType == eTC && pOpening->m_pBayWin->m_nStyle == XBayWindow::BWS_TRAPEZIA) { // 梯形凸窗 double iTiXingkuan = _tstof(aryProp[i]); pOpening->m_pBayWin->m_nTrapezia = iTiXingkuan; } } } } break; case eDXC: // 带型窗 { TDbBandWin *pBanWin = TDbBandWin::cast(pEnt); if (pBanWin == NULL) break; for (int i = 0; i < (int)aryEShowItem.GetSize(); i++) { if (aryEShowItem[i] == eHeiProp) { double iHei = _tstof(aryProp[i]); if (iHei > 0) pBanWin->SetHeight(iHei); } else if (aryEShowItem[i] == eNewLabelProp) { pBanWin->SetLabel(aryProp[i]); } else if (aryEShowItem[i] == eEle) { double iEle = _tstof(aryProp[i]); pBanWin->SetElevation(iEle); } } } break; case eZJC: // 转角窗 { TDbCornerWin *pCorWin = TDbCornerWin::cast(pEnt); if (pCorWin == NULL) break; for (int i = 0; i < (int)aryEShowItem.GetSize(); i++) { if (aryEShowItem[i] == eHeiProp) { double iHei = _tstof(aryProp[i]); if (iHei > 0) pCorWin->SetHeight(iHei); } else if (aryEShowItem[i] == eNewLabelProp) { pCorWin->SetLabel(aryProp[i]); } else if (aryEShowItem[i] == eEle) { double iEle = _tstof(aryProp[i]); pCorWin->SetElevation(iEle); } else if (aryEShowItem[i] == eChutiaoProp && pCorWin->IsProtrude()) { // 转交凸窗才可以编辑出挑长 double iChuTiao = _tstof(aryProp[i]); if (iChuTiao >= 0) { pCorWin->SetProtrude(iChuTiao); // sg modify 120530,增加凸窗出挑长2 pCorWin->SetProtrude2(iChuTiao); } } } } break; case eLHC: // 老虎窗 { TDbDormer *pDormer = TDbDormer::cast(pEnt); if (pDormer == NULL) break; TDormerPar dp = pDormer->GetDormerPar(); for (int i = 0; i < (int)aryEShowItem.GetSize(); i++) { if (aryEShowItem[i] == eHeiProp) { double iHei = _tstof(aryProp[i]); if (iHei > 0) dp.SetWindowHeight(iHei); } else if (aryEShowItem[i] == eNewLabelProp) { pDormer->SetLabel(aryProp[i]); } } pDormer->SetDormerPar(dp); } break; default: return; break; } } extern TARCH_IMPEXP void CheckOp3dStyle(AcDbObjectId idStyle3d); extern TARCH_IMPEXP void CheckOp2dStyle(AcDbObjectId idStyle2d); void UpdateEntStyle(TDbEntity *pEnt, EEntType eEntType, CString strStyle, bool b2dOr3d) { if (pEnt == NULL) return; pEnt->assertWriteEnabled(); if (IsSlideType(eEntType)) { TDbOpening *pOpening = TDbOpening::cast(pEnt); if (pOpening == NULL) return; AcDbObjectId idStyle; XString sBlock2d(_T("%s%s"), g_sDwbPath, strStyle); XString szBlock2d; Adesk::Boolean bLoad2d=(LoadDwbBlock(sBlock2d, szBlock2d)==RTNORM); idStyle=InitBlock(szBlock2d); if (b2dOr3d) { // CheckOp2dStyle(idStyle); if (!!idStyle) pOpening->m_nIdStyle2d = idStyle; } else { // CheckOp3dStyle(idStyle); if (!!idStyle) pOpening->m_nIdStyle3d = idStyle; } } } BOOL CheckName(const CString &strName) { CString strHead = _T(""), strHei = _T(""), strWid = _T(""); if (GetSize(strName, strHead, strHei, strWid)) { if (TextLabelType(strHead) < eDoorTypeNum) return TRUE; } return FALSE; } // 获取尺寸编号的尺寸 === "前缀 + 高(2位) + 宽(2位)" BOOL GetSize(const CString &strName, CString &strHead, CString &strHei, CString &strWid) { if (strName.GetLength() < 5) return FALSE; // 不够5个长度肯定不是尺寸编号, CString strSize = strName.Right(4); strWid = strSize.Left(2); strHei = strSize.Right(2); if (_ttoi(strHei) > 0 && _ttoi(strWid) > 0) { strHead = strName.Left(strName.GetLength() - 4); return TRUE; } return FALSE; } BOOL GetSize(const CString &strName, CString &strHead, double &dHei, double &dWid) { CString strHei = _T(""), strWid = _T(""); if (GetSize(strName, strHead, strHei, strWid)) { dHei = _tstof(strHei) * 100; dWid = _tstof(strWid) * 100; return TRUE; } else return FALSE; } EEntType TextLabelType(const CString &strLabelHead) { CString sHead = strLabelHead; if (strLabelHead.GetLength()>1 && strLabelHead.GetAt(strLabelHead.GetLength()-1) == _T('-')) { sHead = strLabelHead.Left(strLabelHead.GetLength()-1); } const CString sDoorDatas[eDoorTypeNum] = { _T("Door"), _T("DoorWin"), _T("TwoDoor"), _T("GroupOpening"), _T("Window"), _T("ArcWin"), _T("BayWin"), _T("CornerWin"), _T("BandWin"), _T("Dormer"), _T("Hole") }; TOpeningLabelData ddd; for (int i = 0; i < eDoorTypeNum; i++) { CStringArray arystr; ddd.GetSubLabelPrefix(sDoorDatas[i], arystr); for (int j = 0; j < (int)arystr.GetSize(); j++) { if (arystr[j].CompareNoCase(sHead) == 0) return EEntType(i); } } return eDoorTypeNum; } BOOL TestEmptyItem(CItem *pItem, BOOL bText, BOOL bBlock) { if (pItem == NULL) return TRUE; else { for (int jProp = 0; jProp < (int)pItem->aryProp.GetSize(); jProp++) { if ((!bBlock && pItem->aryProp[jProp].bBlock) || (!bText && pItem->aryProp[jProp].bText)) continue; else return FALSE; } return TRUE; } } BOOL TestItemEmpty(const AryItemPtr &aryItemPtr, BOOL bText, BOOL bBlock) { if (bText && bBlock) { // 文字和快都显示,则直接查看该数组是否为空 return IsEmpty(aryItemPtr); } for (int i = 0; i < (int)aryItemPtr.GetSize(); i++) { if (TestEmptyItem(aryItemPtr[i], bText, bBlock)) continue; else return FALSE; } return TRUE; } BOOL TestItemEmpty(const AryWidItemPtr &aryItemPtr, BOOL bText, BOOL bBlock) { if (bText && bBlock) { // 文字和快都显示,则直接查看该数组是否为空 return IsEmpty(aryItemPtr); } for (int iWid = 0; iWid < (int)aryItemPtr.GetSize(); iWid++) { CWidItem *pWid = aryItemPtr[iWid]; if (pWid == NULL) continue; for (int iItem = 0; iItem < (int)pWid->aryItem.GetSize(); iItem++) { if (TestEmptyItem(pWid->aryItem[iItem], bText, bBlock)) continue; else return FALSE; } } return TRUE; } //add by lgy 20120227 添加该函数是为了解析获得的参照中的实体样式字符串,以用来 //解决在门窗检查命令中如果图纸中保存的是DWG参照,无法读取实体的样式 CString FindSpace(CString &str, const CString &sSep) { CString sLeft = _T(""); int iPos = 0; if((iPos = str.Find(sSep)) != -1) { sLeft = str.Left(iPos); sLeft.TrimLeft(); sLeft.TrimRight(); int iLen = sSep.GetLength(); str = str.Mid(iPos+iLen); str.TrimLeft(); str.TrimRight(); return sLeft; } return str; } BOOL GetDoorWinProp(AcDbObjectId &id, SOpeningProp &soprop, EEntType &eOpType) { OPENOBJ_BEGIN(id, AcDb::kForRead, AcDbEntity, pEnt) if (pEnt == NULL) return FALSE; soprop.bText = false; if (pEnt->isKindOf(TDbOpening::desc())) { TDbOpening *pOpening = TDbOpening::cast(pEnt); TDbOpening::OpeningKind kind = pOpening->GetKind(); if ((pOpening->GetSubKind() == _T("电梯门")) || (pOpening->GetSubKind() == _T("隔断门")) || (pOpening->m_nOpStyle&OPS_LIFTDOOR) || (pOpening->m_nOpStyle&OPS_LVTRY)) { // 隔断门和电梯门,不处理 return FALSE; } soprop.strLabel = pOpening->GetLabel(); soprop.nHei = (int)(pOpening->GetHeight()); soprop.nWid = (int)(pOpening->GetWidth()); // 这几个属性是共有的。 soprop.nEle = (int)(pOpening->GetElevation()); soprop.strType = pOpening->GetSubKind(); XString sDwb2D, sDwb3D, sDwg2D, sDwg3D; if (pOpening->GetStyle2dName(sDwb2D, sDwg2D)==Acad::eOk) { soprop.str2DShowStyle = XString(_T("%s(%s)"), (TCHAR *)sDwb2D, (TCHAR *)sDwg2D); } else { //modify by lgy 20120227 图块参照中的实体读不出来样式 //原来如果图纸中是DWG参照,则无法读取实体的三维样式和二维样式 //旧版图纸转化而来 //soprop.str2DShowStyle = _T(""); XString strDwbTemp; pOpening->GetStyle2dName(strDwbTemp); CString strDwb2D = strDwbTemp; FindSpace(strDwb2D, _T("$")); CString strTemp = FindSpace(strDwb2D, _T("$")); strTemp = strTemp + _T("(") + strDwb2D + _T(")"); soprop.str2DShowStyle = strTemp; } if (pOpening->GetStyle3dName(sDwb3D, sDwg3D)==Acad::eOk) { soprop.str3DShowStyle = XString(_T("%s(%s)"), (TCHAR *)sDwb3D, (TCHAR *)sDwg3D); } //add by lgy 20120227 图块参照中的实体读不出来三维样式 //原来如果图纸中是DWG参照,则无法读取实体的三维样式和二维样式 //现在添加else分支,这样可以保证读取3维样式能读取出来 else { XString strDwbTemp; pOpening->GetStyle3dName(strDwbTemp); CString strDwb3D = strDwbTemp; FindSpace(strDwb3D, _T("$")); //首先保证读取出来的3维样式字符串中只有一个$分隔符 CString strTemp = FindSpace(strDwb3D, _T("$")); strTemp = strTemp + _T("(") + strDwb3D + _T(")"); soprop.str3DShowStyle = strTemp; } switch(kind) { case TDbOpening::OP_DOOR: // 门 eOpType = eM; break; case TDbOpening::OP_WINDOW: // 窗 eOpType = eC; break; case TDbOpening::OP_CORNWIN: eOpType = eC; break; case TDbOpening::OP_ARCWIN: // 弧窗 eOpType = eHC; break; case TDbOpening::OP_DOORWIN: // 门连窗 eOpType = eMLC; break; case TDbOpening::OP_TWODOOR: // 子母门 eOpType = eZMM; break; case TDbOpening::OP_GROUP: // 组合门窗 eOpType = eZHMC; break; case TDbOpening::OP_HOLE: // 洞口 eOpType = eDK; break; case TDbOpening::OP_PROWIN:// 凸窗 eOpType = eTC; soprop.eProWinGeo = pOpening->m_pBayWin->m_nStyle; // 型式 soprop.nChuTiaoChang = (int)(pOpening->m_pBayWin->m_nProtrude); soprop.nTixingkuan = (int)(pOpening->m_pBayWin->m_nTrapezia); break; default: return FALSE; break; } return TRUE; } else if (pEnt->isKindOf(TDbCornerWin::desc())) { soprop.str2DShowStyle = _T(""); soprop.str3DShowStyle = _T(""); if (pEnt->isKindOf(TDbBandWin::desc())) { // 带型窗 TDbBandWin *pBanWin = TDbBandWin::cast(pEnt); soprop.strLabel = pBanWin->GetLabel(); soprop.nHei = (int)(pBanWin->GetHeight()); // sg modify 120514,根据9.0需求,带形窗宽度的测量改用中心线 //soprop.nWid = (int)(pBanWin->GetWidth()); soprop.nWid = (int)(pBanWin->GetGeomCenterWidth()); soprop.nEle = (int)(pBanWin->GetElevation()); eOpType = eDXC; } else { // 转角窗 TDbCornerWin *pCorWin = TDbCornerWin::cast(pEnt); soprop.strLabel = pCorWin->GetLabel(); soprop.nHei = (int)(pCorWin->GetHeight()); // sg modify 120514,根据9.0需求,转角窗宽度的测量要根据编号设置,分别按阴角、中线、阳角分别读取 //soprop.nWid = (int)(pCorWin->GetWidth1() + pCorWin->GetWidth2()); { TOpeningLabelData labelData; TOpeningLabelData::ECalWidthRule nRule = labelData.GetCalWidthRule(); double dWidth1 = pCorWin->GetWidth1(), dWidth2 = pCorWin->GetWidth2(); if (nRule == TOpeningLabelData::kMiddle) { dWidth1 = dWidth1 + pCorWin->GetWallThick2()*0.5; dWidth2 = dWidth2 + pCorWin->GetWallThick1()*0.5; } else if (nRule == TOpeningLabelData::kOutboard) { dWidth1 = dWidth1 + pCorWin->GetWallThick2(); dWidth2 = dWidth2 + pCorWin->GetWallThick1(); } soprop.nWid = (int)(dWidth1 + dWidth2); } soprop.nEle = (int)(pCorWin->GetElevation()); soprop.nChuTiaoChang = (int)(pCorWin->GetProtrude()); // 出挑长 soprop.bZJCTuChuang = pCorWin->IsProtrude() ? true : false; eOpType = eZJC; } return TRUE; } else if (pEnt->isKindOf(TDbDormer::desc())) { // 老虎窗 soprop.str2DShowStyle = _T(""); soprop.str3DShowStyle = _T(""); TDbDormer *pDormer = TDbDormer::cast(pEnt); const TDormerPar &dp = pDormer->GetDormerPar(); soprop.strLabel = pDormer->GetLabel(); soprop.nHei = (int)(dp.GetWindowHeight()); soprop.nWid = (int)(dp.GetWindowWidth()); eOpType = eLHC; return TRUE; } else if (pEnt->isKindOf(AcDbText::desc())) { AcDbText *pText = AcDbText::cast(pEnt); CString strText = pText->textString(); soprop.bText = true; CString strHead; double dHei = 0.0, dWid = 0.0; if (GetSize(strText, strHead, dHei, dWid)) { soprop.strLabel = strText; soprop.nWid = (int)dWid; soprop.nHei = (int)dHei; eOpType = TextLabelType(strHead); if (eOpType >= eDoorTypeNum) return FALSE; } else return FALSE; return TRUE; } else if (pEnt->isKindOf(TDbText::desc())) { TDbText *pText = TDbText::cast(pEnt); CString strText = pText->GetText(); soprop.bText = true; CString strHead; double dHei = 0.0, dWid = 0.0; if (GetSize(strText, strHead, dHei, dWid)) { soprop.strLabel = strText; soprop.nWid = (int)dWid; soprop.nHei = (int)dHei; eOpType = TextLabelType(strHead); if (eOpType >= eDoorTypeNum) return FALSE; } else return FALSE; return TRUE; } else return FALSE; OPENOBJ_END(); return FALSE; } CString GetDoorWinSizeLabel(EEntType eEntType, const SOpeningProp &sProp) { const CString sDoorDatas[eDoorTypeNum] = { _T("Door"), _T("DoorWin"), _T("TwoDoor"), _T("GroupOpening"), _T("Window"), _T("ArcWin"), _T("BayWin"), _T("CornerWin"), _T("BandWin"), _T("Dormer"), _T("Hole") }; TOpeningLabelData ddd; CStringArray arystr; CString strHead; ddd.GetSubLabelPrefix(sDoorDatas[eEntType], arystr); if (arystr.GetSize() == 1) strHead = arystr[0]; else { int i ; for (i = 0; i < (int)arystr.GetSize(); i++) { if (arystr[i].CompareNoCase(sProp.strType) == 0) { strHead = arystr[i]; break; } } if (i == (int)arystr.GetSize()) strHead = arystr[0]; } CString strHei, strWid; strWid.Format(_T("%i"), sProp.nWid/100); strHei.Format(_T("%i"), sProp.nHei/100); while (strWid.GetLength() < 2) strWid = _T("0")+strWid; while (strHei.GetLength() < 2) strHei = _T("0")+strHei; strHead.Format(_T("%s%s%s%s"), strHead, (ddd.HasHypen() ? _T("-") : _T("")), strWid, strHei); return strHead; } CString GeoType2String(XBayWindow::XBayWinStyle eProWinGeo) { if (eProWinGeo == XBayWindow::BWS_TRAPEZIA) { return _T("梯形"); } else if (eProWinGeo == XBayWindow::BWS_TRIANGLE) { return _T("三角形"); } else if (eProWinGeo == XBayWindow::BWS_ARC) { return _T("弧形"); } else if (eProWinGeo == XBayWindow::BWS_RECT) { return _T("矩形"); } else return _T(""); } XBayWindow::XBayWinStyle GeoType2Style(CString &strGeoType) { if (strGeoType.CompareNoCase(_T("梯形")) == 0) { return XBayWindow::BWS_TRAPEZIA; } else if (strGeoType.CompareNoCase(_T("三角形")) == 0) { return XBayWindow::BWS_TRIANGLE; } else if (strGeoType.CompareNoCase(_T("弧形")) == 0) { return XBayWindow::BWS_ARC; } else if (strGeoType.CompareNoCase(_T("矩形")) == 0) { return XBayWindow::BWS_RECT; } else return XBayWindow::BWS_UNKNOWN; } void SetPropData(SOpeningProp &sProp, EShowItem eShowItem, CString strData) { strData.TrimLeft(); strData.TrimRight(); int nValData = _ttoi(strData); switch (eShowItem) { case eWidProp: sProp.nWid = nValData; break; case eTypeProp: sProp.strType = strData; break; case eHeiProp: sProp.nHei = nValData; break; case eEle: sProp.nEle = nValData; break; case eGeoTypeProp: sProp.eProWinGeo = GeoType2Style(strData); break; case eChutiaoProp: sProp.nChuTiaoChang = nValData; break; case eTixingkuanProp: sProp.nTixingkuan = nValData; break; case eNewLabelProp: sProp.strLabel = strData; break; default: break; } } CString PropToString(const SOpeningProp &prop, EShowItem eShowItem) { CString strRet; switch (eShowItem) { case eLabelProp: if (prop.strLabel.IsEmpty()) { if (prop.pItem == NULL) { ASSERT(0); strRet = _T("empty"); } else strRet = prop.pItem->strLabel; } else strRet = prop.strLabel; break; case eNewLabelProp: strRet = prop.strLabel; break; case eTypeProp: strRet = prop.strType; break; case eWidProp: strRet.Format(_T("%d"), prop.nWid); break; case eHeiProp: strRet.Format(_T("%d"), prop.nHei); break; case eEle: strRet.Format(_T("%d"), prop.nEle); break; case eGeoTypeProp: strRet = GeoType2String(prop.eProWinGeo); break; case eChutiaoProp: strRet.Format(_T("%d"), prop.nChuTiaoChang); break; case eTixingkuanProp: strRet.Format(_T("%d"), prop.nTixingkuan); break; default: return prop.strLabel; } return strRet; } // 检测属性是否冲突, // 检测当前显示的属性是否一致,排除底高,门窗显示的二、三维样式也是判断冲突的依据 BOOL TestConflict(EEntType eEnttype, const SOpeningProp &sprop1, const SOpeningProp &sprop2) { // 文字不存于冲突测试, if (sprop1.bText || sprop2.bText) return FALSE; AryEtype aryEtype; aryEtype.Add(eEnttype); // 类型 AryEShowItem aryEShowItem; // 参数 DWORD flagCheck = CSetDlg::GetCheckFlag(aryEtype, aryEShowItem); for (int i = 0; i < (int)aryEShowItem.GetSize(); i++) { if (aryEShowItem[i] == eEle || aryEShowItem[i] == eLabelProp || aryEShowItem[i] == eNewLabelProp) continue; CString str1 = PropToString(sprop1, aryEShowItem[i]); CString str2 = PropToString(sprop2, aryEShowItem[i]); if (str1.CompareNoCase(str2) != 0) { return TRUE; } } if ((sprop1.str2DShowStyle.Compare(sprop2.str2DShowStyle) != 0) || (sprop1.str3DShowStyle.Compare(sprop2.str3DShowStyle) != 0)) return TRUE; return FALSE; } BOOL TestConflict(CItem *pItem) { for (int i = 0; i < (int)pItem->aryProp.GetSize(); i++) { for (int j = 0; j < (int)pItem->aryProp.GetSize(); j++) { if (TestConflict(pItem->eDoorWinType, pItem->aryProp[i], pItem->aryProp[j])) return TRUE; } } return FALSE; } BOOL TestConflict(CItem *pItem1, CItem *pItem2) { for (int i = 0; i < (int)pItem1->aryProp.GetSize(); i++) { for (int j = 0; j < (int)pItem2->aryProp.GetSize(); j++) { if (TestConflict(pItem1->eDoorWinType, pItem1->aryProp[i], pItem2->aryProp[j])) return TRUE; } } return FALSE; } int FindEType(AryWidItemPtr &aryWidItem, AryEtype &aryEtype) { BOOL bFlag[eDoorTypeNum]; memset(bFlag, 0, sizeof(BOOL)*eDoorTypeNum); for (int i = 0; i < (int)aryWidItem.GetSize(); i++) { if (!IsEmpty(aryWidItem[i]->aryItem)) { bFlag[aryWidItem[i]->aryItem[0]->eDoorWinType] = TRUE; } } for (int k = 0; k < eDoorTypeNum; k++) { EEntType eEntType = EEntType(k); if (bFlag[k]) aryEtype.Add(eEntType); } return (int)aryEtype.GetSize(); } int FindEType(CWidItem *pWidItem, AryEtype &aryEtype) { if (pWidItem != NULL && !IsEmpty(pWidItem->aryItem)) { aryEtype.Add(pWidItem->aryItem[0]->eDoorWinType); } return 1; } CString CItem::GetItemName(bool bCheckText, bool bBlock) const { CString sLabel = _T(""); if (this->strLabel.IsEmpty()) sLabel = _T("未命名"); { sLabel.Format(_T("%s[%d]"), strLabel, ItemNum(bCheckText, bBlock)); } return sLabel; } // 非文字的个数。 int CItem::NoTextDataNum() const { int iCount = 0; for (int i = 0; i < (int)aryProp.GetSize(); i++) { if (!aryProp[i].bText) iCount++; } return iCount; } int CItem::ItemNum(bool bText, bool bBlock) const { AcDbObjectIdArray idAryTemp; for (int i = 0; i < (int)aryId.length(); i++) { if (!bText && aryProp[i].bText) continue; if (!bBlock && aryProp[i].bBlock) continue; if (FindIdArry(idAryTemp, aryId[i]) == -1) { // 如果之前没有添加的话, 那么添加 idAryTemp.append(aryId[i]); } } //modify by lgy 20120229 框选块参照时无法正确显示出来选中的实体个数 //9.0需求导致实际上以上代码多没有用处,只需要返回该行的id数组的长度就可以,不用 //处理这些id是否是同名的块参照或者外部参照 //return (int)idAryTemp.length(); return (int)aryId.length(); } bool CItem::HasItem(bool bText, bool bBlock) const { return ItemNum(bText, bBlock) != 0; } void CItem::AddProp(SOpeningProp &prop) { prop.pItem = this; aryProp.Add(const_cast(prop)); } bool CItem::TestRepeatBlock(int index) const { if (aryId.length() < index) return true; if (!aryProp[index].bBlock) return false; int iFind = FindIdArry(aryId, aryId[index]); return (iFind != index); } CString EntTypeToString(EEntType eEntType) { if (eEntType == eM) return _T("普通门"); else if (eEntType == eC) return _T("普通窗"); else if (eEntType == eHC) return _T("普通窗"); else return _T(""); } // 检测id对应实体的属性跟sValue是否相等 BOOL IsPropModify(AcDbObjectId id, EShowItem eShowItem, CString sValue) { SOpeningProp sp; EEntType eEntType; if (GetDoorWinProp(id, sp, eEntType) && eEntType >= 0 && eEntType < eDoorTypeNum) { CString strValue; if (PropToString(sp, eShowItem).CompareNoCase(sValue) == 0) return FALSE; else return TRUE; } return TRUE; } void CWidItem::CopyFrom(const CWidItem &widItem) { this->aryItem.Append(widItem.aryItem); this->strLabel = widItem.strLabel; } int CWidItem::GetEntNum(bool bCheckText, bool bBlock) const { AcDbObjectIdArray aryIdTemp; for (int i = 0; i < (int)aryItem.GetSize(); i++) { CItem *pItem = aryItem[i]; for (int j = 0; j < (int)pItem->aryId.length(); j++) { if (pItem->aryProp[j].bText && !bCheckText) continue; if (pItem->aryProp[j].bBlock && !bBlock) continue; AcDbObjectId idTemp = pItem->aryId[j]; // if (FindIdArry(aryIdTemp, idTemp) == -1) { aryIdTemp.append(pItem->aryId[j]); } } } return (int)aryIdTemp.length(); } void CWidItem::AddItem(CItem* pItem) { if (pItem == NULL) return; int i = 0; for (i = 0; i < (int)aryItem.GetSize(); i++) { if (aryItem[i] == pItem) return; // 已经添加了该指针 } if (IsEmpty(aryItem)) { strLabel = pItem->strLabel; } aryItem.Add(pItem); } CString CWidItem::GetItemName(bool bCheckText, bool bBlock) const { if (IsEmpty(aryItem)) return _T(""); int nNum = GetEntNum(bCheckText, bBlock); CString sLabelDump; sLabelDump.Format(_T("%s[%d]"), strLabel, nNum); return sLabelDump; } CString CWidItem::StyleString(BOOL is2D) const { CString strStyle; for (int iWid = 0; iWid < (int)aryItem.GetSize(); iWid++) { CItem *pItem = aryItem[iWid]; for (int iItem = 0; iItem < (int)pItem->aryProp.GetSize(); iItem++) { CString strCurr = is2D ? pItem->aryProp[iItem].str2DShowStyle : pItem->aryProp[iItem].str3DShowStyle; if (iWid == 0 && iItem == 0) { strStyle = strCurr; } else { if (strStyle.CompareNoCase(strCurr) != 0) return CString(_T("")); } } } return strStyle; } bool CWidItem::TestRepeatBlock(int nItem, int index) const { if (aryItem.GetSize() < nItem + 1) return true; if (aryItem[nItem]->aryId.length() < index + 1) return true; AcDbObjectId id = aryItem[nItem]->aryId[index]; for (int i = 0; i < nItem; i++) { if (FindIdArry(aryItem[i]->aryId, id) != -1) return true; // 找到了 } return aryItem[i]->TestRepeatBlock(index); } void CWidItem::GetIdAry(TDPtrList &idLst) { for (int i = 0; i < (int)aryItem.GetSize(); i++) { CItem *pItem = aryItem[i]; if (pItem != NULL) { for (int j = 0; j < (int)pItem->aryId.length(); j++) { idLst.Append(new AcDbObjectId(pItem->aryId[j])); } } } } CGroup::CGroup() { m_strFloor = _T(""); m_bCurrDoc = FALSE; } CGroup::~CGroup() { for (int i = 0; i < eDoorTypeNum; i++) { for (int j = 0; j < (int)m_doors[i].GetSize(); j++) { delete m_doors[i].GetAt(j); m_doors[i][j] = NULL; } m_doors[i].RemoveAll(); } } void CGroup::Clear() { for (int i = 0; i < eDoorTypeNum; i++) { for (int j = 0; j < (int)m_doors[i].GetSize(); j++) { delete m_doors[i].GetAt(j); m_doors[i][j] = NULL; } m_doors[i].RemoveAll(); } m_bCurrDoc = FALSE; } // 按照类型添加门窗,返回门窗对应的check指针 // 同名,同类型,放在同一个下边,注意监测冲突标记 CItem* CGroup::AddOpening(AcDbObjectId &id, SOpeningProp &prop, EEntType eEntType) { AryItemPtr &aryDoorCheckPtr = m_doors[eEntType]; CItem *pItem = NULL; int i = 0; CString strComparLabel = prop.strLabel.IsEmpty() ? GetDoorWinSizeLabel(eEntType, prop) : prop.strLabel; for (i = 0; i < (int)aryDoorCheckPtr.GetSize(); i++) { if (aryDoorCheckPtr[i]->strLabel.CompareNoCase(strComparLabel) == 0) { pItem = aryDoorCheckPtr[i]; break; } } if (pItem == NULL) { pItem = new CItem; pItem->strLabel = strComparLabel; pItem->eDoorWinType = eEntType; pItem->pGroup = this; aryDoorCheckPtr.Add(pItem); } pItem->aryId.append(id); // 添加属性,并且检测是否冲突. pItem->AddProp(prop); prop.strType = EntTypeToString(eEntType); return pItem; } // 获取楼层名字 CString CGroup::GetFloorName() const { return m_strFloor + _T("层"); } void CGroup::SetFloorName(CString strName) { m_strFloor = strName; } // 是否当前文档 BOOL CGroup::IsCurrDoc() const { return m_bCurrDoc; } // 根据类型获取CheckItem; const AryItemPtr& CGroup::GetItemAry(EEntType eType) const { return m_doors[eType]; } int CGroup::FindEType(AryEtype &aryEType) const { for (int i = 0; i < eDoorTypeNum; i++) { if (!IsEmpty(GetItemAry(EEntType(i)))) { EEntType eEntType = EEntType(i); aryEType.Add(eEntType); } } return (int)aryEType.GetSize(); } void CGroup::FilterId(AcDbObjectIdArray &idArray) { for (int iEntType = 0; iEntType < eDoorTypeNum; iEntType++) { AryItemPtr& aryItemPtr = m_doors[iEntType]; for (int iAryItem = 0; iAryItem < (int)aryItemPtr.GetSize(); iAryItem++) { CItem *pItem = aryItemPtr.GetAt(iAryItem); for (int iItem = (int)pItem->aryId.length()-1; iItem >= 0 ; iItem--) { int iPos = FindIdArry(idArray, pItem->aryId[iItem]); if (iPos == -1) { // 没找到 // pItem->aryId.RemoveAt(iItem); pItem->aryId.removeAt(iItem); pItem->aryProp.RemoveAt(iItem); } else { idArray.removeAt(iPos); } } // 检测,如果pItem空了,则需要删除这个pItem; if ((pItem->aryId.isEmpty())) { aryItemPtr.RemoveAt(iAryItem--); delete pItem; pItem = NULL; } // pItem更新之后,这里没有重新作出冲突检测,因为相对全图来说,这里还是冲突的。 } } } ////////////////////////////////////////////////////////////////////////// // projectInfo.... void SProjectInfo::Clear() { strProjectName = _T(""); strProjectFullName = _T(""); aryFloorInfo.RemoveAll(); // lstFloorData.(); } void SProjectInfo::Init() { strProjectName = _T(""); strProjectFullName = _T(""); aryFloorInfo.RemoveAll(); } void SProjectInfo::AddFloorInfoByDoc(CString _strFloorNo, CString _strFloorDoc) { _SFloorInfo sfi; sfi.bInFrame = false; sfi.strfloorNo = _strFloorNo; sfi.strFloorDoc = _strFloorDoc; aryFloorInfo.Add(sfi); } void SProjectInfo::AddFloorByRange(CString _strFloorNo, CString _strFloorDoc, XPoint _ptMin, XPoint _ptMax) { _SFloorInfo sfi; sfi.bInFrame = true; sfi.strfloorNo = _strFloorNo; sfi.strFloorDoc = _strFloorDoc; sfi.ptMin = _ptMin; sfi.ptMax = _ptMax; aryFloorInfo.Add(sfi); } // 比较,没有差异的话,返回true.否则返回false; bool SProjectInfo::Compare(const SProjectInfo &sProjectInfo) const { if (strProjectName.CompareNoCase(sProjectInfo.strProjectName) != 0 || strProjectFullName.CompareNoCase(sProjectInfo.strProjectFullName) != 0 || aryFloorInfo.GetSize() != sProjectInfo.aryFloorInfo.GetSize()) return false; // // 比较每一层是否有差异: for (int i = 0; i < (int)aryFloorInfo.GetSize(); i++) { const _SFloorInfo &sfi1 = aryFloorInfo[i]; const _SFloorInfo &sfi2 = sProjectInfo.aryFloorInfo[i]; if (sfi1.strfloorNo.CompareNoCase(sfi2.strfloorNo) != 0 || sfi1.strFloorDoc.CompareNoCase(sfi2.strFloorDoc) != 0 || sfi1.bInFrame != sfi2.bInFrame) return false; if (sfi1.bInFrame) { if (sfi1.ptMin != sfi2.ptMin || sfi1.ptMax != sfi2.ptMax) return false; } } return true; } void SProjectInfo::ReadProjInfo() { TProjectGroupItem *pFloorLst = GetFloorTable(); // 楼层参数,用来取得每个楼层对应得名字 // DList lstFloorData; // GetFloorData(this->lstFloorData); } CDataTable::CDataTable() : m_strCurrDoc(_T("")), m_bOldData(false) { m_dataNoProject.m_pDataTable = this; m_projectInfo.Init(); } CDataTable::~CDataTable() { for (int i = 0; i < m_aryDataAll.GetSize(); i++) { if (m_aryDataAll[i] != NULL) { delete m_aryDataAll[i]; m_aryDataAll[i] = NULL; } } m_aryDataAll.RemoveAll(); } void CDataTable::Clear() { for (int i = 0; i < m_aryDataAll.GetSize(); i++) { if (m_aryDataAll[i] != NULL) { delete m_aryDataAll[i]; m_aryDataAll[i] = NULL; } } m_aryDataAll.RemoveAll(); m_dataNoProject.Clear(); // m_strProjName = _T(""); // m_strProjFullName = _T(""); m_projectInfo.Clear(); m_strCurrDoc = _T(""); m_bSelBox = false; } // 判断数据是否为空 BOOL CDataTable::IsEmptyTable() const { return m_projectInfo.strProjectName.IsEmpty() && m_strCurrDoc.IsEmpty(); } BOOL CDataTable::IsProjChange() const { CString strCurrProj, strCurrDoc, strCurrProjFullName; GetCurrProjAndDoc(strCurrProj, strCurrDoc, strCurrProjFullName); // CString strKeepFull = ProjectFullName(); // CString strKeepProj = return (GetProjFullName().CompareNoCase(strCurrProjFullName) != 0 || GetProjName().CompareNoCase(strCurrProj) != 0); } BOOL CDataTable::IsDocChange() const { CString strCurrProj, strCurrDoc, strCurrProjFullName; GetCurrProjAndDoc(strCurrProj, strCurrDoc, strCurrProjFullName); return (GetDocName().CompareNoCase(strCurrDoc) != 0); } bool CDataTable::IsCurrDocNotInProj() const { XStringList sFiles; ::GetFloorFiles(sFiles); // 所有的DWG XString sCurDoc = curDoc()->fileName(); for (int i = 0; i < sFiles.Length(); i++) { XString str = sFiles[i]; if (str == sCurDoc) return false; } return true; } // 根据楼层添加ID。nFloor是GetFloorTable()中的索引顺序,并非真正的楼层编号 void CDataTable::AddIdByFloor(AcDbObjectIdArray &idAry, int nFloor, CString &floorName, BOOL bCurrDoc, AcDbObjectIdArray *pAryIdBlock) { #ifndef NDEBUG DWORD d1 = GetTickCount(); #endif int i = 0, j = 0; m_aryDataAll[nFloor] = new CGroup(); m_aryDataAll[nFloor]->SetFloorName(floorName); m_aryDataAll[nFloor]->m_bCurrDoc = bCurrDoc; m_aryDataAll[nFloor]->m_pDataTable = this; for (i = 0; i < (int)idAry.length(); i++) { SOpeningProp soprop; EEntType eEntType; AcDbObjectId id = idAry[i]; if (GetDoorWinProp(id, soprop, eEntType) && eEntType >= 0 && eEntType < eDoorTypeNum) { if (pAryIdBlock != NULL && FindIdArry(*pAryIdBlock, id) != -1) soprop.bBlock = true; m_aryDataAll[nFloor]->AddOpening(id, soprop, eEntType); } } #ifndef NDEBUG dwtime += (GetTickCount() - d1); #endif } // 添加不属于工程的数据,只有当前图才考虑添加不属于工程的数据 void CDataTable::AddIdNoProject(AcDbObjectIdArray &idAry, AcDbObjectIdArray *pAryIdBlock) { #ifndef NDEBUG DWORD d1 = GetTickCount(); #endif m_dataNoProject.m_bCurrDoc = TRUE;// 冲突门窗只有本图的。 AcDbObjectId _refID(AcDbObjectId::kNull), _tblRecID(AcDbObjectId::kNull); AcDbEntity *_pEnt = NULL; AcDbBlockTableRecord *_pTblRec = NULL; for (int i = 0; i < (int)idAry.length(); i++) { SOpeningProp soprop; EEntType eEntType; _refID = idAry[i]; if (GetDoorWinProp(idAry[i], soprop, eEntType) && eEntType >= 0 && eEntType < eDoorTypeNum) { if (pAryIdBlock != NULL && FindIdArry(*pAryIdBlock, idAry[i]) != -1) { // 下面判断是否是dwg文件参照块 acdbOpenObject(_pEnt, _refID, AcDb::kForRead); if (_pEnt) { AcDbObjectId idtmp = _pEnt->ownerId(); acdbOpenObject(_pTblRec, idtmp, AcDb::kForRead); if (_pTblRec) { LPCTSTR scomm; _pTblRec->getName(scomm); CString sName = scomm; //LH 20120925 转换字符串均为小写 sName.MakeLower(); if (sName.CompareNoCase(_T("*model_space")) == 0 || -1 != sName.Find(_T('|'))) soprop.bExternBlock = true; else soprop.bExternBlock = false; _pTblRec->close(); } _pEnt->close(); } soprop.bBlock = true; } m_dataNoProject.AddOpening(idAry[i], soprop, eEntType); } } #ifndef NDEBUG dwtime += (GetTickCount() - d1); #endif } void CDataTable::SetFloorNum(int n) { if (n > 0) { m_aryDataAll.SetSize(n); for (int i = 0; i < (int)m_aryDataAll.GetSize(); i++) m_aryDataAll[i] = NULL; } } int CDataTable::GetFloorNum() const { return (int)m_aryDataAll.GetSize(); } CGroup* CDataTable::GetFloor(int nFloor) const { return m_aryDataAll[nFloor]; } // 本工程的数据包含的所有的门窗类型 int CDataTable::FindETypeProj(AryEtype &aryEType) const { BOOL bFlag[eDoorTypeNum]; memset(bFlag, 0, sizeof(BOOL)*eDoorTypeNum); for (int i = 0; i < (int)m_aryDataAll.GetSize(); i++) { for (int j = 0; j < eDoorTypeNum; j++) { if (GetFloor(i) != NULL && !IsEmpty(m_aryDataAll[i]->GetItemAry(eDoorTypeNum))) { bFlag[j] = TRUE; } } } for (int k = 0; k < eDoorTypeNum; k++) { EEntType eEntType = EEntType(k); if (bFlag[k]) aryEType.Add(eEntType); } return (int)aryEType.GetSize(); } int CDataTable::FindETypeDwg(AryEtype &aryEType) const { BOOL bFlag[eDoorTypeNum]; memset(bFlag, 0, sizeof(BOOL)*eDoorTypeNum); for (int i = 0; i < (int)m_aryDataAll.GetSize(); i++) { if (GetFloor(i) == NULL || !m_aryDataAll[i]->IsCurrDoc()) continue; for (int j = 0; j < eDoorTypeNum; j++) { if (!IsEmpty(m_aryDataAll[i]->GetItemAry(eDoorTypeNum))) { bFlag[j] = TRUE; } } } for (int k = 0; k < eDoorTypeNum; k++) { EEntType eEntType = EEntType(k); if (bFlag[k]) aryEType.Add(eEntType); } return (int)aryEType.GetSize(); } int CDataTable::FindETypeNoProj(AryEtype &aryEtype) const { for (int i = 0; i < eDoorTypeNum; i++) { if (!IsEmpty(m_dataNoProject.GetItemAry(EEntType(i)))) { EEntType eEntType = EEntType(i); aryEtype.Add(eEntType); } } return (int)aryEtype.GetSize(); } int CDataTable::FindEType(AryWidItemPtr widItemPtr[eDoorTypeNum], AryEtype &aryEtype) { for (int i = 0; i < eDoorTypeNum; i++) { AryWidItemPtr &widItemPtrCurr = widItemPtr[i]; if (!IsEmpty(widItemPtrCurr)) { EEntType eEntType = EEntType(i); aryEtype.Add(eEntType); } } return (int)aryEtype.GetSize(); } // 合并本工程的所有的数据,不分楼层。 void CDataTable::GetDataPNf(AryWidItemPtr doors[eDoorTypeNum]) const { for (int i = 0; i < (int)m_aryDataAll.GetSize(); i++) { // 遍历AllData; CGroup *pFloor = m_aryDataAll[i]; if (pFloor == NULL) continue; for (int iType = 0; iType < eDoorTypeNum; iType++) { // 添加本类型 AryItemPtr &aryItemPtr = const_cast(pFloor->GetItemAry(EEntType(iType))); for (int k = 0; k < (int)aryItemPtr.GetSize(); k++) { AddItemToWidItemAry(doors[iType], aryItemPtr[k]); } } } } void CDataTable::GetDataPF(AryAllData &data) const { data.Append(m_aryDataAll); } // 工程内冲突工程数据 void CDataTable::GetConflictProj(AryWidItemPtr widItem[eDoorTypeNum]) const {// 合并所有的数据,取出其中冲突的 for (int i = 0; i < eDoorTypeNum; i++) { for (int j = 0; j < (int)m_aryDataAll.GetSize(); j++) { if (GetFloor(j) == NULL) continue; AryItemPtr &aryItem = const_cast(m_aryDataAll[j]->GetItemAry(EEntType(i))); for (int k = 0; k < (int)aryItem.GetSize(); k++) { if (aryItem[k]->bConflict) AddItemToWidItemAry(widItem[i], aryItem[k]); } } } } // 获取工程内本图的数据,分楼层 void CDataTable::GetDataDPF(AryAllData &data) const { for (int i = 0; i < (int)m_aryDataAll.GetSize(); i++) { if (m_aryDataAll[i] != NULL && m_aryDataAll[i]->IsCurrDoc()) data.Add(const_cast(m_aryDataAll[i]) ); } } // 获取工程内本图内不分楼层的数据 void CDataTable::GetCurrDPNf(AryWidItemPtr widItem[eDoorTypeNum]) const { for (int i = 0; i < eDoorTypeNum; i++) { for (int j = 0; j < (int)m_aryDataAll.GetSize(); j++) { CGroup *pFloor = m_aryDataAll[j]; if (pFloor == NULL || !pFloor->IsCurrDoc()) continue; AryItemPtr &aryItemPtrCurr = const_cast(pFloor->GetItemAry(EEntType(i))); for (int k = 0; k < (int)aryItemPtrCurr.GetSize(); k++) { AddItemToWidItemAry(widItem[EEntType(i)], aryItemPtrCurr[k]); } } } } // 工程内本图内冲突数据 void CDataTable::GetConflictDP(AryWidItemPtr widItem[eDoorTypeNum]) const { for (int i = 0; i < eDoorTypeNum; i++) { for (int j = 0; j < (int)m_aryDataAll.GetSize(); j++) { CGroup *pFloor = m_aryDataAll[j]; if (pFloor == NULL || !pFloor->IsCurrDoc()) continue; AryItemPtr &aryItem = const_cast(pFloor->GetItemAry(EEntType(i))); for (int k = 0; k < (int)aryItem.GetSize(); k++) { if (aryItem[k]->bConflict) AddItemToWidItemAry(widItem[i], aryItem[k]); } } } } // 获取全部本图数据,不管工程, void CDataTable::GetDataDNpNf(AryWidItemPtr widItem[eDoorTypeNum]) const { for (int i = 0; i < eDoorTypeNum; i++) { for (int j = -1; j < (int)m_aryDataAll.GetSize(); j++) { const CGroup *pFloor = NULL; if (j == -1) pFloor = (&m_dataNoProject); else pFloor = m_aryDataAll[j]; if (pFloor == NULL || !pFloor->IsCurrDoc()) continue; AryItemPtr &aryItemPtrCurr = const_cast(pFloor->GetItemAry(EEntType(i))); for (int k = 0; k < (int)aryItemPtrCurr.GetSize(); k++) { AddItemToWidItemAry(widItem[EEntType(i)], aryItemPtrCurr[k]); } } } } // 全部本图的冲突数据 void CDataTable::GetConflictDNp(AryWidItemPtr widItem[eDoorTypeNum]) const { for (int i = 0; i < eDoorTypeNum; i++) { for (int j = -1; j < (int)m_aryDataAll.GetSize(); j++) { const CGroup *pFloor = NULL; if (j == -1) pFloor = (&m_dataNoProject); else pFloor = m_aryDataAll[j]; if (pFloor == NULL || !pFloor->IsCurrDoc()) continue; AryItemPtr &aryItem = const_cast(pFloor->GetItemAry(EEntType(i))); for (int k = 0; k < (int)aryItem.GetSize(); k++) { if (aryItem[k]->bConflict) AddItemToWidItemAry(widItem[i], aryItem[k]); } } } } // 获取未创建工程数据 void CDataTable::GetDataNp(AryWidItemPtr widItem[eDoorTypeNum]) const { for (int i = 0; i < eDoorTypeNum; i++) { ItemPtrAry2Wid(m_dataNoProject.GetItemAry(EEntType(i)), widItem[i]); } } // 未创建工程的冲突数据 void CDataTable::GetConflictNoProj(AryWidItemPtr widItem[eDoorTypeNum]) const { for (int i = 0; i < eDoorTypeNum; i++) { AryItemPtr& aryItem = const_cast(m_dataNoProject.GetItemAry(EEntType(i))); for (int j = 0; j < (int)aryItem.GetSize(); j++) { if ((aryItem[j])->bConflict) AddItemToWidItemAry(widItem[i], aryItem[j]); } } } // 根据当前的形式计算冲突数据,在CItem中设置标记 void CDataTable::CalcConflictData() { // 1、得到要排序的数据集合, _AryDataStruct aryDataStruct; bool bProj = IsSelData() ? false : IsCheckProj(); GetAryDataStruct(aryDataStruct, IsCheckDWG(), bProj, IsCheckText(), IsCheckBlock()); // 2、对这些数据按照编号进行排序 _DataStruct *pData = aryDataStruct.GetData(); qsort(pData, (size_t)aryDataStruct.GetSize(), sizeof(_DataStruct), CDataTable::Cmp_DataStruct); // 3、同名数据检测冲突,并且在CItem中设置冲突标记。 CString strName; if (!IsEmpty(aryDataStruct)) strName = aryDataStruct[0].prop->pItem->strLabel; int iStart = 0; for (int i = 0; i < (int)aryDataStruct.GetSize()+1; i++) { if ((i == (int)aryDataStruct.GetSize()) || (strName.CompareNoCase(aryDataStruct[i].prop->pItem->strLabel) != 0) ) { // 比较从iStart到i【)这段数据的冲突性 // 循环检测: int iTestStart = iStart; int iTestEnd = i; // bool bConflict = false; for (iTestStart; iTestStart < iTestEnd - 1; iTestStart++) { _DataStruct *pDs1 = &(aryDataStruct[iTestStart]); for (int j = iTestStart+1; j < iTestEnd; j++) { _DataStruct *pDs2 = &(aryDataStruct[j]); if (pDs1->prop->pItem->eDoorWinType != pDs2->prop->pItem->eDoorWinType) { bConflict = true; break; } else { if (TestConflict(pDs1->prop->pItem->eDoorWinType, *(pDs1->prop), *(pDs2->prop))) { bConflict = true; break; } } } if (bConflict) break; } iTestStart = iStart; iTestEnd = i; for (iTestStart; iTestStart < iTestEnd; iTestStart++) { aryDataStruct[iTestStart].prop->pItem->bConflict = bConflict;// 设置冲突标记 } if (i < (int)aryDataStruct.GetSize()) { strName = aryDataStruct[i].prop->pItem->strLabel; iStart = i; } } } } // // // 获取本图不分楼层的数据 // void CDataTable::GetNoFloorCurrProj(AryWidItemPtr widItem[eDoorTypeNum]) const // { // for (int i = 0; i < eDoorTypeNum; i++) // { // for (int j = 0; j < (int)m_aryDataAll.GetSize(); j++) // { // CGroup *pFloor = m_aryDataAll[j]; // if (pFloor == NULL) // continue; // // AryItemPtr &aryItemPtrCurr = const_cast(pFloor->GetItemAry(EEntType(i))); // for (int k = 0; k < (int)aryItemPtrCurr.GetSize(); k++) // { // AddItemToWidItemAry(widItem[EEntType(i)], aryItemPtrCurr[k]); // } // } // } // } // 判断有没有未创建工程的数据 BOOL CDataTable::HasNoProjData() const { for (int i = 0; i < eDoorTypeNum; i++) { if (!IsEmpty(m_dataNoProject.GetItemAry(EEntType(i)))) return TRUE; } return FALSE; } int CDataTable::Cmp_DataStruct(const void *ds1, const void *ds2) { _DataStruct *pDataStruct1 = (_DataStruct*)ds1; _DataStruct *pDataStruct2 = (_DataStruct*)ds2; // 注意这里使用过的是CItem中的编号,因为prop中的编号是可能为空的。 return pDataStruct1->prop->pItem->strLabel.CompareNoCase(pDataStruct2->prop->pItem->strLabel); } //enum EDataChange {eProjChange = 0x01, eDocChange = 0x02, eLabelChange = 0x04}; DWORD CDataTable::Compare(const CDataTable &dataTable) const { DWORD dwFlag = 0; // if (this->GetProjFullName().CompareNoCase(dataTable.GetProjFullName()) != 0) // CDataTable::SetDataChange(dwFlag, eProjChange, TRUE); if (!this->m_projectInfo.Compare(dataTable.m_projectInfo)) CDataTable::SetDataChange(dwFlag, eProjChange, TRUE); if (this->GetDocName().CompareNoCase(dataTable.GetDocName()) != 0) CDataTable::SetDataChange(dwFlag, eDocChange, TRUE); if (!TestDataChange(dwFlag, eProjChange) && !TestDataChange(dwFlag, eDocChange)) { DWORD dwDataFlag = this->DataCompare(dataTable, IsCheckDWG(), IsCheckProj(), IsCheckText(), IsCheckBlock()); dwFlag |= dwDataFlag; } return dwFlag; } // 比较数据查看是否有以下问题 // 编号修改,实体添加,实体删除,实体属性修改。 DWORD CDataTable::DataCompare(const CDataTable &dataTable, bool bOnlyDWG, bool bOnlyProj, bool bNeedText, bool bNeedBlock) const { DWORD dwFlagRet = 0; _AryDataStruct _aryDataStruct1, _aryDataStruct2; this->GetAryDataStruct(_aryDataStruct1, bOnlyDWG, bOnlyProj, bNeedText, bNeedBlock); dataTable.GetAryDataStruct(_aryDataStruct2, bOnlyDWG, bOnlyProj, bNeedText, bNeedBlock); int iIndex = 0; for (iIndex = 0; iIndex < (int)_aryDataStruct1.GetSize(); iIndex++) { if (!_aryDataStruct1[iIndex].prop->pItem->pGroup->IsCurrDoc()) continue; SOpeningProp *pProp = GetProp(_aryDataStruct2, _aryDataStruct1[iIndex].id); if (pProp == NULL) { // 新的数据里找不到该数据,判断为删除 SetDataChange(dwFlagRet, eIdDel, TRUE); #ifndef NDEBUG ads_printf(_T("Add id Num: %d \n"), _aryDataStruct1[iIndex].id.asOldId()); #endif } else { CString strLabelTemp = _aryDataStruct1[iIndex].prop->strLabel; if (strLabelTemp.IsEmpty()) { strLabelTemp = GetDoorWinSizeLabel(_aryDataStruct1[iIndex].eEntType, *(_aryDataStruct1[iIndex].prop)); } if (pProp->pItem->strLabel.CompareNoCase(strLabelTemp) != 0) SetDataChange(dwFlagRet, eLabelChange, TRUE); else { for (int j = 0; j < eDoorWinParmNum; j++) { CString str1 = PropToString(*pProp, GetShowItem(EShowItem(j))); CString str2 = PropToString(*_aryDataStruct1[iIndex].prop, GetShowItem(EShowItem(j))); if (str1.CompareNoCase(str2) != 0) { SetDataChange(dwFlagRet, ePropChange, TRUE); break; } } if ((pProp->str2DShowStyle.CompareNoCase(_aryDataStruct1[iIndex].prop->str2DShowStyle) != 0) || (pProp->str3DShowStyle.CompareNoCase(_aryDataStruct1[iIndex].prop->str3DShowStyle) != 0)) { SetDataChange(dwFlagRet, ePropChange, TRUE); } } } } for (iIndex = 0; iIndex < (int)_aryDataStruct2.GetSize(); iIndex++) { if (!_aryDataStruct2[iIndex].prop->pItem->pGroup->IsCurrDoc()) continue; SOpeningProp *pProp = GetProp(_aryDataStruct1, _aryDataStruct2[iIndex].id); if (pProp == NULL) { // 旧的数据里找不到该数据,判断为添加 SetDataChange(dwFlagRet, eIdAdd, TRUE); #ifndef NDEBUG ads_printf(_T("Del id Num: %d \n"), _aryDataStruct2[iIndex].id.asOldId()); #endif } } //add by lgy 20120306 如果删除了同名块参照或者外部参照,应该处理为删除了实体,而现有程序无法处理该种情况 if ((int)_aryDataStruct1.GetSize() != (int)_aryDataStruct2.GetSize())//重新获得的数据和原有数据其中实体个数是否一样 { if (dwFlagRet == 0) //重新获得的实体个数跟原有实体个数不一致,并且标志却没有改变,认为是删除或者添加了参照 { SetDataChange(dwFlagRet, eIdDel, TRUE); } } return dwFlagRet; } BOOL CDataTable::TestDataChange(const DWORD dwFlag, EDataChange eChange) { return dwFlag & eChange; } void CDataTable::SetDataChange(DWORD &dwFlag, EDataChange eChange, BOOL bSet) { if (bSet) { dwFlag |= eChange; } else { dwFlag &= (~eChange); } } // 更新属性:更新属性中除了编号之外的其他内容,只更新当前文档 void CDataTable::UpdateProp(const CDataTable &dataTable) { _AryDataStruct _aryDataStruct1, _aryDataStruct2; this->GetAryDataStruct(_aryDataStruct1, true, false, true, true); dataTable.GetAryDataStruct(_aryDataStruct2, true, false, true, true); int iIndex = 0; for (iIndex = 0; iIndex < (int)_aryDataStruct1.GetSize(); iIndex++) { SOpeningProp *pProp = GetProp(_aryDataStruct2, _aryDataStruct1[iIndex].id); if (pProp != NULL) { SOpeningProp *thisProp = _aryDataStruct1[iIndex].prop; thisProp->nHei = pProp->nHei; thisProp->nWid = pProp->nWid; thisProp->nEle = pProp->nEle; thisProp->strType = pProp->strType; thisProp->eProWinGeo = pProp->eProWinGeo; thisProp->nChuTiaoChang = pProp->nChuTiaoChang; thisProp->nTixingkuan = pProp->nTixingkuan; thisProp->str3DShowStyle = pProp->str3DShowStyle; thisProp->str2DShowStyle = pProp->str2DShowStyle; thisProp->bZJCTuChuang = pProp->bZJCTuChuang; } } } void CDataTable::FilterId(AcDbObjectIdArray &idArray) { // AcDbObjectIdArray idArray; // ss.AsIdArray(idArray); for (int i = 0; i < (int)m_aryDataAll.GetSize(); i++) { CGroup *pGroup = m_aryDataAll[i]; if (pGroup == NULL || !pGroup->IsCurrDoc()) { m_aryDataAll.RemoveAt(i--); delete pGroup; pGroup = NULL; } else pGroup->FilterId(idArray); } m_dataNoProject.FilterId(idArray); } int CDataTable::GetNoNameLabeNum(bool bOnlyDWG, bool bOnlyProj, bool bNeedText, bool bNeedBlock) const { _AryDataStruct aryDataStruct; GetAryDataStruct(aryDataStruct, bOnlyDWG, bOnlyProj, bNeedText, bNeedBlock); int nNum = 0; for (int i = 0; i < (int)aryDataStruct.GetSize(); i++) { if (aryDataStruct[i].prop->strLabel.IsEmpty()) nNum++; } return nNum; } bool CDataTable::TestHasData(bool bOnlyDWG, bool bOnlyProj, bool bNeedText, bool bNeedBlock) const { _AryDataStruct aryDataStruct; GetAryDataStruct(aryDataStruct, bOnlyDWG, bOnlyProj, bNeedText, bNeedBlock); return !IsEmpty(aryDataStruct); } bool CDataTable::HasFloor() const { return !IsEmpty(m_aryDataAll); } // 检测是否有未创建工程的数据。 bool CDataTable::TestHasNoProjData(bool bNeedText, bool bNeedBlock) const { for (int i = 0; i < eDoorTypeNum; i++) { const AryItemPtr &aryItemPtr = m_dataNoProject.GetItemAry(EEntType(i)); for (int j = 0; j < (int)aryItemPtr.GetSize(); j++) { CItem *pItem = aryItemPtr[j]; if (pItem != NULL) { if (pItem->HasItem(bNeedText, bNeedBlock)) return true; } } } return false; // 空的情况。 } void CDataTable::SetFileInfo() { CString strCurrProj, strCurrDoc, strCurrProjFullName; GetCurrProjAndDoc(strCurrProj, strCurrDoc, strCurrProjFullName); SetProjName(strCurrProj); SetDocName(strCurrDoc); SetProjFullName(strCurrProjFullName); SetSelFlag(false); // 非框选 } void CDataTable::ClearNullFloor() { for (int i = 0; i < (int)m_aryDataAll.GetSize(); i++) { if (m_aryDataAll[i] == NULL) m_aryDataAll.RemoveAt(i--); } } void CDataTable::AddFloorInfo(CString strFloorNo, CString strFloorDoc, bool bInFrame, const XPoint &ptMin, const XPoint &ptMax) { if (bInFrame) m_projectInfo.AddFloorByRange(strFloorNo, strFloorDoc, ptMin, ptMax); else m_projectInfo.AddFloorInfoByDoc(strFloorNo, strFloorDoc); } SOpeningProp* CDataTable::GetProp(CDataTable::_AryDataStruct &_aryDataStruct, const AcDbObjectId &id) { for (int i = 0; i < (int)_aryDataStruct.GetSize(); i++) { if (_aryDataStruct[i].id.asOldId() == id.asOldId()) return _aryDataStruct[i].prop; } return NULL; } void CDataTable::GetAryDataStruct(CDataTable::_AryDataStruct &aryDataStruct, bool bOnLyDWG, bool bOnLyProj, bool bNeedText, bool bNeedBlock)const { _DataStruct dsTemp; for (int iFloor = 0; iFloor < (int)m_aryDataAll.GetSize(); iFloor++) { CGroup *pGroup = m_aryDataAll[iFloor]; if (pGroup == NULL) continue; if (bOnLyDWG && !pGroup->IsCurrDoc()) continue; for (int iType = 0; iType < eDoorTypeNum; iType++) { const AryItemPtr& aryItemPtr = pGroup->GetItemAry(EEntType(iType)); for (int iItem = 0; iItem < (int)aryItemPtr.GetSize(); iItem++) { CItem *pItem = aryItemPtr[iItem]; for (int iId = 0; iId < (int)pItem->aryId.length(); iId++) { if (pItem->aryProp[iId].bText && !bNeedText) continue; dsTemp.id = pItem->aryId[iId]; dsTemp.prop = &(pItem->aryProp[iId]); dsTemp.eEntType = pItem->eDoorWinType; aryDataStruct.Add(dsTemp); } } } } if (!bOnLyProj) { for (int iType = 0; iType < eDoorTypeNum; iType++) { const AryItemPtr& aryItemPtr = m_dataNoProject.GetItemAry(EEntType(iType)); for (int iItem = 0; iItem < (int)aryItemPtr.GetSize(); iItem++) { CItem *pItem = aryItemPtr[iItem]; for (int iId = 0; iId < (int)pItem->aryId.length(); iId++) { if (pItem->aryProp[iId].bText && !bNeedText) continue; dsTemp.id = pItem->aryId[iId]; dsTemp.prop = &(pItem->aryProp[iId]); dsTemp.eEntType = pItem->eDoorWinType; aryDataStruct.Add(dsTemp); } } } } } void CDataTable::ClearFloorDataAry(AryAllData &aryData) { for (int i = 0; i < (int)aryData.GetSize(); i++) { CGroup *pGroup = aryData[i]; delete pGroup; } aryData.RemoveAll(); } void GetOpeningIdListNew(DList &dbList, DList &idList) { XStringList lstFiles; ::GetFloorFiles(lstFiles); CString sCurDwg=curDoc()->fileName(); for(int i=0; ireadDwgFile(lstFiles[i], _SH_DENYNO, false)==Acad::eOk) #else if (dwgDb->readDwgFile(lstFiles[i], AcDbDatabase::kForReadAndAllShare, false)==Acad::eOk) #endif { GetEntityFromDatabase(idList, *dwgDb, _T("TCH_OPENING"), 0, ACDB_MODEL_SPACE); } } GetEntFromBlockByDxf(idList, _T("TCH_OPENING")); } // 构建跟pFloorLst对应的DWG列表 void BulidFloorFile(CStringArray &aryDWG, TProjectGroupItem *pFloorLst, DList &lstFloorData) { if (pFloorLst == NULL || pFloorLst->GetDataNum() == 0) return; aryDWG.SetSize(pFloorLst->GetDataNum()); int i = 0, j = 0; // 查找FloorList中每个数据所对应的DWG文件, for (i=0; iGetDataNum(); i++) { TProjectFloor *pFloor = (TProjectFloor *)pFloorLst->GetAt(i); DList lstFloor; // 对应的多个楼层,比较第一个就可以 if (StrToIntList(pFloor->GetLayerNo(), lstFloor)) { int iFloor = *(lstFloor[0]); for (j = 0; j < lstFloorData.Length(); j++) { if (lstFloorData[j]->m_nIndex == iFloor) { aryDWG[i] = lstFloorData[j]->m_sDwgFile; break; } } } } } int IdCmp(const AcDbObjectId *id1, const void *_id2) { AcDbObjectId *id2 = (AcDbObjectId*)_id2; if (id1->asOldId() == id2->asOldId()) return 0; else return 1; } void GetCurrProjAndDoc(CString &strCurrProj, CString &strCurrDoc, CString &strCurrProjFullName) { strCurrDoc = curDoc()->fileName(); strCurrProj = ProjectName(); strCurrProjFullName = ProjectFullName(); } BOOL TextLayCompare(CString &strTextLay); bool FilterDoorWinText(AcDbEntity *pTextEnt) { if (pTextEnt == NULL) return false; CString strText; if (pTextEnt->isKindOf(TDbText::desc())) { strText = TDbText::cast(pTextEnt)->GetText(); } else if (pTextEnt->isKindOf(AcDbText::desc())) { strText = AcDbText::cast(pTextEnt)->textString(); } else { return false; } // lgh 修改了参数图层的替换条件 if (TextLayCompare(CString(pTextEnt->layer())) && CheckName(strText)) { return true; } else return false; // if ((strLayer1.Compare(pTextEnt->layer()) == 0 || strLayer2.Compare(pTextEnt->layer()) == 0) && // CheckName(strText)) // return true; // else return false; } bool FilterDoorWinText(AcDbObjectId &idText) { OPENOBJ_BEGIN(idText, AcDb::kForRead, AcDbEntity, pEnt) return FilterDoorWinText(pEnt); OPENOBJ_END() return false; } void FilterDoorWinText(AcDbObjectIdArray &aryId) { for (long iT = 0; iT < (int)aryId.length(); iT++) { if (!FilterDoorWinText(aryId[iT])) { aryId.removeAt(iT--); } } } void FilterDoorWinText(DList &lstId) { for (long iT = 0; iT < lstId.Length(); iT++) { if (!FilterDoorWinText(*(lstId[iT]))) { lstId.Remove(iT--); } } } void GetDoorWinIdsAll(AcDbObjectIdArray &aryIdAll, XPoint ptMin, XPoint ptMax) { #ifndef NDEBUG DWORD d1 = GetTickCount(); #endif XPoint _ptMax = Max(ptMax, ptMin); XPoint _ptMin = Min(ptMax, ptMin); ptMin = _ptMin; ptMax = _ptMax; GetViewSafeSelection(aryIdAll, TRUE, ptMin, ptMax, _T("TCH_OPENING,TCH_DORMER,TCH_CORNER_WINDOW,TCH_TEXT,TEXT,INSERT"), 1); for (int i = 0; i < (int)aryIdAll.length(); i++) { OPENOBJ_BEGIN(aryIdAll[i], AcDb::kForRead, AcDbEntity, pEnt) { if (pEnt->isKindOf(AcDbText::desc()) || pEnt->isKindOf(TDbText::desc())) { if (FilterDoorWinText(pEnt)) continue; else aryIdAll.removeAt(i--); } } OPENOBJ_END() } #ifndef NDEBUG dwRead += (GetTickCount() - d1); dwRead1 += (GetTickCount() - d1); #endif } void GetDoorWinIdsNoBlock(AcDbObjectIdArray &aryIdsNoblock, AcDbDatabase *pDataBase, XPoint ptMin, XPoint ptMax) { #ifndef NDEBUG DWORD d1 = GetTickCount(); #endif DList lstIdAll; GetEntityFromDatabase(lstIdAll, *pDataBase, _T("TCH_OPENING,TCH_CORNER_WINDOW,TCH_DORMER"), 1, ACDB_MODEL_SPACE, ptMin, ptMax); int i = 0; #ifndef NDEBUG for (i = 0; i < (int)lstIdAll.Length(); i++) { acutPrintf(_T("ID%d: = %d\t"), i, lstIdAll[i]->asOldId()); } #endif DList lstTextId; GetEntityFromDatabase(lstTextId, *pDataBase, _T("TCH_TEXT,TEXT"), 1, ACDB_MODEL_SPACE, ptMin, ptMax); FilterDoorWinText(lstTextId); lstIdAll << lstTextId; // 所有的ID,不带block for (i = 0; i < (int)lstIdAll.Length(); i++) { aryIdsNoblock.append(*(lstIdAll[i])); } #ifndef NDEBUG dwRead += (GetTickCount() - d1); dwRead2 += (GetTickCount() - d1); #endif } void GetDoorWinIds(AcDbObjectIdArray &aryIdAll, AcDbObjectIdArray &aryIdBlock) { #ifndef NDEBUG DWORD d1 = GetTickCount(); #endif XPoint ptMax = curDoc()->database()->extmax(); XPoint ptMin = curDoc()->database()->extmin(); double dExtx = (ptMax.x - ptMin.x) * 0.1; double dExty = (ptMax.y - ptMin.y) * 0.1; ptMin.x -= dExtx; ptMin.y -= dExty; ptMax.x += dExtx; ptMax.y += dExty; // 读出所有的实体的ID,包括块内实体。块内实体如果有多个,会重复列出。 GetDoorWinIdsAll(aryIdAll, ptMin, ptMax); AcDbObjectIdArray aryIdNoBlock; GetDoorWinIdsNoBlock(aryIdNoBlock, curDoc()->database(), ptMin, ptMax); for (int i = 0; i < (int)aryIdAll.length(); i++) { if (FindIdArry(aryIdNoBlock, aryIdAll[i]) == -1) { aryIdBlock.append(aryIdAll[i]); } } #ifndef NDEBUG // dwRead += (GetTickCount() - d1); #endif } // 下面的算法设计考虑了一下效率的问题:因为一个图形可能会对应多个楼层, // 所以希望打开一个图形的时候,能够一次读出该图形中所有的楼层,而不用多次打开一个图形。 void GetOpeningDataTable(CDataTable &dataTable) { #ifndef NDEBUG dwtime = 0; dwRead = 0; #endif CString strCurrProj, strCurrDoc, strCurrProjFullName; GetCurrProjAndDoc(strCurrProj, strCurrDoc, strCurrProjFullName); dataTable.SetProjName(strCurrProj); dataTable.SetDocName(strCurrDoc); dataTable.SetProjFullName(strCurrProjFullName); dataTable.SetSelFlag(false); // 非框选 if (IsEmptyProject()) { // 没有工程,则本图全部数据都是未创建工程数据 // DList lstId; AcDbObjectIdArray aryIdAll, aryIDBlock; GetDoorWinIds(aryIdAll, aryIDBlock); dataTable.AddIdNoProject(aryIdAll, &aryIDBlock); } else { // 本工程, // 读取工程文件的算法有些诡异,为了保证每个文件不被多次打开(效率问题),使用一下方法: // 读取所有的楼层,和楼层对应的文件; // 读取所有的文件, // 遍历所有的文件,跟楼层表对应,如果某楼层在该文件内,则读取该楼层的数据。 // 另外本图需要识别工程内,和工程外。 // 因为需要识别本图未创建工程数据,因此,总是需要打开楼层列表,检测不在楼层列表的数据。 // 楼层列表,用它来跟XFloorData匹配检测对应的文档 TProjectGroupItem *pFloorLst = GetFloorTable(); CStringArray aryDWGPath; // 跟楼层对应,每个楼层所对应的floor文件 // 楼层参数,用来取得每个楼层对应得名字 DList lstFloorData; GetFloorData(lstFloorData); // 构建了楼层对应的DWG数组,就可以用该数组来打开对应的文件。 BulidFloorFile(aryDWGPath, pFloorLst, lstFloorData); dataTable.SetFloorNum((int)aryDWGPath.GetSize()); DList dbList; // 本工程的Database;保持打开的状态,以保存ID XStringList lstFiles; ::GetFloorFiles(lstFiles); // 所有的DWG CString sCurDwg=curDoc()->fileName(); int i = 0, j = 0; bool bFindCurrDoc = false; for(i=0; iGetAt(j); if (pFloor != NULL) { XPoint ptMin, ptMax; if (!pFloor->IsFloorInFrame()) { ptMax = curDoc()->database()->extmax(); ptMin = curDoc()->database()->extmin(); } else pFloor->GetRange(ptMin, ptMax); AcDbObjectIdArray aryIdFloor; GetDoorWinIdsAll(aryIdFloor, ptMin, ptMax); dataTable.AddIdByFloor(aryIdFloor, j, pFloor->GetLayerNo(), TRUE, &aryIDBlock); dataTable.AddFloorInfo(pFloor->GetLayerNo(), lstFiles[i], pFloor->IsFloorInFrame(), ptMin, ptMax); // 从中删除属于楼层的ID,剩余的都是不在工程中的ID; for (int k = 0; k < (int)aryIdFloor.length(); k++) { int nPos = FindIdArry(aryIdAll, aryIdFloor[k]); if (nPos != -1) aryIdAll.removeAt(nPos); } } } } // end read DWG; dataTable.AddIdNoProject(aryIdAll, &aryIDBlock); // 当前图层的所有的ID } else { // 其他图只读取工程内的数据 AcDbDatabase *dwgDb=new AcDbDatabase(false, true); dbList.Append(dwgDb); #if ADS < 21 if (dwgDb->readDwgFile(lstFiles[i], _SH_DENYNO, false)==Acad::eOk) #else if (dwgDb->readDwgFile(lstFiles[i], AcDbDatabase::kForReadAndAllShare, false)==Acad::eOk) #endif { for (j = 0; j < (int)aryDWGPath.GetSize(); j++) { // 打开该图形对应的所有的楼层 if (aryDWGPath[j].CompareNoCase(lstFiles[i]) == 0) { TProjectFloor *pFloor = (TProjectFloor *)pFloorLst->GetAt(j); if (pFloor != NULL) { DList idList; XPoint ptMin, ptMax; if (!pFloor->IsFloorInFrame()) { ptMax = dwgDb->extmax(); ptMin = dwgDb->extmin(); } else pFloor->GetRange(ptMin, ptMax); AcDbObjectIdArray aryIdFloor; // 其他图中无提供读取块实体的接口 GetDoorWinIdsNoBlock(aryIdFloor, dwgDb, ptMin, ptMax); dataTable.AddIdByFloor(aryIdFloor, j, pFloor->GetLayerNo(), FALSE, NULL); dataTable.AddFloorInfo(pFloor->GetLayerNo(), lstFiles[i], pFloor->IsFloorInFrame(), ptMin, ptMax); } } } } // end read dwg; } }// end for(i=0; iCreate(NULL, _T("门窗检查"), WS_OVERLAPPEDWINDOW, CRect(0, 0, 480, 600), acedGetAcadDwgView()); } // 如果没有的话,则显示出来。 // if (!pFrame->IsWindowVisible()) { pFrame->ReadDWG(); pFrame->ShowWindow(SW_SHOWNORMAL); } #ifndef NDEBUG ads_printf(XString(_T("\n窗口显示的时间:%d"), GetTickCount() - d1)); #endif } void CloseDoorWindow() { if (pFrame != NULL) { pFrame->DestroyWindow(); pFrame = NULL; } }