Files
envi-code/SourceCode/Code2026/tg_shs/shs_kerncmd/OpeningCheck.cpp
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

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;
}
}