1054 lines
26 KiB
C++
1054 lines
26 KiB
C++
#include "stdafx.h"
|
|
|
|
|
|
extern BOOL GetCtrlToggle();
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
const Adesk::UInt8 TDbGroupOpening::g_nVersion = 0; //可能需要与TDbOpening::g_nVersion关联!
|
|
ACRX_DXF_DEFINE_MEMBERS(ATSGroupOpening, ATSOpening, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
|
|
1, ATS_GROUPOPENING, "ATS_GROUPOPENING图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
|
|
|
|
IMPLEMENT_TENTBASE(TDbGroupOpening);
|
|
|
|
TDbGroupOpening::TDbGroupOpening()
|
|
{
|
|
SetKind(TOpeningData::OP_GROUP);
|
|
}
|
|
|
|
BOOL TDbGroupOpening::IsValid()const
|
|
{
|
|
for(long i=0;i<m_lstOpening.Length();i++)
|
|
if(!m_lstOpening[i].IsValid())
|
|
return FALSE;
|
|
|
|
return m_lstOpening.Length()>0;
|
|
}
|
|
void TDbGroupOpening::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag)
|
|
{
|
|
assertWriteEnabled();
|
|
TDbOpening::CopyPropertiesFrom(pSrcEntity, gMatchFlag);
|
|
TDbGroupOpening *pSrc=TDbGroupOpening::cast(pSrcEntity);
|
|
if(pSrc)
|
|
{
|
|
m_lstOpening.Reset();
|
|
for(long i=0;i<pSrc->GetOpeningNum();i++)
|
|
m_lstOpening.Append((TDbOpening*)(*pSrc)[i]->clone());
|
|
}
|
|
}
|
|
void TDbGroupOpening::Update(bool bFromChild)
|
|
{
|
|
if(GetOpeningNum()<1)
|
|
return;
|
|
|
|
if(bFromChild)
|
|
{
|
|
SetWallId(m_lstOpening[0]->GetWallId());
|
|
TDbWall*pWall=NULL;
|
|
acdbOpenObject(pWall,GetWallId(),AcDb::kForRead);
|
|
if(pWall==NULL)
|
|
return;
|
|
pWall->SortOpening(m_lstOpening);
|
|
pWall->close();
|
|
}
|
|
|
|
//宽高由m_lstOpening决定
|
|
m_nWidth=0;
|
|
for(long i=0;i<m_lstOpening.Length();i++)
|
|
m_nWidth+=m_lstOpening[i]->GetWidth();
|
|
double botElev=m_lstOpening[0]->GetElevation(),topElev=m_lstOpening[0]->GetTopElev();
|
|
for(i=1;i<m_lstOpening.Length();i++)
|
|
{
|
|
TDbOpening*pOpening=m_lstOpening[i];
|
|
if(pOpening->GetElevation()<botElev)
|
|
botElev=pOpening->GetElevation();
|
|
if(pOpening->GetTopElev()>topElev)
|
|
topElev=pOpening->GetTopElev();
|
|
}
|
|
m_ptLocation.z=botElev;
|
|
m_nHeight=topElev-botElev;
|
|
|
|
if(bFromChild)
|
|
{
|
|
XPoint ptStart,ptMid,ptEnd;
|
|
m_lstOpening.Head()->GetSidePoints(ptStart,ptMid);
|
|
m_lstOpening.Tail()->GetSidePoints(ptMid,ptEnd);
|
|
Midpoint(ptStart,ptEnd,m_ptLocation);
|
|
m_nRotation=m_lstOpening.Head()->m_nRotation;
|
|
if(!m_sLabel)//如果编号不空,则位置己定
|
|
m_ptLabel=GetDefaultLabPos();
|
|
}
|
|
else
|
|
{
|
|
//Location由this决定
|
|
XPoint ptStart,ptEnd,ptMid;
|
|
GetSidePoints(ptStart,ptEnd);
|
|
double offset=0;
|
|
for(long i=0;i<m_lstOpening.Length();i++)
|
|
{
|
|
TDbOpening*pOpening=m_lstOpening[i];
|
|
ads_polar(ptStart,m_nRotation,offset+pOpening->GetWidth()/2,ptMid);
|
|
ptMid.z=pOpening->GetElevation();
|
|
|
|
pOpening->SetLocation(ptMid);
|
|
pOpening->SetWallId(GetWallId());
|
|
pOpening->m_nRotation=m_nRotation;
|
|
pOpening->SetLabel(_T(""));
|
|
|
|
offset+=pOpening->GetWidth();
|
|
}
|
|
}
|
|
}
|
|
|
|
Acad::ErrorStatus TDbGroupOpening::SetSill(double nSill)
|
|
{ //改变窗台高度
|
|
if(nSill < -1.0E-6) return Acad::eInvalidInput;
|
|
double offset=nSill-GetSill();
|
|
TOpeningData::SetSill(nSill);
|
|
for(long i=0;i<m_lstOpening.Length();i++)
|
|
{
|
|
TDbOpening*pWin=m_lstOpening[i];
|
|
pWin->SetSill(pWin->GetSill()+offset);
|
|
}
|
|
return Acad::eOk;
|
|
}
|
|
Acad::ErrorStatus TDbGroupOpening::SetWidth(double nW)
|
|
{
|
|
if(nW<1.0E-6) return Acad::eInvalidInput;
|
|
double s=nW/GetWidth();
|
|
m_nWidth = nW;
|
|
for(long i=0;i<m_lstOpening.Length();i++)
|
|
{
|
|
TDbOpening*pWin=m_lstOpening[i];
|
|
pWin->SetWidth(pWin->GetWidth()*s);
|
|
}
|
|
Update(false);
|
|
return Acad::eOk;
|
|
}
|
|
Acad::ErrorStatus TDbGroupOpening::SetHeight(double nH)
|
|
{ //窗高为0,则无3D
|
|
double s=nH/GetHeight();
|
|
m_nHeight = nH;
|
|
double nSill=GetSill();
|
|
for(long i=0;i<m_lstOpening.Length();i++)
|
|
{
|
|
TDbOpening*pWin=m_lstOpening[i];
|
|
pWin->SetHeight(pWin->GetHeight()*s);
|
|
|
|
double offset=pWin->GetSill()-nSill;
|
|
offset*=s;
|
|
pWin->SetSill(nSill+offset);
|
|
}
|
|
return Acad::eOk;
|
|
}
|
|
// 验证调整和墙的配属关系
|
|
// 方法: 如果有配属的墙则验证是否成立配属关系; 否则寻找一配属墙,确立新的关系
|
|
// 注意: 在命令结束时处理
|
|
void TDbGroupOpening::ValidateContainership(DList<AcDbObjectId> &lstWalls)
|
|
{
|
|
assertWriteEnabled();
|
|
|
|
double nDirectionOld=m_nRotation;
|
|
TDbOpening::ValidateContainership(lstWalls);
|
|
|
|
//新方向与旧方向夹角大于90度时,尽量维持原开启方向
|
|
if(fabs(m_nRotation-nDirectionOld)>PI/2)
|
|
{
|
|
for(long i=0;i<m_lstOpening.Length();i++)
|
|
{
|
|
TDbOpening*pOpening=m_lstOpening[i];
|
|
if(pOpening->m_nQuadrant==0)
|
|
pOpening->m_nQuadrant=2;
|
|
else if(pOpening->m_nQuadrant==2)
|
|
pOpening->m_nQuadrant=0;
|
|
else if(pOpening->m_nQuadrant==1)
|
|
pOpening->m_nQuadrant=3;
|
|
else
|
|
pOpening->m_nQuadrant=1;
|
|
}
|
|
|
|
m_lstOpening.Reverse();
|
|
}
|
|
}
|
|
const TCHAR* TDbGroupOpening::GetKindString()const
|
|
{
|
|
for(long i=0;i<m_lstOpening.Length();i++)
|
|
{
|
|
const TDbOpening&op=m_lstOpening[i];
|
|
if(op.GetKind()==TOpeningData::OP_DOOR||
|
|
op.GetKind()==TOpeningData::OP_DOORWIN||
|
|
op.GetKind()==TOpeningData::OP_TWODOOR)
|
|
return _T("组合门");
|
|
}
|
|
|
|
return _T("组合窗");
|
|
}
|
|
void TDbGroupOpening::GetElevOutline(XPoly2D&poly)const
|
|
{
|
|
if(!IsValid())
|
|
return;
|
|
|
|
XPoly3D polyTemp;
|
|
m_lstOpening[0].GetElevOutline(polyTemp);
|
|
AcGeVector3d vt=polyTemp.GetNormal(false);
|
|
poly=polyTemp.WcsToPlane(vt);
|
|
for(long i=1;i<m_lstOpening.Length();i++)
|
|
{
|
|
XPoly3D poly1(1);
|
|
DList<XPoly2D> poly2;
|
|
m_lstOpening[i].GetElevOutline(poly1);
|
|
poly1=poly1.WcsToPlane(vt);
|
|
TchSubExport::Union(poly,poly1,poly2);
|
|
if(poly2.Length()>0)
|
|
poly=*poly2[0];
|
|
}
|
|
poly.Compress();
|
|
poly=poly.PlaneToWcs(vt);
|
|
}
|
|
void TDbGroupOpening::MirrorSelf(BOOL bLeftRight)
|
|
{
|
|
assertWriteEnabled();
|
|
|
|
TDbOpening::MirrorSelf(bLeftRight);
|
|
for(long i=0;i<m_lstOpening.Length();i++)
|
|
m_lstOpening[i]->MirrorSelf(bLeftRight);
|
|
if(bLeftRight)
|
|
m_lstOpening.Reverse();
|
|
}
|
|
Acad::ErrorStatus TDbGroupOpening::ExplodeOrDraw2d(XExplodeDraw&dc)const
|
|
{
|
|
assertReadEnabled();
|
|
if (!IsValid())
|
|
return Acad::eNotApplicable;
|
|
|
|
TDbOpening::ExplodeOrDraw2d(dc);
|
|
|
|
{
|
|
XPushMemVar<BOOL> vTemp(g_bSubEntity,TRUE);
|
|
if(dc.IsFullExplode())
|
|
{
|
|
XPushMemVar<AcDbDatabase*> vTemp0(g_pCurrentDb,database());
|
|
for(long i=0;i<m_lstOpening.Length();i++)
|
|
{
|
|
const TDbOpening& win=m_lstOpening[i];
|
|
win.ExplodeOrDraw2d(dc);
|
|
}
|
|
}
|
|
else
|
|
for(long i=0;i<m_lstOpening.Length();i++)
|
|
dc.DrawEntity((AcDbEntity&)m_lstOpening[i]);
|
|
}
|
|
|
|
|
|
return Acad::eOk;
|
|
}
|
|
Acad::ErrorStatus TDbGroupOpening::ExplodeOrDraw3d(XExplodeDraw&dc)const
|
|
{
|
|
assertReadEnabled();
|
|
if (!IsValid())
|
|
return Acad::eNotApplicable;
|
|
{
|
|
XPushMemVar<BOOL> vTemp(g_bSubEntity,TRUE);
|
|
|
|
if(dc.IsFullExplode())
|
|
{
|
|
XPushMemVar<AcDbDatabase*> vTemp0(g_pCurrentDb,database());
|
|
for(long i=0;i<m_lstOpening.Length();i++)
|
|
m_lstOpening[i].ExplodeOrDraw3d(dc);
|
|
}
|
|
else
|
|
for(long i=0;i<m_lstOpening.Length();i++)
|
|
dc.DrawEntity((AcDbEntity&)m_lstOpening[i]);
|
|
}
|
|
|
|
return Acad::eOk;
|
|
}
|
|
Acad::ErrorStatus TDbGroupOpening::GetGripText(int i,CString&cs)const
|
|
{
|
|
if(i<GetOpeningNum()*2+1)//分隔点
|
|
{
|
|
if(i%2==0)
|
|
{
|
|
if(i==0||i==GetOpeningNum()*2)
|
|
cs=GetCtrlToggle()? _T("单侧改宽(Ctrl-移动门窗)") : _T("移动门窗(Ctrl-单侧宽度)");
|
|
else
|
|
cs=_T("调整宽度");
|
|
}
|
|
else
|
|
cs=_T("局部改变开启方向");
|
|
}
|
|
else if(i==GetOpeningNum()*2+1)
|
|
cs=_T("整体改变开启方向");
|
|
else
|
|
cs=_T("改变编号位置");
|
|
|
|
return Acad::eOk;
|
|
}
|
|
Acad::ErrorStatus TDbGroupOpening::subClose()
|
|
{
|
|
Acad::ErrorStatus es=TDbOpening::subClose();
|
|
if(es==Acad::eOk&&isModified()&&!isUndoing()&&database()==acdbCurDwg())
|
|
Update(false);
|
|
return Acad::eOk;
|
|
}
|
|
|
|
// 从DWG读入数据:
|
|
// 注意: 有待加入版本控制
|
|
Acad::ErrorStatus TDbGroupOpening::dwgInFields (AcDbDwgFiler* pFiler)
|
|
{
|
|
assertWriteEnabled();
|
|
|
|
Acad::ErrorStatus es = TDbOpening::dwgInFields(pFiler);
|
|
if(es != Acad::eOk) return es;
|
|
Adesk::UInt8 nVer;
|
|
pFiler->readItem(&nVer);
|
|
if(nVer>g_nVersion)
|
|
return Acad::eMakeMeProxy;
|
|
|
|
Adesk::Int32 num;
|
|
pFiler->readItem(&num);
|
|
m_lstOpening.Reset();
|
|
for(long i=0;i<num;i++)
|
|
{
|
|
TDbOpening* pOpening=new TDbOpening;
|
|
m_lstOpening.Append(pOpening);
|
|
es=pOpening->dwgInFields(pFiler);
|
|
if(es!=Acad::eOk)
|
|
return es;//可能是Acad::eMakeMeProxy;
|
|
}
|
|
|
|
return pFiler->filerStatus();
|
|
}
|
|
|
|
// 写出数据到dwg:
|
|
Acad::ErrorStatus TDbGroupOpening::dwgOutFields(AcDbDwgFiler* pFiler) const
|
|
{
|
|
assertReadEnabled();
|
|
Acad::ErrorStatus es = TDbOpening::dwgOutFields(pFiler);
|
|
if(es != Acad::eOk) return es;
|
|
|
|
pFiler->writeItem(g_nVersion);
|
|
|
|
pFiler->writeItem((Adesk::Int32)GetOpeningNum());
|
|
|
|
for(long i=0;i<GetOpeningNum();i++)
|
|
m_lstOpening[i].dwgOutFields(pFiler);
|
|
|
|
return es;
|
|
}
|
|
|
|
|
|
Acad::ErrorStatus TDbGroupOpening::dxfInFields (AcDbDxfFiler* pFiler)
|
|
{
|
|
assertWriteEnabled();
|
|
|
|
Acad::ErrorStatus es = TDbOpening::dxfInFields(pFiler);
|
|
if(es!=Acad::eOk)
|
|
return es;
|
|
|
|
if (!pFiler->atSubclassData(_T("TDbGroupOpening"))) {
|
|
return Acad::eBadDxfSequence;
|
|
}
|
|
|
|
{
|
|
XPushMemVar<BOOL> vTemp(g_bSubEntity,TRUE);
|
|
m_lstOpening.Reset();
|
|
|
|
resbuf rb;
|
|
while ((es == Acad::eOk)
|
|
&& ((es = pFiler->readResBuf(&rb)) == Acad::eOk))
|
|
{
|
|
switch (rb.restype)
|
|
{
|
|
case AcDb::kDxfInt8:
|
|
{
|
|
TDbOpening* pOpening=new TDbOpening;
|
|
m_lstOpening.Append(pOpening);
|
|
es=pOpening->dxfInFields(pFiler);
|
|
if(es!=Acad::eOk)
|
|
return es;
|
|
}
|
|
break;
|
|
default:
|
|
pFiler->pushBackItem();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return pFiler->filerStatus();
|
|
}
|
|
|
|
Acad::ErrorStatus TDbGroupOpening::dxfOutFields(AcDbDxfFiler* pFiler) const
|
|
{
|
|
assertReadEnabled();
|
|
Acad::ErrorStatus es;
|
|
|
|
es = TDbOpening::dxfOutFields(pFiler);
|
|
assert(es == Acad::eOk);
|
|
|
|
es = pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbGroupOpening"));
|
|
assert(es == Acad::eOk);
|
|
|
|
for(long i=0;i<GetOpeningNum();i++)
|
|
{
|
|
pFiler->writeItem(AcDb::kDxfInt8,(Adesk::Int8)0);
|
|
m_lstOpening[i].dxfOutFields(pFiler);
|
|
}
|
|
|
|
return es;
|
|
}
|
|
Acad::ErrorStatus TDbGroupOpening::subGetGripPoints(AcGePoint3dArray& gripPoints,
|
|
AcDbIntArray& osnapModes,
|
|
AcDbIntArray& geomIds) const
|
|
{
|
|
assertReadEnabled();
|
|
|
|
for(long i=0;i<m_lstOpening.Length();i++)
|
|
{
|
|
AcDbIntArray osnapModes1,geomIds1;
|
|
AcGePoint3dArray gripPoints1;
|
|
m_lstOpening[i].getGripPoints(gripPoints1,osnapModes1,geomIds1);
|
|
|
|
if(i==0)
|
|
gripPoints.append(gripPoints1[1]);
|
|
gripPoints.append(gripPoints1[3]);
|
|
gripPoints.append(gripPoints1[2]);
|
|
}
|
|
AcDbIntArray osnapModes1,geomIds1;
|
|
AcGePoint3dArray gripPoints1;
|
|
TDbOpening::subGetGripPoints(gripPoints1,osnapModes1,geomIds1);
|
|
gripPoints.append(gripPoints1[3]);
|
|
if(!!m_sLabel)
|
|
gripPoints.append(m_ptLabel);
|
|
return Acad::eOk;
|
|
}
|
|
Acad::ErrorStatus TDbGroupOpening::subMoveGripPointsAt(const AcDbIntArray& indices,const AcGeVector3d& offset)
|
|
{
|
|
assertWriteEnabled();
|
|
|
|
TDbGroupOpening backup;
|
|
backup.CopyPropertiesFrom(this,0);
|
|
for(long i=0;i<indices.length();i++)
|
|
{
|
|
AcDbIntArray indices1;
|
|
long index=indices[i];
|
|
if(index<GetOpeningNum()*2+1)//分隔点
|
|
{
|
|
if(index%2==0)
|
|
{
|
|
if(index==0||index==GetOpeningNum()*2)
|
|
{
|
|
if(GetCtrlToggle())
|
|
{
|
|
indices1.append(index==0?1:2);
|
|
double dWidth = 0;
|
|
for(long i=0; i<GetOpeningNum(); i++)
|
|
dWidth += m_lstOpening[i]->GetWidth();
|
|
for(long iWin=0;iWin<GetOpeningNum();iWin++)
|
|
{
|
|
TDbOpening *pOpening=m_lstOpening[iWin];
|
|
AcGeVector3d offset1=offset*(pOpening->GetWidth()/dWidth);
|
|
pOpening->moveGripPointsAt(indices1,offset1);
|
|
}
|
|
|
|
TDbOpening::subMoveGripPointsAt(indices1,offset);
|
|
}
|
|
else
|
|
{
|
|
indices1.append(0);
|
|
for(long iWin=0;iWin<GetOpeningNum();iWin++)
|
|
m_lstOpening[iWin]->moveGripPointsAt(indices1,offset);
|
|
TDbOpening::subMoveGripPointsAt(indices1,offset);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
XPushMemVar<BOOL> vTemp(GetCtrlToggle(),TRUE);
|
|
long iWin=index/2;
|
|
indices1.append(1);
|
|
m_lstOpening[iWin]->moveGripPointsAt(indices1,offset);
|
|
indices1[0]=2;
|
|
m_lstOpening[iWin-1]->moveGripPointsAt(indices1,offset);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
long iWin=index/2;
|
|
indices1.append(3);
|
|
m_lstOpening[iWin]->moveGripPointsAt(indices1,offset);
|
|
}
|
|
}
|
|
else if(index==GetOpeningNum()*2+1)//总体开启方向控制
|
|
{
|
|
AcDbIntArray indice1;
|
|
indice1.append(3);
|
|
int oldQuadrant=m_nQuadrant;
|
|
TDbOpening::subMoveGripPointsAt(indice1,offset);
|
|
if(m_nQuadrant!=oldQuadrant)
|
|
{
|
|
BOOL bLeftRight=TRUE;
|
|
for(long iWin=0;iWin<m_lstOpening.Length();iWin++)
|
|
{
|
|
if(oldQuadrant==0)
|
|
{
|
|
if(m_nQuadrant==1)
|
|
m_lstOpening[iWin]->MirrorSelf(TRUE);
|
|
else if(m_nQuadrant==2)
|
|
{
|
|
m_lstOpening[iWin]->MirrorSelf(TRUE);
|
|
m_lstOpening[iWin]->MirrorSelf(FALSE);
|
|
}
|
|
else if(m_nQuadrant==3)
|
|
{
|
|
m_lstOpening[iWin]->MirrorSelf(FALSE);
|
|
bLeftRight=FALSE;
|
|
}
|
|
}
|
|
else if(oldQuadrant==1)
|
|
{
|
|
if(m_nQuadrant==0)
|
|
m_lstOpening[iWin]->MirrorSelf(TRUE);
|
|
else if(m_nQuadrant==3)
|
|
{
|
|
m_lstOpening[iWin]->MirrorSelf(TRUE);
|
|
m_lstOpening[iWin]->MirrorSelf(FALSE);
|
|
}
|
|
else if(m_nQuadrant==2)
|
|
{
|
|
m_lstOpening[iWin]->MirrorSelf(FALSE);
|
|
bLeftRight=FALSE;
|
|
}
|
|
}
|
|
else if(oldQuadrant==2)
|
|
{
|
|
if(m_nQuadrant==3)
|
|
m_lstOpening[iWin]->MirrorSelf(TRUE);
|
|
else if(m_nQuadrant==0)
|
|
{
|
|
m_lstOpening[iWin]->MirrorSelf(TRUE);
|
|
m_lstOpening[iWin]->MirrorSelf(FALSE);
|
|
}
|
|
else if(m_nQuadrant==1)
|
|
{
|
|
m_lstOpening[iWin]->MirrorSelf(FALSE);
|
|
bLeftRight=FALSE;
|
|
}
|
|
}
|
|
else if(oldQuadrant==3)
|
|
{
|
|
if(m_nQuadrant==2)
|
|
m_lstOpening[iWin]->MirrorSelf(TRUE);
|
|
else if(m_nQuadrant==1)
|
|
{
|
|
m_lstOpening[iWin]->MirrorSelf(TRUE);
|
|
m_lstOpening[iWin]->MirrorSelf(FALSE);
|
|
}
|
|
else if(m_nQuadrant==0)
|
|
{
|
|
m_lstOpening[iWin]->MirrorSelf(FALSE);
|
|
bLeftRight=FALSE;
|
|
}
|
|
}
|
|
}
|
|
if(bLeftRight)
|
|
m_lstOpening.Reverse();
|
|
}
|
|
}
|
|
else//编号位置
|
|
m_ptLabel+=offset;
|
|
}
|
|
|
|
if(!IsValid())
|
|
{
|
|
CopyPropertiesFrom(&backup,0);
|
|
return Acad::eInvalidInput;
|
|
}
|
|
else
|
|
Update(false);
|
|
|
|
return Acad::eOk;
|
|
}
|
|
#if ADS>15
|
|
void TDbGroupOpening::CreateGrip()
|
|
{
|
|
TDbEntity::CreateGrip();
|
|
XCurveSegment curve;
|
|
if(GetCenterCurve(curve)&&curve.Is(CURVE_LINE))
|
|
{
|
|
long num=GetOpeningNum()*2+1;
|
|
for(long i=0;i<num;i+=2)
|
|
if(i==0||i==GetOpeningNum()*2)//两侧夹点
|
|
{
|
|
GetGrip(i)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimResultantLength));//总宽
|
|
GetGrip(i)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimDeltaLength));//垛距(前或后)
|
|
GetGrip(i)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimDeltaLength,false));//相对距离
|
|
}
|
|
else//间隔夹点
|
|
{
|
|
GetGrip(i)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimResultantLength));//左窗宽
|
|
GetGrip(i)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimResultantLength));//后窗宽
|
|
}
|
|
}
|
|
}
|
|
Acad::ErrorStatus TDbGroupOpening::EntityToDim(long iGrip,long iDim,const AcDbEntity*pEnt0)
|
|
{
|
|
XCurveSegment wall;
|
|
if(!GetCenterCurve(wall))//中线
|
|
return Acad::eInvalidInput;
|
|
|
|
TDbGripDim*pDim=GetGripDim(iGrip,iDim);
|
|
if(pDim==NULL)
|
|
return Acad::eInvalidInput;
|
|
|
|
TDbGroupOpening*pEnt=TDbGroupOpening::cast(pEnt0);
|
|
if(pEnt==NULL)
|
|
pEnt=this;
|
|
|
|
if(iGrip == 0)
|
|
{// 起点
|
|
switch(iDim)
|
|
{
|
|
case 0://总宽
|
|
{
|
|
TDbGripDistDim*pDistDim=(TDbGripDistDim*)pDim;
|
|
XPoint ptSideStart, ptSideEnd;
|
|
pEnt->GetSidePoints(ptSideStart, ptSideEnd);
|
|
pDistDim->SetData(ptSideStart.AsAcGePoint3d(),ptSideEnd.AsAcGePoint3d(),1500);
|
|
}
|
|
break;
|
|
case 1://前垛距
|
|
{
|
|
XCurveSegment seg;
|
|
TDbGripDistDim*pDistDim=(TDbGripDistDim*)pDim;
|
|
XPoint pt;
|
|
if(GetNeighbourPoint(pt,true))
|
|
{
|
|
XPoint ptSideStart,ptSideEnd;
|
|
pEnt->GetSidePoints(ptSideStart, ptSideEnd);
|
|
wall.ProjectToMe(pt,pt);
|
|
wall.ProjectToMe(ptSideStart,ptSideStart);
|
|
pDistDim->SetData(pt.AsAcGePoint3d(),ptSideStart.AsAcGePoint3d(),1200);
|
|
}
|
|
}
|
|
break;
|
|
case 2://相对距离
|
|
{
|
|
TDbGripDistDim*pDistDim=(TDbGripDistDim*)pDim;
|
|
XPoint ptSideStart,ptSideEnd;
|
|
pEnt->GetSidePoints(ptSideStart, ptSideEnd);
|
|
wall.ProjectToMe(ptSideStart,ptSideStart);
|
|
pDistDim->SetData(pDim->GripPoint(),ptSideStart.AsAcGePoint3d(),800);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
else if(iGrip == GetOpeningNum()*2)
|
|
{// 终点
|
|
switch(iDim)
|
|
{
|
|
case 0://总宽
|
|
{
|
|
TDbGripDistDim*pDistDim=(TDbGripDistDim*)pDim;
|
|
XPoint ptSideStart, ptSideEnd;
|
|
pEnt->GetSidePoints(ptSideStart, ptSideEnd);
|
|
pDistDim->SetData(ptSideStart.AsAcGePoint3d(),ptSideEnd.AsAcGePoint3d(),1500);
|
|
}
|
|
break;
|
|
case 1://后垛距
|
|
{
|
|
XCurveSegment seg;
|
|
TDbGripDistDim*pDistDim=(TDbGripDistDim*)pDim;
|
|
XPoint pt;
|
|
if(GetNeighbourPoint(pt,false))
|
|
{
|
|
XPoint ptSideStart,ptSideEnd;
|
|
pEnt->GetSidePoints(ptSideStart, ptSideEnd);
|
|
wall.ProjectToMe(pt,pt);
|
|
wall.ProjectToMe(ptSideEnd,ptSideEnd);
|
|
pDistDim->SetData(ptSideEnd.AsAcGePoint3d(),pt.AsAcGePoint3d(),1200);
|
|
}
|
|
}
|
|
break;
|
|
case 2://相对距离
|
|
{
|
|
TDbGripDistDim*pDistDim=(TDbGripDistDim*)pDim;
|
|
XPoint ptSideStart,ptSideEnd;
|
|
pEnt->GetSidePoints(ptSideStart, ptSideEnd);
|
|
wall.ProjectToMe(ptSideEnd,ptSideEnd);
|
|
pDistDim->SetData(pDim->GripPoint(),ptSideEnd.AsAcGePoint3d(),800);
|
|
}
|
|
break;
|
|
default:
|
|
return Acad::eNotImplementedYet;
|
|
}
|
|
}
|
|
else
|
|
{// 中间点
|
|
switch(iDim)
|
|
{
|
|
case 0://左窗宽
|
|
{
|
|
TDbGripDistDim*pDistDim=(TDbGripDistDim*)pDim;
|
|
XPoint ptSideStart, ptSideEnd;
|
|
long iWin=iGrip/2;
|
|
pEnt->m_lstOpening[iWin-1]->GetSidePoints(ptSideStart, ptSideEnd);
|
|
pDistDim->SetData(ptSideStart.AsAcGePoint3d(),ptSideEnd.AsAcGePoint3d(),1500);
|
|
}
|
|
break;
|
|
case 1://右窗宽
|
|
{
|
|
TDbGripDistDim*pDistDim=(TDbGripDistDim*)pDim;
|
|
XPoint ptSideStart, ptSideEnd;
|
|
long iWin=iGrip/2;
|
|
pEnt->m_lstOpening[iWin]->GetSidePoints(ptSideStart, ptSideEnd);
|
|
pDistDim->SetData(ptSideStart.AsAcGePoint3d(),ptSideEnd.AsAcGePoint3d(),1500);
|
|
}
|
|
break;
|
|
default:
|
|
return Acad::eNotImplementedYet;
|
|
}
|
|
}
|
|
return Acad::eOk;
|
|
}
|
|
Acad::ErrorStatus TDbGroupOpening::DimToEntity(long iGrip,long iDim,double newValue,const AcGeVector3d&offset)
|
|
{
|
|
assertWriteEnabled();
|
|
AcGePoint3d ptNew=GetGripPoint(iGrip)+offset;
|
|
|
|
XCurveSegment wall;
|
|
GetCenterCurve(wall);
|
|
XPoint vt=wall.EndPoint()-wall.StartPoint();
|
|
vt.Normalize();
|
|
|
|
if(iGrip == 0)
|
|
{// 起点
|
|
switch(iDim)
|
|
{
|
|
case 0://总宽
|
|
if(newValue>1E-6)
|
|
{
|
|
double dWidth = 0;
|
|
for(long i=0; i<GetOpeningNum(); i++)
|
|
dWidth += m_lstOpening[i]->GetWidth();
|
|
|
|
vt *= (dWidth - newValue)/2;
|
|
m_ptLocation += vt;
|
|
m_ptLabel+=vt;
|
|
for(long i=0; i<GetOpeningNum(); i++)
|
|
{
|
|
double oldWidth = m_lstOpening[i]->GetWidth();
|
|
m_lstOpening[i]->SetWidth(oldWidth*newValue/dWidth);
|
|
}
|
|
}
|
|
break;
|
|
case 1://前垛距
|
|
{
|
|
XPoint pt;
|
|
GetNeighbourPoint(pt,true);
|
|
wall.ProjectToMe(pt,pt);
|
|
|
|
double oldValue=pt.Distance2d(GetGripPoint(iGrip));
|
|
if(GetCtrlToggle())//单侧改宽
|
|
{
|
|
double dWidth = 0;
|
|
for(long i=0; i<GetOpeningNum(); i++)
|
|
dWidth += m_lstOpening[i]->GetWidth();
|
|
|
|
newValue=dWidth-newValue+oldValue;
|
|
if(newValue>1E-6)
|
|
{
|
|
vt*=((dWidth-newValue)/2);
|
|
m_ptLocation+=vt;
|
|
m_ptLabel+=vt;
|
|
for(long i=0; i<GetOpeningNum(); i++)
|
|
{
|
|
double oldWidth = m_lstOpening[i]->GetWidth();
|
|
m_lstOpening[i]->SetWidth(oldWidth*newValue/dWidth);
|
|
}
|
|
}
|
|
}
|
|
else//整体偏移
|
|
{
|
|
vt*=(newValue-oldValue);
|
|
m_ptLocation+=vt;
|
|
m_ptLabel+=vt;
|
|
}
|
|
}
|
|
break;
|
|
case 2://相对距离
|
|
{
|
|
if(GetCtrlToggle())//单侧改宽
|
|
{
|
|
double dWidth = 0;
|
|
for(long i=0; i<GetOpeningNum(); i++)
|
|
dWidth += m_lstOpening[i]->GetWidth();
|
|
if(vt.AsAcGeVector3d().dotProduct(offset)>0)
|
|
newValue=dWidth-newValue;
|
|
else
|
|
newValue=dWidth+newValue;
|
|
|
|
if(newValue>1E-6)
|
|
{
|
|
vt *= (dWidth - newValue)/2;
|
|
m_ptLocation += vt;
|
|
m_ptLabel+=vt;
|
|
for(long i=0; i<GetOpeningNum(); i++)
|
|
{
|
|
double oldWidth = m_lstOpening[i]->GetWidth();
|
|
m_lstOpening[i]->SetWidth(oldWidth*newValue/dWidth);
|
|
}
|
|
}
|
|
}
|
|
else//整体偏移
|
|
{
|
|
if(vt.AsAcGeVector3d().dotProduct(offset)>0)
|
|
vt*=newValue;
|
|
else
|
|
vt*=-newValue;
|
|
m_ptLocation+=vt;
|
|
m_ptLabel+=vt;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
else if(iGrip == GetOpeningNum()*2)
|
|
{// 终点
|
|
switch(iDim)
|
|
{
|
|
case 0://总宽
|
|
{
|
|
double dWidth = 0;
|
|
for(long i=0; i<GetOpeningNum(); i++)
|
|
dWidth += m_lstOpening[i]->GetWidth();
|
|
|
|
vt *= (newValue - dWidth)/2;
|
|
m_ptLocation += vt;
|
|
m_ptLabel+=vt;
|
|
for(long i=0; i<GetOpeningNum(); i++)
|
|
{
|
|
double oldWidth = m_lstOpening[i]->GetWidth();
|
|
m_lstOpening[i]->SetWidth(oldWidth*newValue/dWidth);
|
|
}
|
|
}
|
|
break;
|
|
case 1://后垛距
|
|
{
|
|
XCurveSegment seg;
|
|
XPoint pt;
|
|
GetNeighbourPoint(pt,false);
|
|
wall.ProjectToMe(pt,pt);
|
|
|
|
double oldValue=pt.Distance2d(GetGripPoint(iGrip));
|
|
if(GetCtrlToggle())//单侧改宽
|
|
{
|
|
double dWidth = 0;
|
|
for(long i=0; i<GetOpeningNum(); i++)
|
|
dWidth += m_lstOpening[i]->GetWidth();
|
|
|
|
newValue=dWidth-newValue+oldValue;
|
|
if(newValue>1E-6)
|
|
{
|
|
vt*=((newValue-dWidth)/2);
|
|
m_ptLocation+=vt;
|
|
m_ptLabel+=vt;
|
|
for(long i=0; i<GetOpeningNum(); i++)
|
|
{
|
|
double oldWidth = m_lstOpening[i]->GetWidth();
|
|
m_lstOpening[i]->SetWidth(oldWidth*newValue/dWidth);
|
|
}
|
|
}
|
|
}
|
|
else//整体偏移
|
|
{
|
|
vt*=(oldValue-newValue);
|
|
m_ptLocation+=vt;
|
|
m_ptLabel+=vt;
|
|
}
|
|
}
|
|
break;
|
|
case 2://相对距离
|
|
{
|
|
if(GetCtrlToggle())//单侧改宽
|
|
{
|
|
double dWidth = 0;
|
|
for(long i=0; i<GetOpeningNum(); i++)
|
|
dWidth += m_lstOpening[i]->GetWidth();
|
|
if(vt.AsAcGeVector3d().dotProduct(offset)>0)
|
|
newValue=dWidth+newValue;
|
|
else
|
|
newValue=dWidth-newValue;
|
|
|
|
if(newValue>1E-6)
|
|
{
|
|
vt *= (newValue - dWidth)/2;
|
|
m_ptLocation += vt;
|
|
m_ptLabel+=vt;
|
|
for(long i=0; i<GetOpeningNum(); i++)
|
|
{
|
|
double oldWidth = m_lstOpening[i]->GetWidth();
|
|
m_lstOpening[i]->SetWidth(oldWidth*newValue/dWidth);
|
|
}
|
|
}
|
|
}
|
|
else//整体偏移
|
|
{
|
|
if(vt.AsAcGeVector3d().dotProduct(offset)>0)
|
|
vt*=newValue;
|
|
else
|
|
vt*=-newValue;
|
|
m_ptLocation+=vt;
|
|
m_ptLabel+=vt;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{// 中间点
|
|
switch(iDim)
|
|
{
|
|
case 0://左窗宽
|
|
{
|
|
long iWin=iGrip/2;
|
|
double dTolWidth = m_lstOpening[iWin-1]->GetWidth() + m_lstOpening[iWin]->GetWidth();
|
|
if(newValue > 1E-6 && (newValue - dTolWidth) < 1E-6)
|
|
{
|
|
XPushMemVar<BOOL> vTemp(GetCtrlToggle(),TRUE);
|
|
m_lstOpening[iWin-1]->SetWidth(newValue);
|
|
m_lstOpening[iWin]->SetWidth(dTolWidth - newValue);
|
|
}
|
|
}
|
|
break;
|
|
case 1://右窗宽
|
|
{
|
|
long iWin=iGrip/2;
|
|
double dTolWidth = m_lstOpening[iWin-1]->GetWidth() + m_lstOpening[iWin]->GetWidth();
|
|
if(newValue > 1E-6 && (newValue - dTolWidth) < 1E-6)
|
|
{
|
|
XPushMemVar<BOOL> vTemp(GetCtrlToggle(),TRUE);
|
|
m_lstOpening[iWin-1]->SetWidth(dTolWidth - newValue);
|
|
m_lstOpening[iWin]->SetWidth(newValue);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return Acad::eOk;
|
|
}
|
|
#endif
|
|
|
|
Acad::ErrorStatus TDbGroupOpening::subTransformBy(const AcGeMatrix3d& xform)
|
|
{
|
|
assertWriteEnabled();
|
|
TDbOpening::subTransformBy(xform);
|
|
for(long i=0;i<GetOpeningNum();i++)
|
|
m_lstOpening[i]->transformBy(xform);
|
|
|
|
return Acad::eOk;
|
|
}
|
|
Acad::ErrorStatus TDbGroupOpening::subGetOsnapPoints(
|
|
AcDb::OsnapMode osnapMode,
|
|
INT_PTR gsSelectionMark,
|
|
const AcGePoint3d& pickPoint,
|
|
const AcGePoint3d& lastPoint,
|
|
const AcGeMatrix3d& viewXform,
|
|
AcGePoint3dArray& snapPoints,
|
|
AcDbIntArray& geomIds) const
|
|
{
|
|
return TDbEntity::subGetOsnapPoints(osnapMode,gsSelectionMark,pickPoint,lastPoint,viewXform,snapPoints,geomIds);
|
|
}
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
void InitDbGroupOpening(BOOL bTrue)
|
|
{
|
|
if(bTrue)
|
|
{
|
|
TDbGroupOpening::rxInit();
|
|
acrxBuildClassHierarchy();
|
|
TDbGroupOpening::InitMatchProtocol(TRUE);
|
|
}
|
|
else
|
|
{
|
|
TDbGroupOpening::InitMatchProtocol(FALSE);
|
|
deleteAcRxClass(TDbGroupOpening::desc());
|
|
}
|
|
}
|
|
void GroupOpening()
|
|
{
|
|
PickSet ss(SS_FREE);
|
|
if(SelectEntities(_T("\n选择需要组合的门窗和编号文字:"),ss,RBList(RTDXF0,_T("ATS_OPENING,ATS_TEXT"),NULL))!=RTNORM)
|
|
return;
|
|
|
|
TDbGroupOpening *pOpening=new TDbGroupOpening;
|
|
pOpening->InitHardPointerId();
|
|
AcDbObjectId wallId=AcDbObjectId::kNull;
|
|
bool bNamed=false;
|
|
for(long i=0;i<ss.Length();i++)
|
|
{
|
|
Entity ent=ss[i];
|
|
if(ent.Is(_T("ATS_TEXT")))
|
|
{
|
|
OPENOBJ_BEGIN(ent,AcDb::kForRead,TDbText,pText);
|
|
if(pText!=NULL)
|
|
{
|
|
pOpening->SetLabel(pText->GetText());
|
|
pOpening->SetLabelPos(pText->GetLocation());
|
|
bNamed=true;
|
|
}
|
|
OPENOBJ_END()
|
|
}
|
|
else
|
|
{
|
|
OPENOBJ_BEGIN(ent,AcDb::kForWrite,TDbOpening,pEnt);
|
|
if(pEnt!=NULL)
|
|
{
|
|
if(pEnt->GetKind()==TOpeningData::OP_GROUP)//组合门窗不能嵌套
|
|
continue;
|
|
|
|
if(wallId==AcDbObjectId::kNull)
|
|
{
|
|
wallId=pEnt->GetWallId();
|
|
pOpening->SetWallId(wallId);
|
|
}
|
|
else if(wallId!=pEnt->GetWallId())
|
|
{
|
|
adsout<<_T("\n组合的门窗必须属于同一面墙!");
|
|
wallId=AcDbObjectId::kNull;
|
|
break;
|
|
}
|
|
pOpening->Append((TDbOpening*)pEnt->clone());
|
|
}
|
|
OPENOBJ_END()
|
|
}
|
|
}
|
|
|
|
if(wallId!=AcDbObjectId::kNull)
|
|
{
|
|
pOpening->Update(TRUE);
|
|
// sg add 110126,组合门窗设置布局转角,保证标注方向正确
|
|
pOpening->SetLayoutRotation(Ucs2Wcs(0));
|
|
if(!bNamed)
|
|
{
|
|
XString sName;
|
|
if(acedGetString(TRUE,_T("\n输入编号:"),sName)==RTNORM)
|
|
pOpening->SetLabel(sName);
|
|
}
|
|
|
|
if(pOpening->IsValid())
|
|
{
|
|
ss.Erase();
|
|
|
|
AcDbObjectId idOpening=pOpening->AddToMSpace(Adesk::kTrue);
|
|
TDbWall*pWall=NULL;
|
|
acdbOpenObject(pWall,wallId,AcDb::kForWrite);
|
|
if(pWall!=NULL)
|
|
{
|
|
pWall->AddOpeningId(idOpening);
|
|
pWall->close();
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
adsout<<_T("\n组合门窗失败!");
|
|
delete pOpening;
|
|
} |