//-----------------------------------------------------------------------------+ // Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd. // = FileName : TWallData.cpp // = Version : ver2.0 // = Author : xlc // = CreateDate : 2002-09-09 // = Description: 墙体数据类的定义 // = Maintainers: // //-----------------------------------------------------------------------------+ #include "StdAfx.h" #include "DbConfig.h" #include "Symdef.h" #include "TWallData.h" #include "TDbWall.h" #include "TAcDbObjectPtr.h" #include "TSortSideOnVertex.h" #include "TGGiWallVector.h" #include "TPushMemVar.h" #include "TDbColumn.h" #include "OpeningData.h" #include "TGGeArc.h" #include "TPushPrec.h" #include "TAecSpaceWall.h" #include "TGGeLine.h" #include "TDPtrList.h" extern double g_nInsulateThick; extern BOOL g_bSkipWallMaterial; TWallData* TWallData::g_pWall = NULL; static int CmpSortWallLoc(const TSortWallOnPt *p1, const void *p2) { TSortWallOnPt *pp1 = (TSortWallOnPt *)p1; //modify by xlc on 120425 墙柱关系精确判断 //return !pp1->Include(*(const TADSGePoint3d *)p2); return !pp1->ExactInclude(*(const TADSGePoint3d *)p2); } TWallData::TWallData() { _TWallData(); } //设置默认值 void TWallData::_TWallData() { //(WF_STARTTERM+WF_ENDTERM); //俩端封头 m_nWallFlag = 0; m_lWidth = m_rWidth = _AS_SYS_UNIT(g_nIntWallWidth) / 2.0; m_nHeight = DocGetLHeight(); m_nUsageFlag = kNormal; m_style = kBrick; // wlw modify 100914,修改默认厚度g_nInsulateThick如果是小数位是0则右保温与左一样,否则按实际值取。 int nLeft, nRight; DoubleToTowInt(g_nInsulateThick, nLeft, nRight); m_nInsuThick = _AS_SYS_UNIT(TowIntToDouble(nLeft, nRight)); m_nFromLeftStart = m_nFromLeftEnd = m_nFromRightStart = m_nFromRightEnd = 0.0; //端部保温封口 SetInsulateCap(g_bWallHasInsulateCap); m_idKatanaEnd = m_idKatanaStart = AcDbObjectId::kNull; } // 直墙 TWallData::TWallData(const TADSGePoint3d &ptStart, const TADSGePoint3d &ptEnd, double nSweepAngle) : TGGeCurveSegment(ptStart, ptEnd, nSweepAngle) { _TWallData(); } // 从一实体中取得数据 // 参数: // ent--可以是LINE,ARC,也可以是TDbWall TWallData::TWallData(const TEntitySet &ent) { _TWallData(); TAcDbObjectPtr obj(ent.name, AcDb::kForRead, Adesk::kTrue); if (obj.m_pObject != NULL) { AcDbEntity &dbEnt = obj; if (dbEnt.isKindOf(TDbWall::desc())) { TDbWall *pDbWall = (TDbWall *)&dbEnt; *this = *pDbWall; } else { TGGeCurveSegment seg(ent); TGGeCurveSegment &segThis = *this; segThis = seg; } } } TWallData::TWallData(const TWallData &src) { _TWallData(); *this = src; } // 赋值操作 TWallData & TWallData::operator = (const TWallData &src) { TGGeCurveSegment & segThis = *this; segThis = (const TGGeCurveSegment &)src; m_nWallFlag = src.m_nWallFlag; m_lWidth = src.m_lWidth; m_rWidth = src.m_rWidth; m_nHeight = src.m_nHeight; //左宽,右宽,墙高 m_style = src.m_style; m_idColuStart = src.m_idColuStart; m_idColuEnd = src.m_idColuEnd; m_idLeftStart = src.m_idLeftStart; m_idRightStart = src.m_idRightStart; m_idLeftEnd = src.m_idLeftEnd; m_idRightEnd = src.m_idRightEnd; m_nUsageFlag = src.m_nUsageFlag; m_nInsuThick = src.m_nInsuThick; m_nFromLeftStart = src.m_nFromLeftStart; m_nFromLeftEnd = src.m_nFromLeftEnd; m_nFromRightStart = src.m_nFromRightStart; m_nFromRightEnd = src.m_nFromRightEnd; m_idKatanaStart = src.m_idKatanaStart; m_idKatanaEnd = src.m_idKatanaEnd; return *this; } // 左右两侧任何一侧优先级别大于当前,那么当前就是优先级别低 // nTerm--0:起始端;1:终止端 BOOL TWallData::IsLowPriorityAt(int nTerm) const { AcDbObjectId idLeft = nTerm ? m_idLeftEnd : m_idLeftStart; AcDbObjectId idRight = nTerm ? m_idRightEnd : m_idRightStart; if (!idLeft || !idRight) { return FALSE; } OPENOBJ_BEGIN(idLeft, AcDb::kForRead, TDbWall, pWall); if (pWall && pWall->GetPriority() > GetPriority()) { return TRUE; } OPENOBJ_END(); OPENOBJ_BEGIN(idRight, AcDb::kForRead, TDbWall, pWall); if (pWall && pWall->GetPriority() > GetPriority()) { return TRUE; } OPENOBJ_END(); return FALSE; } // 0:左侧;1:右侧;2:双侧;-1:内墙 int TWallData::GetExtSide() const { BOOL bLeft = IsExternal1(OFFSET_LEFT); BOOL bRight = IsExternal1(OFFSET_RIGHT); int nFlag = -1; if (bLeft && bRight) { nFlag = 2; } else if (bLeft) { nFlag = 0; } else if (bRight) { nFlag = 1; } return nFlag; } // 是否为外墙 BOOL TWallData::IsExternal() const { return ((m_nWallFlag & WF_EXTERNAL) != 0); } // 某一侧是否朝外,只对外墙 BOOL TWallData::IsExternal(int nSide) const { if (!(m_nWallFlag & WF_EXTERNAL)) { return FALSE; } return IsExternal1(nSide); } // 某一侧是否朝外 BOOL TWallData::IsExternal1(int nSide) const { BOOL bRet; if (!nSide) //左侧 { bRet = ((m_nWallFlag & WF_LEFTEXT) ? TRUE : FALSE); } else //右侧 { bRet = ((m_nWallFlag & WF_RIGHTEXT) ? TRUE : FALSE); } return bRet; } void TWallData::SetExternal(BOOL bTrue) { if (bTrue) { m_nWallFlag |= WF_EXTERNAL; } else { m_nWallFlag &= ~WF_EXTERNAL; } } void TWallData::SetExternal(int nSide, BOOL bTrue) { if (!nSide) //左侧 { if (bTrue) { m_nWallFlag |= WF_LEFTEXT; } else { m_nWallFlag &= ~WF_LEFTEXT; } } else //右侧 { if (bTrue) { m_nWallFlag |= WF_RIGHTEXT; } else { m_nWallFlag &= ~WF_RIGHTEXT; } } } // 当包括保温层时, 不是实际厚度, 而是显示(视觉)厚度 // nSide: 0--左侧; 1--右侧; 2--包括保温层左侧; 3--包括保温层右侧; 4--包括保温层的总厚度 double TWallData::GetWidth(int nSide) const { double nWidth = m_lWidth + m_rWidth; switch(nSide) { case 0: nWidth = m_lWidth; break; case 1: nWidth = m_rWidth; break; case 2: nWidth = m_lWidth + ((m_nWallFlag & WF_LEFT_INSULATE) ? GetInsulateThick() : 0.0); break; case 3: nWidth = m_rWidth + ((m_nWallFlag & WF_RIGHT_INSULATE) ? GetInsulateThick(1) : 0.0); break; case 4: nWidth += ((m_nWallFlag & WF_LEFT_INSULATE) ? GetInsulateThick() : 0.0) + ((m_nWallFlag & WF_RIGHT_INSULATE) ? GetInsulateThick(1) : 0.0); break; default: break; } return nWidth; } // 对两点排序,返回 -1/1/0 // 注: 靠近起点的为小 // 注: 可以把此功能移到基类 TGGeCurveSegment int TWallData::CompareLocation(const TADSGePoint3d &p1, const TADSGePoint3d &p2) const { assert(!Is(CURVE_CIRCLE)); TADSGePoint3d ptProject1, ptProject2; const TGGeCurveSegment &seg = *this; seg.ProjectToMe(p1, ptProject1); seg.ProjectToMe(p2, ptProject2); if ((ptProject1 & seg) != PR_INSIDE || (ptProject2 & seg) != PR_INSIDE) { return 0; } if (Is(CURVE_LINE)) { return (ads_distance(GetStartPoint(), ptProject1) < ads_distance(GetStartPoint(), ptProject2) ? -1 : 1); } TGGeArc arc = GetArc(); TGGeArc arc1(arc), arc2(arc); arc1.SetEndAngle(ads_angle(arc1.GetCenterPt(), ptProject1)); arc2.SetEndAngle(ads_angle(arc2.GetCenterPt(), ptProject2)); return (arc1.GetLength() < arc2.GetLength() ? -1 : 1); } // 对门窗进行排序 void TWallData::SortOpening(TDPtrList &lstOpenings) const { g_pWall = (TWallData *)this; lstOpenings.QuickSort(TWallData::CompareOpening); g_pWall = NULL; } void TWallData::SortOpening(TDPtrList &lstOpenings)const { g_pWall = (TWallData *)this; lstOpenings.QuickSort(TWallData::CompareOpening); g_pWall = NULL; } //最可能的外方向 ads_real TWallData::ExtDirection(const TADSGePoint3d &ptLoc) const { ads_real nDrt = OrthoDirection(ptLoc); if (m_nWallFlag & WF_EXTERNAL) { if (m_nWallFlag & WF_LEFTEXT) { nDrt = AngleRangeTo2PI(nDrt + PI); } } else if (m_lWidth < m_rWidth) //确保右宽在外边 { } else //确保左宽在外边 { nDrt = AngleRangeTo2PI(nDrt+PI); } return nDrt; } // 求侧面的朝向 double TWallData::GetAzimuth(int nSide) const { TADSGePoint3d ptMid = MidPoint(); ads_real nDrt = OrthoDirection(ptMid); return (nSide ? nDrt : AngleRangeTo2PI(nDrt + PI)); } // 求侧面的朝向 double TWallData::GetAzimuth(int nSide, TADSGePoint3d ptPos) const { ptPos.z = GetElevation(); ads_real nDrt = OrthoDirection(ptPos); //ptPos可以不在基线上 return (nSide ? nDrt : AngleRangeTo2PI(nDrt + PI)); } #ifndef OBJECTDBX // 判断ptAccut在线段内,还是在延长线上,ptAccut如果不在线段所在直线上,返回值不确定 // ret:FALSE:在延长线上,TRUE:线段内(包括在端点上) BOOL IsPointOnWallLineSeg(const XCurveSegment &lineSeg, const TADSGePoint3d &ptAccut) { double dDist1 = ptAccut.Distance2d(lineSeg.StartPoint()); double dDist2 = ptAccut.Distance2d(lineSeg.EndPoint()); double dLen = lineSeg.GetLength(); double dTol = dDist1 + dDist2 - dLen; if (fabs (dTol) < 1E-6) return TRUE; else return FALSE; } // sg add 110119,修改根据墙体得到轴线的算法,扩大搜索范围 // 综合考虑墙基线,边线的起点和终点,然后取包络,然后对这根线延伸0.5个长度 TGGeCurveSegment TWallData::GetLongBaseLine() const { if (this == NULL) { return XCurveSegment(); } // 转换cvBase TGGeCurveSegment cvBase = *this; if (!cvBase.Is(CURVE_LINE)) // 只处理直线的情况 { return cvBase; } XCurveSegment lSide, rSide; GetSideCurve(lSide, rSide); // 左边线和右边线向基线做投影,取延伸出来的部分 TADSGePoint3d ptSLeftRes, ptSRightRes, ptELeftRes, ptERightRes; cvBase.ProjectToMe(lSide.StartPoint(), ptSLeftRes); cvBase.ProjectToMe(rSide.StartPoint(), ptSRightRes); double dDist1 = 0.0, dDist2 = 0.0, dDist = 0.0; if (!IsPointOnWallLineSeg(cvBase, ptSLeftRes)) { cvBase.SetStartPoint(ptSLeftRes); } if (!IsPointOnWallLineSeg(cvBase, ptSRightRes)) { cvBase.SetStartPoint(ptSRightRes); } cvBase.ProjectToMe(lSide.EndPoint(), ptELeftRes); cvBase.ProjectToMe(rSide.EndPoint(), ptERightRes); if (!IsPointOnWallLineSeg(cvBase, ptELeftRes)) { cvBase.SetEndPoint(ptELeftRes); } if (!IsPointOnWallLineSeg(cvBase, ptERightRes)) { cvBase.SetEndPoint(ptERightRes); } // 将刚刚得到的cvBase延伸半个墙体总宽度 double dWid = GetWidth(0) + GetWidth(1); TADSGePointDir2d ptExtStart, ptExtEnd; cvBase.Polar(-dWid, ptExtStart, TRUE); cvBase.Polar(-dWid, ptExtEnd, FALSE); cvBase.SetPoints(ptExtStart, ptExtEnd); return cvBase; } // 返回: 位0x01--左轴线, 位0x02--右轴线 int TWallData::GetAxises(const TADSGePoint3d &ptAt, TEntitySet &lEntAxis, TEntitySet &rEntAxis) const { TPickEntSet ss(SS_FREE); // sg modify 110119,根据8.5需求,在获得墙体范围内的轴线时,采取扩大搜索范围的算法 // TGGeCurveSegment segThis = *this; TGGeCurveSegment segThis = GetLongBaseLine(),segthis1; segThis.SetElevation(0.0); TADSGePointDir2d ptExtStart, ptExtEnd; TADSGePoint3d ptExtStart3d, ptExtEnd3d; segThis.Polar(-_AS_SYS_UNIT(g_nDistPrec), ptExtStart, TRUE); segThis.Polar(-_AS_SYS_UNIT(g_nDistPrec), ptExtEnd, FALSE); ptExtStart3d = Wcs2Ucs(ptExtStart); //wlw 140212 支持UCS ptExtEnd3d = Wcs2Ucs(ptExtEnd); segThis.SetPoints(ptExtStart, ptExtEnd); segthis1 = segThis; segthis1.SetPoints(ptExtStart3d, ptExtEnd3d); TGGePoly2D poly; segthis1.AsPoly2D(poly); TGGePoly poly1; poly.MapToPolygon(poly1); if (ss.Get(_T("F"), TRBList(poly1.Fence()), NULL, TRBList(RTDXF0, _T("LINE,ARC,CIRCLE"), 8, LAY_AXIS, NULL)) != RTNORM) { return 0; } int nRetFlag = 0; segThis.SetLineFlag(LS_FINITE); ads_real nDist = segThis.PathDistance(TADSGePoint3d(ptAt.x, ptAt.y)); ads_real nDistLeft = 0.0, nDistRight = segThis.GetLength(); long ssLen = ss.Length(); for (long i = 0; i < ssLen; i++) { TEntitySet ent = ss[i]; TGGeCurveSegment segAxis(ent, LS_FINITE); segAxis.SetElevation(0.0); if (Is(CURVE_ARC)) { if (!segAxis.Is(CURVE_LINE)) { continue; } TGGeArc ar = GetArc(); double nDistTo = ar.GetCenterPt().Distance(&segAxis); if (nDistTo > _DIST_SNAP) { continue; } } TADSGePoint3d ptInt[2]; int nInt = segThis.Intersection(segAxis, ptInt[0], ptInt[1]); if (!nInt) { continue; } TADSGePoint3d ptInters; if (nInt == 1) { ptInters = ptInt[0]; } else { ptInters = TGGeLine(ptInt[0], ptInt[1]).NearPoint(TADSGePoint3d(ptAt.x, ptAt.y)); } ads_real nDist0 = segThis.PathDistance(ptInters); if (nDist0 < nDist) { if (nDist0 > nDistLeft) { nRetFlag |= 0x01; nDistLeft = nDist0; lEntAxis = ent; } } else { if (nDist0 < nDistRight) { nRetFlag |= 0x02; nDistRight = nDist0; rEntAxis = ent; } } } return nRetFlag; } #endif // 判断是否可以同另一墙段合并 // 方法: // 当两墙可以合并时,调整几何端点和端点的参数及墙体特征 // 只有材料相同时才可以合并 // 参数: another(IN) -- 另一墙段 // 终点对终点合并,或者起点对起点合并可能有问题 // 返回: kTrue--进行合并; kFalse--不能进行合并 //modified by w on 050726 ,解决圆墙问题 //modify by xlc on 100823 校正终点对终点合并,或者起点对起点合并问题,增加保温属性判断 Adesk::Boolean TWallData::MergeWith(const TWallData &another) { TGGeCurveSegment seg; int bLine1 = Is(CURVE_LINE), bLine2 = another.Is(CURVE_LINE); if (bLine1 != bLine2 || GetPriority() != another.GetPriority()) { return Adesk::kFalse; } //add by xlc on 110309 不同用途的墙不合并 if (GetUsageFlag() != another.GetUsageFlag()) { return Adesk::kFalse; } // add by gjm 2013/08/05 // 当本墙起始点处的 katana 对像的ID 与 合并墙 终点处的 katana 对象的ID 相同时 或 // 本墙起终点处的 katana 对像的ID 与 合并墙 起点处的 katana 对象的ID 相同时 // 不合并 if ((m_idKatanaStart.isValid() && m_idKatanaStart == another.GetEndKatanaID())) { if (!m_idKatanaStart.isErased()) return Adesk::kFalse; } if ((m_idKatanaEnd.isValid() && m_idKatanaEnd == another.GetStartKatanaID())) { if (!m_idKatanaEnd.isErased()) return Adesk::kFalse; } //modify by xlc on 100823 校正终点对终点合并,或者起点对起点合并问题,增加保温属性判断 if (/*fabs(m_lWidth - another.m_lWidth) > 1.0E-6 || fabs(m_rWidth - another.m_rWidth) > 1.0E-6 || */fabs(m_nHeight - another.GetHeight()) > 1.0E-6 || fabs(GetElevation() - another.GetElevation()) > 1.0E-6) { return Adesk::kFalse; } seg = *this; int nPosFlag = 0; if (GetStartPoint() == another.GetStartPoint()) { // modify by xlc on 100823 墙宽不一致,不合并 if (fabs(m_lWidth - another.m_rWidth) > 1.0E-6 ||fabs(m_rWidth - another.m_lWidth) > 1.0E-6 ) { return Adesk::kFalse; } // modify by xlc on 100823 保温属性不一致,不合并 if(IsInsulateOnSide(OFFSET_LEFT) != another.IsInsulateOnSide(OFFSET_RIGHT) ||IsInsulateOnSide(OFFSET_RIGHT) != another.IsInsulateOnSide(OFFSET_LEFT)) { return Adesk::kFalse; } // modify by xlc on 100823 有保温时,厚度不一致不合并 if((IsInsulateOnSide(OFFSET_LEFT) && fabs(GetInsulateThick(OFFSET_LEFT) - another.GetInsulateThick(OFFSET_RIGHT)) > _DIST_SNAP) || (IsInsulateOnSide(OFFSET_RIGHT) && fabs(GetInsulateThick(OFFSET_RIGHT) - another.GetInsulateThick(OFFSET_LEFT)) > _DIST_SNAP)) { return Adesk::kFalse; } nPosFlag = 1; //合并两个起点 } else if (GetStartPoint() == another.GetEndPoint()) { // modify by xlc on 100823 墙宽不一致,不合并 if (fabs(m_lWidth - another.m_lWidth) > 1.0E-6 ||fabs(m_rWidth - another.m_rWidth) > 1.0E-6 ) { return Adesk::kFalse; } // modify by xlc on 100823 保温属性不一致,不合并 if(IsInsulateOnSide(OFFSET_LEFT) != another.IsInsulateOnSide(OFFSET_LEFT) ||IsInsulateOnSide(OFFSET_RIGHT) != another.IsInsulateOnSide(OFFSET_RIGHT)) { return Adesk::kFalse; } // modify by xlc on 100823 有保温时,厚度不一致不合并 if((IsInsulateOnSide(OFFSET_LEFT) && fabs(GetInsulateThick(OFFSET_LEFT) - another.GetInsulateThick(OFFSET_LEFT)) > _DIST_SNAP) || (IsInsulateOnSide(OFFSET_RIGHT) && fabs(GetInsulateThick(OFFSET_RIGHT) - another.GetInsulateThick(OFFSET_RIGHT)) > _DIST_SNAP)) { return Adesk::kFalse; } nPosFlag = 2; //合并自己的起点和另外的终点 } else if (GetEndPoint() == another.GetEndPoint()) { // modify by xlc on 100823 墙宽不一致,不合并 if (fabs(m_lWidth - another.m_rWidth) > 1.0E-6 ||fabs(m_rWidth - another.m_lWidth) > 1.0E-6 ) { return Adesk::kFalse; } // modify by xlc on 100823 保温属性不一致,不合并 if(IsInsulateOnSide(OFFSET_LEFT) != another.IsInsulateOnSide(OFFSET_RIGHT) ||IsInsulateOnSide(OFFSET_RIGHT) != another.IsInsulateOnSide(OFFSET_LEFT)) { return Adesk::kFalse; } // modify by xlc on 100823 有保温时,厚度不一致不合并 if((IsInsulateOnSide(OFFSET_LEFT) && fabs(GetInsulateThick(OFFSET_LEFT) - another.GetInsulateThick(OFFSET_RIGHT)) > _DIST_SNAP) || (IsInsulateOnSide(OFFSET_RIGHT) && fabs(GetInsulateThick(OFFSET_RIGHT) - another.GetInsulateThick(OFFSET_LEFT)) > _DIST_SNAP)) { return Adesk::kFalse; } nPosFlag = 3; //合并两个终点 } else if (GetEndPoint() == another.GetStartPoint()) { // modify by xlc on 100823 墙宽不一致,不合并 if (fabs(m_lWidth - another.m_lWidth) > 1.0E-6 ||fabs(m_rWidth - another.m_rWidth) > 1.0E-6 ) { return Adesk::kFalse; } // modify by xlc on 100823 保温属性不一致,不合并 if(IsInsulateOnSide(OFFSET_LEFT) != another.IsInsulateOnSide(OFFSET_LEFT) ||IsInsulateOnSide(OFFSET_RIGHT) != another.IsInsulateOnSide(OFFSET_RIGHT)) { return Adesk::kFalse; } // modify by xlc on 100823 有保温时,厚度不一致不合并 if((IsInsulateOnSide(OFFSET_LEFT) && fabs(GetInsulateThick(OFFSET_LEFT) - another.GetInsulateThick(OFFSET_LEFT)) > _DIST_SNAP) || (IsInsulateOnSide(OFFSET_RIGHT) && fabs(GetInsulateThick(OFFSET_RIGHT) - another.GetInsulateThick(OFFSET_RIGHT)) > _DIST_SNAP)) { return Adesk::kFalse; } nPosFlag = 4; //合并自己的终点和另外的起点 } if (!nPosFlag) { return Adesk::kFalse; } Adesk::Boolean bCanMerge = Adesk::kFalse; //曲线类型相同 if (bLine1) { if (IsSameDrt(TGGeLine::Direction(), another.TGGeLine::Direction(), _angSnap)) { if (nPosFlag == 4) { seg.SetPoints(StartPoint(), another.EndPoint()); bCanMerge = Adesk::kTrue; } else if (nPosFlag == 2) { seg.SetPoints(another.StartPoint(), EndPoint()); bCanMerge = Adesk::kTrue; } else if (nPosFlag == 1) { seg.SetPoints(another.EndPoint(), EndPoint()); bCanMerge = Adesk::kTrue; } else if (nPosFlag == 3) { seg.SetPoints(StartPoint(), another.StartPoint()); bCanMerge = Adesk::kTrue; } } } else { TGGeArc arc1 = GetArc(), arc2 = another.GetArc(); if (fabs(arc1.GetRadius() - arc2.GetRadius()) < _DIST_SNAP && arc1.GetCenterPt() == arc2.GetCenterPt()) { if (nPosFlag == 4) { //add by w on 050726,不能合并为圆墙 if (GetStartPoint() == another.GetEndPoint()) { return Adesk::kFalse; } seg.SetPoints(StartPoint(), another.EndPoint()); bCanMerge = Adesk::kTrue; } else if (nPosFlag == 2) { //add by w on 050726,不能合并为圆墙 if (another.GetStartPoint() == GetEndPoint()) { return Adesk::kFalse; } seg.SetPoints(another.StartPoint(), EndPoint()); bCanMerge = Adesk::kTrue; } } } if (bCanMerge) { //add by xlc on 120509 当发生合并的墙体都在带形窗上时,不进行合并操作 OPENOBJ_BEGIN(another.GetMyObjectId(),AcDb::kForRead,TDbWall, pWall); { if (pWall) { int k = 0; for (k = 0; k < pWall->GetOpeningIdList().Length(); k++) { AcDbSoftPointerId id = pWall->GetOpeningIdList()[k]; OPENOBJ_BEGIN(id, AcDb::kForRead, TDbBandWin, pEnt); if (pEnt) { if(pEnt->FindWallId(pWall->objectId())!= NOT_FOUND && pEnt->FindWallId(GetMyObjectId())!= NOT_FOUND) { return Adesk::kFalse; } } OPENOBJ_END(); } } } OPENOBJ_END(); if (nPosFlag == 4) //终点和another起点合并 { m_idLeftEnd = another.m_idLeftEnd; m_idRightEnd = another.m_idRightEnd; m_nFromLeftEnd = another.m_nFromLeftEnd; m_nFromRightEnd = another.m_nFromRightEnd; m_idColuEnd=another.m_idColuEnd; } else if (nPosFlag == 2) // 起点和another终点合并 { m_idLeftStart = another.m_idLeftStart; m_idRightStart = another.m_idRightStart; m_nFromLeftStart = another.m_nFromLeftStart; m_nFromRightStart = another.m_nFromRightStart; m_idColuStart = another.m_idColuStart; } else if (nPosFlag == 1) //起点和起点合并 { m_idLeftStart = another.m_idRightEnd; m_idRightStart = another.m_idLeftEnd; m_nFromLeftStart = another.m_nFromRightEnd; m_nFromRightStart = another.m_nFromLeftEnd; m_idColuStart = another.m_idColuEnd; } else if (nPosFlag == 3) //终点和终点合并 { m_idLeftEnd = another.m_idRightStart; m_idRightEnd = another.m_idLeftStart; m_nFromLeftEnd = another.m_nFromRightStart; m_nFromRightEnd = another.m_nFromLeftStart; m_idColuEnd = another.m_idColuStart; } (TGGeCurveSegment &)*this = seg; m_nWallFlag &= ~WF_POLYSHAPE; } return bCanMerge; } // static 全局函数 int TWallData::CompareOpening(const TOpeningData *p1, const TOpeningData *p2) { return g_pWall->CompareLocation(p1->m_ptLocation, p2->m_ptLocation); } int TWallData::CompareOpening(const TDbOpening *p1, const TDbOpening *p2) { return g_pWall->CompareLocation(p1->m_ptLocation, p2->m_ptLocation); } // 基线立面转平面的转换矩阵 // 仅适用与直墙 void TWallData::GetPlanarMatrix(ads_matrix matTrans) const { ASSERT(Is(CURVE_LINE)); TADSGePoint3d pt3 = GetEndPoint(); pt3.z += 3000; ConstructMatrix(GetStartPoint(), GetEndPoint(), pt3, matTrans); } const TCHAR * TWallData::GetStyleText() const { const TCHAR *szText; switch(m_style) { case kDivider: szText = WALLMATE_Divider; break; case kRocket: szText = WALLMATE_Rocket; break; case kBrick: szText = WALLMATE_Brick; break; case kCurtain: szText = WALLMATE_Curtain; break; case kFill: szText = WALLMATE_Fill; break; case kFill1: szText = WALLMATE_Fill1; break; case kFill2: szText = WALLMATE_Fill2; break; case kConcrete: szText = WALLMATE_Concrete; break; default: szText = WALLMATE_NoDefine; } return szText; } // 不做任何处理的墙外轮廓 wlw 110316 void TWallData::StandardGetOutlinePoly(double nElev, TGGePoly2D &wOutline, BOOL bIncludeInsulate) const { TGGeCurveSegment cvLeft, cvRight; cvLeft = GetRelativeSideCurve(OFFSET_LEFT, StartPoint(), 0.0, bIncludeInsulate); cvRight = GetRelativeSideCurve(OFFSET_RIGHT, StartPoint(), 0.0, bIncludeInsulate); TGGeCurveSegment cvCenter = GetHatchCenterCurve(); wOutline.Reset(); wOutline.SetFlag(1); wOutline.AppendNode(cvLeft.StartPoint()); wOutline.AppendNode(cvCenter.StartPoint()); wOutline.AppendNode(cvRight.StartPoint(), cvRight.GetBulge()); wOutline.AppendNode(cvRight.EndPoint()); wOutline.AppendNode(cvCenter.EndPoint()); wOutline.AppendNode(cvLeft.EndPoint(), -cvLeft.GetBulge()); wOutline.SetElevation(nElev); wOutline.Compress(); } // 获得某个标高上的轮廓,不扣除柱子, 顶点考虑了基线端点 void TWallData::GetOutlinePoly(double nElev, TGGePoly2D &wOutline, BOOL bIncludeInsulate) const { TGGeCurveSegment cvLeft, cvRight; //modified by W on 061115 //GetSideCurve(cvLeft, cvRight, 0.0, bIncludeInsulate); GetStandardCurve(cvLeft, cvRight, 0.0, bIncludeInsulate); TGGeCurveSegment cvCenter = GetHatchCenterCurve(); wOutline.Reset(); wOutline.SetFlag(1); wOutline.AppendNode(cvLeft.StartPoint()); wOutline.AppendNode(cvCenter.StartPoint()); wOutline.AppendNode(cvRight.StartPoint(), cvRight.GetBulge()); wOutline.AppendNode(cvRight.EndPoint()); wOutline.AppendNode(cvCenter.EndPoint()); wOutline.AppendNode(cvLeft.EndPoint(), -cvLeft.GetBulge()); wOutline.SetElevation(nElev); wOutline.Compress();//add by W on 070326 } // 获得某个标高上的轮廓(扣除柱子), 顶点考虑了基线端点 void TWallData::GetOutlinePoly1(double nElev, TGGePoly2D &wOutline, BOOL bIncludeInsulate) const { BOOL bBaseInWall = (GetWidth(0) > _DIST_SNAP && GetWidth(1) > _DIST_SNAP); TGGeCurveSegment cvLeft, cvRight; GetSideCurve(cvLeft, cvRight, 0.0, bIncludeInsulate); wOutline.Reset(); wOutline.SetFlag(1); wOutline.AppendNode(cvLeft.StartPoint()); if (bBaseInWall && !HasColumnAt(0)) { wOutline.AppendNode(StartPoint()); } wOutline.AppendNode(cvRight.StartPoint(), cvRight.GetBulge()); wOutline.AppendNode(cvRight.EndPoint()); if (bBaseInWall && !HasColumnAt(1)) { wOutline.AppendNode(EndPoint()); } wOutline.AppendNode(cvLeft.EndPoint(), -cvLeft.GetBulge()); wOutline.SetElevation(nElev); } // 通过一近似的位置取得门窗的精确插入位置 // ptBase--近似位置; opk--门窗类型; nOpenWidth--门窗宽度; ptInsert(O)--精确位置 // 门窗宽度按墙体基线进行测量 // OP_DOOR, OP_WINDOW, OP_HOLE, OP_PROWIN -- 插入点在几何中心线的弦上 // OP_ARCWIN, OP_CORNWIN -- 插入点投影到几何中心线上 Adesk::Boolean TWallData::GetOpeningLocation(const TADSGePoint3d &ptBase, TOpeningData::OpeningKind opk, ads_real nOpenWidth, TADSGePoint3d &ptInsert) const { TGGeCurveSegment seg = OffsetGeomCenter(LS_INFINITE, TRUE); TADSGePoint3d ptOnCenter; //几何中心线 if (seg.ProjectToMe(ptBase, ptOnCenter) != RTNORM) { return Adesk::kFalse; } if (opk == TOpeningData::OP_ARCWIN || opk == TOpeningData::OP_CORNWIN) { // OP_ARCWIN, OP_CORNWIN -- 插入点投影到几何中心线上 ptInsert = ptOnCenter; } else { if (seg.Is(CURVE_ARC)) { TGGeArc ar = seg.GetArc(), arSub; double nDirToCen = ads_angle(ptOnCenter, ar.GetCenterPt()); if (ar.TGGeCircle::GetSubArc(ptOnCenter, nOpenWidth, arSub) != RTNORM) { return Adesk::kFalse; } double nArchHeight = nOpenWidth / 2.0 * tan(arSub.Bulge() / 4); ads_polar(ptOnCenter, nDirToCen, nArchHeight, ptInsert); } else { ptInsert = ptOnCenter; } } ptInsert.z = ptBase.z; return Adesk::kTrue; } // 验证门窗是否干涉 // Status: 两个窗完全重合时,没有验证出来 Adesk::Boolean TWallData::Validate(TDPtrList &lstOpenings) const { //暂时不验证 SortOpening(lstOpenings); //只验证单线 { TGGeCurveSegment curve1; TADSGePoint3d ptOnWall; ProjectToMe(lstOpenings[0]->m_ptLocation, ptOnWall); if (GetSubSegment(ptOnWall, GetChordLength(lstOpenings[0]->m_nWidth), curve1) != RTNORM) { return Adesk::kFalse; } for (int i = 1; i < lstOpenings.Length(); i++) { TGGeCurveSegment curve2; ProjectToMe(lstOpenings[i]->m_ptLocation, ptOnWall); if (GetSubSegment(ptOnWall, GetChordLength(lstOpenings[i]->m_nWidth), curve2) != RTNORM) { return 0; } TADSGePoint3d ptMid1 = curve1.MidPoint(); TADSGePoint3d ptMid2 = curve2.MidPoint(); if ((curve1.GetStartPoint() & curve2) == PR_INSIDE || (curve1.GetEndPoint() & curve2) == PR_INSIDE || (curve2.GetStartPoint() & curve1) == PR_INSIDE || (curve2.GetEndPoint() & curve1) == PR_INSIDE || (ptMid1 & curve2) == PR_INSIDE || (ptMid2 & curve1) == PR_INSIDE) { return Adesk::kFalse; } curve1 = curve2; } } //验证双线 { // 构造两条XPoly2D, 从0开始排曲线段, 奇数为洞, 偶数为墙, 长度为0的段不绘 TGGeCurveSegment cvLeft, cvRight; GetSideCurve(cvLeft, cvRight); cvLeft.SetLineFlag(LS_FINITE); cvRight.SetLineFlag(LS_FINITE); for (int nSide = 0; nSide < 2; nSide++) { TGGeCurveSegment &curveSeg = nSide ? cvRight : cvLeft; for (int i = 0; i < lstOpenings.Length(); i++) { TOpeningData &opening = *lstOpenings[i]; TADSGePoint3d ptOpenLoc= opening.m_ptLocation; ptOpenLoc.z = GetStartPoint().z; //确保门窗z值与墙相同 // Update New: 增加对弧窗的判断, bug exists if (opening.GetKind() == TOpeningData::OP_ARCWIN) { if (!Is(CURVE_ARC)) { return Adesk::kFalse; } TGGeArc ar = GetArc(); TADSGePoint3d ptTmp = ar.GetCenterPt(); ptTmp.z = GetElevation(); ar.SetCenterPt(ptTmp); //弧窗的左右线不同于弦窗 double nRad = ads_distance(ar.GetCenterPt(), ptOpenLoc); double nSweepAng = opening.GetWidth() / nRad; double nStartAng = AngleRangeTo2PI(ads_angle(ar.GetCenterPt(), ptOpenLoc) - nSweepAng / 2.0), nEndAng = AngleRangeTo2PI(ads_angle(ar.GetCenterPt(), ptOpenLoc) + nSweepAng / 2.0); TGGeArc arMid(ar.GetCenterPt(), nRad, nStartAng, nEndAng); //使用 nRad 作为半径 lfy 2009-11-08 double nOff = GetWidth() / 2.0; TGGeArc arSide = arMid.Offset(nSide ? nOff : -nOff); TADSGePoint3d ptStart1, ptEnd1; arSide.GetStartPoint(ptStart1); arSide.GetEndPoint(ptEnd1); int nFlag1 = ptStart1 & curveSeg; int nFlag2 = ptEnd1 & curveSeg; if ((nFlag1 == PR_INSIDE || nFlag1 == PR_ONPT1 || nFlag1 == PR_ONPT2) && (nFlag2 == PR_INSIDE || nFlag2 == PR_ONPT1 || nFlag1 == PR_ONPT2)) { ; } else { return Adesk::kFalse; } } else { ads_real nOrthoDrt = OrthoDirection(ptOpenLoc); TGGeLine ln; ads_polar(ptOpenLoc, nOrthoDrt, (m_rWidth + m_lWidth) * 2, ln.StartPoint()); ads_polar(ptOpenLoc, nOrthoDrt + PI, (m_rWidth + m_lWidth) * 2, ln.EndPoint()); // 门窗的左右线, 相对于墙的起点和终点方向而言 TGGeLine lnLeft = ln.Offset(-fabs(opening.m_nWidth) / 2.0), lnRight = ln.Offset(fabs(opening.m_nWidth) / 2.0); if (opening.GetKind() == TOpeningData::OP_CORNWIN) //转角窗 { double nPathDistLoc = PathDistance(ptOpenLoc); TADSGePointDir2d ptStart, ptEnd; Polar(nPathDistLoc - opening.GetWidth() / 2.0, ptStart); Polar(nPathDistLoc + opening.GetWidth() / 2.0, ptEnd); if (ptStart.Distance(StartPoint()) < _DIST_SNAP) { lnLeft.SetStartPoint(cvRight.GetStartPoint()); lnLeft.SetEndPoint(cvLeft.GetStartPoint()); } if (ptEnd.Distance(EndPoint()) < _DIST_SNAP) { lnRight.SetStartPoint(cvRight.GetEndPoint()); lnRight.SetEndPoint(cvLeft.GetEndPoint()); } } lnLeft.SetLineFlag(LS_FINITE); lnRight.SetLineFlag(LS_FINITE); TADSGePoint3d ptInterLeft, ptInterRight; int nNumLeft = curveSeg.Intersection(lnLeft, ptInterLeft, TADSGePoint3d()), nNumRight = curveSeg.Intersection(lnRight, ptInterRight, TADSGePoint3d()); if (nNumLeft != 1 || nNumRight != 1) { return Adesk::kFalse; } } } } } return Adesk::kTrue; } //找相邻的墙段,bBaseOnPrior--是启用优先级 AcDbObjectId TWallData::GetLeftStart(BOOL bBaseOnPrior) const { if (!bBaseOnPrior) { return m_idLeftStart; } AcDbObjectId idRet; if (!m_idLeftStart) { return idRet; } OPENOBJ_BEGIN(m_idLeftStart, AcDb::kForRead, TDbWall, pWall); if (pWall) { if (pWall->GetPriority() == GetPriority()) { return m_idLeftStart; } else if (pWall->GetPriority() > GetPriority()) // 连接墙优先级高 { // 如果与右端连接墙优先级相同且方向相同则自己优先级高,否则,连接墙优先级高 if (!!m_idRightStart) { AcDbObjectId idNext = GetStartPoint().Distance(pWall->StartPoint()) < GetStartPoint().Distance(pWall->EndPoint()) ? pWall->GetLeftStart(FALSE) : pWall->GetRightEnd(FALSE); if (idNext == m_idRightStart) // T型连接 { OPENOBJ_BEGIN(m_idRightStart, AcDb::kForRead, TDbWall, pRightStart); if (pRightStart && pRightStart->GetPriority() == GetPriority()) { int nSide = GetStartPoint().Distance(pRightStart->StartPoint()) < GetStartPoint().Distance(pRightStart->EndPoint()) ? 0 : 1; double nDir = pRightStart->IDirection(nSide); if (fabs(AngleRangeTo2PI(nDir - IDirection(0)) - PI) < _angSnap) { return m_idRightStart; } } OPENOBJ_END(); } } return m_idLeftStart; } else //自己优先级高 { // 如果左右两端连接墙同向且优先级相同,返回左端连接墙ID if (!!m_idRightStart) { AcDbObjectId idNext = GetStartPoint().Distance(pWall->StartPoint()) < GetStartPoint().Distance(pWall->EndPoint()) ? pWall->GetLeftStart(FALSE) : pWall->GetRightEnd(FALSE); if (idNext == m_idRightStart) // T形连接 { OPENOBJ_BEGIN(m_idRightStart, AcDb::kForRead, TDbWall, pRightStart); if (pRightStart && pRightStart->GetPriority() == pWall->GetPriority()) { int nSide1 = GetStartPoint().Distance(pRightStart->StartPoint()) < GetStartPoint().Distance(pRightStart->EndPoint()) ? 0 : 1; int nSide2 = GetStartPoint().Distance(pWall->StartPoint()) < GetStartPoint().Distance(pWall->EndPoint()) ? 0 : 1; if (fabs(AngleRangeTo2PI(pRightStart->IDirection(nSide1) - pWall->IDirection(nSide2)) - PI) < _angSnap) { return m_idLeftStart; } } OPENOBJ_END(); } } } if (GetStartPoint().Distance(pWall->StartPoint()) < GetStartPoint().Distance(pWall->EndPoint())) { idRet = pWall->GetLeftStart(bBaseOnPrior); } else { idRet = pWall->GetRightEnd(bBaseOnPrior); } } OPENOBJ_END(); if (idRet == GetMyObjectId()) { idRet = AcDbObjectId::kNull; } return idRet; } AcDbObjectId TWallData::GetRightStart(BOOL bBaseOnPrior) const { if (!bBaseOnPrior) { return m_idRightStart; } AcDbObjectId idRet; if (!m_idRightStart) { return idRet; } OPENOBJ_BEGIN(m_idRightStart, AcDb::kForRead, TDbWall, pWall); if (pWall) { if (pWall->GetPriority() == GetPriority()) { return m_idRightStart; } else if (pWall->GetPriority() > GetPriority()) //连接墙优先级高 { // 如果与左端连接墙优先级相同且方向相同则自己优先级高,否则,连接墙优先级高 if (!!m_idLeftStart) { AcDbObjectId idNext = GetStartPoint().Distance(pWall->StartPoint()) < GetStartPoint().Distance(pWall->EndPoint()) ? pWall->GetRightStart(FALSE) : pWall->GetLeftEnd(FALSE); if (idNext == m_idLeftStart) //T形连接 { OPENOBJ_BEGIN(m_idLeftStart, AcDb::kForRead, TDbWall, pLeftStart); if (pLeftStart && pLeftStart->GetPriority() == GetPriority()) { int nSide = GetStartPoint().Distance(pLeftStart->StartPoint()) < GetStartPoint().Distance(pLeftStart->EndPoint()) ? 0 : 1; double nDir = pLeftStart->IDirection(nSide); if (fabs(AngleRangeTo2PI(nDir - IDirection(0)) - PI) < _angSnap) { return m_idLeftStart; } } OPENOBJ_END(); } } return m_idRightStart; } else //自己优先级高 { // 如果左右两端连接墙同向且优先级相同,返回右端连接墙ID if (!!m_idLeftStart) { AcDbObjectId idNext = GetStartPoint().Distance(pWall->StartPoint()) < GetStartPoint().Distance(pWall->EndPoint()) ? pWall->GetRightStart(FALSE) : pWall->GetLeftEnd(FALSE); if (idNext == m_idLeftStart) // T形连接 { OPENOBJ_BEGIN(m_idLeftStart, AcDb::kForRead, TDbWall, pLeftStart); if (pLeftStart && pLeftStart->GetPriority() == pWall->GetPriority()) { int nSide1 = GetStartPoint().Distance(pLeftStart->StartPoint()) < GetStartPoint().Distance(pLeftStart->EndPoint()) ? 0 : 1; int nSide2 = GetStartPoint().Distance(pWall->StartPoint()) EndPoint()) ? 0 : 1; if (fabs(AngleRangeTo2PI(pLeftStart->IDirection(nSide1) - pWall->IDirection(nSide2)) - PI) < _angSnap) { return m_idRightStart; } } OPENOBJ_END(); } } } if (GetStartPoint().Distance(pWall->StartPoint()) < GetStartPoint().Distance(pWall->EndPoint())) { idRet = pWall->GetRightStart(bBaseOnPrior); } else { idRet = pWall->GetLeftEnd(bBaseOnPrior); } } OPENOBJ_END(); if (idRet == GetMyObjectId()) { idRet = AcDbObjectId::kNull; } return idRet; } AcDbObjectId TWallData::GetLeftEnd(BOOL bBaseOnPrior) const { if (!bBaseOnPrior) { return m_idLeftEnd; } AcDbObjectId idRet; if (!m_idLeftEnd) { return idRet; } OPENOBJ_BEGIN(m_idLeftEnd, AcDb::kForRead, TDbWall, pWall); if (pWall) { if (pWall->GetPriority() == GetPriority()) { return m_idLeftEnd; } else if (pWall->GetPriority() > GetPriority()) //连接墙优先级高 { // 如果与右端连接墙优先级相同且方向相同则自己优先级高,否则,连接墙优先级高 if (!!m_idRightEnd) { AcDbObjectId idNext = GetEndPoint().Distance(pWall->StartPoint()) < GetEndPoint().Distance(pWall->EndPoint()) ? pWall->GetRightStart(FALSE) : pWall->GetLeftEnd(FALSE); if (idNext == m_idRightEnd) // T形连接 { OPENOBJ_BEGIN(m_idRightEnd, AcDb::kForRead, TDbWall, pRightEnd); if (pRightEnd && pRightEnd->GetPriority() == GetPriority()) { int nSide = GetEndPoint().Distance(pRightEnd->StartPoint()) < GetEndPoint().Distance(pRightEnd->EndPoint()) ? 0 : 1; double nDir = pRightEnd->IDirection(nSide); if (fabs(AngleRangeTo2PI(nDir - IDirection(1)) - PI) < _angSnap) { return m_idRightEnd; } } OPENOBJ_END(); } } return m_idLeftEnd; } else //自己优先级高 { // 如果左右两端连接墙方向和优先级都相同,返回左端连接墙ID if (!!m_idRightEnd) { AcDbObjectId idNext = GetEndPoint().Distance(pWall->StartPoint()) < GetEndPoint().Distance(pWall->EndPoint()) ? pWall->GetRightStart(FALSE) : pWall->GetLeftEnd(FALSE); if (idNext == m_idRightEnd) // T形连接 { OPENOBJ_BEGIN(m_idRightEnd, AcDb::kForRead, TDbWall, pRightEnd); if (pRightEnd && pRightEnd->GetPriority() == pWall->GetPriority()) { int nSide1 = GetEndPoint().Distance(pRightEnd->StartPoint()) < GetEndPoint().Distance(pRightEnd->EndPoint()) ? 0 : 1; int nSide2 = GetEndPoint().Distance(pWall->StartPoint()) < GetEndPoint().Distance(pWall->EndPoint()) ? 0 : 1; if (fabs(AngleRangeTo2PI(pRightEnd->IDirection(nSide1) - pWall->IDirection(nSide2)) - PI) < _angSnap) { return m_idLeftEnd; } } OPENOBJ_END(); } } } if (GetEndPoint().Distance(pWall->StartPoint()) < GetEndPoint().Distance(pWall->EndPoint())) { idRet = pWall->GetRightStart(bBaseOnPrior); } else { idRet = pWall->GetLeftEnd(bBaseOnPrior); } } OPENOBJ_END(); if (idRet == GetMyObjectId()) { idRet = AcDbObjectId::kNull; } return idRet; } AcDbObjectId TWallData::GetRightEnd(BOOL bBaseOnPrior) const { if (!bBaseOnPrior) { return m_idRightEnd; } AcDbObjectId idRet; if (!m_idRightEnd) { return idRet; } OPENOBJ_BEGIN(m_idRightEnd, AcDb::kForRead, TDbWall, pWall); if (pWall) { if (pWall->GetPriority() == GetPriority()) { return m_idRightEnd; } else if (pWall->GetPriority() > GetPriority()) //连接墙优先级高 { // 如果左端连接墙的优先级和方向与自己都相同,则自己优先级高,否则,连接墙优先级高 if (!!m_idLeftEnd) { AcDbObjectId idNext = GetEndPoint().Distance(pWall->StartPoint()) < GetEndPoint().Distance(pWall->EndPoint()) ? pWall->GetLeftStart(FALSE) : pWall->GetRightEnd(FALSE); if (idNext == m_idLeftEnd) //T形连接 { OPENOBJ_BEGIN(m_idLeftEnd, AcDb::kForRead, TDbWall, pLeftEnd); if (pLeftEnd && pLeftEnd->GetPriority() == GetPriority()) { int nSide = GetEndPoint().Distance(pLeftEnd->StartPoint()) < GetEndPoint().Distance(pLeftEnd->EndPoint()) ? 0 : 1; double nDir = pLeftEnd->IDirection(nSide); if (fabs(AngleRangeTo2PI(nDir - IDirection(1)) - PI) < _angSnap) { return m_idLeftEnd; } } OPENOBJ_END(); } } return m_idRightEnd; } else // 自己优先级高 { //如果两端连接墙方向和优先级都相同,返回右端连接墙ID if (!!m_idLeftEnd) { AcDbObjectId idNext = GetEndPoint().Distance(pWall->StartPoint()) < GetEndPoint().Distance(pWall->EndPoint()) ? pWall->GetLeftStart(FALSE) : pWall->GetRightEnd(FALSE); if (idNext == m_idLeftEnd) // T形连接 { OPENOBJ_BEGIN(m_idLeftEnd, AcDb::kForRead, TDbWall, pLeftEnd); if (pLeftEnd && pLeftEnd->GetPriority() == pWall->GetPriority()) { int nSide1 = GetEndPoint().Distance(pLeftEnd->StartPoint()) < GetEndPoint().Distance(pLeftEnd->EndPoint()) ? 0 : 1; int nSide2 = GetEndPoint().Distance(pWall->StartPoint()) < GetEndPoint().Distance(pWall->EndPoint()) ? 0 : 1; if (fabs(AngleRangeTo2PI(pLeftEnd->IDirection(nSide1) - pWall->IDirection(nSide2)) - PI) < _angSnap) { return m_idRightEnd; } } OPENOBJ_END(); } } } if (GetEndPoint().Distance(pWall->StartPoint()) < GetEndPoint().Distance(pWall->EndPoint())) { idRet = pWall->GetLeftStart(bBaseOnPrior); } else { idRet = pWall->GetRightEnd(bBaseOnPrior); } } OPENOBJ_END(); if (idRet == GetMyObjectId()) { idRet = AcDbObjectId::kNull; } return idRet; } // 往侧边投影, 如果src在中心,则投影点在中心 // 返回: 0--左侧,1--右侧,-1有错,否则在中心 int TWallData::ProjectSide(const TADSGePoint3d &src, TADSGePoint3d &res) const { TGGeCurveSegment segCenter = OffsetGeomCenter(); int flg = segCenter.OnWhichSide(src); if (flg != 1 && flg != 0) { res = src; res.z = GetStartPoint().z; return flg; } TGGeCurveSegment curve = GetRelativeSideCurve(flg, StartPoint()); if (curve.ProjectToMe(src, res) != RTNORM) { return -1; } return flg; } // 返回一AcDbCurve的指针 // nFlag: 0--基线; 1--几何中线; 2--左边线; 3--右边线 AcDbCurve * TWallData::GetAcDbCurve(int nFlag) const { TGGeCurveSegment seg, s; switch(nFlag) { case 0: seg = *this; break; case 1: seg = OffsetGeomCenter(); break; case 2: { GetSideCurve(seg, s); break; } case 3: { GetSideCurve(s, seg); break; } default: ASSERT(0); } return seg.AsAcDbCurve(); } // 用AcDbCurve的参数来更新墙体的几何 Acad::ErrorStatus TWallData::SetFromCurve(const AcDbCurve &curve) { AcDbLine *pLine = AcDbLine::cast(&curve); AcDbArc *pArc = AcDbArc::cast(&curve); if (pLine) { *(TGGeLine *)this = TGGeLine(TADSGePoint3d(pLine->startPoint()), TADSGePoint3d(pLine->endPoint())); } else if (pArc) { TGGeArc ar(TADSGePoint3d(pArc->center()), pArc->radius(), pArc->startAngle(), pArc->endAngle()); *(TGGeCurveSegment *)this = ar; } else { return Acad::eInvalidInput; } return Acad::eOk; } // 几何形心上的曲线, 端点位置不能作为准确的依据 TGGeCurveSegment TWallData::OffsetGeomCenter(int cvFlag, BOOL bIncludeInsulateLayer) const { double lWidth = m_lWidth, rWidth = m_rWidth; if (bIncludeInsulateLayer) { double nInsulateThickL = GetInsulateThick(); double nInsulateThickR = GetInsulateThick(1); if (m_nWallFlag & WF_LEFT_INSULATE) { lWidth += nInsulateThickL; } if (m_nWallFlag & WF_RIGHT_INSULATE) { rWidth += nInsulateThickR; } } double nGeomCenterLeftOffset = (lWidth - rWidth) / 2.0; TGGeCurveSegment cv = TGGeCurveSegment::Offset(OFFSET_LEFT, nGeomCenterLeftOffset, cvFlag); return cv; } // 以ptRef为参考点定义左右方向,返回指定对中心偏移率的原始曲线 TGGeCurveSegment TWallData::GetRelativeOffsetCurveFromCenter(int nSide, double nRatio, const TADSGePoint3d &ptRef) const { TGGeCurveSegment segCenter = OffsetGeomCenter(LS_INFINITE); double nDist = nRatio * GetWidth(); const void *pNear = (const void *)(((TGGeLine *)this)->NearPoint(ptRef)); if (pNear == &StartPoint()) //与绝对方向相同 { return segCenter.Offset(nSide, nDist, LS_INFINITE); } //与绝对方向相反 return segCenter.Offset(nSide == OFFSET_LEFT ? OFFSET_RIGHT : OFFSET_LEFT, nDist, LS_INFINITE); } // 以ptRef为参考点定义左右方向,返回指定的原始侧边线 // nSide--相对与ptFef的左右侧, nDistToSide--距侧边的距离(负往内,正往外) TGGeCurveSegment TWallData::GetRelativeSideCurve(int nSide, const TADSGePoint3d &ptRef, double nDistToSide, BOOL bFromInsulate) const { int nCurveFlag = LS_INFINITE; const void *pNear = (const void *)(((TGGeLine *)this)->NearPoint(ptRef)); int nAbsSide = (pNear == &StartPoint()) ? nSide : (1 - nSide); ads_real dist = GetWidth(nAbsSide + bFromInsulate * 2); dist += nDistToSide; return TGGeCurveSegment::Offset(nAbsSide, dist, nCurveFlag); } // 考虑保温线标准的两侧边线(即不考虑墙角是否有柱子) // nSide--绝对的方向, nDistToside--距离边线 // 修改: 2002/3/26 有柱子时不与邻墙求交 // pPareStart, pPareEnd 是否平行的标志 TGGeCurveSegment TWallData::GetStandardSideCurve1(int nSide, double nDistToSide, BOOL *pPareStart, BOOL *pPareEnd) const { BOOL bFromInsulate = TRUE; //wlw add 20100913 取消考虑柱子影响 return GetStandardSideCurve(nSide, nDistToSide, bFromInsulate, pPareStart, pPareEnd); TGGeCurveSegment cvInitCurve = GetRelativeSideCurve(nSide, StartPoint(), nDistToSide, bFromInsulate); TADSGePoint3d ptInitStart = cvInitCurve.GetStartPoint(), ptInitEnd = cvInitCurve.GetEndPoint(); AcDbObjectId idStart = nSide == OFFSET_LEFT ? m_idLeftStart : m_idRightStart; AcDbObjectId idEnd = nSide == OFFSET_LEFT ? m_idLeftEnd : m_idRightEnd; double nElev = GetElevation(); int nOppsiteSide = nSide == OFFSET_LEFT ? OFFSET_RIGHT : OFFSET_LEFT; if (pPareStart) { *pPareStart = FALSE; } if (pPareEnd) { *pPareEnd = FALSE; } // 求左边起始角点 if (!!idStart) { OPENOBJ_BEGIN(idStart, AcDb::kForRead, TDbWall, pStart); if (pStart) { TGGeCurveSegment cvStart = pStart->GetRelativeSideCurve(nOppsiteSide, StartPoint(), nDistToSide, bFromInsulate); cvStart.SetElevation(nElev); BOOL bParell = FALSE; if (cvStart.Is(CURVE_LINE) && cvInitCurve.Is(CURVE_LINE)) { //modify by xlc on 091113 解决墙体显示不正常问题 double dPrec = sin(PI / 36); TPushMemVar temp(_angSnap, dPrec);//临时改变角度精度,小于5度时当作平行处理 if (IsSameDrt(cvStart.TGGeLine::Direction(), cvInitCurve.TGGeLine::Direction(), _angSnap)) { bParell = TRUE; } } if (pPareStart) { *pPareStart = bParell; } if (!bParell) { TADSGePoint3d ptInters[2]; int nIntNum = cvInitCurve.Intersection(cvStart, ptInters[0], ptInters[1]); if (nIntNum == 1) { ptInitStart = ptInters[0]; } else if (nIntNum == 2) { double nDist1 = cvInitCurve.GetStartPoint().Distance2d(ptInters[0]); double nDist2 = cvInitCurve.GetStartPoint().Distance2d(ptInters[1]); if (fabs(nDist1 - nDist2) < _DIST_SNAP) { nDist1 = cvInitCurve.PathDistance(ptInters[0], FALSE); nDist2 = cvInitCurve.PathDistance(ptInters[1], FALSE); ptInitStart = (fabs(nDist1)GetRelativeSideCurve(0, StartPoint(), nDistToSide, bFromInsulate); TGGeCurveSegment cv2 = pStart->GetRelativeSideCurve(1, StartPoint(), nDistToSide, bFromInsulate); TGGeCurveSegment cvThis = cvInitCurve; cv1.SetLineFlag(LS_INFINITE); cv2.SetLineFlag(LS_INFINITE); cvThis.SetLineFlag(LS_INFINITE); TADSGePoint3d ptInt1[2], ptInt2[2], pt1, pt2; int num1 = 0, num2 = 0; BOOL bPar1 = FALSE, bPar2 = FALSE; if (cv1.Is(CURVE_LINE) && cvThis.Is(CURVE_LINE)) { //modify by xlc on 091113 解决墙体显示不正常问题 double dPrec = sin(PI / 36); TPushMemVar temp(_angSnap, dPrec);//临时改变角度精度,小于5度时当作平行处理 if (IsSameDrt(cv1.TGGeLine::Direction(), cvThis.TGGeLine::Direction(), _angSnap)) { bPar1 = TRUE; } } if (cv2.Is(CURVE_LINE) && cvThis.Is(CURVE_LINE)) { //modify by xlc on 091113 解决墙体显示不正常问题 double dPrec = sin(PI / 36); TPushMemVar temp(_angSnap, dPrec);//临时改变角度精度,小于5度时当作平行处理 if (IsSameDrt(cv2.TGGeLine::Direction(), cvThis.TGGeLine::Direction(), _angSnap)) { bPar2 = TRUE; } } if (!bPar1) { num1 = cv1.Intersection(cvThis, ptInt1[0], ptInt1[1]); } if (!bPar2) { num2 = cv2.Intersection(cvThis, ptInt2[0], ptInt2[1]); } if (num1 && num2) { if (num1 == 1) { pt1 = ptInt1[0]; } else { pt1 = TGGeLine(ptInt1[0], ptInt1[1]).NearPoint(ptInitStart); } if (num2 == 1) { pt2 = ptInt2[0]; } else { pt2 = TGGeLine(ptInt2[0], ptInt2[1]).NearPoint(ptInitStart); } double nDist1 = cvThis.PathDistance(pt1); double nDist2 = cvThis.PathDistance(pt2); double nDist = min(nDist1, nDist2); if (nDist < 0.0) { TADSGePointDir2d ptTemp; cvThis.Polar(nDist, ptTemp); ptInitStart = ptTemp; } } } OPENOBJ_END(); } // 左边终止角点 if (!!idEnd) { OPENOBJ_BEGIN(idEnd, AcDb::kForRead, TDbWall, pEnd); if (pEnd) { TGGeCurveSegment cvEnd = pEnd->GetRelativeSideCurve(nSide, EndPoint(), nDistToSide, bFromInsulate); cvEnd.SetElevation(nElev); BOOL bParell = FALSE; if (cvEnd.Is(CURVE_LINE) && cvInitCurve.Is(CURVE_LINE)) { //modify by xlc on 091113 解决墙体显示不正常问题 double dPrec = sin(PI / 36); TPushMemVar temp(_angSnap, dPrec);//临时改变角度精度,小于5度时当作平行处理 if (IsSameDrt(cvEnd.TGGeLine::Direction(), cvInitCurve.TGGeLine::Direction(), _angSnap)) { bParell = TRUE; } } if (pPareEnd) { *pPareEnd = bParell; } if (!bParell) { TADSGePoint3d ptInters[2]; int nIntNum = cvInitCurve.Intersection(cvEnd, ptInters[0], ptInters[1]); if (nIntNum == 1) { ptInitEnd = ptInters[0]; } else if (nIntNum == 2) { ptInitEnd = TGGeLine(ptInters[0], ptInters[1]).NearPoint(cvInitCurve.GetEndPoint()); double nDist1 = cvInitCurve.GetEndPoint().Distance2d(ptInters[0]); double nDist2 = cvInitCurve.GetEndPoint().Distance2d(ptInters[1]); if (fabs(nDist1 - nDist2) < _DIST_SNAP) { nDist1 = cvInitCurve.PathDistance(ptInters[0], TRUE); nDist2 = cvInitCurve.PathDistance(ptInters[1], TRUE); ptInitEnd = (fabs(nDist1) < fabs(nDist2) ? ptInters[0] : ptInters[1]); } else if (nDist1 < nDist2) { ptInitEnd = ptInters[0]; } else { ptInitEnd = ptInters[1]; } } } } OPENOBJ_END(); } else if (m_idLeftEnd == m_idRightEnd && !!m_idLeftEnd) //终点是转角, 并且当前优先 { OPENOBJ_BEGIN(m_idLeftEnd, AcDb::kForRead, TDbWall, pEnd); if (pEnd) { TGGeCurveSegment cv1 = pEnd->GetRelativeSideCurve(0, EndPoint(), nDistToSide, bFromInsulate); TGGeCurveSegment cv2 = pEnd->GetRelativeSideCurve(1, EndPoint(), nDistToSide, bFromInsulate); TGGeCurveSegment cvThis = cvInitCurve; cv1.SetLineFlag(LS_INFINITE); cv2.SetLineFlag(LS_INFINITE); cvThis.SetLineFlag(LS_INFINITE); TADSGePoint3d ptInt1[2], ptInt2[2], pt1, pt2; int num1 = 0, num2 = 0; BOOL bPar1 = FALSE, bPar2 = FALSE; if (cv1.Is(CURVE_LINE) && cvThis.Is(CURVE_LINE)) { //modify by xlc on 091113 解决墙体显示不正常问题 double dPrec = sin(PI / 36); TPushMemVar temp(_angSnap, dPrec);//临时改变角度精度,小于5度时当作平行处理 if (IsSameDrt(cv1.TGGeLine::Direction(), cvThis.TGGeLine::Direction(), _angSnap)) { bPar1 = TRUE; } } if (cv2.Is(CURVE_LINE) && cvThis.Is(CURVE_LINE)) { //modify by xlc on 091113 解决墙体显示不正常问题 double dPrec = sin(PI / 36); TPushMemVar temp(_angSnap, dPrec);//临时改变角度精度,小于5度时当作平行处理 if (IsSameDrt(cv2.TGGeLine::Direction(), cvThis.TGGeLine::Direction(), _angSnap)) { bPar2 = TRUE; } } if (!bPar1) { num1 = cv1.Intersection(cvThis, ptInt1[0], ptInt1[1]); } if (!bPar2) { num2 = cv2.Intersection(cvThis, ptInt2[0], ptInt2[1]); } if (num1 && num2) { if (num1 == 1) { pt1 = ptInt1[0]; } else { pt1 = TGGeLine(ptInt1[0], ptInt1[1]).NearPoint(ptInitEnd); } if (num2 == 1) { pt2 = ptInt2[0]; } else { pt2 = TGGeLine(ptInt2[0], ptInt2[1]).NearPoint(ptInitEnd); } double nDist1 = cvThis.PathDistance(pt1, FALSE); double nDist2 = cvThis.PathDistance(pt2, FALSE); double nDist = min(nDist1, nDist2); if (nDist < 0.0) { TADSGePointDir2d ptTemp; cvThis.Polar(nDist, ptTemp, FALSE); ptInitEnd = ptTemp; } } } OPENOBJ_END(); } // Modified on 2002/6/17, 对优弧和劣弧进行判断, 在几乎要变成圆墙的时候可能有错误 if (cvInitCurve.Is(CURVE_ARC)) { TPushPrec vTemp(1.0E-6, 1.0E-9); TGGeArc ar = cvInitCurve.GetArc(); //假如ptInitStart离End更近而且在弧外,那么就需要取消其有效性 if (ptInitStart.Distance2d(cvInitCurve.EndPoint()) < ptInitStart.Distance2d(cvInitCurve.StartPoint()) && ar.AngleFlag(ads_angle(ar.GetCenterPt(), ptInitStart)) == PR_OUTSIDE) { ptInitStart = cvInitCurve.GetStartPoint(); } //假如ptInitEnd离Start更近而且在弧外,那么就需要取消其有效性 if (ptInitEnd.Distance2d(cvInitCurve.StartPoint()) < ptInitEnd.Distance2d(cvInitCurve.EndPoint()) && ar.AngleFlag(ads_angle(ar.GetCenterPt(), ptInitEnd)) == PR_OUTSIDE) { ptInitEnd = cvInitCurve.GetEndPoint(); } } //add by xlc on 091106 校正墙线 AdjustStandardSideCurve(ptInitStart,ptInitEnd); cvInitCurve.SetPoints(ptInitStart, ptInitEnd); return cvInitCurve; } //add by xlc on 091106 校正墙线,解决复制隔墙出现连线的情况(避免出线下边的墙线) // --------- // | // ----------- void TWallData::AdjustStandardSideCurve(TADSGePoint3d &ptInitStart,TADSGePoint3d &ptInitEnd)const { AcGeLineSeg3d lineSegCv;//墙边线段 lineSegCv.set((AcGePoint3d)ptInitStart, (AcGePoint3d)ptInitEnd); AcGePoint3d ptMid = lineSegCv.midPoint(); AcGeLine3d lineCv;//墙边线 lineCv.set((AcGePoint3d)ptInitStart,(AcGePoint3d)ptInitEnd); AcGePoint3d ptOnS = lineCv.closestPointTo((AcGePoint3d)GetStartPoint()), ptOnE = lineCv.closestPointTo((AcGePoint3d)GetEndPoint()); TGGeLine line((TADSGePoint3d)ptOnS,(TADSGePoint3d)ptOnE); line.SetElevation(0); int nRetS = line.HitTest2d(ptInitStart), nRetE = line.HitTest2d(ptInitEnd); // modify by xlc on 100830 允许落在近距离的延长线上(解决基线在外侧插入角柱会多线的问题) //if (nRetS < 3|| nRetS > 6) //start 端奇异(墙线起点不在投影线上或起始侧的延长线上) if (nRetS < 3) //start 端奇异(墙线起点不在投影线上) { ptInitStart = ptOnS; } //校正墙线时有时墙线距离起始点很远 //add by xlc on 091116 // modify by xlc on 100830 允许落在近距离的延长线上(解决基线在外侧插入角柱会多线的问题) //else if (nRetS == 6) else if (nRetS >= 6) { if (ptInitStart.Distance2d(ptOnS) > line.GetLength() * 10) { ptInitStart = ptOnS; } } // modify by xlc on 100830 允许落在近距离的延长线上(解决基线在外侧插入角柱会多线的问题) //if (nRetE < 3|| nRetE == 6) //end 端奇异(墙线终点不在投影线上或终点侧的延长线上) if (nRetE < 3) //end 端奇异(墙线终点不在投影线上) { ptInitEnd = ptOnE; } //校正墙线时有时墙线距离起始点很远 //add by xlc on 091116 // modify by xlc on 100830 允许落在近距离的延长线上(解决基线在外侧插入角柱会多线的问题) //else if (nRetE == 7) else if (nRetE >= 6) { if (ptInitEnd.Distance2d(ptOnE) > line.GetLength() * 10) { ptInitEnd = ptOnE; } } } // 2002/4/5修改,解决不同材质的墙相交的问题 // 2002/7/2修改,解决墙局部外包柱子的问题 TGGeCurveSegment TWallData::GetStandardSideCurve(int nSide, double nDistToSide, BOOL bFromInsulate, BOOL *pPareStart, BOOL *pPareEnd) const { //add by W on 070928 //判断是否连接数据异常,可以解决块内墙影响填充问题 TDPtrList lstId0,lstId1; GetIdStyles(0, lstId0); GetIdStyles(1,lstId1); lstId0 << lstId1; if (lstId0.Length() > 0) { IdDotStyle *pIdStyle = lstId0.Head(); OPENOBJ_BEGIN(pIdStyle->id, AcDb::kForRead, TDbWall, pWall); if (pWall) { if (pWall->ownerId() != GetMyOwnerId()) { return GetRelativeSideCurve(nSide, StartPoint(), nDistToSide, bFromInsulate); } } OPENOBJ_END(); } if (bFromInsulate) { //wlw mod 100913 连接处不考虑柱子 //return GetStandardSideCurve1(nSide, nDistToSide, pPareStart, pPareEnd); } // 先求自己的偏移线 TGGeCurveSegment cvInitCurve = GetRelativeSideCurve(nSide, StartPoint(), nDistToSide, bFromInsulate); //add by xlc on 110121 解决直墙和弧墙连接问题(幕墙显示异常) TGGeCurveSegment cvInitCurveOther = GetRelativeSideCurve(nSide? OFFSET_LEFT : OFFSET_RIGHT, StartPoint(), nDistToSide, bFromInsulate); cvInitCurveOther.SetLineFlag(LS_INFINITE); bool bFlag = false; //是否特殊处理 TADSGePoint3d ptInitStart = cvInitCurve.GetStartPoint(), ptInitEnd = cvInitCurve.GetEndPoint(); double nElev = GetElevation(); if (pPareStart) { *pPareStart = FALSE; } if (pPareEnd) { *pPareEnd = FALSE; } int nOppsiteSide = nSide == OFFSET_LEFT ? OFFSET_RIGHT : OFFSET_LEFT; { //对起始侧 TDPtrList lstIdStyles; GetIdStyles(0, lstIdStyles); int nCount = lstIdStyles.Length(); BOOL bParell = FALSE, bSameStyle = FALSE; BOOL bContinue = FALSE, bAddition = FALSE; TGGeCurveSegment cvStart, cvAddition; TGGeCurveSegment cvStartBase,cvAdditionBase; TGGeCurveSegment cvStartOther; //与cvStart相对的线 if (nCount == 0) //单甩 { } else if (nCount == 1) //转角 { IdDotStyle *pIdStyle = lstIdStyles.Head(); int nCmp = CompareWallStyle(GetPriority(), pIdStyle->GetPriority()); // add by xlc on 110310绘制带形窗计算时直接按墙同优先级计算 if (g_bSkipWallMaterial) { nCmp = 0; } if (nCmp == 0) //常规 { OPENOBJ_BEGIN(pIdStyle->id, AcDb::kForRead, TDbWall, pWall); if (pWall) { //modify by xlc on 110614 解决连接墙转角处存在短门窗套融合时墙线融合错误的问题 //cvStart = pWall->GetRelativeSideCurve(nOppsiteSide, StartPoint(), nDistToSide, bFromInsulate); bool bSameToStart = pWall->StartPoint().Distance2d(StartPoint()) < pWall->EndPoint().Distance2d(StartPoint()); double dSlotThick = 0; //门窗套伸出长度 bool bConnectShortSlot = false; //连接墙是否在墙角处有短门窗套 TDPtrList lstOpenings; //墙上的所有穿透的门窗洞 pWall->GetSortedOpenings(lstOpenings); if (lstOpenings.Length()>0) { TOpeningData *pWin = NULL; if (bSameToStart) { pWin = lstOpenings[0]; } else { pWin = lstOpenings[lstOpenings.Length()-1]; } if (pWin->HasSlot()) { TADSGePoint3d ptLoc = pWin->GetLocation(),ptProj; ptLoc.Project(&cvInitCurve,ptProj); bool bRightExt = (pWall->GetWallFlag() & WF_LEFTEXT) == 0; // 左墙线时连接墙起点,门窗套在右侧或连接墙终点门窗套在左侧 // 右墙线时连接墙起点,门窗套在左侧或连接墙终点门窗套在右侧 if ((nSide == 0 &&((bRightExt&&bSameToStart) || (!(bRightExt||bSameToStart)))) ||(nSide == 1 &&((!bRightExt&&bSameToStart) || (!(!bRightExt||bSameToStart)))) ) { double dSlotWidth = pWin->GetSlotWidth(); if (ptLoc.Distance2d(ptProj) < dSlotWidth + pWin->GetWidth()*0.5) { bConnectShortSlot = true; dSlotThick = pWin->GetSlotExt(); } } } } if (bConnectShortSlot) { cvStart = pWall->GetRelativeSideCurve(nOppsiteSide, StartPoint(), nDistToSide+dSlotThick, bFromInsulate); } else { cvStart = pWall->GetRelativeSideCurve(nOppsiteSide, StartPoint(), nDistToSide, bFromInsulate); } cvStartBase = *pWall; bContinue = TRUE; bSameStyle = TRUE; } OPENOBJ_END(); } else //优先不一样 { OPENOBJ_BEGIN(pIdStyle->id, AcDb::kForRead, TDbWall, pWall); if (pWall) { //add by xlc on 100806 解决弧墙和直墙端头连接问题 //int nOffSide = pWall->OnWhichSide(EndPoint()); //if (nCmp > 0) //{ // nOffSide = !nOffSide; //} int nOffSide = 0; if ((Is(CURVE_LINE) && pWall->Is(CURVE_LINE))) { nOffSide = pWall->OnWhichSide(EndPoint()); if (nCmp > 0) { nOffSide = !nOffSide; } } else { TADSGePoint3d ptTest = EndPoint(); BOOL bStart = TRUE; //连接墙的端点 if (StartPoint().Distance(pWall->StartPoint()) > StartPoint().Distance(pWall->EndPoint())) { bStart = FALSE; } //存在弧墙时直接以端点判断可能会影响结果 if (Is(CURVE_LINE)) { TADSGePointDir2d ptRes; if ( pWall->Polar(_AS_SYS_UNIT(300), ptRes , bStart) == RTNORM) { ptTest = ptRes; } nOffSide = OnWhichSide(ptTest); } else { TADSGePointDir2d ptRes; if ( Polar(_AS_SYS_UNIT(300), ptRes , TRUE) == RTNORM) { ptTest = ptRes; } nOffSide = pWall->OnWhichSide(ptTest); } //考虑弧墙连接处平行的情况 { double dPrec = sin(PI / 72); TPushMemVar temp(_angSnap, dPrec);//临时改变角度精度,小于2.5度时当作平行处理 double dStart = Direction(StartPoint()); double dConnect = 0; if (bStart) { dConnect = pWall->Direction(pWall->StartPoint()); } else { dConnect = pWall->Direction(pWall->EndPoint()); } if (IsSameDrt(dStart, dConnect, _angSnap)) { bParell = TRUE; } } if (nCmp > 0) { if (!bStart) { nOffSide = !nOffSide; } else { if (pWall->Is(CURVE_LINE) || (!Is(CURVE_LINE) && !pWall->Is(CURVE_LINE))) { nOffSide = !nOffSide; } } } else { if (bStart) { if (Is(CURVE_LINE) && !pWall->Is(CURVE_LINE)) { nOffSide = !nOffSide; } } } } cvStart = pWall->Offset(nOffSide, pWall->GetWidth(nOffSide), LS_INFINITE); //add by xlc on 110121 仅处理直墙和弧墙连接 if ((Is(CURVE_LINE) && !pWall->Is(CURVE_LINE)) ||(!Is(CURVE_LINE) && pWall->Is(CURVE_LINE))) { if (nOffSide == 0) { nOffSide = 1; } else { nOffSide = 0; } cvStartOther = pWall->Offset(nOffSide, pWall->GetWidth(nOffSide), LS_INFINITE); bFlag = true; } cvStartBase = *pWall; bContinue = TRUE; } OPENOBJ_END(); } } else //多分支 { AcDbIntArray intArray; GetStyleKindArray(lstIdStyles, intArray); int nThisStyle = (GetPriority()); if (!intArray.contains(nThisStyle)) { intArray.append(nThisStyle); } int nKindCount = intArray.length(); //wlw 11.06.13 绘制保温时直接按墙同优先级计算 if (g_bSkipWallMaterial) { nKindCount = 1; } if (nKindCount > 2) //超过2种以上的材料 { } else if (nKindCount == 1) //常规情况 { OPENOBJ_BEGIN(nSide == 0 ? lstIdStyles.Head()->id : lstIdStyles.Tail()->id, AcDb::kForRead, TDbWall, pWall); if (pWall) { cvStart = pWall->GetRelativeSideCurve(nOppsiteSide, StartPoint(), nDistToSide, bFromInsulate); cvStartBase = *pWall; bContinue = TRUE; bSameStyle = TRUE; } OPENOBJ_END(); } else //2种材料 { int nThisStyleCount = GetStyleCount(GetPriority(), lstIdStyles); int nOtherStyleCount = lstIdStyles.Length()-nThisStyleCount; nThisStyleCount++; //包括自己 BOOL bAdvance = TRUE; if (nThisStyleCount > nOtherStyleCount) //当前优先 { } else if (nThisStyleCount == nOtherStyleCount) { int stOther = GetAnotherStyle(GetPriority(), lstIdStyles); if (CompareWallStyle(GetPriority(), stOther) < 0) { bAdvance = FALSE; } } else { bAdvance = FALSE; } if (bAdvance) //按正或反方向找id { AcDbObjectId idOther = GetSameStyleId(GetPriority(), lstIdStyles, nSide); OPENOBJ_BEGIN(idOther, AcDb::kForRead, TDbWall, pWall); if (pWall) { cvStart = pWall->GetRelativeSideCurve(nOppsiteSide, StartPoint(), nDistToSide, bFromInsulate); cvStartBase = *pWall; bContinue = TRUE; bSameStyle = TRUE; } OPENOBJ_END(); } else { AcDbObjectId idOther; int stOther; if (nSide == 0) { idOther = lstIdStyles.Head()->id; stOther = lstIdStyles.Head()->GetPriority(); } else { idOther = lstIdStyles.Tail()->id; stOther = lstIdStyles.Tail()->GetPriority(); } OPENOBJ_BEGIN(idOther, AcDb::kForRead, TDbWall, pWall); if (pWall) { bSameStyle = (stOther == GetPriority()); double nDist = bSameStyle ? nDistToSide : 0.0; BOOL bIns = bSameStyle ? bFromInsulate : FALSE; cvStart = pWall->GetRelativeSideCurve(nOppsiteSide, StartPoint(), nDist, bIns); cvStartBase = *pWall; bContinue = TRUE; if (!bSameStyle) //附加裁剪线 { AcDbObjectId idAdd; if (nSide == 0) { idAdd = lstIdStyles.Tail()->id; } else { idAdd = lstIdStyles.Head()->id; } ASSERT(idAdd != idOther); OPENOBJ_BEGIN(idAdd, AcDb::kForRead, TDbWall, pAdd); if (pAdd) { cvAddition = pAdd->GetRelativeSideCurve(nSide, StartPoint(), 0.0, FALSE); cvAdditionBase = *pAdd; bAddition = TRUE; } OPENOBJ_END(); } } OPENOBJ_END(); } } } if (bContinue && !!m_idColuStart) //有柱子的情况有可能基线不交,这时不应连接墙角 { if (GetStartPoint().Distance2d(cvStartBase.StartPoint()) > _AS_SYS_UNIT(g_nDistPrec) && GetStartPoint().Distance2d(cvStartBase.EndPoint()) > _AS_SYS_UNIT(g_nDistPrec)) { //modify by xlc on 120606 确定基线不相交,解决有柱子时基线相交大大于墙精度时墙线错误的问题 TADSGePoint3d ptInters[2]; int nOldThis = cvInitCurve.GetLineFlag(); int nOldThat = cvStart.GetLineFlag(); cvInitCurve.SetLineFlag(LS_FINITE); cvStart.SetLineFlag(LS_FINITE); int nNum = cvInitCurve.Intersection(cvStart, ptInters[0], ptInters[1]); if (nNum == 0) { bContinue = FALSE; } cvInitCurve.SetLineFlag(nOldThis); cvStart.SetLineFlag(nOldThat); } if (bContinue && bAddition) { if (GetStartPoint().Distance2d(cvAdditionBase.StartPoint()) > _AS_SYS_UNIT(g_nDistPrec) && GetStartPoint().Distance2d(cvAdditionBase.EndPoint()) > _AS_SYS_UNIT(g_nDistPrec)) { bAddition = FALSE; } } } // // 基线不相交的不连接墙角 -- wyg20090713 // else if (bContinue) // { // if (GetStartPoint().Distance2d(cvStartBase.StartPoint())>_AS_SYS_UNIT(g_nDistPrec)&& // GetStartPoint().Distance2d(cvStartBase.EndPoint())>_AS_SYS_UNIT(g_nDistPrec)) // bContinue = FALSE; // } if (bContinue) { cvStart.SetLineFlag(LS_INFINITE); cvInitCurve.SetLineFlag(LS_INFINITE); cvStart.SetElevation(nElev); if (cvStart.Is(CURVE_LINE) && cvInitCurve.Is(CURVE_LINE)) { //modify by xlc on 091113 解决墙体显示不正常问题 double dPrec = sin(PI / 36); TPushMemVar temp(_angSnap, dPrec);//临时改变角度精度,小于5度时当作平行处理 if (IsSameDrt(cvStart.TGGeLine::Direction(), cvInitCurve.TGGeLine::Direction(), _angSnap)) { bParell = TRUE; } } if (pPareStart) { *pPareStart = (bParell && bSameStyle); } if (!bParell) { TADSGePoint3d ptInters[2]; int nIntNum = cvInitCurve.Intersection(cvStart, ptInters[0], ptInters[1]); //add by xlc on 110121 特殊处理的直墙和弧墙连接 if (bFlag) { TADSGePoint3d ptInters2[2], ptInters3[2], ptInters4[2]; int nIntNum2=0, nIntNum3=0, nIntNum4=0; //交点个数 nIntNum2 = cvInitCurve.Intersection(cvStartOther, ptInters2[0], ptInters2[1]); nIntNum3 = cvInitCurveOther.Intersection(cvStartOther, ptInters3[0], ptInters3[1]); nIntNum4 = cvInitCurveOther.Intersection(cvStart, ptInters4[0], ptInters4[1]); if ((nIntNum == 0 && nIntNum2 != 0) || (nIntNum != 0 && nIntNum2 == 0) || (nIntNum3 == 0 && nIntNum4 != 0) || (nIntNum3 != 0 && nIntNum4 == 0) || (nIntNum == 0 && nIntNum4 != 0) || (nIntNum != 0 && nIntNum4 == 0) || (nIntNum3 == 0 && nIntNum2 != 0) || (nIntNum3 != 0 && nIntNum2 == 0))//特殊处理的情况 { if (Is(CURVE_LINE)) { nIntNum = 1; ptInters[0] = ptInitStart; } else { if (ptInitStart.Distance2d(cvStart.StartPoint()) < ptInitStart.Distance2d(cvStart.EndPoint())) { cvStart.SetEndPoint(cvStartOther.StartPoint()); } else { cvStart.SetStartPoint(cvStartOther.EndPoint()); } nIntNum = cvInitCurve.Intersection(cvStart, ptInters[0], ptInters[1]); } } } if (nIntNum == 1) { ptInitStart = ptInters[0]; } else if (nIntNum == 2) { double nDist1 = cvInitCurve.StartPoint().Distance2d(ptInters[0]); double nDist2 = cvInitCurve.StartPoint().Distance2d(ptInters[1]); if (fabs(nDist1 - nDist2) < _DIST_SNAP) { nDist1 = cvInitCurve.PathDistance(ptInters[0], FALSE); nDist2 = cvInitCurve.PathDistance(ptInters[1], FALSE); ptInitStart = (fabs(nDist1) < fabs(nDist2) ? ptInters[0] : ptInters[1]); } else if (nDist1 < nDist2) { ptInitStart = ptInters[0]; } else { ptInitStart = ptInters[1]; } } else // 无交点,平行 { bParell = TRUE; } } if (bAddition) // Modify on 2002/5/28, 多种材料的墙的交点仍然有问题 { TADSGePoint3d ptInters[2]; TADSGePoint3d ptInt; cvAddition.SetElevation(nElev); cvAddition.SetLineFlag(LS_INFINITE); int nIntNum = cvAddition.Intersection(cvStart, ptInters[0], ptInters[1]); if (nIntNum == 0) { } else { if (nIntNum == 1) { ptInt = ptInters[0]; } else { ptInt = TGGeLine(ptInters[0], ptInters[1]).NearPoint(cvInitCurve.GetStartPoint()); } if (ptInt.Distance2d(cvAddition.StartPoint()) < ptInt.Distance2d(cvAddition.EndPoint())) { cvAddition.SetPoints(ptInt, cvAddition.EndPoint()); } else { cvAddition.SetPoints(cvAddition.StartPoint(), ptInt); } cvAddition.SetLineFlag(LS_FINITE); //按有限长度 } nIntNum = cvInitCurve.Intersection(cvAddition, ptInters[0], ptInters[1]); if (nIntNum == 1) { ptInt = ptInters[0]; } else if (nIntNum == 2) { ptInt = TGGeLine(ptInters[0], ptInters[1]).NearPoint(cvInitCurve.GetStartPoint()); } if (nIntNum > 0) { if (ptInitEnd.Distance2d(ptInt) < ptInitEnd.Distance2d(ptInitStart)) { ptInitStart = ptInt; } } } } } { //对终止侧 TDPtrList lstIdStyles; GetIdStyles(1, lstIdStyles); int nCount = lstIdStyles.Length(); BOOL bParell = FALSE, bSameStyle = FALSE; BOOL bContinue = FALSE, bAddition = FALSE; TGGeCurveSegment cvEnd, cvAddition; TGGeCurveSegment cvEndBase, cvAdditionBase; TGGeCurveSegment cvEndOther; // 与cvEnd相对的边 bFlag = false; if (nCount == 0) //单甩 { } else if (nCount == 1) //转角 { IdDotStyle *pIdStyle = lstIdStyles.Head(); int nCmp = CompareWallStyle(GetPriority(), pIdStyle->GetPriority()); // add by xlc on 110310绘制带形窗计算时直接按墙同优先级计算 if (g_bSkipWallMaterial) { nCmp = 0; } if (nCmp == 0) //常规 { OPENOBJ_BEGIN(pIdStyle->id, AcDb::kForRead, TDbWall, pWall); if (pWall) { //modify by xlc on 110614 解决连接墙转角处存在短门窗套融合时墙线融合错误的问题 //cvEnd = pWall->GetRelativeSideCurve(nSide, EndPoint(), nDistToSide, bFromInsulate); bool bSameToStart = pWall->StartPoint().Distance2d(EndPoint()) < pWall->EndPoint().Distance2d(EndPoint()); double dSlotThick = 0; //门窗套伸出长度 bool bConnectShortSlot = false; //连接墙是否在墙角处有短门窗套 TDPtrList lstOpenings; //墙上的所有穿透的门窗洞 pWall->GetSortedOpenings(lstOpenings); if (lstOpenings.Length()>0) { TOpeningData *pWin = NULL; if (bSameToStart) { pWin = lstOpenings[0]; } else { pWin = lstOpenings[lstOpenings.Length()-1]; } if (pWin->HasSlot()) { TADSGePoint3d ptLoc = pWin->GetLocation(),ptProj; ptLoc.Project(&cvInitCurve,ptProj); bool bRightExt = (pWall->GetWallFlag() & WF_LEFTEXT) == 0; // 左墙线时连接墙起点,门窗套在左侧或连接墙终点门窗套在右侧 // 右墙线时连接墙起点,门窗套在右侧或连接墙终点门窗套在左侧 if ((nSide == 0 &&((!bRightExt&&bSameToStart) || (!(!bRightExt||bSameToStart)))) ||(nSide == 1 &&((bRightExt&&bSameToStart) || (!(bRightExt||bSameToStart))))) { double dSlotWidth = pWin->GetSlotWidth(); if (ptLoc.Distance2d(ptProj) < dSlotWidth + pWin->GetWidth()*0.5 + _DIST_SNAP) { bConnectShortSlot = true; dSlotThick = pWin->GetSlotExt(); } } } } if (bConnectShortSlot) { cvEnd = pWall->GetRelativeSideCurve(nSide, EndPoint(), nDistToSide+dSlotThick, bFromInsulate); } else { cvEnd = pWall->GetRelativeSideCurve(nSide, EndPoint(), nDistToSide, bFromInsulate); } cvEndBase = *pWall; bSameStyle = TRUE; bContinue = TRUE; } OPENOBJ_END(); } else //优先不一样 { OPENOBJ_BEGIN(pIdStyle->id, AcDb::kForRead, TDbWall, pWall); if (pWall) { //add by xlc on 100806 解决弧墙和直墙端头连接问题 //int nOffSide = pWall->OnWhichSide(StartPoint()); //if (nCmp > 0) //{ // nOffSide = !nOffSide; //} int nOffSide = 0; if ((Is(CURVE_LINE) && pWall->Is(CURVE_LINE))) { nOffSide = pWall->OnWhichSide(StartPoint()); if (nCmp > 0) { nOffSide = !nOffSide; } } else { TADSGePoint3d ptTest = StartPoint(); BOOL bStart = TRUE; //连接墙的端点 if (EndPoint().Distance(pWall->StartPoint()) > EndPoint().Distance(pWall->EndPoint())) { bStart = FALSE; } //存在弧墙时直接以端点判断可能会影响结果 if (Is(CURVE_LINE)) { TADSGePointDir2d ptRes; if ( pWall->Polar(_AS_SYS_UNIT(300), ptRes , bStart) == RTNORM) { ptTest = ptRes; } nOffSide = OnWhichSide(ptTest); } else { TADSGePointDir2d ptRes; if ( Polar(_AS_SYS_UNIT(300), ptRes , FALSE) == RTNORM) { ptTest = ptRes; } nOffSide = pWall->OnWhichSide(ptTest); } //考虑弧墙连接处平行的情况 { double dPrec = sin(PI / 72); TPushMemVar temp(_angSnap, dPrec);//临时改变角度精度,小于2.5度时当作平行处理 double dStart = Direction(EndPoint()); double dConnect = 0; if (bStart) { dConnect = pWall->Direction(pWall->StartPoint()); } else { dConnect = pWall->Direction(pWall->EndPoint()); } if (IsSameDrt(dStart, dConnect, _angSnap)) { bParell = TRUE; } } if (nCmp > 0) { if (bStart) { nOffSide = !nOffSide; } else { if (pWall->Is(CURVE_LINE) || (!Is(CURVE_LINE) && !pWall->Is(CURVE_LINE))) { nOffSide = !nOffSide; } } } else { if (!bStart) { if (Is(CURVE_LINE) && !pWall->Is(CURVE_LINE)) { nOffSide = !nOffSide; } } } } cvEnd = pWall->Offset(nOffSide, pWall->GetWidth(nOffSide), LS_FINITE); //add by xlc on 110121 仅处理直墙和弧墙连接 if ((Is(CURVE_LINE) && !pWall->Is(CURVE_LINE)) ||(!Is(CURVE_LINE) && pWall->Is(CURVE_LINE))) { if (nOffSide == 0) { nOffSide = 1; } else { nOffSide = 0; } cvEndOther = pWall->Offset(nOffSide, pWall->GetWidth(nOffSide), LS_INFINITE); bFlag = true; } cvEndBase = *pWall; bContinue = TRUE; } OPENOBJ_END(); } } else //多分支 { AcDbIntArray intArray; GetStyleKindArray(lstIdStyles, intArray); int nThisStyle = (GetPriority()); if (!intArray.contains(nThisStyle)) { intArray.append(nThisStyle); } int nKindCount = intArray.length(); //wlw 11.06.13 绘制保温时直接按墙同优先级计算 if (g_bSkipWallMaterial) { nKindCount = 1; } if (nKindCount > 2) //超过2种以上的材料 { } else if (nKindCount == 1)//常规情况 { OPENOBJ_BEGIN(nSide == 1 ? lstIdStyles.Head()->id : lstIdStyles.Tail()->id, AcDb::kForRead, TDbWall, pWall); if (pWall) { cvEnd = pWall->GetRelativeSideCurve(nSide, EndPoint(), nDistToSide, bFromInsulate); cvEndBase = *pWall; bContinue = TRUE; bSameStyle = TRUE; } OPENOBJ_END(); } else //2种材料 { int nThisStyleCount = GetStyleCount(GetPriority(), lstIdStyles); int nOtherStyleCount = lstIdStyles.Length()-nThisStyleCount; nThisStyleCount++; //包括自己 BOOL bAdvance = TRUE; if (nThisStyleCount > nOtherStyleCount) //当前优先 { } else if (nThisStyleCount == nOtherStyleCount) { int stOther = GetAnotherStyle(GetPriority(), lstIdStyles); if (CompareWallStyle(GetPriority(), stOther) < 0) { bAdvance = FALSE; } } else { bAdvance = FALSE; } if (bAdvance) //按正或反方向找id { AcDbObjectId idOther = GetSameStyleId(GetPriority(), lstIdStyles, nOppsiteSide); OPENOBJ_BEGIN(idOther, AcDb::kForRead, TDbWall, pWall); if (pWall) { cvEnd = pWall->GetRelativeSideCurve(nSide, EndPoint(), nDistToSide, bFromInsulate); cvEndBase = *pWall; bContinue = TRUE; bSameStyle = TRUE; } OPENOBJ_END(); } else { AcDbObjectId idOther; int stOther; if (nSide == 0) { idOther = lstIdStyles.Tail()->id; stOther = lstIdStyles.Tail()->GetPriority(); } else { idOther = lstIdStyles.Head()->id; stOther = lstIdStyles.Head()->GetPriority(); } OPENOBJ_BEGIN(idOther, AcDb::kForRead, TDbWall, pWall); if (pWall) { bSameStyle = (stOther == GetPriority()); double nDist = bSameStyle ? nDistToSide : 0.0; BOOL bIns = bSameStyle ? bFromInsulate : FALSE; cvEnd = pWall->GetRelativeSideCurve(nSide, EndPoint(), nDist, bIns); cvEndBase = *pWall; bContinue = TRUE; if (!bSameStyle) //附加裁剪线 { AcDbObjectId idAdd; if (nSide == 0) { idAdd = lstIdStyles.Head()->id; } else { idAdd = lstIdStyles.Tail()->id; } ASSERT(idAdd != idOther); OPENOBJ_BEGIN(idAdd, AcDb::kForRead, TDbWall, pAdd); if (pAdd) { cvAddition = pAdd->GetRelativeSideCurve(nOppsiteSide, EndPoint(), 0.0, FALSE); cvAdditionBase = *pAdd; bAddition = TRUE; } OPENOBJ_END(); } } OPENOBJ_END(); } } } if (bContinue && !!m_idColuEnd) //有柱子的情况有可能基线不交,这时不应连接墙角 { if (GetEndPoint().Distance2d(cvEndBase.StartPoint()) > _AS_SYS_UNIT(g_nDistPrec) && GetEndPoint().Distance2d(cvEndBase.EndPoint()) > _AS_SYS_UNIT(g_nDistPrec)) { //modify by xlc on 120606 确定基线不相交,解决有柱子时基线相交大大于墙精度时墙线错误的问题 TADSGePoint3d ptInters[2]; int nOldThis = cvInitCurve.GetLineFlag(); int nOldThat = cvEnd.GetLineFlag(); cvInitCurve.SetLineFlag(LS_FINITE); cvEnd.SetLineFlag(LS_FINITE); int nNum = cvInitCurve.Intersection(cvEnd, ptInters[0], ptInters[1]); if (nNum == 0) { bContinue = FALSE; } cvInitCurve.SetLineFlag(nOldThis); cvEnd.SetLineFlag(nOldThat); } if (bContinue&&bAddition) { if (GetEndPoint().Distance2d(cvAdditionBase.StartPoint()) > _AS_SYS_UNIT(g_nDistPrec) && GetEndPoint().Distance2d(cvAdditionBase.EndPoint()) > _AS_SYS_UNIT(g_nDistPrec)) { bAddition = FALSE; } } } // // 基线不相交的不连接墙角 -- wyg20090713 // else if (bContinue) // { // if (GetEndPoint().Distance2d(cvEndBase.StartPoint())>_AS_SYS_UNIT(g_nDistPrec)&& // GetEndPoint().Distance2d(cvEndBase.EndPoint())>_AS_SYS_UNIT(g_nDistPrec)) // bContinue = FALSE; // } if (bContinue) { cvEnd.SetLineFlag(LS_INFINITE); cvInitCurve.SetLineFlag(LS_INFINITE); cvEnd.SetElevation(nElev); if (cvEnd.Is(CURVE_LINE) && cvInitCurve.Is(CURVE_LINE)) { //modify by xlc on 091113 解决墙体显示不正常问题 double dPrec = sin(PI / 36); TPushMemVar temp(_angSnap, dPrec);//临时改变角度精度,小于5度时当作平行处理 if (IsSameDrt(cvEnd.TGGeLine::Direction(), cvInitCurve.TGGeLine::Direction(), _angSnap)) { bParell = TRUE; } } if (pPareEnd) { *pPareEnd = (bParell && bSameStyle); } if (!bParell) { TADSGePoint3d ptInters[2]; int nIntNum = cvInitCurve.Intersection(cvEnd, ptInters[0], ptInters[1]); //add by xlc on 110121 特殊处理的直墙和弧墙连接 if (bFlag) { TADSGePoint3d ptInters2[2]; int nIntNum2 = cvInitCurve.Intersection(cvEndOther, ptInters2[0], ptInters2[1]); TADSGePoint3d ptInters3[2], ptInters4[2]; int nIntNum3=0, nIntNum4=0; nIntNum3 = cvInitCurveOther.Intersection(cvEndOther, ptInters3[0], ptInters3[1]); nIntNum4 = cvInitCurveOther.Intersection(cvEnd, ptInters4[0], ptInters4[1]); if ((nIntNum == 0 && nIntNum2 != 0) || (nIntNum != 0 && nIntNum2 == 0) || (nIntNum3 == 0 && nIntNum4 != 0) || (nIntNum3 != 0 && nIntNum4 == 0) || (nIntNum == 0 && nIntNum4 != 0) || (nIntNum != 0 && nIntNum4 == 0) || (nIntNum3 == 0 && nIntNum2 != 0) || (nIntNum3 != 0 && nIntNum2 == 0))// 特殊处理的情况 { if (Is(CURVE_LINE)) { nIntNum = 1; ptInters[0] = ptInitEnd; } else { if (ptInitEnd.Distance2d(cvEnd.StartPoint()) < ptInitEnd.Distance2d(cvEnd.EndPoint())) { cvEnd.SetEndPoint(cvEndOther.StartPoint()); } else { cvEnd.SetStartPoint(cvEndOther.EndPoint()); } nIntNum = cvInitCurve.Intersection(cvEnd, ptInters[0], ptInters[1]); } } } if (nIntNum == 1) { ptInitEnd = ptInters[0]; } else if (nIntNum == 2) { double nDist1 = cvInitCurve.GetEndPoint().Distance2d(ptInters[0]); double nDist2 = cvInitCurve.GetEndPoint().Distance2d(ptInters[1]); if (fabs(nDist1 - nDist2) < _DIST_SNAP) { nDist1 = cvInitCurve.PathDistance(ptInters[0], TRUE); nDist2 = cvInitCurve.PathDistance(ptInters[1], TRUE); ptInitEnd = (fabs(nDist1) < fabs(nDist2) ? ptInters[0] : ptInters[1]); } else if (nDist1 < nDist2) { ptInitEnd = ptInters[0]; } else { ptInitEnd = ptInters[1]; } } else // 无交点,平行 { bParell = TRUE; } } if (bAddition) // Modify on 2002/5/28 { TADSGePoint3d ptInters[2]; TADSGePoint3d ptInt; cvAddition.SetLineFlag(LS_INFINITE); cvAddition.SetElevation(nElev); int nIntNum = cvAddition.Intersection(cvEnd, ptInters[0], ptInters[1]); if (nIntNum == 0) { } else { if (nIntNum == 1) { ptInt = ptInters[0]; } else { ptInt = TGGeLine(ptInters[0], ptInters[1]).NearPoint(cvInitCurve.GetStartPoint()); } if (ptInt.Distance2d(cvAddition.StartPoint()) < ptInt.Distance2d(cvAddition.EndPoint())) { cvAddition.SetPoints(ptInt, cvAddition.EndPoint()); } else { cvAddition.SetPoints(cvAddition.StartPoint(), ptInt); } cvAddition.SetLineFlag(LS_FINITE); //按有限长度 } nIntNum = cvInitCurve.Intersection(cvAddition, ptInters[0], ptInters[1]); if (nIntNum == 1) { ptInt = ptInters[0]; } else if (nIntNum == 2) { //modify by xlc on 100809 解决多分支连接缺线问题 //ptInt = TGGeLine(ptInters[0], ptInters[1]).NearPoint(cvInitCurve.GetStartPoint()); ptInt = TGGeLine(ptInters[0], ptInters[1]).NearPoint(cvInitCurve.GetEndPoint()); } if (nIntNum > 0 ) { if (ptInitStart.Distance2d(ptInt) < ptInitStart.Distance2d(ptInitEnd)) { ptInitEnd = ptInt; } } } } } // Modified on 2002/6/17, 对优弧和劣弧进行判断, 在几乎要变成圆墙的时候可能有错误 if (cvInitCurve.Is(CURVE_ARC)) { TPushPrec vTemp(1.0E-6, 1.0E-9); TGGeArc ar = cvInitCurve.GetArc(); //假如ptInitStart离End更近而且在弧外,那么就需要取消其有效性 if (ptInitStart.Distance2d(cvInitCurve.EndPoint()) < ptInitStart.Distance2d(cvInitCurve.StartPoint()) && ar.AngleFlag(ads_angle(ar.GetCenterPt(), ptInitStart)) == PR_OUTSIDE) { ptInitStart = cvInitCurve.GetStartPoint(); } //假如ptInitEnd离Start更近而且在弧外,那么就需要取消其有效性 if (ptInitEnd.Distance2d(cvInitCurve.StartPoint()) < ptInitEnd.Distance2d(cvInitCurve.EndPoint()) && ar.AngleFlag(ads_angle(ar.GetCenterPt(), ptInitEnd)) == PR_OUTSIDE) { ptInitEnd = cvInitCurve.GetEndPoint(); } } //本处cinitcurve 和 GetStartPoint()-GetEndPoint() 校正 //add by xlc on 091106 校正墙线 AdjustStandardSideCurve(ptInitStart,ptInitEnd); cvInitCurve.SetPoints(ptInitStart, ptInitEnd); return cvInitCurve; } TGGeCurveSegment TWallData::GetHatchCenterCurve() const { TGGeCurveSegment cvInitCurve = OffsetGeomCenter(LS_INFINITE); TADSGePoint3d ptStart = cvInitCurve.GetStartPoint(),ptEnd = cvInitCurve.GetEndPoint(); { //对起始侧 TDPtrList lstIdStyles; GetIdStyles(0, lstIdStyles); if (lstIdStyles.Length() > 0) { for (long i = 0; i < lstIdStyles.Length(); i++) { IdDotStyle st = *lstIdStyles[i]; if (st.GetPriority() > GetPriority()) //遭遇大优先级墙 { lstIdStyles.Reset(); } else if (st.GetPriority() < GetPriority()) //遭遇小优先墙,忽略之 { lstIdStyles.Remove(i--); } } TADSGePointList ptList; TDbWall *pWall = NULL; for (i = 0; i < lstIdStyles.Length(); i++) { IdDotStyle st = *lstIdStyles[i]; acdbOpenObject(pWall,st.id,AcDb::kForRead); if (pWall != NULL) { TGGeCurveSegment lCurve,rCurve; pWall->GetStandardCurve(lCurve,rCurve); if (pWall->GetStartPoint().Distance2d(StartPoint()) < _AS_SYS_UNIT(g_nDistPrec)) { ptList.NewAppend(lCurve.StartPoint()); ptList.NewAppend(rCurve.StartPoint()); } else if (pWall->GetEndPoint().Distance2d(StartPoint()) < _AS_SYS_UNIT(g_nDistPrec)) { ptList.NewAppend(lCurve.EndPoint()); ptList.NewAppend(rCurve.EndPoint()); } pWall->close(); } } TGGeCurveSegment lCurve,rCurve; GetStandardCurve(lCurve,rCurve); // modify by xlc on 110222 弧墙墙体填充显示不全问题 //ptList.NewAppend(lCurve.StartPoint()); //ptList.NewAppend(rCurve.StartPoint()); int nLength = ptList.Length(); int nPos1 = ptList.NewAppend(lCurve.StartPoint()); int nPos2 = ptList.NewAppend(rCurve.StartPoint()); if (ptList.Length() > nLength && lstIdStyles.Length() ==1) { ptList.Remove(nPos1 < nPos2 ? nPos1 : nPos2); } ptList.Center(ptStart); } } { //对起始侧 TDPtrList lstIdStyles; GetIdStyles(1, lstIdStyles); if (lstIdStyles.Length() > 0) { for (long i = 0; i < lstIdStyles.Length(); i++) { IdDotStyle st = *lstIdStyles[i]; if (st.GetPriority() > GetPriority()) //遭遇大优先级墙 { lstIdStyles.Reset(); } else if (st.GetPriority() < GetPriority()) //遭遇小优先墙,忽略之 { lstIdStyles.Remove(i--); } } TADSGePointList ptList; for (i = 0; i < lstIdStyles.Length(); i++) { IdDotStyle st = *lstIdStyles[i]; TDbWall *pWall = NULL; acdbOpenObject(pWall,st.id,AcDb::kForRead); if (pWall != NULL) { TGGeCurveSegment lCurve,rCurve; pWall->GetStandardCurve(lCurve,rCurve); if (pWall->GetStartPoint().Distance2d(EndPoint()) < _AS_SYS_UNIT(g_nDistPrec)) { ptList.NewAppend(lCurve.StartPoint()); ptList.NewAppend(rCurve.StartPoint()); } else if (pWall->GetEndPoint().Distance2d(EndPoint()) < _AS_SYS_UNIT(g_nDistPrec)) { ptList.NewAppend(lCurve.EndPoint()); ptList.NewAppend(rCurve.EndPoint()); } pWall->close(); } } TGGeCurveSegment lCurve,rCurve; GetStandardCurve(lCurve,rCurve); // modify by xlc on 110222 弧墙墙体填充显示不全问题 //ptList.NewAppend(lCurve.EndPoint()); //ptList.NewAppend(rCurve.EndPoint()); int nLength = ptList.Length(); int nPos1 = ptList.NewAppend(lCurve.EndPoint()); int nPos2 = ptList.NewAppend(rCurve.EndPoint()); if (ptList.Length() > nLength && lstIdStyles.Length() ==1) { ptList.Remove(nPos1 < nPos2 ? nPos1 : nPos2); } ptList.Center(ptEnd); } } cvInitCurve.SetStartPoint(ptStart); cvInitCurve.SetEndPoint(ptEnd); return cvInitCurve; } void TWallData::GetStandardCurve(TGGeCurveSegment &lCurve, TGGeCurveSegment &rCurve, double nDistToSide, BOOL bFromInsulate) const { //add by W on 070928 //判断是否连接数据异常,可以解决块内墙影响填充问题 TDPtrList lstId0,lstId1; GetIdStyles(0, lstId0); GetIdStyles(1,lstId1); lstId0 << lstId1; if (lstId0.Length() > 0) { IdDotStyle *pIdStyle = lstId0.Head(); OPENOBJ_BEGIN(pIdStyle->id, AcDb::kForRead, TDbWall, pWall); if (pWall) { if (pWall->ownerId() != GetMyOwnerId()) { BOOL bHasInsulate = ((m_nWallFlag & WF_LEFT_INSULATE) || (m_nWallFlag & WF_RIGHT_INSULATE)); BOOL bConsideIns = (bHasInsulate && bFromInsulate); if (!bConsideIns && fabs(nDistToSide) < _DIST_SNAP) { TADSGePointDir2d ptNewStart, ptNewEnd; ads_real nDistFromStart = 0.0, nDistFromEnd = 0.0; for (int nSide = 0; nSide < 2; nSide++) { TGGeCurveSegment &curveSeg = nSide ? rCurve : lCurve; curveSeg = Offset(nSide ? OFFSET_RIGHT : OFFSET_LEFT, GetWidth(nSide), LS_FINITE); nDistFromStart = nSide ? m_nFromRightStart : m_nFromLeftStart; nDistFromEnd = nSide ? m_nFromRightEnd : m_nFromLeftEnd; curveSeg.Polar(nDistFromStart, ptNewStart, 1); curveSeg.Polar(nDistFromEnd, ptNewEnd, 0); curveSeg.SetPoints(ptNewStart, ptNewEnd); } } else { lCurve = GetRelativeSideCurve(OFFSET_LEFT, StartPoint(), nDistToSide, bFromInsulate); rCurve = GetRelativeSideCurve(OFFSET_RIGHT, StartPoint(), nDistToSide, bFromInsulate); } return; } } OPENOBJ_END(); } lCurve = GetStandardSideCurve(OFFSET_LEFT,nDistToSide,bFromInsulate); rCurve = GetStandardSideCurve(OFFSET_RIGHT,nDistToSide,bFromInsulate); } // 计算两侧的参数 // 参数: // entThis--Wall实体或变双线前的实体 // Note: 考虑了基面标高 // 修改历史: // 1998.3.7 求交时忽略Z坐标 int TWallData::CalSideParameters(const TEntitySet &entThis, TDPtrList &lstAllSortedWalls, TGGeCurveSegment &lCurve, TGGeCurveSegment &rCurve) { int nRetRes = 0; ASSERT(!Is(CURVE_CIRCLE)); TGGePoly2D *sPoly = NULL, *ePoly = NULL; //找两端的裁剪边界 for (int nCorner = 0; nCorner < 2; nCorner++) { TADSGePoint3d &ptCorner = nCorner ? EndPoint() : StartPoint(); TSortWallOnPt *ptrSortWall = lstAllSortedWalls.FindNode(&ptCorner,CmpSortWallLoc); if (!ptrSortWall) { continue; } // 取得端点的排序墙 TGGePoly2D *pPolyTar = NULL; TSortWallOnPt &lstSortedWalls = *ptrSortWall; if (nCorner == 0) { sPoly = pPolyTar = &lstSortedWalls.polyExtend; } else { ePoly = pPolyTar = &lstSortedWalls.polyExtend; } TGGiWallVector *ptrVectorTemp = lstSortedWalls.FindNode(&entThis, TGGiWallVector::FindByEntity); //当重合时可能找不到 if (!ptrVectorTemp) { return 0; } ASSERT(lstSortedWalls.Length()); int i = lstSortedWalls.CurPosition(); BOOL bSamePrev = TRUE, bSameNext = TRUE; // 调整双线 TGGiWallVector *curWall = lstSortedWalls[i]; TGGiWallVector *prevWall = lstSortedWalls.GetPrevWall(i, &bSamePrev); TGGiWallVector *nextWall = lstSortedWalls.GetNextWall(i, &bSameNext); // 后一墙的右侧和当前墙的左侧求交, 左右的提法为相对于当前端点,而不是墙线方向 // 前一墙的左侧和当前墙的右侧求交, 左右的提法为相对于当前端点,而不是墙线方向 TGGeCurveSegment curSegLeft = curWall->LeftCurve(&lstSortedWalls, LS_INFINITE), curSegRight = curWall->RightCurve(&lstSortedWalls, LS_INFINITE), prevSeg, nextSeg; if (prevWall) { prevSeg = prevWall->LeftCurve(&lstSortedWalls, LS_INFINITE); } if (nextWall) { nextSeg = nextWall->RightCurve(&lstSortedWalls, LS_INFINITE); } // 把Z坐标调整到0进行求交 prevSeg.SetElevation(0.0); curSegLeft.SetElevation(0.0); curSegRight.SetElevation(0.0); nextSeg.SetElevation(0.0); TADSGePoint3d ptInters[2]; TADSGePoint3d ptInt; //左边 if (!nCorner) { lCurve = curSegLeft; rCurve = curSegRight; } if (nextWall) { int nIntNum = curSegLeft.Intersection(nextSeg, ptInters[0], ptInters[1]); if (nIntNum == 1) { ptInt = ptInters[0]; } else if (nIntNum == 2) { ptInt = TGGeLine(ptInters[0], ptInters[1]).NearPoint(!nCorner ? curSegLeft.GetStartPoint() : curSegLeft.GetEndPoint()); } if (nIntNum) { if (!nCorner) { lCurve.SetPoints(ptInt, TADSGePoint3d(lCurve.GetEndPoint())); } else { rCurve.SetPoints(TADSGePoint3d(rCurve.GetStartPoint()), ptInt); } } } // 右边 if (prevWall) { int nIntNum = curSegRight.Intersection(prevSeg, ptInters[0], ptInters[1]); if (nIntNum == 1) { ptInt = ptInters[0]; } else if (nIntNum == 2) { ptInt = TGGeLine(ptInters[0], ptInters[1]).NearPoint(!nCorner ? curSegLeft.GetStartPoint() : curSegLeft.GetEndPoint()); } if (nIntNum) { if (!nCorner) { rCurve.SetPoints(ptInt, TADSGePoint3d(rCurve.GetEndPoint())); } else { lCurve.SetPoints(TADSGePoint3d(lCurve.GetStartPoint()), ptInt); } } } } return nRetRes; } // 取得墙的最终偏移线, 考虑柱子裁剪 TGGeCurveSegment TWallData::GetFinalSideCurve(int nSide, double nDistToSide, BOOL bFromInsulate, bool bColInsulate /*= true*/) const { TGGeCurveSegment cvOffset = GetStandardSideCurve(nSide, nDistToSide, bFromInsulate); cvOffset.SetLineFlag(LS_FINITE); TGGePoly2D sPoly(1), ePoly(1); TADSGePoint3d ptInter; if (!!m_idColuStart) { OPENOBJ_BEGIN(m_idColuStart, AcDb::kForRead, TDbColumn, pStart); if (pStart) { pStart->GetOutline(sPoly); //如果柱子有保温,则取保温的外轮廓wulw if (pStart->IsInsulateOnColumn() && bColInsulate) { pStart->GetIntersectWithCurveSeg(cvOffset, ptInter); if (pStart->HasSurFaceWithVector(ptInter - pStart->m_ptLocation)) { GetOffsetPoly2D(pStart->m_polyOutline, sPoly, pStart->m_nInsulateThick); } } if (int(m_style) == int(pStart->GetMaterial())) //同材料 { TGGePoly2D polyOffset(1); if (sPoly.QuickOffset(nDistToSide, polyOffset) == RTNORM) { sPoly = polyOffset; } } } OPENOBJ_END(); } if (!!m_idColuEnd) { OPENOBJ_BEGIN(m_idColuEnd, AcDb::kForRead, TDbColumn, pEnd); if (pEnd) { pEnd->GetOutline(ePoly); //如果柱子有保温,则取保温的外轮廓 if (pEnd->IsInsulateOnColumn() && bColInsulate) { pEnd->GetIntersectWithCurveSeg(cvOffset, ptInter); if (pEnd->HasSurFaceWithVector(ptInter - pEnd->m_ptLocation)) { GetOffsetPoly2D(pEnd->m_polyOutline, ePoly, pEnd->m_nInsulateThick); } } if (int(m_style) == int(pEnd->GetMaterial())) //同材料 { TGGePoly2D polyOffset(1); if (ePoly.QuickOffset(nDistToSide, polyOffset) == RTNORM) { ePoly = polyOffset; } } } OPENOBJ_END(); } sPoly.SetElevation(0); ePoly.SetElevation(0); double nElev = cvOffset.GetStartPoint().z; cvOffset.SetElevation(0.0); TGGeCurveSegment seg = TchPrivate::GetCurveContainPointAfterClip(MidPoint(), cvOffset, sPoly, ePoly); seg.SetElevation(nElev); return seg; } // 取得墙基面上的两条边线,考虑了扣除了柱子和邻居墙体的影响 // 返回: 0--正常; 1--无左边线; 2--无右边线; 3--无左右边线 void TWallData::GetSideCurve(TGGeCurveSegment &lCurve, TGGeCurveSegment &rCurve, double nDistToSide, BOOL bFromInsulate, bool bColInsulate /*= true*/) const { BOOL bHasInsulate = ((m_nWallFlag & WF_LEFT_INSULATE) || (m_nWallFlag & WF_RIGHT_INSULATE)); BOOL bConsideIns = (bHasInsulate && bFromInsulate); TADSGePointDir2d ptNewStart, ptNewEnd; ads_real nDistFromStart = 0.0,nDistFromEnd = 0.0; if (!bConsideIns && fabs(nDistToSide) < _DIST_SNAP) { //加速算法 for (int nSide = 0; nSide < 2; nSide++) { TGGeCurveSegment &curveSeg = nSide ? rCurve : lCurve; curveSeg = Offset(nSide? OFFSET_RIGHT:OFFSET_LEFT, GetWidth(nSide), LS_FINITE); nDistFromStart = nSide ? m_nFromRightStart : m_nFromLeftStart; nDistFromEnd = nSide ? m_nFromRightEnd : m_nFromLeftEnd; curveSeg.Polar(nDistFromStart, ptNewStart, 1); curveSeg.Polar(nDistFromEnd, ptNewEnd, 0); curveSeg.SetPoints(ptNewStart, ptNewEnd); } } else { TGGeCurveSegment cvStdLeft, cvStdRight; cvStdLeft = GetFinalSideCurve(OFFSET_LEFT, nDistToSide, bFromInsulate, bColInsulate); cvStdRight = GetFinalSideCurve(OFFSET_RIGHT, nDistToSide, bFromInsulate, bColInsulate); cvStdLeft.SetLineFlag(lCurve.GetLineFlag()); cvStdRight.SetLineFlag(rCurve.GetLineFlag()); lCurve = cvStdLeft; rCurve = cvStdRight; } } // 2002/4/5修改,解决不同材质的墙相交的问题 TGGeCurveSegment TWallData::GetStdOffsetCurveFromCenter(int nSide, double nRatio) const { TGGeCurveSegment cvCenter = OffsetGeomCenter(); TGGeCurveSegment cvInitCurve = cvCenter.Offset(nSide, nRatio * GetWidth(), LS_INFINITE); TADSGePoint3d ptInitStart = cvInitCurve.GetStartPoint(), ptInitEnd = cvInitCurve.GetEndPoint(); int nOppsiteSide = nSide == OFFSET_LEFT ? OFFSET_RIGHT : OFFSET_LEFT; double nElev = GetElevation(); //add by xlc on 110121 解决直墙和弧墙连接问题(幕墙显示异常) TGGeCurveSegment cvInitCurveThis = GetRelativeSideCurve(nSide, StartPoint()); TGGeCurveSegment cvInitCurveOther = GetRelativeSideCurve(nOppsiteSide, StartPoint()); cvInitCurveThis.SetLineFlag(LS_INFINITE); cvInitCurveOther.SetLineFlag(LS_INFINITE); bool bFlag = false; //是否特殊处理 { //对起始侧 TDPtrList lstIdStyles; GetIdStyles(0, lstIdStyles); int nCount = lstIdStyles.Length(); BOOL bParell = FALSE, bSameStyle = FALSE; BOOL bContinue = FALSE, bAddition = FALSE; TGGeCurveSegment cvStartThis; // 边线 TGGeCurveSegment cvStartOther; // 与cvStartThis相对的线 //add by xlc on 120426 解决异形柱的连接的上带型窗裁剪错误的问题 bool bStart = true; //起端线在柱子内部时不进行求交处理 TGGePoly2D sPoly(1); if (!!m_idColuStart) { OPENOBJ_BEGIN(m_idColuStart, AcDb::kForRead, TDbColumn, pEnt); if (pEnt) { pEnt->GetOutline(sPoly); TADSGePoint3d ptTest = ptInitStart; ptTest.z = sPoly[0]->z; if ((ptTest & sPoly) == PR_INSIDE) { //modify by xlc on 120620 仅对异形柱做特殊处理 if(pEnt->GetSectionShape() == TDbColumn::kPoly) { bStart = false; } } } OPENOBJ_END(); } TGGeCurveSegment cvStart, cvAddition; if (nCount == 0) //单甩 { } //modify by xlc on 120426 //else if (nCount == 1) //转角 else if (nCount == 1 && bStart) //转角 { IdDotStyle *pIdStyle = lstIdStyles.Head(); int nCmp = CompareWallStyle(GetPriority(), pIdStyle->GetPriority()); // add by xlc on 110310绘制带形窗计算时直接按墙同优先级计算 if (g_bSkipWallMaterial) { nCmp = 0; } if (nCmp == 0) //常规 { OPENOBJ_BEGIN(pIdStyle->id, AcDb::kForRead, TDbWall, pWall); if (pWall) { cvStart = pWall->GetRelativeOffsetCurveFromCenter(nOppsiteSide, nRatio, GetStartPoint()); bContinue = TRUE; bSameStyle = TRUE; } OPENOBJ_END(); } else //优先不一样 { OPENOBJ_BEGIN(pIdStyle->id, AcDb::kForRead, TDbWall, pWall); if (pWall) { //add by xlc on 100806 解决弧墙和直墙端头连接问题 //int nOffSide = pWall->OnWhichSide(GetEndPoint()); //if (nCmp > 0) //{ // nOffSide = !nOffSide; //} int nOffSide = 0; if (Is(CURVE_LINE) && pWall->Is(CURVE_LINE)) { nOffSide = pWall->OnWhichSide(GetEndPoint()); if (nCmp > 0) { nOffSide = !nOffSide; } } else { TADSGePoint3d ptTest = GetEndPoint(); BOOL bStart = TRUE; //连接墙的端点 if (StartPoint().Distance(pWall->StartPoint()) > StartPoint().Distance(pWall->EndPoint())) { bStart = FALSE; } //存在弧墙时直接以端点判断可能会影响结果 if (Is(CURVE_LINE)) { TADSGePointDir2d ptRes; if ( pWall->Polar(_AS_SYS_UNIT(300), ptRes , bStart) == RTNORM) { ptTest = ptRes; } nOffSide = OnWhichSide(ptTest); } else { TADSGePointDir2d ptRes; if ( Polar(_AS_SYS_UNIT(300), ptRes , TRUE) == RTNORM) { ptTest = ptRes; } nOffSide = pWall->OnWhichSide(ptTest); } //考虑弧墙连接处平行的情况 { double dPrec = sin(PI / 72); TPushMemVar temp(_angSnap, dPrec);//临时改变角度精度,小于2.5度时当作平行处理 double dStart = Direction(StartPoint()); double dConnect = 0; if (bStart) { dConnect = pWall->Direction(pWall->StartPoint()); } else { dConnect = pWall->Direction(pWall->EndPoint()); } if (IsSameDrt(dStart, dConnect, _angSnap)) { bParell = TRUE; } } if (nCmp > 0) { if (!bStart) { nOffSide = !nOffSide; } else { if (pWall->Is(CURVE_LINE)) { nOffSide = !nOffSide; } } } else { if (bStart) { if (Is(CURVE_LINE)) { nOffSide = !nOffSide; } } } } cvStart = pWall->Offset(nOffSide, pWall->GetWidth(nOffSide), LS_INFINITE); //add by xlc on 110121 仅处理直墙和弧墙连接 if ((Is(CURVE_LINE) && !pWall->Is(CURVE_LINE)) ||(!Is(CURVE_LINE) && pWall->Is(CURVE_LINE))) { cvStartThis = pWall->Offset(nOffSide, pWall->GetWidth(nOffSide), LS_INFINITE); if (nOffSide == 0) { nOffSide = 1; } else { nOffSide = 0; } cvStartOther = pWall->Offset(nOffSide, pWall->GetWidth(nOffSide), LS_INFINITE); bFlag = true; } bContinue = TRUE; } OPENOBJ_END(); } } //modify by xlc on 120426 //else //多分支 else if(bStart) //多分支 { AcDbIntArray intArray; GetStyleKindArray(lstIdStyles, intArray); int nThisStyle = (GetPriority()); if (!intArray.contains(nThisStyle)) { intArray.append(nThisStyle); } int nKindCount = intArray.length(); //wlw 11.06.13 绘制保温时直接按墙同优先级计算 if (g_bSkipWallMaterial) { nKindCount = 1; } if (nKindCount > 2) //超过2种以上的材料 { } else if (nKindCount == 1)//常规情况 { OPENOBJ_BEGIN(lstIdStyles.Head()->id, AcDb::kForRead, TDbWall, pWall); if (pWall) { cvStart = pWall->GetRelativeOffsetCurveFromCenter(nOppsiteSide, nRatio, GetStartPoint()); bContinue = TRUE; bSameStyle = TRUE; } OPENOBJ_END(); } else //2种材料 { int nThisStyleCount = GetStyleCount(GetPriority(), lstIdStyles); int nOtherStyleCount = lstIdStyles.Length() - nThisStyleCount; nThisStyleCount++; //包括自己 BOOL bAdvance = TRUE; if (nThisStyleCount > nOtherStyleCount) //当前优先 { } else if (nThisStyleCount == nOtherStyleCount) { int stOther = GetAnotherStyle(GetPriority(), lstIdStyles); if (CompareWallStyle(GetPriority(), stOther) < 0) { bAdvance = FALSE; } } else { bAdvance = FALSE; } if (bAdvance) //按正或反方向找id { AcDbObjectId idOther = GetSameStyleId(GetPriority(), lstIdStyles, nSide); OPENOBJ_BEGIN(idOther, AcDb::kForRead, TDbWall, pWall); if (pWall) { cvStart = pWall->GetRelativeOffsetCurveFromCenter(nOppsiteSide, nRatio, GetStartPoint()); bContinue = TRUE; bSameStyle = TRUE; } OPENOBJ_END(); } else { AcDbObjectId idOther; int stOther; if (nSide == 0) { idOther = lstIdStyles.Head()->id; stOther = lstIdStyles.Head()->GetPriority(); } else { idOther = lstIdStyles.Tail()->id; stOther = lstIdStyles.Tail()->GetPriority(); } OPENOBJ_BEGIN(idOther, AcDb::kForRead, TDbWall, pWall); if (pWall) { bSameStyle = (stOther == GetPriority()); if (bSameStyle) { cvStart = pWall->GetRelativeOffsetCurveFromCenter(nOppsiteSide, nRatio, GetStartPoint()); } else { cvStart = pWall->GetRelativeSideCurve(nOppsiteSide, GetStartPoint(), 0.0, FALSE); } bContinue = TRUE; if (!bSameStyle) //附加裁剪线 { AcDbObjectId idAdd; if (nSide == 0) { idAdd = lstIdStyles.Tail()->id; } else { idAdd = lstIdStyles.Head()->id; } ASSERT(idAdd != idOther); OPENOBJ_BEGIN(idAdd, AcDb::kForRead, TDbWall, pAdd); if (pAdd) { cvAddition = pAdd->GetRelativeSideCurve(nSide, GetStartPoint(), 0.0, FALSE); bAddition = TRUE; } OPENOBJ_END(); } } OPENOBJ_END(); } } } if (bContinue) { cvStart.SetLineFlag(LS_INFINITE); cvInitCurve.SetLineFlag(LS_INFINITE); cvStart.SetElevation(nElev); if (cvStart.Is(CURVE_LINE) && cvInitCurve.Is(CURVE_LINE)) { //modify by xlc on 091113 解决墙体显示不正常问题 double dPrec = sin(PI / 36); TPushMemVar temp(_angSnap, dPrec);//临时改变角度精度,小于5度时当作平行处理 if (IsSameDrt(cvStart.TGGeLine::Direction(), cvInitCurve.TGGeLine::Direction(), _angSnap)) { bParell = TRUE; } } if (!bParell) { TADSGePoint3d ptInters[2]; int nIntNum = cvInitCurve.Intersection(cvStart, ptInters[0], ptInters[1]); //add by xlc on 110121 特殊处理的直墙和弧墙连接 if (bFlag) { TADSGePoint3d ptInters0[2], ptInters2[2], ptInters3[2], ptInters4[2]; int nIntNum0, nIntNum2=0, nIntNum3=0, nIntNum4=0; //交点个数 nIntNum0 = cvInitCurveThis.Intersection(cvStartThis, ptInters0[0], ptInters0[1]); nIntNum2 = cvInitCurveThis.Intersection(cvStartOther, ptInters2[0], ptInters2[1]); nIntNum3 = cvInitCurveOther.Intersection(cvStartOther, ptInters3[0], ptInters3[1]); nIntNum4 = cvInitCurveOther.Intersection(cvStartThis, ptInters4[0], ptInters4[1]); if ((nIntNum0 == 0 && nIntNum2 != 0) || (nIntNum0 != 0 && nIntNum2 == 0) || (nIntNum3 == 0 && nIntNum4 != 0) || (nIntNum3 != 0 && nIntNum4 == 0) || (nIntNum0 == 0 && nIntNum4 != 0) || (nIntNum0 != 0 && nIntNum4 == 0) || (nIntNum3 == 0 && nIntNum2 != 0) || (nIntNum3 != 0 && nIntNum2 == 0))//特殊处理的情况 { if (ptInitStart.Distance2d(cvStartThis.StartPoint()) < ptInitStart.Distance2d(cvStartThis.EndPoint())) { cvStart.SetStartPoint(cvStartThis.StartPoint()); cvStart.SetEndPoint(cvStartOther.StartPoint()); } else { cvStart.SetStartPoint(cvStartOther.EndPoint()); cvStart.SetEndPoint(cvStartThis.EndPoint()); } cvStart.SetBulge(0.0); nIntNum = cvInitCurve.Intersection(cvStart, ptInters[0], ptInters[1]); } } if (nIntNum == 1) { ptInitStart = ptInters[0]; } else if (nIntNum == 2) { ptInitStart = TGGeLine(ptInters[0], ptInters[1]).NearPoint(cvInitCurve.GetStartPoint()); } else // 无交点,平行 { bParell = TRUE; } } if (bAddition) { TADSGePoint3d ptInters[2]; TADSGePoint3d ptInt; cvAddition.SetElevation(nElev); cvAddition.SetLineFlag(LS_INFINITE); int nIntNum = cvInitCurve.Intersection(cvAddition, ptInters[0], ptInters[1]); if (nIntNum == 1) { ptInt = ptInters[0]; } else if (nIntNum == 2) { ptInt = TGGeLine(ptInters[0], ptInters[1]).NearPoint(cvInitCurve.GetStartPoint()); } if (ptInitEnd.Distance2d(ptInt) < ptInitEnd.Distance2d(ptInitStart)) { ptInitStart = ptInt; } } } } { //对终止侧 TDPtrList lstIdStyles; GetIdStyles(1, lstIdStyles); int nCount = lstIdStyles.Length(); BOOL bParell = FALSE, bSameStyle = FALSE; BOOL bContinue = FALSE, bAddition = FALSE; TGGeCurveSegment cvEnd, cvAddition; TGGeCurveSegment cvEndThis; // 边线 TGGeCurveSegment cvEndOther; // 与cvEndThis相对的线 bFlag = false; //add by xlc on 120426 解决异形柱的连接的上带型窗裁剪错误的问题 bool bEnd = true; //尾端线在柱子内部时不进行求交处理 TGGePoly2D ePoly(1); if (!!m_idColuEnd) { OPENOBJ_BEGIN(m_idColuEnd, AcDb::kForRead, TDbColumn, pEnd); if (pEnd) { pEnd->GetOutline(ePoly); TADSGePoint3d ptTest = ptInitEnd; ptTest.z = ePoly[0]->z; if ((ptInitEnd & ePoly) == PR_INSIDE) { //modify by xlc on 120620 仅对异形柱做特殊处理 if(pEnd->GetSectionShape() == TDbColumn::kPoly) { bEnd = false; } } } OPENOBJ_END(); } if (nCount == 0) //单甩 { } //modify by xlc on 120426 //else if (nCount == 1) //转角 else if (nCount == 1 && bEnd) //转角 { IdDotStyle *pIdStyle = lstIdStyles.Head(); int nCmp = CompareWallStyle(GetPriority(), pIdStyle->GetPriority()); // add by xlc on 110310绘制带形窗计算时直接按墙同优先级计算 if (g_bSkipWallMaterial) { nCmp = 0; } if (nCmp == 0) //常规 { OPENOBJ_BEGIN(pIdStyle->id, AcDb::kForRead, TDbWall, pWall); if (pWall) { cvEnd = pWall->GetRelativeOffsetCurveFromCenter(nSide, nRatio, GetEndPoint()); bSameStyle = TRUE; bContinue = TRUE; } OPENOBJ_END(); } else //优先不一样 { OPENOBJ_BEGIN(pIdStyle->id, AcDb::kForRead, TDbWall, pWall); if (pWall) { //add by xlc on 100806 解决弧墙和直墙端头连接问题 //int nOffSide = pWall->OnWhichSide(GetStartPoint()); //if (nCmp > 0) //{ // nOffSide = !nOffSide; //} int nOffSide = 0; if (Is(CURVE_LINE) && pWall->Is(CURVE_LINE)) { nOffSide = pWall->OnWhichSide(GetStartPoint()); if (nCmp > 0) { nOffSide = !nOffSide; } } else { TADSGePoint3d ptTest = GetStartPoint(); BOOL bStart = TRUE; //连接墙的端点 if (EndPoint().Distance(pWall->StartPoint()) > EndPoint().Distance(pWall->EndPoint())) { bStart = FALSE; } //存在弧墙时直接以端点判断可能会影响结果 if (Is(CURVE_LINE)) { TADSGePointDir2d ptRes; if ( pWall->Polar(_AS_SYS_UNIT(300), ptRes , bStart) == RTNORM) { ptTest = ptRes; } nOffSide = OnWhichSide(ptTest); } else { TADSGePointDir2d ptRes; if ( Polar(_AS_SYS_UNIT(300), ptRes , FALSE) == RTNORM) { ptTest = ptRes; } nOffSide = pWall->OnWhichSide(ptTest); } //考虑弧墙连接处平行的情况 { double dPrec = sin(PI / 72); TPushMemVar temp(_angSnap, dPrec);//临时改变角度精度,小于2.5度时当作平行处理 double dStart = Direction(EndPoint()); double dConnect = 0; if (bStart) { dConnect = pWall->Direction(pWall->StartPoint()); } else { dConnect = pWall->Direction(pWall->EndPoint()); } if (IsSameDrt(dStart, dConnect, _angSnap)) { bParell = TRUE; } } if (nCmp > 0) { if (bStart) { nOffSide = !nOffSide; } else { if (pWall->Is(CURVE_LINE)) { nOffSide = !nOffSide; } } } else { if (!bStart) { if (Is(CURVE_LINE)) { nOffSide = !nOffSide; } } } } cvEnd = pWall->Offset(nOffSide, pWall->GetWidth(nOffSide), LS_FINITE); //add by xlc on 110121 仅处理直墙和弧墙连接 if ((Is(CURVE_LINE) && !pWall->Is(CURVE_LINE)) ||(!Is(CURVE_LINE) && pWall->Is(CURVE_LINE))) { cvEndThis = pWall->Offset(nOffSide, pWall->GetWidth(nOffSide), LS_FINITE); if (nOffSide == 0) { nOffSide = 1; } else { nOffSide = 0; } cvEndOther = pWall->Offset(nOffSide, pWall->GetWidth(nOffSide), LS_INFINITE); bFlag = true; } bContinue = TRUE; } OPENOBJ_END(); } } //modify by xlc on 120426 //else //多分支 else if(bEnd) //多分支 { AcDbIntArray intArray; GetStyleKindArray(lstIdStyles, intArray); int nThisStyle = (GetPriority()); if (!intArray.contains(nThisStyle)) { intArray.append(nThisStyle); } int nKindCount = intArray.length(); //wlw 11.06.13 绘制保温时直接按墙同优先级计算 if (g_bSkipWallMaterial) { nKindCount = 1; } if (nKindCount > 2) //超过2种以上的材料 { } else if (nKindCount == 1) //常规情况 { OPENOBJ_BEGIN(lstIdStyles.Head()->id, AcDb::kForRead, TDbWall, pWall); if (pWall) { cvEnd = pWall->GetRelativeOffsetCurveFromCenter(nSide, nRatio, GetEndPoint()); bContinue = TRUE; bSameStyle = TRUE; } OPENOBJ_END(); } else //2种材料 { int nThisStyleCount = GetStyleCount(GetPriority(), lstIdStyles); int nOtherStyleCount = lstIdStyles.Length()-nThisStyleCount; nThisStyleCount++; //包括自己 BOOL bAdvance = TRUE; if (nThisStyleCount > nOtherStyleCount) //当前优先 { } else if (nThisStyleCount == nOtherStyleCount) { int stOther = GetAnotherStyle(GetPriority(), lstIdStyles); if (CompareWallStyle(GetPriority(), stOther) < 0) { bAdvance = FALSE; } } else { bAdvance = FALSE; } if (bAdvance) //按正或反方向找id { AcDbObjectId idOther = GetSameStyleId(GetPriority(), lstIdStyles, nOppsiteSide); OPENOBJ_BEGIN(idOther, AcDb::kForRead, TDbWall, pWall); if (pWall) { cvEnd = pWall->GetRelativeOffsetCurveFromCenter(nSide, nRatio, GetEndPoint()); bContinue = TRUE; bSameStyle = TRUE; } OPENOBJ_END(); } else { AcDbObjectId idOther; int stOther; if (nSide == 0) { idOther = lstIdStyles.Tail()->id; stOther = lstIdStyles.Tail()->GetPriority(); } else { idOther = lstIdStyles.Head()->id; stOther = lstIdStyles.Head()->GetPriority(); } OPENOBJ_BEGIN(idOther, AcDb::kForRead, TDbWall, pWall); if (pWall) { bSameStyle = (stOther == GetPriority()); if (bSameStyle) { cvEnd = pWall->GetRelativeOffsetCurveFromCenter(nSide, nRatio, GetEndPoint()); } else { cvEnd = pWall->GetRelativeSideCurve(nSide, GetEndPoint(), 0.0, FALSE); } bContinue = TRUE; if (!bSameStyle) //附加裁剪线 { AcDbObjectId idAdd; if (nSide == 0) { idAdd = lstIdStyles.Head()->id; } else { idAdd = lstIdStyles.Tail()->id; } ASSERT(idAdd != idOther); OPENOBJ_BEGIN(idAdd, AcDb::kForRead, TDbWall, pAdd); if (pAdd) { cvAddition = pAdd->GetRelativeSideCurve(nOppsiteSide, GetEndPoint(), 0.0, FALSE); bAddition = TRUE; } OPENOBJ_END(); } } OPENOBJ_END(); } } } if (bContinue) { cvEnd.SetLineFlag(LS_INFINITE); cvInitCurve.SetLineFlag(LS_INFINITE); cvEnd.SetElevation(nElev); if (cvEnd.Is(CURVE_LINE) && cvInitCurve.Is(CURVE_LINE)) { //modify by xlc on 091113 解决墙体显示不正常问题 double dPrec = sin(PI / 36); TPushMemVar temp(_angSnap, dPrec);//临时改变角度精度,小于5度时当作平行处理 if (IsSameDrt(cvEnd.TGGeLine::Direction(), cvInitCurve.TGGeLine::Direction(), _angSnap)) { bParell = TRUE; } } if (!bParell) { TADSGePoint3d ptInters[2]; int nIntNum = cvInitCurve.Intersection(cvEnd, ptInters[0], ptInters[1]); //add by xlc on 110121 特殊处理的直墙和弧墙连接 if (bFlag) { cvEndThis.SetLineFlag(LS_INFINITE); cvEndOther.SetLineFlag(LS_INFINITE); TADSGePoint3d ptInters0[2], ptInters2[2]; int nIntNum0 = cvInitCurveThis.Intersection(cvEndThis, ptInters0[0], ptInters0[1]); int nIntNum2 = cvInitCurveThis.Intersection(cvEndOther, ptInters2[0], ptInters2[1]); TADSGePoint3d ptInters3[2], ptInters4[2]; int nIntNum3=0, nIntNum4=0; nIntNum3 = cvInitCurveOther.Intersection(cvEndOther, ptInters3[0], ptInters3[1]); nIntNum4 = cvInitCurveOther.Intersection(cvEndThis, ptInters4[0], ptInters4[1]); if ((nIntNum0 == 0 && nIntNum2 != 0) || (nIntNum0 != 0 && nIntNum2 == 0) || (nIntNum3 == 0 && nIntNum4 != 0) || (nIntNum3 != 0 && nIntNum4 == 0) || (nIntNum0 == 0 && nIntNum4 != 0) || (nIntNum0 != 0 && nIntNum4 == 0) || (nIntNum3 == 0 && nIntNum2 != 0) || (nIntNum3 != 0 && nIntNum2 == 0))// 特殊处理的情况 { if (ptInitEnd.Distance2d(cvEndThis.StartPoint()) < ptInitEnd.Distance2d(cvEndThis.EndPoint())) { cvEnd.SetStartPoint(cvEndThis.StartPoint()); cvEnd.SetEndPoint(cvEndOther.StartPoint()); } else { cvEnd.SetStartPoint(cvEndOther.EndPoint()); cvEnd.SetEndPoint(cvEndThis.EndPoint()); } cvEnd.SetBulge(0.0); nIntNum = cvInitCurve.Intersection(cvEnd, ptInters[0], ptInters[1]); } } if (nIntNum == 1) { ptInitEnd = ptInters[0]; } else if (nIntNum == 2) { ptInitEnd = TGGeLine(ptInters[0], ptInters[1]).NearPoint(cvInitCurve.GetEndPoint()); } else //无交点,平行 { bParell = TRUE; } } if (bAddition) { TADSGePoint3d ptInters[2]; TADSGePoint3d ptInt; cvAddition.SetLineFlag(LS_INFINITE); cvAddition.SetElevation(nElev); int nIntNum = cvInitCurve.Intersection(cvAddition, ptInters[0], ptInters[1]); if (nIntNum == 1) { ptInt = ptInters[0]; } else if (nIntNum == 2) { //modify by xlc on 100809 解决多分支连接缺线问题 //ptInt = TGGeLine(ptInters[0], ptInters[1]).NearPoint(cvInitCurve.GetEndPoint()); ptInt = TGGeLine(ptInters[0], ptInters[1]).NearPoint(cvInitCurve.GetEndPoint()); } if (ptInitStart.Distance2d(ptInt) < ptInitStart.Distance2d(ptInitEnd)) { ptInitEnd = ptInt; } } } } cvInitCurve.SetPoints(ptInitStart, ptInitEnd); return cvInitCurve; } // 取得墙的最终偏移线, 考虑柱子裁剪 TGGeCurveSegment TWallData::GetFinalOffsetCurveFromCenter(int nSide, double nRatio) const { TGGeCurveSegment cvOffset = GetStdOffsetCurveFromCenter(nSide, nRatio); cvOffset.SetLineFlag(LS_FINITE); TDPtrList lstSegLeft, lstSegRight; TGGePoly2D sPoly(1), ePoly(1); if (!!m_idColuStart) { OPENOBJ_BEGIN(m_idColuStart, AcDb::kForRead, TDbColumn, pStart); if (pStart) { pStart->GetOutline(sPoly); } OPENOBJ_END(); } if (!!m_idColuEnd) { OPENOBJ_BEGIN(m_idColuEnd, AcDb::kForRead, TDbColumn, pEnd); if (pEnd) { pEnd->GetOutline(ePoly); } OPENOBJ_END(); } TDPtrList lstSource, lstIn, lstOut, lstEdge; lstSource.Append(new TGGeCurveSegment(cvOffset)); for (int nFrom = 0; nFrom < 2; nFrom++) { //起点裁剪和终点裁剪 TGGePoly2D &poly = nFrom ? ePoly : sPoly; if (!!poly) { lstOut.Reset(); PolyClip(lstSource, poly, lstIn, lstOut, lstEdge); lstSource.Reset(); for (int i = 0; i < lstOut.Length(); i++) { lstSource.Append(new TGGeCurveSegment(*lstOut[i])); } } } // 取裁剪后最长的边线作为代表(经验解) int nRetCode = 0; if (!lstSource) { ; } else { TGGeCurveSegment *pMax = lstSource[0]; for (int i = 1; i < lstSource.Length(); i++) { if (lstSource[i]->GetLength() > pMax->GetLength()) { pMax = lstSource[i]; } } cvOffset = *pMax; } return cvOffset; } // 计算两侧的参数 // 参数: // entThis--Wall实体或变双线前的实体 // Note: 考虑了基面标高 // 修改历史: // 1998.3.7 求交时忽略Z坐标 // 重大变动 int TWallData::CalSideParameters(const TEntitySet &entThis, TDPtrList &lstAllSortedWalls, TGGeRectAngle *pBox) { int nRetRes = 0; ASSERT(!Is(CURVE_CIRCLE)); TADSGePoint3d ptTest; for (int nCorner = 0; nCorner < 2; nCorner++) // 0--起点,1--终点 { TADSGePoint3d &ptCorner = nCorner ? EndPoint() : StartPoint(); if (pBox) { if (!(ptCorner.x>pBox->lowLeft.x && ptCorner.y>pBox->lowLeft.y && ptCorner.xupRight.x && ptCorner.yupRight.y)) { continue; //不在指定范围内 } } TSortWallOnPt *ptrSortWall = lstAllSortedWalls.FindNode(&ptCorner, CmpSortWallLoc); ASSERT(ptrSortWall); if (!ptrSortWall) { //当重合时可能找不到 continue; } // 取得端点的排序墙 TSortWallOnPt &lstSortedWalls = *ptrSortWall; //add by xlc on 110106 解决墙角插圆柱时墙角缺口的问题 bool bColu = false; //是否有柱子 TGGePoly2D polyColu; //柱子 OPENOBJ_BEGIN(lstSortedWalls.m_idColumn, AcDb::kForRead, TDbColumn, pColu); if (pColu) { pColu->GetOutline(polyColu); //add by xlc on 110311 确定点跟柱子在同一平面内 ptTest = ptCorner; if (polyColu.Length() > 0) { ptTest.z = polyColu[0]->z; } bColu = true; } OPENOBJ_END(); if (nCorner == 0) { m_idColuStart = lstSortedWalls.m_idColumn; //add by xlc on 110106 解决墙角插圆柱时墙角缺口的问题 if (bColu) //add by xlc on 110106 解决墙角插圆柱时墙角缺口的问题 if (bColu) { if( (ptTest&polyColu) == PR_OUTSIDE) { m_idColuStart.setNull(); } } } else { m_idColuEnd = lstSortedWalls.m_idColumn; //add by xlc on 110106 解决墙角插圆柱时墙角缺口的问题 if (bColu) { if( (ptTest&polyColu) == PR_OUTSIDE) { m_idColuEnd.setNull(); } } } TGGiWallVector *ptrVectorTemp = lstSortedWalls.FindNode(&entThis, TGGiWallVector::FindByEntity); if (!ptrVectorTemp) { //当重合时可能找不到 continue; } ASSERT(lstSortedWalls.Length()); int i = lstSortedWalls.CurPosition(); BOOL bSamePrev = TRUE, bSameNext = TRUE; //没有用 // 调整双线 TGGiWallVector *prevWall = lstSortedWalls.GetPrevWall(i, &bSamePrev); TGGiWallVector *nextWall = lstSortedWalls.GetNextWall(i, &bSameNext); if (nextWall) { acdbGetObjectId(nCorner == 0 ? m_idLeftStart : m_idRightEnd, nextWall->pWall->m_ent); } else { (nCorner == 0 ? m_idLeftStart : m_idRightEnd) = AcDbObjectId::kNull; } if (prevWall) { acdbGetObjectId(nCorner == 0 ? m_idRightStart : m_idLeftEnd, prevWall->pWall->m_ent); } else { (nCorner == 0 ? m_idRightStart : m_idLeftEnd) = AcDbObjectId::kNull; } // Add on 2002/4/5 if (prevWall && (prevWall == nextWall)) { int nCmp = CompareWallStyle(GetPriority(), prevWall->pWall->GetPriority()); if (nCmp > 0) { m_nWallFlag |= (nCorner ? WF_END_TERM : WF_START_TERM); } else { m_nWallFlag &= ~(nCorner ? WF_END_TERM : WF_START_TERM); } } else { m_nWallFlag &= ~(nCorner ? WF_END_TERM : WF_START_TERM); } } return RTNORM; } void TWallData::CalSideParameters1(TGGeRectAngle *pBox) { TGGeCurveSegment curSegLeft = Offset(OFFSET_LEFT, GetWidth(0), LS_FINITE); TGGeCurveSegment curSegRight = Offset(OFFSET_RIGHT, GetWidth(1), LS_FINITE); TGGeCurveSegment cvStdLeft, cvStdRight; cvStdLeft = GetFinalSideCurve(OFFSET_LEFT, 0.0, FALSE); cvStdRight = GetFinalSideCurve(OFFSET_RIGHT, 0.0, FALSE); for (int nCorner = 0; nCorner < 2; nCorner++) // 0--起点,1--终点 { TADSGePoint3d &ptCorner = nCorner ? EndPoint() : StartPoint(); if (pBox) { if (!(ptCorner.x > pBox->lowLeft.x && ptCorner.y > pBox->lowLeft.y && ptCorner.x < pBox->upRight.x && ptCorner.y < pBox->upRight.y)) { continue; //不在指定范围内 } } if (nCorner == 0) { m_nFromLeftStart = curSegLeft.PathDistance(cvStdLeft.GetStartPoint(), TRUE); m_nFromRightStart = curSegRight.PathDistance(cvStdRight.GetStartPoint(), TRUE); } else { m_nFromLeftEnd = curSegLeft.PathDistance(cvStdLeft.GetEndPoint(), FALSE); m_nFromRightEnd = curSegRight.PathDistance(cvStdRight.GetEndPoint(), FALSE); } } } // 是否为单甩端点 BOOL TWallData::IsTermAt(int nTerm) const { BOOL bTerm = FALSE; if (nTerm) { //removed by W on 081016 //if (m_idColuEnd.isValid()) // return bTerm; if ((!m_idRightEnd.isValid() && !m_idLeftEnd.isValid()) || (m_nWallFlag & WF_END_TERM)) { bTerm = TRUE; } } else { //removed by w on 081016 //if (m_idColuStart.isValid()) // return bTerm; if ((!m_idRightStart.isValid() && !m_idLeftStart.isValid()) || (m_nWallFlag & WF_START_TERM)) { bTerm = TRUE; } } if (!bTerm) { TDPtrList lstIdStyle; GetIdStyles(nTerm, lstIdStyle); if (!lstIdStyle) { bTerm = TRUE; } else if (lstIdStyle.Length() == 1) { if (lstIdStyle.Head()->GetPriority() < GetPriority()) { bTerm = TRUE; } } } return bTerm; } // New method on 2002/4/5 // 按逆时针方向,以pt点为起点的射线,找下一个墙 AcDbObjectId TWallData::GetNextWall(TADSGePoint3d pt) const { AcDbObjectId id; if (pt.Distance2d(GetStartPoint()) < pt.Distance2d(GetEndPoint())) //起点 { id = m_idLeftStart; } else { id = m_idRightEnd; } return id; } // nSide: 0--start; 1--end; // 以端点出发的射线为起始轴,按逆时针排序,不包括自己 void TWallData::GetIdStyles(int nSide, TDPtrList &lstIdStyle) const { AcDbObjectId idMe = GetMyObjectId(); lstIdStyle.Reset(); if (nSide == 0) //起点方向 { if (m_idLeftStart == m_idRightStart) //单甩或双分支 { if (!m_idLeftStart) //单甩 { ; } else //双分支 { OPENOBJ_BEGIN(m_idLeftStart, AcDb::kForRead, TDbWall, pWall); if (pWall && pWall->GetUsageFlag() != TWallData::kVirtual) { lstIdStyle.Append(new IdDotStyle(m_idLeftStart, pWall->GetPriority())); } OPENOBJ_END(); } } else //多个分支 { AcDbObjectId idNext = m_idLeftStart; long count = 0; while(!!idNext) { if ((++count) == 500) //防止有虚墙时的死循环,add by W on 070627 { break; } if (idNext == idMe) { break; } OPENOBJ_BEGIN(idNext, AcDb::kForRead, TDbWall, pWall); if (pWall) { if (lstIdStyle.FindNode(&idNext, CompareIdDotStyleForFind)) { break; } else if (pWall->GetUsageFlag() != TWallData::kVirtual) { lstIdStyle.Append(new IdDotStyle(idNext, pWall->GetPriority())); } if (idNext == m_idRightStart) { break; } idNext = pWall->GetNextWall(GetStartPoint()); } else { break; } OPENOBJ_END(); } } } else //终点方向 { if (m_idRightEnd == m_idLeftEnd) //单甩或双分支 { if (!m_idRightEnd) //单甩 { ; } else //双分支 { OPENOBJ_BEGIN(m_idRightEnd, AcDb::kForRead, TDbWall, pWall); if (pWall && pWall->GetUsageFlag() != TWallData::kVirtual) { lstIdStyle.Append(new IdDotStyle(m_idRightEnd, pWall->GetPriority())); } OPENOBJ_END(); } } else //多个分支 { AcDbObjectId idNext = m_idRightEnd; long count = 0; while (!!idNext) { if ((++count) == 500) //防止有虚墙时的死循环,add by W on 070627 { break; } if (idNext == idMe) { break; } OPENOBJ_BEGIN(idNext, AcDb::kForRead, TDbWall, pWall); if (pWall) { if (lstIdStyle.FindNode(&idNext, CompareIdDotStyleForFind)) { break; } else if (pWall->GetUsageFlag() != TWallData::kVirtual) { lstIdStyle.Append(new IdDotStyle(idNext, pWall->GetPriority())); } if (idNext == m_idLeftEnd) { break; } idNext = pWall->GetNextWall(GetEndPoint()); } else { break; } OPENOBJ_END(); } } } } int TWallData::GetStyleCount(int st, const TDPtrList &lstStyles) const { int nCount = 0; for (int i = 0; i < lstStyles.Length(); i++) { if (lstStyles[i].GetPriority() == st) { nCount++; } } return nCount; } void TWallData::GetStyleKindArray(const TDPtrList &lstStyles, AcDbIntArray &intArray) const { for (int i = 0; i < lstStyles.Length(); i++) { int st = int(lstStyles[i].GetPriority()); if (!intArray.contains(st)) { intArray.append(st); } } } int TWallData::GetAnotherStyle(int st, const TDPtrList &lstStyle) const { for (int i = 0; i < lstStyle.Length(); i++) { if (lstStyle[i].GetPriority() != st) { return lstStyle[i].GetPriority(); } } return st; } AcDbObjectId TWallData::GetSameStyleId(int st, const TDPtrList &lstStyle, BOOL bReverse) const { AcDbObjectId idRet; if (bReverse) { for (int i = lstStyle.Length() - 1; i >= 0; i--) { if (lstStyle[i].GetPriority() == st) { idRet = lstStyle[i].id; break; } } } else { for (int i = 0; i < lstStyle.Length(); i++) { if (lstStyle[i].GetPriority() == st) { idRet = lstStyle[i].id; break; } } } return idRet; } int TWallData::CompareIdDotStyleForFind(const IdDotStyle *p1, const void *p2) { const AcDbObjectId &id = *(const AcDbObjectId *)p2; if (id == p1->id) { return 0; } return 1; } void TWallData::SetUsageFlag(UsageFlag flg) { m_nUsageFlag = flg; } void TWallData::UpdateWallWidth() { } BOOL TWallData::IsInsulateOnSide(int nSide) const { int nBitFlag = nSide == OFFSET_LEFT ? WF_LEFT_INSULATE : WF_RIGHT_INSULATE; return ((m_nWallFlag & nBitFlag) != 0); } // 增加或移除保温 void TWallData::SetInsulateOnSide(int nSide, BOOL bAdd) { int nBitFlag = nSide == OFFSET_LEFT ? WF_LEFT_INSULATE : WF_RIGHT_INSULATE; if (bAdd) { m_nWallFlag |= nBitFlag; } else { m_nWallFlag &= ~nBitFlag; } } void TWallData::SetInsulateThick(double nThick, int nSide/* = 0*/) { int nLThick = 0; int nRThick = 0; DoubleToTowInt(m_nInsuThick,nLThick,nRThick); if (nSide == 0) { m_nInsuThick = TowIntToDouble((int)nThick,nRThick); } else { m_nInsuThick = TowIntToDouble(nLThick,(int)nThick); } //如果保温是0则去掉有保温属性 2011-6-23 if (nThick < 1.E-5) { SetInsulateOnSide(nSide,FALSE); } } double TWallData::GetInsulateThick(int nSide/* = 0*/) const { int nLThick = 0; int nRThick = 0; DoubleToTowInt(m_nInsuThick,nLThick,nRThick); if (nSide == 0) { return nLThick; } return nRThick; } BOOL TWallData::HasTop() const { return ((m_nWallFlag & WF_TOP) != 0); } BOOL TWallData::HasBottom() const { return ((m_nWallFlag & WF_BOTTOM) != 0); } void TWallData::SetTop(BOOL bTrue) { if (bTrue) { m_nWallFlag |= WF_TOP; } else { m_nWallFlag &= ~WF_TOP; } } void TWallData::SetBottom(BOOL bTrue) { if (bTrue) { m_nWallFlag |= WF_BOTTOM; } else { m_nWallFlag &= ~WF_BOTTOM; } } Acad::ErrorStatus TWallData::SetWidth(int nSide, double nw) { if (nSide) { m_rWidth = nw; } else { m_lWidth = nw; } return Acad::eOk; } Acad::ErrorStatus TWallData::SetHeight(double nh) { m_nHeight = nh; return Acad::eOk; } void TWallData::SetStyle(TWallStyle st) { m_style = st; } int TWallData::GetWallFlag() const { return m_nWallFlag; } void TWallData::SetWallFlag(int nFlag) { m_nWallFlag = nFlag; UpdateWallWidth(); //玻璃幕墙,需要重新计算左右宽度 } void TWallData::SetFlagData(int nFlag) { m_nWallFlag = nFlag; } BOOL TWallData::HasColumnAt(int nTerm) const { return nTerm ? !!m_idColuEnd : !!m_idColuStart; } TWallData::UsageFlag TWallData::GetUsageFlag() const { return m_nUsageFlag; } double TWallData::GetWidth() const { return fabs(m_rWidth + m_lWidth); } double TWallData::GetHeight() const { return m_nHeight; } double TWallData::GetElevation() const { return GetStartPoint().z; } TWallData::TWallStyle TWallData::GetStyle() const { return m_style; } AcDbObjectId TWallData::GetStartColumnId() const { return m_idColuStart; } AcDbObjectId TWallData::GetEndColumnId() const { return m_idColuEnd; } void TWallData::RemoveColumn(AcDbObjectId idColumn) { if (idColumn == m_idColuStart) { m_idColuStart = NULL; } if (idColumn == m_idColuEnd) { m_idColuEnd = NULL; } CalSideParameters1(); } BOOL TWallData::Has3D() const { return (m_nHeight > _DIST_SNAP && GetUsageFlag() != kVirtual); } int TWallData::GetPriority()const { if (GetUsageFlag() != TWallData::kParapet) { return GetStyle(); } else { return -1000000 + (int)GetHeight(); } } int TWallData::CompareWallStyle(int st1, int st2) const { if (st1 == st2) { return 0; } else if (st1 > st2) { return 1; } return -1; } AcDbObjectId TWallData::GetMyObjectId() const { return AcDbObjectId::kNull; } AcDbObjectId TWallData::GetMyOwnerId()const { return AcDbObjectId::kNull; } //墙保温增加-wlw BOOL TWallData::HasInsulateCap() const { return ((m_nWallFlag & WF_INSULATE_CAP) != 0); } void TWallData::SetInsulateCap(BOOL bTrue) { if (bTrue) { m_nWallFlag |= WF_INSULATE_CAP; } else { m_nWallFlag &= ~WF_INSULATE_CAP; } } BOOL TWallData::HasInsulateEnd() const { return ((m_nWallFlag & WF_INSULATE_END) != 0); } void TWallData::SetInsulateEnd(BOOL bTrue) { if (bTrue) { m_nWallFlag |= WF_INSULATE_END; } else { m_nWallFlag &= ~WF_INSULATE_END; } } void TWallData::DoubleToTowInt(double dSrc, int& nLeftThick,int& nRightThick) const { nLeftThick = nRightThick = 0; int n; CString str; str.Format(_T("%.3f"),dSrc);//3小数位 n = str.Find(_T("."));//整数位 CString sLeftThick, sRightThick; sLeftThick = str.Left(n); sRightThick = str.Right(3); nLeftThick = _ttoi(sLeftThick); nRightThick = _ttoi(sRightThick); //如果保温只给了整数,那么默认左右保温相同 if (nRightThick < 1.E-5) { nRightThick = nLeftThick; } } double TWallData::TowIntToDouble(int nLeftThick, int nRightThick) const { //wlw mod 100914 取3小数位 double dThick = nLeftThick + nRightThick * 0.001; //四舍五入 dThick += 0.000000001; return dThick; } //add by xlc on 101110 墙体材料字符串 CString TWallData::GetStyle(TWallStyle st)const { CString strMaterial(WALLMATE_NoDefine); switch (st) { case kDivider: strMaterial = WALLMATE_Divider; break; case kCurtain: strMaterial = WALLMATE_Curtain; break; case kRocket: strMaterial = WALLMATE_Rocket; break; case kBrick: strMaterial = WALLMATE_Brick; break; case kConcrete: strMaterial = WALLMATE_Concrete; break; case kFill: strMaterial = WALLMATE_Fill; break; case kFill1: strMaterial = WALLMATE_Fill1; break; case kFill2: strMaterial = WALLMATE_Fill2; break; } return strMaterial; } //add by xlc on 101110 墙体用途字符串 CString TWallData::GetUsageFlag(UsageFlag flg)const { CString strUse(_T("交互")); switch (flg) { case kNormal: strUse = _T("一般墙"); break; case kApartment: strUse = _T("卫生断墙"); break; case kVirtual: strUse = _T("虚墙"); break; case kParapet: strUse = _T("矮墙"); break; } return strUse; }