Files
envi-code/SourceCode/Code2026/tg_shs/shs_kernal/DbSpace.cpp
T
2026-09-28 15:28:50 +08:00

2969 lines
74 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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;
}