1390 lines
33 KiB
C++
1390 lines
33 KiB
C++
//-------------------------------------------------------------------------------------------------------+
|
||
// Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd.
|
||
// = FileName : TSearchSpaceFromWall 类
|
||
// = Version : ver2.0
|
||
// = Author : wlw
|
||
// = CreateDate : 2002-09-09
|
||
// = Description: TSearchSpaceFromWall 定义
|
||
// = Maintainers:
|
||
//
|
||
//-------------------------------------------------------------------------------------------------------+
|
||
#include "StdAfx.h"
|
||
#include "Symdef.h"
|
||
#include "TSearchSpaceFromWall.h"
|
||
#include "TAecSpaceWall.h"
|
||
#include "TAecSpaceCell.h"
|
||
#include "TDbWall.h"
|
||
#include "TGGiWallVector.h"
|
||
#include "TDbColumn.h"
|
||
#include "TAcDbObjectPtr.h"
|
||
#include "TArchCmdReactor.h"
|
||
#include "TGGeCurveSegment.h"
|
||
#include "TSortSideOnVertex.h"
|
||
#include "TADSGePoint3d.h"
|
||
#include "TSortWallOnPt.h"
|
||
#include "tgkatana.h"
|
||
|
||
void ErrorPosition(const TADSGePoint3d &, const TADSGePoint3d &, const TCHAR *);
|
||
TDPtrList<TSortWallOnPt> TSearchSpaceFromWall::g_lstAllSortWalls;
|
||
char TSearchSpaceFromWall::s_chConstructed = 0;
|
||
extern int g_nRunMode;
|
||
|
||
static int CmpSortWallLoc(const TSortWallOnPt *p1, const void *p2)
|
||
{
|
||
TSortWallOnPt *pp1=(TSortWallOnPt *)p1;
|
||
return !pp1->ExactInclude(*(const TADSGePoint3d *)p2);
|
||
}
|
||
|
||
static int ComparePoint2d(const TADSGePoint3d *p1, const void * p2)
|
||
{
|
||
TADSGePoint3d pt1 = *p1,
|
||
pt2 = *(const TADSGePoint3d *)p2;
|
||
|
||
BOOL bEqual = (fabs(pt1.x - pt2.x) <= _AS_SYS_UNIT(g_nDistPrec)
|
||
&& fabs(pt1.y - pt2.y) <= _AS_SYS_UNIT(g_nDistPrec));
|
||
return !bEqual;
|
||
}
|
||
|
||
static int ComparePoint2dByInclude(const TADSGePoint3d *p1, const void *p2)
|
||
{
|
||
TSortWallOnPt *pSortOnWall = (TSortWallOnPt *)p2;
|
||
return !pSortOnWall->ExactInclude(*p1);
|
||
}
|
||
|
||
TSearchSpaceFromWall::TSearchSpaceFromWall()
|
||
{
|
||
_SearchSpaceFromWall();
|
||
}
|
||
|
||
void TSearchSpaceFromWall::_SearchSpaceFromWall()
|
||
{
|
||
assert(!s_chConstructed);
|
||
|
||
s_chConstructed = 1;
|
||
TAecSpaceWall::g_pAllWalls = &walls;
|
||
TAecSpaceCell::g_pAllSpaces = &spaces;
|
||
TAecSpaceCell::g_nGlobalIndex = 0;
|
||
g_lstAllSortWalls.Reset();
|
||
}
|
||
|
||
// 支持后台数据库的搜索
|
||
void TSearchSpaceFromWall::InitStart(const TDPtrList<AcDbObjectId> &idWalls, const TDPtrList<AcDbObjectId> &idColus)
|
||
{
|
||
int nCount = idColus.Length();
|
||
for (int n = 0; n < nCount; n++)
|
||
{
|
||
TGGePoly2D polySrc(1);
|
||
const AcDbObjectId &idColu = idColus[n];
|
||
|
||
OPENOBJ_BEGIN(idColu, AcDb::kForRead, TDbColumn, pColu);
|
||
if (!pColu || pColu->IsFortifyColumn())
|
||
{
|
||
continue;
|
||
}
|
||
// sg modify 100728,根据8.5需求,搜索房间要考虑柱子保温
|
||
// pColu->GetOutline(polySrc);
|
||
pColu->GetColSurFacePoly2D(polySrc);
|
||
OPENOBJ_END();
|
||
|
||
TADSGePoint3d ptCen;
|
||
polySrc.Center(ptCen);
|
||
|
||
if (g_lstAllSortWalls.FindNode(ptCen, CmpSortWallLoc))
|
||
{
|
||
TchGeLib::adsout << _T("\n发现重合的柱子, 注意消除!");
|
||
}
|
||
else
|
||
{
|
||
TSortWallOnPt *pNode = new TSortWallOnPt(ptCen, idColu);
|
||
g_lstAllSortWalls.Append(pNode);
|
||
}
|
||
}
|
||
|
||
// 构造排序墙
|
||
int nLen = idWalls.Length();
|
||
for (int i = 0; i < nLen; i++)
|
||
{
|
||
TEntitySet ent;
|
||
AcDbObjectId id = idWalls[i];
|
||
if (acdbGetAdsName(ent.name, id) != Acad::eOk)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
if (ent.Is(_T("CIRCLE")))
|
||
{
|
||
continue;
|
||
}
|
||
|
||
TAecSpaceWall *pWall = new TAecSpaceWall(ent);
|
||
if (!*pWall)
|
||
{
|
||
delete pWall;
|
||
continue;
|
||
}
|
||
else
|
||
{
|
||
NewAppend(pWall);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 由选择集构造墙表
|
||
// ssWalls可以是Line也可以是AecWall
|
||
void TSearchSpaceFromWall::InitStart(TPickEntSet &ssWalls, const TDPtrList<AcDbObjectId> &lstColu)
|
||
{
|
||
int nFoundAt = 0;
|
||
int nCount = lstColu.Length();
|
||
for (int n = 0; n < nCount; n++)
|
||
{
|
||
TGGePoly2D polySrc(1);
|
||
const AcDbObjectId &idColu = lstColu[n];
|
||
|
||
OPENOBJ_BEGIN(idColu, AcDb::kForRead, TDbColumn, pColu);
|
||
if (!pColu || pColu->IsFortifyColumn())
|
||
{
|
||
continue;
|
||
}
|
||
// sg modify 100728,根据8.5需求,搜索房间要考虑柱子保温
|
||
// pColu->GetOutline(polySrc);
|
||
pColu->GetColSurFacePoly2D(polySrc);
|
||
OPENOBJ_END();
|
||
|
||
TADSGePoint3d ptCen;
|
||
polySrc.Center(ptCen);
|
||
|
||
if (g_lstAllSortWalls.FindNode(ptCen, CmpSortWallLoc))
|
||
{
|
||
extern GEOAPI BOOL g_bAutoCheckWall;
|
||
TADSGePoint3d ptLow, ptUp;
|
||
polySrc.GetExtend(ptLow, ptUp);
|
||
|
||
if (g_bAutoCheckWall)
|
||
{
|
||
TchGeLib::adsout << _T("\n发现重合的柱子, 注意消除!");
|
||
ErrorPosition(ptLow, ptUp, _T("重合的柱子"));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
TSortWallOnPt *pNode = new TSortWallOnPt(ptCen, idColu);
|
||
g_lstAllSortWalls.Append(pNode);
|
||
}
|
||
}
|
||
|
||
// 构造排序墙
|
||
AcDbObjectId idWall;
|
||
|
||
long nLen = ssWalls.Length();
|
||
for (long i = 0; i < nLen; i++)
|
||
{
|
||
TEntitySet ent = ssWalls[i];
|
||
|
||
if (ent.Is(_T("CIRCLE")))
|
||
{
|
||
continue;
|
||
}
|
||
|
||
TAecSpaceWall *pWall = new TAecSpaceWall(ent);
|
||
if (!*pWall)
|
||
{
|
||
delete pWall;
|
||
continue;
|
||
}
|
||
else
|
||
{
|
||
NewAppend(pWall);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 释放全局变量
|
||
TSearchSpaceFromWall::~TSearchSpaceFromWall()
|
||
{
|
||
TAecSpaceWall::g_pAllWalls = NULL;
|
||
TAecSpaceCell::g_pAllSpaces = NULL;
|
||
TAecSpaceCell::g_nGlobalIndex = 0;
|
||
|
||
g_lstAllSortWalls.Reset();
|
||
s_chConstructed = 0;
|
||
}
|
||
|
||
// 找墙体的两个节点,返回节点数目
|
||
int TSearchSpaceFromWall::FindLinkNode(const TAecSpaceWall *pWall, int *pIndex1, int *pIndex2)
|
||
{
|
||
int nNodeNum = 0;
|
||
for (int i = 0; i < g_lstAllSortWalls.Length(); i++)
|
||
{
|
||
TSortWallOnPt &wallsAtPos = *g_lstAllSortWalls[i];
|
||
TGGiWallVector *pVector = wallsAtPos.FindNode(&pWall->m_ent, TGGiWallVector::FindByEntity);
|
||
if (pVector)
|
||
{
|
||
nNodeNum++;
|
||
if (nNodeNum == 1)
|
||
{
|
||
*pIndex1 = i;
|
||
}
|
||
else
|
||
{
|
||
*pIndex2 = i;
|
||
}
|
||
|
||
if (nNodeNum >= 2)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
return nNodeNum;
|
||
}
|
||
|
||
// 更新柱子的连接信息
|
||
void TSearchSpaceFromWall::UpdateColuLinkage(const TGGeRectAngle *box)
|
||
{
|
||
for (int i = 0; i < g_lstAllSortWalls.Length(); i++)
|
||
{
|
||
TSortWallOnPt &wallsAtPos = *g_lstAllSortWalls[i];
|
||
if (!wallsAtPos.m_idColumn)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
wallsAtPos.UpdateColuLinkage(box);
|
||
}
|
||
}
|
||
|
||
// 在墙角打断墙体
|
||
void TSearchSpaceFromWall::BreakWalls(TADSGePointList &lstCorners, TPickEntSet &ssAdd)
|
||
{
|
||
int nLen = g_lstAllSortWalls.Length();
|
||
|
||
/*-------------------------------------------------------------------------------
|
||
//错误说明:
|
||
//解决方法:
|
||
// BreakWallAt 函数内部对 walls 重复的提取外部边界耗费大量的时间,导致系统变慢
|
||
// 所以本类增加 m_mapWallId2OutlinePl 缓冲属性,在获取wall 的外部边界时,通过id
|
||
// 临时保存wall的边界,使得取边界一次即可,节约了整体时间
|
||
//修改人: lfy
|
||
//日期 : 2010-4-28
|
||
---------------------------------------------------------------------------------*/
|
||
long lKey = 0l;
|
||
PVOID pVal = NULL;
|
||
TGGePoly2D* pPl = NULL;
|
||
for (POSITION ps = m_mapWallId2OutlinePl.GetStartPosition();ps != NULL;)
|
||
{
|
||
pVal = NULL;
|
||
m_mapWallId2OutlinePl.GetNextAssoc(ps,lKey,pVal);
|
||
if (pVal != NULL)
|
||
{
|
||
pPl = (TGGePoly2D*)pVal;
|
||
delete pPl;
|
||
}
|
||
}
|
||
m_mapWallId2OutlinePl.RemoveAll();
|
||
|
||
for (int i = 0; i < nLen; i++)
|
||
{
|
||
BreakWallAt(i, lstCorners, ssAdd);
|
||
}
|
||
|
||
/*-------------------------------------------------------------------------------
|
||
//错误说明:
|
||
//解决方法:
|
||
// BreakWallAt 函数内部对 walls 重复的提取外部边界耗费大量的时间,导致系统变慢
|
||
// 所以本类增加 m_mapWallId2OutlinePl 缓冲属性,在获取wall 的外部边界时,通过id
|
||
// 临时保存wall的边界,使得取边界一次即可,节约了整体时间
|
||
//修改人: lfy
|
||
//日期 : 2010-4-28
|
||
---------------------------------------------------------------------------------*/
|
||
for (ps = m_mapWallId2OutlinePl.GetStartPosition();ps != NULL;)
|
||
{
|
||
pVal = NULL;
|
||
m_mapWallId2OutlinePl.GetNextAssoc(ps,lKey,pVal);
|
||
if (pVal != NULL)
|
||
{
|
||
pPl = (TGGePoly2D*)pVal;
|
||
delete pPl;
|
||
}
|
||
}
|
||
m_mapWallId2OutlinePl.RemoveAll();
|
||
}
|
||
|
||
// 在第nPos个墙角断开墙段
|
||
// lstCorners -- 发生变化的墙角
|
||
// 返回: kTrue--合并进行; kFalse--没有合并
|
||
// Status: 考虑了墙体的底标高, 用区域来判断两端点是否相等
|
||
// 没有考虑在柱子处断开
|
||
Adesk::Boolean TSearchSpaceFromWall::BreakWallAt(int nPos, TADSGePointList &lstCorners, TPickEntSet &ssAdd)
|
||
{
|
||
TSortWallOnPt &wallsAtPos = *g_lstAllSortWalls[nPos];
|
||
|
||
// 是否在变化墙角
|
||
if (!lstCorners.FindNode(&wallsAtPos, ComparePoint2dByInclude))
|
||
{
|
||
return Adesk::kFalse;
|
||
}
|
||
|
||
TAecSpaceWall *pThisWall = NULL;
|
||
TDbWall *pDbWall1 = NULL;
|
||
AcDbObjectId idNewWall;
|
||
|
||
// add by xlc on 110106
|
||
Adesk::Boolean bRet = Adesk::kFalse;
|
||
|
||
for (int i = 0; i < walls.Length(); i++)
|
||
{
|
||
pThisWall = walls[i];
|
||
if (!pThisWall->m_pStartNode || !pThisWall->m_pEndNode)
|
||
{
|
||
TchGeLib::adsout << _T("\n严重警告: 墙体的位置关系发生错乱! ");
|
||
throw pThisWall;
|
||
continue;
|
||
}
|
||
|
||
ASSERT(!!pThisWall->m_ent);
|
||
TAcDbObjectPtr obj1(pThisWall->m_ent, AcDb::kForRead);
|
||
if (!obj1)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
pDbWall1 = TDbWall::cast(obj1.m_pObject);
|
||
ASSERT(pDbWall1);
|
||
|
||
|
||
// Update New: 加入判据, 避免当墙的端点位于柱子内部时, 进行打断产生无效短墙
|
||
// 假如有柱子的话,ptLoc位于墙体内是断开; 否则ptLoc距离墙基线<g_nDistPrec时断开
|
||
if (pDbWall1->BreakAt(wallsAtPos.ptLoc, idNewWall, wallsAtPos.HasColumn() ? &wallsAtPos.polyExtend : NULL,&m_mapWallId2OutlinePl) == Adesk::kTrue)
|
||
{
|
||
ASSERT(!!idNewWall);
|
||
TEntitySet entNewWall;
|
||
acdbGetAdsName(entNewWall.name, idNewWall);
|
||
ssAdd += entNewWall; // Z add on 2003/11/14
|
||
|
||
TAecSpaceWall *pNewWall = new TAecSpaceWall(entNewWall);
|
||
walls.Append(pNewWall);
|
||
|
||
(TWallData &)(*pThisWall) = (TWallData &)(*pDbWall1); //修改数据
|
||
|
||
ASSERT(pThisWall->m_pStartNode && pThisWall->m_pEndNode);
|
||
|
||
TSortWallOnPt &wallsAtOne = *pThisWall->m_pStartNode,
|
||
&wallsAtTwo = *pThisWall->m_pEndNode;
|
||
|
||
if ( wallsAtOne.ExactInclude(pThisWall->StartPoint())
|
||
|| wallsAtOne.ExactInclude(pThisWall->EndPoint()))
|
||
{
|
||
TGGiWallVector *pVector = wallsAtTwo.FindNode(&pThisWall->m_ent, TGGiWallVector::FindByEntity);
|
||
ASSERT(pVector && pVector->pWall == pThisWall);
|
||
pVector->pWall = pNewWall;
|
||
|
||
if(wallsAtTwo.ExactInclude(pNewWall->StartPoint()))
|
||
{
|
||
pNewWall->m_pStartNode = &wallsAtTwo;
|
||
}
|
||
else
|
||
{
|
||
pNewWall->m_pEndNode = &wallsAtTwo;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
TGGiWallVector *pVector = wallsAtOne.FindNode(&pThisWall->m_ent, TGGiWallVector::FindByEntity);
|
||
ASSERT(pVector && pVector->pWall == pThisWall);
|
||
pVector->pWall = pNewWall;
|
||
|
||
if (wallsAtOne.ExactInclude(pNewWall->StartPoint()))
|
||
{
|
||
pNewWall->m_pStartNode = &wallsAtOne;
|
||
}
|
||
else
|
||
{
|
||
pNewWall->m_pEndNode = &wallsAtOne;
|
||
}
|
||
}
|
||
|
||
//调整节点数据
|
||
//本节点,加入两段墙
|
||
obj1.Close(); //下列语句可能导致同用户的交互,因此必须关闭已经打开的对象
|
||
|
||
wallsAtPos.Insert(pNewWall);
|
||
wallsAtPos.Insert(pThisWall);
|
||
|
||
//modify by xlc on 110106 解决墙角插圆柱时墙角缺口的问题
|
||
//return Adesk::kTrue;
|
||
bRet = Adesk::kTrue;
|
||
}
|
||
}
|
||
|
||
//return Adesk::kFalse;
|
||
return bRet;
|
||
}
|
||
|
||
// 合并所有墙段
|
||
void TSearchSpaceFromWall::MergeWalls(TADSGePointList &lstCorners, TPickEntSet &ssDel)
|
||
{
|
||
int nLen = g_lstAllSortWalls.Length();
|
||
for (int i = 0; i < nLen; i++)
|
||
{
|
||
if (MergeWallAt(i, lstCorners, ssDel) == Adesk::kTrue)
|
||
{
|
||
i--;
|
||
nLen--;
|
||
}
|
||
}
|
||
}
|
||
|
||
namespace
|
||
{
|
||
void ProcessKatanaRelation(TAecSpaceWall *pKeep, TAecSpaceWall *pDel,
|
||
TDbWall *pKeepWall, TDbWall *pDelWall)
|
||
{
|
||
// 判断两墙左右
|
||
TAecSpaceWall *pLeft(NULL), *pRight(NULL);
|
||
if (pKeepWall->StartPoint() == pDelWall->EndPoint())
|
||
{
|
||
pRight = pKeep;
|
||
pLeft = pDel;
|
||
}
|
||
if (pKeepWall->EndPoint() == pDelWall->StartPoint())
|
||
{
|
||
pRight = pDel;
|
||
pLeft = pKeep;
|
||
}
|
||
// end
|
||
if (!pLeft || !pRight) return;
|
||
|
||
if (pLeft == pDel)
|
||
{
|
||
/*
|
||
DelWall KeepWall
|
||
|-----------|------------|--------------|------------|
|
||
|--OldLeft--|----Left----|-----Right----|--OldRight--|
|
||
|-----------|------------|--------------|------------|
|
||
|
|
||
被删除的刀对象
|
||
*/
|
||
// 将 keepwall 与 oldleft 关联
|
||
AcDbObjectId BegKatanaId = KatanaToolkit::GetBegKatanaIdByWall(pDelWall);
|
||
KatanaToolkit::SetBegKatanaIdForWall(pKeep, BegKatanaId);
|
||
KatanaToolkit::SetRightWallIdForKatana(pKeepWall->objectId(), BegKatanaId);
|
||
KatanaToolkit::SetBegKatanaIdForWall(pDelWall, AcDbObjectId::kNull);
|
||
// 修改反应器
|
||
AcDbObjectId LeftWallId = KatanaToolkit::GetLeftWallIdByKatana(BegKatanaId);
|
||
KatanaToolkit::UnRegister(pDelWall, LeftWallId);
|
||
KatanaToolkit::Register(pKeepWall, LeftWallId);
|
||
}
|
||
else if (pRight = pDel)
|
||
{
|
||
/*
|
||
KeepWall DelWall
|
||
|-----------|------------|--------------|------------|
|
||
|--OldLeft--|----Left----|-----Right----|--OldRight--|
|
||
|-----------|------------|--------------|------------|
|
||
|
|
||
被删除的刀对象
|
||
*/
|
||
// 将 keepwall 与 oldleft 关联
|
||
AcDbObjectId EndKatanaId = KatanaToolkit::GetEndKatanaIdByWall(pDelWall);
|
||
KatanaToolkit::SetEndKatanaIdForWall(pKeep, EndKatanaId);
|
||
KatanaToolkit::SetLeftWallIdForKatana(pKeepWall->objectId(), EndKatanaId);
|
||
KatanaToolkit::SetEndKatanaIdForWall(pDelWall, AcDbObjectId::kNull);
|
||
// 修改反应器
|
||
AcDbObjectId RightWallId = KatanaToolkit::GetRightWallIdByKatana( EndKatanaId);
|
||
KatanaToolkit::UnRegister(pDelWall, RightWallId);
|
||
KatanaToolkit::Register(pKeepWall, RightWallId);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
// 在第nPos个墙角合并墙段
|
||
// lstCorners -- 发生变化的墙角
|
||
// 返回: kTrue--合并进行; kFalse--没有合并
|
||
// Status: 考虑了墙体的底标高
|
||
Adesk::Boolean TSearchSpaceFromWall::MergeWallAt(int nPos, TADSGePointList &lstCorners, TPickEntSet &ssDel)
|
||
{
|
||
TSortWallOnPt &wallsAtPos = *g_lstAllSortWalls[nPos];
|
||
if (wallsAtPos.Length() != 2 || wallsAtPos.HasColumn())
|
||
{
|
||
return Adesk::kFalse;
|
||
}
|
||
|
||
int nTotalWalls = walls.Length();
|
||
TADSGePoint3d ptToBeMerged = wallsAtPos.ptLoc;
|
||
for(int i = 0; i < nTotalWalls; i++)
|
||
{
|
||
TWallData &wall = *walls[i];
|
||
ptToBeMerged.z = wall.GetElevation();
|
||
|
||
//在某墙段内不能合并
|
||
if ((ptToBeMerged&wall) == PR_INSIDE)
|
||
{
|
||
return Adesk::kFalse;
|
||
}
|
||
}
|
||
|
||
// 是否在变化墙角
|
||
int nCornerPos = -1;
|
||
|
||
//没有柱子的时候可以用点相等来比较
|
||
if (lstCorners.FindNode(&wallsAtPos.ptLoc, ComparePoint2d))
|
||
{
|
||
nCornerPos = lstCorners.CurPosition();
|
||
}
|
||
else
|
||
{
|
||
return Adesk::kFalse;
|
||
}
|
||
|
||
TGGiWallVector &vt1 = *wallsAtPos[0], &vt2 = *wallsAtPos[1]; //vt2的墙被合到vt1
|
||
ASSERT(!!vt1.pWall->m_ent && !!vt2.pWall->m_ent);
|
||
double dFistWallLenght = vt1.pWall->GetLength();
|
||
if (vt1.pWall->MergeWith(*vt2.pWall))
|
||
{
|
||
TAcDbObjectPtr obj1(vt1.pWall->m_ent, AcDb::kForWrite),
|
||
obj2(vt2.pWall->m_ent, AcDb::kForWrite);
|
||
|
||
if (!obj1 || !obj2)
|
||
{
|
||
return Adesk::kFalse;
|
||
}
|
||
|
||
TDbWall *pDbWall1 = TDbWall::cast(obj1.m_pObject);
|
||
TDbWall *pDbWall2 = TDbWall::cast(obj2.m_pObject);
|
||
ASSERT(pDbWall1 && pDbWall2);
|
||
|
||
// 处理 katana 对象关系 by gjm
|
||
// 由于 vt1.pWall 会覆盖掉 pDBWall1, 而 vt1.pWall内信息又不全,故这里放入所有参数.
|
||
ProcessKatanaRelation(vt1.pWall, vt2.pWall, pDbWall1, pDbWall2);
|
||
|
||
//modify by xlc on 101027 解决墙体合并后更新不及时的问题
|
||
ModifyModelRecordZone(pDbWall1);
|
||
ModifyModelRecordZone(pDbWall2);
|
||
|
||
pDbWall1->assertWriteEnabled();
|
||
(TWallData &)(*pDbWall1 ) = *vt1.pWall;
|
||
|
||
//add by xlc on 120509 提前对带形窗处理,解决墙体合并时带形窗丢失的问题
|
||
int k=0;
|
||
for (k = 0; k < pDbWall2->GetOpeningIdList().Length(); k++)
|
||
{
|
||
AcDbSoftPointerId id = pDbWall2->GetOpeningIdList()[k];
|
||
OPENOBJ_BEGIN(id, AcDb::kForWrite, TDbBandWin, pEnt);
|
||
if (pEnt)
|
||
{
|
||
if (pEnt->FindWallId(pDbWall1->objectId()) == NOT_FOUND)
|
||
{
|
||
pEnt->ModifyWallId(pDbWall2->objectId(), pDbWall1->objectId());
|
||
}
|
||
|
||
pDbWall2->RemoveReferenceOpening(id);
|
||
pDbWall1->AddOpeningId(id);
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
|
||
// 合并墙体,调整门窗对墙体的引用
|
||
pDbWall2->MoveOpeningTo(*pDbWall1);
|
||
pDbWall2->MovePatchTo(*pDbWall1);
|
||
|
||
TAecSpaceWall &wall1 = *vt1.pWall,
|
||
&wall2 = *vt2.pWall;
|
||
|
||
TSortWallOnPt *pNode2 = wall2.m_pStartNode == &wallsAtPos
|
||
? wall2.m_pEndNode : wall2.m_pStartNode;
|
||
|
||
if (wall1.m_pStartNode == &wallsAtPos)
|
||
{
|
||
wall1.m_pStartNode = pNode2;
|
||
}
|
||
else
|
||
{
|
||
wall1.m_pEndNode = pNode2;
|
||
}
|
||
|
||
TGGiWallVector *pVector = pNode2->FindNode(&wall2.m_ent, TGGiWallVector::FindByEntity);
|
||
ASSERT(pVector && pVector->pWall == &wall2);
|
||
pVector->pWall = &wall1;
|
||
|
||
acedSSSetFirst(NULL,NULL); //add by wlw on 20160914 CAD2015以上平台,解决墙体融合崩溃
|
||
|
||
//删除另一墙段
|
||
ssDel += pDbWall2->objectId();
|
||
pDbWall2->erase();
|
||
TDbCurtainWall::RearrangeCol(pDbWall1, dFistWallLenght);
|
||
|
||
obj2.Close();
|
||
obj1.Close();
|
||
|
||
for (int i = 0; i < walls.Length(); i++)
|
||
{
|
||
if (walls[i] == &wall2)
|
||
{
|
||
walls.Remove();
|
||
break;
|
||
}
|
||
}
|
||
|
||
//消除本节点
|
||
g_lstAllSortWalls.Remove(nPos);
|
||
lstCorners.Remove(nCornerPos); //减变化墙角
|
||
return Adesk::kTrue;
|
||
}
|
||
return Adesk::kFalse;
|
||
}
|
||
|
||
// 在全局墙表中添加一项并根据需要构造排序墙表
|
||
// Status: 考虑了墙体的底标高
|
||
void TSearchSpaceFromWall::NewAppend(TAecSpaceWall *pWall)
|
||
{
|
||
walls.Append(pWall);
|
||
for(int n = 0; n < 2; n++)
|
||
{
|
||
TSortWallOnPt *pSortWall1 = g_lstAllSortWalls.FindNode(n ? &pWall->EndPoint() : &pWall->StartPoint(), CmpSortWallLoc);
|
||
if (pSortWall1)
|
||
{
|
||
pSortWall1->Insert(pWall);
|
||
}
|
||
else
|
||
{
|
||
pSortWall1 = new TSortWallOnPt(n ? pWall->GetEndPoint() : pWall->GetStartPoint(), AcDbObjectId::kNull);
|
||
pSortWall1->Insert(pWall);
|
||
g_lstAllSortWalls.Append(pSortWall1);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 由AecSpaceWall生成AecWall实体
|
||
// bCreateAlone是否创建孤独的不连接两个空间的墙, 在轴线变墙时用到
|
||
void TSearchSpaceFromWall::CreateWalls(BOOL bCreateAlone)
|
||
{
|
||
BOOL bOldVar = g_bDwgBegin;
|
||
DocSetIsDwgBegin(FALSE); //加速
|
||
TDPtrList<TGGeCurveSegment> lstCurves;
|
||
|
||
int nLen=walls.Length();
|
||
for (int i = 0; i < nLen; i++)
|
||
{
|
||
TAecSpaceWall &wall = *walls[i];
|
||
if (!bCreateAlone && !wall.leftSpace && !wall.rightSpace)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
// v2.0 求墙体参数不在这儿
|
||
if (g_nRunMode)
|
||
{
|
||
TGGeCurveSegment *lCurve = new TGGeCurveSegment;
|
||
TGGeCurveSegment *rCurve = new TGGeCurveSegment;
|
||
wall.CalSideParameters(wall.m_ent, g_lstAllSortWalls, *lCurve, *rCurve);
|
||
|
||
if (!(*lCurve))
|
||
{
|
||
delete lCurve;
|
||
}
|
||
else
|
||
{
|
||
lstCurves.Append(lCurve);
|
||
}
|
||
|
||
if (!(*rCurve))
|
||
{
|
||
delete rCurve;
|
||
}
|
||
else
|
||
{
|
||
lstCurves.Append(rCurve);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
TDbWall *pWall = new TDbWall;
|
||
pWall->SetLayerHatch2d(InitLayer(LAY_HATCH, FALSE));//add by W on 050531
|
||
|
||
TWallData &wall1 = *pWall;
|
||
wall1 = wall;
|
||
|
||
pWall->AddToMSpace(Adesk::kTrue);
|
||
acdbGetAdsName(wall.m_ent.name,pWall->objectId()); //把单线的实体名换成墙实体名
|
||
}
|
||
}
|
||
|
||
if (g_nRunMode)
|
||
{
|
||
RemoveDupCurves(lstCurves);
|
||
nLen = lstCurves.Length();
|
||
for (i = 0; i < nLen; i++)
|
||
{
|
||
lstCurves[i]->Make(LAY_WALL);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (i = 0; i < nLen; i++)
|
||
{
|
||
TEntitySet &ent = walls[i]->m_ent;
|
||
OPENOBJ_BEGIN(ent, AcDb::kForWrite, TDbWall, pWall);
|
||
if (pWall)
|
||
{
|
||
pWall->assertWriteEnabled();
|
||
pWall->CalSideParameters(ent, TSearchSpaceFromWall::g_lstAllSortWalls);
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
|
||
for (i = 0; i < nLen; i++)
|
||
{
|
||
TEntitySet &ent = walls[i]->m_ent;
|
||
OPENOBJ_BEGIN(ent, AcDb::kForWrite, TDbWall, pWall);
|
||
if (pWall)
|
||
{
|
||
pWall->assertWriteEnabled();
|
||
pWall->CalSideParameters1();
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
//wlw 2014.05.20 下面代码更新柱子会全图更新,并影响柱子和墙的融合先注释掉,如果对其它功能有影响请提出
|
||
//UpdateColuLinkage();
|
||
}
|
||
|
||
TArchCmdReactor::ResetAll();
|
||
DocSetIsDwgBegin(bOldVar);
|
||
}
|
||
|
||
// 通过一实体名找墙体
|
||
TAecSpaceWall * TSearchSpaceFromWall::FindWall(const TEntitySet &ent)
|
||
{
|
||
for (int i = 0; i < walls.Length(); i++)
|
||
{
|
||
TAecSpaceWall *pWall = walls[i];
|
||
if (pWall->m_ent == ent)
|
||
{
|
||
return pWall;
|
||
}
|
||
}
|
||
|
||
return NULL;
|
||
}
|
||
|
||
//取得在墙角的所有实体
|
||
//Status: 考虑了不同标高
|
||
void TSearchSpaceFromWall::GetEntitiesAtCorners(TADSGePointList &lstCorners, TPickEntSet &ss)
|
||
{
|
||
int nNum = g_lstAllSortWalls.Length();
|
||
for (int n = 0; n < nNum; n++)
|
||
{
|
||
TSortWallOnPt *pSortWallAtCorner = g_lstAllSortWalls[n];
|
||
int nCount = lstCorners.Length();
|
||
for (int i = 0; i < nCount; i++)
|
||
{
|
||
TADSGePoint3d ptCorner = *lstCorners[i];
|
||
if (pSortWallAtCorner->ExactInclude(ptCorner))
|
||
{
|
||
for (int j = 0; j < pSortWallAtCorner->Length(); j++)
|
||
{
|
||
ss += (*pSortWallAtCorner)[j]->pWall->m_ent;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 取得所有的墙角
|
||
// 参数: lstCorners(OUT)--获得的墙角
|
||
void TSearchSpaceFromWall::GetAllCorners(TADSGePointList &lstCorners)
|
||
{
|
||
int nNum = g_lstAllSortWalls.Length();
|
||
for (int n = 0; n < nNum; n++)
|
||
{
|
||
TSortWallOnPt *pSortWallAtCorner = g_lstAllSortWalls[n];
|
||
lstCorners.Append(new TADSGePoint3d(pSortWallAtCorner->ptLoc));
|
||
}
|
||
}
|
||
|
||
// 功能: 找所有的空间
|
||
// 并设置外墙标志
|
||
// 返回室外空间
|
||
TAecSpaceCell * TSearchSpaceFromWall::SearchSpaces()
|
||
{
|
||
TAecSpaceCell * ptrExt = SearchExtSpace(walls, spaces);
|
||
if (ptrExt)
|
||
{
|
||
int nWallNum = walls.Length();
|
||
for (int i = 0; i < nWallNum; i++)
|
||
{
|
||
TAecSpaceWall &wall = *walls[i];
|
||
if (wall.leftSpace == ptrExt)
|
||
{
|
||
wall.m_nWallFlag |= WF_EXTERNAL;
|
||
wall.m_nWallFlag |= WF_LEFTEXT;
|
||
}
|
||
else if (wall.rightSpace == ptrExt)
|
||
{
|
||
wall.m_nWallFlag |= WF_EXTERNAL;
|
||
wall.m_nWallFlag &= ~WF_LEFTEXT;
|
||
}
|
||
else
|
||
{
|
||
wall.m_nWallFlag &= ~WF_EXTERNAL;
|
||
wall.m_nWallFlag &= ~WF_LEFTEXT;
|
||
}
|
||
}
|
||
}
|
||
return ptrExt;
|
||
}
|
||
|
||
// 通过给定的点搜索房间
|
||
// 返回: 0--没有找到; 1--室内; 2--室外
|
||
int TSearchSpaceFromWall::SearchSpace(const TADSGePoint3d &ptPick, TAecSpaceCell &space)
|
||
{
|
||
int nRetFlag = 0;
|
||
int nWallNumber = walls.Length();
|
||
|
||
// 查找最近墙
|
||
TAecSpaceWall *pNearestWall = NULL;
|
||
ads_real nMinDist = 0.0;
|
||
|
||
for (int i = 0; i < nWallNumber; i++)
|
||
{
|
||
TADSGePoint3d ptProject;
|
||
TAecSpaceWall *pWall = 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 nSide = 0; //1:left; 2:right
|
||
BOOL bSubtract = TRUE; //用相减的方法,适合于室内; 否则为室外
|
||
TAecSpaceCell lSpace, rSpace, *pSpace = NULL;
|
||
|
||
if (pNearestWall && SearchTwoSpace(*pNearestWall, lSpace, rSpace) == RTNORM)
|
||
{
|
||
TGGePoly2D lPoly, rPoly;
|
||
lSpace.CenterPoly2D(lPoly);
|
||
rSpace.CenterPoly2D(rPoly);
|
||
|
||
int nPrFlag1 = ptPick&lPoly;
|
||
int nPrFlag2 = ptPick&rPoly;
|
||
|
||
if (nPrFlag1 == PR_INSIDE && nPrFlag2 == PR_INSIDE)
|
||
{
|
||
//两个都包括该点, 则取面积较小的, 并且一定是室内空间
|
||
ads_real nArea1 = lPoly.Area();
|
||
ads_real nArea2 = rPoly.Area();
|
||
if (nArea1 < nArea2)
|
||
{
|
||
pSpace = &lSpace;
|
||
nSide = 1;
|
||
}
|
||
else
|
||
{
|
||
pSpace = &rSpace;
|
||
nSide = 2;
|
||
}
|
||
|
||
nRetFlag = 1;
|
||
}
|
||
else if (nPrFlag1 == PR_INSIDE)
|
||
{
|
||
pSpace = &lSpace;
|
||
nSide = 1;
|
||
nRetFlag = 1;
|
||
}
|
||
else if (nPrFlag2 == PR_INSIDE)
|
||
{
|
||
pSpace = &rSpace;
|
||
nSide = 2;
|
||
nRetFlag = 1;
|
||
}
|
||
else
|
||
{ // 双方都不包含给定的点, 那么一定是室外空间, 并且取面积较大的
|
||
ads_real nArea1 = lPoly.Area();
|
||
ads_real nArea2 = rPoly.Area();
|
||
if (nArea1 > nArea2)
|
||
{
|
||
pSpace = &lSpace;
|
||
nSide = 1;
|
||
}
|
||
else
|
||
{
|
||
pSpace = &rSpace;
|
||
nSide = 2;
|
||
}
|
||
nRetFlag = 2;
|
||
bSubtract= FALSE;
|
||
}
|
||
}
|
||
|
||
if (nRetFlag)
|
||
{
|
||
TAecSpaceCell &spFind = *pSpace;
|
||
space.Reset();
|
||
|
||
for (int n = 0; n < spFind.Length(); n++)
|
||
{
|
||
TAecSpaceWall *pWall = spFind[n];
|
||
if (pWall->leftSpace == pSpace)
|
||
{
|
||
pWall->leftSpace = &space;
|
||
}
|
||
else
|
||
{
|
||
pWall->rightSpace = pSpace;
|
||
}
|
||
|
||
space.Append(pWall);
|
||
}
|
||
}
|
||
|
||
return nRetFlag;
|
||
}
|
||
|
||
// 根据内外墙设置缺省宽度
|
||
// 备注: 事先得找出所有的房间,用SearchSpaces
|
||
void TSearchSpaceFromWall::SetDefaultWidth()
|
||
{
|
||
int nWallNum = walls.Length();
|
||
for (int i = 0; i < nWallNum; i++)
|
||
{
|
||
TAecSpaceWall &wall = *walls[i];
|
||
if (wall.m_nWallFlag & WF_EXTERNAL)
|
||
{
|
||
if (wall.m_nWallFlag & WF_LEFTEXT)
|
||
{
|
||
wall.m_lWidth = _AS_SYS_UNIT(g_nExtWidth);
|
||
wall.m_rWidth = _AS_SYS_UNIT(g_nIntWidth);
|
||
}
|
||
else
|
||
{
|
||
wall.m_lWidth = _AS_SYS_UNIT(g_nIntWidth);
|
||
wall.m_rWidth = _AS_SYS_UNIT(g_nExtWidth);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
wall.m_lWidth = _AS_SYS_UNIT(g_nIntWallWidth) / 2.0;
|
||
wall.m_rWidth = _AS_SYS_UNIT(g_nIntWallWidth) / 2.0;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 搜索一墙的左右房间
|
||
// 参数:
|
||
// aWall(IN)--给定的墙
|
||
// lSpace(OUT)--左边的空间
|
||
// rSpace(OUT)--右边的空间
|
||
// 返回: RTNORM/RTERROR
|
||
int TSearchSpaceFromWall::SearchTwoSpace(TAecSpaceWall &aWall,
|
||
TAecSpaceCell &lSpace, TAecSpaceCell &rSpace)
|
||
{
|
||
if (!aWall)
|
||
{
|
||
return RTERROR;
|
||
}
|
||
|
||
aWall.g_pCurSpace = aWall.leftSpace = &lSpace;
|
||
lSpace.Push(&aWall);
|
||
|
||
if (aWall.Trival(aWall.m_pStartNode, 0) != RTNORM)
|
||
{
|
||
return RTERROR;
|
||
}
|
||
|
||
int nWallNum = TAecSpaceWall::g_pCurSpace->Length();
|
||
for (int n = 0; n < nWallNum; n++)
|
||
{
|
||
TAecSpaceWall &wall = *(*aWall.g_pCurSpace)[n];
|
||
if (wall.curSide)
|
||
{
|
||
wall.rightSpace = aWall.g_pCurSpace;
|
||
}
|
||
else
|
||
{
|
||
wall.leftSpace = aWall.g_pCurSpace;
|
||
}
|
||
}
|
||
|
||
aWall.g_pCurSpace = aWall.rightSpace = &rSpace;
|
||
rSpace.Push(&aWall);
|
||
|
||
if (aWall.Trival(aWall.m_pStartNode, 1) != RTNORM)
|
||
{
|
||
return RTERROR;
|
||
}
|
||
|
||
nWallNum = TAecSpaceWall::g_pCurSpace->Length();
|
||
for (n = 0; n < nWallNum; n++)
|
||
{
|
||
TAecSpaceWall &wall = *(*aWall.g_pCurSpace)[n];
|
||
if (wall.curSide)
|
||
{
|
||
wall.rightSpace = aWall.g_pCurSpace;
|
||
}
|
||
else
|
||
{
|
||
wall.leftSpace = aWall.g_pCurSpace;
|
||
}
|
||
}
|
||
|
||
return RTNORM;
|
||
}
|
||
|
||
// 查找左侧或右侧房间
|
||
int TSearchSpaceFromWall::SearchOneSpace(TAecSpaceWall &aWall,
|
||
int nSide, TAecSpaceCell &aSpace)
|
||
{
|
||
if (!aWall)
|
||
{
|
||
return RTERROR;
|
||
}
|
||
|
||
if (nSide == 0)
|
||
{
|
||
aWall.g_pCurSpace = aWall.leftSpace = &aSpace;
|
||
aSpace.Push(&aWall);
|
||
|
||
if (aWall.Trival(aWall.m_pStartNode, 0) != RTNORM)
|
||
{
|
||
return RTERROR;
|
||
}
|
||
|
||
int nWallNum = TAecSpaceWall::g_pCurSpace->Length();
|
||
for (int n = 0; n < nWallNum; n++)
|
||
{
|
||
TAecSpaceWall &wall = *(*aWall.g_pCurSpace)[n];
|
||
if (wall.curSide)
|
||
{
|
||
wall.rightSpace = aWall.g_pCurSpace;
|
||
}
|
||
else
|
||
{
|
||
wall.leftSpace = aWall.g_pCurSpace;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
aWall.g_pCurSpace = aWall.rightSpace = &aSpace;
|
||
aSpace.Push(&aWall);
|
||
|
||
if (aWall.Trival(aWall.m_pStartNode, 1) != RTNORM)
|
||
{
|
||
return RTERROR;
|
||
}
|
||
|
||
int nWallNum = TAecSpaceWall::g_pCurSpace->Length();
|
||
for (int n = 0; n < nWallNum; n++)
|
||
{
|
||
TAecSpaceWall &wall = *(*aWall.g_pCurSpace)[n];
|
||
if (wall.curSide)
|
||
{
|
||
wall.rightSpace = aWall.g_pCurSpace;
|
||
}
|
||
else
|
||
{
|
||
wall.leftSpace = aWall.g_pCurSpace;
|
||
}
|
||
}
|
||
}
|
||
|
||
return RTNORM;
|
||
}
|
||
|
||
// 找由fromWall到toWall的一条路径, 应当没有找出区域的情况下使用
|
||
int TSearchSpaceFromWall::SearchPath(TAecSpaceWall &fromWall, TAecSpaceWall &toWall, TDPtrStack<TAecSpaceWall> &lstWallPath)
|
||
{
|
||
if (!fromWall)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
TAecSpaceCell lSpace, rSpace;
|
||
fromWall.g_pCurSpace = fromWall.leftSpace = &lSpace;
|
||
lSpace.Push(&fromWall);
|
||
|
||
if (fromWall.TrivalTo(toWall, fromWall.m_pStartNode, 0) == RTNORM)
|
||
{ //按正向
|
||
int nWallNum = TAecSpaceWall::g_pCurSpace->Length();
|
||
for (int n = 0; n < nWallNum; n++)
|
||
{
|
||
TAecSpaceWall *wall = (*fromWall.g_pCurSpace)[n];
|
||
lstWallPath.Push(wall);
|
||
}
|
||
|
||
return 1;
|
||
}
|
||
|
||
fromWall.g_pCurSpace = fromWall.rightSpace = &rSpace;
|
||
rSpace.Push(&fromWall);
|
||
if (fromWall.TrivalTo(toWall, fromWall.m_pEndNode, 0) == RTNORM)
|
||
{ //按逆向
|
||
int nWallNum = TAecSpaceWall::g_pCurSpace->Length();
|
||
for (int n = 0; n < nWallNum; n++)
|
||
{
|
||
TAecSpaceWall *wall = (*fromWall.g_pCurSpace)[n];
|
||
lstWallPath.Push(wall);
|
||
}
|
||
|
||
return 2;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
int TSearchSpaceFromWall::SearchPath(TAecSpaceWall &fromWall, TAecSpaceWall &toWall, TGGePoly2D &poly, int nType)
|
||
{
|
||
TDPtrStack<TAecSpaceWall> lstWalls;
|
||
int nRetCode = SearchPath(fromWall, toWall, lstWalls);
|
||
if (!nRetCode)
|
||
{
|
||
return RTERROR;
|
||
}
|
||
|
||
poly.Reset();
|
||
poly.SetFlag(0);
|
||
|
||
int nLen = lstWalls.Length();
|
||
if (!nLen)
|
||
{
|
||
return RTERROR;
|
||
}
|
||
|
||
TAecSpaceWall &wall0 = *lstWalls[0];
|
||
TGGeCurveSegment wall = wall0;
|
||
if (nType == 1)
|
||
{
|
||
wall = wall0.GetStdOffsetCurveFromCenter(OFFSET_LEFT, 0.0);
|
||
}
|
||
else if (nType == 2)
|
||
{
|
||
wall = wall0.GetStandardSideCurve(OFFSET_LEFT,0,TRUE);
|
||
}
|
||
else if (nType == 3)
|
||
{
|
||
wall = wall0.GetStandardSideCurve(OFFSET_RIGHT,0,TRUE);
|
||
}
|
||
|
||
TDualPtrList<TSortWallOnPt*> lstNode;
|
||
if (nLen == 1 && wall.Is(CURVE_CIRCLE))// 分成两个半圆
|
||
{
|
||
ASSERT(0); //不考虑圆墙
|
||
}
|
||
else
|
||
{
|
||
TGGeCurveSegment cvLastSeg = wall;
|
||
cvLastSeg.SetLineFlag(LS_INFINITE);
|
||
TADSGePoint3d ptS = nRetCode == 1 ? wall.GetStartPoint() : wall.GetEndPoint();
|
||
|
||
for (int i = 0; i < nLen; i++)
|
||
{
|
||
TAecSpaceWall &curWall = *lstWalls[i];
|
||
lstNode.FindOrAddTail(curWall.m_pStartNode);
|
||
lstNode.FindOrAddTail(curWall.m_pEndNode);
|
||
|
||
if ( i > 0 && nType > 1)
|
||
{
|
||
if (curWall.m_pStartNode == lstWalls[i-1]->m_pStartNode
|
||
|| curWall.m_pEndNode== lstWalls[i-1]->m_pEndNode)//反一下
|
||
{
|
||
if (nType == 2)
|
||
{
|
||
nType = 3;
|
||
}
|
||
else if (nType == 3)
|
||
{
|
||
nType = 2;
|
||
}
|
||
}
|
||
}
|
||
|
||
TGGeCurveSegment curSeg = curWall;
|
||
if (nType == 1)
|
||
{
|
||
curSeg = curWall.GetStdOffsetCurveFromCenter(OFFSET_LEFT, 0.0);
|
||
}
|
||
else if (nType == 2)
|
||
{
|
||
curSeg = curWall.GetStandardSideCurve(OFFSET_LEFT,0,TRUE);
|
||
}
|
||
else if (nType == 3)
|
||
{
|
||
curSeg = curWall.GetStandardSideCurve(OFFSET_RIGHT,0,TRUE);
|
||
}
|
||
|
||
double *pNextPt = curSeg.FarPoint(ptS);
|
||
|
||
//modify by xlc on 100414解决阳台沿墙绘制时圆弧部分错误的问题
|
||
//if (pNextPt == &(curSeg.GetStartPoint().x) && curSeg.Is(CURVE_ARC))
|
||
if (pNextPt == &(curSeg.StartPoint().x) && curSeg.Is(CURVE_ARC))
|
||
|
||
{
|
||
poly.AppendNode(ptS, -curSeg.GetBulge());
|
||
}
|
||
else
|
||
{
|
||
poly.AppendNode(ptS, curSeg.GetBulge());
|
||
}
|
||
|
||
ptS = pNextPt;
|
||
}
|
||
|
||
poly.AppendNode(ptS);
|
||
}
|
||
|
||
// Modify on 2002/2/21 by Z 忽略Z坐标
|
||
poly.SetElevation(0.0);
|
||
|
||
return RTNORM;
|
||
}
|
||
|
||
// 更新墙体标志(内外墙)
|
||
void TSearchSpaceFromWall::UpdateWallFlags()
|
||
{
|
||
for (int i = 0; i < walls.Length(); i++)
|
||
{
|
||
TAecSpaceWall *pWall = walls[i];
|
||
ASSERT(!!pWall->m_ent);
|
||
|
||
TAcDbObjectPtr obj(pWall->m_ent, AcDb::kForWrite);
|
||
if (!obj)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
TDbWall *pDbWall = TDbWall::cast(obj.m_pObject);
|
||
if (pDbWall)
|
||
{
|
||
pDbWall->assertWriteEnabled();
|
||
pDbWall->m_nWallFlag = pWall->m_nWallFlag;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 搜出所有房间(包括室外空间), 并返最大室外空间
|
||
// 参数:
|
||
// walls(IN)--所有的墙
|
||
// spaces(OUT)--所有的空间
|
||
// Note: 仅限于内部使用
|
||
// modified by W 080103,解决室外空间确定个别情况误判问题
|
||
TAecSpaceCell * TSearchSpaceFromWall::SearchExtSpace(TDPtrList<TAecSpaceWall> &walls, TDPtrList<TAecSpaceCell> &spaces)
|
||
{
|
||
double dMinPathArea = 0;
|
||
TAecSpaceCell *extCell = NULL;
|
||
|
||
// 查找墙两侧的房间
|
||
int nLen = walls.Length();
|
||
for (int i = 0; i < nLen; i++)
|
||
{
|
||
TAecSpaceWall &aWall = *walls[(int)i];
|
||
TSortWallOnPt *pSortWalls = aWall.m_pStartNode;
|
||
|
||
if (!pSortWalls) // 当前墙孤立
|
||
{
|
||
continue;
|
||
}
|
||
|
||
if (!(nLen % 50))
|
||
{
|
||
TchGeLib::adsout << _T(".");
|
||
}
|
||
|
||
aWall.g_pCurSpace = NULL;
|
||
if (!aWall.leftSpace)
|
||
{
|
||
aWall.g_pCurSpace = new TAecSpaceCell;
|
||
aWall.g_pCurSpace->Push(&aWall);
|
||
|
||
if (aWall.Trival(aWall.m_pStartNode, 0) == RTNORM)
|
||
{
|
||
spaces.Append(aWall.g_pCurSpace);
|
||
int nWallNum = TAecSpaceWall::g_pCurSpace->Length();
|
||
for (int n = 0; n < nWallNum; n++)
|
||
{
|
||
TAecSpaceWall &wl = *(*aWall.g_pCurSpace)[n];
|
||
if (wl.curSide)
|
||
{
|
||
wl.rightSpace = aWall.g_pCurSpace;
|
||
}
|
||
else
|
||
{
|
||
wl.leftSpace = aWall.g_pCurSpace;
|
||
}
|
||
}
|
||
|
||
aWall.g_pCurSpace->Reverse(); // add by W 080103,保证内环顺时针
|
||
|
||
// sg add 091106,解决离坐标原点较远时,积分出错的情况
|
||
//double pathArea = aWall.g_pCurSpace->PathArea();
|
||
double dPathArea = aWall.g_pCurSpace->PathArea(pSortWalls->ptLoc);
|
||
if (dPathArea < dMinPathArea)
|
||
{
|
||
dMinPathArea = dPathArea;
|
||
extCell = aWall.g_pCurSpace;
|
||
}
|
||
|
||
aWall.g_pCurSpace->Reverse(); // 恢复方向
|
||
}
|
||
else
|
||
{
|
||
delete TAecSpaceWall::g_pCurSpace;
|
||
}
|
||
}
|
||
|
||
if (!aWall.rightSpace)
|
||
{
|
||
aWall.g_pCurSpace = new TAecSpaceCell;
|
||
aWall.g_pCurSpace->Push(&aWall);
|
||
|
||
if (aWall.Trival(aWall.m_pStartNode, 1) == RTNORM)
|
||
{
|
||
spaces.Append(aWall.g_pCurSpace);
|
||
int nWallNum = TAecSpaceWall::g_pCurSpace->Length();
|
||
for (int n = 0; n < nWallNum; n++)
|
||
{
|
||
TAecSpaceWall &wl = *(*aWall.g_pCurSpace)[n];
|
||
if (wl.curSide)
|
||
{
|
||
wl.rightSpace = aWall.g_pCurSpace;
|
||
}
|
||
else
|
||
{
|
||
wl.leftSpace = aWall.g_pCurSpace;
|
||
}
|
||
}
|
||
|
||
// sg add 091106,解决离坐标原点较远时,积分出错的情况
|
||
//double pathArea = aWall.g_pCurSpace->PathArea();
|
||
double dPathArea = aWall.g_pCurSpace->PathArea(pSortWalls->ptLoc);
|
||
if (dPathArea < dMinPathArea)
|
||
{
|
||
dMinPathArea = dPathArea;
|
||
extCell = aWall.g_pCurSpace;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
delete TAecSpaceWall::g_pCurSpace;
|
||
}
|
||
}
|
||
}
|
||
|
||
return extCell;
|
||
} |