//-----------------------------------------------------------------------------+ // 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::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 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 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 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 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 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 precTemp(_angSnap, 0.001); poly.Compress(true); // add by W on 061129 } // sg modify 110123,根据8.5需求,散水搜索支持单独绕墙体造型,而不饶柱子 // if (nCtrlFlag) if (nCtrlFlag || nDealWallPatch) { // 获得与墙体相连的柱子和墙体造型 TDPtrStack lstNodes; TDPtrList 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 &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 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 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 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 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 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; }