2897 lines
72 KiB
C++
2897 lines
72 KiB
C++
#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<AcDbObjectId> &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<AcDbObjectId> &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<SOpeningProp&>(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<AcDbObjectId> &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<XFloorData> 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<AryItemPtr&>(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<AryItemPtr &>(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<CGroup*>(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<AryItemPtr&>(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<AryItemPtr&>(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<AryItemPtr&>(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<AryItemPtr&>(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<AryItemPtr&>(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<AryItemPtr&>(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<AcDbDatabase> &dbList, DList<AcDbObjectId> &idList)
|
|
{
|
|
XStringList lstFiles;
|
|
::GetFloorFiles(lstFiles);
|
|
CString sCurDwg=curDoc()->fileName();
|
|
for(int i=0; i<lstFiles.Length(); i++)
|
|
{
|
|
LPCTSTR szddd = lstFiles[i];
|
|
if (_tcsicmp(sCurDwg, lstFiles[i])==0)
|
|
continue; // Disalbe CurDwg
|
|
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
|
|
{
|
|
GetEntityFromDatabase(idList, *dwgDb, _T("TCH_OPENING"), 0, ACDB_MODEL_SPACE);
|
|
}
|
|
}
|
|
|
|
GetEntFromBlockByDxf(idList, _T("TCH_OPENING"));
|
|
}
|
|
|
|
// 构建跟pFloorLst对应的DWG列表
|
|
void BulidFloorFile(CStringArray &aryDWG, TProjectGroupItem *pFloorLst, DList<XFloorData> &lstFloorData)
|
|
{
|
|
if (pFloorLst == NULL || pFloorLst->GetDataNum() == 0)
|
|
return;
|
|
|
|
aryDWG.SetSize(pFloorLst->GetDataNum());
|
|
|
|
int i = 0, j = 0;
|
|
// 查找FloorList中每个数据所对应的DWG文件,
|
|
for (i=0; i<pFloorLst->GetDataNum(); i++)
|
|
{
|
|
TProjectFloor *pFloor = (TProjectFloor *)pFloorLst->GetAt(i);
|
|
|
|
DList<int> 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<AcDbObjectId> &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<AcDbObjectId> 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<AcDbObjectId> 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<AcDbObjectId> lstId;
|
|
AcDbObjectIdArray aryIdAll, aryIDBlock;
|
|
GetDoorWinIds(aryIdAll, aryIDBlock);
|
|
dataTable.AddIdNoProject(aryIdAll, &aryIDBlock);
|
|
}
|
|
else
|
|
{ // 本工程,
|
|
// 读取工程文件的算法有些诡异,为了保证每个文件不被多次打开(效率问题),使用一下方法:
|
|
// 读取所有的楼层,和楼层对应的文件;
|
|
// 读取所有的文件,
|
|
// 遍历所有的文件,跟楼层表对应,如果某楼层在该文件内,则读取该楼层的数据。
|
|
// 另外本图需要识别工程内,和工程外。
|
|
|
|
|
|
// 因为需要识别本图未创建工程数据,因此,总是需要打开楼层列表,检测不在楼层列表的数据。
|
|
|
|
// 楼层列表,用它来跟XFloorData匹配检测对应的文档
|
|
TProjectGroupItem *pFloorLst = GetFloorTable();
|
|
CStringArray aryDWGPath; // 跟楼层对应,每个楼层所对应的floor文件
|
|
// 楼层参数,用来取得每个楼层对应得名字
|
|
DList<XFloorData> lstFloorData;
|
|
GetFloorData(lstFloorData);
|
|
// 构建了楼层对应的DWG数组,就可以用该数组来打开对应的文件。
|
|
BulidFloorFile(aryDWGPath, pFloorLst, lstFloorData);
|
|
|
|
dataTable.SetFloorNum((int)aryDWGPath.GetSize());
|
|
|
|
DList<AcDbDatabase> dbList; // 本工程的Database;保持打开的状态,以保存ID
|
|
XStringList lstFiles;
|
|
::GetFloorFiles(lstFiles); // 所有的DWG
|
|
CString sCurDwg=curDoc()->fileName();
|
|
int i = 0, j = 0;
|
|
bool bFindCurrDoc = false;
|
|
for(i=0; i<lstFiles.Length(); i++)
|
|
{
|
|
LPCTSTR file = lstFiles[i];
|
|
|
|
if (_tcsicmp(sCurDwg, lstFiles[i])==0)
|
|
{ // 当前图
|
|
bFindCurrDoc = true;
|
|
AcDbObjectIdArray aryIdAll, aryIDBlock;
|
|
GetDoorWinIds(aryIdAll, aryIDBlock);
|
|
|
|
for (j = 0; j < (int)aryDWGPath.GetSize(); j++)
|
|
{ // 打开该图形对应的所有的楼层
|
|
if (aryDWGPath[j].CompareNoCase(lstFiles[i]) == 0)
|
|
{ // 本图中的楼层
|
|
TProjectFloor *pFloor = (TProjectFloor *)pFloorLst->GetAt(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<AcDbObjectId> 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; i<lstFiles.Length(); i++) , 遍历所有的DWG
|
|
|
|
if (!bFindCurrDoc)
|
|
{ // 如果当前楼层不在工程中:
|
|
AcDbObjectIdArray aryIdAll, aryIDBlock;
|
|
GetDoorWinIds(aryIdAll, aryIDBlock);
|
|
dataTable.AddIdNoProject(aryIdAll, &aryIDBlock);
|
|
}
|
|
|
|
// 清除空的楼层:
|
|
dataTable.ClearNullFloor();
|
|
} // end else 本工程
|
|
#ifndef NDEBUG
|
|
ads_printf(XString(_T("\n属性检测花费的时间:%d"), dwtime));
|
|
ads_printf(XString(_T("\n读取DWG花费的时间:%d"), dwRead));
|
|
ads_printf(XString(_T("\n读取DWG111花费的时间:%d"), dwRead1));
|
|
ads_printf(XString(_T("\n读取DWG222花费的时间:%d"), dwRead2));
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// 门窗检查
|
|
using namespace NDoorWinCheck;
|
|
void ValidateOpening()
|
|
{
|
|
#ifndef NDEBUG
|
|
DWORD d1 = GetTickCount();
|
|
#endif
|
|
|
|
//LH 2013-2-23 解决门窗检查时Create界面崩溃的问题
|
|
CAcModuleResourceOverride vTemp;
|
|
|
|
if (pFrame == NULL)
|
|
{
|
|
pFrame = new CDoorWinFrame;
|
|
BOOL bRes = pFrame->Create(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;
|
|
|
|
}
|
|
}
|
|
|