2969 lines
74 KiB
C++
2969 lines
74 KiB
C++
#include "stdafx.h"
|
||
#include "TAecSpaceCell.h"
|
||
#include "TAecSpaceWall.h"
|
||
#include "TSearchSpaceFromWall.h"
|
||
|
||
|
||
extern int CompNodeByEqual(const XSortWallOnPt *p1, const void *p2);
|
||
extern AcDbObjectId GetValidTextStyle(AcDbDatabase *pDb, const TCHAR *pStyle);
|
||
//Acad::ErrorStatus WritePoly2D(AcDbDwgFiler *pFiler, const XPoly2D &poly);
|
||
//Acad::ErrorStatus ReadPoly2D(AcDbDwgFiler *pFiler, XPoly2D &poly);
|
||
double GetTextSize(const TCHAR *m_sTextStyle);
|
||
extern void xh1cpy(TCHAR *to, const TCHAR *src);
|
||
|
||
|
||
#define SP_QUANTUM_1 _T("地面面积")
|
||
#define SP_QUANTUM_2 _T("顶棚面积")
|
||
#define SP_QUANTUM_3 _T("轴线面积")
|
||
#define SP_QUANTUM_4 _T("墙壁面积")
|
||
#define SP_QUANTUM_5 _T("周长")
|
||
#define SP_QUANTUM_6 _T("踢脚线")
|
||
#define SP_QUANTUM_7 _T("净容积")
|
||
|
||
|
||
|
||
|
||
////////////////////////////////////////////////////
|
||
// 房间实体类
|
||
////////////////////////////////////////////////////
|
||
|
||
// ver:2-TArch5;3-TArch6;4-TArch7;5-TArch8
|
||
const Adesk::UInt8 TDbSpace::g_nVersion = 5;
|
||
|
||
|
||
ACRX_DXF_DEFINE_MEMBERS(ATSSpace, ATSEntity, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
|
||
1, ATS_SPACE, "ATS_SPACE图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
|
||
|
||
IMPLEMENT_TENTBASE(TDbSpace);
|
||
|
||
TDbSpace::TDbSpace()
|
||
{
|
||
m_nSpaceFlag = 0;
|
||
m_nNewFlag = 0;
|
||
m_nRotation = 0;
|
||
m_nTextHeight = 5.0;
|
||
m_nFloorThick = _AS_SYS_UNIT(120.0);
|
||
m_nUseArea = 0;
|
||
m_nOccuArea = 0;
|
||
m_nCeilArea = 0;
|
||
m_nWallSurfArea = 0;
|
||
m_nExtWallArea = 0;
|
||
m_nExtWinArea = 0;
|
||
m_nExtDoorArea = 0;
|
||
m_nType = kUseArea;
|
||
m_nHatchColor = 256;//默认color by layer
|
||
|
||
m_dbTempSum = 26;//夏季室内设计温度
|
||
m_dbTempWin = 18;//冬季室内设计温度
|
||
m_nUnitNo = 0; //空调系统单元号
|
||
m_dbColdLoad = 0;//冷负荷
|
||
m_dbHeatLoad = 0;//热负荷
|
||
|
||
m_dHatchScale = 100; // sg add 081125
|
||
m_dHatchAngle = 0;
|
||
m_bMText = FALSE; // sg add 081211
|
||
m_sSndName = _T("ROOM");
|
||
|
||
m_bIsStretch = false;
|
||
}
|
||
|
||
TDbSpace::~TDbSpace()
|
||
{
|
||
}
|
||
|
||
BOOL
|
||
TDbSpace::IsValid() const
|
||
{
|
||
BOOL bRet = TDbEntity::IsValid();
|
||
if (!bRet)
|
||
return bRet;
|
||
bRet = !!m_outline;
|
||
return bRet;
|
||
}
|
||
|
||
// 提供对格式刷的支持
|
||
void TDbSpace::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag)
|
||
{
|
||
assertWriteEnabled();
|
||
TDbEntity::CopyPropertiesFrom(pSrcEntity, gMatchFlag);
|
||
|
||
TDbSpace *pSrc = TDbSpace::cast(pSrcEntity);
|
||
if (pSrc != NULL)
|
||
{
|
||
m_nSpaceFlag = pSrc->m_nSpaceFlag;
|
||
m_nNewFlag = pSrc->m_nNewFlag;
|
||
m_nType = pSrc->m_nType;
|
||
m_nFloorThick = pSrc->m_nFloorThick;
|
||
m_sHatchStyle = pSrc->m_sHatchStyle;
|
||
m_nHatchColor = pSrc->m_nHatchColor;
|
||
m_nRotation = pSrc->m_nRotation;
|
||
m_nTextHeight = pSrc->m_nTextHeight;
|
||
|
||
if (database() == NULL ||
|
||
pSrcEntity->database() == NULL ||
|
||
database() == pSrcEntity->database()) // add by whl on 060317
|
||
{
|
||
m_idTextStyle = pSrc->m_idTextStyle;
|
||
m_idHatchLayer = pSrc->m_idHatchLayer;
|
||
}
|
||
|
||
m_dHatchAngle = pSrc->m_dHatchAngle; // sg add 090206
|
||
m_dHatchScale = pSrc->m_dHatchScale;
|
||
|
||
// sg add 110307,根据需求要求,真彩色支持格式刷
|
||
SetHatchTrueColor(pSrc->GetHatchTrueColor());
|
||
}
|
||
}
|
||
|
||
Acad::ErrorStatus TDbSpace::SetPathPoly(const XPoly2D &polyPath, const AcGeVector3d&normal)
|
||
{
|
||
assertWriteEnabled();
|
||
m_outline = polyPath;
|
||
if (m_outline.PathArea() > 0)
|
||
m_outline.Reverse();
|
||
|
||
m_nUseArea = _AS_SQMETER(m_outline.Area());
|
||
// sg add 090602,更新周长
|
||
m_nPerimeter = m_outline.Distance2d();
|
||
return Acad::eOk;
|
||
}
|
||
|
||
Acad::ErrorStatus TDbSpace::GetPathPoly(XPoly2D &polyPath, AcGeVector3d&normal) const
|
||
{
|
||
assertReadEnabled();
|
||
polyPath = m_outline;
|
||
normal = AcGeVector3d::kZAxis;
|
||
return Acad::eOk;
|
||
}
|
||
|
||
// sg add 090508,获取所属户,动态数据
|
||
AcDbObjectId TDbSpace::GetHouseId() const
|
||
{
|
||
assertReadEnabled();
|
||
AcDbSoftPointerId idHouse;
|
||
const TEntityFields &fd = GetFields();
|
||
fd.GFD(_T("阳台所属户"), idHouse);
|
||
return idHouse;
|
||
}
|
||
|
||
void TDbSpace::SetHouseId(AcDbObjectId id)
|
||
{
|
||
assertWriteEnabled();
|
||
AcDbSoftPointerId idHouse = id;
|
||
TEntityFields &fd = Fields();
|
||
fd.SFD(_T("阳台所属户"), idHouse);
|
||
}
|
||
|
||
// sg add 100907,增加粉刷层厚度的动态数据
|
||
double TDbSpace::GetStuccoThickness() const
|
||
{
|
||
assertReadEnabled();
|
||
double dThickness(0);
|
||
const TEntityFields &fd = GetFields();
|
||
fd.GFD(_T("粉刷层厚度"), dThickness);
|
||
return dThickness;
|
||
}
|
||
|
||
void TDbSpace::SetStuccoThickness(double dThickness)
|
||
{
|
||
// 获取旧的粉刷层厚度
|
||
double dOldThickness(0);
|
||
const TEntityFields &fdOld = GetFields();
|
||
|
||
// 通过返回值,判断是否有“粉刷层厚度”的动态数据,并在Offset时,进行不同的操作
|
||
bool bRet = fdOld.GFD(_T("粉刷层厚度"), dOldThickness);
|
||
|
||
// 设置新的粉刷层厚度
|
||
assertWriteEnabled();
|
||
TEntityFields &fd = Fields();
|
||
fd.SFD(_T("粉刷层厚度"), dThickness);
|
||
|
||
// 自动处理轮廓线问题
|
||
XPoly2D polyPath, polyNewPath;
|
||
AcGeVector3d normal;
|
||
GetPathPoly(polyPath, normal);
|
||
|
||
// 获得偏移距离
|
||
// 注:此处存在问题,跟踪发现GetPathPoly函数得到的普通房间PLine线中的点方向第一次设置后,会发生变化
|
||
double dOffset = 0;
|
||
if (m_nType == kTotalArea) // 如果是建筑轮廓,向外侧偏移
|
||
{
|
||
dOffset = dThickness - dOldThickness;
|
||
}
|
||
else // 其他房间,向内侧偏移
|
||
{
|
||
if (!bRet) // 以前没有动态数据
|
||
{
|
||
dOffset = dThickness - dOldThickness;
|
||
}
|
||
else
|
||
{
|
||
dOffset = dOldThickness - dThickness;
|
||
}
|
||
}
|
||
polyPath.Offset(dOffset, polyNewPath);
|
||
|
||
// 重新设置外轮廓线,并更新面积、周长等数据
|
||
SetPathPoly(polyNewPath, normal);
|
||
}
|
||
|
||
// sg add 100907,增加房间填充真彩色的动态数据,原有的m_nHatchColor不再使用
|
||
AcCmColor TDbSpace::GetHatchTrueColor() const
|
||
{
|
||
assertReadEnabled();
|
||
Adesk::UInt32 nColor = m_nHatchColor;
|
||
|
||
const TEntityFields &fd = GetFields();
|
||
fd.GFD(_T("填充真彩颜色"), nColor);
|
||
|
||
AcCmColor color;
|
||
#if ADS > 23
|
||
#if defined(ZWCAD) && (ADS == 24 || defined(R24))
|
||
color.setRGB(GetRValue(nColor), GetGValue(nColor), GetBValue(nColor));
|
||
#else
|
||
color.setRGB(nColor);
|
||
#endif
|
||
#else
|
||
color.setColor(nColor);
|
||
#endif
|
||
return color;
|
||
}
|
||
|
||
void TDbSpace::SetHatchTrueColor(const AcCmColor &color)
|
||
{
|
||
assertWriteEnabled();
|
||
#if ADS > 23
|
||
#if defined(ZWCAD) && (ADS == 24 || defined(R24))
|
||
Adesk::UInt32 nColor = RGB(color.red(), color.green(), color.blue());
|
||
#else
|
||
Adesk::UInt32 nColor = color.getRGB();
|
||
#endif
|
||
#else
|
||
Adesk::UInt32 nColor = color.color();
|
||
#endif
|
||
|
||
TEntityFields &fd = Fields();
|
||
fd.SFD(_T("填充真彩颜色"), nColor);
|
||
|
||
// 考虑与旧版软件图纸交流问题
|
||
SetHatchColor(color.colorIndex());
|
||
}
|
||
|
||
// add by xly on 101020 支持改进房间对象编号、名称和面积的显示控制
|
||
// 设置高级选项中的控制方式:1——随图纸中的变量统一控制,默认,考虑与旧图兼容;0——独立控制
|
||
void TDbSpace::SetSpaceDispMode(int nConfig)
|
||
{
|
||
assertWriteEnabled();
|
||
|
||
Adesk::UInt8 nConfigNum = nConfig;
|
||
TEntityFields &fd = Fields();
|
||
fd.SFD(_T("房间显示控制"), nConfigNum);
|
||
}
|
||
|
||
// 获得高级选项中的控制方式:1——随图纸中的变量统一控制,默认,考虑与旧图兼容;0——独立控制
|
||
int TDbSpace::GetSpaceDispMode() const
|
||
{
|
||
assertReadEnabled();
|
||
Adesk::UInt8 nConfig = 1; // 默认随Config,即:全局控制
|
||
|
||
const TEntityFields &fd = GetFields();
|
||
fd.GFD(_T("房间显示控制"), nConfig);
|
||
|
||
return nConfig;
|
||
}
|
||
|
||
// 设置房间对象的显示方式
|
||
void TDbSpace::SetSpaceDispFlag(int nFlag)
|
||
{
|
||
assertWriteEnabled();
|
||
Adesk::UInt8 nMode = nFlag;
|
||
|
||
// 获取显示控制方式
|
||
int nDispMode = GetSpaceDispMode();
|
||
if (nDispMode == 1) // 随图纸中的变量统一控制
|
||
{
|
||
DocSetSpaceDispMode(nFlag);
|
||
}
|
||
else // 独立控制
|
||
{
|
||
TEntityFields &fd = Fields();
|
||
fd.SFD(_T("房间显示方式"), nMode);
|
||
}
|
||
}
|
||
|
||
// 获得房间对象的显示方式
|
||
int TDbSpace::GetSpaceDispFlag() const
|
||
{
|
||
assertReadEnabled();
|
||
// 默认从图纸中拷贝数据
|
||
Adesk::UInt8 nMode = DocGetSpaceDispMode();
|
||
|
||
// 获取显示控制方式
|
||
int nDispMode = GetSpaceDispMode();
|
||
if (nDispMode == 0) // 独立控制
|
||
{
|
||
const TEntityFields &fd = GetFields();
|
||
fd.GFD(_T("房间显示方式"), nMode);
|
||
}
|
||
|
||
return nMode;
|
||
}
|
||
|
||
// 设置名称、编号是否显示
|
||
void TDbSpace::SetDimNameAndCode(BOOL bDimName, BOOL bDimCode)
|
||
{
|
||
assertWriteEnabled();
|
||
|
||
// 获取显示控制方式
|
||
int nFlag = GetSpaceDispFlag();
|
||
if (bDimCode && bDimName) // 同时标注
|
||
{
|
||
nFlag |= SPF_NAME_AND_CODE;
|
||
nFlag &= ~SPF_CODE;
|
||
nFlag &= ~SPF_NULL;
|
||
}
|
||
else if (bDimCode) // 只标注编号
|
||
{
|
||
nFlag &= ~SPF_NAME_AND_CODE;
|
||
nFlag |= SPF_CODE;
|
||
nFlag &= ~SPF_NULL;
|
||
}
|
||
else if (bDimName) // 只标注名称
|
||
{
|
||
nFlag &= ~SPF_NAME_AND_CODE;
|
||
nFlag &= ~SPF_CODE;
|
||
nFlag &= ~SPF_NULL;
|
||
}
|
||
else // 都不标注
|
||
{
|
||
nFlag &= ~SPF_NAME_AND_CODE;
|
||
nFlag &= ~SPF_CODE;
|
||
nFlag |= SPF_NULL;
|
||
}
|
||
|
||
SetSpaceDispFlag(nFlag);
|
||
}
|
||
|
||
// 获得名称是否显示
|
||
BOOL TDbSpace::IsDimName() const
|
||
{
|
||
assertReadEnabled();
|
||
|
||
BOOL bRet(FALSE); // 只标注编号,或者都不标注
|
||
|
||
int nFlag = GetSpaceDispFlag();
|
||
if ((nFlag&SPF_NAME_AND_CODE) != 0) // 同时标注名称和编号
|
||
{
|
||
bRet = TRUE;
|
||
}
|
||
else if ((nFlag&SPF_CODE) == 0 && (nFlag&SPF_NULL) == 0) // 只标注名称
|
||
{
|
||
bRet = TRUE;
|
||
}
|
||
return bRet;
|
||
}
|
||
|
||
// 获得房间编号是否显示
|
||
BOOL TDbSpace::IsDimCode() const
|
||
{
|
||
assertReadEnabled();
|
||
|
||
BOOL bRet(FALSE); // 只标注名称,或者都不标注
|
||
|
||
int nFlag = GetSpaceDispFlag();
|
||
if ((nFlag&SPF_NAME_AND_CODE) != 0) // 同时标注名称和编号
|
||
{
|
||
bRet = TRUE;
|
||
}
|
||
else if ((nFlag&SPF_CODE) != 0) // 只标注编号
|
||
{
|
||
bRet = TRUE;
|
||
}
|
||
return bRet;
|
||
}
|
||
|
||
// 设置房间面积是否显示
|
||
void TDbSpace::SetDimArea(BOOL bDim)
|
||
{
|
||
assertWriteEnabled();
|
||
|
||
// 获取显示控制方式
|
||
int nFlag = GetSpaceDispFlag();
|
||
if (bDim) // 标注房间面积
|
||
{
|
||
nFlag |= SPF_AREA;
|
||
}
|
||
else // 不标注房间面积
|
||
{
|
||
nFlag &= ~SPF_AREA;
|
||
}
|
||
|
||
SetSpaceDispFlag(nFlag);
|
||
}
|
||
|
||
// 获得房间面积是否显示
|
||
BOOL TDbSpace::IsDimArea() const
|
||
{
|
||
assertReadEnabled();
|
||
|
||
BOOL bRet(FALSE);
|
||
int nFlag = GetSpaceDispFlag();
|
||
bRet = ((nFlag&SPF_AREA) != 0); // 判断是否标注面积
|
||
return bRet;
|
||
}
|
||
|
||
// 设置面积单位是否显示
|
||
void TDbSpace::SetDimUnit(BOOL bDim)
|
||
{
|
||
assertWriteEnabled();
|
||
|
||
// 获取显示控制方式
|
||
int nFlag = GetSpaceDispFlag();
|
||
if (bDim) // 标注房间面积单位
|
||
{
|
||
nFlag |= SPF_UNIT;
|
||
}
|
||
else // 不标注面积单位
|
||
{
|
||
nFlag &= ~SPF_UNIT;
|
||
}
|
||
|
||
SetSpaceDispFlag(nFlag);
|
||
}
|
||
|
||
// 获得面积单位是否显示
|
||
BOOL TDbSpace::IsDimUnit() const
|
||
{
|
||
assertReadEnabled();
|
||
|
||
BOOL bRet(FALSE);
|
||
int nFlag = GetSpaceDispFlag();
|
||
bRet = ((nFlag&SPF_UNIT) != 0); // 判断是否标注面积单位
|
||
return bRet;
|
||
}
|
||
|
||
|
||
Acad::ErrorStatus
|
||
TDbSpace::subGetClassID(CLSID* pClsid) const
|
||
{
|
||
return Acad::eOk;
|
||
}
|
||
|
||
|
||
// 从DWG读入数据:
|
||
// 注意: 有待加入版本控制
|
||
Acad::ErrorStatus TDbSpace::dwgInFields(AcDbDwgFiler* pFiler)
|
||
{
|
||
assertWriteEnabled();
|
||
|
||
Acad::ErrorStatus es = TDbEntity::dwgInFields(pFiler);
|
||
if (es != Acad::eOk) return es;
|
||
Adesk::UInt8 nVer;
|
||
pFiler->readItem(&nVer);
|
||
if (nVer > g_nVersion) {// Version is too new
|
||
return Acad::eMakeMeProxy;
|
||
}
|
||
|
||
pFiler->readItem(&m_nEnFlag); //是否有顶,是否有底
|
||
pFiler->readItem((AcGePoint3d *)&m_ptLocation);
|
||
ReadString(pFiler, m_sCode);
|
||
ReadString(pFiler, m_sName);
|
||
pFiler->readItem(&m_nUseArea);
|
||
pFiler->readItem(&m_nOccuArea);
|
||
pFiler->readItem(&m_nCeilArea);
|
||
pFiler->readItem(&m_nWallSurfArea);
|
||
pFiler->readItem(&m_nExtWallArea);
|
||
pFiler->readItem(&m_nExtWinArea);
|
||
pFiler->readItem(&m_nExtDoorArea);
|
||
pFiler->readItem(&m_nHeight);
|
||
pFiler->readItem(&m_nPerimeter);
|
||
pFiler->readItem(&m_nKickboardLength);
|
||
|
||
|
||
ReadPoly2D(pFiler, m_outline);
|
||
if (nVer > 1) {
|
||
pFiler->readItem(&m_nSpaceFlag);
|
||
}
|
||
m_lstWallEnclosure.Reset();
|
||
|
||
if (nVer > 2) { // TArch6
|
||
pFiler->readItem(&m_idTextStyle);
|
||
pFiler->readItem(&m_nTextHeight);
|
||
pFiler->readItem(&m_nRotation);
|
||
pFiler->readItem(&m_nFloorThick);
|
||
Adesk::UInt8 nCount = 0;
|
||
pFiler->readItem(&nCount);
|
||
for (Adesk::UInt8 n = 0; n < nCount; n++) {
|
||
AcDbSoftPointerId idWall;
|
||
pFiler->readItem(&idWall);
|
||
m_lstWallEnclosure.Append(new AcDbObjectId(idWall));
|
||
}
|
||
}
|
||
else {
|
||
SetHas3D(FALSE);
|
||
if (database() == acdbCurDwg()) {
|
||
m_idTextStyle = InitTextStyle(TS_SPACE);
|
||
}
|
||
else {
|
||
m_idTextStyle = GetValidTextStyle(database(), _T("_TCH_SPACE"));
|
||
}
|
||
}
|
||
|
||
if (nVer > 3)//TArch7
|
||
{
|
||
pFiler->readItem(&m_dbTempSum);
|
||
pFiler->readItem(&m_dbTempWin);
|
||
pFiler->readItem(&m_nUnitNo);
|
||
pFiler->readItem(&m_dbColdLoad);
|
||
pFiler->readItem(&m_dbHeatLoad);
|
||
ReadString(pFiler, m_strDownFloorCons);
|
||
ReadString(pFiler, m_strUpFloorCons);
|
||
}
|
||
|
||
if (nVer > 4)//TArch8
|
||
{
|
||
pFiler->readItem(&m_nNewFlag);
|
||
|
||
Adesk::Int8 type;
|
||
pFiler->readItem(&type);
|
||
m_nType = (AreaType)type;
|
||
|
||
ReadString(pFiler, m_sHatchStyle);
|
||
pFiler->readItem(&m_nHatchColor);
|
||
pFiler->readItem(&m_idHatchLayer);
|
||
pFiler->readItem(&m_dHatchScale); // sg add 081124
|
||
pFiler->readItem(&m_dHatchAngle);
|
||
pFiler->readItem(&m_bMText); // sg add 081211
|
||
ReadString(pFiler, m_sSndName); // sg add 081215
|
||
|
||
Adesk::Int32 count;
|
||
pFiler->readItem(&count);
|
||
m_lstBalconyArea.Reset();
|
||
for (long i = 0; i < count; i++)
|
||
{
|
||
AcDbSoftPointerId *pid = new AcDbSoftPointerId;
|
||
pFiler->readItem(pid);
|
||
m_lstBalconyArea.Append(pid);
|
||
}
|
||
|
||
pFiler->readItem(&count);
|
||
m_lstBalcony.Reset();
|
||
for (i = 0; i < count; i++)
|
||
{
|
||
AcDbSoftPointerId *pid = new AcDbSoftPointerId;
|
||
pFiler->readItem(pid);
|
||
m_lstBalcony.Append(pid);
|
||
}
|
||
}
|
||
|
||
// sg add 090602,8.0的正式版起,将“文字转角”并入“布局转角”
|
||
m_nLayoutRotation = m_nLayoutRotation + m_nRotation;
|
||
m_nRotation = 0;
|
||
return pFiler->filerStatus();
|
||
}
|
||
|
||
Acad::ErrorStatus TDbSpace::dwgOutFields(AcDbDwgFiler* pFiler) const
|
||
{
|
||
assertReadEnabled();
|
||
Acad::ErrorStatus es = TDbEntity::dwgOutFields(pFiler);
|
||
if (es != Acad::eOk) return es;
|
||
|
||
if (g_nSaveTArchVer == 5)
|
||
pFiler->writeItem((Adesk::UInt8)2);
|
||
else if (g_nSaveTArchVer == 6)
|
||
pFiler->writeItem((Adesk::UInt8)3);
|
||
else if (g_nSaveTArchVer == 7)
|
||
pFiler->writeItem((Adesk::UInt8)4);
|
||
else
|
||
pFiler->writeItem(g_nVersion);
|
||
|
||
pFiler->writeItem(m_nEnFlag); //是否有顶,是否有底
|
||
pFiler->writeItem((AcGePoint3d &)m_ptLocation);
|
||
pFiler->writeItem((const TCHAR *)m_sCode);
|
||
pFiler->writeItem((const TCHAR *)m_sName);
|
||
pFiler->writeItem(m_nUseArea);
|
||
pFiler->writeItem(m_nOccuArea);
|
||
pFiler->writeItem(m_nCeilArea);
|
||
pFiler->writeItem(m_nWallSurfArea);
|
||
pFiler->writeItem(m_nExtWallArea);
|
||
pFiler->writeItem(m_nExtWinArea);
|
||
pFiler->writeItem(m_nExtDoorArea);
|
||
pFiler->writeItem(m_nHeight);
|
||
pFiler->writeItem(m_nPerimeter);
|
||
pFiler->writeItem(m_nKickboardLength);
|
||
|
||
WritePoly2D(pFiler, m_outline);
|
||
|
||
if (g_nSaveTArchVer == 5)
|
||
{
|
||
Adesk::UInt8 spFlag = ((m_nSpaceFlag&SF_MASK) ? SF_MASK : 0);
|
||
pFiler->writeItem(spFlag);
|
||
}
|
||
else
|
||
{
|
||
pFiler->writeItem(m_nSpaceFlag);
|
||
pFiler->writeItem(m_idTextStyle);
|
||
pFiler->writeItem(m_nTextHeight);
|
||
pFiler->writeItem(m_nRotation);
|
||
pFiler->writeItem(m_nFloorThick);
|
||
Adesk::UInt8 nCount = m_lstWallEnclosure.Length();
|
||
pFiler->writeItem(nCount);
|
||
for (Adesk::UInt8 i = 0; i < nCount; i++)
|
||
{
|
||
AcDbSoftPointerId idWall = m_lstWallEnclosure[i];
|
||
|
||
// add by xlc on 100825 解决块参照里删除墙后提示丢失参照无法保存的问题
|
||
if (idWall.isErased())
|
||
{
|
||
idWall = AcDbObjectId::kNull;
|
||
}
|
||
pFiler->writeItem(idWall);
|
||
}
|
||
}
|
||
|
||
if (g_nSaveTArchVer > 6)
|
||
{
|
||
pFiler->writeItem(m_dbTempSum);
|
||
pFiler->writeItem(m_dbTempWin);
|
||
pFiler->writeItem(m_nUnitNo);
|
||
pFiler->writeItem(m_dbColdLoad);
|
||
pFiler->writeItem(m_dbHeatLoad);
|
||
pFiler->writeString(m_strDownFloorCons);
|
||
pFiler->writeString(m_strUpFloorCons);
|
||
}
|
||
|
||
if (g_nSaveTArchVer > 7)
|
||
{
|
||
pFiler->writeItem(m_nNewFlag);
|
||
|
||
Adesk::Int8 type = (Adesk::Int8)m_nType;
|
||
pFiler->writeItem(type);
|
||
|
||
pFiler->writeString(m_sHatchStyle);
|
||
pFiler->writeItem(m_nHatchColor);
|
||
pFiler->writeItem(m_idHatchLayer);
|
||
pFiler->writeItem(m_dHatchScale); // sg add 081124
|
||
pFiler->writeItem(m_dHatchAngle);
|
||
pFiler->writeItem(m_bMText); // sg add 081211
|
||
pFiler->writeItem(m_sSndName); // sg add 081215
|
||
|
||
Adesk::Int32 count = m_lstBalconyArea.Length();
|
||
pFiler->writeItem(count);
|
||
for (long i = 0; i < count; i++)
|
||
pFiler->writeItem(m_lstBalconyArea[i]);
|
||
|
||
count = m_lstBalcony.Length();
|
||
pFiler->writeItem(count);
|
||
for (i = 0; i < count; i++)
|
||
pFiler->writeItem(m_lstBalcony[i]);
|
||
}
|
||
|
||
return pFiler->filerStatus();
|
||
}
|
||
|
||
Acad::ErrorStatus TDbSpace::dxfInFields(AcDbDxfFiler* pFiler)
|
||
{
|
||
assertWriteEnabled();
|
||
|
||
Acad::ErrorStatus es = TDbEntity::dxfInFields(pFiler);
|
||
if (es != Acad::eOk)
|
||
return es;
|
||
|
||
if (!pFiler->atSubclassData(_T("TDbSpace"))) {
|
||
return Acad::eBadDxfSequence;
|
||
}
|
||
|
||
XString sTextStyle;
|
||
double nTextAng = 0.0;
|
||
double nTextHeight = 5.0;
|
||
double nSlabThick = 0.0;
|
||
XString sName, sCode;
|
||
double r1, r2;
|
||
int nFlag;
|
||
Adesk::Int32 type;
|
||
XPoint pt;
|
||
Adesk::UInt32 fieldsFlags = 0;
|
||
resbuf rb;
|
||
while ((es == Acad::eOk)
|
||
&& ((es = pFiler->readResBuf(&rb)) == Acad::eOk)) {
|
||
switch (rb.restype) {
|
||
case AcDb::kDxfInt16:
|
||
nFlag = rb.resval.rint;
|
||
fieldsFlags |= 0x01;
|
||
break;
|
||
case AcDb::kDxfXCoord:
|
||
pt = rb.resval.rpoint;
|
||
fieldsFlags |= 0x02;
|
||
break;
|
||
case AcDb::kDxfText:
|
||
fieldsFlags |= 0x04;
|
||
sName = rb.resval.rstring;
|
||
free(rb.resval.rstring);
|
||
break;
|
||
case AcDb::kDxfText + 1:
|
||
sCode = rb.resval.rstring;
|
||
fieldsFlags |= 0x08;
|
||
free(rb.resval.rstring);
|
||
break;
|
||
case AcDb::kDxfReal + 1:
|
||
fieldsFlags |= 0x10;
|
||
r1 = rb.resval.rreal;
|
||
break;
|
||
case AcDb::kDxfReal + 2:
|
||
fieldsFlags |= 0x20;
|
||
r2 = rb.resval.rreal;
|
||
break;
|
||
// TArch6
|
||
case AcDb::kDxfTextStyleName:
|
||
sTextStyle = rb.resval.rstring;
|
||
fieldsFlags |= 0x40;
|
||
free(rb.resval.rstring);
|
||
break;
|
||
case AcDb::kDxfReal:
|
||
fieldsFlags |= 0x80;
|
||
nTextHeight = rb.resval.rreal;
|
||
break;
|
||
case AcDb::kDxfReal + 3:
|
||
fieldsFlags |= 0x100;
|
||
nSlabThick = rb.resval.rreal;
|
||
break;
|
||
case 50:
|
||
fieldsFlags |= 0x200;
|
||
nTextAng = rb.resval.rreal;
|
||
break;
|
||
case AcDb::kDxfInt32:
|
||
type = (Adesk::Int32)(rb.resval.rint);
|
||
fieldsFlags |= 0x400;
|
||
break;
|
||
|
||
//fall through intentional
|
||
default:
|
||
// An unrecognized group. Push it back so that
|
||
// the subclass can read it again.
|
||
pFiler->pushBackItem();
|
||
es = Acad::eEndOfFile;
|
||
break;
|
||
}
|
||
}
|
||
|
||
// At this point the es variable must contain eEndOfFile
|
||
// - either from readResBuf() or from pushback. If not,
|
||
// it indicates that an error happened and we should
|
||
// return immediately.
|
||
//
|
||
if (es != Acad::eEndOfFile)
|
||
return Acad::eInvalidResBuf;
|
||
|
||
if (fieldsFlags & 0x01)
|
||
m_nSpaceFlag = nFlag;
|
||
if (fieldsFlags & 0x02)
|
||
m_ptLocation = pt;
|
||
if (fieldsFlags & 0x04)
|
||
m_sName = sName;
|
||
if (fieldsFlags & 0x08)
|
||
m_sCode = sCode;
|
||
if (fieldsFlags & 0x10)
|
||
m_nUseArea = r1;
|
||
if (fieldsFlags & 0x20)
|
||
m_nPerimeter = r2;
|
||
|
||
AcDbObjectId id;
|
||
if (fieldsFlags & 0x40)
|
||
id = TchExport::GetTextStyleId(sName, database());
|
||
if (!id)
|
||
{
|
||
XString style;
|
||
xg_getvar(_T("TEXTSTYLE"), style);
|
||
m_idTextStyle = TchExport::GetTextStyleId(style, database());
|
||
}
|
||
else
|
||
m_idTextStyle = id;
|
||
|
||
if (fieldsFlags & 0x80)
|
||
m_nTextHeight = nTextHeight;
|
||
if (fieldsFlags & 0x100)
|
||
m_nFloorThick = nSlabThick;
|
||
if (fieldsFlags & 0x200)
|
||
m_nRotation = nTextAng;
|
||
if (fieldsFlags & 0x400)
|
||
m_nType = (AreaType)type;
|
||
|
||
return pFiler->filerStatus();
|
||
}
|
||
|
||
Acad::ErrorStatus TDbSpace::dxfOutFields(AcDbDxfFiler* pFiler) const
|
||
{
|
||
Acad::ErrorStatus es = TDbEntity::dxfOutFields(pFiler);
|
||
assert(es == Acad::eOk);
|
||
|
||
es = pFiler->writeItem(AcDb::kDxfSubclass, _T("TDbSpace"));
|
||
assert(es == Acad::eOk);
|
||
|
||
pFiler->writeInt16(AcDb::kDxfInt16, m_nSpaceFlag);
|
||
pFiler->writePoint2d(AcDb::kDxfXCoord, m_ptLocation);
|
||
pFiler->writeString(AcDb::kDxfText, (const TCHAR *)GetName());
|
||
pFiler->writeString(AcDb::kDxfText + 1, (const TCHAR *)GetCode());
|
||
pFiler->writeString(AcDb::kDxfTextStyleName, (const TCHAR *)GetSymbolName(m_idTextStyle));
|
||
pFiler->writeDouble(AcDb::kDxfReal, m_nTextHeight);
|
||
pFiler->writeDouble(AcDb::kDxfReal + 1, GetUseArea());
|
||
pFiler->writeDouble(AcDb::kDxfReal + 2, GetPerimeter());
|
||
pFiler->writeDouble(AcDb::kDxfReal + 3, m_nFloorThick);
|
||
pFiler->writeDouble(50, m_nRotation);
|
||
pFiler->writeInt32(AcDb::kDxfInt32, (Adesk::Int32)m_nType);
|
||
|
||
return pFiler->filerStatus();
|
||
}
|
||
|
||
|
||
Acad::ErrorStatus
|
||
TDbSpace::subIntersectWith(const AcDbEntity* ent,
|
||
AcDb::Intersect intType,
|
||
AcGePoint3dArray& points,
|
||
INT_PTR thisGsMarker,
|
||
INT_PTR otherGsMarker) const
|
||
{
|
||
assertReadEnabled();
|
||
return Acad::eNotApplicable;
|
||
}
|
||
|
||
Acad::ErrorStatus
|
||
TDbSpace::subIntersectWith(const AcDbEntity* ent,
|
||
AcDb::Intersect intType,
|
||
const AcGePlane& projPlane,
|
||
AcGePoint3dArray& points,
|
||
INT_PTR thisGsMarker,
|
||
INT_PTR otherGsMarker) const
|
||
{
|
||
assertReadEnabled();
|
||
return Acad::eNotApplicable;
|
||
}
|
||
|
||
Acad::ErrorStatus TDbSpace::subGetOsnapPoints(
|
||
AcDb::OsnapMode osnapMode,
|
||
INT_PTR gsSelectionMark,
|
||
const AcGePoint3d& ptPick,
|
||
const AcGePoint3d& lastPoint,
|
||
const AcGeMatrix3d& viewXform,
|
||
AcGePoint3dArray& snapPoints,
|
||
AcDbIntArray& geomIds) const
|
||
{
|
||
assertReadEnabled();
|
||
Acad::ErrorStatus es = Acad::eNotApplicable;
|
||
switch (osnapMode)
|
||
{
|
||
case AcDb::kOsModeIns:
|
||
case AcDb::kOsModeNode:
|
||
snapPoints.append(m_ptLocation);
|
||
es = Acad::eOk;
|
||
break;
|
||
default:
|
||
//add by lgy 20120221 9.0房间面积对象顶点和边都需要被捕捉
|
||
{
|
||
AcDbVoidPtrArray allEnt;
|
||
XExplodeStream dc(allEnt);
|
||
dc.SetPropertiesFrom(this);
|
||
ExplodeOrDraw2d(dc); // 炸开对象
|
||
|
||
for (long i = 0L; i < allEnt.length(); i++)
|
||
{
|
||
AcDbEntity *pEnt = (AcDbEntity*)allEnt[i];
|
||
if (pEnt == NULL || pEnt->isKindOf(TDbText::desc()) || pEnt->isKindOf(AcDbHatch::desc()))
|
||
{
|
||
continue; // 如果指针为空,或者是文字和填充对象for循环继续
|
||
}
|
||
|
||
pEnt->getOsnapPoints(osnapMode, gsSelectionMark, ptPick, lastPoint,
|
||
viewXform, snapPoints, geomIds);
|
||
}
|
||
}
|
||
es = Acad::eOk;
|
||
break;
|
||
}
|
||
return es;
|
||
}
|
||
|
||
// -----------------------------------------------------------------------
|
||
// Overriden functions for edit
|
||
// to do:
|
||
// 对于自定义柱子,应当允许通过夹点改变边界
|
||
Acad::ErrorStatus TDbSpace::subGetGripPoints(AcGePoint3dArray& gripPoints,
|
||
AcDbIntArray& osnapModes,
|
||
AcDbIntArray& geomIds) const
|
||
{
|
||
gripPoints.append(m_ptLocation);
|
||
int nEdgeNum = m_outline.TotalSegments();
|
||
for (int i = 0; i < nEdgeNum; i++)
|
||
{
|
||
XPoint pt = m_outline[i];
|
||
gripPoints.append(pt);
|
||
}
|
||
|
||
// 边上的夹点
|
||
for (i = 0; i < nEdgeNum; i++)
|
||
{
|
||
XCurveSegment edge;
|
||
m_outline.Nth(i, edge);
|
||
XPoint ptMid = edge.MidPoint();
|
||
gripPoints.append(ptMid);
|
||
}
|
||
|
||
return Acad::eOk;
|
||
}
|
||
|
||
// stretch points is diffrent from grep points, with no midpoint included
|
||
Acad::ErrorStatus TDbSpace::subGetStretchPoints(AcGePoint3dArray & stretchPoints) const
|
||
{
|
||
stretchPoints.append(m_ptLocation);
|
||
int nEdgeNum = m_outline.TotalSegments();
|
||
for (int i = 0; i < nEdgeNum; i++)
|
||
{
|
||
XPoint pt = m_outline[i];
|
||
stretchPoints.append(pt);
|
||
}
|
||
|
||
return Acad::eOk;
|
||
}
|
||
|
||
|
||
// Active when being rotated, scaled, moved, etc.
|
||
Acad::ErrorStatus TDbSpace::subTransformBy(const AcGeMatrix3d& xform)
|
||
{
|
||
assertWriteEnabled();
|
||
TDbEntity::subTransformBy(xform);
|
||
ads_matrix mat;
|
||
memcpy(mat, &xform, sizeof(ads_matrix));
|
||
m_ptLocation.TransformBy(mat);
|
||
m_outline.TransformBy(xform);
|
||
|
||
// sg delete 090602,8.0的正式版起,将“文字转角”并入“布局转角”
|
||
/*
|
||
if(!g_bLayoutRotate)
|
||
{
|
||
if(!IsMirrorMatrix(xform))
|
||
{
|
||
AcGeVector3d vt(cos(m_nRotation), sin(m_nRotation), 0.0);
|
||
vt.transformBy(xform);
|
||
m_nRotation = ads_angle(XPoint(), XPoint(vt[0], vt[1]));
|
||
}
|
||
}
|
||
*/
|
||
return Acad::eOk;
|
||
}
|
||
|
||
// 功能: 夹点操作
|
||
// 状态: 有待完成修改相关墙体的操作
|
||
Acad::ErrorStatus TDbSpace::subMoveGripPointsAt(
|
||
const AcDbIntArray& indices,
|
||
const AcGeVector3d& offset)
|
||
{
|
||
assertWriteEnabled();
|
||
|
||
XPoint vtOffset = *(XPoint *)&offset;
|
||
//m_ptLocation += vtOffset;
|
||
XPoly2D &m_polyOutline = m_outline;
|
||
int nTotalEdge = m_outline.TotalSegments();
|
||
XPoly2D polyBack(m_polyOutline);
|
||
|
||
vtOffset.z = 0;
|
||
for (int i = 0; i < indices.length(); i++)
|
||
{
|
||
int idx = indices[i];
|
||
if (idx == 0)
|
||
{
|
||
m_ptLocation += vtOffset;
|
||
continue;
|
||
}
|
||
idx--;
|
||
|
||
//modify by lgy 20120314 不能使用以下方式判断条件是否成立
|
||
//ASSERT(idx<2*nTotalEdge);
|
||
if (!(idx < 2 * nTotalEdge))
|
||
{
|
||
break;
|
||
}
|
||
|
||
if (idx < nTotalEdge)
|
||
{
|
||
// modify by lgy 20120221,9.0房间对象顶点夹点新添加功能
|
||
// *m_polyOutline[idx] += vtOffset;
|
||
if (!GetCtrlToggle()) //移动顶点
|
||
{
|
||
*m_polyOutline[idx] += vtOffset;
|
||
}
|
||
else //添加夹点
|
||
{
|
||
// 获取所点位置的夹点,将其偏移后加入到外包装线中设置好凸度值
|
||
XPoint ptAdd = *m_polyOutline[idx];
|
||
ptAdd += vtOffset;
|
||
|
||
// m_polyOutline.InsertNodeAt(idx+1, ptAdd, m_polyOutline.GetBulge(idx));
|
||
// 判断增加到idx之前或者之后
|
||
int nPrev = idx - 1;
|
||
nPrev = DePeriod(nTotalEdge, nPrev);
|
||
if (nPrev >= 0 && nPrev < nTotalEdge)
|
||
{
|
||
XDirectionCurve prevSeg;
|
||
m_polyOutline.Nth(nPrev, prevSeg);
|
||
|
||
XPoint ptProject1, ptProject2;
|
||
prevSeg.ProjectToMe(ptAdd, ptProject1);
|
||
if ((ptProject1&prevSeg) == PR_INSIDE) // 在前1段上
|
||
{
|
||
XDirectionCurve curSeg;
|
||
m_polyOutline.Nth(idx, curSeg);
|
||
|
||
curSeg.ProjectToMe(ptAdd, ptProject2);
|
||
if ((ptProject2&curSeg) == PR_INSIDE) // 同时也在当前段上,看离哪个近
|
||
{
|
||
double dDist1 = ptAdd.Distance(ptProject1),
|
||
dDist2 = ptAdd.Distance(ptProject2);
|
||
if (dDist1 < dDist2 - _DIST_SNAP)
|
||
m_polyOutline.InsertNodeAt(idx, ptAdd, m_polyOutline.GetBulge(idx));
|
||
else
|
||
m_polyOutline.InsertNodeAt(idx + 1, ptAdd, m_polyOutline.GetBulge(idx));
|
||
}
|
||
else
|
||
m_polyOutline.InsertNodeAt(idx, ptAdd, m_polyOutline.GetBulge(idx));
|
||
}
|
||
else
|
||
m_polyOutline.InsertNodeAt(idx + 1, ptAdd, m_polyOutline.GetBulge(idx));
|
||
}
|
||
else
|
||
m_polyOutline.InsertNodeAt(idx + 1, ptAdd, m_polyOutline.GetBulge(idx));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
int nEdgeIndex = idx - nTotalEdge;
|
||
//modify by lgy 20120314 要求不让用ASSERT判断条件
|
||
//ASSERT(nEdgeIndex<nTotalEdge);
|
||
if (!(nEdgeIndex < nTotalEdge))
|
||
{
|
||
break;
|
||
}
|
||
|
||
XDirectionCurve cv;
|
||
m_polyOutline.Nth(nEdgeIndex, cv);
|
||
//modify by lgy 20120314 要求不让用ASSERT判断条件
|
||
//ASSERT(!!cv);
|
||
if (!cv)
|
||
{
|
||
break;
|
||
}
|
||
|
||
if (cv.Is(CURVE_LINE))
|
||
{ // Move
|
||
XLine ln = cv.GetLine();
|
||
ln.StartPoint() += vtOffset;
|
||
ln.EndPoint() += vtOffset;
|
||
ln.SetLineFlag(LS_INFINITE);
|
||
XDirectionCurve prevSeg, nextSeg;
|
||
int nPrev = nEdgeIndex - 1, nNext = nEdgeIndex + 1;
|
||
nPrev = DePeriod(nTotalEdge, nPrev);
|
||
nNext = DePeriod(nTotalEdge, nNext);
|
||
|
||
XPoint ptStart, ptEnd;
|
||
BOOL bUpdateIt = TRUE;
|
||
//更新起点
|
||
if (nPrev >= 0 && nPrev < nTotalEdge)
|
||
{
|
||
m_polyOutline.Nth(nPrev, prevSeg);
|
||
prevSeg.SetLineFlag(LS_INFINITE);
|
||
XPoint ptInt[2];
|
||
int nIntNum = prevSeg.Intersection(ln, ptInt[0], ptInt[1]);
|
||
if (nIntNum == 1) ptStart = ptInt[0];
|
||
else if (nIntNum == 2) {
|
||
ptStart = XLine(ptInt[0], ptInt[1]).NearPoint(ln.StartPoint());
|
||
}
|
||
else bUpdateIt = FALSE;
|
||
}
|
||
else
|
||
{
|
||
ptStart = *m_polyOutline[nEdgeIndex] + vtOffset;
|
||
}
|
||
|
||
// 更新下一点
|
||
if (nNext >= 0 && nNext < nTotalEdge)
|
||
{
|
||
m_polyOutline.Nth(nNext, nextSeg);
|
||
nextSeg.SetLineFlag(LS_INFINITE);
|
||
XPoint ptInt[2];
|
||
int nIntNum = nextSeg.Intersection(ln, ptInt[0], ptInt[1]);
|
||
if (nIntNum == 1) ptEnd = ptInt[0];
|
||
else if (nIntNum == 2) {
|
||
ptEnd = XLine(ptInt[0], ptInt[1]).NearPoint(ln.EndPoint());
|
||
}
|
||
else bUpdateIt = FALSE;
|
||
}
|
||
else
|
||
{
|
||
ptEnd = *m_polyOutline[nEdgeIndex + 1] + vtOffset;
|
||
}
|
||
|
||
if (bUpdateIt)
|
||
{
|
||
double nPrevBulge = 0.0, nNextBulge = 0.0;
|
||
if (fabs(prevSeg.GetBulge()) > 1.0E-5) {
|
||
XArc prevArc = prevSeg.GetArc();
|
||
double nAngBeg = ads_angle(prevArc.GetCenterPt(), prevSeg.StartPoint());
|
||
double nAngEnd = ads_angle(prevArc.GetCenterPt(), ptStart);
|
||
if (prevSeg.IsMinusArc()) {
|
||
nPrevBulge = -CT_std_angle(nAngBeg - nAngEnd);
|
||
}
|
||
else {
|
||
nPrevBulge = CT_std_angle(nAngEnd - nAngBeg);
|
||
}
|
||
}
|
||
if (fabs(nextSeg.GetBulge()) > 1.0E-5) {
|
||
XArc nextArc = nextSeg.GetArc();
|
||
double nAngBeg = ads_angle(nextArc.GetCenterPt(), ptEnd);
|
||
double nAngEnd = ads_angle(nextArc.GetCenterPt(), nextSeg.EndPoint());
|
||
if (nextSeg.IsMinusArc()) {
|
||
nNextBulge = -CT_std_angle(nAngBeg - nAngEnd);
|
||
}
|
||
else {
|
||
nNextBulge = CT_std_angle(nAngEnd - nAngBeg);
|
||
}
|
||
}
|
||
|
||
*m_polyOutline[nEdgeIndex] = ptStart;
|
||
if (nNext >= 0 && nNext < m_polyOutline.Length())
|
||
{
|
||
*m_polyOutline[nNext] = ptEnd;
|
||
m_polyOutline.SetBulge(nNext, nNextBulge);
|
||
}
|
||
if (nPrev >= 0 && nPrev < m_polyOutline.Length())
|
||
m_polyOutline.SetBulge(nPrev, nPrevBulge);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// Change Arc Segment--bulge
|
||
XPoint ptMid = cv.MidPoint();
|
||
XPoint ptMidNew = ptMid + vtOffset;
|
||
XArc arNew(cv.StartPoint(), ptMidNew, cv.EndPoint());
|
||
if (!!arNew)
|
||
{ //新的弧有效
|
||
XCurveSegment cvLine(cv.StartPoint(), cv.EndPoint(), 0.0);
|
||
int nSideOld = cvLine.OnWhichSide(ptMid);
|
||
int nSideNew = cvLine.OnWhichSide(ptMidNew);
|
||
double nSignal = cv.GetBulge() / fabs(cv.GetBulge());
|
||
if (nSideOld == nSideNew)
|
||
{
|
||
m_polyOutline.SetBulge(nEdgeIndex, nSignal*arNew.Bulge());
|
||
}
|
||
else
|
||
{
|
||
m_polyOutline.SetBulge(nEdgeIndex, -nSignal*arNew.Bulge());
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
Acad::ErrorStatus es = Acad::eOk;
|
||
if (m_polyOutline.IsSelfIntersect())
|
||
{
|
||
m_polyOutline = polyBack;
|
||
es = Acad::eInvalidInput;
|
||
}
|
||
else
|
||
{
|
||
// 判断弧段是否相交
|
||
BOOL bSelfIntersect = FALSE;
|
||
|
||
int nSegNum = m_polyOutline.TotalSegments();
|
||
for (int m = 0; m < nSegNum; m++)
|
||
{
|
||
XCurveSegment seg1;
|
||
m_polyOutline.Nth(m, seg1);
|
||
if (fabs(seg1.GetBulge()) < _DIST_SNAP || seg1.GetLength() < _DIST_SNAP) // 去掉短弧线和直线
|
||
{
|
||
continue;
|
||
}
|
||
|
||
int nPrev = m - 1,
|
||
nNext = m + 1;
|
||
nPrev = DePeriod(nSegNum, nPrev);
|
||
nNext = DePeriod(nSegNum, nNext);
|
||
|
||
for (int n = 0; n < nSegNum; n++)
|
||
{
|
||
if (n == m || n == nPrev || n == nNext)
|
||
continue;
|
||
|
||
XCurveSegment seg2;
|
||
m_polyOutline.Nth(n, seg2);
|
||
if (seg2.GetLength() < _DIST_SNAP) // 去掉短弧线
|
||
{
|
||
continue;
|
||
}
|
||
|
||
XPoint pt1, pt2;
|
||
if (seg1.Intersection(seg2, pt1, pt2))
|
||
{
|
||
bSelfIntersect = TRUE;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (bSelfIntersect)
|
||
{
|
||
m_polyOutline = polyBack;
|
||
es = Acad::eInvalidInput;
|
||
}
|
||
else
|
||
{
|
||
m_nUseArea = _AS_SQMETER(m_polyOutline.Area());
|
||
// 更新周长
|
||
m_nPerimeter = m_outline.Distance2d();
|
||
}
|
||
}
|
||
return es;
|
||
}
|
||
|
||
// 功能: 夹点操作
|
||
Acad::ErrorStatus TDbSpace::subMoveStretchPointsAt(
|
||
const AcDbIntArray& indices,
|
||
const AcGeVector3d& offset)
|
||
{
|
||
// moidfy by lgy 20120221,9.0房间对象中需要顶点夹点添加新功能,再调用移动夹点函数出错
|
||
// return subMoveGripPointsAt(indices, offset);
|
||
assertWriteEnabled();
|
||
|
||
XPoint vtOffset = *(XPoint *)&offset;
|
||
XPoly2D &m_polyOutline = m_outline;
|
||
int nTotalEdge = m_outline.TotalSegments();
|
||
XPoly2D polyBack(m_polyOutline);
|
||
|
||
vtOffset.z = 0;
|
||
for (int i = 0; i < indices.length(); i++)
|
||
{
|
||
int idx = indices[i];
|
||
if (idx == 0)
|
||
{
|
||
m_ptLocation += vtOffset;
|
||
continue;
|
||
}
|
||
idx--;
|
||
|
||
// modify by lgy 20120314,判断条件时要求不让用assert函数
|
||
// ASSERT(idx<2*nTotalEdge);
|
||
if (!(idx < 2 * nTotalEdge))
|
||
{
|
||
break;
|
||
}
|
||
|
||
if (idx < nTotalEdge)
|
||
{
|
||
*m_polyOutline[idx] += vtOffset;
|
||
continue;
|
||
}
|
||
|
||
int nEdgeIndex = idx - nTotalEdge;
|
||
// modify by lgy 20120314,判断条件时要求不让用assert函数
|
||
// ASSERT(nEdgeIndex<nTotalEdge);
|
||
if (!(nEdgeIndex < nTotalEdge))
|
||
{
|
||
break;
|
||
}
|
||
|
||
XDirectionCurve cv;
|
||
m_polyOutline.Nth(nEdgeIndex, cv);
|
||
// modify by lgy 20120314,判断条件时要求不让用assert函数
|
||
// ASSERT(!!cv);
|
||
if (!cv)
|
||
{
|
||
break;
|
||
}
|
||
|
||
if (cv.Is(CURVE_LINE))
|
||
{ // Move
|
||
XLine ln = cv.GetLine();
|
||
ln.StartPoint() += vtOffset;
|
||
ln.EndPoint() += vtOffset;
|
||
ln.SetLineFlag(LS_INFINITE);
|
||
XDirectionCurve prevSeg, nextSeg;
|
||
int nPrev = nEdgeIndex - 1, nNext = nEdgeIndex + 1;
|
||
nPrev = DePeriod(nTotalEdge, nPrev);
|
||
nNext = DePeriod(nTotalEdge, nNext);
|
||
|
||
XPoint ptStart, ptEnd;
|
||
BOOL bUpdateIt = TRUE;
|
||
//更新起点
|
||
if (nPrev >= 0 && nPrev < nTotalEdge)
|
||
{
|
||
m_polyOutline.Nth(nPrev, prevSeg);
|
||
prevSeg.SetLineFlag(LS_INFINITE);
|
||
XPoint ptInt[2];
|
||
int nIntNum = prevSeg.Intersection(ln, ptInt[0], ptInt[1]);
|
||
if (nIntNum == 1)
|
||
ptStart = ptInt[0];
|
||
else if (nIntNum == 2)
|
||
{
|
||
ptStart = XLine(ptInt[0], ptInt[1]).NearPoint(ln.StartPoint());
|
||
}
|
||
else
|
||
bUpdateIt = FALSE;
|
||
}
|
||
else
|
||
{
|
||
ptStart = *m_polyOutline[nEdgeIndex] + vtOffset;
|
||
}
|
||
|
||
// 更新下一点
|
||
if (nNext >= 0 && nNext < nTotalEdge)
|
||
{
|
||
m_polyOutline.Nth(nNext, nextSeg);
|
||
nextSeg.SetLineFlag(LS_INFINITE);
|
||
XPoint ptInt[2];
|
||
int nIntNum = nextSeg.Intersection(ln, ptInt[0], ptInt[1]);
|
||
if (nIntNum == 1)
|
||
ptEnd = ptInt[0];
|
||
else if (nIntNum == 2)
|
||
{
|
||
ptEnd = XLine(ptInt[0], ptInt[1]).NearPoint(ln.EndPoint());
|
||
}
|
||
else
|
||
bUpdateIt = FALSE;
|
||
}
|
||
else
|
||
{
|
||
ptEnd = *m_polyOutline[nEdgeIndex + 1] + vtOffset;
|
||
}
|
||
|
||
if (bUpdateIt)
|
||
{
|
||
double nPrevBulge = 0.0, nNextBulge = 0.0;
|
||
if (fabs(prevSeg.GetBulge()) > 1.0E-5)
|
||
{
|
||
XArc prevArc = prevSeg.GetArc();
|
||
double nAngBeg = ads_angle(prevArc.GetCenterPt(), prevSeg.StartPoint());
|
||
double nAngEnd = ads_angle(prevArc.GetCenterPt(), ptStart);
|
||
if (prevSeg.IsMinusArc())
|
||
{
|
||
nPrevBulge = -CT_std_angle(nAngBeg - nAngEnd);
|
||
}
|
||
else
|
||
{
|
||
nPrevBulge = CT_std_angle(nAngEnd - nAngBeg);
|
||
}
|
||
}
|
||
if (fabs(nextSeg.GetBulge()) > 1.0E-5)
|
||
{
|
||
XArc nextArc = nextSeg.GetArc();
|
||
double nAngBeg = ads_angle(nextArc.GetCenterPt(), ptEnd);
|
||
double nAngEnd = ads_angle(nextArc.GetCenterPt(), nextSeg.EndPoint());
|
||
if (nextSeg.IsMinusArc())
|
||
{
|
||
nNextBulge = -CT_std_angle(nAngBeg - nAngEnd);
|
||
}
|
||
else
|
||
{
|
||
nNextBulge = CT_std_angle(nAngEnd - nAngBeg);
|
||
}
|
||
}
|
||
|
||
*m_polyOutline[nEdgeIndex] = ptStart;
|
||
if (nNext >= 0 && nNext < m_polyOutline.Length())
|
||
{
|
||
*m_polyOutline[nNext] = ptEnd;
|
||
m_polyOutline.SetBulge(nNext, nNextBulge);
|
||
}
|
||
if (nPrev >= 0 && nPrev < m_polyOutline.Length())
|
||
m_polyOutline.SetBulge(nPrev, nPrevBulge);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// Change Arc Segment--bulge
|
||
XPoint ptMid = cv.MidPoint();
|
||
XPoint ptMidNew = ptMid + vtOffset;
|
||
XArc arNew(cv.StartPoint(), ptMidNew, cv.EndPoint());
|
||
if (!!arNew)
|
||
{ //新的弧有效
|
||
XCurveSegment cvLine(cv.StartPoint(), cv.EndPoint(), 0.0);
|
||
int nSideOld = cvLine.OnWhichSide(ptMid);
|
||
int nSideNew = cvLine.OnWhichSide(ptMidNew);
|
||
double nSignal = cv.GetBulge() / fabs(cv.GetBulge());
|
||
if (nSideOld == nSideNew)
|
||
{
|
||
m_polyOutline.SetBulge(nEdgeIndex, nSignal*arNew.Bulge());
|
||
}
|
||
else
|
||
{
|
||
m_polyOutline.SetBulge(nEdgeIndex, -nSignal*arNew.Bulge());
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
Acad::ErrorStatus es = Acad::eOk;
|
||
if (m_polyOutline.IsSelfIntersect())
|
||
{
|
||
m_polyOutline = polyBack;
|
||
es = Acad::eInvalidInput;
|
||
}
|
||
else
|
||
{
|
||
// 判断弧段是否相交
|
||
BOOL bSelfIntersect = FALSE;
|
||
|
||
int nSegNum = m_polyOutline.TotalSegments();
|
||
for (int m = 0; m < nSegNum; m++)
|
||
{
|
||
XCurveSegment seg1;
|
||
m_polyOutline.Nth(m, seg1);
|
||
if (fabs(seg1.GetBulge()) < _DIST_SNAP || seg1.GetLength() < _DIST_SNAP) // 去掉短弧线和直线
|
||
{
|
||
continue;
|
||
}
|
||
|
||
int nPrev = m - 1,
|
||
nNext = m + 1;
|
||
nPrev = DePeriod(nSegNum, nPrev);
|
||
nNext = DePeriod(nSegNum, nNext);
|
||
|
||
for (int n = 0; n < nSegNum; n++)
|
||
{
|
||
if (n == m || n == nPrev || n == nNext)
|
||
continue;
|
||
|
||
XCurveSegment seg2;
|
||
m_polyOutline.Nth(n, seg2);
|
||
if (seg2.GetLength() < _DIST_SNAP) // 去掉短弧线
|
||
{
|
||
continue;
|
||
}
|
||
|
||
XPoint pt1, pt2;
|
||
if (seg1.Intersection(seg2, pt1, pt2))
|
||
{
|
||
bSelfIntersect = TRUE;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (bSelfIntersect)
|
||
{
|
||
m_polyOutline = polyBack;
|
||
es = Acad::eInvalidInput;
|
||
}
|
||
else
|
||
{
|
||
m_nUseArea = _AS_SQMETER(m_polyOutline.Area());
|
||
// 更新周长
|
||
m_nPerimeter = m_outline.Distance2d();
|
||
}
|
||
}
|
||
return es;
|
||
}
|
||
|
||
// 取得夹点说明
|
||
Acad::ErrorStatus TDbSpace::GetGripText(int idx, CString &cs) const
|
||
{
|
||
if (idx == 0)
|
||
cs = _T("移动房间名称");
|
||
else
|
||
{
|
||
XString sInfo;
|
||
int i = idx - 1;
|
||
if (i < m_outline.TotalSegments())
|
||
{
|
||
//modify by lgy 20120221 9.0房间对象顶点夹点需要新功能
|
||
//sInfo << _T("移动第") << (i+1) << _T("个顶点");
|
||
if (!GetCtrlToggle()) //移动顶点
|
||
{
|
||
sInfo << _T("移动第") << (i + 1) << _T("个顶点(Ctrl-增加顶点)");
|
||
}
|
||
else //添加夹点
|
||
{
|
||
sInfo << _T("增加顶点") << _T("(Ctrl-移动第") << (i + 1) << _T("个顶点)");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
sInfo << _T("移动第") << (i - m_outline.TotalSegments() + 1) << _T("条边");
|
||
}
|
||
cs = sInfo;
|
||
}
|
||
return Acad::eOk;
|
||
}
|
||
|
||
|
||
#if ADS>15
|
||
void TDbSpace::CreateGrip()
|
||
{
|
||
TDbEntity::CreateGrip();
|
||
::CreateGrip(this, m_outline, 1);
|
||
}
|
||
|
||
Acad::ErrorStatus TDbSpace::EntityToDim(long iGrip, long iDim, const AcDbEntity*pEnt)
|
||
{
|
||
TEntityBase *pCurve = TDbSpace::cast(pEnt);
|
||
if (pCurve == NULL)
|
||
pCurve = this;
|
||
|
||
XPoly2D polyPath;
|
||
AcGeVector3d normal;
|
||
pCurve->GetPathPoly(polyPath, normal);
|
||
return ::EntityToDim(this, polyPath, iGrip, iDim, 1);
|
||
}
|
||
|
||
Acad::ErrorStatus TDbSpace::DimToEntity(long iGrip, long iDim, double newValue,
|
||
const AcGeVector3d& offset)
|
||
{
|
||
assertWriteEnabled();
|
||
TDbSpace curve;
|
||
curve.CopyPropertiesFrom(this, 0);
|
||
|
||
Acad::ErrorStatus es = ::DimToEntity(this, m_outline, iGrip, iDim, newValue,
|
||
offset, 1);
|
||
if (es == Acad::eOk && !IsValid())
|
||
{
|
||
CopyPropertiesFrom(&curve, 0);
|
||
return Acad::eInvalidInput;
|
||
}
|
||
|
||
// sg add 090326,解决“动态输入后,房间面积不随之发生变化”的BUG
|
||
m_nUseArea = _AS_SQMETER(m_outline.Area());
|
||
// sg add 090602,更新周长
|
||
m_nPerimeter = m_outline.Distance2d();
|
||
return es;
|
||
}
|
||
#endif
|
||
|
||
|
||
// 控制面积标注精确度
|
||
CString TDbSpace::GetAreaByPrecision() const
|
||
{
|
||
double dUseArea = IsHalfArea() ? m_nUseArea*0.5 : m_nUseArea;
|
||
|
||
CString csArea;
|
||
int nPrecisionNum = DocGetSpaceAreaPrecision(); // 小数部分的精确度
|
||
switch (nPrecisionNum)
|
||
{
|
||
case 0:
|
||
csArea.Format(_T("%.0f"), dUseArea);
|
||
break;
|
||
case 1:
|
||
csArea.Format(_T("%.1f"), dUseArea);
|
||
break;
|
||
case 2:
|
||
csArea.Format(_T("%.2f"), dUseArea);
|
||
break;
|
||
case 3:
|
||
csArea.Format(_T("%.3f"), dUseArea);
|
||
break;
|
||
case 4:
|
||
csArea.Format(_T("%.4f"), dUseArea);
|
||
break;
|
||
case 5:
|
||
csArea.Format(_T("%.5f"), dUseArea);
|
||
break;
|
||
case 6:
|
||
csArea.Format(_T("%.6f"), dUseArea);
|
||
break;
|
||
case 7:
|
||
csArea.Format(_T("%.7f"), dUseArea);
|
||
break;
|
||
case 8:
|
||
csArea.Format(_T("%.8f"), dUseArea);
|
||
break;
|
||
default:
|
||
csArea.Format(_T("%.2f"), dUseArea);
|
||
break;
|
||
}
|
||
return csArea;
|
||
}
|
||
|
||
|
||
// 获取“房间编号”的绘制外包框
|
||
void TDbSpace::GetCodeExtentPts(XPoly2D &poly, XPoint pt, XVector3D vt) const
|
||
{
|
||
// XPoint ptTmp1, ptTmp2; // 对角线点
|
||
// double dYDist = vt.y*0.5 + 0.15*m_nTextHeight*GetPScale(), // Y方向上的偏移距离
|
||
// dXDist = vt.x*0.5 + 0.15*m_nTextHeight*GetPScale(); // X方向上的偏移距离
|
||
// ads_polar(pt, -PI/2, dYDist, ptTmp1);
|
||
// ads_polar(pt, PI/2, dYDist, ptTmp2);
|
||
// ads_polar(ptTmp1, 0, -dXDist, ptTmp1);
|
||
// ads_polar(ptTmp2, 0, dXDist, ptTmp2);
|
||
//
|
||
// XRectAngle rect(ptTmp1, ptTmp2);
|
||
// poly.flag = 1;
|
||
// rect.AsPoly2D(poly);
|
||
|
||
vt.x += vt.y * 0.3; // sg modify 081225,将外包框的算法与文字屏蔽一致
|
||
vt.y *= 1.3;
|
||
|
||
// sg modify 090602,8.0的正式版起,将“文字转角”并入“布局转角”
|
||
// double dXDir = GetRotation() + m_nLayoutRotation,
|
||
double dXDir = m_nLayoutRotation,
|
||
dYDir = dXDir + PI / 2.0;
|
||
ads_polar(pt, dXDir + PI, vt.y*0.1, pt); // 调整中心位置
|
||
ads_polar(pt, dYDir + PI, vt.y*0.2, pt);
|
||
|
||
XVector3D u(cos(dXDir), sin(dXDir), 0),
|
||
v(cos(dYDir), sin(dYDir), 0);
|
||
u *= vt.x;
|
||
v *= vt.y;
|
||
poly.SetFlag(1);
|
||
poly.AppendNode(pt);
|
||
poly.AppendNode(pt + u);
|
||
poly.AppendNode(pt + u + v);
|
||
poly.AppendNode(pt + v);
|
||
}
|
||
|
||
|
||
double TDbSpace::GetNameDistRatio(BOOL bChineseName) const // 名称位置
|
||
{
|
||
double dResult = 0.7;
|
||
|
||
// modify by xly on 101020,根据8.5需求,房间对象支持编号、名称、面积和面积单位的独立控制显示
|
||
// int nSpFlag = DocGetSpaceDispMode();
|
||
// if ((nSpFlag&SPF_NAME_AND_CODE) != 0) // 名称、编号同时标注
|
||
if (IsDimName() && IsDimCode()) // 名称、编号同时标注
|
||
{
|
||
// sg modify 081225,“建筑轮廓”不绘制“编号”
|
||
dResult = (m_nType == TDbSpace::kTotalArea) ? 0.7 : 1.6; // 单行名称
|
||
if (m_bMText)
|
||
{
|
||
dResult = bChineseName ? 2.25 : 1.1; // 两行名称
|
||
if (m_nType == TDbSpace::kTotalArea) // 建筑轮廓
|
||
{
|
||
dResult = bChineseName ? 1.4 : 0.25; // 两行名称
|
||
}
|
||
}
|
||
}
|
||
// else if (((nSpFlag&SPF_CODE) == 0) && (m_bMText)) // 只标注名称,且为两行文字
|
||
else if (IsDimName() && (m_bMText)) // 只标注名称,且为两行文字
|
||
{
|
||
dResult = bChineseName ? 1.4 : 0.25;
|
||
}
|
||
|
||
return dResult;
|
||
}
|
||
|
||
double TDbSpace::GetCodeDistRatio() const // 编号位置
|
||
{
|
||
double dResult = 0.7;
|
||
|
||
// modify by xly on 101020,根据8.5需求,房间对象支持编号、名称、面积和面积单位的独立控制显示
|
||
// int nSpFlag = DocGetSpaceDispMode();
|
||
// if ((nSpFlag&SPF_NAME_AND_CODE) != 0) // 名称、编号同时标注
|
||
if (IsDimName() && IsDimCode()) // 名称、编号同时标注
|
||
{
|
||
dResult = m_bMText ? (-0.25) : 0.25;
|
||
}
|
||
|
||
return dResult;
|
||
}
|
||
|
||
double TDbSpace::GetAreaDistRatio() const // 面积位置
|
||
{
|
||
double dResult = -0.5;
|
||
|
||
// modify by xly on 101020,根据8.5需求,房间对象支持编号、名称、面积和面积单位的独立控制显示
|
||
// int nSpFlag = DocGetSpaceDispMode();
|
||
// if ((nSpFlag&SPF_NAME_AND_CODE) != 0) // 名称、编号同时标注
|
||
if (IsDimName() && IsDimCode()) // 名称、编号同时标注
|
||
{
|
||
dResult = (m_nType == TDbSpace::kTotalArea) ? -0.5 : -1.1;
|
||
if (m_bMText)
|
||
{
|
||
dResult = (m_nType == TDbSpace::kTotalArea) ? -0.95 : -1.6;
|
||
}
|
||
}
|
||
// else if (((nSpFlag&SPF_CODE) == 0) && (m_bMText)) // 只标注名称,且为两行文字
|
||
else if (IsDimName() && (m_bMText)) // 只标注名称,且为两行文字
|
||
{
|
||
dResult = -0.95;
|
||
}
|
||
|
||
return dResult;
|
||
}
|
||
|
||
// sg add 081224,支持图形导出命令
|
||
Acad::ErrorStatus TDbSpace::DownGradeSave(int nDrawMode,
|
||
AcDbVoidPtrArray &entSet,
|
||
BOOL *bErase)
|
||
{
|
||
// sg add 090519,如果是按半面积标注,比如:阳台对象,则导出T7后,炸开
|
||
// sg modify 101209,如果房间名称和房间编号都不标注,导出T7后,炸开
|
||
// if (IsHalfArea())
|
||
if ((g_nSaveTArchVer > 3 && g_nSaveTArchVer < 8) && (IsHalfArea() || (!IsDimName() && !IsDimCode())))
|
||
{
|
||
XExplodeStream dc(entSet);
|
||
if (!OnExplodeOrDraw(dc))
|
||
return Acad::eOk;
|
||
|
||
Acad::ErrorStatus es = Acad::eOk;
|
||
dc.SetPropertiesFrom(this);
|
||
if (nDrawMode == DRAW_2D)
|
||
es = ExplodeOrDraw2d(dc);
|
||
else
|
||
es = ExplodeOrDraw3d(dc);
|
||
|
||
if (bErase)
|
||
*bErase = TRUE;
|
||
return es;
|
||
}
|
||
|
||
int nSpFlag = DocGetSpaceDispMode();
|
||
// sg modify 101216,如果独立控制,导出T7后,炸开,但是需要特殊处理名称和房间编号全部标注的情况
|
||
if ((g_nSaveTArchVer>3 && g_nSaveTArchVer < 8) && (GetSpaceDispMode() == 0))
|
||
{
|
||
if ((nSpFlag&SPF_NAME_AND_CODE) != 0 && IsDimName() && IsDimCode())
|
||
; // 特殊处理一下,放置和以前的处理规则不统一,将编号变成单行文字
|
||
else
|
||
{
|
||
XExplodeStream dc(entSet);
|
||
if (!OnExplodeOrDraw(dc))
|
||
return Acad::eOk;
|
||
|
||
Acad::ErrorStatus es = Acad::eOk;
|
||
dc.SetPropertiesFrom(this);
|
||
if (nDrawMode == DRAW_2D)
|
||
es = ExplodeOrDraw2d(dc);
|
||
else
|
||
es = ExplodeOrDraw3d(dc);
|
||
|
||
if (bErase)
|
||
*bErase = TRUE;
|
||
return es;
|
||
}
|
||
}
|
||
|
||
BOOL bFlag = // 是否Erase原来的,并clone出新对象的标记
|
||
m_bMText || HasHatch() || (nSpFlag&SPF_NAME_AND_CODE) != 0;
|
||
if (bFlag && g_nSaveTArchVer > 3 && g_nSaveTArchVer < 8) // 导出为T5、T6、T7
|
||
{
|
||
XString szName(1024); // sg modify 090423,解决图形导出崩溃问题
|
||
szName << m_sName;
|
||
if (m_bMText)
|
||
{
|
||
szName << _T(" ") << m_sSndName; // 两行名称合并为一行
|
||
}
|
||
|
||
if (HasHatch()) // 绘制“填充”,增加一个“填充”对象
|
||
{
|
||
// sg modify 090512,解决角度导出后不起作用的问题
|
||
// AcDbHatch *pHatch = NewHatchFromPoly2D(m_outline, m_sHatchStyle, m_dHatchScale);
|
||
// sg modify 090602,填充对象,也要考虑布局转角
|
||
// AcDbHatch *pHatch = NewHatchFromPoly2D(m_outline, m_sHatchStyle, m_dHatchScale, m_dHatchAngle);
|
||
double dCurrentUcs = Ucs2Wcs(0.0);
|
||
|
||
AcDbHatch *pHatch = NewHatchFromPoly2D(m_outline, m_sHatchStyle, m_dHatchScale, m_dHatchAngle + m_nLayoutRotation - dCurrentUcs);
|
||
if (pHatch != NULL)
|
||
{
|
||
pHatch->setLayer(m_idHatchLayer);
|
||
// sg modify 101207,8.5起支持真彩色设置,修改对应的填充对象导出;
|
||
// pHatch->setColorIndex(m_nHatchColor);
|
||
AcCmColor cmColor = GetHatchTrueColor();
|
||
pHatch->setColor(cmColor);
|
||
// pHatch->setPatternAngle(m_dHatchAngle);
|
||
entSet.append(pHatch);
|
||
}
|
||
}
|
||
|
||
TDbSpace *pSpace = NULL; // sg modify 090325,防止导出T7崩溃
|
||
{
|
||
XPushMemVar<int> vTemp(g_nSaveTArchVer, _TCH_VERSION);
|
||
pSpace = (TDbSpace*)clone();
|
||
}
|
||
pSpace->SetMText(FALSE);
|
||
pSpace->SetHasHatch(FALSE);
|
||
pSpace->SetName(szName);
|
||
entSet.append(pSpace);
|
||
|
||
// 同时标注名称和编号,增加一个“单行文字”
|
||
// sg add 090527,建筑轮廓不增加编号的单行文字
|
||
if ((nSpFlag&SPF_NAME_AND_CODE) != 0 && m_nType != TDbSpace::kTotalArea)
|
||
{
|
||
ads_matrix matRot;
|
||
XPoint ptDim = m_ptLocation;
|
||
ptDim.y += 1.9*m_nTextHeight*GetPScale();
|
||
m_ptLocation.GetRotationMatrix(Layout2Wcs(m_nRotation), matRot);
|
||
ptDim.TransformBy(matRot);
|
||
|
||
TDbText *pText = new TDbText;
|
||
pText->CopyPropertiesFrom(this, 0);
|
||
pText->SetMaskFlag(IsMask()); // 自动屏蔽
|
||
pText->SetHeight(m_nTextHeight);
|
||
pText->SetStyleId(m_idTextStyle);
|
||
pText->SetAlignment(XExplodeDraw::kMiddleCenter);
|
||
// sg delete 090602,8.0的正式版起,将“文字转角”并入“布局转角”
|
||
// pText->SetRotation(m_nRotation);
|
||
pText->SetLocation(ptDim);
|
||
pText->SetText(m_sCode);
|
||
pText->setLayer(layerId());
|
||
pText->setColorIndex(colorIndex());
|
||
entSet.append(pText);
|
||
}
|
||
|
||
if (bErase)
|
||
{
|
||
*bErase = TRUE;
|
||
}
|
||
return Acad::eOk;
|
||
}
|
||
return TDbEntity::DownGradeSave(nDrawMode, entSet, bErase); // 其他情况,基类处理
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////////
|
||
// 显示房间: 编号/名称,面积
|
||
// _T("名称")在_T("面积")上面0.5mm
|
||
Acad::ErrorStatus
|
||
TDbSpace::ExplodeOrDraw2d(XExplodeDraw &dcText) const
|
||
{
|
||
assertReadEnabled();
|
||
|
||
std::vector<TGGePoly2D> holds(0);// 房间所产生的遮盖曲线
|
||
|
||
// 如果不需要屏蔽文字背景,则先画并且用TGGeSolid先画填充,再画文字
|
||
// modify jsx on 060524 TGGeSolid绘制填充的时候,无论是否屏蔽文字背景,都需要先绘制TGGeSolid填充。
|
||
if (m_sHatchStyle == "SOLID" || !IsMask())
|
||
{
|
||
DrawHatchInExplode(dcText, holds);
|
||
DrawTextInExplode(dcText, holds);
|
||
}
|
||
else
|
||
{
|
||
DrawTextInExplode(dcText, holds);
|
||
DrawHatchInExplode(dcText, holds);
|
||
}
|
||
|
||
AcDbObjectId idMe = objectId();
|
||
BOOL bHighlight = !idMe;
|
||
if (!bHighlight)
|
||
bHighlight = IsHighlight();
|
||
|
||
if (bHighlight || IsShowOutline())
|
||
dcText << m_outline;
|
||
return Acad::eOk;
|
||
}
|
||
|
||
Acad::ErrorStatus
|
||
TDbSpace::ExplodeOrDraw3d(XExplodeDraw &dc) const
|
||
{
|
||
assertReadEnabled();
|
||
if (Has3D())
|
||
{
|
||
XVector3D vt(0, 0, -m_nFloorThick);
|
||
XPoly2D polyFloor = m_outline;
|
||
polyFloor.SetElevation(GetElevation());
|
||
dc.DrawBody(polyFloor, vt);
|
||
}
|
||
return Acad::eOk;
|
||
}
|
||
|
||
|
||
int TDbSpace::ConvertText(TConvertTextPtr ptr, void *pData)
|
||
{
|
||
XString sText;
|
||
int nRet = ptr(m_sName, sText, pData);
|
||
if (nRet == RTNORM)
|
||
{
|
||
assertWriteEnabled();
|
||
m_sName = sText;
|
||
}
|
||
return nRet;
|
||
}
|
||
|
||
|
||
// 注:查找替换只需要支持对房间名称的操作
|
||
BOOL
|
||
TDbSpace::GetText(Adesk::UInt32 cookies, TDbText &text) const
|
||
{
|
||
// if (cookies != 0) // sg modify 081212,支持两行名称
|
||
if ((m_bMText && cookies != 0 && cookies != 1) || (!m_bMText && cookies != 0))
|
||
return FALSE;
|
||
|
||
XPoint ptName = m_ptLocation, // 名称或标号的位置,在上面
|
||
ptName2 = m_ptLocation, // 第二行名称,sg add 081212
|
||
ptArea = m_ptLocation; // 面积的位置,在下面
|
||
|
||
text.setPropertiesFrom(this);
|
||
text.SetMaskFlag(IsMask()); // 自动屏蔽
|
||
|
||
// sg modify 110908,解决外部参照中包含房间标注中的崩溃问题
|
||
// 所有的数据从对象中保存的数据读取
|
||
/*
|
||
//AcDbObjectId idStyle = InitTextStyle(TS_SPACE, database());
|
||
AcDbObjectId idStyle = InitTextStyle(TS_SPACE);
|
||
ASSERT(!!idStyle);
|
||
|
||
double nTextSize = 3.5;
|
||
OPENOBJ_BEGIN(idStyle, AcDb::kForRead, AcDbTextStyleTableRecord, pStyle);
|
||
ASSERT(pStyle);
|
||
nTextSize = pStyle->textSize();
|
||
if (nTextSize < 1.0E-3)
|
||
nTextSize = 3.5;
|
||
OPENOBJ_END();
|
||
|
||
text.SetHeight(nTextSize);
|
||
text.SetStyleId(idStyle);
|
||
int nColor = GetTextStyleColor(idStyle);
|
||
if (nColor > 0)
|
||
text.setColorIndex(nColor);
|
||
*/
|
||
text.SetHeight(m_nTextHeight);
|
||
text.SetStyleId(m_idTextStyle);
|
||
double nTextSize = m_nTextHeight;
|
||
|
||
nTextSize *= GetPScale();
|
||
|
||
// ptName.y += nTextSize*0.7; // sg modify 081211,只需要支持查找两行“房间名称”
|
||
// ptArea.y -= nTextSize*0.5;
|
||
ptName.y += nTextSize*GetNameDistRatio(TRUE);
|
||
ptName2.y += nTextSize*GetNameDistRatio(FALSE);
|
||
text.SetAlignment(XExplodeDraw::kMiddleCenter);
|
||
|
||
// text.SetLocation(ptName); // sg modify 081212
|
||
// text.SetText(m_sName);
|
||
if (cookies == 1) // 第二行名称
|
||
{
|
||
text.SetLocation(ptName2);
|
||
text.SetText(m_sSndName);
|
||
}
|
||
else // 第一行名称
|
||
{
|
||
text.SetLocation(ptName);
|
||
text.SetText(m_sName);
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
// 返回发现的位置,同时posStart往前移动(以便继续找下一个使用),
|
||
TTextPosition
|
||
TDbSpace::FindSubText(const TCHAR *sSubText, TTextPosition &posStart, TTextRange *pRange) const
|
||
{
|
||
TTextPosition pos;
|
||
if (!sSubText || !sSubText[0])
|
||
return pos;
|
||
|
||
TTextPosition posNext = posStart;
|
||
while (1)
|
||
{
|
||
TDbText text;
|
||
if (!GetText(posNext.m_nCookies, text))
|
||
break;
|
||
|
||
TTextPosition posFind = text.FindSubText(sSubText, posNext, pRange);
|
||
if (!posFind)
|
||
{
|
||
posNext.m_nCookies++;
|
||
posNext.m_nTextPos = 0;
|
||
}
|
||
else
|
||
{
|
||
posStart = posNext;
|
||
if (!posStart)
|
||
{
|
||
posStart.m_nCookies++;
|
||
posStart.m_nTextPos = 0;
|
||
}
|
||
posFind.m_nCookies = posNext.m_nCookies;
|
||
pos = posFind;
|
||
break;
|
||
}
|
||
}
|
||
return pos;
|
||
}
|
||
|
||
// 返回下一次查找的开始位置
|
||
TTextPosition
|
||
TDbSpace::ReplaceSubText(const TTextPosition &posRep, const TCHAR *sRepText, TTextRange *pRange)
|
||
{
|
||
assertWriteEnabled();
|
||
TTextPosition posNext;
|
||
TDbText text;
|
||
if (!GetText(posRep.m_nCookies, text))
|
||
return posNext;
|
||
posNext = text.ReplaceSubText(posRep, sRepText, pRange);
|
||
|
||
int cookies = posRep.m_nCookies;
|
||
if (cookies == 0) // 第一行名称,sg modify 081212
|
||
{
|
||
SetName(text.GetText());
|
||
}
|
||
else if (cookies == 1) // 第二行名称
|
||
{
|
||
SetSndName(text.GetText()); // 修改第二行
|
||
}
|
||
/*
|
||
else if (cookies == 1) {
|
||
SetText2 (text.GetText());
|
||
}
|
||
*/
|
||
if (!posNext)
|
||
{
|
||
posNext.m_nCookies = posRep.m_nCookies + 1;
|
||
posNext.m_nTextPos = 0;
|
||
}
|
||
return posNext;
|
||
}
|
||
|
||
|
||
void TDbSpace::CreateWipeOut(AcDbVoidPtrArray &entSet) const
|
||
{
|
||
AcDbVoidPtrArray ssText;
|
||
XExplodeStream dc(ssText);
|
||
dc.SetPropertiesFrom(this); // add by whl on 060404
|
||
ExplodeOrDraw2d(dc);
|
||
|
||
int nLen = ssText.length();
|
||
for (int i = 0; i < nLen; i++)
|
||
{
|
||
TDbText *pText = TDbText::cast((AcRxObject*)ssText[i]);
|
||
if (pText)
|
||
{
|
||
AcDbEntity *pEnt = pText->CreateWipeOut();
|
||
if (pEnt)
|
||
entSet.append(pEnt);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
//////////////////////////////////////////////////////////////////
|
||
// 取 动 态 属 性 显 示 数 据 的 函 数
|
||
void TDbSpace::GetTips(DList<TObjInfoUnit> &lstInfo) const
|
||
{
|
||
lstInfo.Append(new TObjInfoUnit(_T("对象类型"), _T("房间")));
|
||
lstInfo.Append(new TObjInfoUnit(_T("编号"), m_sCode));
|
||
// lstInfo.Append(new TObjInfoUnit(_T("名称"), m_sName)); // sg modify 081212
|
||
if (m_bMText) // 两行名称
|
||
{
|
||
lstInfo.Append(new TObjInfoUnit(_T("名称1"), m_sName));
|
||
lstInfo.Append(new TObjInfoUnit(_T("名称2"), m_sSndName));
|
||
}
|
||
else // 单行名称
|
||
lstInfo.Append(new TObjInfoUnit(_T("名称"), m_sName));
|
||
|
||
// add xly on 101019,显示房间对象归属套内面积的户号
|
||
if (m_nType == kBalconyArea) // 套内阳台
|
||
{
|
||
AcDbObjectId idHouse = GetHouseId();
|
||
TDbSpace *pSpace = NULL;
|
||
if (idHouse.isValid()) // 套内阳台有户号
|
||
{
|
||
CString csCode = _T("");
|
||
acdbOpenObject(pSpace, idHouse, AcDb::kForRead);
|
||
if (pSpace != NULL)
|
||
{
|
||
csCode = pSpace->m_sCode;
|
||
pSpace->close();
|
||
}
|
||
|
||
lstInfo.Append(new TObjInfoUnit(_T("归属户号"), csCode));
|
||
}
|
||
else // 套内阳台不属于套内面积
|
||
{
|
||
lstInfo.Append(new TObjInfoUnit(_T("归属户号"), _T("")));
|
||
}
|
||
}
|
||
|
||
lstInfo.Append(new TObjInfoUnit(_T("面积"), XString(_T("%.2f"), m_nUseArea)));
|
||
lstInfo.Append(new TObjInfoUnit(_T("体积"), XString(_T("%.3f"), GetUseVolume())));
|
||
lstInfo.Append(new TObjInfoUnit(_T("周长"), Dist2Str(m_nPerimeter)));
|
||
|
||
// sg modify 090526,多数情况下,m_nKickboardLength也没有随着轮廓线的更新而更新,造成显示错误,因此在此重新计算
|
||
// 如果围护结构不存在,踢脚长必然等于周长;有门存在,踢脚线长等于周长,减去门的总长度
|
||
double dKickboardLen = m_nKickboardLength;
|
||
int nLength = m_lstWallEnclosure.Length();
|
||
if (nLength == 0)
|
||
dKickboardLen = m_nPerimeter;
|
||
// lstInfo.Append(new TObjInfoUnit(_T("踢脚长"), Dist2Str(m_nKickboardLength)));
|
||
lstInfo.Append(new TObjInfoUnit(_T("踢脚长"), Dist2Str(dKickboardLen)));
|
||
|
||
lstInfo.Append(new TObjInfoUnit(_T("墙壁面积"), XString(_T("%.2f"), m_nWallSurfArea)));
|
||
lstInfo.Append(new TObjInfoUnit(_T("外墙面积"), XString(_T("%.2f"), m_nExtWallArea)));
|
||
lstInfo.Append(new TObjInfoUnit(_T("外门面积"), XString(_T("%.2f"), m_nExtDoorArea)));
|
||
lstInfo.Append(new TObjInfoUnit(_T("外窗面积"), XString(_T("%.2f"), m_nExtWinArea)));
|
||
}
|
||
|
||
const TCHAR *
|
||
TDbSpace::GetDefaultLayer() const
|
||
{
|
||
return LAY_SPACE;
|
||
}
|
||
|
||
|
||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
// 搜索房间中取得数据
|
||
Acad::ErrorStatus
|
||
TDbSpace::UpdateFrom(const XAecSpaceCell &src, BOOL bExtSpace)
|
||
{
|
||
double nTotalDoorWidth = 0.0, nTotalHoleArea = 0.0;
|
||
double nExtWinArea = 0.0, nExtDoorArea = 0.0, nExtWallArea = 0.0;
|
||
|
||
//add by whl on 060329,否则搜索房间会重复记录
|
||
m_lstWallEnclosure.Reset();
|
||
|
||
double dMinHeight = 0.0;
|
||
for (int k = 0; k < src.Length(); k++)
|
||
{
|
||
const XAecSpaceWall &wall = src[k];
|
||
|
||
OPENOBJ_BEGIN(wall.m_ent.name, AcDb::kForRead, TDbWall, pDbWall);
|
||
if (pDbWall)
|
||
{
|
||
/////////////////////////////////////////////////////////////////////////
|
||
// 建立墙和房间的关联, 供概预算软件使用
|
||
m_lstWallEnclosure.Append(new AcDbObjectId(pDbWall->objectId())); //不驻留DWG
|
||
if (objectId())
|
||
{
|
||
if (pDbWall->upgradeOpen() == Acad::eOk)
|
||
{
|
||
ASSERT(wall.leftSpace == &src || wall.rightSpace == &src);
|
||
if (wall.leftSpace == &src) pDbWall->SetLeftSpace(objectId());
|
||
else pDbWall->SetRightSpace(objectId());
|
||
pDbWall->downgradeOpen();
|
||
}
|
||
}
|
||
|
||
double nHoleArea = _AS_SQMETER(pDbWall->GetHoleArea());
|
||
nTotalHoleArea += nHoleArea;
|
||
DList<TOpeningData> lstOpenings;
|
||
pDbWall->GetOpenings(lstOpenings, TRUE);
|
||
for (int i = 0; i < lstOpenings.Length(); i++)
|
||
{
|
||
TOpeningData *pOpening = lstOpenings[i];
|
||
if (pOpening->GetKind() == TOpeningData::OP_DOOR)
|
||
nTotalDoorWidth += pOpening->GetWidth();
|
||
}
|
||
|
||
if (pDbWall->IsExternal(0))
|
||
{
|
||
nExtWallArea += _AS_SQMETER(pDbWall->GetSurfaceArea(0));
|
||
nExtWinArea += _AS_SQMETER(pDbWall->GetHoleArea(TOpeningData::OP_WINDOW)
|
||
+ pDbWall->GetHoleArea(TOpeningData::OP_PROWIN)
|
||
+ pDbWall->GetHoleArea(TOpeningData::OP_ARCWIN));
|
||
nExtDoorArea += _AS_SQMETER(pDbWall->GetHoleArea(TOpeningData::OP_DOOR));
|
||
}
|
||
else if (pDbWall->IsExternal(1))
|
||
{
|
||
nExtWallArea += _AS_SQMETER(pDbWall->GetSurfaceArea(1));
|
||
nExtWinArea += _AS_SQMETER(pDbWall->GetHoleArea(TOpeningData::OP_WINDOW)
|
||
+ pDbWall->GetHoleArea(TOpeningData::OP_PROWIN)
|
||
+ pDbWall->GetHoleArea(TOpeningData::OP_ARCWIN));
|
||
nExtDoorArea += _AS_SQMETER(pDbWall->GetHoleArea(TOpeningData::OP_DOOR));
|
||
}
|
||
|
||
if (dMinHeight < 1e-6 || pDbWall->GetHeight() < dMinHeight)
|
||
dMinHeight = pDbWall->GetHeight();
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
|
||
XPoly2D polyWall(1), polyCen;
|
||
((XAecSpaceCell &)src).InternalPoly2D(polyWall, bExtSpace ? 2 : 1);
|
||
((XAecSpaceCell &)src).CenterPoly2D(polyCen);
|
||
|
||
polyWall.SetElevation(0.0);
|
||
|
||
|
||
m_nUseArea = _AS_SQMETER(polyWall.Area());
|
||
m_nOccuArea = _AS_SQMETER(polyCen.Area());
|
||
m_nCeilArea = _AS_SQMETER(polyWall.Area());
|
||
//m_nHeight,
|
||
m_nPerimeter = polyWall.Distance2d();
|
||
m_nWallSurfArea = _AS_SQMETER(m_nHeight*m_nPerimeter) - nTotalHoleArea;
|
||
m_nKickboardLength = m_nPerimeter - nTotalDoorWidth;
|
||
m_nExtWinArea = nExtWinArea;
|
||
m_nExtDoorArea = nExtDoorArea;
|
||
m_nExtWallArea = nExtWallArea;
|
||
m_outline = polyWall;
|
||
if (bExtSpace && m_outline.PathArea() > 0.0)
|
||
m_outline.Reverse();
|
||
else if (!bExtSpace && m_outline.PathArea() < 0.0)
|
||
m_outline.Reverse();
|
||
|
||
m_nHeight = dMinHeight; // 节能修改要求,高度设为最小墙高,modified by wyg 20090624
|
||
// m_nHeight=DocGetLHeight();//add by whl on 051227
|
||
return Acad::eOk;
|
||
}
|
||
|
||
|
||
BOOL
|
||
TDbSpace::IsMask() const
|
||
{
|
||
return ((m_nSpaceFlag&SF_MASK) != 0);
|
||
}
|
||
|
||
BOOL
|
||
TDbSpace::IsHighlight() const
|
||
{
|
||
return ((m_nSpaceFlag&SF_HIGHLIGHT) != 0);
|
||
}
|
||
|
||
BOOL
|
||
TDbSpace::IsShowOutline() const
|
||
{
|
||
return ((m_nSpaceFlag&SF_SHOWOUTLINE) != 0);
|
||
}
|
||
|
||
void TDbSpace::SetMask(BOOL bTrue)
|
||
{
|
||
assertWriteEnabled();
|
||
if (bTrue)
|
||
m_nSpaceFlag |= SF_MASK;
|
||
else
|
||
m_nSpaceFlag &= ~SF_MASK;
|
||
}
|
||
|
||
void TDbSpace::SetHighlight(BOOL bTrue)
|
||
{
|
||
assertWriteEnabled();
|
||
if (bTrue)
|
||
m_nSpaceFlag |= SF_HIGHLIGHT;
|
||
else
|
||
m_nSpaceFlag &= ~SF_HIGHLIGHT;
|
||
}
|
||
|
||
void TDbSpace::SetShowOutline(BOOL bTrue)
|
||
{
|
||
assertWriteEnabled();
|
||
if (bTrue)
|
||
m_nSpaceFlag |= SF_SHOWOUTLINE;
|
||
else
|
||
m_nSpaceFlag &= ~SF_SHOWOUTLINE;
|
||
}
|
||
|
||
|
||
// sg modify 081212,两行名称,及名称、编号同时显示
|
||
// 注:在位编辑,需要支持名称和编号
|
||
void TDbSpace::SetSubText(long i, CString sText)
|
||
{
|
||
assertWriteEnabled();
|
||
// xly modify 101111,根据8.5需求,房间对象支持编号、名称、面积和面积单位的独立控制显示
|
||
// int nSpFlag = DocGetSpaceDispMode();
|
||
BOOL bShowName = IsDimName(),
|
||
bShowCode = IsDimCode();
|
||
|
||
if (i == 0)
|
||
{
|
||
// if ((nSpFlag&SPF_CODE) != 0)
|
||
if (bShowCode && !bShowName)
|
||
SetCode(sText); // 编号
|
||
// else
|
||
else if (bShowCode || bShowName)
|
||
SetName(sText); // 名称(同时标注时,也是名称在编号之上)
|
||
}
|
||
else if (i == 1)
|
||
{
|
||
// if ((nSpFlag&SPF_NAME_AND_CODE) != 0)
|
||
if (bShowName && bShowCode) // 同时标注
|
||
{
|
||
if (m_bMText)
|
||
{
|
||
SetSndName(sText); // 两行名称中的第二行
|
||
}
|
||
else if (m_nType != TDbSpace::kTotalArea)
|
||
{
|
||
SetCode(sText); // 编号
|
||
}
|
||
}
|
||
// else if ((nSpFlag&SPF_CODE)==0 && m_bMText) // 只标注名称,但为两行名称
|
||
else if (bShowCode && m_bMText) // 只标注名称,但为两行名称
|
||
{
|
||
SetSndName(sText); // 两行名称中的第二行
|
||
}
|
||
}
|
||
else if (i == 2)
|
||
{
|
||
// if ((nSpFlag&SPF_NAME_AND_CODE)!=0 && m_bMText && (m_nType!=TDbSpace::kTotalArea))
|
||
if (bShowName && bShowCode && m_bMText && (m_nType != TDbSpace::kTotalArea))
|
||
{
|
||
SetCode(sText); // 同时标注,且为两行名称时的编号
|
||
}
|
||
}
|
||
}
|
||
|
||
// sg add 111116,支持导出XML
|
||
CString TDbSpace::GetXml(const AcGeMatrix3d& mat) const
|
||
{
|
||
TXmlTree xmlTree;
|
||
POSITION posRoot = xmlTree.Insert(_T("ATS_SPACE"), NULL, NULL);
|
||
{
|
||
xmlTree.SetAttribute(posRoot, _T("name"), _T("房间"));
|
||
xmlTree.SetAttribute(posRoot, _T("comment"), _T("上华对象名称"));
|
||
}
|
||
|
||
CString strText;
|
||
POSITION posItem1 = xmlTree.Insert(_T("Object_ID"), posRoot, NULL);
|
||
{
|
||
xmlTree.SetAttribute(posItem1, _T("name"), _T("对象编号"));
|
||
xmlTree.SetAttribute(posItem1, _T("comment"), _T("当前对象的句柄"));
|
||
strText.Format(_T("%ld"), objectId());
|
||
xmlTree.SetItemText(posItem1, strText);
|
||
}
|
||
|
||
POSITION posItem = NULL;
|
||
POSITION posItem2 = xmlTree.Insert(_T("Area"), posRoot, posItem1);
|
||
{
|
||
xmlTree.SetAttribute(posItem2, _T("name"), _T("面积参数"));
|
||
|
||
posItem = NULL;
|
||
posItem = xmlTree.Insert(_T("Area_feature"), posItem2, posItem);
|
||
{
|
||
xmlTree.SetAttribute(posItem, _T("name"), _T("面积性质"));
|
||
|
||
AreaType nType = GetType();
|
||
switch (nType)
|
||
{
|
||
case kUseArea:
|
||
strText = _T("使用面积");
|
||
break;
|
||
case kHouseArea:
|
||
strText = _T("套内面积");
|
||
break;
|
||
case kTotalArea:
|
||
strText = _T("建筑面积");
|
||
break;
|
||
case kHoleArea:
|
||
strText = _T("洞口面积");
|
||
break;
|
||
case kShareArea:
|
||
strText = _T("公摊面积");
|
||
break;
|
||
case kBalconyArea:
|
||
strText = _T("阳台面积");
|
||
break;
|
||
case kOther:
|
||
strText = _T("其他面积");
|
||
break;
|
||
}
|
||
xmlTree.SetItemText(posItem, strText);
|
||
}
|
||
|
||
posItem = xmlTree.Insert(_T("Area_half"), posItem2, posItem);
|
||
{
|
||
xmlTree.SetAttribute(posItem, _T("name"), _T("面积取一半"));
|
||
strText = IsHalfArea() ? _T("1") : _T("0");
|
||
xmlTree.SetItemText(posItem, strText);
|
||
}
|
||
|
||
posItem = xmlTree.Insert(_T("Area_thick"), posItem2, posItem);
|
||
{
|
||
xmlTree.SetAttribute(posItem, _T("name"), _T("地板厚度"));
|
||
strText.Format(_T("%.0f"), GetFloorThick());
|
||
xmlTree.SetItemText(posItem, strText);
|
||
}
|
||
|
||
posItem = xmlTree.Insert(_T("Area_finish"), posItem2, posItem);
|
||
{
|
||
xmlTree.SetAttribute(posItem, _T("name"), _T("粉刷层厚度"));
|
||
strText.Format(_T("%.0f"), GetStuccoThickness());
|
||
xmlTree.SetItemText(posItem, strText);
|
||
}
|
||
}
|
||
|
||
POSITION posItem3 = xmlTree.Insert(_T("Room"), posRoot, posItem2);
|
||
{
|
||
xmlTree.SetAttribute(posItem3, _T("name"), _T("房间参数"));
|
||
|
||
posItem = NULL;
|
||
posItem = xmlTree.Insert(_T("Room_Name1"), posItem3, posItem);
|
||
{
|
||
xmlTree.SetAttribute(posItem, _T("name"), _T("房间名称"));
|
||
xmlTree.SetItemText(posItem, m_sName);
|
||
}
|
||
|
||
if (m_bMText)
|
||
{
|
||
posItem = xmlTree.Insert(_T("Room_Name2"), posItem3, posItem);
|
||
{
|
||
xmlTree.SetAttribute(posItem, _T("name"), _T("房间别名"));
|
||
xmlTree.SetItemText(posItem, m_sSndName);
|
||
}
|
||
}
|
||
|
||
posItem = xmlTree.Insert(_T("Room_Number"), posItem3, posItem);
|
||
{
|
||
xmlTree.SetAttribute(posItem, _T("name"), _T("房间编号"));
|
||
xmlTree.SetItemText(posItem, m_sCode);
|
||
}
|
||
|
||
// cet 2013.7.25 add 导出编号位置
|
||
posItem = xmlTree.Insert(_T("LabelPosition"), posItem3, posItem);
|
||
{
|
||
XPoint ptLoc = m_ptLocation;
|
||
ptLoc.TransformBy(mat);
|
||
xmlTree.SetAttribute(posItem, _T("name"), _T("标记位置"));
|
||
strText.Format(_T("%f,%f,%f"), ptLoc.x, ptLoc.y, ptLoc.z);
|
||
xmlTree.SetItemText(posItem, strText);
|
||
}
|
||
}
|
||
|
||
POSITION posItem4 = xmlTree.Insert(_T("Baseline"), posRoot, posItem3);
|
||
{
|
||
xmlTree.SetAttribute(posItem4, _T("name"), _T("房间轮廓"));
|
||
|
||
posItem = NULL;
|
||
TADSGePoint3d ptNode;
|
||
int nLen = m_outline.Length();
|
||
for (int i = 0; i < nLen; i++)
|
||
{
|
||
ptNode = m_outline[i];
|
||
// sg add 120117,对点进行坐标变换
|
||
ptNode.TransformBy(mat);
|
||
|
||
strText.Format(_T("Point_%d"), i + 1);
|
||
posItem = xmlTree.Insert(strText, posItem4, posItem);
|
||
{
|
||
strText.Format(_T("第%d点"), i + 1);
|
||
xmlTree.SetAttribute(posItem, _T("name"), strText);
|
||
strText.Format(_T("%f,%f,%f"), ptNode.x, ptNode.y, ptNode.z);
|
||
xmlTree.SetItemText(posItem, strText);
|
||
}
|
||
|
||
strText.Format(_T("Ang_%d"), i + 1);
|
||
posItem = xmlTree.Insert(strText, posItem4, posItem);
|
||
{
|
||
strText.Format(_T("圆心角%d"), i + 1);
|
||
xmlTree.SetAttribute(posItem, _T("name"), strText);
|
||
strText.Format(_T("%f"), m_outline.GetBulge(i));
|
||
xmlTree.SetItemText(posItem, strText);
|
||
}
|
||
}
|
||
}
|
||
|
||
CString strBase = TEntityBase::GetXml(mat);
|
||
CString strXml = xmlTree.GetXml();
|
||
int nIndex = strXml.Find(_T("<Object_ID"));
|
||
strXml.Insert(nIndex, strBase);
|
||
|
||
return strXml;
|
||
}
|
||
|
||
void TDbSpace::DrawHatchInExplode(TGGiExplodeDrawBase &dc, const std::vector<TGGePoly2D> &holds) const
|
||
{
|
||
if (!HasHatch() || !m_sHatchStyle) return;
|
||
TMasterProperties prop;
|
||
dc.BackUpProperties(prop);
|
||
|
||
#if ADS < 16 // 15平台没有真彩色
|
||
dcText.SetColorLayer(m_nHatchColor, m_idHatchLayer);
|
||
#else
|
||
dc.SetLayer(m_idHatchLayer);
|
||
AcCmColor color = GetHatchTrueColor();
|
||
dc.SetTrueColor(color);
|
||
#endif
|
||
|
||
if (m_sHatchStyle == _T("SOLID") /*&& !IsMask()*/)
|
||
{
|
||
dc << TGGeSolid(m_outline);
|
||
}
|
||
else
|
||
{
|
||
double dTmp = Ucs2Wcs(0.0);
|
||
TGGeHatch hatch(m_outline, m_sHatchStyle, m_dHatchScale, m_dHatchAngle + m_nLayoutRotation - dTmp);
|
||
hatch.SetHatchPoly(m_outline); // 确保最外面曲线被正确设置。
|
||
if (IsMask() && !holds.empty())
|
||
hatch.AppendPoly(holds);
|
||
dc << hatch;
|
||
}
|
||
dc.RestoreProperties(prop);
|
||
|
||
#if ADS > 15 // 15平台没有真彩色
|
||
AcCmColor colorOld;
|
||
colorOld.setColorIndex(colorIndex());
|
||
dc.SetTrueColor(colorOld);
|
||
#endif
|
||
}
|
||
|
||
void TDbSpace::DrawTextInExplode(TGGiExplodeDrawBase &dc, std::vector<TGGePoly2D> &holds) const
|
||
{
|
||
BOOL bShowName = IsDimName(), bShowCode = IsDimCode();
|
||
|
||
if (bShowName && bShowCode) // 同时标注编号和名称
|
||
{
|
||
TDbText text;
|
||
text.setPropertiesFrom(this);
|
||
text.SetMaskFlag(IsMask()); // 自动屏蔽
|
||
AcDbObjectId idStyle = m_idTextStyle;
|
||
assert(!!idStyle);
|
||
|
||
double nTextSize = m_nTextHeight;
|
||
text.SetHeight(nTextSize);
|
||
text.SetStyleId(idStyle);
|
||
nTextSize *= GetPScale();
|
||
text.SetAlignment(XExplodeDraw::kMiddleCenter);
|
||
// sg delete 090602,8.0的正式版起,将“文字转角”并入“布局转角”
|
||
// text.SetRotation(m_nRotation); // 文字角度
|
||
|
||
ads_matrix matRot;
|
||
// sg modify 090602,8.0的正式版起,将“文字转角”并入“布局转角”
|
||
// m_ptLocation.GetRotationMatrix(Layout2Wcs(m_nRotation), matRot);
|
||
m_ptLocation.GetRotationMatrix(m_nLayoutRotation, matRot);
|
||
|
||
if (!!m_sCode || !!m_sName || g_bExplodeSubText)
|
||
{
|
||
XPoint ptDim = m_ptLocation;
|
||
ptDim.y += nTextSize*GetNameDistRatio(TRUE); // 名称位置,sg modify 081212
|
||
ptDim.TransformBy(matRot);
|
||
text.SetLocation(ptDim);
|
||
text.SetText(m_sName);
|
||
if (dc.IsFullExplode()) // 先标注房间名称
|
||
text.ExplodeOrDraw2d(dc);
|
||
else
|
||
dc.DrawEntity(text);
|
||
text.GetMaskPoly(holds);
|
||
|
||
if (m_bMText) // 两行名称文字,sg add 081212
|
||
{
|
||
ptDim = m_ptLocation;
|
||
ptDim.y += nTextSize*GetNameDistRatio(FALSE);
|
||
ptDim.TransformBy(matRot);
|
||
text.SetLocation(ptDim);
|
||
text.SetText(m_sSndName);
|
||
if (dc.IsFullExplode()) // 标注第二行房间名称
|
||
text.ExplodeOrDraw2d(dc);
|
||
else
|
||
dc.DrawEntity(text);
|
||
text.GetMaskPoly(holds);
|
||
}
|
||
|
||
if (m_nType != TDbSpace::kTotalArea) // 除建筑轮廓外,标编号,sg add 081225
|
||
{
|
||
ptDim = m_ptLocation;
|
||
ptDim.y += nTextSize*GetCodeDistRatio(); // 编号位置
|
||
ptDim.TransformBy(matRot);
|
||
text.SetLocation(ptDim);
|
||
text.SetText(m_sCode);
|
||
if (dc.IsFullExplode()) // 再标注房间编号
|
||
text.ExplodeOrDraw2d(dc);
|
||
else
|
||
dc.DrawEntity(text);
|
||
text.GetMaskPoly(holds);
|
||
|
||
XVector3D vtExt = text.GetExtents();
|
||
ptDim = text.Align2Base(ptDim, vtExt);
|
||
|
||
XPoly2D polyExtents; // sg add 081211,增加绘制编号外包框的功能
|
||
GetCodeExtentPts(polyExtents, ptDim, vtExt);
|
||
dc << polyExtents;
|
||
}
|
||
}
|
||
|
||
if (IsDimArea())
|
||
{
|
||
XPoint ptArea = m_ptLocation;
|
||
ptArea.y += nTextSize*GetAreaDistRatio(); // 面积位置
|
||
ptArea.TransformBy(matRot);
|
||
text.SetLocation(ptArea);
|
||
text.SetHeight(text.GetHeight()*0.7);
|
||
|
||
CString csUseArea = GetAreaByPrecision(); // sg modify 081127
|
||
if (IsDimUnit())
|
||
csUseArea = csUseArea + _T("m^U2^U");
|
||
|
||
text.SetText(csUseArea);
|
||
if (dc.IsFullExplode())
|
||
text.ExplodeOrDraw2d(dc);
|
||
else
|
||
dc.DrawEntity(text);
|
||
text.GetMaskPoly(holds);
|
||
}
|
||
}
|
||
// else // 只显示名称或编号
|
||
else if (bShowName || bShowCode) // 只显示名称或编号
|
||
{
|
||
XPoint ptName = m_ptLocation; // 名称或者标号的位置,在上面
|
||
XPoint ptName2 = m_ptLocation; // sg add 081212,第二行名称
|
||
XPoint ptArea = m_ptLocation; // 面积的位置,在下面
|
||
|
||
TDbText text;
|
||
text.setPropertiesFrom(this);
|
||
text.SetMaskFlag(IsMask()); // 自动屏蔽
|
||
AcDbObjectId idStyle = m_idTextStyle;
|
||
assert(!!idStyle);
|
||
|
||
double nTextSize = m_nTextHeight;
|
||
text.SetHeight(nTextSize);
|
||
text.SetStyleId(idStyle);
|
||
nTextSize *= GetPScale();
|
||
|
||
ptName.y += nTextSize*GetNameDistRatio(TRUE);
|
||
ptArea.y += nTextSize*GetAreaDistRatio();
|
||
text.SetAlignment(XExplodeDraw::kMiddleCenter);
|
||
// sg delete 090602,8.0的正式版起,将“文字转角”并入“布局转角”
|
||
// text.SetRotation(m_nRotation);
|
||
|
||
ads_matrix matRot;
|
||
// sg modify 090602,8.0的正式版起,将“文字转角”并入“布局转角”
|
||
// m_ptLocation.GetRotationMatrix(Layout2Wcs(m_nRotation), matRot);
|
||
m_ptLocation.GetRotationMatrix(m_nLayoutRotation, matRot);
|
||
ptName.TransformBy(matRot);
|
||
ptArea.TransformBy(matRot);
|
||
|
||
// XString sDisp = ((nSpFlag&SPF_CODE)!=0? m_sCode : m_sName);
|
||
XString sDisp = (bShowCode ? m_sCode : m_sName);
|
||
if (!!sDisp || g_bExplodeSubText)
|
||
{
|
||
text.SetLocation(ptName);
|
||
if (m_nType == TDbSpace::kTotalArea) // 建筑轮廓永远显示名称,sg modify 090320
|
||
sDisp = m_sName;
|
||
text.SetText(sDisp);
|
||
|
||
if (dc.IsFullExplode())
|
||
text.ExplodeOrDraw2d(dc);
|
||
else
|
||
dc.DrawEntity(text);
|
||
text.GetMaskPoly(holds);
|
||
|
||
// sg add 081212,只标注名称,且为两行文字
|
||
// if ((nSpFlag&SPF_CODE)==0 && m_bMText)
|
||
if (bShowName && m_bMText)
|
||
{
|
||
ptName2.y += nTextSize * GetNameDistRatio(FALSE);
|
||
ptName2.TransformBy(matRot);
|
||
text.SetLocation(ptName2);
|
||
text.SetText(m_sSndName);
|
||
|
||
if (dc.IsFullExplode())
|
||
text.ExplodeOrDraw2d(dc);
|
||
else
|
||
dc.DrawEntity(text);
|
||
text.GetMaskPoly(holds);
|
||
}
|
||
}
|
||
|
||
// if (nSpFlag&SPF_AREA) // 标注面积
|
||
if (IsDimArea()) // 标注面积
|
||
{
|
||
text.SetLocation(ptArea);
|
||
text.SetHeight(text.GetHeight()*0.7);
|
||
|
||
CString csUseArea = GetAreaByPrecision(); // sg modify 081127
|
||
// if (nSpFlag&SPF_UNIT)
|
||
if (IsDimUnit())
|
||
csUseArea = csUseArea + _T("m^U2^U");
|
||
|
||
text.SetText(csUseArea);
|
||
if (dc.IsFullExplode())
|
||
text.ExplodeOrDraw2d(dc);
|
||
else
|
||
dc.DrawEntity(text);
|
||
text.GetMaskPoly(holds);
|
||
}
|
||
}
|
||
else // add by xly on 101018,名称、编号都不显示
|
||
{
|
||
if (IsDimArea()) // 标注面积
|
||
{
|
||
// 设置文字信息
|
||
TDbText text;
|
||
text.setPropertiesFrom(this);
|
||
text.SetMaskFlag(IsMask()); // 自动屏蔽
|
||
AcDbObjectId idStyle = m_idTextStyle;
|
||
assert(!!idStyle);
|
||
|
||
double nTextSize = m_nTextHeight;
|
||
text.SetHeight(nTextSize);
|
||
text.SetStyleId(idStyle);
|
||
nTextSize *= GetPScale();
|
||
|
||
text.SetAlignment(XExplodeDraw::kMiddleCenter);
|
||
XPoint ptArea = m_ptLocation;
|
||
ptArea.y -= nTextSize*GetAreaDistRatio();
|
||
|
||
ads_matrix matRot;
|
||
m_ptLocation.GetRotationMatrix(m_nLayoutRotation, matRot);
|
||
|
||
text.SetLocation(ptArea);
|
||
text.SetHeight(text.GetHeight()*0.7);
|
||
|
||
CString csUseArea = GetAreaByPrecision();
|
||
if (IsDimUnit()) // 面积单位的显示
|
||
csUseArea = csUseArea + _T("m^U2^U");
|
||
|
||
text.SetText(csUseArea);
|
||
if (dc.IsFullExplode())
|
||
text.ExplodeOrDraw2d(dc);
|
||
else
|
||
dc.DrawEntity(text);
|
||
text.GetMaskPoly(holds);
|
||
}
|
||
}
|
||
}
|
||
|
||
#if 0
|
||
/* ----------------------------------------------------------------------- */
|
||
/////////////////////////////////////////////////////////////////////////////////////
|
||
// 通过量化属性取得属性量
|
||
Acad::ErrorStatus
|
||
TDbSpace::GetQuantumByName(const TCHAR *pszName, double *pQuantum) const
|
||
{
|
||
ASSERT(pszName && pQuantum);
|
||
Acad::ErrorStatus es = Acad::eOk;
|
||
double nRes=0.0;
|
||
if(strcmp(pszName, SP_QUANTUM_1)==0) {
|
||
nRes = GetUseArea();
|
||
} else if(strcmp(pszName, SP_QUANTUM_2)==0) {
|
||
nRes = GetCeilArea();
|
||
} else if(strcmp(pszName, SP_QUANTUM_3)==0) {
|
||
nRes = GetOccuArea();
|
||
} else if(strcmp(pszName, SP_QUANTUM_4)==0) {
|
||
nRes = GetWallSurfArea();
|
||
} else if(strcmp(pszName, SP_QUANTUM_5)==0) {
|
||
nRes = AS_METER(GetPerimeter());
|
||
} else if(strcmp(pszName, SP_QUANTUM_6)==0) {
|
||
nRes = AS_METER(GetKickboard());
|
||
} else if(strcmp(pszName, SP_QUANTUM_7)==0) {
|
||
nRes = GetUseVolume();
|
||
} else {
|
||
es = Acad::eInvalidInput;
|
||
}
|
||
*pQuantum = nRes;
|
||
return es;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// 初始化注册量化的属性名字
|
||
void TDbSpace::InitQuantumProtocol(BOOL bTrue)
|
||
{
|
||
static XQuantumProtocol *pProtocol=NULL;
|
||
if(bTrue) {
|
||
pProtocol=new XQuantumProtocol;
|
||
pProtocol->m_lstQuantumNames.Append(strnew(SP_QUANTUM_1));
|
||
pProtocol->m_lstQuantumNames.Append(strnew(SP_QUANTUM_2));
|
||
pProtocol->m_lstQuantumNames.Append(strnew(SP_QUANTUM_3));
|
||
pProtocol->m_lstQuantumNames.Append(strnew(SP_QUANTUM_4));
|
||
pProtocol->m_lstQuantumNames.Append(strnew(SP_QUANTUM_5));
|
||
pProtocol->m_lstQuantumNames.Append(strnew(SP_QUANTUM_6));
|
||
pProtocol->m_lstQuantumNames.Append(strnew(SP_QUANTUM_7));
|
||
|
||
desc()->addX(XQuantumProtocol::desc(), pProtocol);
|
||
} else {
|
||
desc()->delX(XQuantumProtocol::desc());
|
||
delete pProtocol;
|
||
pProtocol = NULL;
|
||
}
|
||
}
|
||
#endif
|
||
|
||
|
||
int EditSpace0(AcDbObjectId id)
|
||
{
|
||
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbSpace, pSpace);
|
||
if (!pSpace)
|
||
return RTERROR;
|
||
while (1) {
|
||
adsout << _T("\n选择 [名称(N)/编号(C)/参数(L)]<退出>: ");
|
||
XString sKeyword;
|
||
int nRet = 0;
|
||
INITGET_BEG(0, _T("N C L"));
|
||
nRet = ads_getkword(_T(""), sKeyword);
|
||
INITGET_END();
|
||
|
||
if (nRet != RTNORM)
|
||
break;
|
||
if (sKeyword[0] == _T('N')) {
|
||
XString sName;
|
||
if (ads_getstring(0, _T("\n房间名称:"), sName) == RTNORM) {
|
||
if (pSpace->upgradeOpen() != Acad::eOk)
|
||
return RTERROR;
|
||
pSpace->assertWriteEnabled();
|
||
pSpace->m_sName = sName;
|
||
pSpace->downgradeOpen();
|
||
}
|
||
}
|
||
else if (sKeyword[0] == _T('C')) {
|
||
XString sCode;
|
||
if (ads_getstring(0, _T("\n房间名称:"), sCode) == RTNORM) {
|
||
if (pSpace->upgradeOpen() != Acad::eOk)
|
||
return RTERROR;
|
||
pSpace->assertWriteEnabled();
|
||
pSpace->m_sCode = sCode;
|
||
pSpace->downgradeOpen();
|
||
}
|
||
}
|
||
else if (sKeyword[0] == _T('L')) {
|
||
pSpace->list();
|
||
}
|
||
}
|
||
|
||
OPENOBJ_END();
|
||
return RTNORM;
|
||
}
|
||
|
||
|
||
void InitDbSpace(BOOL bTrue)
|
||
{
|
||
if (bTrue) {
|
||
TDbSpace::rxInit();
|
||
TDbSpace::SetEditMethod(EditSpace0);
|
||
acrxBuildClassHierarchy();
|
||
//TDbSpace::InitProperty(TRUE);
|
||
TDbSpace::InitMatchProtocol(TRUE);
|
||
}
|
||
else {
|
||
//TDbSpace::InitQuantumProtocol(FALSE);
|
||
//TDbSpace::InitProperty(FALSE);
|
||
TDbSpace::InitMatchProtocol(FALSE);
|
||
deleteAcRxClass(TDbSpace::desc());
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
// 通过一点确定一房间的信息
|
||
// ptPick--WCS point
|
||
// Return: 0--Fail, 1--Normal Space, 2--External Space
|
||
int GenSpaceInfo(const XPoint &ptPick0, TDbSpace &space, BOOL bIgnoreVirt)
|
||
{
|
||
XPoint ptPick = ptPick0;
|
||
ptPick.z = 0;
|
||
BOOL bFindExtSpace = FALSE;
|
||
// 找到所有墙
|
||
PickSet ssWalls0(SS_FREE);
|
||
if (ssWalls0.Get(_T("X"), NULL, NULL, RBList(RTDXF0, _T("ATS_WALL,ATS_CURTAIN_WALL"), NULL)) != RTNORM)
|
||
return 0;
|
||
|
||
PickSet ssWalls(SS_FREE);
|
||
if (bIgnoreVirt)
|
||
{
|
||
long num = ssWalls0.Length();
|
||
for (long n = 0; n < num; n++) {
|
||
Entity ent = ssWalls0[n];
|
||
BOOL bVirt = FALSE;
|
||
OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbWall, pWall);
|
||
if (pWall) {
|
||
if (pWall->GetUsageFlag() == TWallData::kVirtual)
|
||
bVirt = TRUE;
|
||
}
|
||
OPENOBJ_END();
|
||
if (!bVirt)
|
||
ssWalls += ent;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ssWalls += ssWalls0;
|
||
}
|
||
|
||
DList<AcDbObjectId> lstColu;
|
||
GetEntFromBlockByDxf(lstColu, _T("ATS_COLUMN"));
|
||
XSearchSpaceFromWall aSearch;
|
||
try
|
||
{
|
||
aSearch.InitStart(ssWalls, lstColu);
|
||
}
|
||
catch (...)
|
||
{
|
||
adsout << /*UMSG*/_T("\n发生例外情况!");
|
||
return 0;
|
||
}
|
||
|
||
|
||
int nWallNumber = aSearch.walls.Length();
|
||
// Search the most near wall
|
||
XAecSpaceWall *pNearestWall = NULL;
|
||
ads_real nMinDist = 0.0;
|
||
for (int i = 0; i < nWallNumber; i++)
|
||
{
|
||
XPoint ptProject;
|
||
XAecSpaceWall *pWall = aSearch.walls[i];
|
||
if (pWall->ProjectToMe(ptPick, ptProject) != RTNORM || (ptProject&(*pWall)) != PR_INSIDE)
|
||
continue;
|
||
ptProject.z = ptPick.z; //忽略Z坐标
|
||
ads_real nDist = ads_distance(ptPick, ptProject);
|
||
if (!pNearestWall) {
|
||
nMinDist = nDist;
|
||
pNearestWall = pWall;
|
||
}
|
||
else if (nDist < nMinDist) {
|
||
nMinDist = nDist;
|
||
pNearestWall = pWall;
|
||
}
|
||
}
|
||
|
||
int nRet = RTERROR;
|
||
XPoly2D poly(1);
|
||
|
||
int nWho = 0; //1:left; 2:right
|
||
BOOL bSubtract = TRUE; //用相减的方法,适合于室内; 否则为室外
|
||
XAecSpaceCell lSpace, rSpace;
|
||
if (pNearestWall && aSearch.SearchTwoSpace(*pNearestWall, lSpace, rSpace) == RTNORM)
|
||
{
|
||
//找出2房间
|
||
XPoly2D lPoly, rPoly;
|
||
lSpace.CenterPoly2D(lPoly);
|
||
rSpace.CenterPoly2D(rPoly);
|
||
int nPrFlag1 = ptPick&lPoly;
|
||
int nPrFlag2 = ptPick&rPoly;
|
||
if (nPrFlag1 == PR_INSIDE && nPrFlag2 == PR_INSIDE) {
|
||
lSpace.InternalPoly2D(lPoly, 0, 0);
|
||
rSpace.InternalPoly2D(rPoly, 0, 0);
|
||
//Both include ptPick, then the smaller space is required
|
||
ads_real nArea1 = lPoly.Area();
|
||
ads_real nArea2 = rPoly.Area();
|
||
if (nArea1 < nArea2) { poly = lPoly; nWho = 1; }
|
||
else { poly = rPoly; nWho = 2; }
|
||
nRet = RTNORM;
|
||
}
|
||
else if (nPrFlag1 == PR_INSIDE) {
|
||
poly = lPoly;
|
||
nWho = 1;
|
||
nRet = RTNORM;
|
||
}
|
||
else if (nPrFlag2 == PR_INSIDE) {
|
||
poly = rPoly;
|
||
nWho = 2;
|
||
nRet = RTNORM;
|
||
}
|
||
else { // Both exclude ptPick, then the larger space is required
|
||
ads_real nArea1 = lPoly.Area();
|
||
ads_real nArea2 = rPoly.Area();
|
||
if (nArea1 > nArea2) { poly = lPoly; nWho = 1; }
|
||
else { poly = rPoly; nWho = 2; }
|
||
nRet = RTNORM;
|
||
bSubtract = FALSE;
|
||
}
|
||
}
|
||
else if (pNearestWall)
|
||
{
|
||
lSpace.Reset();
|
||
rSpace.Reset();
|
||
if (aSearch.SearchOneSpace(*pNearestWall, 0, lSpace) == RTNORM) {
|
||
lSpace.CenterPoly2D(poly);
|
||
if ((ptPick&poly) == PR_INSIDE) {
|
||
nWho = 1;
|
||
nRet = RTNORM;
|
||
}
|
||
}
|
||
else if (aSearch.SearchOneSpace(*pNearestWall, 1, rSpace) == RTNORM) {
|
||
rSpace.CenterPoly2D(poly);
|
||
if ((ptPick&poly) == PR_INSIDE) {
|
||
nWho = 2;
|
||
nRet = RTNORM;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
if (nWho && nRet == RTNORM)
|
||
{
|
||
if (bSubtract == FALSE)
|
||
{
|
||
bFindExtSpace = TRUE;
|
||
}
|
||
|
||
//扣除柱子部分
|
||
XAecSpaceCell *pSpace = nWho == 1 ? &lSpace : &rSpace;
|
||
space.UpdateFrom(*pSpace, bFindExtSpace);
|
||
if (bFindExtSpace)
|
||
return 2;
|
||
return 1;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|