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

1334 lines
36 KiB
C++

#include "stdafx.h"
#include "TSearchSpaceFromWall.h"
#include "TAecSpaceWall.h"
#include "TchKernalGlobalFunc.h"
#include "TArchCmdReactor.h"
#include "OpeningLabelData.h"
ACRX_DXF_DEFINE_MEMBERS(ATSBandWin,ATSCornerWin,AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
1, ATS_CORNER_WINDOW, "ATS_CORNER_WINDOW图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
const Adesk::UInt8 TDbBandWin::g_nVersion=0;
//add by xlc on 110310 带形窗里忽略墙体材料
BOOL g_bSkipWallMaterial = FALSE;
IMPLEMENT_TENTBASE(TDbBandWin);
TDbBandWin::TDbBandWin():m_polyFirst(0),m_polyFirstBase(0)
{
}
BOOL TDbBandWin::IsValid()const
{
if(!TDbCornerWin::IsValid())
return FALSE;
if(m_polyFirst.TotalSegments()!=GetWallNum()||
m_polyFirstBase.TotalSegments()!=GetWallNum())
return FALSE;
//add by whl on 060210
for(long i=0;i<GetWallNum();i++)
if(GetWallId(i).isNull())
return FALSE;
return TRUE;
}
void TDbBandWin::SetMidWallIds(const DList<AcDbObjectId>&idWalls)
{
assertWriteEnabled();
m_idMidWalls.Reset();
for(long i=0;i<idWalls.Length();i++)
m_idMidWalls.Append(new AcDbSoftPointerId(idWalls[i]));
}
AcDbObjectId TDbBandWin::GetWallId(long i)const
{
assertReadEnabled();
if(i==0)
return m_idWall1;
else if(i<GetWallNum()-1)
return m_idMidWalls[i-1];
else
return m_idWall2;
}
// sg add 101115,根据8.5需求调整默认标注位置,返回默认标注墙ID编号
long TDbBandWin::GetDefaultLabelWallNum() const
{
long nIdIndex = (GetWallNum()-1)/2;
return nIdIndex;
}
void TDbBandWin::SetWallId(long i,const AcDbObjectId&id)
{
assertWriteEnabled();
//add by whl on 060210
if(i<0||i>=GetWallNum())
return;
if(i==0)
m_idWall1=id;
else if(i<GetWallNum()-1)
*m_idMidWalls[i-1]=id;
else
m_idWall2=id;
}
XPoly2D *g_pPolyOfBase=NULL;
int CompareWallByPolyPath(const AcDbSoftPointerId* idWall1,const AcDbSoftPointerId* idWall2)
{
double dist1=0,dist2=0;
TDbWall*pWall1=NULL,*pWall2=NULL;
acdbOpenObject(pWall1,*idWall1,AcDb::kForRead);
if(pWall1!=NULL)
{
dist1=g_pPolyOfBase->PathDistance2d(pWall1->MidPoint());
pWall1->close();
}
acdbOpenObject(pWall2,*idWall2,AcDb::kForRead);
if(pWall2!=NULL)
{
dist2=g_pPolyOfBase->PathDistance2d(pWall2->MidPoint());
pWall2->close();
}
if(dist1>dist2)
return 1;
else if(dist1<dist2)
return -1;
else
return 0;
}
BOOL TDbBandWin::UpdateParameters()
{
assertWriteEnabled();
try
{
//removed by whl on 060214
//m_polyFirst.Reset();
//m_polyFirstBase.Reset();
XPoint ptStart=m_ptStart, ptEnd=m_ptEnd;
//PickSet ssWalls(SS_FREE);
DList<AcDbObjectId> ssWalls;
for(long i=0;i<GetWallNum();i++)
{
AcDbObjectId id=GetWallId(i);
if(!id.isNull())
ssWalls.Append(new AcDbObjectId(id));
}
Entity eStart,eEnd;
if(acdbGetAdsName(eStart.name,m_idWall1)!=Acad::eOk||
acdbGetAdsName(eEnd.name,m_idWall2)!=Acad::eOk)
return FALSE;
XAecSpaceWall *pWallStart=NULL, *pWallEnd=NULL;
// 寻找外墙
DList<AcDbObjectId> lstColu;
//GetEntFromBlockByDxf(lstColu, _T("ATS_COLUMN"));
XSearchSpaceFromWall aSearch;
try {
aSearch.InitStart(ssWalls, lstColu);
} catch(...) {
return FALSE;
}
int nWallNum=aSearch.walls.Length();
for(i=0; i<nWallNum; i++) {
XAecSpaceWall *pWall=aSearch.walls[i];
if(pWall->m_ent == eStart)
pWallStart=pWall;
if(pWall->m_ent == eEnd)
pWallEnd = pWall;
}
if(!pWallStart||!pWallEnd)
return FALSE;
//add by xlc on 110310 忽略墙体材料
TPushMemVar<BOOL> vTemp1(g_bSkipWallMaterial, TRUE);
XPoly2D polyPath;
if(aSearch.SearchPath(*pWallStart, *pWallEnd, polyPath, TRUE)==RTNORM)
{
XPoly2D polyPathOnBase;
if(aSearch.SearchPath(*pWallStart, *pWallEnd, polyPathOnBase, FALSE)!=RTNORM)
return FALSE;
//add by whl on 060215
if(!polyPathOnBase||!polyPath)
return FALSE;
//add by whl on 060214
m_polyFirst.Reset();
m_polyFirstBase.Reset();
XCurveSegment segStart1, segEnd1, segStart2, segEnd2;
polyPath.Nth(0, segStart1);
polyPath.Nth(polyPath.TotalSegments()-1, segEnd1);
polyPathOnBase.Nth(0, segStart2);
polyPathOnBase.Nth(polyPathOnBase.TotalSegments()-1, segEnd2);
XPoint ptBrkS1, ptBrkE1, ptBrkS2, ptBrkE2;
segStart1.ProjectToMe(ptStart, ptBrkS1);
segEnd1.ProjectToMe(ptEnd, ptBrkE1);
segStart2.ProjectToMe(ptStart, ptBrkS2);
segEnd2.ProjectToMe(ptEnd, ptBrkE2);
polyPath.SetFlag(1); //封闭
polyPathOnBase.SetFlag(1);
XPoly2D polySecond(0),polySecondBase(0);
if(SplitPoly2D(polyPath, ptBrkS1, ptBrkE1, m_polyFirst, polySecond)!=RTNORM)
return FALSE;
if(SplitPoly2D(polyPathOnBase, ptBrkS2, ptBrkE2, m_polyFirstBase, polySecondBase)!=RTNORM)
return FALSE;
if(m_polyFirst.TotalSegments()!=GetWallNum()||m_polyFirst.Length()!=m_polyFirstBase.Length())
return FALSE;
m_ptStart=ptBrkS1;
m_ptEnd=ptBrkE1;
m_polyFirstBase.Nth(0,segStart2);
m_nWidth1=segStart2.GetLength();
m_polyFirstBase.Nth(GetWallNum()-1,segEnd2);
m_nWidth2=segEnd2.GetLength();
}
else
return FALSE;
XPushMemVar<XPoly2D*> vTemp(g_pPolyOfBase,&m_polyFirstBase);;
m_idMidWalls.QuickSort(CompareWallByPolyPath);
}
catch(...)
{
return FALSE;
}
return TRUE;
}
BOOL TDbBandWin::GetKeyCurves(XPoly2D&polyInside,XPoly2D&polyGlass1,XPoly2D&polyGlass2,XPoly2D&polyOutSide)const
{
if(!IsValid())
return FALSE;
polyInside=m_polyFirstBase;
polyGlass1=polyGlass2=polyOutSide=m_polyFirst;
return TRUE;
}
//转化为带形窗(T5转角窗),调用程序负责释放delete
TDbOpening *TDbBandWin::GetOpening(long n) const
{
if(n<0||n>=GetWallNum())
return NULL;
XCurveSegment seg, segBase;
m_polyFirst.Nth(n, seg);
//add by xlc on 110311 墙体单侧带保温时,中线不正确
AcDbObjectId idWall = GetWallId(n);
OPENOBJ_BEGIN(idWall,AcDb::kForRead, TDbWall, pWall);
if (pWall)
{
seg = pWall->OffsetGeomCenter(LS_INFINITE, TRUE);
}
OPENOBJ_END();
m_polyFirstBase.Nth(n, segBase);
XPoint ptMid0=segBase.MidPoint();
XPoint ptMid;
seg.ProjectToMe(ptMid0, ptMid);
ptMid.z=GetElevation();
TDbOpening *pOp=new TDbOpening;
pOp->setPropertiesFrom(this);
pOp->m_ptLocation = ptMid;
pOp->SetWidth(segBase.GetLength());
pOp->SetKind(TOpeningData::OP_CORNWIN);
pOp->SetLabel(GetLabel());
pOp->SetHeight(GetHeight());
pOp->m_ptLabel = GetLabelPos();
pOp->m_nRotation =(segBase.EndPoint()-segBase.StartPoint()).AsAcGeVector2d().angle();
pOp->m_nIdOfWall =GetWallId(n);
pOp->SetTextStyle(m_idTextStyle);
pOp->SetTextHeight(GetTextHeight());
return pOp;
}
void TDbBandWin::ValidateContainership(DList<AcDbObjectId> &lstWalls)
{
assertWriteEnabled();
AcDbObjectIdArray idArray;
int validCount=0;
for(int idx=0; idx<GetWallNum(); idx++)
{
AcDbObjectId idWall=GetWallId(idx);
if(!idWall)
continue;
OPENOBJ_BEGIN(idWall, AcDb::kForRead, TDbWall, pWall);
if(pWall)
{
TDbOpening *pOp=AsOpening(pWall);
if(pOp)
{
if(!pWall->CanContain(*pOp))
{
if(pWall->upgradeOpen()==Acad::eOk)
{
pWall->assertWriteEnabled();
pWall->RemoveReferenceOpening(objectId());
SetWallId(idx,AcDbObjectId::kNull);
pWall->downgradeOpen();
}
}
else
{ //确保互相引用关系
if(pWall->upgradeOpen()==Acad::eOk)
{
pWall->AddOpeningId(objectId());
pWall->downgradeOpen();
}
validCount++;//到了这里表示状态良好。
}
delete pOp;
}
}
OPENOBJ_END();
}
// 如果配属关系不全,则重新建立
if(validCount<GetWallNum()&&
m_polyFirstBase.TotalSegments()==GetWallNum())
{
validCount=0;
XCurveSegment cvFirst,cvLast;
m_polyFirstBase.Nth(0,cvFirst);
m_polyFirstBase.Nth(m_polyFirstBase.TotalSegments()-1,cvLast);
for(long i=0; i<lstWalls.Length(); i++)
{
AcDbObjectId idWall=*lstWalls[i];
OPENOBJ_BEGIN(idWall, AcDb::kForWrite, TDbWall, pWall);
if(pWall)
{
int nRet1=pWall->HitTest2d(cvFirst.StartPoint()),nRet2=pWall->HitTest2d(cvFirst.EndPoint());
if(nRet1>2&&nRet1<6&&
nRet2>2&&nRet2<6)
{
m_idWall1=idWall;
pWall->AddOpeningId(objectId());
validCount++;
}
else
{
int nRet1=pWall->HitTest2d(cvLast.StartPoint()),nRet2=pWall->HitTest2d(cvLast.EndPoint());
if(nRet1>2&&nRet1<6&&
nRet2>2&&nRet2<6)
{
m_idWall2=idWall;
pWall->AddOpeningId(objectId());
validCount++;
}
else
{
int nRet=m_polyFirstBase.HitTestOnCurve(pWall->MidPoint(),20);
if(nRet<0)//命中边
{
SetWallId(-nRet-1,idWall);
pWall->AddOpeningId(objectId());
validCount++;
}
}
}
}
OPENOBJ_END();
}
}
if(validCount>=GetWallNum())
if(UpdateParameters())
return;
for(idx=0; idx<GetWallNum(); idx++)
{
TDbWall*pWall=NULL;
acdbOpenObject(pWall,GetWallId(idx), AcDb::kForWrite);
if(pWall!=NULL)
{
pWall->RemoveReferenceOpening(objectId());
pWall->close();
}
}
}
void TDbBandWin::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag)
{
assertWriteEnabled();
TDbCornerWin::CopyPropertiesFrom(pSrcEntity, gMatchFlag);
TDbBandWin *pSrc=TDbBandWin::cast(pSrcEntity);
if(pSrc)
{
//removed by whl on 060210
//m_idMidWalls.Reset();
//for(long i=0;i<pSrc->m_idMidWalls.Length();i++)
// m_idMidWalls.Append(new AcDbSoftPointerId(*pSrc->m_idMidWalls[i]));
//m_polyFirst=pSrc->m_polyFirst;
//m_polyFirstBase=pSrc->m_polyFirstBase;
//m_ptStart=pSrc->m_ptStart;
//m_ptEnd=pSrc->m_ptEnd;
}
}
Acad::ErrorStatus TDbBandWin::ExplodeOrDraw2d(XExplodeDraw&dc)const
{
assertReadEnabled();
if(!objectId()&&_tcsicmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0&&!dc.IsPlotGeneration())
dc<<m_polyFirst;
else if(IsHole())
{
if(_tcsicmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0&&!dc.IsPlotGeneration())
{
for(long i=1;i<m_polyFirst.Length()-1;i++)
{
const XPoint pt=m_polyFirst[i];
dc << XLine(pt,pt);
}
}
}
else
{
//add by xlc on 110310 忽略墙体材料
TPushMemVar<BOOL> vTemp1(g_bSkipWallMaterial, TRUE);
//bool bArc = false;
double dWidthL(0),dWidthR(0); // 左右墙宽
double dDir; // 带形窗端点处的切向
TADSGePoint3d ptStart,ptEnd;
for(long i=0;i<GetWallNum();i++)
{
TDbOpening*pOpening=GetOpening(i);
if(pOpening!=NULL)
{
XPushMemVar<BOOL> vTemp(g_bSubEntity,TRUE);
pOpening->SetLabel(_T(""));
if(dc.IsFullExplode())
{
XPushMemVar<AcDbDatabase*> vTemp0(g_pCurrentDb,database());
pOpening->ExplodeOrDraw2d(dc);
}
else
dc.DrawEntity(*pOpening);
// add by xlc on 100127 带形窗端头封口,捕捉状态就不画了
if (!g_bOsnapExpl)
{
// modify by xlc on 110517 弧墙计算有误差
//if (i == 0)
//{
// //del by xlc on 110406 弧墙添加封口,已在GetOutlinePoly中计算正确
// //modify by xlc on 110325 弧墙不添加封口
// //bArc = false;
// //OPENOBJ_BEGIN(m_idWall1,AcDb::kForRead, TDbWall, pWall);
// //if (pWall)
// //{
// // bArc = pWall->Is(CURVE_ARC);
// //}
// //OPENOBJ_END();
// //if (!bArc)
// {
// TGGePoly2D poly;
// pOpening->GetOutlinePoly(0, poly);
// TGGeCurveSegment cv;
// poly.Nth(2, cv);
// dc << cv;
// }
//}
//if (i == GetWallNum() - 1)
//{
// //del by xlc on 110406 弧墙添加封口,已在GetOutlinePoly中计算正确
// //modify by xlc on 110325 弧墙不添加封口
// //bArc = false;
// //OPENOBJ_BEGIN(m_idWall2,AcDb::kForRead, TDbWall, pWall);
// //if (pWall)
// //{
// // bArc = pWall->Is(CURVE_ARC);
// //}
// //OPENOBJ_END();
// //
// //if (!bArc)
// {
// TGGePoly2D poly;
// pOpening->GetOutlinePoly(0, poly);
// TGGeCurveSegment cv;
// poly.Nth(0, cv);
// dc << cv;
// }
//}
if (i == 0)
{
OPENOBJ_BEGIN(m_idWall1, AcDb::kForRead, TDbWall, pWall);
if (pWall)
{
dWidthL = dWidthR = (pWall->GetWidth(0) + pWall->GetWidth(1)) * 0.5;
if (pWall->IsInsulateOnSide(0))
{
dWidthL += pWall->GetInsulateThick(0);
}
if (pWall->IsInsulateOnSide(1))
{
dWidthR += pWall->GetInsulateThick(1);
}
dDir = pWall->Direction(m_ptStart);
ads_polar(TADSGePoint3d(m_ptStart), dDir+PI*0.5, dWidthL, ptStart);
ads_polar(TADSGePoint3d(m_ptStart), dDir-PI*0.5, dWidthR, ptEnd);
dc << TGGeLine(ptStart, ptEnd);
}
OPENOBJ_END();
}
if (i == GetWallNum() -1)
{
OPENOBJ_BEGIN(m_idWall2, AcDb::kForRead, TDbWall, pWall);
if (pWall)
{
dWidthL = dWidthR = (pWall->GetWidth(0) + pWall->GetWidth(1)) * 0.5;
if (pWall->IsInsulateOnSide(0))
{
dWidthL += pWall->GetInsulateThick(0);
}
if (pWall->IsInsulateOnSide(1))
{
dWidthR += pWall->GetInsulateThick(1);
}
dDir = pWall->Direction(m_ptEnd);
ads_polar(TADSGePoint3d(m_ptEnd), dDir+PI*0.5, dWidthL, ptStart);
ads_polar(TADSGePoint3d(m_ptEnd), dDir-PI*0.5, dWidthR, ptEnd);
dc << TGGeLine(ptStart, ptEnd);
}
OPENOBJ_END();
}
}
delete pOpening;
}
}
}
if((g_bExplodeSubText||!!m_sLabel) && !!m_idTextStyle)
{
// bug: 如果设置了图层,则插门的时候出错AcGi-SelectionMarker
// sg add 101222,根据8.5需求,带型窗支持隐藏编号
if (!g_bExplodeSubText && IsHideLabel())
return Acad::eOk;
TDbText textLabel;
textLabel.setPropertiesFrom(this);
//XString sStyleName=GetSymbolName(idTextStyle);
if(!!m_idLayerText)
textLabel.setLayer(m_idLayerText);
textLabel.SetStyleId(m_idTextStyle);
textLabel.SetLocation(XPoint(m_ptLabel.x, m_ptLabel.y));
textLabel.SetAlignment(XExplodeDraw::kMiddleCenter);
textLabel.SetRotation(xg_angle(m_nTextRotation));
textLabel.SetHeight(m_nTextHeight>1.0E-3? m_nTextHeight : 3.5);
XString sTemp;
sTemp=m_sLabel;
//modified by whl on 060223
//strupr(sTemp);
TDbConfig *pConfig=GetDwgGlobal(AcDb::kForRead, database());
if(pConfig && pConfig->IsCapLabel())
_tcsupr(sTemp);
if(pConfig) pConfig->close();
textLabel.SetText(sTemp);
TPushProperty vProp(&textLabel, dc);
if(dc.IsFullExplode()) {
textLabel.ExplodeOrDraw2d(dc);
} else
dc.DrawEntity(textLabel);
}
return Acad::eOk;
}
void TDbBandWin::GetTips(DList<TObjInfoUnit> &lstInfo) const
{
//add by whl
AcDbHandle h;
getAcDbHandle(h);
TCHAR pBuf[1024];
h.getIntoAsciiBuffer(pBuf);
lstInfo.Append(new TObjInfoUnit(_T("对象句柄"), pBuf));
lstInfo.Append(new TObjInfoUnit(_T("对象类型"), GetKindString()));
lstInfo.Append(new TObjInfoUnit(_T("门窗名称"), m_sLabel));
lstInfo.Append(new TObjInfoUnit(_T("宽度"), Dist2Str(GetWidth())));
lstInfo.Append(new TObjInfoUnit(_T("高度"), Dist2Str(m_nHeight)));
lstInfo.Append(new TObjInfoUnit(_T("离地高度"), Dist2Str(m_ptLocation[2])));
lstInfo.Append(new TObjInfoUnit(_T("文字样式"), GetSymbolName(m_idTextStyle)));
lstInfo.Append(new TObjInfoUnit(_T("文字图层"), GetSymbolName(m_idLayerText)));
lstInfo.Append(new TObjInfoUnit(_T("文字高度"), XString(_T("%.1f"), m_nTextHeight)));
if(m_nWinFlag&CWF_PROTRUDE) {
lstInfo.Append(new TObjInfoUnit(_T("凸出宽度"), Dist2Str(m_nProtrude)));
lstInfo.Append(new TObjInfoUnit(_T("超出窗台板1"), Dist2Str(m_nExtrude1)));
lstInfo.Append(new TObjInfoUnit(_T("超出窗台板2"), Dist2Str(m_nExtrude2)));
lstInfo.Append(new TObjInfoUnit(_T("窗台板厚"), Dist2Str(m_nSlabThickness)));
//double m_nGlassDist; //玻璃距离窗台板边缘
}
//Adesk::UInt16 m_style3d; //三维样式
lstInfo.Append(new TObjInfoUnit(_T("玻璃图层"), GetSymbolName(m_idLayerGlass3d)));
lstInfo.Append(new TObjInfoUnit(_T("窗框图层"), GetSymbolName(m_idLayerFrame3d)));
lstInfo.Append(new TObjInfoUnit(_T("窗板图层"), GetSymbolName(m_idLayerSlab3d)));
//double m_uFrame, m_vFrame; //窗框(竖直)高度和窗框(水平)厚度
// ...
}
Acad::ErrorStatus TDbBandWin::GetGripText(int i,CString &cs)const
{
if(i==0)
cs=_T("改变起点位置");
else if(i==1)
cs=_T("改变终点位置");
else
cs=_T("改变编号位置");
return Acad::eOk;
}
#if ADS>15
void TDbBandWin::CreateGrip()
{
TDbEntity::CreateGrip();
if(m_polyFirst.Length()>2)
{
if(fabs(m_polyFirst.GetBulge(0))<1E-6)//暂不处理弧段了
GetGrip(0)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimResultantLength));
if(fabs(m_polyFirst.GetBulge(m_polyFirst.TotalSegments()-1))<1E-6)//暂不处理弧段了
GetGrip(1)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimResultantLength));
}
}
Acad::ErrorStatus TDbBandWin::EntityToDim(long iGrip,long iDim,const AcDbEntity*pEnt)
{
TDbGripDim*pDim=GetGripDim(iGrip,iDim);
if(pDim==NULL)
return Acad::eInvalidInput;
if(pEnt==NULL)
pEnt=this;
TDbBandWin *pWin=TDbBandWin::cast(pEnt);
if(pWin==NULL)
return Acad::eInvalidInput;
XPoly2D poly;
AcGeVector3d vt;
pWin->GetPathPoly(poly,vt);
if(poly.Length()<2)
return Acad::eInvalidInput;
if(iGrip==0)//起点
{
TDbGripDistDim*pDistDim=(TDbGripDistDim*)pDim;
pDistDim->SetData(poly[1]->AsAcGePoint3d(),poly[0]->AsAcGePoint3d());
}
else if(iGrip==1)//终点
{
TDbGripDistDim*pDistDim=(TDbGripDistDim*)pDim;
pDistDim->SetData(poly[poly.Length()-1]->AsAcGePoint3d(),poly[poly.Length()-2]->AsAcGePoint3d());
}
else
return Acad::eNotImplementedYet;
return Acad::eOk;
}
Acad::ErrorStatus TDbBandWin::DimToEntity(long iGrip,long iDim,double newValue,const AcGeVector3d& offset)
{
assertWriteEnabled();
if(m_polyFirst.Length()<2)
return Acad::eInvalidInput;
if(iGrip==0)
{
if(newValue<1E-6)
return Acad::eInvalidInput;
XPoint dir=XPoint(m_ptStart)-*m_polyFirst[1];
dir.Normalize();
dir.Scale(newValue);
m_ptStart=*m_polyFirst[0]=*m_polyFirst[1]+dir;
}
else if(iGrip==1)
{
if(newValue<1E-6)
return Acad::eInvalidInput;
XPoint dir=XPoint(m_ptEnd)-*m_polyFirst[m_polyFirst.Length()-2];
dir.Normalize();
dir.Scale(newValue);
m_ptEnd=*m_polyFirst[m_polyFirst.Length()-1]=*m_polyFirst[m_polyFirst.Length()-2]+dir;
}
else
return Acad::eNotImplementedYet;
return Acad::eOk;
}
#endif
Acad::ErrorStatus TDbBandWin::dwgInFields(AcDbDwgFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbCornerWin::dwgInFields(pFiler);
if(es != Acad::eOk) return es;
Adesk::UInt8 nVer=0;
pFiler->readItem(&nVer);
if(nVer>g_nVersion)
return Acad::eMakeMeProxy;
Adesk::Int32 num;
pFiler->readItem(&num);
m_idMidWalls.Reset();
for(long i=0;i<num;i++)
{
AcDbSoftPointerId idWall;
pFiler->readItem(&idWall);
m_idMidWalls.Append(new AcDbSoftPointerId(idWall));
}
pFiler->readItem(&m_ptStart);
pFiler->readItem(&m_ptEnd);
ReadPoly2D(pFiler,m_polyFirst);
ReadPoly2D(pFiler,m_polyFirstBase);
return pFiler->filerStatus();
}
// 写出数据到dwg:
Acad::ErrorStatus
TDbBandWin::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es = TDbCornerWin::dwgOutFields(pFiler);
if(es != Acad::eOk) return es;
pFiler->writeItem(g_nVersion);
pFiler->writeItem((Adesk::Int32)m_idMidWalls.Length());
for(long i=0;i<m_idMidWalls.Length();i++)
pFiler->writeItem(m_idMidWalls[i]);
pFiler->writeItem(m_ptStart);
pFiler->writeItem(m_ptEnd);
WritePoly2D(pFiler,m_polyFirst);
WritePoly2D(pFiler,m_polyFirstBase);
return pFiler->filerStatus();
}
Acad::ErrorStatus
TDbBandWin::dxfInFields (AcDbDxfFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbCornerWin::dxfInFields(pFiler);
if(es!=Acad::eOk)
return es;
if (!pFiler->atSubclassData(_T("TDbBandWin")))
return Acad::eBadDxfSequence;
DList<AcDbSoftPointerId> lstIds;
AcDbObjectId id;
resbuf rb;
while ((es == Acad::eOk)
&& ((es = pFiler->readResBuf(&rb)) == Acad::eOk)) {
switch (rb.restype)
{
case AcDb::kDxfSoftPointerId:
acdbGetObjectId(id, rb.resval.rlname);
lstIds.Append(new AcDbSoftPointerId(id));
break;
default:
// An unrecognized group. Push it back so that
// the subclass can read it again.
pFiler->pushBackItem();
es = Acad::eEndOfFile;
break;
}
}
if (es != Acad::eEndOfFile)
return Acad::eInvalidResBuf;
m_idMidWalls.Reset();
lstIds.SetDelFlag(FALSE);
for(int i=0; i<lstIds.Length(); i++)
m_idMidWalls.Append(lstIds[i]);
return pFiler->filerStatus();
}
Acad::ErrorStatus
TDbBandWin::dxfOutFields(AcDbDxfFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es;
es = TDbCornerWin::dxfOutFields(pFiler);
assert(es == Acad::eOk);
es = pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbBandWin"));
assert(es == Acad::eOk);
for(int i=0; i<m_idMidWalls.Length(); i++)
{
const AcDbSoftPointerId &id=m_idMidWalls[i];
pFiler->writeItem(AcDb::kDxfSoftPointerId,id);
}
return es;
}
Acad::ErrorStatus TDbBandWin::subGetGripPoints(AcGePoint3dArray& gripPoints,
AcDbIntArray& osnapModes,
AcDbIntArray& geomIds) const
{
assertReadEnabled();
gripPoints.append(m_ptStart);
gripPoints.append(m_ptEnd);
if(!(!m_sLabel))
gripPoints.append(m_ptLabel);
return Acad::eOk;
}
Acad::ErrorStatus TDbBandWin::subMoveGripPointsAt(
const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
TDbBandWin backWin;
backWin.copyFrom(this);
for (int i = 0; i < indices.length(); i++)
switch(indices[i])
{
case 0:
m_ptStart+=offset;
break;
case 1:
m_ptEnd+=offset;
break;
case 2:
m_ptLabel+=offset;
break;
}
if(!UpdateParameters()||!IsValid())
{
copyFrom(&backWin);
return Acad::eInvalidInput;
}
return Acad::eOk;
}
// Stretch的夹点只有插入点和标号位置
Acad::ErrorStatus TDbBandWin::subGetStretchPoints(AcGePoint3dArray & stretchPoints) const
{
assertReadEnabled();
if(!!m_sLabel)
stretchPoints.append(m_ptLabel);
stretchPoints.append(m_ptStart);
stretchPoints.append(m_ptEnd);
return Acad::eOk;
}
// 功能: 夹点操作
Acad::ErrorStatus TDbBandWin::subMoveStretchPointsAt(
const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
if(indices.length()==1&&indices[0]==0)
m_ptLabel += offset;
else
{
AcGeMatrix3d mat;
mat.setTranslation(offset);
subTransformBy(mat);
}
return Acad::eOk;
}
Acad::ErrorStatus TDbBandWin::subTransformBy(const AcGeMatrix3d&xform)
{
assertWriteEnabled();
TDbCornerWin::subTransformBy(xform);
m_ptStart.transformBy(xform);
m_ptEnd.transformBy(xform);
m_polyFirst.TransformBy(xform);
m_polyFirstBase.TransformBy(xform);
return Acad::eOk;
}
// sg add 101119,支持导出XML
CString TDbBandWin::GetXml(const AcGeMatrix3d& mat) const
{
TXmlTree xmlTree;
POSITION posRoot = xmlTree.Insert(_T("TCH_BAND_WINDOW"), NULL, NULL);
{
xmlTree.SetAttribute(posRoot, _T("name"), _T("带形窗"));
xmlTree.SetAttribute(posRoot, _T("comment"), _T("上华对象名称"));
}
CString strText;
POSITION posItem = NULL;
POSITION posItem1 = xmlTree.Insert(_T("Object_ID"), posRoot, NULL);
{
xmlTree.SetAttribute(posItem1, _T("name"), _T("对象编号"));
xmlTree.SetAttribute(posItem1, _T("comment"), _T("当前对象的句柄"));
strText.Format(_T("%ld"), objectId());
xmlTree.SetItemText(posItem1, strText);
}
POSITION posItem2 = xmlTree.Insert(_T("Link_WALL"), posRoot, posItem1);
{
xmlTree.SetAttribute(posItem2, _T("name"), _T("连接墙体"));
posItem = NULL;
int iLen = GetWallNum();
for (int i = 0; i < iLen; i++)
{
posItem = xmlTree.Insert(_T("Link_ID"), posItem2, posItem);
{
AcDbObjectId id = GetWallId(i);
strText.Format(_T("墙体句柄%d"), i + 1);
xmlTree.SetAttribute(posItem, _T("name"), strText);
strText.Format(_T("%ld"), id.asOldId());
xmlTree.SetItemText(posItem, strText);
}
}
}
POSITION posItem3 = xmlTree.Insert(_T("Net_height"), posRoot, posItem2);
{
xmlTree.SetAttribute(posItem3, _T("name"), _T("门窗高"));
xmlTree.SetAttribute(posItem3, _T("comment"), _T("从门窗底起算的窗高"));
strText.Format(_T("%f"), GetHeight());
xmlTree.SetItemText(posItem3, strText);
}
POSITION posItem4 = xmlTree.Insert(_T("Sill_height"), posRoot, posItem3);
{
xmlTree.SetAttribute(posItem4, _T("name"), _T("窗台高"));
xmlTree.SetAttribute(posItem4, _T("comment"), _T("从楼面起算的窗台高"));
strText.Format(_T("%f"), GetElevation());
xmlTree.SetItemText(posItem4, strText);
}
POSITION posItem5 = xmlTree.Insert(_T("Length1"), posRoot, posItem4);
{
xmlTree.SetAttribute(posItem5, _T("name"), _T("门窗宽1"));
xmlTree.SetAttribute(posItem5, _T("comment"), _T("门窗在第一道墙的宽度"));
strText.Format(_T("%f"), GetWidth1());
xmlTree.SetItemText(posItem5, strText);
}
POSITION posItem6 = xmlTree.Insert(_T("Length2"), posRoot, posItem5);
{
xmlTree.SetAttribute(posItem6, _T("name"), _T("门窗宽2"));
xmlTree.SetAttribute(posItem6, _T("comment"), _T("门窗在末一道墙宽度"));
strText.Format(_T("%f"), GetWidth2());
xmlTree.SetItemText(posItem6, strText);
}
POSITION posBaseLine = xmlTree.Insert(_T("Baseline"), posRoot, posItem6);
{
xmlTree.SetAttribute(posBaseLine, _T("name"), _T("路径"));
POSITION posItem = NULL;
TADSGePoint3d ptNode;
int iLen = m_polyFirstBase.Length();
for (int i = 0; i < iLen; i++)
{
ptNode = m_polyFirstBase[i];
// 对点进行坐标变换
ptNode.TransformBy(mat);
strText.Format(_T("Point_%d"), i + 1);
posItem = xmlTree.Insert(strText, posBaseLine, posItem);
{
strText.Format(_T("第%d点"), i + 1);
xmlTree.SetAttribute(posItem, _T("name"), strText);
strText.Format(_T("%f,%f,%f"), ptNode.x, ptNode.y, ptNode.z);
xmlTree.SetItemText(posItem, strText);
}
strText.Format(_T("Ang_%d"), i + 1);
posItem = xmlTree.Insert(strText, posBaseLine, posItem);
{
strText.Format(_T("圆心角%d"), i + 1);
xmlTree.SetAttribute(posItem, _T("name"), strText);
strText.Format(_T("%f"), m_polyFirstBase.GetBulge(i));
xmlTree.SetItemText(posItem, strText);
}
}
}
CString strBase = TEntityBase::GetXml(mat);
CString strXml = xmlTree.GetXml();
int nIndex = strXml.Find(_T("<Object_ID"));
strXml.Insert(nIndex, strBase);
return strXml;
}
// sg add 120511,获取带形窗的形心线长度,含保温
double TDbBandWin::GetGeomCenterWidth() const
{
TDPtrList<AcDbSoftPointerId> idAllWall;
idAllWall.Append(new AcDbSoftPointerId(m_idWall1));
int nLength = m_idMidWalls.Length();
for (int i=0; i<nLength; i++)
{
idAllWall.Append(new AcDbSoftPointerId(m_idMidWalls[i]));
}
idAllWall.Append(new AcDbSoftPointerId(m_idWall2));
TGGePoly2D polyGeomCenterPt;
TGGeCurveSegment segCur, segPre, segNext;
TADSGePoint3d pt1, pt2, pt;
nLength = idAllWall.Length();
for (i=0; i<nLength; i++)
{
if (i == 0) // 首段
{
OPENOBJ_BEGIN(*idAllWall[i], AcDb::kForRead, TDbWall, pWall);
if (pWall != NULL)
{
segCur = pWall->OffsetGeomCenter(LS_INFINITE, TRUE); // 当前段
}
OPENOBJ_END();
segCur.ProjectToMe(m_ptStart, pt);
}
else // 其他段
{
if (segCur.Intersection(segPre, pt1, pt2) != 1) // 考虑平行的情况
{
pt1 = segPre.StartPoint();
pt2 = segPre.EndPoint();
}
pt = TGGeLine(pt1, pt2).NearPoint(segCur.StartPoint());
}
polyGeomCenterPt.AppendNode(pt, segCur.GetBulge()); // 起点
if (i+1 < nLength) // 其他段
{
OPENOBJ_BEGIN(*idAllWall[i+1], AcDb::kForRead, TDbWall, pWall);
if (pWall != NULL)
{
segNext = pWall->OffsetGeomCenter(LS_INFINITE, TRUE); // 下一段
}
OPENOBJ_END();
}
else // 末段
{
segCur.ProjectToMe(m_ptEnd, pt);
polyGeomCenterPt.AppendNode(pt, 0); // 终点
}
segPre = segCur; // 前一段
segCur = segNext;
}
double dWidth = polyGeomCenterPt.Distance2d();
return dWidth;
}
// sg add 110224,增加自动编号
CString TDbBandWin::GetAutoLabel(bool &bAddNum)const
{
TOpeningLabelData data;
CStringArray arSubType; // 获得类型数组
data.GetSubType(_T("BandWin"),arSubType);
CString csNewName = _T("DC");
if (arSubType.GetSize() > 0)
{
data.GetOpeningLabel(_T("BandWin"),arSubType[0], csNewName);
}
// 获得是否需要添加连字符
CString csHypen = _T("");
if (data.HasHypen())
csHypen = _T("-");
bool bRound = data.IsRound(); // 是否进行四舍五入
TOpeningLabelData::ESerialRule nRule = data.GetNumRule();
if (nRule == TOpeningLabelData::kSize) // 按尺寸标注
{
bAddNum = false;
// 洞口尺寸宽+高
// sg add 120511,根据9.0需求,编号时,根据墙中线长度来作为宽度,GetWidth里面去的是墙基线的长度
// double nWidth = GetWidth(),
double nWidth = GetGeomCenterWidth(),
nHeight = GetHeight();
int nWidth1 = AS_INT(nWidth/100),
nHeight1 = AS_INT(nHeight/100);
if (!bRound) // 不进行四舍五入
{
nWidth1 = AS_INT(nWidth)/100;
nHeight1 = AS_INT(nHeight)/100;
}
if (nWidth1>9&&nHeight1>9)
csNewName.Format(_T("%s%s%d%d"),csNewName, csHypen, nWidth1, nHeight1);
else if (nWidth1<10&&nHeight1>9)
csNewName.Format(_T("%s%s0%d%d"),csNewName, csHypen, nWidth1, nHeight1);
else if (nWidth1>9&&nHeight1<10)
csNewName.Format(_T("%s%s%d0%d"),csNewName, csHypen, nWidth1, nHeight1);
else
csNewName.Format(_T("%s%s0%d0%d"),csNewName, csHypen, nWidth1, nHeight1);
}
else // 按数序排列
{
csNewName.Format(_T("%s%s"), csNewName, csHypen);
bAddNum = true; // 由对话框处进行+1工作
}
return csNewName;
}
////////////////////////////////////////////////////////////////////////////////////////////
void InitDbBandWin(BOOL bTrue)
{
if(bTrue)
{
TDbBandWin::rxInit();
acrxBuildClassHierarchy();
TDbBandWin::InitMatchProtocol(TRUE);
}
else
{
TDbBandWin::InitMatchProtocol(FALSE);
deleteAcRxClass(TDbBandWin::desc());
}
}
void BanOpening()
{
XPushVar<int> vOsMode(_T("OSMODE"), 512);
extern TARCH_IMPEXP BOOL g_bEnableCornWinWarning;
XPoint ptStart, ptEnd;
if(XGetPoint(NULL, _T("\n起始点"), ptStart)!=RTNORM ||
XGetPoint(NULL, _T("\n终止点"), ptEnd)!=RTNORM)
return;
static double nSill=800.0, nHeight=1800.0;
Entity eStart, eEnd;
PickSet ssWalls(SS_FREE);
g_ssPickFirst.Free();
if(SelectEntities(_T("\n选择带形窗经过的墙:"),ssWalls, RBList(RTDXF0, _T("ATS_WALL,ATS_CURTAIN_WALL"), NULL))!=RTNORM)
return;
BOOL bHas3D=TRUE;
DList<AcDbObjectId> idMidWalls;
AcDbObjectId idStart,idEnd;
int nWallCount=int(ssWalls.Length());
for(long i=0; i<nWallCount; i++) {
Entity idWall=ssWalls[long(i)];
AcDbObjectId objectId;
acdbGetObjectId(objectId,idWall);
XDbObject objWall(idWall, AcDb::kForRead);
if(!objWall) continue;
TDbWall *pWall=TDbWall::cast(objWall.m_pObject);
XPoly2D poly(1), poly1(1);
pWall->GetOutlinePoly(ptStart.z, poly);
if(!pWall->Has3D())
bHas3D=FALSE;
double nDevation= (poly.PathArea()<0.0)? (_DIST_SNAP*2) : -(_DIST_SNAP*2);
poly.Offset(nDevation, poly1);
bool bTerm=false;
if((ptStart&poly1) != PR_OUTSIDE)
{
if(!!eStart) {
adsout << /*UMSG*/ _T("\n起点处发现不止一段墙, 不能完成带形窗!");
return;
}
eStart=idWall;
idStart=objectId;
bTerm=true;
}
if((ptEnd&poly1) != PR_OUTSIDE)
{
if(!!eEnd) {
adsout << /*UMSG*/ _T("\n终点处发现不止一段墙, 不能完成带形窗!");
return;
}
eEnd=idWall;
idEnd=objectId;
bTerm=true;
}
if(!bTerm)
idMidWalls.Append(new AcDbObjectId(objectId));
}
if(!eStart) {
adsout << /*UMSG*/ _T("\n找不到起点处的墙!");
return;
}
if(!eEnd) {
adsout << /*UMSG*/ _T("\n找不到终点处的墙!");
return;
}
if(eStart==eEnd)
{
XCurveSegment seg, segBase;
OPENOBJ_BEGIN(eStart, AcDb::kForRead, TDbWall, pWall);
ASSERT(pWall);
segBase = *pWall;
seg=pWall->OffsetGeomCenter(LS_INFINITE, TRUE);
seg.ProjectToMe(XPoint(ptStart), ptStart);
seg.ProjectToMe(XPoint(ptEnd), ptEnd);
seg.SetPoints(ptStart, ptEnd);
segBase.ProjectToMe(XPoint(ptStart), ptStart);
segBase.ProjectToMe(XPoint(ptEnd), ptEnd);
if(!segBase.Is(CURVE_LINE)&&//弧段
segBase.PathDistance(ptStart)>segBase.PathDistance(ptEnd))
segBase.SetPoints(ptEnd,ptStart);
else
segBase.SetPoints(ptStart,ptEnd);
OPENOBJ_END();
if(bHas3D) {
if(GetReal(_T("\n窗台高"), nSill)==RTCAN || GetReal(_T("\n窗户高"), nHeight)==RTCAN)
return;
}
BOOL bWarn=g_bEnableCornWinWarning;
g_bEnableCornWinWarning=FALSE;
XPoint ptMid0=segBase.MidPoint();
XPoint ptMid;
seg.ProjectToMe(ptMid0, ptMid);
ptMid.z = bHas3D? nSill : 0.0;
TDbOpening *pOpening= new TDbOpening;
pOpening->m_ptLocation = ptMid;
pOpening->SetWidth(segBase.GetLength());
pOpening->SetHeight(bHas3D? nHeight : 0.0);
pOpening->SetKind(TOpeningData::OP_CORNWIN);
// 设定编号位置
ads_polar(ptMid, seg.Direction(ptMid)-PI/2.0, _AS_SYS_UNIT(600.0), pOpening->m_ptLabel);
pOpening->m_ptLabel.z = 0;
pOpening->InitHardPointerId();
pOpening->AddToMSpace(Adesk::kTrue);
TArchCmdReactor::UpdateOpenings();
TArchCmdReactor::ResetAll();
g_bEnableCornWinWarning=bWarn;
//adsout << _T("\n起点和终点都在同一墙段上, 没有转角!");
return;
}
if(GetReal(_T("\n窗台高"), nSill)==RTCAN ||
GetReal(_T("\n窗户高"), nHeight)==RTCAN)
return;
BOOL bWarn=g_bEnableCornWinWarning;
g_bEnableCornWinWarning=FALSE;
TDbBandWin *pWin=new TDbBandWin;
pWin->SetHeight(nHeight);
pWin->SetElevation(nSill);
pWin->SetLayerGlass3d(InitLayer(LAY_3DGLASS, FALSE));
pWin->SetLayerFrame3d(InitLayer(LAY_3DFRAME, FALSE));
pWin->SetLayerSlab3d(InitLayer(LAY_WALL, FALSE));
pWin->SetLayerText(InitLayer(LAY_OPENING_DIM, FALSE));
pWin->SetTextStyle(InitTextStyle(TS_WINDOW));
pWin->SetStartPoint(ptStart);
pWin->SetEndPoint(ptEnd);
pWin->SetWallId(0,idStart);
pWin->SetWallId(1,idEnd);
pWin->SetMidWallIds(idMidWalls);
if(!pWin->UpdateParameters())
{
adsout<<_T("\n未能生成带形窗!");
delete pWin;
return;
}
pWin->UpdateLabelPos();
AcDbObjectId idWin=pWin->AddToMSpace(Adesk::kTrue);
for(i=0;i<ssWalls.Length();i++)
{
Entity ent=ssWalls[i];
OPENOBJ_BEGIN(ent, AcDb::kForWrite, TDbWall, pWall);
if(pWall)
pWall->AddOpeningId(idWin);
OPENOBJ_END();
}
g_bEnableCornWinWarning=bWarn;
}
bool TDbBandWin::GetSection( const AcDbFace &face, const AcGeVector3d& vtPlaneSecDir, std::vector<TObjSectionRecord> &sectionRecords, AcDbVoidPtrArray& arFillPtrs ) const
{
TGGeSectionPlane section(face, vtPlaneSecDir);
AcDbObjectId id(objectId()), layer(layerId());
TObjSectionRecord::SectionType type = TObjSectionRecord::eTCH_CORNER_WINDOW;
double dDist = 0.;
TGGePoly2D poly;
for(long i = 0; i < GetWallNum(); i++)
{
TDbOpening *pOpening = GetOpening(i);
if (!pOpening)
continue;
double dDist = .0;
poly.Reset();
XCurveSegment segLeftSide, segLeft, segMid, segRight, segRightSide;
pOpening->GetBanWinSegs(segLeftSide, segLeft, segMid, segRight, segRightSide);
double elev = pOpening->GetElevation(),
height = pOpening->GetHeight();
AcGePoint3d pt1(segLeftSide.GetStartPoint()), pt2(segLeftSide.GetEndPoint()),
pt3(pt2), pt4(pt1);
pt1.z = pt2.z = elev;
pt3.z = pt4.z = elev + height;
TGGeSectionPlane plane1(pt1, pt2, pt3, pt4, vtPlaneSecDir);
dDist = SectionUtility::Projection_plane2plane(section, plane1, poly);
if (poly.Length())
sectionRecords.push_back(TObjSectionRecord(id, layer, type, dDist, poly));
pt1 = segRightSide.GetStartPoint(), pt2 = segRightSide.GetEndPoint(),
pt3 = pt2, pt4 = pt1;
pt1.z = pt2.z = elev;
pt3.z = pt4.z = elev + height;
poly.Reset();
TGGeSectionPlane plane2(pt1, pt2, pt3, pt4, vtPlaneSecDir);
dDist = SectionUtility::Projection_plane2plane(section, plane2, poly);
if (poly.Length())
sectionRecords.push_back(TObjSectionRecord(id, layer, type, dDist, poly));
}
return true;
}