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

1012 lines
26 KiB
C++

//-----------------------------------------------------------------------------+
// Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd.
// = FileName : TAecSpaceCell 类
// = Version : ver2.0
// = Author : wlw
// = CreateDate : 2002-09-09
// = Description: TAecSpaceCell 定义
// = Maintainers:
//
//-----------------------------------------------------------------------------+
#include "StdAfx.h"
#include "TAecSpaceCell.h"
#include "TDbColumn.h"
#include "TDbWallPatch.h"
#include "TDPtrList.h"
#include "TPushMemVar.h"
#include "Symdef.h"
TAecSpaceCell * TAecSpaceWall::g_pCurSpace = NULL;
TDPtrList<TAecSpaceCell> * TAecSpaceCell::g_pAllSpaces = NULL;
int TAecSpaceCell::g_nGlobalIndex = 0;
TAecSpaceCell::TAecSpaceCell()
{
m_nIndex = g_nGlobalIndex;
g_nGlobalIndex++;
}
TAecSpaceCell::~TAecSpaceCell()
{
g_nGlobalIndex--;
}
// 求路径积分的面积
// Modify on 2002/2/22, 当存在误差时,微小的不封闭可能导致巨大的误差。
ads_real TAecSpaceCell::PathArea()
{
int len = Length();
if (!len)
{
return 0;
}
TADSGePoint3d tmpt = (*this)[0]->GetStartPoint();
TADSGePoint3d ptBack = tmpt;
ads_real result = 0.0;
for (int i = 0; i < len; i++)
{
result += (*this)[i]->PathArea(tmpt);
}
if (ptBack.Distance2d(tmpt) > _DIST_SNAP)
{
result += (ptBack.x - tmpt.x) * (tmpt.y + ptBack.y) / 2.0;
}
return result;
}
// sg add 091106,解决离坐标原点较远时,积分出错的情况
// 功能与不带参数的同名函数一致,仅提供积分起点
ads_real TAecSpaceCell::PathArea(TADSGePoint3d ptStart)
{
int len = Length();
if (!len)
{
return 0;
}
TADSGePoint3d tmpt = ptStart;
// sg add 091118,如果是弧段是第一段,由于在此之前调用了Reverse,起点、终点会发生反转,需要对算法进行修正
double dBulge = (*this)[0]->GetBulge();
if (fabs(dBulge) > 1.0E-5) // 首段是弧段
{
tmpt = (*this)[0]->GetStartPoint();
}
TADSGePoint3d ptBack = tmpt;
ads_real result = 0.0;
for (int i = 0; i < len; i++)
{
result += (*this)[i]->PathArea(tmpt);
}
// sg增加本行注释,下面这个判断如果成立,通常会引起积分结果错误,提醒注意
if (ptBack.Distance2d(tmpt) > _DIST_SNAP)
{
result += (ptBack.x - tmpt.x) * (tmpt.y + ptBack.y) / 2.0;
}
return result;
}
// 得到墙基线上的POLYLINE
// poly -- result
// 解决了墙体非精确连接和缺口问题,设置了polyline标高为墙体底标高, 071211
// 解决了节点有柱,但墙连接于柱外的问题。071217
int TAecSpaceCell::CenterPoly2D(TGGePoly2D &poly)
{
poly.Reset();
int len = Length();
if (!len)
{
return RTERROR;
}
TAecSpaceWall &wall = *(*this)[len - 1];
if (len == 1 && wall.Is(CURVE_CIRCLE))
{
// 分成两个半圆
ASSERT(0); //不考虑圆墙
}
else
{
poly.SetFlag(1);
TGGeCurveSegment lastSeg = wall;
lastSeg.SetElevation(0);
lastSeg.SetLineFlag(LS_INFINITE);
TADSGePoint3d spt=(*this)[0]->GetStartPoint(); // 房间的绕向由第一个墙的方向确定
TADSGePoint3d nextPt;
for (int i = 0; i < len; i++)
{
TAecSpaceWall &curWall = *(*this)[i];
TGGeCurveSegment curSeg = curWall;
curSeg.SetElevation(0);
curSeg.SetLineFlag(LS_INFINITE);
spt.z = curWall.GetEndPoint().z;
BOOL bCurWallDirection; //遍历方向与curWal墙方向是否相同
TADSGePoint3d ept;
if (spt.Distance(curWall.GetStartPoint()) < spt.Distance(curWall.GetEndPoint()))
{
bCurWallDirection = TRUE;
ept = curWall.GetEndPoint();
}
else
{
bCurWallDirection = FALSE;
ept = curWall.GetStartPoint();
}
TADSGePoint3d pt1, pt2, curPt;
if (i == 0)
{
BOOL bNotIntersect = FALSE; // 求当前点
int ptNum = curSeg.Intersection(lastSeg, pt1, pt2);
if (ptNum > 0)
{
if (ptNum == 2)
{
curPt = TGGeLine(pt1,pt2).NearPoint(spt);
}
else if (ptNum == 1)
{
curPt = pt1;
}
//判断是否接近平行
double a1 = lastSeg.Direction(lastSeg.NearPoint(spt));
double a2 = curSeg.Direction(curSeg.NearPoint(spt));
double na = NA(a1 - a2);
if (fabs(na) < _angSnap || fabs(na - PI) < _angSnap || fabs(na - PI * 2) < _angSnap)//平行
{
curPt = curSeg.NearPoint(spt);
if ((curPt&lastSeg) == PR_OUTSIDE) //不共线
{
bNotIntersect = TRUE;
}
}
else if (curWall.HasColumnAt(0)) //节点有柱时特殊处理,i=0时一定是起始节点
{
TDbColumn *pColu = NULL;
acdbOpenObject(pColu,curWall.GetStartColumnId(),AcDb::kForRead);
if (pColu != NULL)
{
TGGePoly2D polyColu;
pColu->GetOutline(polyColu);
pColu->close();
polyColu.SetElevation(0);
TPushMemVar<double> precTemp(_distSnap,0.1);
Refresh_DIST_SNAP();
if ((curPt & polyColu) == PR_OUTSIDE //交点在柱外
&& curWall.GetStartPoint().Distance2d(wall.NearPoint(spt)) > g_nDistPrec)//墙体本身不连接
{
curPt = curSeg.NearPoint(spt);
bNotIntersect = TRUE;
}
}
Refresh_DIST_SNAP();
}
}
else //平行墙
{
curPt = curSeg.NearPoint(spt);
if ((curPt & lastSeg) == PR_OUTSIDE) //不共线
{
bNotIntersect = TRUE;
}
}
if (bNotIntersect) //不连续段
{
poly.AppendNode(lastSeg.NearPoint(spt)); //add by W on 060911
}
}
else
{
curPt = nextPt; //上次求得的下一点
}
// 求下一个端点
int nextIndex = i >= len - 1 ? 0 : i + 1; // 当前段为最后时, 下一段为起始段
TAecSpaceWall &nextWall = *(*this)[nextIndex];
TGGeCurveSegment nextSeg = nextWall;
nextSeg.SetElevation(0);
nextSeg.SetLineFlag(LS_INFINITE);
int ptNum = curSeg.Intersection(nextSeg, pt1, pt2);
BOOL bNotIntersect = FALSE;
if (ptNum > 0)
{
if (ptNum == 2)
{
nextPt = TGGeLine(pt1, pt2).NearPoint(ept);
}
else if (ptNum == 1)
{
nextPt = pt1;
}
//判断是否接近平行
double a1 = nextSeg.Direction(nextSeg.NearPoint(ept));
double a2 = curSeg.Direction(curSeg.NearPoint(ept));
double na = NA(a1 - a2);
if (fabs(na) < _angSnap || fabs(na - PI) < _angSnap || fabs(na - PI * 2) < _angSnap)//平行
{
nextPt = curSeg.NearPoint(ept);
if ((nextPt & nextSeg) == PR_OUTSIDE)//不共线
{
bNotIntersect = TRUE;
}
}
else if(curWall.HasColumnAt(bCurWallDirection ? 1 : 0))//节点有柱时特殊处理
{
TDbColumn *pColu = NULL;
acdbOpenObject(pColu,bCurWallDirection ? curWall.GetEndColumnId() : curWall.GetStartColumnId(),AcDb::kForRead);
if (pColu != NULL)
{
TGGePoly2D polyColu;
pColu->GetOutline(polyColu);
pColu->close();
polyColu.SetElevation(0);
TPushMemVar<double> precTemp(_distSnap,0.1);
Refresh_DIST_SNAP();
if ((nextPt & polyColu) == PR_OUTSIDE //交点在柱外
&& TADSGePoint3d(curWall.NearPoint(ept)).Distance2d(nextWall.NearPoint(ept)) > g_nDistPrec)//墙体本身不连接
{
nextPt = curSeg.NearPoint(ept);
bNotIntersect = TRUE;
}
}
Refresh_DIST_SNAP();
}
}
else
{
nextPt = curSeg.NearPoint(ept); // 同一方向上, 两段衔接.
if ((nextPt & nextSeg) == PR_OUTSIDE) //不共线
{
bNotIntersect = TRUE;
}
}
//添一段
poly.Append(new TADSGePoint3d(curPt));
if (curSeg.Is(CURVE_LINE))
{
poly.AppendBugle(0.0);
}
else if (curSeg.Is(CURVE_ARC))
{
TGGeArc arc = curSeg.GetArc();
if (spt.Distance2d(curWall.GetStartPoint()) < spt.Distance2d(curWall.GetEndPoint()))
{ //逆时针
arc.SetStarAngle(ads_angle(arc.GetCenterPt(), curPt));
arc.SetEndAngle(ads_angle(arc.GetCenterPt(), nextPt));
poly.AppendBugle(arc.Bulge());
}
else
{
arc.SetEndAngle(ads_angle(arc.GetCenterPt(), curPt));
arc.SetStarAngle(ads_angle(arc.GetCenterPt(), nextPt));
poly.AppendBugle(-arc.Bulge());
}
}
else
{
TchGeLib::adsout << _T("\nFetal error!");
assert(0);
}
if (bNotIntersect)//平行段
{
poly.AppendNode(nextPt);
nextPt = nextSeg.NearPoint(ept);
}
spt = ept;
lastSeg = curSeg;
}
}
poly.SetElevation(wall.GetElevation());
{
TPushMemVar<double> precTemp(_angSnap,0.001);
poly.Compress(true); //add by W on 061129
}
return RTNORM;
}
// 产生空间内侧POLYLINE
// 对于室外则沿外侧产生
// 解决了墙体非精确连接和缺口问题,设置了polyline标高为墙体底标高, 071211
// 解决了节点有柱,但墙连接于柱外的问题。071217
// sg modify 091117,增加是否处理墙体造型的设置,只在nCtrlFlag大于0时有效,只要为解决散水不需要绕墙体造型的问题
// nDealWallPatch==0不考虑墙体造型,1--考虑墙体造型与柱子使用相同的室内、室外方法
// 2--考虑墙体造型,固定室外;3--考虑墙体造型,固定室内
// int TAecSpaceCell::InternalPoly2D(TGGePoly2D &poly, int nCtrlFlag)
// int TAecSpaceCell::InternalPoly2D(TGGePoly2D &poly, int nCtrlFlag, BOOL bDealWallPatch)
int TAecSpaceCell::InternalPoly2D(TGGePoly2D &poly, int nCtrlFlag, int nDealWallPatch)
{
poly.Reset();
int len = Length();
if (!len)
{
return RTERROR;
}
TAecSpaceWall &wall = *(*this)[len - 1];
if (len == 1 && wall.Is(CURVE_CIRCLE))
{
// 不考虑圆墙,分成两个半圆
ASSERT(0);
int nSide = wall.leftSpace == this ? OFFSET_LEFT : OFFSET_RIGHT;
TGGeCurveSegment curveSeg = wall.GetRelativeSideCurve(nSide, wall.GetStartPoint(), 0.0, TRUE);
curveSeg.SetElevation(0.0);
poly.SetFlag(1);
poly.Append(new TADSGePoint3d(curveSeg.GetStartPoint()));
poly.AppendBugle(PI);
poly.Append(new TADSGePoint3d(curveSeg.GetEndPoint()));
poly.AppendBugle(PI);
}
else
{
poly.SetFlag(1);
int nSide = wall.leftSpace == this ? OFFSET_LEFT : OFFSET_RIGHT;
TGGeCurveSegment lastSeg = wall.GetRelativeSideCurve(nSide, wall.GetStartPoint(), 0.0, TRUE);
lastSeg.SetElevation(0.0);
TADSGePoint3d spt = (*this)[0]->GetStartPoint(); // 房间的绕向由第一个墙的方向确定
TADSGePoint3d nextPt;
for (int i = 0; i < len; i++)
{
TAecSpaceWall &curWall = *(*this)[i];
nSide = curWall.leftSpace == this ? OFFSET_LEFT : OFFSET_RIGHT;
TGGeCurveSegment curSeg = curWall.GetRelativeSideCurve(nSide, curWall.GetStartPoint(), 0.0, TRUE);
curSeg.SetElevation(0.0);
spt.z = curWall.GetEndPoint().z;
TADSGePoint3d ept;
BOOL bCurWallDirection; // 遍历方向与curWal墙方向是否相同
if (spt.Distance(curWall.GetStartPoint()) < spt.Distance(curWall.GetEndPoint()))
{
bCurWallDirection = TRUE;
ept = curWall.GetEndPoint();
}
else
{
bCurWallDirection = FALSE;
ept = curWall.GetStartPoint();
}
TADSGePoint3d pt1, pt2, curPt;
if (i == 0)
{
BOOL bNotIntersect = FALSE;
int ptNum = curSeg.Intersection(lastSeg, pt1, pt2);
if (ptNum > 0)
{
if (ptNum == 2)
{
curPt = TGGeLine(pt1,pt2).NearPoint(spt);
}
else if (ptNum == 1)
{
curPt = pt1;
}
// 判断是否接近平行
double a1 = lastSeg.Direction(lastSeg.NearPoint(spt));
double a2 = curSeg.Direction(curSeg.NearPoint(spt));
double na = NA(a1 - a2);
if (fabs(na) < _angSnap || fabs(na - PI) < _angSnap || fabs(na - PI * 2) < _angSnap) // 平行
{
curPt = curSeg.NearPoint(spt);
if ((curPt & lastSeg) == PR_OUTSIDE) // 不共线
{
bNotIntersect = TRUE;
}
}
else if (curWall.HasColumnAt(0)) // 节点有柱时特殊处理,i=0时一定是起始节点
{
TDbColumn *pColu = NULL;
acdbOpenObject(pColu,curWall.GetStartColumnId(),AcDb::kForRead);
if (pColu != NULL)
{
TGGePoly2D polyColu;
pColu->GetOutline(polyColu);
pColu->close();
polyColu.SetElevation(0);
TPushMemVar<double> precTemp(_distSnap,0.1);
Refresh_DIST_SNAP();
if ((curPt & polyColu) == PR_OUTSIDE // 交点在柱外
&& curWall.GetStartPoint().Distance2d(wall.NearPoint(spt)) > g_nDistPrec) // 墙体本身不连接
{
curPt = curSeg.NearPoint(spt);
bNotIntersect = TRUE;
}
}
Refresh_DIST_SNAP();
}
}
else // 平行墙
{
curPt = curSeg.NearPoint(spt);
if ((curPt & lastSeg) == PR_OUTSIDE) // 不共线
{
bNotIntersect = TRUE;
}
}
if (bNotIntersect) // 不连续段
{
poly.AppendNode(lastSeg.NearPoint(spt)); // add by W on 060911
}
}
else
{
curPt = nextPt; // 上次求得的下一点
}
// 求下一个端点
int nextIndex = i >= len - 1 ? 0 : i + 1; // 当前段为最后时, 下一段为起始段
TAecSpaceWall &nextWall = *(*this)[nextIndex];
nSide = nextWall.leftSpace == this ? OFFSET_LEFT : OFFSET_RIGHT;
TGGeCurveSegment nextSeg = nextWall.GetRelativeSideCurve(nSide, nextWall.GetStartPoint(), 0.0, TRUE);
nextSeg.SetElevation(0.0);
BOOL bNotIntersect = FALSE;
int ptNum = curSeg.Intersection(nextSeg, pt1, pt2);
if (ptNum > 0)
{
if (ptNum == 2)
{
nextPt = TGGeLine(pt1, pt2).NearPoint(ept);
}
else if (ptNum == 1)
{
nextPt = pt1;
}
// 判断是否接近平行
double a1 = nextSeg.Direction(nextSeg.NearPoint(ept));
double a2 = curSeg.Direction(curSeg.NearPoint(ept));
double na = NA(a1 - a2);
if (fabs(na) < _angSnap || fabs(na - PI) < _angSnap || fabs(na - PI * 2) < _angSnap) // 平行
{
nextPt = curSeg.NearPoint(ept);
if ((nextPt & nextSeg) == PR_OUTSIDE) // 不共线
{
bNotIntersect = TRUE;
}
}
else if (curWall.HasColumnAt(bCurWallDirection ? 1 : 0)) // 节点有柱时特殊处理
{
TDbColumn *pColu = NULL;
acdbOpenObject(pColu, bCurWallDirection ? curWall.GetEndColumnId() : curWall.GetStartColumnId(), AcDb::kForRead);
if (pColu != NULL)
{
TGGePoly2D polyColu;
pColu->GetOutline(polyColu);
pColu->close();
polyColu.SetElevation(0);
TPushMemVar<double> precTemp(_distSnap,0.1);
Refresh_DIST_SNAP();
if ((nextPt & polyColu) == PR_OUTSIDE // 交点在柱外
&& TADSGePoint3d(curWall.NearPoint(ept)).Distance2d(nextWall.NearPoint(ept)) > g_nDistPrec) // 墙体本身不连接
{
nextPt = curSeg.NearPoint(ept);
bNotIntersect = TRUE;
}
}
Refresh_DIST_SNAP();
}
}
else
{
nextPt = curSeg.NearPoint(ept); // 同一方向上, 两段衔接.
if ((nextPt & nextSeg) == PR_OUTSIDE) // 不共线
{
bNotIntersect = TRUE;
}
}
// 添一段
poly.Append(new TADSGePoint3d(curPt));
if (curSeg.Is(CURVE_LINE))
{
poly.AppendBugle(0.0);
}
else if (curSeg.Is(CURVE_ARC))
{
TGGeArc arc = curSeg.GetArc();
if (spt.Distance2d(curWall.GetStartPoint()) < spt.Distance2d(curWall.GetEndPoint()))
{
// 逆时针
arc.SetStarAngle(ads_angle(arc.GetCenterPt(), curPt));
arc.SetEndAngle(ads_angle(arc.GetCenterPt(), nextPt));
poly.AppendBugle(arc.Bulge());
}
else
{
arc.SetEndAngle(ads_angle(arc.GetCenterPt(), curPt));
arc.SetStarAngle(ads_angle(arc.GetCenterPt(), nextPt));
poly.AppendBugle(-arc.Bulge());
}
}
else
{
TchGeLib::adsout << _T("\nFetal error!");
assert(0);
}
if (bNotIntersect) // 不连续段
{
poly.AppendNode(nextPt);
nextPt = nextSeg.NearPoint(ept);
}
spt = ept;
lastSeg = curSeg;
}
}
poly.SetElevation(0.0);
{
TPushMemVar<double> precTemp(_angSnap, 0.001);
poly.Compress(true); // add by W on 061129
}
// sg modify 110123,根据8.5需求,散水搜索支持单独绕墙体造型,而不饶柱子
// if (nCtrlFlag)
if (nCtrlFlag || nDealWallPatch)
{
// 获得与墙体相连的柱子和墙体造型
TDPtrStack<TSortWallOnPt> lstNodes;
TDPtrList<AcDbObjectId> lstPatchIds;
for (int k = 0; k < Length(); k++)
{
const TAecSpaceWall &wall = *(*this)[k];
if (!lstNodes.FindNode(wall.m_pStartNode, CompNodeByEqual))
{
lstNodes.Append(wall.m_pStartNode);
}
if (!lstNodes.FindNode(wall.m_pEndNode, CompNodeByEqual))
{
lstNodes.Append(wall.m_pEndNode);
}
OPENOBJ_BEGIN(wall.m_ent.name, AcDb::kForRead, TDbWall, pDbWall);
if (pDbWall)
{
const TDPtrList<AcDbSoftPointerId> &lstPatch = pDbWall->GetPatchIdList();
for (int j = 0; j < lstPatch.Length(); j++)
{
const AcDbObjectId &rId = lstPatch[j];
if (!lstPatchIds.FindNode(&rId, CompareObjectId))
{
lstPatchIds.Append(new AcDbObjectId(rId));
}
}
}
OPENOBJ_END();
}
TGGePoly2D &polyWall = poly;
// sg add 110123,判断是否绕柱子
if (nCtrlFlag)
{
for (int n = 0; n < lstNodes.Length(); n++)
{
// 扣除柱子
TSortWallOnPt *pNode = lstNodes[n];
if (pNode->HasColumn())
{
TGGePoly2D polyColu = pNode->polyExtend;
polyColu.SetElevation(0.0);
AcDb::BoolOperType opt = (nCtrlFlag == 2) ? AcDb::kBoolUnite : AcDb::kBoolSubtract;
TDPtrList<TGGePoly2D> resArray;
if (PolyBoolOper(polyWall, polyColu, resArray, opt))
{
if (resArray.Length() == 1)
{
polyWall = *resArray[0];
}
}
else // sg add 091111,考虑稳定性,当此处的布尔运算不成功时,再使用第三套布尔运算
{
resArray.Reset();
RegionBoolOper(polyWall, polyColu, resArray, opt);
if (resArray.Length() == 1)
{
polyWall = *resArray[0];
}
}
}
}
}
// 扣除附件(扶墙柱)
// sg add 091117,只对设置了处理墙体造型的情况,进行处理
if (nDealWallPatch)
{
for (int n = 0; n < lstPatchIds.Length(); n++)
{
TGGePoly2D polyPatch(1);
bool bConcave = false;
OPENOBJ_BEGIN(*lstPatchIds[n], AcDb::kForRead, TDbWallPatch, pPatch);
if (!pPatch)
{
continue;
}
pPatch->GetOutlinePoly(polyPatch);
bConcave = pPatch->GetUsageFlag() == TDbWallPatch::kConcave;
OPENOBJ_END();
polyPatch.SetElevation(0.0);
// sg add 110123,墙体造型单独判断室内、室外
int nPatchFlag = (nDealWallPatch==1)?nCtrlFlag:nDealWallPatch;
AcDb::BoolOperType opt;
if (bConcave)
{
// opt = (nCtrlFlag == 2) ? AcDb::kBoolSubtract : AcDb::kBoolUnite;
opt = (nPatchFlag == 2) ? AcDb::kBoolSubtract : AcDb::kBoolUnite;
}
else
{
// opt = (nCtrlFlag == 2) ? AcDb::kBoolUnite : AcDb::kBoolSubtract;
opt = (nPatchFlag == 2) ? AcDb::kBoolUnite : AcDb::kBoolSubtract;
}
TDPtrList<TGGePoly2D> resArray;
if (PolyBoolOper(polyWall, polyPatch, resArray, opt))
{
if (resArray.Length() == 1)
{
polyWall = *resArray[0];
}
}
else // sg add 091111,考虑稳定性,当此处的布尔运算不成功时,再使用第三套布尔运算
{
resArray.Reset();
RegionBoolOper(polyWall, polyPatch, resArray, opt);
if (resArray.Length() == 1)
{
polyWall = *resArray[0];
}
}
}
}
}
poly.SetElevation(wall.GetElevation());
return RTNORM;
}
// 产生墙体几何中心POLYLINE
// 解决了墙体非精确连接和缺口问题,设置了polyline标高为墙体底标高, 071211
// 解决了节点有柱,但墙连接于柱外的问题。071217
int TAecSpaceCell::GeomCenterPoly2D(TGGePoly2D &poly)
{
poly.Reset();
int len = Length();
if (!len)
{
return RTERROR;
}
TAecSpaceWall &wall = *(*this)[len - 1];
if (len == 1 && wall.Is(CURVE_CIRCLE))
{
// 分成两个半圆
ASSERT(0); //不考虑圆墙
}
else
{
poly.SetFlag(1);
int nSide = wall.leftSpace == this ? OFFSET_LEFT : OFFSET_RIGHT;
TGGeCurveSegment lastSeg = wall.OffsetGeomCenter(LS_INFINITE, TRUE);
lastSeg.SetElevation(0);
lastSeg.SetLineFlag(LS_INFINITE);
TADSGePoint3d spt = (*this)[0]->GetStartPoint(); // 房间的绕向由第一个墙的方向确定
TADSGePoint3d nextPt;
for (int i = 0; i < len; i++)
{
TAecSpaceWall &curWall = *(*this)[i];
TGGeCurveSegment curSeg = curWall.OffsetGeomCenter(LS_INFINITE, TRUE);
curSeg.SetElevation(0);
lastSeg.SetLineFlag(LS_INFINITE);
spt.z = curWall.GetEndPoint().z;
BOOL bCurWallDirection; //遍历方向与curWal墙方向是否相同
TADSGePoint3d ept;
if (spt.Distance(curWall.GetStartPoint()) < spt.Distance(curWall.GetEndPoint()))
{
bCurWallDirection = TRUE;
ept = curWall.GetEndPoint();
}
else
{
bCurWallDirection = FALSE;
ept = curWall.GetStartPoint();
}
TADSGePoint3d pt1, pt2, curPt;
if (i == 0)
{
BOOL bNotIntersect = FALSE; // 求当前点
int ptNum = curSeg.Intersection(lastSeg, pt1, pt2);
if (ptNum > 0)
{
if (ptNum == 2)
{
curPt = TGGeLine(pt1,pt2).NearPoint(spt);
}
else if (ptNum == 1)
{
curPt = pt1;
}
//判断是否接近平行
double a1 = lastSeg.Direction(lastSeg.NearPoint(spt));
double a2 = curSeg.Direction(curSeg.NearPoint(spt));
double na = NA(a1 - a2);
if (fabs(na) < _angSnap || fabs(na - PI) < _angSnap || fabs(na - PI * 2) < _angSnap)//平行
{
curPt = curSeg.NearPoint(spt);
if ((curPt & lastSeg) == PR_OUTSIDE) //不共线
{
bNotIntersect = TRUE;
}
}
else if (curWall.HasColumnAt(0)) //节点有柱时特殊处理,i=0时一定是起始节点
{
TDbColumn *pColu = NULL;
acdbOpenObject(pColu,curWall.GetStartColumnId(),AcDb::kForRead);
if (pColu != NULL)
{
TGGePoly2D polyColu;
pColu->GetOutline(polyColu);
pColu->close();
polyColu.SetElevation(0);
TPushMemVar<double> precTemp(_distSnap,0.1);
Refresh_DIST_SNAP();
if ((curPt&polyColu) == PR_OUTSIDE //交点在柱外
&& curWall.GetStartPoint().Distance2d(wall.NearPoint(spt)) > g_nDistPrec)//墙体本身不连接
{
curPt = curSeg.NearPoint(spt);
bNotIntersect = TRUE;
}
}
Refresh_DIST_SNAP();
}
}
else //平行墙
{
curPt = curSeg.NearPoint(spt);
if ((curPt & lastSeg) == PR_OUTSIDE) //不共线
{
bNotIntersect = TRUE;
}
}
if (bNotIntersect) //不连续段
{
poly.AppendNode(lastSeg.NearPoint(spt));//add by W on 060911
}
}
else
{
curPt = nextPt; //上次求得的下一点
}
// 求下一个端点
int nextIndex = i>= len - 1 ? 0 : i + 1; // 当前段为最后时, 下一段为起始段
TAecSpaceWall &nextWall = *(*this)[nextIndex];
TGGeCurveSegment nextSeg = nextWall.OffsetGeomCenter(LS_INFINITE, TRUE);
nextSeg.SetElevation(0);
lastSeg.SetLineFlag(LS_INFINITE);
int ptNum = curSeg.Intersection(nextSeg, pt1, pt2);
BOOL bNotIntersect = FALSE;
if (ptNum > 0)
{
if (ptNum == 2)
{
nextPt = TGGeLine(pt1, pt2).NearPoint(ept);
}
else if (ptNum == 1)
{
nextPt = pt1;
}
//判断是否接近平行
double a1 = nextSeg.Direction(nextSeg.NearPoint(ept));
double a2 = curSeg.Direction(curSeg.NearPoint(ept));
double na = NA(a1 - a2);
if (fabs(na) < _angSnap || fabs(na - PI) < _angSnap || fabs(na - PI * 2) < _angSnap)//平行
{
nextPt = curSeg.NearPoint(ept);
if ((nextPt & nextSeg) == PR_OUTSIDE) //不共线
{
bNotIntersect = TRUE;
}
}
else if (curWall.HasColumnAt(bCurWallDirection ? 1 : 0))//节点有柱时特殊处理
{
TDbColumn *pColu = NULL;
acdbOpenObject(pColu,bCurWallDirection ? curWall.GetEndColumnId() : curWall.GetStartColumnId(),AcDb::kForRead);
if (pColu != NULL)
{
TGGePoly2D polyColu;
pColu->GetOutline(polyColu);
pColu->close();
polyColu.SetElevation(0);
TPushMemVar<double> precTemp(_distSnap,0.1);
Refresh_DIST_SNAP();
if ((nextPt & polyColu) == PR_OUTSIDE //交点在柱外
&& TADSGePoint3d(curWall.NearPoint(ept)).Distance2d(nextWall.NearPoint(ept)) > g_nDistPrec)//墙体本身不连接
{
nextPt = curSeg.NearPoint(ept);
bNotIntersect = TRUE;
}
}
Refresh_DIST_SNAP();
}
}
else
{
nextPt = curSeg.NearPoint(ept); // 同一方向上, 两段衔接.
if ((nextPt & nextSeg) == PR_OUTSIDE) //不共线
{
bNotIntersect = TRUE;
}
}
//添一段
poly.Append(new TADSGePoint3d(curPt));
if (curSeg.Is(CURVE_LINE))
{
poly.AppendBugle(0.0);
}
else if (curSeg.Is(CURVE_ARC))
{
TGGeArc arc = curSeg.GetArc();
if (spt.Distance2d(curWall.GetStartPoint()) < spt.Distance2d(curWall.GetEndPoint()))
{ //逆时针
arc.SetStarAngle(ads_angle(arc.GetCenterPt(), curPt));
arc.SetEndAngle(ads_angle(arc.GetCenterPt(), nextPt));
poly.AppendBugle(arc.Bulge());
}
else
{
arc.SetEndAngle(ads_angle(arc.GetCenterPt(), curPt));
arc.SetStarAngle(ads_angle(arc.GetCenterPt(), nextPt));
poly.AppendBugle(-arc.Bulge());
}
}
if (bNotIntersect) //平行段
{
poly.AppendNode(nextPt);
nextPt = nextSeg.NearPoint(ept);
}
spt = ept;
lastSeg = curSeg;
}
}
poly.SetElevation(wall.GetElevation());
{
TPushMemVar<double> precTemp(_angSnap,0.001);
poly.Compress(true); //add by W on 061129
}
return RTNORM;
}
int TAecSpaceCell::ShowMe()
{
ads_redraw(NULL, 0);
int len = Length();
for (int i = 0; i < len; i++)
{
(*this)[i]->m_ent.Redraw(3);
}
TchGeLib::adsout << _T(" Area=") << PathArea() / 1.0E6;
return ads_getstring(0, _T("\nPress return:"), TCString());
}
void TAecSpaceCell::Redraw(int nMode)
{
int len = Length();
for (int i = 0; i < len; i++)
{
(*this)[i]->m_ent.Redraw(nMode);
}
}
//求房间中心线的界限
int TAecSpaceCell::GetExtend(TADSGePoint3d &ptLow, TADSGePoint3d &ptUp)
{
if (!Length())
{
return RTERROR;
}
for (int i = 0; i < Length(); i++)
{
TAecSpaceWall &wall = *(*this)[i];
if (i == 0)
{
wall.TGGeCurveSegment::GetExtend(ptLow, ptUp);
}
else
{
TADSGePoint3d pt1, pt2;
wall.TGGeCurveSegment::GetExtend(pt1, pt2);
ptLow = Min(ptLow, pt1);
ptUp = Max(ptUp, pt2);
}
}
return RTNORM;
}