#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;i0; } 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;iGetOpeningNum();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;iGetWidth(); double botElev=m_lstOpening[0]->GetElevation(),topElev=m_lstOpening[0]->GetTopElev(); for(i=1;iGetElevation()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;iGetWidth()/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;iSetSill(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;iSetWidth(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;iSetHeight(pWin->GetHeight()*s); double offset=pWin->GetSill()-nSill; offset*=s; pWin->SetSill(nSill+offset); } return Acad::eOk; } // 验证调整和墙的配属关系 // 方法: 如果有配属的墙则验证是否成立配属关系; 否则寻找一配属墙,确立新的关系 // 注意: 在命令结束时处理 void TDbGroupOpening::ValidateContainership(DList &lstWalls) { assertWriteEnabled(); double nDirectionOld=m_nRotation; TDbOpening::ValidateContainership(lstWalls); //新方向与旧方向夹角大于90度时,尽量维持原开启方向 if(fabs(m_nRotation-nDirectionOld)>PI/2) { for(long i=0;im_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 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;iMirrorSelf(bLeftRight); if(bLeftRight) m_lstOpening.Reverse(); } Acad::ErrorStatus TDbGroupOpening::ExplodeOrDraw2d(XExplodeDraw&dc)const { assertReadEnabled(); if (!IsValid()) return Acad::eNotApplicable; TDbOpening::ExplodeOrDraw2d(dc); { XPushMemVar vTemp(g_bSubEntity,TRUE); if(dc.IsFullExplode()) { XPushMemVar vTemp0(g_pCurrentDb,database()); for(long i=0;i vTemp(g_bSubEntity,TRUE); if(dc.IsFullExplode()) { XPushMemVar vTemp0(g_pCurrentDb,database()); for(long i=0;ireadItem(&nVer); if(nVer>g_nVersion) return Acad::eMakeMeProxy; Adesk::Int32 num; pFiler->readItem(&num); m_lstOpening.Reset(); for(long i=0;idwgInFields(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;iatSubclassData(_T("TDbGroupOpening"))) { return Acad::eBadDxfSequence; } { XPushMemVar 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;iwriteItem(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;iGetWidth(); for(long iWin=0;iWinGetWidth()/dWidth); pOpening->moveGripPointsAt(indices1,offset1); } TDbOpening::subMoveGripPointsAt(indices1,offset); } else { indices1.append(0); for(long iWin=0;iWinmoveGripPointsAt(indices1,offset); TDbOpening::subMoveGripPointsAt(indices1,offset); } } else { XPushMemVar 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;iWinMirrorSelf(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;iAppendDim(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; iGetWidth(); vt *= (dWidth - newValue)/2; m_ptLocation += vt; m_ptLabel+=vt; for(long i=0; iGetWidth(); 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; iGetWidth(); newValue=dWidth-newValue+oldValue; if(newValue>1E-6) { vt*=((dWidth-newValue)/2); m_ptLocation+=vt; m_ptLabel+=vt; for(long i=0; iGetWidth(); 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; iGetWidth(); 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; iGetWidth(); 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; iGetWidth(); vt *= (newValue - dWidth)/2; m_ptLocation += vt; m_ptLabel+=vt; for(long i=0; iGetWidth(); 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; iGetWidth(); newValue=dWidth-newValue+oldValue; if(newValue>1E-6) { vt*=((newValue-dWidth)/2); m_ptLocation+=vt; m_ptLabel+=vt; for(long i=0; iGetWidth(); 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; iGetWidth(); 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; iGetWidth(); 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 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 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;itransformBy(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;iSetLabel(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; }